1b01b01dddd64c945dd8dfa896648aa36dc47dde3Chris Banes/*
2b01b01dddd64c945dd8dfa896648aa36dc47dde3Chris Banes * Copyright (C) 2015 The Android Open Source Project
3b01b01dddd64c945dd8dfa896648aa36dc47dde3Chris Banes *
4b01b01dddd64c945dd8dfa896648aa36dc47dde3Chris Banes * Licensed under the Apache License, Version 2.0 (the "License");
5b01b01dddd64c945dd8dfa896648aa36dc47dde3Chris Banes * you may not use this file except in compliance with the License.
6b01b01dddd64c945dd8dfa896648aa36dc47dde3Chris Banes * You may obtain a copy of the License at
7b01b01dddd64c945dd8dfa896648aa36dc47dde3Chris Banes *
8b01b01dddd64c945dd8dfa896648aa36dc47dde3Chris Banes *      http://www.apache.org/licenses/LICENSE-2.0
9b01b01dddd64c945dd8dfa896648aa36dc47dde3Chris Banes *
10b01b01dddd64c945dd8dfa896648aa36dc47dde3Chris Banes * Unless required by applicable law or agreed to in writing, software
11b01b01dddd64c945dd8dfa896648aa36dc47dde3Chris Banes * distributed under the License is distributed on an "AS IS" BASIS,
12b01b01dddd64c945dd8dfa896648aa36dc47dde3Chris Banes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13b01b01dddd64c945dd8dfa896648aa36dc47dde3Chris Banes * See the License for the specific language governing permissions and
14b01b01dddd64c945dd8dfa896648aa36dc47dde3Chris Banes * limitations under the License.
15b01b01dddd64c945dd8dfa896648aa36dc47dde3Chris Banes */
16b01b01dddd64c945dd8dfa896648aa36dc47dde3Chris Banes
17b01b01dddd64c945dd8dfa896648aa36dc47dde3Chris Banespackage android.support.v4.graphics.drawable;
18b01b01dddd64c945dd8dfa896648aa36dc47dde3Chris Banes
19b01b01dddd64c945dd8dfa896648aa36dc47dde3Chris Banesimport android.graphics.drawable.Drawable;
20b01b01dddd64c945dd8dfa896648aa36dc47dde3Chris Banesimport android.util.Log;
21b01b01dddd64c945dd8dfa896648aa36dc47dde3Chris Banesimport android.widget.CompoundButton;
22b01b01dddd64c945dd8dfa896648aa36dc47dde3Chris Banes
23b01b01dddd64c945dd8dfa896648aa36dc47dde3Chris Banesimport java.lang.reflect.Field;
24b01b01dddd64c945dd8dfa896648aa36dc47dde3Chris Banesimport java.lang.reflect.InvocationTargetException;
25b01b01dddd64c945dd8dfa896648aa36dc47dde3Chris Banesimport java.lang.reflect.Method;
26b01b01dddd64c945dd8dfa896648aa36dc47dde3Chris Banes
27b01b01dddd64c945dd8dfa896648aa36dc47dde3Chris Banes/**
28b01b01dddd64c945dd8dfa896648aa36dc47dde3Chris Banes * Implementation of drawable compatibility that can call Jellybean MR1 APIs.
29b01b01dddd64c945dd8dfa896648aa36dc47dde3Chris Banes */
30b01b01dddd64c945dd8dfa896648aa36dc47dde3Chris Banesclass DrawableCompatJellybeanMr1 {
31b01b01dddd64c945dd8dfa896648aa36dc47dde3Chris Banes
32b01b01dddd64c945dd8dfa896648aa36dc47dde3Chris Banes    private static final String TAG = "DrawableCompatJellybeanMr1";
33b01b01dddd64c945dd8dfa896648aa36dc47dde3Chris Banes
34b01b01dddd64c945dd8dfa896648aa36dc47dde3Chris Banes    private static Method sSetLayoutDirectionMethod;
35b01b01dddd64c945dd8dfa896648aa36dc47dde3Chris Banes    private static boolean sSetLayoutDirectionMethodFetched;
36b01b01dddd64c945dd8dfa896648aa36dc47dde3Chris Banes
37b01b01dddd64c945dd8dfa896648aa36dc47dde3Chris Banes    private static Method sGetLayoutDirectionMethod;
38b01b01dddd64c945dd8dfa896648aa36dc47dde3Chris Banes    private static boolean sGetLayoutDirectionMethodFetched;
39b01b01dddd64c945dd8dfa896648aa36dc47dde3Chris Banes
402118c89bff1334815e82f89c4fdc9572d0a04c52Alan Viverette    public static boolean setLayoutDirection(Drawable drawable, int layoutDirection) {
41b01b01dddd64c945dd8dfa896648aa36dc47dde3Chris Banes        if (!sSetLayoutDirectionMethodFetched) {
42b01b01dddd64c945dd8dfa896648aa36dc47dde3Chris Banes            try {
43b01b01dddd64c945dd8dfa896648aa36dc47dde3Chris Banes                sSetLayoutDirectionMethod =
44b01b01dddd64c945dd8dfa896648aa36dc47dde3Chris Banes                        Drawable.class.getDeclaredMethod("setLayoutDirection", int.class);
45b01b01dddd64c945dd8dfa896648aa36dc47dde3Chris Banes                sSetLayoutDirectionMethod.setAccessible(true);
46b01b01dddd64c945dd8dfa896648aa36dc47dde3Chris Banes            } catch (NoSuchMethodException e) {
47b01b01dddd64c945dd8dfa896648aa36dc47dde3Chris Banes                Log.i(TAG, "Failed to retrieve setLayoutDirection(int) method", e);
48b01b01dddd64c945dd8dfa896648aa36dc47dde3Chris Banes            }
49b01b01dddd64c945dd8dfa896648aa36dc47dde3Chris Banes            sSetLayoutDirectionMethodFetched = true;
50b01b01dddd64c945dd8dfa896648aa36dc47dde3Chris Banes        }
51b01b01dddd64c945dd8dfa896648aa36dc47dde3Chris Banes
52b01b01dddd64c945dd8dfa896648aa36dc47dde3Chris Banes        if (sSetLayoutDirectionMethod != null) {
53b01b01dddd64c945dd8dfa896648aa36dc47dde3Chris Banes            try {
54b01b01dddd64c945dd8dfa896648aa36dc47dde3Chris Banes                sSetLayoutDirectionMethod.invoke(drawable, layoutDirection);
552118c89bff1334815e82f89c4fdc9572d0a04c52Alan Viverette                return true;
56b01b01dddd64c945dd8dfa896648aa36dc47dde3Chris Banes            } catch (Exception e) {
57b01b01dddd64c945dd8dfa896648aa36dc47dde3Chris Banes                Log.i(TAG, "Failed to invoke setLayoutDirection(int) via reflection", e);
58b01b01dddd64c945dd8dfa896648aa36dc47dde3Chris Banes                sSetLayoutDirectionMethod = null;
59b01b01dddd64c945dd8dfa896648aa36dc47dde3Chris Banes            }
60b01b01dddd64c945dd8dfa896648aa36dc47dde3Chris Banes        }
612118c89bff1334815e82f89c4fdc9572d0a04c52Alan Viverette        return false;
62b01b01dddd64c945dd8dfa896648aa36dc47dde3Chris Banes    }
63b01b01dddd64c945dd8dfa896648aa36dc47dde3Chris Banes
64b01b01dddd64c945dd8dfa896648aa36dc47dde3Chris Banes    public static int getLayoutDirection(Drawable drawable) {
65b01b01dddd64c945dd8dfa896648aa36dc47dde3Chris Banes        if (!sGetLayoutDirectionMethodFetched) {
66b01b01dddd64c945dd8dfa896648aa36dc47dde3Chris Banes            try {
67b01b01dddd64c945dd8dfa896648aa36dc47dde3Chris Banes                sGetLayoutDirectionMethod = Drawable.class.getDeclaredMethod("getLayoutDirection");
68b01b01dddd64c945dd8dfa896648aa36dc47dde3Chris Banes                sGetLayoutDirectionMethod.setAccessible(true);
69b01b01dddd64c945dd8dfa896648aa36dc47dde3Chris Banes            } catch (NoSuchMethodException e) {
70b01b01dddd64c945dd8dfa896648aa36dc47dde3Chris Banes                Log.i(TAG, "Failed to retrieve getLayoutDirection() method", e);
71b01b01dddd64c945dd8dfa896648aa36dc47dde3Chris Banes            }
72b01b01dddd64c945dd8dfa896648aa36dc47dde3Chris Banes            sGetLayoutDirectionMethodFetched = true;
73b01b01dddd64c945dd8dfa896648aa36dc47dde3Chris Banes        }
74b01b01dddd64c945dd8dfa896648aa36dc47dde3Chris Banes
75b01b01dddd64c945dd8dfa896648aa36dc47dde3Chris Banes        if (sGetLayoutDirectionMethod != null) {
76b01b01dddd64c945dd8dfa896648aa36dc47dde3Chris Banes            try {
77b01b01dddd64c945dd8dfa896648aa36dc47dde3Chris Banes                return (int) sGetLayoutDirectionMethod.invoke(drawable);
78b01b01dddd64c945dd8dfa896648aa36dc47dde3Chris Banes            } catch (Exception e) {
79b01b01dddd64c945dd8dfa896648aa36dc47dde3Chris Banes                Log.i(TAG, "Failed to invoke getLayoutDirection() via reflection", e);
80b01b01dddd64c945dd8dfa896648aa36dc47dde3Chris Banes                sGetLayoutDirectionMethod = null;
81b01b01dddd64c945dd8dfa896648aa36dc47dde3Chris Banes            }
82b01b01dddd64c945dd8dfa896648aa36dc47dde3Chris Banes        }
83b01b01dddd64c945dd8dfa896648aa36dc47dde3Chris Banes        return -1;
84b01b01dddd64c945dd8dfa896648aa36dc47dde3Chris Banes    }
85b01b01dddd64c945dd8dfa896648aa36dc47dde3Chris Banes
86b01b01dddd64c945dd8dfa896648aa36dc47dde3Chris Banes}
87