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