1 /*
2  * Copyright (C) 2014 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 
17 package androidx.appcompat.widget;
18 
19 import static androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP;
20 
21 import android.graphics.Rect;
22 import android.os.Build;
23 import android.util.Log;
24 import android.view.View;
25 
26 import androidx.annotation.RestrictTo;
27 import androidx.core.view.ViewCompat;
28 
29 import java.lang.reflect.InvocationTargetException;
30 import java.lang.reflect.Method;
31 
32 /**
33  * @hide
34  */
35 @RestrictTo(LIBRARY_GROUP)
36 public class ViewUtils {
37     private static final String TAG = "ViewUtils";
38 
39     private static Method sComputeFitSystemWindowsMethod;
40 
41     static {
42         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
43             try {
44                 sComputeFitSystemWindowsMethod = View.class.getDeclaredMethod(
45                         "computeFitSystemWindows", Rect.class, Rect.class);
46                 if (!sComputeFitSystemWindowsMethod.isAccessible()) {
47                     sComputeFitSystemWindowsMethod.setAccessible(true);
48                 }
49             } catch (NoSuchMethodException e) {
50                 Log.d(TAG, "Could not find method computeFitSystemWindows. Oh well.");
51             }
52         }
53     }
54 
ViewUtils()55     private ViewUtils() {}
56 
isLayoutRtl(View view)57     public static boolean isLayoutRtl(View view) {
58         return ViewCompat.getLayoutDirection(view) == ViewCompat.LAYOUT_DIRECTION_RTL;
59     }
60 
61     /**
62      * Allow calling the hidden method {@code computeFitSystemWindows(Rect, Rect)} through
63      * reflection on {@code view}.
64      */
computeFitSystemWindows(View view, Rect inoutInsets, Rect outLocalInsets)65     public static void computeFitSystemWindows(View view, Rect inoutInsets, Rect outLocalInsets) {
66         if (sComputeFitSystemWindowsMethod != null) {
67             try {
68                 sComputeFitSystemWindowsMethod.invoke(view, inoutInsets, outLocalInsets);
69             } catch (Exception e) {
70                 Log.d(TAG, "Could not invoke computeFitSystemWindows", e);
71             }
72         }
73     }
74 
75     /**
76      * Allow calling the hidden method {@code makeOptionalFitsSystem()} through reflection on
77      * {@code view}.
78      */
makeOptionalFitsSystemWindows(View view)79     public static void makeOptionalFitsSystemWindows(View view) {
80         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
81             try {
82                 // We need to use getMethod() for makeOptionalFitsSystemWindows since both View
83                 // and ViewGroup implement the method
84                 Method method = view.getClass().getMethod("makeOptionalFitsSystemWindows");
85                 if (!method.isAccessible()) {
86                     method.setAccessible(true);
87                 }
88                 method.invoke(view);
89             } catch (NoSuchMethodException e) {
90                 Log.d(TAG, "Could not find method makeOptionalFitsSystemWindows. Oh well...");
91             } catch (InvocationTargetException e) {
92                 Log.d(TAG, "Could not invoke makeOptionalFitsSystemWindows", e);
93             } catch (IllegalAccessException e) {
94                 Log.d(TAG, "Could not invoke makeOptionalFitsSystemWindows", e);
95             }
96         }
97     }
98 }
99