Discourage dispatchAccessibilityEvent and onPopulate for non-text modifications

Developers use these methods in non-text ways, which has to
confusing announcements and behavior in accessibility services.

This provides alternatives that have better semantics and which lead to
more consistent user experiences.

Test: n/a (builds)
Bug: 78791516

Change-Id: I84cfc9dd1b7f46fd6af2a5112f526b0d5e327f5a
This commit is contained in:
Sally
2023-05-17 00:44:47 +00:00
parent d9b8ce09d4
commit 6c8a043d7f

View File

@@ -8662,15 +8662,43 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
}
/**
* Dispatches an {@link AccessibilityEvent} to the {@link View} first and then
* to its children for adding their text content to the event. Note that the
* event text is populated in a separate dispatch path since we add to the
* Dispatches an {@link AccessibilityEvent} to the {@link View} to add the text content of the
* view and its children.
* <p>
* <b>Note:</b> This method should only be used with event.setText().
* Avoid mutating other event state in this method. In general, put UI metadata in the node for
* services to easily query.
* <ul>
* <li> If you are modifying other event properties, you may be eliminating semantics
* accessibility services may want. Instead, send a separate event using
* {@link #sendAccessibilityEvent(int)} and override
* {@link #onInitializeAccessibilityEvent(AccessibilityEvent)}.
* </li>
* <li>If you are checking for type {@link AccessibilityEvent#TYPE_WINDOW_STATE_CHANGED}
* to generate window/title announcements, you may be causing disruptive announcements
* (or making no announcements at all). Instead, follow the practices described in
* {@link View#announceForAccessibility(CharSequence)}. <b>Note:</b> this does not suggest
* calling announceForAccessibility(), but using the suggestions listed in its
* documentation.
* </li>
* <li>If you are making changes based on the state of accessibility, such as checking for
* an event type to trigger a UI update, while well-intentioned, you are creating brittle,
* less well-maintained code that works for some users but not others. Instead, leverage
* existing code for equitable experiences and less technical debt. See
* {@link AccessibilityManager#isEnabled()} for an example.
* </li>
* </ul>
* <p>
* Note that the event text is populated in a separate dispatch path
* ({@link #onPopulateAccessibilityEvent(AccessibilityEvent)}) since we add to the
* event not only the text of the source but also the text of all its descendants.
* <p>
* A typical implementation will call
* {@link #onPopulateAccessibilityEvent(AccessibilityEvent)} on the this view
* {@link #onPopulateAccessibilityEvent(AccessibilityEvent)} on this view
* and then call the {@link #dispatchPopulateAccessibilityEvent(AccessibilityEvent)}
* on each child. Override this method if custom population of the event text
* content is required.
* on each child or the first child that is visible. Override this method if custom population
* of the event text content is required.
*
* <p>
* If an {@link AccessibilityDelegate} has been specified via calling
* {@link #setAccessibilityDelegate(AccessibilityDelegate)} its
@@ -8714,9 +8742,12 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
/**
* Called from {@link #dispatchPopulateAccessibilityEvent(AccessibilityEvent)}
* giving a chance to this View to populate the accessibility event with its
* text content. While this method is free to modify event
* attributes other than text content, doing so should normally be performed in
* {@link #onInitializeAccessibilityEvent(AccessibilityEvent)}.
* text content.
* <p>
* <b>Note:</b> This method should only be used with event.setText().
* Avoid mutating other event state in this method. Instead, follow the practices described in
* {@link #dispatchPopulateAccessibilityEvent(AccessibilityEvent)}. In general, put UI
* metadata in the node for services to easily query, than in transient events.
* <p>
* Example: Adding formatted date string to an accessibility event in addition
* to the text added by the super implementation: