diff --git a/frontend/platform/platform_android.c b/frontend/platform/platform_android.c index 82eb9abec8..5df43dd517 100644 --- a/frontend/platform/platform_android.c +++ b/frontend/platform/platform_android.c @@ -154,6 +154,10 @@ void engine_handle_cmd(void *data) static inline void android_app_write_cmd (void *data, int8_t cmd) { struct android_app *android_app = (struct android_app*)data; + + if (!android_app) + return; + if (write(android_app->msgwrite, &cmd, sizeof(cmd)) != sizeof(cmd)) RARCH_ERR("Failure writing android_app cmd: %s\n", strerror(errno)); } @@ -161,6 +165,10 @@ static inline void android_app_write_cmd (void *data, int8_t cmd) static void android_app_set_input (void *data, AInputQueue* inputQueue) { struct android_app *android_app = (struct android_app*)data; + + if (!android_app) + return; + slock_lock(android_app->mutex); android_app->pendingInputQueue = inputQueue; android_app_write_cmd(android_app, APP_CMD_INPUT_CHANGED); @@ -172,13 +180,17 @@ static void android_app_set_input (void *data, AInputQueue* inputQueue) static void android_app_set_window (void *data, ANativeWindow* window) { struct android_app *android_app = (struct android_app*)data; + + if (!android_app) + return; + slock_lock(android_app->mutex); - if (android_app->pendingWindow != NULL) + if (android_app->pendingWindow) android_app_write_cmd(android_app, APP_CMD_TERM_WINDOW); android_app->pendingWindow = window; - if (window != NULL) + if (window) android_app_write_cmd(android_app, APP_CMD_INIT_WINDOW); while (android_app->window != android_app->pendingWindow) @@ -190,6 +202,10 @@ static void android_app_set_window (void *data, ANativeWindow* window) static void android_app_set_activity_state (void *data, int8_t cmd) { struct android_app *android_app = (struct android_app*)data; + + if (!android_app) + return; + slock_lock(android_app->mutex); android_app_write_cmd(android_app, cmd); while (android_app->activityState != cmd && android_app->activityState != APP_CMD_DEAD) @@ -197,21 +213,25 @@ static void android_app_set_activity_state (void *data, int8_t cmd) slock_unlock(android_app->mutex); if (android_app->activityState == APP_CMD_DEAD) - RARCH_LOG("RetroArch thread is dead.\n"); + RARCH_LOG("RetroArch native thread is dead.\n"); } static void onDestroy(ANativeActivity* activity) { - RARCH_LOG("Destroy: %p\n", activity); struct android_app* android_app = (struct android_app*)activity->instance; + if (!android_app) + return; + + RARCH_LOG("onDestroy: %p\n", activity); sthread_join(android_app->thread); - RARCH_LOG("Joined with RetroArch thread.\n"); + RARCH_LOG("Joined with RetroArch native thread.\n"); close(android_app->msgread); close(android_app->msgwrite); scond_free(android_app->cond); slock_free(android_app->mutex); + free(android_app); } @@ -242,6 +262,10 @@ static void onStop(ANativeActivity* activity) static void onConfigurationChanged (ANativeActivity *activity) { struct android_app* android_app = (struct android_app*)activity->instance; + + if (!android_app) + return; + RARCH_LOG("ConfigurationChanged: %p\n", activity); android_app_write_cmd(android_app, APP_CMD_CONFIG_CHANGED); } @@ -279,9 +303,10 @@ static void onInputQueueDestroyed(ANativeActivity* activity, AInputQueue* queue) JNIEnv *jni_thread_getenv(void) { - struct android_app* android_app = (struct android_app*)g_android; JNIEnv *env; + struct android_app* android_app = (struct android_app*)g_android; int status = (*android_app->activity->vm)->AttachCurrentThread(android_app->activity->vm, &env, 0); + if (status < 0) { RARCH_ERR("jni_thread_getenv: Failed to attach current thread.\n"); @@ -294,14 +319,15 @@ JNIEnv *jni_thread_getenv(void) static void jni_thread_destruct(void *value) { - struct android_app* android_app = (struct android_app*)g_android; JNIEnv *env = (JNIEnv*)value; - if (env) - { - if (android_app) - (*android_app->activity->vm)->DetachCurrentThread(android_app->activity->vm); - pthread_setspecific(thread_key, NULL); - } + struct android_app* android_app = (struct android_app*)g_android; + + if (!env) + return; + + if (android_app) + (*android_app->activity->vm)->DetachCurrentThread(android_app->activity->vm); + pthread_setspecific(thread_key, NULL); } // -------------------------------------------------------------------- @@ -311,6 +337,9 @@ static void jni_thread_destruct(void *value) void ANativeActivity_onCreate(ANativeActivity* activity, void* savedState, size_t savedStateSize) { + int msgpipe[2]; + struct android_app* android_app; + (void)savedState; (void)savedStateSize; @@ -335,14 +364,19 @@ void ANativeActivity_onCreate(ANativeActivity* activity, if (pthread_key_create(&thread_key, jni_thread_destruct)) RARCH_ERR("Error initializing pthread_key\n"); - struct android_app* android_app = (struct android_app*)malloc(sizeof(struct android_app)); + android_app = (struct android_app*)calloc(1, sizeof(*android_app)); + if (!android_app) + { + RARCH_ERR("Failed to initialize android_app\n"); + return; + } + memset(android_app, 0, sizeof(struct android_app)); android_app->activity = activity; android_app->mutex = slock_new(); android_app->cond = scond_new(); - int msgpipe[2]; if (pipe(msgpipe)) { RARCH_ERR("could not create pipe: %s.\n", strerror(errno)); @@ -379,10 +413,10 @@ static bool android_run_events (void *data) static void frontend_android_get_environment_settings(int *argc, char *argv[], void *data) { JNIEnv *env; - struct android_app* android_app = (struct android_app*)data; jobject obj = NULL; jstring jstr = NULL; bool valschanged = false; + struct android_app* android_app = (struct android_app*)data; if (!android_app) return; @@ -394,7 +428,7 @@ static void frontend_android_get_environment_settings(int *argc, char *argv[], v CALL_OBJ_METHOD(env, obj, android_app->activity->clazz, android_app->getIntent); RARCH_LOG("Checking arguments passed from intent...\n"); - // ROM + // Content CALL_OBJ_METHOD_PARAM(env, jstr, obj, android_app->getStringExtra, (*env)->NewStringUTF(env, "ROM")); if (android_app->getStringExtra && jstr) { @@ -461,9 +495,9 @@ static void frontend_android_get_environment_settings(int *argc, char *argv[], v } +#if 0 static void process_pending_intent(void *data) { -#if 0 RARCH_LOG("process_pending_intent.\n"); JNIEnv *env; struct android_app* android_app = (struct android_app*)data; @@ -547,8 +581,8 @@ static void process_pending_intent(void *data) } CALL_VOID_METHOD(env, android_app->activity->clazz, android_app->clearPendingIntent); -#endif } +#endif static int frontend_android_process_events(void *data) { @@ -575,11 +609,15 @@ static int frontend_android_process_events(void *data) static void frontend_android_init(void *data) { JNIEnv *env; + ALooper *looper; jclass class = NULL; jobject obj = NULL; struct android_app* android_app = (struct android_app*)data; - ALooper* looper = ALooper_prepare(ALOOPER_PREPARE_ALLOW_NON_CALLBACKS); + if (!android_app) + return; + + looper = (ALooper*)ALooper_prepare(ALOOPER_PREPARE_ALLOW_NON_CALLBACKS); ALooper_addFd(looper, android_app->msgread, LOOPER_ID_MAIN, ALOOPER_EVENT_INPUT, NULL, NULL); android_app->looper = looper; @@ -632,11 +670,14 @@ static void frontend_android_deinit(void *data) { struct android_app* android_app = (struct android_app*)data; + if (!android_app) + return; + RARCH_LOG("Deinitializing RetroArch...\n"); android_app->activityState = APP_CMD_DEAD; RARCH_LOG("android_app_destroy!"); - if (android_app->inputQueue != NULL) + if (android_app->inputQueue) AInputQueue_detachLooper(android_app->inputQueue); }