diff options
| author | Svetoslav Ganov <svetoslavganov@google.com> | 2012-02-21 13:46:36 -0800 |
|---|---|---|
| committer | Svetoslav Ganov <svetoslavganov@google.com> | 2012-02-21 17:09:09 -0800 |
| commit | 0d04e245534cf777dfaf16dce3c51553837c14ff (patch) | |
| tree | 5ef4b779312394e890bfe5078901e896cc92591a /core/java/android/view/accessibility | |
| parent | b6ad5b14cbb09f8a10c3155895337c773e7a850b (diff) | |
| download | frameworks_base-0d04e245534cf777dfaf16dce3c51553837c14ff.zip frameworks_base-0d04e245534cf777dfaf16dce3c51553837c14ff.tar.gz frameworks_base-0d04e245534cf777dfaf16dce3c51553837c14ff.tar.bz2 | |
Improving accessibility APIs used for UI automation.
1. UiTestAutomationBridge was accessing the root node in the
active window by tracking the accessibility event stream
and keeping the last active window changing event. Now
the bridge is stateless and the root node is fetched by
passing special window and view id with the request to
the system.
2. AccessibilityNodeInfos that are cached were not finished,
i.e. not sealed, causing exception when trying to access
their children or rpedecessors.
3. AccessibilityManagerService was not properly restoring its
state after the UI automation bridge disconnects from it.
I particular the devices was still in explore by touch mode
event if no services are enabled and the sutomation bridge
is disconnected.
4. ViewRootImpl for the focused window now fires accessibility
events when accessibility is enabled to allow accessibility
services to determine the current user location.
5. Several missing null checks in ViewRootImpl are fixed since
there were scenraios in which a NPE can occur.
6. Update the internal window content querying tests.
7. ViewRootImpl was firing one extra focus event.
bug:6009813
bug:6026952
Change-Id: Ib2e058d64538ecc268f9ef7a8f36ead047868a05
Diffstat (limited to 'core/java/android/view/accessibility')
| -rw-r--r-- | core/java/android/view/accessibility/AccessibilityInteractionClient.java | 60 | ||||
| -rw-r--r-- | core/java/android/view/accessibility/AccessibilityNodeInfo.java | 17 |
2 files changed, 40 insertions, 37 deletions
diff --git a/core/java/android/view/accessibility/AccessibilityInteractionClient.java b/core/java/android/view/accessibility/AccessibilityInteractionClient.java index 072fdd8..105c010 100644 --- a/core/java/android/view/accessibility/AccessibilityInteractionClient.java +++ b/core/java/android/view/accessibility/AccessibilityInteractionClient.java @@ -153,10 +153,12 @@ public final class AccessibilityInteractionClient * * @param connectionId The id of a connection for interacting with the system. * @param accessibilityWindowId A unique window id. Use - * {@link com.android.server.accessibility.AccessibilityManagerService#ACTIVE_WINDOW_ID} + * {@link android.view.accessibility.AccessibilityNodeInfo#ACTIVE_WINDOW_ID} * to query the currently active window. - * @param accessibilityNodeId A unique node accessibility id - * (accessibility view and virtual descendant id). + * @param accessibilityNodeId A unique view id or virtual descendant id from + * where to start the search. Use + * {@link android.view.accessibility.AccessibilityNodeInfo#ROOT_NODE_ID} + * to start from the root. * @return An {@link AccessibilityNodeInfo} if found, null otherwise. */ public AccessibilityNodeInfo findAccessibilityNodeInfoByAccessibilityId(int connectionId, @@ -164,7 +166,8 @@ public final class AccessibilityInteractionClient try { IAccessibilityServiceConnection connection = getConnection(connectionId); if (connection != null) { - AccessibilityNodeInfo cachedInfo = sAccessibilityNodeInfoCache.get(accessibilityNodeId); + AccessibilityNodeInfo cachedInfo = sAccessibilityNodeInfoCache.get( + accessibilityNodeId); if (cachedInfo != null) { return cachedInfo; } @@ -176,7 +179,7 @@ public final class AccessibilityInteractionClient if (windowScale > 0) { List<AccessibilityNodeInfo> infos = getFindAccessibilityNodeInfosResultAndClear( interactionId); - finalizeAccessibilityNodeInfos(infos, connectionId, windowScale); + finalizeAndCacheAccessibilityNodeInfos(infos, connectionId, windowScale); if (infos != null && !infos.isEmpty()) { return infos.get(0); } @@ -202,10 +205,11 @@ public final class AccessibilityInteractionClient * * @param connectionId The id of a connection for interacting with the system. * @param accessibilityWindowId A unique window id. Use - * {@link com.android.server.accessibility.AccessibilityManagerService#ACTIVE_WINDOW_ID} + * {@link android.view.accessibility.AccessibilityNodeInfo#ACTIVE_WINDOW_ID} * to query the currently active window. - * @param accessibilityNodeId A unique view id from where to start the search. Use - * {@link com.android.server.accessibility.AccessibilityManagerService#ROOT_NODE_ID} + * @param accessibilityNodeId A unique view id or virtual descendant id from + * where to start the search. Use + * {@link android.view.accessibility.AccessibilityNodeInfo#ROOT_NODE_ID} * to start from the root. * @param viewId The id of the view. * @return An {@link AccessibilityNodeInfo} if found, null otherwise. @@ -224,7 +228,7 @@ public final class AccessibilityInteractionClient if (windowScale > 0) { AccessibilityNodeInfo info = getFindAccessibilityNodeInfoResultAndClear( interactionId); - finalizeAccessibilityNodeInfo(info, connectionId, windowScale); + finalizeAndCacheAccessibilityNodeInfo(info, connectionId, windowScale); return info; } } else { @@ -249,10 +253,12 @@ public final class AccessibilityInteractionClient * * @param connectionId The id of a connection for interacting with the system. * @param accessibilityWindowId A unique window id. Use - * {@link com.android.server.accessibility.AccessibilityManagerService#ACTIVE_WINDOW_ID} + * {@link android.view.accessibility.AccessibilityNodeInfo#ACTIVE_WINDOW_ID} * to query the currently active window. - * @param accessibilityNodeId A unique view id from where to start the search. Use - * {@link com.android.server.accessibility.AccessibilityManagerService#ROOT_NODE_ID} + * @param accessibilityNodeId A unique view id or virtual descendant id from + * where to start the search. Use + * {@link android.view.accessibility.AccessibilityNodeInfo#ROOT_NODE_ID} + * to start from the root. * @param text The searched text. * @return A list of found {@link AccessibilityNodeInfo}s. */ @@ -269,7 +275,7 @@ public final class AccessibilityInteractionClient if (windowScale > 0) { List<AccessibilityNodeInfo> infos = getFindAccessibilityNodeInfosResultAndClear( interactionId); - finalizeAccessibilityNodeInfos(infos, connectionId, windowScale); + finalizeAndCacheAccessibilityNodeInfos(infos, connectionId, windowScale); return infos; } } else { @@ -291,9 +297,12 @@ public final class AccessibilityInteractionClient * * @param connectionId The id of a connection for interacting with the system. * @param accessibilityWindowId A unique window id. Use - * {@link com.android.server.accessibility.AccessibilityManagerService#ACTIVE_WINDOW_ID} + * {@link android.view.accessibility.AccessibilityNodeInfo#ACTIVE_WINDOW_ID} * to query the currently active window. - * @param accessibilityNodeId A unique node id (accessibility and virtual descendant id). + * @param accessibilityNodeId A unique view id or virtual descendant id from + * where to start the search. Use + * {@link android.view.accessibility.AccessibilityNodeInfo#ROOT_NODE_ID} + * to start from the root. * @param action The action to perform. * @return Whether the action was performed. */ @@ -323,16 +332,10 @@ public final class AccessibilityInteractionClient } public void clearCache() { - if (DEBUG) { - Log.w(LOG_TAG, "clearCache()"); - } sAccessibilityNodeInfoCache.clear(); } public void removeCachedNode(long accessibilityNodeId) { - if (DEBUG) { - Log.w(LOG_TAG, "removeCachedNode(" + accessibilityNodeId +")"); - } sAccessibilityNodeInfoCache.remove(accessibilityNodeId); } @@ -364,9 +367,6 @@ public final class AccessibilityInteractionClient if (interactionId > mInteractionId) { mFindAccessibilityNodeInfoResult = info; mInteractionId = interactionId; - if (info != null) { - sAccessibilityNodeInfoCache.put(info.getSourceNodeId(), info); - } } mInstanceLock.notifyAll(); } @@ -404,11 +404,6 @@ public final class AccessibilityInteractionClient mFindAccessibilityNodeInfosResult = infos; } mInteractionId = interactionId; - final int infoCount = infos.size(); - for (int i = 0; i < infoCount; i ++) { - AccessibilityNodeInfo info = infos.get(i); - sAccessibilityNodeInfoCache.put(info.getSourceNodeId(), info); - } } mInstanceLock.notifyAll(); } @@ -513,12 +508,13 @@ public final class AccessibilityInteractionClient * @param connectionId The id of the connection to the system. * @param windowScale The source window compatibility scale. */ - private void finalizeAccessibilityNodeInfo(AccessibilityNodeInfo info, int connectionId, + private void finalizeAndCacheAccessibilityNodeInfo(AccessibilityNodeInfo info, int connectionId, float windowScale) { if (info != null) { applyCompatibilityScaleIfNeeded(info, windowScale); info.setConnectionId(connectionId); info.setSealed(true); + sAccessibilityNodeInfoCache.put(info.getSourceNodeId(), info); } } @@ -529,13 +525,13 @@ public final class AccessibilityInteractionClient * @param connectionId The id of the connection to the system. * @param windowScale The source window compatibility scale. */ - private void finalizeAccessibilityNodeInfos(List<AccessibilityNodeInfo> infos, + private void finalizeAndCacheAccessibilityNodeInfos(List<AccessibilityNodeInfo> infos, int connectionId, float windowScale) { if (infos != null) { final int infosCount = infos.size(); for (int i = 0; i < infosCount; i++) { AccessibilityNodeInfo info = infos.get(i); - finalizeAccessibilityNodeInfo(info, connectionId, windowScale); + finalizeAndCacheAccessibilityNodeInfo(info, connectionId, windowScale); } } } diff --git a/core/java/android/view/accessibility/AccessibilityNodeInfo.java b/core/java/android/view/accessibility/AccessibilityNodeInfo.java index d7d6792..84ad268 100644 --- a/core/java/android/view/accessibility/AccessibilityNodeInfo.java +++ b/core/java/android/view/accessibility/AccessibilityNodeInfo.java @@ -52,7 +52,14 @@ public class AccessibilityNodeInfo implements Parcelable { private static final boolean DEBUG = false; - private static final int UNDEFINED = -1; + /** @hide */ + public static final int UNDEFINED = -1; + + /** @hide */ + public static final long ROOT_NODE_ID = makeNodeId(UNDEFINED, UNDEFINED); + + /** @hide */ + public static final int ACTIVE_WINDOW_ID = UNDEFINED; // Actions. @@ -162,8 +169,8 @@ public class AccessibilityNodeInfo implements Parcelable { // Data. private int mWindowId = UNDEFINED; - private long mSourceNodeId = makeNodeId(UNDEFINED, UNDEFINED); - private long mParentNodeId = makeNodeId(UNDEFINED, UNDEFINED); + private long mSourceNodeId = ROOT_NODE_ID; + private long mParentNodeId = ROOT_NODE_ID; private int mBooleanProperties; private final Rect mBoundsInParent = new Rect(); @@ -1160,8 +1167,8 @@ public class AccessibilityNodeInfo implements Parcelable { */ private void clear() { mSealed = false; - mSourceNodeId = makeNodeId(UNDEFINED, UNDEFINED); - mParentNodeId = makeNodeId(UNDEFINED, UNDEFINED); + mSourceNodeId = ROOT_NODE_ID; + mParentNodeId = ROOT_NODE_ID; mWindowId = UNDEFINED; mConnectionId = UNDEFINED; mChildIds.clear(); |
