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