1 /* 2 * Copyright (C) 2009 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.view.accessibility; 18 19 import android.annotation.IntDef; 20 import android.annotation.UnsupportedAppUsage; 21 import android.os.Build; 22 import android.os.Parcel; 23 import android.os.Parcelable; 24 import android.text.TextUtils; 25 import android.util.Pools.SynchronizedPool; 26 27 import com.android.internal.util.BitUtils; 28 29 import java.lang.annotation.Retention; 30 import java.lang.annotation.RetentionPolicy; 31 import java.util.ArrayList; 32 import java.util.List; 33 34 /** 35 * <p> 36 * This class represents accessibility events that are sent by the system when 37 * something notable happens in the user interface. For example, when a 38 * {@link android.widget.Button} is clicked, a {@link android.view.View} is focused, etc. 39 * </p> 40 * <p> 41 * An accessibility event is fired by an individual view which populates the event with 42 * data for its state and requests from its parent to send the event to interested 43 * parties. The parent can optionally modify or even block the event based on its broader 44 * understanding of the user interface's context. 45 * </p> 46 * <p> 47 * The main purpose of an accessibility event is to communicate changes in the UI to an 48 * {@link android.accessibilityservice.AccessibilityService}. The service may then inspect, 49 * if needed the user interface by examining the View hierarchy, as represented by a tree of 50 * {@link AccessibilityNodeInfo}s (snapshot of a View state) 51 * which can be used for exploring the window content. Note that the privilege for accessing 52 * an event's source, thus the window content, has to be explicitly requested. For more 53 * details refer to {@link android.accessibilityservice.AccessibilityService}. If an 54 * accessibility service has not requested to retrieve the window content the event will 55 * not contain reference to its source. Also for events of type 56 * {@link #TYPE_NOTIFICATION_STATE_CHANGED} the source is never available. 57 * </p> 58 * <p> 59 * This class represents various semantically different accessibility event 60 * types. Each event type has an associated set of related properties. In other 61 * words, each event type is characterized via a subset of the properties exposed 62 * by this class. For each event type there is a corresponding constant defined 63 * in this class. Follows a specification of the event types and their associated properties: 64 * </p> 65 * <div class="special reference"> 66 * <h3>Developer Guides</h3> 67 * <p>For more information about creating and processing AccessibilityEvents, read the 68 * <a href="{@docRoot}guide/topics/ui/accessibility/index.html">Accessibility</a> 69 * developer guide.</p> 70 * </div> 71 * <p> 72 * <b>VIEW TYPES</b></br> 73 * </p> 74 * <p> 75 * <b>View clicked</b> - represents the event of clicking on a {@link android.view.View} 76 * like {@link android.widget.Button}, {@link android.widget.CompoundButton}, etc.</br> 77 * <em>Type:</em>{@link #TYPE_VIEW_CLICKED}</br> 78 * <em>Properties:</em></br> 79 * <ul> 80 * <li>{@link #getEventType()} - The type of the event.</li> 81 * <li>{@link #getSource()} - The source info (for registered clients).</li> 82 * <li>{@link #getClassName()} - The class name of the source.</li> 83 * <li>{@link #getPackageName()} - The package name of the source.</li> 84 * <li>{@link #getEventTime()} - The event time.</li> 85 * </ul> 86 * </p> 87 * <p> 88 * <b>View long clicked</b> - represents the event of long clicking on a {@link android.view.View} 89 * like {@link android.widget.Button}, {@link android.widget.CompoundButton}, etc </br> 90 * <em>Type:</em>{@link #TYPE_VIEW_LONG_CLICKED}</br> 91 * <em>Properties:</em></br> 92 * <ul> 93 * <li>{@link #getEventType()} - The type of the event.</li> 94 * <li>{@link #getSource()} - The source info (for registered clients).</li> 95 * <li>{@link #getClassName()} - The class name of the source.</li> 96 * <li>{@link #getPackageName()} - The package name of the source.</li> 97 * <li>{@link #getEventTime()} - The event time.</li> 98 * </ul> 99 * </p> 100 * <p> 101 * <b>View selected</b> - represents the event of selecting an item usually in 102 * the context of an {@link android.widget.AdapterView}.</br> 103 * <em>Type:</em> {@link #TYPE_VIEW_SELECTED}</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 * </ul> 112 * </p> 113 * <p> 114 * <b>View focused</b> - represents the event of focusing a 115 * {@link android.view.View}.</br> 116 * <em>Type:</em> {@link #TYPE_VIEW_FOCUSED}</br> 117 * <em>Properties:</em></br> 118 * <ul> 119 * <li>{@link #getEventType()} - The type of the event.</li> 120 * <li>{@link #getSource()} - The source info (for registered clients).</li> 121 * <li>{@link #getClassName()} - The class name of the source.</li> 122 * <li>{@link #getPackageName()} - The package name of the source.</li> 123 * <li>{@link #getEventTime()} - The event time.</li> 124 * </ul> 125 * </p> 126 * <p> 127 * <b>View text changed</b> - represents the event of changing the text of an 128 * {@link android.widget.EditText}.</br> 129 * <em>Type:</em> {@link #TYPE_VIEW_TEXT_CHANGED}</br> 130 * <em>Properties:</em></br> 131 * <ul> 132 * <li>{@link #getEventType()} - The type of the event.</li> 133 * <li>{@link #getSource()} - The source info (for registered clients).</li> 134 * <li>{@link #getClassName()} - The class name of the source.</li> 135 * <li>{@link #getPackageName()} - The package name of the source.</li> 136 * <li>{@link #getEventTime()} - The event time.</li> 137 * <li>{@link #getText()} - The new text of the source.</li> 138 * <li>{@link #getBeforeText()} - The text of the source before the change.</li> 139 * <li>{@link #getFromIndex()} - The text change start index.</li> 140 * <li>{@link #getAddedCount()} - The number of added characters.</li> 141 * <li>{@link #getRemovedCount()} - The number of removed characters.</li> 142 * </ul> 143 * </p> 144 * <p> 145 * <b>View text selection changed</b> - represents the event of changing the text 146 * selection of an {@link android.widget.EditText}.</br> 147 * <em>Type:</em> {@link #TYPE_VIEW_TEXT_SELECTION_CHANGED} </br> 148 * <em>Properties:</em></br> 149 * <ul> 150 * <li>{@link #getEventType()} - The type of the event.</li> 151 * <li>{@link #getSource()} - The source info (for registered clients).</li> 152 * <li>{@link #getClassName()} - The class name of the source.</li> 153 * <li>{@link #getPackageName()} - The package name of the source.</li> 154 * <li>{@link #getEventTime()} - The event time.</li> 155 * </ul> 156 * </p> 157 * <b>View text traversed at movement granularity</b> - represents the event of traversing the 158 * text of a view at a given granularity. For example, moving to the next word.</br> 159 * <em>Type:</em> {@link #TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY} </br> 160 * <em>Properties:</em></br> 161 * <ul> 162 * <li>{@link #getEventType()} - The type of the event.</li> 163 * <li>{@link #getSource()} - The source info (for registered clients).</li> 164 * <li>{@link #getClassName()} - The class name of the source.</li> 165 * <li>{@link #getPackageName()} - The package name of the source.</li> 166 * <li>{@link #getEventTime()} - The event time.</li> 167 * <li>{@link #getMovementGranularity()} - Sets the granularity at which a view's text 168 * was traversed.</li> 169 * <li>{@link #getText()} - The text of the source's sub-tree.</li> 170 * <li>{@link #getFromIndex()} - The start the text that was skipped over in this movement. 171 * This is the starting point when moving forward through the text, but not when moving 172 * back.</li> 173 * <li>{@link #getToIndex()} - The end of the text that was skipped over in this movement. 174 * This is the ending point when moving forward through the text, but not when moving 175 * back.</li> 176 * <li>{@link #getAction()} - Gets traversal action which specifies the direction.</li> 177 * </ul> 178 * </p> 179 * <p> 180 * <b>View scrolled</b> - represents the event of scrolling a view. </br> 181 * <em>Type:</em> {@link #TYPE_VIEW_SCROLLED}</br> 182 * <em>Properties:</em></br> 183 * <ul> 184 * <li>{@link #getEventType()} - The type of the event.</li> 185 * <li>{@link #getSource()} - The source info (for registered clients).</li> 186 * <li>{@link #getClassName()} - The class name of the source.</li> 187 * <li>{@link #getPackageName()} - The package name of the source.</li> 188 * <li>{@link #getEventTime()} - The event time.</li> 189 * <li>{@link #getScrollDeltaX()} - The difference in the horizontal position.</li> 190 * <li>{@link #getScrollDeltaY()} - The difference in the vertical position.</li> 191 * </ul> 192 * </p> 193 * <p> 194 * <b>TRANSITION TYPES</b></br> 195 * </p> 196 * <p> 197 * <b>Window state changed</b> - represents the event of a change to a section of 198 * the user interface that is visually distinct. Should be sent from either the 199 * root view of a window or from a view that is marked as a pane 200 * {@link android.view.View#setAccessibilityPaneTitle(CharSequence)}. Not that changes 201 * to true windows are represented by {@link #TYPE_WINDOWS_CHANGED}.</br> 202 * <em>Type:</em> {@link #TYPE_WINDOW_STATE_CHANGED}</br> 203 * <em>Properties:</em></br> 204 * <ul> 205 * <li>{@link #getEventType()} - The type of the event.</li> 206 * <li>{@link #getContentChangeTypes()} - The type of state changes.</li> 207 * <li>{@link #getSource()} - The source info (for registered clients).</li> 208 * <li>{@link #getClassName()} - The class name of the source.</li> 209 * <li>{@link #getPackageName()} - The package name of the source.</li> 210 * <li>{@link #getEventTime()} - The event time.</li> 211 * <li>{@link #getText()} - The text of the source's sub-tree, including the pane titles.</li> 212 * </ul> 213 * </p> 214 * <p> 215 * <b>Window content changed</b> - represents the event of change in the 216 * content of a window. This change can be adding/removing view, changing 217 * a view size, etc.</br> 218 * </p> 219 * <p> 220 * <em>Type:</em> {@link #TYPE_WINDOW_CONTENT_CHANGED}</br> 221 * <em>Properties:</em></br> 222 * <ul> 223 * <li>{@link #getEventType()} - The type of the event.</li> 224 * <li>{@link #getContentChangeTypes()} - The type of content changes.</li> 225 * <li>{@link #getSource()} - The source info (for registered clients).</li> 226 * <li>{@link #getClassName()} - The class name of the source.</li> 227 * <li>{@link #getPackageName()} - The package name of the source.</li> 228 * <li>{@link #getEventTime()} - The event time.</li> 229 * </ul> 230 * </p> 231 * <p> 232 * <b>Windows changed</b> - represents a change in the windows shown on 233 * the screen such as a window appeared, a window disappeared, a window size changed, 234 * a window layer changed, etc. These events should only come from the system, which is responsible 235 * for managing windows. The list of windows is available from 236 * {@link android.accessibilityservice.AccessibilityService#getWindows()}. 237 * For regions of the user interface that are presented as windows but are 238 * controlled by an app's process, use {@link #TYPE_WINDOW_STATE_CHANGED}.</br> 239 * <em>Type:</em> {@link #TYPE_WINDOWS_CHANGED}</br> 240 * <em>Properties:</em></br> 241 * <ul> 242 * <li>{@link #getEventType()} - The type of the event.</li> 243 * <li>{@link #getEventTime()} - The event time.</li> 244 * <li>{@link #getWindowChanges()}</li> - The specific change to the source window 245 * </ul> 246 * <em>Note:</em> You can retrieve the {@link AccessibilityWindowInfo} for the window 247 * source of the event by looking through the list returned by 248 * {@link android.accessibilityservice.AccessibilityService#getWindows()} for the window whose ID 249 * matches {@link #getWindowId()}. 250 * </p> 251 * <p> 252 * <b>NOTIFICATION TYPES</b></br> 253 * </p> 254 * <p> 255 * <b>Notification state changed</b> - represents the event showing a transient piece of information 256 * to the user. This information may be a {@link android.app.Notification} or 257 * {@link android.widget.Toast}.</br> 258 * <em>Type:</em> {@link #TYPE_NOTIFICATION_STATE_CHANGED}</br> 259 * <em>Properties:</em></br> 260 * <ul> 261 * <li>{@link #getEventType()} - The type of the event.</li> 262 * <li>{@link #getClassName()} - The class name of the source.</li> 263 * <li>{@link #getPackageName()} - The package name of the source.</li> 264 * <li>{@link #getEventTime()} - The event time.</li> 265 * <li>{@link #getParcelableData()} - The posted {@link android.app.Notification}, if 266 * applicable.</li> 267 * <li>{@link #getText()} - Displayed text of the {@link android.widget.Toast}, if applicable, 268 * or may contain text from the {@link android.app.Notification}, although 269 * {@link #getParcelableData()} is a richer set of data for {@link android.app.Notification}.</li> 270 * </ul> 271 * </p> 272 * <p> 273 * <b>EXPLORATION TYPES</b></br> 274 * </p> 275 * <p> 276 * <b>View hover enter</b> - represents the event of beginning to hover 277 * over a {@link android.view.View}. The hover may be generated via 278 * exploring the screen by touch or via a pointing device.</br> 279 * <em>Type:</em> {@link #TYPE_VIEW_HOVER_ENTER}</br> 280 * <em>Properties:</em></br> 281 * <ul> 282 * <li>{@link #getEventType()} - The type of the event.</li> 283 * <li>{@link #getSource()} - The source info (for registered clients).</li> 284 * <li>{@link #getClassName()} - The class name of the source.</li> 285 * <li>{@link #getPackageName()} - The package name of the source.</li> 286 * <li>{@link #getEventTime()} - The event time.</li> 287 * </ul> 288 * </p> 289 * <b>View hover exit</b> - represents the event of stopping to hover 290 * over a {@link android.view.View}. The hover may be generated via 291 * exploring the screen by touch or via a pointing device.</br> 292 * <em>Type:</em> {@link #TYPE_VIEW_HOVER_EXIT}</br> 293 * <em>Properties:</em></br> 294 * <ul> 295 * <li>{@link #getEventType()} - The type of the event.</li> 296 * <li>{@link #getSource()} - The source info (for registered clients).</li> 297 * <li>{@link #getClassName()} - The class name of the source.</li> 298 * <li>{@link #getPackageName()} - The package name of the source.</li> 299 * <li>{@link #getEventTime()} - The event time.</li> 300 * </ul> 301 * </p> 302 * <p> 303 * <b>Touch interaction start</b> - represents the event of starting a touch 304 * interaction, which is the user starts touching the screen.</br> 305 * <em>Type:</em> {@link #TYPE_TOUCH_INTERACTION_START}</br> 306 * <em>Properties:</em></br> 307 * <ul> 308 * <li>{@link #getEventType()} - The type of the event.</li> 309 * </ul> 310 * <em>Note:</em> This event is fired only by the system and is not passed to the 311 * view tree to be populated.</br> 312 * </p> 313 * <p> 314 * <b>Touch interaction end</b> - represents the event of ending a touch 315 * interaction, which is the user stops touching the screen.</br> 316 * <em>Type:</em> {@link #TYPE_TOUCH_INTERACTION_END}</br> 317 * <em>Properties:</em></br> 318 * <ul> 319 * <li>{@link #getEventType()} - The type of the event.</li> 320 * </ul> 321 * <em>Note:</em> This event is fired only by the system and is not passed to the 322 * view tree to be populated.</br> 323 * </p> 324 * <p> 325 * <b>Touch exploration gesture start</b> - represents the event of starting a touch 326 * exploring gesture.</br> 327 * <em>Type:</em> {@link #TYPE_TOUCH_EXPLORATION_GESTURE_START}</br> 328 * <em>Properties:</em></br> 329 * <ul> 330 * <li>{@link #getEventType()} - The type of the event.</li> 331 * </ul> 332 * <em>Note:</em> This event is fired only by the system and is not passed to the 333 * view tree to be populated.</br> 334 * </p> 335 * <p> 336 * <b>Touch exploration gesture end</b> - represents the event of ending a touch 337 * exploring gesture.</br> 338 * <em>Type:</em> {@link #TYPE_TOUCH_EXPLORATION_GESTURE_END}</br> 339 * <em>Properties:</em></br> 340 * <ul> 341 * <li>{@link #getEventType()} - The type of the event.</li> 342 * </ul> 343 * <em>Note:</em> This event is fired only by the system and is not passed to the 344 * view tree to be populated.</br> 345 * </p> 346 * <p> 347 * <b>Touch gesture detection start</b> - represents the event of starting a user 348 * gesture detection.</br> 349 * <em>Type:</em> {@link #TYPE_GESTURE_DETECTION_START}</br> 350 * <em>Properties:</em></br> 351 * <ul> 352 * <li>{@link #getEventType()} - The type of the event.</li> 353 * </ul> 354 * <em>Note:</em> This event is fired only by the system and is not passed to the 355 * view tree to be populated.</br> 356 * </p> 357 * <p> 358 * <b>Touch gesture detection end</b> - represents the event of ending a user 359 * gesture detection.</br> 360 * <em>Type:</em> {@link #TYPE_GESTURE_DETECTION_END}</br> 361 * <em>Properties:</em></br> 362 * <ul> 363 * <li>{@link #getEventType()} - The type of the event.</li> 364 * </ul> 365 * <em>Note:</em> This event is fired only by the system and is not passed to the 366 * view tree to be populated.</br> 367 * </p> 368 * <p> 369 * <b>MISCELLANEOUS TYPES</b></br> 370 * </p> 371 * <p> 372 * <b>Announcement</b> - represents the event of an application requesting a screen reader to make 373 * an announcement. Because the event carries no semantic meaning, this event is appropriate only 374 * in exceptional situations where additional screen reader output is needed but other types of 375 * accessibility services do not need to be aware of the change.</br> 376 * <em>Type:</em> {@link #TYPE_ANNOUNCEMENT}</br> 377 * <em>Properties:</em></br> 378 * <ul> 379 * <li>{@link #getEventType()} - The type of the event.</li> 380 * <li>{@link #getSource()} - The source info (for registered clients).</li> 381 * <li>{@link #getClassName()} - The class name of the source.</li> 382 * <li>{@link #getPackageName()} - The package name of the source.</li> 383 * <li>{@link #getEventTime()} - The event time.</li> 384 * <li>{@link #getText()} - The text of the announcement.</li> 385 * </ul> 386 * </p> 387 * 388 * @see android.view.accessibility.AccessibilityManager 389 * @see android.accessibilityservice.AccessibilityService 390 * @see AccessibilityNodeInfo 391 */ 392 public final class AccessibilityEvent extends AccessibilityRecord implements Parcelable { 393 private static final boolean DEBUG = false; 394 /** @hide */ 395 public static final boolean DEBUG_ORIGIN = false; 396 397 /** 398 * Invalid selection/focus position. 399 * 400 * @see #getCurrentItemIndex() 401 */ 402 public static final int INVALID_POSITION = -1; 403 404 /** 405 * Maximum length of the text fields. 406 * 407 * @see #getBeforeText() 408 * @see #getText() 409 * </br> 410 * Note: This constant is no longer needed since there 411 * is no limit on the length of text that is contained 412 * in an accessibility event anymore. 413 */ 414 @Deprecated 415 public static final int MAX_TEXT_LENGTH = 500; 416 417 /** 418 * Represents the event of clicking on a {@link android.view.View} like 419 * {@link android.widget.Button}, {@link android.widget.CompoundButton}, etc. 420 */ 421 public static final int TYPE_VIEW_CLICKED = 0x00000001; 422 423 /** 424 * Represents the event of long clicking on a {@link android.view.View} like 425 * {@link android.widget.Button}, {@link android.widget.CompoundButton}, etc. 426 */ 427 public static final int TYPE_VIEW_LONG_CLICKED = 0x00000002; 428 429 /** 430 * Represents the event of selecting an item usually in the context of an 431 * {@link android.widget.AdapterView}. 432 */ 433 public static final int TYPE_VIEW_SELECTED = 0x00000004; 434 435 /** 436 * Represents the event of setting input focus of a {@link android.view.View}. 437 */ 438 public static final int TYPE_VIEW_FOCUSED = 0x00000008; 439 440 /** 441 * Represents the event of changing the text of an {@link android.widget.EditText}. 442 */ 443 public static final int TYPE_VIEW_TEXT_CHANGED = 0x00000010; 444 445 /** 446 * Represents the event of a change to a visually distinct section of the user interface. 447 * These events should only be dispatched from {@link android.view.View}s that have 448 * accessibility pane titles, and replaces {@link #TYPE_WINDOW_CONTENT_CHANGED} for those 449 * sources. Details about the change are available from {@link #getContentChangeTypes()}. 450 */ 451 public static final int TYPE_WINDOW_STATE_CHANGED = 0x00000020; 452 453 /** 454 * Represents the event showing a {@link android.app.Notification}. 455 */ 456 public static final int TYPE_NOTIFICATION_STATE_CHANGED = 0x00000040; 457 458 /** 459 * Represents the event of a hover enter over a {@link android.view.View}. 460 */ 461 public static final int TYPE_VIEW_HOVER_ENTER = 0x00000080; 462 463 /** 464 * Represents the event of a hover exit over a {@link android.view.View}. 465 */ 466 public static final int TYPE_VIEW_HOVER_EXIT = 0x00000100; 467 468 /** 469 * Represents the event of starting a touch exploration gesture. 470 */ 471 public static final int TYPE_TOUCH_EXPLORATION_GESTURE_START = 0x00000200; 472 473 /** 474 * Represents the event of ending a touch exploration gesture. 475 */ 476 public static final int TYPE_TOUCH_EXPLORATION_GESTURE_END = 0x00000400; 477 478 /** 479 * Represents the event of changing the content of a window and more 480 * specifically the sub-tree rooted at the event's source. 481 */ 482 public static final int TYPE_WINDOW_CONTENT_CHANGED = 0x00000800; 483 484 /** 485 * Represents the event of scrolling a view. This event type is generally not sent directly. 486 * @see android.view.View#onScrollChanged(int, int, int, int) 487 */ 488 public static final int TYPE_VIEW_SCROLLED = 0x00001000; 489 490 /** 491 * Represents the event of changing the selection in an {@link android.widget.EditText}. 492 */ 493 public static final int TYPE_VIEW_TEXT_SELECTION_CHANGED = 0x00002000; 494 495 /** 496 * Represents the event of an application making an announcement. 497 */ 498 public static final int TYPE_ANNOUNCEMENT = 0x00004000; 499 500 /** 501 * Represents the event of gaining accessibility focus. 502 */ 503 public static final int TYPE_VIEW_ACCESSIBILITY_FOCUSED = 0x00008000; 504 505 /** 506 * Represents the event of clearing accessibility focus. 507 */ 508 public static final int TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED = 0x00010000; 509 510 /** 511 * Represents the event of traversing the text of a view at a given movement granularity. 512 */ 513 public static final int TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY = 0x00020000; 514 515 /** 516 * Represents the event of beginning gesture detection. 517 */ 518 public static final int TYPE_GESTURE_DETECTION_START = 0x00040000; 519 520 /** 521 * Represents the event of ending gesture detection. 522 */ 523 public static final int TYPE_GESTURE_DETECTION_END = 0x00080000; 524 525 /** 526 * Represents the event of the user starting to touch the screen. 527 */ 528 public static final int TYPE_TOUCH_INTERACTION_START = 0x00100000; 529 530 /** 531 * Represents the event of the user ending to touch the screen. 532 */ 533 public static final int TYPE_TOUCH_INTERACTION_END = 0x00200000; 534 535 /** 536 * Represents the event change in the system windows shown on the screen. This event type should 537 * only be dispatched by the system. 538 */ 539 public static final int TYPE_WINDOWS_CHANGED = 0x00400000; 540 541 /** 542 * Represents the event of a context click on a {@link android.view.View}. 543 */ 544 public static final int TYPE_VIEW_CONTEXT_CLICKED = 0x00800000; 545 546 /** 547 * Represents the event of the assistant currently reading the users screen context. 548 */ 549 public static final int TYPE_ASSIST_READING_CONTEXT = 0x01000000; 550 551 /** 552 * Change type for {@link #TYPE_WINDOW_CONTENT_CHANGED} event: 553 * The type of change is not defined. 554 */ 555 public static final int CONTENT_CHANGE_TYPE_UNDEFINED = 0x00000000; 556 557 /** 558 * Change type for {@link #TYPE_WINDOW_CONTENT_CHANGED} event: 559 * One or more content changes occurred in the the subtree rooted at the source node, 560 * or the subtree's structure changed when a node was added or removed. 561 */ 562 public static final int CONTENT_CHANGE_TYPE_SUBTREE = 0x00000001; 563 564 /** 565 * Change type for {@link #TYPE_WINDOW_CONTENT_CHANGED} event: 566 * The node's text changed. 567 */ 568 public static final int CONTENT_CHANGE_TYPE_TEXT = 0x00000002; 569 570 /** 571 * Change type for {@link #TYPE_WINDOW_CONTENT_CHANGED} event: 572 * The node's content description changed. 573 */ 574 public static final int CONTENT_CHANGE_TYPE_CONTENT_DESCRIPTION = 0x00000004; 575 576 /** 577 * Change type for {@link #TYPE_WINDOW_STATE_CHANGED} event: 578 * The node's pane title changed. 579 */ 580 public static final int CONTENT_CHANGE_TYPE_PANE_TITLE = 0x00000008; 581 582 /** 583 * Change type for {@link #TYPE_WINDOW_STATE_CHANGED} event: 584 * The node has a pane title, and either just appeared or just was assigned a title when it 585 * had none before. 586 */ 587 public static final int CONTENT_CHANGE_TYPE_PANE_APPEARED = 0x00000010; 588 589 /** 590 * Change type for {@link #TYPE_WINDOW_STATE_CHANGED} event: 591 * Can mean one of two slightly different things. The primary meaning is that the node has 592 * a pane title, and was removed from the node hierarchy. It will also be sent if the pane 593 * title is set to {@code null} after it contained a title. 594 * No source will be returned if the node is no longer on the screen. To make the change more 595 * clear for the user, the first entry in {@link #getText()} will return the value that would 596 * have been returned by {@code getSource().getPaneTitle()}. 597 */ 598 public static final int CONTENT_CHANGE_TYPE_PANE_DISAPPEARED = 0x00000020; 599 600 /** 601 * Change type for {@link #TYPE_WINDOWS_CHANGED} event: 602 * The window was added. 603 */ 604 public static final int WINDOWS_CHANGE_ADDED = 0x00000001; 605 606 /** 607 * Change type for {@link #TYPE_WINDOWS_CHANGED} event: 608 * A window was removed. 609 */ 610 public static final int WINDOWS_CHANGE_REMOVED = 0x00000002; 611 612 /** 613 * Change type for {@link #TYPE_WINDOWS_CHANGED} event: 614 * The window's title changed. 615 */ 616 public static final int WINDOWS_CHANGE_TITLE = 0x00000004; 617 618 /** 619 * Change type for {@link #TYPE_WINDOWS_CHANGED} event: 620 * The window's bounds changed. 621 */ 622 public static final int WINDOWS_CHANGE_BOUNDS = 0x00000008; 623 624 /** 625 * Change type for {@link #TYPE_WINDOWS_CHANGED} event: 626 * The window's layer changed. 627 */ 628 public static final int WINDOWS_CHANGE_LAYER = 0x00000010; 629 630 /** 631 * Change type for {@link #TYPE_WINDOWS_CHANGED} event: 632 * The window's {@link AccessibilityWindowInfo#isActive()} changed. 633 */ 634 public static final int WINDOWS_CHANGE_ACTIVE = 0x00000020; 635 636 /** 637 * Change type for {@link #TYPE_WINDOWS_CHANGED} event: 638 * The window's {@link AccessibilityWindowInfo#isFocused()} changed. 639 */ 640 public static final int WINDOWS_CHANGE_FOCUSED = 0x00000040; 641 642 /** 643 * Change type for {@link #TYPE_WINDOWS_CHANGED} event: 644 * The window's {@link AccessibilityWindowInfo#isAccessibilityFocused()} changed. 645 */ 646 public static final int WINDOWS_CHANGE_ACCESSIBILITY_FOCUSED = 0x00000080; 647 648 /** 649 * Change type for {@link #TYPE_WINDOWS_CHANGED} event: 650 * The window's parent changed. 651 */ 652 public static final int WINDOWS_CHANGE_PARENT = 0x00000100; 653 654 /** 655 * Change type for {@link #TYPE_WINDOWS_CHANGED} event: 656 * The window's children changed. 657 */ 658 public static final int WINDOWS_CHANGE_CHILDREN = 0x00000200; 659 660 /** 661 * Change type for {@link #TYPE_WINDOWS_CHANGED} event: 662 * The window either entered or exited picture-in-picture mode. 663 */ 664 public static final int WINDOWS_CHANGE_PIP = 0x00000400; 665 666 /** @hide */ 667 @Retention(RetentionPolicy.SOURCE) 668 @IntDef(flag = true, prefix = { "WINDOWS_CHANGE_" }, value = { 669 WINDOWS_CHANGE_ADDED, 670 WINDOWS_CHANGE_REMOVED, 671 WINDOWS_CHANGE_TITLE, 672 WINDOWS_CHANGE_BOUNDS, 673 WINDOWS_CHANGE_LAYER, 674 WINDOWS_CHANGE_ACTIVE, 675 WINDOWS_CHANGE_FOCUSED, 676 WINDOWS_CHANGE_ACCESSIBILITY_FOCUSED, 677 WINDOWS_CHANGE_PARENT, 678 WINDOWS_CHANGE_CHILDREN, 679 WINDOWS_CHANGE_PIP 680 }) 681 public @interface WindowsChangeTypes {} 682 683 /** @hide */ 684 @Retention(RetentionPolicy.SOURCE) 685 @IntDef(flag = true, prefix = { "CONTENT_CHANGE_TYPE_" }, 686 value = { 687 CONTENT_CHANGE_TYPE_UNDEFINED, 688 CONTENT_CHANGE_TYPE_SUBTREE, 689 CONTENT_CHANGE_TYPE_TEXT, 690 CONTENT_CHANGE_TYPE_CONTENT_DESCRIPTION, 691 CONTENT_CHANGE_TYPE_PANE_TITLE, 692 CONTENT_CHANGE_TYPE_PANE_APPEARED, 693 CONTENT_CHANGE_TYPE_PANE_DISAPPEARED 694 }) 695 public @interface ContentChangeTypes {} 696 697 /** @hide */ 698 @IntDef(flag = true, prefix = { "TYPE_" }, value = { 699 TYPE_VIEW_CLICKED, 700 TYPE_VIEW_LONG_CLICKED, 701 TYPE_VIEW_SELECTED, 702 TYPE_VIEW_FOCUSED, 703 TYPE_VIEW_TEXT_CHANGED, 704 TYPE_WINDOW_STATE_CHANGED, 705 TYPE_NOTIFICATION_STATE_CHANGED, 706 TYPE_VIEW_HOVER_ENTER, 707 TYPE_VIEW_HOVER_EXIT, 708 TYPE_TOUCH_EXPLORATION_GESTURE_START, 709 TYPE_TOUCH_EXPLORATION_GESTURE_END, 710 TYPE_WINDOW_CONTENT_CHANGED, 711 TYPE_VIEW_SCROLLED, 712 TYPE_VIEW_TEXT_SELECTION_CHANGED, 713 TYPE_ANNOUNCEMENT, 714 TYPE_VIEW_ACCESSIBILITY_FOCUSED, 715 TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED, 716 TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY, 717 TYPE_GESTURE_DETECTION_START, 718 TYPE_GESTURE_DETECTION_END, 719 TYPE_TOUCH_INTERACTION_START, 720 TYPE_TOUCH_INTERACTION_END, 721 TYPE_WINDOWS_CHANGED, 722 TYPE_VIEW_CONTEXT_CLICKED, 723 TYPE_ASSIST_READING_CONTEXT 724 }) 725 @Retention(RetentionPolicy.SOURCE) 726 public @interface EventType {} 727 728 /** 729 * Mask for {@link AccessibilityEvent} all types. 730 * 731 * @see #TYPE_VIEW_CLICKED 732 * @see #TYPE_VIEW_LONG_CLICKED 733 * @see #TYPE_VIEW_SELECTED 734 * @see #TYPE_VIEW_FOCUSED 735 * @see #TYPE_VIEW_TEXT_CHANGED 736 * @see #TYPE_WINDOW_STATE_CHANGED 737 * @see #TYPE_NOTIFICATION_STATE_CHANGED 738 * @see #TYPE_VIEW_HOVER_ENTER 739 * @see #TYPE_VIEW_HOVER_EXIT 740 * @see #TYPE_TOUCH_EXPLORATION_GESTURE_START 741 * @see #TYPE_TOUCH_EXPLORATION_GESTURE_END 742 * @see #TYPE_WINDOW_CONTENT_CHANGED 743 * @see #TYPE_VIEW_SCROLLED 744 * @see #TYPE_VIEW_TEXT_SELECTION_CHANGED 745 * @see #TYPE_ANNOUNCEMENT 746 * @see #TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY 747 * @see #TYPE_GESTURE_DETECTION_START 748 * @see #TYPE_GESTURE_DETECTION_END 749 * @see #TYPE_TOUCH_INTERACTION_START 750 * @see #TYPE_TOUCH_INTERACTION_END 751 * @see #TYPE_WINDOWS_CHANGED 752 * @see #TYPE_VIEW_CONTEXT_CLICKED 753 */ 754 public static final int TYPES_ALL_MASK = 0xFFFFFFFF; 755 756 private static final int MAX_POOL_SIZE = 10; 757 private static final SynchronizedPool<AccessibilityEvent> sPool = 758 new SynchronizedPool<>(MAX_POOL_SIZE); 759 760 @UnsupportedAppUsage 761 private @EventType int mEventType; 762 private CharSequence mPackageName; 763 private long mEventTime; 764 int mMovementGranularity; 765 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) 766 int mAction; 767 int mContentChangeTypes; 768 int mWindowChangeTypes; 769 770 /** 771 * The stack trace describing where this event originated from on the app side. 772 * Only populated if {@link #DEBUG_ORIGIN} is enabled 773 * Can be inspected(e.g. printed) from an 774 * {@link android.accessibilityservice.AccessibilityService} to trace where particular events 775 * are being dispatched from. 776 * 777 * @hide 778 */ 779 public StackTraceElement[] originStackTrace = null; 780 781 private ArrayList<AccessibilityRecord> mRecords; 782 783 /* 784 * Hide constructor from clients. 785 */ AccessibilityEvent()786 private AccessibilityEvent() { 787 } 788 789 /** 790 * Initialize an event from another one. 791 * 792 * @param event The event to initialize from. 793 */ init(AccessibilityEvent event)794 void init(AccessibilityEvent event) { 795 super.init(event); 796 mEventType = event.mEventType; 797 mMovementGranularity = event.mMovementGranularity; 798 mAction = event.mAction; 799 mContentChangeTypes = event.mContentChangeTypes; 800 mWindowChangeTypes = event.mWindowChangeTypes; 801 mEventTime = event.mEventTime; 802 mPackageName = event.mPackageName; 803 if (DEBUG_ORIGIN) originStackTrace = event.originStackTrace; 804 } 805 806 /** 807 * Sets if this instance is sealed. 808 * 809 * @param sealed Whether is sealed. 810 * 811 * @hide 812 */ 813 @Override setSealed(boolean sealed)814 public void setSealed(boolean sealed) { 815 super.setSealed(sealed); 816 final List<AccessibilityRecord> records = mRecords; 817 if (records != null) { 818 final int recordCount = records.size(); 819 for (int i = 0; i < recordCount; i++) { 820 AccessibilityRecord record = records.get(i); 821 record.setSealed(sealed); 822 } 823 } 824 } 825 826 /** 827 * Gets the number of records contained in the event. 828 * 829 * @return The number of records. 830 */ getRecordCount()831 public int getRecordCount() { 832 return mRecords == null ? 0 : mRecords.size(); 833 } 834 835 /** 836 * Appends an {@link AccessibilityRecord} to the end of event records. 837 * 838 * @param record The record to append. 839 * 840 * @throws IllegalStateException If called from an AccessibilityService. 841 */ appendRecord(AccessibilityRecord record)842 public void appendRecord(AccessibilityRecord record) { 843 enforceNotSealed(); 844 if (mRecords == null) { 845 mRecords = new ArrayList<AccessibilityRecord>(); 846 } 847 mRecords.add(record); 848 } 849 850 /** 851 * Gets the record at a given index. 852 * 853 * @param index The index. 854 * @return The record at the specified index. 855 */ getRecord(int index)856 public AccessibilityRecord getRecord(int index) { 857 if (mRecords == null) { 858 throw new IndexOutOfBoundsException("Invalid index " + index + ", size is 0"); 859 } 860 return mRecords.get(index); 861 } 862 863 /** 864 * Gets the event type. 865 * 866 * @return The event type. 867 */ getEventType()868 public @EventType int getEventType() { 869 return mEventType; 870 } 871 872 /** 873 * Gets the bit mask of change types signaled by a 874 * {@link #TYPE_WINDOW_CONTENT_CHANGED} event or {@link #TYPE_WINDOW_STATE_CHANGED}. A single 875 * event may represent multiple change types. 876 * 877 * @return The bit mask of change types. One or more of: 878 * <ul> 879 * <li>{@link #CONTENT_CHANGE_TYPE_CONTENT_DESCRIPTION} 880 * <li>{@link #CONTENT_CHANGE_TYPE_SUBTREE} 881 * <li>{@link #CONTENT_CHANGE_TYPE_TEXT} 882 * <li>{@link #CONTENT_CHANGE_TYPE_PANE_TITLE} 883 * <li>{@link #CONTENT_CHANGE_TYPE_UNDEFINED} 884 * <li>{@link #CONTENT_CHANGE_TYPE_PANE_APPEARED} 885 * <li>{@link #CONTENT_CHANGE_TYPE_PANE_DISAPPEARED} 886 * </ul> 887 */ 888 @ContentChangeTypes getContentChangeTypes()889 public int getContentChangeTypes() { 890 return mContentChangeTypes; 891 } 892 contentChangeTypesToString(int types)893 private static String contentChangeTypesToString(int types) { 894 return BitUtils.flagsToString(types, AccessibilityEvent::singleContentChangeTypeToString); 895 } 896 singleContentChangeTypeToString(int type)897 private static String singleContentChangeTypeToString(int type) { 898 switch (type) { 899 case CONTENT_CHANGE_TYPE_CONTENT_DESCRIPTION: 900 return "CONTENT_CHANGE_TYPE_CONTENT_DESCRIPTION"; 901 case CONTENT_CHANGE_TYPE_SUBTREE: return "CONTENT_CHANGE_TYPE_SUBTREE"; 902 case CONTENT_CHANGE_TYPE_TEXT: return "CONTENT_CHANGE_TYPE_TEXT"; 903 case CONTENT_CHANGE_TYPE_PANE_TITLE: return "CONTENT_CHANGE_TYPE_PANE_TITLE"; 904 case CONTENT_CHANGE_TYPE_UNDEFINED: return "CONTENT_CHANGE_TYPE_UNDEFINED"; 905 case CONTENT_CHANGE_TYPE_PANE_APPEARED: return "CONTENT_CHANGE_TYPE_PANE_APPEARED"; 906 case CONTENT_CHANGE_TYPE_PANE_DISAPPEARED: 907 return "CONTENT_CHANGE_TYPE_PANE_DISAPPEARED"; 908 default: return Integer.toHexString(type); 909 } 910 } 911 912 /** 913 * Sets the bit mask of node tree changes signaled by an 914 * {@link #TYPE_WINDOW_CONTENT_CHANGED} event. 915 * 916 * @param changeTypes The bit mask of change types. 917 * @throws IllegalStateException If called from an AccessibilityService. 918 * @see #getContentChangeTypes() 919 */ setContentChangeTypes(@ontentChangeTypes int changeTypes)920 public void setContentChangeTypes(@ContentChangeTypes int changeTypes) { 921 enforceNotSealed(); 922 mContentChangeTypes = changeTypes; 923 } 924 925 /** 926 * Get the bit mask of change types signaled by a {@link #TYPE_WINDOWS_CHANGED} event. A 927 * single event may represent multiple change types. 928 * 929 * @return The bit mask of change types. 930 */ 931 @WindowsChangeTypes getWindowChanges()932 public int getWindowChanges() { 933 return mWindowChangeTypes; 934 } 935 936 /** @hide */ setWindowChanges(@indowsChangeTypes int changes)937 public void setWindowChanges(@WindowsChangeTypes int changes) { 938 mWindowChangeTypes = changes; 939 } 940 windowChangeTypesToString(@indowsChangeTypes int types)941 private static String windowChangeTypesToString(@WindowsChangeTypes int types) { 942 return BitUtils.flagsToString(types, AccessibilityEvent::singleWindowChangeTypeToString); 943 } 944 singleWindowChangeTypeToString(int type)945 private static String singleWindowChangeTypeToString(int type) { 946 switch (type) { 947 case WINDOWS_CHANGE_ADDED: return "WINDOWS_CHANGE_ADDED"; 948 case WINDOWS_CHANGE_REMOVED: return "WINDOWS_CHANGE_REMOVED"; 949 case WINDOWS_CHANGE_TITLE: return "WINDOWS_CHANGE_TITLE"; 950 case WINDOWS_CHANGE_BOUNDS: return "WINDOWS_CHANGE_BOUNDS"; 951 case WINDOWS_CHANGE_LAYER: return "WINDOWS_CHANGE_LAYER"; 952 case WINDOWS_CHANGE_ACTIVE: return "WINDOWS_CHANGE_ACTIVE"; 953 case WINDOWS_CHANGE_FOCUSED: return "WINDOWS_CHANGE_FOCUSED"; 954 case WINDOWS_CHANGE_ACCESSIBILITY_FOCUSED: 955 return "WINDOWS_CHANGE_ACCESSIBILITY_FOCUSED"; 956 case WINDOWS_CHANGE_PARENT: return "WINDOWS_CHANGE_PARENT"; 957 case WINDOWS_CHANGE_CHILDREN: return "WINDOWS_CHANGE_CHILDREN"; 958 case WINDOWS_CHANGE_PIP: return "WINDOWS_CHANGE_PIP"; 959 default: return Integer.toHexString(type); 960 } 961 } 962 963 /** 964 * Sets the event type. 965 * 966 * @param eventType The event type. 967 * 968 * @throws IllegalStateException If called from an AccessibilityService. 969 */ setEventType(@ventType int eventType)970 public void setEventType(@EventType int eventType) { 971 enforceNotSealed(); 972 mEventType = eventType; 973 } 974 975 /** 976 * Gets the time in which this event was sent. 977 * 978 * @return The event time. 979 */ getEventTime()980 public long getEventTime() { 981 return mEventTime; 982 } 983 984 /** 985 * Sets the time in which this event was sent. 986 * 987 * @param eventTime The event time. 988 * 989 * @throws IllegalStateException If called from an AccessibilityService. 990 */ setEventTime(long eventTime)991 public void setEventTime(long eventTime) { 992 enforceNotSealed(); 993 mEventTime = eventTime; 994 } 995 996 /** 997 * Gets the package name of the source. 998 * 999 * @return The package name. 1000 */ getPackageName()1001 public CharSequence getPackageName() { 1002 return mPackageName; 1003 } 1004 1005 /** 1006 * Sets the package name of the source. 1007 * 1008 * @param packageName The package name. 1009 * 1010 * @throws IllegalStateException If called from an AccessibilityService. 1011 */ setPackageName(CharSequence packageName)1012 public void setPackageName(CharSequence packageName) { 1013 enforceNotSealed(); 1014 mPackageName = packageName; 1015 } 1016 1017 /** 1018 * Sets the movement granularity that was traversed. 1019 * 1020 * @param granularity The granularity. 1021 * 1022 * @throws IllegalStateException If called from an AccessibilityService. 1023 */ setMovementGranularity(int granularity)1024 public void setMovementGranularity(int granularity) { 1025 enforceNotSealed(); 1026 mMovementGranularity = granularity; 1027 } 1028 1029 /** 1030 * Gets the movement granularity that was traversed. 1031 * 1032 * @return The granularity. 1033 */ getMovementGranularity()1034 public int getMovementGranularity() { 1035 return mMovementGranularity; 1036 } 1037 1038 /** 1039 * Sets the performed action that triggered this event. 1040 * <p> 1041 * Valid actions are defined in {@link AccessibilityNodeInfo}: 1042 * <ul> 1043 * <li>{@link AccessibilityNodeInfo#ACTION_ACCESSIBILITY_FOCUS} 1044 * <li>{@link AccessibilityNodeInfo#ACTION_CLEAR_ACCESSIBILITY_FOCUS} 1045 * <li>{@link AccessibilityNodeInfo#ACTION_CLEAR_FOCUS} 1046 * <li>{@link AccessibilityNodeInfo#ACTION_CLEAR_SELECTION} 1047 * <li>{@link AccessibilityNodeInfo#ACTION_CLICK} 1048 * <li>etc. 1049 * </ul> 1050 * 1051 * @param action The action. 1052 * @throws IllegalStateException If called from an AccessibilityService. 1053 * @see AccessibilityNodeInfo#performAction(int) 1054 */ setAction(int action)1055 public void setAction(int action) { 1056 enforceNotSealed(); 1057 mAction = action; 1058 } 1059 1060 /** 1061 * Gets the performed action that triggered this event. 1062 * 1063 * @return The action. 1064 */ getAction()1065 public int getAction() { 1066 return mAction; 1067 } 1068 1069 /** 1070 * Convenience method to obtain a {@link #TYPE_WINDOWS_CHANGED} event for a specific window and 1071 * change set. 1072 * 1073 * @param windowId The ID of the window that changed 1074 * @param windowChangeTypes The changes to populate 1075 * @return An instance of a TYPE_WINDOWS_CHANGED, populated with the requested fields and with 1076 * importantForAccessibility set to {@code true}. 1077 * 1078 * @hide 1079 */ obtainWindowsChangedEvent( int windowId, int windowChangeTypes)1080 public static AccessibilityEvent obtainWindowsChangedEvent( 1081 int windowId, int windowChangeTypes) { 1082 final AccessibilityEvent event = AccessibilityEvent.obtain(TYPE_WINDOWS_CHANGED); 1083 event.setWindowId(windowId); 1084 event.setWindowChanges(windowChangeTypes); 1085 event.setImportantForAccessibility(true); 1086 return event; 1087 } 1088 1089 /** 1090 * Returns a cached instance if such is available or a new one is 1091 * instantiated with its type property set. 1092 * 1093 * @param eventType The event type. 1094 * @return An instance. 1095 */ obtain(int eventType)1096 public static AccessibilityEvent obtain(int eventType) { 1097 AccessibilityEvent event = AccessibilityEvent.obtain(); 1098 event.setEventType(eventType); 1099 return event; 1100 } 1101 1102 /** 1103 * Returns a cached instance if such is available or a new one is 1104 * created. The returned instance is initialized from the given 1105 * <code>event</code>. 1106 * 1107 * @param event The other event. 1108 * @return An instance. 1109 */ obtain(AccessibilityEvent event)1110 public static AccessibilityEvent obtain(AccessibilityEvent event) { 1111 AccessibilityEvent eventClone = AccessibilityEvent.obtain(); 1112 eventClone.init(event); 1113 1114 if (event.mRecords != null) { 1115 final int recordCount = event.mRecords.size(); 1116 eventClone.mRecords = new ArrayList<AccessibilityRecord>(recordCount); 1117 for (int i = 0; i < recordCount; i++) { 1118 final AccessibilityRecord record = event.mRecords.get(i); 1119 final AccessibilityRecord recordClone = AccessibilityRecord.obtain(record); 1120 eventClone.mRecords.add(recordClone); 1121 } 1122 } 1123 1124 return eventClone; 1125 } 1126 1127 /** 1128 * Returns a cached instance if such is available or a new one is 1129 * instantiated. 1130 * 1131 * @return An instance. 1132 */ obtain()1133 public static AccessibilityEvent obtain() { 1134 AccessibilityEvent event = sPool.acquire(); 1135 if (event == null) event = new AccessibilityEvent(); 1136 if (DEBUG_ORIGIN) event.originStackTrace = Thread.currentThread().getStackTrace(); 1137 return event; 1138 } 1139 1140 /** 1141 * Recycles an instance back to be reused. 1142 * <p> 1143 * <b>Note: You must not touch the object after calling this function.</b> 1144 * </p> 1145 * 1146 * @throws IllegalStateException If the event is already recycled. 1147 */ 1148 @Override recycle()1149 public void recycle() { 1150 clear(); 1151 sPool.release(this); 1152 } 1153 1154 /** 1155 * Clears the state of this instance. 1156 * 1157 * @hide 1158 */ 1159 @Override clear()1160 protected void clear() { 1161 super.clear(); 1162 mEventType = 0; 1163 mMovementGranularity = 0; 1164 mAction = 0; 1165 mContentChangeTypes = 0; 1166 mWindowChangeTypes = 0; 1167 mPackageName = null; 1168 mEventTime = 0; 1169 if (mRecords != null) { 1170 while (!mRecords.isEmpty()) { 1171 AccessibilityRecord record = mRecords.remove(0); 1172 record.recycle(); 1173 } 1174 } 1175 if (DEBUG_ORIGIN) originStackTrace = null; 1176 } 1177 1178 /** 1179 * Creates a new instance from a {@link Parcel}. 1180 * 1181 * @param parcel A parcel containing the state of a {@link AccessibilityEvent}. 1182 */ initFromParcel(Parcel parcel)1183 public void initFromParcel(Parcel parcel) { 1184 mSealed = (parcel.readInt() == 1); 1185 mEventType = parcel.readInt(); 1186 mMovementGranularity = parcel.readInt(); 1187 mAction = parcel.readInt(); 1188 mContentChangeTypes = parcel.readInt(); 1189 mWindowChangeTypes = parcel.readInt(); 1190 mPackageName = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(parcel); 1191 mEventTime = parcel.readLong(); 1192 mConnectionId = parcel.readInt(); 1193 readAccessibilityRecordFromParcel(this, parcel); 1194 1195 // Read the records. 1196 final int recordCount = parcel.readInt(); 1197 if (recordCount > 0) { 1198 mRecords = new ArrayList<>(recordCount); 1199 for (int i = 0; i < recordCount; i++) { 1200 AccessibilityRecord record = AccessibilityRecord.obtain(); 1201 readAccessibilityRecordFromParcel(record, parcel); 1202 record.mConnectionId = mConnectionId; 1203 mRecords.add(record); 1204 } 1205 } 1206 1207 if (DEBUG_ORIGIN) { 1208 originStackTrace = new StackTraceElement[parcel.readInt()]; 1209 for (int i = 0; i < originStackTrace.length; i++) { 1210 originStackTrace[i] = new StackTraceElement( 1211 parcel.readString(), 1212 parcel.readString(), 1213 parcel.readString(), 1214 parcel.readInt()); 1215 } 1216 } 1217 } 1218 1219 /** 1220 * Reads an {@link AccessibilityRecord} from a parcel. 1221 * 1222 * @param record The record to initialize. 1223 * @param parcel The parcel to read from. 1224 */ readAccessibilityRecordFromParcel(AccessibilityRecord record, Parcel parcel)1225 private void readAccessibilityRecordFromParcel(AccessibilityRecord record, 1226 Parcel parcel) { 1227 record.mBooleanProperties = parcel.readInt(); 1228 record.mCurrentItemIndex = parcel.readInt(); 1229 record.mItemCount = parcel.readInt(); 1230 record.mFromIndex = parcel.readInt(); 1231 record.mToIndex = parcel.readInt(); 1232 record.mScrollX = parcel.readInt(); 1233 record.mScrollY = parcel.readInt(); 1234 record.mScrollDeltaX = parcel.readInt(); 1235 record.mScrollDeltaY = parcel.readInt(); 1236 record.mMaxScrollX = parcel.readInt(); 1237 record.mMaxScrollY = parcel.readInt(); 1238 record.mAddedCount = parcel.readInt(); 1239 record.mRemovedCount = parcel.readInt(); 1240 record.mClassName = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(parcel); 1241 record.mContentDescription = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(parcel); 1242 record.mBeforeText = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(parcel); 1243 record.mParcelableData = parcel.readParcelable(null); 1244 parcel.readList(record.mText, null); 1245 record.mSourceWindowId = parcel.readInt(); 1246 record.mSourceNodeId = parcel.readLong(); 1247 record.mSealed = (parcel.readInt() == 1); 1248 } 1249 1250 /** 1251 * {@inheritDoc} 1252 */ writeToParcel(Parcel parcel, int flags)1253 public void writeToParcel(Parcel parcel, int flags) { 1254 parcel.writeInt(isSealed() ? 1 : 0); 1255 parcel.writeInt(mEventType); 1256 parcel.writeInt(mMovementGranularity); 1257 parcel.writeInt(mAction); 1258 parcel.writeInt(mContentChangeTypes); 1259 parcel.writeInt(mWindowChangeTypes); 1260 TextUtils.writeToParcel(mPackageName, parcel, 0); 1261 parcel.writeLong(mEventTime); 1262 parcel.writeInt(mConnectionId); 1263 writeAccessibilityRecordToParcel(this, parcel, flags); 1264 1265 // Write the records. 1266 final int recordCount = getRecordCount(); 1267 parcel.writeInt(recordCount); 1268 for (int i = 0; i < recordCount; i++) { 1269 AccessibilityRecord record = mRecords.get(i); 1270 writeAccessibilityRecordToParcel(record, parcel, flags); 1271 } 1272 1273 if (DEBUG_ORIGIN) { 1274 if (originStackTrace == null) originStackTrace = Thread.currentThread().getStackTrace(); 1275 parcel.writeInt(originStackTrace.length); 1276 for (StackTraceElement element : originStackTrace) { 1277 parcel.writeString(element.getClassName()); 1278 parcel.writeString(element.getMethodName()); 1279 parcel.writeString(element.getFileName()); 1280 parcel.writeInt(element.getLineNumber()); 1281 } 1282 } 1283 } 1284 1285 /** 1286 * Writes an {@link AccessibilityRecord} to a parcel. 1287 * 1288 * @param record The record to write. 1289 * @param parcel The parcel to which to write. 1290 */ writeAccessibilityRecordToParcel(AccessibilityRecord record, Parcel parcel, int flags)1291 private void writeAccessibilityRecordToParcel(AccessibilityRecord record, Parcel parcel, 1292 int flags) { 1293 parcel.writeInt(record.mBooleanProperties); 1294 parcel.writeInt(record.mCurrentItemIndex); 1295 parcel.writeInt(record.mItemCount); 1296 parcel.writeInt(record.mFromIndex); 1297 parcel.writeInt(record.mToIndex); 1298 parcel.writeInt(record.mScrollX); 1299 parcel.writeInt(record.mScrollY); 1300 parcel.writeInt(record.mScrollDeltaX); 1301 parcel.writeInt(record.mScrollDeltaY); 1302 parcel.writeInt(record.mMaxScrollX); 1303 parcel.writeInt(record.mMaxScrollY); 1304 parcel.writeInt(record.mAddedCount); 1305 parcel.writeInt(record.mRemovedCount); 1306 TextUtils.writeToParcel(record.mClassName, parcel, flags); 1307 TextUtils.writeToParcel(record.mContentDescription, parcel, flags); 1308 TextUtils.writeToParcel(record.mBeforeText, parcel, flags); 1309 parcel.writeParcelable(record.mParcelableData, flags); 1310 parcel.writeList(record.mText); 1311 parcel.writeInt(record.mSourceWindowId); 1312 parcel.writeLong(record.mSourceNodeId); 1313 parcel.writeInt(record.mSealed ? 1 : 0); 1314 } 1315 1316 /** 1317 * {@inheritDoc} 1318 */ describeContents()1319 public int describeContents() { 1320 return 0; 1321 } 1322 1323 @Override toString()1324 public String toString() { 1325 StringBuilder builder = new StringBuilder(); 1326 builder.append("EventType: ").append(eventTypeToString(mEventType)); 1327 builder.append("; EventTime: ").append(mEventTime); 1328 builder.append("; PackageName: ").append(mPackageName); 1329 if (!DEBUG_CONCISE_TOSTRING || mMovementGranularity != 0) { 1330 builder.append("; MovementGranularity: ").append(mMovementGranularity); 1331 } 1332 if (!DEBUG_CONCISE_TOSTRING || mAction != 0) { 1333 builder.append("; Action: ").append(mAction); 1334 } 1335 if (!DEBUG_CONCISE_TOSTRING || mContentChangeTypes != 0) { 1336 builder.append("; ContentChangeTypes: ").append( 1337 contentChangeTypesToString(mContentChangeTypes)); 1338 } 1339 if (!DEBUG_CONCISE_TOSTRING || mWindowChangeTypes != 0) { 1340 builder.append("; WindowChangeTypes: ").append( 1341 windowChangeTypesToString(mWindowChangeTypes)); 1342 } 1343 super.appendTo(builder); 1344 if (DEBUG || DEBUG_CONCISE_TOSTRING) { 1345 if (!DEBUG_CONCISE_TOSTRING) { 1346 builder.append("\n"); 1347 } 1348 if (DEBUG) { 1349 builder.append("; SourceWindowId: ").append(mSourceWindowId); 1350 builder.append("; SourceNodeId: ").append(mSourceNodeId); 1351 } 1352 for (int i = 0; i < getRecordCount(); i++) { 1353 builder.append(" Record ").append(i).append(":"); 1354 getRecord(i).appendTo(builder).append("\n"); 1355 } 1356 } else { 1357 builder.append("; recordCount: ").append(getRecordCount()); 1358 } 1359 return builder.toString(); 1360 } 1361 1362 /** 1363 * Returns the string representation of an event type. For example, 1364 * {@link #TYPE_VIEW_CLICKED} is represented by the string TYPE_VIEW_CLICKED. 1365 * 1366 * @param eventType The event type 1367 * @return The string representation. 1368 */ eventTypeToString(int eventType)1369 public static String eventTypeToString(int eventType) { 1370 if (eventType == TYPES_ALL_MASK) { 1371 return "TYPES_ALL_MASK"; 1372 } 1373 StringBuilder builder = new StringBuilder(); 1374 int eventTypeCount = 0; 1375 while (eventType != 0) { 1376 final int eventTypeFlag = 1 << Integer.numberOfTrailingZeros(eventType); 1377 eventType &= ~eventTypeFlag; 1378 1379 if (eventTypeCount > 0) { 1380 builder.append(", "); 1381 } 1382 builder.append(singleEventTypeToString(eventTypeFlag)); 1383 1384 eventTypeCount++; 1385 } 1386 if (eventTypeCount > 1) { 1387 builder.insert(0, '['); 1388 builder.append(']'); 1389 } 1390 return builder.toString(); 1391 } 1392 singleEventTypeToString(int eventType)1393 private static String singleEventTypeToString(int eventType) { 1394 switch (eventType) { 1395 case TYPE_VIEW_CLICKED: return "TYPE_VIEW_CLICKED"; 1396 case TYPE_VIEW_LONG_CLICKED: return "TYPE_VIEW_LONG_CLICKED"; 1397 case TYPE_VIEW_SELECTED: return "TYPE_VIEW_SELECTED"; 1398 case TYPE_VIEW_FOCUSED: return "TYPE_VIEW_FOCUSED"; 1399 case TYPE_VIEW_TEXT_CHANGED: return "TYPE_VIEW_TEXT_CHANGED"; 1400 case TYPE_WINDOW_STATE_CHANGED: return "TYPE_WINDOW_STATE_CHANGED"; 1401 case TYPE_VIEW_HOVER_ENTER: return "TYPE_VIEW_HOVER_ENTER"; 1402 case TYPE_VIEW_HOVER_EXIT: return "TYPE_VIEW_HOVER_EXIT"; 1403 case TYPE_NOTIFICATION_STATE_CHANGED: return "TYPE_NOTIFICATION_STATE_CHANGED"; 1404 case TYPE_TOUCH_EXPLORATION_GESTURE_START: { 1405 return "TYPE_TOUCH_EXPLORATION_GESTURE_START"; 1406 } 1407 case TYPE_TOUCH_EXPLORATION_GESTURE_END: return "TYPE_TOUCH_EXPLORATION_GESTURE_END"; 1408 case TYPE_WINDOW_CONTENT_CHANGED: return "TYPE_WINDOW_CONTENT_CHANGED"; 1409 case TYPE_VIEW_TEXT_SELECTION_CHANGED: return "TYPE_VIEW_TEXT_SELECTION_CHANGED"; 1410 case TYPE_VIEW_SCROLLED: return "TYPE_VIEW_SCROLLED"; 1411 case TYPE_ANNOUNCEMENT: return "TYPE_ANNOUNCEMENT"; 1412 case TYPE_VIEW_ACCESSIBILITY_FOCUSED: return "TYPE_VIEW_ACCESSIBILITY_FOCUSED"; 1413 case TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED: { 1414 return "TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED"; 1415 } 1416 case TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY: { 1417 return "TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY"; 1418 } 1419 case TYPE_GESTURE_DETECTION_START: return "TYPE_GESTURE_DETECTION_START"; 1420 case TYPE_GESTURE_DETECTION_END: return "TYPE_GESTURE_DETECTION_END"; 1421 case TYPE_TOUCH_INTERACTION_START: return "TYPE_TOUCH_INTERACTION_START"; 1422 case TYPE_TOUCH_INTERACTION_END: return "TYPE_TOUCH_INTERACTION_END"; 1423 case TYPE_WINDOWS_CHANGED: return "TYPE_WINDOWS_CHANGED"; 1424 case TYPE_VIEW_CONTEXT_CLICKED: return "TYPE_VIEW_CONTEXT_CLICKED"; 1425 case TYPE_ASSIST_READING_CONTEXT: return "TYPE_ASSIST_READING_CONTEXT"; 1426 default: return Integer.toHexString(eventType); 1427 } 1428 } 1429 1430 /** 1431 * @see Parcelable.Creator 1432 */ 1433 public static final @android.annotation.NonNull Parcelable.Creator<AccessibilityEvent> CREATOR = 1434 new Parcelable.Creator<AccessibilityEvent>() { 1435 public AccessibilityEvent createFromParcel(Parcel parcel) { 1436 AccessibilityEvent event = AccessibilityEvent.obtain(); 1437 event.initFromParcel(parcel); 1438 return event; 1439 } 1440 1441 public AccessibilityEvent[] newArray(int size) { 1442 return new AccessibilityEvent[size]; 1443 } 1444 }; 1445 } 1446