summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Ryan Lin <ryanlwlin@google.com> 2020-11-18 05:57:28 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2020-11-18 05:57:28 +0000
commite12c50e04242730a54d0abae5e4efc55e5835bea (patch)
tree2d1a37275b87e8d23fd484138a8051d53bd23005
parent0b058f643f207b35ac972208b7de94115d4e256a (diff)
parenta7de339302764ff58359e8c07cf637367c2c7d64 (diff)
Merge "Fix AccessibilityService#getWindows time out"
-rw-r--r--services/core/java/com/android/server/wm/AccessibilityController.java72
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;