1956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov/* 2956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov * Copyright (C) 2012 The Android Open Source Project 3956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov * 4956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov * Licensed under the Apache License, Version 2.0 (the "License"); 5956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov * you may not use this file except in compliance with the License. 6956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov * You may obtain a copy of the License at 7956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov * 8956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov * http://www.apache.org/licenses/LICENSE-2.0 9956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov * 10956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov * Unless required by applicable law or agreed to in writing, software 11956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov * distributed under the License is distributed on an "AS IS" BASIS, 12956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov * See the License for the specific language governing permissions and 14956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov * limitations under the License. 15956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov */ 16956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov 17956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganovpackage android.support.v4.view.accessibility; 18956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov 19956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganovimport android.os.Build; 20d16944cf0ad052b56562a56886fed92afbb9b09fSvetoslav Ganovimport android.os.Bundle; 21247fe5ffc924c052589f31dd3888c2aec297d4e1Alan Viveretteimport android.support.annotation.Nullable; 22645e5c8aa6b31961c5f73f3d30bb5261d5e04aebKirill Grouchnikovimport android.support.annotation.RequiresApi; 232590f2bc16dfd06592c27bacd760136bdc1adabdAurimas Liutikasimport android.view.accessibility.AccessibilityNodeInfo; 242590f2bc16dfd06592c27bacd760136bdc1adabdAurimas Liutikasimport android.view.accessibility.AccessibilityNodeProvider; 25956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov 26956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganovimport java.util.ArrayList; 27956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganovimport java.util.List; 28956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov 29956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov/** 30645e5c8aa6b31961c5f73f3d30bb5261d5e04aebKirill Grouchnikov * Helper for accessing {@link android.view.accessibility.AccessibilityNodeProvider}. 31956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov */ 32956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganovpublic class AccessibilityNodeProviderCompat { 332590f2bc16dfd06592c27bacd760136bdc1adabdAurimas Liutikas @RequiresApi(16) 342590f2bc16dfd06592c27bacd760136bdc1adabdAurimas Liutikas static class AccessibilityNodeProviderApi16 extends AccessibilityNodeProvider { 352590f2bc16dfd06592c27bacd760136bdc1adabdAurimas Liutikas final AccessibilityNodeProviderCompat mCompat; 36956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov 372590f2bc16dfd06592c27bacd760136bdc1adabdAurimas Liutikas AccessibilityNodeProviderApi16(AccessibilityNodeProviderCompat compat) { 382590f2bc16dfd06592c27bacd760136bdc1adabdAurimas Liutikas mCompat = compat; 392590f2bc16dfd06592c27bacd760136bdc1adabdAurimas Liutikas } 40956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov 41956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov @Override 422590f2bc16dfd06592c27bacd760136bdc1adabdAurimas Liutikas public AccessibilityNodeInfo createAccessibilityNodeInfo(int virtualViewId) { 432590f2bc16dfd06592c27bacd760136bdc1adabdAurimas Liutikas final AccessibilityNodeInfoCompat compatInfo = 442590f2bc16dfd06592c27bacd760136bdc1adabdAurimas Liutikas mCompat.createAccessibilityNodeInfo(virtualViewId); 452590f2bc16dfd06592c27bacd760136bdc1adabdAurimas Liutikas if (compatInfo == null) { 462590f2bc16dfd06592c27bacd760136bdc1adabdAurimas Liutikas return null; 472590f2bc16dfd06592c27bacd760136bdc1adabdAurimas Liutikas } else { 482590f2bc16dfd06592c27bacd760136bdc1adabdAurimas Liutikas return compatInfo.unwrap(); 492590f2bc16dfd06592c27bacd760136bdc1adabdAurimas Liutikas } 50956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov } 51956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov 522590f2bc16dfd06592c27bacd760136bdc1adabdAurimas Liutikas @Override 532590f2bc16dfd06592c27bacd760136bdc1adabdAurimas Liutikas public List<AccessibilityNodeInfo> findAccessibilityNodeInfosByText( 542590f2bc16dfd06592c27bacd760136bdc1adabdAurimas Liutikas String text, int virtualViewId) { 552590f2bc16dfd06592c27bacd760136bdc1adabdAurimas Liutikas final List<AccessibilityNodeInfoCompat> compatInfos = 562590f2bc16dfd06592c27bacd760136bdc1adabdAurimas Liutikas mCompat.findAccessibilityNodeInfosByText(text, virtualViewId); 572590f2bc16dfd06592c27bacd760136bdc1adabdAurimas Liutikas if (compatInfos == null) { 582590f2bc16dfd06592c27bacd760136bdc1adabdAurimas Liutikas return null; 592590f2bc16dfd06592c27bacd760136bdc1adabdAurimas Liutikas } else { 602590f2bc16dfd06592c27bacd760136bdc1adabdAurimas Liutikas final List<AccessibilityNodeInfo> infoList = new ArrayList<>(); 612590f2bc16dfd06592c27bacd760136bdc1adabdAurimas Liutikas final int infoCount = compatInfos.size(); 622590f2bc16dfd06592c27bacd760136bdc1adabdAurimas Liutikas for (int i = 0; i < infoCount; i++) { 632590f2bc16dfd06592c27bacd760136bdc1adabdAurimas Liutikas AccessibilityNodeInfoCompat infoCompat = compatInfos.get(i); 642590f2bc16dfd06592c27bacd760136bdc1adabdAurimas Liutikas infoList.add(infoCompat.unwrap()); 652590f2bc16dfd06592c27bacd760136bdc1adabdAurimas Liutikas } 662590f2bc16dfd06592c27bacd760136bdc1adabdAurimas Liutikas return infoList; 672590f2bc16dfd06592c27bacd760136bdc1adabdAurimas Liutikas } 68552766fa685c63ad760c92239faaba12e6ad51f1Aurimas Liutikas } 69552766fa685c63ad760c92239faaba12e6ad51f1Aurimas Liutikas 70956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov @Override 712590f2bc16dfd06592c27bacd760136bdc1adabdAurimas Liutikas public boolean performAction(int virtualViewId, int action, Bundle arguments) { 722590f2bc16dfd06592c27bacd760136bdc1adabdAurimas Liutikas return mCompat.performAction(virtualViewId, action, arguments); 73956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov } 74956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov } 75956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov 76c69882cb9b130902c1554ef5d3e3b06d776cd796Alan Viverette @RequiresApi(19) 772590f2bc16dfd06592c27bacd760136bdc1adabdAurimas Liutikas static class AccessibilityNodeProviderApi19 extends AccessibilityNodeProviderApi16 { 782590f2bc16dfd06592c27bacd760136bdc1adabdAurimas Liutikas AccessibilityNodeProviderApi19(AccessibilityNodeProviderCompat compat) { 792590f2bc16dfd06592c27bacd760136bdc1adabdAurimas Liutikas super(compat); 80552766fa685c63ad760c92239faaba12e6ad51f1Aurimas Liutikas } 81552766fa685c63ad760c92239faaba12e6ad51f1Aurimas Liutikas 82b44045ec70f92d559fe6642e9bdb49ca37cb9f71Alan Viverette @Override 832590f2bc16dfd06592c27bacd760136bdc1adabdAurimas Liutikas public AccessibilityNodeInfo findFocus(int focus) { 842590f2bc16dfd06592c27bacd760136bdc1adabdAurimas Liutikas final AccessibilityNodeInfoCompat compatInfo = mCompat.findFocus(focus); 852590f2bc16dfd06592c27bacd760136bdc1adabdAurimas Liutikas if (compatInfo == null) { 862590f2bc16dfd06592c27bacd760136bdc1adabdAurimas Liutikas return null; 872590f2bc16dfd06592c27bacd760136bdc1adabdAurimas Liutikas } else { 882590f2bc16dfd06592c27bacd760136bdc1adabdAurimas Liutikas return compatInfo.unwrap(); 892590f2bc16dfd06592c27bacd760136bdc1adabdAurimas Liutikas } 90b44045ec70f92d559fe6642e9bdb49ca37cb9f71Alan Viverette } 91b44045ec70f92d559fe6642e9bdb49ca37cb9f71Alan Viverette } 92b44045ec70f92d559fe6642e9bdb49ca37cb9f71Alan Viverette 93dcb9c07ac922c022750a803a74e4bb98a4bd8693Abhinav Baid /** 94dcb9c07ac922c022750a803a74e4bb98a4bd8693Abhinav Baid * The virtual id for the hosting View. 95dcb9c07ac922c022750a803a74e4bb98a4bd8693Abhinav Baid */ 96dcb9c07ac922c022750a803a74e4bb98a4bd8693Abhinav Baid public static final int HOST_VIEW_ID = -1; 97dcb9c07ac922c022750a803a74e4bb98a4bd8693Abhinav Baid 98956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov private final Object mProvider; 99956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov 100956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov /** 101956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov * Creates a new instance. 102956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov */ 103956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov public AccessibilityNodeProviderCompat() { 1042590f2bc16dfd06592c27bacd760136bdc1adabdAurimas Liutikas if (Build.VERSION.SDK_INT >= 19) { 1052590f2bc16dfd06592c27bacd760136bdc1adabdAurimas Liutikas mProvider = new AccessibilityNodeProviderApi19(this); 1062590f2bc16dfd06592c27bacd760136bdc1adabdAurimas Liutikas } else if (Build.VERSION.SDK_INT >= 16) { 1072590f2bc16dfd06592c27bacd760136bdc1adabdAurimas Liutikas mProvider = new AccessibilityNodeProviderApi16(this); 1082590f2bc16dfd06592c27bacd760136bdc1adabdAurimas Liutikas } else { 1092590f2bc16dfd06592c27bacd760136bdc1adabdAurimas Liutikas mProvider = null; 1102590f2bc16dfd06592c27bacd760136bdc1adabdAurimas Liutikas } 111956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov } 112956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov 113956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov /** 114956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov * Creates a new instance wrapping an 115956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov * {@link android.view.accessibility.AccessibilityNodeProvider}. 116956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov * 117956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov * @param provider The provider. 118956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov */ 119956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov public AccessibilityNodeProviderCompat(Object provider) { 120956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov mProvider = provider; 121956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov } 122956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov 123956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov /** 124956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov * @return The wrapped {@link android.view.accessibility.AccessibilityNodeProvider}. 125956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov */ 126956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov public Object getProvider() { 127956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov return mProvider; 128956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov } 129956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov 130956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov /** 131956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov * Returns an {@link AccessibilityNodeInfoCompat} representing a virtual view, 132956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov * i.e. a descendant of the host View, with the given <code>virtualViewId</code> 133dcb9c07ac922c022750a803a74e4bb98a4bd8693Abhinav Baid * or the host View itself if <code>virtualViewId</code> equals to {@link #HOST_VIEW_ID}. 134956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov * <p> 135956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov * A virtual descendant is an imaginary View that is reported as a part of the view 136956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov * hierarchy for accessibility purposes. This enables custom views that draw complex 137956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov * content to report them selves as a tree of virtual views, thus conveying their 138956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov * logical structure. 139956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov * </p> 140956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov * <p> 141956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov * The implementer is responsible for obtaining an accessibility node info from the 142956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov * pool of reusable instances and setting the desired properties of the node info 143956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov * before returning it. 144956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov * </p> 145956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov * 146956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov * @param virtualViewId A client defined virtual view id. 147956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov * @return A populated {@link AccessibilityNodeInfoCompat} for a virtual descendant 148956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov * or the host View. 149956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov * 150956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov * @see AccessibilityNodeInfoCompat 151956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov */ 152247fe5ffc924c052589f31dd3888c2aec297d4e1Alan Viverette @Nullable 153956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov public AccessibilityNodeInfoCompat createAccessibilityNodeInfo(int virtualViewId) { 154956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov return null; 155956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov } 156956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov 157956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov /** 158956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov * Performs an accessibility action on a virtual view, i.e. a descendant of the 159956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov * host View, with the given <code>virtualViewId</code> or the host View itself 160dcb9c07ac922c022750a803a74e4bb98a4bd8693Abhinav Baid * if <code>virtualViewId</code> equals to {@link #HOST_VIEW_ID}. 161956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov * 162956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov * @param virtualViewId A client defined virtual view id. 163d16944cf0ad052b56562a56886fed92afbb9b09fSvetoslav Ganov * @param action The action to perform. 164d16944cf0ad052b56562a56886fed92afbb9b09fSvetoslav Ganov * @param arguments Optional arguments. 165956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov * @return True if the action was performed. 166956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov * 167956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov * @see #createAccessibilityNodeInfo(int) 168956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov * @see AccessibilityNodeInfoCompat 169956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov */ 170d16944cf0ad052b56562a56886fed92afbb9b09fSvetoslav Ganov public boolean performAction(int virtualViewId, int action, Bundle arguments) { 171956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov return false; 172956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov } 173956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov 174956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov /** 175956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov * Finds {@link AccessibilityNodeInfoCompat}s by text. The match is case insensitive 176956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov * containment. The search is relative to the virtual view, i.e. a descendant of the 177956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov * host View, with the given <code>virtualViewId</code> or the host View itself 178dcb9c07ac922c022750a803a74e4bb98a4bd8693Abhinav Baid * <code>virtualViewId</code> equals to {@link #HOST_VIEW_ID}. 179956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov * 180956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov * @param virtualViewId A client defined virtual view id which defined 181956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov * the root of the tree in which to perform the search. 182956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov * @param text The searched text. 183956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov * @return A list of node info. 184956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov * 185956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov * @see #createAccessibilityNodeInfo(int) 186956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov * @see AccessibilityNodeInfoCompat 187956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov */ 188247fe5ffc924c052589f31dd3888c2aec297d4e1Alan Viverette @Nullable 189956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov public List<AccessibilityNodeInfoCompat> findAccessibilityNodeInfosByText(String text, 190956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov int virtualViewId) { 191956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov return null; 192956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov } 193b44045ec70f92d559fe6642e9bdb49ca37cb9f71Alan Viverette 194b44045ec70f92d559fe6642e9bdb49ca37cb9f71Alan Viverette /** 195b44045ec70f92d559fe6642e9bdb49ca37cb9f71Alan Viverette * Find the virtual view, i.e. a descendant of the host View, that has the 196b44045ec70f92d559fe6642e9bdb49ca37cb9f71Alan Viverette * specified focus type. 197b44045ec70f92d559fe6642e9bdb49ca37cb9f71Alan Viverette * 198b44045ec70f92d559fe6642e9bdb49ca37cb9f71Alan Viverette * @param focus The focus to find. One of 199b44045ec70f92d559fe6642e9bdb49ca37cb9f71Alan Viverette * {@link AccessibilityNodeInfoCompat#FOCUS_INPUT} or 200b44045ec70f92d559fe6642e9bdb49ca37cb9f71Alan Viverette * {@link AccessibilityNodeInfoCompat#FOCUS_ACCESSIBILITY}. 201b44045ec70f92d559fe6642e9bdb49ca37cb9f71Alan Viverette * @return The node info of the focused view or null. 202b44045ec70f92d559fe6642e9bdb49ca37cb9f71Alan Viverette * @see AccessibilityNodeInfoCompat#FOCUS_INPUT 203b44045ec70f92d559fe6642e9bdb49ca37cb9f71Alan Viverette * @see AccessibilityNodeInfoCompat#FOCUS_ACCESSIBILITY 204b44045ec70f92d559fe6642e9bdb49ca37cb9f71Alan Viverette */ 205247fe5ffc924c052589f31dd3888c2aec297d4e1Alan Viverette @Nullable 206b44045ec70f92d559fe6642e9bdb49ca37cb9f71Alan Viverette public AccessibilityNodeInfoCompat findFocus(int focus) { 207b44045ec70f92d559fe6642e9bdb49ca37cb9f71Alan Viverette return null; 208b44045ec70f92d559fe6642e9bdb49ca37cb9f71Alan Viverette } 209956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov} 210