| /* |
| * Copyright (C) 2011 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package android.support.v4.accessibilityservice; |
| |
| import android.accessibilityservice.AccessibilityService; |
| import android.accessibilityservice.AccessibilityServiceInfo; |
| import android.content.pm.ResolveInfo; |
| import android.os.Build; |
| import android.view.View; |
| |
| /** |
| * Helper for accessing features in {@link android.accessibilityservice.AccessibilityService} |
| * introduced after API level 4 in a backwards compatible fashion. |
| */ |
| public class AccessibilityServiceInfoCompat { |
| |
| static interface AccessibilityServiceInfoVersionImpl { |
| public String getId(AccessibilityServiceInfo info); |
| public ResolveInfo getResolveInfo(AccessibilityServiceInfo info); |
| public boolean getCanRetrieveWindowContent(AccessibilityServiceInfo info); |
| public String getDescription(AccessibilityServiceInfo info); |
| public String getSettingsActivityName(AccessibilityServiceInfo info); |
| public int getCapabilities(AccessibilityServiceInfo info); |
| } |
| |
| static class AccessibilityServiceInfoStubImpl implements AccessibilityServiceInfoVersionImpl { |
| |
| public boolean getCanRetrieveWindowContent(AccessibilityServiceInfo info) { |
| return false; |
| } |
| |
| public String getDescription(AccessibilityServiceInfo info) { |
| return null; |
| } |
| |
| public String getId(AccessibilityServiceInfo info) { |
| return null; |
| } |
| |
| public ResolveInfo getResolveInfo(AccessibilityServiceInfo info) { |
| return null; |
| } |
| |
| public String getSettingsActivityName(AccessibilityServiceInfo info) { |
| return null; |
| } |
| |
| public int getCapabilities(AccessibilityServiceInfo info) { |
| return 0; |
| } |
| } |
| |
| static class AccessibilityServiceInfoIcsImpl extends AccessibilityServiceInfoStubImpl { |
| |
| @Override |
| public boolean getCanRetrieveWindowContent(AccessibilityServiceInfo info) { |
| return AccessibilityServiceInfoCompatIcs.getCanRetrieveWindowContent(info); |
| } |
| |
| @Override |
| public String getDescription(AccessibilityServiceInfo info) { |
| return AccessibilityServiceInfoCompatIcs.getDescription(info); |
| } |
| |
| @Override |
| public String getId(AccessibilityServiceInfo info) { |
| return AccessibilityServiceInfoCompatIcs.getId(info); |
| } |
| |
| @Override |
| public ResolveInfo getResolveInfo(AccessibilityServiceInfo info) { |
| return AccessibilityServiceInfoCompatIcs.getResolveInfo(info); |
| } |
| |
| @Override |
| public String getSettingsActivityName(AccessibilityServiceInfo info) { |
| return AccessibilityServiceInfoCompatIcs.getSettingsActivityName(info); |
| } |
| |
| @Override |
| public int getCapabilities(AccessibilityServiceInfo info) { |
| if (getCanRetrieveWindowContent(info)) { |
| return CAPABILITY_CAN_RETRIEVE_WINDOW_CONTENT; |
| } |
| return 0; |
| } |
| } |
| |
| static class AccessibilityServiceInfoJellyBeanMr2 extends AccessibilityServiceInfoIcsImpl { |
| @Override |
| public int getCapabilities(AccessibilityServiceInfo info) { |
| return AccessibilityServiceInfoCompatJellyBeanMr2.getCapabilities(info); |
| } |
| } |
| |
| static { |
| if (Build.VERSION.SDK_INT >= 18) { // JellyBean MR2 |
| IMPL = new AccessibilityServiceInfoJellyBeanMr2(); |
| } else if (Build.VERSION.SDK_INT >= 14) { // ICS |
| IMPL = new AccessibilityServiceInfoIcsImpl(); |
| } else { |
| IMPL = new AccessibilityServiceInfoStubImpl(); |
| } |
| } |
| |
| // Capabilities |
| |
| private static final AccessibilityServiceInfoVersionImpl IMPL; |
| |
| /** |
| * Capability: This accessibility service can retrieve the active window content. |
| */ |
| public static final int CAPABILITY_CAN_RETRIEVE_WINDOW_CONTENT = 0x00000001; |
| |
| /** |
| * Capability: This accessibility service can request touch exploration mode in which |
| * touched items are spoken aloud and the UI can be explored via gestures. |
| */ |
| public static final int CAPABILITY_CAN_REQUEST_TOUCH_EXPLORATION = 0x00000002; |
| |
| /** |
| * Capability: This accessibility service can request enhanced web accessibility |
| * enhancements. For example, installing scripts to make app content more accessible. |
| */ |
| public static final int CAPABILITY_CAN_REQUEST_ENHANCED_WEB_ACCESSIBILITY = 0x00000004; |
| |
| /** |
| * Capability: This accessibility service can filter the key event stream. |
| */ |
| public static final int CAPABILITY_CAN_FILTER_KEY_EVENTS = 0x00000008; |
| |
| // Feedback types |
| |
| /** |
| * Denotes braille feedback. |
| */ |
| public static final int FEEDBACK_BRAILLE = 0x0000020; |
| |
| /** |
| * Mask for all feedback types. |
| * |
| * @see AccessibilityServiceInfo#FEEDBACK_SPOKEN |
| * @see AccessibilityServiceInfo#FEEDBACK_HAPTIC |
| * @see AccessibilityServiceInfo#FEEDBACK_AUDIBLE |
| * @see AccessibilityServiceInfo#FEEDBACK_VISUAL |
| * @see AccessibilityServiceInfo#FEEDBACK_GENERIC |
| * @see FEEDBACK_BRAILLE |
| */ |
| public static final int FEEDBACK_ALL_MASK = 0xFFFFFFFF; |
| |
| // Flags |
| |
| /** |
| * If an {@link AccessibilityService} is the default for a given type. |
| * Default service is invoked only if no package specific one exists. In case of |
| * more than one package specific service only the earlier registered is notified. |
| */ |
| public static final int DEFAULT = 0x0000001; |
| |
| /** |
| * If this flag is set the system will regard views that are not important |
| * for accessibility in addition to the ones that are important for accessibility. |
| * That is, views that are marked as not important for accessibility via |
| * {@link View#IMPORTANT_FOR_ACCESSIBILITY_NO} or |
| * {@link View#IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS} and views that are |
| * marked as potentially important for accessibility via |
| * {@link View#IMPORTANT_FOR_ACCESSIBILITY_AUTO} for which the system has determined |
| * that are not important for accessibility, are both reported while querying the |
| * window content and also the accessibility service will receive accessibility events |
| * from them. |
| * <p> |
| * <strong>Note:</strong> For accessibility services targeting API version |
| * {@link Build.VERSION_CODES#JELLY_BEAN} or higher this flag has to be explicitly |
| * set for the system to regard views that are not important for accessibility. For |
| * accessibility services targeting API version lower than |
| * {@link Build.VERSION_CODES#JELLY_BEAN} this flag is ignored and all views are |
| * regarded for accessibility purposes. |
| * </p> |
| * <p> |
| * Usually views not important for accessibility are layout managers that do not |
| * react to user actions, do not draw any content, and do not have any special |
| * semantics in the context of the screen content. For example, a three by three |
| * grid can be implemented as three horizontal linear layouts and one vertical, |
| * or three vertical linear layouts and one horizontal, or one grid layout, etc. |
| * In this context the actual layout mangers used to achieve the grid configuration |
| * are not important, rather it is important that there are nine evenly distributed |
| * elements. |
| * </p> |
| */ |
| public static final int FLAG_INCLUDE_NOT_IMPORTANT_VIEWS = 0x0000002; |
| |
| /** |
| * This flag requests that the system gets into touch exploration mode. |
| * In this mode a single finger moving on the screen behaves as a mouse |
| * pointer hovering over the user interface. The system will also detect |
| * certain gestures performed on the touch screen and notify this service. |
| * The system will enable touch exploration mode if there is at least one |
| * accessibility service that has this flag set. Hence, clearing this |
| * flag does not guarantee that the device will not be in touch exploration |
| * mode since there may be another enabled service that requested it. |
| * <p> |
| * For accessibility services targeting API version higher than |
| * {@link Build.VERSION_CODES#JELLY_BEAN_MR1} that want to set |
| * this flag have to declare this capability in their meta-data by setting |
| * the attribute canRequestTouchExplorationMode to true, otherwise this flag |
| * will be ignored. For how to declare the meta-data of a service refer to |
| * {@value AccessibilityService#SERVICE_META_DATA}. |
| * </p> |
| * <p> |
| * Services targeting API version equal to or lower than |
| * {@link Build.VERSION_CODES#JELLY_BEAN_MR1} will work normally, i.e. |
| * the first time they are run, if this flag is specified, a dialog is |
| * shown to the user to confirm enabling explore by touch. |
| * </p> |
| */ |
| public static final int FLAG_REQUEST_TOUCH_EXPLORATION_MODE = 0x0000004; |
| |
| /** |
| * This flag requests from the system to enable web accessibility enhancing |
| * extensions. Such extensions aim to provide improved accessibility support |
| * for content presented in a {@link android.webkit.WebView}. An example of such |
| * an extension is injecting JavaScript from a secure source. The system will enable |
| * enhanced web accessibility if there is at least one accessibility service |
| * that has this flag set. Hence, clearing this flag does not guarantee that the |
| * device will not have enhanced web accessibility enabled since there may be |
| * another enabled service that requested it. |
| * <p> |
| * Services that want to set this flag have to declare this capability |
| * in their meta-data by setting the attribute canRequestEnhancedWebAccessibility |
| * to true, otherwise this flag will be ignored. For how to declare the meta-data |
| * of a service refer to {@value AccessibilityService#SERVICE_META_DATA}. |
| * </p> |
| */ |
| public static final int FLAG_REQUEST_ENHANCED_WEB_ACCESSIBILITY = 0x00000008; |
| |
| /** |
| * This flag requests that the AccessibilityNodeInfos obtained |
| * by an {@link AccessibilityService} contain the id of the source view. |
| * The source view id will be a fully qualified resource name of the |
| * form "package:id/name", for example "foo.bar:id/my_list", and it is |
| * useful for UI test automation. This flag is not set by default. |
| */ |
| public static final int FLAG_REPORT_VIEW_IDS = 0x00000010; |
| |
| /** |
| * This flag requests from the system to filter key events. If this flag |
| * is set the accessibility service will receive the key events before |
| * applications allowing it implement global shortcuts. Setting this flag |
| * does not guarantee that this service will filter key events since only |
| * one service can do so at any given time. This avoids user confusion due |
| * to behavior change in case different key filtering services are enabled. |
| * If there is already another key filtering service enabled, this one will |
| * not receive key events. |
| * <p> |
| * Services that want to set this flag have to declare this capability |
| * in their meta-data by setting the attribute canRequestFilterKeyEvents |
| * to true, otherwise this flag will be ignored. For how to declare the meta |
| * -data of a service refer to {@value AccessibilityService#SERVICE_META_DATA}. |
| * </p> |
| */ |
| public static final int FLAG_REQUEST_FILTER_KEY_EVENTS = 0x00000020; |
| |
| /* |
| * Hide constructor |
| */ |
| private AccessibilityServiceInfoCompat() { |
| |
| } |
| |
| /** |
| * The accessibility service id. |
| * <p> |
| * <strong>Generated by the system.</strong> |
| * </p> |
| * |
| * @return The id. |
| */ |
| public static String getId(AccessibilityServiceInfo info) { |
| return IMPL.getId(info); |
| } |
| |
| /** |
| * The service {@link ResolveInfo}. |
| * <p> |
| * <strong>Generated by the system.</strong> |
| * </p> |
| * |
| * @return The info. |
| */ |
| public static ResolveInfo getResolveInfo(AccessibilityServiceInfo info) { |
| return IMPL.getResolveInfo(info); |
| } |
| |
| /** |
| * The settings activity name. |
| * <p> |
| * <strong>Statically set from {@link AccessibilityService#SERVICE_META_DATA |
| * meta-data}.</strong> |
| * </p> |
| * |
| * @return The settings activity name. |
| */ |
| public static String getSettingsActivityName(AccessibilityServiceInfo info) { |
| return IMPL.getSettingsActivityName(info); |
| } |
| |
| /** |
| * Whether this service can retrieve the current window's content. |
| * <p> |
| * <strong>Statically set from {@link AccessibilityService#SERVICE_META_DATA |
| * meta-data}.</strong> |
| * </p> |
| * |
| * @return True window content can be retrieved. |
| */ |
| public static boolean getCanRetrieveWindowContent(AccessibilityServiceInfo info) { |
| return IMPL.getCanRetrieveWindowContent(info); |
| } |
| |
| /** |
| * Description of the accessibility service. |
| * <p> |
| * <strong>Statically set from {@link AccessibilityService#SERVICE_META_DATA |
| * meta-data}.</strong> |
| * </p> |
| * |
| * @return The description. |
| */ |
| public static String getDescription(AccessibilityServiceInfo info) { |
| return IMPL.getDescription(info); |
| } |
| |
| /** |
| * Returns the string representation of a feedback type. For example, |
| * {@link AccessibilityServiceInfo#FEEDBACK_SPOKEN} is represented by the |
| * string FEEDBACK_SPOKEN. |
| * |
| * @param feedbackType The feedback type. |
| * @return The string representation. |
| */ |
| public static String feedbackTypeToString(int feedbackType) { |
| StringBuilder builder = new StringBuilder(); |
| builder.append("["); |
| while (feedbackType > 0) { |
| final int feedbackTypeFlag = 1 << Integer.numberOfTrailingZeros(feedbackType); |
| feedbackType &= ~feedbackTypeFlag; |
| if (builder.length() > 1) { |
| builder.append(", "); |
| } |
| switch (feedbackTypeFlag) { |
| case AccessibilityServiceInfo.FEEDBACK_AUDIBLE: |
| builder.append("FEEDBACK_AUDIBLE"); |
| break; |
| case AccessibilityServiceInfo.FEEDBACK_HAPTIC: |
| builder.append("FEEDBACK_HAPTIC"); |
| break; |
| case AccessibilityServiceInfo.FEEDBACK_GENERIC: |
| builder.append("FEEDBACK_GENERIC"); |
| break; |
| case AccessibilityServiceInfo.FEEDBACK_SPOKEN: |
| builder.append("FEEDBACK_SPOKEN"); |
| break; |
| case AccessibilityServiceInfo.FEEDBACK_VISUAL: |
| builder.append("FEEDBACK_VISUAL"); |
| break; |
| } |
| } |
| builder.append("]"); |
| return builder.toString(); |
| } |
| |
| /** |
| * Returns the string representation of a flag. For example, |
| * {@link AccessibilityServiceInfo#DEFAULT} is represented by the |
| * string DEFAULT. |
| * |
| * @param flag The flag. |
| * @return The string representation. |
| */ |
| public static String flagToString(int flag) { |
| switch (flag) { |
| case DEFAULT: |
| return "DEFAULT"; |
| case FLAG_INCLUDE_NOT_IMPORTANT_VIEWS: |
| return "FLAG_INCLUDE_NOT_IMPORTANT_VIEWS"; |
| case FLAG_REQUEST_TOUCH_EXPLORATION_MODE: |
| return "FLAG_REQUEST_TOUCH_EXPLORATION_MODE"; |
| case FLAG_REQUEST_ENHANCED_WEB_ACCESSIBILITY: |
| return "FLAG_REQUEST_ENHANCED_WEB_ACCESSIBILITY"; |
| case FLAG_REPORT_VIEW_IDS: |
| return "FLAG_REPORT_VIEW_IDS"; |
| case FLAG_REQUEST_FILTER_KEY_EVENTS: |
| return "FLAG_REQUEST_FILTER_KEY_EVENTS"; |
| default: |
| return null; |
| } |
| } |
| |
| /** |
| * Returns the bit mask of capabilities this accessibility service has such as |
| * being able to retrieve the active window content, etc. |
| * |
| * @param info The service info whose capabilities to get. |
| * @return The capability bit mask. |
| * |
| * @see #CAPABILITY_CAN_RETRIEVE_WINDOW_CONTENT |
| * @see #CAPABILITY_CAN_REQUEST_TOUCH_EXPLORATION |
| * @see #CAPABILITY_CAN_REQUEST_ENHANCED_WEB_ACCESSIBILITY |
| * @see #CAPABILITY_CAN_FILTER_KEY_EVENTS |
| */ |
| public static int getCapabilities(AccessibilityServiceInfo info) { |
| return IMPL.getCapabilities(info); |
| } |
| |
| /** |
| * Returns the string representation of a capability. For example, |
| * {@link #CAPABILITY_CAN_RETRIEVE_WINDOW_CONTENT} is represented |
| * by the string CAPABILITY_CAN_RETRIEVE_WINDOW_CONTENT. |
| * |
| * @param capability The capability. |
| * @return The string representation. |
| */ |
| public static String capabilityToString(int capability) { |
| switch (capability) { |
| case CAPABILITY_CAN_RETRIEVE_WINDOW_CONTENT: |
| return "CAPABILITY_CAN_RETRIEVE_WINDOW_CONTENT"; |
| case CAPABILITY_CAN_REQUEST_TOUCH_EXPLORATION: |
| return "CAPABILITY_CAN_REQUEST_TOUCH_EXPLORATION"; |
| case CAPABILITY_CAN_REQUEST_ENHANCED_WEB_ACCESSIBILITY: |
| return "CAPABILITY_CAN_REQUEST_ENHANCED_WEB_ACCESSIBILITY"; |
| case CAPABILITY_CAN_FILTER_KEY_EVENTS: |
| return "CAPABILITY_CAN_FILTER_KEY_EVENTS"; |
| default: |
| return "UNKNOWN"; |
| } |
| } |
| } |