From 986d71854a8c3d354570a142bb1a54fc6756242c Mon Sep 17 00:00:00 2001 From: Po Lu Date: Sun, 7 Apr 2024 12:15:39 +0800 Subject: [PATCH] Port new Android window management strategy to Android 5.0 * doc/emacs/android.texi (Android Windowing): Revise to match. * java/org/gnu/emacs/EmacsWindowManager.java (registerWindow) (removeWindowConsumer, pruneWindows): Decrease minimum API for monitoring of tasks to Android 5.0. (getTaskToken): Ignore misleading documentation and access baseIntent by way of RecentTaskInfo. (cherry picked from commit ae296d762bc7366879e74f9dca90bc7edd89e860) --- doc/emacs/android.texi | 2 +- java/org/gnu/emacs/EmacsWindowManager.java | 50 ++++++++++++---------- 2 files changed, 29 insertions(+), 23 deletions(-) diff --git a/doc/emacs/android.texi b/doc/emacs/android.texi index ebc00c74ede..3f784bc9637 100644 --- a/doc/emacs/android.texi +++ b/doc/emacs/android.texi @@ -876,7 +876,7 @@ distributors. @item When the user or the system closes any window created by Emacs on behalf of a specific frame, Emacs deletes the frame displayed within that -window, unless the system is Android 10.0 or later, where such windows +window, unless the system is Android 5.0 or later, where such windows are treated identically to the window created at startup, albeit with no proviso regarding window inactivity. @end itemize diff --git a/java/org/gnu/emacs/EmacsWindowManager.java b/java/org/gnu/emacs/EmacsWindowManager.java index 41ea3a15809..22629cad329 100644 --- a/java/org/gnu/emacs/EmacsWindowManager.java +++ b/java/org/gnu/emacs/EmacsWindowManager.java @@ -23,9 +23,9 @@ import java.util.ArrayList; import java.util.List; import android.app.ActivityManager.AppTask; +import android.app.ActivityManager.RecentTaskInfo; import android.app.ActivityManager; import android.app.ActivityOptions; -import android.app.TaskInfo; import android.content.Context; import android.content.Intent; @@ -60,7 +60,7 @@ import android.util.Log; getAttachmentToken () should return a token uniquely identifying a consumer, which, on API - 29 and up, enables attributing the tasks of activities to the windows + 21 and up, enables attributing the tasks of activities to the windows for which they were created, and with that, consistent interaction between user-visible window state and their underlying frames. */ @@ -182,7 +182,21 @@ public final class EmacsWindowManager /* Intent.FLAG_ACTIVITY_NEW_DOCUMENT is lamentably unavailable on older systems than Lolipop. */ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) - intent.addFlags (Intent.FLAG_ACTIVITY_NEW_DOCUMENT); + { + intent.addFlags (Intent.FLAG_ACTIVITY_NEW_DOCUMENT); + + /* Bind this window to the activity in advance, i.e., before its + creation, so that its ID will be recorded in the RecentTasks + list. */ + token = ++nextActivityToken; + } + else + /* APIs required for linking activities to windows are not + available in earlier Android versions. */ + token = -2; + + window.attachmentToken = token; + intent.putExtra (ACTIVITY_TOKEN, token); if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) EmacsService.SERVICE.startActivity (intent); @@ -191,19 +205,6 @@ public final class EmacsWindowManager /* Specify the desired window size. */ options = ActivityOptions.makeBasic (); options.setLaunchBounds (window.getGeometry ()); - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) - /* Bind this window to the activity in advance, i.e., before - its creation, so that its ID will be recorded in the - RecentTasks list. */ - token = ++nextActivityToken; - else - /* APIs required for linking activities to windows are not - available in earlier Android versions. */ - token = -2; - - window.attachmentToken = token; - intent.putExtra (ACTIVITY_TOKEN, token); EmacsService.SERVICE.startActivity (intent, options.toBundle ()); } @@ -228,7 +229,7 @@ public final class EmacsWindowManager the system-started task. */ if (isFinishing && (!(consumer instanceof EmacsMultitaskActivity) - || Build.VERSION.SDK_INT < Build.VERSION_CODES.Q)) + || Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP)) window.onActivityDetached (); } @@ -297,12 +298,17 @@ public final class EmacsWindowManager private static long getTaskToken (AppTask task) { - TaskInfo info; + RecentTaskInfo info; + + info = task.getTaskInfo (); - info = (TaskInfo) task.getTaskInfo (); + /* baseIntent is a member of info's superclass, TaskInfo, on Android + 10 and later. Prior to this release, it had been a member of + RecentTaskInfo since SDK 1, and whatever the misleading + documentation might suggest, a reference to `baseIntent' through + TaskInfo is just as good a reference to RecentTaskInfo. */ return (info.baseIntent != null - ? info.baseIntent.getLongExtra (ACTIVITY_TOKEN, - -1l) + ? info.baseIntent.getLongExtra (ACTIVITY_TOKEN, -1l) : 0); } @@ -319,7 +325,7 @@ public final class EmacsWindowManager long taskToken; boolean set; - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP || EmacsService.SERVICE == null) return; -- 2.39.5