AccessibilityServiceInfoCompat.java revision 1ef22af9051a858183b028cc4f7c02c973653be4
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 17package android.support.v4.accessibilityservice; 18 19import android.accessibilityservice.AccessibilityService; 20import android.accessibilityservice.AccessibilityServiceInfo; 21import android.content.pm.PackageManager; 22import android.content.pm.ResolveInfo; 23import android.os.Build; 24import android.view.View; 25 26/** 27 * Helper for accessing features in {@link android.accessibilityservice.AccessibilityService} 28 * introduced after API level 4 in a backwards compatible fashion. 29 */ 30public final class AccessibilityServiceInfoCompat { 31 32 static interface AccessibilityServiceInfoVersionImpl { 33 public String getId(AccessibilityServiceInfo info); 34 public ResolveInfo getResolveInfo(AccessibilityServiceInfo info); 35 public boolean getCanRetrieveWindowContent(AccessibilityServiceInfo info); 36 public String getDescription(AccessibilityServiceInfo info); 37 public String getSettingsActivityName(AccessibilityServiceInfo info); 38 public int getCapabilities(AccessibilityServiceInfo info); 39 public String loadDescription(AccessibilityServiceInfo info, PackageManager pm); 40 } 41 42 static class AccessibilityServiceInfoStubImpl implements AccessibilityServiceInfoVersionImpl { 43 44 @Override 45 public boolean getCanRetrieveWindowContent(AccessibilityServiceInfo info) { 46 return false; 47 } 48 49 @Override 50 public String getDescription(AccessibilityServiceInfo info) { 51 return null; 52 } 53 54 @Override 55 public String getId(AccessibilityServiceInfo info) { 56 return null; 57 } 58 59 @Override 60 public ResolveInfo getResolveInfo(AccessibilityServiceInfo info) { 61 return null; 62 } 63 64 @Override 65 public String getSettingsActivityName(AccessibilityServiceInfo info) { 66 return null; 67 } 68 69 @Override 70 public int getCapabilities(AccessibilityServiceInfo info) { 71 return 0; 72 } 73 74 @Override 75 public String loadDescription(AccessibilityServiceInfo info, PackageManager pm) { 76 return null; 77 } 78 } 79 80 static class AccessibilityServiceInfoIcsImpl extends AccessibilityServiceInfoStubImpl { 81 82 @Override 83 public boolean getCanRetrieveWindowContent(AccessibilityServiceInfo info) { 84 return AccessibilityServiceInfoCompatIcs.getCanRetrieveWindowContent(info); 85 } 86 87 @Override 88 public String getDescription(AccessibilityServiceInfo info) { 89 return AccessibilityServiceInfoCompatIcs.getDescription(info); 90 } 91 92 @Override 93 public String getId(AccessibilityServiceInfo info) { 94 return AccessibilityServiceInfoCompatIcs.getId(info); 95 } 96 97 @Override 98 public ResolveInfo getResolveInfo(AccessibilityServiceInfo info) { 99 return AccessibilityServiceInfoCompatIcs.getResolveInfo(info); 100 } 101 102 @Override 103 public String getSettingsActivityName(AccessibilityServiceInfo info) { 104 return AccessibilityServiceInfoCompatIcs.getSettingsActivityName(info); 105 } 106 107 @Override 108 public int getCapabilities(AccessibilityServiceInfo info) { 109 if (getCanRetrieveWindowContent(info)) { 110 return CAPABILITY_CAN_RETRIEVE_WINDOW_CONTENT; 111 } 112 return 0; 113 } 114 } 115 116 static class AccessibilityServiceInfoJellyBeanImpl extends AccessibilityServiceInfoIcsImpl { 117 @Override 118 public String loadDescription(AccessibilityServiceInfo info, PackageManager pm) { 119 return AccessibilityServiceInfoCompatJellyBean.loadDescription(info, pm); 120 } 121 } 122 123 static class AccessibilityServiceInfoJellyBeanMr2Impl 124 extends AccessibilityServiceInfoJellyBeanImpl { 125 @Override 126 public int getCapabilities(AccessibilityServiceInfo info) { 127 return AccessibilityServiceInfoCompatJellyBeanMr2.getCapabilities(info); 128 } 129 } 130 131 static { 132 if (Build.VERSION.SDK_INT >= 18) { // JellyBean MR2 133 IMPL = new AccessibilityServiceInfoJellyBeanMr2Impl(); 134 } else if (Build.VERSION.SDK_INT >= 16) { // JB 135 IMPL = new AccessibilityServiceInfoJellyBeanImpl(); 136 } else if (Build.VERSION.SDK_INT >= 14) { // ICS 137 IMPL = new AccessibilityServiceInfoIcsImpl(); 138 } else { 139 IMPL = new AccessibilityServiceInfoStubImpl(); 140 } 141 } 142 143 // Capabilities 144 145 private static final AccessibilityServiceInfoVersionImpl IMPL; 146 147 /** 148 * Capability: This accessibility service can retrieve the active window content. 149 */ 150 public static final int CAPABILITY_CAN_RETRIEVE_WINDOW_CONTENT = 0x00000001; 151 152 /** 153 * Capability: This accessibility service can request touch exploration mode in which 154 * touched items are spoken aloud and the UI can be explored via gestures. 155 */ 156 public static final int CAPABILITY_CAN_REQUEST_TOUCH_EXPLORATION = 0x00000002; 157 158 /** 159 * Capability: This accessibility service can request enhanced web accessibility 160 * enhancements. For example, installing scripts to make app content more accessible. 161 */ 162 public static final int CAPABILITY_CAN_REQUEST_ENHANCED_WEB_ACCESSIBILITY = 0x00000004; 163 164 /** 165 * Capability: This accessibility service can filter the key event stream. 166 */ 167 public static final int CAPABILITY_CAN_FILTER_KEY_EVENTS = 0x00000008; 168 169 // Feedback types 170 171 /** 172 * Denotes braille feedback. 173 */ 174 public static final int FEEDBACK_BRAILLE = 0x0000020; 175 176 /** 177 * Mask for all feedback types. 178 * 179 * @see AccessibilityServiceInfo#FEEDBACK_SPOKEN 180 * @see AccessibilityServiceInfo#FEEDBACK_HAPTIC 181 * @see AccessibilityServiceInfo#FEEDBACK_AUDIBLE 182 * @see AccessibilityServiceInfo#FEEDBACK_VISUAL 183 * @see AccessibilityServiceInfo#FEEDBACK_GENERIC 184 * @see FEEDBACK_BRAILLE 185 */ 186 public static final int FEEDBACK_ALL_MASK = 0xFFFFFFFF; 187 188 // Flags 189 190 /** 191 * If an {@link AccessibilityService} is the default for a given type. 192 * Default service is invoked only if no package specific one exists. In case of 193 * more than one package specific service only the earlier registered is notified. 194 */ 195 public static final int DEFAULT = 0x0000001; 196 197 /** 198 * If this flag is set the system will regard views that are not important 199 * for accessibility in addition to the ones that are important for accessibility. 200 * That is, views that are marked as not important for accessibility via 201 * {@link View#IMPORTANT_FOR_ACCESSIBILITY_NO} or 202 * {@link View#IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS} and views that are 203 * marked as potentially important for accessibility via 204 * {@link View#IMPORTANT_FOR_ACCESSIBILITY_AUTO} for which the system has determined 205 * that are not important for accessibility, are both reported while querying the 206 * window content and also the accessibility service will receive accessibility events 207 * from them. 208 * <p> 209 * <strong>Note:</strong> For accessibility services targeting API version 210 * {@link Build.VERSION_CODES#JELLY_BEAN} or higher this flag has to be explicitly 211 * set for the system to regard views that are not important for accessibility. For 212 * accessibility services targeting API version lower than 213 * {@link Build.VERSION_CODES#JELLY_BEAN} this flag is ignored and all views are 214 * regarded for accessibility purposes. 215 * </p> 216 * <p> 217 * Usually views not important for accessibility are layout managers that do not 218 * react to user actions, do not draw any content, and do not have any special 219 * semantics in the context of the screen content. For example, a three by three 220 * grid can be implemented as three horizontal linear layouts and one vertical, 221 * or three vertical linear layouts and one horizontal, or one grid layout, etc. 222 * In this context the actual layout mangers used to achieve the grid configuration 223 * are not important, rather it is important that there are nine evenly distributed 224 * elements. 225 * </p> 226 */ 227 public static final int FLAG_INCLUDE_NOT_IMPORTANT_VIEWS = 0x0000002; 228 229 /** 230 * This flag requests that the system gets into touch exploration mode. 231 * In this mode a single finger moving on the screen behaves as a mouse 232 * pointer hovering over the user interface. The system will also detect 233 * certain gestures performed on the touch screen and notify this service. 234 * The system will enable touch exploration mode if there is at least one 235 * accessibility service that has this flag set. Hence, clearing this 236 * flag does not guarantee that the device will not be in touch exploration 237 * mode since there may be another enabled service that requested it. 238 * <p> 239 * For accessibility services targeting API version higher than 240 * {@link Build.VERSION_CODES#JELLY_BEAN_MR1} that want to set 241 * this flag have to declare this capability in their meta-data by setting 242 * the attribute canRequestTouchExplorationMode to true, otherwise this flag 243 * will be ignored. For how to declare the meta-data of a service refer to 244 * {@value AccessibilityService#SERVICE_META_DATA}. 245 * </p> 246 * <p> 247 * Services targeting API version equal to or lower than 248 * {@link Build.VERSION_CODES#JELLY_BEAN_MR1} will work normally, i.e. 249 * the first time they are run, if this flag is specified, a dialog is 250 * shown to the user to confirm enabling explore by touch. 251 * </p> 252 */ 253 public static final int FLAG_REQUEST_TOUCH_EXPLORATION_MODE = 0x0000004; 254 255 /** 256 * This flag requests from the system to enable web accessibility enhancing 257 * extensions. Such extensions aim to provide improved accessibility support 258 * for content presented in a {@link android.webkit.WebView}. An example of such 259 * an extension is injecting JavaScript from a secure source. The system will enable 260 * enhanced web accessibility if there is at least one accessibility service 261 * that has this flag set. Hence, clearing this flag does not guarantee that the 262 * device will not have enhanced web accessibility enabled since there may be 263 * another enabled service that requested it. 264 * <p> 265 * Services that want to set this flag have to declare this capability 266 * in their meta-data by setting the attribute canRequestEnhancedWebAccessibility 267 * to true, otherwise this flag will be ignored. For how to declare the meta-data 268 * of a service refer to {@value AccessibilityService#SERVICE_META_DATA}. 269 * </p> 270 */ 271 public static final int FLAG_REQUEST_ENHANCED_WEB_ACCESSIBILITY = 0x00000008; 272 273 /** 274 * This flag requests that the AccessibilityNodeInfos obtained 275 * by an {@link AccessibilityService} contain the id of the source view. 276 * The source view id will be a fully qualified resource name of the 277 * form "package:id/name", for example "foo.bar:id/my_list", and it is 278 * useful for UI test automation. This flag is not set by default. 279 */ 280 public static final int FLAG_REPORT_VIEW_IDS = 0x00000010; 281 282 /** 283 * This flag requests from the system to filter key events. If this flag 284 * is set the accessibility service will receive the key events before 285 * applications allowing it implement global shortcuts. Setting this flag 286 * does not guarantee that this service will filter key events since only 287 * one service can do so at any given time. This avoids user confusion due 288 * to behavior change in case different key filtering services are enabled. 289 * If there is already another key filtering service enabled, this one will 290 * not receive key events. 291 * <p> 292 * Services that want to set this flag have to declare this capability 293 * in their meta-data by setting the attribute canRequestFilterKeyEvents 294 * to true, otherwise this flag will be ignored. For how to declare the meta 295 * -data of a service refer to {@value AccessibilityService#SERVICE_META_DATA}. 296 * </p> 297 */ 298 public static final int FLAG_REQUEST_FILTER_KEY_EVENTS = 0x00000020; 299 300 /* 301 * Hide constructor 302 */ 303 private AccessibilityServiceInfoCompat() {} 304 305 /** 306 * The accessibility service id. 307 * <p> 308 * <strong>Generated by the system.</strong> 309 * </p> 310 * 311 * @param info The service info of interest 312 * @return The id. 313 */ 314 public static String getId(AccessibilityServiceInfo info) { 315 return IMPL.getId(info); 316 } 317 318 /** 319 * The service {@link ResolveInfo}. 320 * <p> 321 * <strong>Generated by the system.</strong> 322 * </p> 323 * 324 * @param info The service info of interest 325 * @return The info. 326 */ 327 public static ResolveInfo getResolveInfo(AccessibilityServiceInfo info) { 328 return IMPL.getResolveInfo(info); 329 } 330 331 /** 332 * The settings activity name. 333 * <p> 334 * <strong>Statically set from {@link AccessibilityService#SERVICE_META_DATA 335 * meta-data}.</strong> 336 * </p> 337 * 338 * @param info The service info of interest 339 * @return The settings activity name. 340 */ 341 public static String getSettingsActivityName(AccessibilityServiceInfo info) { 342 return IMPL.getSettingsActivityName(info); 343 } 344 345 /** 346 * Whether this service can retrieve the current window's content. 347 * <p> 348 * <strong>Statically set from {@link AccessibilityService#SERVICE_META_DATA 349 * meta-data}.</strong> 350 * </p> 351 * 352 * @param info The service info of interest 353 * @return True window content can be retrieved. 354 */ 355 public static boolean getCanRetrieveWindowContent(AccessibilityServiceInfo info) { 356 return IMPL.getCanRetrieveWindowContent(info); 357 } 358 359 /** 360 * Non-localized description of the accessibility service. 361 * <p> 362 * <strong>Statically set from {@link AccessibilityService#SERVICE_META_DATA 363 * meta-data}.</strong> 364 * </p> 365 * 366 * @param info The service info of interest 367 * @return The description. 368 * 369 * @deprecated Use {@link #loadDescription(AccessibilityServiceInfo, PackageManager)}. 370 */ 371 public static String getDescription(AccessibilityServiceInfo info) { 372 return IMPL.getDescription(info); 373 } 374 375 /** 376 * The localized description of the accessibility service. 377 * <p> 378 * <strong>Statically set from 379 * {@link AccessibilityService#SERVICE_META_DATA meta-data}.</strong> 380 * </p> 381 * 382 * @param info The service info of interest 383 * @param packageManager The current package manager 384 * @return The localized description. 385 */ 386 public static String loadDescription( 387 AccessibilityServiceInfo info, PackageManager packageManager) { 388 return IMPL.loadDescription(info, packageManager); 389 } 390 391 /** 392 * Returns the string representation of a feedback type. For example, 393 * {@link AccessibilityServiceInfo#FEEDBACK_SPOKEN} is represented by the 394 * string FEEDBACK_SPOKEN. 395 * 396 * @param feedbackType The feedback type. 397 * @return The string representation. 398 */ 399 public static String feedbackTypeToString(int feedbackType) { 400 StringBuilder builder = new StringBuilder(); 401 builder.append("["); 402 while (feedbackType > 0) { 403 final int feedbackTypeFlag = 1 << Integer.numberOfTrailingZeros(feedbackType); 404 feedbackType &= ~feedbackTypeFlag; 405 if (builder.length() > 1) { 406 builder.append(", "); 407 } 408 switch (feedbackTypeFlag) { 409 case AccessibilityServiceInfo.FEEDBACK_AUDIBLE: 410 builder.append("FEEDBACK_AUDIBLE"); 411 break; 412 case AccessibilityServiceInfo.FEEDBACK_HAPTIC: 413 builder.append("FEEDBACK_HAPTIC"); 414 break; 415 case AccessibilityServiceInfo.FEEDBACK_GENERIC: 416 builder.append("FEEDBACK_GENERIC"); 417 break; 418 case AccessibilityServiceInfo.FEEDBACK_SPOKEN: 419 builder.append("FEEDBACK_SPOKEN"); 420 break; 421 case AccessibilityServiceInfo.FEEDBACK_VISUAL: 422 builder.append("FEEDBACK_VISUAL"); 423 break; 424 } 425 } 426 builder.append("]"); 427 return builder.toString(); 428 } 429 430 /** 431 * Returns the string representation of a flag. For example, 432 * {@link AccessibilityServiceInfo#DEFAULT} is represented by the 433 * string DEFAULT. 434 * 435 * @param flag The flag. 436 * @return The string representation. 437 */ 438 public static String flagToString(int flag) { 439 switch (flag) { 440 case DEFAULT: 441 return "DEFAULT"; 442 case FLAG_INCLUDE_NOT_IMPORTANT_VIEWS: 443 return "FLAG_INCLUDE_NOT_IMPORTANT_VIEWS"; 444 case FLAG_REQUEST_TOUCH_EXPLORATION_MODE: 445 return "FLAG_REQUEST_TOUCH_EXPLORATION_MODE"; 446 case FLAG_REQUEST_ENHANCED_WEB_ACCESSIBILITY: 447 return "FLAG_REQUEST_ENHANCED_WEB_ACCESSIBILITY"; 448 case FLAG_REPORT_VIEW_IDS: 449 return "FLAG_REPORT_VIEW_IDS"; 450 case FLAG_REQUEST_FILTER_KEY_EVENTS: 451 return "FLAG_REQUEST_FILTER_KEY_EVENTS"; 452 default: 453 return null; 454 } 455 } 456 457 /** 458 * Returns the bit mask of capabilities this accessibility service has such as 459 * being able to retrieve the active window content, etc. 460 * 461 * @param info The service info whose capabilities to get. 462 * @return The capability bit mask. 463 * 464 * @see #CAPABILITY_CAN_RETRIEVE_WINDOW_CONTENT 465 * @see #CAPABILITY_CAN_REQUEST_TOUCH_EXPLORATION 466 * @see #CAPABILITY_CAN_REQUEST_ENHANCED_WEB_ACCESSIBILITY 467 * @see #CAPABILITY_CAN_FILTER_KEY_EVENTS 468 */ 469 public static int getCapabilities(AccessibilityServiceInfo info) { 470 return IMPL.getCapabilities(info); 471 } 472 473 /** 474 * Returns the string representation of a capability. For example, 475 * {@link #CAPABILITY_CAN_RETRIEVE_WINDOW_CONTENT} is represented 476 * by the string CAPABILITY_CAN_RETRIEVE_WINDOW_CONTENT. 477 * 478 * @param capability The capability. 479 * @return The string representation. 480 */ 481 public static String capabilityToString(int capability) { 482 switch (capability) { 483 case CAPABILITY_CAN_RETRIEVE_WINDOW_CONTENT: 484 return "CAPABILITY_CAN_RETRIEVE_WINDOW_CONTENT"; 485 case CAPABILITY_CAN_REQUEST_TOUCH_EXPLORATION: 486 return "CAPABILITY_CAN_REQUEST_TOUCH_EXPLORATION"; 487 case CAPABILITY_CAN_REQUEST_ENHANCED_WEB_ACCESSIBILITY: 488 return "CAPABILITY_CAN_REQUEST_ENHANCED_WEB_ACCESSIBILITY"; 489 case CAPABILITY_CAN_FILTER_KEY_EVENTS: 490 return "CAPABILITY_CAN_FILTER_KEY_EVENTS"; 491 default: 492 return "UNKNOWN"; 493 } 494 } 495} 496