From f9e32ce1575da69cc3a9e4690b6df2dbee41d14d Mon Sep 17 00:00:00 2001 From: Po Lu Date: Sat, 28 Jan 2023 21:21:45 +0800 Subject: [PATCH] Implement `restart-emacs' on Android * java/org/gnu/emacs/EmacsService.java (restartEmacs): New function. * src/android.c (struct android_emacs_service) (android_init_emacs_service): Add new method. (android_restart_emacs): New function. * src/android.h: Update prototypes. * src/emacs.c (Fkill_emacs): Call android_restart_emacs whenever appropriate. --- java/org/gnu/emacs/EmacsService.java | 12 ++++++++++++ src/android.c | 19 +++++++++++++++++++ src/android.h | 1 + src/emacs.c | 16 +++++++++++++++- 4 files changed, 47 insertions(+), 1 deletion(-) diff --git a/java/org/gnu/emacs/EmacsService.java b/java/org/gnu/emacs/EmacsService.java index eb9b61dd876..d17f6d1286c 100644 --- a/java/org/gnu/emacs/EmacsService.java +++ b/java/org/gnu/emacs/EmacsService.java @@ -611,4 +611,16 @@ public class EmacsService extends Service return manager.thing; } + + public void + restartEmacs () + { + Intent intent; + + intent = new Intent (this, EmacsActivity.class); + intent.addFlags (Intent.FLAG_ACTIVITY_NEW_TASK + | Intent.FLAG_ACTIVITY_CLEAR_TASK); + startActivity (intent); + System.exit (0); + } }; diff --git a/src/android.c b/src/android.c index 021bea1fc2f..598d002fb1c 100644 --- a/src/android.c +++ b/src/android.c @@ -97,6 +97,7 @@ struct android_emacs_service jmethodID name_keysym; jmethodID sync; jmethodID browse_url; + jmethodID restart_emacs; }; struct android_emacs_pixmap @@ -1659,6 +1660,7 @@ android_init_emacs_service (void) FIND_METHOD (sync, "sync", "()V"); FIND_METHOD (browse_url, "browseUrl", "(Ljava/lang/String;)" "Ljava/lang/String;"); + FIND_METHOD (restart_emacs, "restartEmacs", "()V"); #undef FIND_METHOD } @@ -4987,6 +4989,23 @@ android_browse_url (Lisp_Object url) return tem; } +/* Tell the system to restart Emacs in a short amount of time, and + then kill Emacs. Never return. This is used to implement + `restart-emacs'. */ + +_Noreturn void +android_restart_emacs (void) +{ + /* Try to call the Java side function. Normally, this should call + System.exit to terminate this process. */ + (*android_java_env)->CallVoidMethod (android_java_env, + emacs_service, + service_class.restart_emacs); + + /* Exit anyway, in case EmacsService did not do so. */ + exit (0); +} + #else /* ANDROID_STUBIFY */ diff --git a/src/android.h b/src/android.h index 8234dbb07c0..9b2eca807cb 100644 --- a/src/android.h +++ b/src/android.h @@ -89,6 +89,7 @@ extern void android_get_keysym_name (int, char *, size_t); extern void android_wait_event (void); extern void android_toggle_on_screen_keyboard (android_window, bool); extern void android_window_updated (android_window, unsigned long); +extern _Noreturn void android_restart_emacs (void); diff --git a/src/emacs.c b/src/emacs.c index a24f9960494..79156c63017 100644 --- a/src/emacs.c +++ b/src/emacs.c @@ -2948,7 +2948,14 @@ killed. */ #ifndef WINDOWSNT /* Do some checking before shutting down Emacs, because errors can't be meaningfully reported afterwards. */ - if (!NILP (restart)) + if (!NILP (restart) + /* Don't perform the following checks when Emacs is running as + an Android GUI application, because there the system is + relied on to restart Emacs. */ +#if defined HAVE_ANDROID && !defined ANDROID_STUBIFY + && !android_init_gui +#endif + ) { /* This is very unlikely, but it's possible to execute a binary (on some systems) with no argv. */ @@ -3010,6 +3017,13 @@ killed. */ if (!NILP (restart)) { turn_on_atimers (false); +#if defined HAVE_ANDROID && !defined ANDROID_STUBIFY + /* Re-executing the Emacs process created by the system doesn't + work. Instead, schedule a restart for a few hundered + milliseconds and exit Emacs. */ + if (android_init_gui) + android_restart_emacs (); +#endif #ifdef WINDOWSNT if (w32_reexec_emacs (initial_cmdline, initial_wd) < 0) #else -- 2.39.5