]> git.eshelyaron.com Git - emacs.git/commitdiff
Implement `restart-emacs' on Android
authorPo Lu <luangruo@yahoo.com>
Sat, 28 Jan 2023 13:21:45 +0000 (21:21 +0800)
committerPo Lu <luangruo@yahoo.com>
Sat, 28 Jan 2023 13:21:45 +0000 (21:21 +0800)
* 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
src/android.c
src/android.h
src/emacs.c

index eb9b61dd8764309e1b1a89c20229492b0bfeca80..d17f6d1286cb14bdf64dd615ac2d29738e431c44 100644 (file)
@@ -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);
+  }
 };
index 021bea1fc2f9cabfb5063e289c67fe1b7f863aa1..598d002fb1c11d2993e77c55297ce32d54fac00e 100644 (file)
@@ -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);
+}
+
 \f
 
 #else /* ANDROID_STUBIFY */
index 8234dbb07c0f5e9d6c43ffaf5c4ad9aa6d0e8ffd..9b2eca807cb18719997cfd96e83c23387d256382 100644 (file)
@@ -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);
 
 \f
 
index a24f9960494204be669453bdc1da01e84d39458f..79156c630173cef151370115c91c975f69f98fb9 100644 (file)
@@ -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