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