diff --git a/src/api-impl-jni/app/android_app_Activity.c b/src/api-impl-jni/app/android_app_Activity.c index 402152ab..3393f312 100644 --- a/src/api-impl-jni/app/android_app_Activity.c +++ b/src/api-impl-jni/app/android_app_Activity.c @@ -10,17 +10,48 @@ static GList *activity_backlog = NULL; static jobject activity_current = NULL; +static jobject activity_toplevel_current = NULL; static void activity_close(JNIEnv *env, jobject activity) { // in case some exception was left unhandled in native code, print it here so we don't confuse it with an exception thrown by onDestroy if((*env)->ExceptionCheck(env)) { - fprintf(stderr, "app_exit: seems there was a pending exception... :"); + fprintf(stderr, "activity.onDestroy: seems there was a pending exception... :"); (*env)->ExceptionDescribe(env); } - /* -- run the main activity's onDestroy -- */ - (*env)->CallVoidMethod(env, activity, handle_cache.activity.onDestroy, NULL); + /* -- run the activity's onDestroy -- */ + (*env)->CallVoidMethod(env, activity, handle_cache.activity.onDestroy); + if((*env)->ExceptionCheck(env)) + (*env)->ExceptionDescribe(env); +} + +static void activity_unfocus(JNIEnv *env, jobject activity) +{ + (*env)->CallVoidMethod(env, activity, handle_cache.activity.onPause); + if((*env)->ExceptionCheck(env)) + (*env)->ExceptionDescribe(env); + + (*env)->CallVoidMethod(env, activity, handle_cache.activity.onStop); + if((*env)->ExceptionCheck(env)) + (*env)->ExceptionDescribe(env); + + (*env)->CallVoidMethod(env, activity, handle_cache.activity.onWindowFocusChanged, false); + if((*env)->ExceptionCheck(env)) + (*env)->ExceptionDescribe(env); +} + +static void activity_focus(JNIEnv *env, jobject activity) +{ + (*env)->CallVoidMethod(env, activity, handle_cache.activity.onStart); + if((*env)->ExceptionCheck(env)) + (*env)->ExceptionDescribe(env); + + (*env)->CallVoidMethod(env, activity, handle_cache.activity.onResume); + if((*env)->ExceptionCheck(env)) + (*env)->ExceptionDescribe(env); + + (*env)->CallVoidMethod(env, activity, handle_cache.activity.onWindowFocusChanged, true); if((*env)->ExceptionCheck(env)) (*env)->ExceptionDescribe(env); } @@ -28,37 +59,28 @@ static void activity_close(JNIEnv *env, jobject activity) static void activity_update_current(JNIEnv *env) { jobject activity_new = activity_backlog ? g_list_first(activity_backlog)->data : NULL; + jobject activity_toplevel_new = activity_backlog ? g_list_last(activity_backlog)->data : NULL; if (activity_current != activity_new) { - if (activity_current) { - (*env)->CallVoidMethod(env, activity_current, handle_cache.activity.onPause); - if((*env)->ExceptionCheck(env)) - (*env)->ExceptionDescribe(env); + if (activity_current) + activity_unfocus(env, activity_current); - (*env)->CallVoidMethod(env, activity_current, handle_cache.activity.onStop); - if((*env)->ExceptionCheck(env)) - (*env)->ExceptionDescribe(env); + if (activity_new) + activity_focus(env, activity_new); - (*env)->CallVoidMethod(env, activity_current, handle_cache.activity.onWindowFocusChanged, false); - if((*env)->ExceptionCheck(env)) - (*env)->ExceptionDescribe(env); - - } - if (activity_new) { - (*env)->CallVoidMethod(env, activity_new, handle_cache.activity.onStart); - if((*env)->ExceptionCheck(env)) - (*env)->ExceptionDescribe(env); - - (*env)->CallVoidMethod(env, activity_new, handle_cache.activity.onResume); - if((*env)->ExceptionCheck(env)) - (*env)->ExceptionDescribe(env); - - (*env)->CallVoidMethod(env, activity_new, handle_cache.activity.onWindowFocusChanged, true); - if((*env)->ExceptionCheck(env)) - (*env)->ExceptionDescribe(env); - } activity_current = activity_new; } + + /* for Activity.recreate */ + if(activity_toplevel_current != activity_toplevel_new) { + if (activity_toplevel_current) + activity_unfocus(env, activity_toplevel_current); + + if (activity_toplevel_new) + activity_focus(env, activity_toplevel_new); + + activity_toplevel_current = activity_toplevel_new; + } } void activity_window_ready(void) @@ -89,15 +111,25 @@ void activity_close_all(void) g_list_free(activities); } -void activity_start(JNIEnv *env, jobject activity_object) +void _activity_start(JNIEnv *env, jobject activity_object, bool recreate) { /* -- run the activity's onCreate -- */ (*env)->CallVoidMethod(env, activity_object, handle_cache.activity.onCreate, NULL); if((*env)->ExceptionCheck(env)) (*env)->ExceptionDescribe(env); - activity_backlog = g_list_prepend(activity_backlog, _REF(activity_object)); + if(recreate) // only allowed for toplevel, so we know for sure where in the stack it belongs + activity_backlog = g_list_append(activity_backlog, _REF(activity_object)); + else + activity_backlog = g_list_prepend(activity_backlog, _REF(activity_object)); + activity_update_current(env); + +} + +void activity_start(JNIEnv *env, jobject activity_object) +{ + _activity_start(env, activity_object, false); } JNIEXPORT void JNICALL Java_android_app_Activity_nativeFinish(JNIEnv *env, jobject this, jlong window) @@ -115,10 +147,16 @@ JNIEXPORT void JNICALL Java_android_app_Activity_nativeFinish(JNIEnv *env, jobje activity_close(env, this); if (removed_activity) _UNREF(removed_activity); - if (activity_backlog == NULL) + if (activity_backlog == NULL && window) gtk_window_close(GTK_WINDOW(_PTR(window))); } +JNIEXPORT void JNICALL Java_android_app_Activity_nativeRecreateActivity(JNIEnv *env, jclass class, jobject activity) +{ + _activity_start(env, activity, true); +} + + JNIEXPORT void JNICALL Java_android_app_Activity_nativeStartActivity(JNIEnv *env, jclass class, jobject activity) { activity_start(env, activity); diff --git a/src/api-impl-jni/generated_headers/android_app_Activity.h b/src/api-impl-jni/generated_headers/android_app_Activity.h index abe54c99..d92f64f7 100644 --- a/src/api-impl-jni/generated_headers/android_app_Activity.h +++ b/src/api-impl-jni/generated_headers/android_app_Activity.h @@ -17,6 +17,14 @@ extern "C" { JNIEXPORT void JNICALL Java_android_app_Activity_nativeFinish (JNIEnv *, jobject, jlong); +/* + * Class: android_app_Activity + * Method: nativeRecreateActivity + * Signature: (Landroid/app/Activity;)V + */ +JNIEXPORT void JNICALL Java_android_app_Activity_nativeRecreateActivity + (JNIEnv *, jclass, jobject); + /* * Class: android_app_Activity * Method: nativeStartActivity diff --git a/src/api-impl/android/app/Activity.java b/src/api-impl/android/app/Activity.java index 11dc47de..e8ca4693 100644 --- a/src/api-impl/android/app/Activity.java +++ b/src/api-impl/android/app/Activity.java @@ -404,7 +404,24 @@ public class Activity extends ContextWrapper implements Window.Callback { return false; } + public void recreate() { + try { + /* TODO: check if this is a toplevel activity */ + Class cls = this.getClass(); + Constructor constructor = cls.getConstructor(); + Activity activity = constructor.newInstance(); + activity.getWindow().native_window = getWindow().native_window; + System.out.println("activity.getWindow().native_window >"+activity.getWindow().native_window+"<"); + nativeFinish(0); + nativeRecreateActivity(activity); + } catch (NoSuchMethodException | SecurityException | InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { + System.out.println("exception in Activity.recreate, this is kinda sus"); + e.printStackTrace(); + } + } + private native void nativeFinish(long native_window); + public static native void nativeRecreateActivity(Activity activity); public static native void nativeStartActivity(Activity activity); public static native void nativeOpenURI(String uri); public static native void nativeShare(String text);