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    private static final AccessibilityNodeProviderImpl IMPL;
85
86    private final Object mProvider;
87
88    static {
89        if (Build.VERSION.SDK_INT >= 16) { // JellyBean
90            IMPL = new AccessibilityNodeProviderJellyBeanImpl();
91        } else {
92            IMPL = new AccessibilityNodeProviderStubImpl();
93        }
94    }
95
96    /**
97     * Creates a new instance.
98     */
99    public AccessibilityNodeProviderCompat() {
100        mProvider = IMPL.newAccessibilityNodeProviderBridge(this);
101    }
102
103    /**
104     * Creates a new instance wrapping an
105     * {@link android.view.accessibility.AccessibilityNodeProvider}.
106     *
107     * @param provider The provider.
108     */
109    public AccessibilityNodeProviderCompat(Object provider) {
110        mProvider = provider;
111    }
112
113    /**
114     * @return The wrapped {@link android.view.accessibility.AccessibilityNodeProvider}.
115     */
116    public Object getProvider() {
117        return mProvider;
118    }
119
120    /**
121     * Returns an {@link AccessibilityNodeInfoCompat} representing a virtual view,
122     * i.e. a descendant of the host View, with the given <code>virtualViewId</code>
123     * or the host View itself if <code>virtualViewId</code> equals to {@link View#NO_ID}.
124     * <p>
125     * A virtual descendant is an imaginary View that is reported as a part of the view
126     * hierarchy for accessibility purposes. This enables custom views that draw complex
127     * content to report them selves as a tree of virtual views, thus conveying their
128     * logical structure.
129     * </p>
130     * <p>
131     * The implementer is responsible for obtaining an accessibility node info from the
132     * pool of reusable instances and setting the desired properties of the node info
133     * before returning it.
134     * </p>
135     *
136     * @param virtualViewId A client defined virtual view id.
137     * @return A populated {@link AccessibilityNodeInfoCompat} for a virtual descendant
138     *     or the host View.
139     *
140     * @see AccessibilityNodeInfoCompat
141     */
142    public AccessibilityNodeInfoCompat createAccessibilityNodeInfo(int virtualViewId) {
143        return null;
144    }
145
146    /**
147     * Performs an accessibility action on a virtual view, i.e. a descendant of the
148     * host View, with the given <code>virtualViewId</code> or the host View itself
149     * if <code>virtualViewId</code> equals to {@link View#NO_ID}.
150     *
151     * @param virtualViewId A client defined virtual view id.
152     * @param action The action to perform.
153     * @param arguments Optional arguments.
154     * @return True if the action was performed.
155     *
156     * @see #createAccessibilityNodeInfo(int)
157     * @see AccessibilityNodeInfoCompat
158     */
159    public boolean performAction(int virtualViewId, int action, Bundle arguments) {
160        return false;
161    }
162
163    /**
164     * Finds {@link AccessibilityNodeInfoCompat}s by text. The match is case insensitive
165     * containment. The search is relative to the virtual view, i.e. a descendant of the
166     * host View, with the given <code>virtualViewId</code> or the host View itself
167     * <code>virtualViewId</code> equals to {@link View#NO_ID}.
168     *
169     * @param virtualViewId A client defined virtual view id which defined
170     *     the root of the tree in which to perform the search.
171     * @param text The searched text.
172     * @return A list of node info.
173     *
174     * @see #createAccessibilityNodeInfo(int)
175     * @see AccessibilityNodeInfoCompat
176     */
177    public List<AccessibilityNodeInfoCompat> findAccessibilityNodeInfosByText(String text,
178            int virtualViewId) {
179        return null;
180    }
181}
182