From a9201bcfee70f455dad10d0a66427af08ec5148a Mon Sep 17 00:00:00 2001 From: Jerry Chang Date: Wed, 20 Jan 2021 17:11:11 +0800 Subject: [PATCH] Add lock task check when applying window container transaction Unbind locked task mode check with legacy split screen. Add checks to prevent performing hierarchy operation or updating windowing mode unexpectedly while task locked. Bug: 177190100 Test: atest CtsWindowManagerDeviceTestCases:MultiWindowTests Test: atest WindowOrganizerTests Change-Id: I33a6509e21af36afbd4554936c4f5e4208e9a8a3 --- .../server/wm/ActivityTaskManagerService.java | 12 +- .../server/wm/WindowOrganizerController.java | 105 ++++++++++-------- 2 files changed, 65 insertions(+), 52 deletions(-) diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java index 56105737bb822..64afa5432aefd 100644 --- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java +++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java @@ -35,6 +35,7 @@ import static android.app.ActivityManagerInternal.ALLOW_NON_FULL; import static android.app.ActivityTaskManager.INVALID_TASK_ID; import static android.app.ActivityTaskManager.RESIZE_MODE_PRESERVE_WINDOW; import static android.app.WindowConfiguration.ACTIVITY_TYPE_DREAM; +import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED; import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; import static android.content.Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS; @@ -1895,6 +1896,12 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { synchronized (mGlobalLock) { final long ident = Binder.clearCallingIdentity(); try { + if (isInLockTaskMode() && windowingMode != WINDOWING_MODE_FULLSCREEN) { + Slog.w(TAG, "setTaskWindowingMode: Is in lock task mode=" + + getLockTaskModeState()); + return false; + } + if (WindowConfiguration.isSplitScreenWindowingMode(windowingMode)) { return setTaskWindowingModeSplitScreen(taskId, windowingMode, toTop); } @@ -2159,11 +2166,6 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { throw new IllegalArgumentException("Calling setTaskWindowingModeSplitScreen with non" + "split-screen mode: " + windowingMode); } - if (isInLockTaskMode()) { - Slog.w(TAG, "setTaskWindowingModeSplitScreen: Is in lock task mode=" - + getLockTaskModeState()); - return false; - } final Task task = mRootWindowContainer.anyTaskForId(taskId, MATCH_ATTACHED_TASK_ONLY); diff --git a/services/core/java/com/android/server/wm/WindowOrganizerController.java b/services/core/java/com/android/server/wm/WindowOrganizerController.java index 043844b2e66b2..1b81914bbe7c8 100644 --- a/services/core/java/com/android/server/wm/WindowOrganizerController.java +++ b/services/core/java/com/android/server/wm/WindowOrganizerController.java @@ -17,6 +17,7 @@ package com.android.server.wm; import static android.Manifest.permission.READ_FRAME_BUFFER; +import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_CHILDREN_TASKS_REPARENT; import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_REORDER; import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_REPARENT; @@ -264,57 +265,63 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub } // Hierarchy changes final List hops = t.getHierarchyOps(); - for (int i = 0, n = hops.size(); i < n; ++i) { - final WindowContainerTransaction.HierarchyOp hop = hops.get(i); - switch (hop.getType()) { - case HIERARCHY_OP_TYPE_SET_LAUNCH_ROOT: { - final WindowContainer wc = WindowContainer.fromBinder(hop.getContainer()); - final Task task = wc != null ? wc.asTask() : null; - if (task != null) { - task.getDisplayArea().setLaunchRootTask(task, - hop.getWindowingModes(), hop.getActivityTypes()); - } else { - throw new IllegalArgumentException( - "Cannot set non-task as launch root: " + wc); + if (!hops.isEmpty() && mService.isInLockTaskMode()) { + Slog.w(TAG, "Attempt to perform hierarchy operations while in lock task mode..."); + } else { + for (int i = 0, n = hops.size(); i < n; ++i) { + final WindowContainerTransaction.HierarchyOp hop = hops.get(i); + switch (hop.getType()) { + case HIERARCHY_OP_TYPE_SET_LAUNCH_ROOT: { + final WindowContainer wc = WindowContainer.fromBinder( + hop.getContainer()); + final Task task = wc != null ? wc.asTask() : null; + if (task != null) { + task.getDisplayArea().setLaunchRootTask(task, + hop.getWindowingModes(), hop.getActivityTypes()); + } else { + throw new IllegalArgumentException( + "Cannot set non-task as launch root: " + wc); + } + break; } - break; - } - case HIERARCHY_OP_TYPE_CHILDREN_TASKS_REPARENT: - effects |= reparentChildrenTasksHierarchyOp(hop, transition, syncId); - break; - case HIERARCHY_OP_TYPE_SET_ADJACENT_ROOTS: - effects |= setAdjacentRootsHierarchyOp(hop); - break; - case HIERARCHY_OP_TYPE_REORDER: - case HIERARCHY_OP_TYPE_REPARENT: - final WindowContainer wc = WindowContainer.fromBinder(hop.getContainer()); - if (wc == null || !wc.isAttached()) { - Slog.e(TAG, "Attempt to operate on detached container: " + wc); - continue; - } - if (syncId >= 0) { - addToSyncSet(syncId, wc); - } - if (transition != null) { - transition.collect(wc); - if (hop.isReparent()) { - if (wc.getParent() != null) { - // Collect the current parent. It's visibility may change as - // a result of this reparenting. - transition.collect(wc.getParent()); - } - if (hop.getNewParent() != null) { - final WindowContainer parentWc = - WindowContainer.fromBinder(hop.getNewParent()); - if (parentWc == null) { - Slog.e(TAG, "Can't resolve parent window from token"); - continue; + case HIERARCHY_OP_TYPE_CHILDREN_TASKS_REPARENT: + effects |= reparentChildrenTasksHierarchyOp(hop, transition, syncId); + break; + case HIERARCHY_OP_TYPE_SET_ADJACENT_ROOTS: + effects |= setAdjacentRootsHierarchyOp(hop); + break; + case HIERARCHY_OP_TYPE_REORDER: + case HIERARCHY_OP_TYPE_REPARENT: + final WindowContainer wc = WindowContainer.fromBinder( + hop.getContainer()); + if (wc == null || !wc.isAttached()) { + Slog.e(TAG, "Attempt to operate on detached container: " + wc); + continue; + } + if (syncId >= 0) { + addToSyncSet(syncId, wc); + } + if (transition != null) { + transition.collect(wc); + if (hop.isReparent()) { + if (wc.getParent() != null) { + // Collect the current parent. It's visibility may change as + // a result of this reparenting. + transition.collect(wc.getParent()); + } + if (hop.getNewParent() != null) { + final WindowContainer parentWc = + WindowContainer.fromBinder(hop.getNewParent()); + if (parentWc == null) { + Slog.e(TAG, "Can't resolve parent window from token"); + continue; + } + transition.collect(parentWc); } - transition.collect(parentWc); } } - } - effects |= sanitizeAndApplyHierarchyOp(wc, hop); + effects |= sanitizeAndApplyHierarchyOp(wc, hop); + } } } // Queue-up bounds-change transactions for tasks which are now organized. Do @@ -412,6 +419,10 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub } if (windowingMode > -1) { + if (mService.isInLockTaskMode() && windowingMode != WINDOWING_MODE_FULLSCREEN) { + throw new UnsupportedOperationException("Not supported to set non-fullscreen" + + " windowing mode during locked task mode."); + } container.setWindowingMode(windowingMode); } return effects;