From 66cb88c56bc869289ef0f41d8925c03120edaeb6 Mon Sep 17 00:00:00 2001 From: Winson Chung Date: Tue, 4 Aug 2020 22:46:55 -0700 Subject: [PATCH] Updating call for single organizer - This call no longer makes sense when organizers are unified, but the caller can set this on a per-task basis. Bug: 161980327 Test: atest WindowOrganizerTests Change-Id: I8b8d3cafdf0f42861e69a28007045f46b351ba94 --- api/test-current.txt | 2 +- .../window/ITaskOrganizerController.aidl | 3 +- core/java/android/window/TaskOrganizer.java | 5 +-- .../window/TaskOrganizerTaskEmbedder.java | 2 +- .../server/wm/TaskOrganizerController.java | 31 ++++++++++--------- .../server/wm/WindowOrganizerTests.java | 17 ++++++++-- 6 files changed, 39 insertions(+), 21 deletions(-) diff --git a/api/test-current.txt b/api/test-current.txt index 529dcf71ef6e1..5741fe7e90a49 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -5579,7 +5579,7 @@ package android.window { method @BinderThread public void onTaskInfoChanged(@NonNull android.app.ActivityManager.RunningTaskInfo); method @BinderThread public void onTaskVanished(@NonNull android.app.ActivityManager.RunningTaskInfo); method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) public final void registerOrganizer(); - method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) public void setInterceptBackPressedOnTaskRoot(boolean); + method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) public void setInterceptBackPressedOnTaskRoot(@NonNull android.window.WindowContainerToken, boolean); method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) public static void setLaunchRoot(int, @NonNull android.window.WindowContainerToken); method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) public final void unregisterOrganizer(); } diff --git a/core/java/android/window/ITaskOrganizerController.aidl b/core/java/android/window/ITaskOrganizerController.aidl index 92fa80e40cafa..12b16ff6645c1 100644 --- a/core/java/android/window/ITaskOrganizerController.aidl +++ b/core/java/android/window/ITaskOrganizerController.aidl @@ -60,5 +60,6 @@ interface ITaskOrganizerController { * Requests that the given task organizer is notified when back is pressed on the root activity * of one of its controlled tasks. */ - void setInterceptBackPressedOnTaskRoot(ITaskOrganizer organizer, boolean interceptBackPressed); + void setInterceptBackPressedOnTaskRoot(in WindowContainerToken task, + boolean interceptBackPressed); } diff --git a/core/java/android/window/TaskOrganizer.java b/core/java/android/window/TaskOrganizer.java index 7ec4f99ce9591..38fb023a08222 100644 --- a/core/java/android/window/TaskOrganizer.java +++ b/core/java/android/window/TaskOrganizer.java @@ -149,9 +149,10 @@ public class TaskOrganizer extends WindowOrganizer { * of one of its controlled tasks. */ @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) - public void setInterceptBackPressedOnTaskRoot(boolean interceptBackPressed) { + public void setInterceptBackPressedOnTaskRoot(@NonNull WindowContainerToken task, + boolean interceptBackPressed) { try { - getController().setInterceptBackPressedOnTaskRoot(mInterface, interceptBackPressed); + getController().setInterceptBackPressedOnTaskRoot(task, interceptBackPressed); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } diff --git a/core/java/android/window/TaskOrganizerTaskEmbedder.java b/core/java/android/window/TaskOrganizerTaskEmbedder.java index 46c72f88e14bb..eb9dfed7f644d 100644 --- a/core/java/android/window/TaskOrganizerTaskEmbedder.java +++ b/core/java/android/window/TaskOrganizerTaskEmbedder.java @@ -74,7 +74,7 @@ public class TaskOrganizerTaskEmbedder extends TaskEmbedder { // windowing mode tasks. Plan is to migrate this to a wm-shell front-end when that // infrastructure is ready. // mTaskOrganizer.registerOrganizer(); - mTaskOrganizer.setInterceptBackPressedOnTaskRoot(true); + // mTaskOrganizer.setInterceptBackPressedOnTaskRoot(true); return super.onInitialize(); } diff --git a/services/core/java/com/android/server/wm/TaskOrganizerController.java b/services/core/java/com/android/server/wm/TaskOrganizerController.java index 1b779c6a0cc91..63a595e3bc17c 100644 --- a/services/core/java/com/android/server/wm/TaskOrganizerController.java +++ b/services/core/java/com/android/server/wm/TaskOrganizerController.java @@ -38,6 +38,7 @@ import android.os.Binder; import android.os.IBinder; import android.os.RemoteException; import android.util.Slog; +import android.util.SparseBooleanArray; import android.view.SurfaceControl; import android.window.ITaskOrganizer; import android.window.ITaskOrganizerController; @@ -50,6 +51,7 @@ import com.android.internal.util.ArrayUtils; import java.io.PrintWriter; import java.util.ArrayList; import java.util.HashMap; +import java.util.HashSet; import java.util.LinkedList; import java.util.List; import java.util.Set; @@ -206,7 +208,6 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub { private final DeathRecipient mDeathRecipient; private final ArrayList mOrganizedTasks = new ArrayList<>(); private final int mUid; - private boolean mInterceptBackPressedOnTaskRoot; TaskOrganizerState(ITaskOrganizer organizer, int uid) { final Consumer deferTaskOrgCallbacksConsumer = @@ -224,10 +225,6 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub { mUid = uid; } - void setInterceptBackPressedOnTaskRoot(boolean interceptBackPressed) { - mInterceptBackPressedOnTaskRoot = interceptBackPressed; - } - void addTask(Task t) { if (t.mTaskAppearedSent) return; @@ -247,6 +244,7 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub { mOrganizer.onTaskVanished(t); } mOrganizedTasks.remove(t); + mInterceptBackPressedOnRootTasks.remove(t.mTaskId); } void dispose() { @@ -278,6 +276,8 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub { private final HashMap mTaskOrganizerStates = new HashMap<>(); private final WeakHashMap mLastSentTaskInfos = new WeakHashMap<>(); private final ArrayList mPendingTaskInfoChanges = new ArrayList<>(); + // Set of organized tasks (by taskId) that dispatch back pressed to their organizers + private final HashSet mInterceptBackPressedOnRootTasks = new HashSet(); private final ActivityTaskManagerService mService; @@ -623,7 +623,7 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub { } @Override - public void setInterceptBackPressedOnTaskRoot(ITaskOrganizer organizer, + public void setInterceptBackPressedOnTaskRoot(WindowContainerToken token, boolean interceptBackPressed) { enforceStackPermission("setInterceptBackPressedOnTaskRoot()"); final long origId = Binder.clearCallingIdentity(); @@ -631,9 +631,15 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub { synchronized (mGlobalLock) { ProtoLog.v(WM_DEBUG_WINDOW_ORGANIZER, "Set intercept back pressed on root=%b", interceptBackPressed); - final TaskOrganizerState state = mTaskOrganizerStates.get(organizer.asBinder()); - if (state != null) { - state.setInterceptBackPressedOnTaskRoot(interceptBackPressed); + final Task task = WindowContainer.fromBinder(token.asBinder()).asTask(); + if (task == null) { + Slog.w(TAG, "Could not resolve task from token"); + return; + } + if (interceptBackPressed) { + mInterceptBackPressedOnRootTasks.add(task.mTaskId); + } else { + mInterceptBackPressedOnRootTasks.remove(task.mTaskId); } } } finally { @@ -642,15 +648,12 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub { } public boolean handleInterceptBackPressedOnTaskRoot(Task task) { - if (task == null || !task.isOrganized()) { + if (task == null || !task.isOrganized() + || !mInterceptBackPressedOnRootTasks.contains(task.mTaskId)) { return false; } final TaskOrganizerState state = mTaskOrganizerStates.get(task.mTaskOrganizer.asBinder()); - if (!state.mInterceptBackPressedOnTaskRoot) { - return false; - } - state.mOrganizer.onBackPressedOnTaskRoot(task); return true; } diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java index 289d54e967f58..46a6a82faba57 100644 --- a/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java @@ -930,23 +930,36 @@ public class WindowOrganizerTests extends WindowTestsBase { final Task stack = createStack(); final Task task = createTask(stack); final ActivityRecord activity = createActivityRecordInTask(stack.mDisplayContent, task); + final Task stack2 = createStack(); + final Task task2 = createTask(stack2); + final ActivityRecord activity2 = createActivityRecordInTask(stack.mDisplayContent, task2); final ITaskOrganizer organizer = registerMockOrganizer(); // Setup the task to be controlled by the MW mode organizer stack.setWindowingMode(WINDOWING_MODE_MULTI_WINDOW); + stack2.setWindowingMode(WINDOWING_MODE_MULTI_WINDOW); assertTrue(stack.isOrganized()); + assertTrue(stack2.isOrganized()); // Verify a back pressed does not call the organizer mWm.mAtmService.onBackPressedOnTaskRoot(activity.token); verify(organizer, never()).onBackPressedOnTaskRoot(any()); // Enable intercepting back - mWm.mAtmService.mTaskOrganizerController.setInterceptBackPressedOnTaskRoot(organizer, - true); + mWm.mAtmService.mTaskOrganizerController.setInterceptBackPressedOnTaskRoot( + stack.mRemoteToken.toWindowContainerToken(), true); // Verify now that the back press does call the organizer mWm.mAtmService.onBackPressedOnTaskRoot(activity.token); verify(organizer, times(1)).onBackPressedOnTaskRoot(any()); + + // Disable intercepting back + mWm.mAtmService.mTaskOrganizerController.setInterceptBackPressedOnTaskRoot( + stack.mRemoteToken.toWindowContainerToken(), false); + + // Verify now that the back press no longer calls the organizer + mWm.mAtmService.onBackPressedOnTaskRoot(activity.token); + verify(organizer, times(1)).onBackPressedOnTaskRoot(any()); } @Test