Merge "Inject back key events if no focus window found." into tm-qpr-dev am: 117bab591c
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/19144840 Change-Id: Ifcb3e44f8ccf21dde71a7663058380a0ca117aa4 Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
@@ -122,7 +122,7 @@ public class ProxyOnBackInvokedDispatcher implements OnBackInvokedDispatcher {
|
|||||||
}
|
}
|
||||||
for (Pair<OnBackInvokedCallback, Integer> callbackPair : mCallbacks) {
|
for (Pair<OnBackInvokedCallback, Integer> callbackPair : mCallbacks) {
|
||||||
int priority = callbackPair.second;
|
int priority = callbackPair.second;
|
||||||
if (priority >= 0) {
|
if (priority >= PRIORITY_DEFAULT) {
|
||||||
mActualDispatcher.registerOnBackInvokedCallback(priority, callbackPair.first);
|
mActualDispatcher.registerOnBackInvokedCallback(priority, callbackPair.first);
|
||||||
} else {
|
} else {
|
||||||
mActualDispatcher.registerSystemOnBackInvokedCallback(callbackPair.first);
|
mActualDispatcher.registerSystemOnBackInvokedCallback(callbackPair.first);
|
||||||
|
|||||||
@@ -30,15 +30,20 @@ import android.database.ContentObserver;
|
|||||||
import android.graphics.Point;
|
import android.graphics.Point;
|
||||||
import android.graphics.PointF;
|
import android.graphics.PointF;
|
||||||
import android.hardware.HardwareBuffer;
|
import android.hardware.HardwareBuffer;
|
||||||
|
import android.hardware.input.InputManager;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
|
import android.os.SystemClock;
|
||||||
import android.os.SystemProperties;
|
import android.os.SystemProperties;
|
||||||
import android.os.UserHandle;
|
import android.os.UserHandle;
|
||||||
import android.provider.Settings.Global;
|
import android.provider.Settings.Global;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.IWindowFocusObserver;
|
import android.view.IWindowFocusObserver;
|
||||||
|
import android.view.InputDevice;
|
||||||
|
import android.view.KeyCharacterMap;
|
||||||
|
import android.view.KeyEvent;
|
||||||
import android.view.MotionEvent;
|
import android.view.MotionEvent;
|
||||||
import android.view.RemoteAnimationTarget;
|
import android.view.RemoteAnimationTarget;
|
||||||
import android.view.SurfaceControl;
|
import android.view.SurfaceControl;
|
||||||
@@ -292,6 +297,9 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
|
|||||||
} else if (keyAction == MotionEvent.ACTION_UP || keyAction == MotionEvent.ACTION_CANCEL) {
|
} else if (keyAction == MotionEvent.ACTION_UP || keyAction == MotionEvent.ACTION_CANCEL) {
|
||||||
ProtoLog.d(WM_SHELL_BACK_PREVIEW,
|
ProtoLog.d(WM_SHELL_BACK_PREVIEW,
|
||||||
"Finishing gesture with event action: %d", keyAction);
|
"Finishing gesture with event action: %d", keyAction);
|
||||||
|
if (keyAction == MotionEvent.ACTION_CANCEL) {
|
||||||
|
mTriggerBack = false;
|
||||||
|
}
|
||||||
onGestureFinished(true);
|
onGestureFinished(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -321,7 +329,6 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
|
|||||||
ProtoLog.d(WM_SHELL_BACK_PREVIEW, "Received backNavigationInfo:%s", backNavigationInfo);
|
ProtoLog.d(WM_SHELL_BACK_PREVIEW, "Received backNavigationInfo:%s", backNavigationInfo);
|
||||||
if (backNavigationInfo == null) {
|
if (backNavigationInfo == null) {
|
||||||
Log.e(TAG, "Received BackNavigationInfo is null.");
|
Log.e(TAG, "Received BackNavigationInfo is null.");
|
||||||
finishAnimation();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
int backType = backNavigationInfo.getType();
|
int backType = backNavigationInfo.getType();
|
||||||
@@ -397,6 +404,25 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
|
|||||||
dispatchOnBackProgressed(targetCallback, backEvent);
|
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) {
|
private void onGestureFinished(boolean fromTouch) {
|
||||||
ProtoLog.d(WM_SHELL_BACK_PREVIEW, "onGestureFinished() mTriggerBack == %s", mTriggerBack);
|
ProtoLog.d(WM_SHELL_BACK_PREVIEW, "onGestureFinished() mTriggerBack == %s", mTriggerBack);
|
||||||
if (fromTouch) {
|
if (fromTouch) {
|
||||||
@@ -405,7 +431,17 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
|
|||||||
mBackGestureStarted = false;
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -131,7 +131,6 @@ class BackNavigationController {
|
|||||||
"Focused window found using getFocusedWindowToken");
|
"Focused window found using getFocusedWindowToken");
|
||||||
}
|
}
|
||||||
|
|
||||||
OnBackInvokedCallbackInfo overrideCallbackInfo = null;
|
|
||||||
if (window != null) {
|
if (window != null) {
|
||||||
// This is needed to bridge the old and new back behavior with recents. While in
|
// 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
|
// 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
|
// 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
|
// launcher and use the legacy behavior of injecting KEYCODE_BACK since the existing
|
||||||
// compat callback in VRI only works when the window is focused.
|
// 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 =
|
final RecentsAnimationController recentsAnimationController =
|
||||||
wmService.getRecentsAnimationController();
|
wmService.getRecentsAnimationController();
|
||||||
if (recentsAnimationController != null
|
final ActivityRecord ar = window.mActivityRecord;
|
||||||
&& recentsAnimationController.shouldApplyInputConsumer(
|
if ((ar != null && ar.isActivityTypeHomeOrRecents()
|
||||||
window.getActivityRecord())) {
|
&& ar.mTransitionController.isTransientLaunch(ar))
|
||||||
window = recentsAnimationController.getTargetAppMainWindow();
|
|| (recentsAnimationController != null
|
||||||
overrideCallbackInfo = recentsAnimationController.getBackInvokedInfo();
|
&& recentsAnimationController.shouldApplyInputConsumer(ar))) {
|
||||||
ProtoLog.d(WM_DEBUG_BACK_PREVIEW, "Current focused window being animated by "
|
ProtoLog.d(WM_DEBUG_BACK_PREVIEW, "Current focused window being animated by "
|
||||||
+ "recents. Overriding back callback to recents controller callback.");
|
+ "recents. Overriding back callback to recents controller callback.");
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -166,9 +168,7 @@ class BackNavigationController {
|
|||||||
if (window != null) {
|
if (window != null) {
|
||||||
currentActivity = window.mActivityRecord;
|
currentActivity = window.mActivityRecord;
|
||||||
currentTask = window.getTask();
|
currentTask = window.getTask();
|
||||||
callbackInfo = overrideCallbackInfo != null
|
callbackInfo = window.getOnBackInvokedCallbackInfo();
|
||||||
? overrideCallbackInfo
|
|
||||||
: window.getOnBackInvokedCallbackInfo();
|
|
||||||
if (callbackInfo == null) {
|
if (callbackInfo == null) {
|
||||||
Slog.e(TAG, "No callback registered, returning null.");
|
Slog.e(TAG, "No callback registered, returning null.");
|
||||||
return null;
|
return null;
|
||||||
@@ -213,8 +213,10 @@ class BackNavigationController {
|
|||||||
Task finalTask = currentTask;
|
Task finalTask = currentTask;
|
||||||
prevActivity = currentTask.getActivity(
|
prevActivity = currentTask.getActivity(
|
||||||
(r) -> !r.finishing && r.getTask() == finalTask && !r.isTopRunningActivity());
|
(r) -> !r.finishing && r.getTask() == finalTask && !r.isTopRunningActivity());
|
||||||
if (window.getParent().getChildCount() > 1 && window.getParent().getChildAt(0)
|
// TODO Dialog window does not need to attach on activity, check
|
||||||
!= window) {
|
// 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
|
// 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.
|
// activity, we won't close the activity.
|
||||||
backType = BackNavigationInfo.TYPE_DIALOG_CLOSE;
|
backType = BackNavigationInfo.TYPE_DIALOG_CLOSE;
|
||||||
@@ -379,7 +381,8 @@ class BackNavigationController {
|
|||||||
|
|
||||||
private void onBackNavigationDone(
|
private void onBackNavigationDone(
|
||||||
Bundle result, WindowState focusedWindow, WindowContainer<?> windowContainer,
|
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();
|
SurfaceControl surfaceControl = windowContainer.getSurfaceControl();
|
||||||
boolean triggerBack = result != null && result.getBoolean(
|
boolean triggerBack = result != null && result.getBoolean(
|
||||||
BackNavigationInfo.KEY_TRIGGER_BACK);
|
BackNavigationInfo.KEY_TRIGGER_BACK);
|
||||||
@@ -404,7 +407,7 @@ class BackNavigationController {
|
|||||||
"Setting Activity.mLauncherTaskBehind to false. Activity=%s",
|
"Setting Activity.mLauncherTaskBehind to false. Activity=%s",
|
||||||
prevActivity);
|
prevActivity);
|
||||||
}
|
}
|
||||||
} else {
|
} else if (task != null) {
|
||||||
task.mBackGestureStarted = false;
|
task.mBackGestureStarted = false;
|
||||||
}
|
}
|
||||||
resetSurfaces(windowContainer);
|
resetSurfaces(windowContainer);
|
||||||
|
|||||||
@@ -19,12 +19,10 @@ package com.android.server.wm;
|
|||||||
import static android.app.ActivityTaskManager.INVALID_TASK_ID;
|
import static android.app.ActivityTaskManager.INVALID_TASK_ID;
|
||||||
import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
|
import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
|
||||||
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
|
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_CLOSING;
|
||||||
import static android.view.RemoteAnimationTarget.MODE_OPENING;
|
import static android.view.RemoteAnimationTarget.MODE_OPENING;
|
||||||
import static android.view.WindowManager.INPUT_CONSUMER_RECENTS_ANIMATION;
|
import static android.view.WindowManager.INPUT_CONSUMER_RECENTS_ANIMATION;
|
||||||
import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
|
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.internal.protolog.ProtoLogGroup.WM_DEBUG_RECENTS_ANIMATIONS;
|
||||||
import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
|
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.Point;
|
||||||
import android.graphics.Rect;
|
import android.graphics.Rect;
|
||||||
import android.hardware.HardwareBuffer;
|
import android.hardware.HardwareBuffer;
|
||||||
import android.hardware.input.InputManager;
|
|
||||||
import android.os.Binder;
|
import android.os.Binder;
|
||||||
import android.os.IBinder.DeathRecipient;
|
import android.os.IBinder.DeathRecipient;
|
||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
@@ -54,18 +51,12 @@ import android.util.SparseBooleanArray;
|
|||||||
import android.util.proto.ProtoOutputStream;
|
import android.util.proto.ProtoOutputStream;
|
||||||
import android.view.IRecentsAnimationController;
|
import android.view.IRecentsAnimationController;
|
||||||
import android.view.IRecentsAnimationRunner;
|
import android.view.IRecentsAnimationRunner;
|
||||||
import android.view.InputDevice;
|
|
||||||
import android.view.InputWindowHandle;
|
import android.view.InputWindowHandle;
|
||||||
import android.view.KeyCharacterMap;
|
|
||||||
import android.view.KeyEvent;
|
|
||||||
import android.view.RemoteAnimationTarget;
|
import android.view.RemoteAnimationTarget;
|
||||||
import android.view.SurfaceControl;
|
import android.view.SurfaceControl;
|
||||||
import android.view.SurfaceControl.Transaction;
|
import android.view.SurfaceControl.Transaction;
|
||||||
import android.view.SurfaceSession;
|
import android.view.SurfaceSession;
|
||||||
import android.view.WindowInsets.Type;
|
import android.view.WindowInsets.Type;
|
||||||
import android.window.BackEvent;
|
|
||||||
import android.window.IOnBackInvokedCallback;
|
|
||||||
import android.window.OnBackInvokedCallbackInfo;
|
|
||||||
import android.window.PictureInPictureSurfaceTransaction;
|
import android.window.PictureInPictureSurfaceTransaction;
|
||||||
import android.window.TaskSnapshot;
|
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 {
|
public interface RecentsAnimationCallbacks {
|
||||||
/** Callback when recents animation is finished. */
|
/** Callback when recents animation is finished. */
|
||||||
void onAnimationFinished(@ReorderMode int reorderMode, boolean sendUserLeaveHint);
|
void onAnimationFinished(@ReorderMode int reorderMode, boolean sendUserLeaveHint);
|
||||||
@@ -1112,10 +1063,6 @@ public class RecentsAnimationController implements DeathRecipient {
|
|||||||
return mTargetActivityRecord.findMainWindow();
|
return mTargetActivityRecord.findMainWindow();
|
||||||
}
|
}
|
||||||
|
|
||||||
OnBackInvokedCallbackInfo getBackInvokedInfo() {
|
|
||||||
return new OnBackInvokedCallbackInfo(mBackCallback, PRIORITY_DEFAULT);
|
|
||||||
}
|
|
||||||
|
|
||||||
DisplayArea getTargetAppDisplayArea() {
|
DisplayArea getTargetAppDisplayArea() {
|
||||||
if (mTargetActivityRecord == null) {
|
if (mTargetActivityRecord == null) {
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
Reference in New Issue
Block a user