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;
21956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganovimport android.view.View;
22956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov
23956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganovimport java.util.ArrayList;
24956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganovimport java.util.List;
25956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov
26956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov/**
27956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov * Helper for accessing {@link android.view.accessibility.AccessibilityNodeProvider}
28956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov * introduced after API level 4 in a backwards compatible fashion.
29956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov */
30956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganovpublic class AccessibilityNodeProviderCompat {
31956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov
32956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov    interface AccessibilityNodeProviderImpl {
33956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov        public Object newAccessibilityNodeProviderBridge(AccessibilityNodeProviderCompat compat);
34956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov    }
35956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov
36956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov    static class AccessibilityNodeProviderStubImpl implements AccessibilityNodeProviderImpl {
37956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov        @Override
38956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov        public Object newAccessibilityNodeProviderBridge(AccessibilityNodeProviderCompat compat) {
39956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov            return null;
40956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov        }
41956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov    }
42956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov
43956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov    static class AccessibilityNodeProviderJellyBeanImpl extends AccessibilityNodeProviderStubImpl {
44956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov        @Override
45956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov        public Object newAccessibilityNodeProviderBridge(
46956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov                final AccessibilityNodeProviderCompat compat) {
47956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov            return AccessibilityNodeProviderCompatJellyBean.newAccessibilityNodeProviderBridge(
48956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov                    new AccessibilityNodeProviderCompatJellyBean.AccessibilityNodeInfoBridge() {
49956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov                        @Override
50d16944cf0ad052b56562a56886fed92afbb9b09fSvetoslav Ganov                        public boolean performAction(int virtualViewId, int action,
51d16944cf0ad052b56562a56886fed92afbb9b09fSvetoslav Ganov                                Bundle arguments) {
52d16944cf0ad052b56562a56886fed92afbb9b09fSvetoslav Ganov                            return compat.performAction(virtualViewId, action, arguments);
53956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov                        }
54956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov
55956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov                        @Override
56956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov                        public List<Object> findAccessibilityNodeInfosByText(
57956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov                                            String text, int virtualViewId) {
58956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov                            List<AccessibilityNodeInfoCompat> compatInfos =
59956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov                                compat.findAccessibilityNodeInfosByText(text, virtualViewId);
60956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov                            List<Object> infos = new ArrayList<Object>();
61956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov                            final int infoCount = compatInfos.size();
62956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov                            for (int i = 0; i < infoCount; i++) {
63956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov                                AccessibilityNodeInfoCompat infoCompat = compatInfos.get(i);
64956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov                                infos.add(infoCompat.getInfo());
65956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov                            }
66956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov                            return infos;
67956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov                        }
68956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov
69956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov                        @Override
70956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov                        public Object createAccessibilityNodeInfo(
71956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov                                int virtualViewId) {
72b1d4cb28db8b08974b651665bf4d1a7926c17b9calanv                            final AccessibilityNodeInfoCompat compatInfo = compat
73b1d4cb28db8b08974b651665bf4d1a7926c17b9calanv                                    .createAccessibilityNodeInfo(virtualViewId);
74b1d4cb28db8b08974b651665bf4d1a7926c17b9calanv                            if (compatInfo == null) {
75b1d4cb28db8b08974b651665bf4d1a7926c17b9calanv                                return null;
76b1d4cb28db8b08974b651665bf4d1a7926c17b9calanv                            } else {
77b1d4cb28db8b08974b651665bf4d1a7926c17b9calanv                                return compatInfo.getInfo();
78b1d4cb28db8b08974b651665bf4d1a7926c17b9calanv                            }
79b1d4cb28db8b08974b651665bf4d1a7926c17b9calanv                        }
80956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov                    });
81956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov        }
82956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov    }
83956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov
84956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov    private static final AccessibilityNodeProviderImpl IMPL;
85956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov
86956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov    private final Object mProvider;
87956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov
88956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov    static {
89f3ed7c56e6c409d27c60f7d74c026906593c21d4Svetoslav Ganov        if (Build.VERSION.SDK_INT >= 16) { // JellyBean
90956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov            IMPL = new AccessibilityNodeProviderJellyBeanImpl();
91956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov        } else {
92956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov            IMPL = new AccessibilityNodeProviderStubImpl();
93956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov        }
94956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov    }
95956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov
96956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov    /**
97956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov     * Creates a new instance.
98956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov     */
99956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov    public AccessibilityNodeProviderCompat() {
100956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov        mProvider = IMPL.newAccessibilityNodeProviderBridge(this);
101956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov    }
102956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov
103956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov    /**
104956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov     * Creates a new instance wrapping an
105956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov     * {@link android.view.accessibility.AccessibilityNodeProvider}.
106956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov     *
107956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov     * @param provider The provider.
108956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov     */
109956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov    public AccessibilityNodeProviderCompat(Object provider) {
110956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov        mProvider = provider;
111956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov    }
112956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov
113956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov    /**
114956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov     * @return The wrapped {@link android.view.accessibility.AccessibilityNodeProvider}.
115956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov     */
116956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov    public Object getProvider() {
117956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov        return mProvider;
118956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov    }
119956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov
120956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov    /**
121956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov     * Returns an {@link AccessibilityNodeInfoCompat} representing a virtual view,
122956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov     * i.e. a descendant of the host View, with the given <code>virtualViewId</code>
123956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov     * or the host View itself if <code>virtualViewId</code> equals to {@link View#NO_ID}.
124956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov     * <p>
125956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov     * A virtual descendant is an imaginary View that is reported as a part of the view
126956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov     * hierarchy for accessibility purposes. This enables custom views that draw complex
127956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov     * content to report them selves as a tree of virtual views, thus conveying their
128956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov     * logical structure.
129956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov     * </p>
130956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov     * <p>
131956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov     * The implementer is responsible for obtaining an accessibility node info from the
132956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov     * pool of reusable instances and setting the desired properties of the node info
133956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov     * before returning it.
134956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov     * </p>
135956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov     *
136956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov     * @param virtualViewId A client defined virtual view id.
137956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov     * @return A populated {@link AccessibilityNodeInfoCompat} for a virtual descendant
138956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov     *     or the host View.
139956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov     *
140956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov     * @see AccessibilityNodeInfoCompat
141956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov     */
142956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov    public AccessibilityNodeInfoCompat createAccessibilityNodeInfo(int virtualViewId) {
143956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov        return null;
144956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov    }
145956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov
146956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov    /**
147956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov     * Performs an accessibility action on a virtual view, i.e. a descendant of the
148956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov     * host View, with the given <code>virtualViewId</code> or the host View itself
149956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov     * if <code>virtualViewId</code> equals to {@link View#NO_ID}.
150956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov     *
151956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov     * @param virtualViewId A client defined virtual view id.
152d16944cf0ad052b56562a56886fed92afbb9b09fSvetoslav Ganov     * @param action The action to perform.
153d16944cf0ad052b56562a56886fed92afbb9b09fSvetoslav Ganov     * @param arguments Optional arguments.
154956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov     * @return True if the action was performed.
155956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov     *
156956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov     * @see #createAccessibilityNodeInfo(int)
157956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov     * @see AccessibilityNodeInfoCompat
158956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov     */
159d16944cf0ad052b56562a56886fed92afbb9b09fSvetoslav Ganov    public boolean performAction(int virtualViewId, int action, Bundle arguments) {
160956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov        return false;
161956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov    }
162956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov
163956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov    /**
164956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov     * Finds {@link AccessibilityNodeInfoCompat}s by text. The match is case insensitive
165956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov     * containment. The search is relative to the virtual view, i.e. a descendant of the
166956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov     * host View, with the given <code>virtualViewId</code> or the host View itself
167956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov     * <code>virtualViewId</code> equals to {@link View#NO_ID}.
168956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov     *
169956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov     * @param virtualViewId A client defined virtual view id which defined
170956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov     *     the root of the tree in which to perform the search.
171956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov     * @param text The searched text.
172956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov     * @return A list of node info.
173956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov     *
174956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov     * @see #createAccessibilityNodeInfo(int)
175956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov     * @see AccessibilityNodeInfoCompat
176956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov     */
177956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov    public List<AccessibilityNodeInfoCompat> findAccessibilityNodeInfosByText(String text,
178956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov            int virtualViewId) {
179956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov        return null;
180956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov    }
181956b013dfda37760b0232ed6d448900a546d2903Svetoslav Ganov}
182