summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/window/BackEvent.java6
-rw-r--r--core/java/android/window/ImeOnBackInvokedDispatcher.java186
-rw-r--r--core/java/android/window/WindowOnBackInvokedDispatcher.java106
3 files changed, 108 insertions, 190 deletions
diff --git a/core/java/android/window/BackEvent.java b/core/java/android/window/BackEvent.java
index 55623608b025..d3733b71f7ee 100644
--- a/core/java/android/window/BackEvent.java
+++ b/core/java/android/window/BackEvent.java
@@ -48,6 +48,12 @@ public final class BackEvent {
@SwipeEdge
private final int mSwipeEdge;
+ /** @hide */
+ public static BackEvent fromBackMotionEvent(BackMotionEvent backMotionEvent) {
+ return new BackEvent(backMotionEvent.getTouchX(), backMotionEvent.getTouchY(),
+ backMotionEvent.getProgress(), backMotionEvent.getSwipeEdge());
+ }
+
/**
* Creates a new {@link BackEvent} instance.
*
diff --git a/core/java/android/window/ImeOnBackInvokedDispatcher.java b/core/java/android/window/ImeOnBackInvokedDispatcher.java
index 3b9b16270600..2a12507679f5 100644
--- a/core/java/android/window/ImeOnBackInvokedDispatcher.java
+++ b/core/java/android/window/ImeOnBackInvokedDispatcher.java
@@ -32,6 +32,7 @@ import android.view.ViewRootImpl;
import com.android.internal.annotations.VisibleForTesting;
import java.util.ArrayList;
+import java.util.function.Consumer;
/**
* A {@link OnBackInvokedDispatcher} for IME that forwards {@link OnBackInvokedCallback}
@@ -52,17 +53,8 @@ public class ImeOnBackInvokedDispatcher implements OnBackInvokedDispatcher, Parc
static final String RESULT_KEY_PRIORITY = "priority";
static final int RESULT_CODE_REGISTER = 0;
static final int RESULT_CODE_UNREGISTER = 1;
- static final int RESULT_CODE_START_DISPATCHING = 2;
- static final int RESULT_CODE_STOP_DISPATCHING = 3;
@NonNull
private final ResultReceiver mResultReceiver;
- @NonNull
- private final BackProgressAnimator mProgressAnimator = new BackProgressAnimator();
- @NonNull
- private final BackTouchTracker mTouchTracker = new BackTouchTracker();
- // The handler to run callbacks on. This should be on the same thread
- // the ViewRootImpl holding IME's WindowOnBackInvokedDispatcher is created on.
- private Handler mHandler;
public ImeOnBackInvokedDispatcher(Handler handler) {
mResultReceiver = new ResultReceiver(handler) {
@@ -89,10 +81,6 @@ public class ImeOnBackInvokedDispatcher implements OnBackInvokedDispatcher, Parc
mResultReceiver = in.readTypedObject(ResultReceiver.CREATOR);
}
- void setHandler(@NonNull Handler handler) {
- mHandler = handler;
- }
-
@Override
public void registerOnBackInvokedCallback(
@OnBackInvokedDispatcher.Priority int priority,
@@ -103,14 +91,7 @@ public class ImeOnBackInvokedDispatcher implements OnBackInvokedDispatcher, Parc
// This is necessary because the callback is sent to and registered from
// the app process, which may treat the IME callback as weakly referenced. This will not
// cause a memory leak because the app side already clears the reference correctly.
- final IOnBackInvokedCallback iCallback =
- new ImeOnBackInvokedCallbackWrapper(
- callback,
- mTouchTracker,
- mProgressAnimator,
- this,
- mHandler != null ? mHandler : Handler.getMain(),
- false /* useWeakRef */);
+ final IOnBackInvokedCallback iCallback = new ImeOnBackInvokedCallbackWrapper(callback);
bundle.putBinder(RESULT_KEY_CALLBACK, iCallback.asBinder());
bundle.putInt(RESULT_KEY_PRIORITY, priority);
bundle.putInt(RESULT_KEY_ID, callback.hashCode());
@@ -135,12 +116,6 @@ public class ImeOnBackInvokedDispatcher implements OnBackInvokedDispatcher, Parc
dest.writeTypedObject(mResultReceiver, flags);
}
- /** Sets the progress thresholds for touch tracking */
- public void setProgressThresholds(float linearDistance, float maxDistance,
- float nonLinearFactor) {
- mTouchTracker.setProgressThresholds(linearDistance, maxDistance, nonLinearFactor);
- }
-
@NonNull
public static final Parcelable.Creator<ImeOnBackInvokedDispatcher> CREATOR =
new Parcelable.Creator<ImeOnBackInvokedDispatcher>() {
@@ -162,15 +137,10 @@ public class ImeOnBackInvokedDispatcher implements OnBackInvokedDispatcher, Parc
int priority = resultData.getInt(RESULT_KEY_PRIORITY);
final IOnBackInvokedCallback callback = IOnBackInvokedCallback.Stub.asInterface(
resultData.getBinder(RESULT_KEY_CALLBACK));
- registerReceivedCallback(
- callback, priority, callbackId, receivingDispatcher);
+ registerReceivedCallback(callback, priority, callbackId, receivingDispatcher);
} else if (resultCode == RESULT_CODE_UNREGISTER) {
final int callbackId = resultData.getInt(RESULT_KEY_ID);
unregisterReceivedCallback(callbackId, receivingDispatcher);
- } else if (resultCode == RESULT_CODE_START_DISPATCHING) {
- receiveStartDispatching(receivingDispatcher);
- } else if (resultCode == RESULT_CODE_STOP_DISPATCHING) {
- receiveStopDispatching(receivingDispatcher);
}
}
@@ -212,63 +182,6 @@ public class ImeOnBackInvokedDispatcher implements OnBackInvokedDispatcher, Parc
mImeCallbacks.remove(callback);
}
- static class ImeOnBackInvokedCallbackWrapper extends
- WindowOnBackInvokedDispatcher.OnBackInvokedCallbackWrapper {
- @NonNull
- private final ImeOnBackInvokedDispatcher mDispatcher;
-
- ImeOnBackInvokedCallbackWrapper(
- @NonNull OnBackInvokedCallback callback,
- @NonNull BackTouchTracker touchTracker,
- @NonNull BackProgressAnimator progressAnimator,
- @NonNull ImeOnBackInvokedDispatcher dispatcher,
- @NonNull Handler handler,
- boolean useWeakRef) {
- super(callback, touchTracker, progressAnimator, handler, useWeakRef);
- mDispatcher = dispatcher;
- }
-
- @Override
- public void onBackStarted(BackMotionEvent backEvent) {
- super.onBackStarted(backEvent);
- mDispatcher.sendStartDispatching();
- }
-
- @Override
- public void onBackCancelled() {
- super.onBackCancelled();
- mDispatcher.sendStopDispatching();
- }
-
- @Override
- public void onBackInvoked() throws RemoteException {
- super.onBackInvoked();
- mDispatcher.sendStopDispatching();
- }
- }
-
- /** Notifies the app process that we've stopped dispatching to an IME callback */
- private void sendStopDispatching() {
- mResultReceiver.send(RESULT_CODE_STOP_DISPATCHING, null /* unused bundle */);
- }
-
- /** Notifies the app process that we've started dispatching to an IME callback */
- private void sendStartDispatching() {
- mResultReceiver.send(RESULT_CODE_START_DISPATCHING, null /* unused bundle */);
- }
-
- /** Receives IME's message that dispatching has started. */
- private void receiveStopDispatching(
- @NonNull WindowOnBackInvokedDispatcher receivingDispatcher) {
- receivingDispatcher.onStopImeDispatching();
- }
-
- /** Receives IME's message that dispatching has stopped. */
- private void receiveStartDispatching(
- @NonNull WindowOnBackInvokedDispatcher receivingDispatcher) {
- receivingDispatcher.onStartImeDispatching();
- }
-
/** Clears all registered callbacks on the instance. */
public void clear() {
// Unregister previously registered callbacks if there's any.
@@ -278,14 +191,10 @@ public class ImeOnBackInvokedDispatcher implements OnBackInvokedDispatcher, Parc
}
}
mImeCallbacks.clear();
- // We should also stop running animations since all callbacks have been removed.
- // note: mSpring.skipToEnd(), in ProgressAnimator.reset(), requires the main handler.
- Handler.getMain().post(mProgressAnimator::reset);
- sendStopDispatching();
}
@VisibleForTesting(visibility = PACKAGE)
- public static class ImeOnBackInvokedCallback implements OnBackInvokedCallback {
+ public static class ImeOnBackInvokedCallback implements OnBackAnimationCallback {
@NonNull
private final IOnBackInvokedCallback mIOnBackInvokedCallback;
/**
@@ -303,22 +212,49 @@ public class ImeOnBackInvokedDispatcher implements OnBackInvokedDispatcher, Parc
}
@Override
+ public void onBackStarted(@NonNull BackEvent backEvent) {
+ try {
+ mIOnBackInvokedCallback.onBackStarted(
+ new BackMotionEvent(backEvent.getTouchX(), backEvent.getTouchY(),
+ backEvent.getProgress(), 0f, 0f, false, backEvent.getSwipeEdge(),
+ null));
+ } catch (RemoteException e) {
+ Log.e(TAG, "Exception when invoking forwarded callback. e: ", e);
+ }
+ }
+
+ @Override
+ public void onBackProgressed(@NonNull BackEvent backEvent) {
+ try {
+ mIOnBackInvokedCallback.onBackProgressed(
+ new BackMotionEvent(backEvent.getTouchX(), backEvent.getTouchY(),
+ backEvent.getProgress(), 0f, 0f, false, backEvent.getSwipeEdge(),
+ null));
+ } catch (RemoteException e) {
+ Log.e(TAG, "Exception when invoking forwarded callback. e: ", e);
+ }
+ }
+
+ @Override
public void onBackInvoked() {
try {
- if (mIOnBackInvokedCallback != null) {
- mIOnBackInvokedCallback.onBackInvoked();
- }
+ mIOnBackInvokedCallback.onBackInvoked();
} catch (RemoteException e) {
Log.e(TAG, "Exception when invoking forwarded callback. e: ", e);
}
}
- private int getId() {
- return mId;
+ @Override
+ public void onBackCancelled() {
+ try {
+ mIOnBackInvokedCallback.onBackCancelled();
+ } catch (RemoteException e) {
+ Log.e(TAG, "Exception when invoking forwarded callback. e: ", e);
+ }
}
- IOnBackInvokedCallback getIOnBackInvokedCallback() {
- return mIOnBackInvokedCallback;
+ private int getId() {
+ return mId;
}
@Override
@@ -358,4 +294,50 @@ public class ImeOnBackInvokedDispatcher implements OnBackInvokedDispatcher, Parc
}
}
}
+
+ /**
+ * Wrapper class that wraps an OnBackInvokedCallback. This is used when a callback is sent from
+ * the IME process to the app process.
+ */
+ private class ImeOnBackInvokedCallbackWrapper extends IOnBackInvokedCallback.Stub {
+
+ private final OnBackInvokedCallback mCallback;
+
+ ImeOnBackInvokedCallbackWrapper(@NonNull OnBackInvokedCallback callback) {
+ mCallback = callback;
+ }
+
+ @Override
+ public void onBackStarted(BackMotionEvent backMotionEvent) {
+ maybeRunOnAnimationCallback((animationCallback) -> animationCallback.onBackStarted(
+ BackEvent.fromBackMotionEvent(backMotionEvent)));
+ }
+
+ @Override
+ public void onBackProgressed(BackMotionEvent backMotionEvent) {
+ maybeRunOnAnimationCallback((animationCallback) -> animationCallback.onBackProgressed(
+ BackEvent.fromBackMotionEvent(backMotionEvent)));
+ }
+
+ @Override
+ public void onBackCancelled() {
+ maybeRunOnAnimationCallback(OnBackAnimationCallback::onBackCancelled);
+ }
+
+ @Override
+ public void onBackInvoked() {
+ mCallback.onBackInvoked();
+ }
+
+ @Override
+ public void setTriggerBack(boolean triggerBack) {
+ // no-op
+ }
+
+ private void maybeRunOnAnimationCallback(Consumer<OnBackAnimationCallback> block) {
+ if (mCallback instanceof OnBackAnimationCallback) {
+ block.accept((OnBackAnimationCallback) mCallback);
+ }
+ }
+ }
}
diff --git a/core/java/android/window/WindowOnBackInvokedDispatcher.java b/core/java/android/window/WindowOnBackInvokedDispatcher.java
index b9c8839ea407..0ff52f13222d 100644
--- a/core/java/android/window/WindowOnBackInvokedDispatcher.java
+++ b/core/java/android/window/WindowOnBackInvokedDispatcher.java
@@ -105,7 +105,6 @@ public class WindowOnBackInvokedDispatcher implements OnBackInvokedDispatcher {
// The threshold for back swipe full progress.
private float mBackSwipeLinearThreshold;
private float mNonLinearProgressFactor;
- private boolean mImeDispatchingActive;
public WindowOnBackInvokedDispatcher(@NonNull Context context, Looper looper) {
mChecker = new Checker(context);
@@ -176,18 +175,19 @@ public class WindowOnBackInvokedDispatcher implements OnBackInvokedDispatcher {
mImeDispatcher.registerOnBackInvokedCallback(priority, callback);
return;
}
- if ((callback instanceof ImeOnBackInvokedDispatcher.DefaultImeOnBackAnimationCallback
- || callback instanceof ImeOnBackInvokedDispatcher.ImeOnBackInvokedCallback)
- && !isOnBackInvokedCallbackEnabled()) {
+ if (callback instanceof ImeOnBackInvokedDispatcher.ImeOnBackInvokedCallback) {
// Fall back to compat back key injection if legacy back behaviour should be used.
- return;
+ if (!isOnBackInvokedCallbackEnabled()) return;
+ if (callback instanceof ImeOnBackInvokedDispatcher.DefaultImeOnBackAnimationCallback
+ && mImeBackAnimationController != null) {
+ // register ImeBackAnimationController instead to play predictive back animation
+ callback = mImeBackAnimationController;
+ }
}
+
if (!mOnBackInvokedCallbacks.containsKey(priority)) {
mOnBackInvokedCallbacks.put(priority, new ArrayList<>());
}
- if (callback instanceof ImeOnBackInvokedDispatcher.DefaultImeOnBackAnimationCallback) {
- callback = mImeBackAnimationController;
- }
ArrayList<OnBackInvokedCallback> callbacks = mOnBackInvokedCallbacks.get(priority);
// If callback has already been added, remove it and re-add it.
@@ -250,7 +250,7 @@ public class WindowOnBackInvokedDispatcher implements OnBackInvokedDispatcher {
*/
public boolean isBackGestureInProgress() {
synchronized (mLock) {
- return mTouchTracker.isActive() || mImeDispatchingActive;
+ return mTouchTracker.isActive();
}
}
@@ -308,16 +308,8 @@ public class WindowOnBackInvokedDispatcher implements OnBackInvokedDispatcher {
OnBackInvokedCallbackInfo callbackInfo = null;
if (callback != null) {
int priority = mAllCallbacks.get(callback);
- final IOnBackInvokedCallback iCallback =
- callback instanceof ImeOnBackInvokedDispatcher
- .ImeOnBackInvokedCallback
- ? ((ImeOnBackInvokedDispatcher.ImeOnBackInvokedCallback)
- callback).getIOnBackInvokedCallback()
- : new OnBackInvokedCallbackWrapper(
- callback,
- mTouchTracker,
- mProgressAnimator,
- mHandler);
+ final IOnBackInvokedCallback iCallback = new OnBackInvokedCallbackWrapper(
+ callback, mTouchTracker, mProgressAnimator, mHandler);
callbackInfo = new OnBackInvokedCallbackInfo(
iCallback,
priority,
@@ -367,10 +359,6 @@ public class WindowOnBackInvokedDispatcher implements OnBackInvokedDispatcher {
float linearDistance = Math.min(maxDistance, mBackSwipeLinearThreshold);
mTouchTracker.setProgressThresholds(
linearDistance, maxDistance, mNonLinearProgressFactor);
- if (mImeDispatcher != null) {
- mImeDispatcher.setProgressThresholds(
- linearDistance, maxDistance, mNonLinearProgressFactor);
- }
}
/**
@@ -402,46 +390,9 @@ public class WindowOnBackInvokedDispatcher implements OnBackInvokedDispatcher {
}
}
- /**
- * Called when we start dispatching to a callback registered from IME.
- */
- public void onStartImeDispatching() {
- synchronized (mLock) {
- mImeDispatchingActive = true;
- }
- }
-
- /**
- * Called when we stop dispatching to a callback registered from IME.
- */
- public void onStopImeDispatching() {
- synchronized (mLock) {
- mImeDispatchingActive = false;
- }
- }
-
- static class OnBackInvokedCallbackWrapper extends IOnBackInvokedCallback.Stub {
- static class CallbackRef {
- final WeakReference<OnBackInvokedCallback> mWeakRef;
- final OnBackInvokedCallback mStrongRef;
- CallbackRef(@NonNull OnBackInvokedCallback callback, boolean useWeakRef) {
- if (useWeakRef) {
- mWeakRef = new WeakReference<>(callback);
- mStrongRef = null;
- } else {
- mStrongRef = callback;
- mWeakRef = null;
- }
- }
-
- OnBackInvokedCallback get() {
- if (mStrongRef != null) {
- return mStrongRef;
- }
- return mWeakRef.get();
- }
- }
- final CallbackRef mCallbackRef;
+ private static class OnBackInvokedCallbackWrapper extends IOnBackInvokedCallback.Stub {
+ @NonNull
+ private final WeakReference<OnBackInvokedCallback> mCallback;
@NonNull
private final BackProgressAnimator mProgressAnimator;
@NonNull
@@ -454,19 +405,7 @@ public class WindowOnBackInvokedDispatcher implements OnBackInvokedDispatcher {
@NonNull BackTouchTracker touchTracker,
@NonNull BackProgressAnimator progressAnimator,
@NonNull Handler handler) {
- mCallbackRef = new CallbackRef(callback, true /* useWeakRef */);
- mTouchTracker = touchTracker;
- mProgressAnimator = progressAnimator;
- mHandler = handler;
- }
-
- OnBackInvokedCallbackWrapper(
- @NonNull OnBackInvokedCallback callback,
- @NonNull BackTouchTracker touchTracker,
- @NonNull BackProgressAnimator progressAnimator,
- @NonNull Handler handler,
- boolean useWeakRef) {
- mCallbackRef = new CallbackRef(callback, useWeakRef);
+ mCallback = new WeakReference<>(callback);
mTouchTracker = touchTracker;
mProgressAnimator = progressAnimator;
mHandler = handler;
@@ -489,11 +428,7 @@ public class WindowOnBackInvokedDispatcher implements OnBackInvokedDispatcher {
backEvent.getTouchX(), backEvent.getTouchY(), backEvent.getSwipeEdge());
if (callback != null) {
- callback.onBackStarted(new BackEvent(
- backEvent.getTouchX(),
- backEvent.getTouchY(),
- backEvent.getProgress(),
- backEvent.getSwipeEdge()));
+ callback.onBackStarted(BackEvent.fromBackMotionEvent(backEvent));
mProgressAnimator.onBackStarted(backEvent, callback::onBackProgressed);
}
});
@@ -519,7 +454,7 @@ public class WindowOnBackInvokedDispatcher implements OnBackInvokedDispatcher {
boolean isInProgress = mProgressAnimator.isBackAnimationInProgress();
mProgressAnimator.reset();
// TODO(b/333957271): Re-introduce auto fling progress generation.
- final OnBackInvokedCallback callback = mCallbackRef.get();
+ final OnBackInvokedCallback callback = mCallback.get();
if (callback == null) {
Log.d(TAG, "Trying to call onBackInvoked() on a null callback reference.");
return;
@@ -539,7 +474,7 @@ public class WindowOnBackInvokedDispatcher implements OnBackInvokedDispatcher {
@Nullable
private OnBackAnimationCallback getBackAnimationCallback() {
- OnBackInvokedCallback callback = mCallbackRef.get();
+ OnBackInvokedCallback callback = mCallback.get();
return callback instanceof OnBackAnimationCallback ? (OnBackAnimationCallback) callback
: null;
}
@@ -569,11 +504,6 @@ public class WindowOnBackInvokedDispatcher implements OnBackInvokedDispatcher {
public void setImeOnBackInvokedDispatcher(
@NonNull ImeOnBackInvokedDispatcher imeDispatcher) {
mImeDispatcher = imeDispatcher;
- mImeDispatcher.setHandler(mHandler);
- mImeDispatcher.setProgressThresholds(
- mTouchTracker.getLinearDistance(),
- mTouchTracker.getMaxDistance(),
- mTouchTracker.getNonLinearFactor());
}
/** Returns true if a non-null {@link ImeOnBackInvokedDispatcher} has been set. **/