diff options
| author | 2023-06-05 17:50:21 +0800 | |
|---|---|---|
| committer | 2023-06-05 18:03:00 +0800 | |
| commit | 6008eca456b1a92f3621ff4d8a36c6ec1ca4142c (patch) | |
| tree | b6fc9a39c2ee7cfeec92260a321c93e22da1d5ed | |
| parent | 25aa2d3c877f7880222695bd4048a8edf0f360fd (diff) | |
Only apply transient visibility for root task
For example, assume all task are opaque (from top to bottom):
TaskR(root)
-TaskA(top split)
-TaskX
-TaskY
-TaskB(bottom split)
-TaskZ
Only TaskX and TaskZ should be visible. TaskY is invisible
because it is occluded by TaskX.
(The problem was that TaskY becomes visible)
In the other words, when entering recents, TaskR is occluded
by recents so only need to force TaskR to be visible. While
the descendant tasks of TaskR should still follow the original
visibility calculation that computes whether they are occluded
inside the parent task.
Fix: 279128366
Test: atest RootTaskTests#testGetVisibility_MultiLevel
Change-Id: Ied02650f08918471257d1cefda9fae365654fd4c
| -rw-r--r-- | services/core/java/com/android/server/wm/TaskFragment.java | 6 | ||||
| -rw-r--r-- | services/tests/wmtests/src/com/android/server/wm/RootTaskTests.java | 25 |
2 files changed, 29 insertions, 2 deletions
diff --git a/services/core/java/com/android/server/wm/TaskFragment.java b/services/core/java/com/android/server/wm/TaskFragment.java index c6c3b14bf98b..0c1f33ccedbc 100644 --- a/services/core/java/com/android/server/wm/TaskFragment.java +++ b/services/core/java/com/android/server/wm/TaskFragment.java @@ -1017,8 +1017,11 @@ class TaskFragment extends WindowContainer<WindowContainer> { if (isTopActivityLaunchedBehind()) { return TASK_FRAGMENT_VISIBILITY_VISIBLE; } + final WindowContainer<?> parent = getParent(); final Task thisTask = asTask(); - if (thisTask != null && mTransitionController.isTransientHide(thisTask)) { + if (thisTask != null && parent.asTask() == null + && mTransitionController.isTransientHide(thisTask)) { + // Keep transient-hide root tasks visible. Non-root tasks still follow standard rule. return TASK_FRAGMENT_VISIBILITY_VISIBLE; } @@ -1028,7 +1031,6 @@ class TaskFragment extends WindowContainer<WindowContainer> { // This TaskFragment is only considered visible if all its parent TaskFragments are // considered visible, so check the visibility of all ancestor TaskFragment first. - final WindowContainer parent = getParent(); if (parent.asTaskFragment() != null) { final int parentVisibility = parent.asTaskFragment().getVisibility(starting); if (parentVisibility == TASK_FRAGMENT_VISIBILITY_INVISIBLE) { diff --git a/services/tests/wmtests/src/com/android/server/wm/RootTaskTests.java b/services/tests/wmtests/src/com/android/server/wm/RootTaskTests.java index fb29d3adb52b..abf21a57dd40 100644 --- a/services/tests/wmtests/src/com/android/server/wm/RootTaskTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/RootTaskTests.java @@ -641,6 +641,31 @@ public class RootTaskTests extends WindowTestsBase { // Home split secondary and home task should be invisible. assertEquals(TASK_FRAGMENT_VISIBILITY_INVISIBLE, splitSecondary.getVisibility(null /* starting */)); + + // Put another task on top of primary split. + final Task topSplitPrimary = new TaskBuilder(mSupervisor).setParentTask(organizer.mPrimary) + .setCreateActivity(true).build(); + doReturn(false).when(topSplitPrimary).isTranslucent(any()); + // Convert the fullscreen translucent task to opaque. + doReturn(false).when(translucentRootTask).isTranslucent(any()); + translucentRootTask.moveToFront("test"); + // The tasks of primary split are occluded by the fullscreen opaque task. + assertEquals(TASK_FRAGMENT_VISIBILITY_INVISIBLE, + organizer.mPrimary.getVisibility(null /* starting */)); + assertEquals(TASK_FRAGMENT_VISIBILITY_INVISIBLE, + topSplitPrimary.getVisibility(null /* starting */)); + // Make primary split root transient-hide. + spyOn(splitPrimary.mTransitionController); + doReturn(true).when(splitPrimary.mTransitionController).isTransientHide( + organizer.mPrimary); + // The split root and its top become visible. + assertEquals(TASK_FRAGMENT_VISIBILITY_VISIBLE, + organizer.mPrimary.getVisibility(null /* starting */)); + assertEquals(TASK_FRAGMENT_VISIBILITY_VISIBLE, + topSplitPrimary.getVisibility(null /* starting */)); + // The bottom of primary split becomes invisible because it is occluded by topSplitPrimary. + assertEquals(TASK_FRAGMENT_VISIBILITY_INVISIBLE, + splitPrimary.getVisibility(null /* starting */)); } @Test |