AccessibilityServiceInfo.java revision 27fcd9c97a2ceb50bab026237390207e5ee9e290
143b5b06c8be24e465bd6a7b22a8d341db1ad50a2Kevin Schoedel/*
289af70bce420f011adfeb0f80984b3895c4d7d9bKevin Schoedel * Copyright (C) 2009 The Android Open Source Project
389af70bce420f011adfeb0f80984b3895c4d7d9bKevin Schoedel *
4e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko * Licensed under the Apache License, Version 2.0 (the "License");
5e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko * you may not use this file except in compliance with the License.
6e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko * You may obtain a copy of the License at
7e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko *
8e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko *      http://www.apache.org/licenses/LICENSE-2.0
989af70bce420f011adfeb0f80984b3895c4d7d9bKevin Schoedel *
10e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko * Unless required by applicable law or agreed to in writing, software
11e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko * distributed under the License is distributed on an "AS IS" BASIS,
12e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko * See the License for the specific language governing permissions and
14e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko * limitations under the License.
15e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko */
16e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
17e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkopackage android.accessibilityservice;
183002b8a74431dd7c005269cf9306443a4b4963f1Kevin Schoedel
19e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoimport android.content.ComponentName;
20e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoimport android.content.Context;
21e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoimport android.content.pm.PackageManager;
22e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoimport android.content.pm.PackageManager.NameNotFoundException;
23e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoimport android.content.pm.ResolveInfo;
24e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoimport android.content.pm.ServiceInfo;
2589af70bce420f011adfeb0f80984b3895c4d7d9bKevin Schoedelimport android.content.res.Resources;
26e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoimport android.content.res.TypedArray;
27e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoimport android.content.res.XmlResourceParser;
28e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoimport android.hardware.fingerprint.FingerprintManager;
29e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoimport android.os.Build;
30e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoimport android.os.Parcel;
31e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoimport android.os.Parcelable;
32e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoimport android.util.AttributeSet;
33e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoimport android.util.SparseArray;
343002b8a74431dd7c005269cf9306443a4b4963f1Kevin Schoedelimport android.util.TypedValue;
35e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoimport android.util.Xml;
36e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoimport android.view.View;
37e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoimport android.view.accessibility.AccessibilityEvent;
38e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoimport android.view.accessibility.AccessibilityNodeInfo;
39e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
40e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoimport com.android.internal.R;
41e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
42e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoimport org.xmlpull.v1.XmlPullParser;
43e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoimport org.xmlpull.v1.XmlPullParserException;
44e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
45e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoimport java.io.IOException;
46e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoimport java.util.ArrayList;
47e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoimport java.util.Collections;
48e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoimport java.util.List;
49e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
50e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko/**
51e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko * This class describes an {@link AccessibilityService}. The system notifies an
52e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko * {@link AccessibilityService} for {@link android.view.accessibility.AccessibilityEvent}s
53e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko * according to the information encapsulated in this class.
54e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko *
55e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko * <div class="special reference">
56e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko * <h3>Developer Guides</h3>
57e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko * <p>For more information about creating AccessibilityServices, read the
58e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko * <a href="{@docRoot}guide/topics/ui/accessibility/index.html">Accessibility</a>
59e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko * developer guide.</p>
60e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko * </div>
61e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko *
62e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko * @attr ref android.R.styleable#AccessibilityService_accessibilityEventTypes
63e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko * @attr ref android.R.styleable#AccessibilityService_accessibilityFeedbackType
64e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko * @attr ref android.R.styleable#AccessibilityService_accessibilityFlags
65e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko * @attr ref android.R.styleable#AccessibilityService_canRequestEnhancedWebAccessibility
66e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko * @attr ref android.R.styleable#AccessibilityService_canRequestFilterKeyEvents
67e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko * @attr ref android.R.styleable#AccessibilityService_canRequestTouchExplorationMode
68e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko * @attr ref android.R.styleable#AccessibilityService_canRetrieveWindowContent
69e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko * @attr ref android.R.styleable#AccessibilityService_description
70e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko * @attr ref android.R.styleable#AccessibilityService_notificationTimeout
71e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko * @attr ref android.R.styleable#AccessibilityService_packageNames
72e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko * @attr ref android.R.styleable#AccessibilityService_settingsActivity
73e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko *
74e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko * @see AccessibilityService
75e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko * @see android.view.accessibility.AccessibilityEvent
76e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko * @see android.view.accessibility.AccessibilityManager
77e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko */
78e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkopublic class AccessibilityServiceInfo implements Parcelable {
79e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
80e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    private static final String TAG_ACCESSIBILITY_SERVICE = "accessibility-service";
81e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
82e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    /**
83e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko     * Capability: This accessibility service can retrieve the active window content.
84e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko     * @see android.R.styleable#AccessibilityService_canRetrieveWindowContent
85e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko     */
86e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    public static final int CAPABILITY_CAN_RETRIEVE_WINDOW_CONTENT = 0x00000001;
87e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
88e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    /**
89e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko     * Capability: This accessibility service can request touch exploration mode in which
90e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko     * touched items are spoken aloud and the UI can be explored via gestures.
910108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel     * @see android.R.styleable#AccessibilityService_canRequestTouchExplorationMode
92e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko     */
930108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel    public static final int CAPABILITY_CAN_REQUEST_TOUCH_EXPLORATION = 0x00000002;
94e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
95e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    /**
9689af70bce420f011adfeb0f80984b3895c4d7d9bKevin Schoedel     * Capability: This accessibility service can request enhanced web accessibility
97e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko     * enhancements. For example, installing scripts to make app content more accessible.
98de1cdaebc9b8fdbc5348e6c07f849b74bacc485dKevin Schoedel     * @see android.R.styleable#AccessibilityService_canRequestEnhancedWebAccessibility
99de1cdaebc9b8fdbc5348e6c07f849b74bacc485dKevin Schoedel     */
100de1cdaebc9b8fdbc5348e6c07f849b74bacc485dKevin Schoedel    public static final int CAPABILITY_CAN_REQUEST_ENHANCED_WEB_ACCESSIBILITY = 0x00000004;
1010108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel
10289af70bce420f011adfeb0f80984b3895c4d7d9bKevin Schoedel    /**
1030108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel     * Capability: This accessibility service can request to filter the key event stream.
1040108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel     * @see android.R.styleable#AccessibilityService_canRequestFilterKeyEvents
1050108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel     */
1060108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel    public static final int CAPABILITY_CAN_REQUEST_FILTER_KEY_EVENTS = 0x00000008;
1070108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel
108e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    /**
1090108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel     * Capability: This accessibility service can control display magnification.
1100108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel     * @see android.R.styleable#AccessibilityService_canControlMagnification
111e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko     */
112e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    public static final int CAPABILITY_CAN_CONTROL_MAGNIFICATION = 0x00000010;
113e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
114e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    /**
115e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko     * Capability: This accessibility service can perform gestures.
116e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko     * @see android.R.styleable#AccessibilityService_canPerformGestures
117e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko     */
118e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    public static final int CAPABILITY_CAN_PERFORM_GESTURES = 0x00000020;
119e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
120e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    /**
121e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko     * Capability: This accessibility service can capture gestures from the fingerprint sensor
122e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko     * @see android.R.styleable#AccessibilityService_canCaptureFingerprintGestures
123e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko     */
124e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    public static final int CAPABILITY_CAN_CAPTURE_FINGERPRINT_GESTURES = 0x00000040;
125e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
12689af70bce420f011adfeb0f80984b3895c4d7d9bKevin Schoedel    private static SparseArray<CapabilityInfo> sAvailableCapabilityInfos;
127e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
128e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    /**
129de1cdaebc9b8fdbc5348e6c07f849b74bacc485dKevin Schoedel     * Denotes spoken feedback.
130de1cdaebc9b8fdbc5348e6c07f849b74bacc485dKevin Schoedel     */
131e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    public static final int FEEDBACK_SPOKEN = 0x0000001;
132e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
1334b64dd48b6896d6b963f0a3a0259d3d2a7076a9eKevin Schoedel    /**
1344b64dd48b6896d6b963f0a3a0259d3d2a7076a9eKevin Schoedel     * Denotes haptic feedback.
1354b64dd48b6896d6b963f0a3a0259d3d2a7076a9eKevin Schoedel     */
136e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    public static final int FEEDBACK_HAPTIC =  0x0000002;
1370108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel
1380108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel    /**
1390108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel     * Denotes audible (not spoken) feedback.
1400108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel     */
1410108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel    public static final int FEEDBACK_AUDIBLE = 0x0000004;
14206936feb07bf6fbef262e4adebeb8e53910d8cf4Santos Cordon
1430108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel    /**
1440108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel     * Denotes visual feedback.
1450108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel     */
1460108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel    public static final int FEEDBACK_VISUAL = 0x0000008;
1470108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel
1480108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel    /**
1490108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel     * Denotes generic feedback.
1500108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel     */
1510108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel    public static final int FEEDBACK_GENERIC = 0x0000010;
152e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
153e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    /**
154e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko     * Denotes braille feedback.
155e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko     */
156e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    public static final int FEEDBACK_BRAILLE = 0x0000020;
157e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko
1580108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel    /**
1590108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel     * Mask for all feedback types.
1600108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel     *
1610108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel     * @see #FEEDBACK_SPOKEN
1620108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel     * @see #FEEDBACK_HAPTIC
1630108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel     * @see #FEEDBACK_AUDIBLE
1640108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel     * @see #FEEDBACK_VISUAL
1650108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel     * @see #FEEDBACK_GENERIC
1660108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel     * @see #FEEDBACK_BRAILLE
1670108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel     */
1680108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel    public static final int FEEDBACK_ALL_MASK = 0xFFFFFFFF;
1690108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel
1700108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel    /**
1710108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel     * If an {@link AccessibilityService} is the default for a given type.
1720108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel     * Default service is invoked only if no package specific one exists. In case of
1730108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel     * more than one package specific service only the earlier registered is notified.
1740108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel     */
1750108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel    public static final int DEFAULT = 0x0000001;
1760108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel
1770108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel    /**
1780108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel     * If this flag is set the system will regard views that are not important
1790108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel     * for accessibility in addition to the ones that are important for accessibility.
1800108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel     * That is, views that are marked as not important for accessibility via
181e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko     * {@link View#IMPORTANT_FOR_ACCESSIBILITY_NO} or
182e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko     * {@link View#IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS} and views that are
183e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko     * marked as potentially important for accessibility via
184e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko     * {@link View#IMPORTANT_FOR_ACCESSIBILITY_AUTO} for which the system has determined
185e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko     * that are not important for accessibility, are reported while querying the window
186e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko     * content and also the accessibility service will receive accessibility events from
187e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko     * them.
1880108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel     * <p>
1890108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel     * <strong>Note:</strong> For accessibility services targeting API version
1900108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel     * {@link Build.VERSION_CODES#JELLY_BEAN} or higher this flag has to be explicitly
1910108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel     * set for the system to regard views that are not important for accessibility. For
1920108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel     * accessibility services targeting API version lower than
1930108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel     * {@link Build.VERSION_CODES#JELLY_BEAN} this flag is ignored and all views are
1940108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel     * regarded for accessibility purposes.
195e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko     * </p>
196e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko     * <p>
197e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko     * Usually views not important for accessibility are layout managers that do not
198e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko     * react to user actions, do not draw any content, and do not have any special
199e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko     * semantics in the context of the screen content. For example, a three by three
200e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko     * grid can be implemented as three horizontal linear layouts and one vertical,
201e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko     * or three vertical linear layouts and one horizontal, or one grid layout, etc.
2020108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel     * In this context the actual layout mangers used to achieve the grid configuration
2030108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel     * are not important, rather it is important that there are nine evenly distributed
2040108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel     * elements.
2050108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel     * </p>
2060108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel     */
2070108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel    public static final int FLAG_INCLUDE_NOT_IMPORTANT_VIEWS = 0x0000002;
2080108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel
209e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    /**
210e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko     * This flag requests that the system gets into touch exploration mode.
211e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko     * In this mode a single finger moving on the screen behaves as a mouse
2124b64dd48b6896d6b963f0a3a0259d3d2a7076a9eKevin Schoedel     * pointer hovering over the user interface. The system will also detect
2134b64dd48b6896d6b963f0a3a0259d3d2a7076a9eKevin Schoedel     * certain gestures performed on the touch screen and notify this service.
214e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko     * The system will enable touch exploration mode if there is at least one
2150108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel     * accessibility service that has this flag set. Hence, clearing this
2160108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel     * flag does not guarantee that the device will not be in touch exploration
2170108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel     * mode since there may be another enabled service that requested it.
2180108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel     * <p>
2190108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel     * For accessibility services targeting API version higher than
2200108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel     * {@link Build.VERSION_CODES#JELLY_BEAN_MR1} that want to set
2210108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel     * this flag have to declare this capability in their meta-data by setting
222e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko     * the attribute {@link android.R.attr#canRequestTouchExplorationMode
223e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko     * canRequestTouchExplorationMode} to true, otherwise this flag will
2240108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel     * be ignored. For how to declare the meta-data of a service refer to
2250108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel     * {@value AccessibilityService#SERVICE_META_DATA}.
2260108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel     * </p>
2270108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel     * <p>
2280108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel     * Services targeting API version equal to or lower than
2290108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel     * {@link Build.VERSION_CODES#JELLY_BEAN_MR1} will work normally, i.e.
2300108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel     * the first time they are run, if this flag is specified, a dialog is
2314b64dd48b6896d6b963f0a3a0259d3d2a7076a9eKevin Schoedel     * shown to the user to confirm enabling explore by touch.
2324b64dd48b6896d6b963f0a3a0259d3d2a7076a9eKevin Schoedel     * </p>
233e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko     * @see android.R.styleable#AccessibilityService_canRequestTouchExplorationMode
234e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko     */
235e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko    public static final int FLAG_REQUEST_TOUCH_EXPLORATION_MODE = 0x0000004;
2360108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel
2370108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel    /**
2380108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel     * This flag requests from the system to enable web accessibility enhancing
2390108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel     * extensions. Such extensions aim to provide improved accessibility support
2400108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel     * for content presented in a {@link android.webkit.WebView}. An example of such
2410108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel     * an extension is injecting JavaScript from a secure source. The system will enable
2420108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel     * enhanced web accessibility if there is at least one accessibility service
243e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko     * that has this flag set. Hence, clearing this flag does not guarantee that the
244e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko     * device will not have enhanced web accessibility enabled since there may be
24543b5b06c8be24e465bd6a7b22a8d341db1ad50a2Kevin Schoedel     * another enabled service that requested it.
24643b5b06c8be24e465bd6a7b22a8d341db1ad50a2Kevin Schoedel     * <p>
2470108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel     * Services that want to set this flag have to declare this capability
2480108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel     * in their meta-data by setting the attribute {@link android.R.attr
2490108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel     * #canRequestEnhancedWebAccessibility canRequestEnhancedWebAccessibility} to
2500108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel     * true, otherwise this flag will be ignored. For how to declare the meta-data
2510108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel     * of a service refer to {@value AccessibilityService#SERVICE_META_DATA}.
2520108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel     * </p>
2530108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel     * @see android.R.styleable#AccessibilityService_canRequestEnhancedWebAccessibility
25443b5b06c8be24e465bd6a7b22a8d341db1ad50a2Kevin Schoedel     */
25543b5b06c8be24e465bd6a7b22a8d341db1ad50a2Kevin Schoedel    public static final int FLAG_REQUEST_ENHANCED_WEB_ACCESSIBILITY = 0x00000008;
2560108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel
2570108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel    /**
2580108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel     * This flag requests that the {@link AccessibilityNodeInfo}s obtained
2590108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel     * by an {@link AccessibilityService} contain the id of the source view.
2600108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel     * The source view id will be a fully qualified resource name of the
2610108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel     * form "package:id/name", for example "foo.bar:id/my_list", and it is
2620108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel     * useful for UI test automation. This flag is not set by default.
26343b5b06c8be24e465bd6a7b22a8d341db1ad50a2Kevin Schoedel     */
26443b5b06c8be24e465bd6a7b22a8d341db1ad50a2Kevin Schoedel    public static final int FLAG_REPORT_VIEW_IDS = 0x00000010;
26543b5b06c8be24e465bd6a7b22a8d341db1ad50a2Kevin Schoedel
26643b5b06c8be24e465bd6a7b22a8d341db1ad50a2Kevin Schoedel    /**
2670108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel     * This flag requests from the system to filter key events. If this flag
2680108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel     * is set the accessibility service will receive the key events before
2690108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel     * applications allowing it implement global shortcuts.
2700108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel     * <p>
2710108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel     * Services that want to set this flag have to declare this capability
2720108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel     * in their meta-data by setting the attribute {@link android.R.attr
2730108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel     * #canRequestFilterKeyEvents canRequestFilterKeyEvents} to true,
27443b5b06c8be24e465bd6a7b22a8d341db1ad50a2Kevin Schoedel     * otherwise this flag will be ignored. For how to declare the meta-data
27543b5b06c8be24e465bd6a7b22a8d341db1ad50a2Kevin Schoedel     * of a service refer to {@value AccessibilityService#SERVICE_META_DATA}.
2760108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel     * </p>
2770108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel     * @see android.R.styleable#AccessibilityService_canRequestFilterKeyEvents
2780108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel     */
2790108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel    public static final int FLAG_REQUEST_FILTER_KEY_EVENTS = 0x00000020;
2800108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel
2814b64dd48b6896d6b963f0a3a0259d3d2a7076a9eKevin Schoedel    /**
2824b64dd48b6896d6b963f0a3a0259d3d2a7076a9eKevin Schoedel     * This flag indicates to the system that the accessibility service wants
2830108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel     * to access content of all interactive windows. An interactive window is a
2840108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel     * window that has input focus or can be touched by a sighted user when explore
2850108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel     * by touch is not enabled. If this flag is not set your service will not receive
2860108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel     * {@link android.view.accessibility.AccessibilityEvent#TYPE_WINDOWS_CHANGED}
287e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko     * events, calling AccessibilityService{@link AccessibilityService#getWindows()
288e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko     * AccessibilityService.getWindows()} will return an empty list, and {@link
289e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko     * AccessibilityNodeInfo#getWindow() AccessibilityNodeInfo.getWindow()} will
290de1cdaebc9b8fdbc5348e6c07f849b74bacc485dKevin Schoedel     * return null.
291de1cdaebc9b8fdbc5348e6c07f849b74bacc485dKevin Schoedel     * <p>
292e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko     * Services that want to set this flag have to declare the capability
2930108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel     * to retrieve window content in their meta-data by setting the attribute
29443b5b06c8be24e465bd6a7b22a8d341db1ad50a2Kevin Schoedel     * {@link android.R.attr#canRetrieveWindowContent canRetrieveWindowContent} to
2954b64dd48b6896d6b963f0a3a0259d3d2a7076a9eKevin Schoedel     * true, otherwise this flag will be ignored. For how to declare the meta-data
2964b64dd48b6896d6b963f0a3a0259d3d2a7076a9eKevin Schoedel     * of a service refer to {@value AccessibilityService#SERVICE_META_DATA}.
2974b64dd48b6896d6b963f0a3a0259d3d2a7076a9eKevin Schoedel     * </p>
29843b5b06c8be24e465bd6a7b22a8d341db1ad50a2Kevin Schoedel     * @see android.R.styleable#AccessibilityService_canRetrieveWindowContent
29943b5b06c8be24e465bd6a7b22a8d341db1ad50a2Kevin Schoedel     */
30043b5b06c8be24e465bd6a7b22a8d341db1ad50a2Kevin Schoedel    public static final int FLAG_RETRIEVE_INTERACTIVE_WINDOWS = 0x00000040;
30143b5b06c8be24e465bd6a7b22a8d341db1ad50a2Kevin Schoedel
3020108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel    /**
30389af70bce420f011adfeb0f80984b3895c4d7d9bKevin Schoedel     * This flag requests that all audio tracks system-wide with
3040108af72a8d8d2ee2af127b4c099b340ad63e3f8Kevin Schoedel     * {@link android.media.AudioAttributes#USAGE_ASSISTANCE_ACCESSIBILITY} be controlled by the
30589af70bce420f011adfeb0f80984b3895c4d7d9bKevin Schoedel     * {@link android.media.AudioManager#STREAM_ACCESSIBILITY} volume.
3063002b8a74431dd7c005269cf9306443a4b4963f1Kevin Schoedel     */
30789af70bce420f011adfeb0f80984b3895c4d7d9bKevin Schoedel    public static final int FLAG_ENABLE_ACCESSIBILITY_VOLUME = 0x00000080;
3083002b8a74431dd7c005269cf9306443a4b4963f1Kevin Schoedel
30989af70bce420f011adfeb0f80984b3895c4d7d9bKevin Schoedel    /**
31043b5b06c8be24e465bd6a7b22a8d341db1ad50a2Kevin Schoedel     * This flag requests that all fingerprint gestures be sent to the accessibility service.
31143b5b06c8be24e465bd6a7b22a8d341db1ad50a2Kevin Schoedel     * It is handled in {@link FingerprintGestureController}
31243b5b06c8be24e465bd6a7b22a8d341db1ad50a2Kevin Schoedel     */
31343b5b06c8be24e465bd6a7b22a8d341db1ad50a2Kevin Schoedel    public static final int FLAG_CAPTURE_FINGERPRINT_GESTURES = 0x00000200;
31443b5b06c8be24e465bd6a7b22a8d341db1ad50a2Kevin Schoedel
31543b5b06c8be24e465bd6a7b22a8d341db1ad50a2Kevin Schoedel    /** {@hide} */
3163002b8a74431dd7c005269cf9306443a4b4963f1Kevin Schoedel    public static final int FLAG_FORCE_DIRECT_BOOT_AWARE = 0x00010000;
3173002b8a74431dd7c005269cf9306443a4b4963f1Kevin Schoedel
31889af70bce420f011adfeb0f80984b3895c4d7d9bKevin Schoedel    /**
31943b5b06c8be24e465bd6a7b22a8d341db1ad50a2Kevin Schoedel     * The event types an {@link AccessibilityService} is interested in.
3204b64dd48b6896d6b963f0a3a0259d3d2a7076a9eKevin Schoedel     * <p>
3214b64dd48b6896d6b963f0a3a0259d3d2a7076a9eKevin Schoedel     *   <strong>Can be dynamically set at runtime.</strong>
3224b64dd48b6896d6b963f0a3a0259d3d2a7076a9eKevin Schoedel     * </p>
3234b64dd48b6896d6b963f0a3a0259d3d2a7076a9eKevin Schoedel     * @see android.view.accessibility.AccessibilityEvent#TYPE_VIEW_CLICKED
324e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko     * @see android.view.accessibility.AccessibilityEvent#TYPE_VIEW_LONG_CLICKED
325e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko     * @see android.view.accessibility.AccessibilityEvent#TYPE_VIEW_FOCUSED
326e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko     * @see android.view.accessibility.AccessibilityEvent#TYPE_VIEW_SELECTED
327e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko     * @see android.view.accessibility.AccessibilityEvent#TYPE_VIEW_TEXT_CHANGED
328     * @see android.view.accessibility.AccessibilityEvent#TYPE_WINDOW_STATE_CHANGED
329     * @see android.view.accessibility.AccessibilityEvent#TYPE_NOTIFICATION_STATE_CHANGED
330     * @see android.view.accessibility.AccessibilityEvent#TYPE_TOUCH_EXPLORATION_GESTURE_START
331     * @see android.view.accessibility.AccessibilityEvent#TYPE_TOUCH_EXPLORATION_GESTURE_END
332     * @see android.view.accessibility.AccessibilityEvent#TYPE_VIEW_HOVER_ENTER
333     * @see android.view.accessibility.AccessibilityEvent#TYPE_VIEW_HOVER_EXIT
334     * @see android.view.accessibility.AccessibilityEvent#TYPE_VIEW_SCROLLED
335     * @see android.view.accessibility.AccessibilityEvent#TYPE_VIEW_TEXT_SELECTION_CHANGED
336     * @see android.view.accessibility.AccessibilityEvent#TYPE_WINDOW_CONTENT_CHANGED
337     * @see android.view.accessibility.AccessibilityEvent#TYPE_TOUCH_INTERACTION_START
338     * @see android.view.accessibility.AccessibilityEvent#TYPE_TOUCH_INTERACTION_END
339     * @see android.view.accessibility.AccessibilityEvent#TYPE_ANNOUNCEMENT
340     * @see android.view.accessibility.AccessibilityEvent#TYPE_GESTURE_DETECTION_START
341     * @see android.view.accessibility.AccessibilityEvent#TYPE_GESTURE_DETECTION_END
342     * @see android.view.accessibility.AccessibilityEvent#TYPE_VIEW_ACCESSIBILITY_FOCUSED
343     * @see android.view.accessibility.AccessibilityEvent#TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED
344     * @see android.view.accessibility.AccessibilityEvent#TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
345     * @see android.view.accessibility.AccessibilityEvent#TYPE_WINDOWS_CHANGED
346     */
347    public int eventTypes;
348
349    /**
350     * The package names an {@link AccessibilityService} is interested in. Setting
351     * to <code>null</code> is equivalent to all packages.
352     * <p>
353     *   <strong>Can be dynamically set at runtime.</strong>
354     * </p>
355     */
356    public String[] packageNames;
357
358    /**
359     * The feedback type an {@link AccessibilityService} provides.
360     * <p>
361     *   <strong>Can be dynamically set at runtime.</strong>
362     * </p>
363     * @see #FEEDBACK_AUDIBLE
364     * @see #FEEDBACK_GENERIC
365     * @see #FEEDBACK_HAPTIC
366     * @see #FEEDBACK_SPOKEN
367     * @see #FEEDBACK_VISUAL
368     * @see #FEEDBACK_BRAILLE
369     */
370    public int feedbackType;
371
372    /**
373     * The timeout after the most recent event of a given type before an
374     * {@link AccessibilityService} is notified.
375     * <p>
376     *   <strong>Can be dynamically set at runtime.</strong>.
377     * </p>
378     * <p>
379     * <strong>Note:</strong> The event notification timeout is useful to avoid propagating
380     *       events to the client too frequently since this is accomplished via an expensive
381     *       interprocess call. One can think of the timeout as a criteria to determine when
382     *       event generation has settled down.
383     */
384    public long notificationTimeout;
385
386    /**
387     * This field represents a set of flags used for configuring an
388     * {@link AccessibilityService}.
389     * <p>
390     *   <strong>Can be dynamically set at runtime.</strong>
391     * </p>
392     * @see #DEFAULT
393     * @see #FLAG_INCLUDE_NOT_IMPORTANT_VIEWS
394     * @see #FLAG_REQUEST_TOUCH_EXPLORATION_MODE
395     * @see #FLAG_REQUEST_ENHANCED_WEB_ACCESSIBILITY
396     * @see #FLAG_REQUEST_FILTER_KEY_EVENTS
397     * @see #FLAG_REPORT_VIEW_IDS
398     * @see #FLAG_RETRIEVE_INTERACTIVE_WINDOWS
399     */
400    public int flags;
401
402    /**
403     * The component name the accessibility service.
404     */
405    private ComponentName mComponentName;
406
407    /**
408     * The Service that implements this accessibility service component.
409     */
410    private ResolveInfo mResolveInfo;
411
412    /**
413     * The accessibility service setting activity's name, used by the system
414     * settings to launch the setting activity of this accessibility service.
415     */
416    private String mSettingsActivityName;
417
418    /**
419     * Bit mask with capabilities of this service.
420     */
421    private int mCapabilities;
422
423    /**
424     * Resource id of the description of the accessibility service.
425     */
426    private int mDescriptionResId;
427
428    /**
429     * Non localized description of the accessibility service.
430     */
431    private String mNonLocalizedDescription;
432
433    /**
434     * Creates a new instance.
435     */
436    public AccessibilityServiceInfo() {
437        /* do nothing */
438    }
439
440    /**
441     * Creates a new instance.
442     *
443     * @param resolveInfo The service resolve info.
444     * @param context Context for accessing resources.
445     * @throws XmlPullParserException If a XML parsing error occurs.
446     * @throws IOException If a XML parsing error occurs.
447     *
448     * @hide
449     */
450    public AccessibilityServiceInfo(ResolveInfo resolveInfo, Context context)
451            throws XmlPullParserException, IOException {
452        ServiceInfo serviceInfo = resolveInfo.serviceInfo;
453        mComponentName = new ComponentName(serviceInfo.packageName, serviceInfo.name);
454        mResolveInfo = resolveInfo;
455
456        XmlResourceParser parser = null;
457
458        try {
459            PackageManager packageManager = context.getPackageManager();
460            parser = serviceInfo.loadXmlMetaData(packageManager,
461                    AccessibilityService.SERVICE_META_DATA);
462            if (parser == null) {
463                return;
464            }
465
466            int type = 0;
467            while (type != XmlPullParser.END_DOCUMENT && type != XmlPullParser.START_TAG) {
468                type = parser.next();
469            }
470
471            String nodeName = parser.getName();
472            if (!TAG_ACCESSIBILITY_SERVICE.equals(nodeName)) {
473                throw new XmlPullParserException( "Meta-data does not start with"
474                        + TAG_ACCESSIBILITY_SERVICE + " tag");
475            }
476
477            AttributeSet allAttributes = Xml.asAttributeSet(parser);
478            Resources resources = packageManager.getResourcesForApplication(
479                    serviceInfo.applicationInfo);
480            TypedArray asAttributes = resources.obtainAttributes(allAttributes,
481                    com.android.internal.R.styleable.AccessibilityService);
482            eventTypes = asAttributes.getInt(
483                    com.android.internal.R.styleable.AccessibilityService_accessibilityEventTypes,
484                    0);
485            String packageNamez = asAttributes.getString(
486                    com.android.internal.R.styleable.AccessibilityService_packageNames);
487            if (packageNamez != null) {
488                packageNames = packageNamez.split("(\\s)*,(\\s)*");
489            }
490            feedbackType = asAttributes.getInt(
491                    com.android.internal.R.styleable.AccessibilityService_accessibilityFeedbackType,
492                    0);
493            notificationTimeout = asAttributes.getInt(
494                    com.android.internal.R.styleable.AccessibilityService_notificationTimeout,
495                    0);
496            flags = asAttributes.getInt(
497                    com.android.internal.R.styleable.AccessibilityService_accessibilityFlags, 0);
498            mSettingsActivityName = asAttributes.getString(
499                    com.android.internal.R.styleable.AccessibilityService_settingsActivity);
500            if (asAttributes.getBoolean(com.android.internal.R.styleable
501                    .AccessibilityService_canRetrieveWindowContent, false)) {
502                mCapabilities |= CAPABILITY_CAN_RETRIEVE_WINDOW_CONTENT;
503            }
504            if (asAttributes.getBoolean(com.android.internal.R.styleable
505                    .AccessibilityService_canRequestTouchExplorationMode, false)) {
506                mCapabilities |= CAPABILITY_CAN_REQUEST_TOUCH_EXPLORATION;
507            }
508            if (asAttributes.getBoolean(com.android.internal.R.styleable
509                        .AccessibilityService_canRequestEnhancedWebAccessibility, false)) {
510                    mCapabilities |= CAPABILITY_CAN_REQUEST_ENHANCED_WEB_ACCESSIBILITY;
511            }
512            if (asAttributes.getBoolean(com.android.internal.R.styleable
513                    .AccessibilityService_canRequestFilterKeyEvents, false)) {
514                mCapabilities |= CAPABILITY_CAN_REQUEST_FILTER_KEY_EVENTS;
515            }
516            if (asAttributes.getBoolean(com.android.internal.R.styleable
517                    .AccessibilityService_canControlMagnification, false)) {
518                mCapabilities |= CAPABILITY_CAN_CONTROL_MAGNIFICATION;
519            }
520            if (asAttributes.getBoolean(com.android.internal.R.styleable
521                    .AccessibilityService_canPerformGestures, false)) {
522                mCapabilities |= CAPABILITY_CAN_PERFORM_GESTURES;
523            }
524            if (asAttributes.getBoolean(com.android.internal.R.styleable
525                    .AccessibilityService_canCaptureFingerprintGestures, false)) {
526                mCapabilities |= CAPABILITY_CAN_CAPTURE_FINGERPRINT_GESTURES;
527            }
528            TypedValue peekedValue = asAttributes.peekValue(
529                    com.android.internal.R.styleable.AccessibilityService_description);
530            if (peekedValue != null) {
531                mDescriptionResId = peekedValue.resourceId;
532                CharSequence nonLocalizedDescription = peekedValue.coerceToString();
533                if (nonLocalizedDescription != null) {
534                    mNonLocalizedDescription = nonLocalizedDescription.toString().trim();
535                }
536            }
537            asAttributes.recycle();
538        } catch (NameNotFoundException e) {
539            throw new XmlPullParserException( "Unable to create context for: "
540                    + serviceInfo.packageName);
541        } finally {
542            if (parser != null) {
543                parser.close();
544            }
545        }
546    }
547
548    /**
549     * Updates the properties that an AccessibilitySerivice can change dynamically.
550     *
551     * @param other The info from which to update the properties.
552     *
553     * @hide
554     */
555    public void updateDynamicallyConfigurableProperties(AccessibilityServiceInfo other) {
556        eventTypes = other.eventTypes;
557        packageNames = other.packageNames;
558        feedbackType = other.feedbackType;
559        notificationTimeout = other.notificationTimeout;
560        flags = other.flags;
561    }
562
563    /**
564     * @hide
565     */
566    public void setComponentName(ComponentName component) {
567        mComponentName = component;
568    }
569
570    /**
571     * @hide
572     */
573    public ComponentName getComponentName() {
574        return mComponentName;
575    }
576
577    /**
578     * The accessibility service id.
579     * <p>
580     *   <strong>Generated by the system.</strong>
581     * </p>
582     * @return The id.
583     */
584    public String getId() {
585        return mComponentName.flattenToShortString();
586    }
587
588    /**
589     * The service {@link ResolveInfo}.
590     * <p>
591     *   <strong>Generated by the system.</strong>
592     * </p>
593     * @return The info.
594     */
595    public ResolveInfo getResolveInfo() {
596        return mResolveInfo;
597    }
598
599    /**
600     * The settings activity name.
601     * <p>
602     *    <strong>Statically set from
603     *    {@link AccessibilityService#SERVICE_META_DATA meta-data}.</strong>
604     * </p>
605     * @return The settings activity name.
606     */
607    public String getSettingsActivityName() {
608        return mSettingsActivityName;
609    }
610
611    /**
612     * Whether this service can retrieve the current window's content.
613     * <p>
614     *    <strong>Statically set from
615     *    {@link AccessibilityService#SERVICE_META_DATA meta-data}.</strong>
616     * </p>
617     * @return True if window content can be retrieved.
618     *
619     * @deprecated Use {@link #getCapabilities()}.
620     */
621    public boolean getCanRetrieveWindowContent() {
622        return (mCapabilities & CAPABILITY_CAN_RETRIEVE_WINDOW_CONTENT) != 0;
623    }
624
625    /**
626     * Returns the bit mask of capabilities this accessibility service has such as
627     * being able to retrieve the active window content, etc.
628     *
629     * @return The capability bit mask.
630     *
631     * @see #CAPABILITY_CAN_RETRIEVE_WINDOW_CONTENT
632     * @see #CAPABILITY_CAN_REQUEST_TOUCH_EXPLORATION
633     * @see #CAPABILITY_CAN_REQUEST_ENHANCED_WEB_ACCESSIBILITY
634     * @see #CAPABILITY_FILTER_KEY_EVENTS
635     * @see #CAPABILITY_CAN_CONTROL_MAGNIFICATION
636     * @see #CAPABILITY_CAN_PERFORM_GESTURES
637     */
638    public int getCapabilities() {
639        return mCapabilities;
640    }
641
642    /**
643     * Sets the bit mask of capabilities this accessibility service has such as
644     * being able to retrieve the active window content, etc.
645     *
646     * @param capabilities The capability bit mask.
647     *
648     * @see #CAPABILITY_CAN_RETRIEVE_WINDOW_CONTENT
649     * @see #CAPABILITY_CAN_REQUEST_TOUCH_EXPLORATION
650     * @see #CAPABILITY_CAN_REQUEST_ENHANCED_WEB_ACCESSIBILITY
651     * @see #CAPABILITY_FILTER_KEY_EVENTS
652     * @see #CAPABILITY_CAN_CONTROL_MAGNIFICATION
653     * @see #CAPABILITY_CAN_PERFORM_GESTURES
654     *
655     * @hide
656     */
657    public void setCapabilities(int capabilities) {
658        mCapabilities = capabilities;
659    }
660
661    /**
662     * Gets the non-localized description of the accessibility service.
663     * <p>
664     *    <strong>Statically set from
665     *    {@link AccessibilityService#SERVICE_META_DATA meta-data}.</strong>
666     * </p>
667     * @return The description.
668     *
669     * @deprecated Use {@link #loadDescription(PackageManager)}.
670     */
671    public String getDescription() {
672        return mNonLocalizedDescription;
673    }
674
675    /**
676     * The localized description of the accessibility service.
677     * <p>
678     *    <strong>Statically set from
679     *    {@link AccessibilityService#SERVICE_META_DATA meta-data}.</strong>
680     * </p>
681     * @return The localized description.
682     */
683    public String loadDescription(PackageManager packageManager) {
684        if (mDescriptionResId == 0) {
685            return mNonLocalizedDescription;
686        }
687        ServiceInfo serviceInfo = mResolveInfo.serviceInfo;
688        CharSequence description = packageManager.getText(serviceInfo.packageName,
689                mDescriptionResId, serviceInfo.applicationInfo);
690        if (description != null) {
691            return description.toString().trim();
692        }
693        return null;
694    }
695
696    /** {@hide} */
697    public boolean isDirectBootAware() {
698        return ((flags & FLAG_FORCE_DIRECT_BOOT_AWARE) != 0)
699                || mResolveInfo.serviceInfo.directBootAware;
700    }
701
702    /**
703     * {@inheritDoc}
704     */
705    public int describeContents() {
706        return 0;
707    }
708
709    public void writeToParcel(Parcel parcel, int flagz) {
710        parcel.writeInt(eventTypes);
711        parcel.writeStringArray(packageNames);
712        parcel.writeInt(feedbackType);
713        parcel.writeLong(notificationTimeout);
714        parcel.writeInt(flags);
715        parcel.writeParcelable(mComponentName, flagz);
716        parcel.writeParcelable(mResolveInfo, 0);
717        parcel.writeString(mSettingsActivityName);
718        parcel.writeInt(mCapabilities);
719        parcel.writeInt(mDescriptionResId);
720        parcel.writeString(mNonLocalizedDescription);
721    }
722
723    private void initFromParcel(Parcel parcel) {
724        eventTypes = parcel.readInt();
725        packageNames = parcel.readStringArray();
726        feedbackType = parcel.readInt();
727        notificationTimeout = parcel.readLong();
728        flags = parcel.readInt();
729        mComponentName = parcel.readParcelable(this.getClass().getClassLoader());
730        mResolveInfo = parcel.readParcelable(null);
731        mSettingsActivityName = parcel.readString();
732        mCapabilities = parcel.readInt();
733        mDescriptionResId = parcel.readInt();
734        mNonLocalizedDescription = parcel.readString();
735    }
736
737    @Override
738    public int hashCode() {
739        return 31 * 1 + ((mComponentName == null) ? 0 : mComponentName.hashCode());
740    }
741
742    @Override
743    public boolean equals(Object obj) {
744        if (this == obj) {
745            return true;
746        }
747        if (obj == null) {
748            return false;
749        }
750        if (getClass() != obj.getClass()) {
751            return false;
752        }
753        AccessibilityServiceInfo other = (AccessibilityServiceInfo) obj;
754        if (mComponentName == null) {
755            if (other.mComponentName != null) {
756                return false;
757            }
758        } else if (!mComponentName.equals(other.mComponentName)) {
759            return false;
760        }
761        return true;
762    }
763
764    @Override
765    public String toString() {
766        StringBuilder stringBuilder = new StringBuilder();
767        appendEventTypes(stringBuilder, eventTypes);
768        stringBuilder.append(", ");
769        appendPackageNames(stringBuilder, packageNames);
770        stringBuilder.append(", ");
771        appendFeedbackTypes(stringBuilder, feedbackType);
772        stringBuilder.append(", ");
773        stringBuilder.append("notificationTimeout: ").append(notificationTimeout);
774        stringBuilder.append(", ");
775        appendFlags(stringBuilder, flags);
776        stringBuilder.append(", ");
777        stringBuilder.append("id: ").append(getId());
778        stringBuilder.append(", ");
779        stringBuilder.append("resolveInfo: ").append(mResolveInfo);
780        stringBuilder.append(", ");
781        stringBuilder.append("settingsActivityName: ").append(mSettingsActivityName);
782        stringBuilder.append(", ");
783        appendCapabilities(stringBuilder, mCapabilities);
784        return stringBuilder.toString();
785    }
786
787    private static void appendFeedbackTypes(StringBuilder stringBuilder, int feedbackTypes) {
788        stringBuilder.append("feedbackTypes:");
789        stringBuilder.append("[");
790        while (feedbackTypes != 0) {
791            final int feedbackTypeBit = (1 << Integer.numberOfTrailingZeros(feedbackTypes));
792            stringBuilder.append(feedbackTypeToString(feedbackTypeBit));
793            feedbackTypes &= ~feedbackTypeBit;
794            if (feedbackTypes != 0) {
795                stringBuilder.append(", ");
796            }
797        }
798        stringBuilder.append("]");
799    }
800
801    private static void appendPackageNames(StringBuilder stringBuilder, String[] packageNames) {
802        stringBuilder.append("packageNames:");
803        stringBuilder.append("[");
804        if (packageNames != null) {
805            final int packageNameCount = packageNames.length;
806            for (int i = 0; i < packageNameCount; i++) {
807                stringBuilder.append(packageNames[i]);
808                if (i < packageNameCount - 1) {
809                    stringBuilder.append(", ");
810                }
811            }
812        }
813        stringBuilder.append("]");
814    }
815
816    private static void appendEventTypes(StringBuilder stringBuilder, int eventTypes) {
817        stringBuilder.append("eventTypes:");
818        stringBuilder.append("[");
819        while (eventTypes != 0) {
820            final int eventTypeBit = (1 << Integer.numberOfTrailingZeros(eventTypes));
821            stringBuilder.append(AccessibilityEvent.eventTypeToString(eventTypeBit));
822            eventTypes &= ~eventTypeBit;
823            if (eventTypes != 0) {
824                stringBuilder.append(", ");
825            }
826        }
827        stringBuilder.append("]");
828    }
829
830    private static void appendFlags(StringBuilder stringBuilder, int flags) {
831        stringBuilder.append("flags:");
832        stringBuilder.append("[");
833        while (flags != 0) {
834            final int flagBit = (1 << Integer.numberOfTrailingZeros(flags));
835            stringBuilder.append(flagToString(flagBit));
836            flags &= ~flagBit;
837            if (flags != 0) {
838                stringBuilder.append(", ");
839            }
840        }
841        stringBuilder.append("]");
842    }
843
844    private static void appendCapabilities(StringBuilder stringBuilder, int capabilities) {
845        stringBuilder.append("capabilities:");
846        stringBuilder.append("[");
847        while (capabilities != 0) {
848            final int capabilityBit = (1 << Integer.numberOfTrailingZeros(capabilities));
849            stringBuilder.append(capabilityToString(capabilityBit));
850            capabilities &= ~capabilityBit;
851            if (capabilities != 0) {
852                stringBuilder.append(", ");
853            }
854        }
855        stringBuilder.append("]");
856    }
857
858    /**
859     * Returns the string representation of a feedback type. For example,
860     * {@link #FEEDBACK_SPOKEN} is represented by the string FEEDBACK_SPOKEN.
861     *
862     * @param feedbackType The feedback type.
863     * @return The string representation.
864     */
865    public static String feedbackTypeToString(int feedbackType) {
866        StringBuilder builder = new StringBuilder();
867        builder.append("[");
868        while (feedbackType != 0) {
869            final int feedbackTypeFlag = 1 << Integer.numberOfTrailingZeros(feedbackType);
870            feedbackType &= ~feedbackTypeFlag;
871            switch (feedbackTypeFlag) {
872                case FEEDBACK_AUDIBLE:
873                    if (builder.length() > 1) {
874                        builder.append(", ");
875                    }
876                    builder.append("FEEDBACK_AUDIBLE");
877                    break;
878                case FEEDBACK_HAPTIC:
879                    if (builder.length() > 1) {
880                        builder.append(", ");
881                    }
882                    builder.append("FEEDBACK_HAPTIC");
883                    break;
884                case FEEDBACK_GENERIC:
885                    if (builder.length() > 1) {
886                        builder.append(", ");
887                    }
888                    builder.append("FEEDBACK_GENERIC");
889                    break;
890                case FEEDBACK_SPOKEN:
891                    if (builder.length() > 1) {
892                        builder.append(", ");
893                    }
894                    builder.append("FEEDBACK_SPOKEN");
895                    break;
896                case FEEDBACK_VISUAL:
897                    if (builder.length() > 1) {
898                        builder.append(", ");
899                    }
900                    builder.append("FEEDBACK_VISUAL");
901                    break;
902                case FEEDBACK_BRAILLE:
903                    if (builder.length() > 1) {
904                        builder.append(", ");
905                    }
906                    builder.append("FEEDBACK_BRAILLE");
907                    break;
908            }
909        }
910        builder.append("]");
911        return builder.toString();
912    }
913
914    /**
915     * Returns the string representation of a flag. For example,
916     * {@link #DEFAULT} is represented by the string DEFAULT.
917     *
918     * @param flag The flag.
919     * @return The string representation.
920     */
921    public static String flagToString(int flag) {
922        switch (flag) {
923            case DEFAULT:
924                return "DEFAULT";
925            case FLAG_INCLUDE_NOT_IMPORTANT_VIEWS:
926                return "FLAG_INCLUDE_NOT_IMPORTANT_VIEWS";
927            case FLAG_REQUEST_TOUCH_EXPLORATION_MODE:
928                return "FLAG_REQUEST_TOUCH_EXPLORATION_MODE";
929            case FLAG_REQUEST_ENHANCED_WEB_ACCESSIBILITY:
930                return "FLAG_REQUEST_ENHANCED_WEB_ACCESSIBILITY";
931            case FLAG_REPORT_VIEW_IDS:
932                return "FLAG_REPORT_VIEW_IDS";
933            case FLAG_REQUEST_FILTER_KEY_EVENTS:
934                return "FLAG_REQUEST_FILTER_KEY_EVENTS";
935            case FLAG_RETRIEVE_INTERACTIVE_WINDOWS:
936                return "FLAG_RETRIEVE_INTERACTIVE_WINDOWS";
937            case FLAG_ENABLE_ACCESSIBILITY_VOLUME:
938                return "FLAG_ENABLE_ACCESSIBILITY_VOLUME";
939            case FLAG_CAPTURE_FINGERPRINT_GESTURES:
940                return "FLAG_CAPTURE_FINGERPRINT_GESTURES";
941            default:
942                return null;
943        }
944    }
945
946    /**
947     * Returns the string representation of a capability. For example,
948     * {@link #CAPABILITY_CAN_RETRIEVE_WINDOW_CONTENT} is represented
949     * by the string CAPABILITY_CAN_RETRIEVE_WINDOW_CONTENT.
950     *
951     * @param capability The capability.
952     * @return The string representation.
953     */
954    public static String capabilityToString(int capability) {
955        switch (capability) {
956            case CAPABILITY_CAN_RETRIEVE_WINDOW_CONTENT:
957                return "CAPABILITY_CAN_RETRIEVE_WINDOW_CONTENT";
958            case CAPABILITY_CAN_REQUEST_TOUCH_EXPLORATION:
959                return "CAPABILITY_CAN_REQUEST_TOUCH_EXPLORATION";
960            case CAPABILITY_CAN_REQUEST_ENHANCED_WEB_ACCESSIBILITY:
961                return "CAPABILITY_CAN_REQUEST_ENHANCED_WEB_ACCESSIBILITY";
962            case CAPABILITY_CAN_REQUEST_FILTER_KEY_EVENTS:
963                return "CAPABILITY_CAN_FILTER_KEY_EVENTS";
964            case CAPABILITY_CAN_CONTROL_MAGNIFICATION:
965                return "CAPABILITY_CAN_CONTROL_MAGNIFICATION";
966            case CAPABILITY_CAN_PERFORM_GESTURES:
967                return "CAPABILITY_CAN_PERFORM_GESTURES";
968            case CAPABILITY_CAN_CAPTURE_FINGERPRINT_GESTURES:
969                return "CAPABILITY_CAN_CAPTURE_FINGERPRINT_GESTURES";
970            default:
971                return "UNKNOWN";
972        }
973    }
974
975    /**
976     * @hide
977     * @return The list of {@link CapabilityInfo} objects.
978     * @deprecated The version that takes a context works better.
979     */
980    public List<CapabilityInfo> getCapabilityInfos() {
981        return getCapabilityInfos(null);
982    }
983
984    /**
985     * @hide
986     * @param context A valid context
987     * @return The list of {@link CapabilityInfo} objects.
988     */
989    public List<CapabilityInfo> getCapabilityInfos(Context context) {
990        if (mCapabilities == 0) {
991            return Collections.emptyList();
992        }
993        int capabilities = mCapabilities;
994        List<CapabilityInfo> capabilityInfos = new ArrayList<CapabilityInfo>();
995        SparseArray<CapabilityInfo> capabilityInfoSparseArray =
996                getCapabilityInfoSparseArray(context);
997        while (capabilities != 0) {
998            final int capabilityBit = 1 << Integer.numberOfTrailingZeros(capabilities);
999            capabilities &= ~capabilityBit;
1000            CapabilityInfo capabilityInfo = capabilityInfoSparseArray.get(capabilityBit);
1001            if (capabilityInfo != null) {
1002                capabilityInfos.add(capabilityInfo);
1003            }
1004        }
1005        return capabilityInfos;
1006    }
1007
1008    private static SparseArray<CapabilityInfo> getCapabilityInfoSparseArray(Context context) {
1009        if (sAvailableCapabilityInfos == null) {
1010            sAvailableCapabilityInfos = new SparseArray<CapabilityInfo>();
1011            sAvailableCapabilityInfos.put(CAPABILITY_CAN_RETRIEVE_WINDOW_CONTENT,
1012                    new CapabilityInfo(CAPABILITY_CAN_RETRIEVE_WINDOW_CONTENT,
1013                            R.string.capability_title_canRetrieveWindowContent,
1014                            R.string.capability_desc_canRetrieveWindowContent));
1015            sAvailableCapabilityInfos.put(CAPABILITY_CAN_REQUEST_TOUCH_EXPLORATION,
1016                    new CapabilityInfo(CAPABILITY_CAN_REQUEST_TOUCH_EXPLORATION,
1017                            R.string.capability_title_canRequestTouchExploration,
1018                            R.string.capability_desc_canRequestTouchExploration));
1019            sAvailableCapabilityInfos.put(CAPABILITY_CAN_REQUEST_ENHANCED_WEB_ACCESSIBILITY,
1020                    new CapabilityInfo(CAPABILITY_CAN_REQUEST_ENHANCED_WEB_ACCESSIBILITY,
1021                            R.string.capability_title_canRequestEnhancedWebAccessibility,
1022                            R.string.capability_desc_canRequestEnhancedWebAccessibility));
1023            sAvailableCapabilityInfos.put(CAPABILITY_CAN_REQUEST_FILTER_KEY_EVENTS,
1024                    new CapabilityInfo(CAPABILITY_CAN_REQUEST_FILTER_KEY_EVENTS,
1025                            R.string.capability_title_canRequestFilterKeyEvents,
1026                            R.string.capability_desc_canRequestFilterKeyEvents));
1027            sAvailableCapabilityInfos.put(CAPABILITY_CAN_CONTROL_MAGNIFICATION,
1028                    new CapabilityInfo(CAPABILITY_CAN_CONTROL_MAGNIFICATION,
1029                            R.string.capability_title_canControlMagnification,
1030                            R.string.capability_desc_canControlMagnification));
1031            sAvailableCapabilityInfos.put(CAPABILITY_CAN_PERFORM_GESTURES,
1032                    new CapabilityInfo(CAPABILITY_CAN_PERFORM_GESTURES,
1033                            R.string.capability_title_canPerformGestures,
1034                            R.string.capability_desc_canPerformGestures));
1035            if ((context == null)
1036                    || context.getSystemService(FingerprintManager.class).isHardwareDetected()) {
1037                sAvailableCapabilityInfos.put(CAPABILITY_CAN_CAPTURE_FINGERPRINT_GESTURES,
1038                        new CapabilityInfo(CAPABILITY_CAN_CAPTURE_FINGERPRINT_GESTURES,
1039                                R.string.capability_title_canCaptureFingerprintGestures,
1040                                R.string.capability_desc_canCaptureFingerprintGestures));
1041            }
1042        }
1043        return sAvailableCapabilityInfos;
1044    }
1045
1046    /**
1047     * @hide
1048     */
1049    public static final class CapabilityInfo {
1050        public final int capability;
1051        public final int titleResId;
1052        public final int descResId;
1053
1054        public CapabilityInfo(int capability, int titleResId, int descResId) {
1055            this.capability = capability;
1056            this.titleResId = titleResId;
1057            this.descResId = descResId;
1058        }
1059    }
1060
1061    /**
1062     * @see Parcelable.Creator
1063     */
1064    public static final Parcelable.Creator<AccessibilityServiceInfo> CREATOR =
1065            new Parcelable.Creator<AccessibilityServiceInfo>() {
1066        public AccessibilityServiceInfo createFromParcel(Parcel parcel) {
1067            AccessibilityServiceInfo info = new AccessibilityServiceInfo();
1068            info.initFromParcel(parcel);
1069            return info;
1070        }
1071
1072        public AccessibilityServiceInfo[] newArray(int size) {
1073            return new AccessibilityServiceInfo[size];
1074        }
1075    };
1076}
1077