OLD | NEW |
(Empty) | |
| 1 /* |
| 2 * Copyright (C) 2010 The Android Open Source Project |
| 3 * |
| 4 * Licensed under the Apache License, Version 2.0 (the "License"); |
| 5 * you may not use this file except in compliance with the License. |
| 6 * You may obtain a copy of the License at |
| 7 * |
| 8 * http://www.apache.org/licenses/LICENSE-2.0 |
| 9 * |
| 10 * Unless required by applicable law or agreed to in writing, software |
| 11 * distributed under the License is distributed on an "AS IS" BASIS, |
| 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 13 * See the License for the specific language governing permissions and |
| 14 * limitations under the License. |
| 15 * |
| 16 */ |
| 17 |
| 18 #ifndef _ANDROID_NATIVE_APP_GLUE_H |
| 19 #define _ANDROID_NATIVE_APP_GLUE_H |
| 20 |
| 21 #include <poll.h> |
| 22 #include <pthread.h> |
| 23 #include <sched.h> |
| 24 |
| 25 #include <android/configuration.h> |
| 26 #include <android/looper.h> |
| 27 #include <android/native_activity.h> |
| 28 |
| 29 #ifdef __cplusplus |
| 30 extern "C" { |
| 31 #endif |
| 32 |
| 33 /** |
| 34 * The native activity interface provided by <android/native_activity.h> |
| 35 * is based on a set of application-provided callbacks that will be called |
| 36 * by the Activity's main thread when certain events occur. |
| 37 * |
| 38 * This means that each one of this callbacks _should_ _not_ block, or they |
| 39 * risk having the system force-close the application. This programming |
| 40 * model is direct, lightweight, but constraining. |
| 41 * |
| 42 * The 'android_native_app_glue' static library is used to provide a different |
| 43 * execution model where the application can implement its own main event |
| 44 * loop in a different thread instead. Here's how it works: |
| 45 * |
| 46 * 1/ The application must provide a function named "android_main()" that |
| 47 * will be called when the activity is created, in a new thread that is |
| 48 * distinct from the activity's main thread. |
| 49 * |
| 50 * 2/ android_main() receives a pointer to a valid "android_app" structure |
| 51 * that contains references to other important objects, e.g. the |
| 52 * ANativeActivity obejct instance the application is running in. |
| 53 * |
| 54 * 3/ the "android_app" object holds an ALooper instance that already |
| 55 * listens to two important things: |
| 56 * |
| 57 * - activity lifecycle events (e.g. "pause", "resume"). See APP_CMD_XXX |
| 58 * declarations below. |
| 59 * |
| 60 * - input events coming from the AInputQueue attached to the activity. |
| 61 * |
| 62 * Each of these correspond to an ALooper identifier returned by |
| 63 * ALooper_pollOnce with values of LOOPER_ID_MAIN and LOOPER_ID_INPUT, |
| 64 * respectively. |
| 65 * |
| 66 * Your application can use the same ALooper to listen to additional |
| 67 * file-descriptors. They can either be callback based, or with return |
| 68 * identifiers starting with LOOPER_ID_USER. |
| 69 * |
| 70 * 4/ Whenever you receive a LOOPER_ID_MAIN or LOOPER_ID_INPUT event, |
| 71 * the returned data will point to an android_poll_source structure. You |
| 72 * can call the process() function on it, and fill in android_app->onAppCmd |
| 73 * and android_app->onInputEvent to be called for your own processing |
| 74 * of the event. |
| 75 * |
| 76 * Alternatively, you can call the low-level functions to read and process |
| 77 * the data directly... look at the process_cmd() and process_input() |
| 78 * implementations in the glue to see how to do this. |
| 79 * |
| 80 * See the sample named "native-activity" that comes with the NDK with a |
| 81 * full usage example. Also look at the JavaDoc of NativeActivity. |
| 82 */ |
| 83 |
| 84 struct android_app; |
| 85 |
| 86 /** |
| 87 * Data associated with an ALooper fd that will be returned as the "outData" |
| 88 * when that source has data ready. |
| 89 */ |
| 90 struct android_poll_source { |
| 91 // The identifier of this source. May be LOOPER_ID_MAIN or |
| 92 // LOOPER_ID_INPUT. |
| 93 int32_t id; |
| 94 |
| 95 // The android_app this ident is associated with. |
| 96 struct android_app* app; |
| 97 |
| 98 // Function to call to perform the standard processing of data from |
| 99 // this source. |
| 100 void (*process)(struct android_app* app, struct android_poll_source* source)
; |
| 101 }; |
| 102 |
| 103 /** |
| 104 * This is the interface for the standard glue code of a threaded |
| 105 * application. In this model, the application's code is running |
| 106 * in its own thread separate from the main thread of the process. |
| 107 * It is not required that this thread be associated with the Java |
| 108 * VM, although it will need to be in order to make JNI calls any |
| 109 * Java objects. |
| 110 */ |
| 111 struct android_app { |
| 112 // The application can place a pointer to its own state object |
| 113 // here if it likes. |
| 114 void* userData; |
| 115 |
| 116 // Fill this in with the function to process main app commands (APP_CMD_*) |
| 117 void (*onAppCmd)(struct android_app* app, int32_t cmd); |
| 118 |
| 119 // Fill this in with the function to process input events. At this point |
| 120 // the event has already been pre-dispatched, and it will be finished upon |
| 121 // return. Return 1 if you have handled the event, 0 for any default |
| 122 // dispatching. |
| 123 int32_t (*onInputEvent)(struct android_app* app, AInputEvent* event); |
| 124 |
| 125 // The ANativeActivity object instance that this app is running in. |
| 126 ANativeActivity* activity; |
| 127 |
| 128 // The current configuration the app is running in. |
| 129 AConfiguration* config; |
| 130 |
| 131 // This is the last instance's saved state, as provided at creation time. |
| 132 // It is NULL if there was no state. You can use this as you need; the |
| 133 // memory will remain around until you call android_app_exec_cmd() for |
| 134 // APP_CMD_RESUME, at which point it will be freed and savedState set to NUL
L. |
| 135 // These variables should only be changed when processing a APP_CMD_SAVE_STA
TE, |
| 136 // at which point they will be initialized to NULL and you can malloc your |
| 137 // state and place the information here. In that case the memory will be |
| 138 // freed for you later. |
| 139 void* savedState; |
| 140 size_t savedStateSize; |
| 141 |
| 142 // The ALooper associated with the app's thread. |
| 143 ALooper* looper; |
| 144 |
| 145 // When non-NULL, this is the input queue from which the app will |
| 146 // receive user input events. |
| 147 AInputQueue* inputQueue; |
| 148 |
| 149 // When non-NULL, this is the window surface that the app can draw in. |
| 150 ANativeWindow* window; |
| 151 |
| 152 // Current content rectangle of the window; this is the area where the |
| 153 // window's content should be placed to be seen by the user. |
| 154 ARect contentRect; |
| 155 |
| 156 // Current state of the app's activity. May be either APP_CMD_START, |
| 157 // APP_CMD_RESUME, APP_CMD_PAUSE, or APP_CMD_STOP; see below. |
| 158 int activityState; |
| 159 |
| 160 // This is non-zero when the application's NativeActivity is being |
| 161 // destroyed and waiting for the app thread to complete. |
| 162 int destroyRequested; |
| 163 |
| 164 // ------------------------------------------------- |
| 165 // Below are "private" implementation of the glue code. |
| 166 |
| 167 pthread_mutex_t mutex; |
| 168 pthread_cond_t cond; |
| 169 |
| 170 int msgread; |
| 171 int msgwrite; |
| 172 |
| 173 pthread_t thread; |
| 174 |
| 175 struct android_poll_source cmdPollSource; |
| 176 struct android_poll_source inputPollSource; |
| 177 |
| 178 int running; |
| 179 int stateSaved; |
| 180 int destroyed; |
| 181 int redrawNeeded; |
| 182 AInputQueue* pendingInputQueue; |
| 183 ANativeWindow* pendingWindow; |
| 184 ARect pendingContentRect; |
| 185 }; |
| 186 |
| 187 enum { |
| 188 /** |
| 189 * Looper data ID of commands coming from the app's main thread, which |
| 190 * is returned as an identifier from ALooper_pollOnce(). The data for this |
| 191 * identifier is a pointer to an android_poll_source structure. |
| 192 * These can be retrieved and processed with android_app_read_cmd() |
| 193 * and android_app_exec_cmd(). |
| 194 */ |
| 195 LOOPER_ID_MAIN = 1, |
| 196 |
| 197 /** |
| 198 * Looper data ID of events coming from the AInputQueue of the |
| 199 * application's window, which is returned as an identifier from |
| 200 * ALooper_pollOnce(). The data for this identifier is a pointer to an |
| 201 * android_poll_source structure. These can be read via the inputQueue |
| 202 * object of android_app. |
| 203 */ |
| 204 LOOPER_ID_INPUT = 2, |
| 205 |
| 206 /** |
| 207 * Start of user-defined ALooper identifiers. |
| 208 */ |
| 209 LOOPER_ID_USER = 3, |
| 210 }; |
| 211 |
| 212 enum { |
| 213 /** |
| 214 * Command from main thread: the AInputQueue has changed. Upon processing |
| 215 * this command, android_app->inputQueue will be updated to the new queue |
| 216 * (or NULL). |
| 217 */ |
| 218 APP_CMD_INPUT_CHANGED, |
| 219 |
| 220 /** |
| 221 * Command from main thread: a new ANativeWindow is ready for use. Upon |
| 222 * receiving this command, android_app->window will contain the new window |
| 223 * surface. |
| 224 */ |
| 225 APP_CMD_INIT_WINDOW, |
| 226 |
| 227 /** |
| 228 * Command from main thread: the existing ANativeWindow needs to be |
| 229 * terminated. Upon receiving this command, android_app->window still |
| 230 * contains the existing window; after calling android_app_exec_cmd |
| 231 * it will be set to NULL. |
| 232 */ |
| 233 APP_CMD_TERM_WINDOW, |
| 234 |
| 235 /** |
| 236 * Command from main thread: the current ANativeWindow has been resized. |
| 237 * Please redraw with its new size. |
| 238 */ |
| 239 APP_CMD_WINDOW_RESIZED, |
| 240 |
| 241 /** |
| 242 * Command from main thread: the system needs that the current ANativeWindow |
| 243 * be redrawn. You should redraw the window before handing this to |
| 244 * android_app_exec_cmd() in order to avoid transient drawing glitches. |
| 245 */ |
| 246 APP_CMD_WINDOW_REDRAW_NEEDED, |
| 247 |
| 248 /** |
| 249 * Command from main thread: the content area of the window has changed, |
| 250 * such as from the soft input window being shown or hidden. You can |
| 251 * find the new content rect in android_app::contentRect. |
| 252 */ |
| 253 APP_CMD_CONTENT_RECT_CHANGED, |
| 254 |
| 255 /** |
| 256 * Command from main thread: the app's activity window has gained |
| 257 * input focus. |
| 258 */ |
| 259 APP_CMD_GAINED_FOCUS, |
| 260 |
| 261 /** |
| 262 * Command from main thread: the app's activity window has lost |
| 263 * input focus. |
| 264 */ |
| 265 APP_CMD_LOST_FOCUS, |
| 266 |
| 267 /** |
| 268 * Command from main thread: the current device configuration has changed. |
| 269 */ |
| 270 APP_CMD_CONFIG_CHANGED, |
| 271 |
| 272 /** |
| 273 * Command from main thread: the system is running low on memory. |
| 274 * Try to reduce your memory use. |
| 275 */ |
| 276 APP_CMD_LOW_MEMORY, |
| 277 |
| 278 /** |
| 279 * Command from main thread: the app's activity has been started. |
| 280 */ |
| 281 APP_CMD_START, |
| 282 |
| 283 /** |
| 284 * Command from main thread: the app's activity has been resumed. |
| 285 */ |
| 286 APP_CMD_RESUME, |
| 287 |
| 288 /** |
| 289 * Command from main thread: the app should generate a new saved state |
| 290 * for itself, to restore from later if needed. If you have saved state, |
| 291 * allocate it with malloc and place it in android_app.savedState with |
| 292 * the size in android_app.savedStateSize. The will be freed for you |
| 293 * later. |
| 294 */ |
| 295 APP_CMD_SAVE_STATE, |
| 296 |
| 297 /** |
| 298 * Command from main thread: the app's activity has been paused. |
| 299 */ |
| 300 APP_CMD_PAUSE, |
| 301 |
| 302 /** |
| 303 * Command from main thread: the app's activity has been stopped. |
| 304 */ |
| 305 APP_CMD_STOP, |
| 306 |
| 307 /** |
| 308 * Command from main thread: the app's activity is being destroyed, |
| 309 * and waiting for the app thread to clean up and exit before proceeding. |
| 310 */ |
| 311 APP_CMD_DESTROY, |
| 312 }; |
| 313 |
| 314 /** |
| 315 * Call when ALooper_pollAll() returns LOOPER_ID_MAIN, reading the next |
| 316 * app command message. |
| 317 */ |
| 318 int8_t android_app_read_cmd(struct android_app* android_app); |
| 319 |
| 320 /** |
| 321 * Call with the command returned by android_app_read_cmd() to do the |
| 322 * initial pre-processing of the given command. You can perform your own |
| 323 * actions for the command after calling this function. |
| 324 */ |
| 325 void android_app_pre_exec_cmd(struct android_app* android_app, int8_t cmd); |
| 326 |
| 327 /** |
| 328 * Call with the command returned by android_app_read_cmd() to do the |
| 329 * final post-processing of the given command. You must have done your own |
| 330 * actions for the command before calling this function. |
| 331 */ |
| 332 void android_app_post_exec_cmd(struct android_app* android_app, int8_t cmd); |
| 333 |
| 334 /** |
| 335 * Dummy function you can call to ensure glue code isn't stripped. |
| 336 */ |
| 337 void app_dummy(); |
| 338 |
| 339 /** |
| 340 * This is the function that application code must implement, representing |
| 341 * the main entry to the app. |
| 342 */ |
| 343 extern void android_main(struct android_app* app); |
| 344 |
| 345 #ifdef __cplusplus |
| 346 } |
| 347 #endif |
| 348 |
| 349 #endif /* _ANDROID_NATIVE_APP_GLUE_H */ |
OLD | NEW |