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