diff options
| author | 2020-11-18 05:57:28 +0000 | |
|---|---|---|
| committer | 2020-11-18 05:57:28 +0000 | |
| commit | e12c50e04242730a54d0abae5e4efc55e5835bea (patch) | |
| tree | 2d1a37275b87e8d23fd484138a8051d53bd23005 | |
| parent | 0b058f643f207b35ac972208b7de94115d4e256a (diff) | |
| parent | a7de339302764ff58359e8c07cf637367c2c7d64 (diff) | |
Merge "Fix AccessibilityService#getWindows time out"
| -rw-r--r-- | services/core/java/com/android/server/wm/AccessibilityController.java | 72 |
1 files changed, 68 insertions, 4 deletions
diff --git a/services/core/java/com/android/server/wm/AccessibilityController.java b/services/core/java/com/android/server/wm/AccessibilityController.java index f4e0fb16ed3f..6bd49902e2f8 100644 --- a/services/core/java/com/android/server/wm/AccessibilityController.java +++ b/services/core/java/com/android/server/wm/AccessibilityController.java @@ -70,6 +70,7 @@ import com.android.server.wm.WindowManagerInternal.WindowsForAccessibilityCallba import java.io.PrintWriter; import java.util.ArrayList; +import java.util.Arrays; import java.util.HashSet; import java.util.List; import java.util.Set; @@ -93,6 +94,9 @@ final class AccessibilityController { private SparseArray<WindowsForAccessibilityObserver> mWindowsForAccessibilityObserver = new SparseArray<>(); + // Set to true if initializing window population complete. + private boolean mAllObserversInitialized = true; + public boolean setMagnificationCallbacksLocked(int displayId, MagnificationCallbacks callbacks) { boolean result = false; @@ -111,7 +115,7 @@ final class AccessibilityController { } } else { final DisplayMagnifier displayMagnifier = mDisplayMagnifiers.get(displayId); - if (displayMagnifier == null) { + if (displayMagnifier == null) { throw new IllegalStateException("Magnification callbacks already cleared!"); } displayMagnifier.destroyLocked(); @@ -151,8 +155,10 @@ final class AccessibilityController { "Windows for accessibility callback of display " + displayId + " already set!"); } - mWindowsForAccessibilityObserver.put(displayId, - new WindowsForAccessibilityObserver(mService, displayId, callback)); + final WindowsForAccessibilityObserver observer = + new WindowsForAccessibilityObserver(mService, displayId, callback); + mWindowsForAccessibilityObserver.put(displayId, observer); + mAllObserversInitialized &= observer.mInitialized; } else { if (isEmbeddedDisplay(dc)) { // If this display is an embedded one, its window observer should be removed along @@ -276,6 +282,41 @@ final class AccessibilityController { if (observer != null) { observer.performComputeChangedWindowsNotLocked(false); } + // Since we abandon initializing observers if no window has focus, make sure all observers + // are initialized. + sendCallbackToUninitializedObserversIfNeeded(); + } + + private void sendCallbackToUninitializedObserversIfNeeded() { + List<WindowsForAccessibilityObserver> unInitializedObservers; + synchronized (mService.mGlobalLock) { + if (mAllObserversInitialized) { + return; + } + if (mService.mRoot.getTopFocusedDisplayContent().mCurrentFocus == null) { + return; + } + unInitializedObservers = new ArrayList<>(); + for (int i = mWindowsForAccessibilityObserver.size() - 1; i >= 0; --i) { + final WindowsForAccessibilityObserver observer = + mWindowsForAccessibilityObserver.valueAt(i); + if (!observer.mInitialized) { + unInitializedObservers.add(observer); + } + } + // Reset the flag to record the new added observer. + mAllObserversInitialized = true; + } + + boolean areAllObserversInitialized = true; + for (int i = unInitializedObservers.size() - 1; i >= 0; --i) { + final WindowsForAccessibilityObserver observer = unInitializedObservers.get(i); + observer.performComputeChangedWindowsNotLocked(true); + areAllObserversInitialized &= observer.mInitialized; + } + synchronized (mService.mGlobalLock) { + mAllObserversInitialized &= areAllObserversInitialized; + } } /** @@ -362,6 +403,8 @@ final class AccessibilityController { + "Magnification display# " + mDisplayMagnifiers.keyAt(i)); } } + pw.println(prefix + + "mWindowsForAccessibilityObserver=" + mWindowsForAccessibilityObserver); } private void removeObserverOfEmbeddedDisplay(WindowsForAccessibilityObserver @@ -1217,6 +1260,9 @@ final class AccessibilityController { private final IntArray mEmbeddedDisplayIdList = new IntArray(0); + // Set to true if initializing window population complete. + private boolean mInitialized; + public WindowsForAccessibilityObserver(WindowManagerService windowManagerService, int displayId, WindowsForAccessibilityCallback callback) { @@ -1275,10 +1321,17 @@ final class AccessibilityController { // the window manager is still looking for where to put it. // We will do the work when we get a focus change callback. final WindowState topFocusedWindowState = getTopFocusWindow(); - if (topFocusedWindowState == null) return; + if (topFocusedWindowState == null) { + if (DEBUG) { + Slog.d(LOG_TAG, "top focused window is null, compute it again later"); + } + return; + } final DisplayContent dc = mService.mRoot.getDisplayContent(mDisplayId); if (dc == null) { + //It should not happen because it is created while adding the callback. + Slog.w(LOG_TAG, "display content is null, should be created later"); return; } final Display display = dc.getDisplay(); @@ -1370,6 +1423,7 @@ final class AccessibilityController { // Recycle the windows as we do not need them. clearAndRecycleWindows(windows); + mInitialized = true; } private boolean windowMattersToAccessibility(WindowState windowState, @@ -1555,6 +1609,16 @@ final class AccessibilityController { return mService.mRoot.getTopFocusedDisplayContent().mCurrentFocus; } + @Override + public String toString() { + return "WindowsForAccessibilityObserver{" + + "mDisplayId=" + mDisplayId + + ", mEmbeddedDisplayIdList=" + + Arrays.toString(mEmbeddedDisplayIdList.toArray()) + + ", mInitialized=" + mInitialized + + '}'; + } + private class MyHandler extends Handler { public static final int MESSAGE_COMPUTE_CHANGED_WINDOWS = 1; |