Merge "Additional behavior for a11y panes"

This commit is contained in:
Phil Weaver
2018-01-17 05:44:16 +00:00
committed by Android (Google) Code Review
3 changed files with 74 additions and 8 deletions

View File

@@ -48040,6 +48040,8 @@ package android.view.accessibility {
method public void setPackageName(java.lang.CharSequence);
method public void writeToParcel(android.os.Parcel, int);
field public static final int CONTENT_CHANGE_TYPE_CONTENT_DESCRIPTION = 4; // 0x4
field public static final int CONTENT_CHANGE_TYPE_PANE_APPEARED = 16; // 0x10
field public static final int CONTENT_CHANGE_TYPE_PANE_DISAPPEARED = 32; // 0x20
field public static final int CONTENT_CHANGE_TYPE_PANE_TITLE = 8; // 0x8
field public static final int CONTENT_CHANGE_TYPE_SUBTREE = 1; // 0x1
field public static final int CONTENT_CHANGE_TYPE_TEXT = 2; // 0x2

View File

@@ -3226,6 +3226,11 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
*/
private static final int PFLAG3_SCREEN_READER_FOCUSABLE = 0x10000000;
/**
* The last aggregated visibility. Used to detect when it truly changes.
*/
private static final int PFLAG3_AGGREGATED_VISIBLE = 0x20000000;
/* End of masks for mPrivateFlags3 */
/**
@@ -7366,7 +7371,12 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
* @hide
*/
public void sendAccessibilityEventUncheckedInternal(AccessibilityEvent event) {
if (!isShown()) {
// Panes disappearing are relevant even if though the view is no longer visible.
boolean isWindowStateChanged =
(event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
boolean isWindowDisappearedEvent = isWindowStateChanged && ((event.getContentChangeTypes()
& AccessibilityEvent.CONTENT_CHANGE_TYPE_PANE_DISAPPEARED) != 0);
if (!isShown() && !isWindowDisappearedEvent) {
return;
}
onInitializeAccessibilityEvent(event);
@@ -7474,6 +7484,10 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
* @hide
*/
public void onPopulateAccessibilityEventInternal(AccessibilityEvent event) {
if ((event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED)
&& !TextUtils.isEmpty(getAccessibilityPaneTitle())) {
event.getText().add(getAccessibilityPaneTitle());
}
}
/**
@@ -11599,6 +11613,23 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
if (!AccessibilityManager.getInstance(mContext).isEnabled() || mAttachInfo == null) {
return;
}
// Changes to views with a pane title count as window state changes, as the pane title
// marks them as significant parts of the UI.
if (!TextUtils.isEmpty(getAccessibilityPaneTitle())) {
final AccessibilityEvent event = AccessibilityEvent.obtain();
event.setEventType(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
event.setContentChangeTypes(changeType);
onPopulateAccessibilityEvent(event);
if (mParent != null) {
try {
mParent.requestSendAccessibilityEvent(this, event);
} catch (AbstractMethodError e) {
Log.e(VIEW_LOG_TAG, mParent.getClass().getSimpleName()
+ " does not fully implement ViewParent", e);
}
}
}
if (mParent != null) {
try {
mParent.notifySubtreeAccessibilityStateChanged(this, source, changeType);
@@ -12532,6 +12563,10 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
*/
@CallSuper
public void onVisibilityAggregated(boolean isVisible) {
// Update our internal visibility tracking so we can detect changes
boolean oldVisible = (mPrivateFlags3 & PFLAG3_AGGREGATED_VISIBLE) != 0;
mPrivateFlags3 = isVisible ? (mPrivateFlags3 | PFLAG3_AGGREGATED_VISIBLE)
: (mPrivateFlags3 & ~PFLAG3_AGGREGATED_VISIBLE);
if (isVisible && mAttachInfo != null) {
initialAwakenScrollBars();
}
@@ -12572,6 +12607,13 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
}
}
}
if (!TextUtils.isEmpty(getAccessibilityPaneTitle())) {
if (isVisible != oldVisible) {
notifyAccessibilityStateChanged(isVisible
? AccessibilityEvent.CONTENT_CHANGE_TYPE_PANE_APPEARED
: AccessibilityEvent.CONTENT_CHANGE_TYPE_PANE_DISAPPEARED);
}
}
}
/**

View File

@@ -192,9 +192,11 @@ import java.util.List;
* <b>TRANSITION TYPES</b></br>
* </p>
* <p>
* <b>Window state changed</b> - represents the event of opening a
* {@link android.widget.PopupWindow}, {@link android.view.Menu},
* {@link android.app.Dialog}, etc.</br>
* <b>Window state changed</b> - represents the event of a change to a section of
* the user interface that is visually distinct. Should be sent from either the
* root view of a window or from a view that is marked as a pane
* {@link android.view.View#setAccessibilityPaneTitle(CharSequence)}. Not that changes
* to true windows are represented by {@link #TYPE_WINDOWS_CHANGED}.</br>
* <em>Type:</em> {@link #TYPE_WINDOW_STATE_CHANGED}</br>
* <em>Properties:</em></br>
* <ul>
@@ -203,7 +205,7 @@ import java.util.List;
* <li>{@link #getClassName()} - The class name of the source.</li>
* <li>{@link #getPackageName()} - The package name of the source.</li>
* <li>{@link #getEventTime()} - The event time.</li>
* <li>{@link #getText()} - The text of the source's sub-tree.</li>
* <li>{@link #getText()} - The text of the source's sub-tree, including the pane titles.</li>
* </ul>
* </p>
* <p>
@@ -436,8 +438,10 @@ public final class AccessibilityEvent extends AccessibilityRecord implements Par
public static final int TYPE_VIEW_TEXT_CHANGED = 0x00000010;
/**
* Represents the event of opening a {@link android.widget.PopupWindow},
* {@link android.view.Menu}, {@link android.app.Dialog}, etc.
* Represents the event of a change to a visually distinct section of the user interface.
* These events should only be dispatched from {@link android.view.View}s that have
* accessibility pane titles, and replaces {@link #TYPE_WINDOW_CONTENT_CHANGED} for those
* sources. Details about the change are available from {@link #getContentChangeTypes()}.
*/
public static final int TYPE_WINDOW_STATE_CHANGED = 0x00000020;
@@ -565,11 +569,29 @@ public final class AccessibilityEvent extends AccessibilityRecord implements Par
public static final int CONTENT_CHANGE_TYPE_CONTENT_DESCRIPTION = 0x00000004;
/**
* Change type for {@link #TYPE_WINDOW_CONTENT_CHANGED} event:
* Change type for {@link #TYPE_WINDOW_STATE_CHANGED} event:
* The node's pane title changed.
*/
public static final int CONTENT_CHANGE_TYPE_PANE_TITLE = 0x00000008;
/**
* Change type for {@link #TYPE_WINDOW_STATE_CHANGED} event:
* The node has a pane title, and either just appeared or just was assigned a title when it
* had none before.
*/
public static final int CONTENT_CHANGE_TYPE_PANE_APPEARED = 0x00000010;
/**
* Change type for {@link #TYPE_WINDOW_STATE_CHANGED} event:
* Can mean one of two slightly different things. The primary meaning is that the node has
* a pane title, and was removed from the node hierarchy. It will also be sent if the pane
* title is set to {@code null} after it contained a title.
* No source will be returned if the node is no longer on the screen. To make the change more
* clear for the user, the first entry in {@link #getText()} will return the value that would
* have been returned by {@code getSource().getPaneTitle()}.
*/
public static final int CONTENT_CHANGE_TYPE_PANE_DISAPPEARED = 0x00000020;
/**
* Change type for {@link #TYPE_WINDOWS_CHANGED} event:
* The window was added.