123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344 |
- /*
- * © 2010 The Android Open Source Project
- *
- * Лицензировано по лицензии Apache License, версия 2.0 ( "Лицензия");
- *этот файл можно использовать только в соответствии с лицензией.
- *Копию лицензии можно получить на веб-сайте
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- *Если только не требуется в соответствии с применимым законодательством или согласовано в письменном виде, программное обеспечение
- * распространяется в рамках лицензии на УСЛОВИЯХ "КАК ЕСТЬ",
- * БЕЗ ГАРАНТИЙ И УСЛОВИЙ ЛЮБОГО РОДА, явно выраженных и подразумеваемых.
- * См. лицензию для получения информации об определенных разрешениях по использованию языка и
- * ограничениях в рамках лицензии.
- *
- */
- #ifndef _ANDROID_NATIVE_APP_GLUE_H
- #define _ANDROID_NATIVE_APP_GLUE_H
- #include <poll.h>
- #include <pthread.h>
- #include <sched.h>
- #include <android/configuration.h>
- #include <android/looper.h>
- #include <android/native_activity.h>
- #ifdef __cplusplus
- extern "C" {
- #endif
- /**
- * Интерфейс NativeActivity, предоставленный <android/native_activity.h>,
- * основан на наборе предоставленных приложением обратных вызовов, которые вызываются
- *основным потоком действия при возникновении определенных событий.
- *
- * Это означает, что ни один из данных обратных вызовов _не_ _должен_ блокироваться, иначе
- * существует риск принудительного закрытия приложения системой. Эта модель программирования
- * прямая, простая, но имеет ограничения.
- *
- * Статическая библиотека threaded_native_app используется для обеспечения другой
- * модели выполнения, в которой приложение может реализовать свой собственный цикл главного события
- * в другом потоке вместо этого. Это работает так:
- *
- * 1/ Приложение должно предоставить функцию с именем android_main(), которая
- * будет вызываться при создании действия в новом потоке,
- * отличающемся от основного потока действия.
- *
- * 2/ android_main() получает указатель на допустимую структуру android_app,
- * которая содержит ссылки на другие важные объекты, например экземпляр объекта
- * ANativeActivity, где выполняется приложение.
- *
- * 3/ Объект android_app содержит экземпляр ALooper, который уже
- * ожидает две важных вещи:
- *
- * - событий жизненного цикла действия (например, "pause", "resume"). См. объявления APP_CMD_XXX
- * ниже.
- *
- * - входных событий, поступающих из очереди AInputQueue, присоединенной к действию.
- *
- * Каждое из этих событий соответствует идентификатору ALooper, возвращенному
- * ALooper_pollOnce со значениями LOOPER_ID_MAIN и LOOPER_ID_INPUT,
- *, соответственно.
- *
- * Ваше приложение может использовать тот же ALooper для прослушивания дополнительных
- * дескрипторов файла. Они могут быть основаны либо на обратных вызовах, либо поступают с идентификаторами возврата,
- * начинающимися с LOOPER_ID_USER.
- *
- * 4/ При получении события LOOPER_ID_MAIN или LOOPER_ID_INPUT
- * возвращенные данные будут указывать на структуру android_poll_source. Для нее
- * можно вызвать функцию process() и заполнить android_app->onAppCmd
- * и android_app->onInputEvent, для того чтобы они вызывались для вашей собственной обработки
- * события.
- *
- * Вместо этого можно вызвать функции нижнего уровня для чтения и обработки
- * данных непосредственно... посмотрите на реализации process_cmd() и process_input()
- * в приклеивании, чтобы выяснить, как это делается.
- *
- * См. пример "native-activity" в NDK с
- * полной демонстрацией использования. Также посмотрите JavaDoc в NativeActivity.
- */
- struct android_app;
- /**
- * Данные, связанные с ALooper fd, которые будут возвращаться как outData
- * при готовности данных в этом источнике.
- */
- struct android_poll_source {
- // Идентификатор данного источника. Может быть LOOPER_ID_MAIN или
- // LOOPER_ID_INPUT.
- int32_t id;
- // android_app, с которым связан данный идентификатор.
- struct android_app* app;
- // Функция, вызываемая для стандартной обработки данных из
- // этого источника.
- void (*process)(struct android_app* app, struct android_poll_source* source);
- };
- /**
- * Это интерфейс стандартного кода приклеивания поточного
- * приложения. В этой модели код приложения выполняется
- * в своем собственном потоке, отдельном от основного потока процесса.
- * Не требуется связь данного потока с ВМ Java
- *, хотя это необходимо для выполнения вызовов JNI любых
- * объектов Java.
- */
- struct android_app {
- // Приложение может поместить указатель на свой собственный объект состояния
- // здесь, если нужно.
- void* userData;
- // Введите здесь код функции для обработки основных команд приложения (APP_CMD_*)
- void (*onAppCmd)(struct android_app* app, int32_t cmd);
- // Введите здесь код функции для обработки входных событий. Сейчас
- // событие уже было предварительно отправлено и будет завершено при
- // возврате. Верните 1, если событие обработано, 0 — для любой диспетчеризации
- // по умолчанию.
- int32_t (*onInputEvent)(struct android_app* app, AInputEvent* event);
- // Экземпляр объекта ANativeActivity, в котором выполняется это приложение.
- ANativeActivity* activity;
- // Текущая конфигурация, в которой выполняется это приложение.
- AConfiguration* config;
- // Это последнее сохраненное состояние экземпляра, предоставленное во время создания.
- // Значение равно NULL, если состояния не было. Можно использовать это по мере необходимости;
- // память останется доступной до вызова android_app_exec_cmd() для
- // APP_CMD_RESUME, после чего она будет освобождена, а savedState получит значение NULL.
- // Эти переменные необходимо изменять только при обработке APP_CMD_SAVE_STATE,
- // когда их значения будут инициализироваться в NULL и можно будет выполнить malloc для
- // состояния и поместить здесь информацию. В этом случае память будет
- // освобождена позднее.
- void* savedState;
- size_t savedStateSize;
- // ALooper, связанный с потоком приложения.
- ALooper* looper;
- // Если значение не равно NULL, то это входная очередь, из которой приложение будет
- // получать входные события пользователя.
- AInputQueue* inputQueue;
- // Если значение не равно NULL, то это поверхность окна, в котором приложение может рисовать.
- ANativeWindow* window;
- // Текущий прямоугольник содержимого окна. Это область, в которой
- // должно помещаться содержимое окна, чтобы его видел пользователь.
- ARect contentRect;
- // Текущее состояние действия приложения. Может быть APP_CMD_START,
- // APP_CMD_RESUME, APP_CMD_PAUSE или APP_CMD_STOP; см. ниже.
- int activityState;
- // Значение не равно нулю, когда NativeActivity приложения
- // разрушается и ожидает завершения потока приложения.
- int destroyRequested;
- // -------------------------------------------------
- // Ниже показан "частная" реализация кода прилипания.
- pthread_mutex_t mutex;
- pthread_cond_t cond;
- int msgread;
- int msgwrite;
- pthread_t thread;
- struct android_poll_source cmdPollSource;
- struct android_poll_source inputPollSource;
- int running;
- int stateSaved;
- int destroyed;
- int redrawNeeded;
- AInputQueue* pendingInputQueue;
- ANativeWindow* pendingWindow;
- ARect pendingContentRect;
- };
- enum {
- /**
- * Идентификатор данных Looper команд, поступающих из основного потока приложения, который
- * возвращается как идентификатор от ALooper_pollOnce(). Данные для этого идентификатора
- * являются указателем на структуру android_poll_source.
- * Их можно извлечь и обработать с помощью android_app_read_cmd()
- * и android_app_exec_cmd().
- */
- LOOPER_ID_MAIN = 1,
- /**
- * Идентификатор данных Looper событий, поступающий из AInputQueue окна
- * приложения, который возвращается как идентификатор из
- * ALooper_pollOnce(). Данные этого идентификатора являются указателем на структуру
- * android_poll_source. Их можно прочитать через объект inputQueue
- * приложения android_app.
- */
- LOOPER_ID_INPUT = 2,
- /**
- * Запуск определяемых пользователем идентификаторов ALooper.
- */
- LOOPER_ID_USER = 3,
- };
- enum {
- /**
- * Команда из основного потока: AInputQueue изменена. После обработки
- * этой команды android_app->inputQueue будет обновлена в новую очередь
- * (или NULL).
- */
- APP_CMD_INPUT_CHANGED,
- /**
- * Команда из основного потока: новое окно ANativeWindow готово к использованию. После
- * получения этой команды окно android_app-> будет содержать новую поверхность
- *окна.
- */
- APP_CMD_INIT_WINDOW,
- /**
- * Команда из основного потока: существующее окно ANativeWindow необходимо
- * прекратить. После получения этой команды окно android_app->по-прежнему
- * содержит существующее окно; после вызова android_app_exec_cmd
- * оно получит значение NULL.
- */
- APP_CMD_TERM_WINDOW,
- /**
- * Команда из основного потока: текущее окно ANativeWindow изменило размер.
- * Перерисуйте согласно новом размеру.
- */
- APP_CMD_WINDOW_RESIZED,
- /**
- * Команда из основного потока: системе необходимо, чтобы текущее окно ANativeWindow
- * было перерисовано. Необходимо перерисовать окно перед ее передачей в
- * android_app_exec_cmd(), чтобы избежать переходных сбоев рисования.
- */
- APP_CMD_WINDOW_REDRAW_NEEDED,
- /**
- * Команда из основного потока: область содержимого окна изменена
- * таким образом, что из функционального ввода окно показывается или скрывается. Можно
- * найти новый прямоугольник содержимого в android_app::contentRect.
- */
- APP_CMD_CONTENT_RECT_CHANGED,
- /**
- * Команда из основного потока: окно действия приложения получило
- * фокус ввода.
- */
- APP_CMD_GAINED_FOCUS,
- /**
- * Команда из основного потока: окно действия приложения потеряло
- * фокус ввода.
- */
- APP_CMD_LOST_FOCUS,
- /**
- * Команда из основного потока: изменена текущая конфигурация устройства.
- */
- APP_CMD_CONFIG_CHANGED,
- /**
- * Команда из основного потока: системе не хватает памяти.
- * Попробуйте уменьшить использование памяти.
- */
- APP_CMD_LOW_MEMORY,
- /**
- * Команда из основного потока: действие приложения было запущено.
- */
- APP_CMD_START,
- /**
- * Команда из основного потока: действие приложения было возобновлено.
- */
- APP_CMD_RESUME,
- /**
- * Команда из основного потока: приложение должно создать новое сохраненное состояние
- * для себя, чтобы восстанавливаться из него позднее в случае необходимости. Если вы сохранили состояние,
- * выделите его с использованием malloc и поместите в android_app.savedState с
- * размером android_app.savedStateSize. Память будет освобождена
- * позднее.
- */
- APP_CMD_SAVE_STATE,
- /**
- * Команда из основного потока: пауза в действии приложения.
- */
- APP_CMD_PAUSE,
- /**
- * Команда из основного потока: действие приложения было остановлено.
- */
- APP_CMD_STOP,
- /**
- * Команда из основного потока: действие приложения уничтожается,
- * и ожидает очистки потока приложения и выхода перед обработкой.
- */
- APP_CMD_DESTROY,
- };
- /**
- * Вызовите, когда ALooper_pollAll() возвращает LOOPER_ID_MAIN, при чтении следующего сообщения команды
- *приложения.
- */
- int8_t android_app_read_cmd(struct android_app* android_app);
- /**
- * Вызовите с помощью команды, возвращенной android_app_read_cmd() для выполнения
- * начальной предварительной обработки данной команды. Можно выполнить собственные
- * действия для команды после вызова этой функции.
- */
- void android_app_pre_exec_cmd(struct android_app* android_app, int8_t cmd);
- /**
- * Вызовите с помощью команды, возвращенной android_app_read_cmd(), для
- * окончательной предварительной обработки данной команды. Необходимо завершить собственные
- * действия с командой до вызова этой функции.
- */
- void android_app_post_exec_cmd(struct android_app* android_app, int8_t cmd);
- /**
- * Это функция, которую должен реализовать код приложения, представляет собой
- * главный вход в приложение.
- */
- extern void android_main(struct android_app* app);
- #ifdef __cplusplus
- }
- #endif
- #endif /* _ANDROID_NATIVE_APP_GLUE_H */
|