summaryrefslogtreecommitdiff
path: root/libs
diff options
context:
space:
mode:
author wilsonshih <wilsonshih@google.com> 2022-07-01 15:28:47 +0800
committer wilsonshih <wilsonshih@google.com> 2022-07-29 13:00:54 +0800
commitf22e6b03efc694d30e450aac0b293c8cc4dc5fdf (patch)
tree98f539de51c03c19fb1d3f82df885d32d40c9b8c /libs
parentf52b49886c3ad3a62109b704300e015c61674a8f (diff)
Inject back key events if no focus window found.
If user applied a back gesture but core cannot find a focus window, inject back key event, so that event can dispatch to client once it gain focus window. And since the gesture was happened, treat it as onBackPressed. And if device is playing recents animation but the focus window is point to live tile, we can also inject back key because Home/Recents activity shall not have the same behavior as normal app. Bug: 237629607 Test: cross test that back gesture can finish recents with legacy/shell transition on Nexus/3rd launcher. Test: test on BackTestApp for both 3btn mode and gesture mode. Test: atest AnrTests BackNavigationLegacyGestureTest Test: atest OnBackInvokedDispatcherTest KeyboardVisibilityControlTest BackInvokedOnWidgetTest BackNavigationTests BackNavigationControllerTests Change-Id: If754e66ea7c1c4ec313c45d17d7f6c10bfc2c465
Diffstat (limited to 'libs')
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java40
1 files changed, 38 insertions, 2 deletions
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;
}