diff options
author | 2024-06-10 12:06:01 +0000 | |
---|---|---|
committer | 2024-06-10 12:06:01 +0000 | |
commit | d30e9888dab1b10b29b84de143b3174bd42fd7ac (patch) | |
tree | 54c5b20d7b60ad13980ac3f92f4acb10de47a9e3 | |
parent | e7a9896a57108d661f70bb1f9e20ee2baf7ad2a8 (diff) | |
parent | d07089a69412353f260ea3362ccaa511e3fb869a (diff) |
Merge "Revert "Enable IME predictive back animation in all apps"" into main
4 files changed, 31 insertions, 101 deletions
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index cb82278ca577..54ee37519546 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -7504,8 +7504,6 @@ public final class ViewRootImpl implements ViewParent, final KeyEvent event = (KeyEvent)q.mEvent; if (mView.dispatchKeyEventPreIme(event)) { return FINISH_HANDLED; - } else if (q.forPreImeOnly()) { - return FINISH_NOT_HANDLED; } return FORWARD; } @@ -10002,7 +10000,6 @@ public final class ViewRootImpl implements ViewParent, public static final int FLAG_RESYNTHESIZED = 1 << 4; public static final int FLAG_UNHANDLED = 1 << 5; public static final int FLAG_MODIFIED_FOR_COMPATIBILITY = 1 << 6; - public static final int FLAG_PRE_IME_ONLY = 1 << 7; public QueuedInputEvent mNext; @@ -10010,13 +10007,6 @@ public final class ViewRootImpl implements ViewParent, public InputEventReceiver mReceiver; public int mFlags; - public boolean forPreImeOnly() { - if ((mFlags & FLAG_PRE_IME_ONLY) != 0) { - return true; - } - return false; - } - public boolean shouldSkipIme() { if ((mFlags & FLAG_DELIVER_POST_IME) != 0) { return true; @@ -10043,7 +10033,6 @@ public final class ViewRootImpl implements ViewParent, hasPrevious = flagToString("FINISHED_HANDLED", FLAG_FINISHED_HANDLED, hasPrevious, sb); hasPrevious = flagToString("RESYNTHESIZED", FLAG_RESYNTHESIZED, hasPrevious, sb); hasPrevious = flagToString("UNHANDLED", FLAG_UNHANDLED, hasPrevious, sb); - hasPrevious = flagToString("FLAG_PRE_IME_ONLY", FLAG_PRE_IME_ONLY, hasPrevious, sb); if (!hasPrevious) { sb.append("0"); } @@ -10100,7 +10089,7 @@ public final class ViewRootImpl implements ViewParent, } @UnsupportedAppUsage - QueuedInputEvent enqueueInputEvent(InputEvent event, + void enqueueInputEvent(InputEvent event, InputEventReceiver receiver, int flags, boolean processImmediately) { QueuedInputEvent q = obtainQueuedInputEvent(event, receiver, flags); @@ -10139,7 +10128,6 @@ public final class ViewRootImpl implements ViewParent, } else { scheduleProcessInputEvents(); } - return q; } private void scheduleProcessInputEvents() { @@ -12461,45 +12449,29 @@ public final class ViewRootImpl implements ViewParent, + "IWindow:%s Session:%s", mOnBackInvokedDispatcher, mBasePackageName, mWindow, mWindowSession)); } - mOnBackInvokedDispatcher.attachToWindow(mWindowSession, mWindow, this, + mOnBackInvokedDispatcher.attachToWindow(mWindowSession, mWindow, mImeBackAnimationController); } - /** - * Sends {@link KeyEvent#ACTION_DOWN ACTION_DOWN} and {@link KeyEvent#ACTION_UP ACTION_UP} - * back key events - * - * @param preImeOnly whether the back events should be sent to the pre-ime stage only - * @return whether the event was handled (i.e. onKeyPreIme consumed it if preImeOnly=true) - */ - public boolean injectBackKeyEvents(boolean preImeOnly) { - boolean consumed; - try { - processingBackKey(true); - sendBackKeyEvent(KeyEvent.ACTION_DOWN, preImeOnly); - consumed = sendBackKeyEvent(KeyEvent.ACTION_UP, preImeOnly); - } finally { - processingBackKey(false); - } - return consumed; - } - - private boolean sendBackKeyEvent(int action, boolean preImeOnly) { + private void sendBackKeyEvent(int action) { long when = SystemClock.uptimeMillis(); final KeyEvent ev = new KeyEvent(when, when, action, KeyEvent.KEYCODE_BACK, 0 /* repeat */, 0 /* metaState */, KeyCharacterMap.VIRTUAL_KEYBOARD, 0 /* scancode */, KeyEvent.FLAG_FROM_SYSTEM | KeyEvent.FLAG_VIRTUAL_HARD_KEY, InputDevice.SOURCE_KEYBOARD); - int flags = preImeOnly ? QueuedInputEvent.FLAG_PRE_IME_ONLY : 0; - QueuedInputEvent q = enqueueInputEvent(ev, null /* receiver */, flags, - true /* processImmediately */); - return (q.mFlags & QueuedInputEvent.FLAG_FINISHED_HANDLED) != 0; + enqueueInputEvent(ev, null /* receiver */, 0 /* flags */, true /* processImmediately */); } private void registerCompatOnBackInvokedCallback() { mCompatOnBackInvokedCallback = () -> { - injectBackKeyEvents(/* preImeOnly */ false); + try { + processingBackKey(true); + sendBackKeyEvent(KeyEvent.ACTION_DOWN); + sendBackKeyEvent(KeyEvent.ACTION_UP); + } finally { + processingBackKey(false); + } }; if (mOnBackInvokedDispatcher.hasImeOnBackInvokedDispatcher()) { Log.d(TAG, "Skip registering CompatOnBackInvokedCallback on IME dispatcher"); diff --git a/core/java/android/window/WindowOnBackInvokedDispatcher.java b/core/java/android/window/WindowOnBackInvokedDispatcher.java index 4c993c2544ce..b7f6f363dd04 100644 --- a/core/java/android/window/WindowOnBackInvokedDispatcher.java +++ b/core/java/android/window/WindowOnBackInvokedDispatcher.java @@ -37,7 +37,6 @@ import android.view.IWindow; import android.view.IWindowSession; import android.view.ImeBackAnimationController; import android.view.MotionEvent; -import android.view.ViewRootImpl; import androidx.annotation.VisibleForTesting; @@ -50,7 +49,6 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.Objects; import java.util.TreeMap; -import java.util.function.BooleanSupplier; import java.util.function.Supplier; /** @@ -70,7 +68,6 @@ import java.util.function.Supplier; public class WindowOnBackInvokedDispatcher implements OnBackInvokedDispatcher { private IWindowSession mWindowSession; private IWindow mWindow; - private ViewRootImpl mViewRoot; @VisibleForTesting public final BackTouchTracker mTouchTracker = new BackTouchTracker(); @VisibleForTesting @@ -137,12 +134,10 @@ public class WindowOnBackInvokedDispatcher implements OnBackInvokedDispatcher { * is attached a window. */ public void attachToWindow(@NonNull IWindowSession windowSession, @NonNull IWindow window, - @Nullable ViewRootImpl viewRoot, @Nullable ImeBackAnimationController imeBackAnimationController) { synchronized (mLock) { mWindowSession = windowSession; mWindow = window; - mViewRoot = viewRoot; mImeBackAnimationController = imeBackAnimationController; if (!mAllCallbacks.isEmpty()) { setTopOnBackInvokedCallback(getTopCallback()); @@ -156,7 +151,6 @@ public class WindowOnBackInvokedDispatcher implements OnBackInvokedDispatcher { clear(); mWindow = null; mWindowSession = null; - mViewRoot = null; mImeBackAnimationController = null; } } @@ -182,6 +176,8 @@ public class WindowOnBackInvokedDispatcher implements OnBackInvokedDispatcher { return; } if (callback instanceof ImeOnBackInvokedDispatcher.ImeOnBackInvokedCallback) { + // Fall back to compat back key injection if legacy back behaviour should be used. + if (!isOnBackInvokedCallbackEnabled()) return; if (callback instanceof ImeOnBackInvokedDispatcher.DefaultImeOnBackAnimationCallback && mImeBackAnimationController != null) { // register ImeBackAnimationController instead to play predictive back animation @@ -304,14 +300,6 @@ public class WindowOnBackInvokedDispatcher implements OnBackInvokedDispatcher { } } - private boolean callOnKeyPreIme() { - if (mViewRoot != null && !isOnBackInvokedCallbackEnabled(mViewRoot.mContext)) { - return mViewRoot.injectBackKeyEvents(/*preImeOnly*/ true); - } else { - return false; - } - } - private void setTopOnBackInvokedCallback(@Nullable OnBackInvokedCallback callback) { if (mWindowSession == null || mWindow == null) { return; @@ -320,8 +308,8 @@ public class WindowOnBackInvokedDispatcher implements OnBackInvokedDispatcher { OnBackInvokedCallbackInfo callbackInfo = null; if (callback != null) { int priority = mAllCallbacks.get(callback); - final IOnBackInvokedCallback iCallback = new OnBackInvokedCallbackWrapper(callback, - mTouchTracker, mProgressAnimator, mHandler, this::callOnKeyPreIme); + final IOnBackInvokedCallback iCallback = new OnBackInvokedCallbackWrapper( + callback, mTouchTracker, mProgressAnimator, mHandler); callbackInfo = new OnBackInvokedCallbackInfo( iCallback, priority, @@ -411,20 +399,16 @@ public class WindowOnBackInvokedDispatcher implements OnBackInvokedDispatcher { private final BackTouchTracker mTouchTracker; @NonNull private final Handler mHandler; - @NonNull - private final BooleanSupplier mOnKeyPreIme; OnBackInvokedCallbackWrapper( @NonNull OnBackInvokedCallback callback, @NonNull BackTouchTracker touchTracker, @NonNull BackProgressAnimator progressAnimator, - @NonNull Handler handler, - @NonNull BooleanSupplier onKeyPreIme) { + @NonNull Handler handler) { mCallback = new WeakReference<>(callback); mTouchTracker = touchTracker; mProgressAnimator = progressAnimator; mHandler = handler; - mOnKeyPreIme = onKeyPreIme; } @Override @@ -467,7 +451,6 @@ public class WindowOnBackInvokedDispatcher implements OnBackInvokedDispatcher { public void onBackInvoked() throws RemoteException { mHandler.post(() -> { mTouchTracker.reset(); - if (consumedByOnKeyPreIme()) return; boolean isInProgress = mProgressAnimator.isBackAnimationInProgress(); final OnBackInvokedCallback callback = mCallback.get(); if (callback == null) { @@ -489,30 +472,6 @@ public class WindowOnBackInvokedDispatcher implements OnBackInvokedDispatcher { }); } - private boolean consumedByOnKeyPreIme() { - final OnBackInvokedCallback callback = mCallback.get(); - if (callback instanceof ImeBackAnimationController - || callback instanceof ImeOnBackInvokedDispatcher.ImeOnBackInvokedCallback) { - // call onKeyPreIme API if the current callback is an IME callback and the app has - // not set enableOnBackInvokedCallback="false" - try { - boolean consumed = mOnKeyPreIme.getAsBoolean(); - if (consumed) { - // back event intercepted by app in onKeyPreIme -> cancel the IME animation. - final OnBackAnimationCallback animationCallback = - getBackAnimationCallback(); - if (animationCallback != null) { - mProgressAnimator.onBackCancelled(animationCallback::onBackCancelled); - } - return true; - } - } catch (Exception e) { - Log.d(TAG, "Failed to call onKeyPreIme", e); - } - } - return false; - } - @Override public void setTriggerBack(boolean triggerBack) throws RemoteException { mTouchTracker.setTriggerBack(triggerBack); diff --git a/core/tests/coretests/src/android/window/WindowOnBackInvokedDispatcherTest.java b/core/tests/coretests/src/android/window/WindowOnBackInvokedDispatcherTest.java index d4482f243939..b0190a5c8218 100644 --- a/core/tests/coretests/src/android/window/WindowOnBackInvokedDispatcherTest.java +++ b/core/tests/coretests/src/android/window/WindowOnBackInvokedDispatcherTest.java @@ -112,7 +112,7 @@ public class WindowOnBackInvokedDispatcherTest { doReturn(mApplicationInfo).when(mContext).getApplicationInfo(); mDispatcher = new WindowOnBackInvokedDispatcher(mContext, Looper.getMainLooper()); - mDispatcher.attachToWindow(mWindowSession, mWindow, null, mImeBackAnimationController); + mDispatcher.attachToWindow(mWindowSession, mWindow, mImeBackAnimationController); } private void waitForIdle() { @@ -455,26 +455,25 @@ public class WindowOnBackInvokedDispatcherTest { @Test public void registerImeCallbacks_onBackInvokedCallbackEnabled() throws RemoteException { - verifyImeCallackRegistrations(); - } - - @Test - public void registerImeCallbacks_onBackInvokedCallbackDisabled() throws RemoteException { - doReturn(false).when(mApplicationInfo).isOnBackInvokedCallbackEnabled(); - verifyImeCallackRegistrations(); - } - - private void verifyImeCallackRegistrations() throws RemoteException { - // verify default callback is replaced with ImeBackAnimationController - mDispatcher.registerOnBackInvokedCallbackUnchecked(mDefaultImeCallback, PRIORITY_DEFAULT); + mDispatcher.registerOnBackInvokedCallback(PRIORITY_DEFAULT, mDefaultImeCallback); assertCallbacksSize(/* default */ 1, /* overlay */ 0); assertSetCallbackInfo(); assertTopCallback(mImeBackAnimationController); - // verify regular ime callback is successfully registered - mDispatcher.registerOnBackInvokedCallbackUnchecked(mImeCallback, PRIORITY_DEFAULT); + mDispatcher.registerOnBackInvokedCallback(PRIORITY_DEFAULT, mImeCallback); assertCallbacksSize(/* default */ 2, /* overlay */ 0); assertSetCallbackInfo(); assertTopCallback(mImeCallback); } + + @Test + public void registerImeCallbacks_legacyBack() throws RemoteException { + doReturn(false).when(mApplicationInfo).isOnBackInvokedCallbackEnabled(); + + mDispatcher.registerOnBackInvokedCallback(PRIORITY_DEFAULT, mDefaultImeCallback); + assertNoSetCallbackInfo(); + + mDispatcher.registerOnBackInvokedCallback(PRIORITY_DEFAULT, mImeCallback); + assertNoSetCallbackInfo(); + } } diff --git a/services/tests/wmtests/src/com/android/server/wm/BackNavigationControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/BackNavigationControllerTests.java index c67d1ec63827..a39a1a8637df 100644 --- a/services/tests/wmtests/src/com/android/server/wm/BackNavigationControllerTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/BackNavigationControllerTests.java @@ -550,7 +550,7 @@ public class BackNavigationControllerTests extends WindowTestsBase { }).when(appWindow.mSession).setOnBackInvokedCallbackInfo(eq(appWindow.mClient), any()); addToWindowMap(appWindow, true); - dispatcher.attachToWindow(appWindow.mSession, appWindow.mClient, null, null); + dispatcher.attachToWindow(appWindow.mSession, appWindow.mClient, null); OnBackInvokedCallback appCallback = createBackCallback(appLatch); |