AccessibilityEvent.java revision 2b435aada3d274a9c08d334946fff1ab9ba15b48
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
17package android.view.accessibility;
18
19import android.os.Parcel;
20import android.os.Parcelable;
21import android.text.TextUtils;
22
23import java.util.ArrayList;
24import 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 #getText()} - The text of the current text at the movement granularity.</li>
240 *   <li>{@link #isPassword()} - Whether the source is password.</li>
241 *   <li>{@link #isEnabled()} - Whether the source is enabled.</li>
242 *   <li>{@link #getContentDescription()} - The content description of the source.</li>
243 *   <li>{@link #getMovementGranularity()} - Sets the granularity at which a view's text
244 *       was traversed.</li>
245 * </ul>
246 * </p>
247 * <p>
248 * <b>View scrolled</b> - represents the event of scrolling a view. If
249 * the source is a descendant of {@link android.widget.AdapterView} the
250 * scroll is reported in terms of visible items - the first visible item,
251 * the last visible item, and the total items - because the the source
252 * is unaware of its pixel size since its adapter is responsible for
253 * creating views. In all other cases the scroll is reported as the current
254 * scroll on the X and Y axis respectively plus the height of the source in
255 * pixels.</br>
256 * <em>Type:</em> {@link #TYPE_VIEW_SCROLLED}</br>
257 * <em>Properties:</em></br>
258 * <ul>
259 *   <li>{@link #getEventType()} - The type of the event.</li>
260 *   <li>{@link #getSource()} - The source info (for registered clients).</li>
261 *   <li>{@link #getClassName()} - The class name of the source.</li>
262 *   <li>{@link #getPackageName()} - The package name of the source.</li>
263 *   <li>{@link #getEventTime()}  - The event time.</li>
264 *   <li>{@link #getText()} - The text of the source's sub-tree.</li>
265 *   <li>{@link #isEnabled()} - Whether the source is enabled.</li>
266 *   <li>{@link #getContentDescription()} - The content description of the source.</li>
267 *   <li>{@link #getScrollX()} - The offset of the source left edge in pixels
268 *       (without descendants of AdapterView).</li>
269 *   <li>{@link #getScrollY()} - The offset of the source top edge in pixels
270 *       (without descendants of AdapterView).</li>
271 *   <li>{@link #getFromIndex()} - The zero based index of the first visible item of the source,
272 *       inclusive (for descendants of AdapterView).</li>
273 *   <li>{@link #getToIndex()} - The zero based index of the last visible item of the source,
274 *       inclusive (for descendants of AdapterView).</li>
275 *   <li>{@link #getItemCount()} - The total items of the source
276 *       (for descendants of AdapterView).</li>
277 * </ul>
278 * <em>Note:</em> This event type is not dispatched to descendants though
279 * {@link android.view.View#dispatchPopulateAccessibilityEvent(AccessibilityEvent)
280 * View.dispatchPopulateAccessibilityEvent(AccessibilityEvent)}, hence the event
281 * source {@link android.view.View} and the sub-tree rooted at it will not receive
282 * calls to {@link android.view.View#onPopulateAccessibilityEvent(AccessibilityEvent)
283 * View.onPopulateAccessibilityEvent(AccessibilityEvent)}. The preferred way to add
284 * text content to such events is by setting the
285 * {@link android.R.styleable#View_contentDescription contentDescription} of the source
286 * view.</br>
287 * </p>
288 * <p>
289 * <b>TRANSITION TYPES</b></br>
290 * </p>
291 * <p>
292 * <b>Window state changed</b> - represents the event of opening a
293 * {@link android.widget.PopupWindow}, {@link android.view.Menu},
294 * {@link android.app.Dialog}, etc.</br>
295 * <em>Type:</em> {@link #TYPE_WINDOW_STATE_CHANGED}</br>
296 * <em>Properties:</em></br>
297 * <ul>
298 *   <li>{@link #getEventType()} - The type of the event.</li>
299 *   <li>{@link #getSource()} - The source info (for registered clients).</li>
300 *   <li>{@link #getClassName()} - The class name of the source.</li>
301 *   <li>{@link #getPackageName()} - The package name of the source.</li>
302 *   <li>{@link #getEventTime()}  - The event time.</li>
303 *   <li>{@link #getText()} - The text of the source's sub-tree.</li>
304 *   <li>{@link #isEnabled()} - Whether the source is enabled.</li>
305 * </ul>
306 * </p>
307 * <p>
308 * <b>Window content changed</b> - represents the event of change in the
309 * content of a window. This change can be adding/removing view, changing
310 * a view size, etc.</br>
311 * </p>
312 * <p>
313 * <strong>Note:</strong> This event is fired only for the window source of the
314 * last accessibility event different from {@link #TYPE_NOTIFICATION_STATE_CHANGED}
315 * and its purpose is to notify clients that the content of the user interaction
316 * window has changed.</br>
317 * <em>Type:</em> {@link #TYPE_WINDOW_CONTENT_CHANGED}</br>
318 * <em>Properties:</em></br>
319 * <ul>
320 *   <li>{@link #getEventType()} - The type of the event.</li>
321 *   <li>{@link #getSource()} - The source info (for registered clients).</li>
322 *   <li>{@link #getClassName()} - The class name of the source.</li>
323 *   <li>{@link #getPackageName()} - The package name of the source.</li>
324 *   <li>{@link #getEventTime()}  - The event time.</li>
325 * </ul>
326 * <em>Note:</em> This event type is not dispatched to descendants though
327 * {@link android.view.View#dispatchPopulateAccessibilityEvent(AccessibilityEvent)
328 * View.dispatchPopulateAccessibilityEvent(AccessibilityEvent)}, hence the event
329 * source {@link android.view.View} and the sub-tree rooted at it will not receive
330 * calls to {@link android.view.View#onPopulateAccessibilityEvent(AccessibilityEvent)
331 * View.onPopulateAccessibilityEvent(AccessibilityEvent)}. The preferred way to add
332 * text content to such events is by setting the
333 * {@link android.R.styleable#View_contentDescription contentDescription} of the source
334 * view.</br>
335 * </p>
336 * <p>
337 * <b>NOTIFICATION TYPES</b></br>
338 * </p>
339 * <p>
340 * <b>Notification state changed</b> - represents the event showing
341 * {@link android.app.Notification}.</br>
342 * <em>Type:</em> {@link #TYPE_NOTIFICATION_STATE_CHANGED}</br>
343 * <em>Properties:</em></br>
344 * <ul>
345 *   <li>{@link #getEventType()} - The type of the event.</li>
346 *   <li>{@link #getClassName()} - The class name of the source.</li>
347 *   <li>{@link #getPackageName()} - The package name of the source.</li>
348 *   <li>{@link #getEventTime()}  - The event time.</li>
349 *   <li>{@link #getText()} - The text of the source's sub-tree.</li>
350 *   <li>{@link #getParcelableData()} - The posted {@link android.app.Notification}.</li>
351 *   <li>{@link #getText()} - Text for providing more context.</li>
352 * </ul>
353 * <em>Note:</em> This event type is not dispatched to descendants though
354 * {@link android.view.View#dispatchPopulateAccessibilityEvent(AccessibilityEvent)
355 * View.dispatchPopulateAccessibilityEvent(AccessibilityEvent)}, hence the event
356 * source {@link android.view.View} and the sub-tree rooted at it will not receive
357 * calls to {@link android.view.View#onPopulateAccessibilityEvent(AccessibilityEvent)
358 * View.onPopulateAccessibilityEvent(AccessibilityEvent)}. The preferred way to add
359 * text content to such events is by setting the
360 * {@link android.R.styleable#View_contentDescription contentDescription} of the source
361 * view.</br>
362 * </p>
363 * <p>
364 * <b>EXPLORATION TYPES</b></br>
365 * </p>
366 * <p>
367 * <b>View hover enter</b> - represents the event of beginning to hover
368 * over a {@link android.view.View}. The hover may be generated via
369 * exploring the screen by touch or via a pointing device.</br>
370 * <em>Type:</em> {@link #TYPE_VIEW_HOVER_ENTER}</br>
371 * <em>Properties:</em></br>
372 * <ul>
373 *   <li>{@link #getEventType()} - The type of the event.</li>
374 *   <li>{@link #getSource()} - The source info (for registered clients).</li>
375 *   <li>{@link #getClassName()} - The class name of the source.</li>
376 *   <li>{@link #getPackageName()} - The package name of the source.</li>
377 *   <li>{@link #getEventTime()}  - The event time.</li>
378 *   <li>{@link #getText()} - The text of the source's sub-tree.</li>
379 *   <li>{@link #isEnabled()} - Whether the source is enabled.</li>
380 *   <li>{@link #getContentDescription()} - The content description of the source.</li>
381 *   <li>{@link #getScrollX()} - The offset of the source left edge in pixels
382 *       (without descendants of AdapterView).</li>
383 *   <li>{@link #getScrollY()} - The offset of the source top edge in pixels
384 *       (without descendants of AdapterView).</li>
385 *   <li>{@link #getFromIndex()} - The zero based index of the first visible item of the source,
386 *       inclusive (for descendants of AdapterView).</li>
387 *   <li>{@link #getToIndex()} - The zero based index of the last visible item of the source,
388 *       inclusive (for descendants of AdapterView).</li>
389 *   <li>{@link #getItemCount()} - The total items of the source
390 *       (for descendants of AdapterView).</li>
391 * </ul>
392 * </p>
393 * <b>View hover exit</b> - represents the event of stopping to hover
394 * over a {@link android.view.View}. The hover may be generated via
395 * exploring the screen by touch or via a pointing device.</br>
396 * <em>Type:</em> {@link #TYPE_VIEW_HOVER_EXIT}</br>
397 * <em>Properties:</em></br>
398 * <ul>
399 *   <li>{@link #getEventType()} - The type of the event.</li>
400 *   <li>{@link #getSource()} - The source info (for registered clients).</li>
401 *   <li>{@link #getClassName()} - The class name of the source.</li>
402 *   <li>{@link #getPackageName()} - The package name of the source.</li>
403 *   <li>{@link #getEventTime()}  - The event time.</li>
404 *   <li>{@link #getText()} - The text of the source's sub-tree.</li>
405 *   <li>{@link #isEnabled()} - Whether the source is enabled.</li>
406 *   <li>{@link #getContentDescription()} - The content description of the source.</li>
407 *   <li>{@link #getScrollX()} - The offset of the source left edge in pixels
408 *       (without descendants of AdapterView).</li>
409 *   <li>{@link #getScrollY()} - The offset of the source top edge in pixels
410 *       (without descendants of AdapterView).</li>
411 *   <li>{@link #getFromIndex()} - The zero based index of the first visible item of the source,
412 *       inclusive (for descendants of AdapterView).</li>
413 *   <li>{@link #getToIndex()} - The zero based index of the last visible item of the source,
414 *       inclusive (for descendants of AdapterView).</li>
415 *   <li>{@link #getItemCount()} - The total items of the source
416 *       (for descendants of AdapterView).</li>
417 * </ul>
418 * </p>
419 * <p>
420 * <b>Touch exploration gesture start</b> - represents the event of starting a touch
421 * exploring gesture.</br>
422 * <em>Type:</em> {@link #TYPE_TOUCH_EXPLORATION_GESTURE_START}</br>
423 * <em>Properties:</em></br>
424 * <ul>
425 *   <li>{@link #getEventType()} - The type of the event.</li>
426 * </ul>
427 * <em>Note:</em> This event type is not dispatched to descendants though
428 * {@link android.view.View#dispatchPopulateAccessibilityEvent(AccessibilityEvent)
429 * View.dispatchPopulateAccessibilityEvent(AccessibilityEvent)}, hence the event
430 * source {@link android.view.View} and the sub-tree rooted at it will not receive
431 * calls to {@link android.view.View#onPopulateAccessibilityEvent(AccessibilityEvent)
432 * View.onPopulateAccessibilityEvent(AccessibilityEvent)}. The preferred way to add
433 * text content to such events is by setting the
434 * {@link android.R.styleable#View_contentDescription contentDescription} of the source
435 * view.</br>
436 * </p>
437 * <p>
438 * <b>Touch exploration gesture end</b> - represents the event of ending a touch
439 * exploring gesture.</br>
440 * <em>Type:</em> {@link #TYPE_TOUCH_EXPLORATION_GESTURE_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 type is not dispatched to descendants though
446 * {@link android.view.View#dispatchPopulateAccessibilityEvent(AccessibilityEvent)
447 * View.dispatchPopulateAccessibilityEvent(AccessibilityEvent)}, hence the event
448 * source {@link android.view.View} and the sub-tree rooted at it will not receive
449 * calls to {@link android.view.View#onPopulateAccessibilityEvent(AccessibilityEvent)
450 * View.onPopulateAccessibilityEvent(AccessibilityEvent)}. The preferred way to add
451 * text content to such events is by setting the
452 * {@link android.R.styleable#View_contentDescription contentDescription} of the source
453 * view.</br>
454 * </p>
455 * <p>
456 * <b>MISCELLANEOUS TYPES</b></br>
457 * </p>
458 * <p>
459 * <b>Announcement</b> - represents the event of an application making an
460 * announcement. Usually this announcement is related to some sort of a context
461 * change for which none of the events representing UI transitions is a good fit.
462 * For example, announcing a new page in a book.</br>
463 * <em>Type:</em> {@link #TYPE_ANNOUNCEMENT}</br>
464 * <em>Properties:</em></br>
465 * <ul>
466 *   <li>{@link #getEventType()} - The type of the event.</li>
467 *   <li>{@link #getSource()} - The source info (for registered clients).</li>
468 *   <li>{@link #getClassName()} - The class name of the source.</li>
469 *   <li>{@link #getPackageName()} - The package name of the source.</li>
470 *   <li>{@link #getEventTime()}  - The event time.</li>
471 *   <li>{@link #getText()} - The text of the announcement.</li>
472 *   <li>{@link #isEnabled()} - Whether the source is enabled.</li>
473 * </ul>
474 * </p>
475 * <p>
476 * <b>Security note</b>
477 * <p>
478 * Since an event contains the text of its source privacy can be compromised by leaking
479 * sensitive information such as passwords. To address this issue any event fired in response
480 * to manipulation of a PASSWORD field does NOT CONTAIN the text of the password.
481 * </p>
482 *
483 * @see android.view.accessibility.AccessibilityManager
484 * @see android.accessibilityservice.AccessibilityService
485 * @see AccessibilityNodeInfo
486 */
487public final class AccessibilityEvent extends AccessibilityRecord implements Parcelable {
488    private static final boolean DEBUG = false;
489
490    /**
491     * Invalid selection/focus position.
492     *
493     * @see #getCurrentItemIndex()
494     */
495    public static final int INVALID_POSITION = -1;
496
497    /**
498     * Maximum length of the text fields.
499     *
500     * @see #getBeforeText()
501     * @see #getText()
502     * </br>
503     * Note: This constant is no longer needed since there
504     *       is no limit on the length of text that is contained
505     *       in an accessibility event anymore.
506     */
507    @Deprecated
508    public static final int MAX_TEXT_LENGTH = 500;
509
510    /**
511     * Represents the event of clicking on a {@link android.view.View} like
512     * {@link android.widget.Button}, {@link android.widget.CompoundButton}, etc.
513     */
514    public static final int TYPE_VIEW_CLICKED = 0x00000001;
515
516    /**
517     * Represents the event of long clicking on a {@link android.view.View} like
518     * {@link android.widget.Button}, {@link android.widget.CompoundButton}, etc.
519     */
520    public static final int TYPE_VIEW_LONG_CLICKED = 0x00000002;
521
522    /**
523     * Represents the event of selecting an item usually in the context of an
524     * {@link android.widget.AdapterView}.
525     */
526    public static final int TYPE_VIEW_SELECTED = 0x00000004;
527
528    /**
529     * Represents the event of setting input focus of a {@link android.view.View}.
530     */
531    public static final int TYPE_VIEW_FOCUSED = 0x00000008;
532
533    /**
534     * Represents the event of changing the text of an {@link android.widget.EditText}.
535     */
536    public static final int TYPE_VIEW_TEXT_CHANGED = 0x00000010;
537
538    /**
539     * Represents the event of opening a {@link android.widget.PopupWindow},
540     * {@link android.view.Menu}, {@link android.app.Dialog}, etc.
541     */
542    public static final int TYPE_WINDOW_STATE_CHANGED = 0x00000020;
543
544    /**
545     * Represents the event showing a {@link android.app.Notification}.
546     */
547    public static final int TYPE_NOTIFICATION_STATE_CHANGED = 0x00000040;
548
549    /**
550     * Represents the event of a hover enter over a {@link android.view.View}.
551     */
552    public static final int TYPE_VIEW_HOVER_ENTER = 0x00000080;
553
554    /**
555     * Represents the event of a hover exit over a {@link android.view.View}.
556     */
557    public static final int TYPE_VIEW_HOVER_EXIT = 0x00000100;
558
559    /**
560     * Represents the event of starting a touch exploration gesture.
561     */
562    public static final int TYPE_TOUCH_EXPLORATION_GESTURE_START = 0x00000200;
563
564    /**
565     * Represents the event of ending a touch exploration gesture.
566     */
567    public static final int TYPE_TOUCH_EXPLORATION_GESTURE_END = 0x00000400;
568
569    /**
570     * Represents the event of changing the content of a window and more
571     * specifically the sub-tree rooted at the event's source.
572     */
573    public static final int TYPE_WINDOW_CONTENT_CHANGED = 0x00000800;
574
575    /**
576     * Represents the event of scrolling a view.
577     */
578    public static final int TYPE_VIEW_SCROLLED = 0x00001000;
579
580    /**
581     * Represents the event of changing the selection in an {@link android.widget.EditText}.
582     */
583    public static final int TYPE_VIEW_TEXT_SELECTION_CHANGED = 0x00002000;
584
585    /**
586     * Represents the event of an application making an announcement.
587     */
588    public static final int TYPE_ANNOUNCEMENT = 0x00004000;
589
590    /**
591     * Represents the event of gaining accessibility focus.
592     */
593    public static final int TYPE_VIEW_ACCESSIBILITY_FOCUSED = 0x00008000;
594
595    /**
596     * Represents the event of clearing accessibility focus.
597     */
598    public static final int TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED = 0x00010000;
599
600    /**
601     * Represents the event of traversing the text of a view at a given movement granularity.
602     */
603    public static final int TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY = 0x00020000;
604
605    /**
606     * Mask for {@link AccessibilityEvent} all types.
607     *
608     * @see #TYPE_VIEW_CLICKED
609     * @see #TYPE_VIEW_LONG_CLICKED
610     * @see #TYPE_VIEW_SELECTED
611     * @see #TYPE_VIEW_FOCUSED
612     * @see #TYPE_VIEW_TEXT_CHANGED
613     * @see #TYPE_WINDOW_STATE_CHANGED
614     * @see #TYPE_NOTIFICATION_STATE_CHANGED
615     * @see #TYPE_VIEW_HOVER_ENTER
616     * @see #TYPE_VIEW_HOVER_EXIT
617     * @see #TYPE_TOUCH_EXPLORATION_GESTURE_START
618     * @see #TYPE_TOUCH_EXPLORATION_GESTURE_END
619     * @see #TYPE_WINDOW_CONTENT_CHANGED
620     * @see #TYPE_VIEW_SCROLLED
621     * @see #TYPE_VIEW_TEXT_SELECTION_CHANGED
622     * @see #TYPE_ANNOUNCEMENT
623     * @see #TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
624     */
625    public static final int TYPES_ALL_MASK = 0xFFFFFFFF;
626
627    private static final int MAX_POOL_SIZE = 10;
628    private static final Object sPoolLock = new Object();
629    private static AccessibilityEvent sPool;
630    private static int sPoolSize;
631    private AccessibilityEvent mNext;
632    private boolean mIsInPool;
633
634    private int mEventType;
635    private CharSequence mPackageName;
636    private long mEventTime;
637    int mMovementGranularity;
638
639    private final ArrayList<AccessibilityRecord> mRecords = new ArrayList<AccessibilityRecord>();
640
641    /*
642     * Hide constructor from clients.
643     */
644    private AccessibilityEvent() {
645    }
646
647    /**
648     * Initialize an event from another one.
649     *
650     * @param event The event to initialize from.
651     */
652    void init(AccessibilityEvent event) {
653        super.init(event);
654        mEventType = event.mEventType;
655        mMovementGranularity = event.mMovementGranularity;
656        mEventTime = event.mEventTime;
657        mPackageName = event.mPackageName;
658    }
659
660    /**
661     * Sets if this instance is sealed.
662     *
663     * @param sealed Whether is sealed.
664     *
665     * @hide
666     */
667    @Override
668    public void setSealed(boolean sealed) {
669        super.setSealed(sealed);
670        List<AccessibilityRecord> records = mRecords;
671        final int recordCount = records.size();
672        for (int i = 0; i < recordCount; i++) {
673            AccessibilityRecord record = records.get(i);
674            record.setSealed(sealed);
675        }
676    }
677
678    /**
679     * Gets the number of records contained in the event.
680     *
681     * @return The number of records.
682     */
683    public int getRecordCount() {
684        return mRecords.size();
685    }
686
687    /**
688     * Appends an {@link AccessibilityRecord} to the end of event records.
689     *
690     * @param record The record to append.
691     *
692     * @throws IllegalStateException If called from an AccessibilityService.
693     */
694    public void appendRecord(AccessibilityRecord record) {
695        enforceNotSealed();
696        mRecords.add(record);
697    }
698
699    /**
700     * Gets the record at a given index.
701     *
702     * @param index The index.
703     * @return The record at the specified index.
704     */
705    public AccessibilityRecord getRecord(int index) {
706        return mRecords.get(index);
707    }
708
709    /**
710     * Gets the event type.
711     *
712     * @return The event type.
713     */
714    public int getEventType() {
715        return mEventType;
716    }
717
718    /**
719     * Sets the event type.
720     *
721     * @param eventType The event type.
722     *
723     * @throws IllegalStateException If called from an AccessibilityService.
724     */
725    public void setEventType(int eventType) {
726        enforceNotSealed();
727        mEventType = eventType;
728    }
729
730    /**
731     * Gets the time in which this event was sent.
732     *
733     * @return The event time.
734     */
735    public long getEventTime() {
736        return mEventTime;
737    }
738
739    /**
740     * Sets the time in which this event was sent.
741     *
742     * @param eventTime The event time.
743     *
744     * @throws IllegalStateException If called from an AccessibilityService.
745     */
746    public void setEventTime(long eventTime) {
747        enforceNotSealed();
748        mEventTime = eventTime;
749    }
750
751    /**
752     * Gets the package name of the source.
753     *
754     * @return The package name.
755     */
756    public CharSequence getPackageName() {
757        return mPackageName;
758    }
759
760    /**
761     * Sets the package name of the source.
762     *
763     * @param packageName The package name.
764     *
765     * @throws IllegalStateException If called from an AccessibilityService.
766     */
767    public void setPackageName(CharSequence packageName) {
768        enforceNotSealed();
769        mPackageName = packageName;
770    }
771
772    /**
773     * Sets the movement granularity that was traversed.
774     *
775     * @param granularity The granularity.
776     *
777     * @throws IllegalStateException If called from an AccessibilityService.
778     */
779    public void setMovementGranularity(int granularity) {
780        enforceNotSealed();
781        mMovementGranularity = granularity;
782    }
783
784    /**
785     * Gets the movement granularity that was traversed.
786     *
787     * @return The granularity.
788     */
789    public int getMovementGranularity() {
790        return mMovementGranularity;
791    }
792
793    /**
794     * Returns a cached instance if such is available or a new one is
795     * instantiated with its type property set.
796     *
797     * @param eventType The event type.
798     * @return An instance.
799     */
800    public static AccessibilityEvent obtain(int eventType) {
801        AccessibilityEvent event = AccessibilityEvent.obtain();
802        event.setEventType(eventType);
803        return event;
804    }
805
806    /**
807     * Returns a cached instance if such is available or a new one is
808     * created. The returned instance is initialized from the given
809     * <code>event</code>.
810     *
811     * @param event The other event.
812     * @return An instance.
813     */
814    public static AccessibilityEvent obtain(AccessibilityEvent event) {
815        AccessibilityEvent eventClone = AccessibilityEvent.obtain();
816        eventClone.init(event);
817
818        final int recordCount = event.mRecords.size();
819        for (int i = 0; i < recordCount; i++) {
820            AccessibilityRecord record = event.mRecords.get(i);
821            AccessibilityRecord recordClone = AccessibilityRecord.obtain(record);
822            eventClone.mRecords.add(recordClone);
823        }
824
825        return eventClone;
826    }
827
828    /**
829     * Returns a cached instance if such is available or a new one is
830     * instantiated.
831     *
832     * @return An instance.
833     */
834    public static AccessibilityEvent obtain() {
835        synchronized (sPoolLock) {
836            if (sPool != null) {
837                AccessibilityEvent event = sPool;
838                sPool = sPool.mNext;
839                sPoolSize--;
840                event.mNext = null;
841                event.mIsInPool = false;
842                return event;
843            }
844            return new AccessibilityEvent();
845        }
846    }
847
848    /**
849     * Recycles an instance back to be reused.
850     * <p>
851     *   <b>Note: You must not touch the object after calling this function.</b>
852     * </p>
853     *
854     * @throws IllegalStateException If the event is already recycled.
855     */
856    @Override
857    public void recycle() {
858        if (mIsInPool) {
859            throw new IllegalStateException("Event already recycled!");
860        }
861        clear();
862        synchronized (sPoolLock) {
863            if (sPoolSize <= MAX_POOL_SIZE) {
864                mNext = sPool;
865                sPool = this;
866                mIsInPool = true;
867                sPoolSize++;
868            }
869        }
870    }
871
872    /**
873     * Clears the state of this instance.
874     *
875     * @hide
876     */
877    @Override
878    protected void clear() {
879        super.clear();
880        mEventType = 0;
881        mMovementGranularity = 0;
882        mPackageName = null;
883        mEventTime = 0;
884        while (!mRecords.isEmpty()) {
885            AccessibilityRecord record = mRecords.remove(0);
886            record.recycle();
887        }
888    }
889
890    /**
891     * Creates a new instance from a {@link Parcel}.
892     *
893     * @param parcel A parcel containing the state of a {@link AccessibilityEvent}.
894     */
895    public void initFromParcel(Parcel parcel) {
896        mSealed = (parcel.readInt() == 1);
897        mEventType = parcel.readInt();
898        mMovementGranularity = parcel.readInt();
899        mPackageName = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(parcel);
900        mEventTime = parcel.readLong();
901        mConnectionId = parcel.readInt();
902        readAccessibilityRecordFromParcel(this, parcel);
903
904        // Read the records.
905        final int recordCount = parcel.readInt();
906        for (int i = 0; i < recordCount; i++) {
907            AccessibilityRecord record = AccessibilityRecord.obtain();
908            readAccessibilityRecordFromParcel(record, parcel);
909            record.mConnectionId = mConnectionId;
910            mRecords.add(record);
911        }
912    }
913
914    /**
915     * Reads an {@link AccessibilityRecord} from a parcel.
916     *
917     * @param record The record to initialize.
918     * @param parcel The parcel to read from.
919     */
920    private void readAccessibilityRecordFromParcel(AccessibilityRecord record,
921            Parcel parcel) {
922        record.mBooleanProperties = parcel.readInt();
923        record.mCurrentItemIndex = parcel.readInt();
924        record.mItemCount = parcel.readInt();
925        record.mFromIndex = parcel.readInt();
926        record.mToIndex = parcel.readInt();
927        record.mScrollX = parcel.readInt();
928        record.mScrollY =  parcel.readInt();
929        record.mMaxScrollX = parcel.readInt();
930        record.mMaxScrollY =  parcel.readInt();
931        record.mAddedCount = parcel.readInt();
932        record.mRemovedCount = parcel.readInt();
933        record.mClassName = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(parcel);
934        record.mContentDescription = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(parcel);
935        record.mBeforeText = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(parcel);
936        record.mParcelableData = parcel.readParcelable(null);
937        parcel.readList(record.mText, null);
938        record.mSourceWindowId = parcel.readInt();
939        record.mSourceNodeId = parcel.readLong();
940        record.mSealed = (parcel.readInt() == 1);
941    }
942
943    /**
944     * {@inheritDoc}
945     */
946    public void writeToParcel(Parcel parcel, int flags) {
947        parcel.writeInt(isSealed() ? 1 : 0);
948        parcel.writeInt(mEventType);
949        parcel.writeInt(mMovementGranularity);
950        TextUtils.writeToParcel(mPackageName, parcel, 0);
951        parcel.writeLong(mEventTime);
952        parcel.writeInt(mConnectionId);
953        writeAccessibilityRecordToParcel(this, parcel, flags);
954
955        // Write the records.
956        final int recordCount = getRecordCount();
957        parcel.writeInt(recordCount);
958        for (int i = 0; i < recordCount; i++) {
959            AccessibilityRecord record = mRecords.get(i);
960            writeAccessibilityRecordToParcel(record, parcel, flags);
961        }
962    }
963
964    /**
965     * Writes an {@link AccessibilityRecord} to a parcel.
966     *
967     * @param record The record to write.
968     * @param parcel The parcel to which to write.
969     */
970    private void writeAccessibilityRecordToParcel(AccessibilityRecord record, Parcel parcel,
971            int flags) {
972        parcel.writeInt(record.mBooleanProperties);
973        parcel.writeInt(record.mCurrentItemIndex);
974        parcel.writeInt(record.mItemCount);
975        parcel.writeInt(record.mFromIndex);
976        parcel.writeInt(record.mToIndex);
977        parcel.writeInt(record.mScrollX);
978        parcel.writeInt(record.mScrollY);
979        parcel.writeInt(record.mMaxScrollX);
980        parcel.writeInt(record.mMaxScrollY);
981        parcel.writeInt(record.mAddedCount);
982        parcel.writeInt(record.mRemovedCount);
983        TextUtils.writeToParcel(record.mClassName, parcel, flags);
984        TextUtils.writeToParcel(record.mContentDescription, parcel, flags);
985        TextUtils.writeToParcel(record.mBeforeText, parcel, flags);
986        parcel.writeParcelable(record.mParcelableData, flags);
987        parcel.writeList(record.mText);
988        parcel.writeInt(record.mSourceWindowId);
989        parcel.writeLong(record.mSourceNodeId);
990        parcel.writeInt(record.mSealed ? 1 : 0);
991    }
992
993    /**
994     * {@inheritDoc}
995     */
996    public int describeContents() {
997        return 0;
998    }
999
1000    @Override
1001    public String toString() {
1002        StringBuilder builder = new StringBuilder();
1003        builder.append("EventType: ").append(eventTypeToString(mEventType));
1004        builder.append("; EventTime: ").append(mEventTime);
1005        builder.append("; PackageName: ").append(mPackageName);
1006        builder.append("; MovementGranularity: ").append(mMovementGranularity);
1007        builder.append(super.toString());
1008        if (DEBUG) {
1009            builder.append("\n");
1010            builder.append("; sourceWindowId: ").append(mSourceWindowId);
1011            builder.append("; mSourceNodeId: ").append(mSourceNodeId);
1012            for (int i = 0; i < mRecords.size(); i++) {
1013                AccessibilityRecord record = mRecords.get(i);
1014                builder.append("  Record ");
1015                builder.append(i);
1016                builder.append(":");
1017                builder.append(" [ ClassName: " + record.mClassName);
1018                builder.append("; Text: " + record.mText);
1019                builder.append("; ContentDescription: " + record.mContentDescription);
1020                builder.append("; ItemCount: " + record.mItemCount);
1021                builder.append("; CurrentItemIndex: " + record.mCurrentItemIndex);
1022                builder.append("; IsEnabled: " + record.isEnabled());
1023                builder.append("; IsPassword: " + record.isPassword());
1024                builder.append("; IsChecked: " + record.isChecked());
1025                builder.append("; IsFullScreen: " + record.isFullScreen());
1026                builder.append("; Scrollable: " + record.isScrollable());
1027                builder.append("; BeforeText: " + record.mBeforeText);
1028                builder.append("; FromIndex: " + record.mFromIndex);
1029                builder.append("; ToIndex: " + record.mToIndex);
1030                builder.append("; ScrollX: " + record.mScrollX);
1031                builder.append("; ScrollY: " + record.mScrollY);
1032                builder.append("; AddedCount: " + record.mAddedCount);
1033                builder.append("; RemovedCount: " + record.mRemovedCount);
1034                builder.append("; ParcelableData: " + record.mParcelableData);
1035                builder.append(" ]");
1036                builder.append("\n");
1037            }
1038        } else {
1039            builder.append("; recordCount: ").append(getRecordCount());
1040        }
1041        return builder.toString();
1042    }
1043
1044    /**
1045     * Returns the string representation of an event type. For example,
1046     * {@link #TYPE_VIEW_CLICKED} is represented by the string TYPE_VIEW_CLICKED.
1047     *
1048     * @param eventType The event type
1049     * @return The string representation.
1050     */
1051    public static String eventTypeToString(int eventType) {
1052        switch (eventType) {
1053            case TYPE_VIEW_CLICKED:
1054                return "TYPE_VIEW_CLICKED";
1055            case TYPE_VIEW_LONG_CLICKED:
1056                return "TYPE_VIEW_LONG_CLICKED";
1057            case TYPE_VIEW_SELECTED:
1058                return "TYPE_VIEW_SELECTED";
1059            case TYPE_VIEW_FOCUSED:
1060                return "TYPE_VIEW_FOCUSED";
1061            case TYPE_VIEW_TEXT_CHANGED:
1062                return "TYPE_VIEW_TEXT_CHANGED";
1063            case TYPE_WINDOW_STATE_CHANGED:
1064                return "TYPE_WINDOW_STATE_CHANGED";
1065            case TYPE_VIEW_HOVER_ENTER:
1066                return "TYPE_VIEW_HOVER_ENTER";
1067            case TYPE_VIEW_HOVER_EXIT:
1068                return "TYPE_VIEW_HOVER_EXIT";
1069            case TYPE_NOTIFICATION_STATE_CHANGED:
1070                return "TYPE_NOTIFICATION_STATE_CHANGED";
1071            case TYPE_TOUCH_EXPLORATION_GESTURE_START:
1072                return "TYPE_TOUCH_EXPLORATION_GESTURE_START";
1073            case TYPE_TOUCH_EXPLORATION_GESTURE_END:
1074                return "TYPE_TOUCH_EXPLORATION_GESTURE_END";
1075            case TYPE_WINDOW_CONTENT_CHANGED:
1076                return "TYPE_WINDOW_CONTENT_CHANGED";
1077            case TYPE_VIEW_TEXT_SELECTION_CHANGED:
1078                return "TYPE_VIEW_TEXT_SELECTION_CHANGED";
1079            case TYPE_VIEW_SCROLLED:
1080                return "TYPE_VIEW_SCROLLED";
1081            case TYPE_ANNOUNCEMENT:
1082                return "TYPE_ANNOUNCEMENT";
1083            case TYPE_VIEW_ACCESSIBILITY_FOCUSED:
1084                return "TYPE_VIEW_ACCESSIBILITY_FOCUSED";
1085            case TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED:
1086                return "TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED";
1087            case TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY:
1088                return "TYPE_CURRENT_AT_GRANULARITY_MOVEMENT_CHANGED";
1089            default:
1090                return null;
1091        }
1092    }
1093
1094    /**
1095     * @see Parcelable.Creator
1096     */
1097    public static final Parcelable.Creator<AccessibilityEvent> CREATOR =
1098            new Parcelable.Creator<AccessibilityEvent>() {
1099        public AccessibilityEvent createFromParcel(Parcel parcel) {
1100            AccessibilityEvent event = AccessibilityEvent.obtain();
1101            event.initFromParcel(parcel);
1102            return event;
1103        }
1104
1105        public AccessibilityEvent[] newArray(int size) {
1106            return new AccessibilityEvent[size];
1107        }
1108    };
1109}
1110