diff options
| author | 2022-08-02 11:40:59 +0000 | |
|---|---|---|
| committer | 2022-08-02 11:40:59 +0000 | |
| commit | 117bab591c2b3eca4ee842c9edaa9f28a34c6e93 (patch) | |
| tree | 4b903cd76ad592946a2bbc06faaf079f6aedde57 | |
| parent | 95a0aa965f41f3d034d56c2111f9a09bd37941dd (diff) | |
| parent | f22e6b03efc694d30e450aac0b293c8cc4dc5fdf (diff) | |
Merge "Inject back key events if no focus window found." into tm-qpr-dev
5 files changed, 57 insertions, 71 deletions
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index 427aa0f3914e..7690af693148 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -10879,8 +10879,8 @@ public final class ViewRootImpl implements ViewParent, private void registerCompatOnBackInvokedCallback() { mCompatOnBackInvokedCallback = () -> { - sendBackKeyEvent(KeyEvent.ACTION_DOWN); - sendBackKeyEvent(KeyEvent.ACTION_UP); + sendBackKeyEvent(KeyEvent.ACTION_DOWN); + sendBackKeyEvent(KeyEvent.ACTION_UP); }; mOnBackInvokedDispatcher.registerOnBackInvokedCallback( OnBackInvokedDispatcher.PRIORITY_DEFAULT, mCompatOnBackInvokedCallback); diff --git a/core/java/android/window/ProxyOnBackInvokedDispatcher.java b/core/java/android/window/ProxyOnBackInvokedDispatcher.java index 8ad109317f4b..49acde9dc295 100644 --- a/core/java/android/window/ProxyOnBackInvokedDispatcher.java +++ b/core/java/android/window/ProxyOnBackInvokedDispatcher.java @@ -122,7 +122,7 @@ public class ProxyOnBackInvokedDispatcher implements OnBackInvokedDispatcher { } for (Pair<OnBackInvokedCallback, Integer> callbackPair : mCallbacks) { int priority = callbackPair.second; - if (priority >= 0) { + if (priority >= PRIORITY_DEFAULT) { mActualDispatcher.registerOnBackInvokedCallback(priority, callbackPair.first); } else { mActualDispatcher.registerSystemOnBackInvokedCallback(callbackPair.first); 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 02211220822a..05fafc54c273 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,15 +30,20 @@ import android.database.ContentObserver; import android.graphics.Point; import android.graphics.PointF; import android.hardware.HardwareBuffer; +import android.hardware.input.InputManager; import android.net.Uri; import android.os.Handler; import android.os.IBinder; import android.os.RemoteException; +import android.os.SystemClock; import android.os.SystemProperties; import android.os.UserHandle; import android.provider.Settings.Global; import android.util.Log; import android.view.IWindowFocusObserver; +import android.view.InputDevice; +import android.view.KeyCharacterMap; +import android.view.KeyEvent; import android.view.MotionEvent; import android.view.RemoteAnimationTarget; import android.view.SurfaceControl; @@ -292,6 +297,9 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont } else if (keyAction == MotionEvent.ACTION_UP || keyAction == MotionEvent.ACTION_CANCEL) { ProtoLog.d(WM_SHELL_BACK_PREVIEW, "Finishing gesture with event action: %d", keyAction); + if (keyAction == MotionEvent.ACTION_CANCEL) { + mTriggerBack = false; + } onGestureFinished(true); } } @@ -321,7 +329,6 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont ProtoLog.d(WM_SHELL_BACK_PREVIEW, "Received backNavigationInfo:%s", backNavigationInfo); if (backNavigationInfo == null) { Log.e(TAG, "Received BackNavigationInfo is null."); - finishAnimation(); return; } int backType = backNavigationInfo.getType(); @@ -397,6 +404,25 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont dispatchOnBackProgressed(targetCallback, backEvent); } + private void injectBackKey() { + sendBackEvent(KeyEvent.ACTION_DOWN); + sendBackEvent(KeyEvent.ACTION_UP); + } + + private void sendBackEvent(int action) { + final 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); + + ev.setDisplayId(mContext.getDisplay().getDisplayId()); + if (!InputManager.getInstance() + .injectInputEvent(ev, InputManager.INJECT_INPUT_EVENT_MODE_ASYNC)) { + Log.e(TAG, "Inject input event fail"); + } + } + private void onGestureFinished(boolean fromTouch) { ProtoLog.d(WM_SHELL_BACK_PREVIEW, "onGestureFinished() mTriggerBack == %s", mTriggerBack); if (fromTouch) { @@ -405,7 +431,17 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont mBackGestureStarted = false; } - if (mTransitionInProgress || mBackNavigationInfo == null) { + if (mTransitionInProgress) { + return; + } + + if (mBackNavigationInfo == null) { + // No focus window found or core are running recents animation, inject back key as + // legacy behavior. + if (mTriggerBack) { + injectBackKey(); + } + finishAnimation(); return; } diff --git a/services/core/java/com/android/server/wm/BackNavigationController.java b/services/core/java/com/android/server/wm/BackNavigationController.java index f967cf995e67..d9ab971c9a78 100644 --- a/services/core/java/com/android/server/wm/BackNavigationController.java +++ b/services/core/java/com/android/server/wm/BackNavigationController.java @@ -131,7 +131,6 @@ class BackNavigationController { "Focused window found using getFocusedWindowToken"); } - OnBackInvokedCallbackInfo overrideCallbackInfo = null; if (window != null) { // This is needed to bridge the old and new back behavior with recents. While in // Overview with live tile enabled, the previous app is technically focused but we @@ -140,15 +139,18 @@ class BackNavigationController { // the right window to consume back while in overview, so we need to route it to // launcher and use the legacy behavior of injecting KEYCODE_BACK since the existing // compat callback in VRI only works when the window is focused. + // This symptom also happen while shell transition enabled, we can check that by + // isTransientLaunch to know whether the focus window is point to live tile. final RecentsAnimationController recentsAnimationController = wmService.getRecentsAnimationController(); - if (recentsAnimationController != null - && recentsAnimationController.shouldApplyInputConsumer( - window.getActivityRecord())) { - window = recentsAnimationController.getTargetAppMainWindow(); - overrideCallbackInfo = recentsAnimationController.getBackInvokedInfo(); + final ActivityRecord ar = window.mActivityRecord; + if ((ar != null && ar.isActivityTypeHomeOrRecents() + && ar.mTransitionController.isTransientLaunch(ar)) + || (recentsAnimationController != null + && recentsAnimationController.shouldApplyInputConsumer(ar))) { ProtoLog.d(WM_DEBUG_BACK_PREVIEW, "Current focused window being animated by " + "recents. Overriding back callback to recents controller callback."); + return null; } } @@ -166,9 +168,7 @@ class BackNavigationController { if (window != null) { currentActivity = window.mActivityRecord; currentTask = window.getTask(); - callbackInfo = overrideCallbackInfo != null - ? overrideCallbackInfo - : window.getOnBackInvokedCallbackInfo(); + callbackInfo = window.getOnBackInvokedCallbackInfo(); if (callbackInfo == null) { Slog.e(TAG, "No callback registered, returning null."); return null; @@ -213,8 +213,10 @@ class BackNavigationController { Task finalTask = currentTask; prevActivity = currentTask.getActivity( (r) -> !r.finishing && r.getTask() == finalTask && !r.isTopRunningActivity()); - if (window.getParent().getChildCount() > 1 && window.getParent().getChildAt(0) - != window) { + // TODO Dialog window does not need to attach on activity, check + // window.mAttrs.type != TYPE_BASE_APPLICATION + if ((window.getParent().getChildCount() > 1 + && window.getParent().getChildAt(0) != window)) { // Are we the top window of our parent? If not, we are a window on top of the // activity, we won't close the activity. backType = BackNavigationInfo.TYPE_DIALOG_CLOSE; @@ -379,7 +381,8 @@ class BackNavigationController { private void onBackNavigationDone( Bundle result, WindowState focusedWindow, WindowContainer<?> windowContainer, - int backType, Task task, ActivityRecord prevActivity, boolean prepareAnimation) { + int backType, @Nullable Task task, @Nullable ActivityRecord prevActivity, + boolean prepareAnimation) { SurfaceControl surfaceControl = windowContainer.getSurfaceControl(); boolean triggerBack = result != null && result.getBoolean( BackNavigationInfo.KEY_TRIGGER_BACK); @@ -404,7 +407,7 @@ class BackNavigationController { "Setting Activity.mLauncherTaskBehind to false. Activity=%s", prevActivity); } - } else { + } else if (task != null) { task.mBackGestureStarted = false; } resetSurfaces(windowContainer); diff --git a/services/core/java/com/android/server/wm/RecentsAnimationController.java b/services/core/java/com/android/server/wm/RecentsAnimationController.java index 53f1fe6abec5..1cff69334679 100644 --- a/services/core/java/com/android/server/wm/RecentsAnimationController.java +++ b/services/core/java/com/android/server/wm/RecentsAnimationController.java @@ -19,12 +19,10 @@ package com.android.server.wm; import static android.app.ActivityTaskManager.INVALID_TASK_ID; import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME; import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; -import static android.hardware.input.InputManager.INJECT_INPUT_EVENT_MODE_ASYNC; import static android.view.RemoteAnimationTarget.MODE_CLOSING; import static android.view.RemoteAnimationTarget.MODE_OPENING; import static android.view.WindowManager.INPUT_CONSUMER_RECENTS_ANIMATION; import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION; -import static android.window.OnBackInvokedDispatcher.PRIORITY_DEFAULT; import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_RECENTS_ANIMATIONS; import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER; @@ -41,7 +39,6 @@ import android.graphics.GraphicBuffer; import android.graphics.Point; import android.graphics.Rect; import android.hardware.HardwareBuffer; -import android.hardware.input.InputManager; import android.os.Binder; import android.os.IBinder.DeathRecipient; import android.os.RemoteException; @@ -54,18 +51,12 @@ import android.util.SparseBooleanArray; import android.util.proto.ProtoOutputStream; import android.view.IRecentsAnimationController; import android.view.IRecentsAnimationRunner; -import android.view.InputDevice; import android.view.InputWindowHandle; -import android.view.KeyCharacterMap; -import android.view.KeyEvent; import android.view.RemoteAnimationTarget; import android.view.SurfaceControl; import android.view.SurfaceControl.Transaction; import android.view.SurfaceSession; import android.view.WindowInsets.Type; -import android.window.BackEvent; -import android.window.IOnBackInvokedCallback; -import android.window.OnBackInvokedCallbackInfo; import android.window.PictureInPictureSurfaceTransaction; import android.window.TaskSnapshot; @@ -195,46 +186,6 @@ public class RecentsAnimationController implements DeathRecipient { } }; - /** - * Back invoked callback for legacy recents transition with the new back dispatch system. - */ - final IOnBackInvokedCallback mBackCallback = new IOnBackInvokedCallback.Stub() { - @Override - public void onBackStarted() { - // Do nothing - } - - @Override - public void onBackProgressed(BackEvent backEvent) { - // Do nothing - } - - @Override - public void onBackCancelled() { - // Do nothing - } - - @Override - public void onBackInvoked() { - sendBackEvent(KeyEvent.ACTION_DOWN); - sendBackEvent(KeyEvent.ACTION_UP); - } - - private void sendBackEvent(int action) { - if (mTargetActivityRecord == null) { - return; - } - 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); - ev.setDisplayId(mTargetActivityRecord.getDisplayId()); - InputManager.getInstance().injectInputEvent(ev, INJECT_INPUT_EVENT_MODE_ASYNC); - } - }; - public interface RecentsAnimationCallbacks { /** Callback when recents animation is finished. */ void onAnimationFinished(@ReorderMode int reorderMode, boolean sendUserLeaveHint); @@ -1112,10 +1063,6 @@ public class RecentsAnimationController implements DeathRecipient { return mTargetActivityRecord.findMainWindow(); } - OnBackInvokedCallbackInfo getBackInvokedInfo() { - return new OnBackInvokedCallbackInfo(mBackCallback, PRIORITY_DEFAULT); - } - DisplayArea getTargetAppDisplayArea() { if (mTargetActivityRecord == null) { return null; |