From 5e1c3b468bfdb4816c0079d006941b8c26d32e02 Mon Sep 17 00:00:00 2001 From: Jeff Chang Date: Fri, 22 Apr 2022 15:50:55 +0800 Subject: [PATCH] Allows the hierarchy operations in lock-task mode For the hierarchy op :reparent-children-tasks/launch-task are skipped currently. That makes the split-screen can not work in lock-task mode. This CL allows the system to execute the reparent-children-task, launch task and reorder hierarchy op if the tasks are not in lock-task violation mode. Bug: 199342537 Test: atest MultiWindowTests Test: 1. Enter Kiosk mode 2. Enter split-screen mode 3. Check split-screen work properly Change-Id: Ifdaa1d04b3370fce47a7400628e5881ae7a046bd --- .../server/wm/WindowOrganizerController.java | 88 +++++++++++++------ 1 file changed, 60 insertions(+), 28 deletions(-) diff --git a/services/core/java/com/android/server/wm/WindowOrganizerController.java b/services/core/java/com/android/server/wm/WindowOrganizerController.java index 128b3292983e6..b8268cd126955 100644 --- a/services/core/java/com/android/server/wm/WindowOrganizerController.java +++ b/services/core/java/com/android/server/wm/WindowOrganizerController.java @@ -862,22 +862,22 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub tf.getDisplayContent().setFocusedApp(targetFocus); break; } - default: { - // The other operations may change task order so they are skipped while in lock - // task mode. The above operations are still allowed because they don't move - // tasks. And it may be necessary such as clearing launch root after entering - // lock task mode. - if (isInLockTaskMode) { - Slog.w(TAG, "Skip applying hierarchy operation " + hop - + " while in lock task mode"); - return effects; - } - } - } - - switch (type) { case HIERARCHY_OP_TYPE_CHILDREN_TASKS_REPARENT: { - effects |= reparentChildrenTasksHierarchyOp(hop, transition, syncId); + effects |= reparentChildrenTasksHierarchyOp(hop, transition, syncId, + isInLockTaskMode); + break; + } + case HIERARCHY_OP_TYPE_LAUNCH_TASK: { + mService.mAmInternal.enforceCallingPermission(START_TASKS_FROM_RECENTS, + "launchTask HierarchyOp"); + final Bundle launchOpts = hop.getLaunchOptions(); + final int taskId = launchOpts.getInt( + WindowContainerTransaction.HierarchyOp.LAUNCH_KEY_TASK_ID); + launchOpts.remove(WindowContainerTransaction.HierarchyOp.LAUNCH_KEY_TASK_ID); + final SafeActivityOptions safeOptions = + SafeActivityOptions.fromBundle(launchOpts, caller.mPid, caller.mUid); + waitAsyncStart(() -> mService.mTaskSupervisor.startActivityFromRecents( + caller.mPid, caller.mUid, taskId, safeOptions)); break; } case HIERARCHY_OP_TYPE_REORDER: @@ -887,6 +887,16 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub Slog.e(TAG, "Attempt to operate on detached container: " + wc); break; } + // There is no use case to ask the reparent operation in lock-task mode now, so keep + // skipping this operation as usual. + if (isInLockTaskMode && type == HIERARCHY_OP_TYPE_REPARENT) { + Slog.w(TAG, "Skip applying hierarchy operation " + hop + + " while in lock task mode"); + break; + } + if (isLockTaskModeViolation(wc.getParent(), wc.asTask(), isInLockTaskMode)) { + break; + } if (syncId >= 0) { addToSyncSet(syncId, wc); } @@ -912,19 +922,20 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub effects |= sanitizeAndApplyHierarchyOp(wc, hop); break; } - case HIERARCHY_OP_TYPE_LAUNCH_TASK: { - mService.mAmInternal.enforceCallingPermission(START_TASKS_FROM_RECENTS, - "launchTask HierarchyOp"); - final Bundle launchOpts = hop.getLaunchOptions(); - final int taskId = launchOpts.getInt( - WindowContainerTransaction.HierarchyOp.LAUNCH_KEY_TASK_ID); - launchOpts.remove(WindowContainerTransaction.HierarchyOp.LAUNCH_KEY_TASK_ID); - final SafeActivityOptions safeOptions = - SafeActivityOptions.fromBundle(launchOpts, caller.mPid, caller.mUid); - waitAsyncStart(() -> mService.mTaskSupervisor.startActivityFromRecents( - caller.mPid, caller.mUid, taskId, safeOptions)); - break; + default: { + // The other operations may change task order so they are skipped while in lock + // task mode. The above operations are still allowed because they don't move + // tasks. And it may be necessary such as clearing launch root after entering + // lock task mode. + if (isInLockTaskMode) { + Slog.w(TAG, "Skip applying hierarchy operation " + hop + + " while in lock task mode"); + return effects; + } } + } + + switch (type) { case HIERARCHY_OP_TYPE_PENDING_INTENT: { String resolvedType = hop.getActivityIntent() != null ? hop.getActivityIntent().resolveTypeIfNeeded( @@ -1103,8 +1114,25 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub return TRANSACT_EFFECTS_LIFECYCLE; } + private boolean isLockTaskModeViolation(WindowContainer parent, Task task, + boolean isInLockTaskMode) { + if (!isInLockTaskMode || parent == null || task == null) { + return false; + } + final LockTaskController lockTaskController = mService.getLockTaskController(); + boolean taskViolation = lockTaskController.isLockTaskModeViolation(task); + if (!taskViolation && parent.asTask() != null) { + taskViolation = lockTaskController.isLockTaskModeViolation(parent.asTask()); + } + if (taskViolation) { + Slog.w(TAG, "Can't support the operation since in lock task mode violation. " + + " Task: " + task + " Parent : " + parent); + } + return taskViolation; + } + private int reparentChildrenTasksHierarchyOp(WindowContainerTransaction.HierarchyOp hop, - @Nullable Transition transition, int syncId) { + @Nullable Transition transition, int syncId, boolean isInLockTaskMode) { WindowContainer currentParent = hop.getContainer() != null ? WindowContainer.fromBinder(hop.getContainer()) : null; WindowContainer newParent = hop.getNewParent() != null @@ -1142,6 +1170,7 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub ? newParent.asTask().getDisplayArea() : newParent.asTaskDisplayArea(); final WindowContainer finalCurrentParent = currentParent; + final WindowContainer finalNewParent = newParent; Slog.i(TAG, "reparentChildrenTasksHierarchyOp" + " currentParent=" + currentParent + " newParent=" + newParent + " hop=" + hop); @@ -1165,6 +1194,9 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub || !ArrayUtils.contains(hop.getWindowingModes(), task.getWindowingMode())) { return false; } + if (isLockTaskModeViolation(finalNewParent, task, isInLockTaskMode)) { + return false; + } if (hop.getToTop()) { tasksToReparent.add(0, task);