summaryrefslogtreecommitdiff
path: root/core/java/android
diff options
context:
space:
mode:
authorJacky Kao <jackykao@google.com>2019-09-12 09:59:04 +0800
committerJacky Kao <jackykao@google.com>2019-09-16 17:00:39 +0800
commit35b8966e77daf6ba16dd67d0dd4e50b3bc329db5 (patch)
treef9bb0dd97c4dd0207cc92ff6760a74074b6deb87 /core/java/android
parent2cd85a8ae055a79e7557deb06e776b4acb628b53 (diff)
Modifying the mechanism of A11y window cache
For supoorting new API as below, the A11y window cache needs to modify from one dimension to two dimension. The first dimension is window Id, the second(new) dimention is the display Id. SparseArray<List<AccessibilityWindowInfo>> getWindowsOnAllDisplays() Bug: 133279356 Test: a11y CTS & unit tests Change-Id: Ida49ef22de67bd81353a896491dcae56ed751fd1
Diffstat (limited to 'core/java/android')
-rw-r--r--core/java/android/view/accessibility/AccessibilityCache.java204
-rw-r--r--core/java/android/view/accessibility/AccessibilityInteractionClient.java13
2 files changed, 159 insertions, 58 deletions
diff --git a/core/java/android/view/accessibility/AccessibilityCache.java b/core/java/android/view/accessibility/AccessibilityCache.java
index 484d9a1d173b..dc8bf9b5fbae 100644
--- a/core/java/android/view/accessibility/AccessibilityCache.java
+++ b/core/java/android/view/accessibility/AccessibilityCache.java
@@ -71,7 +71,9 @@ public class AccessibilityCache {
private boolean mIsAllWindowsCached;
- private final SparseArray<AccessibilityWindowInfo> mWindowCache =
+ // The SparseArray of all {@link AccessibilityWindowInfo}s on all displays.
+ // The key of outer SparseArray is display ID and the key of inner SparseArray is window ID.
+ private final SparseArray<SparseArray<AccessibilityWindowInfo>> mWindowCacheByDisplay =
new SparseArray<>();
private final SparseArray<LongSparseArray<AccessibilityNodeInfo>> mNodeCache =
@@ -84,34 +86,66 @@ public class AccessibilityCache {
mAccessibilityNodeRefresher = nodeRefresher;
}
- public void setWindows(List<AccessibilityWindowInfo> windows) {
+ /**
+ * Sets all {@link AccessibilityWindowInfo}s of all displays into the cache.
+ * The key of SparseArray is display ID.
+ *
+ * @param windowsOnAllDisplays The accessibility windows of all displays.
+ */
+ public void setWindowsOnAllDisplays(
+ SparseArray<List<AccessibilityWindowInfo>> windowsOnAllDisplays) {
synchronized (mLock) {
if (DEBUG) {
Log.i(LOG_TAG, "Set windows");
}
- clearWindowCache();
- if (windows == null) {
+ clearWindowCacheLocked();
+ if (windowsOnAllDisplays == null) {
return;
}
- final int windowCount = windows.size();
- for (int i = 0; i < windowCount; i++) {
- final AccessibilityWindowInfo window = windows.get(i);
- addWindow(window);
+
+ final int displayCounts = windowsOnAllDisplays.size();
+ for (int i = 0; i < displayCounts; i++) {
+ final List<AccessibilityWindowInfo> windowsOfDisplay =
+ windowsOnAllDisplays.valueAt(i);
+
+ if (windowsOfDisplay == null) {
+ continue;
+ }
+
+ final int displayId = windowsOnAllDisplays.keyAt(i);
+ final int windowCount = windowsOfDisplay.size();
+ for (int j = 0; j < windowCount; j++) {
+ addWindowByDisplayLocked(displayId, windowsOfDisplay.get(j));
+ }
}
mIsAllWindowsCached = true;
}
}
+ /**
+ * Sets an {@link AccessibilityWindowInfo} into the cache.
+ *
+ * @param window The accessibility window.
+ */
public void addWindow(AccessibilityWindowInfo window) {
synchronized (mLock) {
if (DEBUG) {
- Log.i(LOG_TAG, "Caching window: " + window.getId());
+ Log.i(LOG_TAG, "Caching window: " + window.getId() + " at display Id [ "
+ + window.getDisplayId() + " ]");
}
- final int windowId = window.getId();
- mWindowCache.put(windowId, new AccessibilityWindowInfo(window));
+ addWindowByDisplayLocked(window.getDisplayId(), window);
}
}
+ private void addWindowByDisplayLocked(int displayId, AccessibilityWindowInfo window) {
+ SparseArray<AccessibilityWindowInfo> windows = mWindowCacheByDisplay.get(displayId);
+ if (windows == null) {
+ windows = new SparseArray<>();
+ mWindowCacheByDisplay.put(displayId, windows);
+ }
+ final int windowId = window.getId();
+ windows.put(windowId, new AccessibilityWindowInfo(window));
+ }
/**
* Notifies the cache that the something in the UI changed. As a result
* the cache will either refresh some nodes or evict some nodes.
@@ -236,44 +270,82 @@ public class AccessibilityCache {
}
}
- public List<AccessibilityWindowInfo> getWindows() {
+ /**
+ * Gets all {@link AccessibilityWindowInfo}s of all displays from the cache.
+ *
+ * @return All cached {@link AccessibilityWindowInfo}s of all displays
+ * or null if such not found. The key of SparseArray is display ID.
+ */
+ public SparseArray<List<AccessibilityWindowInfo>> getWindowsOnAllDisplays() {
synchronized (mLock) {
if (!mIsAllWindowsCached) {
return null;
}
+ final SparseArray<List<AccessibilityWindowInfo>> returnWindows = new SparseArray<>();
+ final int displayCounts = mWindowCacheByDisplay.size();
- final int windowCount = mWindowCache.size();
- if (windowCount > 0) {
- // Careful to return the windows in a decreasing layer order.
- SparseArray<AccessibilityWindowInfo> sortedWindows = mTempWindowArray;
- sortedWindows.clear();
+ if (displayCounts > 0) {
+ for (int i = 0; i < displayCounts; i++) {
+ final int displayId = mWindowCacheByDisplay.keyAt(i);
+ final SparseArray<AccessibilityWindowInfo> windowsOfDisplay =
+ mWindowCacheByDisplay.valueAt(i);
- for (int i = 0; i < windowCount; i++) {
- AccessibilityWindowInfo window = mWindowCache.valueAt(i);
- sortedWindows.put(window.getLayer(), window);
- }
+ if (windowsOfDisplay == null) {
+ continue;
+ }
- // It's possible in transient conditions for two windows to share the same
- // layer, which results in sortedWindows being smaller than mWindowCache
- final int sortedWindowCount = sortedWindows.size();
- List<AccessibilityWindowInfo> windows = new ArrayList<>(sortedWindowCount);
- for (int i = sortedWindowCount - 1; i >= 0; i--) {
- AccessibilityWindowInfo window = sortedWindows.valueAt(i);
- windows.add(new AccessibilityWindowInfo(window));
- sortedWindows.removeAt(i);
- }
+ final int windowCount = windowsOfDisplay.size();
+ if (windowCount > 0) {
+ // Careful to return the windows in a decreasing layer order.
+ SparseArray<AccessibilityWindowInfo> sortedWindows = mTempWindowArray;
+ sortedWindows.clear();
- return windows;
+ for (int j = 0; j < windowCount; j++) {
+ AccessibilityWindowInfo window = windowsOfDisplay.valueAt(j);
+ sortedWindows.put(window.getLayer(), window);
+ }
+
+ // It's possible in transient conditions for two windows to share the same
+ // layer, which results in sortedWindows being smaller than
+ // mWindowCacheByDisplay
+ final int sortedWindowCount = sortedWindows.size();
+ List<AccessibilityWindowInfo> windows =
+ new ArrayList<>(sortedWindowCount);
+ for (int j = sortedWindowCount - 1; j >= 0; j--) {
+ AccessibilityWindowInfo window = sortedWindows.valueAt(j);
+ windows.add(new AccessibilityWindowInfo(window));
+ sortedWindows.removeAt(j);
+ }
+ returnWindows.put(displayId, windows);
+ }
+ }
+ return returnWindows;
}
return null;
}
}
+ /**
+ * Gets an {@link AccessibilityWindowInfo} by windowId.
+ *
+ * @param windowId The id of the window.
+ *
+ * @return The {@link AccessibilityWindowInfo} or null if such not found.
+ */
public AccessibilityWindowInfo getWindow(int windowId) {
synchronized (mLock) {
- AccessibilityWindowInfo window = mWindowCache.get(windowId);
- if (window != null) {
- return new AccessibilityWindowInfo(window);
+ final int displayCounts = mWindowCacheByDisplay.size();
+ for (int i = 0; i < displayCounts; i++) {
+ final SparseArray<AccessibilityWindowInfo> windowsOfDisplay =
+ mWindowCacheByDisplay.valueAt(i);
+ if (windowsOfDisplay == null) {
+ continue;
+ }
+
+ AccessibilityWindowInfo window = windowsOfDisplay.get(windowId);
+ if (window != null) {
+ return new AccessibilityWindowInfo(window);
+ }
}
return null;
}
@@ -358,7 +430,7 @@ public class AccessibilityCache {
if (DEBUG) {
Log.i(LOG_TAG, "clear()");
}
- clearWindowCache();
+ clearWindowCacheLocked();
final int nodesForWindowCount = mNodeCache.size();
for (int i = nodesForWindowCount - 1; i >= 0; i--) {
final int windowId = mNodeCache.keyAt(i);
@@ -370,8 +442,23 @@ public class AccessibilityCache {
}
}
- private void clearWindowCache() {
- mWindowCache.clear();
+ private void clearWindowCacheLocked() {
+ if (DEBUG) {
+ Log.i(LOG_TAG, "clearWindowCacheLocked");
+ }
+ final int displayCounts = mWindowCacheByDisplay.size();
+
+ if (displayCounts > 0) {
+ for (int i = displayCounts - 1; i >= 0; i--) {
+ final int displayId = mWindowCacheByDisplay.keyAt(i);
+ final SparseArray<AccessibilityWindowInfo> windows =
+ mWindowCacheByDisplay.get(displayId);
+ if (windows != null) {
+ windows.clear();
+ }
+ mWindowCacheByDisplay.remove(displayId);
+ }
+ }
mIsAllWindowsCached = false;
}
@@ -444,32 +531,41 @@ public class AccessibilityCache {
public void checkIntegrity() {
synchronized (mLock) {
// Get the root.
- if (mWindowCache.size() <= 0 && mNodeCache.size() == 0) {
+ if (mWindowCacheByDisplay.size() <= 0 && mNodeCache.size() == 0) {
return;
}
AccessibilityWindowInfo focusedWindow = null;
AccessibilityWindowInfo activeWindow = null;
- final int windowCount = mWindowCache.size();
- for (int i = 0; i < windowCount; i++) {
- AccessibilityWindowInfo window = mWindowCache.valueAt(i);
+ final int displayCounts = mWindowCacheByDisplay.size();
+ for (int i = 0; i < displayCounts; i++) {
+ final SparseArray<AccessibilityWindowInfo> windowsOfDisplay =
+ mWindowCacheByDisplay.valueAt(i);
- // Check for one active window.
- if (window.isActive()) {
- if (activeWindow != null) {
- Log.e(LOG_TAG, "Duplicate active window:" + window);
- } else {
- activeWindow = window;
- }
+ if (windowsOfDisplay == null) {
+ continue;
}
- // Check for one focused window.
- if (window.isFocused()) {
- if (focusedWindow != null) {
- Log.e(LOG_TAG, "Duplicate focused window:" + window);
- } else {
- focusedWindow = window;
+ final int windowCount = windowsOfDisplay.size();
+ for (int j = 0; j < windowCount; j++) {
+ final AccessibilityWindowInfo window = windowsOfDisplay.valueAt(j);
+
+ // Check for one active window.
+ if (window.isActive()) {
+ if (activeWindow != null) {
+ Log.e(LOG_TAG, "Duplicate active window:" + window);
+ } else {
+ activeWindow = window;
+ }
+ }
+ // Check for one focused window.
+ if (window.isFocused()) {
+ if (focusedWindow != null) {
+ Log.e(LOG_TAG, "Duplicate focused window:" + window);
+ } else {
+ focusedWindow = window;
+ }
}
}
}
diff --git a/core/java/android/view/accessibility/AccessibilityInteractionClient.java b/core/java/android/view/accessibility/AccessibilityInteractionClient.java
index 4db6f4f808f2..d9fa9f24f1ae 100644
--- a/core/java/android/view/accessibility/AccessibilityInteractionClient.java
+++ b/core/java/android/view/accessibility/AccessibilityInteractionClient.java
@@ -28,6 +28,7 @@ import android.os.SystemClock;
import android.util.Log;
import android.util.LongSparseArray;
import android.util.SparseArray;
+import android.view.Display;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.ArrayUtils;
@@ -267,12 +268,14 @@ public final class AccessibilityInteractionClient
try {
IAccessibilityServiceConnection connection = getConnection(connectionId);
if (connection != null) {
- List<AccessibilityWindowInfo> windows = sAccessibilityCache.getWindows();
- if (windows != null) {
+ SparseArray<List<AccessibilityWindowInfo>> allWindows =
+ sAccessibilityCache.getWindowsOnAllDisplays();
+ List<AccessibilityWindowInfo> windows;
+ if (allWindows != null) {
if (DEBUG) {
Log.i(LOG_TAG, "Windows cache hit");
}
- return windows;
+ return allWindows.valueAt(Display.DEFAULT_DISPLAY);
}
if (DEBUG) {
Log.i(LOG_TAG, "Windows cache miss");
@@ -284,7 +287,9 @@ public final class AccessibilityInteractionClient
Binder.restoreCallingIdentity(identityToken);
}
if (windows != null) {
- sAccessibilityCache.setWindows(windows);
+ allWindows = new SparseArray<>();
+ allWindows.put(Display.DEFAULT_DISPLAY, windows);
+ sAccessibilityCache.setWindowsOnAllDisplays(allWindows);
return windows;
}
} else {