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.NonNull; 21 import android.compat.annotation.UnsupportedAppUsage; 22 import android.os.Build; 23 import android.os.Parcel; 24 import android.os.Parcelable; 25 import android.text.TextUtils; 26 import android.util.Log; 27 import android.view.View; 28 29 import com.android.internal.util.BitUtils; 30 31 import java.lang.annotation.Retention; 32 import java.lang.annotation.RetentionPolicy; 33 import java.util.ArrayList; 34 import java.util.List; 35 36 /** 37 * <p> 38 * This class represents accessibility events that are sent by the system when 39 * something notable happens in the user interface. For example, when a 40 * {@link android.widget.Button} is clicked, a {@link android.view.View} is focused, etc. 41 * </p> 42 * <p> 43 * An accessibility event is fired by an individual view which populates the event with 44 * data for its state and requests from its parent to send the event to interested 45 * parties. The parent can optionally modify or even block the event based on its broader 46 * understanding of the user interface's context. 47 * </p> 48 * <p> 49 * The main purpose of an accessibility event is to communicate changes in the UI to an 50 * {@link android.accessibilityservice.AccessibilityService}. If needed, the service may then 51 * inspect the user interface by examining the View hierarchy through the event's 52 * {@link #getSource() source}, as represented by a tree of {@link AccessibilityNodeInfo}s (snapshot 53 * of a View state) which can be used for exploring the window content. Note that the privilege for 54 * accessing an event's source, thus the window content, has to be explicitly requested. For more 55 * details refer to {@link android.accessibilityservice.AccessibilityService}. If an 56 * accessibility service has not requested to retrieve the window content the event will 57 * not contain reference to its source. <strong>Note: </strong> for events of type 58 * {@link #TYPE_NOTIFICATION_STATE_CHANGED} the source is never available, and Views that set 59 * {@link android.view.View#isAccessibilityDataSensitive()} may not populate all event properties on 60 * events sent from higher up in the view hierarchy. 61 * </p> 62 * <p> 63 * This class represents various semantically different accessibility event 64 * types. Each event type has an associated set of related properties. In other 65 * words, each event type is characterized via a subset of the properties exposed 66 * by this class. For each event type there is a corresponding constant defined 67 * in this class. Follows a specification of the event types and their associated properties: 68 * </p> 69 * <div class="special reference"> 70 * <h3>Developer Guides</h3> 71 * <p>For more information about creating and processing AccessibilityEvents, read the 72 * <a href="{@docRoot}guide/topics/ui/accessibility/index.html">Accessibility</a> 73 * developer guide.</p> 74 * </div> 75 * <p> 76 * <b>VIEW TYPES</b></br> 77 * </p> 78 * <p> 79 * <b>View clicked</b> - represents the event of clicking on a {@link android.view.View} 80 * like {@link android.widget.Button}, {@link android.widget.CompoundButton}, etc.</br> 81 * <em>Type:</em>{@link #TYPE_VIEW_CLICKED}</br> 82 * <em>Properties:</em></br> 83 * <ul> 84 * <li>{@link #getEventType()} - The type of the event.</li> 85 * <li>{@link #getSource()} - The source info (for registered clients).</li> 86 * <li>{@link #getClassName()} - The class name of the source.</li> 87 * <li>{@link #getPackageName()} - The package name of the source.</li> 88 * <li>{@link #getEventTime()} - The event time.</li> 89 * </ul> 90 * </p> 91 * <p> 92 * <b>View long clicked</b> - represents the event of long clicking on a {@link android.view.View} 93 * like {@link android.widget.Button}, {@link android.widget.CompoundButton}, etc </br> 94 * <em>Type:</em>{@link #TYPE_VIEW_LONG_CLICKED}</br> 95 * <em>Properties:</em></br> 96 * <ul> 97 * <li>{@link #getEventType()} - The type of the event.</li> 98 * <li>{@link #getSource()} - The source info (for registered clients).</li> 99 * <li>{@link #getClassName()} - The class name of the source.</li> 100 * <li>{@link #getPackageName()} - The package name of the source.</li> 101 * <li>{@link #getEventTime()} - The event time.</li> 102 * </ul> 103 * </p> 104 * <p> 105 * <b>View selected</b> - represents the event of selecting an item usually in 106 * the context of an {@link android.widget.AdapterView}.</br> 107 * <em>Type:</em> {@link #TYPE_VIEW_SELECTED}</br> 108 * <em>Properties:</em></br> 109 * <ul> 110 * <li>{@link #getEventType()} - The type of the event.</li> 111 * <li>{@link #getSource()} - The source info (for registered clients).</li> 112 * <li>{@link #getClassName()} - The class name of the source.</li> 113 * <li>{@link #getPackageName()} - The package name of the source.</li> 114 * <li>{@link #getEventTime()} - The event time.</li> 115 * </ul> 116 * </p> 117 * <p> 118 * <b>View focused</b> - represents the event of focusing a 119 * {@link android.view.View}.</br> 120 * <em>Type:</em> {@link #TYPE_VIEW_FOCUSED}</br> 121 * <em>Properties:</em></br> 122 * <ul> 123 * <li>{@link #getEventType()} - The type of the event.</li> 124 * <li>{@link #getSource()} - The source info (for registered clients).</li> 125 * <li>{@link #getClassName()} - The class name of the source.</li> 126 * <li>{@link #getPackageName()} - The package name of the source.</li> 127 * <li>{@link #getEventTime()} - The event time.</li> 128 * </ul> 129 * </p> 130 * <p> 131 * <b>View text changed</b> - represents the event of changing the text of an 132 * {@link android.widget.EditText}.</br> 133 * <em>Type:</em> {@link #TYPE_VIEW_TEXT_CHANGED}</br> 134 * <em>Properties:</em></br> 135 * <ul> 136 * <li>{@link #getEventType()} - The type of the event.</li> 137 * <li>{@link #getSource()} - The source info (for registered clients).</li> 138 * <li>{@link #getClassName()} - The class name of the source.</li> 139 * <li>{@link #getPackageName()} - The package name of the source.</li> 140 * <li>{@link #getEventTime()} - The event time.</li> 141 * <li>{@link #getText()} - The new text of the source.</li> 142 * <li>{@link #getBeforeText()} - The text of the source before the change.</li> 143 * <li>{@link #getFromIndex()} - The text change start index.</li> 144 * <li>{@link #getAddedCount()} - The number of added characters.</li> 145 * <li>{@link #getRemovedCount()} - The number of removed characters.</li> 146 * </ul> 147 * </p> 148 * <p> 149 * <b>View text selection changed</b> - represents the event of changing the text 150 * selection of an {@link android.widget.EditText}.</br> 151 * <em>Type:</em> {@link #TYPE_VIEW_TEXT_SELECTION_CHANGED} </br> 152 * <em>Properties:</em></br> 153 * <ul> 154 * <li>{@link #getEventType()} - The type of the event.</li> 155 * <li>{@link #getSource()} - The source info (for registered clients).</li> 156 * <li>{@link #getClassName()} - The class name of the source.</li> 157 * <li>{@link #getPackageName()} - The package name of the source.</li> 158 * <li>{@link #getEventTime()} - The event time.</li> 159 * </ul> 160 * </p> 161 * <b>View text traversed at movement granularity</b> - represents the event of traversing the 162 * text of a view at a given granularity. For example, moving to the next word.</br> 163 * <em>Type:</em> {@link #TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY} </br> 164 * <em>Properties:</em></br> 165 * <ul> 166 * <li>{@link #getEventType()} - The type of the event.</li> 167 * <li>{@link #getSource()} - The source info (for registered clients).</li> 168 * <li>{@link #getClassName()} - The class name of the source.</li> 169 * <li>{@link #getPackageName()} - The package name of the source.</li> 170 * <li>{@link #getEventTime()} - The event time.</li> 171 * <li>{@link #getMovementGranularity()} - Sets the granularity at which a view's text 172 * was traversed.</li> 173 * <li>{@link #getText()} - The text of the source's sub-tree.</li> 174 * <li>{@link #getFromIndex()} - The start the text that was skipped over in this movement. 175 * This is the starting point when moving forward through the text, but not when moving 176 * back.</li> 177 * <li>{@link #getToIndex()} - The end of the text that was skipped over in this movement. 178 * This is the ending point when moving forward through the text, but not when moving 179 * back.</li> 180 * <li>{@link #getAction()} - Gets traversal action which specifies the direction.</li> 181 * </ul> 182 * </p> 183 * <p> 184 * <b>View scrolled</b> - represents the event of scrolling a view. </br> 185 * <em>Type:</em> {@link #TYPE_VIEW_SCROLLED}</br> 186 * <em>Properties:</em></br> 187 * <ul> 188 * <li>{@link #getEventType()} - The type of the event.</li> 189 * <li>{@link #getSource()} - The source info (for registered clients).</li> 190 * <li>{@link #getClassName()} - The class name of the source.</li> 191 * <li>{@link #getPackageName()} - The package name of the source.</li> 192 * <li>{@link #getEventTime()} - The event time.</li> 193 * <li>{@link #getScrollDeltaX()} - The difference in the horizontal position.</li> 194 * <li>{@link #getScrollDeltaY()} - The difference in the vertical position.</li> 195 * <li>{@link #getMaxScrollX()} ()} - The max scroll offset of the source left edge</li> 196 * <li>{@link #getMaxScrollY()} ()} - The max scroll offset of the source top edge.</li> 197 * </ul> 198 * </p> 199 * <p> 200 * <b>TRANSITION TYPES</b></br> 201 * </p> 202 * <p> 203 * <b>Window state changed</b> - represents the event of a change to a section of 204 * the user interface that is visually distinct. Should be sent from either the 205 * root view of a window or from a view that is marked as a pane 206 * {@link android.view.View#setAccessibilityPaneTitle(CharSequence)}. Note that changes 207 * to true windows are represented by {@link #TYPE_WINDOWS_CHANGED}.</br> 208 * <em>Type:</em> {@link #TYPE_WINDOW_STATE_CHANGED}</br> 209 * <em>Properties:</em></br> 210 * <ul> 211 * <li>{@link #getEventType()} - The type of the event.</li> 212 * <li>{@link #getContentChangeTypes()} - The type of state changes.</li> 213 * <li>{@link #getSource()} - The source info (for registered clients).</li> 214 * <li>{@link #getClassName()} - The class name of the source.</li> 215 * <li>{@link #getPackageName()} - The package name of the source.</li> 216 * <li>{@link #getEventTime()} - The event time.</li> 217 * <li>{@link #getText()} - The text of the source's sub-tree, including the pane titles.</li> 218 * </ul> 219 * </p> 220 * <p> 221 * <b>Window content changed</b> - represents the event of change in the 222 * content of a window. This change can be adding/removing view, changing 223 * a view size, etc.</br> 224 * </p> 225 * <p> 226 * <em>Type:</em> {@link #TYPE_WINDOW_CONTENT_CHANGED}</br> 227 * <em>Properties:</em></br> 228 * <ul> 229 * <li>{@link #getEventType()} - The type of the event.</li> 230 * <li>{@link #getContentChangeTypes()} - The type of content changes.</li> 231 * <li>{@link #getSource()} - The source info (for registered clients).</li> 232 * <li>{@link #getClassName()} - The class name of the source.</li> 233 * <li>{@link #getPackageName()} - The package name of the source.</li> 234 * <li>{@link #getEventTime()} - The event time.</li> 235 * </ul> 236 * </p> 237 * <p> 238 * <b>Windows changed</b> - represents a change in the windows shown on 239 * the screen such as a window appeared, a window disappeared, a window size changed, 240 * a window layer changed, etc. These events should only come from the system, which is responsible 241 * for managing windows. The list of windows is available from 242 * {@link android.accessibilityservice.AccessibilityService#getWindows()}. 243 * For regions of the user interface that are presented as windows but are 244 * controlled by an app's process, use {@link #TYPE_WINDOW_STATE_CHANGED}.</br> 245 * <em>Type:</em> {@link #TYPE_WINDOWS_CHANGED}</br> 246 * <em>Properties:</em></br> 247 * <ul> 248 * <li>{@link #getEventType()} - The type of the event.</li> 249 * <li>{@link #getEventTime()} - The event time.</li> 250 * <li>{@link #getWindowChanges()}</li> - The specific change to the source window 251 * </ul> 252 * <em>Note:</em> You can retrieve the {@link AccessibilityWindowInfo} for the window 253 * source of the event by looking through the list returned by 254 * {@link android.accessibilityservice.AccessibilityService#getWindows()} for the window whose ID 255 * matches {@link #getWindowId()}. 256 * </p> 257 * <p> 258 * <b>NOTIFICATION TYPES</b></br> 259 * </p> 260 * <p> 261 * <b>Notification state changed</b> - represents the event showing a transient piece of information 262 * to the user. This information may be a {@link android.app.Notification} or 263 * {@link android.widget.Toast}.</br> 264 * <em>Type:</em> {@link #TYPE_NOTIFICATION_STATE_CHANGED}</br> 265 * <em>Properties:</em></br> 266 * <ul> 267 * <li>{@link #getEventType()} - The type of the event.</li> 268 * <li>{@link #getClassName()} - The class name of the source.</li> 269 * <li>{@link #getPackageName()} - The package name of the source.</li> 270 * <li>{@link #getEventTime()} - The event time.</li> 271 * <li>{@link #getParcelableData()} - The posted {@link android.app.Notification}, if 272 * applicable.</li> 273 * <li>{@link #getText()} - Displayed text of the {@link android.widget.Toast}, if applicable, 274 * or may contain text from the {@link android.app.Notification}, although 275 * {@link #getParcelableData()} is a richer set of data for {@link android.app.Notification}.</li> 276 * </ul> 277 * </p> 278 * <p> 279 * <b>EXPLORATION TYPES</b></br> 280 * </p> 281 * <p> 282 * <b>View hover enter</b> - represents the event of beginning to hover 283 * over a {@link android.view.View}. The hover may be generated via 284 * exploring the screen by touch or via a pointing device.</br> 285 * <em>Type:</em> {@link #TYPE_VIEW_HOVER_ENTER}</br> 286 * <em>Properties:</em></br> 287 * <ul> 288 * <li>{@link #getEventType()} - The type of the event.</li> 289 * <li>{@link #getSource()} - The source info (for registered clients).</li> 290 * <li>{@link #getClassName()} - The class name of the source.</li> 291 * <li>{@link #getPackageName()} - The package name of the source.</li> 292 * <li>{@link #getEventTime()} - The event time.</li> 293 * </ul> 294 * </p> 295 * <b>View hover exit</b> - represents the event of stopping to hover 296 * over a {@link android.view.View}. The hover may be generated via 297 * exploring the screen by touch or via a pointing device.</br> 298 * <em>Type:</em> {@link #TYPE_VIEW_HOVER_EXIT}</br> 299 * <em>Properties:</em></br> 300 * <ul> 301 * <li>{@link #getEventType()} - The type of the event.</li> 302 * <li>{@link #getSource()} - The source info (for registered clients).</li> 303 * <li>{@link #getClassName()} - The class name of the source.</li> 304 * <li>{@link #getPackageName()} - The package name of the source.</li> 305 * <li>{@link #getEventTime()} - The event time.</li> 306 * </ul> 307 * </p> 308 * <p> 309 * <b>View scrolled to</b> - represents the event of a target node brought on screen by 310 * ACTION_SCROLL_IN_DIRECTION. 311 * <em>Type:</em> {@link #TYPE_VIEW_TARGETED_BY_SCROLL}</br> 312 * <em>Properties:</em></br> 313 * <ul> 314 * <li>{@link #getEventType()} - The type of the event.</li> 315 * <li>{@link #getSource()} - The source info (for registered clients). This represents the node 316 * that is brought on screen as a result of the scroll.</li> 317 * <li>{@link #getClassName()} - The class name of the source.</li> 318 * <li>{@link #getPackageName()} - The package name of the source.</li> 319 * <li>{@link #getEventTime()} - The event time.</li> 320 * </ul> 321 * </p> 322 * <p> 323 * <b>Touch interaction start</b> - represents the event of starting a touch 324 * interaction, which is the user starts touching the screen.</br> 325 * <em>Type:</em> {@link #TYPE_TOUCH_INTERACTION_START}</br> 326 * <em>Properties:</em></br> 327 * <ul> 328 * <li>{@link #getEventType()} - The type of the event.</li> 329 * </ul> 330 * <em>Note:</em> This event is fired only by the system and is not passed to the 331 * view tree to be populated.</br> 332 * </p> 333 * <p> 334 * <b>Touch interaction end</b> - represents the event of ending a touch 335 * interaction, which is the user stops touching the screen.</br> 336 * <em>Type:</em> {@link #TYPE_TOUCH_INTERACTION_END}</br> 337 * <em>Properties:</em></br> 338 * <ul> 339 * <li>{@link #getEventType()} - The type of the event.</li> 340 * </ul> 341 * <em>Note:</em> This event is fired only by the system and is not passed to the 342 * view tree to be populated.</br> 343 * </p> 344 * <p> 345 * <b>Touch exploration gesture start</b> - represents the event of starting a touch 346 * exploring gesture.</br> 347 * <em>Type:</em> {@link #TYPE_TOUCH_EXPLORATION_GESTURE_START}</br> 348 * <em>Properties:</em></br> 349 * <ul> 350 * <li>{@link #getEventType()} - The type of the event.</li> 351 * </ul> 352 * <em>Note:</em> This event is fired only by the system and is not passed to the 353 * view tree to be populated.</br> 354 * </p> 355 * <p> 356 * <b>Touch exploration gesture end</b> - represents the event of ending a touch 357 * exploring gesture.</br> 358 * <em>Type:</em> {@link #TYPE_TOUCH_EXPLORATION_GESTURE_END}</br> 359 * <em>Properties:</em></br> 360 * <ul> 361 * <li>{@link #getEventType()} - The type of the event.</li> 362 * </ul> 363 * <em>Note:</em> This event is fired only by the system and is not passed to the 364 * view tree to be populated.</br> 365 * </p> 366 * <p> 367 * <b>Touch gesture detection start</b> - represents the event of starting a user 368 * gesture detection.</br> 369 * <em>Type:</em> {@link #TYPE_GESTURE_DETECTION_START}</br> 370 * <em>Properties:</em></br> 371 * <ul> 372 * <li>{@link #getEventType()} - The type of the event.</li> 373 * </ul> 374 * <em>Note:</em> This event is fired only by the system and is not passed to the 375 * view tree to be populated.</br> 376 * </p> 377 * <p> 378 * <b>Touch gesture detection end</b> - represents the event of ending a user 379 * gesture detection.</br> 380 * <em>Type:</em> {@link #TYPE_GESTURE_DETECTION_END}</br> 381 * <em>Properties:</em></br> 382 * <ul> 383 * <li>{@link #getEventType()} - The type of the event.</li> 384 * </ul> 385 * <em>Note:</em> This event is fired only by the system and is not passed to the 386 * view tree to be populated.</br> 387 * </p> 388 * <p> 389 * <b>MISCELLANEOUS TYPES</b></br> 390 * </p> 391 * <p> 392 * <b>Announcement</b> - represents the event of an application requesting a screen reader to make 393 * an announcement. Because the event carries no semantic meaning, this event is appropriate only 394 * in exceptional situations where additional screen reader output is needed but other types of 395 * accessibility services do not need to be aware of the change.</br> 396 * <em>Type:</em> {@link #TYPE_ANNOUNCEMENT}</br> 397 * <em>Properties:</em></br> 398 * <ul> 399 * <li>{@link #getEventType()} - The type of the event.</li> 400 * <li>{@link #getSource()} - The source info (for registered clients).</li> 401 * <li>{@link #getClassName()} - The class name of the source.</li> 402 * <li>{@link #getPackageName()} - The package name of the source.</li> 403 * <li>{@link #getEventTime()} - The event time.</li> 404 * <li>{@link #getText()} - The text of the announcement.</li> 405 * </ul> 406 * </p> 407 * <p> 408 * <b>speechStateChanged</b> 409 * <em>Type:</em> {@link #TYPE_SPEECH_STATE_CHANGE}</br> 410 * Represents a change in the speech state defined by the 411 * bit mask of the speech state change types. 412 * A change in the speech state occurs when an application wants to signal that 413 * it is either speaking or listening for human speech. 414 * This event helps avoid conflicts where two applications want to speak or one listens 415 * when another speaks. 416 * When sending this event, the sender should ensure that the accompanying state change types 417 * make sense. For example, the sender should not send 418 * {@link #SPEECH_STATE_SPEAKING_START} and {@link #SPEECH_STATE_SPEAKING_END} together. 419 * <em>Properties:</em></br> 420 * <ul> 421 * <li>{@link #getSpeechStateChangeTypes()} - The type of state changes</li> 422 * <li>{@link #getPackageName()} - The package name of the source.</li> 423 * <li>{@link #getEventTime()} - The event time.</li> 424 * </ul> 425 * </p> 426 * 427 * @see android.view.accessibility.AccessibilityManager 428 * @see android.accessibilityservice.AccessibilityService 429 * @see AccessibilityNodeInfo 430 */ 431 public final class AccessibilityEvent extends AccessibilityRecord implements Parcelable { 432 private static final String LOG_TAG = "AccessibilityEvent"; 433 434 private static final boolean DEBUG = Log.isLoggable(LOG_TAG, Log.DEBUG) && Build.IS_DEBUGGABLE; 435 436 /** @hide */ 437 public static final boolean DEBUG_ORIGIN = false; 438 439 /** 440 * Invalid selection/focus position. 441 * 442 * @see #getCurrentItemIndex() 443 */ 444 public static final int INVALID_POSITION = -1; 445 446 /** 447 * Maximum length of the text fields. 448 * 449 * @see #getBeforeText() 450 * @see #getText() 451 * </br> 452 * Note: This constant is no longer needed since there 453 * is no limit on the length of text that is contained 454 * in an accessibility event anymore. 455 */ 456 @Deprecated 457 public static final int MAX_TEXT_LENGTH = 500; 458 459 // Event types. 460 461 /** 462 * Represents the event of clicking on a {@link android.view.View} like 463 * {@link android.widget.Button}, {@link android.widget.CompoundButton}, etc. 464 * <p>See {@link AccessibilityNodeInfo.AccessibilityAction#ACTION_CLICK} for more 465 * details. 466 */ 467 public static final int TYPE_VIEW_CLICKED = 1 /* << 0 */;; 468 469 /** 470 * Represents the event of long clicking on a {@link android.view.View} like 471 * {@link android.widget.Button}, {@link android.widget.CompoundButton}, etc. 472 * <p>See {@link AccessibilityNodeInfo.AccessibilityAction#ACTION_LONG_CLICK} for more 473 * details. 474 */ 475 public static final int TYPE_VIEW_LONG_CLICKED = 1 << 1; 476 477 /** 478 * Represents the event of selecting an item usually in the context of an 479 * {@link android.widget.AdapterView}. 480 * @see AccessibilityNodeInfo.AccessibilityAction#ACTION_SELECT 481 */ 482 public static final int TYPE_VIEW_SELECTED = 1 << 2; 483 484 /** 485 * Represents the event of setting input focus of a {@link android.view.View}. 486 * @see AccessibilityNodeInfo.AccessibilityAction#ACTION_ACCESSIBILITY_FOCUS for the difference 487 * between input and accessibility focus. 488 */ 489 public static final int TYPE_VIEW_FOCUSED = 1 << 3; 490 491 /** 492 * Represents the event of changing the text of an {@link android.widget.EditText}. 493 * @see AccessibilityNodeInfo#setText(CharSequence) 494 */ 495 public static final int TYPE_VIEW_TEXT_CHANGED = 1 << 4; 496 497 /** 498 * Represents the event of a change to a visually distinct section of the user interface. 499 * <p> 500 * These events should only be dispatched from {@link android.view.View}s that have 501 * accessibility pane titles, and replaces {@link #TYPE_WINDOW_CONTENT_CHANGED} for those 502 * sources. Details about the change are available from {@link #getContentChangeTypes()}. 503 * <p> 504 * Do not use this to get an accessibility service to make non-pane announcements. Instead, 505 * follow the practices described in {@link View#announceForAccessibility(CharSequence)}. 506 * <b>Note:</b> this does not suggest calling announceForAccessibility(), but using the 507 * suggestions listed in its documentation. 508 */ 509 public static final int TYPE_WINDOW_STATE_CHANGED = 1 << 5; 510 511 /** 512 * Represents the event showing a {@link android.app.Notification}. 513 */ 514 public static final int TYPE_NOTIFICATION_STATE_CHANGED = 1 << 6; 515 516 /** 517 * Represents the event of a hover enter over a {@link android.view.View}. 518 */ 519 public static final int TYPE_VIEW_HOVER_ENTER = 1 << 7; 520 521 /** 522 * Represents the event of a hover exit over a {@link android.view.View}. 523 */ 524 public static final int TYPE_VIEW_HOVER_EXIT = 1 << 8; 525 526 /** 527 * Represents the event of starting a touch exploration gesture. 528 */ 529 public static final int TYPE_TOUCH_EXPLORATION_GESTURE_START = 1 << 9; 530 531 /** 532 * Represents the event of ending a touch exploration gesture. 533 */ 534 public static final int TYPE_TOUCH_EXPLORATION_GESTURE_END = 1 << 10; 535 536 /** 537 * Represents the event of changing the content of a window and more 538 * specifically the sub-tree rooted at the event's source. 539 */ 540 public static final int TYPE_WINDOW_CONTENT_CHANGED = 1 << 11; 541 542 /** 543 * Represents the event of scrolling a view. This event type is generally not sent directly. In 544 * the View system, this is sent in 545 * {@link android.view.View#onScrollChanged(int, int, int, int)} 546 * <p>In addition to the source and package name, the event should populate scroll-specific 547 * properties like {@link #setScrollDeltaX(int)}, {@link #setScrollDeltaY(int)}, 548 * {@link #setMaxScrollX(int)}, and {@link #setMaxScrollY(int)}. 549 * <p>Services are encouraged to rely on the source to query UI state over AccessibilityEvents 550 * properties. For example, to check after a scroll if the bottom of the scrolling UI element 551 * has been reached, check if the source node is scrollable and has the 552 * {@link AccessibilityNodeInfo.AccessibilityAction#ACTION_SCROLL_BACKWARD} action but not the 553 * {@link AccessibilityNodeInfo.AccessibilityAction#ACTION_SCROLL_FORWARD} action. 554 * For scrolling to a target, use {@link #TYPE_VIEW_TARGETED_BY_SCROLL}. 555 */ 556 public static final int TYPE_VIEW_SCROLLED = 1 << 12; 557 558 /** 559 * Represents the event of changing the selection in an {@link android.widget.EditText}. 560 */ 561 public static final int TYPE_VIEW_TEXT_SELECTION_CHANGED = 1 << 13; 562 563 /** 564 * Represents the event of an application making an announcement. 565 * <p> 566 * In general, follow the practices described in 567 * {@link View#announceForAccessibility(CharSequence)}. 568 */ 569 public static final int TYPE_ANNOUNCEMENT = 1 << 14; 570 571 /** 572 * Represents the event of gaining accessibility focus. 573 * @see AccessibilityNodeInfo.AccessibilityAction#ACTION_ACCESSIBILITY_FOCUS for the difference 574 * between input and accessibility focus. 575 */ 576 public static final int TYPE_VIEW_ACCESSIBILITY_FOCUSED = 1 << 15; 577 578 /** 579 * Represents the event of clearing accessibility focus. 580 * @see AccessibilityNodeInfo.AccessibilityAction#ACTION_ACCESSIBILITY_FOCUS for the difference 581 * between input and accessibility focus. 582 */ 583 public static final int TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED = 1 << 16; 584 585 /** 586 * Represents the event of traversing the text of a view at a given movement granularity. 587 */ 588 public static final int TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY = 1 << 17; 589 590 /** 591 * Represents the event of beginning gesture detection. 592 */ 593 public static final int TYPE_GESTURE_DETECTION_START = 1 << 18; 594 595 /** 596 * Represents the event of ending gesture detection. 597 */ 598 public static final int TYPE_GESTURE_DETECTION_END = 1 << 19; 599 600 /** 601 * Represents the event of the user starting to touch the screen. 602 */ 603 public static final int TYPE_TOUCH_INTERACTION_START = 1 << 20; 604 605 /** 606 * Represents the event of the user ending to touch the screen. 607 */ 608 public static final int TYPE_TOUCH_INTERACTION_END = 1 << 21; 609 610 /** 611 * Represents the event change in the system windows shown on the screen. This event type should 612 * only be dispatched by the system. 613 */ 614 public static final int TYPE_WINDOWS_CHANGED = 1 << 22; 615 616 /** 617 * Represents the event of a context click on a {@link android.view.View}. 618 * <p>See {@link AccessibilityNodeInfo.AccessibilityAction#ACTION_CONTEXT_CLICK} for more 619 * details. 620 */ 621 public static final int TYPE_VIEW_CONTEXT_CLICKED = 1 << 23; 622 623 /** 624 * Represents the event of the assistant currently reading the users screen context. 625 */ 626 public static final int TYPE_ASSIST_READING_CONTEXT = 1 << 24; 627 628 /** 629 * Represents a change in the speech state defined by the speech state change types. 630 * A change in the speech state occurs when an application wants to signal that it is either 631 * speaking or listening for human speech. 632 * This event helps avoid conflicts where two applications want to speak or one listens 633 * when another speaks. 634 * When sending this event, the sender should ensure that the accompanying state change types 635 * make sense. For example, the sender should not send 636 * {@link #SPEECH_STATE_SPEAKING_START} and {@link #SPEECH_STATE_SPEAKING_END} together. 637 * @see #SPEECH_STATE_SPEAKING_START 638 * @see #SPEECH_STATE_SPEAKING_END 639 * @see #SPEECH_STATE_LISTENING_START 640 * @see #SPEECH_STATE_LISTENING_END 641 * @see #getSpeechStateChangeTypes 642 * @see #setSpeechStateChangeTypes 643 */ 644 public static final int TYPE_SPEECH_STATE_CHANGE = 1 << 25; 645 646 /** 647 * Represents the event of a scroll having completed and brought the target node on screen. 648 */ 649 public static final int TYPE_VIEW_TARGETED_BY_SCROLL = 1 << 26; 650 651 // Content change types. 652 653 /** 654 * Change type for {@link #TYPE_WINDOW_CONTENT_CHANGED} event: The type of change is not 655 * defined. 656 */ 657 public static final int CONTENT_CHANGE_TYPE_UNDEFINED = 0; 658 659 /** 660 * Change type for {@link #TYPE_WINDOW_CONTENT_CHANGED} event: 661 * One or more content changes occurred in the the subtree rooted at the source node, 662 * or the subtree's structure changed when a node was added or removed. 663 */ 664 public static final int CONTENT_CHANGE_TYPE_SUBTREE = 1 /* << 0 */; 665 666 /** 667 * Change type for {@link #TYPE_WINDOW_CONTENT_CHANGED} event: 668 * The node's text changed. 669 * @see AccessibilityNodeInfo#setText(CharSequence) 670 */ 671 public static final int CONTENT_CHANGE_TYPE_TEXT = 1 << 1; 672 673 /** 674 * Change type for {@link #TYPE_WINDOW_CONTENT_CHANGED} event: 675 * The node's content description changed. 676 */ 677 public static final int CONTENT_CHANGE_TYPE_CONTENT_DESCRIPTION = 1 << 2; 678 679 /** 680 * Change type for {@link #TYPE_WINDOW_STATE_CHANGED} event: 681 * The node's pane title changed. 682 * <p> 683 * If this makes the pane appear, {@link #CONTENT_CHANGE_TYPE_PANE_APPEARED} is sent 684 * instead. If this makes the pane disappear, {@link #CONTENT_CHANGE_TYPE_PANE_DISAPPEARED} 685 * is sent. 686 * @see View#setAccessibilityPaneTitle(CharSequence) 687 */ 688 public static final int CONTENT_CHANGE_TYPE_PANE_TITLE = 1 << 3; 689 690 /** 691 * Change type for {@link #TYPE_WINDOW_STATE_CHANGED} event: 692 * The node has a pane title, and either just appeared or just was assigned a title when it 693 * had none before. 694 * @see View#setAccessibilityPaneTitle(CharSequence) 695 */ 696 public static final int CONTENT_CHANGE_TYPE_PANE_APPEARED = 1 << 4; 697 698 /** 699 * Change type for {@link #TYPE_WINDOW_STATE_CHANGED} event: 700 * Can mean one of two slightly different things. The primary meaning is that the node has 701 * a pane title, and was removed from the node hierarchy. It will also be sent if the pane 702 * title is set to {@code null} after it contained a title. 703 * No source will be returned if the node is no longer on the screen. To make the change more 704 * clear for the user, the first entry in {@link #getText()} will return the value that would 705 * have been returned by {@code getSource().getPaneTitle()}. 706 * @see View#setAccessibilityPaneTitle(CharSequence) 707 */ 708 public static final int CONTENT_CHANGE_TYPE_PANE_DISAPPEARED = 1 << 5; 709 710 /** 711 * Change type for {@link #TYPE_WINDOW_CONTENT_CHANGED} event: 712 * state description of the node as returned by 713 * {@link AccessibilityNodeInfo#getStateDescription} changed. If part of the state description 714 * changes, the changed part can be put into event text. For example, if state description 715 * changed from "on, wifi signal full" to "on, wifi three bars", "wifi three bars" can be put 716 * into the event text. 717 * @see View#setStateDescription(CharSequence) 718 */ 719 public static final int CONTENT_CHANGE_TYPE_STATE_DESCRIPTION = 1 << 6; 720 721 /** 722 * Change type for {@link #TYPE_WINDOW_CONTENT_CHANGED} event: 723 * A drag has started while accessibility is enabled. This is either via an 724 * AccessibilityAction, or via touch events. This is sent from the source that initiated the 725 * drag. 726 * 727 * @see AccessibilityNodeInfo.AccessibilityAction#ACTION_DRAG_START 728 */ 729 public static final int CONTENT_CHANGE_TYPE_DRAG_STARTED = 1 << 7; 730 731 /** 732 * Change type for {@link #TYPE_WINDOW_CONTENT_CHANGED} event: 733 * A drag in with accessibility enabled has ended. This means the content has been 734 * successfully dropped. This is sent from the target that accepted the dragged content. 735 * 736 * @see AccessibilityNodeInfo.AccessibilityAction#ACTION_DRAG_DROP 737 */ 738 public static final int CONTENT_CHANGE_TYPE_DRAG_DROPPED = 1 << 8; 739 740 /** 741 * Change type for {@link #TYPE_WINDOW_CONTENT_CHANGED} event: 742 * A drag in with accessibility enabled has ended. This means the content has been 743 * unsuccessfully dropped, the user has canceled the action via an AccessibilityAction, or 744 * no drop has been detected within a timeout and the drag was automatically cancelled. This is 745 * sent from the source that initiated the drag. 746 * 747 * @see AccessibilityNodeInfo.AccessibilityAction#ACTION_DRAG_CANCEL 748 */ 749 public static final int CONTENT_CHANGE_TYPE_DRAG_CANCELLED = 1 << 9; 750 751 /** 752 * Change type for {@link #TYPE_WINDOW_CONTENT_CHANGED} event: 753 * The source node changed its content validity returned by 754 * {@link AccessibilityNodeInfo#isContentInvalid}. 755 * The view changing content validity should call 756 * {@link AccessibilityNodeInfo#setContentInvalid} and then send this event. 757 * 758 * @see AccessibilityNodeInfo#isContentInvalid 759 * @see AccessibilityNodeInfo#setContentInvalid 760 */ 761 public static final int CONTENT_CHANGE_TYPE_CONTENT_INVALID = 1 << 10; 762 763 /** 764 * Change type for {@link #TYPE_WINDOW_CONTENT_CHANGED} event: 765 * The source node changed its erroneous content's error message returned by 766 * {@link AccessibilityNodeInfo#getError}. 767 * The view changing erroneous content's error message should call 768 * {@link AccessibilityNodeInfo#setError} and then send this event. 769 * 770 * @see AccessibilityNodeInfo#getError 771 * @see AccessibilityNodeInfo#setError 772 */ 773 public static final int CONTENT_CHANGE_TYPE_ERROR = 1 << 11; 774 775 /** 776 * Change type for {@link #TYPE_WINDOW_CONTENT_CHANGED} event: 777 * The source node changed its ability to interact returned by 778 * {@link AccessibilityNodeInfo#isEnabled}. 779 * The view changing content's ability to interact should call 780 * {@link AccessibilityNodeInfo#setEnabled} and then send this event. 781 * 782 * @see AccessibilityNodeInfo#isEnabled 783 * @see AccessibilityNodeInfo#setEnabled 784 */ 785 public static final int CONTENT_CHANGE_TYPE_ENABLED = 1 << 12; 786 787 // Speech state change types. 788 789 /** Change type for {@link #TYPE_SPEECH_STATE_CHANGE} event: another service is speaking. */ 790 public static final int SPEECH_STATE_SPEAKING_START = 1 /* << 0 */;; 791 792 /** 793 * Change type for {@link #TYPE_SPEECH_STATE_CHANGE} event: another service is no longer 794 * speaking. 795 */ 796 public static final int SPEECH_STATE_SPEAKING_END = 1 << 1; 797 798 /** 799 * Change type for {@link #TYPE_SPEECH_STATE_CHANGE} event: another service is listening to the 800 * microphone. 801 */ 802 public static final int SPEECH_STATE_LISTENING_START = 1 << 2; 803 804 /** 805 * Change type for {@link #TYPE_SPEECH_STATE_CHANGE} event: another service is no longer 806 * listening to the microphone. 807 */ 808 public static final int SPEECH_STATE_LISTENING_END = 1 << 3; 809 810 // Windows change types. 811 812 /** 813 * Change type for {@link #TYPE_WINDOWS_CHANGED} event: 814 * The window was added. 815 */ 816 public static final int WINDOWS_CHANGE_ADDED = 1 /* << 0 */;; 817 818 /** 819 * Change type for {@link #TYPE_WINDOWS_CHANGED} event: 820 * A window was removed. 821 */ 822 public static final int WINDOWS_CHANGE_REMOVED = 1 << 1; 823 824 /** 825 * Change type for {@link #TYPE_WINDOWS_CHANGED} event: 826 * The window's title changed. 827 */ 828 public static final int WINDOWS_CHANGE_TITLE = 1 << 2; 829 830 /** 831 * Change type for {@link #TYPE_WINDOWS_CHANGED} event: 832 * The window's bounds changed. 833 * <p> 834 * Starting in {@link android.os.Build.VERSION_CODES#R R}, this event implies the window's 835 * region changed. It's also possible that region changed but bounds doesn't. 836 * </p> 837 */ 838 public static final int WINDOWS_CHANGE_BOUNDS = 1 << 3; 839 840 /** 841 * Change type for {@link #TYPE_WINDOWS_CHANGED} event: 842 * The window's layer changed. 843 */ 844 public static final int WINDOWS_CHANGE_LAYER = 1 << 4; 845 846 /** 847 * Change type for {@link #TYPE_WINDOWS_CHANGED} event: 848 * The window's {@link AccessibilityWindowInfo#isActive()} changed. 849 */ 850 public static final int WINDOWS_CHANGE_ACTIVE = 1 << 5; 851 852 /** 853 * Change type for {@link #TYPE_WINDOWS_CHANGED} event: 854 * The window's {@link AccessibilityWindowInfo#isFocused()} changed. 855 */ 856 public static final int WINDOWS_CHANGE_FOCUSED = 1 << 6; 857 858 /** 859 * Change type for {@link #TYPE_WINDOWS_CHANGED} event: 860 * The window's {@link AccessibilityWindowInfo#isAccessibilityFocused()} changed. 861 */ 862 public static final int WINDOWS_CHANGE_ACCESSIBILITY_FOCUSED = 1 << 7; 863 864 /** 865 * Change type for {@link #TYPE_WINDOWS_CHANGED} event: 866 * The window's parent changed. 867 */ 868 public static final int WINDOWS_CHANGE_PARENT = 1 << 8; 869 870 /** 871 * Change type for {@link #TYPE_WINDOWS_CHANGED} event: 872 * The window's children changed. 873 */ 874 public static final int WINDOWS_CHANGE_CHILDREN = 1 << 9; 875 876 /** 877 * Change type for {@link #TYPE_WINDOWS_CHANGED} event: 878 * The window either entered or exited picture-in-picture mode. 879 */ 880 public static final int WINDOWS_CHANGE_PIP = 1 << 10; 881 882 /** @hide */ 883 @Retention(RetentionPolicy.SOURCE) 884 @IntDef(flag = true, prefix = { "WINDOWS_CHANGE_" }, value = { 885 WINDOWS_CHANGE_ADDED, 886 WINDOWS_CHANGE_REMOVED, 887 WINDOWS_CHANGE_TITLE, 888 WINDOWS_CHANGE_BOUNDS, 889 WINDOWS_CHANGE_LAYER, 890 WINDOWS_CHANGE_ACTIVE, 891 WINDOWS_CHANGE_FOCUSED, 892 WINDOWS_CHANGE_ACCESSIBILITY_FOCUSED, 893 WINDOWS_CHANGE_PARENT, 894 WINDOWS_CHANGE_CHILDREN, 895 WINDOWS_CHANGE_PIP 896 }) 897 public @interface WindowsChangeTypes {} 898 899 /** @hide */ 900 @Retention(RetentionPolicy.SOURCE) 901 @IntDef( 902 flag = true, 903 prefix = {"CONTENT_CHANGE_TYPE_"}, 904 value = { 905 CONTENT_CHANGE_TYPE_UNDEFINED, 906 CONTENT_CHANGE_TYPE_SUBTREE, 907 CONTENT_CHANGE_TYPE_TEXT, 908 CONTENT_CHANGE_TYPE_CONTENT_DESCRIPTION, 909 CONTENT_CHANGE_TYPE_STATE_DESCRIPTION, 910 CONTENT_CHANGE_TYPE_PANE_TITLE, 911 CONTENT_CHANGE_TYPE_PANE_APPEARED, 912 CONTENT_CHANGE_TYPE_PANE_DISAPPEARED, 913 CONTENT_CHANGE_TYPE_DRAG_STARTED, 914 CONTENT_CHANGE_TYPE_DRAG_DROPPED, 915 CONTENT_CHANGE_TYPE_DRAG_CANCELLED, 916 CONTENT_CHANGE_TYPE_CONTENT_INVALID, 917 CONTENT_CHANGE_TYPE_ERROR, 918 CONTENT_CHANGE_TYPE_ENABLED, 919 }) 920 public @interface ContentChangeTypes {} 921 922 /** @hide */ 923 @Retention(RetentionPolicy.SOURCE) 924 @IntDef( 925 flag = true, 926 prefix = {"SPEECH_STATE_"}, 927 value = { 928 SPEECH_STATE_SPEAKING_START, 929 SPEECH_STATE_SPEAKING_END, 930 SPEECH_STATE_LISTENING_START, 931 SPEECH_STATE_LISTENING_END 932 }) 933 public @interface SpeechStateChangeTypes {} 934 935 /** @hide */ 936 @Retention(RetentionPolicy.SOURCE) 937 @IntDef( 938 flag = true, 939 prefix = {"TYPE_"}, 940 value = { 941 TYPE_VIEW_CLICKED, 942 TYPE_VIEW_LONG_CLICKED, 943 TYPE_VIEW_SELECTED, 944 TYPE_VIEW_FOCUSED, 945 TYPE_VIEW_TEXT_CHANGED, 946 TYPE_WINDOW_STATE_CHANGED, 947 TYPE_NOTIFICATION_STATE_CHANGED, 948 TYPE_VIEW_HOVER_ENTER, 949 TYPE_VIEW_HOVER_EXIT, 950 TYPE_TOUCH_EXPLORATION_GESTURE_START, 951 TYPE_TOUCH_EXPLORATION_GESTURE_END, 952 TYPE_WINDOW_CONTENT_CHANGED, 953 TYPE_VIEW_SCROLLED, 954 TYPE_VIEW_TEXT_SELECTION_CHANGED, 955 TYPE_ANNOUNCEMENT, 956 TYPE_VIEW_ACCESSIBILITY_FOCUSED, 957 TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED, 958 TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY, 959 TYPE_GESTURE_DETECTION_START, 960 TYPE_GESTURE_DETECTION_END, 961 TYPE_TOUCH_INTERACTION_START, 962 TYPE_TOUCH_INTERACTION_END, 963 TYPE_WINDOWS_CHANGED, 964 TYPE_VIEW_CONTEXT_CLICKED, 965 TYPE_ASSIST_READING_CONTEXT, 966 TYPE_SPEECH_STATE_CHANGE, 967 TYPE_VIEW_TARGETED_BY_SCROLL 968 }) 969 public @interface EventType {} 970 971 /** 972 * Mask for {@link AccessibilityEvent} all types. 973 * 974 * @see #TYPE_VIEW_CLICKED 975 * @see #TYPE_VIEW_LONG_CLICKED 976 * @see #TYPE_VIEW_SELECTED 977 * @see #TYPE_VIEW_FOCUSED 978 * @see #TYPE_VIEW_TEXT_CHANGED 979 * @see #TYPE_WINDOW_STATE_CHANGED 980 * @see #TYPE_NOTIFICATION_STATE_CHANGED 981 * @see #TYPE_VIEW_HOVER_ENTER 982 * @see #TYPE_VIEW_HOVER_EXIT 983 * @see #TYPE_TOUCH_EXPLORATION_GESTURE_START 984 * @see #TYPE_TOUCH_EXPLORATION_GESTURE_END 985 * @see #TYPE_WINDOW_CONTENT_CHANGED 986 * @see #TYPE_VIEW_SCROLLED 987 * @see #TYPE_VIEW_TEXT_SELECTION_CHANGED 988 * @see #TYPE_ANNOUNCEMENT 989 * @see #TYPE_VIEW_ACCESSIBILITY_FOCUSED 990 * @see #TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED 991 * @see #TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY 992 * @see #TYPE_GESTURE_DETECTION_START 993 * @see #TYPE_GESTURE_DETECTION_END 994 * @see #TYPE_TOUCH_INTERACTION_START 995 * @see #TYPE_TOUCH_INTERACTION_END 996 * @see #TYPE_WINDOWS_CHANGED 997 * @see #TYPE_VIEW_CONTEXT_CLICKED 998 * @see #TYPE_ASSIST_READING_CONTEXT 999 * @see #TYPE_SPEECH_STATE_CHANGE 1000 * @see #TYPE_VIEW_TARGETED_BY_SCROLL 1001 */ 1002 public static final int TYPES_ALL_MASK = 0xFFFFFFFF; 1003 1004 @UnsupportedAppUsage 1005 @EventType 1006 private int mEventType; 1007 private CharSequence mPackageName; 1008 private long mEventTime; 1009 int mMovementGranularity; 1010 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) 1011 int mAction; 1012 int mContentChangeTypes; 1013 int mWindowChangeTypes; 1014 int mSpeechStateChangeTypes; 1015 1016 /** 1017 * The stack trace describing where this event originated from on the app side. 1018 * Only populated if {@link #DEBUG_ORIGIN} is enabled 1019 * Can be inspected(e.g. printed) from an 1020 * {@link android.accessibilityservice.AccessibilityService} to trace where particular events 1021 * are being dispatched from. 1022 * 1023 * @hide 1024 */ 1025 public StackTraceElement[] originStackTrace = null; 1026 1027 private ArrayList<AccessibilityRecord> mRecords; 1028 1029 /** 1030 * Creates a new {@link AccessibilityEvent}. 1031 */ AccessibilityEvent()1032 public AccessibilityEvent() { 1033 if (DEBUG_ORIGIN) originStackTrace = Thread.currentThread().getStackTrace(); 1034 } 1035 1036 1037 /** 1038 * Creates a new {@link AccessibilityEvent} with the given <code>eventType</code>. 1039 * 1040 * @param eventType The event type. 1041 */ AccessibilityEvent(int eventType)1042 public AccessibilityEvent(int eventType) { 1043 mEventType = eventType; 1044 if (DEBUG_ORIGIN) originStackTrace = Thread.currentThread().getStackTrace(); 1045 } 1046 1047 /** 1048 * Copy constructor. Creates a new {@link AccessibilityEvent}, and this instance is initialized 1049 * from the given <code>event</code>. 1050 * 1051 * @param event The other event. 1052 */ AccessibilityEvent(@onNull AccessibilityEvent event)1053 public AccessibilityEvent(@NonNull AccessibilityEvent event) { 1054 init(event); 1055 } 1056 1057 /** 1058 * Initialize an event from another one. 1059 * 1060 * @param event The event to initialize from. 1061 */ init(AccessibilityEvent event)1062 void init(AccessibilityEvent event) { 1063 super.init(event); 1064 mEventType = event.mEventType; 1065 mMovementGranularity = event.mMovementGranularity; 1066 mAction = event.mAction; 1067 mContentChangeTypes = event.mContentChangeTypes; 1068 mSpeechStateChangeTypes = event.mSpeechStateChangeTypes; 1069 mWindowChangeTypes = event.mWindowChangeTypes; 1070 mEventTime = event.mEventTime; 1071 mPackageName = event.mPackageName; 1072 if (event.mRecords != null) { 1073 mRecords = new ArrayList<>(event.mRecords.size()); 1074 for (AccessibilityRecord record : event.mRecords) { 1075 final AccessibilityRecord recordClone = new AccessibilityRecord(record); 1076 mRecords.add(recordClone); 1077 } 1078 } 1079 if (DEBUG_ORIGIN) originStackTrace = event.originStackTrace; 1080 } 1081 1082 /** 1083 * Sets if this instance is sealed. 1084 * 1085 * @param sealed Whether is sealed. 1086 * 1087 * @hide 1088 */ 1089 @Override setSealed(boolean sealed)1090 public void setSealed(boolean sealed) { 1091 super.setSealed(sealed); 1092 final List<AccessibilityRecord> records = mRecords; 1093 if (records != null) { 1094 for (AccessibilityRecord record : records) { 1095 record.setSealed(sealed); 1096 } 1097 } 1098 } 1099 1100 /** 1101 * Gets the number of records contained in the event. 1102 * 1103 * @return The number of records. 1104 */ getRecordCount()1105 public int getRecordCount() { 1106 return mRecords == null ? 0 : mRecords.size(); 1107 } 1108 1109 /** 1110 * Appends an {@link AccessibilityRecord} to the end of event records. 1111 * 1112 * @param record The record to append. 1113 * 1114 * @throws IllegalStateException If called from an AccessibilityService. 1115 */ appendRecord(AccessibilityRecord record)1116 public void appendRecord(AccessibilityRecord record) { 1117 enforceNotSealed(); 1118 if (mRecords == null) { 1119 mRecords = new ArrayList<AccessibilityRecord>(); 1120 } 1121 mRecords.add(record); 1122 } 1123 1124 /** 1125 * Gets the record at a given index. 1126 * 1127 * @param index The index. 1128 * @return The record at the specified index. 1129 */ getRecord(int index)1130 public AccessibilityRecord getRecord(int index) { 1131 if (mRecords == null) { 1132 throw new IndexOutOfBoundsException("Invalid index " + index + ", size is 0"); 1133 } 1134 return mRecords.get(index); 1135 } 1136 1137 /** 1138 * Gets the event type. 1139 * 1140 * @return The event type. 1141 */ 1142 @EventType getEventType()1143 public int getEventType() { 1144 return mEventType; 1145 } 1146 1147 /** 1148 * Gets the bit mask of change types signaled by a 1149 * {@link #TYPE_WINDOW_CONTENT_CHANGED} event or {@link #TYPE_WINDOW_STATE_CHANGED}. A single 1150 * event may represent multiple change types. 1151 * 1152 * @return The bit mask of change types. One or more of: 1153 * <ul> 1154 * <li>{@link #CONTENT_CHANGE_TYPE_CONTENT_DESCRIPTION} 1155 * <li>{@link #CONTENT_CHANGE_TYPE_STATE_DESCRIPTION} 1156 * <li>{@link #CONTENT_CHANGE_TYPE_SUBTREE} 1157 * <li>{@link #CONTENT_CHANGE_TYPE_TEXT} 1158 * <li>{@link #CONTENT_CHANGE_TYPE_PANE_TITLE} 1159 * <li>{@link #CONTENT_CHANGE_TYPE_UNDEFINED} 1160 * <li>{@link #CONTENT_CHANGE_TYPE_PANE_APPEARED} 1161 * <li>{@link #CONTENT_CHANGE_TYPE_PANE_DISAPPEARED} 1162 * <li>{@link #CONTENT_CHANGE_TYPE_DRAG_STARTED} 1163 * <li>{@link #CONTENT_CHANGE_TYPE_DRAG_DROPPED} 1164 * <li>{@link #CONTENT_CHANGE_TYPE_DRAG_CANCELLED} 1165 * <li>{@link #CONTENT_CHANGE_TYPE_CONTENT_INVALID} 1166 * <li>{@link #CONTENT_CHANGE_TYPE_ERROR} 1167 * <li>{@link #CONTENT_CHANGE_TYPE_ENABLED} 1168 * </ul> 1169 */ 1170 @ContentChangeTypes getContentChangeTypes()1171 public int getContentChangeTypes() { 1172 return mContentChangeTypes; 1173 } 1174 contentChangeTypesToString(int types)1175 private static String contentChangeTypesToString(int types) { 1176 return BitUtils.flagsToString(types, AccessibilityEvent::singleContentChangeTypeToString); 1177 } 1178 singleContentChangeTypeToString(int type)1179 private static String singleContentChangeTypeToString(int type) { 1180 switch (type) { 1181 case CONTENT_CHANGE_TYPE_CONTENT_DESCRIPTION: 1182 return "CONTENT_CHANGE_TYPE_CONTENT_DESCRIPTION"; 1183 case CONTENT_CHANGE_TYPE_STATE_DESCRIPTION: 1184 return "CONTENT_CHANGE_TYPE_STATE_DESCRIPTION"; 1185 case CONTENT_CHANGE_TYPE_SUBTREE: return "CONTENT_CHANGE_TYPE_SUBTREE"; 1186 case CONTENT_CHANGE_TYPE_TEXT: return "CONTENT_CHANGE_TYPE_TEXT"; 1187 case CONTENT_CHANGE_TYPE_PANE_TITLE: return "CONTENT_CHANGE_TYPE_PANE_TITLE"; 1188 case CONTENT_CHANGE_TYPE_UNDEFINED: return "CONTENT_CHANGE_TYPE_UNDEFINED"; 1189 case CONTENT_CHANGE_TYPE_PANE_APPEARED: return "CONTENT_CHANGE_TYPE_PANE_APPEARED"; 1190 case CONTENT_CHANGE_TYPE_PANE_DISAPPEARED: 1191 return "CONTENT_CHANGE_TYPE_PANE_DISAPPEARED"; 1192 case CONTENT_CHANGE_TYPE_DRAG_STARTED: return "CONTENT_CHANGE_TYPE_DRAG_STARTED"; 1193 case CONTENT_CHANGE_TYPE_DRAG_DROPPED: return "CONTENT_CHANGE_TYPE_DRAG_DROPPED"; 1194 case CONTENT_CHANGE_TYPE_DRAG_CANCELLED: return "CONTENT_CHANGE_TYPE_DRAG_CANCELLED"; 1195 case CONTENT_CHANGE_TYPE_CONTENT_INVALID: 1196 return "CONTENT_CHANGE_TYPE_CONTENT_INVALID"; 1197 case CONTENT_CHANGE_TYPE_ERROR: return "CONTENT_CHANGE_TYPE_ERROR"; 1198 case CONTENT_CHANGE_TYPE_ENABLED: return "CONTENT_CHANGE_TYPE_ENABLED"; 1199 default: return Integer.toHexString(type); 1200 } 1201 } 1202 1203 /** 1204 * Sets the bit mask of node tree changes signaled by an 1205 * {@link #TYPE_WINDOW_CONTENT_CHANGED} event. 1206 * 1207 * @param changeTypes The bit mask of change types. 1208 * @throws IllegalStateException If called from an AccessibilityService. 1209 * @see #getContentChangeTypes() 1210 */ setContentChangeTypes(@ontentChangeTypes int changeTypes)1211 public void setContentChangeTypes(@ContentChangeTypes int changeTypes) { 1212 enforceNotSealed(); 1213 mContentChangeTypes = changeTypes; 1214 } 1215 1216 /** 1217 * Whether the event should only be delivered to an 1218 * {@link android.accessibilityservice.AccessibilityService} with the 1219 * {@link android.accessibilityservice.AccessibilityServiceInfo#isAccessibilityTool} property 1220 * set to true. 1221 * 1222 * <p> 1223 * Initial value matches the {@link android.view.View#isAccessibilityDataSensitive} property 1224 * from the event's source node, if present, or false by default. 1225 * </p> 1226 * 1227 * @return True if the event should be delivered only to isAccessibilityTool services, false 1228 * otherwise. 1229 * @see #setAccessibilityDataSensitive 1230 */ 1231 @Override isAccessibilityDataSensitive()1232 public boolean isAccessibilityDataSensitive() { 1233 return super.isAccessibilityDataSensitive(); 1234 } 1235 1236 /** 1237 * Sets whether the event should only be delivered to an 1238 * {@link android.accessibilityservice.AccessibilityService} with the 1239 * {@link android.accessibilityservice.AccessibilityServiceInfo#isAccessibilityTool} property 1240 * set to true. 1241 * 1242 * <p> 1243 * This will be set automatically based on the event's source (if present). If creating and 1244 * sending an event directly through {@link AccessibilityManager} (where an event may have 1245 * no source) then this method must be called explicitly if you want non-default behavior. 1246 * </p> 1247 * 1248 * @param accessibilityDataSensitive True if the event should be delivered only to 1249 * isAccessibilityTool services, false otherwise. 1250 * @throws IllegalStateException If called from an AccessibilityService. 1251 */ 1252 @Override setAccessibilityDataSensitive(boolean accessibilityDataSensitive)1253 public void setAccessibilityDataSensitive(boolean accessibilityDataSensitive) { 1254 super.setAccessibilityDataSensitive(accessibilityDataSensitive); 1255 } 1256 1257 /** 1258 * Gets the bit mask of the speech state signaled by a {@link #TYPE_SPEECH_STATE_CHANGE} event. 1259 * 1260 * @return The bit mask of speech change types. 1261 * 1262 * @see #SPEECH_STATE_SPEAKING_START 1263 * @see #SPEECH_STATE_SPEAKING_END 1264 * @see #SPEECH_STATE_LISTENING_START 1265 * @see #SPEECH_STATE_LISTENING_END 1266 */ getSpeechStateChangeTypes()1267 public int getSpeechStateChangeTypes() { 1268 return mSpeechStateChangeTypes; 1269 } 1270 speechStateChangeTypesToString(int types)1271 private static String speechStateChangeTypesToString(int types) { 1272 return BitUtils.flagsToString( 1273 types, AccessibilityEvent::singleSpeechStateChangeTypeToString); 1274 } 1275 singleSpeechStateChangeTypeToString(int type)1276 private static String singleSpeechStateChangeTypeToString(int type) { 1277 switch (type) { 1278 case SPEECH_STATE_SPEAKING_START: 1279 return "SPEECH_STATE_SPEAKING_START"; 1280 case SPEECH_STATE_LISTENING_START: 1281 return "SPEECH_STATE_LISTENING_START"; 1282 case SPEECH_STATE_SPEAKING_END: 1283 return "SPEECH_STATE_SPEAKING_END"; 1284 case SPEECH_STATE_LISTENING_END: 1285 return "SPEECH_STATE_LISTENING_END"; 1286 default: 1287 return Integer.toHexString(type); 1288 } 1289 } 1290 1291 /** 1292 * Sets the bit mask of the speech state change types 1293 * signaled by a {@link #TYPE_SPEECH_STATE_CHANGE} event. 1294 * The sender is responsible for ensuring that the state change types make sense. For example, 1295 * the sender should not send 1296 * {@link #SPEECH_STATE_SPEAKING_START} and {@link #SPEECH_STATE_SPEAKING_END} together. 1297 * 1298 * @see #SPEECH_STATE_SPEAKING_START 1299 * @see #SPEECH_STATE_SPEAKING_END 1300 * @see #SPEECH_STATE_LISTENING_START 1301 * @see #SPEECH_STATE_LISTENING_END 1302 */ setSpeechStateChangeTypes(@peechStateChangeTypes int state)1303 public void setSpeechStateChangeTypes(@SpeechStateChangeTypes int state) { 1304 enforceNotSealed(); 1305 mSpeechStateChangeTypes = state; 1306 } 1307 1308 /** 1309 * Get the bit mask of change types signaled by a {@link #TYPE_WINDOWS_CHANGED} event. A 1310 * single event may represent multiple change types. 1311 * 1312 * @return The bit mask of change types. 1313 * 1314 * @see #WINDOWS_CHANGE_ADDED 1315 * @see #WINDOWS_CHANGE_REMOVED 1316 * @see #WINDOWS_CHANGE_TITLE 1317 * @see #WINDOWS_CHANGE_BOUNDS 1318 * @see #WINDOWS_CHANGE_LAYER 1319 * @see #WINDOWS_CHANGE_ACTIVE 1320 * @see #WINDOWS_CHANGE_FOCUSED 1321 * @see #WINDOWS_CHANGE_ACCESSIBILITY_FOCUSED 1322 * @see #WINDOWS_CHANGE_PARENT 1323 * @see #WINDOWS_CHANGE_CHILDREN 1324 * @see #WINDOWS_CHANGE_PIP 1325 */ 1326 @WindowsChangeTypes getWindowChanges()1327 public int getWindowChanges() { 1328 return mWindowChangeTypes; 1329 } 1330 1331 /** @hide */ setWindowChanges(@indowsChangeTypes int changes)1332 public void setWindowChanges(@WindowsChangeTypes int changes) { 1333 mWindowChangeTypes = changes; 1334 } 1335 windowChangeTypesToString(@indowsChangeTypes int types)1336 private static String windowChangeTypesToString(@WindowsChangeTypes int types) { 1337 return BitUtils.flagsToString(types, AccessibilityEvent::singleWindowChangeTypeToString); 1338 } 1339 singleWindowChangeTypeToString(int type)1340 private static String singleWindowChangeTypeToString(int type) { 1341 switch (type) { 1342 case WINDOWS_CHANGE_ADDED: return "WINDOWS_CHANGE_ADDED"; 1343 case WINDOWS_CHANGE_REMOVED: return "WINDOWS_CHANGE_REMOVED"; 1344 case WINDOWS_CHANGE_TITLE: return "WINDOWS_CHANGE_TITLE"; 1345 case WINDOWS_CHANGE_BOUNDS: return "WINDOWS_CHANGE_BOUNDS"; 1346 case WINDOWS_CHANGE_LAYER: return "WINDOWS_CHANGE_LAYER"; 1347 case WINDOWS_CHANGE_ACTIVE: return "WINDOWS_CHANGE_ACTIVE"; 1348 case WINDOWS_CHANGE_FOCUSED: return "WINDOWS_CHANGE_FOCUSED"; 1349 case WINDOWS_CHANGE_ACCESSIBILITY_FOCUSED: 1350 return "WINDOWS_CHANGE_ACCESSIBILITY_FOCUSED"; 1351 case WINDOWS_CHANGE_PARENT: return "WINDOWS_CHANGE_PARENT"; 1352 case WINDOWS_CHANGE_CHILDREN: return "WINDOWS_CHANGE_CHILDREN"; 1353 case WINDOWS_CHANGE_PIP: return "WINDOWS_CHANGE_PIP"; 1354 default: return Integer.toHexString(type); 1355 } 1356 } 1357 1358 /** 1359 * Sets the event type. 1360 * 1361 * <b>Note: An event must represent a single event type.</b> 1362 * @param eventType The event type. 1363 * 1364 * @throws IllegalStateException If called from an AccessibilityService. 1365 */ setEventType(@ventType int eventType)1366 public void setEventType(@EventType int eventType) { 1367 enforceNotSealed(); 1368 mEventType = eventType; 1369 } 1370 1371 /** 1372 * Gets the time in which this event was sent. 1373 * 1374 * @return The event time. 1375 */ getEventTime()1376 public long getEventTime() { 1377 return mEventTime; 1378 } 1379 1380 /** 1381 * Sets the time in which this event was sent. 1382 * 1383 * @param eventTime The event time. 1384 * 1385 * @throws IllegalStateException If called from an AccessibilityService. 1386 */ setEventTime(long eventTime)1387 public void setEventTime(long eventTime) { 1388 enforceNotSealed(); 1389 mEventTime = eventTime; 1390 } 1391 1392 /** 1393 * Gets the package name of the source. 1394 * 1395 * @return The package name. 1396 */ getPackageName()1397 public CharSequence getPackageName() { 1398 return mPackageName; 1399 } 1400 1401 /** 1402 * Sets the package name of the source. 1403 * 1404 * @param packageName The package name. 1405 * 1406 * @throws IllegalStateException If called from an AccessibilityService. 1407 */ setPackageName(CharSequence packageName)1408 public void setPackageName(CharSequence packageName) { 1409 enforceNotSealed(); 1410 mPackageName = packageName; 1411 } 1412 1413 /** 1414 * Sets the movement granularity that was traversed. 1415 * 1416 * @param granularity The granularity. 1417 * 1418 * @throws IllegalStateException If called from an AccessibilityService. 1419 */ setMovementGranularity(int granularity)1420 public void setMovementGranularity(int granularity) { 1421 enforceNotSealed(); 1422 mMovementGranularity = granularity; 1423 } 1424 1425 /** 1426 * Gets the movement granularity that was traversed. 1427 * 1428 * @return The granularity. 1429 */ getMovementGranularity()1430 public int getMovementGranularity() { 1431 return mMovementGranularity; 1432 } 1433 1434 /** 1435 * Sets the performed action that triggered this event. 1436 * <p> 1437 * Valid actions are defined in {@link AccessibilityNodeInfo}: 1438 * <ul> 1439 * <li>{@link AccessibilityNodeInfo#ACTION_ACCESSIBILITY_FOCUS} 1440 * <li>{@link AccessibilityNodeInfo#ACTION_CLEAR_ACCESSIBILITY_FOCUS} 1441 * <li>{@link AccessibilityNodeInfo#ACTION_CLEAR_FOCUS} 1442 * <li>{@link AccessibilityNodeInfo#ACTION_CLEAR_SELECTION} 1443 * <li>{@link AccessibilityNodeInfo#ACTION_CLICK} 1444 * <li>{@link AccessibilityNodeInfo#ACTION_LONG_CLICK} 1445 * <li>{@link AccessibilityNodeInfo#ACTION_NEXT_AT_MOVEMENT_GRANULARITY} 1446 * <li>{@link AccessibilityNodeInfo#ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY} 1447 * <li>{@link AccessibilityNodeInfo#ACTION_NEXT_HTML_ELEMENT} 1448 * <li>{@link AccessibilityNodeInfo#ACTION_PREVIOUS_HTML_ELEMENT} 1449 * <li>{@link AccessibilityNodeInfo#ACTION_SCROLL_FORWARD} 1450 * <li>{@link AccessibilityNodeInfo#ACTION_SCROLL_BACKWARD} 1451 * <li>{@link AccessibilityNodeInfo#ACTION_COPY} 1452 * <li>{@link AccessibilityNodeInfo#ACTION_PASTE} 1453 * <li>{@link AccessibilityNodeInfo#ACTION_CUT} 1454 * <li>{@link AccessibilityNodeInfo#ACTION_SET_SELECTION} 1455 * <li>{@link AccessibilityNodeInfo#ACTION_EXPAND} 1456 * <li>{@link AccessibilityNodeInfo#ACTION_COLLAPSE} 1457 * <li>{@link AccessibilityNodeInfo#ACTION_DISMISS} 1458 * <li>{@link AccessibilityNodeInfo#ACTION_SET_TEXT} 1459 * <li>etc. 1460 * </ul> 1461 * 1462 * @param action The action. 1463 * @throws IllegalStateException If called from an AccessibilityService. 1464 * @see AccessibilityNodeInfo#performAction(int) 1465 */ setAction(int action)1466 public void setAction(int action) { 1467 enforceNotSealed(); 1468 mAction = action; 1469 } 1470 1471 /** 1472 * Gets the performed action that triggered this event. 1473 * 1474 * @return The action. 1475 */ getAction()1476 public int getAction() { 1477 return mAction; 1478 } 1479 1480 /** 1481 * Convenience method to obtain a {@link #TYPE_WINDOWS_CHANGED} event for a specific window and 1482 * change set. 1483 * 1484 * @param displayId The ID of the display from which the event comes from 1485 * @param windowId The ID of the window that changed 1486 * @param windowChangeTypes The changes to populate 1487 * @return An instance of a TYPE_WINDOWS_CHANGED, populated with the requested fields and with 1488 * importantForAccessibility set to {@code true}. 1489 * 1490 * @hide 1491 */ obtainWindowsChangedEvent( int displayId, int windowId, int windowChangeTypes)1492 public static AccessibilityEvent obtainWindowsChangedEvent( 1493 int displayId, int windowId, int windowChangeTypes) { 1494 final AccessibilityEvent event = new AccessibilityEvent(TYPE_WINDOWS_CHANGED); 1495 event.setDisplayId(displayId); 1496 event.setWindowId(windowId); 1497 event.setWindowChanges(windowChangeTypes); 1498 event.setImportantForAccessibility(true); 1499 return event; 1500 } 1501 1502 /** 1503 * Instantiates a new AccessibilityEvent instance with its type property set. 1504 * 1505 * @deprecated Object pooling has been discontinued. Create a new instance using the 1506 * constructor {@link #AccessibilityEvent()} instead. 1507 * @param eventType The event type. 1508 * @return An instance. 1509 */ 1510 @Deprecated obtain(int eventType)1511 public static AccessibilityEvent obtain(int eventType) { 1512 AccessibilityEvent event = new AccessibilityEvent(); 1513 event.setEventType(eventType); 1514 return event; 1515 } 1516 1517 /** 1518 * Instantiates a new AccessibilityEvent instance. 1519 * The returned instance is initialized from the given 1520 * <code>event</code>. 1521 * 1522 * @deprecated Object pooling has been discontinued. Create a new instance using the 1523 * constructor {@link #AccessibilityEvent()} instead. 1524 * @param event The other event. 1525 * @return An instance. 1526 */ 1527 @Deprecated obtain(AccessibilityEvent event)1528 public static AccessibilityEvent obtain(AccessibilityEvent event) { 1529 AccessibilityEvent eventClone = new AccessibilityEvent(); 1530 eventClone.init(event); 1531 return eventClone; 1532 } 1533 1534 /** 1535 * Instantiates a new AccessibilityEvent instance. 1536 * 1537 * @deprecated Object pooling has been discontinued. Create a new instance using the 1538 * constructor {@link #AccessibilityEvent()} instead. 1539 * @return An instance. 1540 */ 1541 @Deprecated obtain()1542 public static AccessibilityEvent obtain() { 1543 return new AccessibilityEvent(); 1544 } 1545 1546 /** 1547 * Previously would recycle an instance back to be reused. 1548 * 1549 * @deprecated Object pooling has been discontinued. Calling this function now will have 1550 * no effect. 1551 */ 1552 @Override 1553 @Deprecated recycle()1554 public void recycle() {} 1555 1556 /** 1557 * Clears the state of this instance. 1558 * 1559 * @hide 1560 */ 1561 @Override clear()1562 protected void clear() { 1563 super.clear(); 1564 mEventType = 0; 1565 mMovementGranularity = 0; 1566 mAction = 0; 1567 mContentChangeTypes = 0; 1568 mWindowChangeTypes = 0; 1569 mSpeechStateChangeTypes = 0; 1570 mPackageName = null; 1571 mEventTime = 0; 1572 if (mRecords != null) { 1573 while (!mRecords.isEmpty()) { 1574 AccessibilityRecord record = mRecords.remove(0); 1575 } 1576 } 1577 if (DEBUG_ORIGIN) originStackTrace = null; 1578 } 1579 1580 /** 1581 * Creates a new instance from a {@link Parcel}. 1582 * 1583 * @param parcel A parcel containing the state of a {@link AccessibilityEvent}. 1584 */ initFromParcel(Parcel parcel)1585 public void initFromParcel(Parcel parcel) { 1586 mSealed = (parcel.readInt() == 1); 1587 mEventType = parcel.readInt(); 1588 mMovementGranularity = parcel.readInt(); 1589 mAction = parcel.readInt(); 1590 mContentChangeTypes = parcel.readInt(); 1591 mWindowChangeTypes = parcel.readInt(); 1592 mSpeechStateChangeTypes = parcel.readInt(); 1593 mPackageName = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(parcel); 1594 mEventTime = parcel.readLong(); 1595 mConnectionId = parcel.readInt(); 1596 readAccessibilityRecordFromParcel(this, parcel); 1597 1598 // Read the records. 1599 final int recordCount = parcel.readInt(); 1600 if (recordCount > 0) { 1601 mRecords = new ArrayList<>(recordCount); 1602 for (int i = 0; i < recordCount; i++) { 1603 AccessibilityRecord record = new AccessibilityRecord(); 1604 readAccessibilityRecordFromParcel(record, parcel); 1605 record.mConnectionId = mConnectionId; 1606 mRecords.add(record); 1607 } 1608 } 1609 1610 if (DEBUG_ORIGIN) { 1611 originStackTrace = new StackTraceElement[parcel.readInt()]; 1612 for (int i = 0; i < originStackTrace.length; i++) { 1613 originStackTrace[i] = new StackTraceElement( 1614 parcel.readString(), 1615 parcel.readString(), 1616 parcel.readString(), 1617 parcel.readInt()); 1618 } 1619 } 1620 } 1621 1622 /** 1623 * Reads an {@link AccessibilityRecord} from a parcel. 1624 * 1625 * @param record The record to initialize. 1626 * @param parcel The parcel to read from. 1627 */ readAccessibilityRecordFromParcel(AccessibilityRecord record, Parcel parcel)1628 private void readAccessibilityRecordFromParcel(AccessibilityRecord record, 1629 Parcel parcel) { 1630 record.mBooleanProperties = parcel.readInt(); 1631 record.mCurrentItemIndex = parcel.readInt(); 1632 record.mItemCount = parcel.readInt(); 1633 record.mFromIndex = parcel.readInt(); 1634 record.mToIndex = parcel.readInt(); 1635 record.mScrollX = parcel.readInt(); 1636 record.mScrollY = parcel.readInt(); 1637 record.mScrollDeltaX = parcel.readInt(); 1638 record.mScrollDeltaY = parcel.readInt(); 1639 record.mMaxScrollX = parcel.readInt(); 1640 record.mMaxScrollY = parcel.readInt(); 1641 record.mAddedCount = parcel.readInt(); 1642 record.mRemovedCount = parcel.readInt(); 1643 record.mClassName = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(parcel); 1644 record.mContentDescription = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(parcel); 1645 record.mBeforeText = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(parcel); 1646 record.mParcelableData = parcel.readParcelable(null); 1647 parcel.readList(record.mText, null, java.lang.CharSequence.class); 1648 record.mSourceWindowId = parcel.readInt(); 1649 record.mSourceNodeId = parcel.readLong(); 1650 record.mSourceDisplayId = parcel.readInt(); 1651 record.mSealed = (parcel.readInt() == 1); 1652 } 1653 1654 /** 1655 * {@inheritDoc} 1656 */ writeToParcel(Parcel parcel, int flags)1657 public void writeToParcel(Parcel parcel, int flags) { 1658 parcel.writeInt(isSealed() ? 1 : 0); 1659 parcel.writeInt(mEventType); 1660 parcel.writeInt(mMovementGranularity); 1661 parcel.writeInt(mAction); 1662 parcel.writeInt(mContentChangeTypes); 1663 parcel.writeInt(mWindowChangeTypes); 1664 parcel.writeInt(mSpeechStateChangeTypes); 1665 TextUtils.writeToParcel(mPackageName, parcel, 0); 1666 parcel.writeLong(mEventTime); 1667 parcel.writeInt(mConnectionId); 1668 writeAccessibilityRecordToParcel(this, parcel, flags); 1669 1670 // Write the records. 1671 final int recordCount = getRecordCount(); 1672 parcel.writeInt(recordCount); 1673 for (int i = 0; i < recordCount; i++) { 1674 AccessibilityRecord record = mRecords.get(i); 1675 writeAccessibilityRecordToParcel(record, parcel, flags); 1676 } 1677 1678 if (DEBUG_ORIGIN) { 1679 if (originStackTrace == null) originStackTrace = Thread.currentThread().getStackTrace(); 1680 parcel.writeInt(originStackTrace.length); 1681 for (StackTraceElement element : originStackTrace) { 1682 parcel.writeString(element.getClassName()); 1683 parcel.writeString(element.getMethodName()); 1684 parcel.writeString(element.getFileName()); 1685 parcel.writeInt(element.getLineNumber()); 1686 } 1687 } 1688 } 1689 1690 /** 1691 * Writes an {@link AccessibilityRecord} to a parcel. 1692 * 1693 * @param record The record to write. 1694 * @param parcel The parcel to which to write. 1695 */ writeAccessibilityRecordToParcel(AccessibilityRecord record, Parcel parcel, int flags)1696 private void writeAccessibilityRecordToParcel(AccessibilityRecord record, Parcel parcel, 1697 int flags) { 1698 parcel.writeInt(record.mBooleanProperties); 1699 parcel.writeInt(record.mCurrentItemIndex); 1700 parcel.writeInt(record.mItemCount); 1701 parcel.writeInt(record.mFromIndex); 1702 parcel.writeInt(record.mToIndex); 1703 parcel.writeInt(record.mScrollX); 1704 parcel.writeInt(record.mScrollY); 1705 parcel.writeInt(record.mScrollDeltaX); 1706 parcel.writeInt(record.mScrollDeltaY); 1707 parcel.writeInt(record.mMaxScrollX); 1708 parcel.writeInt(record.mMaxScrollY); 1709 parcel.writeInt(record.mAddedCount); 1710 parcel.writeInt(record.mRemovedCount); 1711 TextUtils.writeToParcel(record.mClassName, parcel, flags); 1712 TextUtils.writeToParcel(record.mContentDescription, parcel, flags); 1713 TextUtils.writeToParcel(record.mBeforeText, parcel, flags); 1714 parcel.writeParcelable(record.mParcelableData, flags); 1715 parcel.writeList(record.mText); 1716 parcel.writeInt(record.mSourceWindowId); 1717 parcel.writeLong(record.mSourceNodeId); 1718 parcel.writeInt(record.mSourceDisplayId); 1719 parcel.writeInt(record.mSealed ? 1 : 0); 1720 } 1721 1722 /** 1723 * {@inheritDoc} 1724 */ describeContents()1725 public int describeContents() { 1726 return 0; 1727 } 1728 1729 @Override toString()1730 public String toString() { 1731 StringBuilder builder = new StringBuilder(); 1732 builder.append("EventType: ").append(eventTypeToString(mEventType)); 1733 builder.append("; EventTime: ").append(mEventTime); 1734 builder.append("; PackageName: ").append(mPackageName); 1735 if (!DEBUG_CONCISE_TOSTRING || mMovementGranularity != 0) { 1736 builder.append("; MovementGranularity: ").append(mMovementGranularity); 1737 } 1738 if (!DEBUG_CONCISE_TOSTRING || mAction != 0) { 1739 builder.append("; Action: ").append(mAction); 1740 } 1741 if (!DEBUG_CONCISE_TOSTRING || mContentChangeTypes != 0) { 1742 builder.append("; ContentChangeTypes: ").append( 1743 contentChangeTypesToString(mContentChangeTypes)); 1744 } 1745 if (!DEBUG_CONCISE_TOSTRING || mWindowChangeTypes != 0) { 1746 builder.append("; WindowChangeTypes: ").append( 1747 windowChangeTypesToString(mWindowChangeTypes)); 1748 } 1749 super.appendTo(builder); 1750 if (DEBUG || DEBUG_CONCISE_TOSTRING) { 1751 if (!DEBUG_CONCISE_TOSTRING) { 1752 builder.append("\n"); 1753 } 1754 if (DEBUG) { 1755 builder.append("; SourceWindowId: 0x").append(Long.toHexString(mSourceWindowId)); 1756 builder.append("; SourceNodeId: 0x").append(Long.toHexString(mSourceNodeId)); 1757 builder.append("; SourceDisplayId: ").append(mSourceDisplayId); 1758 } 1759 for (int i = 0; i < getRecordCount(); i++) { 1760 builder.append(" Record ").append(i).append(":"); 1761 getRecord(i).appendTo(builder).append("\n"); 1762 } 1763 } else { 1764 builder.append("; recordCount: ").append(getRecordCount()); 1765 } 1766 return builder.toString(); 1767 } 1768 1769 /** 1770 * Returns the string representation of an event type. For example, 1771 * {@link #TYPE_VIEW_CLICKED} is represented by the string TYPE_VIEW_CLICKED. 1772 * 1773 * @param eventType The event type 1774 * @return The string representation. 1775 */ eventTypeToString(int eventType)1776 public static String eventTypeToString(int eventType) { 1777 if (eventType == TYPES_ALL_MASK) { 1778 return "TYPES_ALL_MASK"; 1779 } 1780 StringBuilder builder = new StringBuilder(); 1781 int eventTypeCount = 0; 1782 while (eventType != 0) { 1783 final int eventTypeFlag = 1 << Integer.numberOfTrailingZeros(eventType); 1784 eventType &= ~eventTypeFlag; 1785 1786 if (eventTypeCount > 0) { 1787 builder.append(", "); 1788 } 1789 builder.append(singleEventTypeToString(eventTypeFlag)); 1790 1791 eventTypeCount++; 1792 } 1793 if (eventTypeCount > 1) { 1794 builder.insert(0, '['); 1795 builder.append(']'); 1796 } 1797 return builder.toString(); 1798 } 1799 singleEventTypeToString(int eventType)1800 private static String singleEventTypeToString(int eventType) { 1801 switch (eventType) { 1802 case TYPE_VIEW_CLICKED: return "TYPE_VIEW_CLICKED"; 1803 case TYPE_VIEW_LONG_CLICKED: return "TYPE_VIEW_LONG_CLICKED"; 1804 case TYPE_VIEW_SELECTED: return "TYPE_VIEW_SELECTED"; 1805 case TYPE_VIEW_FOCUSED: return "TYPE_VIEW_FOCUSED"; 1806 case TYPE_VIEW_TEXT_CHANGED: return "TYPE_VIEW_TEXT_CHANGED"; 1807 case TYPE_WINDOW_STATE_CHANGED: return "TYPE_WINDOW_STATE_CHANGED"; 1808 case TYPE_VIEW_HOVER_ENTER: return "TYPE_VIEW_HOVER_ENTER"; 1809 case TYPE_VIEW_HOVER_EXIT: return "TYPE_VIEW_HOVER_EXIT"; 1810 case TYPE_NOTIFICATION_STATE_CHANGED: return "TYPE_NOTIFICATION_STATE_CHANGED"; 1811 case TYPE_TOUCH_EXPLORATION_GESTURE_START: { 1812 return "TYPE_TOUCH_EXPLORATION_GESTURE_START"; 1813 } 1814 case TYPE_TOUCH_EXPLORATION_GESTURE_END: return "TYPE_TOUCH_EXPLORATION_GESTURE_END"; 1815 case TYPE_WINDOW_CONTENT_CHANGED: return "TYPE_WINDOW_CONTENT_CHANGED"; 1816 case TYPE_VIEW_TEXT_SELECTION_CHANGED: return "TYPE_VIEW_TEXT_SELECTION_CHANGED"; 1817 case TYPE_VIEW_SCROLLED: return "TYPE_VIEW_SCROLLED"; 1818 case TYPE_ANNOUNCEMENT: return "TYPE_ANNOUNCEMENT"; 1819 case TYPE_VIEW_ACCESSIBILITY_FOCUSED: return "TYPE_VIEW_ACCESSIBILITY_FOCUSED"; 1820 case TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED: { 1821 return "TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED"; 1822 } 1823 case TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY: { 1824 return "TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY"; 1825 } 1826 case TYPE_GESTURE_DETECTION_START: return "TYPE_GESTURE_DETECTION_START"; 1827 case TYPE_GESTURE_DETECTION_END: return "TYPE_GESTURE_DETECTION_END"; 1828 case TYPE_TOUCH_INTERACTION_START: return "TYPE_TOUCH_INTERACTION_START"; 1829 case TYPE_TOUCH_INTERACTION_END: return "TYPE_TOUCH_INTERACTION_END"; 1830 case TYPE_WINDOWS_CHANGED: return "TYPE_WINDOWS_CHANGED"; 1831 case TYPE_VIEW_CONTEXT_CLICKED: return "TYPE_VIEW_CONTEXT_CLICKED"; 1832 case TYPE_ASSIST_READING_CONTEXT: return "TYPE_ASSIST_READING_CONTEXT"; 1833 case TYPE_SPEECH_STATE_CHANGE: return "TYPE_SPEECH_STATE_CHANGE"; 1834 case TYPE_VIEW_TARGETED_BY_SCROLL: return "TYPE_VIEW_TARGETED_BY_SCROLL"; 1835 default: return Integer.toHexString(eventType); 1836 } 1837 } 1838 1839 /** 1840 * @see Parcelable.Creator 1841 */ 1842 @NonNull 1843 public static final Parcelable.Creator<AccessibilityEvent> CREATOR = 1844 new Parcelable.Creator<AccessibilityEvent>() { 1845 public AccessibilityEvent createFromParcel(Parcel parcel) { 1846 AccessibilityEvent event = new AccessibilityEvent(); 1847 event.initFromParcel(parcel); 1848 return event; 1849 } 1850 1851 public AccessibilityEvent[] newArray(int size) { 1852 return new AccessibilityEvent[size]; 1853 } 1854 }; 1855 } 1856