• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2009 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.view.accessibility;
18 
19 import android.annotation.IntDef;
20 import android.annotation.NonNull;
21 import android.compat.annotation.UnsupportedAppUsage;
22 import android.os.Build;
23 import android.os.Parcel;
24 import android.os.Parcelable;
25 import android.text.TextUtils;
26 import android.util.Log;
27 import android.view.View;
28 
29 import com.android.internal.util.BitUtils;
30 
31 import java.lang.annotation.Retention;
32 import java.lang.annotation.RetentionPolicy;
33 import java.util.ArrayList;
34 import java.util.List;
35 
36 /**
37  * <p>
38  * This class represents accessibility events that are sent by the system when
39  * something notable happens in the user interface. For example, when a
40  * {@link android.widget.Button} is clicked, a {@link android.view.View} is focused, etc.
41  * </p>
42  * <p>
43  * An accessibility event is fired by an individual view which populates the event with
44  * data for its state and requests from its parent to send the event to interested
45  * parties. The parent can optionally modify or even block the event based on its broader
46  * understanding of the user interface's context.
47  * </p>
48  * <p>
49  * The main purpose of an accessibility event is to communicate changes in the UI to an
50  * {@link android.accessibilityservice.AccessibilityService}. If needed, the service may then
51  * inspect the user interface by examining the View hierarchy through the event's
52  * {@link #getSource() source}, as represented by a tree of {@link AccessibilityNodeInfo}s (snapshot
53  * of a View state) which can be used for exploring the window content. Note that the privilege for
54  * accessing an event's source, thus the window content, has to be explicitly requested. For more
55  * details refer to {@link android.accessibilityservice.AccessibilityService}. If an
56  * accessibility service has not requested to retrieve the window content the event will
57  * not contain reference to its source. <strong>Note: </strong> for events of type
58  * {@link #TYPE_NOTIFICATION_STATE_CHANGED} the source is never available, and Views that set
59  * {@link android.view.View#isAccessibilityDataSensitive()} may not populate all event properties on
60  * events sent from higher up in the view hierarchy.
61  * </p>
62  * <p>
63  * This class represents various semantically different accessibility event
64  * types. Each event type has an associated set of related properties. In other
65  * words, each event type is characterized via a subset of the properties exposed
66  * by this class. For each event type there is a corresponding constant defined
67  * in this class. Follows a specification of the event types and their associated properties:
68  * </p>
69  * <div class="special reference">
70  * <h3>Developer Guides</h3>
71  * <p>For more information about creating and processing AccessibilityEvents, read the
72  * <a href="{@docRoot}guide/topics/ui/accessibility/index.html">Accessibility</a>
73  * developer guide.</p>
74  * </div>
75  * <p>
76  * <b>VIEW TYPES</b></br>
77  * </p>
78  * <p>
79  * <b>View clicked</b> - represents the event of clicking on a {@link android.view.View}
80  * like {@link android.widget.Button}, {@link android.widget.CompoundButton}, etc.</br>
81  * <em>Type:</em>{@link #TYPE_VIEW_CLICKED}</br>
82  * <em>Properties:</em></br>
83  * <ul>
84  *   <li>{@link #getEventType()} - The type of the event.</li>
85  *   <li>{@link #getSource()} - The source info (for registered clients).</li>
86  *   <li>{@link #getClassName()} - The class name of the source.</li>
87  *   <li>{@link #getPackageName()} - The package name of the source.</li>
88  *   <li>{@link #getEventTime()}  - The event time.</li>
89  * </ul>
90  * </p>
91  * <p>
92  * <b>View long clicked</b> - represents the event of long clicking on a {@link android.view.View}
93  * like {@link android.widget.Button}, {@link android.widget.CompoundButton}, etc </br>
94  * <em>Type:</em>{@link #TYPE_VIEW_LONG_CLICKED}</br>
95  * <em>Properties:</em></br>
96  * <ul>
97  *   <li>{@link #getEventType()} - The type of the event.</li>
98  *   <li>{@link #getSource()} - The source info (for registered clients).</li>
99  *   <li>{@link #getClassName()} - The class name of the source.</li>
100  *   <li>{@link #getPackageName()} - The package name of the source.</li>
101  *   <li>{@link #getEventTime()}  - The event time.</li>
102  * </ul>
103  * </p>
104  * <p>
105  * <b>View selected</b> - represents the event of selecting an item usually in
106  * the context of an {@link android.widget.AdapterView}.</br>
107  * <em>Type:</em> {@link #TYPE_VIEW_SELECTED}</br>
108  * <em>Properties:</em></br>
109  * <ul>
110  *   <li>{@link #getEventType()} - The type of the event.</li>
111  *   <li>{@link #getSource()} - The source info (for registered clients).</li>
112  *   <li>{@link #getClassName()} - The class name of the source.</li>
113  *   <li>{@link #getPackageName()} - The package name of the source.</li>
114  *   <li>{@link #getEventTime()}  - The event time.</li>
115  * </ul>
116  * </p>
117  * <p>
118  * <b>View focused</b> - represents the event of focusing a
119  * {@link android.view.View}.</br>
120  * <em>Type:</em> {@link #TYPE_VIEW_FOCUSED}</br>
121  * <em>Properties:</em></br>
122  * <ul>
123  *   <li>{@link #getEventType()} - The type of the event.</li>
124  *   <li>{@link #getSource()} - The source info (for registered clients).</li>
125  *   <li>{@link #getClassName()} - The class name of the source.</li>
126  *   <li>{@link #getPackageName()} - The package name of the source.</li>
127  *   <li>{@link #getEventTime()}  - The event time.</li>
128  * </ul>
129  * </p>
130  * <p>
131  * <b>View text changed</b> - represents the event of changing the text of an
132  * {@link android.widget.EditText}.</br>
133  * <em>Type:</em> {@link #TYPE_VIEW_TEXT_CHANGED}</br>
134  * <em>Properties:</em></br>
135  * <ul>
136  *   <li>{@link #getEventType()} - The type of the event.</li>
137  *   <li>{@link #getSource()} - The source info (for registered clients).</li>
138  *   <li>{@link #getClassName()} - The class name of the source.</li>
139  *   <li>{@link #getPackageName()} - The package name of the source.</li>
140  *   <li>{@link #getEventTime()}  - The event time.</li>
141  *   <li>{@link #getText()} - The new text of the source.</li>
142  *   <li>{@link #getBeforeText()} - The text of the source before the change.</li>
143  *   <li>{@link #getFromIndex()} - The text change start index.</li>
144  *   <li>{@link #getAddedCount()} - The number of added characters.</li>
145  *   <li>{@link #getRemovedCount()} - The number of removed characters.</li>
146  * </ul>
147  * </p>
148  * <p>
149  * <b>View text selection changed</b> - represents the event of changing the text
150  * selection of an {@link android.widget.EditText}.</br>
151  * <em>Type:</em> {@link #TYPE_VIEW_TEXT_SELECTION_CHANGED} </br>
152  * <em>Properties:</em></br>
153  * <ul>
154  *   <li>{@link #getEventType()} - The type of the event.</li>
155  *   <li>{@link #getSource()} - The source info (for registered clients).</li>
156  *   <li>{@link #getClassName()} - The class name of the source.</li>
157  *   <li>{@link #getPackageName()} - The package name of the source.</li>
158  *   <li>{@link #getEventTime()}  - The event time.</li>
159  * </ul>
160  * </p>
161  * <b>View text traversed at movement granularity</b> - represents the event of traversing the
162  * text of a view at a given granularity. For example, moving to the next word.</br>
163  * <em>Type:</em> {@link #TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY} </br>
164  * <em>Properties:</em></br>
165  * <ul>
166  *   <li>{@link #getEventType()} - The type of the event.</li>
167  *   <li>{@link #getSource()} - The source info (for registered clients).</li>
168  *   <li>{@link #getClassName()} - The class name of the source.</li>
169  *   <li>{@link #getPackageName()} - The package name of the source.</li>
170  *   <li>{@link #getEventTime()}  - The event time.</li>
171  *   <li>{@link #getMovementGranularity()} - Sets the granularity at which a view's text
172  *       was traversed.</li>
173  *   <li>{@link #getText()} -  The text of the source's sub-tree.</li>
174  *   <li>{@link #getFromIndex()} - The start the text that was skipped over in this movement.
175  *       This is the starting point when moving forward through the text, but not when moving
176  *       back.</li>
177  *   <li>{@link #getToIndex()} - The end of the text that was skipped over in this movement.
178  *       This is the ending point when moving forward through the text, but not when moving
179  *       back.</li>
180  *   <li>{@link #getAction()} - Gets traversal action which specifies the direction.</li>
181  * </ul>
182  * </p>
183  * <p>
184  * <b>View scrolled</b> - represents the event of scrolling a view. </br>
185  * <em>Type:</em> {@link #TYPE_VIEW_SCROLLED}</br>
186  * <em>Properties:</em></br>
187  * <ul>
188  *   <li>{@link #getEventType()} - The type of the event.</li>
189  *   <li>{@link #getSource()} - The source info (for registered clients).</li>
190  *   <li>{@link #getClassName()} - The class name of the source.</li>
191  *   <li>{@link #getPackageName()} - The package name of the source.</li>
192  *   <li>{@link #getEventTime()}  - The event time.</li>
193  *   <li>{@link #getScrollDeltaX()} - The difference in the horizontal position.</li>
194  *   <li>{@link #getScrollDeltaY()} - The difference in the vertical position.</li>
195  *   <li>{@link #getMaxScrollX()} ()} -  The max scroll offset of the source left edge</li>
196  *   <li>{@link #getMaxScrollY()} ()} - The max scroll offset of the source top edge.</li>
197  * </ul>
198  * </p>
199  * <p>
200  * <b>TRANSITION TYPES</b></br>
201  * </p>
202  * <p>
203  * <b>Window state changed</b> - represents the event of a change to a section of
204  * the user interface that is visually distinct. Should be sent from either the
205  * root view of a window or from a view that is marked as a pane
206  * {@link android.view.View#setAccessibilityPaneTitle(CharSequence)}. Note that changes
207  * to true windows are represented by {@link #TYPE_WINDOWS_CHANGED}.</br>
208  * <em>Type:</em> {@link #TYPE_WINDOW_STATE_CHANGED}</br>
209  * <em>Properties:</em></br>
210  * <ul>
211  *   <li>{@link #getEventType()} - The type of the event.</li>
212  *   <li>{@link #getContentChangeTypes()} - The type of state changes.</li>
213  *   <li>{@link #getSource()} - The source info (for registered clients).</li>
214  *   <li>{@link #getClassName()} - The class name of the source.</li>
215  *   <li>{@link #getPackageName()} - The package name of the source.</li>
216  *   <li>{@link #getEventTime()}  - The event time.</li>
217  *   <li>{@link #getText()} - The text of the source's sub-tree, including the pane titles.</li>
218  * </ul>
219  * </p>
220  * <p>
221  * <b>Window content changed</b> - represents the event of change in the
222  * content of a window. This change can be adding/removing view, changing
223  * a view size, etc.</br>
224  * </p>
225  * <p>
226  * <em>Type:</em> {@link #TYPE_WINDOW_CONTENT_CHANGED}</br>
227  * <em>Properties:</em></br>
228  * <ul>
229  *   <li>{@link #getEventType()} - The type of the event.</li>
230  *   <li>{@link #getContentChangeTypes()} - The type of content changes.</li>
231  *   <li>{@link #getSource()} - The source info (for registered clients).</li>
232  *   <li>{@link #getClassName()} - The class name of the source.</li>
233  *   <li>{@link #getPackageName()} - The package name of the source.</li>
234  *   <li>{@link #getEventTime()}  - The event time.</li>
235  * </ul>
236  * </p>
237  * <p>
238  * <b>Windows changed</b> - represents a change in the windows shown on
239  * the screen such as a window appeared, a window disappeared, a window size changed,
240  * a window layer changed, etc. These events should only come from the system, which is responsible
241  * for managing windows. The list of windows is available from
242  * {@link android.accessibilityservice.AccessibilityService#getWindows()}.
243  * For regions of the user interface that are presented as windows but are
244  * controlled by an app's process, use {@link #TYPE_WINDOW_STATE_CHANGED}.</br>
245  * <em>Type:</em> {@link #TYPE_WINDOWS_CHANGED}</br>
246  * <em>Properties:</em></br>
247  * <ul>
248  *   <li>{@link #getEventType()} - The type of the event.</li>
249  *   <li>{@link #getEventTime()} - The event time.</li>
250  *   <li>{@link #getWindowChanges()}</li> - The specific change to the source window
251  * </ul>
252  * <em>Note:</em> You can retrieve the {@link AccessibilityWindowInfo} for the window
253  * source of the event by looking through the list returned by
254  * {@link android.accessibilityservice.AccessibilityService#getWindows()} for the window whose ID
255  * matches {@link #getWindowId()}.
256  * </p>
257  * <p>
258  * <b>NOTIFICATION TYPES</b></br>
259  * </p>
260  * <p>
261  * <b>Notification state changed</b> - represents the event showing a transient piece of information
262  * to the user. This information may be a {@link android.app.Notification} or
263  * {@link android.widget.Toast}.</br>
264  * <em>Type:</em> {@link #TYPE_NOTIFICATION_STATE_CHANGED}</br>
265  * <em>Properties:</em></br>
266  * <ul>
267  *   <li>{@link #getEventType()} - The type of the event.</li>
268  *   <li>{@link #getClassName()} - The class name of the source.</li>
269  *   <li>{@link #getPackageName()} - The package name of the source.</li>
270  *   <li>{@link #getEventTime()}  - The event time.</li>
271  *   <li>{@link #getParcelableData()} - The posted {@link android.app.Notification}, if
272  *   applicable.</li>
273  *   <li>{@link #getText()} - Displayed text of the {@link android.widget.Toast}, if applicable,
274  *   or may contain text from the {@link android.app.Notification}, although
275  *   {@link #getParcelableData()} is a richer set of data for {@link android.app.Notification}.</li>
276  * </ul>
277  * </p>
278  * <p>
279  * <b>EXPLORATION TYPES</b></br>
280  * </p>
281  * <p>
282  * <b>View hover enter</b> - represents the event of beginning to hover
283  * over a {@link android.view.View}. The hover may be generated via
284  * exploring the screen by touch or via a pointing device.</br>
285  * <em>Type:</em> {@link #TYPE_VIEW_HOVER_ENTER}</br>
286  * <em>Properties:</em></br>
287  * <ul>
288  *   <li>{@link #getEventType()} - The type of the event.</li>
289  *   <li>{@link #getSource()} - The source info (for registered clients).</li>
290  *   <li>{@link #getClassName()} - The class name of the source.</li>
291  *   <li>{@link #getPackageName()} - The package name of the source.</li>
292  *   <li>{@link #getEventTime()}  - The event time.</li>
293  * </ul>
294  * </p>
295  * <b>View hover exit</b> - represents the event of stopping to hover
296  * over a {@link android.view.View}. The hover may be generated via
297  * exploring the screen by touch or via a pointing device.</br>
298  * <em>Type:</em> {@link #TYPE_VIEW_HOVER_EXIT}</br>
299  * <em>Properties:</em></br>
300  * <ul>
301  *   <li>{@link #getEventType()} - The type of the event.</li>
302  *   <li>{@link #getSource()} - The source info (for registered clients).</li>
303  *   <li>{@link #getClassName()} - The class name of the source.</li>
304  *   <li>{@link #getPackageName()} - The package name of the source.</li>
305  *   <li>{@link #getEventTime()}  - The event time.</li>
306  * </ul>
307  * </p>
308  * <p>
309  * <b>View scrolled to</b> - represents the event of a target node brought on screen by
310  * ACTION_SCROLL_IN_DIRECTION.
311  * <em>Type:</em> {@link #TYPE_VIEW_TARGETED_BY_SCROLL}</br>
312  * <em>Properties:</em></br>
313  * <ul>
314  *   <li>{@link #getEventType()} - The type of the event.</li>
315  *   <li>{@link #getSource()} - The source info (for registered clients). This represents the node
316  *   that is brought on screen as a result of the scroll.</li>
317  *   <li>{@link #getClassName()} - The class name of the source.</li>
318  *   <li>{@link #getPackageName()} - The package name of the source.</li>
319  *   <li>{@link #getEventTime()}  - The event time.</li>
320  * </ul>
321  * </p>
322  * <p>
323  * <b>Touch interaction start</b> - represents the event of starting a touch
324  * interaction, which is the user starts touching the screen.</br>
325  * <em>Type:</em> {@link #TYPE_TOUCH_INTERACTION_START}</br>
326  * <em>Properties:</em></br>
327  * <ul>
328  *   <li>{@link #getEventType()} - The type of the event.</li>
329  * </ul>
330  * <em>Note:</em> This event is fired only by the system and is not passed to the
331  * view tree to be populated.</br>
332  * </p>
333  * <p>
334  * <b>Touch interaction end</b> - represents the event of ending a touch
335  * interaction, which is the user stops touching the screen.</br>
336  * <em>Type:</em> {@link #TYPE_TOUCH_INTERACTION_END}</br>
337  * <em>Properties:</em></br>
338  * <ul>
339  *   <li>{@link #getEventType()} - The type of the event.</li>
340  * </ul>
341  * <em>Note:</em> This event is fired only by the system and is not passed to the
342  * view tree to be populated.</br>
343  * </p>
344  * <p>
345  * <b>Touch exploration gesture start</b> - represents the event of starting a touch
346  * exploring gesture.</br>
347  * <em>Type:</em> {@link #TYPE_TOUCH_EXPLORATION_GESTURE_START}</br>
348  * <em>Properties:</em></br>
349  * <ul>
350  *   <li>{@link #getEventType()} - The type of the event.</li>
351  * </ul>
352  * <em>Note:</em> This event is fired only by the system and is not passed to the
353  * view tree to be populated.</br>
354  * </p>
355  * <p>
356  * <b>Touch exploration gesture end</b> - represents the event of ending a touch
357  * exploring gesture.</br>
358  * <em>Type:</em> {@link #TYPE_TOUCH_EXPLORATION_GESTURE_END}</br>
359  * <em>Properties:</em></br>
360  * <ul>
361  *   <li>{@link #getEventType()} - The type of the event.</li>
362  * </ul>
363  * <em>Note:</em> This event is fired only by the system and is not passed to the
364  * view tree to be populated.</br>
365  * </p>
366  * <p>
367  * <b>Touch gesture detection start</b> - represents the event of starting a user
368  * gesture detection.</br>
369  * <em>Type:</em> {@link #TYPE_GESTURE_DETECTION_START}</br>
370  * <em>Properties:</em></br>
371  * <ul>
372  *   <li>{@link #getEventType()} - The type of the event.</li>
373  * </ul>
374  * <em>Note:</em> This event is fired only by the system and is not passed to the
375  * view tree to be populated.</br>
376  * </p>
377  * <p>
378  * <b>Touch gesture detection end</b> - represents the event of ending a user
379  * gesture detection.</br>
380  * <em>Type:</em> {@link #TYPE_GESTURE_DETECTION_END}</br>
381  * <em>Properties:</em></br>
382  * <ul>
383  *   <li>{@link #getEventType()} - The type of the event.</li>
384  * </ul>
385  * <em>Note:</em> This event is fired only by the system and is not passed to the
386  * view tree to be populated.</br>
387  * </p>
388  * <p>
389  * <b>MISCELLANEOUS TYPES</b></br>
390  * </p>
391  * <p>
392  * <b>Announcement</b> - represents the event of an application requesting a screen reader to make
393  * an announcement. Because the event carries no semantic meaning, this event is appropriate only
394  * in exceptional situations where additional screen reader output is needed but other types of
395  * accessibility services do not need to be aware of the change.</br>
396  * <em>Type:</em> {@link #TYPE_ANNOUNCEMENT}</br>
397  * <em>Properties:</em></br>
398  * <ul>
399  *   <li>{@link #getEventType()} - The type of the event.</li>
400  *   <li>{@link #getSource()} - The source info (for registered clients).</li>
401  *   <li>{@link #getClassName()} - The class name of the source.</li>
402  *   <li>{@link #getPackageName()} - The package name of the source.</li>
403  *   <li>{@link #getEventTime()}  - The event time.</li>
404  *   <li>{@link #getText()} - The text of the announcement.</li>
405  * </ul>
406  * </p>
407   * <p>
408  * <b>speechStateChanged</b>
409  * <em>Type:</em> {@link #TYPE_SPEECH_STATE_CHANGE}</br>
410  * Represents a change in the speech state defined by the
411  * bit mask of the speech state change types.
412  * A change in the speech state occurs when an application wants to signal that
413  * it is either speaking or listening for human speech.
414  * This event helps avoid conflicts where two applications want to speak or one listens
415  * when another speaks.
416  * When sending this event, the sender should ensure that  the accompanying state change types
417  * make sense. For example, the sender should not send
418  * {@link #SPEECH_STATE_SPEAKING_START} and {@link #SPEECH_STATE_SPEAKING_END} together.
419  * <em>Properties:</em></br>
420  * <ul>
421  *   <li>{@link #getSpeechStateChangeTypes()} - The type of state changes</li>
422  *   <li>{@link #getPackageName()} - The package name of the source.</li>
423  *   <li>{@link #getEventTime()}  - The event time.</li>
424  * </ul>
425  * </p>
426  *
427  * @see android.view.accessibility.AccessibilityManager
428  * @see android.accessibilityservice.AccessibilityService
429  * @see AccessibilityNodeInfo
430  */
431 public final class AccessibilityEvent extends AccessibilityRecord implements Parcelable {
432     private static final String LOG_TAG = "AccessibilityEvent";
433 
434     private static final boolean DEBUG = Log.isLoggable(LOG_TAG, Log.DEBUG) && Build.IS_DEBUGGABLE;
435 
436     /** @hide */
437     public static final boolean DEBUG_ORIGIN = false;
438 
439     /**
440      * Invalid selection/focus position.
441      *
442      * @see #getCurrentItemIndex()
443      */
444     public static final int INVALID_POSITION = -1;
445 
446     /**
447      * Maximum length of the text fields.
448      *
449      * @see #getBeforeText()
450      * @see #getText()
451      * </br>
452      * Note: This constant is no longer needed since there
453      *       is no limit on the length of text that is contained
454      *       in an accessibility event anymore.
455      */
456     @Deprecated
457     public static final int MAX_TEXT_LENGTH = 500;
458 
459     // Event types.
460 
461     /**
462      * Represents the event of clicking on a {@link android.view.View} like
463      * {@link android.widget.Button}, {@link android.widget.CompoundButton}, etc.
464      * <p>See {@link AccessibilityNodeInfo.AccessibilityAction#ACTION_CLICK} for more
465      * details.
466      */
467     public static final int TYPE_VIEW_CLICKED = 1 /* << 0 */;;
468 
469     /**
470      * Represents the event of long clicking on a {@link android.view.View} like
471      * {@link android.widget.Button}, {@link android.widget.CompoundButton}, etc.
472      * <p>See {@link AccessibilityNodeInfo.AccessibilityAction#ACTION_LONG_CLICK} for more
473      * details.
474      */
475     public static final int TYPE_VIEW_LONG_CLICKED = 1 << 1;
476 
477     /**
478      * Represents the event of selecting an item usually in the context of an
479      * {@link android.widget.AdapterView}.
480      * @see AccessibilityNodeInfo.AccessibilityAction#ACTION_SELECT
481      */
482     public static final int TYPE_VIEW_SELECTED = 1 << 2;
483 
484     /**
485      * Represents the event of setting input focus of a {@link android.view.View}.
486      * @see AccessibilityNodeInfo.AccessibilityAction#ACTION_ACCESSIBILITY_FOCUS for the difference
487      * between input and accessibility focus.
488      */
489     public static final int TYPE_VIEW_FOCUSED = 1 << 3;
490 
491     /**
492      * Represents the event of changing the text of an {@link android.widget.EditText}.
493      * @see AccessibilityNodeInfo#setText(CharSequence)
494      */
495     public static final int TYPE_VIEW_TEXT_CHANGED = 1 << 4;
496 
497     /**
498      * Represents the event of a change to a visually distinct section of the user interface.
499      * <p>
500      * These events should only be dispatched from {@link android.view.View}s that have
501      * accessibility pane titles, and replaces {@link #TYPE_WINDOW_CONTENT_CHANGED} for those
502      * sources. Details about the change are available from {@link #getContentChangeTypes()}.
503      * <p>
504      * Do not use this to get an accessibility service to make non-pane announcements. Instead,
505      * follow the practices described in {@link View#announceForAccessibility(CharSequence)}.
506      * <b>Note:</b> this does not suggest calling announceForAccessibility(), but using the
507      * suggestions listed in its documentation.
508      */
509     public static final int TYPE_WINDOW_STATE_CHANGED = 1 << 5;
510 
511     /**
512      * Represents the event showing a {@link android.app.Notification}.
513      */
514     public static final int TYPE_NOTIFICATION_STATE_CHANGED = 1 << 6;
515 
516     /**
517      * Represents the event of a hover enter over a {@link android.view.View}.
518      */
519     public static final int TYPE_VIEW_HOVER_ENTER = 1 << 7;
520 
521     /**
522      * Represents the event of a hover exit over a {@link android.view.View}.
523      */
524     public static final int TYPE_VIEW_HOVER_EXIT = 1 << 8;
525 
526     /**
527      * Represents the event of starting a touch exploration gesture.
528      */
529     public static final int TYPE_TOUCH_EXPLORATION_GESTURE_START = 1 << 9;
530 
531     /**
532      * Represents the event of ending a touch exploration gesture.
533      */
534     public static final int TYPE_TOUCH_EXPLORATION_GESTURE_END = 1 << 10;
535 
536     /**
537      * Represents the event of changing the content of a window and more
538      * specifically the sub-tree rooted at the event's source.
539      */
540     public static final int TYPE_WINDOW_CONTENT_CHANGED = 1 << 11;
541 
542     /**
543      * Represents the event of scrolling a view. This event type is generally not sent directly. In
544      * the View system, this is sent in
545      * {@link android.view.View#onScrollChanged(int, int, int, int)}
546      * <p>In addition to the source and package name, the event should populate scroll-specific
547      * properties like {@link #setScrollDeltaX(int)}, {@link #setScrollDeltaY(int)},
548      * {@link #setMaxScrollX(int)}, and {@link #setMaxScrollY(int)}.
549      * <p>Services are encouraged to rely on the source to query UI state over AccessibilityEvents
550      * properties. For example, to check after a scroll if the bottom of the scrolling UI element
551      * has been reached, check if the source node is scrollable and has the
552      * {@link AccessibilityNodeInfo.AccessibilityAction#ACTION_SCROLL_BACKWARD} action but not the
553      * {@link AccessibilityNodeInfo.AccessibilityAction#ACTION_SCROLL_FORWARD} action.
554      * For scrolling to a target, use {@link #TYPE_VIEW_TARGETED_BY_SCROLL}.
555      */
556     public static final int TYPE_VIEW_SCROLLED = 1 << 12;
557 
558     /**
559      * Represents the event of changing the selection in an {@link android.widget.EditText}.
560      */
561     public static final int TYPE_VIEW_TEXT_SELECTION_CHANGED = 1 << 13;
562 
563     /**
564      * Represents the event of an application making an announcement.
565      * <p>
566      * In general, follow the practices described in
567      * {@link View#announceForAccessibility(CharSequence)}.
568      */
569     public static final int TYPE_ANNOUNCEMENT = 1 << 14;
570 
571     /**
572      * Represents the event of gaining accessibility focus.
573      * @see AccessibilityNodeInfo.AccessibilityAction#ACTION_ACCESSIBILITY_FOCUS for the difference
574      * between input and accessibility focus.
575      */
576     public static final int TYPE_VIEW_ACCESSIBILITY_FOCUSED = 1 << 15;
577 
578     /**
579      * Represents the event of clearing accessibility focus.
580      * @see AccessibilityNodeInfo.AccessibilityAction#ACTION_ACCESSIBILITY_FOCUS for the difference
581      * between input and accessibility focus.
582      */
583     public static final int TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED = 1 << 16;
584 
585     /**
586      * Represents the event of traversing the text of a view at a given movement granularity.
587      */
588     public static final int TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY = 1 << 17;
589 
590     /**
591      * Represents the event of beginning gesture detection.
592      */
593     public static final int TYPE_GESTURE_DETECTION_START = 1 << 18;
594 
595     /**
596      * Represents the event of ending gesture detection.
597      */
598     public static final int TYPE_GESTURE_DETECTION_END = 1 << 19;
599 
600     /**
601      * Represents the event of the user starting to touch the screen.
602      */
603     public static final int TYPE_TOUCH_INTERACTION_START = 1 << 20;
604 
605     /**
606      * Represents the event of the user ending to touch the screen.
607      */
608     public static final int TYPE_TOUCH_INTERACTION_END = 1 << 21;
609 
610     /**
611      * Represents the event change in the system windows shown on the screen. This event type should
612      * only be dispatched by the system.
613      */
614     public static final int TYPE_WINDOWS_CHANGED = 1 << 22;
615 
616     /**
617      * Represents the event of a context click on a {@link android.view.View}.
618      * <p>See {@link AccessibilityNodeInfo.AccessibilityAction#ACTION_CONTEXT_CLICK} for more
619      * details.
620      */
621     public static final int TYPE_VIEW_CONTEXT_CLICKED = 1 << 23;
622 
623     /**
624      * Represents the event of the assistant currently reading the users screen context.
625      */
626     public static final int TYPE_ASSIST_READING_CONTEXT = 1 << 24;
627 
628     /**
629      * Represents a change in the speech state defined by the speech state change types.
630      * A change in the speech state occurs when an application wants to signal that it is either
631      * speaking or listening for human speech.
632      * This event helps avoid conflicts where two applications want to speak or one listens
633      * when another speaks.
634      * When sending this event, the sender should ensure that  the accompanying state change types
635      * make sense. For example, the sender should not send
636      * {@link #SPEECH_STATE_SPEAKING_START} and {@link #SPEECH_STATE_SPEAKING_END} together.
637      * @see #SPEECH_STATE_SPEAKING_START
638      * @see #SPEECH_STATE_SPEAKING_END
639      * @see #SPEECH_STATE_LISTENING_START
640      * @see #SPEECH_STATE_LISTENING_END
641      * @see #getSpeechStateChangeTypes
642      * @see #setSpeechStateChangeTypes
643      */
644     public static final int TYPE_SPEECH_STATE_CHANGE = 1 << 25;
645 
646     /**
647      * Represents the event of a scroll having completed and brought the target node on screen.
648      */
649     public static final int TYPE_VIEW_TARGETED_BY_SCROLL = 1 << 26;
650 
651     // Content change types.
652 
653     /**
654      * Change type for {@link #TYPE_WINDOW_CONTENT_CHANGED} event: The type of change is not
655      * defined.
656      */
657     public static final int CONTENT_CHANGE_TYPE_UNDEFINED = 0;
658 
659     /**
660      * Change type for {@link #TYPE_WINDOW_CONTENT_CHANGED} event:
661      * One or more content changes occurred in the the subtree rooted at the source node,
662      * or the subtree's structure changed when a node was added or removed.
663      */
664     public static final int CONTENT_CHANGE_TYPE_SUBTREE = 1 /* << 0 */;
665 
666     /**
667      * Change type for {@link #TYPE_WINDOW_CONTENT_CHANGED} event:
668      * The node's text changed.
669      * @see AccessibilityNodeInfo#setText(CharSequence)
670      */
671     public static final int CONTENT_CHANGE_TYPE_TEXT = 1 << 1;
672 
673     /**
674      * Change type for {@link #TYPE_WINDOW_CONTENT_CHANGED} event:
675      * The node's content description changed.
676      */
677     public static final int CONTENT_CHANGE_TYPE_CONTENT_DESCRIPTION = 1 << 2;
678 
679     /**
680      * Change type for {@link #TYPE_WINDOW_STATE_CHANGED} event:
681      * The node's pane title changed.
682      * <p>
683      * If this makes the pane appear, {@link #CONTENT_CHANGE_TYPE_PANE_APPEARED} is sent
684      * instead. If this makes the pane disappear, {@link #CONTENT_CHANGE_TYPE_PANE_DISAPPEARED}
685      * is sent.
686      * @see View#setAccessibilityPaneTitle(CharSequence)
687      */
688     public static final int CONTENT_CHANGE_TYPE_PANE_TITLE = 1 << 3;
689 
690     /**
691      * Change type for {@link #TYPE_WINDOW_STATE_CHANGED} event:
692      * The node has a pane title, and either just appeared or just was assigned a title when it
693      * had none before.
694      * @see View#setAccessibilityPaneTitle(CharSequence)
695      */
696     public static final int CONTENT_CHANGE_TYPE_PANE_APPEARED = 1 << 4;
697 
698     /**
699      * Change type for {@link #TYPE_WINDOW_STATE_CHANGED} event:
700      * Can mean one of two slightly different things. The primary meaning is that the node has
701      * a pane title, and was removed from the node hierarchy. It will also be sent if the pane
702      * title is set to {@code null} after it contained a title.
703      * No source will be returned if the node is no longer on the screen. To make the change more
704      * clear for the user, the first entry in {@link #getText()} will return the value that would
705      * have been returned by {@code getSource().getPaneTitle()}.
706      * @see View#setAccessibilityPaneTitle(CharSequence)
707      */
708     public static final int CONTENT_CHANGE_TYPE_PANE_DISAPPEARED = 1 << 5;
709 
710     /**
711      * Change type for {@link #TYPE_WINDOW_CONTENT_CHANGED} event:
712      * state description of the node as returned by
713      * {@link AccessibilityNodeInfo#getStateDescription} changed. If part of the state description
714      * changes, the changed part can be put into event text. For example, if state description
715      * changed from "on, wifi signal full" to "on, wifi three bars", "wifi three bars" can be put
716      * into the event text.
717      * @see View#setStateDescription(CharSequence)
718      */
719     public static final int CONTENT_CHANGE_TYPE_STATE_DESCRIPTION = 1 << 6;
720 
721     /**
722      * Change type for {@link #TYPE_WINDOW_CONTENT_CHANGED} event:
723      * A drag has started while accessibility is enabled. This is either via an
724      * AccessibilityAction, or via touch events. This is sent from the source that initiated the
725      * drag.
726      *
727      * @see AccessibilityNodeInfo.AccessibilityAction#ACTION_DRAG_START
728      */
729     public static final int CONTENT_CHANGE_TYPE_DRAG_STARTED = 1 << 7;
730 
731     /**
732      * Change type for {@link #TYPE_WINDOW_CONTENT_CHANGED} event:
733      * A drag in with accessibility enabled has ended. This means the content has been
734      * successfully dropped. This is sent from the target that accepted the dragged content.
735      *
736      * @see AccessibilityNodeInfo.AccessibilityAction#ACTION_DRAG_DROP
737      */
738     public static final int CONTENT_CHANGE_TYPE_DRAG_DROPPED = 1 << 8;
739 
740     /**
741      * Change type for {@link #TYPE_WINDOW_CONTENT_CHANGED} event:
742      * A drag in with accessibility enabled has ended. This means the content has been
743      * unsuccessfully dropped, the user has canceled the action via an AccessibilityAction, or
744      * no drop has been detected within a timeout and the drag was automatically cancelled. This is
745      * sent from the source that initiated the drag.
746      *
747      * @see AccessibilityNodeInfo.AccessibilityAction#ACTION_DRAG_CANCEL
748      */
749     public static final int CONTENT_CHANGE_TYPE_DRAG_CANCELLED = 1 << 9;
750 
751     /**
752      * Change type for {@link #TYPE_WINDOW_CONTENT_CHANGED} event:
753      * The source node changed its content validity returned by
754      * {@link AccessibilityNodeInfo#isContentInvalid}.
755      * The view changing content validity should call
756      * {@link AccessibilityNodeInfo#setContentInvalid} and then send this event.
757      *
758      * @see AccessibilityNodeInfo#isContentInvalid
759      * @see AccessibilityNodeInfo#setContentInvalid
760      */
761     public static final int CONTENT_CHANGE_TYPE_CONTENT_INVALID = 1 << 10;
762 
763     /**
764      * Change type for {@link #TYPE_WINDOW_CONTENT_CHANGED} event:
765      * The source node changed its erroneous content's error message returned by
766      * {@link AccessibilityNodeInfo#getError}.
767      * The view changing erroneous content's error message should call
768      * {@link AccessibilityNodeInfo#setError} and then send this event.
769      *
770      * @see AccessibilityNodeInfo#getError
771      * @see AccessibilityNodeInfo#setError
772      */
773     public static final int CONTENT_CHANGE_TYPE_ERROR = 1 << 11;
774 
775     /**
776      * Change type for {@link #TYPE_WINDOW_CONTENT_CHANGED} event:
777      * The source node changed its ability to interact returned by
778      * {@link AccessibilityNodeInfo#isEnabled}.
779      * The view changing content's ability to interact should call
780      * {@link AccessibilityNodeInfo#setEnabled} and then send this event.
781      *
782      * @see AccessibilityNodeInfo#isEnabled
783      * @see AccessibilityNodeInfo#setEnabled
784      */
785     public static final int CONTENT_CHANGE_TYPE_ENABLED = 1 << 12;
786 
787     // Speech state change types.
788 
789     /** Change type for {@link #TYPE_SPEECH_STATE_CHANGE} event: another service is speaking. */
790     public static final int SPEECH_STATE_SPEAKING_START = 1 /* << 0 */;;
791 
792     /**
793      * Change type for {@link #TYPE_SPEECH_STATE_CHANGE} event: another service is no longer
794      * speaking.
795      */
796     public static final int SPEECH_STATE_SPEAKING_END = 1 << 1;
797 
798     /**
799      * Change type for {@link #TYPE_SPEECH_STATE_CHANGE} event: another service is listening to the
800      * microphone.
801      */
802     public static final int SPEECH_STATE_LISTENING_START = 1 << 2;
803 
804     /**
805      * Change type for {@link #TYPE_SPEECH_STATE_CHANGE} event: another service is no longer
806      * listening to the microphone.
807      */
808     public static final int SPEECH_STATE_LISTENING_END = 1 << 3;
809 
810     // Windows change types.
811 
812     /**
813      * Change type for {@link #TYPE_WINDOWS_CHANGED} event:
814      * The window was added.
815      */
816     public static final int WINDOWS_CHANGE_ADDED = 1 /* << 0 */;;
817 
818     /**
819      * Change type for {@link #TYPE_WINDOWS_CHANGED} event:
820      * A window was removed.
821      */
822     public static final int WINDOWS_CHANGE_REMOVED = 1 << 1;
823 
824     /**
825      * Change type for {@link #TYPE_WINDOWS_CHANGED} event:
826      * The window's title changed.
827      */
828     public static final int WINDOWS_CHANGE_TITLE = 1 << 2;
829 
830     /**
831      * Change type for {@link #TYPE_WINDOWS_CHANGED} event:
832      * The window's bounds changed.
833      * <p>
834      * Starting in {@link android.os.Build.VERSION_CODES#R R}, this event implies the window's
835      * region changed. It's also possible that region changed but bounds doesn't.
836      * </p>
837      */
838     public static final int WINDOWS_CHANGE_BOUNDS = 1 << 3;
839 
840     /**
841      * Change type for {@link #TYPE_WINDOWS_CHANGED} event:
842      * The window's layer changed.
843      */
844     public static final int WINDOWS_CHANGE_LAYER = 1 << 4;
845 
846     /**
847      * Change type for {@link #TYPE_WINDOWS_CHANGED} event:
848      * The window's {@link AccessibilityWindowInfo#isActive()} changed.
849      */
850     public static final int WINDOWS_CHANGE_ACTIVE = 1 << 5;
851 
852     /**
853      * Change type for {@link #TYPE_WINDOWS_CHANGED} event:
854      * The window's {@link AccessibilityWindowInfo#isFocused()} changed.
855      */
856     public static final int WINDOWS_CHANGE_FOCUSED = 1 << 6;
857 
858     /**
859      * Change type for {@link #TYPE_WINDOWS_CHANGED} event:
860      * The window's {@link AccessibilityWindowInfo#isAccessibilityFocused()} changed.
861      */
862     public static final int WINDOWS_CHANGE_ACCESSIBILITY_FOCUSED = 1 << 7;
863 
864     /**
865      * Change type for {@link #TYPE_WINDOWS_CHANGED} event:
866      * The window's parent changed.
867      */
868     public static final int WINDOWS_CHANGE_PARENT = 1 << 8;
869 
870     /**
871      * Change type for {@link #TYPE_WINDOWS_CHANGED} event:
872      * The window's children changed.
873      */
874     public static final int WINDOWS_CHANGE_CHILDREN = 1 << 9;
875 
876     /**
877      * Change type for {@link #TYPE_WINDOWS_CHANGED} event:
878      * The window either entered or exited picture-in-picture mode.
879      */
880     public static final int WINDOWS_CHANGE_PIP = 1 << 10;
881 
882     /** @hide */
883     @Retention(RetentionPolicy.SOURCE)
884     @IntDef(flag = true, prefix = { "WINDOWS_CHANGE_" }, value = {
885             WINDOWS_CHANGE_ADDED,
886             WINDOWS_CHANGE_REMOVED,
887             WINDOWS_CHANGE_TITLE,
888             WINDOWS_CHANGE_BOUNDS,
889             WINDOWS_CHANGE_LAYER,
890             WINDOWS_CHANGE_ACTIVE,
891             WINDOWS_CHANGE_FOCUSED,
892             WINDOWS_CHANGE_ACCESSIBILITY_FOCUSED,
893             WINDOWS_CHANGE_PARENT,
894             WINDOWS_CHANGE_CHILDREN,
895             WINDOWS_CHANGE_PIP
896     })
897     public @interface WindowsChangeTypes {}
898 
899     /** @hide */
900     @Retention(RetentionPolicy.SOURCE)
901     @IntDef(
902             flag = true,
903             prefix = {"CONTENT_CHANGE_TYPE_"},
904             value = {
905                 CONTENT_CHANGE_TYPE_UNDEFINED,
906                 CONTENT_CHANGE_TYPE_SUBTREE,
907                 CONTENT_CHANGE_TYPE_TEXT,
908                 CONTENT_CHANGE_TYPE_CONTENT_DESCRIPTION,
909                 CONTENT_CHANGE_TYPE_STATE_DESCRIPTION,
910                 CONTENT_CHANGE_TYPE_PANE_TITLE,
911                 CONTENT_CHANGE_TYPE_PANE_APPEARED,
912                 CONTENT_CHANGE_TYPE_PANE_DISAPPEARED,
913                 CONTENT_CHANGE_TYPE_DRAG_STARTED,
914                 CONTENT_CHANGE_TYPE_DRAG_DROPPED,
915                 CONTENT_CHANGE_TYPE_DRAG_CANCELLED,
916                 CONTENT_CHANGE_TYPE_CONTENT_INVALID,
917                 CONTENT_CHANGE_TYPE_ERROR,
918                 CONTENT_CHANGE_TYPE_ENABLED,
919             })
920     public @interface ContentChangeTypes {}
921 
922     /** @hide */
923     @Retention(RetentionPolicy.SOURCE)
924     @IntDef(
925             flag = true,
926             prefix = {"SPEECH_STATE_"},
927             value = {
928                 SPEECH_STATE_SPEAKING_START,
929                 SPEECH_STATE_SPEAKING_END,
930                 SPEECH_STATE_LISTENING_START,
931                 SPEECH_STATE_LISTENING_END
932             })
933     public @interface SpeechStateChangeTypes {}
934 
935     /** @hide */
936     @Retention(RetentionPolicy.SOURCE)
937     @IntDef(
938             flag = true,
939             prefix = {"TYPE_"},
940             value = {
941                 TYPE_VIEW_CLICKED,
942                 TYPE_VIEW_LONG_CLICKED,
943                 TYPE_VIEW_SELECTED,
944                 TYPE_VIEW_FOCUSED,
945                 TYPE_VIEW_TEXT_CHANGED,
946                 TYPE_WINDOW_STATE_CHANGED,
947                 TYPE_NOTIFICATION_STATE_CHANGED,
948                 TYPE_VIEW_HOVER_ENTER,
949                 TYPE_VIEW_HOVER_EXIT,
950                 TYPE_TOUCH_EXPLORATION_GESTURE_START,
951                 TYPE_TOUCH_EXPLORATION_GESTURE_END,
952                 TYPE_WINDOW_CONTENT_CHANGED,
953                 TYPE_VIEW_SCROLLED,
954                 TYPE_VIEW_TEXT_SELECTION_CHANGED,
955                 TYPE_ANNOUNCEMENT,
956                 TYPE_VIEW_ACCESSIBILITY_FOCUSED,
957                 TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED,
958                 TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY,
959                 TYPE_GESTURE_DETECTION_START,
960                 TYPE_GESTURE_DETECTION_END,
961                 TYPE_TOUCH_INTERACTION_START,
962                 TYPE_TOUCH_INTERACTION_END,
963                 TYPE_WINDOWS_CHANGED,
964                 TYPE_VIEW_CONTEXT_CLICKED,
965                 TYPE_ASSIST_READING_CONTEXT,
966                 TYPE_SPEECH_STATE_CHANGE,
967                 TYPE_VIEW_TARGETED_BY_SCROLL
968             })
969     public @interface EventType {}
970 
971     /**
972      * Mask for {@link AccessibilityEvent} all types.
973      *
974      * @see #TYPE_VIEW_CLICKED
975      * @see #TYPE_VIEW_LONG_CLICKED
976      * @see #TYPE_VIEW_SELECTED
977      * @see #TYPE_VIEW_FOCUSED
978      * @see #TYPE_VIEW_TEXT_CHANGED
979      * @see #TYPE_WINDOW_STATE_CHANGED
980      * @see #TYPE_NOTIFICATION_STATE_CHANGED
981      * @see #TYPE_VIEW_HOVER_ENTER
982      * @see #TYPE_VIEW_HOVER_EXIT
983      * @see #TYPE_TOUCH_EXPLORATION_GESTURE_START
984      * @see #TYPE_TOUCH_EXPLORATION_GESTURE_END
985      * @see #TYPE_WINDOW_CONTENT_CHANGED
986      * @see #TYPE_VIEW_SCROLLED
987      * @see #TYPE_VIEW_TEXT_SELECTION_CHANGED
988      * @see #TYPE_ANNOUNCEMENT
989      * @see #TYPE_VIEW_ACCESSIBILITY_FOCUSED
990      * @see #TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED
991      * @see #TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
992      * @see #TYPE_GESTURE_DETECTION_START
993      * @see #TYPE_GESTURE_DETECTION_END
994      * @see #TYPE_TOUCH_INTERACTION_START
995      * @see #TYPE_TOUCH_INTERACTION_END
996      * @see #TYPE_WINDOWS_CHANGED
997      * @see #TYPE_VIEW_CONTEXT_CLICKED
998      * @see #TYPE_ASSIST_READING_CONTEXT
999      * @see #TYPE_SPEECH_STATE_CHANGE
1000      * @see #TYPE_VIEW_TARGETED_BY_SCROLL
1001      */
1002     public static final int TYPES_ALL_MASK = 0xFFFFFFFF;
1003 
1004     @UnsupportedAppUsage
1005     @EventType
1006     private int mEventType;
1007     private CharSequence mPackageName;
1008     private long mEventTime;
1009     int mMovementGranularity;
1010     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
1011     int mAction;
1012     int mContentChangeTypes;
1013     int mWindowChangeTypes;
1014     int mSpeechStateChangeTypes;
1015 
1016     /**
1017      * The stack trace describing where this event originated from on the app side.
1018      * Only populated if {@link #DEBUG_ORIGIN} is enabled
1019      * Can be inspected(e.g. printed) from an
1020      * {@link android.accessibilityservice.AccessibilityService} to trace where particular events
1021      * are being dispatched from.
1022      *
1023      * @hide
1024      */
1025     public StackTraceElement[] originStackTrace = null;
1026 
1027     private ArrayList<AccessibilityRecord> mRecords;
1028 
1029     /**
1030      * Creates a new {@link AccessibilityEvent}.
1031      */
AccessibilityEvent()1032     public AccessibilityEvent() {
1033         if (DEBUG_ORIGIN) originStackTrace = Thread.currentThread().getStackTrace();
1034     }
1035 
1036 
1037     /**
1038      * Creates a new {@link AccessibilityEvent} with the given <code>eventType</code>.
1039      *
1040      * @param eventType The event type.
1041      */
AccessibilityEvent(int eventType)1042     public AccessibilityEvent(int eventType) {
1043         mEventType = eventType;
1044         if (DEBUG_ORIGIN) originStackTrace = Thread.currentThread().getStackTrace();
1045     }
1046 
1047     /**
1048      * Copy constructor. Creates a new {@link AccessibilityEvent}, and this instance is initialized
1049      * from the given <code>event</code>.
1050      *
1051      * @param event The other event.
1052      */
AccessibilityEvent(@onNull AccessibilityEvent event)1053     public AccessibilityEvent(@NonNull AccessibilityEvent event) {
1054         init(event);
1055     }
1056 
1057     /**
1058      * Initialize an event from another one.
1059      *
1060      * @param event The event to initialize from.
1061      */
init(AccessibilityEvent event)1062     void init(AccessibilityEvent event) {
1063         super.init(event);
1064         mEventType = event.mEventType;
1065         mMovementGranularity = event.mMovementGranularity;
1066         mAction = event.mAction;
1067         mContentChangeTypes = event.mContentChangeTypes;
1068         mSpeechStateChangeTypes = event.mSpeechStateChangeTypes;
1069         mWindowChangeTypes = event.mWindowChangeTypes;
1070         mEventTime = event.mEventTime;
1071         mPackageName = event.mPackageName;
1072         if (event.mRecords != null) {
1073             mRecords = new ArrayList<>(event.mRecords.size());
1074             for (AccessibilityRecord record : event.mRecords) {
1075                 final AccessibilityRecord recordClone = new AccessibilityRecord(record);
1076                 mRecords.add(recordClone);
1077             }
1078         }
1079         if (DEBUG_ORIGIN) originStackTrace = event.originStackTrace;
1080     }
1081 
1082     /**
1083      * Sets if this instance is sealed.
1084      *
1085      * @param sealed Whether is sealed.
1086      *
1087      * @hide
1088      */
1089     @Override
setSealed(boolean sealed)1090     public void setSealed(boolean sealed) {
1091         super.setSealed(sealed);
1092         final List<AccessibilityRecord> records = mRecords;
1093         if (records != null) {
1094             for (AccessibilityRecord record : records) {
1095                 record.setSealed(sealed);
1096             }
1097         }
1098     }
1099 
1100     /**
1101      * Gets the number of records contained in the event.
1102      *
1103      * @return The number of records.
1104      */
getRecordCount()1105     public int getRecordCount() {
1106         return mRecords == null ? 0 : mRecords.size();
1107     }
1108 
1109     /**
1110      * Appends an {@link AccessibilityRecord} to the end of event records.
1111      *
1112      * @param record The record to append.
1113      *
1114      * @throws IllegalStateException If called from an AccessibilityService.
1115      */
appendRecord(AccessibilityRecord record)1116     public void appendRecord(AccessibilityRecord record) {
1117         enforceNotSealed();
1118         if (mRecords == null) {
1119             mRecords = new ArrayList<AccessibilityRecord>();
1120         }
1121         mRecords.add(record);
1122     }
1123 
1124     /**
1125      * Gets the record at a given index.
1126      *
1127      * @param index The index.
1128      * @return The record at the specified index.
1129      */
getRecord(int index)1130     public AccessibilityRecord getRecord(int index) {
1131         if (mRecords == null) {
1132             throw new IndexOutOfBoundsException("Invalid index " + index + ", size is 0");
1133         }
1134         return mRecords.get(index);
1135     }
1136 
1137     /**
1138      * Gets the event type.
1139      *
1140      * @return The event type.
1141      */
1142     @EventType
getEventType()1143     public int getEventType() {
1144         return mEventType;
1145     }
1146 
1147     /**
1148      * Gets the bit mask of change types signaled by a
1149      * {@link #TYPE_WINDOW_CONTENT_CHANGED} event or {@link #TYPE_WINDOW_STATE_CHANGED}. A single
1150      * event may represent multiple change types.
1151      *
1152      * @return The bit mask of change types. One or more of:
1153      *         <ul>
1154      *         <li>{@link #CONTENT_CHANGE_TYPE_CONTENT_DESCRIPTION}
1155      *         <li>{@link #CONTENT_CHANGE_TYPE_STATE_DESCRIPTION}
1156      *         <li>{@link #CONTENT_CHANGE_TYPE_SUBTREE}
1157      *         <li>{@link #CONTENT_CHANGE_TYPE_TEXT}
1158      *         <li>{@link #CONTENT_CHANGE_TYPE_PANE_TITLE}
1159      *         <li>{@link #CONTENT_CHANGE_TYPE_UNDEFINED}
1160      *         <li>{@link #CONTENT_CHANGE_TYPE_PANE_APPEARED}
1161      *         <li>{@link #CONTENT_CHANGE_TYPE_PANE_DISAPPEARED}
1162      *         <li>{@link #CONTENT_CHANGE_TYPE_DRAG_STARTED}
1163      *         <li>{@link #CONTENT_CHANGE_TYPE_DRAG_DROPPED}
1164      *         <li>{@link #CONTENT_CHANGE_TYPE_DRAG_CANCELLED}
1165      *         <li>{@link #CONTENT_CHANGE_TYPE_CONTENT_INVALID}
1166      *         <li>{@link #CONTENT_CHANGE_TYPE_ERROR}
1167      *         <li>{@link #CONTENT_CHANGE_TYPE_ENABLED}
1168      *         </ul>
1169      */
1170     @ContentChangeTypes
getContentChangeTypes()1171     public int getContentChangeTypes() {
1172         return mContentChangeTypes;
1173     }
1174 
contentChangeTypesToString(int types)1175     private static String contentChangeTypesToString(int types) {
1176         return BitUtils.flagsToString(types, AccessibilityEvent::singleContentChangeTypeToString);
1177     }
1178 
singleContentChangeTypeToString(int type)1179     private static String singleContentChangeTypeToString(int type) {
1180         switch (type) {
1181             case CONTENT_CHANGE_TYPE_CONTENT_DESCRIPTION:
1182                 return "CONTENT_CHANGE_TYPE_CONTENT_DESCRIPTION";
1183             case CONTENT_CHANGE_TYPE_STATE_DESCRIPTION:
1184                 return "CONTENT_CHANGE_TYPE_STATE_DESCRIPTION";
1185             case CONTENT_CHANGE_TYPE_SUBTREE: return "CONTENT_CHANGE_TYPE_SUBTREE";
1186             case CONTENT_CHANGE_TYPE_TEXT: return "CONTENT_CHANGE_TYPE_TEXT";
1187             case CONTENT_CHANGE_TYPE_PANE_TITLE: return "CONTENT_CHANGE_TYPE_PANE_TITLE";
1188             case CONTENT_CHANGE_TYPE_UNDEFINED: return "CONTENT_CHANGE_TYPE_UNDEFINED";
1189             case CONTENT_CHANGE_TYPE_PANE_APPEARED: return "CONTENT_CHANGE_TYPE_PANE_APPEARED";
1190             case CONTENT_CHANGE_TYPE_PANE_DISAPPEARED:
1191                 return "CONTENT_CHANGE_TYPE_PANE_DISAPPEARED";
1192             case CONTENT_CHANGE_TYPE_DRAG_STARTED: return "CONTENT_CHANGE_TYPE_DRAG_STARTED";
1193             case CONTENT_CHANGE_TYPE_DRAG_DROPPED: return "CONTENT_CHANGE_TYPE_DRAG_DROPPED";
1194             case CONTENT_CHANGE_TYPE_DRAG_CANCELLED: return "CONTENT_CHANGE_TYPE_DRAG_CANCELLED";
1195             case CONTENT_CHANGE_TYPE_CONTENT_INVALID:
1196                 return "CONTENT_CHANGE_TYPE_CONTENT_INVALID";
1197             case CONTENT_CHANGE_TYPE_ERROR: return "CONTENT_CHANGE_TYPE_ERROR";
1198             case CONTENT_CHANGE_TYPE_ENABLED: return "CONTENT_CHANGE_TYPE_ENABLED";
1199             default: return Integer.toHexString(type);
1200         }
1201     }
1202 
1203     /**
1204      * Sets the bit mask of node tree changes signaled by an
1205      * {@link #TYPE_WINDOW_CONTENT_CHANGED} event.
1206      *
1207      * @param changeTypes The bit mask of change types.
1208      * @throws IllegalStateException If called from an AccessibilityService.
1209      * @see #getContentChangeTypes()
1210      */
setContentChangeTypes(@ontentChangeTypes int changeTypes)1211     public void setContentChangeTypes(@ContentChangeTypes int changeTypes) {
1212         enforceNotSealed();
1213         mContentChangeTypes = changeTypes;
1214     }
1215 
1216     /**
1217      * Whether the event should only be delivered to an
1218      * {@link android.accessibilityservice.AccessibilityService} with the
1219      * {@link android.accessibilityservice.AccessibilityServiceInfo#isAccessibilityTool} property
1220      * set to true.
1221      *
1222      * <p>
1223      * Initial value matches the {@link android.view.View#isAccessibilityDataSensitive} property
1224      * from the event's source node, if present, or false by default.
1225      * </p>
1226      *
1227      * @return True if the event should be delivered only to isAccessibilityTool services, false
1228      * otherwise.
1229      * @see #setAccessibilityDataSensitive
1230      */
1231     @Override
isAccessibilityDataSensitive()1232     public boolean isAccessibilityDataSensitive() {
1233         return super.isAccessibilityDataSensitive();
1234     }
1235 
1236     /**
1237      * Sets whether the event should only be delivered to an
1238      * {@link android.accessibilityservice.AccessibilityService} with the
1239      * {@link android.accessibilityservice.AccessibilityServiceInfo#isAccessibilityTool} property
1240      * set to true.
1241      *
1242      * <p>
1243      * This will be set automatically based on the event's source (if present). If creating and
1244      * sending an event directly through {@link AccessibilityManager} (where an event may have
1245      * no source) then this method must be called explicitly if you want non-default behavior.
1246      * </p>
1247      *
1248      * @param accessibilityDataSensitive True if the event should be delivered only to
1249      *                                 isAccessibilityTool services, false otherwise.
1250      * @throws IllegalStateException If called from an AccessibilityService.
1251      */
1252     @Override
setAccessibilityDataSensitive(boolean accessibilityDataSensitive)1253     public void setAccessibilityDataSensitive(boolean accessibilityDataSensitive) {
1254         super.setAccessibilityDataSensitive(accessibilityDataSensitive);
1255     }
1256 
1257     /**
1258      * Gets the bit mask of the speech state signaled by a {@link #TYPE_SPEECH_STATE_CHANGE} event.
1259      *
1260      * @return The bit mask of speech change types.
1261      *
1262      * @see #SPEECH_STATE_SPEAKING_START
1263      * @see #SPEECH_STATE_SPEAKING_END
1264      * @see #SPEECH_STATE_LISTENING_START
1265      * @see #SPEECH_STATE_LISTENING_END
1266      */
getSpeechStateChangeTypes()1267     public int getSpeechStateChangeTypes() {
1268         return mSpeechStateChangeTypes;
1269     }
1270 
speechStateChangeTypesToString(int types)1271     private static String speechStateChangeTypesToString(int types) {
1272         return BitUtils.flagsToString(
1273                 types, AccessibilityEvent::singleSpeechStateChangeTypeToString);
1274     }
1275 
singleSpeechStateChangeTypeToString(int type)1276     private static String singleSpeechStateChangeTypeToString(int type) {
1277         switch (type) {
1278             case SPEECH_STATE_SPEAKING_START:
1279                 return "SPEECH_STATE_SPEAKING_START";
1280             case SPEECH_STATE_LISTENING_START:
1281                 return "SPEECH_STATE_LISTENING_START";
1282             case SPEECH_STATE_SPEAKING_END:
1283                 return "SPEECH_STATE_SPEAKING_END";
1284             case SPEECH_STATE_LISTENING_END:
1285                 return "SPEECH_STATE_LISTENING_END";
1286             default:
1287                 return Integer.toHexString(type);
1288         }
1289     }
1290 
1291     /**
1292      * Sets the bit mask of the speech state change types
1293      * signaled by a {@link #TYPE_SPEECH_STATE_CHANGE} event.
1294      * The sender is responsible for ensuring that  the state change types  make sense. For example,
1295      * the sender should not send
1296      * {@link #SPEECH_STATE_SPEAKING_START} and {@link #SPEECH_STATE_SPEAKING_END} together.
1297      *
1298      * @see #SPEECH_STATE_SPEAKING_START
1299      * @see #SPEECH_STATE_SPEAKING_END
1300      * @see #SPEECH_STATE_LISTENING_START
1301      * @see #SPEECH_STATE_LISTENING_END
1302      */
setSpeechStateChangeTypes(@peechStateChangeTypes int state)1303     public void setSpeechStateChangeTypes(@SpeechStateChangeTypes int state) {
1304         enforceNotSealed();
1305         mSpeechStateChangeTypes = state;
1306     }
1307 
1308     /**
1309      * Get the bit mask of change types signaled by a {@link #TYPE_WINDOWS_CHANGED} event. A
1310      * single event may represent multiple change types.
1311      *
1312      * @return The bit mask of change types.
1313      *
1314      * @see #WINDOWS_CHANGE_ADDED
1315      * @see #WINDOWS_CHANGE_REMOVED
1316      * @see #WINDOWS_CHANGE_TITLE
1317      * @see #WINDOWS_CHANGE_BOUNDS
1318      * @see #WINDOWS_CHANGE_LAYER
1319      * @see #WINDOWS_CHANGE_ACTIVE
1320      * @see #WINDOWS_CHANGE_FOCUSED
1321      * @see #WINDOWS_CHANGE_ACCESSIBILITY_FOCUSED
1322      * @see #WINDOWS_CHANGE_PARENT
1323      * @see #WINDOWS_CHANGE_CHILDREN
1324      * @see #WINDOWS_CHANGE_PIP
1325      */
1326     @WindowsChangeTypes
getWindowChanges()1327     public int getWindowChanges() {
1328         return mWindowChangeTypes;
1329     }
1330 
1331     /** @hide  */
setWindowChanges(@indowsChangeTypes int changes)1332     public void setWindowChanges(@WindowsChangeTypes int changes) {
1333         mWindowChangeTypes = changes;
1334     }
1335 
windowChangeTypesToString(@indowsChangeTypes int types)1336     private static String windowChangeTypesToString(@WindowsChangeTypes int types) {
1337         return BitUtils.flagsToString(types, AccessibilityEvent::singleWindowChangeTypeToString);
1338     }
1339 
singleWindowChangeTypeToString(int type)1340     private static String singleWindowChangeTypeToString(int type) {
1341         switch (type) {
1342             case WINDOWS_CHANGE_ADDED: return "WINDOWS_CHANGE_ADDED";
1343             case WINDOWS_CHANGE_REMOVED: return "WINDOWS_CHANGE_REMOVED";
1344             case WINDOWS_CHANGE_TITLE: return "WINDOWS_CHANGE_TITLE";
1345             case WINDOWS_CHANGE_BOUNDS: return "WINDOWS_CHANGE_BOUNDS";
1346             case WINDOWS_CHANGE_LAYER: return "WINDOWS_CHANGE_LAYER";
1347             case WINDOWS_CHANGE_ACTIVE: return "WINDOWS_CHANGE_ACTIVE";
1348             case WINDOWS_CHANGE_FOCUSED: return "WINDOWS_CHANGE_FOCUSED";
1349             case WINDOWS_CHANGE_ACCESSIBILITY_FOCUSED:
1350                 return "WINDOWS_CHANGE_ACCESSIBILITY_FOCUSED";
1351             case WINDOWS_CHANGE_PARENT: return "WINDOWS_CHANGE_PARENT";
1352             case WINDOWS_CHANGE_CHILDREN: return "WINDOWS_CHANGE_CHILDREN";
1353             case WINDOWS_CHANGE_PIP: return "WINDOWS_CHANGE_PIP";
1354             default: return Integer.toHexString(type);
1355         }
1356     }
1357 
1358     /**
1359      * Sets the event type.
1360      *
1361      * <b>Note: An event must represent a single event type.</b>
1362      * @param eventType The event type.
1363      *
1364      * @throws IllegalStateException If called from an AccessibilityService.
1365      */
setEventType(@ventType int eventType)1366     public void setEventType(@EventType int eventType) {
1367         enforceNotSealed();
1368         mEventType = eventType;
1369     }
1370 
1371     /**
1372      * Gets the time in which this event was sent.
1373      *
1374      * @return The event time.
1375      */
getEventTime()1376     public long getEventTime() {
1377         return mEventTime;
1378     }
1379 
1380     /**
1381      * Sets the time in which this event was sent.
1382      *
1383      * @param eventTime The event time.
1384      *
1385      * @throws IllegalStateException If called from an AccessibilityService.
1386      */
setEventTime(long eventTime)1387     public void setEventTime(long eventTime) {
1388         enforceNotSealed();
1389         mEventTime = eventTime;
1390     }
1391 
1392     /**
1393      * Gets the package name of the source.
1394      *
1395      * @return The package name.
1396      */
getPackageName()1397     public CharSequence getPackageName() {
1398         return mPackageName;
1399     }
1400 
1401     /**
1402      * Sets the package name of the source.
1403      *
1404      * @param packageName The package name.
1405      *
1406      * @throws IllegalStateException If called from an AccessibilityService.
1407      */
setPackageName(CharSequence packageName)1408     public void setPackageName(CharSequence packageName) {
1409         enforceNotSealed();
1410         mPackageName = packageName;
1411     }
1412 
1413     /**
1414      * Sets the movement granularity that was traversed.
1415      *
1416      * @param granularity The granularity.
1417      *
1418      * @throws IllegalStateException If called from an AccessibilityService.
1419      */
setMovementGranularity(int granularity)1420     public void setMovementGranularity(int granularity) {
1421         enforceNotSealed();
1422         mMovementGranularity = granularity;
1423     }
1424 
1425     /**
1426      * Gets the movement granularity that was traversed.
1427      *
1428      * @return The granularity.
1429      */
getMovementGranularity()1430     public int getMovementGranularity() {
1431         return mMovementGranularity;
1432     }
1433 
1434     /**
1435      * Sets the performed action that triggered this event.
1436      * <p>
1437      * Valid actions are defined in {@link AccessibilityNodeInfo}:
1438      * <ul>
1439      * <li>{@link AccessibilityNodeInfo#ACTION_ACCESSIBILITY_FOCUS}
1440      * <li>{@link AccessibilityNodeInfo#ACTION_CLEAR_ACCESSIBILITY_FOCUS}
1441      * <li>{@link AccessibilityNodeInfo#ACTION_CLEAR_FOCUS}
1442      * <li>{@link AccessibilityNodeInfo#ACTION_CLEAR_SELECTION}
1443      * <li>{@link AccessibilityNodeInfo#ACTION_CLICK}
1444      * <li>{@link AccessibilityNodeInfo#ACTION_LONG_CLICK}
1445      * <li>{@link AccessibilityNodeInfo#ACTION_NEXT_AT_MOVEMENT_GRANULARITY}
1446      * <li>{@link AccessibilityNodeInfo#ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY}
1447      * <li>{@link AccessibilityNodeInfo#ACTION_NEXT_HTML_ELEMENT}
1448      * <li>{@link AccessibilityNodeInfo#ACTION_PREVIOUS_HTML_ELEMENT}
1449      * <li>{@link AccessibilityNodeInfo#ACTION_SCROLL_FORWARD}
1450      * <li>{@link AccessibilityNodeInfo#ACTION_SCROLL_BACKWARD}
1451      * <li>{@link AccessibilityNodeInfo#ACTION_COPY}
1452      * <li>{@link AccessibilityNodeInfo#ACTION_PASTE}
1453      * <li>{@link AccessibilityNodeInfo#ACTION_CUT}
1454      * <li>{@link AccessibilityNodeInfo#ACTION_SET_SELECTION}
1455      * <li>{@link AccessibilityNodeInfo#ACTION_EXPAND}
1456      * <li>{@link AccessibilityNodeInfo#ACTION_COLLAPSE}
1457      * <li>{@link AccessibilityNodeInfo#ACTION_DISMISS}
1458      * <li>{@link AccessibilityNodeInfo#ACTION_SET_TEXT}
1459      * <li>etc.
1460      * </ul>
1461      *
1462      * @param action The action.
1463      * @throws IllegalStateException If called from an AccessibilityService.
1464      * @see AccessibilityNodeInfo#performAction(int)
1465      */
setAction(int action)1466     public void setAction(int action) {
1467         enforceNotSealed();
1468         mAction = action;
1469     }
1470 
1471     /**
1472      * Gets the performed action that triggered this event.
1473      *
1474      * @return The action.
1475      */
getAction()1476     public int getAction() {
1477         return mAction;
1478     }
1479 
1480     /**
1481      * Convenience method to obtain a {@link #TYPE_WINDOWS_CHANGED} event for a specific window and
1482      * change set.
1483      *
1484      * @param displayId The ID of the display from which the event comes from
1485      * @param windowId The ID of the window that changed
1486      * @param windowChangeTypes The changes to populate
1487      * @return An instance of a TYPE_WINDOWS_CHANGED, populated with the requested fields and with
1488      *         importantForAccessibility set to {@code true}.
1489      *
1490      * @hide
1491      */
obtainWindowsChangedEvent( int displayId, int windowId, int windowChangeTypes)1492     public static AccessibilityEvent obtainWindowsChangedEvent(
1493             int displayId, int windowId, int windowChangeTypes) {
1494         final AccessibilityEvent event = new AccessibilityEvent(TYPE_WINDOWS_CHANGED);
1495         event.setDisplayId(displayId);
1496         event.setWindowId(windowId);
1497         event.setWindowChanges(windowChangeTypes);
1498         event.setImportantForAccessibility(true);
1499         return event;
1500     }
1501 
1502     /**
1503      * Instantiates a new AccessibilityEvent instance with its type property set.
1504      *
1505      * @deprecated Object pooling has been discontinued. Create a new instance using the
1506      * constructor {@link #AccessibilityEvent()} instead.
1507      * @param eventType The event type.
1508      * @return An instance.
1509      */
1510     @Deprecated
obtain(int eventType)1511     public static AccessibilityEvent obtain(int eventType) {
1512         AccessibilityEvent event = new AccessibilityEvent();
1513         event.setEventType(eventType);
1514         return event;
1515     }
1516 
1517     /**
1518      * Instantiates a new AccessibilityEvent instance.
1519      * The returned instance is initialized from the given
1520      * <code>event</code>.
1521      *
1522      * @deprecated Object pooling has been discontinued. Create a new instance using the
1523      * constructor {@link #AccessibilityEvent()} instead.
1524      * @param event The other event.
1525      * @return An instance.
1526      */
1527     @Deprecated
obtain(AccessibilityEvent event)1528     public static AccessibilityEvent obtain(AccessibilityEvent event) {
1529         AccessibilityEvent eventClone = new AccessibilityEvent();
1530         eventClone.init(event);
1531         return eventClone;
1532     }
1533 
1534     /**
1535      * Instantiates a new AccessibilityEvent instance.
1536      *
1537      * @deprecated Object pooling has been discontinued. Create a new instance using the
1538      * constructor {@link #AccessibilityEvent()} instead.
1539      * @return An instance.
1540      */
1541     @Deprecated
obtain()1542     public static AccessibilityEvent obtain() {
1543         return new AccessibilityEvent();
1544     }
1545 
1546     /**
1547      * Previously would recycle an instance back to be reused.
1548      *
1549      * @deprecated Object pooling has been discontinued. Calling this function now will have
1550      * no effect.
1551      */
1552     @Override
1553     @Deprecated
recycle()1554     public void recycle() {}
1555 
1556     /**
1557      * Clears the state of this instance.
1558      *
1559      * @hide
1560      */
1561     @Override
clear()1562     protected void clear() {
1563         super.clear();
1564         mEventType = 0;
1565         mMovementGranularity = 0;
1566         mAction = 0;
1567         mContentChangeTypes = 0;
1568         mWindowChangeTypes = 0;
1569         mSpeechStateChangeTypes = 0;
1570         mPackageName = null;
1571         mEventTime = 0;
1572         if (mRecords != null) {
1573             while (!mRecords.isEmpty()) {
1574                 AccessibilityRecord record = mRecords.remove(0);
1575             }
1576         }
1577         if (DEBUG_ORIGIN) originStackTrace = null;
1578     }
1579 
1580     /**
1581      * Creates a new instance from a {@link Parcel}.
1582      *
1583      * @param parcel A parcel containing the state of a {@link AccessibilityEvent}.
1584      */
initFromParcel(Parcel parcel)1585     public void initFromParcel(Parcel parcel) {
1586         mSealed = (parcel.readInt() == 1);
1587         mEventType = parcel.readInt();
1588         mMovementGranularity = parcel.readInt();
1589         mAction = parcel.readInt();
1590         mContentChangeTypes = parcel.readInt();
1591         mWindowChangeTypes = parcel.readInt();
1592         mSpeechStateChangeTypes = parcel.readInt();
1593         mPackageName = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(parcel);
1594         mEventTime = parcel.readLong();
1595         mConnectionId = parcel.readInt();
1596         readAccessibilityRecordFromParcel(this, parcel);
1597 
1598         // Read the records.
1599         final int recordCount = parcel.readInt();
1600         if (recordCount > 0) {
1601             mRecords = new ArrayList<>(recordCount);
1602             for (int i = 0; i < recordCount; i++) {
1603                 AccessibilityRecord record = new AccessibilityRecord();
1604                 readAccessibilityRecordFromParcel(record, parcel);
1605                 record.mConnectionId = mConnectionId;
1606                 mRecords.add(record);
1607             }
1608         }
1609 
1610         if (DEBUG_ORIGIN) {
1611             originStackTrace = new StackTraceElement[parcel.readInt()];
1612             for (int i = 0; i < originStackTrace.length; i++) {
1613                 originStackTrace[i] = new StackTraceElement(
1614                         parcel.readString(),
1615                         parcel.readString(),
1616                         parcel.readString(),
1617                         parcel.readInt());
1618             }
1619         }
1620     }
1621 
1622     /**
1623      * Reads an {@link AccessibilityRecord} from a parcel.
1624      *
1625      * @param record The record to initialize.
1626      * @param parcel The parcel to read from.
1627      */
readAccessibilityRecordFromParcel(AccessibilityRecord record, Parcel parcel)1628     private void readAccessibilityRecordFromParcel(AccessibilityRecord record,
1629             Parcel parcel) {
1630         record.mBooleanProperties = parcel.readInt();
1631         record.mCurrentItemIndex = parcel.readInt();
1632         record.mItemCount = parcel.readInt();
1633         record.mFromIndex = parcel.readInt();
1634         record.mToIndex = parcel.readInt();
1635         record.mScrollX = parcel.readInt();
1636         record.mScrollY =  parcel.readInt();
1637         record.mScrollDeltaX =  parcel.readInt();
1638         record.mScrollDeltaY =  parcel.readInt();
1639         record.mMaxScrollX = parcel.readInt();
1640         record.mMaxScrollY =  parcel.readInt();
1641         record.mAddedCount = parcel.readInt();
1642         record.mRemovedCount = parcel.readInt();
1643         record.mClassName = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(parcel);
1644         record.mContentDescription = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(parcel);
1645         record.mBeforeText = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(parcel);
1646         record.mParcelableData = parcel.readParcelable(null);
1647         parcel.readList(record.mText, null, java.lang.CharSequence.class);
1648         record.mSourceWindowId = parcel.readInt();
1649         record.mSourceNodeId = parcel.readLong();
1650         record.mSourceDisplayId = parcel.readInt();
1651         record.mSealed = (parcel.readInt() == 1);
1652     }
1653 
1654     /**
1655      * {@inheritDoc}
1656      */
writeToParcel(Parcel parcel, int flags)1657     public void writeToParcel(Parcel parcel, int flags) {
1658         parcel.writeInt(isSealed() ? 1 : 0);
1659         parcel.writeInt(mEventType);
1660         parcel.writeInt(mMovementGranularity);
1661         parcel.writeInt(mAction);
1662         parcel.writeInt(mContentChangeTypes);
1663         parcel.writeInt(mWindowChangeTypes);
1664         parcel.writeInt(mSpeechStateChangeTypes);
1665         TextUtils.writeToParcel(mPackageName, parcel, 0);
1666         parcel.writeLong(mEventTime);
1667         parcel.writeInt(mConnectionId);
1668         writeAccessibilityRecordToParcel(this, parcel, flags);
1669 
1670         // Write the records.
1671         final int recordCount = getRecordCount();
1672         parcel.writeInt(recordCount);
1673         for (int i = 0; i < recordCount; i++) {
1674             AccessibilityRecord record = mRecords.get(i);
1675             writeAccessibilityRecordToParcel(record, parcel, flags);
1676         }
1677 
1678         if (DEBUG_ORIGIN) {
1679             if (originStackTrace == null) originStackTrace = Thread.currentThread().getStackTrace();
1680             parcel.writeInt(originStackTrace.length);
1681             for (StackTraceElement element : originStackTrace) {
1682                 parcel.writeString(element.getClassName());
1683                 parcel.writeString(element.getMethodName());
1684                 parcel.writeString(element.getFileName());
1685                 parcel.writeInt(element.getLineNumber());
1686             }
1687         }
1688     }
1689 
1690     /**
1691      * Writes an {@link AccessibilityRecord} to a parcel.
1692      *
1693      * @param record The record to write.
1694      * @param parcel The parcel to which to write.
1695      */
writeAccessibilityRecordToParcel(AccessibilityRecord record, Parcel parcel, int flags)1696     private void writeAccessibilityRecordToParcel(AccessibilityRecord record, Parcel parcel,
1697             int flags) {
1698         parcel.writeInt(record.mBooleanProperties);
1699         parcel.writeInt(record.mCurrentItemIndex);
1700         parcel.writeInt(record.mItemCount);
1701         parcel.writeInt(record.mFromIndex);
1702         parcel.writeInt(record.mToIndex);
1703         parcel.writeInt(record.mScrollX);
1704         parcel.writeInt(record.mScrollY);
1705         parcel.writeInt(record.mScrollDeltaX);
1706         parcel.writeInt(record.mScrollDeltaY);
1707         parcel.writeInt(record.mMaxScrollX);
1708         parcel.writeInt(record.mMaxScrollY);
1709         parcel.writeInt(record.mAddedCount);
1710         parcel.writeInt(record.mRemovedCount);
1711         TextUtils.writeToParcel(record.mClassName, parcel, flags);
1712         TextUtils.writeToParcel(record.mContentDescription, parcel, flags);
1713         TextUtils.writeToParcel(record.mBeforeText, parcel, flags);
1714         parcel.writeParcelable(record.mParcelableData, flags);
1715         parcel.writeList(record.mText);
1716         parcel.writeInt(record.mSourceWindowId);
1717         parcel.writeLong(record.mSourceNodeId);
1718         parcel.writeInt(record.mSourceDisplayId);
1719         parcel.writeInt(record.mSealed ? 1 : 0);
1720     }
1721 
1722     /**
1723      * {@inheritDoc}
1724      */
describeContents()1725     public int describeContents() {
1726         return 0;
1727     }
1728 
1729     @Override
toString()1730     public String toString() {
1731         StringBuilder builder = new StringBuilder();
1732         builder.append("EventType: ").append(eventTypeToString(mEventType));
1733         builder.append("; EventTime: ").append(mEventTime);
1734         builder.append("; PackageName: ").append(mPackageName);
1735         if (!DEBUG_CONCISE_TOSTRING || mMovementGranularity != 0) {
1736             builder.append("; MovementGranularity: ").append(mMovementGranularity);
1737         }
1738         if (!DEBUG_CONCISE_TOSTRING || mAction != 0) {
1739             builder.append("; Action: ").append(mAction);
1740         }
1741         if (!DEBUG_CONCISE_TOSTRING || mContentChangeTypes != 0) {
1742             builder.append("; ContentChangeTypes: ").append(
1743                     contentChangeTypesToString(mContentChangeTypes));
1744         }
1745         if (!DEBUG_CONCISE_TOSTRING || mWindowChangeTypes != 0) {
1746             builder.append("; WindowChangeTypes: ").append(
1747                     windowChangeTypesToString(mWindowChangeTypes));
1748         }
1749         super.appendTo(builder);
1750         if (DEBUG || DEBUG_CONCISE_TOSTRING) {
1751             if (!DEBUG_CONCISE_TOSTRING) {
1752                 builder.append("\n");
1753             }
1754             if (DEBUG) {
1755                 builder.append("; SourceWindowId: 0x").append(Long.toHexString(mSourceWindowId));
1756                 builder.append("; SourceNodeId: 0x").append(Long.toHexString(mSourceNodeId));
1757                 builder.append("; SourceDisplayId: ").append(mSourceDisplayId);
1758             }
1759             for (int i = 0; i < getRecordCount(); i++) {
1760                 builder.append("  Record ").append(i).append(":");
1761                 getRecord(i).appendTo(builder).append("\n");
1762             }
1763         } else {
1764             builder.append("; recordCount: ").append(getRecordCount());
1765         }
1766         return builder.toString();
1767     }
1768 
1769     /**
1770      * Returns the string representation of an event type. For example,
1771      * {@link #TYPE_VIEW_CLICKED} is represented by the string TYPE_VIEW_CLICKED.
1772      *
1773      * @param eventType The event type
1774      * @return The string representation.
1775      */
eventTypeToString(int eventType)1776     public static String eventTypeToString(int eventType) {
1777         if (eventType == TYPES_ALL_MASK) {
1778             return "TYPES_ALL_MASK";
1779         }
1780         StringBuilder builder = new StringBuilder();
1781         int eventTypeCount = 0;
1782         while (eventType != 0) {
1783             final int eventTypeFlag = 1 << Integer.numberOfTrailingZeros(eventType);
1784             eventType &= ~eventTypeFlag;
1785 
1786             if (eventTypeCount > 0) {
1787                 builder.append(", ");
1788             }
1789             builder.append(singleEventTypeToString(eventTypeFlag));
1790 
1791             eventTypeCount++;
1792         }
1793         if (eventTypeCount > 1) {
1794             builder.insert(0, '[');
1795             builder.append(']');
1796         }
1797         return builder.toString();
1798     }
1799 
singleEventTypeToString(int eventType)1800     private static String singleEventTypeToString(int eventType) {
1801         switch (eventType) {
1802             case TYPE_VIEW_CLICKED: return "TYPE_VIEW_CLICKED";
1803             case TYPE_VIEW_LONG_CLICKED: return "TYPE_VIEW_LONG_CLICKED";
1804             case TYPE_VIEW_SELECTED: return "TYPE_VIEW_SELECTED";
1805             case TYPE_VIEW_FOCUSED: return "TYPE_VIEW_FOCUSED";
1806             case TYPE_VIEW_TEXT_CHANGED: return "TYPE_VIEW_TEXT_CHANGED";
1807             case TYPE_WINDOW_STATE_CHANGED: return "TYPE_WINDOW_STATE_CHANGED";
1808             case TYPE_VIEW_HOVER_ENTER: return "TYPE_VIEW_HOVER_ENTER";
1809             case TYPE_VIEW_HOVER_EXIT: return "TYPE_VIEW_HOVER_EXIT";
1810             case TYPE_NOTIFICATION_STATE_CHANGED: return "TYPE_NOTIFICATION_STATE_CHANGED";
1811             case TYPE_TOUCH_EXPLORATION_GESTURE_START: {
1812                 return "TYPE_TOUCH_EXPLORATION_GESTURE_START";
1813             }
1814             case TYPE_TOUCH_EXPLORATION_GESTURE_END: return "TYPE_TOUCH_EXPLORATION_GESTURE_END";
1815             case TYPE_WINDOW_CONTENT_CHANGED: return "TYPE_WINDOW_CONTENT_CHANGED";
1816             case TYPE_VIEW_TEXT_SELECTION_CHANGED: return "TYPE_VIEW_TEXT_SELECTION_CHANGED";
1817             case TYPE_VIEW_SCROLLED: return "TYPE_VIEW_SCROLLED";
1818             case TYPE_ANNOUNCEMENT: return "TYPE_ANNOUNCEMENT";
1819             case TYPE_VIEW_ACCESSIBILITY_FOCUSED: return "TYPE_VIEW_ACCESSIBILITY_FOCUSED";
1820             case TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED: {
1821                 return "TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED";
1822             }
1823             case TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY: {
1824                 return "TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY";
1825             }
1826             case TYPE_GESTURE_DETECTION_START: return "TYPE_GESTURE_DETECTION_START";
1827             case TYPE_GESTURE_DETECTION_END: return "TYPE_GESTURE_DETECTION_END";
1828             case TYPE_TOUCH_INTERACTION_START: return "TYPE_TOUCH_INTERACTION_START";
1829             case TYPE_TOUCH_INTERACTION_END: return "TYPE_TOUCH_INTERACTION_END";
1830             case TYPE_WINDOWS_CHANGED: return "TYPE_WINDOWS_CHANGED";
1831             case TYPE_VIEW_CONTEXT_CLICKED: return "TYPE_VIEW_CONTEXT_CLICKED";
1832             case TYPE_ASSIST_READING_CONTEXT: return "TYPE_ASSIST_READING_CONTEXT";
1833             case TYPE_SPEECH_STATE_CHANGE: return "TYPE_SPEECH_STATE_CHANGE";
1834             case TYPE_VIEW_TARGETED_BY_SCROLL: return "TYPE_VIEW_TARGETED_BY_SCROLL";
1835             default: return Integer.toHexString(eventType);
1836         }
1837     }
1838 
1839     /**
1840      * @see Parcelable.Creator
1841      */
1842     @NonNull
1843     public static final Parcelable.Creator<AccessibilityEvent> CREATOR =
1844             new Parcelable.Creator<AccessibilityEvent>() {
1845         public AccessibilityEvent createFromParcel(Parcel parcel) {
1846             AccessibilityEvent event = new AccessibilityEvent();
1847             event.initFromParcel(parcel);
1848             return event;
1849         }
1850 
1851         public AccessibilityEvent[] newArray(int size) {
1852             return new AccessibilityEvent[size];
1853         }
1854     };
1855 }
1856