Merge "Force input focus to the last focused non-proxy display." into udc-dev
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
index 0d973d9..a3b4a0f 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -194,7 +194,8 @@
AccessibilityUserState.ServiceInfoChangeListener,
AccessibilityWindowManager.AccessibilityEventSender,
AccessibilitySecurityPolicy.AccessibilityUserManager,
- SystemActionPerformer.SystemActionsChangedListener, ProxyManager.SystemSupport{
+ SystemActionPerformer.SystemActionsChangedListener,
+ SystemActionPerformer.DisplayUpdateCallBack, ProxyManager.SystemSupport {
private static final boolean DEBUG = false;
@@ -1219,7 +1220,7 @@
private SystemActionPerformer getSystemActionPerformer() {
if (mSystemActionPerformer == null) {
mSystemActionPerformer =
- new SystemActionPerformer(mContext, mWindowManagerService, null, this);
+ new SystemActionPerformer(mContext, mWindowManagerService, null, this, this);
}
return mSystemActionPerformer;
}
@@ -1619,6 +1620,18 @@
}
}
+ @Override
+ // TODO(b/276459590): Remove when this is resolved at the virtual device/input level.
+ public void moveNonProxyTopFocusedDisplayToTopIfNeeded() {
+ mA11yWindowManager.moveNonProxyTopFocusedDisplayToTopIfNeeded();
+ }
+
+ @Override
+ // TODO(b/276459590): Remove when this is resolved at the virtual device/input level.
+ public int getLastNonProxyTopFocusedDisplayId() {
+ return mA11yWindowManager.getLastNonProxyTopFocusedDisplayId();
+ }
+
@VisibleForTesting
void notifySystemActionsChangedLocked(AccessibilityUserState userState) {
for (int i = userState.mBoundServices.size() - 1; i >= 0; i--) {
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityWindowManager.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityWindowManager.java
index a8a5365..78f07e4 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityWindowManager.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityWindowManager.java
@@ -103,6 +103,9 @@
// The top focused display and window token updated with the callback of window lists change.
private int mTopFocusedDisplayId;
private IBinder mTopFocusedWindowToken;
+
+ // The non-proxy display that most recently had top focus.
+ private int mLastNonProxyTopFocusedDisplayId;
// The display has the accessibility focused window currently.
private int mAccessibilityFocusedDisplayId = Display.INVALID_DISPLAY;
@@ -451,6 +454,9 @@
}
if (shouldUpdateWindowsLocked(forceSend, windows)) {
mTopFocusedDisplayId = topFocusedDisplayId;
+ if (!isProxyed(topFocusedDisplayId)) {
+ mLastNonProxyTopFocusedDisplayId = topFocusedDisplayId;
+ }
mTopFocusedWindowToken = topFocusedWindowToken;
if (DEBUG) {
Slogf.d(LOG_TAG, "onWindowsForAccessibilityChanged(): updating windows for "
@@ -1141,6 +1147,21 @@
return false;
}
+ private boolean isProxyed(int displayId) {
+ final DisplayWindowsObserver observer = mDisplayWindowsObservers.get(displayId);
+ return (observer != null && observer.mIsProxy);
+ }
+
+ void moveNonProxyTopFocusedDisplayToTopIfNeeded() {
+ if (mHasProxy
+ && (mLastNonProxyTopFocusedDisplayId != mTopFocusedDisplayId)) {
+ mWindowManagerInternal.moveDisplayToTopIfAllowed(mLastNonProxyTopFocusedDisplayId);
+ }
+ }
+ int getLastNonProxyTopFocusedDisplayId() {
+ return mLastNonProxyTopFocusedDisplayId;
+ }
+
/**
* Checks if we are tracking windows on specified display.
*
diff --git a/services/accessibility/java/com/android/server/accessibility/SystemActionPerformer.java b/services/accessibility/java/com/android/server/accessibility/SystemActionPerformer.java
index c89b9b8..a13df47 100644
--- a/services/accessibility/java/com/android/server/accessibility/SystemActionPerformer.java
+++ b/services/accessibility/java/com/android/server/accessibility/SystemActionPerformer.java
@@ -72,6 +72,13 @@
}
private final SystemActionsChangedListener mListener;
+ interface DisplayUpdateCallBack {
+ void moveNonProxyTopFocusedDisplayToTopIfNeeded();
+
+ int getLastNonProxyTopFocusedDisplayId();
+ }
+ private final DisplayUpdateCallBack mDisplayUpdateCallBack;
+
private final Object mSystemActionLock = new Object();
// Resource id based ActionId -> RemoteAction
@GuardedBy("mSystemActionLock")
@@ -94,7 +101,7 @@
public SystemActionPerformer(
Context context,
WindowManagerInternal windowManagerInternal) {
- this(context, windowManagerInternal, null, null);
+ this(context, windowManagerInternal, null, null, null);
}
// Used to mock ScreenshotHelper
@@ -103,17 +110,19 @@
Context context,
WindowManagerInternal windowManagerInternal,
Supplier<ScreenshotHelper> screenshotHelperSupplier) {
- this(context, windowManagerInternal, screenshotHelperSupplier, null);
+ this(context, windowManagerInternal, screenshotHelperSupplier, null, null);
}
public SystemActionPerformer(
Context context,
WindowManagerInternal windowManagerInternal,
Supplier<ScreenshotHelper> screenshotHelperSupplier,
- SystemActionsChangedListener listener) {
+ SystemActionsChangedListener listener,
+ DisplayUpdateCallBack callback) {
mContext = context;
mWindowManagerService = windowManagerInternal;
mListener = listener;
+ mDisplayUpdateCallBack = callback;
mScreenshotHelperSupplier = screenshotHelperSupplier;
mLegacyHomeAction = new AccessibilityAction(
@@ -245,6 +254,7 @@
final long identity = Binder.clearCallingIdentity();
try {
synchronized (mSystemActionLock) {
+ mDisplayUpdateCallBack.moveNonProxyTopFocusedDisplayToTopIfNeeded();
// If a system action is registered with the given actionId, call the corresponding
// RemoteAction.
RemoteAction registeredAction = mRegisteredSystemActions.get(actionId);
@@ -341,7 +351,7 @@
int source) {
KeyEvent event = KeyEvent.obtain(downTime, time, action, keyCode, 0, 0,
KeyCharacterMap.VIRTUAL_KEYBOARD, 0, KeyEvent.FLAG_FROM_SYSTEM,
- source, null);
+ source, mDisplayUpdateCallBack.getLastNonProxyTopFocusedDisplayId(), null);
mContext.getSystemService(InputManager.class)
.injectInputEvent(event, InputManager.INJECT_INPUT_EVENT_MODE_ASYNC);
event.recycle();
diff --git a/services/accessibility/java/com/android/server/accessibility/gestures/TouchState.java b/services/accessibility/java/com/android/server/accessibility/gestures/TouchState.java
index eb71885..d9e25ef 100644
--- a/services/accessibility/java/com/android/server/accessibility/gestures/TouchState.java
+++ b/services/accessibility/java/com/android/server/accessibility/gestures/TouchState.java
@@ -199,6 +199,9 @@
case AccessibilityEvent.TYPE_VIEW_HOVER_EXIT:
mLastTouchedWindowId = event.getWindowId();
break;
+ case AccessibilityEvent.TYPE_TOUCH_INTERACTION_END:
+ mAms.moveNonProxyTopFocusedDisplayToTopIfNeeded();
+ break;
}
}
diff --git a/services/core/java/com/android/server/wm/WindowManagerInternal.java b/services/core/java/com/android/server/wm/WindowManagerInternal.java
index 4922523..792ec2e 100644
--- a/services/core/java/com/android/server/wm/WindowManagerInternal.java
+++ b/services/core/java/com/android/server/wm/WindowManagerInternal.java
@@ -444,6 +444,11 @@
public abstract IBinder getFocusedWindowTokenFromWindowStates();
/**
+ * Moves the given display to the top.
+ */
+ public abstract void moveDisplayToTopIfAllowed(int displayId);
+
+ /**
* @return Whether the keyguard is engaged.
*/
public abstract boolean isKeyguardLocked();
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 62b3c7c..8822193 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -7716,6 +7716,11 @@
}
@Override
+ public void moveDisplayToTopIfAllowed(int displayId) {
+ WindowManagerService.this.moveDisplayToTopIfAllowed(displayId);
+ }
+
+ @Override
public boolean isKeyguardLocked() {
return WindowManagerService.this.isKeyguardLocked();
}
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/SystemActionPerformerTest.java b/services/tests/servicestests/src/com/android/server/accessibility/SystemActionPerformerTest.java
index d9461aa..b62dbcd 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/SystemActionPerformerTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/SystemActionPerformerTest.java
@@ -108,6 +108,7 @@
@Mock private StatusBarManager mMockStatusBarManager;
@Mock private ScreenshotHelper mMockScreenshotHelper;
@Mock private SystemActionPerformer.SystemActionsChangedListener mMockListener;
+ @Mock private SystemActionPerformer.DisplayUpdateCallBack mMockCallback;
@Before
public void setup() {
@@ -125,7 +126,7 @@
mMockContext,
mMockWindowManagerInternal,
() -> mMockScreenshotHelper,
- mMockListener);
+ mMockListener, mMockCallback);
}
private void setupWithRealContext() {
@@ -133,7 +134,7 @@
InstrumentationRegistry.getContext(),
mMockWindowManagerInternal,
() -> mMockScreenshotHelper,
- mMockListener);
+ mMockListener, mMockCallback);
}
// We need below two help functions because AccessbilityAction.equals function only compares