Loading services/core/java/com/android/server/wm/TaskFragment.java +23 −14 Original line number Diff line number Diff line Loading @@ -904,37 +904,46 @@ class TaskFragment extends WindowContainer<WindowContainer> { * starting (about to be visible) activity that is fullscreen (opaque). * @param starting The currently starting activity or null if there is none. */ @VisibleForTesting boolean isTranslucent(ActivityRecord starting) { boolean isTranslucent(@Nullable ActivityRecord starting) { if (!isAttached() || isForceHidden() || isForceTranslucent()) { return true; } final PooledPredicate p = PooledLambda.obtainPredicate(TaskFragment::isOpaqueActivity, PooledLambda.__(ActivityRecord.class), starting); PooledLambda.__(ActivityRecord.class), starting, false /* including*/); final ActivityRecord opaque = getActivity(p); p.recycle(); return opaque == null; } private static boolean isOpaqueActivity(ActivityRecord r, ActivityRecord starting) { if (r.finishing) { // We don't factor in finishing activities when determining translucency since // they will be gone soon. return false; /** * Whether the TaskFragment should be treated as translucent for the current transition. * This is different from {@link #isTranslucent(ActivityRecord)} as this function also checks * finishing activities when the TaskFragment itself is becoming invisible. */ boolean isTranslucentForTransition() { if (!isAttached() || isForceHidden() || isForceTranslucent()) { return true; } // Including finishing Activity if the TaskFragment is becoming invisible in the transition. final boolean includingFinishing = !isVisibleRequested(); final PooledPredicate p = PooledLambda.obtainPredicate(TaskFragment::isOpaqueActivity, PooledLambda.__(ActivityRecord.class), null /* starting */, includingFinishing); final ActivityRecord opaque = getActivity(p); p.recycle(); return opaque == null; } private static boolean isOpaqueActivity(@NonNull ActivityRecord r, @Nullable ActivityRecord starting, boolean includingFinishing) { if (!r.visibleIgnoringKeyguard && r != starting) { // Also ignore invisible activities that are not the currently starting // activity (about to be visible). return false; } if (r.occludesParent()) { // Root task isn't translucent if it has at least one fullscreen activity // that is visible. return true; } return false; // TaskFragment isn't translucent if it has at least one fullscreen activity that is // visible. return r.occludesParent(includingFinishing); } ActivityRecord getTopNonFinishingActivity() { Loading services/core/java/com/android/server/wm/Transition.java +18 −15 Original line number Diff line number Diff line Loading @@ -1447,23 +1447,26 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener { private static boolean isTranslucent(@NonNull WindowContainer wc) { final TaskFragment taskFragment = wc.asTaskFragment(); if (taskFragment != null) { if (taskFragment.isTranslucent(null /* starting */)) { if (taskFragment == null) { return !wc.fillsParent(); } // Check containers differently as they are affected by child visibility. if (taskFragment.isTranslucentForTransition()) { // TaskFragment doesn't contain occluded ActivityRecord. return true; } final TaskFragment adjacentTaskFragment = taskFragment.getAdjacentTaskFragment(); if (adjacentTaskFragment != null) { // Treat the TaskFragment as translucent if its adjacent TF is, otherwise everything // behind two adjacent TaskFragments are occluded. return adjacentTaskFragment.isTranslucent(null /* starting */); } } // TODO(b/172695805): hierarchical check. This is non-trivial because for containers // it is effected by child visibility but needs to work even // before visibility is committed. This means refactoring some // checks to use requested visibility. // When the TaskFragment has an adjacent TaskFragment, sibling behind them should be // hidden unless any of them are translucent. return adjacentTaskFragment.isTranslucentForTransition(); } else { // Non-filling without adjacent is considered as translucent. return !wc.fillsParent(); } } /** * Under some conditions (eg. all visible targets within a parent container are transitioning Loading services/tests/wmtests/src/com/android/server/wm/TransitionTests.java +189 −11 Original line number Diff line number Diff line Loading @@ -704,15 +704,15 @@ public class TransitionTests extends WindowTestsBase { ArrayMap<WindowContainer, Transition.ChangeInfo> changes = transition.mChanges; ArraySet<WindowContainer> participants = transition.mParticipants; final Task newTask = createTask(mDisplayContent); doReturn(false).when(newTask).isTranslucent(any()); final Task oldTask = createTask(mDisplayContent); doReturn(false).when(oldTask).isTranslucent(any()); final Task newTask = createTask(mDisplayContent); final ActivityRecord closing = createActivityRecord(oldTask); closing.setOccludesParent(true); closing.visibleIgnoringKeyguard = true; final ActivityRecord opening = createActivityRecord(newTask); opening.setOccludesParent(false); opening.setOccludesParent(true); opening.visibleIgnoringKeyguard = true; // Start states. changes.put(newTask, new Transition.ChangeInfo(newTask, false /* vis */, true /* exChg */)); changes.put(oldTask, new Transition.ChangeInfo(oldTask, true /* vis */, false /* exChg */)); Loading @@ -735,8 +735,8 @@ public class TransitionTests extends WindowTestsBase { assertEquals(2, info.getChanges().size()); assertEquals(transit, info.getType()); assertTrue((info.getChanges().get(0).getFlags() & FLAG_TRANSLUCENT) == 0); assertTrue((info.getChanges().get(1).getFlags() & FLAG_TRANSLUCENT) == 0); assertFalse(info.getChanges().get(0).hasFlags(FLAG_TRANSLUCENT)); assertFalse(info.getChanges().get(1).hasFlags(FLAG_TRANSLUCENT)); } @Test Loading @@ -745,15 +745,15 @@ public class TransitionTests extends WindowTestsBase { ArrayMap<WindowContainer, Transition.ChangeInfo> changes = transition.mChanges; ArraySet<WindowContainer> participants = transition.mParticipants; final Task newTask = createTask(mDisplayContent); doReturn(true).when(newTask).isTranslucent(any()); final Task oldTask = createTask(mDisplayContent); doReturn(false).when(oldTask).isTranslucent(any()); final Task newTask = createTask(mDisplayContent); final ActivityRecord closing = createActivityRecord(oldTask); closing.setOccludesParent(true); closing.visibleIgnoringKeyguard = true; final ActivityRecord opening = createActivityRecord(newTask); opening.setOccludesParent(false); opening.visibleIgnoringKeyguard = true; // Start states. changes.put(newTask, new Transition.ChangeInfo(newTask, false /* vis */, true /* exChg */)); changes.put(oldTask, new Transition.ChangeInfo(oldTask, true /* vis */, false /* exChg */)); Loading @@ -776,8 +776,186 @@ public class TransitionTests extends WindowTestsBase { assertEquals(2, info.getChanges().size()); assertEquals(transit, info.getType()); assertTrue((info.getChanges().get(0).getFlags() & FLAG_TRANSLUCENT) != 0); assertTrue((info.getChanges().get(1).getFlags() & FLAG_TRANSLUCENT) == 0); assertTrue(info.getChanges().get(0).hasFlags(FLAG_TRANSLUCENT)); assertFalse(info.getChanges().get(1).hasFlags(FLAG_TRANSLUCENT)); } @Test public void testOpenOpaqueTaskFragment() { final Transition transition = createTestTransition(TRANSIT_OPEN); ArrayMap<WindowContainer, Transition.ChangeInfo> changes = transition.mChanges; ArraySet<WindowContainer> participants = transition.mParticipants; final Task task = createTask(mDisplayContent); final TaskFragment closingTaskFragment = createTaskFragmentWithActivity(task); final TaskFragment openingTaskFragment = createTaskFragmentWithActivity(task); final ActivityRecord closing = closingTaskFragment.getTopMostActivity(); closing.setOccludesParent(true); closing.visibleIgnoringKeyguard = true; final ActivityRecord opening = openingTaskFragment.getTopMostActivity(); opening.setOccludesParent(true); opening.visibleIgnoringKeyguard = true; // Start states. changes.put(openingTaskFragment, new Transition.ChangeInfo(openingTaskFragment, false /* vis */, true /* exChg */)); changes.put(closingTaskFragment, new Transition.ChangeInfo(closingTaskFragment, true /* vis */, false /* exChg */)); changes.put(opening, new Transition.ChangeInfo(opening, false /* vis */, true /* exChg */)); changes.put(closing, new Transition.ChangeInfo(closing, true /* vis */, false /* exChg */)); fillChangeMap(changes, openingTaskFragment); // End states. closing.setVisibleRequested(false); opening.setVisibleRequested(true); final int transit = transition.mType; int flags = 0; // Check basic both tasks participating participants.add(closingTaskFragment); participants.add(openingTaskFragment); ArrayList<Transition.ChangeInfo> targets = Transition.calculateTargets(participants, changes); TransitionInfo info = Transition.calculateTransitionInfo(transit, flags, targets, mMockT); assertEquals(2, info.getChanges().size()); assertEquals(transit, info.getType()); assertFalse(info.getChanges().get(0).hasFlags(FLAG_TRANSLUCENT)); assertFalse(info.getChanges().get(1).hasFlags(FLAG_TRANSLUCENT)); } @Test public void testOpenTranslucentTaskFragment() { final Transition transition = createTestTransition(TRANSIT_OPEN); ArrayMap<WindowContainer, Transition.ChangeInfo> changes = transition.mChanges; ArraySet<WindowContainer> participants = transition.mParticipants; final Task task = createTask(mDisplayContent); final TaskFragment closingTaskFragment = createTaskFragmentWithActivity(task); final TaskFragment openingTaskFragment = createTaskFragmentWithActivity(task); final ActivityRecord closing = closingTaskFragment.getTopMostActivity(); closing.setOccludesParent(true); closing.visibleIgnoringKeyguard = true; final ActivityRecord opening = openingTaskFragment.getTopMostActivity(); opening.setOccludesParent(false); opening.visibleIgnoringKeyguard = true; // Start states. changes.put(openingTaskFragment, new Transition.ChangeInfo(openingTaskFragment, false /* vis */, true /* exChg */)); changes.put(closingTaskFragment, new Transition.ChangeInfo(closingTaskFragment, true /* vis */, false /* exChg */)); changes.put(opening, new Transition.ChangeInfo(opening, false /* vis */, true /* exChg */)); changes.put(closing, new Transition.ChangeInfo(closing, true /* vis */, false /* exChg */)); fillChangeMap(changes, openingTaskFragment); // End states. closing.setVisibleRequested(false); opening.setVisibleRequested(true); final int transit = transition.mType; int flags = 0; // Check basic both tasks participating participants.add(closingTaskFragment); participants.add(openingTaskFragment); ArrayList<Transition.ChangeInfo> targets = Transition.calculateTargets(participants, changes); TransitionInfo info = Transition.calculateTransitionInfo(transit, flags, targets, mMockT); assertEquals(2, info.getChanges().size()); assertEquals(transit, info.getType()); assertTrue(info.getChanges().get(0).hasFlags(FLAG_TRANSLUCENT)); assertFalse(info.getChanges().get(1).hasFlags(FLAG_TRANSLUCENT)); } @Test public void testCloseOpaqueTaskFragment_withFinishingActivity() { final Transition transition = createTestTransition(TRANSIT_CLOSE); ArrayMap<WindowContainer, Transition.ChangeInfo> changes = transition.mChanges; ArraySet<WindowContainer> participants = transition.mParticipants; final Task task = createTask(mDisplayContent); final TaskFragment openingTaskFragment = createTaskFragmentWithActivity(task); final TaskFragment closingTaskFragment = createTaskFragmentWithActivity(task); final ActivityRecord opening = openingTaskFragment.getTopMostActivity(); opening.setOccludesParent(true); opening.visibleIgnoringKeyguard = true; final ActivityRecord closing = closingTaskFragment.getTopMostActivity(); closing.setOccludesParent(true); closing.visibleIgnoringKeyguard = true; closing.finishing = true; // Start states. changes.put(openingTaskFragment, new Transition.ChangeInfo(openingTaskFragment, false /* vis */, true /* exChg */)); changes.put(closingTaskFragment, new Transition.ChangeInfo(closingTaskFragment, true /* vis */, false /* exChg */)); changes.put(opening, new Transition.ChangeInfo(opening, false /* vis */, true /* exChg */)); changes.put(closing, new Transition.ChangeInfo(closing, true /* vis */, false /* exChg */)); fillChangeMap(changes, openingTaskFragment); // End states. closing.setVisibleRequested(false); opening.setVisibleRequested(true); final int transit = transition.mType; int flags = 0; // Check basic both tasks participating participants.add(closingTaskFragment); participants.add(openingTaskFragment); ArrayList<Transition.ChangeInfo> targets = Transition.calculateTargets(participants, changes); TransitionInfo info = Transition.calculateTransitionInfo(transit, flags, targets, mMockT); assertEquals(2, info.getChanges().size()); assertEquals(transit, info.getType()); assertFalse(info.getChanges().get(0).hasFlags(FLAG_TRANSLUCENT)); assertFalse(info.getChanges().get(1).hasFlags(FLAG_TRANSLUCENT)); } @Test public void testCloseTranslucentTaskFragment_withFinishingActivity() { final Transition transition = createTestTransition(TRANSIT_CLOSE); ArrayMap<WindowContainer, Transition.ChangeInfo> changes = transition.mChanges; ArraySet<WindowContainer> participants = transition.mParticipants; final Task task = createTask(mDisplayContent); final TaskFragment openingTaskFragment = createTaskFragmentWithActivity(task); final TaskFragment closingTaskFragment = createTaskFragmentWithActivity(task); final ActivityRecord opening = openingTaskFragment.getTopMostActivity(); opening.setOccludesParent(true); opening.visibleIgnoringKeyguard = true; final ActivityRecord closing = closingTaskFragment.getTopMostActivity(); closing.setOccludesParent(false); closing.visibleIgnoringKeyguard = true; closing.finishing = true; // Start states. changes.put(openingTaskFragment, new Transition.ChangeInfo(openingTaskFragment, false /* vis */, true /* exChg */)); changes.put(closingTaskFragment, new Transition.ChangeInfo(closingTaskFragment, true /* vis */, false /* exChg */)); changes.put(opening, new Transition.ChangeInfo(opening, false /* vis */, true /* exChg */)); changes.put(closing, new Transition.ChangeInfo(closing, true /* vis */, false /* exChg */)); fillChangeMap(changes, openingTaskFragment); // End states. closing.setVisibleRequested(false); opening.setVisibleRequested(true); final int transit = transition.mType; int flags = 0; // Check basic both tasks participating participants.add(closingTaskFragment); participants.add(openingTaskFragment); ArrayList<Transition.ChangeInfo> targets = Transition.calculateTargets(participants, changes); TransitionInfo info = Transition.calculateTransitionInfo(transit, flags, targets, mMockT); assertEquals(2, info.getChanges().size()); assertEquals(transit, info.getType()); assertTrue(info.getChanges().get(0).hasFlags(FLAG_TRANSLUCENT)); assertFalse(info.getChanges().get(1).hasFlags(FLAG_TRANSLUCENT)); } @Test Loading Loading
services/core/java/com/android/server/wm/TaskFragment.java +23 −14 Original line number Diff line number Diff line Loading @@ -904,37 +904,46 @@ class TaskFragment extends WindowContainer<WindowContainer> { * starting (about to be visible) activity that is fullscreen (opaque). * @param starting The currently starting activity or null if there is none. */ @VisibleForTesting boolean isTranslucent(ActivityRecord starting) { boolean isTranslucent(@Nullable ActivityRecord starting) { if (!isAttached() || isForceHidden() || isForceTranslucent()) { return true; } final PooledPredicate p = PooledLambda.obtainPredicate(TaskFragment::isOpaqueActivity, PooledLambda.__(ActivityRecord.class), starting); PooledLambda.__(ActivityRecord.class), starting, false /* including*/); final ActivityRecord opaque = getActivity(p); p.recycle(); return opaque == null; } private static boolean isOpaqueActivity(ActivityRecord r, ActivityRecord starting) { if (r.finishing) { // We don't factor in finishing activities when determining translucency since // they will be gone soon. return false; /** * Whether the TaskFragment should be treated as translucent for the current transition. * This is different from {@link #isTranslucent(ActivityRecord)} as this function also checks * finishing activities when the TaskFragment itself is becoming invisible. */ boolean isTranslucentForTransition() { if (!isAttached() || isForceHidden() || isForceTranslucent()) { return true; } // Including finishing Activity if the TaskFragment is becoming invisible in the transition. final boolean includingFinishing = !isVisibleRequested(); final PooledPredicate p = PooledLambda.obtainPredicate(TaskFragment::isOpaqueActivity, PooledLambda.__(ActivityRecord.class), null /* starting */, includingFinishing); final ActivityRecord opaque = getActivity(p); p.recycle(); return opaque == null; } private static boolean isOpaqueActivity(@NonNull ActivityRecord r, @Nullable ActivityRecord starting, boolean includingFinishing) { if (!r.visibleIgnoringKeyguard && r != starting) { // Also ignore invisible activities that are not the currently starting // activity (about to be visible). return false; } if (r.occludesParent()) { // Root task isn't translucent if it has at least one fullscreen activity // that is visible. return true; } return false; // TaskFragment isn't translucent if it has at least one fullscreen activity that is // visible. return r.occludesParent(includingFinishing); } ActivityRecord getTopNonFinishingActivity() { Loading
services/core/java/com/android/server/wm/Transition.java +18 −15 Original line number Diff line number Diff line Loading @@ -1447,23 +1447,26 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener { private static boolean isTranslucent(@NonNull WindowContainer wc) { final TaskFragment taskFragment = wc.asTaskFragment(); if (taskFragment != null) { if (taskFragment.isTranslucent(null /* starting */)) { if (taskFragment == null) { return !wc.fillsParent(); } // Check containers differently as they are affected by child visibility. if (taskFragment.isTranslucentForTransition()) { // TaskFragment doesn't contain occluded ActivityRecord. return true; } final TaskFragment adjacentTaskFragment = taskFragment.getAdjacentTaskFragment(); if (adjacentTaskFragment != null) { // Treat the TaskFragment as translucent if its adjacent TF is, otherwise everything // behind two adjacent TaskFragments are occluded. return adjacentTaskFragment.isTranslucent(null /* starting */); } } // TODO(b/172695805): hierarchical check. This is non-trivial because for containers // it is effected by child visibility but needs to work even // before visibility is committed. This means refactoring some // checks to use requested visibility. // When the TaskFragment has an adjacent TaskFragment, sibling behind them should be // hidden unless any of them are translucent. return adjacentTaskFragment.isTranslucentForTransition(); } else { // Non-filling without adjacent is considered as translucent. return !wc.fillsParent(); } } /** * Under some conditions (eg. all visible targets within a parent container are transitioning Loading
services/tests/wmtests/src/com/android/server/wm/TransitionTests.java +189 −11 Original line number Diff line number Diff line Loading @@ -704,15 +704,15 @@ public class TransitionTests extends WindowTestsBase { ArrayMap<WindowContainer, Transition.ChangeInfo> changes = transition.mChanges; ArraySet<WindowContainer> participants = transition.mParticipants; final Task newTask = createTask(mDisplayContent); doReturn(false).when(newTask).isTranslucent(any()); final Task oldTask = createTask(mDisplayContent); doReturn(false).when(oldTask).isTranslucent(any()); final Task newTask = createTask(mDisplayContent); final ActivityRecord closing = createActivityRecord(oldTask); closing.setOccludesParent(true); closing.visibleIgnoringKeyguard = true; final ActivityRecord opening = createActivityRecord(newTask); opening.setOccludesParent(false); opening.setOccludesParent(true); opening.visibleIgnoringKeyguard = true; // Start states. changes.put(newTask, new Transition.ChangeInfo(newTask, false /* vis */, true /* exChg */)); changes.put(oldTask, new Transition.ChangeInfo(oldTask, true /* vis */, false /* exChg */)); Loading @@ -735,8 +735,8 @@ public class TransitionTests extends WindowTestsBase { assertEquals(2, info.getChanges().size()); assertEquals(transit, info.getType()); assertTrue((info.getChanges().get(0).getFlags() & FLAG_TRANSLUCENT) == 0); assertTrue((info.getChanges().get(1).getFlags() & FLAG_TRANSLUCENT) == 0); assertFalse(info.getChanges().get(0).hasFlags(FLAG_TRANSLUCENT)); assertFalse(info.getChanges().get(1).hasFlags(FLAG_TRANSLUCENT)); } @Test Loading @@ -745,15 +745,15 @@ public class TransitionTests extends WindowTestsBase { ArrayMap<WindowContainer, Transition.ChangeInfo> changes = transition.mChanges; ArraySet<WindowContainer> participants = transition.mParticipants; final Task newTask = createTask(mDisplayContent); doReturn(true).when(newTask).isTranslucent(any()); final Task oldTask = createTask(mDisplayContent); doReturn(false).when(oldTask).isTranslucent(any()); final Task newTask = createTask(mDisplayContent); final ActivityRecord closing = createActivityRecord(oldTask); closing.setOccludesParent(true); closing.visibleIgnoringKeyguard = true; final ActivityRecord opening = createActivityRecord(newTask); opening.setOccludesParent(false); opening.visibleIgnoringKeyguard = true; // Start states. changes.put(newTask, new Transition.ChangeInfo(newTask, false /* vis */, true /* exChg */)); changes.put(oldTask, new Transition.ChangeInfo(oldTask, true /* vis */, false /* exChg */)); Loading @@ -776,8 +776,186 @@ public class TransitionTests extends WindowTestsBase { assertEquals(2, info.getChanges().size()); assertEquals(transit, info.getType()); assertTrue((info.getChanges().get(0).getFlags() & FLAG_TRANSLUCENT) != 0); assertTrue((info.getChanges().get(1).getFlags() & FLAG_TRANSLUCENT) == 0); assertTrue(info.getChanges().get(0).hasFlags(FLAG_TRANSLUCENT)); assertFalse(info.getChanges().get(1).hasFlags(FLAG_TRANSLUCENT)); } @Test public void testOpenOpaqueTaskFragment() { final Transition transition = createTestTransition(TRANSIT_OPEN); ArrayMap<WindowContainer, Transition.ChangeInfo> changes = transition.mChanges; ArraySet<WindowContainer> participants = transition.mParticipants; final Task task = createTask(mDisplayContent); final TaskFragment closingTaskFragment = createTaskFragmentWithActivity(task); final TaskFragment openingTaskFragment = createTaskFragmentWithActivity(task); final ActivityRecord closing = closingTaskFragment.getTopMostActivity(); closing.setOccludesParent(true); closing.visibleIgnoringKeyguard = true; final ActivityRecord opening = openingTaskFragment.getTopMostActivity(); opening.setOccludesParent(true); opening.visibleIgnoringKeyguard = true; // Start states. changes.put(openingTaskFragment, new Transition.ChangeInfo(openingTaskFragment, false /* vis */, true /* exChg */)); changes.put(closingTaskFragment, new Transition.ChangeInfo(closingTaskFragment, true /* vis */, false /* exChg */)); changes.put(opening, new Transition.ChangeInfo(opening, false /* vis */, true /* exChg */)); changes.put(closing, new Transition.ChangeInfo(closing, true /* vis */, false /* exChg */)); fillChangeMap(changes, openingTaskFragment); // End states. closing.setVisibleRequested(false); opening.setVisibleRequested(true); final int transit = transition.mType; int flags = 0; // Check basic both tasks participating participants.add(closingTaskFragment); participants.add(openingTaskFragment); ArrayList<Transition.ChangeInfo> targets = Transition.calculateTargets(participants, changes); TransitionInfo info = Transition.calculateTransitionInfo(transit, flags, targets, mMockT); assertEquals(2, info.getChanges().size()); assertEquals(transit, info.getType()); assertFalse(info.getChanges().get(0).hasFlags(FLAG_TRANSLUCENT)); assertFalse(info.getChanges().get(1).hasFlags(FLAG_TRANSLUCENT)); } @Test public void testOpenTranslucentTaskFragment() { final Transition transition = createTestTransition(TRANSIT_OPEN); ArrayMap<WindowContainer, Transition.ChangeInfo> changes = transition.mChanges; ArraySet<WindowContainer> participants = transition.mParticipants; final Task task = createTask(mDisplayContent); final TaskFragment closingTaskFragment = createTaskFragmentWithActivity(task); final TaskFragment openingTaskFragment = createTaskFragmentWithActivity(task); final ActivityRecord closing = closingTaskFragment.getTopMostActivity(); closing.setOccludesParent(true); closing.visibleIgnoringKeyguard = true; final ActivityRecord opening = openingTaskFragment.getTopMostActivity(); opening.setOccludesParent(false); opening.visibleIgnoringKeyguard = true; // Start states. changes.put(openingTaskFragment, new Transition.ChangeInfo(openingTaskFragment, false /* vis */, true /* exChg */)); changes.put(closingTaskFragment, new Transition.ChangeInfo(closingTaskFragment, true /* vis */, false /* exChg */)); changes.put(opening, new Transition.ChangeInfo(opening, false /* vis */, true /* exChg */)); changes.put(closing, new Transition.ChangeInfo(closing, true /* vis */, false /* exChg */)); fillChangeMap(changes, openingTaskFragment); // End states. closing.setVisibleRequested(false); opening.setVisibleRequested(true); final int transit = transition.mType; int flags = 0; // Check basic both tasks participating participants.add(closingTaskFragment); participants.add(openingTaskFragment); ArrayList<Transition.ChangeInfo> targets = Transition.calculateTargets(participants, changes); TransitionInfo info = Transition.calculateTransitionInfo(transit, flags, targets, mMockT); assertEquals(2, info.getChanges().size()); assertEquals(transit, info.getType()); assertTrue(info.getChanges().get(0).hasFlags(FLAG_TRANSLUCENT)); assertFalse(info.getChanges().get(1).hasFlags(FLAG_TRANSLUCENT)); } @Test public void testCloseOpaqueTaskFragment_withFinishingActivity() { final Transition transition = createTestTransition(TRANSIT_CLOSE); ArrayMap<WindowContainer, Transition.ChangeInfo> changes = transition.mChanges; ArraySet<WindowContainer> participants = transition.mParticipants; final Task task = createTask(mDisplayContent); final TaskFragment openingTaskFragment = createTaskFragmentWithActivity(task); final TaskFragment closingTaskFragment = createTaskFragmentWithActivity(task); final ActivityRecord opening = openingTaskFragment.getTopMostActivity(); opening.setOccludesParent(true); opening.visibleIgnoringKeyguard = true; final ActivityRecord closing = closingTaskFragment.getTopMostActivity(); closing.setOccludesParent(true); closing.visibleIgnoringKeyguard = true; closing.finishing = true; // Start states. changes.put(openingTaskFragment, new Transition.ChangeInfo(openingTaskFragment, false /* vis */, true /* exChg */)); changes.put(closingTaskFragment, new Transition.ChangeInfo(closingTaskFragment, true /* vis */, false /* exChg */)); changes.put(opening, new Transition.ChangeInfo(opening, false /* vis */, true /* exChg */)); changes.put(closing, new Transition.ChangeInfo(closing, true /* vis */, false /* exChg */)); fillChangeMap(changes, openingTaskFragment); // End states. closing.setVisibleRequested(false); opening.setVisibleRequested(true); final int transit = transition.mType; int flags = 0; // Check basic both tasks participating participants.add(closingTaskFragment); participants.add(openingTaskFragment); ArrayList<Transition.ChangeInfo> targets = Transition.calculateTargets(participants, changes); TransitionInfo info = Transition.calculateTransitionInfo(transit, flags, targets, mMockT); assertEquals(2, info.getChanges().size()); assertEquals(transit, info.getType()); assertFalse(info.getChanges().get(0).hasFlags(FLAG_TRANSLUCENT)); assertFalse(info.getChanges().get(1).hasFlags(FLAG_TRANSLUCENT)); } @Test public void testCloseTranslucentTaskFragment_withFinishingActivity() { final Transition transition = createTestTransition(TRANSIT_CLOSE); ArrayMap<WindowContainer, Transition.ChangeInfo> changes = transition.mChanges; ArraySet<WindowContainer> participants = transition.mParticipants; final Task task = createTask(mDisplayContent); final TaskFragment openingTaskFragment = createTaskFragmentWithActivity(task); final TaskFragment closingTaskFragment = createTaskFragmentWithActivity(task); final ActivityRecord opening = openingTaskFragment.getTopMostActivity(); opening.setOccludesParent(true); opening.visibleIgnoringKeyguard = true; final ActivityRecord closing = closingTaskFragment.getTopMostActivity(); closing.setOccludesParent(false); closing.visibleIgnoringKeyguard = true; closing.finishing = true; // Start states. changes.put(openingTaskFragment, new Transition.ChangeInfo(openingTaskFragment, false /* vis */, true /* exChg */)); changes.put(closingTaskFragment, new Transition.ChangeInfo(closingTaskFragment, true /* vis */, false /* exChg */)); changes.put(opening, new Transition.ChangeInfo(opening, false /* vis */, true /* exChg */)); changes.put(closing, new Transition.ChangeInfo(closing, true /* vis */, false /* exChg */)); fillChangeMap(changes, openingTaskFragment); // End states. closing.setVisibleRequested(false); opening.setVisibleRequested(true); final int transit = transition.mType; int flags = 0; // Check basic both tasks participating participants.add(closingTaskFragment); participants.add(openingTaskFragment); ArrayList<Transition.ChangeInfo> targets = Transition.calculateTargets(participants, changes); TransitionInfo info = Transition.calculateTransitionInfo(transit, flags, targets, mMockT); assertEquals(2, info.getChanges().size()); assertEquals(transit, info.getType()); assertTrue(info.getChanges().get(0).hasFlags(FLAG_TRANSLUCENT)); assertFalse(info.getChanges().get(1).hasFlags(FLAG_TRANSLUCENT)); } @Test Loading