svetoslavganov | 75986cf | 2009-05-14 22:28:01 -0700 | [diff] [blame] | 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.accessibilityservice; |
| 18 | |
Phil Weaver | c09a021 | 2018-03-13 09:50:43 -0700 | [diff] [blame] | 19 | import static android.content.pm.PackageManager.FEATURE_FINGERPRINT; |
| 20 | |
Svetoslav Ganov | 24c9045 | 2017-12-27 15:17:14 -0800 | [diff] [blame] | 21 | import android.annotation.IntDef; |
Mathew Inwood | 62992f1 | 2018-08-01 14:28:00 +0100 | [diff] [blame] | 22 | import android.annotation.UnsupportedAppUsage; |
Svetoslav Ganov | cc4053e | 2011-05-23 13:37:44 -0700 | [diff] [blame] | 23 | import android.content.ComponentName; |
| 24 | import android.content.Context; |
| 25 | import android.content.pm.PackageManager; |
| 26 | import android.content.pm.PackageManager.NameNotFoundException; |
| 27 | import android.content.pm.ResolveInfo; |
| 28 | import android.content.pm.ServiceInfo; |
| 29 | import android.content.res.Resources; |
| 30 | import android.content.res.TypedArray; |
| 31 | import android.content.res.XmlResourceParser; |
Phil Weaver | 27fcd9c | 2017-01-20 15:57:24 -0800 | [diff] [blame] | 32 | import android.hardware.fingerprint.FingerprintManager; |
svetoslavganov | 75986cf | 2009-05-14 22:28:01 -0700 | [diff] [blame] | 33 | import android.os.Parcel; |
| 34 | import android.os.Parcelable; |
Svetoslav Ganov | cc4053e | 2011-05-23 13:37:44 -0700 | [diff] [blame] | 35 | import android.util.AttributeSet; |
Svetoslav | 688a697 | 2013-04-16 18:55:38 -0700 | [diff] [blame] | 36 | import android.util.SparseArray; |
Svetoslav Ganov | 3d0edd3 | 2012-01-03 16:38:46 -0800 | [diff] [blame] | 37 | import android.util.TypedValue; |
Svetoslav Ganov | cc4053e | 2011-05-23 13:37:44 -0700 | [diff] [blame] | 38 | import android.util.Xml; |
Svetoslav Ganov | 4213804 | 2012-03-20 11:51:39 -0700 | [diff] [blame] | 39 | import android.view.View; |
Svetoslav Ganov | cc4053e | 2011-05-23 13:37:44 -0700 | [diff] [blame] | 40 | import android.view.accessibility.AccessibilityEvent; |
Svetoslav Ganov | 80943d8 | 2013-01-02 10:25:37 -0800 | [diff] [blame] | 41 | import android.view.accessibility.AccessibilityNodeInfo; |
Svetoslav Ganov | cc4053e | 2011-05-23 13:37:44 -0700 | [diff] [blame] | 42 | |
Jeff Sharkey | b5e89c6 | 2016-04-01 23:20:31 -0600 | [diff] [blame] | 43 | import com.android.internal.R; |
| 44 | |
Svetoslav Ganov | cc4053e | 2011-05-23 13:37:44 -0700 | [diff] [blame] | 45 | import org.xmlpull.v1.XmlPullParser; |
| 46 | import org.xmlpull.v1.XmlPullParserException; |
| 47 | |
| 48 | import java.io.IOException; |
Svetoslav Ganov | 24c9045 | 2017-12-27 15:17:14 -0800 | [diff] [blame] | 49 | import java.lang.annotation.Retention; |
| 50 | import java.lang.annotation.RetentionPolicy; |
Svetoslav | 688a697 | 2013-04-16 18:55:38 -0700 | [diff] [blame] | 51 | import java.util.ArrayList; |
| 52 | import java.util.Collections; |
| 53 | import java.util.List; |
svetoslavganov | 75986cf | 2009-05-14 22:28:01 -0700 | [diff] [blame] | 54 | |
| 55 | /** |
Svetoslav Ganov | 38e8b4e | 2011-06-29 20:00:53 -0700 | [diff] [blame] | 56 | * This class describes an {@link AccessibilityService}. The system notifies an |
| 57 | * {@link AccessibilityService} for {@link android.view.accessibility.AccessibilityEvent}s |
svetoslavganov | 75986cf | 2009-05-14 22:28:01 -0700 | [diff] [blame] | 58 | * according to the information encapsulated in this class. |
| 59 | * |
Joe Fernandez | e1302ed | 2012-02-06 14:30:15 -0800 | [diff] [blame] | 60 | * <div class="special reference"> |
| 61 | * <h3>Developer Guides</h3> |
| 62 | * <p>For more information about creating AccessibilityServices, read the |
| 63 | * <a href="{@docRoot}guide/topics/ui/accessibility/index.html">Accessibility</a> |
| 64 | * developer guide.</p> |
| 65 | * </div> |
| 66 | * |
Scott Main | 00d17f7 | 2013-06-06 18:37:59 -0700 | [diff] [blame] | 67 | * @attr ref android.R.styleable#AccessibilityService_accessibilityEventTypes |
| 68 | * @attr ref android.R.styleable#AccessibilityService_accessibilityFeedbackType |
| 69 | * @attr ref android.R.styleable#AccessibilityService_accessibilityFlags |
| 70 | * @attr ref android.R.styleable#AccessibilityService_canRequestEnhancedWebAccessibility |
| 71 | * @attr ref android.R.styleable#AccessibilityService_canRequestFilterKeyEvents |
| 72 | * @attr ref android.R.styleable#AccessibilityService_canRequestTouchExplorationMode |
| 73 | * @attr ref android.R.styleable#AccessibilityService_canRetrieveWindowContent |
| 74 | * @attr ref android.R.styleable#AccessibilityService_description |
Saige McVea | 08c41bc | 2017-01-20 20:22:35 -0800 | [diff] [blame] | 75 | * @attr ref android.R.styleable#AccessibilityService_summary |
Scott Main | 00d17f7 | 2013-06-06 18:37:59 -0700 | [diff] [blame] | 76 | * @attr ref android.R.styleable#AccessibilityService_notificationTimeout |
| 77 | * @attr ref android.R.styleable#AccessibilityService_packageNames |
| 78 | * @attr ref android.R.styleable#AccessibilityService_settingsActivity |
svetoslavganov | 75986cf | 2009-05-14 22:28:01 -0700 | [diff] [blame] | 79 | * @see AccessibilityService |
| 80 | * @see android.view.accessibility.AccessibilityEvent |
Svetoslav Ganov | 38e8b4e | 2011-06-29 20:00:53 -0700 | [diff] [blame] | 81 | * @see android.view.accessibility.AccessibilityManager |
svetoslavganov | 75986cf | 2009-05-14 22:28:01 -0700 | [diff] [blame] | 82 | */ |
| 83 | public class AccessibilityServiceInfo implements Parcelable { |
| 84 | |
Svetoslav Ganov | cc4053e | 2011-05-23 13:37:44 -0700 | [diff] [blame] | 85 | private static final String TAG_ACCESSIBILITY_SERVICE = "accessibility-service"; |
| 86 | |
svetoslavganov | 75986cf | 2009-05-14 22:28:01 -0700 | [diff] [blame] | 87 | /** |
Svetoslav | 688a697 | 2013-04-16 18:55:38 -0700 | [diff] [blame] | 88 | * Capability: This accessibility service can retrieve the active window content. |
Scott Main | 00d17f7 | 2013-06-06 18:37:59 -0700 | [diff] [blame] | 89 | * @see android.R.styleable#AccessibilityService_canRetrieveWindowContent |
Svetoslav | 688a697 | 2013-04-16 18:55:38 -0700 | [diff] [blame] | 90 | */ |
| 91 | public static final int CAPABILITY_CAN_RETRIEVE_WINDOW_CONTENT = 0x00000001; |
| 92 | |
| 93 | /** |
| 94 | * Capability: This accessibility service can request touch exploration mode in which |
| 95 | * touched items are spoken aloud and the UI can be explored via gestures. |
Scott Main | 00d17f7 | 2013-06-06 18:37:59 -0700 | [diff] [blame] | 96 | * @see android.R.styleable#AccessibilityService_canRequestTouchExplorationMode |
Svetoslav | 688a697 | 2013-04-16 18:55:38 -0700 | [diff] [blame] | 97 | */ |
| 98 | public static final int CAPABILITY_CAN_REQUEST_TOUCH_EXPLORATION = 0x00000002; |
| 99 | |
| 100 | /** |
Phil Weaver | 09d4ff8 | 2017-03-31 11:22:17 -0700 | [diff] [blame] | 101 | * @deprecated No longer used |
Svetoslav | 688a697 | 2013-04-16 18:55:38 -0700 | [diff] [blame] | 102 | */ |
| 103 | public static final int CAPABILITY_CAN_REQUEST_ENHANCED_WEB_ACCESSIBILITY = 0x00000004; |
| 104 | |
| 105 | /** |
Scott Main | 00d17f7 | 2013-06-06 18:37:59 -0700 | [diff] [blame] | 106 | * Capability: This accessibility service can request to filter the key event stream. |
| 107 | * @see android.R.styleable#AccessibilityService_canRequestFilterKeyEvents |
Svetoslav | 688a697 | 2013-04-16 18:55:38 -0700 | [diff] [blame] | 108 | */ |
| 109 | public static final int CAPABILITY_CAN_REQUEST_FILTER_KEY_EVENTS = 0x00000008; |
| 110 | |
Alan Viverette | 214fb68 | 2015-11-17 09:47:11 -0500 | [diff] [blame] | 111 | /** |
| 112 | * Capability: This accessibility service can control display magnification. |
| 113 | * @see android.R.styleable#AccessibilityService_canControlMagnification |
| 114 | */ |
| 115 | public static final int CAPABILITY_CAN_CONTROL_MAGNIFICATION = 0x00000010; |
| 116 | |
Phil Weaver | a6b64f5 | 2015-12-04 15:21:35 -0800 | [diff] [blame] | 117 | /** |
| 118 | * Capability: This accessibility service can perform gestures. |
| 119 | * @see android.R.styleable#AccessibilityService_canPerformGestures |
| 120 | */ |
| 121 | public static final int CAPABILITY_CAN_PERFORM_GESTURES = 0x00000020; |
| 122 | |
Phil Weaver | 27fcd9c | 2017-01-20 15:57:24 -0800 | [diff] [blame] | 123 | /** |
| 124 | * Capability: This accessibility service can capture gestures from the fingerprint sensor |
Phil Weaver | be2922f | 2017-04-28 14:58:35 -0700 | [diff] [blame] | 125 | * @see android.R.styleable#AccessibilityService_canRequestFingerprintGestures |
Phil Weaver | 27fcd9c | 2017-01-20 15:57:24 -0800 | [diff] [blame] | 126 | */ |
Phil Weaver | be2922f | 2017-04-28 14:58:35 -0700 | [diff] [blame] | 127 | public static final int CAPABILITY_CAN_REQUEST_FINGERPRINT_GESTURES = 0x00000040; |
Phil Weaver | 27fcd9c | 2017-01-20 15:57:24 -0800 | [diff] [blame] | 128 | |
| 129 | private static SparseArray<CapabilityInfo> sAvailableCapabilityInfos; |
Svetoslav | 688a697 | 2013-04-16 18:55:38 -0700 | [diff] [blame] | 130 | |
| 131 | /** |
svetoslavganov | 75986cf | 2009-05-14 22:28:01 -0700 | [diff] [blame] | 132 | * Denotes spoken feedback. |
| 133 | */ |
| 134 | public static final int FEEDBACK_SPOKEN = 0x0000001; |
| 135 | |
| 136 | /** |
| 137 | * Denotes haptic feedback. |
| 138 | */ |
| 139 | public static final int FEEDBACK_HAPTIC = 0x0000002; |
| 140 | |
| 141 | /** |
| 142 | * Denotes audible (not spoken) feedback. |
| 143 | */ |
| 144 | public static final int FEEDBACK_AUDIBLE = 0x0000004; |
| 145 | |
| 146 | /** |
| 147 | * Denotes visual feedback. |
| 148 | */ |
| 149 | public static final int FEEDBACK_VISUAL = 0x0000008; |
| 150 | |
| 151 | /** |
| 152 | * Denotes generic feedback. |
| 153 | */ |
| 154 | public static final int FEEDBACK_GENERIC = 0x0000010; |
| 155 | |
| 156 | /** |
Svetoslav Ganov | eb9862f | 2012-09-06 19:40:29 -0700 | [diff] [blame] | 157 | * Denotes braille feedback. |
| 158 | */ |
| 159 | public static final int FEEDBACK_BRAILLE = 0x0000020; |
| 160 | |
| 161 | /** |
Svetoslav Ganov | 00aabf7 | 2011-07-21 11:35:03 -0700 | [diff] [blame] | 162 | * Mask for all feedback types. |
| 163 | * |
| 164 | * @see #FEEDBACK_SPOKEN |
| 165 | * @see #FEEDBACK_HAPTIC |
| 166 | * @see #FEEDBACK_AUDIBLE |
| 167 | * @see #FEEDBACK_VISUAL |
| 168 | * @see #FEEDBACK_GENERIC |
Svetoslav Ganov | eb9862f | 2012-09-06 19:40:29 -0700 | [diff] [blame] | 169 | * @see #FEEDBACK_BRAILLE |
Svetoslav Ganov | 00aabf7 | 2011-07-21 11:35:03 -0700 | [diff] [blame] | 170 | */ |
| 171 | public static final int FEEDBACK_ALL_MASK = 0xFFFFFFFF; |
| 172 | |
| 173 | /** |
svetoslavganov | 75986cf | 2009-05-14 22:28:01 -0700 | [diff] [blame] | 174 | * If an {@link AccessibilityService} is the default for a given type. |
| 175 | * Default service is invoked only if no package specific one exists. In case of |
| 176 | * more than one package specific service only the earlier registered is notified. |
| 177 | */ |
| 178 | public static final int DEFAULT = 0x0000001; |
| 179 | |
| 180 | /** |
Svetoslav Ganov | 4213804 | 2012-03-20 11:51:39 -0700 | [diff] [blame] | 181 | * If this flag is set the system will regard views that are not important |
| 182 | * for accessibility in addition to the ones that are important for accessibility. |
| 183 | * That is, views that are marked as not important for accessibility via |
Alan Viverette | 23be199 | 2013-10-02 17:41:15 -0700 | [diff] [blame] | 184 | * {@link View#IMPORTANT_FOR_ACCESSIBILITY_NO} or |
| 185 | * {@link View#IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS} and views that are |
| 186 | * marked as potentially important for accessibility via |
Svetoslav Ganov | 4213804 | 2012-03-20 11:51:39 -0700 | [diff] [blame] | 187 | * {@link View#IMPORTANT_FOR_ACCESSIBILITY_AUTO} for which the system has determined |
Alan Viverette | 23be199 | 2013-10-02 17:41:15 -0700 | [diff] [blame] | 188 | * that are not important for accessibility, are reported while querying the window |
| 189 | * content and also the accessibility service will receive accessibility events from |
| 190 | * them. |
Svetoslav Ganov | 4213804 | 2012-03-20 11:51:39 -0700 | [diff] [blame] | 191 | * <p> |
Kevin Hufnagle | 65f4293 | 2018-08-14 17:44:53 -0700 | [diff] [blame] | 192 | * <strong>Note:</strong> For accessibility services targeting Android 4.1 (API level 16) or |
| 193 | * higher, this flag has to be explicitly set for the system to regard views that are not |
| 194 | * important for accessibility. For accessibility services targeting Android 4.0.4 (API level |
| 195 | * 15) or lower, this flag is ignored and all views are regarded for accessibility purposes. |
Svetoslav Ganov | 4213804 | 2012-03-20 11:51:39 -0700 | [diff] [blame] | 196 | * </p> |
| 197 | * <p> |
| 198 | * Usually views not important for accessibility are layout managers that do not |
| 199 | * react to user actions, do not draw any content, and do not have any special |
| 200 | * semantics in the context of the screen content. For example, a three by three |
| 201 | * grid can be implemented as three horizontal linear layouts and one vertical, |
| 202 | * or three vertical linear layouts and one horizontal, or one grid layout, etc. |
kopriva | 82c591b | 2018-10-08 15:57:00 -0700 | [diff] [blame] | 203 | * In this context, the actual layout managers used to achieve the grid configuration |
| 204 | * are not important; rather it is important that there are nine evenly distributed |
Svetoslav Ganov | 4213804 | 2012-03-20 11:51:39 -0700 | [diff] [blame] | 205 | * elements. |
| 206 | * </p> |
| 207 | */ |
Svetoslav Ganov | 3ec2e1b | 2012-05-09 11:02:38 -0700 | [diff] [blame] | 208 | public static final int FLAG_INCLUDE_NOT_IMPORTANT_VIEWS = 0x0000002; |
| 209 | |
| 210 | /** |
| 211 | * This flag requests that the system gets into touch exploration mode. |
| 212 | * In this mode a single finger moving on the screen behaves as a mouse |
| 213 | * pointer hovering over the user interface. The system will also detect |
| 214 | * certain gestures performed on the touch screen and notify this service. |
| 215 | * The system will enable touch exploration mode if there is at least one |
| 216 | * accessibility service that has this flag set. Hence, clearing this |
| 217 | * flag does not guarantee that the device will not be in touch exploration |
| 218 | * mode since there may be another enabled service that requested it. |
Svetoslav | 0ec0418 | 2013-01-31 16:54:40 -0800 | [diff] [blame] | 219 | * <p> |
Kevin Hufnagle | 65f4293 | 2018-08-14 17:44:53 -0700 | [diff] [blame] | 220 | * For accessibility services targeting Android 4.3 (API level 18) or higher |
| 221 | * that want to set this flag have to declare this capability in their |
| 222 | * meta-data by setting the attribute |
| 223 | * {@link android.R.attr#canRequestTouchExplorationMode |
| 224 | * canRequestTouchExplorationMode} to true. Otherwise, this flag will |
Svetoslav | 688a697 | 2013-04-16 18:55:38 -0700 | [diff] [blame] | 225 | * be ignored. For how to declare the meta-data of a service refer to |
| 226 | * {@value AccessibilityService#SERVICE_META_DATA}. |
Svetoslav | 0ec0418 | 2013-01-31 16:54:40 -0800 | [diff] [blame] | 227 | * </p> |
Svetoslav Ganov | 447d946 | 2013-02-01 19:46:20 +0000 | [diff] [blame] | 228 | * <p> |
Kevin Hufnagle | 65f4293 | 2018-08-14 17:44:53 -0700 | [diff] [blame] | 229 | * Services targeting Android 4.2.2 (API level 17) or lower will work |
| 230 | * normally. In other words, the first time they are run, if this flag is |
| 231 | * specified, a dialog is shown to the user to confirm enabling explore by |
| 232 | * touch. |
Svetoslav Ganov | 447d946 | 2013-02-01 19:46:20 +0000 | [diff] [blame] | 233 | * </p> |
Scott Main | 00d17f7 | 2013-06-06 18:37:59 -0700 | [diff] [blame] | 234 | * @see android.R.styleable#AccessibilityService_canRequestTouchExplorationMode |
Svetoslav Ganov | 3ec2e1b | 2012-05-09 11:02:38 -0700 | [diff] [blame] | 235 | */ |
Svetoslav | 0ec0418 | 2013-01-31 16:54:40 -0800 | [diff] [blame] | 236 | public static final int FLAG_REQUEST_TOUCH_EXPLORATION_MODE = 0x0000004; |
Svetoslav Ganov | 4213804 | 2012-03-20 11:51:39 -0700 | [diff] [blame] | 237 | |
| 238 | /** |
Phil Weaver | 09d4ff8 | 2017-03-31 11:22:17 -0700 | [diff] [blame] | 239 | * @deprecated No longer used |
Svetoslav | 3822896 | 2013-01-29 01:04:35 -0800 | [diff] [blame] | 240 | */ |
| 241 | public static final int FLAG_REQUEST_ENHANCED_WEB_ACCESSIBILITY = 0x00000008; |
| 242 | |
| 243 | /** |
Svetoslav Ganov | 80943d8 | 2013-01-02 10:25:37 -0800 | [diff] [blame] | 244 | * This flag requests that the {@link AccessibilityNodeInfo}s obtained |
| 245 | * by an {@link AccessibilityService} contain the id of the source view. |
| 246 | * The source view id will be a fully qualified resource name of the |
| 247 | * form "package:id/name", for example "foo.bar:id/my_list", and it is |
| 248 | * useful for UI test automation. This flag is not set by default. |
| 249 | */ |
Svetoslav | 3822896 | 2013-01-29 01:04:35 -0800 | [diff] [blame] | 250 | public static final int FLAG_REPORT_VIEW_IDS = 0x00000010; |
Svetoslav Ganov | 80943d8 | 2013-01-02 10:25:37 -0800 | [diff] [blame] | 251 | |
| 252 | /** |
Svetoslav | 688a697 | 2013-04-16 18:55:38 -0700 | [diff] [blame] | 253 | * This flag requests from the system to filter key events. If this flag |
| 254 | * is set the accessibility service will receive the key events before |
Phil Weaver | a6b64f5 | 2015-12-04 15:21:35 -0800 | [diff] [blame] | 255 | * applications allowing it implement global shortcuts. |
Svetoslav | 688a697 | 2013-04-16 18:55:38 -0700 | [diff] [blame] | 256 | * <p> |
| 257 | * Services that want to set this flag have to declare this capability |
| 258 | * in their meta-data by setting the attribute {@link android.R.attr |
| 259 | * #canRequestFilterKeyEvents canRequestFilterKeyEvents} to true, |
| 260 | * otherwise this flag will be ignored. For how to declare the meta-data |
| 261 | * of a service refer to {@value AccessibilityService#SERVICE_META_DATA}. |
| 262 | * </p> |
Scott Main | 00d17f7 | 2013-06-06 18:37:59 -0700 | [diff] [blame] | 263 | * @see android.R.styleable#AccessibilityService_canRequestFilterKeyEvents |
Svetoslav | 688a697 | 2013-04-16 18:55:38 -0700 | [diff] [blame] | 264 | */ |
| 265 | public static final int FLAG_REQUEST_FILTER_KEY_EVENTS = 0x00000020; |
| 266 | |
| 267 | /** |
Svetoslav | 8e3feb1 | 2014-02-24 13:46:47 -0800 | [diff] [blame] | 268 | * This flag indicates to the system that the accessibility service wants |
| 269 | * to access content of all interactive windows. An interactive window is a |
Svetoslav | f7174e8 | 2014-06-12 11:29:35 -0700 | [diff] [blame] | 270 | * window that has input focus or can be touched by a sighted user when explore |
| 271 | * by touch is not enabled. If this flag is not set your service will not receive |
Svetoslav | 8e3feb1 | 2014-02-24 13:46:47 -0800 | [diff] [blame] | 272 | * {@link android.view.accessibility.AccessibilityEvent#TYPE_WINDOWS_CHANGED} |
| 273 | * events, calling AccessibilityService{@link AccessibilityService#getWindows() |
| 274 | * AccessibilityService.getWindows()} will return an empty list, and {@link |
| 275 | * AccessibilityNodeInfo#getWindow() AccessibilityNodeInfo.getWindow()} will |
| 276 | * return null. |
| 277 | * <p> |
| 278 | * Services that want to set this flag have to declare the capability |
| 279 | * to retrieve window content in their meta-data by setting the attribute |
| 280 | * {@link android.R.attr#canRetrieveWindowContent canRetrieveWindowContent} to |
| 281 | * true, otherwise this flag will be ignored. For how to declare the meta-data |
| 282 | * of a service refer to {@value AccessibilityService#SERVICE_META_DATA}. |
| 283 | * </p> |
| 284 | * @see android.R.styleable#AccessibilityService_canRetrieveWindowContent |
| 285 | */ |
| 286 | public static final int FLAG_RETRIEVE_INTERACTIVE_WINDOWS = 0x00000040; |
| 287 | |
Phil Weaver | 4acc16d | 2016-09-14 17:04:49 -0700 | [diff] [blame] | 288 | /** |
| 289 | * This flag requests that all audio tracks system-wide with |
| 290 | * {@link android.media.AudioAttributes#USAGE_ASSISTANCE_ACCESSIBILITY} be controlled by the |
| 291 | * {@link android.media.AudioManager#STREAM_ACCESSIBILITY} volume. |
| 292 | */ |
| 293 | public static final int FLAG_ENABLE_ACCESSIBILITY_VOLUME = 0x00000080; |
| 294 | |
Casey Burkhardt | 048c2bc | 2016-12-08 16:09:20 -0800 | [diff] [blame] | 295 | /** |
| 296 | * This flag indicates to the system that the accessibility service requests that an |
| 297 | * accessibility button be shown within the system's navigation area, if available. |
| 298 | */ |
| 299 | public static final int FLAG_REQUEST_ACCESSIBILITY_BUTTON = 0x00000100; |
| 300 | |
Phil Weaver | 27fcd9c | 2017-01-20 15:57:24 -0800 | [diff] [blame] | 301 | /** |
| 302 | * This flag requests that all fingerprint gestures be sent to the accessibility service. |
Phil Weaver | 466b71e | 2018-04-20 14:51:39 -0700 | [diff] [blame] | 303 | * <p> |
| 304 | * Services that want to set this flag have to declare the capability |
| 305 | * to retrieve window content in their meta-data by setting the attribute |
| 306 | * {@link android.R.attr#canRequestFingerprintGestures} to |
| 307 | * true, otherwise this flag will be ignored. For how to declare the meta-data |
| 308 | * of a service refer to {@value AccessibilityService#SERVICE_META_DATA}. |
| 309 | * </p> |
| 310 | * |
| 311 | * @see android.R.styleable#AccessibilityService_canRequestFingerprintGestures |
| 312 | * @see AccessibilityService#getFingerprintGestureController() |
Phil Weaver | 27fcd9c | 2017-01-20 15:57:24 -0800 | [diff] [blame] | 313 | */ |
Phil Weaver | be2922f | 2017-04-28 14:58:35 -0700 | [diff] [blame] | 314 | public static final int FLAG_REQUEST_FINGERPRINT_GESTURES = 0x00000200; |
Phil Weaver | 27fcd9c | 2017-01-20 15:57:24 -0800 | [diff] [blame] | 315 | |
Jeff Sharkey | b5e89c6 | 2016-04-01 23:20:31 -0600 | [diff] [blame] | 316 | /** {@hide} */ |
| 317 | public static final int FLAG_FORCE_DIRECT_BOOT_AWARE = 0x00010000; |
| 318 | |
Svetoslav | 8e3feb1 | 2014-02-24 13:46:47 -0800 | [diff] [blame] | 319 | /** |
svetoslavganov | 75986cf | 2009-05-14 22:28:01 -0700 | [diff] [blame] | 320 | * The event types an {@link AccessibilityService} is interested in. |
Svetoslav Ganov | cc4053e | 2011-05-23 13:37:44 -0700 | [diff] [blame] | 321 | * <p> |
| 322 | * <strong>Can be dynamically set at runtime.</strong> |
| 323 | * </p> |
svetoslavganov | 75986cf | 2009-05-14 22:28:01 -0700 | [diff] [blame] | 324 | * @see android.view.accessibility.AccessibilityEvent#TYPE_VIEW_CLICKED |
Svetoslav Ganov | 9b31779 | 2010-02-17 16:46:42 -0800 | [diff] [blame] | 325 | * @see android.view.accessibility.AccessibilityEvent#TYPE_VIEW_LONG_CLICKED |
svetoslavganov | 75986cf | 2009-05-14 22:28:01 -0700 | [diff] [blame] | 326 | * @see android.view.accessibility.AccessibilityEvent#TYPE_VIEW_FOCUSED |
| 327 | * @see android.view.accessibility.AccessibilityEvent#TYPE_VIEW_SELECTED |
| 328 | * @see android.view.accessibility.AccessibilityEvent#TYPE_VIEW_TEXT_CHANGED |
svetoslavganov | 75986cf | 2009-05-14 22:28:01 -0700 | [diff] [blame] | 329 | * @see android.view.accessibility.AccessibilityEvent#TYPE_WINDOW_STATE_CHANGED |
| 330 | * @see android.view.accessibility.AccessibilityEvent#TYPE_NOTIFICATION_STATE_CHANGED |
Svetoslav Ganov | 38e8b4e | 2011-06-29 20:00:53 -0700 | [diff] [blame] | 331 | * @see android.view.accessibility.AccessibilityEvent#TYPE_TOUCH_EXPLORATION_GESTURE_START |
| 332 | * @see android.view.accessibility.AccessibilityEvent#TYPE_TOUCH_EXPLORATION_GESTURE_END |
| 333 | * @see android.view.accessibility.AccessibilityEvent#TYPE_VIEW_HOVER_ENTER |
| 334 | * @see android.view.accessibility.AccessibilityEvent#TYPE_VIEW_HOVER_EXIT |
| 335 | * @see android.view.accessibility.AccessibilityEvent#TYPE_VIEW_SCROLLED |
| 336 | * @see android.view.accessibility.AccessibilityEvent#TYPE_VIEW_TEXT_SELECTION_CHANGED |
| 337 | * @see android.view.accessibility.AccessibilityEvent#TYPE_WINDOW_CONTENT_CHANGED |
Svetoslav | 8e3feb1 | 2014-02-24 13:46:47 -0800 | [diff] [blame] | 338 | * @see android.view.accessibility.AccessibilityEvent#TYPE_TOUCH_INTERACTION_START |
| 339 | * @see android.view.accessibility.AccessibilityEvent#TYPE_TOUCH_INTERACTION_END |
| 340 | * @see android.view.accessibility.AccessibilityEvent#TYPE_ANNOUNCEMENT |
| 341 | * @see android.view.accessibility.AccessibilityEvent#TYPE_GESTURE_DETECTION_START |
| 342 | * @see android.view.accessibility.AccessibilityEvent#TYPE_GESTURE_DETECTION_END |
| 343 | * @see android.view.accessibility.AccessibilityEvent#TYPE_VIEW_ACCESSIBILITY_FOCUSED |
| 344 | * @see android.view.accessibility.AccessibilityEvent#TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED |
| 345 | * @see android.view.accessibility.AccessibilityEvent#TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY |
| 346 | * @see android.view.accessibility.AccessibilityEvent#TYPE_WINDOWS_CHANGED |
svetoslavganov | 75986cf | 2009-05-14 22:28:01 -0700 | [diff] [blame] | 347 | */ |
| 348 | public int eventTypes; |
| 349 | |
| 350 | /** |
| 351 | * The package names an {@link AccessibilityService} is interested in. Setting |
Svetoslav Ganov | 38e8b4e | 2011-06-29 20:00:53 -0700 | [diff] [blame] | 352 | * to <code>null</code> is equivalent to all packages. |
Svetoslav Ganov | cc4053e | 2011-05-23 13:37:44 -0700 | [diff] [blame] | 353 | * <p> |
| 354 | * <strong>Can be dynamically set at runtime.</strong> |
| 355 | * </p> |
svetoslavganov | 75986cf | 2009-05-14 22:28:01 -0700 | [diff] [blame] | 356 | */ |
| 357 | public String[] packageNames; |
| 358 | |
Svetoslav Ganov | 24c9045 | 2017-12-27 15:17:14 -0800 | [diff] [blame] | 359 | |
| 360 | /** @hide */ |
| 361 | @IntDef(flag = true, prefix = { "FEEDBACK_" }, value = { |
| 362 | FEEDBACK_AUDIBLE, |
| 363 | FEEDBACK_GENERIC, |
| 364 | FEEDBACK_HAPTIC, |
| 365 | FEEDBACK_SPOKEN, |
| 366 | FEEDBACK_VISUAL, |
| 367 | FEEDBACK_BRAILLE |
| 368 | }) |
| 369 | @Retention(RetentionPolicy.SOURCE) |
| 370 | public @interface FeedbackType {} |
| 371 | |
svetoslavganov | 75986cf | 2009-05-14 22:28:01 -0700 | [diff] [blame] | 372 | /** |
| 373 | * The feedback type an {@link AccessibilityService} provides. |
Svetoslav Ganov | cc4053e | 2011-05-23 13:37:44 -0700 | [diff] [blame] | 374 | * <p> |
| 375 | * <strong>Can be dynamically set at runtime.</strong> |
| 376 | * </p> |
svetoslavganov | 75986cf | 2009-05-14 22:28:01 -0700 | [diff] [blame] | 377 | * @see #FEEDBACK_AUDIBLE |
| 378 | * @see #FEEDBACK_GENERIC |
| 379 | * @see #FEEDBACK_HAPTIC |
| 380 | * @see #FEEDBACK_SPOKEN |
| 381 | * @see #FEEDBACK_VISUAL |
Svetoslav Ganov | eb9862f | 2012-09-06 19:40:29 -0700 | [diff] [blame] | 382 | * @see #FEEDBACK_BRAILLE |
svetoslavganov | 75986cf | 2009-05-14 22:28:01 -0700 | [diff] [blame] | 383 | */ |
Svetoslav Ganov | 24c9045 | 2017-12-27 15:17:14 -0800 | [diff] [blame] | 384 | @FeedbackType |
svetoslavganov | 75986cf | 2009-05-14 22:28:01 -0700 | [diff] [blame] | 385 | public int feedbackType; |
| 386 | |
| 387 | /** |
Kevin Hufnagle | 65f4293 | 2018-08-14 17:44:53 -0700 | [diff] [blame] | 388 | * The timeout, in milliseconds, after the most recent event of a given type before an |
svetoslavganov | 75986cf | 2009-05-14 22:28:01 -0700 | [diff] [blame] | 389 | * {@link AccessibilityService} is notified. |
| 390 | * <p> |
Kevin Hufnagle | 65f4293 | 2018-08-14 17:44:53 -0700 | [diff] [blame] | 391 | * <strong>Can be dynamically set at runtime.</strong> |
Svetoslav Ganov | cc4053e | 2011-05-23 13:37:44 -0700 | [diff] [blame] | 392 | * </p> |
| 393 | * <p> |
Svetoslav Ganov | 38e8b4e | 2011-06-29 20:00:53 -0700 | [diff] [blame] | 394 | * <strong>Note:</strong> The event notification timeout is useful to avoid propagating |
| 395 | * events to the client too frequently since this is accomplished via an expensive |
| 396 | * interprocess call. One can think of the timeout as a criteria to determine when |
| 397 | * event generation has settled down. |
svetoslavganov | 75986cf | 2009-05-14 22:28:01 -0700 | [diff] [blame] | 398 | */ |
| 399 | public long notificationTimeout; |
| 400 | |
| 401 | /** |
| 402 | * This field represents a set of flags used for configuring an |
| 403 | * {@link AccessibilityService}. |
Svetoslav Ganov | cc4053e | 2011-05-23 13:37:44 -0700 | [diff] [blame] | 404 | * <p> |
| 405 | * <strong>Can be dynamically set at runtime.</strong> |
| 406 | * </p> |
svetoslavganov | 75986cf | 2009-05-14 22:28:01 -0700 | [diff] [blame] | 407 | * @see #DEFAULT |
Svetoslav Ganov | 3ec2e1b | 2012-05-09 11:02:38 -0700 | [diff] [blame] | 408 | * @see #FLAG_INCLUDE_NOT_IMPORTANT_VIEWS |
| 409 | * @see #FLAG_REQUEST_TOUCH_EXPLORATION_MODE |
Svetoslav | 688a697 | 2013-04-16 18:55:38 -0700 | [diff] [blame] | 410 | * @see #FLAG_REQUEST_ENHANCED_WEB_ACCESSIBILITY |
| 411 | * @see #FLAG_REQUEST_FILTER_KEY_EVENTS |
| 412 | * @see #FLAG_REPORT_VIEW_IDS |
Svetoslav | 8e3feb1 | 2014-02-24 13:46:47 -0800 | [diff] [blame] | 413 | * @see #FLAG_RETRIEVE_INTERACTIVE_WINDOWS |
Casey Burkhardt | 048c2bc | 2016-12-08 16:09:20 -0800 | [diff] [blame] | 414 | * @see #FLAG_ENABLE_ACCESSIBILITY_VOLUME |
| 415 | * @see #FLAG_REQUEST_ACCESSIBILITY_BUTTON |
svetoslavganov | 75986cf | 2009-05-14 22:28:01 -0700 | [diff] [blame] | 416 | */ |
| 417 | public int flags; |
| 418 | |
Svetoslav Ganov | cc4053e | 2011-05-23 13:37:44 -0700 | [diff] [blame] | 419 | /** |
Phil Weaver | c09a021 | 2018-03-13 09:50:43 -0700 | [diff] [blame] | 420 | * Whether or not the service has crashed and is awaiting restart. Only valid from {@link |
| 421 | * android.view.accessibility.AccessibilityManager#getEnabledAccessibilityServiceList(int)}, |
| 422 | * because that is populated from the internal list of running services. |
| 423 | * |
| 424 | * @hide |
| 425 | */ |
| 426 | public boolean crashed; |
| 427 | |
| 428 | /** |
Phil Weaver | 106fe73 | 2016-11-22 18:18:39 -0800 | [diff] [blame] | 429 | * The component name the accessibility service. |
Svetoslav Ganov | cc4053e | 2011-05-23 13:37:44 -0700 | [diff] [blame] | 430 | */ |
Phil Weaver | 106fe73 | 2016-11-22 18:18:39 -0800 | [diff] [blame] | 431 | private ComponentName mComponentName; |
Svetoslav Ganov | cc4053e | 2011-05-23 13:37:44 -0700 | [diff] [blame] | 432 | |
| 433 | /** |
| 434 | * The Service that implements this accessibility service component. |
| 435 | */ |
| 436 | private ResolveInfo mResolveInfo; |
| 437 | |
| 438 | /** |
| 439 | * The accessibility service setting activity's name, used by the system |
| 440 | * settings to launch the setting activity of this accessibility service. |
| 441 | */ |
| 442 | private String mSettingsActivityName; |
| 443 | |
| 444 | /** |
Svetoslav | 688a697 | 2013-04-16 18:55:38 -0700 | [diff] [blame] | 445 | * Bit mask with capabilities of this service. |
Svetoslav Ganov | cc4053e | 2011-05-23 13:37:44 -0700 | [diff] [blame] | 446 | */ |
Svetoslav | 688a697 | 2013-04-16 18:55:38 -0700 | [diff] [blame] | 447 | private int mCapabilities; |
Svetoslav Ganov | cc4053e | 2011-05-23 13:37:44 -0700 | [diff] [blame] | 448 | |
| 449 | /** |
Saige McVea | 08c41bc | 2017-01-20 20:22:35 -0800 | [diff] [blame] | 450 | * Resource id of the summary of the accessibility service. |
| 451 | */ |
| 452 | private int mSummaryResId; |
| 453 | |
| 454 | /** |
| 455 | * Non-localized summary of the accessibility service. |
| 456 | */ |
| 457 | private String mNonLocalizedSummary; |
| 458 | |
| 459 | /** |
Svetoslav Ganov | 3d0edd3 | 2012-01-03 16:38:46 -0800 | [diff] [blame] | 460 | * Resource id of the description of the accessibility service. |
Svetoslav Ganov | 35bfede | 2011-07-14 17:57:06 -0700 | [diff] [blame] | 461 | */ |
Svetoslav Ganov | 3d0edd3 | 2012-01-03 16:38:46 -0800 | [diff] [blame] | 462 | private int mDescriptionResId; |
| 463 | |
| 464 | /** |
| 465 | * Non localized description of the accessibility service. |
| 466 | */ |
| 467 | private String mNonLocalizedDescription; |
Svetoslav Ganov | 35bfede | 2011-07-14 17:57:06 -0700 | [diff] [blame] | 468 | |
| 469 | /** |
Svetoslav Ganov | cc4053e | 2011-05-23 13:37:44 -0700 | [diff] [blame] | 470 | * Creates a new instance. |
| 471 | */ |
| 472 | public AccessibilityServiceInfo() { |
| 473 | /* do nothing */ |
| 474 | } |
| 475 | |
| 476 | /** |
| 477 | * Creates a new instance. |
| 478 | * |
| 479 | * @param resolveInfo The service resolve info. |
| 480 | * @param context Context for accessing resources. |
| 481 | * @throws XmlPullParserException If a XML parsing error occurs. |
| 482 | * @throws IOException If a XML parsing error occurs. |
| 483 | * |
| 484 | * @hide |
| 485 | */ |
| 486 | public AccessibilityServiceInfo(ResolveInfo resolveInfo, Context context) |
| 487 | throws XmlPullParserException, IOException { |
| 488 | ServiceInfo serviceInfo = resolveInfo.serviceInfo; |
Phil Weaver | 106fe73 | 2016-11-22 18:18:39 -0800 | [diff] [blame] | 489 | mComponentName = new ComponentName(serviceInfo.packageName, serviceInfo.name); |
Svetoslav Ganov | cc4053e | 2011-05-23 13:37:44 -0700 | [diff] [blame] | 490 | mResolveInfo = resolveInfo; |
| 491 | |
Svetoslav Ganov | cc4053e | 2011-05-23 13:37:44 -0700 | [diff] [blame] | 492 | XmlResourceParser parser = null; |
| 493 | |
| 494 | try { |
| 495 | PackageManager packageManager = context.getPackageManager(); |
| 496 | parser = serviceInfo.loadXmlMetaData(packageManager, |
| 497 | AccessibilityService.SERVICE_META_DATA); |
| 498 | if (parser == null) { |
| 499 | return; |
| 500 | } |
| 501 | |
| 502 | int type = 0; |
| 503 | while (type != XmlPullParser.END_DOCUMENT && type != XmlPullParser.START_TAG) { |
| 504 | type = parser.next(); |
| 505 | } |
| 506 | |
| 507 | String nodeName = parser.getName(); |
| 508 | if (!TAG_ACCESSIBILITY_SERVICE.equals(nodeName)) { |
| 509 | throw new XmlPullParserException( "Meta-data does not start with" |
| 510 | + TAG_ACCESSIBILITY_SERVICE + " tag"); |
| 511 | } |
| 512 | |
| 513 | AttributeSet allAttributes = Xml.asAttributeSet(parser); |
| 514 | Resources resources = packageManager.getResourcesForApplication( |
| 515 | serviceInfo.applicationInfo); |
| 516 | TypedArray asAttributes = resources.obtainAttributes(allAttributes, |
| 517 | com.android.internal.R.styleable.AccessibilityService); |
| 518 | eventTypes = asAttributes.getInt( |
| 519 | com.android.internal.R.styleable.AccessibilityService_accessibilityEventTypes, |
| 520 | 0); |
| 521 | String packageNamez = asAttributes.getString( |
| 522 | com.android.internal.R.styleable.AccessibilityService_packageNames); |
| 523 | if (packageNamez != null) { |
| 524 | packageNames = packageNamez.split("(\\s)*,(\\s)*"); |
| 525 | } |
| 526 | feedbackType = asAttributes.getInt( |
| 527 | com.android.internal.R.styleable.AccessibilityService_accessibilityFeedbackType, |
| 528 | 0); |
| 529 | notificationTimeout = asAttributes.getInt( |
Svetoslav | 8e3feb1 | 2014-02-24 13:46:47 -0800 | [diff] [blame] | 530 | com.android.internal.R.styleable.AccessibilityService_notificationTimeout, |
Svetoslav Ganov | cc4053e | 2011-05-23 13:37:44 -0700 | [diff] [blame] | 531 | 0); |
| 532 | flags = asAttributes.getInt( |
| 533 | com.android.internal.R.styleable.AccessibilityService_accessibilityFlags, 0); |
| 534 | mSettingsActivityName = asAttributes.getString( |
| 535 | com.android.internal.R.styleable.AccessibilityService_settingsActivity); |
Svetoslav | 688a697 | 2013-04-16 18:55:38 -0700 | [diff] [blame] | 536 | if (asAttributes.getBoolean(com.android.internal.R.styleable |
| 537 | .AccessibilityService_canRetrieveWindowContent, false)) { |
| 538 | mCapabilities |= CAPABILITY_CAN_RETRIEVE_WINDOW_CONTENT; |
| 539 | } |
| 540 | if (asAttributes.getBoolean(com.android.internal.R.styleable |
| 541 | .AccessibilityService_canRequestTouchExplorationMode, false)) { |
| 542 | mCapabilities |= CAPABILITY_CAN_REQUEST_TOUCH_EXPLORATION; |
| 543 | } |
| 544 | if (asAttributes.getBoolean(com.android.internal.R.styleable |
Svetoslav | 688a697 | 2013-04-16 18:55:38 -0700 | [diff] [blame] | 545 | .AccessibilityService_canRequestFilterKeyEvents, false)) { |
| 546 | mCapabilities |= CAPABILITY_CAN_REQUEST_FILTER_KEY_EVENTS; |
| 547 | } |
Alan Viverette | 214fb68 | 2015-11-17 09:47:11 -0500 | [diff] [blame] | 548 | if (asAttributes.getBoolean(com.android.internal.R.styleable |
| 549 | .AccessibilityService_canControlMagnification, false)) { |
| 550 | mCapabilities |= CAPABILITY_CAN_CONTROL_MAGNIFICATION; |
| 551 | } |
Phil Weaver | a6b64f5 | 2015-12-04 15:21:35 -0800 | [diff] [blame] | 552 | if (asAttributes.getBoolean(com.android.internal.R.styleable |
| 553 | .AccessibilityService_canPerformGestures, false)) { |
| 554 | mCapabilities |= CAPABILITY_CAN_PERFORM_GESTURES; |
| 555 | } |
Phil Weaver | 27fcd9c | 2017-01-20 15:57:24 -0800 | [diff] [blame] | 556 | if (asAttributes.getBoolean(com.android.internal.R.styleable |
Phil Weaver | be2922f | 2017-04-28 14:58:35 -0700 | [diff] [blame] | 557 | .AccessibilityService_canRequestFingerprintGestures, false)) { |
| 558 | mCapabilities |= CAPABILITY_CAN_REQUEST_FINGERPRINT_GESTURES; |
Phil Weaver | 27fcd9c | 2017-01-20 15:57:24 -0800 | [diff] [blame] | 559 | } |
Svetoslav Ganov | 3d0edd3 | 2012-01-03 16:38:46 -0800 | [diff] [blame] | 560 | TypedValue peekedValue = asAttributes.peekValue( |
Svetoslav Ganov | 35bfede | 2011-07-14 17:57:06 -0700 | [diff] [blame] | 561 | com.android.internal.R.styleable.AccessibilityService_description); |
Svetoslav Ganov | 3d0edd3 | 2012-01-03 16:38:46 -0800 | [diff] [blame] | 562 | if (peekedValue != null) { |
| 563 | mDescriptionResId = peekedValue.resourceId; |
| 564 | CharSequence nonLocalizedDescription = peekedValue.coerceToString(); |
| 565 | if (nonLocalizedDescription != null) { |
| 566 | mNonLocalizedDescription = nonLocalizedDescription.toString().trim(); |
| 567 | } |
| 568 | } |
Saige McVea | 08c41bc | 2017-01-20 20:22:35 -0800 | [diff] [blame] | 569 | peekedValue = asAttributes.peekValue( |
| 570 | com.android.internal.R.styleable.AccessibilityService_summary); |
| 571 | if (peekedValue != null) { |
| 572 | mSummaryResId = peekedValue.resourceId; |
| 573 | CharSequence nonLocalizedSummary = peekedValue.coerceToString(); |
| 574 | if (nonLocalizedSummary != null) { |
| 575 | mNonLocalizedSummary = nonLocalizedSummary.toString().trim(); |
| 576 | } |
| 577 | } |
Svetoslav Ganov | cc4053e | 2011-05-23 13:37:44 -0700 | [diff] [blame] | 578 | asAttributes.recycle(); |
| 579 | } catch (NameNotFoundException e) { |
| 580 | throw new XmlPullParserException( "Unable to create context for: " |
| 581 | + serviceInfo.packageName); |
| 582 | } finally { |
| 583 | if (parser != null) { |
| 584 | parser.close(); |
| 585 | } |
| 586 | } |
| 587 | } |
| 588 | |
| 589 | /** |
Eugene Susla | d4128ec | 2017-12-04 19:48:41 +0000 | [diff] [blame] | 590 | * Updates the properties that an AccessibilitySerivice can change dynamically. |
Svetoslav Ganov | cc4053e | 2011-05-23 13:37:44 -0700 | [diff] [blame] | 591 | * |
| 592 | * @param other The info from which to update the properties. |
| 593 | * |
| 594 | * @hide |
| 595 | */ |
| 596 | public void updateDynamicallyConfigurableProperties(AccessibilityServiceInfo other) { |
| 597 | eventTypes = other.eventTypes; |
| 598 | packageNames = other.packageNames; |
| 599 | feedbackType = other.feedbackType; |
| 600 | notificationTimeout = other.notificationTimeout; |
| 601 | flags = other.flags; |
| 602 | } |
| 603 | |
| 604 | /** |
Svetoslav | 57bf885 | 2013-02-07 19:21:42 -0800 | [diff] [blame] | 605 | * @hide |
| 606 | */ |
| 607 | public void setComponentName(ComponentName component) { |
Phil Weaver | 106fe73 | 2016-11-22 18:18:39 -0800 | [diff] [blame] | 608 | mComponentName = component; |
| 609 | } |
| 610 | |
| 611 | /** |
| 612 | * @hide |
| 613 | */ |
| 614 | public ComponentName getComponentName() { |
| 615 | return mComponentName; |
Svetoslav | 57bf885 | 2013-02-07 19:21:42 -0800 | [diff] [blame] | 616 | } |
| 617 | |
| 618 | /** |
Svetoslav Ganov | cc4053e | 2011-05-23 13:37:44 -0700 | [diff] [blame] | 619 | * The accessibility service id. |
| 620 | * <p> |
| 621 | * <strong>Generated by the system.</strong> |
| 622 | * </p> |
| 623 | * @return The id. |
| 624 | */ |
| 625 | public String getId() { |
Phil Weaver | 106fe73 | 2016-11-22 18:18:39 -0800 | [diff] [blame] | 626 | return mComponentName.flattenToShortString(); |
Svetoslav Ganov | cc4053e | 2011-05-23 13:37:44 -0700 | [diff] [blame] | 627 | } |
| 628 | |
| 629 | /** |
| 630 | * The service {@link ResolveInfo}. |
| 631 | * <p> |
| 632 | * <strong>Generated by the system.</strong> |
| 633 | * </p> |
| 634 | * @return The info. |
| 635 | */ |
| 636 | public ResolveInfo getResolveInfo() { |
| 637 | return mResolveInfo; |
| 638 | } |
| 639 | |
| 640 | /** |
| 641 | * The settings activity name. |
| 642 | * <p> |
| 643 | * <strong>Statically set from |
| 644 | * {@link AccessibilityService#SERVICE_META_DATA meta-data}.</strong> |
| 645 | * </p> |
| 646 | * @return The settings activity name. |
| 647 | */ |
| 648 | public String getSettingsActivityName() { |
| 649 | return mSettingsActivityName; |
| 650 | } |
| 651 | |
| 652 | /** |
Svetoslav Ganov | 38e8b4e | 2011-06-29 20:00:53 -0700 | [diff] [blame] | 653 | * Whether this service can retrieve the current window's content. |
Svetoslav Ganov | cc4053e | 2011-05-23 13:37:44 -0700 | [diff] [blame] | 654 | * <p> |
| 655 | * <strong>Statically set from |
| 656 | * {@link AccessibilityService#SERVICE_META_DATA meta-data}.</strong> |
| 657 | * </p> |
Svetoslav Ganov | fefd20e | 2012-04-19 21:44:35 -0700 | [diff] [blame] | 658 | * @return True if window content can be retrieved. |
Svetoslav | 688a697 | 2013-04-16 18:55:38 -0700 | [diff] [blame] | 659 | * |
| 660 | * @deprecated Use {@link #getCapabilities()}. |
Svetoslav Ganov | cc4053e | 2011-05-23 13:37:44 -0700 | [diff] [blame] | 661 | */ |
| 662 | public boolean getCanRetrieveWindowContent() { |
Svetoslav | 688a697 | 2013-04-16 18:55:38 -0700 | [diff] [blame] | 663 | return (mCapabilities & CAPABILITY_CAN_RETRIEVE_WINDOW_CONTENT) != 0; |
| 664 | } |
| 665 | |
| 666 | /** |
| 667 | * Returns the bit mask of capabilities this accessibility service has such as |
| 668 | * being able to retrieve the active window content, etc. |
| 669 | * |
| 670 | * @return The capability bit mask. |
| 671 | * |
| 672 | * @see #CAPABILITY_CAN_RETRIEVE_WINDOW_CONTENT |
| 673 | * @see #CAPABILITY_CAN_REQUEST_TOUCH_EXPLORATION |
Casey Burkhardt | 048c2bc | 2016-12-08 16:09:20 -0800 | [diff] [blame] | 674 | * @see #CAPABILITY_CAN_REQUEST_FILTER_KEY_EVENTS |
Phil Weaver | a6b64f5 | 2015-12-04 15:21:35 -0800 | [diff] [blame] | 675 | * @see #CAPABILITY_CAN_CONTROL_MAGNIFICATION |
| 676 | * @see #CAPABILITY_CAN_PERFORM_GESTURES |
Svetoslav | 688a697 | 2013-04-16 18:55:38 -0700 | [diff] [blame] | 677 | */ |
| 678 | public int getCapabilities() { |
| 679 | return mCapabilities; |
Svetoslav Ganov | cc4053e | 2011-05-23 13:37:44 -0700 | [diff] [blame] | 680 | } |
| 681 | |
| 682 | /** |
Svetoslav | 11adf6d | 2013-04-24 14:51:29 -0700 | [diff] [blame] | 683 | * Sets the bit mask of capabilities this accessibility service has such as |
| 684 | * being able to retrieve the active window content, etc. |
| 685 | * |
| 686 | * @param capabilities The capability bit mask. |
| 687 | * |
| 688 | * @see #CAPABILITY_CAN_RETRIEVE_WINDOW_CONTENT |
| 689 | * @see #CAPABILITY_CAN_REQUEST_TOUCH_EXPLORATION |
Casey Burkhardt | 048c2bc | 2016-12-08 16:09:20 -0800 | [diff] [blame] | 690 | * @see #CAPABILITY_CAN_REQUEST_FILTER_KEY_EVENTS |
Phil Weaver | a6b64f5 | 2015-12-04 15:21:35 -0800 | [diff] [blame] | 691 | * @see #CAPABILITY_CAN_CONTROL_MAGNIFICATION |
| 692 | * @see #CAPABILITY_CAN_PERFORM_GESTURES |
Svetoslav | 11adf6d | 2013-04-24 14:51:29 -0700 | [diff] [blame] | 693 | * |
| 694 | * @hide |
| 695 | */ |
Mathew Inwood | 62992f1 | 2018-08-01 14:28:00 +0100 | [diff] [blame] | 696 | @UnsupportedAppUsage |
Svetoslav | 11adf6d | 2013-04-24 14:51:29 -0700 | [diff] [blame] | 697 | public void setCapabilities(int capabilities) { |
| 698 | mCapabilities = capabilities; |
| 699 | } |
| 700 | |
| 701 | /** |
Saige McVea | 08c41bc | 2017-01-20 20:22:35 -0800 | [diff] [blame] | 702 | * The localized summary of the accessibility service. |
| 703 | * <p> |
| 704 | * <strong>Statically set from |
| 705 | * {@link AccessibilityService#SERVICE_META_DATA meta-data}.</strong> |
| 706 | * </p> |
Saige McVea | cb75b54 | 2017-04-28 20:30:25 -0700 | [diff] [blame] | 707 | * @return The localized summary if available, and {@code null} if a summary |
| 708 | * has not been provided. |
Saige McVea | 08c41bc | 2017-01-20 20:22:35 -0800 | [diff] [blame] | 709 | */ |
Saige McVea | cb75b54 | 2017-04-28 20:30:25 -0700 | [diff] [blame] | 710 | public CharSequence loadSummary(PackageManager packageManager) { |
Saige McVea | 08c41bc | 2017-01-20 20:22:35 -0800 | [diff] [blame] | 711 | if (mSummaryResId == 0) { |
| 712 | return mNonLocalizedSummary; |
| 713 | } |
| 714 | ServiceInfo serviceInfo = mResolveInfo.serviceInfo; |
| 715 | CharSequence summary = packageManager.getText(serviceInfo.packageName, |
| 716 | mSummaryResId, serviceInfo.applicationInfo); |
| 717 | if (summary != null) { |
| 718 | return summary.toString().trim(); |
| 719 | } |
| 720 | return null; |
| 721 | } |
| 722 | |
| 723 | /** |
Svetoslav Ganov | 3d0edd3 | 2012-01-03 16:38:46 -0800 | [diff] [blame] | 724 | * Gets the non-localized description of the accessibility service. |
Svetoslav Ganov | 35bfede | 2011-07-14 17:57:06 -0700 | [diff] [blame] | 725 | * <p> |
| 726 | * <strong>Statically set from |
| 727 | * {@link AccessibilityService#SERVICE_META_DATA meta-data}.</strong> |
| 728 | * </p> |
| 729 | * @return The description. |
Svetoslav Ganov | 3d0edd3 | 2012-01-03 16:38:46 -0800 | [diff] [blame] | 730 | * |
| 731 | * @deprecated Use {@link #loadDescription(PackageManager)}. |
Svetoslav Ganov | 35bfede | 2011-07-14 17:57:06 -0700 | [diff] [blame] | 732 | */ |
| 733 | public String getDescription() { |
Svetoslav Ganov | 3d0edd3 | 2012-01-03 16:38:46 -0800 | [diff] [blame] | 734 | return mNonLocalizedDescription; |
| 735 | } |
| 736 | |
| 737 | /** |
| 738 | * The localized description of the accessibility service. |
| 739 | * <p> |
| 740 | * <strong>Statically set from |
| 741 | * {@link AccessibilityService#SERVICE_META_DATA meta-data}.</strong> |
| 742 | * </p> |
| 743 | * @return The localized description. |
| 744 | */ |
| 745 | public String loadDescription(PackageManager packageManager) { |
| 746 | if (mDescriptionResId == 0) { |
| 747 | return mNonLocalizedDescription; |
| 748 | } |
| 749 | ServiceInfo serviceInfo = mResolveInfo.serviceInfo; |
| 750 | CharSequence description = packageManager.getText(serviceInfo.packageName, |
| 751 | mDescriptionResId, serviceInfo.applicationInfo); |
| 752 | if (description != null) { |
| 753 | return description.toString().trim(); |
| 754 | } |
| 755 | return null; |
Svetoslav Ganov | 35bfede | 2011-07-14 17:57:06 -0700 | [diff] [blame] | 756 | } |
| 757 | |
Jeff Sharkey | e88e266 | 2016-02-23 17:52:16 -0700 | [diff] [blame] | 758 | /** {@hide} */ |
Jeff Sharkey | b5e89c6 | 2016-04-01 23:20:31 -0600 | [diff] [blame] | 759 | public boolean isDirectBootAware() { |
| 760 | return ((flags & FLAG_FORCE_DIRECT_BOOT_AWARE) != 0) |
| 761 | || mResolveInfo.serviceInfo.directBootAware; |
Jeff Sharkey | e88e266 | 2016-02-23 17:52:16 -0700 | [diff] [blame] | 762 | } |
| 763 | |
Svetoslav Ganov | 35bfede | 2011-07-14 17:57:06 -0700 | [diff] [blame] | 764 | /** |
Svetoslav Ganov | cc4053e | 2011-05-23 13:37:44 -0700 | [diff] [blame] | 765 | * {@inheritDoc} |
| 766 | */ |
svetoslavganov | 75986cf | 2009-05-14 22:28:01 -0700 | [diff] [blame] | 767 | public int describeContents() { |
| 768 | return 0; |
| 769 | } |
| 770 | |
Svetoslav Ganov | 9b31779 | 2010-02-17 16:46:42 -0800 | [diff] [blame] | 771 | public void writeToParcel(Parcel parcel, int flagz) { |
svetoslavganov | 75986cf | 2009-05-14 22:28:01 -0700 | [diff] [blame] | 772 | parcel.writeInt(eventTypes); |
| 773 | parcel.writeStringArray(packageNames); |
| 774 | parcel.writeInt(feedbackType); |
| 775 | parcel.writeLong(notificationTimeout); |
| 776 | parcel.writeInt(flags); |
Phil Weaver | c09a021 | 2018-03-13 09:50:43 -0700 | [diff] [blame] | 777 | parcel.writeInt(crashed ? 1 : 0); |
Phil Weaver | 106fe73 | 2016-11-22 18:18:39 -0800 | [diff] [blame] | 778 | parcel.writeParcelable(mComponentName, flagz); |
Svetoslav Ganov | cc4053e | 2011-05-23 13:37:44 -0700 | [diff] [blame] | 779 | parcel.writeParcelable(mResolveInfo, 0); |
| 780 | parcel.writeString(mSettingsActivityName); |
Svetoslav | 688a697 | 2013-04-16 18:55:38 -0700 | [diff] [blame] | 781 | parcel.writeInt(mCapabilities); |
Saige McVea | 08c41bc | 2017-01-20 20:22:35 -0800 | [diff] [blame] | 782 | parcel.writeInt(mSummaryResId); |
| 783 | parcel.writeString(mNonLocalizedSummary); |
Svetoslav Ganov | 3d0edd3 | 2012-01-03 16:38:46 -0800 | [diff] [blame] | 784 | parcel.writeInt(mDescriptionResId); |
| 785 | parcel.writeString(mNonLocalizedDescription); |
Svetoslav Ganov | cc4053e | 2011-05-23 13:37:44 -0700 | [diff] [blame] | 786 | } |
| 787 | |
| 788 | private void initFromParcel(Parcel parcel) { |
| 789 | eventTypes = parcel.readInt(); |
| 790 | packageNames = parcel.readStringArray(); |
| 791 | feedbackType = parcel.readInt(); |
| 792 | notificationTimeout = parcel.readLong(); |
| 793 | flags = parcel.readInt(); |
Phil Weaver | c09a021 | 2018-03-13 09:50:43 -0700 | [diff] [blame] | 794 | crashed = parcel.readInt() != 0; |
Phil Weaver | 106fe73 | 2016-11-22 18:18:39 -0800 | [diff] [blame] | 795 | mComponentName = parcel.readParcelable(this.getClass().getClassLoader()); |
Svetoslav Ganov | cc4053e | 2011-05-23 13:37:44 -0700 | [diff] [blame] | 796 | mResolveInfo = parcel.readParcelable(null); |
| 797 | mSettingsActivityName = parcel.readString(); |
Svetoslav | 688a697 | 2013-04-16 18:55:38 -0700 | [diff] [blame] | 798 | mCapabilities = parcel.readInt(); |
Saige McVea | 08c41bc | 2017-01-20 20:22:35 -0800 | [diff] [blame] | 799 | mSummaryResId = parcel.readInt(); |
| 800 | mNonLocalizedSummary = parcel.readString(); |
Svetoslav Ganov | 3d0edd3 | 2012-01-03 16:38:46 -0800 | [diff] [blame] | 801 | mDescriptionResId = parcel.readInt(); |
| 802 | mNonLocalizedDescription = parcel.readString(); |
Svetoslav Ganov | cc4053e | 2011-05-23 13:37:44 -0700 | [diff] [blame] | 803 | } |
| 804 | |
| 805 | @Override |
Svetoslav | 57bf885 | 2013-02-07 19:21:42 -0800 | [diff] [blame] | 806 | public int hashCode() { |
Phil Weaver | 106fe73 | 2016-11-22 18:18:39 -0800 | [diff] [blame] | 807 | return 31 * 1 + ((mComponentName == null) ? 0 : mComponentName.hashCode()); |
Svetoslav | 57bf885 | 2013-02-07 19:21:42 -0800 | [diff] [blame] | 808 | } |
| 809 | |
| 810 | @Override |
| 811 | public boolean equals(Object obj) { |
| 812 | if (this == obj) { |
| 813 | return true; |
| 814 | } |
| 815 | if (obj == null) { |
| 816 | return false; |
| 817 | } |
| 818 | if (getClass() != obj.getClass()) { |
| 819 | return false; |
| 820 | } |
| 821 | AccessibilityServiceInfo other = (AccessibilityServiceInfo) obj; |
Phil Weaver | 106fe73 | 2016-11-22 18:18:39 -0800 | [diff] [blame] | 822 | if (mComponentName == null) { |
| 823 | if (other.mComponentName != null) { |
Svetoslav | 57bf885 | 2013-02-07 19:21:42 -0800 | [diff] [blame] | 824 | return false; |
| 825 | } |
Phil Weaver | 106fe73 | 2016-11-22 18:18:39 -0800 | [diff] [blame] | 826 | } else if (!mComponentName.equals(other.mComponentName)) { |
Svetoslav | 57bf885 | 2013-02-07 19:21:42 -0800 | [diff] [blame] | 827 | return false; |
| 828 | } |
| 829 | return true; |
| 830 | } |
| 831 | |
| 832 | @Override |
Svetoslav Ganov | cc4053e | 2011-05-23 13:37:44 -0700 | [diff] [blame] | 833 | public String toString() { |
| 834 | StringBuilder stringBuilder = new StringBuilder(); |
| 835 | appendEventTypes(stringBuilder, eventTypes); |
| 836 | stringBuilder.append(", "); |
| 837 | appendPackageNames(stringBuilder, packageNames); |
| 838 | stringBuilder.append(", "); |
| 839 | appendFeedbackTypes(stringBuilder, feedbackType); |
| 840 | stringBuilder.append(", "); |
| 841 | stringBuilder.append("notificationTimeout: ").append(notificationTimeout); |
| 842 | stringBuilder.append(", "); |
| 843 | appendFlags(stringBuilder, flags); |
| 844 | stringBuilder.append(", "); |
Phil Weaver | 106fe73 | 2016-11-22 18:18:39 -0800 | [diff] [blame] | 845 | stringBuilder.append("id: ").append(getId()); |
Svetoslav Ganov | cc4053e | 2011-05-23 13:37:44 -0700 | [diff] [blame] | 846 | stringBuilder.append(", "); |
| 847 | stringBuilder.append("resolveInfo: ").append(mResolveInfo); |
| 848 | stringBuilder.append(", "); |
| 849 | stringBuilder.append("settingsActivityName: ").append(mSettingsActivityName); |
| 850 | stringBuilder.append(", "); |
Saige McVea | 08c41bc | 2017-01-20 20:22:35 -0800 | [diff] [blame] | 851 | stringBuilder.append("summary: ").append(mNonLocalizedSummary); |
| 852 | stringBuilder.append(", "); |
Svetoslav | 688a697 | 2013-04-16 18:55:38 -0700 | [diff] [blame] | 853 | appendCapabilities(stringBuilder, mCapabilities); |
Svetoslav Ganov | cc4053e | 2011-05-23 13:37:44 -0700 | [diff] [blame] | 854 | return stringBuilder.toString(); |
| 855 | } |
| 856 | |
Svetoslav Ganov | 24c9045 | 2017-12-27 15:17:14 -0800 | [diff] [blame] | 857 | private static void appendFeedbackTypes(StringBuilder stringBuilder, |
| 858 | @FeedbackType int feedbackTypes) { |
Svetoslav Ganov | cc4053e | 2011-05-23 13:37:44 -0700 | [diff] [blame] | 859 | stringBuilder.append("feedbackTypes:"); |
| 860 | stringBuilder.append("["); |
| 861 | while (feedbackTypes != 0) { |
| 862 | final int feedbackTypeBit = (1 << Integer.numberOfTrailingZeros(feedbackTypes)); |
| 863 | stringBuilder.append(feedbackTypeToString(feedbackTypeBit)); |
| 864 | feedbackTypes &= ~feedbackTypeBit; |
| 865 | if (feedbackTypes != 0) { |
| 866 | stringBuilder.append(", "); |
| 867 | } |
| 868 | } |
| 869 | stringBuilder.append("]"); |
| 870 | } |
| 871 | |
| 872 | private static void appendPackageNames(StringBuilder stringBuilder, String[] packageNames) { |
| 873 | stringBuilder.append("packageNames:"); |
| 874 | stringBuilder.append("["); |
| 875 | if (packageNames != null) { |
| 876 | final int packageNameCount = packageNames.length; |
| 877 | for (int i = 0; i < packageNameCount; i++) { |
| 878 | stringBuilder.append(packageNames[i]); |
| 879 | if (i < packageNameCount - 1) { |
| 880 | stringBuilder.append(", "); |
| 881 | } |
| 882 | } |
| 883 | } |
| 884 | stringBuilder.append("]"); |
| 885 | } |
| 886 | |
| 887 | private static void appendEventTypes(StringBuilder stringBuilder, int eventTypes) { |
| 888 | stringBuilder.append("eventTypes:"); |
| 889 | stringBuilder.append("["); |
| 890 | while (eventTypes != 0) { |
| 891 | final int eventTypeBit = (1 << Integer.numberOfTrailingZeros(eventTypes)); |
| 892 | stringBuilder.append(AccessibilityEvent.eventTypeToString(eventTypeBit)); |
| 893 | eventTypes &= ~eventTypeBit; |
| 894 | if (eventTypes != 0) { |
| 895 | stringBuilder.append(", "); |
| 896 | } |
| 897 | } |
| 898 | stringBuilder.append("]"); |
| 899 | } |
| 900 | |
| 901 | private static void appendFlags(StringBuilder stringBuilder, int flags) { |
| 902 | stringBuilder.append("flags:"); |
| 903 | stringBuilder.append("["); |
| 904 | while (flags != 0) { |
| 905 | final int flagBit = (1 << Integer.numberOfTrailingZeros(flags)); |
| 906 | stringBuilder.append(flagToString(flagBit)); |
| 907 | flags &= ~flagBit; |
| 908 | if (flags != 0) { |
| 909 | stringBuilder.append(", "); |
| 910 | } |
| 911 | } |
| 912 | stringBuilder.append("]"); |
| 913 | } |
| 914 | |
Svetoslav | 688a697 | 2013-04-16 18:55:38 -0700 | [diff] [blame] | 915 | private static void appendCapabilities(StringBuilder stringBuilder, int capabilities) { |
| 916 | stringBuilder.append("capabilities:"); |
| 917 | stringBuilder.append("["); |
| 918 | while (capabilities != 0) { |
| 919 | final int capabilityBit = (1 << Integer.numberOfTrailingZeros(capabilities)); |
| 920 | stringBuilder.append(capabilityToString(capabilityBit)); |
| 921 | capabilities &= ~capabilityBit; |
| 922 | if (capabilities != 0) { |
| 923 | stringBuilder.append(", "); |
| 924 | } |
| 925 | } |
| 926 | stringBuilder.append("]"); |
| 927 | } |
| 928 | |
Svetoslav Ganov | cc4053e | 2011-05-23 13:37:44 -0700 | [diff] [blame] | 929 | /** |
| 930 | * Returns the string representation of a feedback type. For example, |
| 931 | * {@link #FEEDBACK_SPOKEN} is represented by the string FEEDBACK_SPOKEN. |
| 932 | * |
| 933 | * @param feedbackType The feedback type. |
| 934 | * @return The string representation. |
| 935 | */ |
| 936 | public static String feedbackTypeToString(int feedbackType) { |
Svetoslav Ganov | bb1b9ea | 2011-10-19 17:10:14 -0700 | [diff] [blame] | 937 | StringBuilder builder = new StringBuilder(); |
| 938 | builder.append("["); |
Svetoslav Ganov | c6c25f9 | 2012-03-09 16:01:18 -0800 | [diff] [blame] | 939 | while (feedbackType != 0) { |
Svetoslav Ganov | bb1b9ea | 2011-10-19 17:10:14 -0700 | [diff] [blame] | 940 | final int feedbackTypeFlag = 1 << Integer.numberOfTrailingZeros(feedbackType); |
| 941 | feedbackType &= ~feedbackTypeFlag; |
Svetoslav Ganov | bb1b9ea | 2011-10-19 17:10:14 -0700 | [diff] [blame] | 942 | switch (feedbackTypeFlag) { |
| 943 | case FEEDBACK_AUDIBLE: |
Svetoslav Ganov | c6c25f9 | 2012-03-09 16:01:18 -0800 | [diff] [blame] | 944 | if (builder.length() > 1) { |
| 945 | builder.append(", "); |
| 946 | } |
Svetoslav Ganov | bb1b9ea | 2011-10-19 17:10:14 -0700 | [diff] [blame] | 947 | builder.append("FEEDBACK_AUDIBLE"); |
| 948 | break; |
| 949 | case FEEDBACK_HAPTIC: |
Svetoslav Ganov | c6c25f9 | 2012-03-09 16:01:18 -0800 | [diff] [blame] | 950 | if (builder.length() > 1) { |
| 951 | builder.append(", "); |
| 952 | } |
Svetoslav Ganov | bb1b9ea | 2011-10-19 17:10:14 -0700 | [diff] [blame] | 953 | builder.append("FEEDBACK_HAPTIC"); |
| 954 | break; |
| 955 | case FEEDBACK_GENERIC: |
Svetoslav Ganov | c6c25f9 | 2012-03-09 16:01:18 -0800 | [diff] [blame] | 956 | if (builder.length() > 1) { |
| 957 | builder.append(", "); |
| 958 | } |
Svetoslav Ganov | bb1b9ea | 2011-10-19 17:10:14 -0700 | [diff] [blame] | 959 | builder.append("FEEDBACK_GENERIC"); |
| 960 | break; |
| 961 | case FEEDBACK_SPOKEN: |
Svetoslav Ganov | c6c25f9 | 2012-03-09 16:01:18 -0800 | [diff] [blame] | 962 | if (builder.length() > 1) { |
| 963 | builder.append(", "); |
| 964 | } |
Svetoslav Ganov | bb1b9ea | 2011-10-19 17:10:14 -0700 | [diff] [blame] | 965 | builder.append("FEEDBACK_SPOKEN"); |
| 966 | break; |
| 967 | case FEEDBACK_VISUAL: |
Svetoslav Ganov | c6c25f9 | 2012-03-09 16:01:18 -0800 | [diff] [blame] | 968 | if (builder.length() > 1) { |
| 969 | builder.append(", "); |
| 970 | } |
Svetoslav Ganov | bb1b9ea | 2011-10-19 17:10:14 -0700 | [diff] [blame] | 971 | builder.append("FEEDBACK_VISUAL"); |
| 972 | break; |
Svetoslav Ganov | eb9862f | 2012-09-06 19:40:29 -0700 | [diff] [blame] | 973 | case FEEDBACK_BRAILLE: |
| 974 | if (builder.length() > 1) { |
| 975 | builder.append(", "); |
| 976 | } |
| 977 | builder.append("FEEDBACK_BRAILLE"); |
| 978 | break; |
Svetoslav Ganov | bb1b9ea | 2011-10-19 17:10:14 -0700 | [diff] [blame] | 979 | } |
Svetoslav Ganov | cc4053e | 2011-05-23 13:37:44 -0700 | [diff] [blame] | 980 | } |
Svetoslav Ganov | bb1b9ea | 2011-10-19 17:10:14 -0700 | [diff] [blame] | 981 | builder.append("]"); |
| 982 | return builder.toString(); |
Svetoslav Ganov | cc4053e | 2011-05-23 13:37:44 -0700 | [diff] [blame] | 983 | } |
| 984 | |
| 985 | /** |
| 986 | * Returns the string representation of a flag. For example, |
| 987 | * {@link #DEFAULT} is represented by the string DEFAULT. |
| 988 | * |
| 989 | * @param flag The flag. |
| 990 | * @return The string representation. |
| 991 | */ |
| 992 | public static String flagToString(int flag) { |
| 993 | switch (flag) { |
| 994 | case DEFAULT: |
| 995 | return "DEFAULT"; |
Svetoslav Ganov | 3ec2e1b | 2012-05-09 11:02:38 -0700 | [diff] [blame] | 996 | case FLAG_INCLUDE_NOT_IMPORTANT_VIEWS: |
| 997 | return "FLAG_INCLUDE_NOT_IMPORTANT_VIEWS"; |
| 998 | case FLAG_REQUEST_TOUCH_EXPLORATION_MODE: |
| 999 | return "FLAG_REQUEST_TOUCH_EXPLORATION_MODE"; |
Svetoslav | 688a697 | 2013-04-16 18:55:38 -0700 | [diff] [blame] | 1000 | case FLAG_REQUEST_ENHANCED_WEB_ACCESSIBILITY: |
| 1001 | return "FLAG_REQUEST_ENHANCED_WEB_ACCESSIBILITY"; |
| 1002 | case FLAG_REPORT_VIEW_IDS: |
| 1003 | return "FLAG_REPORT_VIEW_IDS"; |
| 1004 | case FLAG_REQUEST_FILTER_KEY_EVENTS: |
| 1005 | return "FLAG_REQUEST_FILTER_KEY_EVENTS"; |
Svetoslav | 8e3feb1 | 2014-02-24 13:46:47 -0800 | [diff] [blame] | 1006 | case FLAG_RETRIEVE_INTERACTIVE_WINDOWS: |
| 1007 | return "FLAG_RETRIEVE_INTERACTIVE_WINDOWS"; |
Phil Weaver | 4acc16d | 2016-09-14 17:04:49 -0700 | [diff] [blame] | 1008 | case FLAG_ENABLE_ACCESSIBILITY_VOLUME: |
| 1009 | return "FLAG_ENABLE_ACCESSIBILITY_VOLUME"; |
Casey Burkhardt | 048c2bc | 2016-12-08 16:09:20 -0800 | [diff] [blame] | 1010 | case FLAG_REQUEST_ACCESSIBILITY_BUTTON: |
| 1011 | return "FLAG_REQUEST_ACCESSIBILITY_BUTTON"; |
Phil Weaver | be2922f | 2017-04-28 14:58:35 -0700 | [diff] [blame] | 1012 | case FLAG_REQUEST_FINGERPRINT_GESTURES: |
| 1013 | return "FLAG_REQUEST_FINGERPRINT_GESTURES"; |
Svetoslav Ganov | cc4053e | 2011-05-23 13:37:44 -0700 | [diff] [blame] | 1014 | default: |
| 1015 | return null; |
| 1016 | } |
svetoslavganov | 75986cf | 2009-05-14 22:28:01 -0700 | [diff] [blame] | 1017 | } |
| 1018 | |
| 1019 | /** |
Svetoslav | 688a697 | 2013-04-16 18:55:38 -0700 | [diff] [blame] | 1020 | * Returns the string representation of a capability. For example, |
| 1021 | * {@link #CAPABILITY_CAN_RETRIEVE_WINDOW_CONTENT} is represented |
| 1022 | * by the string CAPABILITY_CAN_RETRIEVE_WINDOW_CONTENT. |
| 1023 | * |
| 1024 | * @param capability The capability. |
| 1025 | * @return The string representation. |
| 1026 | */ |
| 1027 | public static String capabilityToString(int capability) { |
| 1028 | switch (capability) { |
| 1029 | case CAPABILITY_CAN_RETRIEVE_WINDOW_CONTENT: |
| 1030 | return "CAPABILITY_CAN_RETRIEVE_WINDOW_CONTENT"; |
| 1031 | case CAPABILITY_CAN_REQUEST_TOUCH_EXPLORATION: |
| 1032 | return "CAPABILITY_CAN_REQUEST_TOUCH_EXPLORATION"; |
| 1033 | case CAPABILITY_CAN_REQUEST_ENHANCED_WEB_ACCESSIBILITY: |
| 1034 | return "CAPABILITY_CAN_REQUEST_ENHANCED_WEB_ACCESSIBILITY"; |
| 1035 | case CAPABILITY_CAN_REQUEST_FILTER_KEY_EVENTS: |
Casey Burkhardt | 048c2bc | 2016-12-08 16:09:20 -0800 | [diff] [blame] | 1036 | return "CAPABILITY_CAN_REQUEST_FILTER_KEY_EVENTS"; |
Alan Viverette | 214fb68 | 2015-11-17 09:47:11 -0500 | [diff] [blame] | 1037 | case CAPABILITY_CAN_CONTROL_MAGNIFICATION: |
| 1038 | return "CAPABILITY_CAN_CONTROL_MAGNIFICATION"; |
Phil Weaver | a6b64f5 | 2015-12-04 15:21:35 -0800 | [diff] [blame] | 1039 | case CAPABILITY_CAN_PERFORM_GESTURES: |
| 1040 | return "CAPABILITY_CAN_PERFORM_GESTURES"; |
Phil Weaver | be2922f | 2017-04-28 14:58:35 -0700 | [diff] [blame] | 1041 | case CAPABILITY_CAN_REQUEST_FINGERPRINT_GESTURES: |
| 1042 | return "CAPABILITY_CAN_REQUEST_FINGERPRINT_GESTURES"; |
Svetoslav | 688a697 | 2013-04-16 18:55:38 -0700 | [diff] [blame] | 1043 | default: |
| 1044 | return "UNKNOWN"; |
| 1045 | } |
| 1046 | } |
| 1047 | |
| 1048 | /** |
| 1049 | * @hide |
| 1050 | * @return The list of {@link CapabilityInfo} objects. |
Phil Weaver | 27fcd9c | 2017-01-20 15:57:24 -0800 | [diff] [blame] | 1051 | * @deprecated The version that takes a context works better. |
Svetoslav | 688a697 | 2013-04-16 18:55:38 -0700 | [diff] [blame] | 1052 | */ |
| 1053 | public List<CapabilityInfo> getCapabilityInfos() { |
Phil Weaver | 27fcd9c | 2017-01-20 15:57:24 -0800 | [diff] [blame] | 1054 | return getCapabilityInfos(null); |
| 1055 | } |
| 1056 | |
| 1057 | /** |
| 1058 | * @hide |
| 1059 | * @param context A valid context |
| 1060 | * @return The list of {@link CapabilityInfo} objects. |
| 1061 | */ |
| 1062 | public List<CapabilityInfo> getCapabilityInfos(Context context) { |
Svetoslav | 688a697 | 2013-04-16 18:55:38 -0700 | [diff] [blame] | 1063 | if (mCapabilities == 0) { |
| 1064 | return Collections.emptyList(); |
| 1065 | } |
| 1066 | int capabilities = mCapabilities; |
| 1067 | List<CapabilityInfo> capabilityInfos = new ArrayList<CapabilityInfo>(); |
Phil Weaver | 27fcd9c | 2017-01-20 15:57:24 -0800 | [diff] [blame] | 1068 | SparseArray<CapabilityInfo> capabilityInfoSparseArray = |
| 1069 | getCapabilityInfoSparseArray(context); |
Svetoslav | 688a697 | 2013-04-16 18:55:38 -0700 | [diff] [blame] | 1070 | while (capabilities != 0) { |
| 1071 | final int capabilityBit = 1 << Integer.numberOfTrailingZeros(capabilities); |
| 1072 | capabilities &= ~capabilityBit; |
Phil Weaver | 27fcd9c | 2017-01-20 15:57:24 -0800 | [diff] [blame] | 1073 | CapabilityInfo capabilityInfo = capabilityInfoSparseArray.get(capabilityBit); |
Svetoslav | 688a697 | 2013-04-16 18:55:38 -0700 | [diff] [blame] | 1074 | if (capabilityInfo != null) { |
| 1075 | capabilityInfos.add(capabilityInfo); |
| 1076 | } |
| 1077 | } |
| 1078 | return capabilityInfos; |
| 1079 | } |
| 1080 | |
Phil Weaver | 27fcd9c | 2017-01-20 15:57:24 -0800 | [diff] [blame] | 1081 | private static SparseArray<CapabilityInfo> getCapabilityInfoSparseArray(Context context) { |
| 1082 | if (sAvailableCapabilityInfos == null) { |
| 1083 | sAvailableCapabilityInfos = new SparseArray<CapabilityInfo>(); |
| 1084 | sAvailableCapabilityInfos.put(CAPABILITY_CAN_RETRIEVE_WINDOW_CONTENT, |
| 1085 | new CapabilityInfo(CAPABILITY_CAN_RETRIEVE_WINDOW_CONTENT, |
| 1086 | R.string.capability_title_canRetrieveWindowContent, |
| 1087 | R.string.capability_desc_canRetrieveWindowContent)); |
| 1088 | sAvailableCapabilityInfos.put(CAPABILITY_CAN_REQUEST_TOUCH_EXPLORATION, |
| 1089 | new CapabilityInfo(CAPABILITY_CAN_REQUEST_TOUCH_EXPLORATION, |
| 1090 | R.string.capability_title_canRequestTouchExploration, |
| 1091 | R.string.capability_desc_canRequestTouchExploration)); |
Phil Weaver | 27fcd9c | 2017-01-20 15:57:24 -0800 | [diff] [blame] | 1092 | sAvailableCapabilityInfos.put(CAPABILITY_CAN_REQUEST_FILTER_KEY_EVENTS, |
| 1093 | new CapabilityInfo(CAPABILITY_CAN_REQUEST_FILTER_KEY_EVENTS, |
| 1094 | R.string.capability_title_canRequestFilterKeyEvents, |
| 1095 | R.string.capability_desc_canRequestFilterKeyEvents)); |
| 1096 | sAvailableCapabilityInfos.put(CAPABILITY_CAN_CONTROL_MAGNIFICATION, |
| 1097 | new CapabilityInfo(CAPABILITY_CAN_CONTROL_MAGNIFICATION, |
| 1098 | R.string.capability_title_canControlMagnification, |
| 1099 | R.string.capability_desc_canControlMagnification)); |
| 1100 | sAvailableCapabilityInfos.put(CAPABILITY_CAN_PERFORM_GESTURES, |
| 1101 | new CapabilityInfo(CAPABILITY_CAN_PERFORM_GESTURES, |
| 1102 | R.string.capability_title_canPerformGestures, |
| 1103 | R.string.capability_desc_canPerformGestures)); |
Phil Weaver | 7917a2f | 2017-02-16 19:51:14 -0800 | [diff] [blame] | 1104 | if ((context == null) || fingerprintAvailable(context)) { |
Phil Weaver | be2922f | 2017-04-28 14:58:35 -0700 | [diff] [blame] | 1105 | sAvailableCapabilityInfos.put(CAPABILITY_CAN_REQUEST_FINGERPRINT_GESTURES, |
| 1106 | new CapabilityInfo(CAPABILITY_CAN_REQUEST_FINGERPRINT_GESTURES, |
Phil Weaver | 27fcd9c | 2017-01-20 15:57:24 -0800 | [diff] [blame] | 1107 | R.string.capability_title_canCaptureFingerprintGestures, |
| 1108 | R.string.capability_desc_canCaptureFingerprintGestures)); |
| 1109 | } |
| 1110 | } |
| 1111 | return sAvailableCapabilityInfos; |
| 1112 | } |
| 1113 | |
Phil Weaver | 7917a2f | 2017-02-16 19:51:14 -0800 | [diff] [blame] | 1114 | private static boolean fingerprintAvailable(Context context) { |
| 1115 | return context.getPackageManager().hasSystemFeature(FEATURE_FINGERPRINT) |
| 1116 | && context.getSystemService(FingerprintManager.class).isHardwareDetected(); |
| 1117 | } |
Svetoslav | 688a697 | 2013-04-16 18:55:38 -0700 | [diff] [blame] | 1118 | /** |
| 1119 | * @hide |
| 1120 | */ |
| 1121 | public static final class CapabilityInfo { |
| 1122 | public final int capability; |
| 1123 | public final int titleResId; |
| 1124 | public final int descResId; |
| 1125 | |
| 1126 | public CapabilityInfo(int capability, int titleResId, int descResId) { |
| 1127 | this.capability = capability; |
| 1128 | this.titleResId = titleResId; |
| 1129 | this.descResId = descResId; |
| 1130 | } |
| 1131 | } |
| 1132 | |
| 1133 | /** |
svetoslavganov | 75986cf | 2009-05-14 22:28:01 -0700 | [diff] [blame] | 1134 | * @see Parcelable.Creator |
| 1135 | */ |
| 1136 | public static final Parcelable.Creator<AccessibilityServiceInfo> CREATOR = |
| 1137 | new Parcelable.Creator<AccessibilityServiceInfo>() { |
| 1138 | public AccessibilityServiceInfo createFromParcel(Parcel parcel) { |
| 1139 | AccessibilityServiceInfo info = new AccessibilityServiceInfo(); |
Svetoslav Ganov | cc4053e | 2011-05-23 13:37:44 -0700 | [diff] [blame] | 1140 | info.initFromParcel(parcel); |
svetoslavganov | 75986cf | 2009-05-14 22:28:01 -0700 | [diff] [blame] | 1141 | return info; |
| 1142 | } |
| 1143 | |
| 1144 | public AccessibilityServiceInfo[] newArray(int size) { |
| 1145 | return new AccessibilityServiceInfo[size]; |
| 1146 | } |
| 1147 | }; |
| 1148 | } |