Merge "Force input focus to the last focused non-proxy display." into udc-dev
This commit is contained in:
@@ -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--) {
|
||||
|
||||
@@ -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.
|
||||
*
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user