AccessibilityDelegateCompat.java revision 9648c538bac4f04145c118cc41168d1d7a536312
1/*
2 * Copyright (C) 2011 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;
18
19import android.os.Build;
20import android.support.v4.view.accessibility.AccessibilityNodeInfoCompat;
21import android.view.View;
22import android.view.ViewGroup;
23import android.view.accessibility.AccessibilityEvent;
24
25/**
26 * Helper for accessing AccessibilityDelegate from newer platform versions.
27 */
28public class AccessibilityDelegateCompat {
29
30    static interface AccessibilityDelegateImpl {
31        public Object newAccessiblityDelegateDefaultImpl();
32        public Object newAccessiblityDelegateBridge(AccessibilityDelegateCompat listener);
33        public boolean dispatchPopulateAccessibilityEvent(Object delegate, View host,
34                AccessibilityEvent event);
35        public void onInitializeAccessibilityEvent(Object delegate, View host,
36                AccessibilityEvent event);
37        public void onInitializeAccessibilityNodeInfo(Object delegate, View host, Object info);
38        public void onPopulateAccessibilityEvent(Object delegate, View host,
39                AccessibilityEvent event);
40        public boolean onRequestSendAccessibilityEvent(Object delegate, ViewGroup host, View child,
41                AccessibilityEvent event);
42        public void sendAccessibilityEvent(Object delegate, View host, int eventType);
43        public void sendAccessibilityEventUnchecked(Object delegate, View host,
44                AccessibilityEvent event);
45    }
46
47    static class AccessibilityDelegateStubImpl implements AccessibilityDelegateImpl {
48        public Object newAccessiblityDelegateDefaultImpl() {
49            return null;
50        }
51
52        public Object newAccessiblityDelegateBridge(AccessibilityDelegateCompat listener) {
53            return null;
54        }
55
56        public boolean dispatchPopulateAccessibilityEvent(Object delegate, View host,
57                AccessibilityEvent event) {
58            return false;
59        }
60
61        public void onInitializeAccessibilityEvent(Object delegate, View host,
62                AccessibilityEvent event) {
63
64        }
65
66        public void onInitializeAccessibilityNodeInfo(Object delegate, View host, Object info) {
67
68        }
69
70        public void onPopulateAccessibilityEvent(Object delegate, View host,
71                AccessibilityEvent event) {
72
73        }
74
75        public boolean onRequestSendAccessibilityEvent(Object delegate, ViewGroup host, View child,
76                AccessibilityEvent event) {
77            return true;
78        }
79
80        public void sendAccessibilityEvent(Object delegate, View host, int eventType) {
81
82        }
83
84        public void sendAccessibilityEventUnchecked(Object delegate, View host,
85                AccessibilityEvent event) {
86
87        }
88    }
89
90    static class AccessibilityDelegateIcsImpl extends AccessibilityDelegateStubImpl {
91        @Override
92        public Object newAccessiblityDelegateDefaultImpl() {
93            return AccessibilityDelegateCompatIcs.newAccessibilityDelegateDefaultImpl();
94        }
95
96        @Override
97        public Object newAccessiblityDelegateBridge(final AccessibilityDelegateCompat compat) {
98            return AccessibilityDelegateCompatIcs.newAccessibilityDelegateBridge(
99                    new AccessibilityDelegateCompatIcs.AccessibilityDelegateBridge() {
100                @Override
101                public boolean dispatchPopulateAccessibilityEvent(View host,
102                        AccessibilityEvent event) {
103                    return compat.dispatchPopulateAccessibilityEvent(host, event);
104                }
105
106                @Override
107                public void onInitializeAccessibilityEvent(View host, AccessibilityEvent event) {
108                    compat.onInitializeAccessibilityEvent(host, event);
109                }
110
111                @Override
112                public void onInitializeAccessibilityNodeInfo(View host, Object info) {
113                    compat.onInitializeAccessibilityNodeInfo(host,
114                            new AccessibilityNodeInfoCompat(info));
115                }
116
117                @Override
118                public void onPopulateAccessibilityEvent(View host, AccessibilityEvent event) {
119                    compat.onPopulateAccessibilityEvent(host, event);
120                }
121
122                @Override
123                public boolean onRequestSendAccessibilityEvent(ViewGroup host, View child,
124                        AccessibilityEvent event) {
125                    return compat.onRequestSendAccessibilityEvent(host, child, event);
126                }
127
128                @Override
129                public void sendAccessibilityEvent(View host, int eventType) {
130                    compat.sendAccessibilityEvent(host, eventType);
131                }
132
133                @Override
134                public void sendAccessibilityEventUnchecked(View host, AccessibilityEvent event) {
135                    compat.sendAccessibilityEventUnchecked(host, event);
136                }
137            });
138        }
139
140        @Override
141        public boolean dispatchPopulateAccessibilityEvent(Object delegate, View host,
142                AccessibilityEvent event) {
143            return AccessibilityDelegateCompatIcs.dispatchPopulateAccessibilityEvent(delegate,
144                    host, event);
145        }
146
147        @Override
148        public void onInitializeAccessibilityEvent(Object delegate, View host,
149                AccessibilityEvent event) {
150            AccessibilityDelegateCompatIcs.onInitializeAccessibilityEvent(delegate, host, event);
151        }
152
153        @Override
154        public void onInitializeAccessibilityNodeInfo(Object delegate, View host, Object info) {
155            AccessibilityDelegateCompatIcs.onInitializeAccessibilityNodeInfo(delegate, host, info);
156        }
157
158        @Override
159        public void onPopulateAccessibilityEvent(Object delegate, View host,
160                AccessibilityEvent event) {
161            AccessibilityDelegateCompatIcs.onPopulateAccessibilityEvent(delegate, host, event);
162        }
163
164        @Override
165        public boolean onRequestSendAccessibilityEvent(Object delegate, ViewGroup host, View child,
166                AccessibilityEvent event) {
167            return AccessibilityDelegateCompatIcs.onRequestSendAccessibilityEvent(delegate, host,
168                    child, event);
169        }
170
171        @Override
172        public void sendAccessibilityEvent(Object delegate, View host, int eventType) {
173            AccessibilityDelegateCompatIcs.sendAccessibilityEvent(delegate, host, eventType);
174        }
175
176        @Override
177        public void sendAccessibilityEventUnchecked(Object delegate, View host,
178                AccessibilityEvent event) {
179            AccessibilityDelegateCompatIcs.sendAccessibilityEventUnchecked(delegate, host, event);
180        }
181    }
182
183    private static final AccessibilityDelegateImpl IMPL;
184    private static final Object DEFAULT_DELEGATE;
185
186    static {
187        if (Build.VERSION.SDK_INT >= 14) { // ICS
188            IMPL = new AccessibilityDelegateIcsImpl();
189        } else {
190            IMPL = new AccessibilityDelegateStubImpl();
191        }
192        DEFAULT_DELEGATE = IMPL.newAccessiblityDelegateDefaultImpl();
193    }
194
195    final Object mBridge;
196
197    /**
198     * Creates a new instance.
199     */
200    public AccessibilityDelegateCompat() {
201        mBridge = IMPL.newAccessiblityDelegateBridge(this);
202    }
203
204    /**
205     * @return The wrapped bridge implementation.
206     */
207    Object getBridge() {
208        return mBridge;
209    }
210
211    /**
212     * Sends an accessibility event of the given type. If accessibility is not
213     * enabled this method has no effect.
214     * <p>
215     * The default implementation behaves as {@link View#sendAccessibilityEvent(int)
216     * View#sendAccessibilityEvent(int)} for the case of no accessibility delegate
217     * been set.
218     * </p>
219     *
220     * @param host The View hosting the delegate.
221     * @param eventType The type of the event to send.
222     *
223     * @see View#sendAccessibilityEvent(int) View#sendAccessibilityEvent(int)
224     */
225    public void sendAccessibilityEvent(View host, int eventType) {
226        IMPL.sendAccessibilityEvent(DEFAULT_DELEGATE, host, eventType);
227    }
228
229    /**
230     * Sends an accessibility event. This method behaves exactly as
231     * {@link #sendAccessibilityEvent(View, int)} but takes as an argument an
232     * empty {@link AccessibilityEvent} and does not perform a check whether
233     * accessibility is enabled.
234     * <p>
235     * The default implementation behaves as
236     * {@link View#sendAccessibilityEventUnchecked(AccessibilityEvent)
237     * View#sendAccessibilityEventUnchecked(AccessibilityEvent)} for
238     * the case of no accessibility delegate been set.
239     * </p>
240     *
241     * @param host The View hosting the delegate.
242     * @param event The event to send.
243     *
244     * @see View#sendAccessibilityEventUnchecked(AccessibilityEvent)
245     *      View#sendAccessibilityEventUnchecked(AccessibilityEvent)
246     */
247    public void sendAccessibilityEventUnchecked(View host, AccessibilityEvent event) {
248        IMPL.sendAccessibilityEventUnchecked(DEFAULT_DELEGATE, host, event);
249    }
250
251    /**
252     * Dispatches an {@link AccessibilityEvent} to the host {@link View} first and then
253     * to its children for adding their text content to the event.
254     * <p>
255     * The default implementation behaves as
256     * {@link View#dispatchPopulateAccessibilityEvent(AccessibilityEvent)
257     * View#dispatchPopulateAccessibilityEvent(AccessibilityEvent)} for
258     * the case of no accessibility delegate been set.
259     * </p>
260     *
261     * @param host The View hosting the delegate.
262     * @param event The event.
263     * @return True if the event population was completed.
264     *
265     * @see View#dispatchPopulateAccessibilityEvent(AccessibilityEvent)
266     *      View#dispatchPopulateAccessibilityEvent(AccessibilityEvent)
267     */
268    public boolean dispatchPopulateAccessibilityEvent(View host, AccessibilityEvent event) {
269        return IMPL.dispatchPopulateAccessibilityEvent(DEFAULT_DELEGATE, host, event);
270    }
271
272    /**
273     * Gives a chance to the host View to populate the accessibility event with its
274     * text content.
275     * <p>
276     * The default implementation behaves as
277     * {@link ViewCompat#onPopulateAccessibilityEvent(View, AccessibilityEvent)
278     * ViewCompat#onPopulateAccessibilityEvent(AccessibilityEvent)} for
279     * the case of no accessibility delegate been set.
280     * </p>
281     *
282     * @param host The View hosting the delegate.
283     * @param event The accessibility event which to populate.
284     *
285     * @see ViewCompat#onPopulateAccessibilityEvent(View ,AccessibilityEvent)
286     *      ViewCompat#onPopulateAccessibilityEvent(View, AccessibilityEvent)
287     */
288    public void onPopulateAccessibilityEvent(View host, AccessibilityEvent event) {
289        IMPL.onPopulateAccessibilityEvent(DEFAULT_DELEGATE, host, event);
290    }
291
292    /**
293     * Initializes an {@link AccessibilityEvent} with information about the
294     * the host View which is the event source.
295     * <p>
296     * The default implementation behaves as
297     * {@link ViewCompat#onInitializeAccessibilityEvent(View v, AccessibilityEvent event)
298     * ViewCompat#onInitalizeAccessibilityEvent(View v, AccessibilityEvent event)} for
299     * the case of no accessibility delegate been set.
300     * </p>
301     *
302     * @param host The View hosting the delegate.
303     * @param event The event to initialize.
304     *
305     * @see ViewCompat#onInitializeAccessibilityEvent(View, AccessibilityEvent)
306     *      ViewCompat#onInitializeAccessibilityEvent(View, AccessibilityEvent)
307     */
308    public void onInitializeAccessibilityEvent(View host, AccessibilityEvent event) {
309        IMPL.onInitializeAccessibilityEvent(DEFAULT_DELEGATE, host, event);
310    }
311
312    /**
313     * Initializes an {@link AccessibilityNodeInfoCompat} with information about the host view.
314     * <p>
315     * The default implementation behaves as
316     * {@link ViewCompat#onInitializeAccessibilityNodeInfo(View, AccessibilityNodeInfoCompat)
317     * ViewCompat#onInitializeAccessibilityNodeInfo(View, AccessibilityNodeInfoCompat)} for
318     * the case of no accessibility delegate been set.
319     * </p>
320     *
321     * @param host The View hosting the delegate.
322     * @param info The instance to initialize.
323     *
324     * @see ViewCompat#onInitializeAccessibilityNodeInfo(View, AccessibilityNodeInfoCompat)
325     *      ViewCompat#onInitializeAccessibilityNodeInfo(View, AccessibilityNodeInfoCompat)
326     */
327    public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfoCompat info) {
328        IMPL.onInitializeAccessibilityNodeInfo(DEFAULT_DELEGATE, host, info);
329    }
330
331    /**
332     * Called when a child of the host View has requested sending an
333     * {@link AccessibilityEvent} and gives an opportunity to the parent (the host)
334     * to augment the event.
335     * <p>
336     * The default implementation behaves as
337     * {@link ViewGroupCompat#onRequestSendAccessibilityEvent(ViewGroup, View, AccessibilityEvent)
338     * ViewGroupCompat#onRequestSendAccessibilityEvent(ViewGroup, View, AccessibilityEvent)} for
339     * the case of no accessibility delegate been set.
340     * </p>
341     *
342     * @param host The View hosting the delegate.
343     * @param child The child which requests sending the event.
344     * @param event The event to be sent.
345     * @return True if the event should be sent
346     *
347     * @see ViewGroupCompat#onRequestSendAccessibilityEvent(ViewGroup, View, AccessibilityEvent)
348     *      ViewGroupCompat#onRequestSendAccessibilityEvent(ViewGroup, View, AccessibilityEvent)
349     */
350    public boolean onRequestSendAccessibilityEvent(ViewGroup host, View child,
351            AccessibilityEvent event) {
352        return IMPL.onRequestSendAccessibilityEvent(DEFAULT_DELEGATE, host, child, event);
353    }
354}
355