summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Riddle Hsu <riddlehsu@google.com> 2021-05-07 17:29:55 +0800
committer Riddle Hsu <riddlehsu@google.com> 2021-05-07 09:45:11 +0000
commitda4a464bafa29b1b3a92ae80176c4d2778d7a061 (patch)
treed5829424553212529dc7677b7686c7baf64ca375
parent690dd68dcc31dc7af2cd31475a64d68f29b931e2 (diff)
Only skip hierarchy op which may reorder task in task lock mode
Otherwise when entering task lock mode from split-screen, the request from WindowManagerProxy#applyDismissSplit is ignored. That causes launch root to remain and affect new launch tasks. Bug: 186764983 Test: MultiWindowTests#testDisallowHierarchyOperationWhenInLockedTask Test: 1. Enable App pinning 2. Enter split-screen mode 3. Pin the task on secondary-split 4. Unpin the task and launch other new task The new task should fill screen bounds. "adb shell dumpsys activity a | grep mLaunchRootTasks" must be empty. Change-Id: I890a9e1234b11772f4183168e085b75d31859e20
-rw-r--r--services/core/java/com/android/server/wm/WindowOrganizerController.java182
1 files changed, 96 insertions, 86 deletions
diff --git a/services/core/java/com/android/server/wm/WindowOrganizerController.java b/services/core/java/com/android/server/wm/WindowOrganizerController.java
index c29211f3bb65..c72ef8a4a24d 100644
--- a/services/core/java/com/android/server/wm/WindowOrganizerController.java
+++ b/services/core/java/com/android/server/wm/WindowOrganizerController.java
@@ -302,92 +302,12 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
}
// Hierarchy changes
final List<WindowContainerTransaction.HierarchyOp> hops = t.getHierarchyOps();
- 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;
- }
- case HIERARCHY_OP_TYPE_SET_LAUNCH_ADJACENT_FLAG_ROOT: {
- final WindowContainer wc = WindowContainer.fromBinder(
- hop.getContainer());
- final Task task = wc != null ? wc.asTask() : null;
- if (task == null) {
- throw new IllegalArgumentException("Cannot set "
- + "non-task as launch root: " + wc);
- } else if (!task.mCreatedByOrganizer) {
- throw new UnsupportedOperationException("Cannot set "
- + "non-organized task as adjacent flag root: " + wc);
- } else if (task.mAdjacentTask == null) {
- throw new UnsupportedOperationException("Cannot set "
- + "non-adjacent task as adjacent flag root: " + wc);
- }
-
- final boolean clearRoot = hop.getToTop();
- task.getDisplayArea()
- .setLaunchAdjacentFlagRootTask(clearRoot ? null : task);
- 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;
- }
- transition.collect(parentWc);
- }
- }
- }
- effects |= sanitizeAndApplyHierarchyOp(wc, hop);
- break;
- case HIERARCHY_OP_TYPE_LAUNCH_TASK:
- Bundle launchOpts = hop.getLaunchOptions();
- int taskId = launchOpts.getInt(
- WindowContainerTransaction.HierarchyOp.LAUNCH_KEY_TASK_ID);
- launchOpts.remove(
- WindowContainerTransaction.HierarchyOp.LAUNCH_KEY_TASK_ID);
- mService.startActivityFromRecents(taskId, launchOpts);
- break;
- }
+ final int hopSize = hops.size();
+ if (hopSize > 0) {
+ final boolean isInLockTaskMode = mService.isInLockTaskMode();
+ for (int i = 0; i < hopSize; ++i) {
+ effects |= applyHierarchyOp(hops.get(i), effects, syncId, transition,
+ isInLockTaskMode);
}
}
// Queue-up bounds-change transactions for tasks which are now organized. Do
@@ -541,6 +461,96 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
return effects[0];
}
+ private int applyHierarchyOp(WindowContainerTransaction.HierarchyOp hop, int effects,
+ int syncId, @Nullable Transition transition, boolean isInLockTaskMode) {
+ final int type = hop.getType();
+ switch (type) {
+ 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;
+ }
+ case HIERARCHY_OP_TYPE_SET_LAUNCH_ADJACENT_FLAG_ROOT: {
+ final WindowContainer wc = WindowContainer.fromBinder(hop.getContainer());
+ final Task task = wc != null ? wc.asTask() : null;
+ if (task == null) {
+ throw new IllegalArgumentException("Cannot set non-task as launch root: " + wc);
+ } else if (!task.mCreatedByOrganizer) {
+ throw new UnsupportedOperationException(
+ "Cannot set non-organized task as adjacent flag root: " + wc);
+ } else if (task.mAdjacentTask == null) {
+ throw new UnsupportedOperationException(
+ "Cannot set non-adjacent task as adjacent flag root: " + wc);
+ }
+
+ final boolean clearRoot = hop.getToTop();
+ task.getDisplayArea().setLaunchAdjacentFlagRootTask(clearRoot ? null : task);
+ break;
+ }
+ case HIERARCHY_OP_TYPE_SET_ADJACENT_ROOTS:
+ effects |= setAdjacentRootsHierarchyOp(hop);
+ break;
+ }
+ // The following 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);
+ 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);
+ break;
+ }
+ 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");
+ break;
+ }
+ transition.collect(parentWc);
+ }
+ }
+ }
+ effects |= sanitizeAndApplyHierarchyOp(wc, hop);
+ break;
+ case HIERARCHY_OP_TYPE_LAUNCH_TASK:
+ final Bundle launchOpts = hop.getLaunchOptions();
+ final int taskId = launchOpts.getInt(
+ WindowContainerTransaction.HierarchyOp.LAUNCH_KEY_TASK_ID);
+ launchOpts.remove(WindowContainerTransaction.HierarchyOp.LAUNCH_KEY_TASK_ID);
+ mService.startActivityFromRecents(taskId, launchOpts);
+ break;
+ }
+ return effects;
+ }
+
private int sanitizeAndApplyHierarchyOp(WindowContainer container,
WindowContainerTransaction.HierarchyOp hop) {
final Task task = container.asTask();