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