diff options
author | Alan Viverette <alanv@google.com> | 2013-09-12 17:16:09 -0700 |
---|---|---|
committer | Alan Viverette <alanv@google.com> | 2013-09-12 17:16:09 -0700 |
commit | 77e9a28e2faa36f127231b842476d47f9823a83a (patch) | |
tree | 5637fce8e0565cc1fdd5f0367f38097a472ca6d6 /core/java/android/view/accessibility | |
parent | 14e55996722db1e74996b837c136a6e188143718 (diff) | |
download | frameworks_base-77e9a28e2faa36f127231b842476d47f9823a83a.zip frameworks_base-77e9a28e2faa36f127231b842476d47f9823a83a.tar.gz frameworks_base-77e9a28e2faa36f127231b842476d47f9823a83a.tar.bz2 |
Add live region politeness to View, AccessibilityNodeInfo
Alters the content change API to contain a bit mask of types of
changes represented by the event. Live regions send CONTENT_CHANGED
events immediately. Removes unused APIs for EXPANDABLE/EXPANDED.
BUG: 10527284
Change-Id: I21523e85e47df23706976dc0a8bf615f83072c04
Diffstat (limited to 'core/java/android/view/accessibility')
3 files changed, 80 insertions, 109 deletions
diff --git a/core/java/android/view/accessibility/AccessibilityEvent.java b/core/java/android/view/accessibility/AccessibilityEvent.java index 82c8163..7e2bffa 100644 --- a/core/java/android/view/accessibility/AccessibilityEvent.java +++ b/core/java/android/view/accessibility/AccessibilityEvent.java @@ -326,7 +326,7 @@ import java.util.List; * <em>Properties:</em></br> * <ul> * <li>{@link #getEventType()} - The type of the event.</li> - * <li>{@link #getContentChangeType()} - The type of content change.</li> + * <li>{@link #getContentChangeTypes()} - The type of content changes.</li> * <li>{@link #getSource()} - The source info (for registered clients).</li> * <li>{@link #getClassName()} - The class name of the source.</li> * <li>{@link #getPackageName()} - The package name of the source.</li> @@ -663,15 +663,27 @@ public final class AccessibilityEvent extends AccessibilityRecord implements Par /** * Change type for {@link #TYPE_WINDOW_CONTENT_CHANGED} event: - * The subtree rooted at the source node changed. + * The type of change is not defined. */ - public static final int CONTENT_CHANGE_TYPE_SUBTREE = 0; + public static final int CONTENT_CHANGE_TYPE_UNDEFINED = 0x00000000; /** * Change type for {@link #TYPE_WINDOW_CONTENT_CHANGED} event: - * Only the source node changed. + * A node in the subtree rooted at the source node was added or removed. */ - public static final int CONTENT_CHANGE_TYPE_NODE = 1; + public static final int CONTENT_CHANGE_TYPE_SUBTREE = 0x00000001; + + /** + * Change type for {@link #TYPE_WINDOW_CONTENT_CHANGED} event: + * The node's text changed. + */ + public static final int CONTENT_CHANGE_TYPE_TEXT = 0x00000002; + + /** + * Change type for {@link #TYPE_WINDOW_CONTENT_CHANGED} event: + * The node's content description changed. + */ + public static final int CONTENT_CHANGE_TYPE_CONTENT_DESCRIPTION = 0x00000004; /** * Mask for {@link AccessibilityEvent} all types. @@ -708,7 +720,7 @@ public final class AccessibilityEvent extends AccessibilityRecord implements Par private long mEventTime; int mMovementGranularity; int mAction; - int mContentChangeType; + int mContentChangeTypes; private final ArrayList<AccessibilityRecord> mRecords = new ArrayList<AccessibilityRecord>(); @@ -728,7 +740,7 @@ public final class AccessibilityEvent extends AccessibilityRecord implements Par mEventType = event.mEventType; mMovementGranularity = event.mMovementGranularity; mAction = event.mAction; - mContentChangeType = event.mContentChangeType; + mContentChangeTypes = event.mContentChangeTypes; mEventTime = event.mEventTime; mPackageName = event.mPackageName; } @@ -792,30 +804,33 @@ public final class AccessibilityEvent extends AccessibilityRecord implements Par } /** - * Gets the type of node tree change signaled by an - * {@link #TYPE_WINDOW_CONTENT_CHANGED} event. + * Gets the bit mask of change types signaled by an + * {@link #TYPE_WINDOW_CONTENT_CHANGED} event. A single event may represent + * multiple change types. * - * @see #CONTENT_CHANGE_TYPE_NODE - * @see #CONTENT_CHANGE_TYPE_SUBTREE - * - * @return The change type. + * @return The bit mask of change types. One or more of: + * <ul> + * <li>{@link AccessibilityEvent#CONTENT_CHANGE_TYPE_CONTENT_DESCRIPTION} + * <li>{@link AccessibilityEvent#CONTENT_CHANGE_TYPE_SUBTREE} + * <li>{@link AccessibilityEvent#CONTENT_CHANGE_TYPE_TEXT} + * <li>{@link AccessibilityEvent#CONTENT_CHANGE_TYPE_UNDEFINED} + * </ul> */ - public int getContentChangeType() { - return mContentChangeType; + public int getContentChangeTypes() { + return mContentChangeTypes; } /** - * Sets the type of node tree change signaled by an + * Sets the bit mask of node tree changes signaled by an * {@link #TYPE_WINDOW_CONTENT_CHANGED} event. * - * @see #CONTENT_CHANGE_TYPE_NODE - * @see #CONTENT_CHANGE_TYPE_SUBTREE - * - * @param changeType The change type. + * @param changeTypes The bit mask of change types. + * @throws IllegalStateException If called from an AccessibilityService. + * @see #getContentChangeTypes() */ - public void setContentChangeType(int changeType) { + public void setContentChangeTypes(int changeTypes) { enforceNotSealed(); - mContentChangeType = changeType; + mContentChangeTypes = changeTypes; } /** @@ -985,7 +1000,7 @@ public final class AccessibilityEvent extends AccessibilityRecord implements Par mEventType = 0; mMovementGranularity = 0; mAction = 0; - mContentChangeType = 0; + mContentChangeTypes = 0; mPackageName = null; mEventTime = 0; while (!mRecords.isEmpty()) { @@ -1004,7 +1019,7 @@ public final class AccessibilityEvent extends AccessibilityRecord implements Par mEventType = parcel.readInt(); mMovementGranularity = parcel.readInt(); mAction = parcel.readInt(); - mContentChangeType = parcel.readInt(); + mContentChangeTypes = parcel.readInt(); mPackageName = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(parcel); mEventTime = parcel.readLong(); mConnectionId = parcel.readInt(); @@ -1057,7 +1072,7 @@ public final class AccessibilityEvent extends AccessibilityRecord implements Par parcel.writeInt(mEventType); parcel.writeInt(mMovementGranularity); parcel.writeInt(mAction); - parcel.writeInt(mContentChangeType); + parcel.writeInt(mContentChangeTypes); TextUtils.writeToParcel(mPackageName, parcel, 0); parcel.writeLong(mEventTime); parcel.writeInt(mConnectionId); @@ -1119,7 +1134,7 @@ public final class AccessibilityEvent extends AccessibilityRecord implements Par builder.append(super.toString()); if (DEBUG) { builder.append("\n"); - builder.append("; ContentChangeType: ").append(mContentChangeType); + builder.append("; ContentChangeTypes: ").append(mContentChangeTypes); builder.append("; sourceWindowId: ").append(mSourceWindowId); builder.append("; mSourceNodeId: ").append(mSourceNodeId); for (int i = 0; i < mRecords.size(); i++) { diff --git a/core/java/android/view/accessibility/AccessibilityNodeInfo.java b/core/java/android/view/accessibility/AccessibilityNodeInfo.java index c61516b..9fc37cf 100644 --- a/core/java/android/view/accessibility/AccessibilityNodeInfo.java +++ b/core/java/android/view/accessibility/AccessibilityNodeInfo.java @@ -418,19 +418,13 @@ public class AccessibilityNodeInfo implements Parcelable { private static final int BOOLEAN_PROPERTY_EDITABLE = 0x00001000; - private static final int BOOLEAN_PROPERTY_LIVE_REGION = 0x00002000; + private static final int BOOLEAN_PROPERTY_OPENS_POPUP = 0x00002000; - private static final int BOOLEAN_PROPERTY_OPENS_POPUP = 0x00004000; + private static final int BOOLEAN_PROPERTY_DISMISSABLE = 0x00004000; - private static final int BOOLEAN_PROPERTY_EXPANDABLE = 0x00008000; + private static final int BOOLEAN_PROPERTY_MULTI_LINE = 0x00008000; - private static final int BOOLEAN_PROPERTY_EXPANDED = 0x00010000; - - private static final int BOOLEAN_PROPERTY_DISMISSABLE = 0x00020000; - - private static final int BOOLEAN_PROPERTY_MULTI_LINE = 0x00040000; - - private static final int BOOLEAN_PROPERTY_CONTENT_INVALID = 0x00080000; + private static final int BOOLEAN_PROPERTY_CONTENT_INVALID = 0x00010000; /** * Bits that provide the id of a virtual descendant of a view. @@ -517,6 +511,7 @@ public class AccessibilityNodeInfo implements Parcelable { private int mTextSelectionStart = UNDEFINED; private int mTextSelectionEnd = UNDEFINED; private int mInputType = InputType.TYPE_NULL; + private int mLiveRegion = View.ACCESSIBILITY_LIVE_REGION_NONE; private Bundle mExtras; @@ -1471,39 +1466,42 @@ public class AccessibilityNodeInfo implements Parcelable { } /** - * Gets if the node is a live region. + * Gets the node's live region mode. * <p> - * A live region is a node that contains information that is important - * for the user and when it changes the user has to be notified. For - * example, if the user plays a video and the application shows a - * progress indicator with the percentage of buffering, then the progress - * indicator should be marked as a live region. - * </p> + * A live region is a node that contains information that is important for + * the user and when it changes the user should be notified. For example, + * in a login screen with a TextView that displays an "incorrect password" + * notification, that view should be marked as a live region with mode + * {@link View#ACCESSIBILITY_LIVE_REGION_POLITE}. * <p> - * It is the responsibility of the accessibility - * service to monitor this region and notify the user if it changes. - * </p> + * It is the responsibility of the accessibility service to monitor + * {@link AccessibilityEvent#TYPE_WINDOW_CONTENT_CHANGED} events indicating + * changes to live region nodes and their children. * - * @return If the node is a live region. + * @return The live region mode, or + * {@link View#ACCESSIBILITY_LIVE_REGION_NONE} if the view is not a + * live region. + * @see android.view.View#getAccessibilityLiveRegion() */ - public boolean isLiveRegion() { - return getBooleanProperty(BOOLEAN_PROPERTY_LIVE_REGION); + public int getLiveRegion() { + return mLiveRegion; } /** - * Sets if the node is a live region for whose changes the user - * should be notified. It is the responsibility of the accessibility - * service to monitor this region and notify the user if it changes. + * Sets the node's live region mode. * <p> - * <strong>Note:</strong> Cannot be called from an - * {@link android.accessibilityservice.AccessibilityService}. - * This class is made immutable before being delivered to an AccessibilityService. - * </p> + * <strong>Note:</strong> Cannot be called from an + * {@link android.accessibilityservice.AccessibilityService}. This class is + * made immutable before being delivered to an AccessibilityService. * - * @param liveRegion If the node is a live region. + * @param mode The live region mode, or + * {@link View#ACCESSIBILITY_LIVE_REGION_NONE} if the view is not a + * live region. + * @see android.view.View#setAccessibilityLiveRegion(int) */ - public void setLiveRegion(boolean liveRegion) { - setBooleanProperty(BOOLEAN_PROPERTY_LIVE_REGION, liveRegion); + public void setLiveRegion(int mode) { + enforceNotSealed(); + mLiveRegion = mode; } /** @@ -1554,52 +1552,6 @@ public class AccessibilityNodeInfo implements Parcelable { } /** - * Gets if the node can be expanded. - * - * @return If the node can be expanded. - */ - public boolean isExpandable() { - return getBooleanProperty(BOOLEAN_PROPERTY_EXPANDABLE); - } - - /** - * Sets if the node can be expanded. - * <p> - * <strong>Note:</strong> Cannot be called from an - * {@link android.accessibilityservice.AccessibilityService}. - * This class is made immutable before being delivered to an AccessibilityService. - * </p> - * - * @param expandable If the node can be expanded. - */ - public void setExpandable(boolean expandable) { - setBooleanProperty(BOOLEAN_PROPERTY_EXPANDABLE, expandable); - } - - /** - * Gets if the node is expanded. - * - * @return If the node is expanded. - */ - public boolean isExpanded() { - return getBooleanProperty(BOOLEAN_PROPERTY_EXPANDED); - } - - /** - * Sets if the node is expanded. - * <p> - * <strong>Note:</strong> Cannot be called from an - * {@link android.accessibilityservice.AccessibilityService}. - * This class is made immutable before being delivered to an AccessibilityService. - * </p> - * - * @param expanded If the node is expanded. - */ - public void setExpanded(boolean expanded) { - setBooleanProperty(BOOLEAN_PROPERTY_EXPANDED, expanded); - } - - /** * Gets if the node can be dismissed. * * @return If the node can be dismissed. @@ -2203,6 +2155,7 @@ public class AccessibilityNodeInfo implements Parcelable { parcel.writeInt(mTextSelectionStart); parcel.writeInt(mTextSelectionEnd); parcel.writeInt(mInputType); + parcel.writeInt(mLiveRegion); if (mExtras != null) { parcel.writeInt(1); @@ -2276,6 +2229,7 @@ public class AccessibilityNodeInfo implements Parcelable { mTextSelectionStart = other.mTextSelectionStart; mTextSelectionEnd = other.mTextSelectionEnd; mInputType = other.mInputType; + mLiveRegion = other.mLiveRegion; if (other.mExtras != null && !other.mExtras.isEmpty()) { getExtras().putAll(other.mExtras); } @@ -2334,6 +2288,7 @@ public class AccessibilityNodeInfo implements Parcelable { mTextSelectionEnd = parcel.readInt(); mInputType = parcel.readInt(); + mLiveRegion = parcel.readInt(); if (parcel.readInt() == 1) { getExtras().putAll(parcel.readBundle()); @@ -2389,6 +2344,7 @@ public class AccessibilityNodeInfo implements Parcelable { mTextSelectionStart = UNDEFINED; mTextSelectionEnd = UNDEFINED; mInputType = InputType.TYPE_NULL; + mLiveRegion = View.ACCESSIBILITY_LIVE_REGION_NONE; if (mExtras != null) { mExtras.clear(); } diff --git a/core/java/android/view/accessibility/AccessibilityNodeInfoCache.java b/core/java/android/view/accessibility/AccessibilityNodeInfoCache.java index 1fde2fa..3596daa 100644 --- a/core/java/android/view/accessibility/AccessibilityNodeInfoCache.java +++ b/core/java/android/view/accessibility/AccessibilityNodeInfoCache.java @@ -91,11 +91,11 @@ public class AccessibilityNodeInfoCache { case AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED: { synchronized (mLock) { final long sourceId = event.getSourceNodeId(); - if (event.getContentChangeType() - == AccessibilityEvent.CONTENT_CHANGE_TYPE_NODE) { - refreshCachedNode(sourceId); - } else { + if ((event.getContentChangeTypes() + & AccessibilityEvent.CONTENT_CHANGE_TYPE_SUBTREE) != 0) { clearSubTreeLocked(sourceId); + } else { + refreshCachedNode(sourceId); } } } break; |