ViewCompat.java revision 7cf0b33a31b57e78a06214a43f580598e0f35031
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.graphics.Paint;
20import android.graphics.Rect;
21import android.os.Bundle;
22import android.support.v4.view.accessibility.AccessibilityNodeInfoCompat;
23import android.support.v4.view.accessibility.AccessibilityNodeProviderCompat;
24import android.view.View;
25import android.view.accessibility.AccessibilityEvent;
26
27/**
28 * Helper for accessing features in {@link View} introduced after API
29 * level 4 in a backwards compatible fashion.
30 */
31public class ViewCompat {
32    /**
33     * Always allow a user to over-scroll this view, provided it is a
34     * view that can scroll.
35     */
36    public static final int OVER_SCROLL_ALWAYS = 0;
37
38    /**
39     * Allow a user to over-scroll this view only if the content is large
40     * enough to meaningfully scroll, provided it is a view that can scroll.
41     */
42    public static final int OVER_SCROLL_IF_CONTENT_SCROLLS = 1;
43
44    /**
45     * Never allow a user to over-scroll this view.
46     */
47    public static final int OVER_SCROLL_NEVER = 2;
48
49    private static final long FAKE_FRAME_TIME = 10;
50
51    /**
52     * Automatically determine whether a view is important for accessibility.
53     */
54    public static final int IMPORTANT_FOR_ACCESSIBILITY_AUTO = 0x00000000;
55
56    /**
57     * The view is important for accessibility.
58     */
59    public static final int IMPORTANT_FOR_ACCESSIBILITY_YES = 0x00000001;
60
61    /**
62     * The view is not important for accessibility.
63     */
64    public static final int IMPORTANT_FOR_ACCESSIBILITY_NO = 0x00000002;
65
66    /**
67     * Indicates that the view does not have a layer.
68     */
69    public static final int LAYER_TYPE_NONE = 0;
70
71    /**
72     * <p>Indicates that the view has a software layer. A software layer is backed
73     * by a bitmap and causes the view to be rendered using Android's software
74     * rendering pipeline, even if hardware acceleration is enabled.</p>
75     *
76     * <p>Software layers have various usages:</p>
77     * <p>When the application is not using hardware acceleration, a software layer
78     * is useful to apply a specific color filter and/or blending mode and/or
79     * translucency to a view and all its children.</p>
80     * <p>When the application is using hardware acceleration, a software layer
81     * is useful to render drawing primitives not supported by the hardware
82     * accelerated pipeline. It can also be used to cache a complex view tree
83     * into a texture and reduce the complexity of drawing operations. For instance,
84     * when animating a complex view tree with a translation, a software layer can
85     * be used to render the view tree only once.</p>
86     * <p>Software layers should be avoided when the affected view tree updates
87     * often. Every update will require to re-render the software layer, which can
88     * potentially be slow (particularly when hardware acceleration is turned on
89     * since the layer will have to be uploaded into a hardware texture after every
90     * update.)</p>
91     */
92    public static final int LAYER_TYPE_SOFTWARE = 1;
93
94    /**
95     * <p>Indicates that the view has a hardware layer. A hardware layer is backed
96     * by a hardware specific texture (generally Frame Buffer Objects or FBO on
97     * OpenGL hardware) and causes the view to be rendered using Android's hardware
98     * rendering pipeline, but only if hardware acceleration is turned on for the
99     * view hierarchy. When hardware acceleration is turned off, hardware layers
100     * behave exactly as {@link #LAYER_TYPE_SOFTWARE software layers}.</p>
101     *
102     * <p>A hardware layer is useful to apply a specific color filter and/or
103     * blending mode and/or translucency to a view and all its children.</p>
104     * <p>A hardware layer can be used to cache a complex view tree into a
105     * texture and reduce the complexity of drawing operations. For instance,
106     * when animating a complex view tree with a translation, a hardware layer can
107     * be used to render the view tree only once.</p>
108     * <p>A hardware layer can also be used to increase the rendering quality when
109     * rotation transformations are applied on a view. It can also be used to
110     * prevent potential clipping issues when applying 3D transforms on a view.</p>
111     */
112    public static final int LAYER_TYPE_HARDWARE = 2;
113
114    interface ViewCompatImpl {
115        public boolean canScrollHorizontally(View v, int direction);
116        public boolean canScrollVertically(View v, int direction);
117        public int getOverScrollMode(View v);
118        public void setOverScrollMode(View v, int mode);
119        public void onInitializeAccessibilityEvent(View v, AccessibilityEvent event);
120        public void onPopulateAccessibilityEvent(View v, AccessibilityEvent event);
121        public void onInitializeAccessibilityNodeInfo(View v, AccessibilityNodeInfoCompat info);
122        public void setAccessibilityDelegate(View v, AccessibilityDelegateCompat delegate);
123        public boolean hasTransientState(View view);
124        public void setHasTransientState(View view, boolean hasTransientState);
125        public void postInvalidateOnAnimation(View view);
126        public void postInvalidateOnAnimation(View view, int left, int top, int right, int bottom);
127        public void postOnAnimation(View view, Runnable action);
128        public void postOnAnimationDelayed(View view, Runnable action, long delayMillis);
129        public int getImportantForAccessibility(View view);
130        public void setImportantForAccessibility(View view, int mode);
131        public boolean performAccessibilityAction(View view, int action, Bundle arguments);
132        public AccessibilityNodeProviderCompat getAccessibilityNodeProvider(View view);
133        public void setLayerType(View view, int layerType, Paint paint);
134        public int getLayerType(View view);
135        public int getLabelFor(View view);
136        public void setLabelFor(View view, int id);;
137    }
138
139    static class BaseViewCompatImpl implements ViewCompatImpl {
140        public boolean canScrollHorizontally(View v, int direction) {
141            return false;
142        }
143        public boolean canScrollVertically(View v, int direction) {
144            return false;
145        }
146        public int getOverScrollMode(View v) {
147            return OVER_SCROLL_NEVER;
148        }
149        public void setOverScrollMode(View v, int mode) {
150            // Do nothing; API doesn't exist
151        }
152        public void setAccessibilityDelegate(View v, AccessibilityDelegateCompat delegate) {
153            // Do nothing; API doesn't exist
154        }
155        public void onPopulateAccessibilityEvent(View v, AccessibilityEvent event) {
156            // Do nothing; API doesn't exist
157        }
158        public void onInitializeAccessibilityEvent(View v, AccessibilityEvent event) {
159         // Do nothing; API doesn't exist
160        }
161        public void onInitializeAccessibilityNodeInfo(View v, AccessibilityNodeInfoCompat info) {
162            // Do nothing; API doesn't exist
163        }
164        public boolean hasTransientState(View view) {
165            // A view can't have transient state if transient state wasn't supported.
166            return false;
167        }
168        public void setHasTransientState(View view, boolean hasTransientState) {
169            // Do nothing; API doesn't exist
170        }
171        public void postInvalidateOnAnimation(View view) {
172            view.postInvalidateDelayed(getFrameTime());
173        }
174        public void postInvalidateOnAnimation(View view, int left, int top, int right, int bottom) {
175            view.postInvalidateDelayed(getFrameTime(), left, top, right, bottom);
176        }
177        public void postOnAnimation(View view, Runnable action) {
178            view.postDelayed(action, getFrameTime());
179        }
180        public void postOnAnimationDelayed(View view, Runnable action, long delayMillis) {
181            view.postDelayed(action, getFrameTime() + delayMillis);
182        }
183        long getFrameTime() {
184            return FAKE_FRAME_TIME;
185        }
186        public int getImportantForAccessibility(View view) {
187            return 0;
188        }
189        public void setImportantForAccessibility(View view, int mode) {
190
191        }
192        public boolean performAccessibilityAction(View view, int action, Bundle arguments) {
193            return false;
194        }
195        public AccessibilityNodeProviderCompat getAccessibilityNodeProvider(View view) {
196            return null;
197        }
198        public void setLayerType(View view, int layerType, Paint paint) {
199        }
200        public int getLayerType(View view) {
201            return LAYER_TYPE_NONE;
202        }
203        public int getLabelFor(View view) {
204            return 0;
205        }
206        public void setLabelFor(View view, int id) {
207
208        }
209    }
210
211    static class GBViewCompatImpl extends BaseViewCompatImpl {
212        @Override
213        public int getOverScrollMode(View v) {
214            return ViewCompatGingerbread.getOverScrollMode(v);
215        }
216        @Override
217        public void setOverScrollMode(View v, int mode) {
218            ViewCompatGingerbread.setOverScrollMode(v, mode);
219        }
220    }
221
222    static class HCViewCompatImpl extends GBViewCompatImpl {
223        long getFrameTime() {
224            return ViewCompatHC.getFrameTime();
225        }
226        @Override public void setLayerType(View view, int layerType, Paint paint) {
227            ViewCompatHC.setLayerType(view, layerType, paint);
228        }
229        @Override public int getLayerType(View view)  {
230            return ViewCompatHC.getLayerType(view);
231        }
232    }
233
234    static class ICSViewCompatImpl extends HCViewCompatImpl {
235        @Override
236        public boolean canScrollHorizontally(View v, int direction) {
237            return ViewCompatICS.canScrollHorizontally(v, direction);
238        }
239        @Override
240        public boolean canScrollVertically(View v, int direction) {
241            return ViewCompatICS.canScrollVertically(v, direction);
242        }
243        @Override
244        public void onPopulateAccessibilityEvent(View v, AccessibilityEvent event) {
245            ViewCompatICS.onPopulateAccessibilityEvent(v, event);
246        }
247        @Override
248        public void onInitializeAccessibilityEvent(View v, AccessibilityEvent event) {
249            ViewCompatICS.onInitializeAccessibilityEvent(v, event);
250        }
251        @Override
252        public void onInitializeAccessibilityNodeInfo(View v, AccessibilityNodeInfoCompat info) {
253            ViewCompatICS.onInitializeAccessibilityNodeInfo(v, info.getInfo());
254        }
255        @Override
256        public void setAccessibilityDelegate(View v, AccessibilityDelegateCompat delegate) {
257            ViewCompatICS.setAccessibilityDelegate(v, delegate.getBridge());
258        }
259    }
260
261    static class JBViewCompatImpl extends ICSViewCompatImpl {
262        @Override
263        public boolean hasTransientState(View view) {
264            return ViewCompatJB.hasTransientState(view);
265        }
266        @Override
267        public void setHasTransientState(View view, boolean hasTransientState) {
268            ViewCompatJB.setHasTransientState(view, hasTransientState);
269        }
270        @Override
271        public void postInvalidateOnAnimation(View view) {
272            ViewCompatJB.postInvalidateOnAnimation(view);
273        }
274        @Override
275        public void postInvalidateOnAnimation(View view, int left, int top, int right, int bottom) {
276            ViewCompatJB.postInvalidateOnAnimation(view, left, top, right, bottom);
277        }
278        @Override
279        public void postOnAnimation(View view, Runnable action) {
280            ViewCompatJB.postOnAnimation(view, action);
281        }
282        @Override
283        public void postOnAnimationDelayed(View view, Runnable action, long delayMillis) {
284            ViewCompatJB.postOnAnimationDelayed(view, action, delayMillis);
285        }
286        @Override
287        public int getImportantForAccessibility(View view) {
288            return ViewCompatJB.getImportantForAccessibility(view);
289        }
290        @Override
291        public void setImportantForAccessibility(View view, int mode) {
292            ViewCompatJB.setImportantForAccessibility(view, mode);
293        }
294        @Override
295        public boolean performAccessibilityAction(View view, int action, Bundle arguments) {
296            return ViewCompatJB.performAccessibilityAction(view, action, arguments);
297        }
298        @Override
299        public AccessibilityNodeProviderCompat getAccessibilityNodeProvider(View view) {
300            Object compat = ViewCompatJB.getAccessibilityNodeProvider(view);
301            if (compat != null) {
302                return new AccessibilityNodeProviderCompat(compat);
303            }
304            return null;
305        }
306    }
307
308    static class JbMr1ViewCompatImpl extends JBViewCompatImpl {
309
310        @Override
311        public int getLabelFor(View view) {
312            return ViewCompatJellybeanMr1.getLabelFor(view);
313        }
314
315        @Override
316        public void setLabelFor(View view, int id) {
317            ViewCompatJellybeanMr1.setLabelFor(view, id);
318        }
319    }
320
321    static final ViewCompatImpl IMPL;
322    static {
323        final int version = android.os.Build.VERSION.SDK_INT;
324        if ("JellyBeanMR1".equals(android.os.Build.VERSION.CODENAME)) {
325            IMPL = new JbMr1ViewCompatImpl();
326        } else if (version >= 16) {
327            IMPL = new JBViewCompatImpl();
328        } else if (version >= 14) {
329            IMPL = new ICSViewCompatImpl();
330        } else if (version >= 11) {
331            IMPL = new HCViewCompatImpl();
332        } else if (version >= 9) {
333            IMPL = new GBViewCompatImpl();
334        } else {
335            IMPL = new BaseViewCompatImpl();
336        }
337    }
338
339    /**
340     * Check if this view can be scrolled horizontally in a certain direction.
341     *
342     * @param v The View against which to invoke the method.
343     * @param direction Negative to check scrolling left, positive to check scrolling right.
344     * @return true if this view can be scrolled in the specified direction, false otherwise.
345     */
346    public static boolean canScrollHorizontally(View v, int direction) {
347        return IMPL.canScrollHorizontally(v, direction);
348    }
349
350    /**
351     * Check if this view can be scrolled vertically in a certain direction.
352     *
353     * @param v The View against which to invoke the method.
354     * @param direction Negative to check scrolling up, positive to check scrolling down.
355     * @return true if this view can be scrolled in the specified direction, false otherwise.
356     */
357    public static boolean canScrollVertically(View v, int direction) {
358        return IMPL.canScrollVertically(v, direction);
359    }
360
361    /**
362     * Returns the over-scroll mode for this view. The result will be
363     * one of {@link #OVER_SCROLL_ALWAYS} (default), {@link #OVER_SCROLL_IF_CONTENT_SCROLLS}
364     * (allow over-scrolling only if the view content is larger than the container),
365     * or {@link #OVER_SCROLL_NEVER}.
366     *
367     * @param v The View against which to invoke the method.
368     * @return This view's over-scroll mode.
369     */
370    public static int getOverScrollMode(View v) {
371        return IMPL.getOverScrollMode(v);
372    }
373
374    /**
375     * Set the over-scroll mode for this view. Valid over-scroll modes are
376     * {@link #OVER_SCROLL_ALWAYS} (default), {@link #OVER_SCROLL_IF_CONTENT_SCROLLS}
377     * (allow over-scrolling only if the view content is larger than the container),
378     * or {@link #OVER_SCROLL_NEVER}.
379     *
380     * Setting the over-scroll mode of a view will have an effect only if the
381     * view is capable of scrolling.
382     *
383     * @param v The View against which to invoke the method.
384     * @param overScrollMode The new over-scroll mode for this view.
385     */
386    public static void setOverScrollMode(View v, int overScrollMode) {
387        IMPL.setOverScrollMode(v, overScrollMode);
388    }
389
390    /**
391     * Called from {@link View#dispatchPopulateAccessibilityEvent(AccessibilityEvent)}
392     * giving a chance to this View to populate the accessibility event with its
393     * text content. While this method is free to modify event
394     * attributes other than text content, doing so should normally be performed in
395     * {@link View#onInitializeAccessibilityEvent(AccessibilityEvent)}.
396     * <p>
397     * Example: Adding formatted date string to an accessibility event in addition
398     *          to the text added by the super implementation:
399     * <pre> public void onPopulateAccessibilityEvent(AccessibilityEvent event) {
400     *     super.onPopulateAccessibilityEvent(event);
401     *     final int flags = DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_SHOW_WEEKDAY;
402     *     String selectedDateUtterance = DateUtils.formatDateTime(mContext,
403     *         mCurrentDate.getTimeInMillis(), flags);
404     *     event.getText().add(selectedDateUtterance);
405     * }</pre>
406     * <p>
407     * If an {@link android.view.View.AccessibilityDelegate} has been specified via calling
408     * {@link View#setAccessibilityDelegate(android.view.View.AccessibilityDelegate)} its
409     * {@link android.view.View.AccessibilityDelegate#onPopulateAccessibilityEvent(View,
410     *  AccessibilityEvent)}
411     * is responsible for handling this call.
412     * </p>
413     * <p class="note"><strong>Note:</strong> Always call the super implementation before adding
414     * information to the event, in case the default implementation has basic information to add.
415     * </p>
416     *
417     * @param v The View against which to invoke the method.
418     * @param event The accessibility event which to populate.
419     *
420     * @see View#sendAccessibilityEvent(int)
421     * @see View#dispatchPopulateAccessibilityEvent(AccessibilityEvent)
422     */
423    public static void onPopulateAccessibilityEvent(View v, AccessibilityEvent event) {
424        IMPL.onPopulateAccessibilityEvent(v, event);
425    }
426
427    /**
428     * Initializes an {@link AccessibilityEvent} with information about
429     * this View which is the event source. In other words, the source of
430     * an accessibility event is the view whose state change triggered firing
431     * the event.
432     * <p>
433     * Example: Setting the password property of an event in addition
434     *          to properties set by the super implementation:
435     * <pre> public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
436     *     super.onInitializeAccessibilityEvent(event);
437     *     event.setPassword(true);
438     * }</pre>
439     * <p>
440     * If an {@link android.view.View.AccessibilityDelegate} has been specified via calling
441     * {@link View#setAccessibilityDelegate(android.view.View.AccessibilityDelegate)} its
442     * {@link android.view.View.AccessibilityDelegate#onInitializeAccessibilityEvent(View,
443     *  AccessibilityEvent)}
444     * is responsible for handling this call.
445     * </p>
446     * <p class="note"><strong>Note:</strong> Always call the super implementation before adding
447     * information to the event, in case the default implementation has basic information to add.
448     * </p>
449     *
450     * @param v The View against which to invoke the method.
451     * @param event The event to initialize.
452     *
453     * @see View#sendAccessibilityEvent(int)
454     * @see View#dispatchPopulateAccessibilityEvent(AccessibilityEvent)
455     */
456    public static void onInitializeAccessibilityEvent(View v, AccessibilityEvent event) {
457        IMPL.onInitializeAccessibilityEvent(v, event);
458    }
459
460    /**
461     * Initializes an {@link android.view.accessibility.AccessibilityNodeInfo} with information
462     * about this view. The base implementation sets:
463     * <ul>
464     * <li>{@link android.view.accessibility.AccessibilityNodeInfo#setParent(View)},</li>
465     * <li>{@link android.view.accessibility.AccessibilityNodeInfo#setBoundsInParent(Rect)},</li>
466     * <li>{@link android.view.accessibility.AccessibilityNodeInfo#setBoundsInScreen(Rect)},</li>
467     * <li>{@link android.view.accessibility.AccessibilityNodeInfo#setPackageName(CharSequence)},</li>
468     * <li>{@link android.view.accessibility.AccessibilityNodeInfo#setClassName(CharSequence)},</li>
469     * <li>{@link android.view.accessibility.AccessibilityNodeInfo#setContentDescription(CharSequence)},</li>
470     * <li>{@link android.view.accessibility.AccessibilityNodeInfo#setEnabled(boolean)},</li>
471     * <li>{@link android.view.accessibility.AccessibilityNodeInfo#setClickable(boolean)},</li>
472     * <li>{@link android.view.accessibility.AccessibilityNodeInfo#setFocusable(boolean)},</li>
473     * <li>{@link android.view.accessibility.AccessibilityNodeInfo#setFocused(boolean)},</li>
474     * <li>{@link android.view.accessibility.AccessibilityNodeInfo#setLongClickable(boolean)},</li>
475     * <li>{@link android.view.accessibility.AccessibilityNodeInfo#setSelected(boolean)},</li>
476     * </ul>
477     * <p>
478     * Subclasses should override this method, call the super implementation,
479     * and set additional attributes.
480     * </p>
481     * <p>
482     * If an {@link android.view.View.AccessibilityDelegate} has been specified via calling
483     * {@link View#setAccessibilityDelegate(android.view.View.AccessibilityDelegate)} its
484     * {@link android.view.View.AccessibilityDelegate#onInitializeAccessibilityNodeInfo(View,
485     *  android.view.accessibility.AccessibilityNodeInfo)}
486     * is responsible for handling this call.
487     * </p>
488     *
489     * @param v The View against which to invoke the method.
490     * @param info The instance to initialize.
491     */
492    public static void onInitializeAccessibilityNodeInfo(View v, AccessibilityNodeInfoCompat info) {
493        IMPL.onInitializeAccessibilityNodeInfo(v, info);
494    }
495
496    /**
497     * Sets a delegate for implementing accessibility support via compositon as
498     * opposed to inheritance. The delegate's primary use is for implementing
499     * backwards compatible widgets. For more details see
500     * {@link android.view.View.AccessibilityDelegate}.
501     *
502     * @param v The View against which to invoke the method.
503     * @param delegate The delegate instance.
504     *
505     * @see android.view.View.AccessibilityDelegate
506     */
507    public static void setAccessibilityDelegate(View v, AccessibilityDelegateCompat delegate) {
508        IMPL.setAccessibilityDelegate(v, delegate);
509    }
510
511    /**
512     * Indicates whether the view is currently tracking transient state that the
513     * app should not need to concern itself with saving and restoring, but that
514     * the framework should take special note to preserve when possible.
515     *
516     * @param view View to check for transient state
517     * @return true if the view has transient state
518     */
519    public static boolean hasTransientState(View view) {
520        return IMPL.hasTransientState(view);
521    }
522
523    /**
524     * Set whether this view is currently tracking transient state that the
525     * framework should attempt to preserve when possible.
526     *
527     * @param view View tracking transient state
528     * @param hasTransientState true if this view has transient state
529     */
530    public static void setHasTransientState(View view, boolean hasTransientState) {
531        IMPL.setHasTransientState(view, hasTransientState);
532    }
533
534    /**
535     * <p>Cause an invalidate to happen on the next animation time step, typically the
536     * next display frame.</p>
537     *
538     * <p>This method can be invoked from outside of the UI thread
539     * only when this View is attached to a window.</p>
540     *
541     * @param view View to invalidate
542     */
543    public static void postInvalidateOnAnimation(View view) {
544        IMPL.postInvalidateOnAnimation(view);
545    }
546
547    /**
548     * <p>Cause an invalidate of the specified area to happen on the next animation
549     * time step, typically the next display frame.</p>
550     *
551     * <p>This method can be invoked from outside of the UI thread
552     * only when this View is attached to a window.</p>
553     *
554     * @param view View to invalidate
555     * @param left The left coordinate of the rectangle to invalidate.
556     * @param top The top coordinate of the rectangle to invalidate.
557     * @param right The right coordinate of the rectangle to invalidate.
558     * @param bottom The bottom coordinate of the rectangle to invalidate.
559     */
560    public static void postInvalidateOnAnimation(View view, int left, int top,
561            int right, int bottom) {
562        IMPL.postInvalidateOnAnimation(view, left, top, right, bottom);
563    }
564
565    /**
566     * <p>Causes the Runnable to execute on the next animation time step.
567     * The runnable will be run on the user interface thread.</p>
568     *
569     * <p>This method can be invoked from outside of the UI thread
570     * only when this View is attached to a window.</p>
571     *
572     * @param view View to post this Runnable to
573     * @param action The Runnable that will be executed.
574     */
575    public static void postOnAnimation(View view, Runnable action) {
576        IMPL.postOnAnimation(view, action);
577    }
578
579    /**
580     * <p>Causes the Runnable to execute on the next animation time step,
581     * after the specified amount of time elapses.
582     * The runnable will be run on the user interface thread.</p>
583     *
584     * <p>This method can be invoked from outside of the UI thread
585     * only when this View is attached to a window.</p>
586     *
587     * @param view The view to post this Runnable to
588     * @param action The Runnable that will be executed.
589     * @param delayMillis The delay (in milliseconds) until the Runnable
590     *        will be executed.
591     */
592    public static void postOnAnimationDelayed(View view, Runnable action, long delayMillis) {
593        IMPL.postOnAnimationDelayed(view, action, delayMillis);
594    }
595
596    /**
597     * Gets the mode for determining whether this View is important for accessibility
598     * which is if it fires accessibility events and if it is reported to
599     * accessibility services that query the screen.
600     *
601     * @param view The view whose property to get.
602     * @return The mode for determining whether a View is important for accessibility.
603     *
604     * @see #IMPORTANT_FOR_ACCESSIBILITY_YES
605     * @see #IMPORTANT_FOR_ACCESSIBILITY_NO
606     * @see #IMPORTANT_FOR_ACCESSIBILITY_AUTO
607     */
608    public static int getImportantForAccessibility(View view) {
609        return IMPL.getImportantForAccessibility(view);
610    }
611
612    /**
613     * Sets how to determine whether this view is important for accessibility
614     * which is if it fires accessibility events and if it is reported to
615     * accessibility services that query the screen.
616     *
617     * @param view The view whose property to set.
618     * @param mode How to determine whether this view is important for accessibility.
619     *
620     * @see #IMPORTANT_FOR_ACCESSIBILITY_YES
621     * @see #IMPORTANT_FOR_ACCESSIBILITY_NO
622     * @see #IMPORTANT_FOR_ACCESSIBILITY_AUTO
623     */
624    public static void setImportantForAccessibility(View view, int mode) {
625        IMPL.setImportantForAccessibility(view, mode);
626    }
627
628    /**
629     * Performs the specified accessibility action on the view. For
630     * possible accessibility actions look at {@link AccessibilityNodeInfoCompat}.
631     * <p>
632     * If an {@link AccessibilityDelegateCompat} has been specified via calling
633     * {@link #setAccessibilityDelegate(View, AccessibilityDelegateCompat)} its
634     * {@link AccessibilityDelegateCompat#performAccessibilityAction(View, int, Bundle)}
635     * is responsible for handling this call.
636     * </p>
637     *
638     * @param action The action to perform.
639     * @param arguments Optional action arguments.
640     * @return Whether the action was performed.
641     */
642    public static boolean performAccessibilityAction(View view, int action, Bundle arguments) {
643        return IMPL.performAccessibilityAction(view, action, arguments);
644    }
645
646    /**
647     * Gets the provider for managing a virtual view hierarchy rooted at this View
648     * and reported to {@link android.accessibilityservice.AccessibilityService}s
649     * that explore the window content.
650     * <p>
651     * If this method returns an instance, this instance is responsible for managing
652     * {@link AccessibilityNodeInfoCompat}s describing the virtual sub-tree rooted at
653     * this View including the one representing the View itself. Similarly the returned
654     * instance is responsible for performing accessibility actions on any virtual
655     * view or the root view itself.
656     * </p>
657     * <p>
658     * If an {@link AccessibilityDelegateCompat} has been specified via calling
659     * {@link #setAccessibilityDelegate(View, AccessibilityDelegateCompat) its
660     * {@link AccessibilityDelegateCompat#getAccessibilityNodeProvider(View)}
661     * is responsible for handling this call.
662     * </p>
663     *
664     * @param view The view whose property to get.
665     * @return The provider.
666     *
667     * @see AccessibilityNodeProviderCompat
668     */
669    public static AccessibilityNodeProviderCompat getAccessibilityNodeProvider(View view) {
670        return IMPL.getAccessibilityNodeProvider(view);
671    }
672
673    /**
674     * <p>Specifies the type of layer backing this view. The layer can be
675     * {@link #LAYER_TYPE_NONE disabled}, {@link #LAYER_TYPE_SOFTWARE software} or
676     * {@link #LAYER_TYPE_HARDWARE hardware}.</p>
677     *
678     * <p>A layer is associated with an optional {@link android.graphics.Paint}
679     * instance that controls how the layer is composed on screen. The following
680     * properties of the paint are taken into account when composing the layer:</p>
681     * <ul>
682     * <li>{@link android.graphics.Paint#getAlpha() Translucency (alpha)}</li>
683     * <li>{@link android.graphics.Paint#getXfermode() Blending mode}</li>
684     * <li>{@link android.graphics.Paint#getColorFilter() Color filter}</li>
685     * </ul>
686     *
687     * <p>If this view has an alpha value set to < 1.0 by calling
688     * setAlpha(float), the alpha value of the layer's paint is replaced by
689     * this view's alpha value. Calling setAlpha(float) is therefore
690     * equivalent to setting a hardware layer on this view and providing a paint with
691     * the desired alpha value.<p>
692     *
693     * <p>Refer to the documentation of {@link #LAYER_TYPE_NONE disabled},
694     * {@link #LAYER_TYPE_SOFTWARE software} and {@link #LAYER_TYPE_HARDWARE hardware}
695     * for more information on when and how to use layers.</p>
696     *
697     * @param layerType The ype of layer to use with this view, must be one of
698     *        {@link #LAYER_TYPE_NONE}, {@link #LAYER_TYPE_SOFTWARE} or
699     *        {@link #LAYER_TYPE_HARDWARE}
700     * @param paint The paint used to compose the layer. This argument is optional
701     *        and can be null. It is ignored when the layer type is
702     *        {@link #LAYER_TYPE_NONE}
703     *
704     * @param view View to set the layer type for
705     * @param layerType The type of layer to use with this view, must be one of
706     *        {@link #LAYER_TYPE_NONE}, {@link #LAYER_TYPE_SOFTWARE} or
707     *        {@link #LAYER_TYPE_HARDWARE}
708     * @param paint The paint used to compose the layer. This argument is optional
709     *        and can be null. It is ignored when the layer type is
710     *        {@link #LAYER_TYPE_NONE}
711     */
712    public static void setLayerType(View view, int layerType, Paint paint) {
713        IMPL.setLayerType(view, layerType, paint);
714    }
715
716    /**
717     * Indicates what type of layer is currently associated with this view. By default
718     * a view does not have a layer, and the layer type is {@link #LAYER_TYPE_NONE}.
719     * Refer to the documentation of
720     * {@link #setLayerType(android.view.View, int, android.graphics.Paint)}
721     * for more information on the different types of layers.
722     *
723     * @param view The view to fetch the layer type from
724     * @return {@link #LAYER_TYPE_NONE}, {@link #LAYER_TYPE_SOFTWARE} or
725     *         {@link #LAYER_TYPE_HARDWARE}
726     *
727     * @see #setLayerType(android.view.View, int, android.graphics.Paint)
728     * @see #LAYER_TYPE_NONE
729     * @see #LAYER_TYPE_SOFTWARE
730     * @see #LAYER_TYPE_HARDWARE
731     */
732    public static int getLayerType(View view) {
733        return IMPL.getLayerType(view);
734    }
735
736    /**
737     * Gets the id of a view for which a given view serves as a label for
738     * accessibility purposes.
739     *
740     * @param view The view on which to invoke the corresponding method.
741     * @return The labeled view id.
742     */
743    public static int getLabelFor(View view) {
744        return IMPL.getLabelFor(view);
745    }
746
747    /**
748     * Sets the id of a view for which a given view serves as a label for
749     * accessibility purposes.
750     *
751     * @param view The view on which to invoke the corresponding method.
752     * @param labeledId The labeled view id.
753     */
754    public static void setLabelFor(View view, int labeledId) {
755        IMPL.setLabelFor(view, labeledId);
756    }
757}
758