diff --git a/services/core/java/com/android/server/wm/AccessibilityController.java b/services/core/java/com/android/server/wm/AccessibilityController.java index 14fb94d41b3b9..03abe8931e28c 100644 --- a/services/core/java/com/android/server/wm/AccessibilityController.java +++ b/services/core/java/com/android/server/wm/AccessibilityController.java @@ -318,11 +318,6 @@ final class AccessibilityController { if (displayMagnifier != null) { displayMagnifier.onDisplaySizeChanged(displayContent); } - final WindowsForAccessibilityObserver windowsForA11yObserver = - mWindowsForAccessibilityObserver.get(displayId); - if (windowsForA11yObserver != null) { - windowsForA11yObserver.scheduleComputeChangedWindows(); - } } void onAppWindowTransition(int displayId, int transition) { @@ -350,11 +345,6 @@ final class AccessibilityController { if (displayMagnifier != null) { displayMagnifier.onWindowTransition(windowState, transition); } - final WindowsForAccessibilityObserver windowsForA11yObserver = - mWindowsForAccessibilityObserver.get(displayId); - if (windowsForA11yObserver != null) { - windowsForA11yObserver.scheduleComputeChangedWindows(); - } } void onWindowFocusChangedNot(int displayId) { diff --git a/services/core/java/com/android/server/wm/AccessibilityWindowsPopulator.java b/services/core/java/com/android/server/wm/AccessibilityWindowsPopulator.java index 0260f8584fa0e..cf1ff7713d707 100644 --- a/services/core/java/com/android/server/wm/AccessibilityWindowsPopulator.java +++ b/services/core/java/com/android/server/wm/AccessibilityWindowsPopulator.java @@ -48,6 +48,14 @@ import java.util.List; public final class AccessibilityWindowsPopulator extends WindowInfosListener { private static final String TAG = AccessibilityWindowsPopulator.class.getSimpleName(); + // If the surface flinger callback is not coming within in 2 frames time, i.e. about + // 35ms, then assuming the windows become stable. + private static final int SURFACE_FLINGER_CALLBACK_WINDOWS_STABLE_TIMES_MS = 35; + // To avoid the surface flinger callbacks always comes within in 2 frames, then no windows + // are reported to the A11y framework, and the animation duration time is 500ms, so setting + // this value as the max timeout value to force computing changed windows. + private static final int WINDOWS_CHANGED_NOTIFICATION_MAX_DURATION_TIMES_MS = 500; + private static final float[] sTempFloats = new float[9]; private final WindowManagerService mService; @@ -114,6 +122,12 @@ public final class AccessibilityWindowsPopulator extends WindowInfosListener { } } if (mWindowsNotificationEnabled) { + if (!mHandler.hasMessages( + MyHandler.MESSAGE_NOTIFY_WINDOWS_CHANGED_BY_TIMEOUT)) { + mHandler.sendEmptyMessageDelayed( + MyHandler.MESSAGE_NOTIFY_WINDOWS_CHANGED_BY_TIMEOUT, + WINDOWS_CHANGED_NOTIFICATION_MAX_DURATION_TIMES_MS); + } populateVisibleWindowHandlesAndNotifyWindowsChangeIfNeededLocked(); } } @@ -165,11 +179,18 @@ public final class AccessibilityWindowsPopulator extends WindowInfosListener { final int displayId = tempWindowHandleList.keyAt(i); mInputWindowHandlesOnDisplays.put(displayId, tempWindowHandleList.get(displayId)); } - if (displayIdsForWindowsChanged.size() > 0 - && !mHandler.hasMessages(MyHandler.MESSAGE_NOTIFY_WINDOWS_CHANGED)) { - mHandler.obtainMessage(MyHandler.MESSAGE_NOTIFY_WINDOWS_CHANGED, - displayIdsForWindowsChanged).sendToTarget(); + + if (displayIdsForWindowsChanged.size() > 0) { + if (!mHandler.hasMessages(MyHandler.MESSAGE_NOTIFY_WINDOWS_CHANGED)) { + mHandler.obtainMessage(MyHandler.MESSAGE_NOTIFY_WINDOWS_CHANGED, + displayIdsForWindowsChanged).sendToTarget(); + } + + return; } + mHandler.removeMessages(MyHandler.MESSAGE_NOTIFY_WINDOWS_CHANGED_BY_UI_STABLE); + mHandler.sendEmptyMessageDelayed(MyHandler.MESSAGE_NOTIFY_WINDOWS_CHANGED_BY_UI_STABLE, + SURFACE_FLINGER_CALLBACK_WINDOWS_STABLE_TIMES_MS); } private void getDisplaysForWindowsChangedLocked(List outDisplayIdsForWindowsChanged, @@ -239,22 +260,39 @@ public final class AccessibilityWindowsPopulator extends WindowInfosListener { } private void notifyWindowsChanged(@NonNull List displayIdsForWindowsChanged) { + mHandler.removeMessages(MyHandler.MESSAGE_NOTIFY_WINDOWS_CHANGED_BY_TIMEOUT); + for (int i = 0; i < displayIdsForWindowsChanged.size(); i++) { mAccessibilityController.performComputeChangedWindowsNot( displayIdsForWindowsChanged.get(i), false); } } + private void forceUpdateWindows() { + final List displayIdsForWindowsChanged = new ArrayList<>(); + + synchronized (mLock) { + for (int i = 0; i < mInputWindowHandlesOnDisplays.size(); i++) { + final int displayId = mInputWindowHandlesOnDisplays.keyAt(i); + displayIdsForWindowsChanged.add(displayId); + } + } + notifyWindowsChanged(displayIdsForWindowsChanged); + } + @GuardedBy("mLock") private void releaseResources() { mInputWindowHandlesOnDisplays.clear(); mMagnificationSpecInverseMatrix.clear(); mVisibleWindows.clear(); mWindowsNotificationEnabled = false; + mHandler.removeCallbacksAndMessages(null); } private class MyHandler extends Handler { public static final int MESSAGE_NOTIFY_WINDOWS_CHANGED = 1; + public static final int MESSAGE_NOTIFY_WINDOWS_CHANGED_BY_UI_STABLE = 2; + public static final int MESSAGE_NOTIFY_WINDOWS_CHANGED_BY_TIMEOUT = 3; MyHandler(Looper looper) { super(looper, null, false); @@ -262,9 +300,24 @@ public final class AccessibilityWindowsPopulator extends WindowInfosListener { @Override public void handleMessage(Message message) { - if (message.what == MESSAGE_NOTIFY_WINDOWS_CHANGED) { - final List displayIdsForWindowsChanged = (List) message.obj; - notifyWindowsChanged(displayIdsForWindowsChanged); + switch (message.what) { + case MESSAGE_NOTIFY_WINDOWS_CHANGED: { + final List displayIdsForWindowsChanged = (List) message.obj; + notifyWindowsChanged(displayIdsForWindowsChanged); + } break; + + case MESSAGE_NOTIFY_WINDOWS_CHANGED_BY_UI_STABLE: { + forceUpdateWindows(); + } break; + + case MESSAGE_NOTIFY_WINDOWS_CHANGED_BY_TIMEOUT: { + Slog.w(TAG, "Windows change within in 2 frames continuously over 500 ms " + + "and notify windows changed immediately"); + mHandler.removeMessages( + MyHandler.MESSAGE_NOTIFY_WINDOWS_CHANGED_BY_UI_STABLE); + + forceUpdateWindows(); + } break; } } } diff --git a/services/core/java/com/android/server/wm/ShellRoot.java b/services/core/java/com/android/server/wm/ShellRoot.java index 2eab3bab0bd37..8ec9ef23a3f6b 100644 --- a/services/core/java/com/android/server/wm/ShellRoot.java +++ b/services/core/java/com/android/server/wm/ShellRoot.java @@ -196,9 +196,5 @@ public class ShellRoot { mAccessibilityWindow = null; } } - if (mDisplayContent.mWmService.mAccessibilityController.hasCallbacks()) { - mDisplayContent.mWmService.mAccessibilityController.onSomeWindowResizedOrMoved( - mDisplayContent.getDisplayId()); - } } } diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index 87ef09ee5982a..26acf43cf9edf 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -4992,9 +4992,6 @@ class WindowState extends WindowContainer implements WindowManagerP if (isAnimating()) { return; } - if (mWmService.mAccessibilityController.hasCallbacks()) { - mWmService.mAccessibilityController.onSomeWindowResizedOrMoved(getDisplayId()); - } if (!isSelfOrAncestorWindowAnimatingExit()) { return;