Loading core/java/android/window/BackNavigationInfo.java +11 −1 Original line number Diff line number Diff line Loading @@ -73,6 +73,13 @@ public final class BackNavigationInfo implements Parcelable { */ public static final int TYPE_CALLBACK = 4; /** * A {@link OnBackInvokedCallback} is not available due to a transition is happening. * <p> * @hide */ public static final int TYPE_IN_TRANSITION = 5; /** * Key to access the boolean value passed in {#mOnBackNavigationDone} result bundle * that represents if back navigation has been triggered. Loading Loading @@ -106,7 +113,8 @@ public final class BackNavigationInfo implements Parcelable { TYPE_RETURN_TO_HOME, TYPE_CROSS_ACTIVITY, TYPE_CROSS_TASK, TYPE_CALLBACK TYPE_CALLBACK, TYPE_IN_TRANSITION }) @Retention(RetentionPolicy.SOURCE) public @interface BackTargetType { Loading Loading @@ -339,6 +347,8 @@ public final class BackNavigationInfo implements Parcelable { return "TYPE_CROSS_TASK"; case TYPE_CALLBACK: return "TYPE_CALLBACK"; case TYPE_IN_TRANSITION: return "TYPE_IN_TRANSITION"; } return String.valueOf(type); } Loading core/java/android/window/flags/windowing_frontend.aconfig +10 −0 Original line number Diff line number Diff line Loading @@ -404,6 +404,16 @@ flag { } } flag { name: "predictive_back_intercept_transition" namespace: "windowing_frontend" description: "Allows back gesture to intercept a running transition." bug: "426448018" metadata { purpose: PURPOSE_BUGFIX } } flag { name: "current_animator_scale_uses_shared_memory" namespace: "wear_system_health" Loading libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java +48 −17 Original line number Diff line number Diff line Loading @@ -159,6 +159,7 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont * (and navigation) associated with {@link #mCurrentTracker} have not yet finished. */ private BackTouchTracker mQueuedTracker = new BackTouchTracker(); private final TransitionIdleRunner mTransitionIdleRunner = new TransitionIdleRunner(); private final BackTransitionObserver mBackTransitionObserver = new BackTransitionObserver(); Loading Loading @@ -470,9 +471,17 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont tryPilferPointers(); } if (predictiveBackDelayWmTransition()) { startPredictiveBackAnimationIfNeeded(); } private void startPredictiveBackAnimationIfNeeded() { if (!predictiveBackDelayWmTransition() || !mThresholdCrossed) { return; } mShellExecutor.execute(() -> { if (shouldDispatchToAnimator()) { if (!shouldDispatchToAnimator()) { return; } try { mActivityTaskManager.startPredictiveBackAnimation(); } catch (RemoteException r) { Loading @@ -485,10 +494,8 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont mActiveCallback = null; } requestTopUi(true, backType); } }); } } private boolean isAppProgressGenerationAllowed() { return mBackNavigationInfo.isAppProgressGenerationAllowed() Loading Loading @@ -624,6 +631,22 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont } } private class TransitionIdleRunner implements Runnable { boolean mIsEnable; @Override public void run() { if (!mIsEnable || !mCurrentTracker.isActive()) { return; } ProtoLog.d(WM_SHELL_BACK_PREVIEW, "Gesture hasn't finish after transition " + "idle, start back navigation again."); mIsEnable = false; startBackNavigation(mCurrentTracker); startPredictiveBackAnimationIfNeeded(); } } private void onBackNavigationInfoReceived(@Nullable BackNavigationInfo backNavigationInfo, @NonNull BackTouchTracker touchTracker) { ProtoLog.d(WM_SHELL_BACK_PREVIEW, "Received backNavigationInfo:%s", backNavigationInfo); Loading @@ -635,6 +658,13 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont return; } final int backType = backNavigationInfo.getType(); if (backType == BackNavigationInfo.TYPE_IN_TRANSITION) { mBackNavigationInfo = null; tryPilferPointers(); mTransitionIdleRunner.mIsEnable = true; mTransitions.runOnIdle(() -> mShellExecutor.execute(mTransitionIdleRunner)); return; } final boolean shouldDispatchToAnimator = shouldDispatchToAnimator(); if (shouldDispatchToAnimator) { if (!predictiveBackDelayWmTransition()) { Loading Loading @@ -859,6 +889,7 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont mPointersPilfered = false; mBackGestureStarted = false; activeTouchTracker.setState(BackTouchTracker.TouchTrackerState.FINISHED); mTransitionIdleRunner.mIsEnable = false; if (mPostCommitAnimationInProgress) { ProtoLog.w(WM_SHELL_BACK_PREVIEW, "Animation is still running"); Loading libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/back/BackAnimationControllerTest.java +15 −0 Original line number Diff line number Diff line Loading @@ -60,6 +60,7 @@ import android.os.Handler; import android.os.IBinder; import android.os.RemoteCallback; import android.os.RemoteException; import android.platform.test.annotations.EnableFlags; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; import android.view.IRemoteAnimationRunner; Loading @@ -81,6 +82,7 @@ import android.window.WindowContainerToken; import androidx.annotation.Nullable; import androidx.test.filters.SmallTest; import com.android.window.flags.Flags; import com.android.wm.shell.RootTaskDisplayAreaOrganizer; import com.android.wm.shell.ShellTestCase; import com.android.wm.shell.TestShellExecutor; Loading Loading @@ -276,6 +278,19 @@ public class BackAnimationControllerTest extends ShellTestCase { } } @EnableFlags(Flags.FLAG_PREDICTIVE_BACK_INTERCEPT_TRANSITION) @Test public void noStartInTransition() throws RemoteException { registerAnimation(BackNavigationInfo.TYPE_RETURN_TO_HOME); createNavigationInfo(BackNavigationInfo.TYPE_IN_TRANSITION, /* enableAnimation = */ true, /* isAnimationCallback = */ false); doStartEvents(0, 100); verify(mAppCallback, never()).onBackStarted(any()); verify(mTransitions).runOnIdle(any()); } @Test public void backToHome_dispatchesEvents() throws RemoteException { registerAnimation(BackNavigationInfo.TYPE_RETURN_TO_HOME); Loading services/core/java/com/android/server/wm/BackNavigationController.java +16 −4 Original line number Diff line number Diff line Loading @@ -98,9 +98,13 @@ class BackNavigationController { // back animation. private AnimationHandler.ScheduleAnimationBuilder mCurrentAnimationBuilder; // 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. /** * 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. * * @deprecated Remove after Flags#predictive_back_intercept_transition */ private AnimationHandler.ScheduleAnimationBuilder mPendingAnimationBuilder; private static int sDefaultAnimationResId; Loading Loading @@ -228,6 +232,13 @@ class BackNavigationController { return null; } if (Flags.predictiveBackInterceptTransition() && window.mTransitionController.inTransition()) { infoBuilder.setType(BackNavigationInfo.TYPE_IN_TRANSITION); ProtoLog.d(WM_DEBUG_BACK_PREVIEW, "A transition is happening."); return infoBuilder.build(); } final ArrayList<EmbeddedWindowController.EmbeddedWindow> embeddedWindows = wmService .mEmbeddedWindowController.getByHostWindow(window); Loading Loading @@ -2223,7 +2234,8 @@ class BackNavigationController { } private void scheduleAnimationInner(AnimationHandler.ScheduleAnimationBuilder builder) { if (mWindowManagerService.mAtmService.getTransitionController().inTransition()) { if (!Flags.predictiveBackInterceptTransition() && mWindowManagerService.mAtmService.getTransitionController().inTransition()) { ProtoLog.w(WM_DEBUG_BACK_PREVIEW, "Pending back animation due to another animation is running"); mPendingAnimationBuilder = builder; Loading Loading
core/java/android/window/BackNavigationInfo.java +11 −1 Original line number Diff line number Diff line Loading @@ -73,6 +73,13 @@ public final class BackNavigationInfo implements Parcelable { */ public static final int TYPE_CALLBACK = 4; /** * A {@link OnBackInvokedCallback} is not available due to a transition is happening. * <p> * @hide */ public static final int TYPE_IN_TRANSITION = 5; /** * Key to access the boolean value passed in {#mOnBackNavigationDone} result bundle * that represents if back navigation has been triggered. Loading Loading @@ -106,7 +113,8 @@ public final class BackNavigationInfo implements Parcelable { TYPE_RETURN_TO_HOME, TYPE_CROSS_ACTIVITY, TYPE_CROSS_TASK, TYPE_CALLBACK TYPE_CALLBACK, TYPE_IN_TRANSITION }) @Retention(RetentionPolicy.SOURCE) public @interface BackTargetType { Loading Loading @@ -339,6 +347,8 @@ public final class BackNavigationInfo implements Parcelable { return "TYPE_CROSS_TASK"; case TYPE_CALLBACK: return "TYPE_CALLBACK"; case TYPE_IN_TRANSITION: return "TYPE_IN_TRANSITION"; } return String.valueOf(type); } Loading
core/java/android/window/flags/windowing_frontend.aconfig +10 −0 Original line number Diff line number Diff line Loading @@ -404,6 +404,16 @@ flag { } } flag { name: "predictive_back_intercept_transition" namespace: "windowing_frontend" description: "Allows back gesture to intercept a running transition." bug: "426448018" metadata { purpose: PURPOSE_BUGFIX } } flag { name: "current_animator_scale_uses_shared_memory" namespace: "wear_system_health" Loading
libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java +48 −17 Original line number Diff line number Diff line Loading @@ -159,6 +159,7 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont * (and navigation) associated with {@link #mCurrentTracker} have not yet finished. */ private BackTouchTracker mQueuedTracker = new BackTouchTracker(); private final TransitionIdleRunner mTransitionIdleRunner = new TransitionIdleRunner(); private final BackTransitionObserver mBackTransitionObserver = new BackTransitionObserver(); Loading Loading @@ -470,9 +471,17 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont tryPilferPointers(); } if (predictiveBackDelayWmTransition()) { startPredictiveBackAnimationIfNeeded(); } private void startPredictiveBackAnimationIfNeeded() { if (!predictiveBackDelayWmTransition() || !mThresholdCrossed) { return; } mShellExecutor.execute(() -> { if (shouldDispatchToAnimator()) { if (!shouldDispatchToAnimator()) { return; } try { mActivityTaskManager.startPredictiveBackAnimation(); } catch (RemoteException r) { Loading @@ -485,10 +494,8 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont mActiveCallback = null; } requestTopUi(true, backType); } }); } } private boolean isAppProgressGenerationAllowed() { return mBackNavigationInfo.isAppProgressGenerationAllowed() Loading Loading @@ -624,6 +631,22 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont } } private class TransitionIdleRunner implements Runnable { boolean mIsEnable; @Override public void run() { if (!mIsEnable || !mCurrentTracker.isActive()) { return; } ProtoLog.d(WM_SHELL_BACK_PREVIEW, "Gesture hasn't finish after transition " + "idle, start back navigation again."); mIsEnable = false; startBackNavigation(mCurrentTracker); startPredictiveBackAnimationIfNeeded(); } } private void onBackNavigationInfoReceived(@Nullable BackNavigationInfo backNavigationInfo, @NonNull BackTouchTracker touchTracker) { ProtoLog.d(WM_SHELL_BACK_PREVIEW, "Received backNavigationInfo:%s", backNavigationInfo); Loading @@ -635,6 +658,13 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont return; } final int backType = backNavigationInfo.getType(); if (backType == BackNavigationInfo.TYPE_IN_TRANSITION) { mBackNavigationInfo = null; tryPilferPointers(); mTransitionIdleRunner.mIsEnable = true; mTransitions.runOnIdle(() -> mShellExecutor.execute(mTransitionIdleRunner)); return; } final boolean shouldDispatchToAnimator = shouldDispatchToAnimator(); if (shouldDispatchToAnimator) { if (!predictiveBackDelayWmTransition()) { Loading Loading @@ -859,6 +889,7 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont mPointersPilfered = false; mBackGestureStarted = false; activeTouchTracker.setState(BackTouchTracker.TouchTrackerState.FINISHED); mTransitionIdleRunner.mIsEnable = false; if (mPostCommitAnimationInProgress) { ProtoLog.w(WM_SHELL_BACK_PREVIEW, "Animation is still running"); Loading
libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/back/BackAnimationControllerTest.java +15 −0 Original line number Diff line number Diff line Loading @@ -60,6 +60,7 @@ import android.os.Handler; import android.os.IBinder; import android.os.RemoteCallback; import android.os.RemoteException; import android.platform.test.annotations.EnableFlags; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; import android.view.IRemoteAnimationRunner; Loading @@ -81,6 +82,7 @@ import android.window.WindowContainerToken; import androidx.annotation.Nullable; import androidx.test.filters.SmallTest; import com.android.window.flags.Flags; import com.android.wm.shell.RootTaskDisplayAreaOrganizer; import com.android.wm.shell.ShellTestCase; import com.android.wm.shell.TestShellExecutor; Loading Loading @@ -276,6 +278,19 @@ public class BackAnimationControllerTest extends ShellTestCase { } } @EnableFlags(Flags.FLAG_PREDICTIVE_BACK_INTERCEPT_TRANSITION) @Test public void noStartInTransition() throws RemoteException { registerAnimation(BackNavigationInfo.TYPE_RETURN_TO_HOME); createNavigationInfo(BackNavigationInfo.TYPE_IN_TRANSITION, /* enableAnimation = */ true, /* isAnimationCallback = */ false); doStartEvents(0, 100); verify(mAppCallback, never()).onBackStarted(any()); verify(mTransitions).runOnIdle(any()); } @Test public void backToHome_dispatchesEvents() throws RemoteException { registerAnimation(BackNavigationInfo.TYPE_RETURN_TO_HOME); Loading
services/core/java/com/android/server/wm/BackNavigationController.java +16 −4 Original line number Diff line number Diff line Loading @@ -98,9 +98,13 @@ class BackNavigationController { // back animation. private AnimationHandler.ScheduleAnimationBuilder mCurrentAnimationBuilder; // 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. /** * 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. * * @deprecated Remove after Flags#predictive_back_intercept_transition */ private AnimationHandler.ScheduleAnimationBuilder mPendingAnimationBuilder; private static int sDefaultAnimationResId; Loading Loading @@ -228,6 +232,13 @@ class BackNavigationController { return null; } if (Flags.predictiveBackInterceptTransition() && window.mTransitionController.inTransition()) { infoBuilder.setType(BackNavigationInfo.TYPE_IN_TRANSITION); ProtoLog.d(WM_DEBUG_BACK_PREVIEW, "A transition is happening."); return infoBuilder.build(); } final ArrayList<EmbeddedWindowController.EmbeddedWindow> embeddedWindows = wmService .mEmbeddedWindowController.getByHostWindow(window); Loading Loading @@ -2223,7 +2234,8 @@ class BackNavigationController { } private void scheduleAnimationInner(AnimationHandler.ScheduleAnimationBuilder builder) { if (mWindowManagerService.mAtmService.getTransitionController().inTransition()) { if (!Flags.predictiveBackInterceptTransition() && mWindowManagerService.mAtmService.getTransitionController().inTransition()) { ProtoLog.w(WM_DEBUG_BACK_PREVIEW, "Pending back animation due to another animation is running"); mPendingAnimationBuilder = builder; Loading