diff options
5 files changed, 76 insertions, 9 deletions
diff --git a/core/java/android/window/BackNavigationInfo.java b/core/java/android/window/BackNavigationInfo.java index f24bc74dab7d..57bded7ff2a0 100644 --- a/core/java/android/window/BackNavigationInfo.java +++ b/core/java/android/window/BackNavigationInfo.java @@ -23,6 +23,7 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.TestApi; import android.graphics.Color; +import android.graphics.Rect; import android.os.Bundle; import android.os.Parcel; import android.os.Parcelable; @@ -113,6 +114,8 @@ public final class BackNavigationInfo implements Parcelable { private final CustomAnimationInfo mCustomAnimationInfo; private final int mLetterboxColor; + @NonNull + private final Rect mTouchableRegion; /** * Create a new {@link BackNavigationInfo} instance. @@ -128,7 +131,8 @@ public final class BackNavigationInfo implements Parcelable { boolean isPrepareRemoteAnimation, boolean isAnimationCallback, @Nullable CustomAnimationInfo customAnimationInfo, - int letterboxColor) { + int letterboxColor, + @Nullable Rect touchableRegion) { mType = type; mOnBackNavigationDone = onBackNavigationDone; mOnBackInvokedCallback = onBackInvokedCallback; @@ -136,6 +140,7 @@ public final class BackNavigationInfo implements Parcelable { mAnimationCallback = isAnimationCallback; mCustomAnimationInfo = customAnimationInfo; mLetterboxColor = letterboxColor; + mTouchableRegion = new Rect(touchableRegion); } private BackNavigationInfo(@NonNull Parcel in) { @@ -146,6 +151,7 @@ public final class BackNavigationInfo implements Parcelable { mAnimationCallback = in.readBoolean(); mCustomAnimationInfo = in.readTypedObject(CustomAnimationInfo.CREATOR); mLetterboxColor = in.readInt(); + mTouchableRegion = in.readTypedObject(Rect.CREATOR); } /** @hide */ @@ -158,6 +164,7 @@ public final class BackNavigationInfo implements Parcelable { dest.writeBoolean(mAnimationCallback); dest.writeTypedObject(mCustomAnimationInfo, flags); dest.writeInt(mLetterboxColor); + dest.writeTypedObject(mTouchableRegion, flags); } /** @@ -206,6 +213,16 @@ public final class BackNavigationInfo implements Parcelable { public int getLetterboxColor() { return mLetterboxColor; } + + /** + * @return The app window region where the client can handle touch event. + * @hide + */ + @NonNull + public Rect getTouchableRegion() { + return mTouchableRegion; + } + /** * Callback to be called when the back preview is finished in order to notify the server that * it can clean up the resources created for the animation. @@ -402,6 +419,7 @@ public final class BackNavigationInfo implements Parcelable { private boolean mAnimationCallback = false; private int mLetterboxColor = Color.TRANSPARENT; + private Rect mTouchableRegion; /** * @see BackNavigationInfo#getType() @@ -478,6 +496,13 @@ public final class BackNavigationInfo implements Parcelable { } /** + * @param rect Non-empty for frame of current focus window. + */ + public Builder setTouchableRegion(Rect rect) { + mTouchableRegion = new Rect(rect); + return this; + } + /** * Builds and returns an instance of {@link BackNavigationInfo} */ public BackNavigationInfo build() { @@ -486,7 +511,8 @@ public final class BackNavigationInfo implements Parcelable { mPrepareRemoteAnimation, mAnimationCallback, mCustomAnimationInfo, - mLetterboxColor); + mLetterboxColor, + mTouchableRegion); } } } diff --git a/core/java/android/window/WindowOnBackInvokedDispatcher.java b/core/java/android/window/WindowOnBackInvokedDispatcher.java index b7f6f363dd04..4ca64e73ad7c 100644 --- a/core/java/android/window/WindowOnBackInvokedDispatcher.java +++ b/core/java/android/window/WindowOnBackInvokedDispatcher.java @@ -435,7 +435,16 @@ public class WindowOnBackInvokedDispatcher implements OnBackInvokedDispatcher { } @Override - public void onBackProgressed(BackMotionEvent backEvent) { } + public void onBackProgressed(BackMotionEvent backEvent) { + // This is only called in some special cases such as when activity embedding is active + // or when the activity is letterboxed. Otherwise mProgressAnimator#onBackProgressed is + // called from WindowOnBackInvokedDispatcher#onMotionEvent + mHandler.post(() -> { + if (getBackAnimationCallback() != null) { + mProgressAnimator.onBackProgressed(backEvent); + } + }); + } @Override public void onBackCancelled() { diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java index 0119289cb0da..0fd21f3798ac 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java @@ -30,6 +30,7 @@ import android.content.ContentResolver; import android.content.Context; import android.content.res.Configuration; import android.database.ContentObserver; +import android.graphics.Rect; import android.hardware.input.InputManager; import android.net.Uri; import android.os.Bundle; @@ -47,6 +48,7 @@ import android.view.KeyCharacterMap; import android.view.KeyEvent; import android.view.MotionEvent; import android.view.RemoteAnimationTarget; +import android.view.WindowManager; import android.window.BackAnimationAdapter; import android.window.BackEvent; import android.window.BackMotionEvent; @@ -119,6 +121,9 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont private final ShellCommandHandler mShellCommandHandler; private final ShellExecutor mShellExecutor; private final Handler mBgHandler; + private final WindowManager mWindowManager; + @VisibleForTesting + final Rect mTouchableArea = new Rect(); /** * Tracks the current user back gesture. @@ -222,6 +227,8 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont mShellBackAnimationRegistry = shellBackAnimationRegistry; mLatencyTracker = LatencyTracker.getInstance(mContext); mShellCommandHandler = shellCommandHandler; + mWindowManager = context.getSystemService(WindowManager.class); + updateTouchableArea(); } private void onInit() { @@ -283,6 +290,11 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont @Override public void onConfigurationChanged(Configuration newConfig) { mShellBackAnimationRegistry.onConfigurationChanged(newConfig); + updateTouchableArea(); + } + + private void updateTouchableArea() { + mTouchableArea.set(mWindowManager.getCurrentWindowMetrics().getBounds()); } @Override @@ -416,11 +428,18 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont if (!shouldDispatchToAnimator && mActiveCallback != null) { mCurrentTracker.updateStartLocation(); tryDispatchOnBackStarted(mActiveCallback, mCurrentTracker.createStartEvent(null)); + if (mBackNavigationInfo != null && !isAppProgressGenerationAllowed()) { + tryPilferPointers(); + } } else if (shouldDispatchToAnimator) { tryPilferPointers(); } } + private boolean isAppProgressGenerationAllowed() { + return mBackNavigationInfo.getTouchableRegion().equals(mTouchableArea); + } + /** * Called when a new motion event needs to be transferred to this * {@link BackAnimationController} @@ -536,6 +555,9 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont // App is handling back animation. Cancel system animation latency tracking. cancelLatencyTracking(); tryDispatchOnBackStarted(mActiveCallback, touchTracker.createStartEvent(null)); + if (!isAppProgressGenerationAllowed()) { + tryPilferPointers(); + } } } @@ -642,7 +664,8 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont private void dispatchOnBackProgressed(IOnBackInvokedCallback callback, BackMotionEvent backEvent) { - if (callback == null || !shouldDispatchToAnimator()) { + if (callback == null || (!shouldDispatchToAnimator() && mBackNavigationInfo != null + && isAppProgressGenerationAllowed())) { return; } try { diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/back/BackAnimationControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/back/BackAnimationControllerTest.java index f6f3aa49bc6e..1903586fc317 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/back/BackAnimationControllerTest.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/back/BackAnimationControllerTest.java @@ -123,6 +123,7 @@ public class BackAnimationControllerTest extends ShellTestCase { private DefaultCrossActivityBackAnimation mDefaultCrossActivityBackAnimation; private CrossTaskBackAnimation mCrossTaskBackAnimation; private ShellBackAnimationRegistry mShellBackAnimationRegistry; + private Rect mTouchableRegion; @Before public void setUp() throws Exception { @@ -158,6 +159,8 @@ public class BackAnimationControllerTest extends ShellTestCase { mShellCommandHandler); mShellInit.init(); mShellExecutor.flushAll(); + mTouchableRegion = new Rect(0, 0, 100, 100); + mController.mTouchableArea.set(mTouchableRegion); } private void createNavigationInfo(int backType, @@ -169,7 +172,8 @@ public class BackAnimationControllerTest extends ShellTestCase { .setOnBackNavigationDone(new RemoteCallback((bundle) -> {})) .setOnBackInvokedCallback(mAppCallback) .setPrepareRemoteAnimation(enableAnimation) - .setAnimationCallback(isAnimationCallback); + .setAnimationCallback(isAnimationCallback) + .setTouchableRegion(mTouchableRegion); createNavigationInfo(builder); } @@ -234,7 +238,8 @@ public class BackAnimationControllerTest extends ShellTestCase { .setType(type) .setOnBackInvokedCallback(mAppCallback) .setPrepareRemoteAnimation(true) - .setOnBackNavigationDone(new RemoteCallback(result))); + .setOnBackNavigationDone(new RemoteCallback(result)) + .setTouchableRegion(mTouchableRegion)); triggerBackGesture(); simulateRemoteAnimationStart(); mShellExecutor.flushAll(); @@ -512,7 +517,8 @@ public class BackAnimationControllerTest extends ShellTestCase { .setType(type) .setOnBackInvokedCallback(mAppCallback) .setPrepareRemoteAnimation(true) - .setOnBackNavigationDone(new RemoteCallback(result))); + .setOnBackNavigationDone(new RemoteCallback(result)) + .setTouchableRegion(mTouchableRegion)); triggerBackGesture(); simulateRemoteAnimationStart(); mShellExecutor.flushAll(); @@ -543,7 +549,8 @@ public class BackAnimationControllerTest extends ShellTestCase { createNavigationInfo(new BackNavigationInfo.Builder() .setType(type) .setOnBackInvokedCallback(mAppCallback) - .setOnBackNavigationDone(new RemoteCallback(result))); + .setOnBackNavigationDone(new RemoteCallback(result)) + .setTouchableRegion(mTouchableRegion)); triggerBackGesture(); mShellExecutor.flushAll(); releaseBackGesture(); @@ -570,7 +577,8 @@ public class BackAnimationControllerTest extends ShellTestCase { createNavigationInfo(new BackNavigationInfo.Builder() .setType(type) .setOnBackInvokedCallback(mAppCallback) - .setOnBackNavigationDone(new RemoteCallback(result))); + .setOnBackNavigationDone(new RemoteCallback(result)) + .setTouchableRegion(mTouchableRegion)); doMotionEvent(MotionEvent.ACTION_CANCEL, 0); mShellExecutor.flushAll(); diff --git a/services/core/java/com/android/server/wm/BackNavigationController.java b/services/core/java/com/android/server/wm/BackNavigationController.java index f91ef1d41a0c..0febec9169c0 100644 --- a/services/core/java/com/android/server/wm/BackNavigationController.java +++ b/services/core/java/com/android/server/wm/BackNavigationController.java @@ -200,6 +200,7 @@ class BackNavigationController { } infoBuilder.setOnBackInvokedCallback(callbackInfo.getCallback()); infoBuilder.setAnimationCallback(callbackInfo.isAnimationCallback()); + infoBuilder.setTouchableRegion(window.getFrame()); mNavigationMonitor.startMonitor(window, navigationObserver); ProtoLog.d(WM_DEBUG_BACK_PREVIEW, "startBackNavigation currentTask=%s, " |