Merge "Force input focus to the last focused non-proxy display." into udc-dev

This commit is contained in:
Sally Yuen
2023-04-18 22:14:31 +00:00
committed by Android (Google) Code Review
7 changed files with 66 additions and 8 deletions

View File

@@ -194,7 +194,8 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
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 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
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 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
}
}
@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--) {

View File

@@ -103,6 +103,9 @@ public class AccessibilityWindowManager {
// 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 @@ public class AccessibilityWindowManager {
}
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 @@ public class AccessibilityWindowManager {
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.
*

View File

@@ -72,6 +72,13 @@ public class SystemActionPerformer {
}
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 class SystemActionPerformer {
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 @@ public class SystemActionPerformer {
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 @@ public class SystemActionPerformer {
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 @@ public class SystemActionPerformer {
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();

View File

@@ -199,6 +199,9 @@ public class TouchState {
case AccessibilityEvent.TYPE_VIEW_HOVER_EXIT:
mLastTouchedWindowId = event.getWindowId();
break;
case AccessibilityEvent.TYPE_TOUCH_INTERACTION_END:
mAms.moveNonProxyTopFocusedDisplayToTopIfNeeded();
break;
}
}

View File

@@ -443,6 +443,11 @@ public abstract class WindowManagerInternal {
*/
public abstract IBinder getFocusedWindowTokenFromWindowStates();
/**
* Moves the given display to the top.
*/
public abstract void moveDisplayToTopIfAllowed(int displayId);
/**
* @return Whether the keyguard is engaged.
*/

View File

@@ -7715,6 +7715,11 @@ public class WindowManagerService extends IWindowManager.Stub
}
}
@Override
public void moveDisplayToTopIfAllowed(int displayId) {
WindowManagerService.this.moveDisplayToTopIfAllowed(displayId);
}
@Override
public boolean isKeyguardLocked() {
return WindowManagerService.this.isKeyguardLocked();

View File

@@ -108,6 +108,7 @@ public class SystemActionPerformerTest {
@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 @@ public class SystemActionPerformerTest {
mMockContext,
mMockWindowManagerInternal,
() -> mMockScreenshotHelper,
mMockListener);
mMockListener, mMockCallback);
}
private void setupWithRealContext() {
@@ -133,7 +134,7 @@ public class SystemActionPerformerTest {
InstrumentationRegistry.getContext(),
mMockWindowManagerInternal,
() -> mMockScreenshotHelper,
mMockListener);
mMockListener, mMockCallback);
}
// We need below two help functions because AccessbilityAction.equals function only compares