Loading services/core/java/com/android/server/wm/ActivityRecord.java +2 −14 Original line number Diff line number Diff line Loading @@ -3081,9 +3081,6 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A mAtmService.deferWindowLayout(); try { final Transition newTransition = (!mTransitionController.isCollecting() && mTransitionController.getTransitionPlayer() != null) ? mTransitionController.createTransition(TRANSIT_CLOSE) : null; mTaskSupervisor.mNoHistoryActivities.remove(this); makeFinishingLocked(); // Make a local reference to its task since this.task could be set to null once this Loading Loading @@ -3115,10 +3112,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A final boolean endTask = task.getTopNonFinishingActivity() == null && !task.isClearingToReuseTask(); if (newTransition != null) { mTransitionController.requestStartTransition(newTransition, endTask ? task : null, null /* remote */); } mTransitionController.requestCloseTransitionIfNeeded(endTask ? task : this); if (isState(RESUMED)) { if (endTask) { mAtmService.getTaskChangeNotificationController().notifyTaskRemovalStarted( Loading Loading @@ -3544,13 +3538,6 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A if (stopped) { abortAndClearOptionsAnimation(); } if (mTransitionController.isCollecting()) { // We don't want the finishing to change the transition ready state since there will not // be corresponding setReady for finishing. mTransitionController.collectExistenceChange(this); } else { mTransitionController.requestTransitionIfNeeded(TRANSIT_CLOSE, this); } } /** Loading Loading @@ -3732,6 +3719,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A // to the restarted activity. nowVisible = mVisibleRequested; } mTransitionController.requestCloseTransitionIfNeeded(this); cleanUp(true /* cleanServices */, true /* setState */); if (remove) { if (mStartingData != null && mVisible && task != null) { Loading services/core/java/com/android/server/wm/ActivityTaskSupervisor.java +1 −14 Original line number Diff line number Diff line Loading @@ -44,7 +44,6 @@ import static android.os.PowerManager.PARTIAL_WAKE_LOCK; import static android.os.Process.INVALID_UID; import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER; import static android.view.Display.DEFAULT_DISPLAY; import static android.view.WindowManager.TRANSIT_CLOSE; import static android.view.WindowManager.TRANSIT_TO_FRONT; import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_STATES; Loading Loading @@ -1562,19 +1561,7 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks { // Prevent recursion. return; } if (task.isVisible()) { if (task.mTransitionController.isCollecting()) { // We don't want the finishing to change the transition ready state since there will // not be corresponding setReady for finishing. task.mTransitionController.collectExistenceChange(task); } else { task.mTransitionController.requestTransitionIfNeeded(TRANSIT_CLOSE, task); } } else { // Removing a non-visible task doesn't require a transition, but if there is one // collecting, this should be a member just in case. task.mTransitionController.collect(task); } task.mTransitionController.requestCloseTransitionIfNeeded(task); task.mInRemoveTask = true; try { task.performClearTask(reason); Loading services/core/java/com/android/server/wm/Transition.java +5 −0 Original line number Diff line number Diff line Loading @@ -338,6 +338,11 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe applyReady(); } @VisibleForTesting boolean allReady() { return mReadyTracker.allReady(); } /** * Build a transaction that "resets" all the re-parenting and layer changes. This is * intended to be applied at the end of the transition but before the finish callback. This Loading services/core/java/com/android/server/wm/TransitionController.java +18 −3 Original line number Diff line number Diff line Loading @@ -35,7 +35,6 @@ import android.util.ArrayMap; import android.util.Slog; import android.util.proto.ProtoOutputStream; import android.view.WindowManager; import android.window.IRemoteTransition; import android.window.ITransitionMetricsReporter; import android.window.ITransitionPlayer; import android.window.RemoteTransition; Loading Loading @@ -226,7 +225,7 @@ class TransitionController { } /** * @see #requestTransitionIfNeeded(int, int, WindowContainer, IRemoteTransition) * @see #requestTransitionIfNeeded(int, int, WindowContainer, WindowContainer, RemoteTransition) */ @Nullable Transition requestTransitionIfNeeded(@WindowManager.TransitionType int type, Loading @@ -235,7 +234,7 @@ class TransitionController { } /** * @see #requestTransitionIfNeeded(int, int, WindowContainer, IRemoteTransition) * @see #requestTransitionIfNeeded(int, int, WindowContainer, WindowContainer, RemoteTransition) */ @Nullable Transition requestTransitionIfNeeded(@WindowManager.TransitionType int type, Loading Loading @@ -306,6 +305,22 @@ class TransitionController { return transition; } /** Requests transition for a window container which will be removed or invisible. */ void requestCloseTransitionIfNeeded(@NonNull WindowContainer<?> wc) { if (mTransitionPlayer == null) return; if (wc.isVisibleRequested()) { if (!isCollecting()) { requestStartTransition(createTransition(TRANSIT_CLOSE, 0 /* flags */), wc.asTask(), null /* remoteTransition */); } collectExistenceChange(wc); } else { // Removing a non-visible window doesn't require a transition, but if there is one // collecting, this should be a member just in case. collect(wc); } } /** @see Transition#collect */ void collect(@NonNull WindowContainer wc) { if (mCollectingTransition == null) return; Loading services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java +28 −5 Original line number Diff line number Diff line Loading @@ -166,6 +166,8 @@ public class ActivityRecordTests extends WindowTestsBase { @Before public void setUp() throws Exception { setBooted(mAtm); // Because the booted state is set, avoid starting real home if there is no task. doReturn(false).when(mRootWindowContainer).resumeHomeActivity(any(), anyString(), any()); } private TestStartingWindowOrganizer registerTestStartingWindowOrganizer() { Loading Loading @@ -1083,6 +1085,7 @@ public class ActivityRecordTests extends WindowTestsBase { */ @Test public void testFinishActivityIfPossible_nonVisibleNoAppTransition() { registerTestTransitionPlayer(); final ActivityRecord activity = createActivityWithTask(); // Put an activity on top of test activity to make it invisible and prevent us from // accidentally resuming the topmost one again. Loading @@ -1093,6 +1096,7 @@ public class ActivityRecordTests extends WindowTestsBase { activity.finishIfPossible("test", false /* oomAdj */); verify(activity.mDisplayContent, never()).prepareAppTransition(eq(TRANSIT_CLOSE)); assertFalse(activity.inTransition()); } /** Loading @@ -1101,11 +1105,7 @@ public class ActivityRecordTests extends WindowTestsBase { */ @Test public void testFinishActivityIfPossible_lastInTaskRequestsTransitionWithTrigger() { // Set-up mock shell transitions final TestTransitionPlayer testPlayer = new TestTransitionPlayer( mAtm.getTransitionController(), mAtm.mWindowOrganizerController); mAtm.getTransitionController().registerTransitionPlayer(testPlayer); final TestTransitionPlayer testPlayer = registerTestTransitionPlayer(); final ActivityRecord activity = createActivityWithTask(); activity.finishing = false; activity.mVisibleRequested = true; Loading @@ -1116,6 +1116,29 @@ public class ActivityRecordTests extends WindowTestsBase { assertEquals(activity.getTask().mTaskId, testPlayer.mLastRequest.getTriggerTask().taskId); } /** * Verify that when collecting activity to the existing close transition, it should not affect * ready state. */ @Test public void testFinishActivityIfPossible_collectToExistingTransition() { final TestTransitionPlayer testPlayer = registerTestTransitionPlayer(); final ActivityRecord activity = createActivityWithTask(); activity.setState(PAUSED, "test"); activity.finishIfPossible("test", false /* oomAdj */); final Transition lastTransition = testPlayer.mLastTransit; assertTrue(lastTransition.allReady()); assertTrue(activity.inTransition()); // Collect another activity to the existing transition without changing ready state. final ActivityRecord activity2 = createActivityRecord(activity.getTask()); activity2.setState(PAUSING, "test"); activity2.finishIfPossible("test", false /* oomAdj */); assertTrue(activity2.inTransition()); assertEquals(lastTransition, testPlayer.mLastTransit); assertTrue(lastTransition.allReady()); } /** * Verify that complete finish request for non-finishing activity is invalid. */ Loading Loading
services/core/java/com/android/server/wm/ActivityRecord.java +2 −14 Original line number Diff line number Diff line Loading @@ -3081,9 +3081,6 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A mAtmService.deferWindowLayout(); try { final Transition newTransition = (!mTransitionController.isCollecting() && mTransitionController.getTransitionPlayer() != null) ? mTransitionController.createTransition(TRANSIT_CLOSE) : null; mTaskSupervisor.mNoHistoryActivities.remove(this); makeFinishingLocked(); // Make a local reference to its task since this.task could be set to null once this Loading Loading @@ -3115,10 +3112,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A final boolean endTask = task.getTopNonFinishingActivity() == null && !task.isClearingToReuseTask(); if (newTransition != null) { mTransitionController.requestStartTransition(newTransition, endTask ? task : null, null /* remote */); } mTransitionController.requestCloseTransitionIfNeeded(endTask ? task : this); if (isState(RESUMED)) { if (endTask) { mAtmService.getTaskChangeNotificationController().notifyTaskRemovalStarted( Loading Loading @@ -3544,13 +3538,6 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A if (stopped) { abortAndClearOptionsAnimation(); } if (mTransitionController.isCollecting()) { // We don't want the finishing to change the transition ready state since there will not // be corresponding setReady for finishing. mTransitionController.collectExistenceChange(this); } else { mTransitionController.requestTransitionIfNeeded(TRANSIT_CLOSE, this); } } /** Loading Loading @@ -3732,6 +3719,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A // to the restarted activity. nowVisible = mVisibleRequested; } mTransitionController.requestCloseTransitionIfNeeded(this); cleanUp(true /* cleanServices */, true /* setState */); if (remove) { if (mStartingData != null && mVisible && task != null) { Loading
services/core/java/com/android/server/wm/ActivityTaskSupervisor.java +1 −14 Original line number Diff line number Diff line Loading @@ -44,7 +44,6 @@ import static android.os.PowerManager.PARTIAL_WAKE_LOCK; import static android.os.Process.INVALID_UID; import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER; import static android.view.Display.DEFAULT_DISPLAY; import static android.view.WindowManager.TRANSIT_CLOSE; import static android.view.WindowManager.TRANSIT_TO_FRONT; import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_STATES; Loading Loading @@ -1562,19 +1561,7 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks { // Prevent recursion. return; } if (task.isVisible()) { if (task.mTransitionController.isCollecting()) { // We don't want the finishing to change the transition ready state since there will // not be corresponding setReady for finishing. task.mTransitionController.collectExistenceChange(task); } else { task.mTransitionController.requestTransitionIfNeeded(TRANSIT_CLOSE, task); } } else { // Removing a non-visible task doesn't require a transition, but if there is one // collecting, this should be a member just in case. task.mTransitionController.collect(task); } task.mTransitionController.requestCloseTransitionIfNeeded(task); task.mInRemoveTask = true; try { task.performClearTask(reason); Loading
services/core/java/com/android/server/wm/Transition.java +5 −0 Original line number Diff line number Diff line Loading @@ -338,6 +338,11 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe applyReady(); } @VisibleForTesting boolean allReady() { return mReadyTracker.allReady(); } /** * Build a transaction that "resets" all the re-parenting and layer changes. This is * intended to be applied at the end of the transition but before the finish callback. This Loading
services/core/java/com/android/server/wm/TransitionController.java +18 −3 Original line number Diff line number Diff line Loading @@ -35,7 +35,6 @@ import android.util.ArrayMap; import android.util.Slog; import android.util.proto.ProtoOutputStream; import android.view.WindowManager; import android.window.IRemoteTransition; import android.window.ITransitionMetricsReporter; import android.window.ITransitionPlayer; import android.window.RemoteTransition; Loading Loading @@ -226,7 +225,7 @@ class TransitionController { } /** * @see #requestTransitionIfNeeded(int, int, WindowContainer, IRemoteTransition) * @see #requestTransitionIfNeeded(int, int, WindowContainer, WindowContainer, RemoteTransition) */ @Nullable Transition requestTransitionIfNeeded(@WindowManager.TransitionType int type, Loading @@ -235,7 +234,7 @@ class TransitionController { } /** * @see #requestTransitionIfNeeded(int, int, WindowContainer, IRemoteTransition) * @see #requestTransitionIfNeeded(int, int, WindowContainer, WindowContainer, RemoteTransition) */ @Nullable Transition requestTransitionIfNeeded(@WindowManager.TransitionType int type, Loading Loading @@ -306,6 +305,22 @@ class TransitionController { return transition; } /** Requests transition for a window container which will be removed or invisible. */ void requestCloseTransitionIfNeeded(@NonNull WindowContainer<?> wc) { if (mTransitionPlayer == null) return; if (wc.isVisibleRequested()) { if (!isCollecting()) { requestStartTransition(createTransition(TRANSIT_CLOSE, 0 /* flags */), wc.asTask(), null /* remoteTransition */); } collectExistenceChange(wc); } else { // Removing a non-visible window doesn't require a transition, but if there is one // collecting, this should be a member just in case. collect(wc); } } /** @see Transition#collect */ void collect(@NonNull WindowContainer wc) { if (mCollectingTransition == null) return; Loading
services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java +28 −5 Original line number Diff line number Diff line Loading @@ -166,6 +166,8 @@ public class ActivityRecordTests extends WindowTestsBase { @Before public void setUp() throws Exception { setBooted(mAtm); // Because the booted state is set, avoid starting real home if there is no task. doReturn(false).when(mRootWindowContainer).resumeHomeActivity(any(), anyString(), any()); } private TestStartingWindowOrganizer registerTestStartingWindowOrganizer() { Loading Loading @@ -1083,6 +1085,7 @@ public class ActivityRecordTests extends WindowTestsBase { */ @Test public void testFinishActivityIfPossible_nonVisibleNoAppTransition() { registerTestTransitionPlayer(); final ActivityRecord activity = createActivityWithTask(); // Put an activity on top of test activity to make it invisible and prevent us from // accidentally resuming the topmost one again. Loading @@ -1093,6 +1096,7 @@ public class ActivityRecordTests extends WindowTestsBase { activity.finishIfPossible("test", false /* oomAdj */); verify(activity.mDisplayContent, never()).prepareAppTransition(eq(TRANSIT_CLOSE)); assertFalse(activity.inTransition()); } /** Loading @@ -1101,11 +1105,7 @@ public class ActivityRecordTests extends WindowTestsBase { */ @Test public void testFinishActivityIfPossible_lastInTaskRequestsTransitionWithTrigger() { // Set-up mock shell transitions final TestTransitionPlayer testPlayer = new TestTransitionPlayer( mAtm.getTransitionController(), mAtm.mWindowOrganizerController); mAtm.getTransitionController().registerTransitionPlayer(testPlayer); final TestTransitionPlayer testPlayer = registerTestTransitionPlayer(); final ActivityRecord activity = createActivityWithTask(); activity.finishing = false; activity.mVisibleRequested = true; Loading @@ -1116,6 +1116,29 @@ public class ActivityRecordTests extends WindowTestsBase { assertEquals(activity.getTask().mTaskId, testPlayer.mLastRequest.getTriggerTask().taskId); } /** * Verify that when collecting activity to the existing close transition, it should not affect * ready state. */ @Test public void testFinishActivityIfPossible_collectToExistingTransition() { final TestTransitionPlayer testPlayer = registerTestTransitionPlayer(); final ActivityRecord activity = createActivityWithTask(); activity.setState(PAUSED, "test"); activity.finishIfPossible("test", false /* oomAdj */); final Transition lastTransition = testPlayer.mLastTransit; assertTrue(lastTransition.allReady()); assertTrue(activity.inTransition()); // Collect another activity to the existing transition without changing ready state. final ActivityRecord activity2 = createActivityRecord(activity.getTask()); activity2.setState(PAUSING, "test"); activity2.finishIfPossible("test", false /* oomAdj */); assertTrue(activity2.inTransition()); assertEquals(lastTransition, testPlayer.mLastTransit); assertTrue(lastTransition.allReady()); } /** * Verify that complete finish request for non-finishing activity is invalid. */ Loading