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