• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2012 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.support.v4.view.accessibility;
18 
19 import android.os.Build;
20 import android.os.Bundle;
21 import android.support.annotation.Nullable;
22 import android.view.View;
23 
24 import java.util.ArrayList;
25 import java.util.List;
26 
27 /**
28  * Helper for accessing {@link android.view.accessibility.AccessibilityNodeProvider}
29  * introduced after API level 4 in a backwards compatible fashion.
30  */
31 public class AccessibilityNodeProviderCompat {
32 
33     interface AccessibilityNodeProviderImpl {
newAccessibilityNodeProviderBridge(AccessibilityNodeProviderCompat compat)34         Object newAccessibilityNodeProviderBridge(AccessibilityNodeProviderCompat compat);
35     }
36 
37     static class AccessibilityNodeProviderStubImpl implements AccessibilityNodeProviderImpl {
38         @Override
newAccessibilityNodeProviderBridge(AccessibilityNodeProviderCompat compat)39         public Object newAccessibilityNodeProviderBridge(AccessibilityNodeProviderCompat compat) {
40             return null;
41         }
42     }
43 
44     private static class AccessibilityNodeProviderJellyBeanImpl
45             extends AccessibilityNodeProviderStubImpl {
46         @Override
newAccessibilityNodeProviderBridge( final AccessibilityNodeProviderCompat compat)47         public Object newAccessibilityNodeProviderBridge(
48                 final AccessibilityNodeProviderCompat compat) {
49             return AccessibilityNodeProviderCompatJellyBean.newAccessibilityNodeProviderBridge(
50                     new AccessibilityNodeProviderCompatJellyBean.AccessibilityNodeInfoBridge() {
51                         @Override
52                         public boolean performAction(int virtualViewId, int action,
53                                 Bundle arguments) {
54                             return compat.performAction(virtualViewId, action, arguments);
55                         }
56 
57                         @Override
58                         public List<Object> findAccessibilityNodeInfosByText(
59                                             String text, int virtualViewId) {
60                             final List<AccessibilityNodeInfoCompat> compatInfos =
61                                 compat.findAccessibilityNodeInfosByText(text, virtualViewId);
62                             if (compatInfos == null) {
63                                 return null;
64                             } else {
65                                 final List<Object> infos = new ArrayList<>();
66                                 final int infoCount = compatInfos.size();
67                                 for (int i = 0; i < infoCount; i++) {
68                                     AccessibilityNodeInfoCompat infoCompat = compatInfos.get(i);
69                                     infos.add(infoCompat.getInfo());
70                                 }
71                                 return infos;
72                             }
73                         }
74 
75                         @Override
76                         public Object createAccessibilityNodeInfo(
77                                 int virtualViewId) {
78                             final AccessibilityNodeInfoCompat compatInfo =
79                                     compat.createAccessibilityNodeInfo(virtualViewId);
80                             if (compatInfo == null) {
81                                 return null;
82                             } else {
83                                 return compatInfo.getInfo();
84                             }
85                         }
86                     });
87         }
88     }
89 
90     private static class AccessibilityNodeProviderKitKatImpl
91             extends AccessibilityNodeProviderStubImpl {
92         @Override
93         public Object newAccessibilityNodeProviderBridge(
94                 final AccessibilityNodeProviderCompat compat) {
95             return AccessibilityNodeProviderCompatKitKat.newAccessibilityNodeProviderBridge(
96                     new AccessibilityNodeProviderCompatKitKat.AccessibilityNodeInfoBridge() {
97                         @Override
98                         public boolean performAction(
99                                 int virtualViewId, int action, Bundle arguments) {
100                             return compat.performAction(virtualViewId, action, arguments);
101                         }
102 
103                         @Override
104                         public List<Object> findAccessibilityNodeInfosByText(
105                                 String text, int virtualViewId) {
106                             final List<AccessibilityNodeInfoCompat> compatInfos =
107                                     compat.findAccessibilityNodeInfosByText(text, virtualViewId);
108                             if (compatInfos == null) {
109                                 return null;
110                             } else {
111                                 final List<Object> infos = new ArrayList<>();
112                                 final int infoCount = compatInfos.size();
113                                 for (int i = 0; i < infoCount; i++) {
114                                     AccessibilityNodeInfoCompat infoCompat = compatInfos.get(i);
115                                     infos.add(infoCompat.getInfo());
116                                 }
117                                 return infos;
118                             }
119                         }
120 
121                         @Override
122                         public Object createAccessibilityNodeInfo(int virtualViewId) {
123                             final AccessibilityNodeInfoCompat compatInfo =
124                                     compat.createAccessibilityNodeInfo(virtualViewId);
125                             if (compatInfo == null) {
126                                 return null;
127                             } else {
128                                 return compatInfo.getInfo();
129                             }
130                         }
131 
132                         @Override
133                         public Object findFocus(int focus) {
134                             final AccessibilityNodeInfoCompat compatInfo = compat.findFocus(focus);
135                             if (compatInfo == null) {
136                                 return null;
137                             } else {
138                                 return compatInfo.getInfo();
139                             }
140                         }
141                     });
142         }
143     }
144 
145     /**
146      * The virtual id for the hosting View.
147      */
148     public static final int HOST_VIEW_ID = -1;
149 
150     private static final AccessibilityNodeProviderImpl IMPL;
151 
152     private final Object mProvider;
153 
154     static {
155         if (Build.VERSION.SDK_INT >= 19) { // KitKat
156             IMPL = new AccessibilityNodeProviderKitKatImpl();
157         } else if (Build.VERSION.SDK_INT >= 16) { // JellyBean
158             IMPL = new AccessibilityNodeProviderJellyBeanImpl();
159         } else {
160             IMPL = new AccessibilityNodeProviderStubImpl();
161         }
162     }
163 
164     /**
165      * Creates a new instance.
166      */
167     public AccessibilityNodeProviderCompat() {
168         mProvider = IMPL.newAccessibilityNodeProviderBridge(this);
169     }
170 
171     /**
172      * Creates a new instance wrapping an
173      * {@link android.view.accessibility.AccessibilityNodeProvider}.
174      *
175      * @param provider The provider.
176      */
177     public AccessibilityNodeProviderCompat(Object provider) {
178         mProvider = provider;
179     }
180 
181     /**
182      * @return The wrapped {@link android.view.accessibility.AccessibilityNodeProvider}.
183      */
184     public Object getProvider() {
185         return mProvider;
186     }
187 
188     /**
189      * Returns an {@link AccessibilityNodeInfoCompat} representing a virtual view,
190      * i.e. a descendant of the host View, with the given <code>virtualViewId</code>
191      * or the host View itself if <code>virtualViewId</code> equals to {@link #HOST_VIEW_ID}.
192      * <p>
193      * A virtual descendant is an imaginary View that is reported as a part of the view
194      * hierarchy for accessibility purposes. This enables custom views that draw complex
195      * content to report them selves as a tree of virtual views, thus conveying their
196      * logical structure.
197      * </p>
198      * <p>
199      * The implementer is responsible for obtaining an accessibility node info from the
200      * pool of reusable instances and setting the desired properties of the node info
201      * before returning it.
202      * </p>
203      *
204      * @param virtualViewId A client defined virtual view id.
205      * @return A populated {@link AccessibilityNodeInfoCompat} for a virtual descendant
206      *     or the host View.
207      *
208      * @see AccessibilityNodeInfoCompat
209      */
210     @Nullable
211     public AccessibilityNodeInfoCompat createAccessibilityNodeInfo(int virtualViewId) {
212         return null;
213     }
214 
215     /**
216      * Performs an accessibility action on a virtual view, i.e. a descendant of the
217      * host View, with the given <code>virtualViewId</code> or the host View itself
218      * if <code>virtualViewId</code> equals to {@link #HOST_VIEW_ID}.
219      *
220      * @param virtualViewId A client defined virtual view id.
221      * @param action The action to perform.
222      * @param arguments Optional arguments.
223      * @return True if the action was performed.
224      *
225      * @see #createAccessibilityNodeInfo(int)
226      * @see AccessibilityNodeInfoCompat
227      */
228     public boolean performAction(int virtualViewId, int action, Bundle arguments) {
229         return false;
230     }
231 
232     /**
233      * Finds {@link AccessibilityNodeInfoCompat}s by text. The match is case insensitive
234      * containment. The search is relative to the virtual view, i.e. a descendant of the
235      * host View, with the given <code>virtualViewId</code> or the host View itself
236      * <code>virtualViewId</code> equals to {@link #HOST_VIEW_ID}.
237      *
238      * @param virtualViewId A client defined virtual view id which defined
239      *     the root of the tree in which to perform the search.
240      * @param text The searched text.
241      * @return A list of node info.
242      *
243      * @see #createAccessibilityNodeInfo(int)
244      * @see AccessibilityNodeInfoCompat
245      */
246     @Nullable
247     public List<AccessibilityNodeInfoCompat> findAccessibilityNodeInfosByText(String text,
248             int virtualViewId) {
249         return null;
250     }
251 
252     /**
253      * Find the virtual view, i.e. a descendant of the host View, that has the
254      * specified focus type.
255      *
256      * @param focus The focus to find. One of
257      *            {@link AccessibilityNodeInfoCompat#FOCUS_INPUT} or
258      *            {@link AccessibilityNodeInfoCompat#FOCUS_ACCESSIBILITY}.
259      * @return The node info of the focused view or null.
260      * @see AccessibilityNodeInfoCompat#FOCUS_INPUT
261      * @see AccessibilityNodeInfoCompat#FOCUS_ACCESSIBILITY
262      */
263     @Nullable
264     public AccessibilityNodeInfoCompat findFocus(int focus) {
265         return null;
266     }
267 }
268