Loading core/java/android/window/BackProgressAnimator.java +26 −4 Original line number Diff line number Diff line Loading @@ -16,8 +16,11 @@ package android.window; import static android.window.BackEvent.EDGE_NONE; import static com.android.internal.annotations.VisibleForTesting.Visibility.PACKAGE; import static com.android.window.flags.Flags.predictiveBackTimestampApi; import static com.android.window.flags.Flags.predictiveBackSwipeEdgeNoneApi; import android.annotation.NonNull; import android.annotation.Nullable; Loading Loading @@ -60,6 +63,12 @@ public class BackProgressAnimator implements DynamicAnimation.OnAnimationUpdateL @Nullable private Runnable mBackInvokedFinishRunnable; private FlingAnimation mBackInvokedFlingAnim; private final SpringForce mGestureSpringForce = new SpringForce() .setStiffness(SpringForce.STIFFNESS_MEDIUM) .setDampingRatio(SpringForce.DAMPING_RATIO_NO_BOUNCY); private final SpringForce mButtonSpringForce = new SpringForce() .setStiffness(500) .setDampingRatio(SpringForce.DAMPING_RATIO_NO_BOUNCY); private final DynamicAnimation.OnAnimationEndListener mOnAnimationEndListener = (animation, canceled, value, velocity) -> { if (mBackCancelledFinishRunnable != null) invokeBackCancelledRunnable(); Loading Loading @@ -109,9 +118,7 @@ public class BackProgressAnimator implements DynamicAnimation.OnAnimationUpdateL public BackProgressAnimator() { mSpring = new SpringAnimation(this, PROGRESS_PROP); mSpring.addUpdateListener(this); mSpring.setSpring(new SpringForce() .setStiffness(SpringForce.STIFFNESS_MEDIUM) .setDampingRatio(SpringForce.DAMPING_RATIO_NO_BOUNCY)); mSpring.setSpring(mGestureSpringForce); } /** Loading @@ -123,6 +130,11 @@ public class BackProgressAnimator implements DynamicAnimation.OnAnimationUpdateL if (!mBackAnimationInProgress) { return; } if (predictiveBackSwipeEdgeNoneApi()) { if (event.getSwipeEdge() == EDGE_NONE) { return; } } mLastBackEvent = event; if (mSpring == null) { return; Loading @@ -143,8 +155,18 @@ public class BackProgressAnimator implements DynamicAnimation.OnAnimationUpdateL mBackAnimationInProgress = true; updateProgressValue(/* progress */ 0, /* velocity */ 0, /* frameTime */ System.nanoTime() / TimeUtils.NANOS_PER_MS); if (predictiveBackSwipeEdgeNoneApi()) { if (event.getSwipeEdge() == EDGE_NONE) { mSpring.setSpring(mButtonSpringForce); mSpring.animateToFinalPosition(SCALE_FACTOR); } else { mSpring.setSpring(mGestureSpringForce); onBackProgressed(event); } } else { onBackProgressed(event); } } /** * Resets the back progress animation. This should be called when back is invoked or cancelled. Loading core/java/android/window/flags/windowing_frontend.aconfig +8 −1 Original line number Diff line number Diff line Loading @@ -389,3 +389,10 @@ flag { is_fixed_read_only: true bug: "362938401" } flag { name: "predictive_back_three_button_nav" namespace: "systemui" description: "Enable Predictive Back Animation for 3-button-nav" bug: "373544911" } libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java +15 −1 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ import static android.view.RemoteAnimationTarget.MODE_CLOSING; import static android.view.RemoteAnimationTarget.MODE_OPENING; import static android.view.WindowManager.TRANSIT_CHANGE; import static android.view.WindowManager.TRANSIT_CLOSE_PREPARE_BACK_NAVIGATION; import static android.window.BackEvent.EDGE_NONE; import static android.window.TransitionInfo.FLAG_BACK_GESTURE_ANIMATED; import static android.window.TransitionInfo.FLAG_IS_WALLPAPER; import static android.window.TransitionInfo.FLAG_MOVED_TO_TOP; Loading Loading @@ -533,8 +534,16 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont if (keyAction == MotionEvent.ACTION_DOWN) { if (!mBackGestureStarted) { if (swipeEdge == EDGE_NONE) { // start animation immediately for non-gestural sources (without ACTION_MOVE // events) mThresholdCrossed = true; onGestureStarted(touchX, touchY, swipeEdge); mShouldStartOnNextMoveEvent = false; } else { mShouldStartOnNextMoveEvent = true; } } } else if (keyAction == MotionEvent.ACTION_MOVE) { if (!mBackGestureStarted && mShouldStartOnNextMoveEvent) { // Let the animation initialized here to make sure the onPointerDownOutsideFocus Loading Loading @@ -1074,6 +1083,11 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont mCurrentTracker.updateStartLocation(); BackMotionEvent startEvent = mCurrentTracker.createStartEvent(mApps[0]); dispatchOnBackStarted(mActiveCallback, startEvent); // TODO(b/373544911): onBackStarted is dispatched here so that // WindowOnBackInvokedDispatcher knows about the back navigation and intercepts touch // events while it's active. It would be cleaner and safer to disable multitouch // altogether (same as in gesture-nav). dispatchOnBackStarted(mBackNavigationInfo.getOnBackInvokedCallback(), startEvent); } } Loading packages/SystemUI/shared/src/com/android/systemui/shared/recents/ISystemUiProxy.aidl +3 −2 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ import android.graphics.Insets; import android.graphics.Rect; import android.os.Bundle; import android.os.UserHandle; import android.view.KeyEvent; import android.view.MotionEvent; import com.android.internal.util.ScreenshotRequest; Loading Loading @@ -102,9 +103,9 @@ interface ISystemUiProxy { oneway void expandNotificationPanel() = 29; /** * Notifies SystemUI to invoke Back. * Notifies SystemUI of a back KeyEvent. */ oneway void onBackPressed() = 44; oneway void onBackEvent(in KeyEvent keyEvent) = 44; /** Sets home rotation enabled. */ oneway void setHomeRotationEnabled(boolean enabled) = 45; Loading packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java +7 −5 Original line number Diff line number Diff line Loading @@ -1191,12 +1191,14 @@ public class EdgeBackGestureHandler implements PluginListener<NavigationEdgeBack } private void pilferPointers() { if (mInputMonitor != null) { // Capture inputs mInputMonitor.pilferPointers(); // Notify FalsingManager that an intentional gesture has occurred. mFalsingManager.isFalseTouch(BACK_GESTURE); mInputEventReceiver.setBatchingEnabled(true); } } private boolean isButtonPressFromTrackpad(MotionEvent ev) { // We don't allow back for button press from the trackpad, and yet we do with a mouse. Loading Loading
core/java/android/window/BackProgressAnimator.java +26 −4 Original line number Diff line number Diff line Loading @@ -16,8 +16,11 @@ package android.window; import static android.window.BackEvent.EDGE_NONE; import static com.android.internal.annotations.VisibleForTesting.Visibility.PACKAGE; import static com.android.window.flags.Flags.predictiveBackTimestampApi; import static com.android.window.flags.Flags.predictiveBackSwipeEdgeNoneApi; import android.annotation.NonNull; import android.annotation.Nullable; Loading Loading @@ -60,6 +63,12 @@ public class BackProgressAnimator implements DynamicAnimation.OnAnimationUpdateL @Nullable private Runnable mBackInvokedFinishRunnable; private FlingAnimation mBackInvokedFlingAnim; private final SpringForce mGestureSpringForce = new SpringForce() .setStiffness(SpringForce.STIFFNESS_MEDIUM) .setDampingRatio(SpringForce.DAMPING_RATIO_NO_BOUNCY); private final SpringForce mButtonSpringForce = new SpringForce() .setStiffness(500) .setDampingRatio(SpringForce.DAMPING_RATIO_NO_BOUNCY); private final DynamicAnimation.OnAnimationEndListener mOnAnimationEndListener = (animation, canceled, value, velocity) -> { if (mBackCancelledFinishRunnable != null) invokeBackCancelledRunnable(); Loading Loading @@ -109,9 +118,7 @@ public class BackProgressAnimator implements DynamicAnimation.OnAnimationUpdateL public BackProgressAnimator() { mSpring = new SpringAnimation(this, PROGRESS_PROP); mSpring.addUpdateListener(this); mSpring.setSpring(new SpringForce() .setStiffness(SpringForce.STIFFNESS_MEDIUM) .setDampingRatio(SpringForce.DAMPING_RATIO_NO_BOUNCY)); mSpring.setSpring(mGestureSpringForce); } /** Loading @@ -123,6 +130,11 @@ public class BackProgressAnimator implements DynamicAnimation.OnAnimationUpdateL if (!mBackAnimationInProgress) { return; } if (predictiveBackSwipeEdgeNoneApi()) { if (event.getSwipeEdge() == EDGE_NONE) { return; } } mLastBackEvent = event; if (mSpring == null) { return; Loading @@ -143,8 +155,18 @@ public class BackProgressAnimator implements DynamicAnimation.OnAnimationUpdateL mBackAnimationInProgress = true; updateProgressValue(/* progress */ 0, /* velocity */ 0, /* frameTime */ System.nanoTime() / TimeUtils.NANOS_PER_MS); if (predictiveBackSwipeEdgeNoneApi()) { if (event.getSwipeEdge() == EDGE_NONE) { mSpring.setSpring(mButtonSpringForce); mSpring.animateToFinalPosition(SCALE_FACTOR); } else { mSpring.setSpring(mGestureSpringForce); onBackProgressed(event); } } else { onBackProgressed(event); } } /** * Resets the back progress animation. This should be called when back is invoked or cancelled. Loading
core/java/android/window/flags/windowing_frontend.aconfig +8 −1 Original line number Diff line number Diff line Loading @@ -389,3 +389,10 @@ flag { is_fixed_read_only: true bug: "362938401" } flag { name: "predictive_back_three_button_nav" namespace: "systemui" description: "Enable Predictive Back Animation for 3-button-nav" bug: "373544911" }
libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java +15 −1 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ import static android.view.RemoteAnimationTarget.MODE_CLOSING; import static android.view.RemoteAnimationTarget.MODE_OPENING; import static android.view.WindowManager.TRANSIT_CHANGE; import static android.view.WindowManager.TRANSIT_CLOSE_PREPARE_BACK_NAVIGATION; import static android.window.BackEvent.EDGE_NONE; import static android.window.TransitionInfo.FLAG_BACK_GESTURE_ANIMATED; import static android.window.TransitionInfo.FLAG_IS_WALLPAPER; import static android.window.TransitionInfo.FLAG_MOVED_TO_TOP; Loading Loading @@ -533,8 +534,16 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont if (keyAction == MotionEvent.ACTION_DOWN) { if (!mBackGestureStarted) { if (swipeEdge == EDGE_NONE) { // start animation immediately for non-gestural sources (without ACTION_MOVE // events) mThresholdCrossed = true; onGestureStarted(touchX, touchY, swipeEdge); mShouldStartOnNextMoveEvent = false; } else { mShouldStartOnNextMoveEvent = true; } } } else if (keyAction == MotionEvent.ACTION_MOVE) { if (!mBackGestureStarted && mShouldStartOnNextMoveEvent) { // Let the animation initialized here to make sure the onPointerDownOutsideFocus Loading Loading @@ -1074,6 +1083,11 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont mCurrentTracker.updateStartLocation(); BackMotionEvent startEvent = mCurrentTracker.createStartEvent(mApps[0]); dispatchOnBackStarted(mActiveCallback, startEvent); // TODO(b/373544911): onBackStarted is dispatched here so that // WindowOnBackInvokedDispatcher knows about the back navigation and intercepts touch // events while it's active. It would be cleaner and safer to disable multitouch // altogether (same as in gesture-nav). dispatchOnBackStarted(mBackNavigationInfo.getOnBackInvokedCallback(), startEvent); } } Loading
packages/SystemUI/shared/src/com/android/systemui/shared/recents/ISystemUiProxy.aidl +3 −2 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ import android.graphics.Insets; import android.graphics.Rect; import android.os.Bundle; import android.os.UserHandle; import android.view.KeyEvent; import android.view.MotionEvent; import com.android.internal.util.ScreenshotRequest; Loading Loading @@ -102,9 +103,9 @@ interface ISystemUiProxy { oneway void expandNotificationPanel() = 29; /** * Notifies SystemUI to invoke Back. * Notifies SystemUI of a back KeyEvent. */ oneway void onBackPressed() = 44; oneway void onBackEvent(in KeyEvent keyEvent) = 44; /** Sets home rotation enabled. */ oneway void setHomeRotationEnabled(boolean enabled) = 45; Loading
packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java +7 −5 Original line number Diff line number Diff line Loading @@ -1191,12 +1191,14 @@ public class EdgeBackGestureHandler implements PluginListener<NavigationEdgeBack } private void pilferPointers() { if (mInputMonitor != null) { // Capture inputs mInputMonitor.pilferPointers(); // Notify FalsingManager that an intentional gesture has occurred. mFalsingManager.isFalseTouch(BACK_GESTURE); mInputEventReceiver.setBatchingEnabled(true); } } private boolean isButtonPressFromTrackpad(MotionEvent ev) { // We don't allow back for button press from the trackpad, and yet we do with a mouse. Loading