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 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); 34 } 35 36 static class AccessibilityEventStubImpl implements AccessibilityEventVersionImpl { 37 38 @Override appendRecord(AccessibilityEvent event, Object record)39 public void appendRecord(AccessibilityEvent event, Object record) { 40 41 } 42 43 @Override getRecord(AccessibilityEvent event, int index)44 public Object getRecord(AccessibilityEvent event, int index) { 45 return null; 46 } 47 48 @Override setContentChangeTypes(AccessibilityEvent event, int types)49 public void setContentChangeTypes(AccessibilityEvent event, int types) { 50 51 } 52 53 @Override getRecordCount(AccessibilityEvent event)54 public int getRecordCount(AccessibilityEvent event) { 55 return 0; 56 } 57 58 @Override getContentChangeTypes(AccessibilityEvent event)59 public int getContentChangeTypes(AccessibilityEvent event) { 60 return 0; 61 } 62 } 63 64 static class AccessibilityEventIcsImpl extends AccessibilityEventStubImpl { 65 66 @Override appendRecord(AccessibilityEvent event, Object record)67 public void appendRecord(AccessibilityEvent event, Object record) { 68 AccessibilityEventCompatIcs.appendRecord(event, record); 69 } 70 71 @Override getRecord(AccessibilityEvent event, int index)72 public Object getRecord(AccessibilityEvent event, int index) { 73 return AccessibilityEventCompatIcs.getRecord(event, index); 74 } 75 76 @Override getRecordCount(AccessibilityEvent event)77 public int getRecordCount(AccessibilityEvent event) { 78 return AccessibilityEventCompatIcs.getRecordCount(event); 79 } 80 } 81 82 static class AccessibilityEventKitKatImpl extends AccessibilityEventIcsImpl { 83 84 @Override setContentChangeTypes(AccessibilityEvent event, int types)85 public void setContentChangeTypes(AccessibilityEvent event, int types) { 86 AccessibilityEventCompatKitKat.setContentChangeTypes(event, types); 87 } 88 89 @Override getContentChangeTypes(AccessibilityEvent event)90 public int getContentChangeTypes(AccessibilityEvent event) { 91 return AccessibilityEventCompatKitKat.getContentChangeTypes(event); 92 } 93 } 94 95 private final static AccessibilityEventVersionImpl IMPL; 96 97 static { 98 if (Build.VERSION.SDK_INT >= 19) { // KitKat 99 IMPL = new AccessibilityEventKitKatImpl(); 100 } else if (Build.VERSION.SDK_INT >= 14) { // ICS 101 IMPL = new AccessibilityEventIcsImpl(); 102 } else { 103 IMPL = new AccessibilityEventStubImpl(); 104 } 105 } 106 107 /** 108 * Represents the event of a hover enter over a {@link android.view.View}. 109 */ 110 public static final int TYPE_VIEW_HOVER_ENTER = 0x00000080; 111 112 /** 113 * Represents the event of a hover exit over a {@link android.view.View}. 114 */ 115 public static final int TYPE_VIEW_HOVER_EXIT = 0x00000100; 116 117 /** 118 * Represents the event of starting a touch exploration gesture. 119 */ 120 public static final int TYPE_TOUCH_EXPLORATION_GESTURE_START = 0x00000200; 121 122 /** 123 * Represents the event of ending a touch exploration gesture. 124 */ 125 public static final int TYPE_TOUCH_EXPLORATION_GESTURE_END = 0x00000400; 126 127 /** 128 * Represents the event of changing the content of a window. 129 */ 130 public static final int TYPE_WINDOW_CONTENT_CHANGED = 0x00000800; 131 132 /** 133 * Represents the event of scrolling a view. 134 */ 135 public static final int TYPE_VIEW_SCROLLED = 0x00001000; 136 137 /** 138 * Represents the event of changing the selection in an {@link android.widget.EditText}. 139 */ 140 public static final int TYPE_VIEW_TEXT_SELECTION_CHANGED = 0x00002000; 141 142 /** 143 * Represents the event of an application making an announcement. 144 */ 145 public static final int TYPE_ANNOUNCEMENT = 0x00004000; 146 147 /** 148 * Represents the event of gaining accessibility focus. 149 */ 150 public static final int TYPE_VIEW_ACCESSIBILITY_FOCUSED = 0x00008000; 151 152 /** 153 * Represents the event of clearing accessibility focus. 154 */ 155 public static final int TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED = 0x00010000; 156 157 /** 158 * Represents the event of traversing the text of a view at a given movement granularity. 159 */ 160 public static final int TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY = 0x00020000; 161 162 /** 163 * Represents the event of beginning gesture detection. 164 */ 165 public static final int TYPE_GESTURE_DETECTION_START = 0x00040000; 166 167 /** 168 * Represents the event of ending gesture detection. 169 */ 170 public static final int TYPE_GESTURE_DETECTION_END = 0x00080000; 171 172 /** 173 * Represents the event of the user starting to touch the screen. 174 */ 175 public static final int TYPE_TOUCH_INTERACTION_START = 0x00100000; 176 177 /** 178 * Represents the event of the user ending to touch the screen. 179 */ 180 public static final int TYPE_TOUCH_INTERACTION_END = 0x00200000; 181 182 /** 183 * Change type for {@link #TYPE_WINDOW_CONTENT_CHANGED} event: 184 * The type of change is not defined. 185 */ 186 public static final int CONTENT_CHANGE_TYPE_UNDEFINED = 0x00000000; 187 188 /** 189 * Change type for {@link #TYPE_WINDOW_CONTENT_CHANGED} event: 190 * A node in the subtree rooted at the source node was added or removed. 191 */ 192 public static final int CONTENT_CHANGE_TYPE_SUBTREE = 0x00000001; 193 194 /** 195 * Change type for {@link #TYPE_WINDOW_CONTENT_CHANGED} event: 196 * The node's text changed. 197 */ 198 public static final int CONTENT_CHANGE_TYPE_TEXT = 0x00000002; 199 200 /** 201 * Change type for {@link #TYPE_WINDOW_CONTENT_CHANGED} event: 202 * The node's content description changed. 203 */ 204 public static final int CONTENT_CHANGE_TYPE_CONTENT_DESCRIPTION = 0x00000004; 205 206 /** 207 * Mask for {@link AccessibilityEvent} all types. 208 * 209 * @see AccessibilityEvent#TYPE_VIEW_CLICKED 210 * @see AccessibilityEvent#TYPE_VIEW_LONG_CLICKED 211 * @see AccessibilityEvent#TYPE_VIEW_SELECTED 212 * @see AccessibilityEvent#TYPE_VIEW_FOCUSED 213 * @see AccessibilityEvent#TYPE_VIEW_TEXT_CHANGED 214 * @see AccessibilityEvent#TYPE_WINDOW_STATE_CHANGED 215 * @see AccessibilityEvent#TYPE_NOTIFICATION_STATE_CHANGED 216 * @see #TYPE_VIEW_HOVER_ENTER 217 * @see #TYPE_VIEW_HOVER_EXIT 218 * @see #TYPE_TOUCH_EXPLORATION_GESTURE_START 219 * @see #TYPE_TOUCH_EXPLORATION_GESTURE_END 220 * @see #TYPE_WINDOW_CONTENT_CHANGED 221 * @see #TYPE_VIEW_SCROLLED 222 * @see #TYPE_VIEW_TEXT_SELECTION_CHANGED 223 * @see #TYPE_ANNOUNCEMENT 224 * @see #TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY 225 * @see #TYPE_GESTURE_DETECTION_START 226 * @see #TYPE_GESTURE_DETECTION_END 227 * @see #TYPE_TOUCH_INTERACTION_START 228 * @see #TYPE_TOUCH_INTERACTION_END 229 */ 230 public static final int TYPES_ALL_MASK = 0xFFFFFFFF; 231 232 /* 233 * Hide constructor from clients. 234 */ AccessibilityEventCompat()235 private AccessibilityEventCompat() { 236 237 } 238 239 /** 240 * Gets the number of records contained in the event. 241 * 242 * @return The number of records. 243 */ getRecordCount(AccessibilityEvent event)244 public static int getRecordCount(AccessibilityEvent event) { 245 return IMPL.getRecordCount(event); 246 } 247 248 /** 249 * Appends an {@link android.view.accessibility.AccessibilityRecord} to the end of 250 * event records. 251 * 252 * @param record The record to append. 253 * 254 * @throws IllegalStateException If called from an AccessibilityService. 255 */ appendRecord(AccessibilityEvent event, AccessibilityRecordCompat record)256 public static void appendRecord(AccessibilityEvent event, AccessibilityRecordCompat record) { 257 IMPL.appendRecord(event, record.getImpl()); 258 } 259 260 /** 261 * Gets the record at a given index. 262 * 263 * @param index The index. 264 * @return The record at the specified index. 265 */ getRecord(AccessibilityEvent event, int index)266 public static AccessibilityRecordCompat getRecord(AccessibilityEvent event, int index) { 267 return new AccessibilityRecordCompat(IMPL.getRecord(event, index)); 268 } 269 270 /** 271 * Creates an {@link AccessibilityRecordCompat} from an {@link AccessibilityEvent} 272 * that can be used to manipulate the event properties defined in 273 * {@link android.view.accessibility.AccessibilityRecord}. 274 * <p> 275 * <strong>Note:</strong> Do not call {@link AccessibilityRecordCompat#recycle()} on the 276 * returned {@link AccessibilityRecordCompat}. Call {@link AccessibilityEvent#recycle()} 277 * in case you want to recycle the event. 278 * </p> 279 * 280 * @param event The from which to create a record. 281 * @return An {@link AccessibilityRecordCompat}. 282 */ asRecord(AccessibilityEvent event)283 public static AccessibilityRecordCompat asRecord(AccessibilityEvent event) { 284 return new AccessibilityRecordCompat(event); 285 } 286 287 /** 288 * Sets the bit mask of node tree changes signaled by an 289 * {@link #TYPE_WINDOW_CONTENT_CHANGED} event. 290 * 291 * @param changeTypes The bit mask of change types. 292 * @throws IllegalStateException If called from an AccessibilityService. 293 * @see #getContentChangeTypes(AccessibilityEvent) 294 */ setContentChangeTypes(AccessibilityEvent event, int changeTypes)295 public static void setContentChangeTypes(AccessibilityEvent event, int changeTypes) { 296 IMPL.setContentChangeTypes(event, changeTypes); 297 } 298 299 /** 300 * Gets the bit mask of change types signaled by an 301 * {@link #TYPE_WINDOW_CONTENT_CHANGED} event. A single event may represent 302 * multiple change types. 303 * 304 * @return The bit mask of change types. One or more of: 305 * <ul> 306 * <li>{@link AccessibilityEvent#CONTENT_CHANGE_TYPE_CONTENT_DESCRIPTION} 307 * <li>{@link AccessibilityEvent#CONTENT_CHANGE_TYPE_SUBTREE} 308 * <li>{@link AccessibilityEvent#CONTENT_CHANGE_TYPE_TEXT} 309 * <li>{@link AccessibilityEvent#CONTENT_CHANGE_TYPE_UNDEFINED} 310 * </ul> 311 */ getContentChangeTypes(AccessibilityEvent event)312 public static int getContentChangeTypes(AccessibilityEvent event) { 313 return IMPL.getContentChangeTypes(event); 314 } 315 316 } 317