• 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 exploration gesture start</b> - represents the event of starting a touch
428  * exploring gesture.</br>
429  * <em>Type:</em> {@link #TYPE_TOUCH_EXPLORATION_GESTURE_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 type is not dispatched to descendants though
435  * {@link android.view.View#dispatchPopulateAccessibilityEvent(AccessibilityEvent)
436  * View.dispatchPopulateAccessibilityEvent(AccessibilityEvent)}, hence the event
437  * source {@link android.view.View} and the sub-tree rooted at it will not receive
438  * calls to {@link android.view.View#onPopulateAccessibilityEvent(AccessibilityEvent)
439  * View.onPopulateAccessibilityEvent(AccessibilityEvent)}. The preferred way to add
440  * text content to such events is by setting the
441  * {@link android.R.styleable#View_contentDescription contentDescription} of the source
442  * view.</br>
443  * </p>
444  * <p>
445  * <b>Touch exploration gesture end</b> - represents the event of ending a touch
446  * exploring gesture.</br>
447  * <em>Type:</em> {@link #TYPE_TOUCH_EXPLORATION_GESTURE_END}</br>
448  * <em>Properties:</em></br>
449  * <ul>
450  *   <li>{@link #getEventType()} - The type of the event.</li>
451  * </ul>
452  * <em>Note:</em> This event type is not dispatched to descendants though
453  * {@link android.view.View#dispatchPopulateAccessibilityEvent(AccessibilityEvent)
454  * View.dispatchPopulateAccessibilityEvent(AccessibilityEvent)}, hence the event
455  * source {@link android.view.View} and the sub-tree rooted at it will not receive
456  * calls to {@link android.view.View#onPopulateAccessibilityEvent(AccessibilityEvent)
457  * View.onPopulateAccessibilityEvent(AccessibilityEvent)}. The preferred way to add
458  * text content to such events is by setting the
459  * {@link android.R.styleable#View_contentDescription contentDescription} of the source
460  * view.</br>
461  * </p>
462  * <p>
463  * <b>MISCELLANEOUS TYPES</b></br>
464  * </p>
465  * <p>
466  * <b>Announcement</b> - represents the event of an application making an
467  * announcement. Usually this announcement is related to some sort of a context
468  * change for which none of the events representing UI transitions is a good fit.
469  * For example, announcing a new page in a book.</br>
470  * <em>Type:</em> {@link #TYPE_ANNOUNCEMENT}</br>
471  * <em>Properties:</em></br>
472  * <ul>
473  *   <li>{@link #getEventType()} - The type of the event.</li>
474  *   <li>{@link #getSource()} - The source info (for registered clients).</li>
475  *   <li>{@link #getClassName()} - The class name of the source.</li>
476  *   <li>{@link #getPackageName()} - The package name of the source.</li>
477  *   <li>{@link #getEventTime()}  - The event time.</li>
478  *   <li>{@link #getText()} - The text of the announcement.</li>
479  *   <li>{@link #isEnabled()} - Whether the source is enabled.</li>
480  * </ul>
481  * </p>
482  * <p>
483  * <b>Security note</b>
484  * <p>
485  * Since an event contains the text of its source privacy can be compromised by leaking
486  * sensitive information such as passwords. To address this issue any event fired in response
487  * to manipulation of a PASSWORD field does NOT CONTAIN the text of the password.
488  * </p>
489  *
490  * @see android.view.accessibility.AccessibilityManager
491  * @see android.accessibilityservice.AccessibilityService
492  * @see AccessibilityNodeInfo
493  */
494 public final class AccessibilityEvent extends AccessibilityRecord implements Parcelable {
495     private static final boolean DEBUG = false;
496 
497     /**
498      * Invalid selection/focus position.
499      *
500      * @see #getCurrentItemIndex()
501      */
502     public static final int INVALID_POSITION = -1;
503 
504     /**
505      * Maximum length of the text fields.
506      *
507      * @see #getBeforeText()
508      * @see #getText()
509      * </br>
510      * Note: This constant is no longer needed since there
511      *       is no limit on the length of text that is contained
512      *       in an accessibility event anymore.
513      */
514     @Deprecated
515     public static final int MAX_TEXT_LENGTH = 500;
516 
517     /**
518      * Represents the event of clicking on a {@link android.view.View} like
519      * {@link android.widget.Button}, {@link android.widget.CompoundButton}, etc.
520      */
521     public static final int TYPE_VIEW_CLICKED = 0x00000001;
522 
523     /**
524      * Represents the event of long clicking on a {@link android.view.View} like
525      * {@link android.widget.Button}, {@link android.widget.CompoundButton}, etc.
526      */
527     public static final int TYPE_VIEW_LONG_CLICKED = 0x00000002;
528 
529     /**
530      * Represents the event of selecting an item usually in the context of an
531      * {@link android.widget.AdapterView}.
532      */
533     public static final int TYPE_VIEW_SELECTED = 0x00000004;
534 
535     /**
536      * Represents the event of setting input focus of a {@link android.view.View}.
537      */
538     public static final int TYPE_VIEW_FOCUSED = 0x00000008;
539 
540     /**
541      * Represents the event of changing the text of an {@link android.widget.EditText}.
542      */
543     public static final int TYPE_VIEW_TEXT_CHANGED = 0x00000010;
544 
545     /**
546      * Represents the event of opening a {@link android.widget.PopupWindow},
547      * {@link android.view.Menu}, {@link android.app.Dialog}, etc.
548      */
549     public static final int TYPE_WINDOW_STATE_CHANGED = 0x00000020;
550 
551     /**
552      * Represents the event showing a {@link android.app.Notification}.
553      */
554     public static final int TYPE_NOTIFICATION_STATE_CHANGED = 0x00000040;
555 
556     /**
557      * Represents the event of a hover enter over a {@link android.view.View}.
558      */
559     public static final int TYPE_VIEW_HOVER_ENTER = 0x00000080;
560 
561     /**
562      * Represents the event of a hover exit over a {@link android.view.View}.
563      */
564     public static final int TYPE_VIEW_HOVER_EXIT = 0x00000100;
565 
566     /**
567      * Represents the event of starting a touch exploration gesture.
568      */
569     public static final int TYPE_TOUCH_EXPLORATION_GESTURE_START = 0x00000200;
570 
571     /**
572      * Represents the event of ending a touch exploration gesture.
573      */
574     public static final int TYPE_TOUCH_EXPLORATION_GESTURE_END = 0x00000400;
575 
576     /**
577      * Represents the event of changing the content of a window and more
578      * specifically the sub-tree rooted at the event's source.
579      */
580     public static final int TYPE_WINDOW_CONTENT_CHANGED = 0x00000800;
581 
582     /**
583      * Represents the event of scrolling a view.
584      */
585     public static final int TYPE_VIEW_SCROLLED = 0x00001000;
586 
587     /**
588      * Represents the event of changing the selection in an {@link android.widget.EditText}.
589      */
590     public static final int TYPE_VIEW_TEXT_SELECTION_CHANGED = 0x00002000;
591 
592     /**
593      * Represents the event of an application making an announcement.
594      */
595     public static final int TYPE_ANNOUNCEMENT = 0x00004000;
596 
597     /**
598      * Represents the event of gaining accessibility focus.
599      */
600     public static final int TYPE_VIEW_ACCESSIBILITY_FOCUSED = 0x00008000;
601 
602     /**
603      * Represents the event of clearing accessibility focus.
604      */
605     public static final int TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED = 0x00010000;
606 
607     /**
608      * Represents the event of traversing the text of a view at a given movement granularity.
609      */
610     public static final int TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY = 0x00020000;
611 
612     /**
613      * Mask for {@link AccessibilityEvent} all types.
614      *
615      * @see #TYPE_VIEW_CLICKED
616      * @see #TYPE_VIEW_LONG_CLICKED
617      * @see #TYPE_VIEW_SELECTED
618      * @see #TYPE_VIEW_FOCUSED
619      * @see #TYPE_VIEW_TEXT_CHANGED
620      * @see #TYPE_WINDOW_STATE_CHANGED
621      * @see #TYPE_NOTIFICATION_STATE_CHANGED
622      * @see #TYPE_VIEW_HOVER_ENTER
623      * @see #TYPE_VIEW_HOVER_EXIT
624      * @see #TYPE_TOUCH_EXPLORATION_GESTURE_START
625      * @see #TYPE_TOUCH_EXPLORATION_GESTURE_END
626      * @see #TYPE_WINDOW_CONTENT_CHANGED
627      * @see #TYPE_VIEW_SCROLLED
628      * @see #TYPE_VIEW_TEXT_SELECTION_CHANGED
629      * @see #TYPE_ANNOUNCEMENT
630      * @see #TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
631      */
632     public static final int TYPES_ALL_MASK = 0xFFFFFFFF;
633 
634     private static final int MAX_POOL_SIZE = 10;
635     private static final Object sPoolLock = new Object();
636     private static AccessibilityEvent sPool;
637     private static int sPoolSize;
638     private AccessibilityEvent mNext;
639     private boolean mIsInPool;
640 
641     private int mEventType;
642     private CharSequence mPackageName;
643     private long mEventTime;
644     int mMovementGranularity;
645     int mAction;
646 
647     private final ArrayList<AccessibilityRecord> mRecords = new ArrayList<AccessibilityRecord>();
648 
649     /*
650      * Hide constructor from clients.
651      */
AccessibilityEvent()652     private AccessibilityEvent() {
653     }
654 
655     /**
656      * Initialize an event from another one.
657      *
658      * @param event The event to initialize from.
659      */
init(AccessibilityEvent event)660     void init(AccessibilityEvent event) {
661         super.init(event);
662         mEventType = event.mEventType;
663         mMovementGranularity = event.mMovementGranularity;
664         mAction = event.mAction;
665         mEventTime = event.mEventTime;
666         mPackageName = event.mPackageName;
667     }
668 
669     /**
670      * Sets if this instance is sealed.
671      *
672      * @param sealed Whether is sealed.
673      *
674      * @hide
675      */
676     @Override
setSealed(boolean sealed)677     public void setSealed(boolean sealed) {
678         super.setSealed(sealed);
679         List<AccessibilityRecord> records = mRecords;
680         final int recordCount = records.size();
681         for (int i = 0; i < recordCount; i++) {
682             AccessibilityRecord record = records.get(i);
683             record.setSealed(sealed);
684         }
685     }
686 
687     /**
688      * Gets the number of records contained in the event.
689      *
690      * @return The number of records.
691      */
getRecordCount()692     public int getRecordCount() {
693         return mRecords.size();
694     }
695 
696     /**
697      * Appends an {@link AccessibilityRecord} to the end of event records.
698      *
699      * @param record The record to append.
700      *
701      * @throws IllegalStateException If called from an AccessibilityService.
702      */
appendRecord(AccessibilityRecord record)703     public void appendRecord(AccessibilityRecord record) {
704         enforceNotSealed();
705         mRecords.add(record);
706     }
707 
708     /**
709      * Gets the record at a given index.
710      *
711      * @param index The index.
712      * @return The record at the specified index.
713      */
getRecord(int index)714     public AccessibilityRecord getRecord(int index) {
715         return mRecords.get(index);
716     }
717 
718     /**
719      * Gets the event type.
720      *
721      * @return The event type.
722      */
getEventType()723     public int getEventType() {
724         return mEventType;
725     }
726 
727     /**
728      * Sets the event type.
729      *
730      * @param eventType The event type.
731      *
732      * @throws IllegalStateException If called from an AccessibilityService.
733      */
setEventType(int eventType)734     public void setEventType(int eventType) {
735         enforceNotSealed();
736         mEventType = eventType;
737     }
738 
739     /**
740      * Gets the time in which this event was sent.
741      *
742      * @return The event time.
743      */
getEventTime()744     public long getEventTime() {
745         return mEventTime;
746     }
747 
748     /**
749      * Sets the time in which this event was sent.
750      *
751      * @param eventTime The event time.
752      *
753      * @throws IllegalStateException If called from an AccessibilityService.
754      */
setEventTime(long eventTime)755     public void setEventTime(long eventTime) {
756         enforceNotSealed();
757         mEventTime = eventTime;
758     }
759 
760     /**
761      * Gets the package name of the source.
762      *
763      * @return The package name.
764      */
getPackageName()765     public CharSequence getPackageName() {
766         return mPackageName;
767     }
768 
769     /**
770      * Sets the package name of the source.
771      *
772      * @param packageName The package name.
773      *
774      * @throws IllegalStateException If called from an AccessibilityService.
775      */
setPackageName(CharSequence packageName)776     public void setPackageName(CharSequence packageName) {
777         enforceNotSealed();
778         mPackageName = packageName;
779     }
780 
781     /**
782      * Sets the movement granularity that was traversed.
783      *
784      * @param granularity The granularity.
785      *
786      * @throws IllegalStateException If called from an AccessibilityService.
787      */
setMovementGranularity(int granularity)788     public void setMovementGranularity(int granularity) {
789         enforceNotSealed();
790         mMovementGranularity = granularity;
791     }
792 
793     /**
794      * Gets the movement granularity that was traversed.
795      *
796      * @return The granularity.
797      */
getMovementGranularity()798     public int getMovementGranularity() {
799         return mMovementGranularity;
800     }
801 
802     /**
803      * Sets the performed action that triggered this event.
804      *
805      * @param action The action.
806      *
807      * @throws IllegalStateException If called from an AccessibilityService.
808      */
setAction(int action)809     public void setAction(int action) {
810         enforceNotSealed();
811         mAction = action;
812     }
813 
814     /**
815      * Gets the performed action that triggered this event.
816      *
817      * @return The action.
818      */
getAction()819     public int getAction() {
820         return mAction;
821     }
822 
823     /**
824      * Returns a cached instance if such is available or a new one is
825      * instantiated with its type property set.
826      *
827      * @param eventType The event type.
828      * @return An instance.
829      */
obtain(int eventType)830     public static AccessibilityEvent obtain(int eventType) {
831         AccessibilityEvent event = AccessibilityEvent.obtain();
832         event.setEventType(eventType);
833         return event;
834     }
835 
836     /**
837      * Returns a cached instance if such is available or a new one is
838      * created. The returned instance is initialized from the given
839      * <code>event</code>.
840      *
841      * @param event The other event.
842      * @return An instance.
843      */
obtain(AccessibilityEvent event)844     public static AccessibilityEvent obtain(AccessibilityEvent event) {
845         AccessibilityEvent eventClone = AccessibilityEvent.obtain();
846         eventClone.init(event);
847 
848         final int recordCount = event.mRecords.size();
849         for (int i = 0; i < recordCount; i++) {
850             AccessibilityRecord record = event.mRecords.get(i);
851             AccessibilityRecord recordClone = AccessibilityRecord.obtain(record);
852             eventClone.mRecords.add(recordClone);
853         }
854 
855         return eventClone;
856     }
857 
858     /**
859      * Returns a cached instance if such is available or a new one is
860      * instantiated.
861      *
862      * @return An instance.
863      */
obtain()864     public static AccessibilityEvent obtain() {
865         synchronized (sPoolLock) {
866             if (sPool != null) {
867                 AccessibilityEvent event = sPool;
868                 sPool = sPool.mNext;
869                 sPoolSize--;
870                 event.mNext = null;
871                 event.mIsInPool = false;
872                 return event;
873             }
874             return new AccessibilityEvent();
875         }
876     }
877 
878     /**
879      * Recycles an instance back to be reused.
880      * <p>
881      *   <b>Note: You must not touch the object after calling this function.</b>
882      * </p>
883      *
884      * @throws IllegalStateException If the event is already recycled.
885      */
886     @Override
recycle()887     public void recycle() {
888         if (mIsInPool) {
889             throw new IllegalStateException("Event already recycled!");
890         }
891         clear();
892         synchronized (sPoolLock) {
893             if (sPoolSize <= MAX_POOL_SIZE) {
894                 mNext = sPool;
895                 sPool = this;
896                 mIsInPool = true;
897                 sPoolSize++;
898             }
899         }
900     }
901 
902     /**
903      * Clears the state of this instance.
904      *
905      * @hide
906      */
907     @Override
clear()908     protected void clear() {
909         super.clear();
910         mEventType = 0;
911         mMovementGranularity = 0;
912         mAction = 0;
913         mPackageName = null;
914         mEventTime = 0;
915         while (!mRecords.isEmpty()) {
916             AccessibilityRecord record = mRecords.remove(0);
917             record.recycle();
918         }
919     }
920 
921     /**
922      * Creates a new instance from a {@link Parcel}.
923      *
924      * @param parcel A parcel containing the state of a {@link AccessibilityEvent}.
925      */
initFromParcel(Parcel parcel)926     public void initFromParcel(Parcel parcel) {
927         mSealed = (parcel.readInt() == 1);
928         mEventType = parcel.readInt();
929         mMovementGranularity = parcel.readInt();
930         mAction = parcel.readInt();
931         mPackageName = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(parcel);
932         mEventTime = parcel.readLong();
933         mConnectionId = parcel.readInt();
934         readAccessibilityRecordFromParcel(this, parcel);
935 
936         // Read the records.
937         final int recordCount = parcel.readInt();
938         for (int i = 0; i < recordCount; i++) {
939             AccessibilityRecord record = AccessibilityRecord.obtain();
940             readAccessibilityRecordFromParcel(record, parcel);
941             record.mConnectionId = mConnectionId;
942             mRecords.add(record);
943         }
944     }
945 
946     /**
947      * Reads an {@link AccessibilityRecord} from a parcel.
948      *
949      * @param record The record to initialize.
950      * @param parcel The parcel to read from.
951      */
readAccessibilityRecordFromParcel(AccessibilityRecord record, Parcel parcel)952     private void readAccessibilityRecordFromParcel(AccessibilityRecord record,
953             Parcel parcel) {
954         record.mBooleanProperties = parcel.readInt();
955         record.mCurrentItemIndex = parcel.readInt();
956         record.mItemCount = parcel.readInt();
957         record.mFromIndex = parcel.readInt();
958         record.mToIndex = parcel.readInt();
959         record.mScrollX = parcel.readInt();
960         record.mScrollY =  parcel.readInt();
961         record.mMaxScrollX = parcel.readInt();
962         record.mMaxScrollY =  parcel.readInt();
963         record.mAddedCount = parcel.readInt();
964         record.mRemovedCount = parcel.readInt();
965         record.mClassName = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(parcel);
966         record.mContentDescription = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(parcel);
967         record.mBeforeText = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(parcel);
968         record.mParcelableData = parcel.readParcelable(null);
969         parcel.readList(record.mText, null);
970         record.mSourceWindowId = parcel.readInt();
971         record.mSourceNodeId = parcel.readLong();
972         record.mSealed = (parcel.readInt() == 1);
973     }
974 
975     /**
976      * {@inheritDoc}
977      */
writeToParcel(Parcel parcel, int flags)978     public void writeToParcel(Parcel parcel, int flags) {
979         parcel.writeInt(isSealed() ? 1 : 0);
980         parcel.writeInt(mEventType);
981         parcel.writeInt(mMovementGranularity);
982         parcel.writeInt(mAction);
983         TextUtils.writeToParcel(mPackageName, parcel, 0);
984         parcel.writeLong(mEventTime);
985         parcel.writeInt(mConnectionId);
986         writeAccessibilityRecordToParcel(this, parcel, flags);
987 
988         // Write the records.
989         final int recordCount = getRecordCount();
990         parcel.writeInt(recordCount);
991         for (int i = 0; i < recordCount; i++) {
992             AccessibilityRecord record = mRecords.get(i);
993             writeAccessibilityRecordToParcel(record, parcel, flags);
994         }
995     }
996 
997     /**
998      * Writes an {@link AccessibilityRecord} to a parcel.
999      *
1000      * @param record The record to write.
1001      * @param parcel The parcel to which to write.
1002      */
writeAccessibilityRecordToParcel(AccessibilityRecord record, Parcel parcel, int flags)1003     private void writeAccessibilityRecordToParcel(AccessibilityRecord record, Parcel parcel,
1004             int flags) {
1005         parcel.writeInt(record.mBooleanProperties);
1006         parcel.writeInt(record.mCurrentItemIndex);
1007         parcel.writeInt(record.mItemCount);
1008         parcel.writeInt(record.mFromIndex);
1009         parcel.writeInt(record.mToIndex);
1010         parcel.writeInt(record.mScrollX);
1011         parcel.writeInt(record.mScrollY);
1012         parcel.writeInt(record.mMaxScrollX);
1013         parcel.writeInt(record.mMaxScrollY);
1014         parcel.writeInt(record.mAddedCount);
1015         parcel.writeInt(record.mRemovedCount);
1016         TextUtils.writeToParcel(record.mClassName, parcel, flags);
1017         TextUtils.writeToParcel(record.mContentDescription, parcel, flags);
1018         TextUtils.writeToParcel(record.mBeforeText, parcel, flags);
1019         parcel.writeParcelable(record.mParcelableData, flags);
1020         parcel.writeList(record.mText);
1021         parcel.writeInt(record.mSourceWindowId);
1022         parcel.writeLong(record.mSourceNodeId);
1023         parcel.writeInt(record.mSealed ? 1 : 0);
1024     }
1025 
1026     /**
1027      * {@inheritDoc}
1028      */
describeContents()1029     public int describeContents() {
1030         return 0;
1031     }
1032 
1033     @Override
toString()1034     public String toString() {
1035         StringBuilder builder = new StringBuilder();
1036         builder.append("EventType: ").append(eventTypeToString(mEventType));
1037         builder.append("; EventTime: ").append(mEventTime);
1038         builder.append("; PackageName: ").append(mPackageName);
1039         builder.append("; MovementGranularity: ").append(mMovementGranularity);
1040         builder.append("; Action: ").append(mAction);
1041         builder.append(super.toString());
1042         if (DEBUG) {
1043             builder.append("\n");
1044             builder.append("; sourceWindowId: ").append(mSourceWindowId);
1045             builder.append("; mSourceNodeId: ").append(mSourceNodeId);
1046             for (int i = 0; i < mRecords.size(); i++) {
1047                 AccessibilityRecord record = mRecords.get(i);
1048                 builder.append("  Record ");
1049                 builder.append(i);
1050                 builder.append(":");
1051                 builder.append(" [ ClassName: " + record.mClassName);
1052                 builder.append("; Text: " + record.mText);
1053                 builder.append("; ContentDescription: " + record.mContentDescription);
1054                 builder.append("; ItemCount: " + record.mItemCount);
1055                 builder.append("; CurrentItemIndex: " + record.mCurrentItemIndex);
1056                 builder.append("; IsEnabled: " + record.isEnabled());
1057                 builder.append("; IsPassword: " + record.isPassword());
1058                 builder.append("; IsChecked: " + record.isChecked());
1059                 builder.append("; IsFullScreen: " + record.isFullScreen());
1060                 builder.append("; Scrollable: " + record.isScrollable());
1061                 builder.append("; BeforeText: " + record.mBeforeText);
1062                 builder.append("; FromIndex: " + record.mFromIndex);
1063                 builder.append("; ToIndex: " + record.mToIndex);
1064                 builder.append("; ScrollX: " + record.mScrollX);
1065                 builder.append("; ScrollY: " + record.mScrollY);
1066                 builder.append("; AddedCount: " + record.mAddedCount);
1067                 builder.append("; RemovedCount: " + record.mRemovedCount);
1068                 builder.append("; ParcelableData: " + record.mParcelableData);
1069                 builder.append(" ]");
1070                 builder.append("\n");
1071             }
1072         } else {
1073             builder.append("; recordCount: ").append(getRecordCount());
1074         }
1075         return builder.toString();
1076     }
1077 
1078     /**
1079      * Returns the string representation of an event type. For example,
1080      * {@link #TYPE_VIEW_CLICKED} is represented by the string TYPE_VIEW_CLICKED.
1081      *
1082      * @param eventType The event type
1083      * @return The string representation.
1084      */
eventTypeToString(int eventType)1085     public static String eventTypeToString(int eventType) {
1086         switch (eventType) {
1087             case TYPE_VIEW_CLICKED:
1088                 return "TYPE_VIEW_CLICKED";
1089             case TYPE_VIEW_LONG_CLICKED:
1090                 return "TYPE_VIEW_LONG_CLICKED";
1091             case TYPE_VIEW_SELECTED:
1092                 return "TYPE_VIEW_SELECTED";
1093             case TYPE_VIEW_FOCUSED:
1094                 return "TYPE_VIEW_FOCUSED";
1095             case TYPE_VIEW_TEXT_CHANGED:
1096                 return "TYPE_VIEW_TEXT_CHANGED";
1097             case TYPE_WINDOW_STATE_CHANGED:
1098                 return "TYPE_WINDOW_STATE_CHANGED";
1099             case TYPE_VIEW_HOVER_ENTER:
1100                 return "TYPE_VIEW_HOVER_ENTER";
1101             case TYPE_VIEW_HOVER_EXIT:
1102                 return "TYPE_VIEW_HOVER_EXIT";
1103             case TYPE_NOTIFICATION_STATE_CHANGED:
1104                 return "TYPE_NOTIFICATION_STATE_CHANGED";
1105             case TYPE_TOUCH_EXPLORATION_GESTURE_START:
1106                 return "TYPE_TOUCH_EXPLORATION_GESTURE_START";
1107             case TYPE_TOUCH_EXPLORATION_GESTURE_END:
1108                 return "TYPE_TOUCH_EXPLORATION_GESTURE_END";
1109             case TYPE_WINDOW_CONTENT_CHANGED:
1110                 return "TYPE_WINDOW_CONTENT_CHANGED";
1111             case TYPE_VIEW_TEXT_SELECTION_CHANGED:
1112                 return "TYPE_VIEW_TEXT_SELECTION_CHANGED";
1113             case TYPE_VIEW_SCROLLED:
1114                 return "TYPE_VIEW_SCROLLED";
1115             case TYPE_ANNOUNCEMENT:
1116                 return "TYPE_ANNOUNCEMENT";
1117             case TYPE_VIEW_ACCESSIBILITY_FOCUSED:
1118                 return "TYPE_VIEW_ACCESSIBILITY_FOCUSED";
1119             case TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED:
1120                 return "TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED";
1121             case TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY:
1122                 return "TYPE_CURRENT_AT_GRANULARITY_MOVEMENT_CHANGED";
1123             default:
1124                 return null;
1125         }
1126     }
1127 
1128     /**
1129      * @see Parcelable.Creator
1130      */
1131     public static final Parcelable.Creator<AccessibilityEvent> CREATOR =
1132             new Parcelable.Creator<AccessibilityEvent>() {
1133         public AccessibilityEvent createFromParcel(Parcel parcel) {
1134             AccessibilityEvent event = AccessibilityEvent.obtain();
1135             event.initFromParcel(parcel);
1136             return event;
1137         }
1138 
1139         public AccessibilityEvent[] newArray(int size) {
1140             return new AccessibilityEvent[size];
1141         }
1142     };
1143 }
1144