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