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.PixelFormat;
21import android.graphics.Rect;
22import android.graphics.drawable.Drawable;
23import android.os.Bundle;
24import android.support.annotation.IdRes;
25import android.support.annotation.IntDef;
26import android.support.annotation.Nullable;
27import android.support.v4.view.accessibility.AccessibilityNodeInfoCompat;
28import android.support.v4.view.accessibility.AccessibilityNodeProviderCompat;
29import android.util.Log;
30import android.view.View;
31import android.view.ViewGroup;
32import android.view.ViewParent;
33import android.view.accessibility.AccessibilityEvent;
34
35import java.lang.annotation.Retention;
36import java.lang.annotation.RetentionPolicy;
37import java.lang.reflect.Field;
38import java.lang.reflect.Method;
39import java.util.WeakHashMap;
40
41/**
42 * Helper for accessing features in {@link View} introduced after API
43 * level 4 in a backwards compatible fashion.
44 */
45public class ViewCompat {
46    private static final String TAG = "ViewCompat";
47
48
49    /** @hide */
50    @IntDef({OVER_SCROLL_ALWAYS, OVER_SCROLL_IF_CONTENT_SCROLLS, OVER_SCROLL_IF_CONTENT_SCROLLS})
51    @Retention(RetentionPolicy.SOURCE)
52    private @interface OverScroll {}
53
54    /**
55     * Always allow a user to over-scroll this view, provided it is a
56     * view that can scroll.
57     */
58    public static final int OVER_SCROLL_ALWAYS = 0;
59
60    /**
61     * Allow a user to over-scroll this view only if the content is large
62     * enough to meaningfully scroll, provided it is a view that can scroll.
63     */
64    public static final int OVER_SCROLL_IF_CONTENT_SCROLLS = 1;
65
66    /**
67     * Never allow a user to over-scroll this view.
68     */
69    public static final int OVER_SCROLL_NEVER = 2;
70
71    private static final long FAKE_FRAME_TIME = 10;
72
73    /** @hide */
74    @IntDef({
75            IMPORTANT_FOR_ACCESSIBILITY_AUTO,
76            IMPORTANT_FOR_ACCESSIBILITY_YES,
77            IMPORTANT_FOR_ACCESSIBILITY_NO,
78            IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS
79    })
80    @Retention(RetentionPolicy.SOURCE)
81    private @interface ImportantForAccessibility {}
82
83    /**
84     * Automatically determine whether a view is important for accessibility.
85     */
86    public static final int IMPORTANT_FOR_ACCESSIBILITY_AUTO = 0x00000000;
87
88    /**
89     * The view is important for accessibility.
90     */
91    public static final int IMPORTANT_FOR_ACCESSIBILITY_YES = 0x00000001;
92
93    /**
94     * The view is not important for accessibility.
95     */
96    public static final int IMPORTANT_FOR_ACCESSIBILITY_NO = 0x00000002;
97
98    /**
99     * The view is not important for accessibility, nor are any of its
100     * descendant views.
101     */
102    public static final int IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS = 0x00000004;
103
104    /** @hide */
105    @IntDef({
106            ACCESSIBILITY_LIVE_REGION_NONE,
107            ACCESSIBILITY_LIVE_REGION_POLITE,
108            ACCESSIBILITY_LIVE_REGION_ASSERTIVE
109    })
110    @Retention(RetentionPolicy.SOURCE)
111    private @interface AccessibilityLiveRegion {}
112
113    /**
114     * Live region mode specifying that accessibility services should not
115     * automatically announce changes to this view. This is the default live
116     * region mode for most views.
117     * <p>
118     * Use with {@link ViewCompat#setAccessibilityLiveRegion(View, int)}.
119     */
120    public static final int ACCESSIBILITY_LIVE_REGION_NONE = 0x00000000;
121
122    /**
123     * Live region mode specifying that accessibility services should announce
124     * changes to this view.
125     * <p>
126     * Use with {@link ViewCompat#setAccessibilityLiveRegion(View, int)}.
127     */
128    public static final int ACCESSIBILITY_LIVE_REGION_POLITE = 0x00000001;
129
130    /**
131     * Live region mode specifying that accessibility services should interrupt
132     * ongoing speech to immediately announce changes to this view.
133     * <p>
134     * Use with {@link ViewCompat#setAccessibilityLiveRegion(View, int)}.
135     */
136    public static final int ACCESSIBILITY_LIVE_REGION_ASSERTIVE = 0x00000002;
137
138    /** @hide */
139    @IntDef({LAYER_TYPE_NONE, LAYER_TYPE_SOFTWARE, LAYER_TYPE_HARDWARE})
140    @Retention(RetentionPolicy.SOURCE)
141    private @interface LayerType {}
142
143    /**
144     * Indicates that the view does not have a layer.
145     */
146    public static final int LAYER_TYPE_NONE = 0;
147
148    /**
149     * <p>Indicates that the view has a software layer. A software layer is backed
150     * by a bitmap and causes the view to be rendered using Android's software
151     * rendering pipeline, even if hardware acceleration is enabled.</p>
152     *
153     * <p>Software layers have various usages:</p>
154     * <p>When the application is not using hardware acceleration, a software layer
155     * is useful to apply a specific color filter and/or blending mode and/or
156     * translucency to a view and all its children.</p>
157     * <p>When the application is using hardware acceleration, a software layer
158     * is useful to render drawing primitives not supported by the hardware
159     * accelerated pipeline. It can also be used to cache a complex view tree
160     * into a texture and reduce the complexity of drawing operations. For instance,
161     * when animating a complex view tree with a translation, a software layer can
162     * be used to render the view tree only once.</p>
163     * <p>Software layers should be avoided when the affected view tree updates
164     * often. Every update will require to re-render the software layer, which can
165     * potentially be slow (particularly when hardware acceleration is turned on
166     * since the layer will have to be uploaded into a hardware texture after every
167     * update.)</p>
168     */
169    public static final int LAYER_TYPE_SOFTWARE = 1;
170
171    /**
172     * <p>Indicates that the view has a hardware layer. A hardware layer is backed
173     * by a hardware specific texture (generally Frame Buffer Objects or FBO on
174     * OpenGL hardware) and causes the view to be rendered using Android's hardware
175     * rendering pipeline, but only if hardware acceleration is turned on for the
176     * view hierarchy. When hardware acceleration is turned off, hardware layers
177     * behave exactly as {@link #LAYER_TYPE_SOFTWARE software layers}.</p>
178     *
179     * <p>A hardware layer is useful to apply a specific color filter and/or
180     * blending mode and/or translucency to a view and all its children.</p>
181     * <p>A hardware layer can be used to cache a complex view tree into a
182     * texture and reduce the complexity of drawing operations. For instance,
183     * when animating a complex view tree with a translation, a hardware layer can
184     * be used to render the view tree only once.</p>
185     * <p>A hardware layer can also be used to increase the rendering quality when
186     * rotation transformations are applied on a view. It can also be used to
187     * prevent potential clipping issues when applying 3D transforms on a view.</p>
188     */
189    public static final int LAYER_TYPE_HARDWARE = 2;
190
191    /** @hide */
192    @IntDef({
193            LAYOUT_DIRECTION_LTR,
194            LAYOUT_DIRECTION_RTL,
195            LAYOUT_DIRECTION_INHERIT,
196            LAYOUT_DIRECTION_LOCALE})
197    @Retention(RetentionPolicy.SOURCE)
198    private @interface LayoutDirectionMode {}
199
200    /** @hide */
201    @IntDef({
202            LAYOUT_DIRECTION_LTR,
203            LAYOUT_DIRECTION_RTL
204    })
205    @Retention(RetentionPolicy.SOURCE)
206    private @interface ResolvedLayoutDirectionMode {}
207
208    /**
209     * Horizontal layout direction of this view is from Left to Right.
210     */
211    public static final int LAYOUT_DIRECTION_LTR = 0;
212
213    /**
214     * Horizontal layout direction of this view is from Right to Left.
215     */
216    public static final int LAYOUT_DIRECTION_RTL = 1;
217
218    /**
219     * Horizontal layout direction of this view is inherited from its parent.
220     * Use with {@link #setLayoutDirection}.
221     */
222    public static final int LAYOUT_DIRECTION_INHERIT = 2;
223
224    /**
225     * Horizontal layout direction of this view is from deduced from the default language
226     * script for the locale. Use with {@link #setLayoutDirection}.
227     */
228    public static final int LAYOUT_DIRECTION_LOCALE = 3;
229
230    /**
231     * Bits of {@link #getMeasuredWidthAndState} and
232     * {@link #getMeasuredWidthAndState} that provide the actual measured size.
233     */
234    public static final int MEASURED_SIZE_MASK = 0x00ffffff;
235
236    /**
237     * Bits of {@link #getMeasuredWidthAndState} and
238     * {@link #getMeasuredWidthAndState} that provide the additional state bits.
239     */
240    public static final int MEASURED_STATE_MASK = 0xff000000;
241
242    /**
243     * Bit shift of {@link #MEASURED_STATE_MASK} to get to the height bits
244     * for functions that combine both width and height into a single int,
245     * such as {@link #getMeasuredState} and the childState argument of
246     * {@link #resolveSizeAndState(int, int, int)}.
247     */
248    public static final int MEASURED_HEIGHT_STATE_SHIFT = 16;
249
250    /**
251     * Bit of {@link #getMeasuredWidthAndState} and
252     * {@link #getMeasuredWidthAndState} that indicates the measured size
253     * is smaller that the space the view would like to have.
254     */
255    public static final int MEASURED_STATE_TOO_SMALL = 0x01000000;
256
257    interface ViewCompatImpl {
258        public boolean canScrollHorizontally(View v, int direction);
259        public boolean canScrollVertically(View v, int direction);
260        public int getOverScrollMode(View v);
261        public void setOverScrollMode(View v, int mode);
262        public void onInitializeAccessibilityEvent(View v, AccessibilityEvent event);
263        public void onPopulateAccessibilityEvent(View v, AccessibilityEvent event);
264        public void onInitializeAccessibilityNodeInfo(View v, AccessibilityNodeInfoCompat info);
265        public void setAccessibilityDelegate(View v, @Nullable AccessibilityDelegateCompat delegate);
266        public boolean hasAccessibilityDelegate(View v);
267        public boolean hasTransientState(View view);
268        public void setHasTransientState(View view, boolean hasTransientState);
269        public void postInvalidateOnAnimation(View view);
270        public void postInvalidateOnAnimation(View view, int left, int top, int right, int bottom);
271        public void postOnAnimation(View view, Runnable action);
272        public void postOnAnimationDelayed(View view, Runnable action, long delayMillis);
273        public int getImportantForAccessibility(View view);
274        public void setImportantForAccessibility(View view, int mode);
275        public boolean isImportantForAccessibility(View view);
276        public boolean performAccessibilityAction(View view, int action, Bundle arguments);
277        public AccessibilityNodeProviderCompat getAccessibilityNodeProvider(View view);
278        public float getAlpha(View view);
279        public void setLayerType(View view, int layerType, Paint paint);
280        public int getLayerType(View view);
281        public int getLabelFor(View view);
282        public void setLabelFor(View view, int id);
283        public void setLayerPaint(View view, Paint paint);
284        public int getLayoutDirection(View view);
285        public void setLayoutDirection(View view, int layoutDirection);
286        public ViewParent getParentForAccessibility(View view);
287        public boolean isOpaque(View view);
288        public int resolveSizeAndState(int size, int measureSpec, int childMeasuredState);
289        public int getMeasuredWidthAndState(View view);
290        public int getMeasuredHeightAndState(View view);
291        public int getMeasuredState(View view);
292        public int getAccessibilityLiveRegion(View view);
293        public void setAccessibilityLiveRegion(View view, int mode);
294        public int getPaddingStart(View view);
295        public int getPaddingEnd(View view);
296        public void setPaddingRelative(View view, int start, int top, int end, int bottom);
297        public void dispatchStartTemporaryDetach(View view);
298        public void dispatchFinishTemporaryDetach(View view);
299        public float getX(View view);
300        public float getY(View view);
301        public float getRotation(View view);
302        public float getRotationX(View view);
303        public float getRotationY(View view);
304        public float getScaleX(View view);
305        public float getScaleY(View view);
306        public float getTranslationX(View view);
307        public float getTranslationY(View view);
308        public int getMinimumWidth(View view);
309        public int getMinimumHeight(View view);
310        public ViewPropertyAnimatorCompat animate(View view);
311        public void setRotation(View view, float value);
312        public void setRotationX(View view, float value);
313        public void setRotationY(View view, float value);
314        public void setScaleX(View view, float value);
315        public void setScaleY(View view, float value);
316        public void setTranslationX(View view, float value);
317        public void setTranslationY(View view, float value);
318        public void setX(View view, float value);
319        public void setY(View view, float value);
320        public void setAlpha(View view, float value);
321        public void setPivotX(View view, float value);
322        public void setPivotY(View view, float value);
323        public float getPivotX(View view);
324        public float getPivotY(View view);
325        public void setElevation(View view, float elevation);
326        public float getElevation(View view);
327        public void setTranslationZ(View view, float translationZ);
328        public float getTranslationZ(View view);
329        public void setTransitionName(View view, String transitionName);
330        public String getTransitionName(View view);
331        public int getWindowSystemUiVisibility(View view);
332        public void requestApplyInsets(View view);
333        public void setChildrenDrawingOrderEnabled(ViewGroup viewGroup, boolean enabled);
334        public boolean getFitsSystemWindows(View view);
335        void setFitsSystemWindows(View view, boolean fitSystemWindows);
336        void jumpDrawablesToCurrentState(View v);
337        void setOnApplyWindowInsetsListener(View view, OnApplyWindowInsetsListener listener);
338        void setSaveFromParentEnabled(View view, boolean enabled);
339        void setActivated(View view, boolean activated);
340    }
341
342    static class BaseViewCompatImpl implements ViewCompatImpl {
343        private Method mDispatchStartTemporaryDetach;
344        private Method mDispatchFinishTemporaryDetach;
345        private boolean mTempDetachBound;
346        WeakHashMap<View, ViewPropertyAnimatorCompat> mViewPropertyAnimatorCompatMap = null;
347
348
349        public boolean canScrollHorizontally(View v, int direction) {
350            return false;
351        }
352        public boolean canScrollVertically(View v, int direction) {
353            return false;
354        }
355        public int getOverScrollMode(View v) {
356            return OVER_SCROLL_NEVER;
357        }
358        public void setOverScrollMode(View v, int mode) {
359            // Do nothing; API doesn't exist
360        }
361        public void setAccessibilityDelegate(View v, AccessibilityDelegateCompat delegate) {
362            // Do nothing; API doesn't exist
363        }
364
365        @Override
366        public boolean hasAccessibilityDelegate(View v) {
367            return false;
368        }
369
370        public void onPopulateAccessibilityEvent(View v, AccessibilityEvent event) {
371            // Do nothing; API doesn't exist
372        }
373        public void onInitializeAccessibilityEvent(View v, AccessibilityEvent event) {
374         // Do nothing; API doesn't exist
375        }
376        public void onInitializeAccessibilityNodeInfo(View v, AccessibilityNodeInfoCompat info) {
377            // Do nothing; API doesn't exist
378        }
379        public boolean hasTransientState(View view) {
380            // A view can't have transient state if transient state wasn't supported.
381            return false;
382        }
383        public void setHasTransientState(View view, boolean hasTransientState) {
384            // Do nothing; API doesn't exist
385        }
386        public void postInvalidateOnAnimation(View view) {
387            view.invalidate();
388        }
389        public void postInvalidateOnAnimation(View view, int left, int top, int right, int bottom) {
390            view.invalidate(left, top, right, bottom);
391        }
392        public void postOnAnimation(View view, Runnable action) {
393            view.postDelayed(action, getFrameTime());
394        }
395        public void postOnAnimationDelayed(View view, Runnable action, long delayMillis) {
396            view.postDelayed(action, getFrameTime() + delayMillis);
397        }
398        long getFrameTime() {
399            return FAKE_FRAME_TIME;
400        }
401        public int getImportantForAccessibility(View view) {
402            return 0;
403        }
404        public void setImportantForAccessibility(View view, int mode) {
405
406        }
407        public boolean isImportantForAccessibility(View view) {
408            return true;
409        }
410        public boolean performAccessibilityAction(View view, int action, Bundle arguments) {
411            return false;
412        }
413        public AccessibilityNodeProviderCompat getAccessibilityNodeProvider(View view) {
414            return null;
415        }
416        public float getAlpha(View view) {
417            return 1.0f;
418        }
419        public void setLayerType(View view, int layerType, Paint paint) {
420            // No-op until layers became available (HC)
421        }
422        public int getLayerType(View view) {
423            return LAYER_TYPE_NONE;
424        }
425        public int getLabelFor(View view) {
426            return 0;
427        }
428        public void setLabelFor(View view, int id) {
429
430        }
431        public void setLayerPaint(View view, Paint p) {
432            // No-op until layers became available (HC)
433        }
434
435        @Override
436        public int getLayoutDirection(View view) {
437            return LAYOUT_DIRECTION_LTR;
438        }
439
440        @Override
441        public void setLayoutDirection(View view, int layoutDirection) {
442            // No-op
443        }
444
445        @Override
446        public ViewParent getParentForAccessibility(View view) {
447            return view.getParent();
448        }
449
450        @Override
451        public boolean isOpaque(View view) {
452            final Drawable bg = view.getBackground();
453            if (bg != null) {
454                return bg.getOpacity() == PixelFormat.OPAQUE;
455            }
456            return false;
457        }
458
459        public int resolveSizeAndState(int size, int measureSpec, int childMeasuredState) {
460            return View.resolveSize(size, measureSpec);
461        }
462
463        @Override
464        public int getMeasuredWidthAndState(View view) {
465            return view.getMeasuredWidth();
466        }
467
468        @Override
469        public int getMeasuredHeightAndState(View view) {
470            return view.getMeasuredHeight();
471        }
472
473        @Override
474        public int getMeasuredState(View view) {
475            return 0;
476        }
477
478        @Override
479        public int getAccessibilityLiveRegion(View view) {
480            return ACCESSIBILITY_LIVE_REGION_NONE;
481        }
482
483        @Override
484        public void setAccessibilityLiveRegion(View view, int mode) {
485            // No-op
486        }
487
488        @Override
489        public int getPaddingStart(View view) {
490            return view.getPaddingLeft();
491        }
492
493        @Override
494        public int getPaddingEnd(View view) {
495            return view.getPaddingRight();
496        }
497
498        @Override
499        public void setPaddingRelative(View view, int start, int top, int end, int bottom) {
500            view.setPadding(start, top, end, bottom);
501        }
502
503        @Override
504        public void dispatchStartTemporaryDetach(View view) {
505            if (!mTempDetachBound) {
506                bindTempDetach();
507            }
508            if (mDispatchStartTemporaryDetach != null) {
509                try {
510                    mDispatchStartTemporaryDetach.invoke(view);
511                } catch (Exception e) {
512                    Log.d(TAG, "Error calling dispatchStartTemporaryDetach", e);
513                }
514            } else {
515                // Try this instead
516                view.onStartTemporaryDetach();
517            }
518        }
519
520        @Override
521        public void dispatchFinishTemporaryDetach(View view) {
522            if (!mTempDetachBound) {
523                bindTempDetach();
524            }
525            if (mDispatchFinishTemporaryDetach != null) {
526                try {
527                    mDispatchFinishTemporaryDetach.invoke(view);
528                } catch (Exception e) {
529                    Log.d(TAG, "Error calling dispatchFinishTemporaryDetach", e);
530                }
531            } else {
532                // Try this instead
533                view.onFinishTemporaryDetach();
534            }
535        }
536
537        private void bindTempDetach() {
538            try {
539                mDispatchStartTemporaryDetach = View.class.getDeclaredMethod(
540                        "dispatchStartTemporaryDetach");
541                mDispatchFinishTemporaryDetach = View.class.getDeclaredMethod(
542                        "dispatchFinishTemporaryDetach");
543            } catch (NoSuchMethodException e) {
544                Log.e(TAG, "Couldn't find method", e);
545            }
546            mTempDetachBound = true;
547        }
548
549        @Override
550        public float getTranslationX(View view) {
551            return 0;
552        }
553
554        @Override
555        public float getTranslationY(View view) {
556            return 0;
557        }
558
559        @Override
560        public float getX(View view) {
561            return 0;
562        }
563
564        @Override
565        public float getY(View view) {
566            return 0;
567        }
568
569        @Override
570        public float getRotation(View view) {
571            return 0;
572        }
573
574        @Override
575        public float getRotationX(View view) {
576            return 0;
577        }
578
579        @Override
580        public float getRotationY(View view) {
581            return 0;
582        }
583
584        @Override
585        public float getScaleX(View view) {
586            return 0;
587        }
588
589        @Override
590        public float getScaleY(View view) {
591            return 0;
592        }
593
594        @Override
595        public int getMinimumWidth(View view) {
596            return 0;
597        }
598
599        @Override
600        public int getMinimumHeight(View view) {
601            return 0;
602        }
603
604        @Override
605        public ViewPropertyAnimatorCompat animate(View view) {
606            return new ViewPropertyAnimatorCompat(view);
607        }
608
609        @Override
610        public void setRotation(View view, float value) {
611            // noop
612        }
613
614        @Override
615        public void setTranslationX(View view, float value) {
616            // noop
617        }
618
619        @Override
620        public void setTranslationY(View view, float value) {
621            // noop
622        }
623
624        @Override
625        public void setAlpha(View view, float value) {
626            // noop
627        }
628
629        @Override
630        public void setRotationX(View view, float value) {
631            // noop
632        }
633
634        @Override
635        public void setRotationY(View view, float value) {
636            // noop
637        }
638
639        @Override
640        public void setScaleX(View view, float value) {
641            // noop
642        }
643
644        @Override
645        public void setScaleY(View view, float value) {
646            // noop
647        }
648
649        @Override
650        public void setX(View view, float value) {
651            // noop
652        }
653
654        @Override
655        public void setY(View view, float value) {
656            // noop
657        }
658
659        @Override
660        public void setPivotX(View view, float value) {
661            // noop
662        }
663
664        @Override
665        public void setPivotY(View view, float value) {
666            // noop
667        }
668
669        @Override
670        public float getPivotX(View view) {
671            return 0;
672        }
673
674        @Override
675        public float getPivotY(View view) {
676            return 0;
677        }
678
679        @Override
680        public void setTransitionName(View view, String transitionName) {
681        }
682
683        @Override
684        public String getTransitionName(View view) {
685            return null;
686        }
687
688        @Override
689        public int getWindowSystemUiVisibility(View view) {
690            return 0;
691        }
692
693        @Override
694        public void requestApplyInsets(View view) {
695        }
696
697        @Override
698        public void setElevation(View view, float elevation) {
699        }
700
701        @Override
702        public float getElevation(View view) {
703            return 0f;
704        }
705
706        @Override
707        public void setTranslationZ(View view, float translationZ) {
708        }
709
710        @Override
711        public float getTranslationZ(View view) {
712            return 0f;
713        }
714
715        @Override
716        public void setChildrenDrawingOrderEnabled(ViewGroup viewGroup, boolean enabled) {
717            // noop
718        }
719
720        @Override
721        public boolean getFitsSystemWindows(View view) {
722            return false;
723        }
724
725        @Override
726        public void setFitsSystemWindows(View view, boolean fitSystemWindows) {
727            // noop
728        }
729
730        @Override
731        public void jumpDrawablesToCurrentState(View view) {
732            // Do nothing; API didn't exist.
733        }
734
735        @Override
736        public void setOnApplyWindowInsetsListener(View view,
737                OnApplyWindowInsetsListener listener) {
738            // noop
739        }
740
741        @Override
742        public void setSaveFromParentEnabled(View v, boolean enabled) {
743            // noop
744        }
745
746        @Override
747        public void setActivated(View view, boolean activated) {
748            // noop
749        }
750    }
751
752    static class EclairMr1ViewCompatImpl extends BaseViewCompatImpl {
753        @Override
754        public boolean isOpaque(View view) {
755            return ViewCompatEclairMr1.isOpaque(view);
756        }
757
758        @Override
759        public void setChildrenDrawingOrderEnabled(ViewGroup viewGroup, boolean enabled) {
760            ViewCompatEclairMr1.setChildrenDrawingOrderEnabled(viewGroup, enabled);
761        }
762    }
763
764    static class GBViewCompatImpl extends EclairMr1ViewCompatImpl {
765        @Override
766        public int getOverScrollMode(View v) {
767            return ViewCompatGingerbread.getOverScrollMode(v);
768        }
769        @Override
770        public void setOverScrollMode(View v, int mode) {
771            ViewCompatGingerbread.setOverScrollMode(v, mode);
772        }
773    }
774
775    static class HCViewCompatImpl extends GBViewCompatImpl {
776        @Override
777        long getFrameTime() {
778            return ViewCompatHC.getFrameTime();
779        }
780        @Override
781        public float getAlpha(View view) {
782            return ViewCompatHC.getAlpha(view);
783        }
784        @Override
785        public void setLayerType(View view, int layerType, Paint paint) {
786            ViewCompatHC.setLayerType(view, layerType, paint);
787        }
788        @Override
789        public int getLayerType(View view)  {
790            return ViewCompatHC.getLayerType(view);
791        }
792        @Override
793        public void setLayerPaint(View view, Paint paint) {
794            // Make sure the paint is correct; this will be cheap if it's the same
795            // instance as was used to call setLayerType earlier.
796            setLayerType(view, getLayerType(view), paint);
797            // This is expensive, but the only way to accomplish this before JB-MR1.
798            view.invalidate();
799        }
800        @Override
801        public int resolveSizeAndState(int size, int measureSpec, int childMeasuredState) {
802            return ViewCompatHC.resolveSizeAndState(size, measureSpec, childMeasuredState);
803        }
804        @Override
805        public int getMeasuredWidthAndState(View view) {
806            return ViewCompatHC.getMeasuredWidthAndState(view);
807        }
808        @Override
809        public int getMeasuredHeightAndState(View view) {
810            return ViewCompatHC.getMeasuredHeightAndState(view);
811        }
812        @Override
813        public int getMeasuredState(View view) {
814            return ViewCompatHC.getMeasuredState(view);
815        }
816        @Override
817        public float getTranslationX(View view) {
818            return ViewCompatHC.getTranslationX(view);
819        }
820        @Override
821        public float getTranslationY(View view) {
822            return ViewCompatHC.getTranslationY(view);
823        }
824        @Override
825        public void setTranslationX(View view, float value) {
826            ViewCompatHC.setTranslationX(view, value);
827        }
828        @Override
829        public void setTranslationY(View view, float value) {
830            ViewCompatHC.setTranslationY(view, value);
831        }
832        @Override
833        public void setAlpha(View view, float value) {
834            ViewCompatHC.setAlpha(view, value);
835        }
836        @Override
837        public void setX(View view, float value) {
838            ViewCompatHC.setX(view, value);
839        }
840        @Override
841        public void setY(View view, float value) {
842            ViewCompatHC.setY(view, value);
843        }
844        @Override
845        public void setRotation(View view, float value) {
846            ViewCompatHC.setRotation(view, value);
847        }
848        @Override
849        public void setRotationX(View view, float value) {
850            ViewCompatHC.setRotationX(view, value);
851        }
852        @Override
853        public void setRotationY(View view, float value) {
854            ViewCompatHC.setRotationY(view, value);
855        }
856        @Override
857        public void setScaleX(View view, float value) {
858            ViewCompatHC.setScaleX(view, value);
859        }
860        @Override
861        public void setScaleY(View view, float value) {
862            ViewCompatHC.setScaleY(view, value);
863        }
864        @Override
865        public void setPivotX(View view, float value) {
866            ViewCompatHC.setPivotX(view, value);
867        }
868        @Override
869        public void setPivotY(View view, float value) {
870            ViewCompatHC.setPivotY(view, value);
871        }
872        @Override
873        public float getX(View view) {
874            return ViewCompatHC.getX(view);
875        }
876
877        @Override
878        public float getY(View view) {
879            return ViewCompatHC.getY(view);
880        }
881
882        @Override
883        public float getRotation(View view) {
884            return ViewCompatHC.getRotation(view);
885        }
886
887        @Override
888        public float getRotationX(View view) {
889            return ViewCompatHC.getRotationX(view);
890        }
891
892        @Override
893        public float getRotationY(View view) {
894            return ViewCompatHC.getRotationY(view);
895        }
896
897        @Override
898        public float getScaleX(View view) {
899            return ViewCompatHC.getScaleX(view);
900        }
901
902        @Override
903        public float getScaleY(View view) {
904            return ViewCompatHC.getScaleY(view);
905        }
906
907        @Override
908        public float getPivotX(View view) {
909            return ViewCompatHC.getPivotX(view);
910        }
911        @Override
912        public float getPivotY(View view) {
913            return ViewCompatHC.getPivotY(view);
914        }
915        @Override
916        public void jumpDrawablesToCurrentState(View view) {
917            ViewCompatHC.jumpDrawablesToCurrentState(view);
918        }
919
920        @Override
921        public void setSaveFromParentEnabled(View view, boolean enabled) {
922            ViewCompatHC.setSaveFromParentEnabled(view, enabled);
923        }
924
925        @Override
926        public void setActivated(View view, boolean activated) {
927            ViewCompatHC.setActivated(view, activated);
928        }
929    }
930
931    static class ICSViewCompatImpl extends HCViewCompatImpl {
932        static Field mAccessibilityDelegateField;
933        static boolean accessibilityDelegateCheckFailed = false;
934        @Override
935        public boolean canScrollHorizontally(View v, int direction) {
936            return ViewCompatICS.canScrollHorizontally(v, direction);
937        }
938        @Override
939        public boolean canScrollVertically(View v, int direction) {
940            return ViewCompatICS.canScrollVertically(v, direction);
941        }
942        @Override
943        public void onPopulateAccessibilityEvent(View v, AccessibilityEvent event) {
944            ViewCompatICS.onPopulateAccessibilityEvent(v, event);
945        }
946        @Override
947        public void onInitializeAccessibilityEvent(View v, AccessibilityEvent event) {
948            ViewCompatICS.onInitializeAccessibilityEvent(v, event);
949        }
950        @Override
951        public void onInitializeAccessibilityNodeInfo(View v, AccessibilityNodeInfoCompat info) {
952            ViewCompatICS.onInitializeAccessibilityNodeInfo(v, info.getInfo());
953        }
954        @Override
955        public void setAccessibilityDelegate(View v,
956                @Nullable AccessibilityDelegateCompat delegate) {
957            ViewCompatICS.setAccessibilityDelegate(v,
958                    delegate == null ? null : delegate.getBridge());
959        }
960
961        @Override
962        public boolean hasAccessibilityDelegate(View v) {
963            if (accessibilityDelegateCheckFailed) {
964                return false; // View implementation might have changed.
965            }
966            if (mAccessibilityDelegateField == null) {
967                try {
968                    mAccessibilityDelegateField = View.class
969                            .getDeclaredField("mAccessibilityDelegate");
970                    mAccessibilityDelegateField.setAccessible(true);
971                } catch (Throwable t) {
972                    accessibilityDelegateCheckFailed = true;
973                    return false;
974                }
975            }
976            try {
977                return mAccessibilityDelegateField.get(v) != null;
978            } catch (Throwable t) {
979                accessibilityDelegateCheckFailed = true;
980                return false;
981            }
982        }
983
984        @Override
985        public ViewPropertyAnimatorCompat animate(View view) {
986            if (mViewPropertyAnimatorCompatMap == null) {
987                mViewPropertyAnimatorCompatMap =
988                        new WeakHashMap<View, ViewPropertyAnimatorCompat>();
989            }
990            ViewPropertyAnimatorCompat vpa = mViewPropertyAnimatorCompatMap.get(view);
991            if (vpa == null) {
992                vpa = new ViewPropertyAnimatorCompat(view);
993                mViewPropertyAnimatorCompatMap.put(view, vpa);
994            }
995            return vpa;
996        }
997
998        @Override
999        public void setFitsSystemWindows(View view, boolean fitSystemWindows) {
1000            ViewCompatICS.setFitsSystemWindows(view, fitSystemWindows);
1001        }
1002    }
1003
1004    static class JBViewCompatImpl extends ICSViewCompatImpl {
1005        @Override
1006        public boolean hasTransientState(View view) {
1007            return ViewCompatJB.hasTransientState(view);
1008        }
1009        @Override
1010        public void setHasTransientState(View view, boolean hasTransientState) {
1011            ViewCompatJB.setHasTransientState(view, hasTransientState);
1012        }
1013        @Override
1014        public void postInvalidateOnAnimation(View view) {
1015            ViewCompatJB.postInvalidateOnAnimation(view);
1016        }
1017        @Override
1018        public void postInvalidateOnAnimation(View view, int left, int top, int right, int bottom) {
1019            ViewCompatJB.postInvalidateOnAnimation(view, left, top, right, bottom);
1020        }
1021        @Override
1022        public void postOnAnimation(View view, Runnable action) {
1023            ViewCompatJB.postOnAnimation(view, action);
1024        }
1025        @Override
1026        public void postOnAnimationDelayed(View view, Runnable action, long delayMillis) {
1027            ViewCompatJB.postOnAnimationDelayed(view, action, delayMillis);
1028        }
1029        @Override
1030        public int getImportantForAccessibility(View view) {
1031            return ViewCompatJB.getImportantForAccessibility(view);
1032        }
1033        @Override
1034        public void setImportantForAccessibility(View view, int mode) {
1035            // IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS is not available
1036            // on this platform so replace with IMPORTANT_FOR_ACCESSIBILITY_NO
1037            // which is closer semantically.
1038            if (mode == IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS) {
1039                mode = IMPORTANT_FOR_ACCESSIBILITY_NO;
1040            }
1041            ViewCompatJB.setImportantForAccessibility(view, mode);
1042        }
1043        @Override
1044        public boolean performAccessibilityAction(View view, int action, Bundle arguments) {
1045            return ViewCompatJB.performAccessibilityAction(view, action, arguments);
1046        }
1047        @Override
1048        public AccessibilityNodeProviderCompat getAccessibilityNodeProvider(View view) {
1049            Object compat = ViewCompatJB.getAccessibilityNodeProvider(view);
1050            if (compat != null) {
1051                return new AccessibilityNodeProviderCompat(compat);
1052            }
1053            return null;
1054        }
1055
1056        @Override
1057        public ViewParent getParentForAccessibility(View view) {
1058            return ViewCompatJB.getParentForAccessibility(view);
1059        }
1060
1061        @Override
1062        public int getMinimumWidth(View view) {
1063            return ViewCompatJB.getMinimumWidth(view);
1064        }
1065
1066        @Override
1067        public int getMinimumHeight(View view) {
1068            return ViewCompatJB.getMinimumHeight(view);
1069        }
1070
1071        @Override
1072        public void requestApplyInsets(View view) {
1073            ViewCompatJB.requestApplyInsets(view);
1074        }
1075
1076        @Override
1077        public boolean getFitsSystemWindows(View view) {
1078            return ViewCompatJB.getFitsSystemWindows(view);
1079        }
1080    }
1081
1082    static class JbMr1ViewCompatImpl extends JBViewCompatImpl {
1083
1084        @Override
1085        public int getLabelFor(View view) {
1086            return ViewCompatJellybeanMr1.getLabelFor(view);
1087        }
1088
1089        @Override
1090        public void setLabelFor(View view, int id) {
1091            ViewCompatJellybeanMr1.setLabelFor(view, id);
1092        }
1093
1094        @Override
1095        public void setLayerPaint(View view, Paint paint) {
1096            ViewCompatJellybeanMr1.setLayerPaint(view, paint);
1097        }
1098
1099        @Override
1100        public int getLayoutDirection(View view) {
1101            return ViewCompatJellybeanMr1.getLayoutDirection(view);
1102        }
1103
1104        @Override
1105        public void setLayoutDirection(View view, int layoutDirection) {
1106            ViewCompatJellybeanMr1.setLayoutDirection(view, layoutDirection);
1107        }
1108
1109        @Override
1110        public int getPaddingStart(View view) {
1111            return ViewCompatJellybeanMr1.getPaddingStart(view);
1112        }
1113
1114        @Override
1115        public int getPaddingEnd(View view) {
1116            return ViewCompatJellybeanMr1.getPaddingEnd(view);
1117        }
1118
1119        @Override
1120        public void setPaddingRelative(View view, int start, int top, int end, int bottom) {
1121            ViewCompatJellybeanMr1.setPaddingRelative(view, start, top, end, bottom);
1122        }
1123
1124        @Override
1125        public int getWindowSystemUiVisibility(View view) {
1126            return ViewCompatJellybeanMr1.getWindowSystemUiVisibility(view);
1127        }
1128    }
1129
1130    static class KitKatViewCompatImpl extends JbMr1ViewCompatImpl {
1131        @Override
1132        public int getAccessibilityLiveRegion(View view) {
1133            return ViewCompatKitKat.getAccessibilityLiveRegion(view);
1134        }
1135
1136        @Override
1137        public void setAccessibilityLiveRegion(View view, int mode) {
1138            ViewCompatKitKat.setAccessibilityLiveRegion(view, mode);
1139        }
1140
1141        @Override
1142        public void setImportantForAccessibility(View view, int mode) {
1143            ViewCompatJB.setImportantForAccessibility(view, mode);
1144        }
1145    }
1146
1147    static class Api21ViewCompatImpl extends KitKatViewCompatImpl {
1148        @Override
1149        public void setTransitionName(View view, String transitionName) {
1150            ViewCompatApi21.setTransitionName(view, transitionName);
1151        }
1152
1153        @Override
1154        public String getTransitionName(View view) {
1155            return ViewCompatApi21.getTransitionName(view);
1156        }
1157
1158        @Override
1159        public void requestApplyInsets(View view) {
1160            ViewCompatApi21.requestApplyInsets(view);
1161        }
1162
1163        @Override
1164        public void setElevation(View view, float elevation) {
1165            ViewCompatApi21.setElevation(view, elevation);
1166        }
1167
1168        @Override
1169        public float getElevation(View view) {
1170            return ViewCompatApi21.getElevation(view);
1171        }
1172
1173        @Override
1174        public void setTranslationZ(View view, float translationZ) {
1175            ViewCompatApi21.setTranslationZ(view, translationZ);
1176        }
1177
1178        @Override
1179        public float getTranslationZ(View view) {
1180            return ViewCompatApi21.getTranslationZ(view);
1181        }
1182
1183        @Override
1184        public void setOnApplyWindowInsetsListener(View view, OnApplyWindowInsetsListener listener) {
1185            ViewCompatApi21.setOnApplyWindowInsetsListener(view, listener);
1186        }
1187
1188        @Override
1189        public boolean isImportantForAccessibility(View view) {
1190            return ViewCompatApi21.isImportantForAccessibility(view);
1191        }
1192    }
1193
1194    static final ViewCompatImpl IMPL;
1195    static {
1196        final int version = android.os.Build.VERSION.SDK_INT;
1197        if (version >= 21) {
1198            IMPL = new Api21ViewCompatImpl();
1199        } else if (version >= 19) {
1200            IMPL = new KitKatViewCompatImpl();
1201        } else if (version >= 17) {
1202            IMPL = new JbMr1ViewCompatImpl();
1203        } else if (version >= 16) {
1204            IMPL = new JBViewCompatImpl();
1205        } else if (version >= 14) {
1206            IMPL = new ICSViewCompatImpl();
1207        } else if (version >= 11) {
1208            IMPL = new HCViewCompatImpl();
1209        } else if (version >= 9) {
1210            IMPL = new GBViewCompatImpl();
1211        } else if (version >= 7) {
1212            IMPL = new EclairMr1ViewCompatImpl();
1213        } else {
1214            IMPL = new BaseViewCompatImpl();
1215        }
1216    }
1217
1218    /**
1219     * Check if this view can be scrolled horizontally in a certain direction.
1220     *
1221     * @param v The View against which to invoke the method.
1222     * @param direction Negative to check scrolling left, positive to check scrolling right.
1223     * @return true if this view can be scrolled in the specified direction, false otherwise.
1224     */
1225    public static boolean canScrollHorizontally(View v, int direction) {
1226        return IMPL.canScrollHorizontally(v, direction);
1227    }
1228
1229    /**
1230     * Check if this view can be scrolled vertically in a certain direction.
1231     *
1232     * @param v The View against which to invoke the method.
1233     * @param direction Negative to check scrolling up, positive to check scrolling down.
1234     * @return true if this view can be scrolled in the specified direction, false otherwise.
1235     */
1236    public static boolean canScrollVertically(View v, int direction) {
1237        return IMPL.canScrollVertically(v, direction);
1238    }
1239
1240    /**
1241     * Returns the over-scroll mode for this view. The result will be
1242     * one of {@link #OVER_SCROLL_ALWAYS} (default), {@link #OVER_SCROLL_IF_CONTENT_SCROLLS}
1243     * (allow over-scrolling only if the view content is larger than the container),
1244     * or {@link #OVER_SCROLL_NEVER}.
1245     *
1246     * @param v The View against which to invoke the method.
1247     * @return This view's over-scroll mode.
1248     */
1249    @OverScroll
1250    public static int getOverScrollMode(View v) {
1251        return IMPL.getOverScrollMode(v);
1252    }
1253
1254    /**
1255     * Set the over-scroll mode for this view. Valid over-scroll modes are
1256     * {@link #OVER_SCROLL_ALWAYS} (default), {@link #OVER_SCROLL_IF_CONTENT_SCROLLS}
1257     * (allow over-scrolling only if the view content is larger than the container),
1258     * or {@link #OVER_SCROLL_NEVER}.
1259     *
1260     * Setting the over-scroll mode of a view will have an effect only if the
1261     * view is capable of scrolling.
1262     *
1263     * @param v The View against which to invoke the method.
1264     * @param overScrollMode The new over-scroll mode for this view.
1265     */
1266    public static void setOverScrollMode(View v, @OverScroll int overScrollMode) {
1267        IMPL.setOverScrollMode(v, overScrollMode);
1268    }
1269
1270    /**
1271     * Called from {@link View#dispatchPopulateAccessibilityEvent(AccessibilityEvent)}
1272     * giving a chance to this View to populate the accessibility event with its
1273     * text content. While this method is free to modify event
1274     * attributes other than text content, doing so should normally be performed in
1275     * {@link View#onInitializeAccessibilityEvent(AccessibilityEvent)}.
1276     * <p>
1277     * Example: Adding formatted date string to an accessibility event in addition
1278     *          to the text added by the super implementation:
1279     * <pre> public void onPopulateAccessibilityEvent(AccessibilityEvent event) {
1280     *     super.onPopulateAccessibilityEvent(event);
1281     *     final int flags = DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_SHOW_WEEKDAY;
1282     *     String selectedDateUtterance = DateUtils.formatDateTime(mContext,
1283     *         mCurrentDate.getTimeInMillis(), flags);
1284     *     event.getText().add(selectedDateUtterance);
1285     * }</pre>
1286     * <p>
1287     * If an {@link android.view.View.AccessibilityDelegate} has been specified via calling
1288     * {@link View#setAccessibilityDelegate(android.view.View.AccessibilityDelegate)} its
1289     * {@link android.view.View.AccessibilityDelegate#onPopulateAccessibilityEvent(View,
1290     *  AccessibilityEvent)}
1291     * is responsible for handling this call.
1292     * </p>
1293     * <p class="note"><strong>Note:</strong> Always call the super implementation before adding
1294     * information to the event, in case the default implementation has basic information to add.
1295     * </p>
1296     *
1297     * @param v The View against which to invoke the method.
1298     * @param event The accessibility event which to populate.
1299     *
1300     * @see View#sendAccessibilityEvent(int)
1301     * @see View#dispatchPopulateAccessibilityEvent(AccessibilityEvent)
1302     */
1303    public static void onPopulateAccessibilityEvent(View v, AccessibilityEvent event) {
1304        IMPL.onPopulateAccessibilityEvent(v, event);
1305    }
1306
1307    /**
1308     * Initializes an {@link AccessibilityEvent} with information about
1309     * this View which is the event source. In other words, the source of
1310     * an accessibility event is the view whose state change triggered firing
1311     * the event.
1312     * <p>
1313     * Example: Setting the password property of an event in addition
1314     *          to properties set by the super implementation:
1315     * <pre> public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
1316     *     super.onInitializeAccessibilityEvent(event);
1317     *     event.setPassword(true);
1318     * }</pre>
1319     * <p>
1320     * If an {@link android.view.View.AccessibilityDelegate} has been specified via calling
1321     * {@link View#setAccessibilityDelegate(android.view.View.AccessibilityDelegate)} its
1322     * {@link android.view.View.AccessibilityDelegate#onInitializeAccessibilityEvent(View,
1323     *  AccessibilityEvent)}
1324     * is responsible for handling this call.
1325     * </p>
1326     * <p class="note"><strong>Note:</strong> Always call the super implementation before adding
1327     * information to the event, in case the default implementation has basic information to add.
1328     * </p>
1329     *
1330     * @param v The View against which to invoke the method.
1331     * @param event The event to initialize.
1332     *
1333     * @see View#sendAccessibilityEvent(int)
1334     * @see View#dispatchPopulateAccessibilityEvent(AccessibilityEvent)
1335     */
1336    public static void onInitializeAccessibilityEvent(View v, AccessibilityEvent event) {
1337        IMPL.onInitializeAccessibilityEvent(v, event);
1338    }
1339
1340    /**
1341     * Initializes an {@link android.view.accessibility.AccessibilityNodeInfo} with information
1342     * about this view. The base implementation sets:
1343     * <ul>
1344     * <li>{@link android.view.accessibility.AccessibilityNodeInfo#setParent(View)},</li>
1345     * <li>{@link android.view.accessibility.AccessibilityNodeInfo#setBoundsInParent(Rect)},</li>
1346     * <li>{@link android.view.accessibility.AccessibilityNodeInfo#setBoundsInScreen(Rect)},</li>
1347     * <li>{@link android.view.accessibility.AccessibilityNodeInfo#setPackageName(CharSequence)},</li>
1348     * <li>{@link android.view.accessibility.AccessibilityNodeInfo#setClassName(CharSequence)},</li>
1349     * <li>{@link android.view.accessibility.AccessibilityNodeInfo#setContentDescription(CharSequence)},</li>
1350     * <li>{@link android.view.accessibility.AccessibilityNodeInfo#setEnabled(boolean)},</li>
1351     * <li>{@link android.view.accessibility.AccessibilityNodeInfo#setClickable(boolean)},</li>
1352     * <li>{@link android.view.accessibility.AccessibilityNodeInfo#setFocusable(boolean)},</li>
1353     * <li>{@link android.view.accessibility.AccessibilityNodeInfo#setFocused(boolean)},</li>
1354     * <li>{@link android.view.accessibility.AccessibilityNodeInfo#setLongClickable(boolean)},</li>
1355     * <li>{@link android.view.accessibility.AccessibilityNodeInfo#setSelected(boolean)},</li>
1356     * </ul>
1357     * <p>
1358     * Subclasses should override this method, call the super implementation,
1359     * and set additional attributes.
1360     * </p>
1361     * <p>
1362     * If an {@link android.view.View.AccessibilityDelegate} has been specified via calling
1363     * {@link View#setAccessibilityDelegate(android.view.View.AccessibilityDelegate)} its
1364     * {@link android.view.View.AccessibilityDelegate#onInitializeAccessibilityNodeInfo(View,
1365     *  android.view.accessibility.AccessibilityNodeInfo)}
1366     * is responsible for handling this call.
1367     * </p>
1368     *
1369     * @param v The View against which to invoke the method.
1370     * @param info The instance to initialize.
1371     */
1372    public static void onInitializeAccessibilityNodeInfo(View v, AccessibilityNodeInfoCompat info) {
1373        IMPL.onInitializeAccessibilityNodeInfo(v, info);
1374    }
1375
1376    /**
1377     * Sets a delegate for implementing accessibility support via compositon as
1378     * opposed to inheritance. The delegate's primary use is for implementing
1379     * backwards compatible widgets. For more details see
1380     * {@link android.view.View.AccessibilityDelegate}.
1381     *
1382     * @param v The View against which to invoke the method.
1383     * @param delegate The delegate instance.
1384     *
1385     * @see android.view.View.AccessibilityDelegate
1386     */
1387    public static void setAccessibilityDelegate(View v, AccessibilityDelegateCompat delegate) {
1388        IMPL.setAccessibilityDelegate(v, delegate);
1389    }
1390
1391    /**
1392     * Checks whether provided View has an accessibility delegate attached to it.
1393     *
1394     * @param v The View instance to check
1395     * @return True if the View has an accessibility delegate
1396     */
1397    public static boolean hasAccessibilityDelegate(View v) {
1398        return IMPL.hasAccessibilityDelegate(v);
1399    }
1400
1401    /**
1402     * Indicates whether the view is currently tracking transient state that the
1403     * app should not need to concern itself with saving and restoring, but that
1404     * the framework should take special note to preserve when possible.
1405     *
1406     * @param view View to check for transient state
1407     * @return true if the view has transient state
1408     */
1409    public static boolean hasTransientState(View view) {
1410        return IMPL.hasTransientState(view);
1411    }
1412
1413    /**
1414     * Set whether this view is currently tracking transient state that the
1415     * framework should attempt to preserve when possible.
1416     *
1417     * @param view View tracking transient state
1418     * @param hasTransientState true if this view has transient state
1419     */
1420    public static void setHasTransientState(View view, boolean hasTransientState) {
1421        IMPL.setHasTransientState(view, hasTransientState);
1422    }
1423
1424    /**
1425     * <p>Cause an invalidate to happen on the next animation time step, typically the
1426     * next display frame.</p>
1427     *
1428     * <p>This method can be invoked from outside of the UI thread
1429     * only when this View is attached to a window.</p>
1430     *
1431     * @param view View to invalidate
1432     */
1433    public static void postInvalidateOnAnimation(View view) {
1434        IMPL.postInvalidateOnAnimation(view);
1435    }
1436
1437    /**
1438     * <p>Cause an invalidate of the specified area to happen on the next animation
1439     * time step, typically the next display frame.</p>
1440     *
1441     * <p>This method can be invoked from outside of the UI thread
1442     * only when this View is attached to a window.</p>
1443     *
1444     * @param view View to invalidate
1445     * @param left The left coordinate of the rectangle to invalidate.
1446     * @param top The top coordinate of the rectangle to invalidate.
1447     * @param right The right coordinate of the rectangle to invalidate.
1448     * @param bottom The bottom coordinate of the rectangle to invalidate.
1449     */
1450    public static void postInvalidateOnAnimation(View view, int left, int top,
1451            int right, int bottom) {
1452        IMPL.postInvalidateOnAnimation(view, left, top, right, bottom);
1453    }
1454
1455    /**
1456     * <p>Causes the Runnable to execute on the next animation time step.
1457     * The runnable will be run on the user interface thread.</p>
1458     *
1459     * <p>This method can be invoked from outside of the UI thread
1460     * only when this View is attached to a window.</p>
1461     *
1462     * @param view View to post this Runnable to
1463     * @param action The Runnable that will be executed.
1464     */
1465    public static void postOnAnimation(View view, Runnable action) {
1466        IMPL.postOnAnimation(view, action);
1467    }
1468
1469    /**
1470     * <p>Causes the Runnable to execute on the next animation time step,
1471     * after the specified amount of time elapses.
1472     * The runnable will be run on the user interface thread.</p>
1473     *
1474     * <p>This method can be invoked from outside of the UI thread
1475     * only when this View is attached to a window.</p>
1476     *
1477     * @param view The view to post this Runnable to
1478     * @param action The Runnable that will be executed.
1479     * @param delayMillis The delay (in milliseconds) until the Runnable
1480     *        will be executed.
1481     */
1482    public static void postOnAnimationDelayed(View view, Runnable action, long delayMillis) {
1483        IMPL.postOnAnimationDelayed(view, action, delayMillis);
1484    }
1485
1486    /**
1487     * Gets the mode for determining whether this View is important for accessibility
1488     * which is if it fires accessibility events and if it is reported to
1489     * accessibility services that query the screen.
1490     *
1491     * @param view The view whose property to get.
1492     * @return The mode for determining whether a View is important for accessibility.
1493     *
1494     * @see #IMPORTANT_FOR_ACCESSIBILITY_YES
1495     * @see #IMPORTANT_FOR_ACCESSIBILITY_NO
1496     * @see #IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS
1497     * @see #IMPORTANT_FOR_ACCESSIBILITY_AUTO
1498     */
1499    @ImportantForAccessibility
1500    public static int getImportantForAccessibility(View view) {
1501        return IMPL.getImportantForAccessibility(view);
1502    }
1503
1504    /**
1505     * Sets how to determine whether this view is important for accessibility
1506     * which is if it fires accessibility events and if it is reported to
1507     * accessibility services that query the screen.
1508     * <p>
1509     * <em>Note:</em> If the current paltform version does not support the
1510     *  {@link #IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS} mode, then
1511     *  {@link #IMPORTANT_FOR_ACCESSIBILITY_NO} will be used as it is the
1512     *  closest terms of semantics.
1513     * </p>
1514     *
1515     * @param view The view whose property to set.
1516     * @param mode How to determine whether this view is important for accessibility.
1517     *
1518     * @see #IMPORTANT_FOR_ACCESSIBILITY_YES
1519     * @see #IMPORTANT_FOR_ACCESSIBILITY_NO
1520     * @see #IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS
1521     * @see #IMPORTANT_FOR_ACCESSIBILITY_AUTO
1522     */
1523    public static void setImportantForAccessibility(View view,
1524            @ImportantForAccessibility int mode) {
1525        IMPL.setImportantForAccessibility(view, mode);
1526    }
1527
1528    /**
1529     * Performs the specified accessibility action on the view. For
1530     * possible accessibility actions look at {@link AccessibilityNodeInfoCompat}.
1531     * <p>
1532     * If an {@link AccessibilityDelegateCompat} has been specified via calling
1533     * {@link #setAccessibilityDelegate(View, AccessibilityDelegateCompat)} its
1534     * {@link AccessibilityDelegateCompat#performAccessibilityAction(View, int, Bundle)}
1535     * is responsible for handling this call.
1536     * </p>
1537     *
1538     * @param action The action to perform.
1539     * @param arguments Optional action arguments.
1540     * @return Whether the action was performed.
1541     */
1542    public static boolean performAccessibilityAction(View view, int action, Bundle arguments) {
1543        return IMPL.performAccessibilityAction(view, action, arguments);
1544    }
1545
1546    /**
1547     * Gets the provider for managing a virtual view hierarchy rooted at this View
1548     * and reported to {@link android.accessibilityservice.AccessibilityService}s
1549     * that explore the window content.
1550     * <p>
1551     * If this method returns an instance, this instance is responsible for managing
1552     * {@link AccessibilityNodeInfoCompat}s describing the virtual sub-tree rooted at
1553     * this View including the one representing the View itself. Similarly the returned
1554     * instance is responsible for performing accessibility actions on any virtual
1555     * view or the root view itself.
1556     * </p>
1557     * <p>
1558     * If an {@link AccessibilityDelegateCompat} has been specified via calling
1559     * {@link #setAccessibilityDelegate(View, AccessibilityDelegateCompat)} its
1560     * {@link AccessibilityDelegateCompat#getAccessibilityNodeProvider(View)}
1561     * is responsible for handling this call.
1562     * </p>
1563     *
1564     * @param view The view whose property to get.
1565     * @return The provider.
1566     *
1567     * @see AccessibilityNodeProviderCompat
1568     */
1569    public static AccessibilityNodeProviderCompat getAccessibilityNodeProvider(View view) {
1570        return IMPL.getAccessibilityNodeProvider(view);
1571    }
1572
1573    /**
1574     * The opacity of the view. This is a value from 0 to 1, where 0 means the view is
1575     * completely transparent and 1 means the view is completely opaque.
1576     *
1577     * <p>By default this is 1.0f. Prior to API 11, the returned value is always 1.0f.
1578     * @return The opacity of the view.
1579     */
1580    public static float getAlpha(View view) {
1581        return IMPL.getAlpha(view);
1582    }
1583
1584    /**
1585     * <p>Specifies the type of layer backing this view. The layer can be
1586     * {@link #LAYER_TYPE_NONE disabled}, {@link #LAYER_TYPE_SOFTWARE software} or
1587     * {@link #LAYER_TYPE_HARDWARE hardware}.</p>
1588     *
1589     * <p>A layer is associated with an optional {@link android.graphics.Paint}
1590     * instance that controls how the layer is composed on screen. The following
1591     * properties of the paint are taken into account when composing the layer:</p>
1592     * <ul>
1593     * <li>{@link android.graphics.Paint#getAlpha() Translucency (alpha)}</li>
1594     * <li>{@link android.graphics.Paint#getXfermode() Blending mode}</li>
1595     * <li>{@link android.graphics.Paint#getColorFilter() Color filter}</li>
1596     * </ul>
1597     *
1598     * <p>If this view has an alpha value set to < 1.0 by calling
1599     * setAlpha(float), the alpha value of the layer's paint is replaced by
1600     * this view's alpha value. Calling setAlpha(float) is therefore
1601     * equivalent to setting a hardware layer on this view and providing a paint with
1602     * the desired alpha value.<p>
1603     *
1604     * <p>Refer to the documentation of {@link #LAYER_TYPE_NONE disabled},
1605     * {@link #LAYER_TYPE_SOFTWARE software} and {@link #LAYER_TYPE_HARDWARE hardware}
1606     * for more information on when and how to use layers.</p>
1607     *
1608     * @param layerType The ype of layer to use with this view, must be one of
1609     *        {@link #LAYER_TYPE_NONE}, {@link #LAYER_TYPE_SOFTWARE} or
1610     *        {@link #LAYER_TYPE_HARDWARE}
1611     * @param paint The paint used to compose the layer. This argument is optional
1612     *        and can be null. It is ignored when the layer type is
1613     *        {@link #LAYER_TYPE_NONE}
1614     *
1615     * @param view View to set the layer type for
1616     * @param layerType The type of layer to use with this view, must be one of
1617     *        {@link #LAYER_TYPE_NONE}, {@link #LAYER_TYPE_SOFTWARE} or
1618     *        {@link #LAYER_TYPE_HARDWARE}
1619     * @param paint The paint used to compose the layer. This argument is optional
1620     *        and can be null. It is ignored when the layer type is
1621     *        {@link #LAYER_TYPE_NONE}
1622     */
1623    public static void setLayerType(View view, @LayerType int layerType, Paint paint) {
1624        IMPL.setLayerType(view, layerType, paint);
1625    }
1626
1627    /**
1628     * Indicates what type of layer is currently associated with this view. By default
1629     * a view does not have a layer, and the layer type is {@link #LAYER_TYPE_NONE}.
1630     * Refer to the documentation of
1631     * {@link #setLayerType(android.view.View, int, android.graphics.Paint)}
1632     * for more information on the different types of layers.
1633     *
1634     * @param view The view to fetch the layer type from
1635     * @return {@link #LAYER_TYPE_NONE}, {@link #LAYER_TYPE_SOFTWARE} or
1636     *         {@link #LAYER_TYPE_HARDWARE}
1637     *
1638     * @see #setLayerType(android.view.View, int, android.graphics.Paint)
1639     * @see #LAYER_TYPE_NONE
1640     * @see #LAYER_TYPE_SOFTWARE
1641     * @see #LAYER_TYPE_HARDWARE
1642     */
1643    @LayerType
1644    public static int getLayerType(View view) {
1645        return IMPL.getLayerType(view);
1646    }
1647
1648    /**
1649     * Gets the id of a view for which a given view serves as a label for
1650     * accessibility purposes.
1651     *
1652     * @param view The view on which to invoke the corresponding method.
1653     * @return The labeled view id.
1654     */
1655    public static int getLabelFor(View view) {
1656        return IMPL.getLabelFor(view);
1657    }
1658
1659    /**
1660     * Sets the id of a view for which a given view serves as a label for
1661     * accessibility purposes.
1662     *
1663     * @param view The view on which to invoke the corresponding method.
1664     * @param labeledId The labeled view id.
1665     */
1666    public static void setLabelFor(View view, @IdRes int labeledId) {
1667        IMPL.setLabelFor(view, labeledId);
1668    }
1669
1670    /**
1671     * Updates the {@link Paint} object used with the current layer (used only if the current
1672     * layer type is not set to {@link #LAYER_TYPE_NONE}). Changed properties of the Paint
1673     * provided to {@link #setLayerType(android.view.View, int, android.graphics.Paint)}
1674     * will be used the next time the View is redrawn, but
1675     * {@link #setLayerPaint(android.view.View, android.graphics.Paint)}
1676     * must be called to ensure that the view gets redrawn immediately.
1677     *
1678     * <p>A layer is associated with an optional {@link android.graphics.Paint}
1679     * instance that controls how the layer is composed on screen. The following
1680     * properties of the paint are taken into account when composing the layer:</p>
1681     * <ul>
1682     * <li>{@link android.graphics.Paint#getAlpha() Translucency (alpha)}</li>
1683     * <li>{@link android.graphics.Paint#getXfermode() Blending mode}</li>
1684     * <li>{@link android.graphics.Paint#getColorFilter() Color filter}</li>
1685     * </ul>
1686     *
1687     * <p>If this view has an alpha value set to < 1.0 by calling
1688     * View#setAlpha(float), the alpha value of the layer's paint is replaced by
1689     * this view's alpha value. Calling View#setAlpha(float) is therefore
1690     * equivalent to setting a hardware layer on this view and providing a paint with
1691     * the desired alpha value.</p>
1692     *
1693     * @param view View to set a layer paint for
1694     * @param paint The paint used to compose the layer. This argument is optional
1695     *        and can be null. It is ignored when the layer type is
1696     *        {@link #LAYER_TYPE_NONE}
1697     *
1698     * @see #setLayerType(View, int, android.graphics.Paint)
1699     */
1700    public static void setLayerPaint(View view, Paint paint) {
1701        IMPL.setLayerPaint(view, paint);
1702    }
1703
1704    /**
1705     * Returns the resolved layout direction for this view.
1706     *
1707     * @param view View to get layout direction for
1708     * @return {@link #LAYOUT_DIRECTION_RTL} if the layout direction is RTL or returns
1709     * {@link #LAYOUT_DIRECTION_LTR} if the layout direction is not RTL.
1710     *
1711     * For compatibility, this will return {@link #LAYOUT_DIRECTION_LTR} if API version
1712     * is lower than Jellybean MR1 (API 17)
1713     */
1714    @ResolvedLayoutDirectionMode
1715    public static int getLayoutDirection(View view) {
1716        return IMPL.getLayoutDirection(view);
1717    }
1718
1719    /**
1720     * Set the layout direction for this view. This will propagate a reset of layout direction
1721     * resolution to the view's children and resolve layout direction for this view.
1722     *
1723     * @param view View to set layout direction for
1724     * @param layoutDirection the layout direction to set. Should be one of:
1725     *
1726     * {@link #LAYOUT_DIRECTION_LTR},
1727     * {@link #LAYOUT_DIRECTION_RTL},
1728     * {@link #LAYOUT_DIRECTION_INHERIT},
1729     * {@link #LAYOUT_DIRECTION_LOCALE}.
1730     *
1731     * Resolution will be done if the value is set to LAYOUT_DIRECTION_INHERIT. The resolution
1732     * proceeds up the parent chain of the view to get the value. If there is no parent, then it
1733     * will return the default {@link #LAYOUT_DIRECTION_LTR}.
1734     */
1735    public static void setLayoutDirection(View view, @LayoutDirectionMode int layoutDirection) {
1736        IMPL.setLayoutDirection(view, layoutDirection);
1737    }
1738
1739    /**
1740     * Gets the parent for accessibility purposes. Note that the parent for
1741     * accessibility is not necessary the immediate parent. It is the first
1742     * predecessor that is important for accessibility.
1743     *
1744     * @param view View to retrieve parent for
1745     * @return The parent for use in accessibility inspection
1746     */
1747    public static ViewParent getParentForAccessibility(View view) {
1748        return IMPL.getParentForAccessibility(view);
1749    }
1750
1751    /**
1752     * Indicates whether this View is opaque. An opaque View guarantees that it will
1753     * draw all the pixels overlapping its bounds using a fully opaque color.
1754     *
1755     * On API 7 and above this will call View's true isOpaque method. On previous platform
1756     * versions it will check the opacity of the view's background drawable if present.
1757     *
1758     * @return True if this View is guaranteed to be fully opaque, false otherwise.
1759     */
1760    public static boolean isOpaque(View view) {
1761        return IMPL.isOpaque(view);
1762    }
1763
1764    /**
1765     * Utility to reconcile a desired size and state, with constraints imposed
1766     * by a MeasureSpec.  Will take the desired size, unless a different size
1767     * is imposed by the constraints.  The returned value is a compound integer,
1768     * with the resolved size in the {@link #MEASURED_SIZE_MASK} bits and
1769     * optionally the bit {@link #MEASURED_STATE_TOO_SMALL} set if the resulting
1770     * size is smaller than the size the view wants to be.
1771     *
1772     * @param size How big the view wants to be
1773     * @param measureSpec Constraints imposed by the parent
1774     * @return Size information bit mask as defined by
1775     * {@link #MEASURED_SIZE_MASK} and {@link #MEASURED_STATE_TOO_SMALL}.
1776     */
1777    public static int resolveSizeAndState(int size, int measureSpec, int childMeasuredState) {
1778        return IMPL.resolveSizeAndState(size, measureSpec, childMeasuredState);
1779    }
1780
1781    /**
1782     * Return the full width measurement information for this view as computed
1783     * by the most recent call to {@link android.view.View#measure(int, int)}.
1784     * This result is a bit mask as defined by {@link #MEASURED_SIZE_MASK} and
1785     * {@link #MEASURED_STATE_TOO_SMALL}.
1786     * This should be used during measurement and layout calculations only. Use
1787     * {@link android.view.View#getWidth()} to see how wide a view is after layout.
1788     *
1789     * @return The measured width of this view as a bit mask.
1790     */
1791    public static int getMeasuredWidthAndState(View view) {
1792        return IMPL.getMeasuredWidthAndState(view);
1793    }
1794
1795    /**
1796     * Return the full height measurement information for this view as computed
1797     * by the most recent call to {@link android.view.View#measure(int, int)}.
1798     * This result is a bit mask as defined by {@link #MEASURED_SIZE_MASK} and
1799     * {@link #MEASURED_STATE_TOO_SMALL}.
1800     * This should be used during measurement and layout calculations only. Use
1801     * {@link android.view.View#getHeight()} to see how wide a view is after layout.
1802     *
1803     * @return The measured width of this view as a bit mask.
1804     */
1805    public static int getMeasuredHeightAndState(View view) {
1806        return IMPL.getMeasuredHeightAndState(view);
1807    }
1808
1809    /**
1810     * Return only the state bits of {@link #getMeasuredWidthAndState}
1811     * and {@link #getMeasuredHeightAndState}, combined into one integer.
1812     * The width component is in the regular bits {@link #MEASURED_STATE_MASK}
1813     * and the height component is at the shifted bits
1814     * {@link #MEASURED_HEIGHT_STATE_SHIFT}>>{@link #MEASURED_STATE_MASK}.
1815     */
1816    public static int getMeasuredState(View view) {
1817        return IMPL.getMeasuredState(view);
1818    }
1819
1820    /**
1821     * Gets the live region mode for the specified View.
1822     *
1823     * @param view The view from which to obtain the live region mode
1824     * @return The live region mode for the view.
1825     *
1826     * @see ViewCompat#setAccessibilityLiveRegion(View, int)
1827     */
1828    @AccessibilityLiveRegion
1829    public static int getAccessibilityLiveRegion(View view) {
1830        return IMPL.getAccessibilityLiveRegion(view);
1831    }
1832
1833    /**
1834     * Sets the live region mode for the specified view. This indicates to
1835     * accessibility services whether they should automatically notify the user
1836     * about changes to the view's content description or text, or to the
1837     * content descriptions or text of the view's children (where applicable).
1838     * <p>
1839     * For example, in a login screen with a TextView that displays an "incorrect
1840     * password" notification, that view should be marked as a live region with
1841     * mode {@link #ACCESSIBILITY_LIVE_REGION_POLITE}.
1842     * <p>
1843     * To disable change notifications for this view, use
1844     * {@link #ACCESSIBILITY_LIVE_REGION_NONE}. This is the default live region
1845     * mode for most views.
1846     * <p>
1847     * To indicate that the user should be notified of changes, use
1848     * {@link #ACCESSIBILITY_LIVE_REGION_POLITE}.
1849     * <p>
1850     * If the view's changes should interrupt ongoing speech and notify the user
1851     * immediately, use {@link #ACCESSIBILITY_LIVE_REGION_ASSERTIVE}.
1852     *
1853     * @param view The view on which to set the live region mode
1854     * @param mode The live region mode for this view, one of:
1855     *        <ul>
1856     *        <li>{@link #ACCESSIBILITY_LIVE_REGION_NONE}
1857     *        <li>{@link #ACCESSIBILITY_LIVE_REGION_POLITE}
1858     *        <li>{@link #ACCESSIBILITY_LIVE_REGION_ASSERTIVE}
1859     *        </ul>
1860     */
1861    public static void setAccessibilityLiveRegion(View view, @AccessibilityLiveRegion int mode) {
1862        IMPL.setAccessibilityLiveRegion(view, mode);
1863    }
1864
1865    /**
1866     * Returns the start padding of the specified view depending on its resolved layout direction.
1867     * If there are inset and enabled scrollbars, this value may include the space
1868     * required to display the scrollbars as well.
1869     *
1870     * @param view The view to get padding for
1871     * @return the start padding in pixels
1872     */
1873    public static int getPaddingStart(View view) {
1874        return IMPL.getPaddingStart(view);
1875    }
1876
1877    /**
1878     * Returns the end padding of the specified view depending on its resolved layout direction.
1879     * If there are inset and enabled scrollbars, this value may include the space
1880     * required to display the scrollbars as well.
1881     *
1882     * @param view The view to get padding for
1883     * @return the end padding in pixels
1884     */
1885    public static int getPaddingEnd(View view) {
1886        return IMPL.getPaddingEnd(view);
1887    }
1888
1889    /**
1890     * Sets the relative padding. The view may add on the space required to display
1891     * the scrollbars, depending on the style and visibility of the scrollbars.
1892     * So the values returned from {@link #getPaddingStart}, {@link View#getPaddingTop},
1893     * {@link #getPaddingEnd} and {@link View#getPaddingBottom} may be different
1894     * from the values set in this call.
1895     *
1896     * @param view The view on which to set relative padding
1897     * @param start the start padding in pixels
1898     * @param top the top padding in pixels
1899     * @param end the end padding in pixels
1900     * @param bottom the bottom padding in pixels
1901     */
1902    public static void setPaddingRelative(View view, int start, int top, int end, int bottom) {
1903        IMPL.setPaddingRelative(view, start, top, end, bottom);
1904    }
1905
1906    /**
1907     * Notify a view that it is being temporarily detached.
1908     */
1909    public static void dispatchStartTemporaryDetach(View view) {
1910        IMPL.dispatchStartTemporaryDetach(view);
1911    }
1912
1913    /**
1914     * Notify a view that its temporary detach has ended; the view is now reattached.
1915     */
1916    public static void dispatchFinishTemporaryDetach(View view) {
1917        IMPL.dispatchFinishTemporaryDetach(view);
1918    }
1919
1920    /**
1921     * The horizontal location of this view relative to its {@link View#getLeft() left} position.
1922     * This position is post-layout, in addition to wherever the object's
1923     * layout placed it.
1924     *
1925     * <p>Prior to API 11 this will return 0.</p>
1926     *
1927     * @return The horizontal position of this view relative to its left position, in pixels.
1928     */
1929    public static float getTranslationX(View view) {
1930        return IMPL.getTranslationX(view);
1931    }
1932
1933    /**
1934     * The vertical location of this view relative to its {@link View#getTop() left} position.
1935     * This position is post-layout, in addition to wherever the object's
1936     * layout placed it.
1937     *
1938     * <p>Prior to API 11 this will return 0.</p>
1939     *
1940     * @return The vertical position of this view relative to its top position, in pixels.
1941     */
1942    public static float getTranslationY(View view) {
1943        return IMPL.getTranslationY(view);
1944    }
1945
1946    /**
1947     * Returns the minimum width of the view.
1948     *
1949     * <p>Prior to API 16 this will return 0.</p>
1950     *
1951     * @return the minimum width the view will try to be.
1952     */
1953    public static int getMinimumWidth(View view) {
1954        return IMPL.getMinimumWidth(view);
1955    }
1956
1957    /**
1958     * Returns the minimum height of the view.
1959     *
1960     * <p>Prior to API 16 this will return 0.</p>
1961     *
1962     * @return the minimum height the view will try to be.
1963     */
1964    public static int getMinimumHeight(View view) {
1965        return IMPL.getMinimumHeight(view);
1966    }
1967
1968    /**
1969     * This method returns a ViewPropertyAnimator object, which can be used to animate
1970     * specific properties on this View.
1971     *
1972     * <p>Prior to API 14, this method will do nothing.</p>
1973     *
1974     * @return ViewPropertyAnimator The ViewPropertyAnimator associated with this View.
1975     */
1976    public static ViewPropertyAnimatorCompat animate(View view) {
1977        return IMPL.animate(view);
1978    }
1979
1980    /**
1981     * Sets the horizontal location of this view relative to its left position.
1982     * This effectively positions the object post-layout, in addition to wherever the object's
1983     * layout placed it.
1984     *
1985     * <p>Prior to API 11 this will have no effect.</p>
1986     *
1987     * @param value The horizontal position of this view relative to its left position,
1988     * in pixels.
1989     */
1990    public static void setTranslationX(View view, float value) {
1991        IMPL.setTranslationX(view, value);
1992    }
1993
1994    /**
1995     * Sets the vertical location of this view relative to its top position.
1996     * This effectively positions the object post-layout, in addition to wherever the object's
1997     * layout placed it.
1998     *
1999     * <p>Prior to API 11 this will have no effect.</p>
2000     *
2001     * @param value The vertical position of this view relative to its top position,
2002     * in pixels.
2003     *
2004     * @attr ref android.R.styleable#View_translationY
2005     */
2006    public static void setTranslationY(View view, float value) {
2007        IMPL.setTranslationY(view, value);
2008    }
2009
2010    /**
2011     * <p>Sets the opacity of the view. This is a value from 0 to 1, where 0 means the view is
2012     * completely transparent and 1 means the view is completely opaque.</p>
2013     *
2014     * <p> Note that setting alpha to a translucent value (0 < alpha < 1) can have significant
2015     * performance implications, especially for large views. It is best to use the alpha property
2016     * sparingly and transiently, as in the case of fading animations.</p>
2017     *
2018     * <p>Prior to API 11 this will have no effect.</p>
2019     *
2020     * @param value The opacity of the view.
2021     */
2022    public static void setAlpha(View view, float value) {
2023        IMPL.setAlpha(view, value);
2024    }
2025
2026    /**
2027     * Sets the visual x position of this view, in pixels. This is equivalent to setting the
2028     * {@link #setTranslationX(View, float) translationX} property to be the difference between
2029     * the x value passed in and the current left property of the view as determined
2030     * by the layout bounds.
2031     *
2032     * <p>Prior to API 11 this will have no effect.</p>
2033     *
2034     * @param value The visual x position of this view, in pixels.
2035     */
2036    public static void setX(View view, float value) {
2037        IMPL.setX(view, value);
2038    }
2039
2040    /**
2041     * Sets the visual y position of this view, in pixels. This is equivalent to setting the
2042     * {@link #setTranslationY(View, float) translationY} property to be the difference between
2043     * the y value passed in and the current top property of the view as determined by the
2044     * layout bounds.
2045     *
2046     * <p>Prior to API 11 this will have no effect.</p>
2047     *
2048     * @param value The visual y position of this view, in pixels.
2049     */
2050    public static void setY(View view, float value) {
2051        IMPL.setY(view, value);
2052    }
2053
2054    /**
2055     * Sets the degrees that the view is rotated around the pivot point. Increasing values
2056     * result in clockwise rotation.
2057     *
2058     * <p>Prior to API 11 this will have no effect.</p>
2059     *
2060     * @param value The degrees of rotation.
2061     */
2062    public static void setRotation(View view, float value) {
2063        IMPL.setRotation(view, value);
2064    }
2065
2066    /**
2067     * Sets the degrees that the view is rotated around the horizontal axis through the pivot point.
2068     * Increasing values result in clockwise rotation from the viewpoint of looking down the
2069     * x axis.
2070     *
2071     * <p>Prior to API 11 this will have no effect.</p>
2072     *
2073     * @param value The degrees of X rotation.
2074     */
2075    public static void setRotationX(View view, float value) {
2076        IMPL.setRotationX(view, value);
2077    }
2078
2079    /**
2080     * Sets the degrees that the view is rotated around the vertical axis through the pivot point.
2081     * Increasing values result in counter-clockwise rotation from the viewpoint of looking
2082     * down the y axis.
2083     *
2084     * <p>Prior to API 11 this will have no effect.</p>
2085     *
2086     * @param value The degrees of Y rotation.
2087     */
2088    public static void setRotationY(View view, float value) {
2089        IMPL.setRotationY(view, value);
2090    }
2091
2092    /**
2093     * Sets the amount that the view is scaled in x around the pivot point, as a proportion of
2094     * the view's unscaled width. A value of 1 means that no scaling is applied.
2095     *
2096     * <p>Prior to API 11 this will have no effect.</p>
2097     *
2098     * @param value The scaling factor.
2099     */
2100    public static void setScaleX(View view, float value) {
2101        IMPL.setScaleX(view, value);
2102    }
2103
2104    /**
2105     * Sets the amount that the view is scaled in Y around the pivot point, as a proportion of
2106     * the view's unscaled width. A value of 1 means that no scaling is applied.
2107     *
2108     * <p>Prior to API 11 this will have no effect.</p>
2109     *
2110     * @param value The scaling factor.
2111     */
2112    public static void setScaleY(View view, float value) {
2113        IMPL.setScaleY(view, value);
2114    }
2115
2116    /**
2117     * The x location of the point around which the view is
2118     * {@link #setRotation(View, float) rotated} and {@link #setScaleX(View, float) scaled}.
2119     *
2120     * <p>Prior to API 11 this will have no effect.</p>
2121     *
2122     */
2123    public static float getPivotX(View view) {
2124        return IMPL.getPivotX(view);
2125    }
2126
2127    /**
2128     * Sets the x location of the point around which the view is
2129     * {@link #setRotation(View, float) rotated} and {@link #setScaleX(View, float) scaled}.
2130     * By default, the pivot point is centered on the object.
2131     * Setting this property disables this behavior and causes the view to use only the
2132     * explicitly set pivotX and pivotY values.
2133     *
2134     * <p>Prior to API 11 this will have no effect.</p>
2135     *
2136     * @param value The x location of the pivot point.
2137     */
2138    public static void setPivotX(View view, float value) {
2139        IMPL.setPivotX(view, value);
2140    }
2141
2142    /**
2143     * The y location of the point around which the view is {@link #setRotation(View,
2144     * float) rotated} and {@link #setScaleY(View, float) scaled}.
2145     *
2146     * <p>Prior to API 11 this will return 0.</p>
2147     *
2148     * @return The y location of the pivot point.
2149     */
2150    public static float getPivotY(View view) {
2151        return IMPL.getPivotY(view);
2152    }
2153
2154    /**
2155     * Sets the y location of the point around which the view is
2156     * {@link #setRotation(View, float) rotated} and {@link #setScaleY(View, float) scaled}.
2157     * By default, the pivot point is centered on the object.
2158     * Setting this property disables this behavior and causes the view to use only the
2159     * explicitly set pivotX and pivotY values.
2160     *
2161     * <p>Prior to API 11 this will have no effect.</p>
2162     *
2163     * @param value The y location of the pivot point.
2164     */
2165    public static void setPivotY(View view, float value) {
2166        IMPL.setPivotX(view, value);
2167    }
2168
2169    public static float getRotation(View view) {
2170        return IMPL.getRotation(view);
2171    }
2172
2173    public static float getRotationX(View view) {
2174        return IMPL.getRotationX(view);
2175    }
2176
2177    public static float getRotationY(View view) {
2178        return IMPL.getRotationY(view);
2179    }
2180
2181    public static float getScaleX(View view) {
2182        return IMPL.getScaleX(view);
2183    }
2184
2185    public static float getScaleY(View view) {
2186        return IMPL.getScaleY(view);
2187    }
2188
2189    public static float getX(View view) {
2190        return IMPL.getX(view);
2191    }
2192
2193    public static float getY(View view) {
2194        return IMPL.getY(view);
2195    }
2196
2197    /**
2198     * Sets the base elevation of this view, in pixels.
2199     */
2200    public static void setElevation(View view, float elevation) {
2201        IMPL.setElevation(view, elevation);
2202    }
2203
2204    /**
2205     * The base elevation of this view relative to its parent, in pixels.
2206     *
2207     * @return The base depth position of the view, in pixels.
2208     */
2209    public static float getElevation(View view) {
2210        return IMPL.getElevation(view);
2211    }
2212
2213    /**
2214     * Sets the depth location of this view relative to its {@link #getElevation(View) elevation}.
2215     */
2216    public static void setTranslationZ(View view, float translationZ) {
2217        IMPL.setTranslationZ(view, translationZ);
2218    }
2219
2220    /**
2221     * The depth location of this view relative to its {@link #getElevation(View) elevation}.
2222     *
2223     * @return The depth of this view relative to its elevation.
2224     */
2225    public static float getTranslationZ(View view) {
2226        return IMPL.getTranslationZ(view);
2227    }
2228
2229    /**
2230     * Sets the name of the View to be used to identify Views in Transitions.
2231     * Names should be unique in the View hierarchy.
2232     *
2233     * @param view The View against which to invoke the method.
2234     * @param transitionName The name of the View to uniquely identify it for Transitions.
2235     */
2236    public static void setTransitionName(View view, String transitionName) {
2237        IMPL.setTransitionName(view, transitionName);
2238    }
2239
2240    /**
2241     * Returns the name of the View to be used to identify Views in Transitions.
2242     * Names should be unique in the View hierarchy.
2243     *
2244     * <p>This returns null if the View has not been given a name.</p>
2245     *
2246     * @param view The View against which to invoke the method.
2247     * @return The name used of the View to be used to identify Views in Transitions or null
2248     * if no name has been given.
2249     */
2250    public static String getTransitionName(View view) {
2251        return IMPL.getTransitionName(view);
2252    }
2253
2254    /**
2255     * Returns the current system UI visibility that is currently set for the entire window.
2256     */
2257    public static int getWindowSystemUiVisibility(View view) {
2258        return IMPL.getWindowSystemUiVisibility(view);
2259    }
2260
2261    /**
2262     * Ask that a new dispatch of {@code View.onApplyWindowInsets(WindowInsets)} be performed. This
2263     * falls back to {@code View.requestFitSystemWindows()} where available.
2264     */
2265    public static void requestApplyInsets(View view) {
2266        IMPL.requestApplyInsets(view);
2267    }
2268
2269    /**
2270     * Tells the ViewGroup whether to draw its children in the order defined by the method
2271     * {@code ViewGroup.getChildDrawingOrder(int, int)}.
2272     *
2273     * @param enabled true if the order of the children when drawing is determined by
2274     *        {@link ViewGroup#getChildDrawingOrder(int, int)}, false otherwise
2275     *
2276     * <p>Prior to API 7 this will have no effect.</p>
2277     */
2278    public static void setChildrenDrawingOrderEnabled(ViewGroup viewGroup, boolean enabled) {
2279       IMPL.setChildrenDrawingOrderEnabled(viewGroup, enabled);
2280    }
2281
2282    /**
2283     * Returns true if this view should adapt to fit system window insets. This method will always
2284     * return false before API 16 (Jellybean).
2285     */
2286    public static boolean getFitsSystemWindows(View v) {
2287        return IMPL.getFitsSystemWindows(v);
2288    }
2289
2290    /**
2291     * Sets whether or not this view should account for system screen decorations
2292     * such as the status bar and inset its content; that is, controlling whether
2293     * the default implementation of {@link View#fitSystemWindows(Rect)} will be
2294     * executed. See that method for more details.
2295     */
2296    public static void setFitsSystemWindows(View view, boolean fitSystemWindows) {
2297        IMPL.setFitsSystemWindows(view, fitSystemWindows);
2298    }
2299
2300    /**
2301     * On API 11 devices and above, call <code>Drawable.jumpToCurrentState()</code>
2302     * on all Drawable objects associated with this view.
2303     * <p>
2304     * On API 21 and above, also calls <code>StateListAnimator#jumpToCurrentState()</code>
2305     * if there is a StateListAnimator attached to this view.
2306     */
2307    public static void jumpDrawablesToCurrentState(View v) {
2308        IMPL.jumpDrawablesToCurrentState(v);
2309    }
2310
2311    /**
2312     * Set an {@link OnApplyWindowInsetsListener} to take over the policy for applying
2313     * window insets to this view. This will only take effect on devices with API 21 or above.
2314     */
2315    public static void setOnApplyWindowInsetsListener(View v,
2316            OnApplyWindowInsetsListener listener) {
2317        IMPL.setOnApplyWindowInsetsListener(v, listener);
2318    }
2319
2320    /**
2321     * Controls whether the entire hierarchy under this view will save its
2322     * state when a state saving traversal occurs from its parent.
2323     *
2324     * @param enabled Set to false to <em>disable</em> state saving, or true
2325     * (the default) to allow it.
2326     */
2327    public static void setSaveFromParentEnabled(View v, boolean enabled) {
2328        IMPL.setSaveFromParentEnabled(v, enabled);
2329    }
2330
2331    /**
2332     * Changes the activated state of this view. A view can be activated or not.
2333     * Note that activation is not the same as selection.  Selection is
2334     * a transient property, representing the view (hierarchy) the user is
2335     * currently interacting with.  Activation is a longer-term state that the
2336     * user can move views in and out of.
2337     *
2338     * @param activated true if the view must be activated, false otherwise
2339     */
2340    public static void setActivated(View view, boolean activated) {
2341        IMPL.setActivated(view, activated);
2342    }
2343
2344    // TODO: getters for various view properties (rotation, etc)
2345}
2346