149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes/*
249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * Copyright (C) 2014 The Android Open Source Project
349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes *
449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * Licensed under the Apache License, Version 2.0 (the "License");
549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * you may not use this file except in compliance with the License.
649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * You may obtain a copy of the License at
749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes *
849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes *      http://www.apache.org/licenses/LICENSE-2.0
949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes *
1049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * Unless required by applicable law or agreed to in writing, software
1149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * distributed under the License is distributed on an "AS IS" BASIS,
1249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * See the License for the specific language governing permissions and
1449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * limitations under the License.
1549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes */
1649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes
17ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikaspackage androidx.appcompat.widget;
1849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes
19ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikasimport static androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP;
208e10080c914d1ad0784394fa3026b85535535847Aurimas Liutikas
211f4989216d62f70088cea29f9ae200a9bb3ff955Chris Banesimport android.graphics.Rect;
221f4989216d62f70088cea29f9ae200a9bb3ff955Chris Banesimport android.os.Build;
231f4989216d62f70088cea29f9ae200a9bb3ff955Chris Banesimport android.util.Log;
2449c78900da0d43140fb602431fb93212bd7f6c70Chris Banesimport android.view.View;
2549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes
263de8a4e8305507475d7890205184946a25cf45e7Aurimas Liutikasimport androidx.annotation.RestrictTo;
273de8a4e8305507475d7890205184946a25cf45e7Aurimas Liutikasimport androidx.core.view.ViewCompat;
283de8a4e8305507475d7890205184946a25cf45e7Aurimas Liutikas
294c5457da0e82b0090f03655545772ebb8cf4a978Chris Banesimport java.lang.reflect.InvocationTargetException;
301f4989216d62f70088cea29f9ae200a9bb3ff955Chris Banesimport java.lang.reflect.Method;
311f4989216d62f70088cea29f9ae200a9bb3ff955Chris Banes
3249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes/**
3349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * @hide
3449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes */
358e10080c914d1ad0784394fa3026b85535535847Aurimas Liutikas@RestrictTo(LIBRARY_GROUP)
3649c78900da0d43140fb602431fb93212bd7f6c70Chris Banespublic class ViewUtils {
371f4989216d62f70088cea29f9ae200a9bb3ff955Chris Banes    private static final String TAG = "ViewUtils";
381f4989216d62f70088cea29f9ae200a9bb3ff955Chris Banes
391f4989216d62f70088cea29f9ae200a9bb3ff955Chris Banes    private static Method sComputeFitSystemWindowsMethod;
401f4989216d62f70088cea29f9ae200a9bb3ff955Chris Banes
411f4989216d62f70088cea29f9ae200a9bb3ff955Chris Banes    static {
421f4989216d62f70088cea29f9ae200a9bb3ff955Chris Banes        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
431f4989216d62f70088cea29f9ae200a9bb3ff955Chris Banes            try {
441f4989216d62f70088cea29f9ae200a9bb3ff955Chris Banes                sComputeFitSystemWindowsMethod = View.class.getDeclaredMethod(
451f4989216d62f70088cea29f9ae200a9bb3ff955Chris Banes                        "computeFitSystemWindows", Rect.class, Rect.class);
464c5457da0e82b0090f03655545772ebb8cf4a978Chris Banes                if (!sComputeFitSystemWindowsMethod.isAccessible()) {
474c5457da0e82b0090f03655545772ebb8cf4a978Chris Banes                    sComputeFitSystemWindowsMethod.setAccessible(true);
484c5457da0e82b0090f03655545772ebb8cf4a978Chris Banes                }
491f4989216d62f70088cea29f9ae200a9bb3ff955Chris Banes            } catch (NoSuchMethodException e) {
504c5457da0e82b0090f03655545772ebb8cf4a978Chris Banes                Log.d(TAG, "Could not find method computeFitSystemWindows. Oh well.");
511f4989216d62f70088cea29f9ae200a9bb3ff955Chris Banes            }
521f4989216d62f70088cea29f9ae200a9bb3ff955Chris Banes        }
531f4989216d62f70088cea29f9ae200a9bb3ff955Chris Banes    }
5449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes
5549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    private ViewUtils() {}
5649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes
5749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    public static boolean isLayoutRtl(View view) {
5849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        return ViewCompat.getLayoutDirection(view) == ViewCompat.LAYOUT_DIRECTION_RTL;
5949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    }
6049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes
6149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    /**
621f4989216d62f70088cea29f9ae200a9bb3ff955Chris Banes     * Allow calling the hidden method {@code computeFitSystemWindows(Rect, Rect)} through
631f4989216d62f70088cea29f9ae200a9bb3ff955Chris Banes     * reflection on {@code view}.
641f4989216d62f70088cea29f9ae200a9bb3ff955Chris Banes     */
651f4989216d62f70088cea29f9ae200a9bb3ff955Chris Banes    public static void computeFitSystemWindows(View view, Rect inoutInsets, Rect outLocalInsets) {
661f4989216d62f70088cea29f9ae200a9bb3ff955Chris Banes        if (sComputeFitSystemWindowsMethod != null) {
671f4989216d62f70088cea29f9ae200a9bb3ff955Chris Banes            try {
681f4989216d62f70088cea29f9ae200a9bb3ff955Chris Banes                sComputeFitSystemWindowsMethod.invoke(view, inoutInsets, outLocalInsets);
691f4989216d62f70088cea29f9ae200a9bb3ff955Chris Banes            } catch (Exception e) {
704c5457da0e82b0090f03655545772ebb8cf4a978Chris Banes                Log.d(TAG, "Could not invoke computeFitSystemWindows", e);
711f4989216d62f70088cea29f9ae200a9bb3ff955Chris Banes            }
721f4989216d62f70088cea29f9ae200a9bb3ff955Chris Banes        }
731f4989216d62f70088cea29f9ae200a9bb3ff955Chris Banes    }
741f4989216d62f70088cea29f9ae200a9bb3ff955Chris Banes
751f4989216d62f70088cea29f9ae200a9bb3ff955Chris Banes    /**
761f4989216d62f70088cea29f9ae200a9bb3ff955Chris Banes     * Allow calling the hidden method {@code makeOptionalFitsSystem()} through reflection on
771f4989216d62f70088cea29f9ae200a9bb3ff955Chris Banes     * {@code view}.
781f4989216d62f70088cea29f9ae200a9bb3ff955Chris Banes     */
791f4989216d62f70088cea29f9ae200a9bb3ff955Chris Banes    public static void makeOptionalFitsSystemWindows(View view) {
804c5457da0e82b0090f03655545772ebb8cf4a978Chris Banes        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
811f4989216d62f70088cea29f9ae200a9bb3ff955Chris Banes            try {
824c5457da0e82b0090f03655545772ebb8cf4a978Chris Banes                // We need to use getMethod() for makeOptionalFitsSystemWindows since both View
834c5457da0e82b0090f03655545772ebb8cf4a978Chris Banes                // and ViewGroup implement the method
844c5457da0e82b0090f03655545772ebb8cf4a978Chris Banes                Method method = view.getClass().getMethod("makeOptionalFitsSystemWindows");
854c5457da0e82b0090f03655545772ebb8cf4a978Chris Banes                if (!method.isAccessible()) {
864c5457da0e82b0090f03655545772ebb8cf4a978Chris Banes                    method.setAccessible(true);
874c5457da0e82b0090f03655545772ebb8cf4a978Chris Banes                }
884c5457da0e82b0090f03655545772ebb8cf4a978Chris Banes                method.invoke(view);
894c5457da0e82b0090f03655545772ebb8cf4a978Chris Banes            } catch (NoSuchMethodException e) {
904c5457da0e82b0090f03655545772ebb8cf4a978Chris Banes                Log.d(TAG, "Could not find method makeOptionalFitsSystemWindows. Oh well...");
914c5457da0e82b0090f03655545772ebb8cf4a978Chris Banes            } catch (InvocationTargetException e) {
924c5457da0e82b0090f03655545772ebb8cf4a978Chris Banes                Log.d(TAG, "Could not invoke makeOptionalFitsSystemWindows", e);
934c5457da0e82b0090f03655545772ebb8cf4a978Chris Banes            } catch (IllegalAccessException e) {
944c5457da0e82b0090f03655545772ebb8cf4a978Chris Banes                Log.d(TAG, "Could not invoke makeOptionalFitsSystemWindows", e);
951f4989216d62f70088cea29f9ae200a9bb3ff955Chris Banes            }
961f4989216d62f70088cea29f9ae200a9bb3ff955Chris Banes        }
971f4989216d62f70088cea29f9ae200a9bb3ff955Chris Banes    }
9849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes}
99