Loading services/core/java/com/android/server/wm/ActivityRecord.java +29 −12 Original line number Diff line number Diff line Loading @@ -3898,6 +3898,12 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A final TaskFragment taskFragment = getTaskFragment(); if (next != null && taskFragment != null && taskFragment.isEmbedded()) { final TaskFragment organized = taskFragment.getOrganizedTaskFragment(); if (Flags.allowMultipleAdjacentTaskFragments()) { delayRemoval = organized != null && organized.topRunningActivity() == null && organized.isDelayLastActivityRemoval() && organized.forOtherAdjacentTaskFragments(next::isDescendantOf); } else { final TaskFragment adjacent = organized != null ? organized.getAdjacentTaskFragment() : null; if (adjacent != null && next.isDescendantOf(adjacent) Loading @@ -3905,6 +3911,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A delayRemoval = organized.isDelayLastActivityRemoval(); } } } // isNextNotYetVisible is to check if the next activity is invisible, or it has been // requested to be invisible but its windows haven't reported as invisible. If so, it Loading Loading @@ -4880,15 +4887,25 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A * @see #canShowWhenLocked(ActivityRecord) */ boolean canShowWhenLocked() { if (!canShowWhenLocked(this)) { return false; } final TaskFragment taskFragment = getTaskFragment(); if (taskFragment != null && taskFragment.getAdjacentTaskFragment() != null && taskFragment.isEmbedded()) { final TaskFragment adjacentTaskFragment = taskFragment.getAdjacentTaskFragment(); final ActivityRecord r = adjacentTaskFragment.getTopNonFinishingActivity(); return canShowWhenLocked(this) && canShowWhenLocked(r); } else { return canShowWhenLocked(this); if (taskFragment == null || !taskFragment.hasAdjacentTaskFragment() || !taskFragment.isEmbedded()) { // No embedded adjacent that need to be checked. return true; } // Make sure the embedded adjacent can also be shown. if (!Flags.allowMultipleAdjacentTaskFragments()) { final ActivityRecord adjacentActivity = taskFragment.getAdjacentTaskFragment() .getTopNonFinishingActivity(); return canShowWhenLocked(adjacentActivity); } final boolean hasAdjacentNotAllowToShow = taskFragment.forOtherAdjacentTaskFragments( adjacentTF -> !canShowWhenLocked(adjacentTF.getTopNonFinishingActivity())); return !hasAdjacentNotAllowToShow; } /** Loading services/core/java/com/android/server/wm/Task.java +15 −4 Original line number Diff line number Diff line Loading @@ -3707,12 +3707,23 @@ class Task extends TaskFragment { // Boost the adjacent TaskFragment for dimmer if needed. final TaskFragment taskFragment = wc.asTaskFragment(); if (taskFragment != null && taskFragment.isEmbedded()) { if (taskFragment != null && taskFragment.isEmbedded() && taskFragment.hasAdjacentTaskFragment()) { if (Flags.allowMultipleAdjacentTaskFragments()) { final int[] nextLayer = { layer }; taskFragment.forOtherAdjacentTaskFragments(adjacentTf -> { if (adjacentTf.shouldBoostDimmer()) { adjacentTf.assignLayer(t, nextLayer[0]++); } }); layer = nextLayer[0]; } else { final TaskFragment adjacentTf = taskFragment.getAdjacentTaskFragment(); if (adjacentTf != null && adjacentTf.shouldBoostDimmer()) { if (adjacentTf.shouldBoostDimmer()) { adjacentTf.assignLayer(t, layer++); } } } // Place the decor surface just above the owner TaskFragment. if (mDecorSurfaceContainer != null Loading services/core/java/com/android/server/wm/TaskDisplayArea.java +1 −1 Original line number Diff line number Diff line Loading @@ -1045,7 +1045,7 @@ final class TaskDisplayArea extends DisplayArea<WindowContainer> { + adjacentFlagRootTask); } if (adjacentFlagRootTask.getAdjacentTaskFragment() == null) { if (!adjacentFlagRootTask.hasAdjacentTaskFragment()) { throw new UnsupportedOperationException( "Can't set non-adjacent root as launch adjacent flag root tr=" + adjacentFlagRootTask); Loading services/core/java/com/android/server/wm/Transition.java +7 −6 Original line number Diff line number Diff line Loading @@ -2542,15 +2542,16 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener { // TaskFragment doesn't contain occluded ActivityRecord. return true; } final TaskFragment adjacentTaskFragment = taskFragment.getAdjacentTaskFragment(); if (adjacentTaskFragment != null) { // When the TaskFragment has an adjacent TaskFragment, sibling behind them should be // hidden unless any of them are translucent. return adjacentTaskFragment.isTranslucentForTransition(); } else { if (!taskFragment.hasAdjacentTaskFragment()) { // Non-filling without adjacent is considered as translucent. return !wc.fillsParent(); } // When the TaskFragment has an adjacent TaskFragment, sibling behind them should be // hidden unless any of them are translucent. if (!Flags.allowMultipleAdjacentTaskFragments()) { return taskFragment.getAdjacentTaskFragment().isTranslucentForTransition(); } return taskFragment.forOtherAdjacentTaskFragments(TaskFragment::isTranslucentForTransition); } private void updatePriorVisibility() { Loading services/tests/wmtests/src/com/android/server/wm/TaskFragmentOrganizerControllerTest.java +10 −10 Original line number Diff line number Diff line Loading @@ -741,16 +741,16 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase { // Not allowed because TaskFragments are not organized by the caller organizer. assertApplyTransactionDisallowed(mTransaction); assertNull(mTaskFragment.getAdjacentTaskFragment()); assertNull(taskFragment2.getAdjacentTaskFragment()); assertFalse(mTaskFragment.hasAdjacentTaskFragment()); assertFalse(taskFragment2.hasAdjacentTaskFragment()); mTaskFragment.setTaskFragmentOrganizer(mOrganizerToken, 10 /* uid */, "Test:TaskFragmentOrganizer" /* processName */); // Not allowed because TaskFragment2 is not organized by the caller organizer. assertApplyTransactionDisallowed(mTransaction); assertNull(mTaskFragment.getAdjacentTaskFragment()); assertNull(taskFragment2.getAdjacentTaskFragment()); assertFalse(mTaskFragment.hasAdjacentTaskFragment()); assertFalse(taskFragment2.hasAdjacentTaskFragment()); mTaskFragment.onTaskFragmentOrganizerRemoved(); taskFragment2.setTaskFragmentOrganizer(mOrganizerToken, 10 /* uid */, Loading @@ -758,14 +758,14 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase { // Not allowed because mTaskFragment is not organized by the caller organizer. assertApplyTransactionDisallowed(mTransaction); assertNull(mTaskFragment.getAdjacentTaskFragment()); assertNull(taskFragment2.getAdjacentTaskFragment()); assertFalse(mTaskFragment.hasAdjacentTaskFragment()); assertFalse(taskFragment2.hasAdjacentTaskFragment()); mTaskFragment.setTaskFragmentOrganizer(mOrganizerToken, 10 /* uid */, "Test:TaskFragmentOrganizer" /* processName */); assertApplyTransactionAllowed(mTransaction); assertEquals(taskFragment2, mTaskFragment.getAdjacentTaskFragment()); assertTrue(mTaskFragment.isAdjacentTo(taskFragment2)); } @Test Loading @@ -790,14 +790,14 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase { // Not allowed because TaskFragment is not organized by the caller organizer. assertApplyTransactionDisallowed(mTransaction); assertEquals(taskFragment2, mTaskFragment.getAdjacentTaskFragment()); assertTrue(mTaskFragment.isAdjacentTo(taskFragment2)); mTaskFragment.setTaskFragmentOrganizer(mOrganizerToken, 10 /* uid */, "Test:TaskFragmentOrganizer" /* processName */); assertApplyTransactionAllowed(mTransaction); assertNull(mTaskFragment.getAdjacentTaskFragment()); assertNull(taskFragment2.getAdjacentTaskFragment()); assertFalse(mTaskFragment.hasAdjacentTaskFragment()); assertFalse(taskFragment2.hasAdjacentTaskFragment()); } @Test Loading Loading
services/core/java/com/android/server/wm/ActivityRecord.java +29 −12 Original line number Diff line number Diff line Loading @@ -3898,6 +3898,12 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A final TaskFragment taskFragment = getTaskFragment(); if (next != null && taskFragment != null && taskFragment.isEmbedded()) { final TaskFragment organized = taskFragment.getOrganizedTaskFragment(); if (Flags.allowMultipleAdjacentTaskFragments()) { delayRemoval = organized != null && organized.topRunningActivity() == null && organized.isDelayLastActivityRemoval() && organized.forOtherAdjacentTaskFragments(next::isDescendantOf); } else { final TaskFragment adjacent = organized != null ? organized.getAdjacentTaskFragment() : null; if (adjacent != null && next.isDescendantOf(adjacent) Loading @@ -3905,6 +3911,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A delayRemoval = organized.isDelayLastActivityRemoval(); } } } // isNextNotYetVisible is to check if the next activity is invisible, or it has been // requested to be invisible but its windows haven't reported as invisible. If so, it Loading Loading @@ -4880,15 +4887,25 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A * @see #canShowWhenLocked(ActivityRecord) */ boolean canShowWhenLocked() { if (!canShowWhenLocked(this)) { return false; } final TaskFragment taskFragment = getTaskFragment(); if (taskFragment != null && taskFragment.getAdjacentTaskFragment() != null && taskFragment.isEmbedded()) { final TaskFragment adjacentTaskFragment = taskFragment.getAdjacentTaskFragment(); final ActivityRecord r = adjacentTaskFragment.getTopNonFinishingActivity(); return canShowWhenLocked(this) && canShowWhenLocked(r); } else { return canShowWhenLocked(this); if (taskFragment == null || !taskFragment.hasAdjacentTaskFragment() || !taskFragment.isEmbedded()) { // No embedded adjacent that need to be checked. return true; } // Make sure the embedded adjacent can also be shown. if (!Flags.allowMultipleAdjacentTaskFragments()) { final ActivityRecord adjacentActivity = taskFragment.getAdjacentTaskFragment() .getTopNonFinishingActivity(); return canShowWhenLocked(adjacentActivity); } final boolean hasAdjacentNotAllowToShow = taskFragment.forOtherAdjacentTaskFragments( adjacentTF -> !canShowWhenLocked(adjacentTF.getTopNonFinishingActivity())); return !hasAdjacentNotAllowToShow; } /** Loading
services/core/java/com/android/server/wm/Task.java +15 −4 Original line number Diff line number Diff line Loading @@ -3707,12 +3707,23 @@ class Task extends TaskFragment { // Boost the adjacent TaskFragment for dimmer if needed. final TaskFragment taskFragment = wc.asTaskFragment(); if (taskFragment != null && taskFragment.isEmbedded()) { if (taskFragment != null && taskFragment.isEmbedded() && taskFragment.hasAdjacentTaskFragment()) { if (Flags.allowMultipleAdjacentTaskFragments()) { final int[] nextLayer = { layer }; taskFragment.forOtherAdjacentTaskFragments(adjacentTf -> { if (adjacentTf.shouldBoostDimmer()) { adjacentTf.assignLayer(t, nextLayer[0]++); } }); layer = nextLayer[0]; } else { final TaskFragment adjacentTf = taskFragment.getAdjacentTaskFragment(); if (adjacentTf != null && adjacentTf.shouldBoostDimmer()) { if (adjacentTf.shouldBoostDimmer()) { adjacentTf.assignLayer(t, layer++); } } } // Place the decor surface just above the owner TaskFragment. if (mDecorSurfaceContainer != null Loading
services/core/java/com/android/server/wm/TaskDisplayArea.java +1 −1 Original line number Diff line number Diff line Loading @@ -1045,7 +1045,7 @@ final class TaskDisplayArea extends DisplayArea<WindowContainer> { + adjacentFlagRootTask); } if (adjacentFlagRootTask.getAdjacentTaskFragment() == null) { if (!adjacentFlagRootTask.hasAdjacentTaskFragment()) { throw new UnsupportedOperationException( "Can't set non-adjacent root as launch adjacent flag root tr=" + adjacentFlagRootTask); Loading
services/core/java/com/android/server/wm/Transition.java +7 −6 Original line number Diff line number Diff line Loading @@ -2542,15 +2542,16 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener { // TaskFragment doesn't contain occluded ActivityRecord. return true; } final TaskFragment adjacentTaskFragment = taskFragment.getAdjacentTaskFragment(); if (adjacentTaskFragment != null) { // When the TaskFragment has an adjacent TaskFragment, sibling behind them should be // hidden unless any of them are translucent. return adjacentTaskFragment.isTranslucentForTransition(); } else { if (!taskFragment.hasAdjacentTaskFragment()) { // Non-filling without adjacent is considered as translucent. return !wc.fillsParent(); } // When the TaskFragment has an adjacent TaskFragment, sibling behind them should be // hidden unless any of them are translucent. if (!Flags.allowMultipleAdjacentTaskFragments()) { return taskFragment.getAdjacentTaskFragment().isTranslucentForTransition(); } return taskFragment.forOtherAdjacentTaskFragments(TaskFragment::isTranslucentForTransition); } private void updatePriorVisibility() { Loading
services/tests/wmtests/src/com/android/server/wm/TaskFragmentOrganizerControllerTest.java +10 −10 Original line number Diff line number Diff line Loading @@ -741,16 +741,16 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase { // Not allowed because TaskFragments are not organized by the caller organizer. assertApplyTransactionDisallowed(mTransaction); assertNull(mTaskFragment.getAdjacentTaskFragment()); assertNull(taskFragment2.getAdjacentTaskFragment()); assertFalse(mTaskFragment.hasAdjacentTaskFragment()); assertFalse(taskFragment2.hasAdjacentTaskFragment()); mTaskFragment.setTaskFragmentOrganizer(mOrganizerToken, 10 /* uid */, "Test:TaskFragmentOrganizer" /* processName */); // Not allowed because TaskFragment2 is not organized by the caller organizer. assertApplyTransactionDisallowed(mTransaction); assertNull(mTaskFragment.getAdjacentTaskFragment()); assertNull(taskFragment2.getAdjacentTaskFragment()); assertFalse(mTaskFragment.hasAdjacentTaskFragment()); assertFalse(taskFragment2.hasAdjacentTaskFragment()); mTaskFragment.onTaskFragmentOrganizerRemoved(); taskFragment2.setTaskFragmentOrganizer(mOrganizerToken, 10 /* uid */, Loading @@ -758,14 +758,14 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase { // Not allowed because mTaskFragment is not organized by the caller organizer. assertApplyTransactionDisallowed(mTransaction); assertNull(mTaskFragment.getAdjacentTaskFragment()); assertNull(taskFragment2.getAdjacentTaskFragment()); assertFalse(mTaskFragment.hasAdjacentTaskFragment()); assertFalse(taskFragment2.hasAdjacentTaskFragment()); mTaskFragment.setTaskFragmentOrganizer(mOrganizerToken, 10 /* uid */, "Test:TaskFragmentOrganizer" /* processName */); assertApplyTransactionAllowed(mTransaction); assertEquals(taskFragment2, mTaskFragment.getAdjacentTaskFragment()); assertTrue(mTaskFragment.isAdjacentTo(taskFragment2)); } @Test Loading @@ -790,14 +790,14 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase { // Not allowed because TaskFragment is not organized by the caller organizer. assertApplyTransactionDisallowed(mTransaction); assertEquals(taskFragment2, mTaskFragment.getAdjacentTaskFragment()); assertTrue(mTaskFragment.isAdjacentTo(taskFragment2)); mTaskFragment.setTaskFragmentOrganizer(mOrganizerToken, 10 /* uid */, "Test:TaskFragmentOrganizer" /* processName */); assertApplyTransactionAllowed(mTransaction); assertNull(mTaskFragment.getAdjacentTaskFragment()); assertNull(taskFragment2.getAdjacentTaskFragment()); assertFalse(mTaskFragment.hasAdjacentTaskFragment()); assertFalse(taskFragment2.hasAdjacentTaskFragment()); } @Test Loading