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