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