• 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.os.Parcel;
20 import android.os.Parcelable;
21 import android.text.TextUtils;
22 
23 import java.util.ArrayList;
24 import java.util.List;
25 
26 /**
27  * <p>
28  * This class represents accessibility events that are sent by the system when
29  * something notable happens in the user interface. For example, when a
30  * {@link android.widget.Button} is clicked, a {@link android.view.View} is focused, etc.
31  * </p>
32  * <p>
33  * An accessibility event is fired by an individual view which populates the event with
34  * data for its state and requests from its parent to send the event to interested
35  * parties. The parent can optionally add an {@link AccessibilityRecord} for itself before
36  * dispatching a similar request to its parent. A parent can also choose not to respect the
37  * request for sending an event. The accessibility event is sent by the topmost view in the
38  * view tree. Therefore, an {@link android.accessibilityservice.AccessibilityService} can
39  * explore all records in an accessibility event to obtain more information about the
40  * context in which the event was fired.
41  * </p>
42  * <p>
43  * The main purpose of an accessibility event is to expose enough information for an
44  * {@link android.accessibilityservice.AccessibilityService} to provide meaningful feedback
45  * to the user. Sometimes however, an accessibility service may need more contextual
46  * information then the one in the event pay-load. In such cases the service can obtain
47  * the event source which is an {@link AccessibilityNodeInfo} (snapshot of a View state)
48  * which can be used for exploring the window content. Note that the privilege for accessing
49  * an event's source, thus the window content, has to be explicitly requested. For more
50  * details refer to {@link android.accessibilityservice.AccessibilityService}. If an
51  * accessibility service has not requested to retrieve the window content the event will
52  * not contain reference to its source. Also for events of type
53  * {@link #TYPE_NOTIFICATION_STATE_CHANGED} the source is never available.
54  * </p>
55  * <p>
56  * This class represents various semantically different accessibility event
57  * types. Each event type has an associated set of related properties. In other
58  * words, each event type is characterized via a subset of the properties exposed
59  * by this class. For each event type there is a corresponding constant defined
60  * in this class. Follows a specification of the event types and their associated properties:
61  * </p>
62  * <div class="special reference">
63  * <h3>Developer Guides</h3>
64  * <p>For more information about creating and processing AccessibilityEvents, read the
65  * <a href="{@docRoot}guide/topics/ui/accessibility/index.html">Accessibility</a>
66  * developer guide.</p>
67  * </div>
68  * <p>
69  * <b>VIEW TYPES</b></br>
70  * </p>
71  * <p>
72  * <b>View clicked</b> - represents the event of clicking on a {@link android.view.View}
73  * like {@link android.widget.Button}, {@link android.widget.CompoundButton}, etc.</br>
74  * <em>Type:</em>{@link #TYPE_VIEW_CLICKED}</br>
75  * <em>Properties:</em></br>
76  * <ul>
77  *   <li>{@link #getEventType()} - The type of the event.</li>
78  *   <li>{@link #getSource()} - The source info (for registered clients).</li>
79  *   <li>{@link #getClassName()} - The class name of the source.</li>
80  *   <li>{@link #getPackageName()} - The package name of the source.</li>
81  *   <li>{@link #getEventTime()}  - The event time.</li>
82  *   <li>{@link #getText()} - The text of the source's sub-tree.</li>
83  *   <li>{@link #isEnabled()} - Whether the source is enabled.</li>
84  *   <li>{@link #isPassword()} - Whether the source is password.</li>
85  *   <li>{@link #isChecked()} - Whether the source is checked.</li>
86  *   <li>{@link #getContentDescription()} - The content description of the source.</li>
87  *   <li>{@link #getScrollX()} - The offset of the source left edge in pixels
88  *       (without descendants of AdapterView).</li>
89  *   <li>{@link #getScrollY()} - The offset of the source top edge in pixels
90  *       (without descendants of AdapterView).</li>
91  *   <li>{@link #getFromIndex()} - The zero based index of the first visible item of the source,
92  *       inclusive (for descendants of AdapterView).</li>
93  *   <li>{@link #getToIndex()} - The zero based index of the last visible item of the source,
94  *       inclusive (for descendants of AdapterView).</li>
95  *   <li>{@link #getItemCount()} - The total items of the source
96  *       (for descendants of AdapterView).</li>
97  * </ul>
98  * </p>
99  * <p>
100  * <b>View long clicked</b> - represents the event of long clicking on a {@link android.view.View}
101  * like {@link android.widget.Button}, {@link android.widget.CompoundButton}, etc </br>
102  * <em>Type:</em>{@link #TYPE_VIEW_LONG_CLICKED}</br>
103  * <em>Properties:</em></br>
104  * <ul>
105  *   <li>{@link #getEventType()} - The type of the event.</li>
106  *   <li>{@link #getSource()} - The source info (for registered clients).</li>
107  *   <li>{@link #getClassName()} - The class name of the source.</li>
108  *   <li>{@link #getPackageName()} - The package name of the source.</li>
109  *   <li>{@link #getEventTime()}  - The event time.</li>
110  *   <li>{@link #getText()} - The text of the source's sub-tree.</li>
111  *   <li>{@link #isEnabled()} - Whether the source is enabled.</li>
112  *   <li>{@link #isPassword()} - Whether the source is password.</li>
113  *   <li>{@link #isChecked()} - Whether the source is checked.</li>
114  *   <li>{@link #getContentDescription()} - The content description of the source.</li>
115  *   <li>{@link #getScrollX()} - The offset of the source left edge in pixels
116  *       (without descendants of AdapterView).</li>
117  *   <li>{@link #getScrollY()} - The offset of the source top edge in pixels
118  *       (without descendants of AdapterView).</li>
119  *   <li>{@link #getFromIndex()} - The zero based index of the first visible item of the source,
120  *       inclusive (for descendants of AdapterView).</li>
121  *   <li>{@link #getToIndex()} - The zero based index of the last visible item of the source,
122  *       inclusive (for descendants of AdapterView).</li>
123  *   <li>{@link #getItemCount()} - The total items of the source
124  *       (for descendants of AdapterView).</li>
125  * </ul>
126  * </p>
127  * <p>
128  * <b>View selected</b> - represents the event of selecting an item usually in
129  * the context of an {@link android.widget.AdapterView}.</br>
130  * <em>Type:</em> {@link #TYPE_VIEW_SELECTED}</br>
131  * <em>Properties:</em></br>
132  * <ul>
133  *   <li>{@link #getEventType()} - The type of the event.</li>
134  *   <li>{@link #getSource()} - The source info (for registered clients).</li>
135  *   <li>{@link #getClassName()} - The class name of the source.</li>
136  *   <li>{@link #getPackageName()} - The package name of the source.</li>
137  *   <li>{@link #getEventTime()}  - The event time.</li>
138  *   <li>{@link #getText()} - The text of the source's sub-tree.</li>
139  *   <li>{@link #isEnabled()} - Whether the source is enabled.</li>
140  *   <li>{@link #isPassword()} - Whether the source is password.</li>
141  *   <li>{@link #isChecked()} - Whether the source is checked.</li>
142  *   <li>{@link #getItemCount()} - The number of selectable items of the source.</li>
143  *   <li>{@link #getCurrentItemIndex()} - The currently selected item index.</li>
144  *   <li>{@link #getContentDescription()} - The content description of the source.</li>
145  *   <li>{@link #getScrollX()} - The offset of the source left edge in pixels
146  *       (without descendants of AdapterView).</li>
147  *   <li>{@link #getScrollY()} - The offset of the source top edge in pixels
148  *       (without descendants of AdapterView).</li>
149  *   <li>{@link #getFromIndex()} - The zero based index of the first visible item of the source,
150  *       inclusive (for descendants of AdapterView).</li>
151  *   <li>{@link #getToIndex()} - The zero based index of the last visible item of the source,
152  *       inclusive (for descendants of AdapterView).</li>
153  *   <li>{@link #getItemCount()} - The total items of the source
154  *       (for descendants of AdapterView).</li>
155  * </ul>
156  * </p>
157  * <p>
158  * <b>View focused</b> - represents the event of focusing a
159  * {@link android.view.View}.</br>
160  * <em>Type:</em> {@link #TYPE_VIEW_FOCUSED}</br>
161  * <em>Properties:</em></br>
162  * <ul>
163  *   <li>{@link #getEventType()} - The type of the event.</li>
164  *   <li>{@link #getSource()} - The source info (for registered clients).</li>
165  *   <li>{@link #getClassName()} - The class name of the source.</li>
166  *   <li>{@link #getPackageName()} - The package name of the source.</li>
167  *   <li>{@link #getEventTime()}  - The event time.</li>
168  *   <li>{@link #getText()} - The text of the source's sub-tree.</li>
169  *   <li>{@link #isEnabled()} - Whether the source is enabled.</li>
170  *   <li>{@link #isPassword()} - Whether the source is password.</li>
171  *   <li>{@link #isChecked()} - Whether the source is checked.</li>
172  *   <li>{@link #getItemCount()} - The number of focusable items on the screen.</li>
173  *   <li>{@link #getCurrentItemIndex()} - The currently focused item index.</li>
174  *   <li>{@link #getContentDescription()} - The content description of the source.</li>
175  *   <li>{@link #getScrollX()} - The offset of the source left edge in pixels
176  *       (without descendants of AdapterView).</li>
177  *   <li>{@link #getScrollY()} - The offset of the source top edge in pixels
178  *       (without descendants of AdapterView).</li>
179  *   <li>{@link #getFromIndex()} - The zero based index of the first visible item of the source,
180  *       inclusive (for descendants of AdapterView).</li>
181  *   <li>{@link #getToIndex()} - The zero based index of the last visible item of the source,
182  *       inclusive (for descendants of AdapterView).</li>
183  *   <li>{@link #getItemCount()} - The total items of the source
184  *       (for descendants of AdapterView).</li>
185  * </ul>
186  * </p>
187  * <p>
188  * <b>View text changed</b> - represents the event of changing the text of an
189  * {@link android.widget.EditText}.</br>
190  * <em>Type:</em> {@link #TYPE_VIEW_TEXT_CHANGED}</br>
191  * <em>Properties:</em></br>
192  * <ul>
193  *   <li>{@link #getEventType()} - The type of the event.</li>
194  *   <li>{@link #getSource()} - The source info (for registered clients).</li>
195  *   <li>{@link #getClassName()} - The class name of the source.</li>
196  *   <li>{@link #getPackageName()} - The package name of the source.</li>
197  *   <li>{@link #getEventTime()}  - The event time.</li>
198  *   <li>{@link #getText()} - The text of the source.</li>
199  *   <li>{@link #isEnabled()} - Whether the source is enabled.</li>
200  *   <li>{@link #isPassword()} - Whether the source is password.</li>
201  *   <li>{@link #isChecked()} - Whether the source is checked.</li>
202  *   <li>{@link #getFromIndex()} - The text change start index.</li>
203  *   <li>{@link #getAddedCount()} - The number of added characters.</li>
204  *   <li>{@link #getRemovedCount()} - The number of removed characters.</li>
205  *   <li>{@link #getBeforeText()} - The text of the source before the change.</li>
206  *   <li>{@link #getContentDescription()} - The content description of the source.</li>
207  * </ul>
208  * </p>
209  * <p>
210  * <b>View text selection changed</b> - represents the event of changing the text
211  * selection of an {@link android.widget.EditText}.</br>
212  * <em>Type:</em> {@link #TYPE_VIEW_TEXT_SELECTION_CHANGED} </br>
213  * <em>Properties:</em></br>
214  * <ul>
215  *   <li>{@link #getEventType()} - The type of the event.</li>
216  *   <li>{@link #getSource()} - The source info (for registered clients).</li>
217  *   <li>{@link #getClassName()} - The class name of the source.</li>
218  *   <li>{@link #getPackageName()} - The package name of the source.</li>
219  *   <li>{@link #getEventTime()}  - The event time.</li>
220  *   <li>{@link #getText()} - The text of the source.</li>
221  *   <li>{@link #isPassword()} - Whether the source is password.</li>
222  *   <li>{@link #getFromIndex()} - The selection start index.</li>
223  *   <li>{@link #getToIndex()} - The selection end index.</li>
224  *   <li>{@link #getItemCount()} - The length of the source text.</li>
225  *   <li>{@link #isEnabled()} - Whether the source is enabled.</li>
226  *   <li>{@link #getContentDescription()} - The content description of the source.</li>
227  * </ul>
228  * </p>
229  * <b>View text traversed at movement granularity</b> - represents the event of traversing the
230  * text of a view at a given granularity. For example, moving to the next word.</br>
231  * <em>Type:</em> {@link #TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY} </br>
232  * <em>Properties:</em></br>
233  * <ul>
234  *   <li>{@link #getEventType()} - The type of the event.</li>
235  *   <li>{@link #getSource()} - The source info (for registered clients).</li>
236  *   <li>{@link #getClassName()} - The class name of the source.</li>
237  *   <li>{@link #getPackageName()} - The package name of the source.</li>
238  *   <li>{@link #getEventTime()}  - The event time.</li>
239  *   <li>{@link #getMovementGranularity()} - Sets the granularity at which a view's text
240  *       was traversed.</li>
241  *   <li>{@link #getText()} -  The text of the source's sub-tree.</li>
242  *   <li>{@link #getFromIndex()} - The start of the next/previous text at the specified granularity
243  *           - inclusive.</li>
244  *   <li>{@link #getToIndex()} - The end of the next/previous text at the specified granularity
245  *           - exclusive.</li>
246  *   <li>{@link #isPassword()} - Whether the source is password.</li>
247  *   <li>{@link #isEnabled()} - Whether the source is enabled.</li>
248  *   <li>{@link #getContentDescription()} - The content description of the source.</li>
249  *   <li>{@link #getMovementGranularity()} - Sets the granularity at which a view's text
250  *       was traversed.</li>
251  *   <li>{@link #getAction()} - Gets traversal action which specifies the direction.</li>
252  * </ul>
253  * </p>
254  * <p>
255  * <b>View scrolled</b> - represents the event of scrolling a view. If
256  * the source is a descendant of {@link android.widget.AdapterView} the
257  * scroll is reported in terms of visible items - the first visible item,
258  * the last visible item, and the total items - because the the source
259  * is unaware of its pixel size since its adapter is responsible for
260  * creating views. In all other cases the scroll is reported as the current
261  * scroll on the X and Y axis respectively plus the height of the source in
262  * pixels.</br>
263  * <em>Type:</em> {@link #TYPE_VIEW_SCROLLED}</br>
264  * <em>Properties:</em></br>
265  * <ul>
266  *   <li>{@link #getEventType()} - The type of the event.</li>
267  *   <li>{@link #getSource()} - The source info (for registered clients).</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 #getText()} - The text of the source's sub-tree.</li>
272  *   <li>{@link #isEnabled()} - Whether the source is enabled.</li>
273  *   <li>{@link #getContentDescription()} - The content description of the source.</li>
274  *   <li>{@link #getScrollX()} - The offset of the source left edge in pixels
275  *       (without descendants of AdapterView).</li>
276  *   <li>{@link #getScrollY()} - The offset of the source top edge in pixels
277  *       (without descendants of AdapterView).</li>
278  *   <li>{@link #getFromIndex()} - The zero based index of the first visible item of the source,
279  *       inclusive (for descendants of AdapterView).</li>
280  *   <li>{@link #getToIndex()} - The zero based index of the last visible item of the source,
281  *       inclusive (for descendants of AdapterView).</li>
282  *   <li>{@link #getItemCount()} - The total items of the source
283  *       (for descendants of AdapterView).</li>
284  * </ul>
285  * <em>Note:</em> This event type is not dispatched to descendants though
286  * {@link android.view.View#dispatchPopulateAccessibilityEvent(AccessibilityEvent)
287  * View.dispatchPopulateAccessibilityEvent(AccessibilityEvent)}, hence the event
288  * source {@link android.view.View} and the sub-tree rooted at it will not receive
289  * calls to {@link android.view.View#onPopulateAccessibilityEvent(AccessibilityEvent)
290  * View.onPopulateAccessibilityEvent(AccessibilityEvent)}. The preferred way to add
291  * text content to such events is by setting the
292  * {@link android.R.styleable#View_contentDescription contentDescription} of the source
293  * view.</br>
294  * </p>
295  * <p>
296  * <b>TRANSITION TYPES</b></br>
297  * </p>
298  * <p>
299  * <b>Window state changed</b> - represents the event of opening a
300  * {@link android.widget.PopupWindow}, {@link android.view.Menu},
301  * {@link android.app.Dialog}, etc.</br>
302  * <em>Type:</em> {@link #TYPE_WINDOW_STATE_CHANGED}</br>
303  * <em>Properties:</em></br>
304  * <ul>
305  *   <li>{@link #getEventType()} - The type of the event.</li>
306  *   <li>{@link #getSource()} - The source info (for registered clients).</li>
307  *   <li>{@link #getClassName()} - The class name of the source.</li>
308  *   <li>{@link #getPackageName()} - The package name of the source.</li>
309  *   <li>{@link #getEventTime()}  - The event time.</li>
310  *   <li>{@link #getText()} - The text of the source's sub-tree.</li>
311  *   <li>{@link #isEnabled()} - Whether the source is enabled.</li>
312  * </ul>
313  * </p>
314  * <p>
315  * <b>Window content changed</b> - represents the event of change in the
316  * content of a window. This change can be adding/removing view, changing
317  * a view size, etc.</br>
318  * </p>
319  * <p>
320  * <strong>Note:</strong> This event is fired only for the window source of the
321  * last accessibility event different from {@link #TYPE_NOTIFICATION_STATE_CHANGED}
322  * and its purpose is to notify clients that the content of the user interaction
323  * window has changed.</br>
324  * <em>Type:</em> {@link #TYPE_WINDOW_CONTENT_CHANGED}</br>
325  * <em>Properties:</em></br>
326  * <ul>
327  *   <li>{@link #getEventType()} - The type of the event.</li>
328  *   <li>{@link #getSource()} - The source info (for registered clients).</li>
329  *   <li>{@link #getClassName()} - The class name of the source.</li>
330  *   <li>{@link #getPackageName()} - The package name of the source.</li>
331  *   <li>{@link #getEventTime()}  - The event time.</li>
332  * </ul>
333  * <em>Note:</em> This event type is not dispatched to descendants though
334  * {@link android.view.View#dispatchPopulateAccessibilityEvent(AccessibilityEvent)
335  * View.dispatchPopulateAccessibilityEvent(AccessibilityEvent)}, hence the event
336  * source {@link android.view.View} and the sub-tree rooted at it will not receive
337  * calls to {@link android.view.View#onPopulateAccessibilityEvent(AccessibilityEvent)
338  * View.onPopulateAccessibilityEvent(AccessibilityEvent)}. The preferred way to add
339  * text content to such events is by setting the
340  * {@link android.R.styleable#View_contentDescription contentDescription} of the source
341  * view.</br>
342  * </p>
343  * <p>
344  * <b>NOTIFICATION TYPES</b></br>
345  * </p>
346  * <p>
347  * <b>Notification state changed</b> - represents the event showing
348  * {@link android.app.Notification}.</br>
349  * <em>Type:</em> {@link #TYPE_NOTIFICATION_STATE_CHANGED}</br>
350  * <em>Properties:</em></br>
351  * <ul>
352  *   <li>{@link #getEventType()} - The type of the event.</li>
353  *   <li>{@link #getClassName()} - The class name of the source.</li>
354  *   <li>{@link #getPackageName()} - The package name of the source.</li>
355  *   <li>{@link #getEventTime()}  - The event time.</li>
356  *   <li>{@link #getText()} - The text of the source's sub-tree.</li>
357  *   <li>{@link #getParcelableData()} - The posted {@link android.app.Notification}.</li>
358  *   <li>{@link #getText()} - Text for providing more context.</li>
359  * </ul>
360  * <em>Note:</em> This event type is not dispatched to descendants though
361  * {@link android.view.View#dispatchPopulateAccessibilityEvent(AccessibilityEvent)
362  * View.dispatchPopulateAccessibilityEvent(AccessibilityEvent)}, hence the event
363  * source {@link android.view.View} and the sub-tree rooted at it will not receive
364  * calls to {@link android.view.View#onPopulateAccessibilityEvent(AccessibilityEvent)
365  * View.onPopulateAccessibilityEvent(AccessibilityEvent)}. The preferred way to add
366  * text content to such events is by setting the
367  * {@link android.R.styleable#View_contentDescription contentDescription} of the source
368  * view.</br>
369  * </p>
370  * <p>
371  * <b>EXPLORATION TYPES</b></br>
372  * </p>
373  * <p>
374  * <b>View hover enter</b> - represents the event of beginning to hover
375  * over a {@link android.view.View}. The hover may be generated via
376  * exploring the screen by touch or via a pointing device.</br>
377  * <em>Type:</em> {@link #TYPE_VIEW_HOVER_ENTER}</br>
378  * <em>Properties:</em></br>
379  * <ul>
380  *   <li>{@link #getEventType()} - The type of the event.</li>
381  *   <li>{@link #getSource()} - The source info (for registered clients).</li>
382  *   <li>{@link #getClassName()} - The class name of the source.</li>
383  *   <li>{@link #getPackageName()} - The package name of the source.</li>
384  *   <li>{@link #getEventTime()}  - The event time.</li>
385  *   <li>{@link #getText()} - The text of the source's sub-tree.</li>
386  *   <li>{@link #isEnabled()} - Whether the source is enabled.</li>
387  *   <li>{@link #getContentDescription()} - The content description of the source.</li>
388  *   <li>{@link #getScrollX()} - The offset of the source left edge in pixels
389  *       (without descendants of AdapterView).</li>
390  *   <li>{@link #getScrollY()} - The offset of the source top edge in pixels
391  *       (without descendants of AdapterView).</li>
392  *   <li>{@link #getFromIndex()} - The zero based index of the first visible item of the source,
393  *       inclusive (for descendants of AdapterView).</li>
394  *   <li>{@link #getToIndex()} - The zero based index of the last visible item of the source,
395  *       inclusive (for descendants of AdapterView).</li>
396  *   <li>{@link #getItemCount()} - The total items of the source
397  *       (for descendants of AdapterView).</li>
398  * </ul>
399  * </p>
400  * <b>View hover exit</b> - represents the event of stopping to hover
401  * over a {@link android.view.View}. The hover may be generated via
402  * exploring the screen by touch or via a pointing device.</br>
403  * <em>Type:</em> {@link #TYPE_VIEW_HOVER_EXIT}</br>
404  * <em>Properties:</em></br>
405  * <ul>
406  *   <li>{@link #getEventType()} - The type of the event.</li>
407  *   <li>{@link #getSource()} - The source info (for registered clients).</li>
408  *   <li>{@link #getClassName()} - The class name of the source.</li>
409  *   <li>{@link #getPackageName()} - The package name of the source.</li>
410  *   <li>{@link #getEventTime()}  - The event time.</li>
411  *   <li>{@link #getText()} - The text of the source's sub-tree.</li>
412  *   <li>{@link #isEnabled()} - Whether the source is enabled.</li>
413  *   <li>{@link #getContentDescription()} - The content description of the source.</li>
414  *   <li>{@link #getScrollX()} - The offset of the source left edge in pixels
415  *       (without descendants of AdapterView).</li>
416  *   <li>{@link #getScrollY()} - The offset of the source top edge in pixels
417  *       (without descendants of AdapterView).</li>
418  *   <li>{@link #getFromIndex()} - The zero based index of the first visible item of the source,
419  *       inclusive (for descendants of AdapterView).</li>
420  *   <li>{@link #getToIndex()} - The zero based index of the last visible item of the source,
421  *       inclusive (for descendants of AdapterView).</li>
422  *   <li>{@link #getItemCount()} - The total items of the source
423  *       (for descendants of AdapterView).</li>
424  * </ul>
425  * </p>
426  * <p>
427  * <b>Touch interaction start</b> - represents the event of starting a touch
428  * interaction, which is the user starts touching the screen.</br>
429  * <em>Type:</em> {@link #TYPE_TOUCH_INTERACTION_START}</br>
430  * <em>Properties:</em></br>
431  * <ul>
432  *   <li>{@link #getEventType()} - The type of the event.</li>
433  * </ul>
434  * <em>Note:</em> This event is fired only by the system and is not passed to the
435  * view tree to be populated.</br>
436  * </p>
437  * <p>
438  * <b>Touch interaction end</b> - represents the event of ending a touch
439  * interaction, which is the user stops touching the screen.</br>
440  * <em>Type:</em> {@link #TYPE_TOUCH_INTERACTION_END}</br>
441  * <em>Properties:</em></br>
442  * <ul>
443  *   <li>{@link #getEventType()} - The type of the event.</li>
444  * </ul>
445  * <em>Note:</em> This event is fired only by the system and is not passed to the
446  * view tree to be populated.</br>
447  * </p>
448  * <p>
449  * <b>Touch exploration gesture start</b> - represents the event of starting a touch
450  * exploring gesture.</br>
451  * <em>Type:</em> {@link #TYPE_TOUCH_EXPLORATION_GESTURE_START}</br>
452  * <em>Properties:</em></br>
453  * <ul>
454  *   <li>{@link #getEventType()} - The type of the event.</li>
455  * </ul>
456  * <em>Note:</em> This event is fired only by the system and is not passed to the
457  * view tree to be populated.</br>
458  * </p>
459  * <p>
460  * <b>Touch exploration gesture end</b> - represents the event of ending a touch
461  * exploring gesture.</br>
462  * <em>Type:</em> {@link #TYPE_TOUCH_EXPLORATION_GESTURE_END}</br>
463  * <em>Properties:</em></br>
464  * <ul>
465  *   <li>{@link #getEventType()} - The type of the event.</li>
466  * </ul>
467  * <em>Note:</em> This event is fired only by the system and is not passed to the
468  * view tree to be populated.</br>
469  * </p>
470  * <p>
471  * <b>Touch gesture detection start</b> - represents the event of starting a user
472  * gesture detection.</br>
473  * <em>Type:</em> {@link #TYPE_GESTURE_DETECTION_START}</br>
474  * <em>Properties:</em></br>
475  * <ul>
476  *   <li>{@link #getEventType()} - The type of the event.</li>
477  * </ul>
478  * <em>Note:</em> This event is fired only by the system and is not passed to the
479  * view tree to be populated.</br>
480  * </p>
481  * <p>
482  * <b>Touch gesture detection end</b> - represents the event of ending a user
483  * gesture detection.</br>
484  * <em>Type:</em> {@link #TYPE_GESTURE_DETECTION_END}</br>
485  * <em>Properties:</em></br>
486  * <ul>
487  *   <li>{@link #getEventType()} - The type of the event.</li>
488  * </ul>
489  * <em>Note:</em> This event is fired only by the system and is not passed to the
490  * view tree to be populated.</br>
491  * </p>
492  * <p>
493  * <b>MISCELLANEOUS TYPES</b></br>
494  * </p>
495  * <p>
496  * <b>Announcement</b> - represents the event of an application making an
497  * announcement. Usually this announcement is related to some sort of a context
498  * change for which none of the events representing UI transitions is a good fit.
499  * For example, announcing a new page in a book.</br>
500  * <em>Type:</em> {@link #TYPE_ANNOUNCEMENT}</br>
501  * <em>Properties:</em></br>
502  * <ul>
503  *   <li>{@link #getEventType()} - The type of the event.</li>
504  *   <li>{@link #getSource()} - The source info (for registered clients).</li>
505  *   <li>{@link #getClassName()} - The class name of the source.</li>
506  *   <li>{@link #getPackageName()} - The package name of the source.</li>
507  *   <li>{@link #getEventTime()}  - The event time.</li>
508  *   <li>{@link #getText()} - The text of the announcement.</li>
509  *   <li>{@link #isEnabled()} - Whether the source is enabled.</li>
510  * </ul>
511  * </p>
512  * <p>
513  * <b>Security note</b>
514  * <p>
515  * Since an event contains the text of its source privacy can be compromised by leaking
516  * sensitive information such as passwords. To address this issue any event fired in response
517  * to manipulation of a PASSWORD field does NOT CONTAIN the text of the password.
518  * </p>
519  *
520  * @see android.view.accessibility.AccessibilityManager
521  * @see android.accessibilityservice.AccessibilityService
522  * @see AccessibilityNodeInfo
523  */
524 public final class AccessibilityEvent extends AccessibilityRecord implements Parcelable {
525     private static final boolean DEBUG = false;
526 
527     /**
528      * Invalid selection/focus position.
529      *
530      * @see #getCurrentItemIndex()
531      */
532     public static final int INVALID_POSITION = -1;
533 
534     /**
535      * Maximum length of the text fields.
536      *
537      * @see #getBeforeText()
538      * @see #getText()
539      * </br>
540      * Note: This constant is no longer needed since there
541      *       is no limit on the length of text that is contained
542      *       in an accessibility event anymore.
543      */
544     @Deprecated
545     public static final int MAX_TEXT_LENGTH = 500;
546 
547     /**
548      * Represents the event of clicking on a {@link android.view.View} like
549      * {@link android.widget.Button}, {@link android.widget.CompoundButton}, etc.
550      */
551     public static final int TYPE_VIEW_CLICKED = 0x00000001;
552 
553     /**
554      * Represents the event of long clicking on a {@link android.view.View} like
555      * {@link android.widget.Button}, {@link android.widget.CompoundButton}, etc.
556      */
557     public static final int TYPE_VIEW_LONG_CLICKED = 0x00000002;
558 
559     /**
560      * Represents the event of selecting an item usually in the context of an
561      * {@link android.widget.AdapterView}.
562      */
563     public static final int TYPE_VIEW_SELECTED = 0x00000004;
564 
565     /**
566      * Represents the event of setting input focus of a {@link android.view.View}.
567      */
568     public static final int TYPE_VIEW_FOCUSED = 0x00000008;
569 
570     /**
571      * Represents the event of changing the text of an {@link android.widget.EditText}.
572      */
573     public static final int TYPE_VIEW_TEXT_CHANGED = 0x00000010;
574 
575     /**
576      * Represents the event of opening a {@link android.widget.PopupWindow},
577      * {@link android.view.Menu}, {@link android.app.Dialog}, etc.
578      */
579     public static final int TYPE_WINDOW_STATE_CHANGED = 0x00000020;
580 
581     /**
582      * Represents the event showing a {@link android.app.Notification}.
583      */
584     public static final int TYPE_NOTIFICATION_STATE_CHANGED = 0x00000040;
585 
586     /**
587      * Represents the event of a hover enter over a {@link android.view.View}.
588      */
589     public static final int TYPE_VIEW_HOVER_ENTER = 0x00000080;
590 
591     /**
592      * Represents the event of a hover exit over a {@link android.view.View}.
593      */
594     public static final int TYPE_VIEW_HOVER_EXIT = 0x00000100;
595 
596     /**
597      * Represents the event of starting a touch exploration gesture.
598      */
599     public static final int TYPE_TOUCH_EXPLORATION_GESTURE_START = 0x00000200;
600 
601     /**
602      * Represents the event of ending a touch exploration gesture.
603      */
604     public static final int TYPE_TOUCH_EXPLORATION_GESTURE_END = 0x00000400;
605 
606     /**
607      * Represents the event of changing the content of a window and more
608      * specifically the sub-tree rooted at the event's source.
609      */
610     public static final int TYPE_WINDOW_CONTENT_CHANGED = 0x00000800;
611 
612     /**
613      * Represents the event of scrolling a view.
614      */
615     public static final int TYPE_VIEW_SCROLLED = 0x00001000;
616 
617     /**
618      * Represents the event of changing the selection in an {@link android.widget.EditText}.
619      */
620     public static final int TYPE_VIEW_TEXT_SELECTION_CHANGED = 0x00002000;
621 
622     /**
623      * Represents the event of an application making an announcement.
624      */
625     public static final int TYPE_ANNOUNCEMENT = 0x00004000;
626 
627     /**
628      * Represents the event of gaining accessibility focus.
629      */
630     public static final int TYPE_VIEW_ACCESSIBILITY_FOCUSED = 0x00008000;
631 
632     /**
633      * Represents the event of clearing accessibility focus.
634      */
635     public static final int TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED = 0x00010000;
636 
637     /**
638      * Represents the event of traversing the text of a view at a given movement granularity.
639      */
640     public static final int TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY = 0x00020000;
641 
642     /**
643      * Represents the event of beginning gesture detection.
644      */
645     public static final int TYPE_GESTURE_DETECTION_START = 0x00040000;
646 
647     /**
648      * Represents the event of ending gesture detection.
649      */
650     public static final int TYPE_GESTURE_DETECTION_END = 0x00080000;
651 
652     /**
653      * Represents the event of the user starting to touch the screen.
654      */
655     public static final int TYPE_TOUCH_INTERACTION_START = 0x00100000;
656 
657     /**
658      * Represents the event of the user ending to touch the screen.
659      */
660     public static final int TYPE_TOUCH_INTERACTION_END = 0x00200000;
661 
662     /**
663      * Mask for {@link AccessibilityEvent} all types.
664      *
665      * @see #TYPE_VIEW_CLICKED
666      * @see #TYPE_VIEW_LONG_CLICKED
667      * @see #TYPE_VIEW_SELECTED
668      * @see #TYPE_VIEW_FOCUSED
669      * @see #TYPE_VIEW_TEXT_CHANGED
670      * @see #TYPE_WINDOW_STATE_CHANGED
671      * @see #TYPE_NOTIFICATION_STATE_CHANGED
672      * @see #TYPE_VIEW_HOVER_ENTER
673      * @see #TYPE_VIEW_HOVER_EXIT
674      * @see #TYPE_TOUCH_EXPLORATION_GESTURE_START
675      * @see #TYPE_TOUCH_EXPLORATION_GESTURE_END
676      * @see #TYPE_WINDOW_CONTENT_CHANGED
677      * @see #TYPE_VIEW_SCROLLED
678      * @see #TYPE_VIEW_TEXT_SELECTION_CHANGED
679      * @see #TYPE_ANNOUNCEMENT
680      * @see #TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
681      * @see #TYPE_GESTURE_DETECTION_START
682      * @see #TYPE_GESTURE_DETECTION_END
683      * @see #TYPE_TOUCH_INTERACTION_START
684      * @see #TYPE_TOUCH_INTERACTION_END
685      */
686     public static final int TYPES_ALL_MASK = 0xFFFFFFFF;
687 
688     private static final int MAX_POOL_SIZE = 10;
689     private static final Object sPoolLock = new Object();
690     private static AccessibilityEvent sPool;
691     private static int sPoolSize;
692     private AccessibilityEvent mNext;
693     private boolean mIsInPool;
694 
695     private int mEventType;
696     private CharSequence mPackageName;
697     private long mEventTime;
698     int mMovementGranularity;
699     int mAction;
700 
701     private final ArrayList<AccessibilityRecord> mRecords = new ArrayList<AccessibilityRecord>();
702 
703     /*
704      * Hide constructor from clients.
705      */
AccessibilityEvent()706     private AccessibilityEvent() {
707     }
708 
709     /**
710      * Initialize an event from another one.
711      *
712      * @param event The event to initialize from.
713      */
init(AccessibilityEvent event)714     void init(AccessibilityEvent event) {
715         super.init(event);
716         mEventType = event.mEventType;
717         mMovementGranularity = event.mMovementGranularity;
718         mAction = event.mAction;
719         mEventTime = event.mEventTime;
720         mPackageName = event.mPackageName;
721     }
722 
723     /**
724      * Sets if this instance is sealed.
725      *
726      * @param sealed Whether is sealed.
727      *
728      * @hide
729      */
730     @Override
setSealed(boolean sealed)731     public void setSealed(boolean sealed) {
732         super.setSealed(sealed);
733         List<AccessibilityRecord> records = mRecords;
734         final int recordCount = records.size();
735         for (int i = 0; i < recordCount; i++) {
736             AccessibilityRecord record = records.get(i);
737             record.setSealed(sealed);
738         }
739     }
740 
741     /**
742      * Gets the number of records contained in the event.
743      *
744      * @return The number of records.
745      */
getRecordCount()746     public int getRecordCount() {
747         return mRecords.size();
748     }
749 
750     /**
751      * Appends an {@link AccessibilityRecord} to the end of event records.
752      *
753      * @param record The record to append.
754      *
755      * @throws IllegalStateException If called from an AccessibilityService.
756      */
appendRecord(AccessibilityRecord record)757     public void appendRecord(AccessibilityRecord record) {
758         enforceNotSealed();
759         mRecords.add(record);
760     }
761 
762     /**
763      * Gets the record at a given index.
764      *
765      * @param index The index.
766      * @return The record at the specified index.
767      */
getRecord(int index)768     public AccessibilityRecord getRecord(int index) {
769         return mRecords.get(index);
770     }
771 
772     /**
773      * Gets the event type.
774      *
775      * @return The event type.
776      */
getEventType()777     public int getEventType() {
778         return mEventType;
779     }
780 
781     /**
782      * Sets the event type.
783      *
784      * @param eventType The event type.
785      *
786      * @throws IllegalStateException If called from an AccessibilityService.
787      */
setEventType(int eventType)788     public void setEventType(int eventType) {
789         enforceNotSealed();
790         mEventType = eventType;
791     }
792 
793     /**
794      * Gets the time in which this event was sent.
795      *
796      * @return The event time.
797      */
getEventTime()798     public long getEventTime() {
799         return mEventTime;
800     }
801 
802     /**
803      * Sets the time in which this event was sent.
804      *
805      * @param eventTime The event time.
806      *
807      * @throws IllegalStateException If called from an AccessibilityService.
808      */
setEventTime(long eventTime)809     public void setEventTime(long eventTime) {
810         enforceNotSealed();
811         mEventTime = eventTime;
812     }
813 
814     /**
815      * Gets the package name of the source.
816      *
817      * @return The package name.
818      */
getPackageName()819     public CharSequence getPackageName() {
820         return mPackageName;
821     }
822 
823     /**
824      * Sets the package name of the source.
825      *
826      * @param packageName The package name.
827      *
828      * @throws IllegalStateException If called from an AccessibilityService.
829      */
setPackageName(CharSequence packageName)830     public void setPackageName(CharSequence packageName) {
831         enforceNotSealed();
832         mPackageName = packageName;
833     }
834 
835     /**
836      * Sets the movement granularity that was traversed.
837      *
838      * @param granularity The granularity.
839      *
840      * @throws IllegalStateException If called from an AccessibilityService.
841      */
setMovementGranularity(int granularity)842     public void setMovementGranularity(int granularity) {
843         enforceNotSealed();
844         mMovementGranularity = granularity;
845     }
846 
847     /**
848      * Gets the movement granularity that was traversed.
849      *
850      * @return The granularity.
851      */
getMovementGranularity()852     public int getMovementGranularity() {
853         return mMovementGranularity;
854     }
855 
856     /**
857      * Sets the performed action that triggered this event.
858      *
859      * @param action The action.
860      *
861      * @throws IllegalStateException If called from an AccessibilityService.
862      */
setAction(int action)863     public void setAction(int action) {
864         enforceNotSealed();
865         mAction = action;
866     }
867 
868     /**
869      * Gets the performed action that triggered this event.
870      *
871      * @return The action.
872      */
getAction()873     public int getAction() {
874         return mAction;
875     }
876 
877     /**
878      * Returns a cached instance if such is available or a new one is
879      * instantiated with its type property set.
880      *
881      * @param eventType The event type.
882      * @return An instance.
883      */
obtain(int eventType)884     public static AccessibilityEvent obtain(int eventType) {
885         AccessibilityEvent event = AccessibilityEvent.obtain();
886         event.setEventType(eventType);
887         return event;
888     }
889 
890     /**
891      * Returns a cached instance if such is available or a new one is
892      * created. The returned instance is initialized from the given
893      * <code>event</code>.
894      *
895      * @param event The other event.
896      * @return An instance.
897      */
obtain(AccessibilityEvent event)898     public static AccessibilityEvent obtain(AccessibilityEvent event) {
899         AccessibilityEvent eventClone = AccessibilityEvent.obtain();
900         eventClone.init(event);
901 
902         final int recordCount = event.mRecords.size();
903         for (int i = 0; i < recordCount; i++) {
904             AccessibilityRecord record = event.mRecords.get(i);
905             AccessibilityRecord recordClone = AccessibilityRecord.obtain(record);
906             eventClone.mRecords.add(recordClone);
907         }
908 
909         return eventClone;
910     }
911 
912     /**
913      * Returns a cached instance if such is available or a new one is
914      * instantiated.
915      *
916      * @return An instance.
917      */
obtain()918     public static AccessibilityEvent obtain() {
919         synchronized (sPoolLock) {
920             if (sPool != null) {
921                 AccessibilityEvent event = sPool;
922                 sPool = sPool.mNext;
923                 sPoolSize--;
924                 event.mNext = null;
925                 event.mIsInPool = false;
926                 return event;
927             }
928             return new AccessibilityEvent();
929         }
930     }
931 
932     /**
933      * Recycles an instance back to be reused.
934      * <p>
935      *   <b>Note: You must not touch the object after calling this function.</b>
936      * </p>
937      *
938      * @throws IllegalStateException If the event is already recycled.
939      */
940     @Override
recycle()941     public void recycle() {
942         if (mIsInPool) {
943             throw new IllegalStateException("Event already recycled!");
944         }
945         clear();
946         synchronized (sPoolLock) {
947             if (sPoolSize <= MAX_POOL_SIZE) {
948                 mNext = sPool;
949                 sPool = this;
950                 mIsInPool = true;
951                 sPoolSize++;
952             }
953         }
954     }
955 
956     /**
957      * Clears the state of this instance.
958      *
959      * @hide
960      */
961     @Override
clear()962     protected void clear() {
963         super.clear();
964         mEventType = 0;
965         mMovementGranularity = 0;
966         mAction = 0;
967         mPackageName = null;
968         mEventTime = 0;
969         while (!mRecords.isEmpty()) {
970             AccessibilityRecord record = mRecords.remove(0);
971             record.recycle();
972         }
973     }
974 
975     /**
976      * Creates a new instance from a {@link Parcel}.
977      *
978      * @param parcel A parcel containing the state of a {@link AccessibilityEvent}.
979      */
initFromParcel(Parcel parcel)980     public void initFromParcel(Parcel parcel) {
981         mSealed = (parcel.readInt() == 1);
982         mEventType = parcel.readInt();
983         mMovementGranularity = parcel.readInt();
984         mAction = parcel.readInt();
985         mPackageName = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(parcel);
986         mEventTime = parcel.readLong();
987         mConnectionId = parcel.readInt();
988         readAccessibilityRecordFromParcel(this, parcel);
989 
990         // Read the records.
991         final int recordCount = parcel.readInt();
992         for (int i = 0; i < recordCount; i++) {
993             AccessibilityRecord record = AccessibilityRecord.obtain();
994             readAccessibilityRecordFromParcel(record, parcel);
995             record.mConnectionId = mConnectionId;
996             mRecords.add(record);
997         }
998     }
999 
1000     /**
1001      * Reads an {@link AccessibilityRecord} from a parcel.
1002      *
1003      * @param record The record to initialize.
1004      * @param parcel The parcel to read from.
1005      */
readAccessibilityRecordFromParcel(AccessibilityRecord record, Parcel parcel)1006     private void readAccessibilityRecordFromParcel(AccessibilityRecord record,
1007             Parcel parcel) {
1008         record.mBooleanProperties = parcel.readInt();
1009         record.mCurrentItemIndex = parcel.readInt();
1010         record.mItemCount = parcel.readInt();
1011         record.mFromIndex = parcel.readInt();
1012         record.mToIndex = parcel.readInt();
1013         record.mScrollX = parcel.readInt();
1014         record.mScrollY =  parcel.readInt();
1015         record.mMaxScrollX = parcel.readInt();
1016         record.mMaxScrollY =  parcel.readInt();
1017         record.mAddedCount = parcel.readInt();
1018         record.mRemovedCount = parcel.readInt();
1019         record.mClassName = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(parcel);
1020         record.mContentDescription = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(parcel);
1021         record.mBeforeText = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(parcel);
1022         record.mParcelableData = parcel.readParcelable(null);
1023         parcel.readList(record.mText, null);
1024         record.mSourceWindowId = parcel.readInt();
1025         record.mSourceNodeId = parcel.readLong();
1026         record.mSealed = (parcel.readInt() == 1);
1027     }
1028 
1029     /**
1030      * {@inheritDoc}
1031      */
writeToParcel(Parcel parcel, int flags)1032     public void writeToParcel(Parcel parcel, int flags) {
1033         parcel.writeInt(isSealed() ? 1 : 0);
1034         parcel.writeInt(mEventType);
1035         parcel.writeInt(mMovementGranularity);
1036         parcel.writeInt(mAction);
1037         TextUtils.writeToParcel(mPackageName, parcel, 0);
1038         parcel.writeLong(mEventTime);
1039         parcel.writeInt(mConnectionId);
1040         writeAccessibilityRecordToParcel(this, parcel, flags);
1041 
1042         // Write the records.
1043         final int recordCount = getRecordCount();
1044         parcel.writeInt(recordCount);
1045         for (int i = 0; i < recordCount; i++) {
1046             AccessibilityRecord record = mRecords.get(i);
1047             writeAccessibilityRecordToParcel(record, parcel, flags);
1048         }
1049     }
1050 
1051     /**
1052      * Writes an {@link AccessibilityRecord} to a parcel.
1053      *
1054      * @param record The record to write.
1055      * @param parcel The parcel to which to write.
1056      */
writeAccessibilityRecordToParcel(AccessibilityRecord record, Parcel parcel, int flags)1057     private void writeAccessibilityRecordToParcel(AccessibilityRecord record, Parcel parcel,
1058             int flags) {
1059         parcel.writeInt(record.mBooleanProperties);
1060         parcel.writeInt(record.mCurrentItemIndex);
1061         parcel.writeInt(record.mItemCount);
1062         parcel.writeInt(record.mFromIndex);
1063         parcel.writeInt(record.mToIndex);
1064         parcel.writeInt(record.mScrollX);
1065         parcel.writeInt(record.mScrollY);
1066         parcel.writeInt(record.mMaxScrollX);
1067         parcel.writeInt(record.mMaxScrollY);
1068         parcel.writeInt(record.mAddedCount);
1069         parcel.writeInt(record.mRemovedCount);
1070         TextUtils.writeToParcel(record.mClassName, parcel, flags);
1071         TextUtils.writeToParcel(record.mContentDescription, parcel, flags);
1072         TextUtils.writeToParcel(record.mBeforeText, parcel, flags);
1073         parcel.writeParcelable(record.mParcelableData, flags);
1074         parcel.writeList(record.mText);
1075         parcel.writeInt(record.mSourceWindowId);
1076         parcel.writeLong(record.mSourceNodeId);
1077         parcel.writeInt(record.mSealed ? 1 : 0);
1078     }
1079 
1080     /**
1081      * {@inheritDoc}
1082      */
describeContents()1083     public int describeContents() {
1084         return 0;
1085     }
1086 
1087     @Override
toString()1088     public String toString() {
1089         StringBuilder builder = new StringBuilder();
1090         builder.append("EventType: ").append(eventTypeToString(mEventType));
1091         builder.append("; EventTime: ").append(mEventTime);
1092         builder.append("; PackageName: ").append(mPackageName);
1093         builder.append("; MovementGranularity: ").append(mMovementGranularity);
1094         builder.append("; Action: ").append(mAction);
1095         builder.append(super.toString());
1096         if (DEBUG) {
1097             builder.append("\n");
1098             builder.append("; sourceWindowId: ").append(mSourceWindowId);
1099             builder.append("; mSourceNodeId: ").append(mSourceNodeId);
1100             for (int i = 0; i < mRecords.size(); i++) {
1101                 AccessibilityRecord record = mRecords.get(i);
1102                 builder.append("  Record ");
1103                 builder.append(i);
1104                 builder.append(":");
1105                 builder.append(" [ ClassName: " + record.mClassName);
1106                 builder.append("; Text: " + record.mText);
1107                 builder.append("; ContentDescription: " + record.mContentDescription);
1108                 builder.append("; ItemCount: " + record.mItemCount);
1109                 builder.append("; CurrentItemIndex: " + record.mCurrentItemIndex);
1110                 builder.append("; IsEnabled: " + record.isEnabled());
1111                 builder.append("; IsPassword: " + record.isPassword());
1112                 builder.append("; IsChecked: " + record.isChecked());
1113                 builder.append("; IsFullScreen: " + record.isFullScreen());
1114                 builder.append("; Scrollable: " + record.isScrollable());
1115                 builder.append("; BeforeText: " + record.mBeforeText);
1116                 builder.append("; FromIndex: " + record.mFromIndex);
1117                 builder.append("; ToIndex: " + record.mToIndex);
1118                 builder.append("; ScrollX: " + record.mScrollX);
1119                 builder.append("; ScrollY: " + record.mScrollY);
1120                 builder.append("; AddedCount: " + record.mAddedCount);
1121                 builder.append("; RemovedCount: " + record.mRemovedCount);
1122                 builder.append("; ParcelableData: " + record.mParcelableData);
1123                 builder.append(" ]");
1124                 builder.append("\n");
1125             }
1126         } else {
1127             builder.append("; recordCount: ").append(getRecordCount());
1128         }
1129         return builder.toString();
1130     }
1131 
1132     /**
1133      * Returns the string representation of an event type. For example,
1134      * {@link #TYPE_VIEW_CLICKED} is represented by the string TYPE_VIEW_CLICKED.
1135      *
1136      * @param eventType The event type
1137      * @return The string representation.
1138      */
eventTypeToString(int eventType)1139     public static String eventTypeToString(int eventType) {
1140         switch (eventType) {
1141             case TYPE_VIEW_CLICKED:
1142                 return "TYPE_VIEW_CLICKED";
1143             case TYPE_VIEW_LONG_CLICKED:
1144                 return "TYPE_VIEW_LONG_CLICKED";
1145             case TYPE_VIEW_SELECTED:
1146                 return "TYPE_VIEW_SELECTED";
1147             case TYPE_VIEW_FOCUSED:
1148                 return "TYPE_VIEW_FOCUSED";
1149             case TYPE_VIEW_TEXT_CHANGED:
1150                 return "TYPE_VIEW_TEXT_CHANGED";
1151             case TYPE_WINDOW_STATE_CHANGED:
1152                 return "TYPE_WINDOW_STATE_CHANGED";
1153             case TYPE_VIEW_HOVER_ENTER:
1154                 return "TYPE_VIEW_HOVER_ENTER";
1155             case TYPE_VIEW_HOVER_EXIT:
1156                 return "TYPE_VIEW_HOVER_EXIT";
1157             case TYPE_NOTIFICATION_STATE_CHANGED:
1158                 return "TYPE_NOTIFICATION_STATE_CHANGED";
1159             case TYPE_TOUCH_EXPLORATION_GESTURE_START:
1160                 return "TYPE_TOUCH_EXPLORATION_GESTURE_START";
1161             case TYPE_TOUCH_EXPLORATION_GESTURE_END:
1162                 return "TYPE_TOUCH_EXPLORATION_GESTURE_END";
1163             case TYPE_WINDOW_CONTENT_CHANGED:
1164                 return "TYPE_WINDOW_CONTENT_CHANGED";
1165             case TYPE_VIEW_TEXT_SELECTION_CHANGED:
1166                 return "TYPE_VIEW_TEXT_SELECTION_CHANGED";
1167             case TYPE_VIEW_SCROLLED:
1168                 return "TYPE_VIEW_SCROLLED";
1169             case TYPE_ANNOUNCEMENT:
1170                 return "TYPE_ANNOUNCEMENT";
1171             case TYPE_VIEW_ACCESSIBILITY_FOCUSED:
1172                 return "TYPE_VIEW_ACCESSIBILITY_FOCUSED";
1173             case TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED:
1174                 return "TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED";
1175             case TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY:
1176                 return "TYPE_CURRENT_AT_GRANULARITY_MOVEMENT_CHANGED";
1177             case TYPE_GESTURE_DETECTION_START:
1178                 return "TYPE_GESTURE_DETECTION_START";
1179             case TYPE_GESTURE_DETECTION_END:
1180                 return "TYPE_GESTURE_DETECTION_END";
1181             case TYPE_TOUCH_INTERACTION_START:
1182                 return "TYPE_TOUCH_INTERACTION_START";
1183             case TYPE_TOUCH_INTERACTION_END:
1184                 return "TYPE_TOUCH_INTERACTION_END";
1185             default:
1186                 return null;
1187         }
1188     }
1189 
1190     /**
1191      * @see Parcelable.Creator
1192      */
1193     public static final Parcelable.Creator<AccessibilityEvent> CREATOR =
1194             new Parcelable.Creator<AccessibilityEvent>() {
1195         public AccessibilityEvent createFromParcel(Parcel parcel) {
1196             AccessibilityEvent event = AccessibilityEvent.obtain();
1197             event.initFromParcel(parcel);
1198             return event;
1199         }
1200 
1201         public AccessibilityEvent[] newArray(int size) {
1202             return new AccessibilityEvent[size];
1203         }
1204     };
1205 }
1206