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.content.Context;
20import android.support.annotation.NonNull;
21import android.support.v4.os.BuildCompat;
22import android.util.Log;
23import android.util.TypedValue;
24import android.view.ViewConfiguration;
25
26import java.lang.reflect.Method;
27
28/**
29 * Helper for accessing features in {@link ViewConfiguration} in a backwards compatible fashion.
30 *
31 * @deprecated Use {@link ViewConfiguration} directly.
32 */
33@Deprecated
34public final class ViewConfigurationCompat {
35    private static final String TAG = "ViewConfigCompat";
36
37    private static Method sGetScaledScrollFactorMethod;
38
39    static {
40        if (android.os.Build.VERSION.SDK_INT >= 25 && !BuildCompat.isAtLeastO()) {
41            try {
42                sGetScaledScrollFactorMethod =
43                        ViewConfiguration.class.getDeclaredMethod("getScaledScrollFactor");
44            } catch (Exception e) {
45                Log.i(TAG, "Could not find method getScaledScrollFactor() on ViewConfiguration");
46            }
47        }
48    }
49
50    /**
51     * Call {@link ViewConfiguration#getScaledPagingTouchSlop()}.
52     *
53     * @deprecated Call {@link ViewConfiguration#getScaledPagingTouchSlop()} directly.
54     * This method will be removed in a future release.
55     */
56    @Deprecated
57    public static int getScaledPagingTouchSlop(ViewConfiguration config) {
58        return config.getScaledPagingTouchSlop();
59    }
60
61    /**
62     * Report if the device has a permanent menu key available to the user, in a backwards
63     * compatible way.
64     *
65     * @deprecated Use {@link ViewConfiguration#hasPermanentMenuKey()} directly.
66     */
67    @Deprecated
68    public static boolean hasPermanentMenuKey(ViewConfiguration config) {
69        return config.hasPermanentMenuKey();
70    }
71
72    /**
73     * @param config Used to get the scaling factor directly from the {@link ViewConfiguration}.
74     * @param context Used to locate a resource value.
75     *
76     * @return Amount to scroll in response to a horizontal {@link MotionEventCompat#ACTION_SCROLL}
77     *         event. Multiply this by the event's axis value to obtain the number of pixels to be
78     *         scrolled.
79     */
80    public static float getScaledHorizontalScrollFactor(@NonNull ViewConfiguration config,
81            @NonNull Context context) {
82        if (BuildCompat.isAtLeastO()) {
83            return config.getScaledHorizontalScrollFactor();
84        } else {
85            return getLegacyScrollFactor(config, context);
86        }
87    }
88
89    /**
90     * @param config Used to get the scaling factor directly from the {@link ViewConfiguration}.
91     * @param context Used to locate a resource value.
92     *
93     * @return Amount to scroll in response to a vertical {@link MotionEventCompat#ACTION_SCROLL}
94     *         event. Multiply this by the event's axis value to obtain the number of pixels to be
95     *         scrolled.
96     */
97    public static float getScaledVerticalScrollFactor(@NonNull ViewConfiguration config,
98            @NonNull Context context) {
99        if (BuildCompat.isAtLeastO()) {
100            return config.getScaledVerticalScrollFactor();
101        } else {
102            return getLegacyScrollFactor(config, context);
103        }
104    }
105
106    private static float getLegacyScrollFactor(ViewConfiguration config, Context context) {
107        if (android.os.Build.VERSION.SDK_INT >= 25 && sGetScaledScrollFactorMethod != null) {
108            try {
109                return (int) sGetScaledScrollFactorMethod.invoke(config);
110            } catch (Exception e) {
111                Log.i(TAG, "Could not find method getScaledScrollFactor() on ViewConfiguration");
112            }
113        }
114        // Fall back to pre-API-25 behavior.
115        TypedValue outValue = new TypedValue();
116        if (context.getTheme().resolveAttribute(
117                android.R.attr.listPreferredItemHeight, outValue, true)) {
118            return outValue.getDimension(context.getResources().getDisplayMetrics());
119        }
120        return 0;
121    }
122
123    private ViewConfigurationCompat() {}
124}
125