Loading libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java +13 −3 Original line number Diff line number Diff line Loading @@ -1135,6 +1135,7 @@ public class RecentsTransitionHandler implements Transitions.TransitionHandler, if (openingLeafCount > 0) { appearedTargets = new RemoteAnimationTarget[openingLeafCount]; } boolean onlyOpeningPausedTasks = true; int nextTargetIdx = 0; for (int i = 0; i < openingTasks.size(); ++i) { final TransitionInfo.Change change = openingTasks.get(i); Loading Loading @@ -1188,6 +1189,7 @@ public class RecentsTransitionHandler implements Transitions.TransitionHandler, " opening new leaf taskId=%d wasClosing=%b", target.taskId, wasClosing); mOpeningTasks.add(new TaskState(change, target.leash)); onlyOpeningPausedTasks = false; } else { ProtoLog.v(ShellProtoLogGroup.WM_SHELL_RECENTS_TRANSITION, " opening new taskId=%d", change.getTaskInfo().taskId); Loading @@ -1196,11 +1198,18 @@ public class RecentsTransitionHandler implements Transitions.TransitionHandler, // is only animating the leafs. startT.show(change.getLeash()); mOpeningTasks.add(new TaskState(change, null)); onlyOpeningPausedTasks = false; } } didMergeThings = true; if (!onlyOpeningPausedTasks) { // If we are only opening paused leaf tasks, then we aren't actually quick // switching or launching a new task from overview, and if Launcher requests to // finish(toHome=false) as a response to the pausing tasks being opened again, // we should allow that to be considered returningToApp mState = STATE_NEW_TASK; } } if (mPausingTasks.isEmpty()) { // The pausing tasks may be removed by the incoming closing tasks. ProtoLog.v(ShellProtoLogGroup.WM_SHELL_RECENTS_TRANSITION, Loading Loading @@ -1368,8 +1377,9 @@ public class RecentsTransitionHandler implements Transitions.TransitionHandler, ProtoLog.v(ShellProtoLogGroup.WM_SHELL_RECENTS_TRANSITION, "[%d] RecentsController.finishInner: toHome=%b userLeave=%b " + "willFinishToHome=%b state=%d reason=%s", mInstanceId, toHome, sendUserLeaveHint, mWillFinishToHome, mState, reason); + "willFinishToHome=%b state=%d hasPausingTasks=%b reason=%s", mInstanceId, toHome, sendUserLeaveHint, mWillFinishToHome, mState, mPausingTasks != null, reason); final SurfaceControl.Transaction t = mFinishTransaction; final WindowContainerTransaction wct = new WindowContainerTransaction(); Loading libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java +5 −0 Original line number Diff line number Diff line Loading @@ -602,6 +602,11 @@ public class Transitions implements RemoteCallable<Transitions>, // Just in case there is a race with another animation (eg. recents finish()). // Changes are visible->visible so it's a problem if it isn't visible. t.show(leash); // If there is a transient launch followed by a launch of one of the pausing tasks, // we may end up with TRANSIT_TO_BACK followed by a CHANGE (w/ flag MOVE_TO_TOP), // but since we are hiding the leash in the finish transaction above, we should also // update the finish transaction here to reflect the change in visibility finishT.show(leash); } } } Loading libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/ShellTransitionTests.java +48 −0 Original line number Diff line number Diff line Loading @@ -37,6 +37,7 @@ import static android.view.WindowManager.TRANSIT_TO_BACK; import static android.view.WindowManager.TRANSIT_TO_FRONT; import static android.window.TransitionInfo.FLAG_DISPLAY_HAS_ALERT_WINDOWS; import static android.window.TransitionInfo.FLAG_IS_DISPLAY; import static android.window.TransitionInfo.FLAG_MOVED_TO_TOP; import static android.window.TransitionInfo.FLAG_SYNC; import static android.window.TransitionInfo.FLAG_TRANSLUCENT; Loading Loading @@ -1742,6 +1743,53 @@ public class ShellTransitionTests extends ShellTestCase { eq(R.styleable.WindowAnimation_activityCloseEnterAnimation), anyBoolean()); } @Test public void testTransientHideWithMoveToTop() { Transitions transitions = createTestTransitions(); transitions.replaceDefaultHandlerForTest(mDefaultHandler); final TransitionAnimation transitionAnimation = new TransitionAnimation(mContext, false, Transitions.TAG); spyOn(transitionAnimation); // Prepare for a TO_BACK transition final RunningTaskInfo taskInfo = createTaskInfo(1); final IBinder closeTransition = new Binder(); final SurfaceControl.Transaction closeTransitionFinishT = mock(SurfaceControl.Transaction.class); // Start a TO_BACK transition transitions.requestStartTransition(closeTransition, new TransitionRequestInfo(TRANSIT_TO_BACK, null /* trigger */, null /* remote */)); TransitionInfo closeInfo = new TransitionInfoBuilder(TRANSIT_TO_BACK) .addChange(TRANSIT_TO_BACK, taskInfo) .build(); transitions.onTransitionReady(closeTransition, closeInfo, new StubTransaction(), closeTransitionFinishT); // Verify that the transition hides the task surface in the finish transaction verify(closeTransitionFinishT).hide(any()); // Prepare for a CHANGE transition final IBinder changeTransition = new Binder(); final SurfaceControl.Transaction changeTransitionFinishT = mock(SurfaceControl.Transaction.class); // Start a CHANGE transition w/ MOVE_TO_FRONT that is merged into the TO_BACK mDefaultHandler.setShouldMerge(changeTransition); transitions.requestStartTransition(changeTransition, new TransitionRequestInfo(TRANSIT_OPEN, null /* trigger */, null /* remote */)); TransitionInfo changeInfo = new TransitionInfoBuilder(TRANSIT_OPEN) .addChange(TRANSIT_CHANGE, FLAG_MOVED_TO_TOP, taskInfo) .build(); transitions.onTransitionReady(changeTransition, changeInfo, new StubTransaction(), changeTransitionFinishT); // Verify that the transition shows the task surface in the finish transaction so that the // when the original transition finishes, the finish transaction does not clobber the // visibility of the merged transition verify(changeTransitionFinishT).show(any()); } class TestTransitionHandler implements Transitions.TransitionHandler { ArrayList<Pair<IBinder, Transitions.TransitionFinishCallback>> mFinishes = new ArrayList<>(); Loading Loading
libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java +13 −3 Original line number Diff line number Diff line Loading @@ -1135,6 +1135,7 @@ public class RecentsTransitionHandler implements Transitions.TransitionHandler, if (openingLeafCount > 0) { appearedTargets = new RemoteAnimationTarget[openingLeafCount]; } boolean onlyOpeningPausedTasks = true; int nextTargetIdx = 0; for (int i = 0; i < openingTasks.size(); ++i) { final TransitionInfo.Change change = openingTasks.get(i); Loading Loading @@ -1188,6 +1189,7 @@ public class RecentsTransitionHandler implements Transitions.TransitionHandler, " opening new leaf taskId=%d wasClosing=%b", target.taskId, wasClosing); mOpeningTasks.add(new TaskState(change, target.leash)); onlyOpeningPausedTasks = false; } else { ProtoLog.v(ShellProtoLogGroup.WM_SHELL_RECENTS_TRANSITION, " opening new taskId=%d", change.getTaskInfo().taskId); Loading @@ -1196,11 +1198,18 @@ public class RecentsTransitionHandler implements Transitions.TransitionHandler, // is only animating the leafs. startT.show(change.getLeash()); mOpeningTasks.add(new TaskState(change, null)); onlyOpeningPausedTasks = false; } } didMergeThings = true; if (!onlyOpeningPausedTasks) { // If we are only opening paused leaf tasks, then we aren't actually quick // switching or launching a new task from overview, and if Launcher requests to // finish(toHome=false) as a response to the pausing tasks being opened again, // we should allow that to be considered returningToApp mState = STATE_NEW_TASK; } } if (mPausingTasks.isEmpty()) { // The pausing tasks may be removed by the incoming closing tasks. ProtoLog.v(ShellProtoLogGroup.WM_SHELL_RECENTS_TRANSITION, Loading Loading @@ -1368,8 +1377,9 @@ public class RecentsTransitionHandler implements Transitions.TransitionHandler, ProtoLog.v(ShellProtoLogGroup.WM_SHELL_RECENTS_TRANSITION, "[%d] RecentsController.finishInner: toHome=%b userLeave=%b " + "willFinishToHome=%b state=%d reason=%s", mInstanceId, toHome, sendUserLeaveHint, mWillFinishToHome, mState, reason); + "willFinishToHome=%b state=%d hasPausingTasks=%b reason=%s", mInstanceId, toHome, sendUserLeaveHint, mWillFinishToHome, mState, mPausingTasks != null, reason); final SurfaceControl.Transaction t = mFinishTransaction; final WindowContainerTransaction wct = new WindowContainerTransaction(); Loading
libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java +5 −0 Original line number Diff line number Diff line Loading @@ -602,6 +602,11 @@ public class Transitions implements RemoteCallable<Transitions>, // Just in case there is a race with another animation (eg. recents finish()). // Changes are visible->visible so it's a problem if it isn't visible. t.show(leash); // If there is a transient launch followed by a launch of one of the pausing tasks, // we may end up with TRANSIT_TO_BACK followed by a CHANGE (w/ flag MOVE_TO_TOP), // but since we are hiding the leash in the finish transaction above, we should also // update the finish transaction here to reflect the change in visibility finishT.show(leash); } } } Loading
libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/ShellTransitionTests.java +48 −0 Original line number Diff line number Diff line Loading @@ -37,6 +37,7 @@ import static android.view.WindowManager.TRANSIT_TO_BACK; import static android.view.WindowManager.TRANSIT_TO_FRONT; import static android.window.TransitionInfo.FLAG_DISPLAY_HAS_ALERT_WINDOWS; import static android.window.TransitionInfo.FLAG_IS_DISPLAY; import static android.window.TransitionInfo.FLAG_MOVED_TO_TOP; import static android.window.TransitionInfo.FLAG_SYNC; import static android.window.TransitionInfo.FLAG_TRANSLUCENT; Loading Loading @@ -1742,6 +1743,53 @@ public class ShellTransitionTests extends ShellTestCase { eq(R.styleable.WindowAnimation_activityCloseEnterAnimation), anyBoolean()); } @Test public void testTransientHideWithMoveToTop() { Transitions transitions = createTestTransitions(); transitions.replaceDefaultHandlerForTest(mDefaultHandler); final TransitionAnimation transitionAnimation = new TransitionAnimation(mContext, false, Transitions.TAG); spyOn(transitionAnimation); // Prepare for a TO_BACK transition final RunningTaskInfo taskInfo = createTaskInfo(1); final IBinder closeTransition = new Binder(); final SurfaceControl.Transaction closeTransitionFinishT = mock(SurfaceControl.Transaction.class); // Start a TO_BACK transition transitions.requestStartTransition(closeTransition, new TransitionRequestInfo(TRANSIT_TO_BACK, null /* trigger */, null /* remote */)); TransitionInfo closeInfo = new TransitionInfoBuilder(TRANSIT_TO_BACK) .addChange(TRANSIT_TO_BACK, taskInfo) .build(); transitions.onTransitionReady(closeTransition, closeInfo, new StubTransaction(), closeTransitionFinishT); // Verify that the transition hides the task surface in the finish transaction verify(closeTransitionFinishT).hide(any()); // Prepare for a CHANGE transition final IBinder changeTransition = new Binder(); final SurfaceControl.Transaction changeTransitionFinishT = mock(SurfaceControl.Transaction.class); // Start a CHANGE transition w/ MOVE_TO_FRONT that is merged into the TO_BACK mDefaultHandler.setShouldMerge(changeTransition); transitions.requestStartTransition(changeTransition, new TransitionRequestInfo(TRANSIT_OPEN, null /* trigger */, null /* remote */)); TransitionInfo changeInfo = new TransitionInfoBuilder(TRANSIT_OPEN) .addChange(TRANSIT_CHANGE, FLAG_MOVED_TO_TOP, taskInfo) .build(); transitions.onTransitionReady(changeTransition, changeInfo, new StubTransaction(), changeTransitionFinishT); // Verify that the transition shows the task surface in the finish transaction so that the // when the original transition finishes, the finish transaction does not clobber the // visibility of the merged transition verify(changeTransitionFinishT).show(any()); } class TestTransitionHandler implements Transitions.TransitionHandler { ArrayList<Pair<IBinder, Transitions.TransitionFinishCallback>> mFinishes = new ArrayList<>(); Loading