blob: f0a0e88310f9170e8e00e29facf4b3b368a781cb [file] [log] [blame]
svetoslavganov75986cf2009-05-14 22:28:01 -07001/*
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
17package android.accessibilityservice;
18
Phil Weaverc09a0212018-03-13 09:50:43 -070019import static android.content.pm.PackageManager.FEATURE_FINGERPRINT;
20
Svetoslav Ganov24c90452017-12-27 15:17:14 -080021import android.annotation.IntDef;
Mathew Inwood62992f12018-08-01 14:28:00 +010022import android.annotation.UnsupportedAppUsage;
Svetoslav Ganovcc4053e2011-05-23 13:37:44 -070023import android.content.ComponentName;
24import android.content.Context;
25import android.content.pm.PackageManager;
26import android.content.pm.PackageManager.NameNotFoundException;
27import android.content.pm.ResolveInfo;
28import android.content.pm.ServiceInfo;
29import android.content.res.Resources;
30import android.content.res.TypedArray;
31import android.content.res.XmlResourceParser;
Phil Weaver27fcd9c2017-01-20 15:57:24 -080032import android.hardware.fingerprint.FingerprintManager;
svetoslavganov75986cf2009-05-14 22:28:01 -070033import android.os.Parcel;
34import android.os.Parcelable;
Svetoslav Ganovcc4053e2011-05-23 13:37:44 -070035import android.util.AttributeSet;
Svetoslav688a6972013-04-16 18:55:38 -070036import android.util.SparseArray;
Svetoslav Ganov3d0edd32012-01-03 16:38:46 -080037import android.util.TypedValue;
Svetoslav Ganovcc4053e2011-05-23 13:37:44 -070038import android.util.Xml;
Svetoslav Ganov42138042012-03-20 11:51:39 -070039import android.view.View;
Svetoslav Ganovcc4053e2011-05-23 13:37:44 -070040import android.view.accessibility.AccessibilityEvent;
Svetoslav Ganov80943d82013-01-02 10:25:37 -080041import android.view.accessibility.AccessibilityNodeInfo;
Svetoslav Ganovcc4053e2011-05-23 13:37:44 -070042
Jeff Sharkeyb5e89c62016-04-01 23:20:31 -060043import com.android.internal.R;
44
Svetoslav Ganovcc4053e2011-05-23 13:37:44 -070045import org.xmlpull.v1.XmlPullParser;
46import org.xmlpull.v1.XmlPullParserException;
47
48import java.io.IOException;
Svetoslav Ganov24c90452017-12-27 15:17:14 -080049import java.lang.annotation.Retention;
50import java.lang.annotation.RetentionPolicy;
Svetoslav688a6972013-04-16 18:55:38 -070051import java.util.ArrayList;
52import java.util.Collections;
53import java.util.List;
svetoslavganov75986cf2009-05-14 22:28:01 -070054
55/**
Svetoslav Ganov38e8b4e2011-06-29 20:00:53 -070056 * This class describes an {@link AccessibilityService}. The system notifies an
57 * {@link AccessibilityService} for {@link android.view.accessibility.AccessibilityEvent}s
svetoslavganov75986cf2009-05-14 22:28:01 -070058 * according to the information encapsulated in this class.
59 *
Joe Fernandeze1302ed2012-02-06 14:30:15 -080060 * <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 Main00d17f72013-06-06 18:37:59 -070067 * @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 McVea08c41bc2017-01-20 20:22:35 -080075 * @attr ref android.R.styleable#AccessibilityService_summary
Scott Main00d17f72013-06-06 18:37:59 -070076 * @attr ref android.R.styleable#AccessibilityService_notificationTimeout
77 * @attr ref android.R.styleable#AccessibilityService_packageNames
78 * @attr ref android.R.styleable#AccessibilityService_settingsActivity
svetoslavganov75986cf2009-05-14 22:28:01 -070079 * @see AccessibilityService
80 * @see android.view.accessibility.AccessibilityEvent
Svetoslav Ganov38e8b4e2011-06-29 20:00:53 -070081 * @see android.view.accessibility.AccessibilityManager
svetoslavganov75986cf2009-05-14 22:28:01 -070082 */
83public class AccessibilityServiceInfo implements Parcelable {
84
Svetoslav Ganovcc4053e2011-05-23 13:37:44 -070085 private static final String TAG_ACCESSIBILITY_SERVICE = "accessibility-service";
86
svetoslavganov75986cf2009-05-14 22:28:01 -070087 /**
Svetoslav688a6972013-04-16 18:55:38 -070088 * Capability: This accessibility service can retrieve the active window content.
Scott Main00d17f72013-06-06 18:37:59 -070089 * @see android.R.styleable#AccessibilityService_canRetrieveWindowContent
Svetoslav688a6972013-04-16 18:55:38 -070090 */
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 Main00d17f72013-06-06 18:37:59 -070096 * @see android.R.styleable#AccessibilityService_canRequestTouchExplorationMode
Svetoslav688a6972013-04-16 18:55:38 -070097 */
98 public static final int CAPABILITY_CAN_REQUEST_TOUCH_EXPLORATION = 0x00000002;
99
100 /**
Phil Weaver09d4ff82017-03-31 11:22:17 -0700101 * @deprecated No longer used
Svetoslav688a6972013-04-16 18:55:38 -0700102 */
103 public static final int CAPABILITY_CAN_REQUEST_ENHANCED_WEB_ACCESSIBILITY = 0x00000004;
104
105 /**
Scott Main00d17f72013-06-06 18:37:59 -0700106 * Capability: This accessibility service can request to filter the key event stream.
107 * @see android.R.styleable#AccessibilityService_canRequestFilterKeyEvents
Svetoslav688a6972013-04-16 18:55:38 -0700108 */
109 public static final int CAPABILITY_CAN_REQUEST_FILTER_KEY_EVENTS = 0x00000008;
110
Alan Viverette214fb682015-11-17 09:47:11 -0500111 /**
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 Weavera6b64f52015-12-04 15:21:35 -0800117 /**
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 Weaver27fcd9c2017-01-20 15:57:24 -0800123 /**
124 * Capability: This accessibility service can capture gestures from the fingerprint sensor
Phil Weaverbe2922f2017-04-28 14:58:35 -0700125 * @see android.R.styleable#AccessibilityService_canRequestFingerprintGestures
Phil Weaver27fcd9c2017-01-20 15:57:24 -0800126 */
Phil Weaverbe2922f2017-04-28 14:58:35 -0700127 public static final int CAPABILITY_CAN_REQUEST_FINGERPRINT_GESTURES = 0x00000040;
Phil Weaver27fcd9c2017-01-20 15:57:24 -0800128
129 private static SparseArray<CapabilityInfo> sAvailableCapabilityInfos;
Svetoslav688a6972013-04-16 18:55:38 -0700130
131 /**
svetoslavganov75986cf2009-05-14 22:28:01 -0700132 * 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 Ganoveb9862f2012-09-06 19:40:29 -0700157 * Denotes braille feedback.
158 */
159 public static final int FEEDBACK_BRAILLE = 0x0000020;
160
161 /**
Svetoslav Ganov00aabf72011-07-21 11:35:03 -0700162 * 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 Ganoveb9862f2012-09-06 19:40:29 -0700169 * @see #FEEDBACK_BRAILLE
Svetoslav Ganov00aabf72011-07-21 11:35:03 -0700170 */
171 public static final int FEEDBACK_ALL_MASK = 0xFFFFFFFF;
172
173 /**
svetoslavganov75986cf2009-05-14 22:28:01 -0700174 * 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 Ganov42138042012-03-20 11:51:39 -0700181 * 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 Viverette23be1992013-10-02 17:41:15 -0700184 * {@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 Ganov42138042012-03-20 11:51:39 -0700187 * {@link View#IMPORTANT_FOR_ACCESSIBILITY_AUTO} for which the system has determined
Alan Viverette23be1992013-10-02 17:41:15 -0700188 * 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 Ganov42138042012-03-20 11:51:39 -0700191 * <p>
Kevin Hufnagle65f42932018-08-14 17:44:53 -0700192 * <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 Ganov42138042012-03-20 11:51:39 -0700196 * </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.
203 * In this context the actual layout mangers used to achieve the grid configuration
204 * are not important, rather it is important that there are nine evenly distributed
205 * elements.
206 * </p>
207 */
Svetoslav Ganov3ec2e1b2012-05-09 11:02:38 -0700208 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.
Svetoslav0ec04182013-01-31 16:54:40 -0800219 * <p>
Kevin Hufnagle65f42932018-08-14 17:44:53 -0700220 * 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
Svetoslav688a6972013-04-16 18:55:38 -0700225 * be ignored. For how to declare the meta-data of a service refer to
226 * {@value AccessibilityService#SERVICE_META_DATA}.
Svetoslav0ec04182013-01-31 16:54:40 -0800227 * </p>
Svetoslav Ganov447d9462013-02-01 19:46:20 +0000228 * <p>
Kevin Hufnagle65f42932018-08-14 17:44:53 -0700229 * 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 Ganov447d9462013-02-01 19:46:20 +0000233 * </p>
Scott Main00d17f72013-06-06 18:37:59 -0700234 * @see android.R.styleable#AccessibilityService_canRequestTouchExplorationMode
Svetoslav Ganov3ec2e1b2012-05-09 11:02:38 -0700235 */
Svetoslav0ec04182013-01-31 16:54:40 -0800236 public static final int FLAG_REQUEST_TOUCH_EXPLORATION_MODE = 0x0000004;
Svetoslav Ganov42138042012-03-20 11:51:39 -0700237
238 /**
Phil Weaver09d4ff82017-03-31 11:22:17 -0700239 * @deprecated No longer used
Svetoslav38228962013-01-29 01:04:35 -0800240 */
241 public static final int FLAG_REQUEST_ENHANCED_WEB_ACCESSIBILITY = 0x00000008;
242
243 /**
Svetoslav Ganov80943d82013-01-02 10:25:37 -0800244 * 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 */
Svetoslav38228962013-01-29 01:04:35 -0800250 public static final int FLAG_REPORT_VIEW_IDS = 0x00000010;
Svetoslav Ganov80943d82013-01-02 10:25:37 -0800251
252 /**
Svetoslav688a6972013-04-16 18:55:38 -0700253 * 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 Weavera6b64f52015-12-04 15:21:35 -0800255 * applications allowing it implement global shortcuts.
Svetoslav688a6972013-04-16 18:55:38 -0700256 * <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 Main00d17f72013-06-06 18:37:59 -0700263 * @see android.R.styleable#AccessibilityService_canRequestFilterKeyEvents
Svetoslav688a6972013-04-16 18:55:38 -0700264 */
265 public static final int FLAG_REQUEST_FILTER_KEY_EVENTS = 0x00000020;
266
267 /**
Svetoslav8e3feb12014-02-24 13:46:47 -0800268 * This flag indicates to the system that the accessibility service wants
269 * to access content of all interactive windows. An interactive window is a
Svetoslavf7174e82014-06-12 11:29:35 -0700270 * 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
Svetoslav8e3feb12014-02-24 13:46:47 -0800272 * {@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 Weaver4acc16d2016-09-14 17:04:49 -0700288 /**
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 Burkhardt048c2bc2016-12-08 16:09:20 -0800295 /**
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 Weaver27fcd9c2017-01-20 15:57:24 -0800301 /**
302 * This flag requests that all fingerprint gestures be sent to the accessibility service.
Phil Weaver466b71e2018-04-20 14:51:39 -0700303 * <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 Weaver27fcd9c2017-01-20 15:57:24 -0800313 */
Phil Weaverbe2922f2017-04-28 14:58:35 -0700314 public static final int FLAG_REQUEST_FINGERPRINT_GESTURES = 0x00000200;
Phil Weaver27fcd9c2017-01-20 15:57:24 -0800315
Jeff Sharkeyb5e89c62016-04-01 23:20:31 -0600316 /** {@hide} */
317 public static final int FLAG_FORCE_DIRECT_BOOT_AWARE = 0x00010000;
318
Svetoslav8e3feb12014-02-24 13:46:47 -0800319 /**
svetoslavganov75986cf2009-05-14 22:28:01 -0700320 * The event types an {@link AccessibilityService} is interested in.
Svetoslav Ganovcc4053e2011-05-23 13:37:44 -0700321 * <p>
322 * <strong>Can be dynamically set at runtime.</strong>
323 * </p>
svetoslavganov75986cf2009-05-14 22:28:01 -0700324 * @see android.view.accessibility.AccessibilityEvent#TYPE_VIEW_CLICKED
Svetoslav Ganov9b317792010-02-17 16:46:42 -0800325 * @see android.view.accessibility.AccessibilityEvent#TYPE_VIEW_LONG_CLICKED
svetoslavganov75986cf2009-05-14 22:28:01 -0700326 * @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
svetoslavganov75986cf2009-05-14 22:28:01 -0700329 * @see android.view.accessibility.AccessibilityEvent#TYPE_WINDOW_STATE_CHANGED
330 * @see android.view.accessibility.AccessibilityEvent#TYPE_NOTIFICATION_STATE_CHANGED
Svetoslav Ganov38e8b4e2011-06-29 20:00:53 -0700331 * @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
Svetoslav8e3feb12014-02-24 13:46:47 -0800338 * @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
svetoslavganov75986cf2009-05-14 22:28:01 -0700347 */
348 public int eventTypes;
349
350 /**
351 * The package names an {@link AccessibilityService} is interested in. Setting
Svetoslav Ganov38e8b4e2011-06-29 20:00:53 -0700352 * to <code>null</code> is equivalent to all packages.
Svetoslav Ganovcc4053e2011-05-23 13:37:44 -0700353 * <p>
354 * <strong>Can be dynamically set at runtime.</strong>
355 * </p>
svetoslavganov75986cf2009-05-14 22:28:01 -0700356 */
357 public String[] packageNames;
358
Svetoslav Ganov24c90452017-12-27 15:17:14 -0800359
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
svetoslavganov75986cf2009-05-14 22:28:01 -0700372 /**
373 * The feedback type an {@link AccessibilityService} provides.
Svetoslav Ganovcc4053e2011-05-23 13:37:44 -0700374 * <p>
375 * <strong>Can be dynamically set at runtime.</strong>
376 * </p>
svetoslavganov75986cf2009-05-14 22:28:01 -0700377 * @see #FEEDBACK_AUDIBLE
378 * @see #FEEDBACK_GENERIC
379 * @see #FEEDBACK_HAPTIC
380 * @see #FEEDBACK_SPOKEN
381 * @see #FEEDBACK_VISUAL
Svetoslav Ganoveb9862f2012-09-06 19:40:29 -0700382 * @see #FEEDBACK_BRAILLE
svetoslavganov75986cf2009-05-14 22:28:01 -0700383 */
Svetoslav Ganov24c90452017-12-27 15:17:14 -0800384 @FeedbackType
svetoslavganov75986cf2009-05-14 22:28:01 -0700385 public int feedbackType;
386
387 /**
Kevin Hufnagle65f42932018-08-14 17:44:53 -0700388 * The timeout, in milliseconds, after the most recent event of a given type before an
svetoslavganov75986cf2009-05-14 22:28:01 -0700389 * {@link AccessibilityService} is notified.
390 * <p>
Kevin Hufnagle65f42932018-08-14 17:44:53 -0700391 * <strong>Can be dynamically set at runtime.</strong>
Svetoslav Ganovcc4053e2011-05-23 13:37:44 -0700392 * </p>
393 * <p>
Svetoslav Ganov38e8b4e2011-06-29 20:00:53 -0700394 * <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.
svetoslavganov75986cf2009-05-14 22:28:01 -0700398 */
399 public long notificationTimeout;
400
401 /**
402 * This field represents a set of flags used for configuring an
403 * {@link AccessibilityService}.
Svetoslav Ganovcc4053e2011-05-23 13:37:44 -0700404 * <p>
405 * <strong>Can be dynamically set at runtime.</strong>
406 * </p>
svetoslavganov75986cf2009-05-14 22:28:01 -0700407 * @see #DEFAULT
Svetoslav Ganov3ec2e1b2012-05-09 11:02:38 -0700408 * @see #FLAG_INCLUDE_NOT_IMPORTANT_VIEWS
409 * @see #FLAG_REQUEST_TOUCH_EXPLORATION_MODE
Svetoslav688a6972013-04-16 18:55:38 -0700410 * @see #FLAG_REQUEST_ENHANCED_WEB_ACCESSIBILITY
411 * @see #FLAG_REQUEST_FILTER_KEY_EVENTS
412 * @see #FLAG_REPORT_VIEW_IDS
Svetoslav8e3feb12014-02-24 13:46:47 -0800413 * @see #FLAG_RETRIEVE_INTERACTIVE_WINDOWS
Casey Burkhardt048c2bc2016-12-08 16:09:20 -0800414 * @see #FLAG_ENABLE_ACCESSIBILITY_VOLUME
415 * @see #FLAG_REQUEST_ACCESSIBILITY_BUTTON
svetoslavganov75986cf2009-05-14 22:28:01 -0700416 */
417 public int flags;
418
Svetoslav Ganovcc4053e2011-05-23 13:37:44 -0700419 /**
Phil Weaverc09a0212018-03-13 09:50:43 -0700420 * 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 Weaver106fe732016-11-22 18:18:39 -0800429 * The component name the accessibility service.
Svetoslav Ganovcc4053e2011-05-23 13:37:44 -0700430 */
Phil Weaver106fe732016-11-22 18:18:39 -0800431 private ComponentName mComponentName;
Svetoslav Ganovcc4053e2011-05-23 13:37:44 -0700432
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 /**
Svetoslav688a6972013-04-16 18:55:38 -0700445 * Bit mask with capabilities of this service.
Svetoslav Ganovcc4053e2011-05-23 13:37:44 -0700446 */
Svetoslav688a6972013-04-16 18:55:38 -0700447 private int mCapabilities;
Svetoslav Ganovcc4053e2011-05-23 13:37:44 -0700448
449 /**
Saige McVea08c41bc2017-01-20 20:22:35 -0800450 * 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 Ganov3d0edd32012-01-03 16:38:46 -0800460 * Resource id of the description of the accessibility service.
Svetoslav Ganov35bfede2011-07-14 17:57:06 -0700461 */
Svetoslav Ganov3d0edd32012-01-03 16:38:46 -0800462 private int mDescriptionResId;
463
464 /**
465 * Non localized description of the accessibility service.
466 */
467 private String mNonLocalizedDescription;
Svetoslav Ganov35bfede2011-07-14 17:57:06 -0700468
469 /**
Svetoslav Ganovcc4053e2011-05-23 13:37:44 -0700470 * 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 Weaver106fe732016-11-22 18:18:39 -0800489 mComponentName = new ComponentName(serviceInfo.packageName, serviceInfo.name);
Svetoslav Ganovcc4053e2011-05-23 13:37:44 -0700490 mResolveInfo = resolveInfo;
491
Svetoslav Ganovcc4053e2011-05-23 13:37:44 -0700492 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(
Svetoslav8e3feb12014-02-24 13:46:47 -0800530 com.android.internal.R.styleable.AccessibilityService_notificationTimeout,
Svetoslav Ganovcc4053e2011-05-23 13:37:44 -0700531 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);
Svetoslav688a6972013-04-16 18:55:38 -0700536 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
Svetoslav688a6972013-04-16 18:55:38 -0700545 .AccessibilityService_canRequestFilterKeyEvents, false)) {
546 mCapabilities |= CAPABILITY_CAN_REQUEST_FILTER_KEY_EVENTS;
547 }
Alan Viverette214fb682015-11-17 09:47:11 -0500548 if (asAttributes.getBoolean(com.android.internal.R.styleable
549 .AccessibilityService_canControlMagnification, false)) {
550 mCapabilities |= CAPABILITY_CAN_CONTROL_MAGNIFICATION;
551 }
Phil Weavera6b64f52015-12-04 15:21:35 -0800552 if (asAttributes.getBoolean(com.android.internal.R.styleable
553 .AccessibilityService_canPerformGestures, false)) {
554 mCapabilities |= CAPABILITY_CAN_PERFORM_GESTURES;
555 }
Phil Weaver27fcd9c2017-01-20 15:57:24 -0800556 if (asAttributes.getBoolean(com.android.internal.R.styleable
Phil Weaverbe2922f2017-04-28 14:58:35 -0700557 .AccessibilityService_canRequestFingerprintGestures, false)) {
558 mCapabilities |= CAPABILITY_CAN_REQUEST_FINGERPRINT_GESTURES;
Phil Weaver27fcd9c2017-01-20 15:57:24 -0800559 }
Svetoslav Ganov3d0edd32012-01-03 16:38:46 -0800560 TypedValue peekedValue = asAttributes.peekValue(
Svetoslav Ganov35bfede2011-07-14 17:57:06 -0700561 com.android.internal.R.styleable.AccessibilityService_description);
Svetoslav Ganov3d0edd32012-01-03 16:38:46 -0800562 if (peekedValue != null) {
563 mDescriptionResId = peekedValue.resourceId;
564 CharSequence nonLocalizedDescription = peekedValue.coerceToString();
565 if (nonLocalizedDescription != null) {
566 mNonLocalizedDescription = nonLocalizedDescription.toString().trim();
567 }
568 }
Saige McVea08c41bc2017-01-20 20:22:35 -0800569 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 Ganovcc4053e2011-05-23 13:37:44 -0700578 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 Suslad4128ec2017-12-04 19:48:41 +0000590 * Updates the properties that an AccessibilitySerivice can change dynamically.
Svetoslav Ganovcc4053e2011-05-23 13:37:44 -0700591 *
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 /**
Svetoslav57bf8852013-02-07 19:21:42 -0800605 * @hide
606 */
607 public void setComponentName(ComponentName component) {
Phil Weaver106fe732016-11-22 18:18:39 -0800608 mComponentName = component;
609 }
610
611 /**
612 * @hide
613 */
614 public ComponentName getComponentName() {
615 return mComponentName;
Svetoslav57bf8852013-02-07 19:21:42 -0800616 }
617
618 /**
Svetoslav Ganovcc4053e2011-05-23 13:37:44 -0700619 * 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 Weaver106fe732016-11-22 18:18:39 -0800626 return mComponentName.flattenToShortString();
Svetoslav Ganovcc4053e2011-05-23 13:37:44 -0700627 }
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 Ganov38e8b4e2011-06-29 20:00:53 -0700653 * Whether this service can retrieve the current window's content.
Svetoslav Ganovcc4053e2011-05-23 13:37:44 -0700654 * <p>
655 * <strong>Statically set from
656 * {@link AccessibilityService#SERVICE_META_DATA meta-data}.</strong>
657 * </p>
Svetoslav Ganovfefd20e2012-04-19 21:44:35 -0700658 * @return True if window content can be retrieved.
Svetoslav688a6972013-04-16 18:55:38 -0700659 *
660 * @deprecated Use {@link #getCapabilities()}.
Svetoslav Ganovcc4053e2011-05-23 13:37:44 -0700661 */
662 public boolean getCanRetrieveWindowContent() {
Svetoslav688a6972013-04-16 18:55:38 -0700663 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 Burkhardt048c2bc2016-12-08 16:09:20 -0800674 * @see #CAPABILITY_CAN_REQUEST_FILTER_KEY_EVENTS
Phil Weavera6b64f52015-12-04 15:21:35 -0800675 * @see #CAPABILITY_CAN_CONTROL_MAGNIFICATION
676 * @see #CAPABILITY_CAN_PERFORM_GESTURES
Svetoslav688a6972013-04-16 18:55:38 -0700677 */
678 public int getCapabilities() {
679 return mCapabilities;
Svetoslav Ganovcc4053e2011-05-23 13:37:44 -0700680 }
681
682 /**
Svetoslav11adf6d2013-04-24 14:51:29 -0700683 * 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 Burkhardt048c2bc2016-12-08 16:09:20 -0800690 * @see #CAPABILITY_CAN_REQUEST_FILTER_KEY_EVENTS
Phil Weavera6b64f52015-12-04 15:21:35 -0800691 * @see #CAPABILITY_CAN_CONTROL_MAGNIFICATION
692 * @see #CAPABILITY_CAN_PERFORM_GESTURES
Svetoslav11adf6d2013-04-24 14:51:29 -0700693 *
694 * @hide
695 */
Mathew Inwood62992f12018-08-01 14:28:00 +0100696 @UnsupportedAppUsage
Svetoslav11adf6d2013-04-24 14:51:29 -0700697 public void setCapabilities(int capabilities) {
698 mCapabilities = capabilities;
699 }
700
701 /**
Saige McVea08c41bc2017-01-20 20:22:35 -0800702 * 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 McVeacb75b542017-04-28 20:30:25 -0700707 * @return The localized summary if available, and {@code null} if a summary
708 * has not been provided.
Saige McVea08c41bc2017-01-20 20:22:35 -0800709 */
Saige McVeacb75b542017-04-28 20:30:25 -0700710 public CharSequence loadSummary(PackageManager packageManager) {
Saige McVea08c41bc2017-01-20 20:22:35 -0800711 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 Ganov3d0edd32012-01-03 16:38:46 -0800724 * Gets the non-localized description of the accessibility service.
Svetoslav Ganov35bfede2011-07-14 17:57:06 -0700725 * <p>
726 * <strong>Statically set from
727 * {@link AccessibilityService#SERVICE_META_DATA meta-data}.</strong>
728 * </p>
729 * @return The description.
Svetoslav Ganov3d0edd32012-01-03 16:38:46 -0800730 *
731 * @deprecated Use {@link #loadDescription(PackageManager)}.
Svetoslav Ganov35bfede2011-07-14 17:57:06 -0700732 */
733 public String getDescription() {
Svetoslav Ganov3d0edd32012-01-03 16:38:46 -0800734 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 Ganov35bfede2011-07-14 17:57:06 -0700756 }
757
Jeff Sharkeye88e2662016-02-23 17:52:16 -0700758 /** {@hide} */
Jeff Sharkeyb5e89c62016-04-01 23:20:31 -0600759 public boolean isDirectBootAware() {
760 return ((flags & FLAG_FORCE_DIRECT_BOOT_AWARE) != 0)
761 || mResolveInfo.serviceInfo.directBootAware;
Jeff Sharkeye88e2662016-02-23 17:52:16 -0700762 }
763
Svetoslav Ganov35bfede2011-07-14 17:57:06 -0700764 /**
Svetoslav Ganovcc4053e2011-05-23 13:37:44 -0700765 * {@inheritDoc}
766 */
svetoslavganov75986cf2009-05-14 22:28:01 -0700767 public int describeContents() {
768 return 0;
769 }
770
Svetoslav Ganov9b317792010-02-17 16:46:42 -0800771 public void writeToParcel(Parcel parcel, int flagz) {
svetoslavganov75986cf2009-05-14 22:28:01 -0700772 parcel.writeInt(eventTypes);
773 parcel.writeStringArray(packageNames);
774 parcel.writeInt(feedbackType);
775 parcel.writeLong(notificationTimeout);
776 parcel.writeInt(flags);
Phil Weaverc09a0212018-03-13 09:50:43 -0700777 parcel.writeInt(crashed ? 1 : 0);
Phil Weaver106fe732016-11-22 18:18:39 -0800778 parcel.writeParcelable(mComponentName, flagz);
Svetoslav Ganovcc4053e2011-05-23 13:37:44 -0700779 parcel.writeParcelable(mResolveInfo, 0);
780 parcel.writeString(mSettingsActivityName);
Svetoslav688a6972013-04-16 18:55:38 -0700781 parcel.writeInt(mCapabilities);
Saige McVea08c41bc2017-01-20 20:22:35 -0800782 parcel.writeInt(mSummaryResId);
783 parcel.writeString(mNonLocalizedSummary);
Svetoslav Ganov3d0edd32012-01-03 16:38:46 -0800784 parcel.writeInt(mDescriptionResId);
785 parcel.writeString(mNonLocalizedDescription);
Svetoslav Ganovcc4053e2011-05-23 13:37:44 -0700786 }
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 Weaverc09a0212018-03-13 09:50:43 -0700794 crashed = parcel.readInt() != 0;
Phil Weaver106fe732016-11-22 18:18:39 -0800795 mComponentName = parcel.readParcelable(this.getClass().getClassLoader());
Svetoslav Ganovcc4053e2011-05-23 13:37:44 -0700796 mResolveInfo = parcel.readParcelable(null);
797 mSettingsActivityName = parcel.readString();
Svetoslav688a6972013-04-16 18:55:38 -0700798 mCapabilities = parcel.readInt();
Saige McVea08c41bc2017-01-20 20:22:35 -0800799 mSummaryResId = parcel.readInt();
800 mNonLocalizedSummary = parcel.readString();
Svetoslav Ganov3d0edd32012-01-03 16:38:46 -0800801 mDescriptionResId = parcel.readInt();
802 mNonLocalizedDescription = parcel.readString();
Svetoslav Ganovcc4053e2011-05-23 13:37:44 -0700803 }
804
805 @Override
Svetoslav57bf8852013-02-07 19:21:42 -0800806 public int hashCode() {
Phil Weaver106fe732016-11-22 18:18:39 -0800807 return 31 * 1 + ((mComponentName == null) ? 0 : mComponentName.hashCode());
Svetoslav57bf8852013-02-07 19:21:42 -0800808 }
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 Weaver106fe732016-11-22 18:18:39 -0800822 if (mComponentName == null) {
823 if (other.mComponentName != null) {
Svetoslav57bf8852013-02-07 19:21:42 -0800824 return false;
825 }
Phil Weaver106fe732016-11-22 18:18:39 -0800826 } else if (!mComponentName.equals(other.mComponentName)) {
Svetoslav57bf8852013-02-07 19:21:42 -0800827 return false;
828 }
829 return true;
830 }
831
832 @Override
Svetoslav Ganovcc4053e2011-05-23 13:37:44 -0700833 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 Weaver106fe732016-11-22 18:18:39 -0800845 stringBuilder.append("id: ").append(getId());
Svetoslav Ganovcc4053e2011-05-23 13:37:44 -0700846 stringBuilder.append(", ");
847 stringBuilder.append("resolveInfo: ").append(mResolveInfo);
848 stringBuilder.append(", ");
849 stringBuilder.append("settingsActivityName: ").append(mSettingsActivityName);
850 stringBuilder.append(", ");
Saige McVea08c41bc2017-01-20 20:22:35 -0800851 stringBuilder.append("summary: ").append(mNonLocalizedSummary);
852 stringBuilder.append(", ");
Svetoslav688a6972013-04-16 18:55:38 -0700853 appendCapabilities(stringBuilder, mCapabilities);
Svetoslav Ganovcc4053e2011-05-23 13:37:44 -0700854 return stringBuilder.toString();
855 }
856
Svetoslav Ganov24c90452017-12-27 15:17:14 -0800857 private static void appendFeedbackTypes(StringBuilder stringBuilder,
858 @FeedbackType int feedbackTypes) {
Svetoslav Ganovcc4053e2011-05-23 13:37:44 -0700859 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
Svetoslav688a6972013-04-16 18:55:38 -0700915 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 Ganovcc4053e2011-05-23 13:37:44 -0700929 /**
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 Ganovbb1b9ea2011-10-19 17:10:14 -0700937 StringBuilder builder = new StringBuilder();
938 builder.append("[");
Svetoslav Ganovc6c25f92012-03-09 16:01:18 -0800939 while (feedbackType != 0) {
Svetoslav Ganovbb1b9ea2011-10-19 17:10:14 -0700940 final int feedbackTypeFlag = 1 << Integer.numberOfTrailingZeros(feedbackType);
941 feedbackType &= ~feedbackTypeFlag;
Svetoslav Ganovbb1b9ea2011-10-19 17:10:14 -0700942 switch (feedbackTypeFlag) {
943 case FEEDBACK_AUDIBLE:
Svetoslav Ganovc6c25f92012-03-09 16:01:18 -0800944 if (builder.length() > 1) {
945 builder.append(", ");
946 }
Svetoslav Ganovbb1b9ea2011-10-19 17:10:14 -0700947 builder.append("FEEDBACK_AUDIBLE");
948 break;
949 case FEEDBACK_HAPTIC:
Svetoslav Ganovc6c25f92012-03-09 16:01:18 -0800950 if (builder.length() > 1) {
951 builder.append(", ");
952 }
Svetoslav Ganovbb1b9ea2011-10-19 17:10:14 -0700953 builder.append("FEEDBACK_HAPTIC");
954 break;
955 case FEEDBACK_GENERIC:
Svetoslav Ganovc6c25f92012-03-09 16:01:18 -0800956 if (builder.length() > 1) {
957 builder.append(", ");
958 }
Svetoslav Ganovbb1b9ea2011-10-19 17:10:14 -0700959 builder.append("FEEDBACK_GENERIC");
960 break;
961 case FEEDBACK_SPOKEN:
Svetoslav Ganovc6c25f92012-03-09 16:01:18 -0800962 if (builder.length() > 1) {
963 builder.append(", ");
964 }
Svetoslav Ganovbb1b9ea2011-10-19 17:10:14 -0700965 builder.append("FEEDBACK_SPOKEN");
966 break;
967 case FEEDBACK_VISUAL:
Svetoslav Ganovc6c25f92012-03-09 16:01:18 -0800968 if (builder.length() > 1) {
969 builder.append(", ");
970 }
Svetoslav Ganovbb1b9ea2011-10-19 17:10:14 -0700971 builder.append("FEEDBACK_VISUAL");
972 break;
Svetoslav Ganoveb9862f2012-09-06 19:40:29 -0700973 case FEEDBACK_BRAILLE:
974 if (builder.length() > 1) {
975 builder.append(", ");
976 }
977 builder.append("FEEDBACK_BRAILLE");
978 break;
Svetoslav Ganovbb1b9ea2011-10-19 17:10:14 -0700979 }
Svetoslav Ganovcc4053e2011-05-23 13:37:44 -0700980 }
Svetoslav Ganovbb1b9ea2011-10-19 17:10:14 -0700981 builder.append("]");
982 return builder.toString();
Svetoslav Ganovcc4053e2011-05-23 13:37:44 -0700983 }
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 Ganov3ec2e1b2012-05-09 11:02:38 -0700996 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";
Svetoslav688a6972013-04-16 18:55:38 -07001000 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";
Svetoslav8e3feb12014-02-24 13:46:47 -08001006 case FLAG_RETRIEVE_INTERACTIVE_WINDOWS:
1007 return "FLAG_RETRIEVE_INTERACTIVE_WINDOWS";
Phil Weaver4acc16d2016-09-14 17:04:49 -07001008 case FLAG_ENABLE_ACCESSIBILITY_VOLUME:
1009 return "FLAG_ENABLE_ACCESSIBILITY_VOLUME";
Casey Burkhardt048c2bc2016-12-08 16:09:20 -08001010 case FLAG_REQUEST_ACCESSIBILITY_BUTTON:
1011 return "FLAG_REQUEST_ACCESSIBILITY_BUTTON";
Phil Weaverbe2922f2017-04-28 14:58:35 -07001012 case FLAG_REQUEST_FINGERPRINT_GESTURES:
1013 return "FLAG_REQUEST_FINGERPRINT_GESTURES";
Svetoslav Ganovcc4053e2011-05-23 13:37:44 -07001014 default:
1015 return null;
1016 }
svetoslavganov75986cf2009-05-14 22:28:01 -07001017 }
1018
1019 /**
Svetoslav688a6972013-04-16 18:55:38 -07001020 * 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 Burkhardt048c2bc2016-12-08 16:09:20 -08001036 return "CAPABILITY_CAN_REQUEST_FILTER_KEY_EVENTS";
Alan Viverette214fb682015-11-17 09:47:11 -05001037 case CAPABILITY_CAN_CONTROL_MAGNIFICATION:
1038 return "CAPABILITY_CAN_CONTROL_MAGNIFICATION";
Phil Weavera6b64f52015-12-04 15:21:35 -08001039 case CAPABILITY_CAN_PERFORM_GESTURES:
1040 return "CAPABILITY_CAN_PERFORM_GESTURES";
Phil Weaverbe2922f2017-04-28 14:58:35 -07001041 case CAPABILITY_CAN_REQUEST_FINGERPRINT_GESTURES:
1042 return "CAPABILITY_CAN_REQUEST_FINGERPRINT_GESTURES";
Svetoslav688a6972013-04-16 18:55:38 -07001043 default:
1044 return "UNKNOWN";
1045 }
1046 }
1047
1048 /**
1049 * @hide
1050 * @return The list of {@link CapabilityInfo} objects.
Phil Weaver27fcd9c2017-01-20 15:57:24 -08001051 * @deprecated The version that takes a context works better.
Svetoslav688a6972013-04-16 18:55:38 -07001052 */
1053 public List<CapabilityInfo> getCapabilityInfos() {
Phil Weaver27fcd9c2017-01-20 15:57:24 -08001054 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) {
Svetoslav688a6972013-04-16 18:55:38 -07001063 if (mCapabilities == 0) {
1064 return Collections.emptyList();
1065 }
1066 int capabilities = mCapabilities;
1067 List<CapabilityInfo> capabilityInfos = new ArrayList<CapabilityInfo>();
Phil Weaver27fcd9c2017-01-20 15:57:24 -08001068 SparseArray<CapabilityInfo> capabilityInfoSparseArray =
1069 getCapabilityInfoSparseArray(context);
Svetoslav688a6972013-04-16 18:55:38 -07001070 while (capabilities != 0) {
1071 final int capabilityBit = 1 << Integer.numberOfTrailingZeros(capabilities);
1072 capabilities &= ~capabilityBit;
Phil Weaver27fcd9c2017-01-20 15:57:24 -08001073 CapabilityInfo capabilityInfo = capabilityInfoSparseArray.get(capabilityBit);
Svetoslav688a6972013-04-16 18:55:38 -07001074 if (capabilityInfo != null) {
1075 capabilityInfos.add(capabilityInfo);
1076 }
1077 }
1078 return capabilityInfos;
1079 }
1080
Phil Weaver27fcd9c2017-01-20 15:57:24 -08001081 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 Weaver27fcd9c2017-01-20 15:57:24 -08001092 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 Weaver7917a2f2017-02-16 19:51:14 -08001104 if ((context == null) || fingerprintAvailable(context)) {
Phil Weaverbe2922f2017-04-28 14:58:35 -07001105 sAvailableCapabilityInfos.put(CAPABILITY_CAN_REQUEST_FINGERPRINT_GESTURES,
1106 new CapabilityInfo(CAPABILITY_CAN_REQUEST_FINGERPRINT_GESTURES,
Phil Weaver27fcd9c2017-01-20 15:57:24 -08001107 R.string.capability_title_canCaptureFingerprintGestures,
1108 R.string.capability_desc_canCaptureFingerprintGestures));
1109 }
1110 }
1111 return sAvailableCapabilityInfos;
1112 }
1113
Phil Weaver7917a2f2017-02-16 19:51:14 -08001114 private static boolean fingerprintAvailable(Context context) {
1115 return context.getPackageManager().hasSystemFeature(FEATURE_FINGERPRINT)
1116 && context.getSystemService(FingerprintManager.class).isHardwareDetected();
1117 }
Svetoslav688a6972013-04-16 18:55:38 -07001118 /**
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 /**
svetoslavganov75986cf2009-05-14 22:28:01 -07001134 * @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 Ganovcc4053e2011-05-23 13:37:44 -07001140 info.initFromParcel(parcel);
svetoslavganov75986cf2009-05-14 22:28:01 -07001141 return info;
1142 }
1143
1144 public AccessibilityServiceInfo[] newArray(int size) {
1145 return new AccessibilityServiceInfo[size];
1146 }
1147 };
1148}