AccessibilityEvent.java revision 9210ccbdc3629cead65a822d729e1783a773118c
1/* 2 * Copyright (C) 2009 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package android.view.accessibility; 18 19import android.accessibilityservice.IAccessibilityServiceConnection; 20import android.os.Parcel; 21import android.os.Parcelable; 22import android.os.RemoteException; 23import android.text.TextUtils; 24import android.view.View; 25 26import java.util.ArrayList; 27 28/** 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 * An accessibility event is fired by an individual view which populates the event with 34 * a record for its state and requests from its parent to send the event to interested 35 * parties. The parent can optionally add a record for itself before dispatching a similar 36 * request to its parent. A parent can also choose not to respect the request for sending 37 * an event. The accessibility event is sent by the topmost view in the view tree. 38 * Therefore, an {@link android.accessibilityservice.AccessibilityService} can explore 39 * all records in an accessibility event to obtain more information about the context 40 * in which the event was fired. 41 * <p> 42 * A client can add, remove, and modify records. The getters and setters for individual 43 * properties operate on the current record which can be explicitly set by the client. By 44 * default current is the first record. Thus, querying a record would require setting 45 * it as the current one and interacting with the property getters and setters. 46 * <p> 47 * This class represents various semantically different accessibility event 48 * types. Each event type has associated a set of related properties. In other 49 * words, each event type is characterized via a subset of the properties exposed 50 * by this class. For each event type there is a corresponding constant defined 51 * in this class. Since some event types are semantically close there are mask 52 * constants that group them together. Follows a specification of the event 53 * types and their associated properties: 54 * <p> 55 * <b>VIEW TYPES</b> <br> 56 * <p> 57 * <b>View clicked</b> - represents the event of clicking on a {@link android.view.View} 58 * like {@link android.widget.Button}, {@link android.widget.CompoundButton}, etc. <br> 59 * Type:{@link #TYPE_VIEW_CLICKED} <br> 60 * Properties: 61 * {@link #getClassName()}, 62 * {@link #getPackageName()}, 63 * {@link #getEventTime()}, 64 * {@link #getText()}, 65 * {@link #isChecked()}, 66 * {@link #isEnabled()}, 67 * {@link #isPassword()}, 68 * {@link #getItemCount()}, 69 * {@link #getCurrentItemIndex()} 70 * <p> 71 * <b>View long clicked</b> - represents the event of long clicking on a {@link android.view.View} 72 * like {@link android.widget.Button}, {@link android.widget.CompoundButton}, etc. <br> 73 * Type:{@link #TYPE_VIEW_LONG_CLICKED} <br> 74 * Properties: 75 * {@link #getClassName()}, 76 * {@link #getPackageName()}, 77 * {@link #getEventTime()}, 78 * {@link #getText()}, 79 * {@link #isChecked()}, 80 * {@link #isEnabled()}, 81 * {@link #isPassword()}, 82 * {@link #getItemCount()}, 83 * {@link #getCurrentItemIndex()} 84 * <p> 85 * <b>View selected</b> - represents the event of selecting an item usually in 86 * the context of an {@link android.widget.AdapterView}. <br> 87 * Type: {@link #TYPE_VIEW_SELECTED} <br> 88 * Properties: 89 * {@link #getClassName()}, 90 * {@link #getPackageName()}, 91 * {@link #getEventTime()}, 92 * {@link #getText()}, 93 * {@link #isChecked()}, 94 * {@link #isEnabled()}, 95 * {@link #isPassword()}, 96 * {@link #getItemCount()}, 97 * {@link #getCurrentItemIndex()} 98 * <p> 99 * <b>View focused</b> - represents the event of focusing a 100 * {@link android.view.View}. <br> 101 * Type: {@link #TYPE_VIEW_FOCUSED} <br> 102 * Properties: 103 * {@link #getClassName()}, 104 * {@link #getPackageName()}, 105 * {@link #getEventTime()}, 106 * {@link #getText()}, 107 * {@link #isChecked()}, 108 * {@link #isEnabled()}, 109 * {@link #isPassword()}, 110 * {@link #getItemCount()}, 111 * {@link #getCurrentItemIndex()} 112 * <p> 113 * <b>View text changed</b> - represents the event of changing the text of an 114 * {@link android.widget.EditText}. <br> 115 * Type: {@link #TYPE_VIEW_TEXT_CHANGED} <br> 116 * Properties: 117 * {@link #getClassName()}, 118 * {@link #getPackageName()}, 119 * {@link #getEventTime()}, 120 * {@link #getText()}, 121 * {@link #isChecked()}, 122 * {@link #isEnabled()}, 123 * {@link #isPassword()}, 124 * {@link #getItemCount()}, 125 * {@link #getCurrentItemIndex()}, 126 * {@link #getFromIndex()}, 127 * {@link #getAddedCount()}, 128 * {@link #getRemovedCount()}, 129 * {@link #getBeforeText()} 130 * <p> 131 * <b>TRANSITION TYPES</b> <br> 132 * <p> 133 * <b>Window state changed</b> - represents the event of opening/closing a 134 * {@link android.widget.PopupWindow}, {@link android.view.Menu}, 135 * {@link android.app.Dialog}, etc. <br> 136 * Type: {@link #TYPE_WINDOW_STATE_CHANGED} <br> 137 * Properties: 138 * {@link #getClassName()}, 139 * {@link #getPackageName()}, 140 * {@link #getEventTime()}, 141 * {@link #getText()} 142 * <p> 143 * <b>NOTIFICATION TYPES</b> <br> 144 * <p> 145 * <b>Notification state changed</b> - represents the event showing/hiding 146 * {@link android.app.Notification}. 147 * Type: {@link #TYPE_NOTIFICATION_STATE_CHANGED} <br> 148 * Properties: 149 * {@link #getClassName()}, 150 * {@link #getPackageName()}, 151 * {@link #getEventTime()}, 152 * {@link #getText()} 153 * {@link #getParcelableData()} 154 * <p> 155 * <b>Security note</b> 156 * <p> 157 * Since an event contains the text of its source privacy can be compromised by leaking of 158 * sensitive information such as passwords. To address this issue any event fired in response 159 * to manipulation of a PASSWORD field does NOT CONTAIN the text of the password. 160 * 161 * @see android.view.accessibility.AccessibilityManager 162 * @see android.accessibilityservice.AccessibilityService 163 */ 164public final class AccessibilityEvent extends AccessibilityRecord implements Parcelable { 165 private static final boolean DEBUG = false; 166 167 /** 168 * Invalid selection/focus position. 169 * 170 * @see #getCurrentItemIndex() 171 */ 172 public static final int INVALID_POSITION = -1; 173 174 /** 175 * Maximum length of the text fields. 176 * 177 * @see #getBeforeText() 178 * @see #getText() 179 * </br> 180 * Note: This constant is no longer needed since there 181 * is no limit on the length of text that is contained 182 * in an accessibility event anymore. 183 */ 184 @Deprecated 185 public static final int MAX_TEXT_LENGTH = 500; 186 187 /** 188 * Represents the event of clicking on a {@link android.view.View} like 189 * {@link android.widget.Button}, {@link android.widget.CompoundButton}, etc. 190 */ 191 public static final int TYPE_VIEW_CLICKED = 0x00000001; 192 193 /** 194 * Represents the event of long clicking on a {@link android.view.View} like 195 * {@link android.widget.Button}, {@link android.widget.CompoundButton}, etc. 196 */ 197 public static final int TYPE_VIEW_LONG_CLICKED = 0x00000002; 198 199 /** 200 * Represents the event of selecting an item usually in the context of an 201 * {@link android.widget.AdapterView}. 202 */ 203 public static final int TYPE_VIEW_SELECTED = 0x00000004; 204 205 /** 206 * Represents the event of focusing a {@link android.view.View}. 207 */ 208 public static final int TYPE_VIEW_FOCUSED = 0x00000008; 209 210 /** 211 * Represents the event of changing the text of an {@link android.widget.EditText}. 212 */ 213 public static final int TYPE_VIEW_TEXT_CHANGED = 0x00000010; 214 215 /** 216 * Represents the event of opening/closing a {@link android.widget.PopupWindow}, 217 * {@link android.view.Menu}, {@link android.app.Dialog}, etc. 218 */ 219 public static final int TYPE_WINDOW_STATE_CHANGED = 0x00000020; 220 221 /** 222 * Represents the event showing/hiding a {@link android.app.Notification}. 223 */ 224 public static final int TYPE_NOTIFICATION_STATE_CHANGED = 0x00000040; 225 226 /** 227 * Represents the event of a hover enter over a {@link android.view.View}. 228 */ 229 public static final int TYPE_VIEW_HOVER_ENTER = 0x00000080; 230 231 /** 232 * Represents the event of a hover exit over a {@link android.view.View}. 233 */ 234 public static final int TYPE_VIEW_HOVER_EXIT = 0x00000100; 235 236 /** 237 * Represents the event of starting a touch exploration gesture. 238 */ 239 public static final int TYPE_TOUCH_EXPLORATION_GESTURE_START = 0x00000200; 240 241 /** 242 * Represents the event of ending a touch exploration gesture. 243 */ 244 public static final int TYPE_TOUCH_EXPLORATION_GESTURE_END = 0x00000400; 245 246 /** 247 * Mask for {@link AccessibilityEvent} all types. 248 * 249 * @see #TYPE_VIEW_CLICKED 250 * @see #TYPE_VIEW_LONG_CLICKED 251 * @see #TYPE_VIEW_SELECTED 252 * @see #TYPE_VIEW_FOCUSED 253 * @see #TYPE_VIEW_TEXT_CHANGED 254 * @see #TYPE_WINDOW_STATE_CHANGED 255 * @see #TYPE_NOTIFICATION_STATE_CHANGED 256 */ 257 public static final int TYPES_ALL_MASK = 0xFFFFFFFF; 258 259 private static final int MAX_POOL_SIZE = 10; 260 private static final Object sPoolLock = new Object(); 261 private static AccessibilityEvent sPool; 262 private static int sPoolSize; 263 private AccessibilityEvent mNext; 264 private boolean mIsInPool; 265 266 private int mEventType; 267 private int mSourceAccessibilityViewId = View.NO_ID; 268 private int mSourceAccessibilityWindowId = View.NO_ID; 269 private CharSequence mPackageName; 270 private long mEventTime; 271 272 private final ArrayList<AccessibilityRecord> mRecords = new ArrayList<AccessibilityRecord>(); 273 274 private IAccessibilityServiceConnection mConnection; 275 276 /* 277 * Hide constructor from clients. 278 */ 279 private AccessibilityEvent() { 280 } 281 282 /** 283 * Initialize an event from another one. 284 * 285 * @param event The event to initialize from. 286 */ 287 void init(AccessibilityEvent event) { 288 super.init(event); 289 mEventType = event.mEventType; 290 mEventTime = event.mEventTime; 291 mSourceAccessibilityWindowId = event.mSourceAccessibilityWindowId; 292 mSourceAccessibilityViewId = event.mSourceAccessibilityViewId; 293 mPackageName = event.mPackageName; 294 mConnection = event.mConnection; 295 } 296 297 /** 298 * Gets the number of records contained in the event. 299 * 300 * @return The number of records. 301 */ 302 public int getRecordCount() { 303 return mRecords.size(); 304 } 305 306 /** 307 * Appends an {@link AccessibilityRecord} to the end of event records. 308 * 309 * @param record The record to append. 310 * 311 * @throws IllegalStateException If called from an AccessibilityService. 312 */ 313 public void appendRecord(AccessibilityRecord record) { 314 enforceNotSealed(); 315 mRecords.add(record); 316 } 317 318 /** 319 * Gets the records at a given index. 320 * 321 * @param index The index. 322 * @return The records at the specified index. 323 */ 324 public AccessibilityRecord getRecord(int index) { 325 return mRecords.get(index); 326 } 327 328 /** 329 * Gets the event type. 330 * 331 * @return The event type. 332 */ 333 public int getEventType() { 334 return mEventType; 335 } 336 337 /** 338 * Sets the event source. 339 * 340 * @param source The source. 341 * 342 * @throws IllegalStateException If called from an AccessibilityService. 343 */ 344 public void setSource(View source) { 345 enforceNotSealed(); 346 if (source != null) { 347 mSourceAccessibilityWindowId = source.getAccessibilityWindowId(); 348 mSourceAccessibilityViewId = source.getAccessibilityViewId(); 349 } else { 350 mSourceAccessibilityWindowId = View.NO_ID; 351 mSourceAccessibilityViewId = View.NO_ID; 352 } 353 } 354 355 /** 356 * Gets the {@link AccessibilityNodeInfo} of the event source. 357 * <p> 358 * <strong> 359 * It is a client responsibility to recycle the received info by 360 * calling {@link AccessibilityNodeInfo#recycle()} to avoid creating 361 * of multiple instances. 362 * </strong> 363 * </p> 364 * @return The info. 365 */ 366 public AccessibilityNodeInfo getSource() { 367 enforceSealed(); 368 if (mSourceAccessibilityWindowId == View.NO_ID 369 || mSourceAccessibilityViewId == View.NO_ID) { 370 return null; 371 } 372 try { 373 return mConnection.findAccessibilityNodeInfoByAccessibilityId( 374 mSourceAccessibilityWindowId, mSourceAccessibilityViewId); 375 } catch (RemoteException e) { 376 return null; 377 } 378 } 379 380 /** 381 * Gets the id of the window from which the event comes from. 382 * 383 * @return The window id. 384 */ 385 public int getAccessibilityWindowId() { 386 return mSourceAccessibilityWindowId; 387 } 388 389 /** 390 * Sets the client token for the accessibility service that 391 * provided this node info. 392 * 393 * @param connection The connection. 394 * 395 * @hide 396 */ 397 public final void setConnection(IAccessibilityServiceConnection connection) { 398 mConnection = connection; 399 } 400 401 /** 402 * Gets the accessibility window id of the source window. 403 * 404 * @return The id. 405 * 406 * @hide 407 */ 408 public int getSourceAccessibilityWindowId() { 409 return mSourceAccessibilityWindowId; 410 } 411 412 /** 413 * Sets the event type. 414 * 415 * @param eventType The event type. 416 * 417 * @throws IllegalStateException If called from an AccessibilityService. 418 */ 419 public void setEventType(int eventType) { 420 enforceNotSealed(); 421 mEventType = eventType; 422 } 423 424 /** 425 * Gets the time in which this event was sent. 426 * 427 * @return The event time. 428 */ 429 public long getEventTime() { 430 return mEventTime; 431 } 432 433 /** 434 * Sets the time in which this event was sent. 435 * 436 * @param eventTime The event time. 437 * 438 * @throws IllegalStateException If called from an AccessibilityService. 439 */ 440 public void setEventTime(long eventTime) { 441 enforceNotSealed(); 442 mEventTime = eventTime; 443 } 444 445 /** 446 * Gets the package name of the source. 447 * 448 * @return The package name. 449 */ 450 public CharSequence getPackageName() { 451 return mPackageName; 452 } 453 454 /** 455 * Sets the package name of the source. 456 * 457 * @param packageName The package name. 458 * 459 * @throws IllegalStateException If called from an AccessibilityService. 460 */ 461 public void setPackageName(CharSequence packageName) { 462 enforceNotSealed(); 463 mPackageName = packageName; 464 } 465 466 /** 467 * Returns a cached instance if such is available or a new one is 468 * instantiated with type property set. 469 * 470 * @param eventType The event type. 471 * @return An instance. 472 */ 473 public static AccessibilityEvent obtain(int eventType) { 474 AccessibilityEvent event = AccessibilityEvent.obtain(); 475 event.setEventType(eventType); 476 return event; 477 } 478 479 /** 480 * Returns a cached instance if such is available or a new one is 481 * instantiated with type property set. 482 * 483 * @param event The other event. 484 * @return An instance. 485 */ 486 public static AccessibilityEvent obtain(AccessibilityEvent event) { 487 AccessibilityEvent eventClone = AccessibilityEvent.obtain(); 488 eventClone.init(event); 489 490 final int recordCount = event.mRecords.size(); 491 for (int i = 0; i < recordCount; i++) { 492 AccessibilityRecord record = event.mRecords.get(i); 493 AccessibilityRecord recordClone = AccessibilityRecord.obtain(record); 494 eventClone.mRecords.add(recordClone); 495 } 496 497 return eventClone; 498 } 499 500 /** 501 * Returns a cached instance if such is available or a new one is 502 * instantiated. 503 * 504 * @return An instance. 505 */ 506 public static AccessibilityEvent obtain() { 507 synchronized (sPoolLock) { 508 if (sPool != null) { 509 AccessibilityEvent event = sPool; 510 sPool = sPool.mNext; 511 sPoolSize--; 512 event.mNext = null; 513 event.mIsInPool = false; 514 return event; 515 } 516 return new AccessibilityEvent(); 517 } 518 } 519 520 /** 521 * Return an instance back to be reused. 522 * <p> 523 * <b>Note: You must not touch the object after calling this function.</b> 524 * 525 * @throws IllegalStateException If the event is already recycled. 526 */ 527 @Override 528 public void recycle() { 529 if (mIsInPool) { 530 throw new IllegalStateException("Event already recycled!"); 531 } 532 clear(); 533 synchronized (sPoolLock) { 534 if (sPoolSize <= MAX_POOL_SIZE) { 535 mNext = sPool; 536 sPool = this; 537 mIsInPool = true; 538 sPoolSize++; 539 } 540 } 541 } 542 543 /** 544 * Clears the state of this instance. 545 * 546 * @hide 547 */ 548 @Override 549 protected void clear() { 550 super.clear(); 551 mConnection = null; 552 mEventType = 0; 553 mSourceAccessibilityViewId = View.NO_ID; 554 mSourceAccessibilityWindowId = View.NO_ID; 555 mPackageName = null; 556 mEventTime = 0; 557 while (!mRecords.isEmpty()) { 558 AccessibilityRecord record = mRecords.remove(0); 559 record.recycle(); 560 } 561 } 562 563 /** 564 * Creates a new instance from a {@link Parcel}. 565 * 566 * @param parcel A parcel containing the state of a {@link AccessibilityEvent}. 567 */ 568 public void initFromParcel(Parcel parcel) { 569 if (parcel.readInt() == 1) { 570 mConnection = IAccessibilityServiceConnection.Stub.asInterface( 571 parcel.readStrongBinder()); 572 } 573 setSealed(parcel.readInt() == 1); 574 mEventType = parcel.readInt(); 575 mSourceAccessibilityWindowId = parcel.readInt(); 576 mSourceAccessibilityViewId = parcel.readInt(); 577 mPackageName = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(parcel); 578 mEventTime = parcel.readLong(); 579 readAccessibilityRecordFromParcel(this, parcel); 580 581 // Read the records. 582 final int recordCount = parcel.readInt(); 583 for (int i = 0; i < recordCount; i++) { 584 AccessibilityRecord record = AccessibilityRecord.obtain(); 585 readAccessibilityRecordFromParcel(record, parcel); 586 mRecords.add(record); 587 } 588 } 589 590 /** 591 * Reads an {@link AccessibilityRecord} from a parcel. 592 * 593 * @param record The record to initialize. 594 * @param parcel The parcel to read from. 595 */ 596 private void readAccessibilityRecordFromParcel(AccessibilityRecord record, 597 Parcel parcel) { 598 record.mBooleanProperties = parcel.readInt(); 599 record.mCurrentItemIndex = parcel.readInt(); 600 record.mItemCount = parcel.readInt(); 601 record.mFromIndex = parcel.readInt(); 602 record.mAddedCount = parcel.readInt(); 603 record.mRemovedCount = parcel.readInt(); 604 record.mClassName = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(parcel); 605 record.mContentDescription = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(parcel); 606 record.mBeforeText = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(parcel); 607 record.mParcelableData = parcel.readParcelable(null); 608 parcel.readList(record.mText, null); 609 } 610 611 /** 612 * {@inheritDoc} 613 */ 614 public void writeToParcel(Parcel parcel, int flags) { 615 if (mConnection == null) { 616 parcel.writeInt(0); 617 } else { 618 parcel.writeInt(1); 619 parcel.writeStrongBinder(mConnection.asBinder()); 620 } 621 parcel.writeInt(isSealed() ? 1 : 0); 622 parcel.writeInt(mEventType); 623 parcel.writeInt(mSourceAccessibilityWindowId); 624 parcel.writeInt(mSourceAccessibilityViewId); 625 TextUtils.writeToParcel(mPackageName, parcel, 0); 626 parcel.writeLong(mEventTime); 627 writeAccessibilityRecordToParcel(this, parcel, flags); 628 629 // Write the records. 630 final int recordCount = getRecordCount(); 631 parcel.writeInt(recordCount); 632 for (int i = 0; i < recordCount; i++) { 633 AccessibilityRecord record = mRecords.get(i); 634 writeAccessibilityRecordToParcel(record, parcel, flags); 635 } 636 } 637 638 /** 639 * Writes an {@link AccessibilityRecord} to a parcel. 640 * 641 * @param record The record to write. 642 * @param parcel The parcel to which to write. 643 */ 644 private void writeAccessibilityRecordToParcel(AccessibilityRecord record, Parcel parcel, 645 int flags) { 646 parcel.writeInt(record.mBooleanProperties); 647 parcel.writeInt(record.mCurrentItemIndex); 648 parcel.writeInt(record.mItemCount); 649 parcel.writeInt(record.mFromIndex); 650 parcel.writeInt(record.mAddedCount); 651 parcel.writeInt(record.mRemovedCount); 652 TextUtils.writeToParcel(record.mClassName, parcel, flags); 653 TextUtils.writeToParcel(record.mContentDescription, parcel, flags); 654 TextUtils.writeToParcel(record.mBeforeText, parcel, flags); 655 parcel.writeParcelable(record.mParcelableData, flags); 656 parcel.writeList(record.mText); 657 } 658 659 /** 660 * {@inheritDoc} 661 */ 662 public int describeContents() { 663 return 0; 664 } 665 666 @Override 667 public String toString() { 668 StringBuilder builder = new StringBuilder(); 669 builder.append("; EventType: ").append(eventTypeToString(mEventType)); 670 builder.append("; EventTime: ").append(mEventTime); 671 builder.append("; PackageName: ").append(mPackageName); 672 builder.append(super.toString()); 673 if (DEBUG) { 674 builder.append("\n"); 675 builder.append("; sourceAccessibilityWindowId: ").append(mSourceAccessibilityWindowId); 676 builder.append("; sourceAccessibilityViewId: ").append(mSourceAccessibilityViewId); 677 for (int i = 0; i < mRecords.size(); i++) { 678 AccessibilityRecord record = mRecords.get(i); 679 builder.append(" Record "); 680 builder.append(i); 681 builder.append(":"); 682 builder.append(" [ ClassName: " + record.mClassName); 683 builder.append("; Text: " + record.mText); 684 builder.append("; ContentDescription: " + record.mContentDescription); 685 builder.append("; ItemCount: " + record.mItemCount); 686 builder.append("; CurrentItemIndex: " + record.mCurrentItemIndex); 687 builder.append("; IsEnabled: " + record.isEnabled()); 688 builder.append("; IsPassword: " + record.isPassword()); 689 builder.append("; IsChecked: " + record.isChecked()); 690 builder.append("; IsFullScreen: " + record.isFullScreen()); 691 builder.append("; BeforeText: " + record.mBeforeText); 692 builder.append("; FromIndex: " + record.mFromIndex); 693 builder.append("; AddedCount: " + record.mAddedCount); 694 builder.append("; RemovedCount: " + record.mRemovedCount); 695 builder.append("; ParcelableData: " + record.mParcelableData); 696 builder.append(" ]"); 697 builder.append("\n"); 698 } 699 } else { 700 builder.append("; recordCount: ").append(getAddedCount()); 701 } 702 return builder.toString(); 703 } 704 705 /** 706 * Returns the string representation of an event type. For example, 707 * {@link #TYPE_VIEW_CLICKED} is represented by the string TYPE_VIEW_CLICKED. 708 * 709 * @param feedbackType The event type 710 * @return The string representation. 711 */ 712 public static String eventTypeToString(int feedbackType) { 713 switch (feedbackType) { 714 case TYPE_VIEW_CLICKED: 715 return "TYPE_VIEW_CLICKED"; 716 case TYPE_VIEW_LONG_CLICKED: 717 return "TYPE_VIEW_LONG_CLICKED"; 718 case TYPE_VIEW_SELECTED: 719 return "TYPE_VIEW_SELECTED"; 720 case TYPE_VIEW_FOCUSED: 721 return "TYPE_VIEW_FOCUSED"; 722 case TYPE_VIEW_TEXT_CHANGED: 723 return "TYPE_VIEW_TEXT_CHANGED"; 724 case TYPE_WINDOW_STATE_CHANGED: 725 return "TYPE_WINDOW_STATE_CHANGED"; 726 case TYPE_VIEW_HOVER_ENTER: 727 return "TYPE_VIEW_HOVER_ENTER"; 728 case TYPE_VIEW_HOVER_EXIT: 729 return "TYPE_VIEW_HOVER_EXIT"; 730 case TYPE_NOTIFICATION_STATE_CHANGED: 731 return "TYPE_NOTIFICATION_STATE_CHANGED"; 732 case TYPE_TOUCH_EXPLORATION_GESTURE_START: 733 return "TYPE_TOUCH_EXPLORATION_GESTURE_START"; 734 case TYPE_TOUCH_EXPLORATION_GESTURE_END: 735 return "TYPE_TOUCH_EXPLORATION_GESTURE_END"; 736 default: 737 return null; 738 } 739 } 740 741 /** 742 * @see Parcelable.Creator 743 */ 744 public static final Parcelable.Creator<AccessibilityEvent> CREATOR = 745 new Parcelable.Creator<AccessibilityEvent>() { 746 public AccessibilityEvent createFromParcel(Parcel parcel) { 747 AccessibilityEvent event = AccessibilityEvent.obtain(); 748 event.initFromParcel(parcel); 749 return event; 750 } 751 752 public AccessibilityEvent[] newArray(int size) { 753 return new AccessibilityEvent[size]; 754 } 755 }; 756} 757