Loading services/core/java/com/android/server/wm/Transition.java +22 −4 Original line number Diff line number Diff line Loading @@ -1051,7 +1051,8 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener { * @return true if we are *guaranteed* to enter-pip. This means we return false if there's * a chance we won't thus legacy-entry (via pause+userLeaving) will return false. */ private boolean checkEnterPipOnFinish(@NonNull ActivityRecord ar) { private boolean checkEnterPipOnFinish(@NonNull ActivityRecord ar, @Nullable ActivityRecord resuming) { if (!mCanPipOnFinish || !ar.isVisible() || ar.getTask() == null || !ar.isState(RESUMED)) { return false; } Loading Loading @@ -1096,8 +1097,7 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener { try { // If not going auto-pip, the activity should be paused with user-leaving. mController.mAtm.mTaskSupervisor.mUserLeaving = true; ar.getTaskFragment().startPausing(false /* uiSleeping */, null /* resuming */, "finishTransition"); ar.getTaskFragment().startPausing(false /* uiSleeping */, resuming, "finishTransition"); } finally { mController.mAtm.mTaskSupervisor.mUserLeaving = false; } Loading Loading @@ -1195,7 +1195,9 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener { final boolean isScreenOff = ar.mDisplayContent == null || ar.mDisplayContent.getDisplayInfo().state == Display.STATE_OFF; if ((!visibleAtTransitionEnd || isScreenOff) && !ar.isVisibleRequested()) { final boolean commitVisibility = !checkEnterPipOnFinish(ar); final ActivityRecord resuming = getVisibleTransientLaunch( ar.getTaskDisplayArea()); final boolean commitVisibility = !checkEnterPipOnFinish(ar, resuming); // Avoid commit visibility if entering pip or else we will get a sudden // "flash" / surface going invisible for a split second. if (commitVisibility) { Loading Loading @@ -1414,6 +1416,22 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener { mController.mSnapshotController.onTransitionFinish(mType, mTargets); } @Nullable private ActivityRecord getVisibleTransientLaunch(TaskDisplayArea taskDisplayArea) { if (mTransientLaunches == null) return null; for (int i = mTransientLaunches.size() - 1; i >= 0; --i) { final ActivityRecord candidateActivity = mTransientLaunches.keyAt(i); if (candidateActivity.getTaskDisplayArea() != taskDisplayArea) { continue; } if (!candidateActivity.isVisible()) { continue; } return candidateActivity; } return null; } void abort() { // This calls back into itself via controller.abort, so just early return here. if (mState == STATE_ABORT) return; Loading services/tests/wmtests/src/com/android/server/wm/TransitionTests.java +3 −0 Original line number Diff line number Diff line Loading @@ -1439,6 +1439,7 @@ public class TransitionTests extends WindowTestsBase { activity1.setVisibleRequested(true); activity1.setVisible(true); activity2.setVisibleRequested(false); activity1.setState(ActivityRecord.State.RESUMED, "test"); // Using abort to force-finish the sync (since we can't wait for drawing in unit test). // We didn't call abort on the transition itself, so it will still run onTransactionReady Loading Loading @@ -1517,6 +1518,8 @@ public class TransitionTests extends WindowTestsBase { // Make sure activity1 visibility was committed assertFalse(activity1.isVisible()); assertFalse(activity1.app.hasActivityInVisibleTask()); // Make sure the userLeaving is true and the resuming activity is given, verify(task1).startPausing(eq(true), anyBoolean(), eq(activity2), any()); verify(taskSnapshotController, times(1)).recordSnapshot(eq(task1)); assertTrue(enteringAnimReports.contains(activity2)); Loading Loading
services/core/java/com/android/server/wm/Transition.java +22 −4 Original line number Diff line number Diff line Loading @@ -1051,7 +1051,8 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener { * @return true if we are *guaranteed* to enter-pip. This means we return false if there's * a chance we won't thus legacy-entry (via pause+userLeaving) will return false. */ private boolean checkEnterPipOnFinish(@NonNull ActivityRecord ar) { private boolean checkEnterPipOnFinish(@NonNull ActivityRecord ar, @Nullable ActivityRecord resuming) { if (!mCanPipOnFinish || !ar.isVisible() || ar.getTask() == null || !ar.isState(RESUMED)) { return false; } Loading Loading @@ -1096,8 +1097,7 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener { try { // If not going auto-pip, the activity should be paused with user-leaving. mController.mAtm.mTaskSupervisor.mUserLeaving = true; ar.getTaskFragment().startPausing(false /* uiSleeping */, null /* resuming */, "finishTransition"); ar.getTaskFragment().startPausing(false /* uiSleeping */, resuming, "finishTransition"); } finally { mController.mAtm.mTaskSupervisor.mUserLeaving = false; } Loading Loading @@ -1195,7 +1195,9 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener { final boolean isScreenOff = ar.mDisplayContent == null || ar.mDisplayContent.getDisplayInfo().state == Display.STATE_OFF; if ((!visibleAtTransitionEnd || isScreenOff) && !ar.isVisibleRequested()) { final boolean commitVisibility = !checkEnterPipOnFinish(ar); final ActivityRecord resuming = getVisibleTransientLaunch( ar.getTaskDisplayArea()); final boolean commitVisibility = !checkEnterPipOnFinish(ar, resuming); // Avoid commit visibility if entering pip or else we will get a sudden // "flash" / surface going invisible for a split second. if (commitVisibility) { Loading Loading @@ -1414,6 +1416,22 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener { mController.mSnapshotController.onTransitionFinish(mType, mTargets); } @Nullable private ActivityRecord getVisibleTransientLaunch(TaskDisplayArea taskDisplayArea) { if (mTransientLaunches == null) return null; for (int i = mTransientLaunches.size() - 1; i >= 0; --i) { final ActivityRecord candidateActivity = mTransientLaunches.keyAt(i); if (candidateActivity.getTaskDisplayArea() != taskDisplayArea) { continue; } if (!candidateActivity.isVisible()) { continue; } return candidateActivity; } return null; } void abort() { // This calls back into itself via controller.abort, so just early return here. if (mState == STATE_ABORT) return; Loading
services/tests/wmtests/src/com/android/server/wm/TransitionTests.java +3 −0 Original line number Diff line number Diff line Loading @@ -1439,6 +1439,7 @@ public class TransitionTests extends WindowTestsBase { activity1.setVisibleRequested(true); activity1.setVisible(true); activity2.setVisibleRequested(false); activity1.setState(ActivityRecord.State.RESUMED, "test"); // Using abort to force-finish the sync (since we can't wait for drawing in unit test). // We didn't call abort on the transition itself, so it will still run onTransactionReady Loading Loading @@ -1517,6 +1518,8 @@ public class TransitionTests extends WindowTestsBase { // Make sure activity1 visibility was committed assertFalse(activity1.isVisible()); assertFalse(activity1.app.hasActivityInVisibleTask()); // Make sure the userLeaving is true and the resuming activity is given, verify(task1).startPausing(eq(true), anyBoolean(), eq(activity2), any()); verify(taskSnapshotController, times(1)).recordSnapshot(eq(task1)); assertTrue(enteringAnimReports.contains(activity2)); Loading