istereo2

annotate src/android/android_native_app_glue.c @ 23:7d795dade0bc

first pass at android port... compiles!
author John Tsiombikas <nuclear@member.fsf.org>
date Sat, 03 Oct 2015 06:10:30 +0300
parents
children
rev   line source
nuclear@23 1 /*
nuclear@23 2 * Copyright (C) 2010 The Android Open Source Project
nuclear@23 3 *
nuclear@23 4 * Licensed under the Apache License, Version 2.0 (the "License");
nuclear@23 5 * you may not use this file except in compliance with the License.
nuclear@23 6 * You may obtain a copy of the License at
nuclear@23 7 *
nuclear@23 8 * http://www.apache.org/licenses/LICENSE-2.0
nuclear@23 9 *
nuclear@23 10 * Unless required by applicable law or agreed to in writing, software
nuclear@23 11 * distributed under the License is distributed on an "AS IS" BASIS,
nuclear@23 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
nuclear@23 13 * See the License for the specific language governing permissions and
nuclear@23 14 * limitations under the License.
nuclear@23 15 *
nuclear@23 16 */
nuclear@23 17
nuclear@23 18 #include <jni.h>
nuclear@23 19
nuclear@23 20 #include <errno.h>
nuclear@23 21 #include <string.h>
nuclear@23 22 #include <unistd.h>
nuclear@23 23 #include <sys/resource.h>
nuclear@23 24
nuclear@23 25 #include "android_native_app_glue.h"
nuclear@23 26 #include <android/log.h>
nuclear@23 27
nuclear@23 28 #define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, "threaded_app", __VA_ARGS__))
nuclear@23 29 #define LOGE(...) ((void)__android_log_print(ANDROID_LOG_ERROR, "threaded_app", __VA_ARGS__))
nuclear@23 30
nuclear@23 31 /* For debug builds, always enable the debug traces in this library */
nuclear@23 32 #ifndef NDEBUG
nuclear@23 33 # define LOGV(...) ((void)__android_log_print(ANDROID_LOG_VERBOSE, "threaded_app", __VA_ARGS__))
nuclear@23 34 #else
nuclear@23 35 # define LOGV(...) ((void)0)
nuclear@23 36 #endif
nuclear@23 37
nuclear@23 38 static void free_saved_state(struct android_app* android_app) {
nuclear@23 39 pthread_mutex_lock(&android_app->mutex);
nuclear@23 40 if (android_app->savedState != NULL) {
nuclear@23 41 free(android_app->savedState);
nuclear@23 42 android_app->savedState = NULL;
nuclear@23 43 android_app->savedStateSize = 0;
nuclear@23 44 }
nuclear@23 45 pthread_mutex_unlock(&android_app->mutex);
nuclear@23 46 }
nuclear@23 47
nuclear@23 48 int8_t android_app_read_cmd(struct android_app* android_app) {
nuclear@23 49 int8_t cmd;
nuclear@23 50 if (read(android_app->msgread, &cmd, sizeof(cmd)) == sizeof(cmd)) {
nuclear@23 51 switch (cmd) {
nuclear@23 52 case APP_CMD_SAVE_STATE:
nuclear@23 53 free_saved_state(android_app);
nuclear@23 54 break;
nuclear@23 55 }
nuclear@23 56 return cmd;
nuclear@23 57 } else {
nuclear@23 58 LOGE("No data on command pipe!");
nuclear@23 59 }
nuclear@23 60 return -1;
nuclear@23 61 }
nuclear@23 62
nuclear@23 63 static void print_cur_config(struct android_app* android_app) {
nuclear@23 64 char lang[2], country[2];
nuclear@23 65 AConfiguration_getLanguage(android_app->config, lang);
nuclear@23 66 AConfiguration_getCountry(android_app->config, country);
nuclear@23 67
nuclear@23 68 LOGV("Config: mcc=%d mnc=%d lang=%c%c cnt=%c%c orien=%d touch=%d dens=%d "
nuclear@23 69 "keys=%d nav=%d keysHid=%d navHid=%d sdk=%d size=%d long=%d "
nuclear@23 70 "modetype=%d modenight=%d",
nuclear@23 71 AConfiguration_getMcc(android_app->config),
nuclear@23 72 AConfiguration_getMnc(android_app->config),
nuclear@23 73 lang[0], lang[1], country[0], country[1],
nuclear@23 74 AConfiguration_getOrientation(android_app->config),
nuclear@23 75 AConfiguration_getTouchscreen(android_app->config),
nuclear@23 76 AConfiguration_getDensity(android_app->config),
nuclear@23 77 AConfiguration_getKeyboard(android_app->config),
nuclear@23 78 AConfiguration_getNavigation(android_app->config),
nuclear@23 79 AConfiguration_getKeysHidden(android_app->config),
nuclear@23 80 AConfiguration_getNavHidden(android_app->config),
nuclear@23 81 AConfiguration_getSdkVersion(android_app->config),
nuclear@23 82 AConfiguration_getScreenSize(android_app->config),
nuclear@23 83 AConfiguration_getScreenLong(android_app->config),
nuclear@23 84 AConfiguration_getUiModeType(android_app->config),
nuclear@23 85 AConfiguration_getUiModeNight(android_app->config));
nuclear@23 86 }
nuclear@23 87
nuclear@23 88 void android_app_pre_exec_cmd(struct android_app* android_app, int8_t cmd) {
nuclear@23 89 switch (cmd) {
nuclear@23 90 case APP_CMD_INPUT_CHANGED:
nuclear@23 91 LOGV("APP_CMD_INPUT_CHANGED\n");
nuclear@23 92 pthread_mutex_lock(&android_app->mutex);
nuclear@23 93 if (android_app->inputQueue != NULL) {
nuclear@23 94 AInputQueue_detachLooper(android_app->inputQueue);
nuclear@23 95 }
nuclear@23 96 android_app->inputQueue = android_app->pendingInputQueue;
nuclear@23 97 if (android_app->inputQueue != NULL) {
nuclear@23 98 LOGV("Attaching input queue to looper");
nuclear@23 99 AInputQueue_attachLooper(android_app->inputQueue,
nuclear@23 100 android_app->looper, LOOPER_ID_INPUT, NULL,
nuclear@23 101 &android_app->inputPollSource);
nuclear@23 102 }
nuclear@23 103 pthread_cond_broadcast(&android_app->cond);
nuclear@23 104 pthread_mutex_unlock(&android_app->mutex);
nuclear@23 105 break;
nuclear@23 106
nuclear@23 107 case APP_CMD_INIT_WINDOW:
nuclear@23 108 LOGV("APP_CMD_INIT_WINDOW\n");
nuclear@23 109 pthread_mutex_lock(&android_app->mutex);
nuclear@23 110 android_app->window = android_app->pendingWindow;
nuclear@23 111 pthread_cond_broadcast(&android_app->cond);
nuclear@23 112 pthread_mutex_unlock(&android_app->mutex);
nuclear@23 113 break;
nuclear@23 114
nuclear@23 115 case APP_CMD_TERM_WINDOW:
nuclear@23 116 LOGV("APP_CMD_TERM_WINDOW\n");
nuclear@23 117 pthread_cond_broadcast(&android_app->cond);
nuclear@23 118 break;
nuclear@23 119
nuclear@23 120 case APP_CMD_RESUME:
nuclear@23 121 case APP_CMD_START:
nuclear@23 122 case APP_CMD_PAUSE:
nuclear@23 123 case APP_CMD_STOP:
nuclear@23 124 LOGV("activityState=%d\n", cmd);
nuclear@23 125 pthread_mutex_lock(&android_app->mutex);
nuclear@23 126 android_app->activityState = cmd;
nuclear@23 127 pthread_cond_broadcast(&android_app->cond);
nuclear@23 128 pthread_mutex_unlock(&android_app->mutex);
nuclear@23 129 break;
nuclear@23 130
nuclear@23 131 case APP_CMD_CONFIG_CHANGED:
nuclear@23 132 LOGV("APP_CMD_CONFIG_CHANGED\n");
nuclear@23 133 AConfiguration_fromAssetManager(android_app->config,
nuclear@23 134 android_app->activity->assetManager);
nuclear@23 135 print_cur_config(android_app);
nuclear@23 136 break;
nuclear@23 137
nuclear@23 138 case APP_CMD_DESTROY:
nuclear@23 139 LOGV("APP_CMD_DESTROY\n");
nuclear@23 140 android_app->destroyRequested = 1;
nuclear@23 141 break;
nuclear@23 142 }
nuclear@23 143 }
nuclear@23 144
nuclear@23 145 void android_app_post_exec_cmd(struct android_app* android_app, int8_t cmd) {
nuclear@23 146 switch (cmd) {
nuclear@23 147 case APP_CMD_TERM_WINDOW:
nuclear@23 148 LOGV("APP_CMD_TERM_WINDOW\n");
nuclear@23 149 pthread_mutex_lock(&android_app->mutex);
nuclear@23 150 android_app->window = NULL;
nuclear@23 151 pthread_cond_broadcast(&android_app->cond);
nuclear@23 152 pthread_mutex_unlock(&android_app->mutex);
nuclear@23 153 break;
nuclear@23 154
nuclear@23 155 case APP_CMD_SAVE_STATE:
nuclear@23 156 LOGV("APP_CMD_SAVE_STATE\n");
nuclear@23 157 pthread_mutex_lock(&android_app->mutex);
nuclear@23 158 android_app->stateSaved = 1;
nuclear@23 159 pthread_cond_broadcast(&android_app->cond);
nuclear@23 160 pthread_mutex_unlock(&android_app->mutex);
nuclear@23 161 break;
nuclear@23 162
nuclear@23 163 case APP_CMD_RESUME:
nuclear@23 164 free_saved_state(android_app);
nuclear@23 165 break;
nuclear@23 166 }
nuclear@23 167 }
nuclear@23 168
nuclear@23 169 void app_dummy() {
nuclear@23 170
nuclear@23 171 }
nuclear@23 172
nuclear@23 173 static void android_app_destroy(struct android_app* android_app) {
nuclear@23 174 LOGV("android_app_destroy!");
nuclear@23 175 free_saved_state(android_app);
nuclear@23 176 pthread_mutex_lock(&android_app->mutex);
nuclear@23 177 if (android_app->inputQueue != NULL) {
nuclear@23 178 AInputQueue_detachLooper(android_app->inputQueue);
nuclear@23 179 }
nuclear@23 180 AConfiguration_delete(android_app->config);
nuclear@23 181 android_app->destroyed = 1;
nuclear@23 182 pthread_cond_broadcast(&android_app->cond);
nuclear@23 183 pthread_mutex_unlock(&android_app->mutex);
nuclear@23 184 // Can't touch android_app object after this.
nuclear@23 185 }
nuclear@23 186
nuclear@23 187 static void process_input(struct android_app* app, struct android_poll_source* source) {
nuclear@23 188 AInputEvent* event = NULL;
nuclear@23 189 while (AInputQueue_getEvent(app->inputQueue, &event) >= 0) {
nuclear@23 190 LOGV("New input event: type=%d\n", AInputEvent_getType(event));
nuclear@23 191 if (AInputQueue_preDispatchEvent(app->inputQueue, event)) {
nuclear@23 192 continue;
nuclear@23 193 }
nuclear@23 194 int32_t handled = 0;
nuclear@23 195 if (app->onInputEvent != NULL) handled = app->onInputEvent(app, event);
nuclear@23 196 AInputQueue_finishEvent(app->inputQueue, event, handled);
nuclear@23 197 }
nuclear@23 198 }
nuclear@23 199
nuclear@23 200 static void process_cmd(struct android_app* app, struct android_poll_source* source) {
nuclear@23 201 int8_t cmd = android_app_read_cmd(app);
nuclear@23 202 android_app_pre_exec_cmd(app, cmd);
nuclear@23 203 if (app->onAppCmd != NULL) app->onAppCmd(app, cmd);
nuclear@23 204 android_app_post_exec_cmd(app, cmd);
nuclear@23 205 }
nuclear@23 206
nuclear@23 207 static void* android_app_entry(void* param) {
nuclear@23 208 struct android_app* android_app = (struct android_app*)param;
nuclear@23 209
nuclear@23 210 android_app->config = AConfiguration_new();
nuclear@23 211 AConfiguration_fromAssetManager(android_app->config, android_app->activity->assetManager);
nuclear@23 212
nuclear@23 213 print_cur_config(android_app);
nuclear@23 214
nuclear@23 215 android_app->cmdPollSource.id = LOOPER_ID_MAIN;
nuclear@23 216 android_app->cmdPollSource.app = android_app;
nuclear@23 217 android_app->cmdPollSource.process = process_cmd;
nuclear@23 218 android_app->inputPollSource.id = LOOPER_ID_INPUT;
nuclear@23 219 android_app->inputPollSource.app = android_app;
nuclear@23 220 android_app->inputPollSource.process = process_input;
nuclear@23 221
nuclear@23 222 ALooper* looper = ALooper_prepare(ALOOPER_PREPARE_ALLOW_NON_CALLBACKS);
nuclear@23 223 ALooper_addFd(looper, android_app->msgread, LOOPER_ID_MAIN, ALOOPER_EVENT_INPUT, NULL,
nuclear@23 224 &android_app->cmdPollSource);
nuclear@23 225 android_app->looper = looper;
nuclear@23 226
nuclear@23 227 pthread_mutex_lock(&android_app->mutex);
nuclear@23 228 android_app->running = 1;
nuclear@23 229 pthread_cond_broadcast(&android_app->cond);
nuclear@23 230 pthread_mutex_unlock(&android_app->mutex);
nuclear@23 231
nuclear@23 232 android_main(android_app);
nuclear@23 233
nuclear@23 234 android_app_destroy(android_app);
nuclear@23 235 return NULL;
nuclear@23 236 }
nuclear@23 237
nuclear@23 238 // --------------------------------------------------------------------
nuclear@23 239 // Native activity interaction (called from main thread)
nuclear@23 240 // --------------------------------------------------------------------
nuclear@23 241
nuclear@23 242 static struct android_app* android_app_create(ANativeActivity* activity,
nuclear@23 243 void* savedState, size_t savedStateSize) {
nuclear@23 244 struct android_app* android_app = (struct android_app*)malloc(sizeof(struct android_app));
nuclear@23 245 memset(android_app, 0, sizeof(struct android_app));
nuclear@23 246 android_app->activity = activity;
nuclear@23 247
nuclear@23 248 pthread_mutex_init(&android_app->mutex, NULL);
nuclear@23 249 pthread_cond_init(&android_app->cond, NULL);
nuclear@23 250
nuclear@23 251 if (savedState != NULL) {
nuclear@23 252 android_app->savedState = malloc(savedStateSize);
nuclear@23 253 android_app->savedStateSize = savedStateSize;
nuclear@23 254 memcpy(android_app->savedState, savedState, savedStateSize);
nuclear@23 255 }
nuclear@23 256
nuclear@23 257 int msgpipe[2];
nuclear@23 258 if (pipe(msgpipe)) {
nuclear@23 259 LOGE("could not create pipe: %s", strerror(errno));
nuclear@23 260 return NULL;
nuclear@23 261 }
nuclear@23 262 android_app->msgread = msgpipe[0];
nuclear@23 263 android_app->msgwrite = msgpipe[1];
nuclear@23 264
nuclear@23 265 pthread_attr_t attr;
nuclear@23 266 pthread_attr_init(&attr);
nuclear@23 267 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
nuclear@23 268 pthread_create(&android_app->thread, &attr, android_app_entry, android_app);
nuclear@23 269
nuclear@23 270 // Wait for thread to start.
nuclear@23 271 pthread_mutex_lock(&android_app->mutex);
nuclear@23 272 while (!android_app->running) {
nuclear@23 273 pthread_cond_wait(&android_app->cond, &android_app->mutex);
nuclear@23 274 }
nuclear@23 275 pthread_mutex_unlock(&android_app->mutex);
nuclear@23 276
nuclear@23 277 return android_app;
nuclear@23 278 }
nuclear@23 279
nuclear@23 280 static void android_app_write_cmd(struct android_app* android_app, int8_t cmd) {
nuclear@23 281 if (write(android_app->msgwrite, &cmd, sizeof(cmd)) != sizeof(cmd)) {
nuclear@23 282 LOGE("Failure writing android_app cmd: %s\n", strerror(errno));
nuclear@23 283 }
nuclear@23 284 }
nuclear@23 285
nuclear@23 286 static void android_app_set_input(struct android_app* android_app, AInputQueue* inputQueue) {
nuclear@23 287 pthread_mutex_lock(&android_app->mutex);
nuclear@23 288 android_app->pendingInputQueue = inputQueue;
nuclear@23 289 android_app_write_cmd(android_app, APP_CMD_INPUT_CHANGED);
nuclear@23 290 while (android_app->inputQueue != android_app->pendingInputQueue) {
nuclear@23 291 pthread_cond_wait(&android_app->cond, &android_app->mutex);
nuclear@23 292 }
nuclear@23 293 pthread_mutex_unlock(&android_app->mutex);
nuclear@23 294 }
nuclear@23 295
nuclear@23 296 static void android_app_set_window(struct android_app* android_app, ANativeWindow* window) {
nuclear@23 297 pthread_mutex_lock(&android_app->mutex);
nuclear@23 298 if (android_app->pendingWindow != NULL) {
nuclear@23 299 android_app_write_cmd(android_app, APP_CMD_TERM_WINDOW);
nuclear@23 300 }
nuclear@23 301 android_app->pendingWindow = window;
nuclear@23 302 if (window != NULL) {
nuclear@23 303 android_app_write_cmd(android_app, APP_CMD_INIT_WINDOW);
nuclear@23 304 }
nuclear@23 305 while (android_app->window != android_app->pendingWindow) {
nuclear@23 306 pthread_cond_wait(&android_app->cond, &android_app->mutex);
nuclear@23 307 }
nuclear@23 308 pthread_mutex_unlock(&android_app->mutex);
nuclear@23 309 }
nuclear@23 310
nuclear@23 311 static void android_app_set_activity_state(struct android_app* android_app, int8_t cmd) {
nuclear@23 312 pthread_mutex_lock(&android_app->mutex);
nuclear@23 313 android_app_write_cmd(android_app, cmd);
nuclear@23 314 while (android_app->activityState != cmd) {
nuclear@23 315 pthread_cond_wait(&android_app->cond, &android_app->mutex);
nuclear@23 316 }
nuclear@23 317 pthread_mutex_unlock(&android_app->mutex);
nuclear@23 318 }
nuclear@23 319
nuclear@23 320 static void android_app_free(struct android_app* android_app) {
nuclear@23 321 pthread_mutex_lock(&android_app->mutex);
nuclear@23 322 android_app_write_cmd(android_app, APP_CMD_DESTROY);
nuclear@23 323 while (!android_app->destroyed) {
nuclear@23 324 pthread_cond_wait(&android_app->cond, &android_app->mutex);
nuclear@23 325 }
nuclear@23 326 pthread_mutex_unlock(&android_app->mutex);
nuclear@23 327
nuclear@23 328 close(android_app->msgread);
nuclear@23 329 close(android_app->msgwrite);
nuclear@23 330 pthread_cond_destroy(&android_app->cond);
nuclear@23 331 pthread_mutex_destroy(&android_app->mutex);
nuclear@23 332 free(android_app);
nuclear@23 333 }
nuclear@23 334
nuclear@23 335 static void onDestroy(ANativeActivity* activity) {
nuclear@23 336 LOGV("Destroy: %p\n", activity);
nuclear@23 337 android_app_free((struct android_app*)activity->instance);
nuclear@23 338 }
nuclear@23 339
nuclear@23 340 static void onStart(ANativeActivity* activity) {
nuclear@23 341 LOGV("Start: %p\n", activity);
nuclear@23 342 android_app_set_activity_state((struct android_app*)activity->instance, APP_CMD_START);
nuclear@23 343 }
nuclear@23 344
nuclear@23 345 static void onResume(ANativeActivity* activity) {
nuclear@23 346 LOGV("Resume: %p\n", activity);
nuclear@23 347 android_app_set_activity_state((struct android_app*)activity->instance, APP_CMD_RESUME);
nuclear@23 348 }
nuclear@23 349
nuclear@23 350 static void* onSaveInstanceState(ANativeActivity* activity, size_t* outLen) {
nuclear@23 351 struct android_app* android_app = (struct android_app*)activity->instance;
nuclear@23 352 void* savedState = NULL;
nuclear@23 353
nuclear@23 354 LOGV("SaveInstanceState: %p\n", activity);
nuclear@23 355 pthread_mutex_lock(&android_app->mutex);
nuclear@23 356 android_app->stateSaved = 0;
nuclear@23 357 android_app_write_cmd(android_app, APP_CMD_SAVE_STATE);
nuclear@23 358 while (!android_app->stateSaved) {
nuclear@23 359 pthread_cond_wait(&android_app->cond, &android_app->mutex);
nuclear@23 360 }
nuclear@23 361
nuclear@23 362 if (android_app->savedState != NULL) {
nuclear@23 363 savedState = android_app->savedState;
nuclear@23 364 *outLen = android_app->savedStateSize;
nuclear@23 365 android_app->savedState = NULL;
nuclear@23 366 android_app->savedStateSize = 0;
nuclear@23 367 }
nuclear@23 368
nuclear@23 369 pthread_mutex_unlock(&android_app->mutex);
nuclear@23 370
nuclear@23 371 return savedState;
nuclear@23 372 }
nuclear@23 373
nuclear@23 374 static void onPause(ANativeActivity* activity) {
nuclear@23 375 LOGV("Pause: %p\n", activity);
nuclear@23 376 android_app_set_activity_state((struct android_app*)activity->instance, APP_CMD_PAUSE);
nuclear@23 377 }
nuclear@23 378
nuclear@23 379 static void onStop(ANativeActivity* activity) {
nuclear@23 380 LOGV("Stop: %p\n", activity);
nuclear@23 381 android_app_set_activity_state((struct android_app*)activity->instance, APP_CMD_STOP);
nuclear@23 382 }
nuclear@23 383
nuclear@23 384 static void onConfigurationChanged(ANativeActivity* activity) {
nuclear@23 385 struct android_app* android_app = (struct android_app*)activity->instance;
nuclear@23 386 LOGV("ConfigurationChanged: %p\n", activity);
nuclear@23 387 android_app_write_cmd(android_app, APP_CMD_CONFIG_CHANGED);
nuclear@23 388 }
nuclear@23 389
nuclear@23 390 static void onLowMemory(ANativeActivity* activity) {
nuclear@23 391 struct android_app* android_app = (struct android_app*)activity->instance;
nuclear@23 392 LOGV("LowMemory: %p\n", activity);
nuclear@23 393 android_app_write_cmd(android_app, APP_CMD_LOW_MEMORY);
nuclear@23 394 }
nuclear@23 395
nuclear@23 396 static void onWindowFocusChanged(ANativeActivity* activity, int focused) {
nuclear@23 397 LOGV("WindowFocusChanged: %p -- %d\n", activity, focused);
nuclear@23 398 android_app_write_cmd((struct android_app*)activity->instance,
nuclear@23 399 focused ? APP_CMD_GAINED_FOCUS : APP_CMD_LOST_FOCUS);
nuclear@23 400 }
nuclear@23 401
nuclear@23 402 static void onNativeWindowCreated(ANativeActivity* activity, ANativeWindow* window) {
nuclear@23 403 LOGV("NativeWindowCreated: %p -- %p\n", activity, window);
nuclear@23 404 android_app_set_window((struct android_app*)activity->instance, window);
nuclear@23 405 }
nuclear@23 406
nuclear@23 407 static void onNativeWindowDestroyed(ANativeActivity* activity, ANativeWindow* window) {
nuclear@23 408 LOGV("NativeWindowDestroyed: %p -- %p\n", activity, window);
nuclear@23 409 android_app_set_window((struct android_app*)activity->instance, NULL);
nuclear@23 410 }
nuclear@23 411
nuclear@23 412 static void onInputQueueCreated(ANativeActivity* activity, AInputQueue* queue) {
nuclear@23 413 LOGV("InputQueueCreated: %p -- %p\n", activity, queue);
nuclear@23 414 android_app_set_input((struct android_app*)activity->instance, queue);
nuclear@23 415 }
nuclear@23 416
nuclear@23 417 static void onInputQueueDestroyed(ANativeActivity* activity, AInputQueue* queue) {
nuclear@23 418 LOGV("InputQueueDestroyed: %p -- %p\n", activity, queue);
nuclear@23 419 android_app_set_input((struct android_app*)activity->instance, NULL);
nuclear@23 420 }
nuclear@23 421
nuclear@23 422 void ANativeActivity_onCreate(ANativeActivity* activity,
nuclear@23 423 void* savedState, size_t savedStateSize) {
nuclear@23 424 LOGV("Creating: %p\n", activity);
nuclear@23 425 activity->callbacks->onDestroy = onDestroy;
nuclear@23 426 activity->callbacks->onStart = onStart;
nuclear@23 427 activity->callbacks->onResume = onResume;
nuclear@23 428 activity->callbacks->onSaveInstanceState = onSaveInstanceState;
nuclear@23 429 activity->callbacks->onPause = onPause;
nuclear@23 430 activity->callbacks->onStop = onStop;
nuclear@23 431 activity->callbacks->onConfigurationChanged = onConfigurationChanged;
nuclear@23 432 activity->callbacks->onLowMemory = onLowMemory;
nuclear@23 433 activity->callbacks->onWindowFocusChanged = onWindowFocusChanged;
nuclear@23 434 activity->callbacks->onNativeWindowCreated = onNativeWindowCreated;
nuclear@23 435 activity->callbacks->onNativeWindowDestroyed = onNativeWindowDestroyed;
nuclear@23 436 activity->callbacks->onInputQueueCreated = onInputQueueCreated;
nuclear@23 437 activity->callbacks->onInputQueueDestroyed = onInputQueueDestroyed;
nuclear@23 438
nuclear@23 439 activity->instance = android_app_create(activity, savedState, savedStateSize);
nuclear@23 440 }