From d3bc43a311d6ac09c4f182a04f45b8bdc51256ff Mon Sep 17 00:00:00 2001 From: Po Lu Date: Thu, 27 Jun 2024 11:06:59 +0800 Subject: [PATCH] Prevent crashes and related issues if initial activity is destroyed on Android * java/org/gnu/emacs/EmacsWindow.java (EmacsWindow) : New variable. (EmacsWindow): If the initial frame has not yet been created, set attachmentToken to -1. * java/org/gnu/emacs/EmacsWindowManager.java (registerWindow): When the window's attachment token is -1 (i.e., it is the default window), start EmacsActivity rather than EmacsMultitaskActivity. Catch exceptions around startActivity. (cherry picked from commit 860840621a1ebe2e4f17ba8ae78d441ea75650b2) --- java/org/gnu/emacs/EmacsWindow.java | 11 ++++++ java/org/gnu/emacs/EmacsWindowManager.java | 43 ++++++++++++++++++---- 2 files changed, 47 insertions(+), 7 deletions(-) diff --git a/java/org/gnu/emacs/EmacsWindow.java b/java/org/gnu/emacs/EmacsWindow.java index 5ffe1128172..698df2bfd64 100644 --- a/java/org/gnu/emacs/EmacsWindow.java +++ b/java/org/gnu/emacs/EmacsWindow.java @@ -74,6 +74,9 @@ public final class EmacsWindow extends EmacsHandleObject { private static final String TAG = "EmacsWindow"; + /* Whether any windows have yet been created in this session. */ + private static boolean initialWindowCreated; + private static class Coordinate { /* Integral coordinate. */ @@ -192,6 +195,14 @@ public final class EmacsWindow extends EmacsHandleObject this.parent = parent; this.overrideRedirect = overrideRedirect; + /* The initial frame should always be bound to the startup + activity. */ + if (!initialWindowCreated) + { + this.attachmentToken = -1; + initialWindowCreated = true; + } + /* Create the list of children. */ children = new ArrayList (); diff --git a/java/org/gnu/emacs/EmacsWindowManager.java b/java/org/gnu/emacs/EmacsWindowManager.java index 03487e853fb..e4bd995f15a 100644 --- a/java/org/gnu/emacs/EmacsWindowManager.java +++ b/java/org/gnu/emacs/EmacsWindowManager.java @@ -174,6 +174,27 @@ public final class EmacsWindowManager } } + /* Do not create a multitasking activity for the initial frame, + but arrange to start EmacsActivity. */ + if (window.attachmentToken == -1) + { + intent = new Intent (EmacsService.SERVICE, + EmacsActivity.class); + intent.addFlags (Intent.FLAG_ACTIVITY_NEW_TASK); + + try + { + EmacsService.SERVICE.startActivity (intent); + } + catch (Exception e) + { + Log.w (TAG, "an activity could not be started on behalf" + + " of the mapped default window " + window.handle); + } + + return; + } + intent = new Intent (EmacsService.SERVICE, EmacsMultitaskActivity.class); @@ -205,14 +226,22 @@ public final class EmacsWindowManager window.attachmentToken = token; intent.putExtra (ACTIVITY_TOKEN, token); - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) - EmacsService.SERVICE.startActivity (intent); - else + try + { + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) + EmacsService.SERVICE.startActivity (intent); + else + { + /* Specify the desired window size. */ + options = ActivityOptions.makeBasic (); + options.setLaunchBounds (window.getGeometry ()); + EmacsService.SERVICE.startActivity (intent, options.toBundle ()); + } + } + catch (Exception e) { - /* Specify the desired window size. */ - options = ActivityOptions.makeBasic (); - options.setLaunchBounds (window.getGeometry ()); - EmacsService.SERVICE.startActivity (intent, options.toBundle ()); + Log.w (TAG, "an activity could not be started on behalf" + + " of a mapped window, " + window.handle); } pruneWindows (); -- 2.39.2