diff options
| author | 2020-04-09 14:30:55 -0700 | |
|---|---|---|
| committer | 2020-04-11 00:01:05 -0700 | |
| commit | 1df39e2cf6baf6441636ef69f8f978bf51a27462 (patch) | |
| tree | 181ec2866cdf1bc6f241c76d900af047842f160d | |
| parent | cb437ade00bd23dba1a8ea729bc4ecefd1bc5fbe (diff) | |
Send task description changed though task org taskInfoChanged
- This removes the need for a separate task stack listener and aligns
with other task info change properties
- Also implement equals/hashCode for the token so we can use it in
containers
Bug: 148977538
Test: atest TaskOrganizerTests
Signed-off-by: Winson Chung <winsonc@google.com>
Change-Id: Ie035e6389fdbdc374c1a4b4a684758efa0cb7a9e
13 files changed, 119 insertions, 81 deletions
diff --git a/api/test-current.txt b/api/test-current.txt index 641767c7bccd..0dff41b6a99c 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -5232,14 +5232,14 @@ package android.window { method @Nullable @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) public static java.util.List<android.app.ActivityManager.RunningTaskInfo> getChildTasks(@NonNull android.window.WindowContainerToken, @NonNull int[]); method @Nullable @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) public static android.window.WindowContainerToken getImeTarget(int); method @Nullable @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) public static java.util.List<android.app.ActivityManager.RunningTaskInfo> getRootTasks(int, @NonNull int[]); - method public void onBackPressedOnTaskRoot(@NonNull android.app.ActivityManager.RunningTaskInfo); - method public void onTaskAppeared(@NonNull android.app.ActivityManager.RunningTaskInfo); - method public void onTaskInfoChanged(@NonNull android.app.ActivityManager.RunningTaskInfo); - method public void onTaskVanished(@NonNull android.app.ActivityManager.RunningTaskInfo); - method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) public void registerOrganizer(int); + method @BinderThread public void onBackPressedOnTaskRoot(@NonNull android.app.ActivityManager.RunningTaskInfo); + method @BinderThread public void onTaskAppeared(@NonNull android.app.ActivityManager.RunningTaskInfo); + 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(int); method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) public void setInterceptBackPressedOnTaskRoot(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 void unregisterOrganizer(); + method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) public final void unregisterOrganizer(); } public final class WindowContainerToken implements android.os.Parcelable { diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java index b6d519ae5d2b..fd73632632ff 100644 --- a/core/java/android/app/ActivityManager.java +++ b/core/java/android/app/ActivityManager.java @@ -69,6 +69,7 @@ import android.os.SystemProperties; import android.os.UserHandle; import android.os.UserManager; import android.os.WorkSource; +import android.text.TextUtils; import android.util.ArrayMap; import android.util.DisplayMetrics; import android.util.Singleton; @@ -1597,6 +1598,39 @@ public class ActivityManager { + " resizeMode: " + ActivityInfo.resizeModeToString(mResizeMode) + " minWidth: " + mMinWidth + " minHeight: " + mMinHeight; } + + @Override + public boolean equals(Object obj) { + if (!(obj instanceof TaskDescription)) { + return false; + } + + TaskDescription other = (TaskDescription) obj; + return TextUtils.equals(mLabel, other.mLabel) + && TextUtils.equals(mIconFilename, other.mIconFilename) + && mIcon == other.mIcon + && mColorPrimary == other.mColorPrimary + && mColorBackground == other.mColorBackground + && mStatusBarColor == other.mStatusBarColor + && mNavigationBarColor == other.mNavigationBarColor + && mEnsureStatusBarContrastWhenTransparent + == other.mEnsureStatusBarContrastWhenTransparent + && mEnsureNavigationBarContrastWhenTransparent + == other.mEnsureNavigationBarContrastWhenTransparent + && mResizeMode == other.mResizeMode + && mMinWidth == other.mMinWidth + && mMinHeight == other.mMinHeight; + } + + /** @hide */ + public static boolean equals(TaskDescription td1, TaskDescription td2) { + if (td1 == null && td2 == null) { + return true; + } else if (td1 != null && td2 != null) { + return td1.equals(td2); + } + return false; + } } /** diff --git a/core/java/android/window/TaskEmbedder.java b/core/java/android/window/TaskEmbedder.java index 45ab310c5148..2ead37a9397d 100644 --- a/core/java/android/window/TaskEmbedder.java +++ b/core/java/android/window/TaskEmbedder.java @@ -26,7 +26,6 @@ import android.app.ActivityTaskManager; import android.app.ActivityView; import android.app.IActivityTaskManager; import android.app.PendingIntent; -import android.app.TaskStackListener; import android.content.ComponentName; import android.content.Context; import android.content.Intent; @@ -129,7 +128,6 @@ public abstract class TaskEmbedder { protected SurfaceControl.Transaction mTransaction; protected SurfaceControl mSurfaceControl; - protected TaskStackListener mTaskStackListener; protected Listener mListener; protected boolean mOpened; // Protected by mGuard. @@ -170,13 +168,6 @@ public abstract class TaskEmbedder { if (!onInitialize()) { return false; } - - mTaskStackListener = createTaskStackListener(); - try { - mActivityTaskManager.registerTaskStackListener(mTaskStackListener); - } catch (RemoteException e) { - Log.e(TAG, "Failed to register task stack listener", e); - } if (mListener != null && isInitialized()) { mListener.onInitialized(); } @@ -187,11 +178,6 @@ public abstract class TaskEmbedder { } /** - * @return the task stack listener for this embedder - */ - public abstract TaskStackListener createTaskStackListener(); - - /** * Whether this container has been initialized. * * @return true if initialized @@ -420,16 +406,6 @@ public abstract class TaskEmbedder { mSurfaceControl.release(); boolean reportReleased = onRelease(); - - if (mTaskStackListener != null) { - try { - mActivityTaskManager.unregisterTaskStackListener(mTaskStackListener); - } catch (RemoteException e) { - Log.e(TAG, "Failed to unregister task stack listener", e); - } - mTaskStackListener = null; - } - if (mListener != null && reportReleased) { mListener.onReleased(); } diff --git a/core/java/android/window/TaskOrganizer.java b/core/java/android/window/TaskOrganizer.java index 5098b4440070..f661d9af5999 100644 --- a/core/java/android/window/TaskOrganizer.java +++ b/core/java/android/window/TaskOrganizer.java @@ -16,6 +16,7 @@ package android.window; +import android.annotation.BinderThread; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.RequiresPermission; @@ -39,7 +40,7 @@ public class TaskOrganizer extends WindowOrganizer { * and receive taskVanished callbacks in the process. */ @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) - public void registerOrganizer(int windowingMode) { + public final void registerOrganizer(int windowingMode) { try { getController().registerTaskOrganizer(mInterface, windowingMode); } catch (RemoteException e) { @@ -49,7 +50,7 @@ public class TaskOrganizer extends WindowOrganizer { /** Unregisters a previously registered task organizer. */ @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) - public void unregisterOrganizer() { + public final void unregisterOrganizer() { try { getController().unregisterTaskOrganizer(mInterface); } catch (RemoteException e) { @@ -57,13 +58,17 @@ public class TaskOrganizer extends WindowOrganizer { } } + @BinderThread public void onTaskAppeared(@NonNull ActivityManager.RunningTaskInfo taskInfo) {} + @BinderThread public void onTaskVanished(@NonNull ActivityManager.RunningTaskInfo taskInfo) {} - public void onTaskInfoChanged(@NonNull ActivityManager.RunningTaskInfo info) {} + @BinderThread + public void onTaskInfoChanged(@NonNull ActivityManager.RunningTaskInfo taskInfo) {} - public void onBackPressedOnTaskRoot(@NonNull ActivityManager.RunningTaskInfo info) {} + @BinderThread + public void onBackPressedOnTaskRoot(@NonNull ActivityManager.RunningTaskInfo taskInfo) {} /** Creates a persistent root task in WM for a particular windowing-mode. */ @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) diff --git a/core/java/android/window/TaskOrganizerTaskEmbedder.java b/core/java/android/window/TaskOrganizerTaskEmbedder.java index 39a0101bbf59..b63741ec69c4 100644 --- a/core/java/android/window/TaskOrganizerTaskEmbedder.java +++ b/core/java/android/window/TaskOrganizerTaskEmbedder.java @@ -21,7 +21,6 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW; import android.app.ActivityManager; import android.app.ActivityOptions; -import android.app.ActivityView; import android.app.TaskStackListener; import android.content.Context; import android.graphics.Rect; @@ -55,11 +54,6 @@ public class TaskOrganizerTaskEmbedder extends TaskEmbedder { super(context, host); } - @Override - public TaskStackListener createTaskStackListener() { - return new TaskStackListenerImpl(); - } - /** * Whether this container has been initialized. * @@ -219,29 +213,6 @@ public class TaskOrganizerTaskEmbedder extends TaskEmbedder { Log.d(TAG, "[" + System.identityHashCode(this) + "] " + msg); } - /** - * A task change listener that detects background color change of the topmost stack on our - * virtual display and updates the background of the surface view. This background will be shown - * when surface view is resized, but the app hasn't drawn its content in new size yet. - * It also calls StateCallback.onTaskMovedToFront to notify interested parties that the stack - * associated with the {@link ActivityView} has had a Task moved to the front. This is useful - * when needing to also bring the host Activity to the foreground at the same time. - */ - private class TaskStackListenerImpl extends TaskStackListener { - - @Override - public void onTaskDescriptionChanged(ActivityManager.RunningTaskInfo taskInfo) { - if (!isInitialized()) { - return; - } - if (taskInfo.taskId == mTaskInfo.taskId) { - mTaskInfo.taskDescription = taskInfo.taskDescription; - mHost.onTaskBackgroundColorChanged(TaskOrganizerTaskEmbedder.this, - taskInfo.taskDescription.getBackgroundColor()); - } - } - } - private class TaskOrganizerImpl extends TaskOrganizer { @Override public void onTaskAppeared(ActivityManager.RunningTaskInfo taskInfo) { @@ -249,7 +220,6 @@ public class TaskOrganizerTaskEmbedder extends TaskEmbedder { log("taskAppeared: " + taskInfo.taskId); } - // TODO: Ensure visibility/alpha of the leash in its initial state? mTaskInfo = taskInfo; mTaskToken = taskInfo.token; mTaskLeash = mTaskToken.getLeash(); @@ -270,6 +240,13 @@ public class TaskOrganizerTaskEmbedder extends TaskEmbedder { } @Override + public void onTaskInfoChanged(ActivityManager.RunningTaskInfo taskInfo) { + mTaskInfo.taskDescription = taskInfo.taskDescription; + mHost.post(() -> mHost.onTaskBackgroundColorChanged(TaskOrganizerTaskEmbedder.this, + taskInfo.taskDescription.getBackgroundColor())); + } + + @Override public void onTaskVanished(ActivityManager.RunningTaskInfo taskInfo) { if (DEBUG) { log("taskVanished: " + taskInfo.taskId); diff --git a/core/java/android/window/VirtualDisplayTaskEmbedder.java b/core/java/android/window/VirtualDisplayTaskEmbedder.java index 0f26d5d00f6d..70164692032f 100644 --- a/core/java/android/window/VirtualDisplayTaskEmbedder.java +++ b/core/java/android/window/VirtualDisplayTaskEmbedder.java @@ -67,6 +67,7 @@ public class VirtualDisplayTaskEmbedder extends TaskEmbedder { private VirtualDisplay mVirtualDisplay; private Insets mForwardedInsets; private DisplayMetrics mTmpDisplayMetrics; + private TaskStackListener mTaskStackListener; /** * Constructs a new TaskEmbedder. @@ -82,11 +83,6 @@ public class VirtualDisplayTaskEmbedder extends TaskEmbedder { mSingleTaskInstance = singleTaskInstance; } - @Override - public TaskStackListener createTaskStackListener() { - return new TaskStackListenerImpl(); - } - /** * Whether this container has been initialized. * @@ -124,6 +120,9 @@ public class VirtualDisplayTaskEmbedder extends TaskEmbedder { .setDisplayToSingleTaskInstance(displayId); } setForwardedInsets(mForwardedInsets); + + mTaskStackListener = new TaskStackListenerImpl(); + mActivityTaskManager.registerTaskStackListener(mTaskStackListener); } catch (RemoteException e) { e.rethrowAsRuntimeException(); } @@ -142,6 +141,15 @@ public class VirtualDisplayTaskEmbedder extends TaskEmbedder { // Clear tap-exclude region (if any) for this window. clearTapExcludeRegion(); + if (mTaskStackListener != null) { + try { + mActivityTaskManager.unregisterTaskStackListener(mTaskStackListener); + } catch (RemoteException e) { + Log.e(TAG, "Failed to unregister task stack listener", e); + } + mTaskStackListener = null; + } + if (isInitialized()) { mVirtualDisplay.release(); mVirtualDisplay = null; diff --git a/core/java/android/window/WindowContainerToken.java b/core/java/android/window/WindowContainerToken.java index dde98dae4057..3316d0e5b71f 100644 --- a/core/java/android/window/WindowContainerToken.java +++ b/core/java/android/window/WindowContainerToken.java @@ -84,4 +84,17 @@ public final class WindowContainerToken implements Parcelable { public int describeContents() { return 0; } + + @Override + public int hashCode() { + return mRealToken.asBinder().hashCode(); + } + + @Override + public boolean equals(Object obj) { + if (!(obj instanceof WindowContainerToken)) { + return false; + } + return mRealToken.asBinder() == ((WindowContainerToken) obj).asBinder(); + } } diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/SplitScreenTaskOrganizer.java b/packages/SystemUI/src/com/android/systemui/stackdivider/SplitScreenTaskOrganizer.java index 91d638e70677..a4b1310687aa 100644 --- a/packages/SystemUI/src/com/android/systemui/stackdivider/SplitScreenTaskOrganizer.java +++ b/packages/SystemUI/src/com/android/systemui/stackdivider/SplitScreenTaskOrganizer.java @@ -105,10 +105,6 @@ class SplitScreenTaskOrganizer extends TaskOrganizer { mDivider.getHandler().post(() -> handleTaskInfoChanged(taskInfo)); } - @Override - public void onBackPressedOnTaskRoot(RunningTaskInfo taskInfo) { - } - /** * This is effectively a finite state machine which moves between the various split-screen * presentations based on the contents of the split regions. diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java index 856fbc70438e..ac13492ab81a 100644 --- a/services/core/java/com/android/server/wm/ActivityRecord.java +++ b/services/core/java/com/android/server/wm/ActivityRecord.java @@ -5592,6 +5592,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A _taskDescription.setIconFilename(iconFilePath); } taskDescription = _taskDescription; + getTask().updateTaskDescription(); } void setVoiceSessionLocked(IVoiceInteractionSession session) { diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java index c253cd2c3297..f4eb0d2c8e89 100644 --- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java +++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java @@ -3061,8 +3061,6 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { ActivityRecord r = ActivityRecord.isInStackLocked(token); if (r != null) { r.setTaskDescription(td); - final Task task = r.getTask(); - task.updateTaskDescription(); } } } diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java index 1e70573a2ada..2742b38b9a58 100644 --- a/services/core/java/com/android/server/wm/Task.java +++ b/services/core/java/com/android/server/wm/Task.java @@ -1767,6 +1767,10 @@ class Task extends WindowContainer<WindowContainer> { t.updateTaskDescription(); } } + + if (isOrganized()) { + mAtmService.mTaskOrganizerController.dispatchTaskInfoChanged(this, true /* force */); + } } private static boolean setTaskDescriptionFromActivityAboveRoot( @@ -1962,7 +1966,7 @@ class Task extends WindowContainer<WindowContainer> { final boolean taskOrgChanged = updateTaskOrganizerState(false /* forceUpdate */); // If the task organizer has changed, then it will already be receiving taskAppeared with // the latest task-info thus the task-info won't have changed. - if (!taskOrgChanged && mTaskOrganizer != null) { + if (!taskOrgChanged && isOrganized()) { mAtmService.mTaskOrganizerController.dispatchTaskInfoChanged(this, false /* force */); } } @@ -4153,8 +4157,6 @@ class Task extends WindowContainer<WindowContainer> { // Let the old organizer know it has lost control. sendTaskVanished(); mTaskOrganizer = organizer; - - sendTaskAppeared(); onTaskOrganizerChanged(); return true; @@ -4291,8 +4293,9 @@ class Task extends WindowContainer<WindowContainer> { void setPictureInPictureParams(PictureInPictureParams p) { mPictureInPictureParams.copyOnlySet(p); - mAtmService.mTaskOrganizerController.dispatchTaskInfoChanged( - this, true /* force */); + if (isOrganized()) { + mAtmService.mTaskOrganizerController.dispatchTaskInfoChanged(this, true /* force */); + } } /** diff --git a/services/core/java/com/android/server/wm/TaskOrganizerController.java b/services/core/java/com/android/server/wm/TaskOrganizerController.java index 9873031e0138..adc50bf70446 100644 --- a/services/core/java/com/android/server/wm/TaskOrganizerController.java +++ b/services/core/java/com/android/server/wm/TaskOrganizerController.java @@ -27,6 +27,7 @@ import static com.android.server.wm.WindowOrganizerController.CONTROLLABLE_WINDO import android.annotation.Nullable; import android.app.ActivityManager; import android.app.ActivityManager.RunningTaskInfo; +import android.app.ActivityManager.TaskDescription; import android.app.WindowConfiguration; import android.content.Intent; import android.content.pm.ActivityInfo; @@ -439,7 +440,8 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub { boolean changed = lastInfo == null || mTmpTaskInfo.topActivityType != lastInfo.topActivityType || mTmpTaskInfo.isResizable() != lastInfo.isResizable() - || mTmpTaskInfo.pictureInPictureParams != lastInfo.pictureInPictureParams; + || mTmpTaskInfo.pictureInPictureParams != lastInfo.pictureInPictureParams + || !TaskDescription.equals(mTmpTaskInfo.taskDescription, lastInfo.taskDescription); if (!changed) { int cfgChanges = mTmpTaskInfo.configuration.diff(lastInfo.configuration); final int winCfgChanges = (cfgChanges & ActivityInfo.CONFIG_WINDOW_CONFIGURATION) != 0 diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskOrganizerTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskOrganizerTests.java index f275e378ed26..e41d4dcdb186 100644 --- a/services/tests/wmtests/src/com/android/server/wm/TaskOrganizerTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/TaskOrganizerTests.java @@ -50,6 +50,7 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyInt; +import android.app.ActivityManager; import android.app.ActivityManager.RunningTaskInfo; import android.app.ActivityManager.StackInfo; import android.app.IRequestFinishCallback; @@ -856,6 +857,30 @@ public class TaskOrganizerTests extends WindowTestsBase { } @Test + public void testChangeTaskDescription() { + class ChangeSavingOrganizer extends StubOrganizer { + RunningTaskInfo mChangedInfo; + @Override + public void onTaskInfoChanged(RunningTaskInfo info) { + mChangedInfo = info; + } + } + ChangeSavingOrganizer o = new ChangeSavingOrganizer(); + mWm.mAtmService.mTaskOrganizerController.registerTaskOrganizer(o, + WINDOWING_MODE_MULTI_WINDOW); + + final ActivityStack stack = createStack(); + final Task task = createTask(stack); + final ActivityRecord record = WindowTestUtils.createActivityRecordInTask( + stack.mDisplayContent, task); + + stack.setWindowingMode(WINDOWING_MODE_MULTI_WINDOW); + record.setTaskDescription(new ActivityManager.TaskDescription("TestDescription")); + waitUntilHandlersIdle(); + assertEquals("TestDescription", o.mChangedInfo.taskDescription.getLabel()); + } + + @Test public void testPreventDuplicateAppear() throws RemoteException { final ActivityStack stack = createStack(); final Task task = createTask(stack); |