Loading libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java +5 −3 Original line number Diff line number Diff line Loading @@ -561,6 +561,9 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont } if (runner.isWaitingAnimation()) { ProtoLog.w(WM_SHELL_BACK_PREVIEW, "Gesture released, but animation didn't ready."); // Supposed it is in post commit animation state, and start the timeout to watch // if the animation is ready. mShellExecutor.executeDelayed(mAnimationTimeoutRunnable, MAX_ANIMATION_DURATION); return; } else if (runner.isAnimationCancelled()) { invokeOrCancelBack(); Loading @@ -577,6 +580,8 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont if (mPostCommitAnimationInProgress) { return; } mShellExecutor.removeCallbacks(mAnimationTimeoutRunnable); ProtoLog.d(WM_SHELL_BACK_PREVIEW, "BackAnimationController: startPostCommitAnimation()"); mPostCommitAnimationInProgress = true; mShellExecutor.executeDelayed(mAnimationTimeoutRunnable, MAX_ANIMATION_DURATION); Loading @@ -595,9 +600,6 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont */ @VisibleForTesting void onBackAnimationFinished() { if (!mPostCommitAnimationInProgress) { return; } // Stop timeout runner. mShellExecutor.removeCallbacks(mAnimationTimeoutRunnable); mPostCommitAnimationInProgress = false; Loading libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/back/BackAnimationControllerTest.java +16 −0 Original line number Diff line number Diff line Loading @@ -166,6 +166,9 @@ public class BackAnimationControllerTest extends ShellTestCase { doMotionEvent(MotionEvent.ACTION_DOWN, 0); doMotionEvent(MotionEvent.ACTION_MOVE, 0); mController.setTriggerBack(true); } private void releaseBackGesture() { doMotionEvent(MotionEvent.ACTION_UP, 0); } Loading Loading @@ -201,6 +204,8 @@ public class BackAnimationControllerTest extends ShellTestCase { .setOnBackNavigationDone(new RemoteCallback(result))); triggerBackGesture(); simulateRemoteAnimationStart(type); mShellExecutor.flushAll(); releaseBackGesture(); simulateRemoteAnimationFinished(); mShellExecutor.flushAll(); Loading Loading @@ -252,6 +257,7 @@ public class BackAnimationControllerTest extends ShellTestCase { createNavigationInfo(BackNavigationInfo.TYPE_RETURN_TO_HOME, false); triggerBackGesture(); releaseBackGesture(); verify(mAppCallback, times(1)).onBackInvoked(); Loading @@ -269,6 +275,8 @@ public class BackAnimationControllerTest extends ShellTestCase { triggerBackGesture(); simulateRemoteAnimationStart(BackNavigationInfo.TYPE_RETURN_TO_HOME); releaseBackGesture(); // Check that back invocation is dispatched. verify(mAnimatorCallback).onBackInvoked(); verify(mBackAnimationRunner).onAnimationStart(anyInt(), any(), any(), any(), any()); Loading Loading @@ -308,6 +316,9 @@ public class BackAnimationControllerTest extends ShellTestCase { triggerBackGesture(); simulateRemoteAnimationStart(BackNavigationInfo.TYPE_RETURN_TO_HOME); mShellExecutor.flushAll(); releaseBackGesture(); // Simulate transition timeout. mShellExecutor.flushAll(); Loading Loading @@ -369,6 +380,9 @@ public class BackAnimationControllerTest extends ShellTestCase { simulateRemoteAnimationStart(type); mShellExecutor.flushAll(); releaseBackGesture(); mShellExecutor.flushAll(); assertTrue("Navigation Done callback not called for " + BackNavigationInfo.typeToString(type), result.mBackNavigationDone); assertTrue("TriggerBack should have been true", result.mTriggerBack); Loading @@ -395,6 +409,8 @@ public class BackAnimationControllerTest extends ShellTestCase { .setOnBackNavigationDone(new RemoteCallback(result))); triggerBackGesture(); mShellExecutor.flushAll(); releaseBackGesture(); mShellExecutor.flushAll(); assertTrue("Navigation Done callback not called for " + BackNavigationInfo.typeToString(type), result.mBackNavigationDone); Loading services/core/java/com/android/server/wm/BackNavigationController.java +24 −16 Original line number Diff line number Diff line Loading @@ -648,31 +648,28 @@ class BackNavigationController { if (finishedTransition == mWaitTransitionFinish) { clearBackAnimations(); } if (!mBackAnimationInProgress || mPendingAnimationBuilder == null) { return false; } ProtoLog.d(WM_DEBUG_BACK_PREVIEW, "Handling the deferred animation after transition finished"); // Show the target surface and its parents to prevent it or its parents hidden when // the transition finished. // The target could be affected by transition when : // Open transition -> the open target in back navigation // Close transition -> the close target in back navigation. // Find the participated container collected by transition when : // Open transition -> the open target in back navigation, the close target in transition. // Close transition -> the close target in back navigation, the open target in transition. boolean hasTarget = false; final SurfaceControl.Transaction t = mPendingAnimationBuilder.mCloseTarget.getPendingTransaction(); for (int i = 0; i < targets.size(); i++) { final WindowContainer wc = targets.get(i).mContainer; if (wc.asActivityRecord() == null && wc.asTask() == null) { continue; } else if (!mPendingAnimationBuilder.containTarget(wc)) { for (int i = 0; i < finishedTransition.mParticipants.size(); i++) { final WindowContainer wc = finishedTransition.mParticipants.valueAt(i); if (wc.asActivityRecord() == null && wc.asTask() == null && wc.asTaskFragment() == null) { continue; } if (mPendingAnimationBuilder.containTarget(wc)) { hasTarget = true; t.show(wc.getSurfaceControl()); break; } } if (!hasTarget) { Loading @@ -689,6 +686,12 @@ class BackNavigationController { return false; } // Ensure the final animation targets which hidden by transition could be visible. for (int i = 0; i < targets.size(); i++) { final WindowContainer wc = targets.get(i).mContainer; wc.prepareSurfaces(); } scheduleAnimation(mPendingAnimationBuilder); mPendingAnimationBuilder = null; return true; Loading Loading @@ -1076,7 +1079,7 @@ class BackNavigationController { boolean containTarget(@NonNull WindowContainer wc) { return wc == mOpenTarget || wc == mCloseTarget || wc.hasChild(mOpenTarget) || wc.hasChild(mCloseTarget); || mOpenTarget.hasChild(wc) || mCloseTarget.hasChild(wc); } /** Loading Loading @@ -1151,6 +1154,11 @@ class BackNavigationController { private static void setLaunchBehind(@NonNull ActivityRecord activity) { if (!activity.isVisibleRequested()) { activity.setVisibility(true); // The transition could commit the visibility and in the finishing state, that could // skip commitVisibility call in setVisibility cause the activity won't visible here. // Call it again to make sure the activity could be visible while handling the pending // animation. activity.commitVisibility(true, true); } activity.mLaunchTaskBehind = true; Loading Loading
libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java +5 −3 Original line number Diff line number Diff line Loading @@ -561,6 +561,9 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont } if (runner.isWaitingAnimation()) { ProtoLog.w(WM_SHELL_BACK_PREVIEW, "Gesture released, but animation didn't ready."); // Supposed it is in post commit animation state, and start the timeout to watch // if the animation is ready. mShellExecutor.executeDelayed(mAnimationTimeoutRunnable, MAX_ANIMATION_DURATION); return; } else if (runner.isAnimationCancelled()) { invokeOrCancelBack(); Loading @@ -577,6 +580,8 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont if (mPostCommitAnimationInProgress) { return; } mShellExecutor.removeCallbacks(mAnimationTimeoutRunnable); ProtoLog.d(WM_SHELL_BACK_PREVIEW, "BackAnimationController: startPostCommitAnimation()"); mPostCommitAnimationInProgress = true; mShellExecutor.executeDelayed(mAnimationTimeoutRunnable, MAX_ANIMATION_DURATION); Loading @@ -595,9 +600,6 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont */ @VisibleForTesting void onBackAnimationFinished() { if (!mPostCommitAnimationInProgress) { return; } // Stop timeout runner. mShellExecutor.removeCallbacks(mAnimationTimeoutRunnable); mPostCommitAnimationInProgress = false; Loading
libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/back/BackAnimationControllerTest.java +16 −0 Original line number Diff line number Diff line Loading @@ -166,6 +166,9 @@ public class BackAnimationControllerTest extends ShellTestCase { doMotionEvent(MotionEvent.ACTION_DOWN, 0); doMotionEvent(MotionEvent.ACTION_MOVE, 0); mController.setTriggerBack(true); } private void releaseBackGesture() { doMotionEvent(MotionEvent.ACTION_UP, 0); } Loading Loading @@ -201,6 +204,8 @@ public class BackAnimationControllerTest extends ShellTestCase { .setOnBackNavigationDone(new RemoteCallback(result))); triggerBackGesture(); simulateRemoteAnimationStart(type); mShellExecutor.flushAll(); releaseBackGesture(); simulateRemoteAnimationFinished(); mShellExecutor.flushAll(); Loading Loading @@ -252,6 +257,7 @@ public class BackAnimationControllerTest extends ShellTestCase { createNavigationInfo(BackNavigationInfo.TYPE_RETURN_TO_HOME, false); triggerBackGesture(); releaseBackGesture(); verify(mAppCallback, times(1)).onBackInvoked(); Loading @@ -269,6 +275,8 @@ public class BackAnimationControllerTest extends ShellTestCase { triggerBackGesture(); simulateRemoteAnimationStart(BackNavigationInfo.TYPE_RETURN_TO_HOME); releaseBackGesture(); // Check that back invocation is dispatched. verify(mAnimatorCallback).onBackInvoked(); verify(mBackAnimationRunner).onAnimationStart(anyInt(), any(), any(), any(), any()); Loading Loading @@ -308,6 +316,9 @@ public class BackAnimationControllerTest extends ShellTestCase { triggerBackGesture(); simulateRemoteAnimationStart(BackNavigationInfo.TYPE_RETURN_TO_HOME); mShellExecutor.flushAll(); releaseBackGesture(); // Simulate transition timeout. mShellExecutor.flushAll(); Loading Loading @@ -369,6 +380,9 @@ public class BackAnimationControllerTest extends ShellTestCase { simulateRemoteAnimationStart(type); mShellExecutor.flushAll(); releaseBackGesture(); mShellExecutor.flushAll(); assertTrue("Navigation Done callback not called for " + BackNavigationInfo.typeToString(type), result.mBackNavigationDone); assertTrue("TriggerBack should have been true", result.mTriggerBack); Loading @@ -395,6 +409,8 @@ public class BackAnimationControllerTest extends ShellTestCase { .setOnBackNavigationDone(new RemoteCallback(result))); triggerBackGesture(); mShellExecutor.flushAll(); releaseBackGesture(); mShellExecutor.flushAll(); assertTrue("Navigation Done callback not called for " + BackNavigationInfo.typeToString(type), result.mBackNavigationDone); Loading
services/core/java/com/android/server/wm/BackNavigationController.java +24 −16 Original line number Diff line number Diff line Loading @@ -648,31 +648,28 @@ class BackNavigationController { if (finishedTransition == mWaitTransitionFinish) { clearBackAnimations(); } if (!mBackAnimationInProgress || mPendingAnimationBuilder == null) { return false; } ProtoLog.d(WM_DEBUG_BACK_PREVIEW, "Handling the deferred animation after transition finished"); // Show the target surface and its parents to prevent it or its parents hidden when // the transition finished. // The target could be affected by transition when : // Open transition -> the open target in back navigation // Close transition -> the close target in back navigation. // Find the participated container collected by transition when : // Open transition -> the open target in back navigation, the close target in transition. // Close transition -> the close target in back navigation, the open target in transition. boolean hasTarget = false; final SurfaceControl.Transaction t = mPendingAnimationBuilder.mCloseTarget.getPendingTransaction(); for (int i = 0; i < targets.size(); i++) { final WindowContainer wc = targets.get(i).mContainer; if (wc.asActivityRecord() == null && wc.asTask() == null) { continue; } else if (!mPendingAnimationBuilder.containTarget(wc)) { for (int i = 0; i < finishedTransition.mParticipants.size(); i++) { final WindowContainer wc = finishedTransition.mParticipants.valueAt(i); if (wc.asActivityRecord() == null && wc.asTask() == null && wc.asTaskFragment() == null) { continue; } if (mPendingAnimationBuilder.containTarget(wc)) { hasTarget = true; t.show(wc.getSurfaceControl()); break; } } if (!hasTarget) { Loading @@ -689,6 +686,12 @@ class BackNavigationController { return false; } // Ensure the final animation targets which hidden by transition could be visible. for (int i = 0; i < targets.size(); i++) { final WindowContainer wc = targets.get(i).mContainer; wc.prepareSurfaces(); } scheduleAnimation(mPendingAnimationBuilder); mPendingAnimationBuilder = null; return true; Loading Loading @@ -1076,7 +1079,7 @@ class BackNavigationController { boolean containTarget(@NonNull WindowContainer wc) { return wc == mOpenTarget || wc == mCloseTarget || wc.hasChild(mOpenTarget) || wc.hasChild(mCloseTarget); || mOpenTarget.hasChild(wc) || mCloseTarget.hasChild(wc); } /** Loading Loading @@ -1151,6 +1154,11 @@ class BackNavigationController { private static void setLaunchBehind(@NonNull ActivityRecord activity) { if (!activity.isVisibleRequested()) { activity.setVisibility(true); // The transition could commit the visibility and in the finishing state, that could // skip commitVisibility call in setVisibility cause the activity won't visible here. // Call it again to make sure the activity could be visible while handling the pending // animation. activity.commitVisibility(true, true); } activity.mLaunchTaskBehind = true; Loading