From 4339880c1e742ae29a82118c2d38ac6ca9210ce3 Mon Sep 17 00:00:00 2001 From: ryanlwlin Date: Thu, 14 Apr 2022 23:15:50 +0800 Subject: Fix invalid active window if accessibility framework doesn't track windows If accessibility framework doesn't track windows, the active window is updated when receving window_state_changed event. ViewRootImpl sends this event when performing traversal first time, however the focused window token is not updated yet from InputManagerService. To fix the regression issue, we fallback to the legacy approach for short term solution. Test: atest android.accessibilityservice.cts Bug: 228442331 Change-Id: I032a73b9f4cf408a5dd6cae8a87bd26131ebdbfa --- .../server/accessibility/AccessibilityWindowManager.java | 2 +- .../java/com/android/server/wm/WindowManagerInternal.java | 8 ++++++++ .../java/com/android/server/wm/WindowManagerService.java | 12 ++++++++++++ .../server/accessibility/AccessibilityWindowManagerTest.java | 4 ++-- 4 files changed, 23 insertions(+), 3 deletions(-) diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityWindowManager.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityWindowManager.java index e30639cf416a..9920cc7e8444 100644 --- a/services/accessibility/java/com/android/server/accessibility/AccessibilityWindowManager.java +++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityWindowManager.java @@ -1661,7 +1661,7 @@ public class AccessibilityWindowManager { if (traceWMEnabled()) { logTraceWM("getFocusedWindowToken", ""); } - final IBinder token = mWindowManagerInternal.getFocusedWindowToken(); + final IBinder token = mWindowManagerInternal.getFocusedWindowTokenFromWindowStates(); synchronized (mLock) { return findWindowIdLocked(userId, token); } diff --git a/services/core/java/com/android/server/wm/WindowManagerInternal.java b/services/core/java/com/android/server/wm/WindowManagerInternal.java index 42fad6d14fb9..f8bc26a7d91d 100644 --- a/services/core/java/com/android/server/wm/WindowManagerInternal.java +++ b/services/core/java/com/android/server/wm/WindowManagerInternal.java @@ -432,6 +432,14 @@ public abstract class WindowManagerInternal { */ public abstract IBinder getFocusedWindowToken(); + /** + * Gets the token of the window that has input focus. It is from the focused + * {@link WindowState}. + * + * @return The token. + */ + public abstract IBinder getFocusedWindowTokenFromWindowStates(); + /** * @return Whether the keyguard is engaged. */ diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index eff75bc0622b..4c4dfc557515 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -7681,6 +7681,18 @@ public class WindowManagerService extends IWindowManager.Stub } } + // TODO (b/229837707): Delete this method after changing the solution. + @Override + public IBinder getFocusedWindowTokenFromWindowStates() { + synchronized (mGlobalLock) { + final WindowState windowState = getFocusedWindowLocked(); + if (windowState != null) { + return windowState.mClient.asBinder(); + } + return null; + } + } + @Override public boolean isKeyguardLocked() { return WindowManagerService.this.isKeyguardLocked(); diff --git a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityWindowManagerTest.java b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityWindowManagerTest.java index ca9ab4fa84eb..4f4be6cd634d 100644 --- a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityWindowManagerTest.java +++ b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityWindowManagerTest.java @@ -543,7 +543,7 @@ public class AccessibilityWindowManagerTest { mWindowInfos.get(Display.DEFAULT_DISPLAY).get(DEFAULT_FOCUSED_INDEX + 1).token; final int eventWindowId = mA11yWindowManager.findWindowIdLocked( USER_SYSTEM_ID, eventWindowToken); - when(mMockWindowManagerInternal.getFocusedWindowToken()) + when(mMockWindowManagerInternal.getFocusedWindowTokenFromWindowStates()) .thenReturn(eventWindowToken); final int noUse = 0; @@ -679,7 +679,7 @@ public class AccessibilityWindowManagerTest { mWindowInfos.get(Display.DEFAULT_DISPLAY).get(DEFAULT_FOCUSED_INDEX).token; final int defaultFocusWindowId = mA11yWindowManager.findWindowIdLocked( USER_SYSTEM_ID, defaultFocusWinToken); - when(mMockWindowManagerInternal.getFocusedWindowToken()) + when(mMockWindowManagerInternal.getFocusedWindowTokenFromWindowStates()) .thenReturn(defaultFocusWinToken); final int newFocusWindowId = getWindowIdFromWindowInfosForDisplay(Display.DEFAULT_DISPLAY, DEFAULT_FOCUSED_INDEX + 1); -- cgit v1.2.3-59-g8ed1b