Loading data/etc/services.core.protolog.json +12 −0 Original line number Diff line number Diff line Loading @@ -271,6 +271,12 @@ "group": "WM_DEBUG_APP_TRANSITIONS_ANIM", "at": "com\/android\/server\/wm\/AppTransition.java" }, "-1868518158": { "message": "Pending back animation due to another animation is running", "level": "WARN", "group": "WM_DEBUG_BACK_PREVIEW", "at": "com\/android\/server\/wm\/BackNavigationController.java" }, "-1868124841": { "message": "screenOnEarly=%b, awake=%b, currentAppOrientation=%d, orientationSensorEnabled=%b, keyguardDrawComplete=%b, windowManagerDrawComplete=%b", "level": "VERBOSE", Loading Loading @@ -1549,6 +1555,12 @@ "group": "WM_DEBUG_ORIENTATION", "at": "com\/android\/server\/wm\/DragState.java" }, "-692907078": { "message": "Handling the deferred animation after transition finished", "level": "DEBUG", "group": "WM_DEBUG_BACK_PREVIEW", "at": "com\/android\/server\/wm\/BackNavigationController.java" }, "-677449371": { "message": "moveTaskToRootTask: moving task=%d to rootTaskId=%d toTop=%b", "level": "DEBUG", Loading libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java +16 −1 Original line number Diff line number Diff line Loading @@ -552,6 +552,9 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont if (runner.isWaitingAnimation()) { ProtoLog.w(WM_SHELL_BACK_PREVIEW, "Gesture released, but animation didn't ready."); return; } else if (runner.isAnimationCancelled()) { invokeOrCancelBack(); return; } startPostCommitAnimation(); } Loading Loading @@ -653,7 +656,19 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont } @Override public void onAnimationCancelled() { } public void onAnimationCancelled() { mShellExecutor.execute(() -> { final BackAnimationRunner runner = mAnimationDefinition.get( mBackNavigationInfo.getType()); if (runner == null) { return; } runner.cancelAnimation(); if (!mBackGestureStarted) { invokeOrCancelBack(); } }); } }; mBackAnimationAdapter = new BackAnimationAdapter(runner); } Loading libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationRunner.java +13 −0 Original line number Diff line number Diff line Loading @@ -41,6 +41,9 @@ class BackAnimationRunner { // Whether we are waiting to receive onAnimationStart private boolean mWaitingAnimation; /** True when the back animation is cancelled */ private boolean mAnimationCancelled; BackAnimationRunner(@NonNull IOnBackInvokedCallback callback, @NonNull IRemoteAnimationRunner runner) { mCallback = callback; Loading Loading @@ -81,9 +84,19 @@ class BackAnimationRunner { void startGesture() { mWaitingAnimation = true; mAnimationCancelled = false; } boolean isWaitingAnimation() { return mWaitingAnimation; } void cancelAnimation() { mWaitingAnimation = false; mAnimationCancelled = true; } boolean isAnimationCancelled() { return mAnimationCancelled; } } services/core/java/com/android/server/wm/BackNavigationController.java +126 −60 Original line number Diff line number Diff line Loading @@ -75,6 +75,11 @@ class BackNavigationController { private final ArrayList<WindowContainer> mTmpOpenApps = new ArrayList<>(); private final ArrayList<WindowContainer> mTmpCloseApps = new ArrayList<>(); // This will be set if the back navigation is in progress and the current transition is still // running. The pending animation builder will do the animation stuff includes creating leashes, // re-parenting leashes and set launch behind, etc. Will be handled when transition finished. private AnimationHandler.ScheduleAnimationBuilder mPendingAnimationBuilder; /** * true if the back predictability feature is enabled */ Loading Loading @@ -305,25 +310,26 @@ class BackNavigationController { || backType == BackNavigationInfo.TYPE_CROSS_ACTIVITY) && adapter != null; // Only prepare animation if no leash has been created (no animation is running). // TODO(b/241808055): Cancel animation when preparing back animation. if (prepareAnimation && (removedWindowContainer.hasCommittedReparentToAnimationLeash() || removedWindowContainer.mTransitionController.inTransition())) { Slog.w(TAG, "Can't prepare back animation due to another animation is running."); prepareAnimation = false; } if (prepareAnimation) { mPendingAnimation = mAnimationHandler.scheduleAnimation(backType, adapter, final AnimationHandler.ScheduleAnimationBuilder builder = mAnimationHandler.prepareAnimation(backType, adapter, currentTask, prevTask, currentActivity, prevActivity); prepareAnimation = mPendingAnimation != null; mBackAnimationInProgress = prepareAnimation; if (prepareAnimation) { mWindowManagerService.mWindowPlacerLocked.requestTraversal(); if (mShowWallpaper) { currentTask.getDisplayContent().mWallpaperController .adjustWallpaperWindows(); mBackAnimationInProgress = builder != null; if (mBackAnimationInProgress) { if (removedWindowContainer.hasCommittedReparentToAnimationLeash() || removedWindowContainer.mTransitionController.inTransition() || mWindowManagerService.mSyncEngine.hasPendingSyncSets()) { ProtoLog.w(WM_DEBUG_BACK_PREVIEW, "Pending back animation due to another animation is running"); mPendingAnimationBuilder = builder; // Current transition is still running, we have to defer the hiding to the // client process to prevent the unexpected relayout when handling the back // animation. if (prevActivity != null) { prevActivity.setDeferHidingClient(true); } } else { scheduleAnimation(builder); } } } Loading @@ -345,6 +351,15 @@ class BackNavigationController { return isWaitBackTransition() || mNavigationMonitor.isMonitoring(); } private void scheduleAnimation(@NonNull AnimationHandler.ScheduleAnimationBuilder builder) { mPendingAnimation = builder.build(); mWindowManagerService.mWindowPlacerLocked.requestTraversal(); if (mShowWallpaper) { mWindowManagerService.getDefaultDisplayContentLocked().mWallpaperController .adjustWallpaperWindows(); } } private boolean isWaitBackTransition() { return mAnimationHandler.mComposed && mAnimationHandler.mWaitTransition; } Loading Loading @@ -526,6 +541,57 @@ class BackNavigationController { mAnimationHandler.clearBackAnimateTarget(cleanupTransaction); } /** * Handle the pending animation when the running transition finished. * @param targets The final animation targets derived in transition. */ boolean handleDeferredBackAnimation(@NonNull ArrayList<Transition.ChangeInfo> targets) { 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. 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)) { continue; } hasTarget = true; t.show(wc.getSurfaceControl()); } if (!hasTarget) { // Skip if no target participated in current finished transition. Slog.w(TAG, "Finished transition didn't include the targets" + " open: " + mPendingAnimationBuilder.mOpenTarget + " close: " + mPendingAnimationBuilder.mCloseTarget); try { mPendingAnimationBuilder.mBackAnimationAdapter.getRunner().onAnimationCancelled(); } catch (RemoteException e) { throw new RuntimeException(e); } mPendingAnimationBuilder = null; return false; } scheduleAnimation(mPendingAnimationBuilder); mPendingAnimationBuilder = null; return true; } /** * Create and handling animations status for an open/close animation targets. */ Loading Loading @@ -638,6 +704,7 @@ class BackNavigationController { if (open) { return wc == mOpenAdaptor.mTarget || mOpenAdaptor.mTarget.hasChild(wc); } if (mSwitchType == TASK_SWITCH) { return wc == mCloseAdaptor.mTarget || (wc.asTask() != null && wc.hasChild(mCloseAdaptor.mTarget)); Loading Loading @@ -841,23 +908,22 @@ class BackNavigationController { } } Runnable scheduleAnimation(int backType, BackAnimationAdapter adapter, ScheduleAnimationBuilder prepareAnimation(int backType, BackAnimationAdapter adapter, Task currentTask, Task previousTask, ActivityRecord currentActivity, ActivityRecord previousActivity) { switch (backType) { case BackNavigationInfo.TYPE_RETURN_TO_HOME: return new ScheduleAnimationBuilder(backType, adapter) .setIsLaunchBehind(true) .setComposeTarget(currentTask, previousTask) .build(); .setComposeTarget(currentTask, previousTask); case BackNavigationInfo.TYPE_CROSS_ACTIVITY: return new ScheduleAnimationBuilder(backType, adapter) .setComposeTarget(currentActivity, previousActivity) .setOpeningSnapshot(getActivitySnapshot(previousActivity)).build(); .setOpeningSnapshot(getActivitySnapshot(previousActivity)); case BackNavigationInfo.TYPE_CROSS_TASK: return new ScheduleAnimationBuilder(backType, adapter) .setComposeTarget(currentTask, previousTask) .setOpeningSnapshot(getTaskSnapshot(previousTask)).build(); .setOpeningSnapshot(getTaskSnapshot(previousTask)); } return null; } Loading Loading @@ -891,6 +957,11 @@ class BackNavigationController { return this; } boolean containTarget(@NonNull WindowContainer wc) { return wc == mOpenTarget || wc == mCloseTarget || wc.hasChild(mOpenTarget) || wc.hasChild(mCloseTarget); } Runnable build() { if (mOpenTarget == null || mCloseTarget == null) { return null; Loading Loading @@ -967,11 +1038,10 @@ class BackNavigationController { } }; } private void setLaunchBehind(ActivityRecord activity) { if (activity == null) { return; } } private static void setLaunchBehind(@NonNull ActivityRecord activity) { if (!activity.isVisibleRequested()) { activity.setVisibility(true); } Loading @@ -993,11 +1063,8 @@ class BackNavigationController { activity.getDisplayContent().ensureActivitiesVisible(null /* starting */, 0 /* configChanges */, false /* preserveWindows */, true); } private void restoreLaunchBehind(ActivityRecord activity) { if (activity == null) { return; } private static void restoreLaunchBehind(@NonNull ActivityRecord activity) { activity.mDisplayContent.continueUpdateOrientationForDiffOrienLaunchingApp(); // Restore the launch-behind state. Loading @@ -1007,8 +1074,6 @@ class BackNavigationController { "Setting Activity.mLauncherTaskBehind to false. Activity=%s", activity); } } } void checkAnimationReady(WallpaperController wallpaperController) { if (!mBackAnimationInProgress) { Loading Loading @@ -1039,6 +1104,7 @@ class BackNavigationController { mNavigationMonitor.stopMonitor(); mBackAnimationInProgress = false; mShowWallpaper = false; mPendingAnimationBuilder = null; } private static TaskSnapshot getActivitySnapshot(@NonNull ActivityRecord r) { Loading services/core/java/com/android/server/wm/Transition.java +3 −0 Original line number Diff line number Diff line Loading @@ -989,6 +989,9 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener { cleanUpInternal(); mController.updateAnimatingState(mTmpTransaction); mTmpTransaction.apply(); // Handle back animation if it's already started. mController.mAtm.mBackNavigationController.handleDeferredBackAnimation(mTargets); } void abort() { Loading Loading
data/etc/services.core.protolog.json +12 −0 Original line number Diff line number Diff line Loading @@ -271,6 +271,12 @@ "group": "WM_DEBUG_APP_TRANSITIONS_ANIM", "at": "com\/android\/server\/wm\/AppTransition.java" }, "-1868518158": { "message": "Pending back animation due to another animation is running", "level": "WARN", "group": "WM_DEBUG_BACK_PREVIEW", "at": "com\/android\/server\/wm\/BackNavigationController.java" }, "-1868124841": { "message": "screenOnEarly=%b, awake=%b, currentAppOrientation=%d, orientationSensorEnabled=%b, keyguardDrawComplete=%b, windowManagerDrawComplete=%b", "level": "VERBOSE", Loading Loading @@ -1549,6 +1555,12 @@ "group": "WM_DEBUG_ORIENTATION", "at": "com\/android\/server\/wm\/DragState.java" }, "-692907078": { "message": "Handling the deferred animation after transition finished", "level": "DEBUG", "group": "WM_DEBUG_BACK_PREVIEW", "at": "com\/android\/server\/wm\/BackNavigationController.java" }, "-677449371": { "message": "moveTaskToRootTask: moving task=%d to rootTaskId=%d toTop=%b", "level": "DEBUG", Loading
libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java +16 −1 Original line number Diff line number Diff line Loading @@ -552,6 +552,9 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont if (runner.isWaitingAnimation()) { ProtoLog.w(WM_SHELL_BACK_PREVIEW, "Gesture released, but animation didn't ready."); return; } else if (runner.isAnimationCancelled()) { invokeOrCancelBack(); return; } startPostCommitAnimation(); } Loading Loading @@ -653,7 +656,19 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont } @Override public void onAnimationCancelled() { } public void onAnimationCancelled() { mShellExecutor.execute(() -> { final BackAnimationRunner runner = mAnimationDefinition.get( mBackNavigationInfo.getType()); if (runner == null) { return; } runner.cancelAnimation(); if (!mBackGestureStarted) { invokeOrCancelBack(); } }); } }; mBackAnimationAdapter = new BackAnimationAdapter(runner); } Loading
libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationRunner.java +13 −0 Original line number Diff line number Diff line Loading @@ -41,6 +41,9 @@ class BackAnimationRunner { // Whether we are waiting to receive onAnimationStart private boolean mWaitingAnimation; /** True when the back animation is cancelled */ private boolean mAnimationCancelled; BackAnimationRunner(@NonNull IOnBackInvokedCallback callback, @NonNull IRemoteAnimationRunner runner) { mCallback = callback; Loading Loading @@ -81,9 +84,19 @@ class BackAnimationRunner { void startGesture() { mWaitingAnimation = true; mAnimationCancelled = false; } boolean isWaitingAnimation() { return mWaitingAnimation; } void cancelAnimation() { mWaitingAnimation = false; mAnimationCancelled = true; } boolean isAnimationCancelled() { return mAnimationCancelled; } }
services/core/java/com/android/server/wm/BackNavigationController.java +126 −60 Original line number Diff line number Diff line Loading @@ -75,6 +75,11 @@ class BackNavigationController { private final ArrayList<WindowContainer> mTmpOpenApps = new ArrayList<>(); private final ArrayList<WindowContainer> mTmpCloseApps = new ArrayList<>(); // This will be set if the back navigation is in progress and the current transition is still // running. The pending animation builder will do the animation stuff includes creating leashes, // re-parenting leashes and set launch behind, etc. Will be handled when transition finished. private AnimationHandler.ScheduleAnimationBuilder mPendingAnimationBuilder; /** * true if the back predictability feature is enabled */ Loading Loading @@ -305,25 +310,26 @@ class BackNavigationController { || backType == BackNavigationInfo.TYPE_CROSS_ACTIVITY) && adapter != null; // Only prepare animation if no leash has been created (no animation is running). // TODO(b/241808055): Cancel animation when preparing back animation. if (prepareAnimation && (removedWindowContainer.hasCommittedReparentToAnimationLeash() || removedWindowContainer.mTransitionController.inTransition())) { Slog.w(TAG, "Can't prepare back animation due to another animation is running."); prepareAnimation = false; } if (prepareAnimation) { mPendingAnimation = mAnimationHandler.scheduleAnimation(backType, adapter, final AnimationHandler.ScheduleAnimationBuilder builder = mAnimationHandler.prepareAnimation(backType, adapter, currentTask, prevTask, currentActivity, prevActivity); prepareAnimation = mPendingAnimation != null; mBackAnimationInProgress = prepareAnimation; if (prepareAnimation) { mWindowManagerService.mWindowPlacerLocked.requestTraversal(); if (mShowWallpaper) { currentTask.getDisplayContent().mWallpaperController .adjustWallpaperWindows(); mBackAnimationInProgress = builder != null; if (mBackAnimationInProgress) { if (removedWindowContainer.hasCommittedReparentToAnimationLeash() || removedWindowContainer.mTransitionController.inTransition() || mWindowManagerService.mSyncEngine.hasPendingSyncSets()) { ProtoLog.w(WM_DEBUG_BACK_PREVIEW, "Pending back animation due to another animation is running"); mPendingAnimationBuilder = builder; // Current transition is still running, we have to defer the hiding to the // client process to prevent the unexpected relayout when handling the back // animation. if (prevActivity != null) { prevActivity.setDeferHidingClient(true); } } else { scheduleAnimation(builder); } } } Loading @@ -345,6 +351,15 @@ class BackNavigationController { return isWaitBackTransition() || mNavigationMonitor.isMonitoring(); } private void scheduleAnimation(@NonNull AnimationHandler.ScheduleAnimationBuilder builder) { mPendingAnimation = builder.build(); mWindowManagerService.mWindowPlacerLocked.requestTraversal(); if (mShowWallpaper) { mWindowManagerService.getDefaultDisplayContentLocked().mWallpaperController .adjustWallpaperWindows(); } } private boolean isWaitBackTransition() { return mAnimationHandler.mComposed && mAnimationHandler.mWaitTransition; } Loading Loading @@ -526,6 +541,57 @@ class BackNavigationController { mAnimationHandler.clearBackAnimateTarget(cleanupTransaction); } /** * Handle the pending animation when the running transition finished. * @param targets The final animation targets derived in transition. */ boolean handleDeferredBackAnimation(@NonNull ArrayList<Transition.ChangeInfo> targets) { 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. 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)) { continue; } hasTarget = true; t.show(wc.getSurfaceControl()); } if (!hasTarget) { // Skip if no target participated in current finished transition. Slog.w(TAG, "Finished transition didn't include the targets" + " open: " + mPendingAnimationBuilder.mOpenTarget + " close: " + mPendingAnimationBuilder.mCloseTarget); try { mPendingAnimationBuilder.mBackAnimationAdapter.getRunner().onAnimationCancelled(); } catch (RemoteException e) { throw new RuntimeException(e); } mPendingAnimationBuilder = null; return false; } scheduleAnimation(mPendingAnimationBuilder); mPendingAnimationBuilder = null; return true; } /** * Create and handling animations status for an open/close animation targets. */ Loading Loading @@ -638,6 +704,7 @@ class BackNavigationController { if (open) { return wc == mOpenAdaptor.mTarget || mOpenAdaptor.mTarget.hasChild(wc); } if (mSwitchType == TASK_SWITCH) { return wc == mCloseAdaptor.mTarget || (wc.asTask() != null && wc.hasChild(mCloseAdaptor.mTarget)); Loading Loading @@ -841,23 +908,22 @@ class BackNavigationController { } } Runnable scheduleAnimation(int backType, BackAnimationAdapter adapter, ScheduleAnimationBuilder prepareAnimation(int backType, BackAnimationAdapter adapter, Task currentTask, Task previousTask, ActivityRecord currentActivity, ActivityRecord previousActivity) { switch (backType) { case BackNavigationInfo.TYPE_RETURN_TO_HOME: return new ScheduleAnimationBuilder(backType, adapter) .setIsLaunchBehind(true) .setComposeTarget(currentTask, previousTask) .build(); .setComposeTarget(currentTask, previousTask); case BackNavigationInfo.TYPE_CROSS_ACTIVITY: return new ScheduleAnimationBuilder(backType, adapter) .setComposeTarget(currentActivity, previousActivity) .setOpeningSnapshot(getActivitySnapshot(previousActivity)).build(); .setOpeningSnapshot(getActivitySnapshot(previousActivity)); case BackNavigationInfo.TYPE_CROSS_TASK: return new ScheduleAnimationBuilder(backType, adapter) .setComposeTarget(currentTask, previousTask) .setOpeningSnapshot(getTaskSnapshot(previousTask)).build(); .setOpeningSnapshot(getTaskSnapshot(previousTask)); } return null; } Loading Loading @@ -891,6 +957,11 @@ class BackNavigationController { return this; } boolean containTarget(@NonNull WindowContainer wc) { return wc == mOpenTarget || wc == mCloseTarget || wc.hasChild(mOpenTarget) || wc.hasChild(mCloseTarget); } Runnable build() { if (mOpenTarget == null || mCloseTarget == null) { return null; Loading Loading @@ -967,11 +1038,10 @@ class BackNavigationController { } }; } private void setLaunchBehind(ActivityRecord activity) { if (activity == null) { return; } } private static void setLaunchBehind(@NonNull ActivityRecord activity) { if (!activity.isVisibleRequested()) { activity.setVisibility(true); } Loading @@ -993,11 +1063,8 @@ class BackNavigationController { activity.getDisplayContent().ensureActivitiesVisible(null /* starting */, 0 /* configChanges */, false /* preserveWindows */, true); } private void restoreLaunchBehind(ActivityRecord activity) { if (activity == null) { return; } private static void restoreLaunchBehind(@NonNull ActivityRecord activity) { activity.mDisplayContent.continueUpdateOrientationForDiffOrienLaunchingApp(); // Restore the launch-behind state. Loading @@ -1007,8 +1074,6 @@ class BackNavigationController { "Setting Activity.mLauncherTaskBehind to false. Activity=%s", activity); } } } void checkAnimationReady(WallpaperController wallpaperController) { if (!mBackAnimationInProgress) { Loading Loading @@ -1039,6 +1104,7 @@ class BackNavigationController { mNavigationMonitor.stopMonitor(); mBackAnimationInProgress = false; mShowWallpaper = false; mPendingAnimationBuilder = null; } private static TaskSnapshot getActivitySnapshot(@NonNull ActivityRecord r) { Loading
services/core/java/com/android/server/wm/Transition.java +3 −0 Original line number Diff line number Diff line Loading @@ -989,6 +989,9 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener { cleanUpInternal(); mController.updateAnimatingState(mTmpTransaction); mTmpTransaction.apply(); // Handle back animation if it's already started. mController.mAtm.mBackNavigationController.handleDeferredBackAnimation(mTargets); } void abort() { Loading