summaryrefslogtreecommitdiffstats
path: root/core/java/android/view/accessibility
diff options
context:
space:
mode:
authorSvetoslav Ganov <svetoslavganov@google.com>2012-02-21 13:46:36 -0800
committerSvetoslav Ganov <svetoslavganov@google.com>2012-02-21 17:09:09 -0800
commit0d04e245534cf777dfaf16dce3c51553837c14ff (patch)
tree5ef4b779312394e890bfe5078901e896cc92591a /core/java/android/view/accessibility
parentb6ad5b14cbb09f8a10c3155895337c773e7a850b (diff)
downloadframeworks_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.java60
-rw-r--r--core/java/android/view/accessibility/AccessibilityNodeInfo.java17
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();