Merge "Inject back key events if no focus window found." into tm-qpr-dev

This commit is contained in:
Wei Sheng Shih
2022-08-02 11:40:59 +00:00
committed by Android (Google) Code Review
5 changed files with 57 additions and 71 deletions

View File

@@ -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);

View File

@@ -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);

View File

@@ -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;
}

View File

@@ -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);

View File

@@ -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;