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