• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2011 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.support.v4.view.accessibility;
18 
19 import android.os.Build;
20 import android.view.accessibility.AccessibilityEvent;
21 
22 /**
23  * Helper for accessing features in {@link AccessibilityEvent}
24  * introduced after API level 4 in a backwards compatible fashion.
25  */
26 public final class AccessibilityEventCompat {
27 
28     static interface AccessibilityEventVersionImpl {
getRecordCount(AccessibilityEvent event)29         int getRecordCount(AccessibilityEvent event);
appendRecord(AccessibilityEvent event, Object record)30         void appendRecord(AccessibilityEvent event, Object record);
getRecord(AccessibilityEvent event, int index)31         Object getRecord(AccessibilityEvent event, int index);
setContentChangeTypes(AccessibilityEvent event, int types)32         void setContentChangeTypes(AccessibilityEvent event, int types);
getContentChangeTypes(AccessibilityEvent event)33         int getContentChangeTypes(AccessibilityEvent event);
setMovementGranularity(AccessibilityEvent event, int granularity)34         public void setMovementGranularity(AccessibilityEvent event, int granularity);
getMovementGranularity(AccessibilityEvent event)35         public int getMovementGranularity(AccessibilityEvent event);
setAction(AccessibilityEvent event, int action)36         public void setAction(AccessibilityEvent event, int action);
getAction(AccessibilityEvent event)37         public int getAction(AccessibilityEvent event);
38     }
39 
40     static class AccessibilityEventStubImpl implements AccessibilityEventVersionImpl {
41 
42         @Override
appendRecord(AccessibilityEvent event, Object record)43         public void appendRecord(AccessibilityEvent event, Object record) {
44 
45         }
46 
47         @Override
getRecord(AccessibilityEvent event, int index)48         public Object getRecord(AccessibilityEvent event, int index) {
49             return null;
50         }
51 
52         @Override
setContentChangeTypes(AccessibilityEvent event, int types)53         public void setContentChangeTypes(AccessibilityEvent event, int types) {
54 
55         }
56 
57         @Override
getRecordCount(AccessibilityEvent event)58         public int getRecordCount(AccessibilityEvent event) {
59             return 0;
60         }
61 
62         @Override
getContentChangeTypes(AccessibilityEvent event)63         public int getContentChangeTypes(AccessibilityEvent event) {
64             return 0;
65         }
66 
67         @Override
setMovementGranularity(AccessibilityEvent event, int granularity)68         public void setMovementGranularity(AccessibilityEvent event, int granularity) {
69         }
70 
71         @Override
getMovementGranularity(AccessibilityEvent event)72         public int getMovementGranularity(AccessibilityEvent event) {
73             return 0;
74         }
75 
76         @Override
setAction(AccessibilityEvent event, int action)77         public void setAction(AccessibilityEvent event, int action) {
78         }
79 
80         @Override
getAction(AccessibilityEvent event)81         public int getAction(AccessibilityEvent event) {
82             return 0;
83         }
84     }
85 
86     static class AccessibilityEventIcsImpl extends AccessibilityEventStubImpl {
87 
88         @Override
appendRecord(AccessibilityEvent event, Object record)89         public void appendRecord(AccessibilityEvent event, Object record) {
90             AccessibilityEventCompatIcs.appendRecord(event, record);
91         }
92 
93         @Override
getRecord(AccessibilityEvent event, int index)94         public Object getRecord(AccessibilityEvent event, int index) {
95             return AccessibilityEventCompatIcs.getRecord(event, index);
96         }
97 
98         @Override
getRecordCount(AccessibilityEvent event)99         public int getRecordCount(AccessibilityEvent event) {
100             return AccessibilityEventCompatIcs.getRecordCount(event);
101         }
102     }
103 
104     static class AccessibilityEventJellyBeanImpl extends AccessibilityEventIcsImpl {
105         @Override
setMovementGranularity(AccessibilityEvent event, int granularity)106         public void setMovementGranularity(AccessibilityEvent event, int granularity) {
107             AccessibilityEventCompatJellyBean.setMovementGranularity(event, granularity);
108         }
109 
110         @Override
getMovementGranularity(AccessibilityEvent event)111         public int getMovementGranularity(AccessibilityEvent event) {
112             return AccessibilityEventCompatJellyBean.getMovementGranularity(event);
113         }
114 
115         @Override
setAction(AccessibilityEvent event, int action)116         public void setAction(AccessibilityEvent event, int action) {
117             AccessibilityEventCompatJellyBean.setAction(event, action);
118         }
119 
120         @Override
getAction(AccessibilityEvent event)121         public int getAction(AccessibilityEvent event) {
122             return AccessibilityEventCompatJellyBean.getAction(event);
123         }
124     }
125 
126     static class AccessibilityEventKitKatImpl extends AccessibilityEventJellyBeanImpl {
127 
128         @Override
setContentChangeTypes(AccessibilityEvent event, int types)129         public void setContentChangeTypes(AccessibilityEvent event, int types) {
130             AccessibilityEventCompatKitKat.setContentChangeTypes(event, types);
131         }
132 
133         @Override
getContentChangeTypes(AccessibilityEvent event)134         public int getContentChangeTypes(AccessibilityEvent event) {
135             return AccessibilityEventCompatKitKat.getContentChangeTypes(event);
136         }
137     }
138 
139     private final static AccessibilityEventVersionImpl IMPL;
140 
141     static {
142         if (Build.VERSION.SDK_INT >= 19) { // KitKat
143             IMPL = new AccessibilityEventKitKatImpl();
144         } else if (Build.VERSION.SDK_INT >= 16) { // Jellybean
145             IMPL = new AccessibilityEventJellyBeanImpl();
146         } else if (Build.VERSION.SDK_INT >= 14) { // ICS
147             IMPL = new AccessibilityEventIcsImpl();
148         } else {
149             IMPL = new AccessibilityEventStubImpl();
150         }
151     }
152 
153     /**
154      * Represents the event of a hover enter over a {@link android.view.View}.
155      */
156     public static final int TYPE_VIEW_HOVER_ENTER = 0x00000080;
157 
158     /**
159      * Represents the event of a hover exit over a {@link android.view.View}.
160      */
161     public static final int TYPE_VIEW_HOVER_EXIT = 0x00000100;
162 
163     /**
164      * Represents the event of starting a touch exploration gesture.
165      */
166     public static final int TYPE_TOUCH_EXPLORATION_GESTURE_START = 0x00000200;
167 
168     /**
169      * Represents the event of ending a touch exploration gesture.
170      */
171     public static final int TYPE_TOUCH_EXPLORATION_GESTURE_END = 0x00000400;
172 
173     /**
174      * Represents the event of changing the content of a window.
175      */
176     public static final int TYPE_WINDOW_CONTENT_CHANGED = 0x00000800;
177 
178     /**
179      * Represents the event of scrolling a view.
180      */
181     public static final int TYPE_VIEW_SCROLLED = 0x00001000;
182 
183     /**
184      * Represents the event of changing the selection in an {@link android.widget.EditText}.
185      */
186     public static final int TYPE_VIEW_TEXT_SELECTION_CHANGED = 0x00002000;
187 
188     /**
189      * Represents the event of an application making an announcement.
190      */
191     public static final int TYPE_ANNOUNCEMENT = 0x00004000;
192 
193     /**
194      * Represents the event of gaining accessibility focus.
195      */
196     public static final int TYPE_VIEW_ACCESSIBILITY_FOCUSED = 0x00008000;
197 
198     /**
199      * Represents the event of clearing accessibility focus.
200      */
201     public static final int TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED = 0x00010000;
202 
203     /**
204      * Represents the event of traversing the text of a view at a given movement granularity.
205      */
206     public static final int TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY = 0x00020000;
207 
208     /**
209      * Represents the event of beginning gesture detection.
210      */
211     public static final int TYPE_GESTURE_DETECTION_START = 0x00040000;
212 
213     /**
214      * Represents the event of ending gesture detection.
215      */
216     public static final int TYPE_GESTURE_DETECTION_END = 0x00080000;
217 
218     /**
219      * Represents the event of the user starting to touch the screen.
220      */
221     public static final int TYPE_TOUCH_INTERACTION_START = 0x00100000;
222 
223     /**
224      * Represents the event of the user ending to touch the screen.
225      */
226     public static final int TYPE_TOUCH_INTERACTION_END = 0x00200000;
227 
228     /**
229      * Represents the event change in the windows shown on the screen.
230      */
231     public static final int TYPE_WINDOWS_CHANGED = 0x00400000;
232 
233     /**
234      * Represents the event of a context click on a {@link android.view.View}.
235      */
236     public static final int TYPE_VIEW_CONTEXT_CLICKED = 0x00800000;
237 
238     /**
239      * Represents the event of the assistant currently reading the users screen context.
240      */
241     public static final int TYPE_ASSIST_READING_CONTEXT = 0x01000000;
242 
243     /**
244      * Change type for {@link #TYPE_WINDOW_CONTENT_CHANGED} event:
245      * The type of change is not defined.
246      */
247     public static final int CONTENT_CHANGE_TYPE_UNDEFINED = 0x00000000;
248 
249     /**
250      * Change type for {@link #TYPE_WINDOW_CONTENT_CHANGED} event:
251      * A node in the subtree rooted at the source node was added or removed.
252      */
253     public static final int CONTENT_CHANGE_TYPE_SUBTREE = 0x00000001;
254 
255     /**
256      * Change type for {@link #TYPE_WINDOW_CONTENT_CHANGED} event:
257      * The node's text changed.
258      */
259     public static final int CONTENT_CHANGE_TYPE_TEXT = 0x00000002;
260 
261     /**
262      * Change type for {@link #TYPE_WINDOW_CONTENT_CHANGED} event:
263      * The node's content description changed.
264      */
265     public static final int CONTENT_CHANGE_TYPE_CONTENT_DESCRIPTION = 0x00000004;
266 
267     /**
268      * Mask for {@link AccessibilityEvent} all types.
269      *
270      * @see AccessibilityEvent#TYPE_VIEW_CLICKED
271      * @see AccessibilityEvent#TYPE_VIEW_LONG_CLICKED
272      * @see AccessibilityEvent#TYPE_VIEW_SELECTED
273      * @see AccessibilityEvent#TYPE_VIEW_FOCUSED
274      * @see AccessibilityEvent#TYPE_VIEW_TEXT_CHANGED
275      * @see AccessibilityEvent#TYPE_WINDOW_STATE_CHANGED
276      * @see AccessibilityEvent#TYPE_NOTIFICATION_STATE_CHANGED
277      * @see #TYPE_VIEW_HOVER_ENTER
278      * @see #TYPE_VIEW_HOVER_EXIT
279      * @see #TYPE_TOUCH_EXPLORATION_GESTURE_START
280      * @see #TYPE_TOUCH_EXPLORATION_GESTURE_END
281      * @see #TYPE_WINDOW_CONTENT_CHANGED
282      * @see #TYPE_VIEW_SCROLLED
283      * @see #TYPE_VIEW_TEXT_SELECTION_CHANGED
284      * @see #TYPE_ANNOUNCEMENT
285      * @see #TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
286      * @see #TYPE_GESTURE_DETECTION_START
287      * @see #TYPE_GESTURE_DETECTION_END
288      * @see #TYPE_TOUCH_INTERACTION_START
289      * @see #TYPE_TOUCH_INTERACTION_END
290      */
291     public static final int TYPES_ALL_MASK = 0xFFFFFFFF;
292 
293     /*
294      * Hide constructor from clients.
295      */
AccessibilityEventCompat()296     private AccessibilityEventCompat() {
297 
298     }
299 
300     /**
301      * Gets the number of records contained in the event.
302      *
303      * @return The number of records.
304      */
getRecordCount(AccessibilityEvent event)305     public static int getRecordCount(AccessibilityEvent event) {
306         return IMPL.getRecordCount(event);
307     }
308 
309     /**
310      * Appends an {@link android.view.accessibility.AccessibilityRecord} to the end of
311      * event records.
312      *
313      * @param record The record to append.
314      *
315      * @throws IllegalStateException If called from an AccessibilityService.
316      */
appendRecord(AccessibilityEvent event, AccessibilityRecordCompat record)317     public static void appendRecord(AccessibilityEvent event, AccessibilityRecordCompat record) {
318         IMPL.appendRecord(event, record.getImpl());
319     }
320 
321     /**
322      * Gets the record at a given index.
323      *
324      * @param index The index.
325      * @return The record at the specified index.
326      */
getRecord(AccessibilityEvent event, int index)327     public static AccessibilityRecordCompat getRecord(AccessibilityEvent event, int index) {
328         return new AccessibilityRecordCompat(IMPL.getRecord(event, index));
329     }
330 
331     /**
332      * Creates an {@link AccessibilityRecordCompat} from an {@link AccessibilityEvent}
333      * that can be used to manipulate the event properties defined in
334      * {@link android.view.accessibility.AccessibilityRecord}.
335      * <p>
336      * <strong>Note:</strong> Do not call {@link AccessibilityRecordCompat#recycle()} on the
337      * returned {@link AccessibilityRecordCompat}. Call {@link AccessibilityEvent#recycle()}
338      * in case you want to recycle the event.
339      * </p>
340      *
341      * @param event The from which to create a record.
342      * @return An {@link AccessibilityRecordCompat}.
343      */
asRecord(AccessibilityEvent event)344     public static AccessibilityRecordCompat asRecord(AccessibilityEvent event) {
345         return new AccessibilityRecordCompat(event);
346     }
347 
348     /**
349      * Sets the bit mask of node tree changes signaled by an
350      * {@link #TYPE_WINDOW_CONTENT_CHANGED} event.
351      *
352      * @param changeTypes The bit mask of change types.
353      * @throws IllegalStateException If called from an AccessibilityService.
354      * @see #getContentChangeTypes(AccessibilityEvent)
355      */
setContentChangeTypes(AccessibilityEvent event, int changeTypes)356     public static void setContentChangeTypes(AccessibilityEvent event, int changeTypes) {
357         IMPL.setContentChangeTypes(event, changeTypes);
358     }
359 
360     /**
361      * Gets the bit mask of change types signaled by an
362      * {@link #TYPE_WINDOW_CONTENT_CHANGED} event. A single event may represent
363      * multiple change types.
364      *
365      * @return The bit mask of change types. One or more of:
366      *         <ul>
367      *         <li>{@link AccessibilityEvent#CONTENT_CHANGE_TYPE_CONTENT_DESCRIPTION}
368      *         <li>{@link AccessibilityEvent#CONTENT_CHANGE_TYPE_SUBTREE}
369      *         <li>{@link AccessibilityEvent#CONTENT_CHANGE_TYPE_TEXT}
370      *         <li>{@link AccessibilityEvent#CONTENT_CHANGE_TYPE_UNDEFINED}
371      *         </ul>
372      */
getContentChangeTypes(AccessibilityEvent event)373     public static int getContentChangeTypes(AccessibilityEvent event) {
374         return IMPL.getContentChangeTypes(event);
375     }
376 
377     /**
378      * Sets the movement granularity that was traversed.
379      *
380      * @param granularity The granularity.
381      *
382      * @throws IllegalStateException If called from an AccessibilityService.
383      */
setMovementGranularity(AccessibilityEvent event, int granularity)384     public void setMovementGranularity(AccessibilityEvent event, int granularity) {
385         IMPL.setMovementGranularity(event, granularity);
386     }
387 
388     /**
389      * Gets the movement granularity that was traversed.
390      *
391      * @return The granularity.
392      */
getMovementGranularity(AccessibilityEvent event)393     public int getMovementGranularity(AccessibilityEvent event) {
394         return IMPL.getMovementGranularity(event);
395     }
396 
397     /**
398      * Sets the performed action that triggered this event.
399      * <p>
400      * Valid actions are defined in {@link AccessibilityNodeInfoCompat}:
401      * <ul>
402      * <li>{@link AccessibilityNodeInfoCompat#ACTION_ACCESSIBILITY_FOCUS}
403      * <li>{@link AccessibilityNodeInfoCompat#ACTION_CLEAR_ACCESSIBILITY_FOCUS}
404      * <li>{@link AccessibilityNodeInfoCompat#ACTION_CLEAR_FOCUS}
405      * <li>{@link AccessibilityNodeInfoCompat#ACTION_CLEAR_SELECTION}
406      * <li>{@link AccessibilityNodeInfoCompat#ACTION_CLICK}
407      * <li>etc.
408      * </ul>
409      *
410      * @param action The action.
411      * @throws IllegalStateException If called from an AccessibilityService.
412      * @see AccessibilityNodeInfoCompat#performAction(int)
413      */
setAction(AccessibilityEvent event, int action)414     public void setAction(AccessibilityEvent event, int action) {
415         IMPL.setAction(event, action);
416     }
417 
418     /**
419      * Gets the performed action that triggered this event.
420      *
421      * @return The action.
422      */
getAction(AccessibilityEvent event)423     public int getAction(AccessibilityEvent event) {
424         return IMPL.getAction(event);
425     }
426 }
427