blob: ee03280578e508a0d9232cb810c0646f8c4885c5 [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
Svetoslav Ganovcc4053e2011-05-23 13:37:44 -070019import android.content.ComponentName;
20import android.content.Context;
21import android.content.pm.PackageManager;
22import android.content.pm.PackageManager.NameNotFoundException;
23import android.content.pm.ResolveInfo;
24import android.content.pm.ServiceInfo;
25import android.content.res.Resources;
26import android.content.res.TypedArray;
27import android.content.res.XmlResourceParser;
Svetoslav Ganov42138042012-03-20 11:51:39 -070028import android.os.Build;
svetoslavganov75986cf2009-05-14 22:28:01 -070029import android.os.Parcel;
30import android.os.Parcelable;
Svetoslav Ganovcc4053e2011-05-23 13:37:44 -070031import android.util.AttributeSet;
Svetoslav688a6972013-04-16 18:55:38 -070032import android.util.SparseArray;
Svetoslav Ganov3d0edd32012-01-03 16:38:46 -080033import android.util.TypedValue;
Svetoslav Ganovcc4053e2011-05-23 13:37:44 -070034import android.util.Xml;
Svetoslav Ganov42138042012-03-20 11:51:39 -070035import android.view.View;
Svetoslav Ganovcc4053e2011-05-23 13:37:44 -070036import android.view.accessibility.AccessibilityEvent;
Svetoslav Ganov80943d82013-01-02 10:25:37 -080037import android.view.accessibility.AccessibilityNodeInfo;
Svetoslav Ganovcc4053e2011-05-23 13:37:44 -070038
Jeff Sharkeyb5e89c62016-04-01 23:20:31 -060039import com.android.internal.R;
40
Svetoslav Ganovcc4053e2011-05-23 13:37:44 -070041import org.xmlpull.v1.XmlPullParser;
42import org.xmlpull.v1.XmlPullParserException;
43
44import java.io.IOException;
Svetoslav688a6972013-04-16 18:55:38 -070045import java.util.ArrayList;
46import java.util.Collections;
47import java.util.List;
svetoslavganov75986cf2009-05-14 22:28:01 -070048
49/**
Svetoslav Ganov38e8b4e2011-06-29 20:00:53 -070050 * This class describes an {@link AccessibilityService}. The system notifies an
51 * {@link AccessibilityService} for {@link android.view.accessibility.AccessibilityEvent}s
svetoslavganov75986cf2009-05-14 22:28:01 -070052 * according to the information encapsulated in this class.
53 *
Joe Fernandeze1302ed2012-02-06 14:30:15 -080054 * <div class="special reference">
55 * <h3>Developer Guides</h3>
56 * <p>For more information about creating AccessibilityServices, read the
57 * <a href="{@docRoot}guide/topics/ui/accessibility/index.html">Accessibility</a>
58 * developer guide.</p>
59 * </div>
60 *
Scott Main00d17f72013-06-06 18:37:59 -070061 * @attr ref android.R.styleable#AccessibilityService_accessibilityEventTypes
62 * @attr ref android.R.styleable#AccessibilityService_accessibilityFeedbackType
63 * @attr ref android.R.styleable#AccessibilityService_accessibilityFlags
64 * @attr ref android.R.styleable#AccessibilityService_canRequestEnhancedWebAccessibility
65 * @attr ref android.R.styleable#AccessibilityService_canRequestFilterKeyEvents
66 * @attr ref android.R.styleable#AccessibilityService_canRequestTouchExplorationMode
67 * @attr ref android.R.styleable#AccessibilityService_canRetrieveWindowContent
68 * @attr ref android.R.styleable#AccessibilityService_description
69 * @attr ref android.R.styleable#AccessibilityService_notificationTimeout
70 * @attr ref android.R.styleable#AccessibilityService_packageNames
71 * @attr ref android.R.styleable#AccessibilityService_settingsActivity
72 *
svetoslavganov75986cf2009-05-14 22:28:01 -070073 * @see AccessibilityService
74 * @see android.view.accessibility.AccessibilityEvent
Svetoslav Ganov38e8b4e2011-06-29 20:00:53 -070075 * @see android.view.accessibility.AccessibilityManager
svetoslavganov75986cf2009-05-14 22:28:01 -070076 */
77public class AccessibilityServiceInfo implements Parcelable {
78
Svetoslav Ganovcc4053e2011-05-23 13:37:44 -070079 private static final String TAG_ACCESSIBILITY_SERVICE = "accessibility-service";
80
svetoslavganov75986cf2009-05-14 22:28:01 -070081 /**
Svetoslav688a6972013-04-16 18:55:38 -070082 * Capability: This accessibility service can retrieve the active window content.
Scott Main00d17f72013-06-06 18:37:59 -070083 * @see android.R.styleable#AccessibilityService_canRetrieveWindowContent
Svetoslav688a6972013-04-16 18:55:38 -070084 */
85 public static final int CAPABILITY_CAN_RETRIEVE_WINDOW_CONTENT = 0x00000001;
86
87 /**
88 * Capability: This accessibility service can request touch exploration mode in which
89 * touched items are spoken aloud and the UI can be explored via gestures.
Scott Main00d17f72013-06-06 18:37:59 -070090 * @see android.R.styleable#AccessibilityService_canRequestTouchExplorationMode
Svetoslav688a6972013-04-16 18:55:38 -070091 */
92 public static final int CAPABILITY_CAN_REQUEST_TOUCH_EXPLORATION = 0x00000002;
93
94 /**
95 * Capability: This accessibility service can request enhanced web accessibility
96 * enhancements. For example, installing scripts to make app content more accessible.
Scott Main00d17f72013-06-06 18:37:59 -070097 * @see android.R.styleable#AccessibilityService_canRequestEnhancedWebAccessibility
Svetoslav688a6972013-04-16 18:55:38 -070098 */
99 public static final int CAPABILITY_CAN_REQUEST_ENHANCED_WEB_ACCESSIBILITY = 0x00000004;
100
101 /**
Scott Main00d17f72013-06-06 18:37:59 -0700102 * Capability: This accessibility service can request to filter the key event stream.
103 * @see android.R.styleable#AccessibilityService_canRequestFilterKeyEvents
Svetoslav688a6972013-04-16 18:55:38 -0700104 */
105 public static final int CAPABILITY_CAN_REQUEST_FILTER_KEY_EVENTS = 0x00000008;
106
Alan Viverette214fb682015-11-17 09:47:11 -0500107 /**
108 * Capability: This accessibility service can control display magnification.
109 * @see android.R.styleable#AccessibilityService_canControlMagnification
110 */
111 public static final int CAPABILITY_CAN_CONTROL_MAGNIFICATION = 0x00000010;
112
Phil Weavera6b64f52015-12-04 15:21:35 -0800113 /**
114 * Capability: This accessibility service can perform gestures.
115 * @see android.R.styleable#AccessibilityService_canPerformGestures
116 */
117 public static final int CAPABILITY_CAN_PERFORM_GESTURES = 0x00000020;
118
Svetoslav688a6972013-04-16 18:55:38 -0700119 private static final SparseArray<CapabilityInfo> sAvailableCapabilityInfos =
120 new SparseArray<CapabilityInfo>();
121 static {
122 sAvailableCapabilityInfos.put(CAPABILITY_CAN_RETRIEVE_WINDOW_CONTENT,
123 new CapabilityInfo(CAPABILITY_CAN_RETRIEVE_WINDOW_CONTENT,
124 R.string.capability_title_canRetrieveWindowContent,
125 R.string.capability_desc_canRetrieveWindowContent));
126 sAvailableCapabilityInfos.put(CAPABILITY_CAN_REQUEST_TOUCH_EXPLORATION,
127 new CapabilityInfo(CAPABILITY_CAN_REQUEST_TOUCH_EXPLORATION,
128 R.string.capability_title_canRequestTouchExploration,
129 R.string.capability_desc_canRequestTouchExploration));
130 sAvailableCapabilityInfos.put(CAPABILITY_CAN_REQUEST_ENHANCED_WEB_ACCESSIBILITY,
131 new CapabilityInfo(CAPABILITY_CAN_REQUEST_ENHANCED_WEB_ACCESSIBILITY,
132 R.string.capability_title_canRequestEnhancedWebAccessibility,
133 R.string.capability_desc_canRequestEnhancedWebAccessibility));
134 sAvailableCapabilityInfos.put(CAPABILITY_CAN_REQUEST_FILTER_KEY_EVENTS,
135 new CapabilityInfo(CAPABILITY_CAN_REQUEST_FILTER_KEY_EVENTS,
136 R.string.capability_title_canRequestFilterKeyEvents,
137 R.string.capability_desc_canRequestFilterKeyEvents));
Alan Viverette214fb682015-11-17 09:47:11 -0500138 sAvailableCapabilityInfos.put(CAPABILITY_CAN_CONTROL_MAGNIFICATION,
139 new CapabilityInfo(CAPABILITY_CAN_CONTROL_MAGNIFICATION,
140 R.string.capability_title_canControlMagnification,
141 R.string.capability_desc_canControlMagnification));
Phil Weavera6b64f52015-12-04 15:21:35 -0800142 sAvailableCapabilityInfos.put(CAPABILITY_CAN_PERFORM_GESTURES,
143 new CapabilityInfo(CAPABILITY_CAN_PERFORM_GESTURES,
144 R.string.capability_title_canPerformGestures,
145 R.string.capability_desc_canPerformGestures));
Svetoslav688a6972013-04-16 18:55:38 -0700146 }
147
148 /**
svetoslavganov75986cf2009-05-14 22:28:01 -0700149 * Denotes spoken feedback.
150 */
151 public static final int FEEDBACK_SPOKEN = 0x0000001;
152
153 /**
154 * Denotes haptic feedback.
155 */
156 public static final int FEEDBACK_HAPTIC = 0x0000002;
157
158 /**
159 * Denotes audible (not spoken) feedback.
160 */
161 public static final int FEEDBACK_AUDIBLE = 0x0000004;
162
163 /**
164 * Denotes visual feedback.
165 */
166 public static final int FEEDBACK_VISUAL = 0x0000008;
167
168 /**
169 * Denotes generic feedback.
170 */
171 public static final int FEEDBACK_GENERIC = 0x0000010;
172
173 /**
Svetoslav Ganoveb9862f2012-09-06 19:40:29 -0700174 * Denotes braille feedback.
175 */
176 public static final int FEEDBACK_BRAILLE = 0x0000020;
177
178 /**
Svetoslav Ganov00aabf72011-07-21 11:35:03 -0700179 * Mask for all feedback types.
180 *
181 * @see #FEEDBACK_SPOKEN
182 * @see #FEEDBACK_HAPTIC
183 * @see #FEEDBACK_AUDIBLE
184 * @see #FEEDBACK_VISUAL
185 * @see #FEEDBACK_GENERIC
Svetoslav Ganoveb9862f2012-09-06 19:40:29 -0700186 * @see #FEEDBACK_BRAILLE
Svetoslav Ganov00aabf72011-07-21 11:35:03 -0700187 */
188 public static final int FEEDBACK_ALL_MASK = 0xFFFFFFFF;
189
190 /**
svetoslavganov75986cf2009-05-14 22:28:01 -0700191 * If an {@link AccessibilityService} is the default for a given type.
192 * Default service is invoked only if no package specific one exists. In case of
193 * more than one package specific service only the earlier registered is notified.
194 */
195 public static final int DEFAULT = 0x0000001;
196
197 /**
Svetoslav Ganov42138042012-03-20 11:51:39 -0700198 * If this flag is set the system will regard views that are not important
199 * for accessibility in addition to the ones that are important for accessibility.
200 * That is, views that are marked as not important for accessibility via
Alan Viverette23be1992013-10-02 17:41:15 -0700201 * {@link View#IMPORTANT_FOR_ACCESSIBILITY_NO} or
202 * {@link View#IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS} and views that are
203 * marked as potentially important for accessibility via
Svetoslav Ganov42138042012-03-20 11:51:39 -0700204 * {@link View#IMPORTANT_FOR_ACCESSIBILITY_AUTO} for which the system has determined
Alan Viverette23be1992013-10-02 17:41:15 -0700205 * that are not important for accessibility, are reported while querying the window
206 * content and also the accessibility service will receive accessibility events from
207 * them.
Svetoslav Ganov42138042012-03-20 11:51:39 -0700208 * <p>
209 * <strong>Note:</strong> For accessibility services targeting API version
210 * {@link Build.VERSION_CODES#JELLY_BEAN} or higher this flag has to be explicitly
211 * set for the system to regard views that are not important for accessibility. For
212 * accessibility services targeting API version lower than
213 * {@link Build.VERSION_CODES#JELLY_BEAN} this flag is ignored and all views are
214 * regarded for accessibility purposes.
215 * </p>
216 * <p>
217 * Usually views not important for accessibility are layout managers that do not
218 * react to user actions, do not draw any content, and do not have any special
219 * semantics in the context of the screen content. For example, a three by three
220 * grid can be implemented as three horizontal linear layouts and one vertical,
221 * or three vertical linear layouts and one horizontal, or one grid layout, etc.
222 * In this context the actual layout mangers used to achieve the grid configuration
223 * are not important, rather it is important that there are nine evenly distributed
224 * elements.
225 * </p>
226 */
Svetoslav Ganov3ec2e1b2012-05-09 11:02:38 -0700227 public static final int FLAG_INCLUDE_NOT_IMPORTANT_VIEWS = 0x0000002;
228
229 /**
230 * This flag requests that the system gets into touch exploration mode.
231 * In this mode a single finger moving on the screen behaves as a mouse
232 * pointer hovering over the user interface. The system will also detect
233 * certain gestures performed on the touch screen and notify this service.
234 * The system will enable touch exploration mode if there is at least one
235 * accessibility service that has this flag set. Hence, clearing this
236 * flag does not guarantee that the device will not be in touch exploration
237 * mode since there may be another enabled service that requested it.
Svetoslav0ec04182013-01-31 16:54:40 -0800238 * <p>
Svetoslav Ganov447d9462013-02-01 19:46:20 +0000239 * For accessibility services targeting API version higher than
240 * {@link Build.VERSION_CODES#JELLY_BEAN_MR1} that want to set
Svetoslav688a6972013-04-16 18:55:38 -0700241 * this flag have to declare this capability in their meta-data by setting
242 * the attribute {@link android.R.attr#canRequestTouchExplorationMode
243 * canRequestTouchExplorationMode} to true, otherwise this flag will
244 * be ignored. For how to declare the meta-data of a service refer to
245 * {@value AccessibilityService#SERVICE_META_DATA}.
Svetoslav0ec04182013-01-31 16:54:40 -0800246 * </p>
Svetoslav Ganov447d9462013-02-01 19:46:20 +0000247 * <p>
248 * Services targeting API version equal to or lower than
249 * {@link Build.VERSION_CODES#JELLY_BEAN_MR1} will work normally, i.e.
250 * the first time they are run, if this flag is specified, a dialog is
251 * shown to the user to confirm enabling explore by touch.
252 * </p>
Scott Main00d17f72013-06-06 18:37:59 -0700253 * @see android.R.styleable#AccessibilityService_canRequestTouchExplorationMode
Svetoslav Ganov3ec2e1b2012-05-09 11:02:38 -0700254 */
Svetoslav0ec04182013-01-31 16:54:40 -0800255 public static final int FLAG_REQUEST_TOUCH_EXPLORATION_MODE = 0x0000004;
Svetoslav Ganov42138042012-03-20 11:51:39 -0700256
257 /**
Svetoslav38228962013-01-29 01:04:35 -0800258 * This flag requests from the system to enable web accessibility enhancing
259 * extensions. Such extensions aim to provide improved accessibility support
260 * for content presented in a {@link android.webkit.WebView}. An example of such
Svetoslav901309c2013-02-04 18:16:52 -0800261 * an extension is injecting JavaScript from a secure source. The system will enable
Svetoslav38228962013-01-29 01:04:35 -0800262 * enhanced web accessibility if there is at least one accessibility service
263 * that has this flag set. Hence, clearing this flag does not guarantee that the
264 * device will not have enhanced web accessibility enabled since there may be
265 * another enabled service that requested it.
Svetoslav0ec04182013-01-31 16:54:40 -0800266 * <p>
Svetoslav688a6972013-04-16 18:55:38 -0700267 * Services that want to set this flag have to declare this capability
268 * in their meta-data by setting the attribute {@link android.R.attr
269 * #canRequestEnhancedWebAccessibility canRequestEnhancedWebAccessibility} to
270 * true, otherwise this flag will be ignored. For how to declare the meta-data
271 * of a service refer to {@value AccessibilityService#SERVICE_META_DATA}.
Svetoslav0ec04182013-01-31 16:54:40 -0800272 * </p>
Scott Main00d17f72013-06-06 18:37:59 -0700273 * @see android.R.styleable#AccessibilityService_canRequestEnhancedWebAccessibility
Svetoslav38228962013-01-29 01:04:35 -0800274 */
275 public static final int FLAG_REQUEST_ENHANCED_WEB_ACCESSIBILITY = 0x00000008;
276
277 /**
Svetoslav Ganov80943d82013-01-02 10:25:37 -0800278 * This flag requests that the {@link AccessibilityNodeInfo}s obtained
279 * by an {@link AccessibilityService} contain the id of the source view.
280 * The source view id will be a fully qualified resource name of the
281 * form "package:id/name", for example "foo.bar:id/my_list", and it is
282 * useful for UI test automation. This flag is not set by default.
283 */
Svetoslav38228962013-01-29 01:04:35 -0800284 public static final int FLAG_REPORT_VIEW_IDS = 0x00000010;
Svetoslav Ganov80943d82013-01-02 10:25:37 -0800285
286 /**
Svetoslav688a6972013-04-16 18:55:38 -0700287 * This flag requests from the system to filter key events. If this flag
288 * is set the accessibility service will receive the key events before
Phil Weavera6b64f52015-12-04 15:21:35 -0800289 * applications allowing it implement global shortcuts.
Svetoslav688a6972013-04-16 18:55:38 -0700290 * <p>
291 * Services that want to set this flag have to declare this capability
292 * in their meta-data by setting the attribute {@link android.R.attr
293 * #canRequestFilterKeyEvents canRequestFilterKeyEvents} to true,
294 * otherwise this flag will be ignored. For how to declare the meta-data
295 * of a service refer to {@value AccessibilityService#SERVICE_META_DATA}.
296 * </p>
Scott Main00d17f72013-06-06 18:37:59 -0700297 * @see android.R.styleable#AccessibilityService_canRequestFilterKeyEvents
Svetoslav688a6972013-04-16 18:55:38 -0700298 */
299 public static final int FLAG_REQUEST_FILTER_KEY_EVENTS = 0x00000020;
300
301 /**
Svetoslav8e3feb12014-02-24 13:46:47 -0800302 * This flag indicates to the system that the accessibility service wants
303 * to access content of all interactive windows. An interactive window is a
Svetoslavf7174e82014-06-12 11:29:35 -0700304 * window that has input focus or can be touched by a sighted user when explore
305 * by touch is not enabled. If this flag is not set your service will not receive
Svetoslav8e3feb12014-02-24 13:46:47 -0800306 * {@link android.view.accessibility.AccessibilityEvent#TYPE_WINDOWS_CHANGED}
307 * events, calling AccessibilityService{@link AccessibilityService#getWindows()
308 * AccessibilityService.getWindows()} will return an empty list, and {@link
309 * AccessibilityNodeInfo#getWindow() AccessibilityNodeInfo.getWindow()} will
310 * return null.
311 * <p>
312 * Services that want to set this flag have to declare the capability
313 * to retrieve window content in their meta-data by setting the attribute
314 * {@link android.R.attr#canRetrieveWindowContent canRetrieveWindowContent} to
315 * true, otherwise this flag will be ignored. For how to declare the meta-data
316 * of a service refer to {@value AccessibilityService#SERVICE_META_DATA}.
317 * </p>
318 * @see android.R.styleable#AccessibilityService_canRetrieveWindowContent
319 */
320 public static final int FLAG_RETRIEVE_INTERACTIVE_WINDOWS = 0x00000040;
321
Jeff Sharkeyb5e89c62016-04-01 23:20:31 -0600322 /** {@hide} */
323 public static final int FLAG_FORCE_DIRECT_BOOT_AWARE = 0x00010000;
324
Svetoslav8e3feb12014-02-24 13:46:47 -0800325 /**
svetoslavganov75986cf2009-05-14 22:28:01 -0700326 * The event types an {@link AccessibilityService} is interested in.
Svetoslav Ganovcc4053e2011-05-23 13:37:44 -0700327 * <p>
328 * <strong>Can be dynamically set at runtime.</strong>
329 * </p>
svetoslavganov75986cf2009-05-14 22:28:01 -0700330 * @see android.view.accessibility.AccessibilityEvent#TYPE_VIEW_CLICKED
Svetoslav Ganov9b317792010-02-17 16:46:42 -0800331 * @see android.view.accessibility.AccessibilityEvent#TYPE_VIEW_LONG_CLICKED
svetoslavganov75986cf2009-05-14 22:28:01 -0700332 * @see android.view.accessibility.AccessibilityEvent#TYPE_VIEW_FOCUSED
333 * @see android.view.accessibility.AccessibilityEvent#TYPE_VIEW_SELECTED
334 * @see android.view.accessibility.AccessibilityEvent#TYPE_VIEW_TEXT_CHANGED
svetoslavganov75986cf2009-05-14 22:28:01 -0700335 * @see android.view.accessibility.AccessibilityEvent#TYPE_WINDOW_STATE_CHANGED
336 * @see android.view.accessibility.AccessibilityEvent#TYPE_NOTIFICATION_STATE_CHANGED
Svetoslav Ganov38e8b4e2011-06-29 20:00:53 -0700337 * @see android.view.accessibility.AccessibilityEvent#TYPE_TOUCH_EXPLORATION_GESTURE_START
338 * @see android.view.accessibility.AccessibilityEvent#TYPE_TOUCH_EXPLORATION_GESTURE_END
339 * @see android.view.accessibility.AccessibilityEvent#TYPE_VIEW_HOVER_ENTER
340 * @see android.view.accessibility.AccessibilityEvent#TYPE_VIEW_HOVER_EXIT
341 * @see android.view.accessibility.AccessibilityEvent#TYPE_VIEW_SCROLLED
342 * @see android.view.accessibility.AccessibilityEvent#TYPE_VIEW_TEXT_SELECTION_CHANGED
343 * @see android.view.accessibility.AccessibilityEvent#TYPE_WINDOW_CONTENT_CHANGED
Svetoslav8e3feb12014-02-24 13:46:47 -0800344 * @see android.view.accessibility.AccessibilityEvent#TYPE_TOUCH_INTERACTION_START
345 * @see android.view.accessibility.AccessibilityEvent#TYPE_TOUCH_INTERACTION_END
346 * @see android.view.accessibility.AccessibilityEvent#TYPE_ANNOUNCEMENT
347 * @see android.view.accessibility.AccessibilityEvent#TYPE_GESTURE_DETECTION_START
348 * @see android.view.accessibility.AccessibilityEvent#TYPE_GESTURE_DETECTION_END
349 * @see android.view.accessibility.AccessibilityEvent#TYPE_VIEW_ACCESSIBILITY_FOCUSED
350 * @see android.view.accessibility.AccessibilityEvent#TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED
351 * @see android.view.accessibility.AccessibilityEvent#TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
352 * @see android.view.accessibility.AccessibilityEvent#TYPE_WINDOWS_CHANGED
svetoslavganov75986cf2009-05-14 22:28:01 -0700353 */
354 public int eventTypes;
355
356 /**
357 * The package names an {@link AccessibilityService} is interested in. Setting
Svetoslav Ganov38e8b4e2011-06-29 20:00:53 -0700358 * to <code>null</code> is equivalent to all packages.
Svetoslav Ganovcc4053e2011-05-23 13:37:44 -0700359 * <p>
360 * <strong>Can be dynamically set at runtime.</strong>
361 * </p>
svetoslavganov75986cf2009-05-14 22:28:01 -0700362 */
363 public String[] packageNames;
364
365 /**
366 * The feedback type an {@link AccessibilityService} provides.
Svetoslav Ganovcc4053e2011-05-23 13:37:44 -0700367 * <p>
368 * <strong>Can be dynamically set at runtime.</strong>
369 * </p>
svetoslavganov75986cf2009-05-14 22:28:01 -0700370 * @see #FEEDBACK_AUDIBLE
371 * @see #FEEDBACK_GENERIC
372 * @see #FEEDBACK_HAPTIC
373 * @see #FEEDBACK_SPOKEN
374 * @see #FEEDBACK_VISUAL
Svetoslav Ganoveb9862f2012-09-06 19:40:29 -0700375 * @see #FEEDBACK_BRAILLE
svetoslavganov75986cf2009-05-14 22:28:01 -0700376 */
377 public int feedbackType;
378
379 /**
380 * The timeout after the most recent event of a given type before an
381 * {@link AccessibilityService} is notified.
382 * <p>
Svetoslav Ganovcc4053e2011-05-23 13:37:44 -0700383 * <strong>Can be dynamically set at runtime.</strong>.
384 * </p>
385 * <p>
Svetoslav Ganov38e8b4e2011-06-29 20:00:53 -0700386 * <strong>Note:</strong> The event notification timeout is useful to avoid propagating
387 * events to the client too frequently since this is accomplished via an expensive
388 * interprocess call. One can think of the timeout as a criteria to determine when
389 * event generation has settled down.
svetoslavganov75986cf2009-05-14 22:28:01 -0700390 */
391 public long notificationTimeout;
392
393 /**
394 * This field represents a set of flags used for configuring an
395 * {@link AccessibilityService}.
Svetoslav Ganovcc4053e2011-05-23 13:37:44 -0700396 * <p>
397 * <strong>Can be dynamically set at runtime.</strong>
398 * </p>
svetoslavganov75986cf2009-05-14 22:28:01 -0700399 * @see #DEFAULT
Svetoslav Ganov3ec2e1b2012-05-09 11:02:38 -0700400 * @see #FLAG_INCLUDE_NOT_IMPORTANT_VIEWS
401 * @see #FLAG_REQUEST_TOUCH_EXPLORATION_MODE
Svetoslav688a6972013-04-16 18:55:38 -0700402 * @see #FLAG_REQUEST_ENHANCED_WEB_ACCESSIBILITY
403 * @see #FLAG_REQUEST_FILTER_KEY_EVENTS
404 * @see #FLAG_REPORT_VIEW_IDS
Svetoslav8e3feb12014-02-24 13:46:47 -0800405 * @see #FLAG_RETRIEVE_INTERACTIVE_WINDOWS
svetoslavganov75986cf2009-05-14 22:28:01 -0700406 */
407 public int flags;
408
Svetoslav Ganovcc4053e2011-05-23 13:37:44 -0700409 /**
410 * The unique string Id to identify the accessibility service.
411 */
412 private String mId;
413
414 /**
415 * The Service that implements this accessibility service component.
416 */
417 private ResolveInfo mResolveInfo;
418
419 /**
420 * The accessibility service setting activity's name, used by the system
421 * settings to launch the setting activity of this accessibility service.
422 */
423 private String mSettingsActivityName;
424
425 /**
Svetoslav688a6972013-04-16 18:55:38 -0700426 * Bit mask with capabilities of this service.
Svetoslav Ganovcc4053e2011-05-23 13:37:44 -0700427 */
Svetoslav688a6972013-04-16 18:55:38 -0700428 private int mCapabilities;
Svetoslav Ganovcc4053e2011-05-23 13:37:44 -0700429
430 /**
Svetoslav Ganov3d0edd32012-01-03 16:38:46 -0800431 * Resource id of the description of the accessibility service.
Svetoslav Ganov35bfede2011-07-14 17:57:06 -0700432 */
Svetoslav Ganov3d0edd32012-01-03 16:38:46 -0800433 private int mDescriptionResId;
434
435 /**
436 * Non localized description of the accessibility service.
437 */
438 private String mNonLocalizedDescription;
Svetoslav Ganov35bfede2011-07-14 17:57:06 -0700439
440 /**
Svetoslav Ganovcc4053e2011-05-23 13:37:44 -0700441 * Creates a new instance.
442 */
443 public AccessibilityServiceInfo() {
444 /* do nothing */
445 }
446
447 /**
448 * Creates a new instance.
449 *
450 * @param resolveInfo The service resolve info.
451 * @param context Context for accessing resources.
452 * @throws XmlPullParserException If a XML parsing error occurs.
453 * @throws IOException If a XML parsing error occurs.
454 *
455 * @hide
456 */
457 public AccessibilityServiceInfo(ResolveInfo resolveInfo, Context context)
458 throws XmlPullParserException, IOException {
459 ServiceInfo serviceInfo = resolveInfo.serviceInfo;
460 mId = new ComponentName(serviceInfo.packageName, serviceInfo.name).flattenToShortString();
461 mResolveInfo = resolveInfo;
462
Svetoslav Ganovcc4053e2011-05-23 13:37:44 -0700463 XmlResourceParser parser = null;
464
465 try {
466 PackageManager packageManager = context.getPackageManager();
467 parser = serviceInfo.loadXmlMetaData(packageManager,
468 AccessibilityService.SERVICE_META_DATA);
469 if (parser == null) {
470 return;
471 }
472
473 int type = 0;
474 while (type != XmlPullParser.END_DOCUMENT && type != XmlPullParser.START_TAG) {
475 type = parser.next();
476 }
477
478 String nodeName = parser.getName();
479 if (!TAG_ACCESSIBILITY_SERVICE.equals(nodeName)) {
480 throw new XmlPullParserException( "Meta-data does not start with"
481 + TAG_ACCESSIBILITY_SERVICE + " tag");
482 }
483
484 AttributeSet allAttributes = Xml.asAttributeSet(parser);
485 Resources resources = packageManager.getResourcesForApplication(
486 serviceInfo.applicationInfo);
487 TypedArray asAttributes = resources.obtainAttributes(allAttributes,
488 com.android.internal.R.styleable.AccessibilityService);
489 eventTypes = asAttributes.getInt(
490 com.android.internal.R.styleable.AccessibilityService_accessibilityEventTypes,
491 0);
492 String packageNamez = asAttributes.getString(
493 com.android.internal.R.styleable.AccessibilityService_packageNames);
494 if (packageNamez != null) {
495 packageNames = packageNamez.split("(\\s)*,(\\s)*");
496 }
497 feedbackType = asAttributes.getInt(
498 com.android.internal.R.styleable.AccessibilityService_accessibilityFeedbackType,
499 0);
500 notificationTimeout = asAttributes.getInt(
Svetoslav8e3feb12014-02-24 13:46:47 -0800501 com.android.internal.R.styleable.AccessibilityService_notificationTimeout,
Svetoslav Ganovcc4053e2011-05-23 13:37:44 -0700502 0);
503 flags = asAttributes.getInt(
504 com.android.internal.R.styleable.AccessibilityService_accessibilityFlags, 0);
505 mSettingsActivityName = asAttributes.getString(
506 com.android.internal.R.styleable.AccessibilityService_settingsActivity);
Svetoslav688a6972013-04-16 18:55:38 -0700507 if (asAttributes.getBoolean(com.android.internal.R.styleable
508 .AccessibilityService_canRetrieveWindowContent, false)) {
509 mCapabilities |= CAPABILITY_CAN_RETRIEVE_WINDOW_CONTENT;
510 }
511 if (asAttributes.getBoolean(com.android.internal.R.styleable
512 .AccessibilityService_canRequestTouchExplorationMode, false)) {
513 mCapabilities |= CAPABILITY_CAN_REQUEST_TOUCH_EXPLORATION;
514 }
515 if (asAttributes.getBoolean(com.android.internal.R.styleable
Svetoslav11adf6d2013-04-24 14:51:29 -0700516 .AccessibilityService_canRequestEnhancedWebAccessibility, false)) {
517 mCapabilities |= CAPABILITY_CAN_REQUEST_ENHANCED_WEB_ACCESSIBILITY;
Svetoslav688a6972013-04-16 18:55:38 -0700518 }
519 if (asAttributes.getBoolean(com.android.internal.R.styleable
520 .AccessibilityService_canRequestFilterKeyEvents, false)) {
521 mCapabilities |= CAPABILITY_CAN_REQUEST_FILTER_KEY_EVENTS;
522 }
Alan Viverette214fb682015-11-17 09:47:11 -0500523 if (asAttributes.getBoolean(com.android.internal.R.styleable
524 .AccessibilityService_canControlMagnification, false)) {
525 mCapabilities |= CAPABILITY_CAN_CONTROL_MAGNIFICATION;
526 }
Phil Weavera6b64f52015-12-04 15:21:35 -0800527 if (asAttributes.getBoolean(com.android.internal.R.styleable
528 .AccessibilityService_canPerformGestures, false)) {
529 mCapabilities |= CAPABILITY_CAN_PERFORM_GESTURES;
530 }
Svetoslav Ganov3d0edd32012-01-03 16:38:46 -0800531 TypedValue peekedValue = asAttributes.peekValue(
Svetoslav Ganov35bfede2011-07-14 17:57:06 -0700532 com.android.internal.R.styleable.AccessibilityService_description);
Svetoslav Ganov3d0edd32012-01-03 16:38:46 -0800533 if (peekedValue != null) {
534 mDescriptionResId = peekedValue.resourceId;
535 CharSequence nonLocalizedDescription = peekedValue.coerceToString();
536 if (nonLocalizedDescription != null) {
537 mNonLocalizedDescription = nonLocalizedDescription.toString().trim();
538 }
539 }
Svetoslav Ganovcc4053e2011-05-23 13:37:44 -0700540 asAttributes.recycle();
541 } catch (NameNotFoundException e) {
542 throw new XmlPullParserException( "Unable to create context for: "
543 + serviceInfo.packageName);
544 } finally {
545 if (parser != null) {
546 parser.close();
547 }
548 }
549 }
550
551 /**
552 * Updates the properties that an AccessibilitySerivice can change dynamically.
553 *
554 * @param other The info from which to update the properties.
555 *
556 * @hide
557 */
558 public void updateDynamicallyConfigurableProperties(AccessibilityServiceInfo other) {
559 eventTypes = other.eventTypes;
560 packageNames = other.packageNames;
561 feedbackType = other.feedbackType;
562 notificationTimeout = other.notificationTimeout;
563 flags = other.flags;
564 }
565
566 /**
Svetoslav57bf8852013-02-07 19:21:42 -0800567 * @hide
568 */
569 public void setComponentName(ComponentName component) {
570 mId = component.flattenToShortString();
571 }
572
573 /**
Svetoslav Ganovcc4053e2011-05-23 13:37:44 -0700574 * The accessibility service id.
575 * <p>
576 * <strong>Generated by the system.</strong>
577 * </p>
578 * @return The id.
579 */
580 public String getId() {
581 return mId;
582 }
583
584 /**
585 * The service {@link ResolveInfo}.
586 * <p>
587 * <strong>Generated by the system.</strong>
588 * </p>
589 * @return The info.
590 */
591 public ResolveInfo getResolveInfo() {
592 return mResolveInfo;
593 }
594
595 /**
596 * The settings activity name.
597 * <p>
598 * <strong>Statically set from
599 * {@link AccessibilityService#SERVICE_META_DATA meta-data}.</strong>
600 * </p>
601 * @return The settings activity name.
602 */
603 public String getSettingsActivityName() {
604 return mSettingsActivityName;
605 }
606
607 /**
Svetoslav Ganov38e8b4e2011-06-29 20:00:53 -0700608 * Whether this service can retrieve the current window's content.
Svetoslav Ganovcc4053e2011-05-23 13:37:44 -0700609 * <p>
610 * <strong>Statically set from
611 * {@link AccessibilityService#SERVICE_META_DATA meta-data}.</strong>
612 * </p>
Svetoslav Ganovfefd20e2012-04-19 21:44:35 -0700613 * @return True if window content can be retrieved.
Svetoslav688a6972013-04-16 18:55:38 -0700614 *
615 * @deprecated Use {@link #getCapabilities()}.
Svetoslav Ganovcc4053e2011-05-23 13:37:44 -0700616 */
617 public boolean getCanRetrieveWindowContent() {
Svetoslav688a6972013-04-16 18:55:38 -0700618 return (mCapabilities & CAPABILITY_CAN_RETRIEVE_WINDOW_CONTENT) != 0;
619 }
620
621 /**
622 * Returns the bit mask of capabilities this accessibility service has such as
623 * being able to retrieve the active window content, etc.
624 *
625 * @return The capability bit mask.
626 *
627 * @see #CAPABILITY_CAN_RETRIEVE_WINDOW_CONTENT
628 * @see #CAPABILITY_CAN_REQUEST_TOUCH_EXPLORATION
629 * @see #CAPABILITY_CAN_REQUEST_ENHANCED_WEB_ACCESSIBILITY
630 * @see #CAPABILITY_FILTER_KEY_EVENTS
Phil Weavera6b64f52015-12-04 15:21:35 -0800631 * @see #CAPABILITY_CAN_CONTROL_MAGNIFICATION
632 * @see #CAPABILITY_CAN_PERFORM_GESTURES
Svetoslav688a6972013-04-16 18:55:38 -0700633 */
634 public int getCapabilities() {
635 return mCapabilities;
Svetoslav Ganovcc4053e2011-05-23 13:37:44 -0700636 }
637
638 /**
Svetoslav11adf6d2013-04-24 14:51:29 -0700639 * Sets the bit mask of capabilities this accessibility service has such as
640 * being able to retrieve the active window content, etc.
641 *
642 * @param capabilities The capability bit mask.
643 *
644 * @see #CAPABILITY_CAN_RETRIEVE_WINDOW_CONTENT
645 * @see #CAPABILITY_CAN_REQUEST_TOUCH_EXPLORATION
646 * @see #CAPABILITY_CAN_REQUEST_ENHANCED_WEB_ACCESSIBILITY
647 * @see #CAPABILITY_FILTER_KEY_EVENTS
Phil Weavera6b64f52015-12-04 15:21:35 -0800648 * @see #CAPABILITY_CAN_CONTROL_MAGNIFICATION
649 * @see #CAPABILITY_CAN_PERFORM_GESTURES
Svetoslav11adf6d2013-04-24 14:51:29 -0700650 *
651 * @hide
652 */
653 public void setCapabilities(int capabilities) {
654 mCapabilities = capabilities;
655 }
656
657 /**
Svetoslav Ganov3d0edd32012-01-03 16:38:46 -0800658 * Gets the non-localized description of the accessibility service.
Svetoslav Ganov35bfede2011-07-14 17:57:06 -0700659 * <p>
660 * <strong>Statically set from
661 * {@link AccessibilityService#SERVICE_META_DATA meta-data}.</strong>
662 * </p>
663 * @return The description.
Svetoslav Ganov3d0edd32012-01-03 16:38:46 -0800664 *
665 * @deprecated Use {@link #loadDescription(PackageManager)}.
Svetoslav Ganov35bfede2011-07-14 17:57:06 -0700666 */
667 public String getDescription() {
Svetoslav Ganov3d0edd32012-01-03 16:38:46 -0800668 return mNonLocalizedDescription;
669 }
670
671 /**
672 * The localized description of the accessibility service.
673 * <p>
674 * <strong>Statically set from
675 * {@link AccessibilityService#SERVICE_META_DATA meta-data}.</strong>
676 * </p>
677 * @return The localized description.
678 */
679 public String loadDescription(PackageManager packageManager) {
680 if (mDescriptionResId == 0) {
681 return mNonLocalizedDescription;
682 }
683 ServiceInfo serviceInfo = mResolveInfo.serviceInfo;
684 CharSequence description = packageManager.getText(serviceInfo.packageName,
685 mDescriptionResId, serviceInfo.applicationInfo);
686 if (description != null) {
687 return description.toString().trim();
688 }
689 return null;
Svetoslav Ganov35bfede2011-07-14 17:57:06 -0700690 }
691
Jeff Sharkeye88e2662016-02-23 17:52:16 -0700692 /** {@hide} */
Jeff Sharkeyb5e89c62016-04-01 23:20:31 -0600693 public boolean isDirectBootAware() {
694 return ((flags & FLAG_FORCE_DIRECT_BOOT_AWARE) != 0)
695 || mResolveInfo.serviceInfo.directBootAware;
Jeff Sharkeye88e2662016-02-23 17:52:16 -0700696 }
697
Svetoslav Ganov35bfede2011-07-14 17:57:06 -0700698 /**
Svetoslav Ganovcc4053e2011-05-23 13:37:44 -0700699 * {@inheritDoc}
700 */
svetoslavganov75986cf2009-05-14 22:28:01 -0700701 public int describeContents() {
702 return 0;
703 }
704
Svetoslav Ganov9b317792010-02-17 16:46:42 -0800705 public void writeToParcel(Parcel parcel, int flagz) {
svetoslavganov75986cf2009-05-14 22:28:01 -0700706 parcel.writeInt(eventTypes);
707 parcel.writeStringArray(packageNames);
708 parcel.writeInt(feedbackType);
709 parcel.writeLong(notificationTimeout);
710 parcel.writeInt(flags);
Svetoslav Ganovcc4053e2011-05-23 13:37:44 -0700711 parcel.writeString(mId);
712 parcel.writeParcelable(mResolveInfo, 0);
713 parcel.writeString(mSettingsActivityName);
Svetoslav688a6972013-04-16 18:55:38 -0700714 parcel.writeInt(mCapabilities);
Svetoslav Ganov3d0edd32012-01-03 16:38:46 -0800715 parcel.writeInt(mDescriptionResId);
716 parcel.writeString(mNonLocalizedDescription);
Svetoslav Ganovcc4053e2011-05-23 13:37:44 -0700717 }
718
719 private void initFromParcel(Parcel parcel) {
720 eventTypes = parcel.readInt();
721 packageNames = parcel.readStringArray();
722 feedbackType = parcel.readInt();
723 notificationTimeout = parcel.readLong();
724 flags = parcel.readInt();
725 mId = parcel.readString();
726 mResolveInfo = parcel.readParcelable(null);
727 mSettingsActivityName = parcel.readString();
Svetoslav688a6972013-04-16 18:55:38 -0700728 mCapabilities = parcel.readInt();
Svetoslav Ganov3d0edd32012-01-03 16:38:46 -0800729 mDescriptionResId = parcel.readInt();
730 mNonLocalizedDescription = parcel.readString();
Svetoslav Ganovcc4053e2011-05-23 13:37:44 -0700731 }
732
733 @Override
Svetoslav57bf8852013-02-07 19:21:42 -0800734 public int hashCode() {
735 return 31 * 1 + ((mId == null) ? 0 : mId.hashCode());
736 }
737
738 @Override
739 public boolean equals(Object obj) {
740 if (this == obj) {
741 return true;
742 }
743 if (obj == null) {
744 return false;
745 }
746 if (getClass() != obj.getClass()) {
747 return false;
748 }
749 AccessibilityServiceInfo other = (AccessibilityServiceInfo) obj;
750 if (mId == null) {
751 if (other.mId != null) {
752 return false;
753 }
754 } else if (!mId.equals(other.mId)) {
755 return false;
756 }
757 return true;
758 }
759
760 @Override
Svetoslav Ganovcc4053e2011-05-23 13:37:44 -0700761 public String toString() {
762 StringBuilder stringBuilder = new StringBuilder();
763 appendEventTypes(stringBuilder, eventTypes);
764 stringBuilder.append(", ");
765 appendPackageNames(stringBuilder, packageNames);
766 stringBuilder.append(", ");
767 appendFeedbackTypes(stringBuilder, feedbackType);
768 stringBuilder.append(", ");
769 stringBuilder.append("notificationTimeout: ").append(notificationTimeout);
770 stringBuilder.append(", ");
771 appendFlags(stringBuilder, flags);
772 stringBuilder.append(", ");
773 stringBuilder.append("id: ").append(mId);
774 stringBuilder.append(", ");
775 stringBuilder.append("resolveInfo: ").append(mResolveInfo);
776 stringBuilder.append(", ");
777 stringBuilder.append("settingsActivityName: ").append(mSettingsActivityName);
778 stringBuilder.append(", ");
Svetoslav688a6972013-04-16 18:55:38 -0700779 appendCapabilities(stringBuilder, mCapabilities);
Svetoslav Ganovcc4053e2011-05-23 13:37:44 -0700780 return stringBuilder.toString();
781 }
782
783 private static void appendFeedbackTypes(StringBuilder stringBuilder, int feedbackTypes) {
784 stringBuilder.append("feedbackTypes:");
785 stringBuilder.append("[");
786 while (feedbackTypes != 0) {
787 final int feedbackTypeBit = (1 << Integer.numberOfTrailingZeros(feedbackTypes));
788 stringBuilder.append(feedbackTypeToString(feedbackTypeBit));
789 feedbackTypes &= ~feedbackTypeBit;
790 if (feedbackTypes != 0) {
791 stringBuilder.append(", ");
792 }
793 }
794 stringBuilder.append("]");
795 }
796
797 private static void appendPackageNames(StringBuilder stringBuilder, String[] packageNames) {
798 stringBuilder.append("packageNames:");
799 stringBuilder.append("[");
800 if (packageNames != null) {
801 final int packageNameCount = packageNames.length;
802 for (int i = 0; i < packageNameCount; i++) {
803 stringBuilder.append(packageNames[i]);
804 if (i < packageNameCount - 1) {
805 stringBuilder.append(", ");
806 }
807 }
808 }
809 stringBuilder.append("]");
810 }
811
812 private static void appendEventTypes(StringBuilder stringBuilder, int eventTypes) {
813 stringBuilder.append("eventTypes:");
814 stringBuilder.append("[");
815 while (eventTypes != 0) {
816 final int eventTypeBit = (1 << Integer.numberOfTrailingZeros(eventTypes));
817 stringBuilder.append(AccessibilityEvent.eventTypeToString(eventTypeBit));
818 eventTypes &= ~eventTypeBit;
819 if (eventTypes != 0) {
820 stringBuilder.append(", ");
821 }
822 }
823 stringBuilder.append("]");
824 }
825
826 private static void appendFlags(StringBuilder stringBuilder, int flags) {
827 stringBuilder.append("flags:");
828 stringBuilder.append("[");
829 while (flags != 0) {
830 final int flagBit = (1 << Integer.numberOfTrailingZeros(flags));
831 stringBuilder.append(flagToString(flagBit));
832 flags &= ~flagBit;
833 if (flags != 0) {
834 stringBuilder.append(", ");
835 }
836 }
837 stringBuilder.append("]");
838 }
839
Svetoslav688a6972013-04-16 18:55:38 -0700840 private static void appendCapabilities(StringBuilder stringBuilder, int capabilities) {
841 stringBuilder.append("capabilities:");
842 stringBuilder.append("[");
843 while (capabilities != 0) {
844 final int capabilityBit = (1 << Integer.numberOfTrailingZeros(capabilities));
845 stringBuilder.append(capabilityToString(capabilityBit));
846 capabilities &= ~capabilityBit;
847 if (capabilities != 0) {
848 stringBuilder.append(", ");
849 }
850 }
851 stringBuilder.append("]");
852 }
853
Svetoslav Ganovcc4053e2011-05-23 13:37:44 -0700854 /**
855 * Returns the string representation of a feedback type. For example,
856 * {@link #FEEDBACK_SPOKEN} is represented by the string FEEDBACK_SPOKEN.
857 *
858 * @param feedbackType The feedback type.
859 * @return The string representation.
860 */
861 public static String feedbackTypeToString(int feedbackType) {
Svetoslav Ganovbb1b9ea2011-10-19 17:10:14 -0700862 StringBuilder builder = new StringBuilder();
863 builder.append("[");
Svetoslav Ganovc6c25f92012-03-09 16:01:18 -0800864 while (feedbackType != 0) {
Svetoslav Ganovbb1b9ea2011-10-19 17:10:14 -0700865 final int feedbackTypeFlag = 1 << Integer.numberOfTrailingZeros(feedbackType);
866 feedbackType &= ~feedbackTypeFlag;
Svetoslav Ganovbb1b9ea2011-10-19 17:10:14 -0700867 switch (feedbackTypeFlag) {
868 case FEEDBACK_AUDIBLE:
Svetoslav Ganovc6c25f92012-03-09 16:01:18 -0800869 if (builder.length() > 1) {
870 builder.append(", ");
871 }
Svetoslav Ganovbb1b9ea2011-10-19 17:10:14 -0700872 builder.append("FEEDBACK_AUDIBLE");
873 break;
874 case FEEDBACK_HAPTIC:
Svetoslav Ganovc6c25f92012-03-09 16:01:18 -0800875 if (builder.length() > 1) {
876 builder.append(", ");
877 }
Svetoslav Ganovbb1b9ea2011-10-19 17:10:14 -0700878 builder.append("FEEDBACK_HAPTIC");
879 break;
880 case FEEDBACK_GENERIC:
Svetoslav Ganovc6c25f92012-03-09 16:01:18 -0800881 if (builder.length() > 1) {
882 builder.append(", ");
883 }
Svetoslav Ganovbb1b9ea2011-10-19 17:10:14 -0700884 builder.append("FEEDBACK_GENERIC");
885 break;
886 case FEEDBACK_SPOKEN:
Svetoslav Ganovc6c25f92012-03-09 16:01:18 -0800887 if (builder.length() > 1) {
888 builder.append(", ");
889 }
Svetoslav Ganovbb1b9ea2011-10-19 17:10:14 -0700890 builder.append("FEEDBACK_SPOKEN");
891 break;
892 case FEEDBACK_VISUAL:
Svetoslav Ganovc6c25f92012-03-09 16:01:18 -0800893 if (builder.length() > 1) {
894 builder.append(", ");
895 }
Svetoslav Ganovbb1b9ea2011-10-19 17:10:14 -0700896 builder.append("FEEDBACK_VISUAL");
897 break;
Svetoslav Ganoveb9862f2012-09-06 19:40:29 -0700898 case FEEDBACK_BRAILLE:
899 if (builder.length() > 1) {
900 builder.append(", ");
901 }
902 builder.append("FEEDBACK_BRAILLE");
903 break;
Svetoslav Ganovbb1b9ea2011-10-19 17:10:14 -0700904 }
Svetoslav Ganovcc4053e2011-05-23 13:37:44 -0700905 }
Svetoslav Ganovbb1b9ea2011-10-19 17:10:14 -0700906 builder.append("]");
907 return builder.toString();
Svetoslav Ganovcc4053e2011-05-23 13:37:44 -0700908 }
909
910 /**
911 * Returns the string representation of a flag. For example,
912 * {@link #DEFAULT} is represented by the string DEFAULT.
913 *
914 * @param flag The flag.
915 * @return The string representation.
916 */
917 public static String flagToString(int flag) {
918 switch (flag) {
919 case DEFAULT:
920 return "DEFAULT";
Svetoslav Ganov3ec2e1b2012-05-09 11:02:38 -0700921 case FLAG_INCLUDE_NOT_IMPORTANT_VIEWS:
922 return "FLAG_INCLUDE_NOT_IMPORTANT_VIEWS";
923 case FLAG_REQUEST_TOUCH_EXPLORATION_MODE:
924 return "FLAG_REQUEST_TOUCH_EXPLORATION_MODE";
Svetoslav688a6972013-04-16 18:55:38 -0700925 case FLAG_REQUEST_ENHANCED_WEB_ACCESSIBILITY:
926 return "FLAG_REQUEST_ENHANCED_WEB_ACCESSIBILITY";
927 case FLAG_REPORT_VIEW_IDS:
928 return "FLAG_REPORT_VIEW_IDS";
929 case FLAG_REQUEST_FILTER_KEY_EVENTS:
930 return "FLAG_REQUEST_FILTER_KEY_EVENTS";
Svetoslav8e3feb12014-02-24 13:46:47 -0800931 case FLAG_RETRIEVE_INTERACTIVE_WINDOWS:
932 return "FLAG_RETRIEVE_INTERACTIVE_WINDOWS";
Svetoslav Ganovcc4053e2011-05-23 13:37:44 -0700933 default:
934 return null;
935 }
svetoslavganov75986cf2009-05-14 22:28:01 -0700936 }
937
938 /**
Svetoslav688a6972013-04-16 18:55:38 -0700939 * Returns the string representation of a capability. For example,
940 * {@link #CAPABILITY_CAN_RETRIEVE_WINDOW_CONTENT} is represented
941 * by the string CAPABILITY_CAN_RETRIEVE_WINDOW_CONTENT.
942 *
943 * @param capability The capability.
944 * @return The string representation.
945 */
946 public static String capabilityToString(int capability) {
947 switch (capability) {
948 case CAPABILITY_CAN_RETRIEVE_WINDOW_CONTENT:
949 return "CAPABILITY_CAN_RETRIEVE_WINDOW_CONTENT";
950 case CAPABILITY_CAN_REQUEST_TOUCH_EXPLORATION:
951 return "CAPABILITY_CAN_REQUEST_TOUCH_EXPLORATION";
952 case CAPABILITY_CAN_REQUEST_ENHANCED_WEB_ACCESSIBILITY:
953 return "CAPABILITY_CAN_REQUEST_ENHANCED_WEB_ACCESSIBILITY";
954 case CAPABILITY_CAN_REQUEST_FILTER_KEY_EVENTS:
955 return "CAPABILITY_CAN_FILTER_KEY_EVENTS";
Alan Viverette214fb682015-11-17 09:47:11 -0500956 case CAPABILITY_CAN_CONTROL_MAGNIFICATION:
957 return "CAPABILITY_CAN_CONTROL_MAGNIFICATION";
Phil Weavera6b64f52015-12-04 15:21:35 -0800958 case CAPABILITY_CAN_PERFORM_GESTURES:
959 return "CAPABILITY_CAN_PERFORM_GESTURES";
Svetoslav688a6972013-04-16 18:55:38 -0700960 default:
961 return "UNKNOWN";
962 }
963 }
964
965 /**
966 * @hide
967 * @return The list of {@link CapabilityInfo} objects.
968 */
969 public List<CapabilityInfo> getCapabilityInfos() {
970 if (mCapabilities == 0) {
971 return Collections.emptyList();
972 }
973 int capabilities = mCapabilities;
974 List<CapabilityInfo> capabilityInfos = new ArrayList<CapabilityInfo>();
975 while (capabilities != 0) {
976 final int capabilityBit = 1 << Integer.numberOfTrailingZeros(capabilities);
977 capabilities &= ~capabilityBit;
978 CapabilityInfo capabilityInfo = sAvailableCapabilityInfos.get(capabilityBit);
979 if (capabilityInfo != null) {
980 capabilityInfos.add(capabilityInfo);
981 }
982 }
983 return capabilityInfos;
984 }
985
986 /**
987 * @hide
988 */
989 public static final class CapabilityInfo {
990 public final int capability;
991 public final int titleResId;
992 public final int descResId;
993
994 public CapabilityInfo(int capability, int titleResId, int descResId) {
995 this.capability = capability;
996 this.titleResId = titleResId;
997 this.descResId = descResId;
998 }
999 }
1000
1001 /**
svetoslavganov75986cf2009-05-14 22:28:01 -07001002 * @see Parcelable.Creator
1003 */
1004 public static final Parcelable.Creator<AccessibilityServiceInfo> CREATOR =
1005 new Parcelable.Creator<AccessibilityServiceInfo>() {
1006 public AccessibilityServiceInfo createFromParcel(Parcel parcel) {
1007 AccessibilityServiceInfo info = new AccessibilityServiceInfo();
Svetoslav Ganovcc4053e2011-05-23 13:37:44 -07001008 info.initFromParcel(parcel);
svetoslavganov75986cf2009-05-14 22:28:01 -07001009 return info;
1010 }
1011
1012 public AccessibilityServiceInfo[] newArray(int size) {
1013 return new AccessibilityServiceInfo[size];
1014 }
1015 };
1016}