| /* |
| * Copyright (C) 2011 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package android.support.v13.app; |
| |
| import android.app.Fragment; |
| import android.content.Context; |
| import android.content.pm.PackageManager; |
| import android.os.Build; |
| import android.os.Handler; |
| import android.os.Looper; |
| import android.support.annotation.NonNull; |
| import android.support.annotation.RequiresApi; |
| import android.support.annotation.RestrictTo; |
| |
| import java.util.Arrays; |
| |
| /** |
| * Helper for accessing features in {@link Fragment} in a backwards compatible fashion. |
| * |
| * @deprecated Use {@link android.support.v4.app.Fragment} instead of the framework fragment. |
| */ |
| @Deprecated |
| public class FragmentCompat { |
| |
| /** |
| * @deprecated Use {@link android.support.v4.app.Fragment} instead of the framework fragment. |
| */ |
| @Deprecated |
| public FragmentCompat() { |
| } |
| |
| interface FragmentCompatImpl { |
| void setUserVisibleHint(Fragment f, boolean deferStart); |
| void requestPermissions(Fragment fragment, String[] permissions, int requestCode); |
| boolean shouldShowRequestPermissionRationale(Fragment fragment, String permission); |
| } |
| |
| /** |
| * Customizable delegate that allows delegating permission related compatibility methods |
| * to a custom implementation. |
| * |
| * <p> |
| * To delegate fragment compatibility methods to a custom class, implement this interface, |
| * and call {@code FragmentCompat.setPermissionCompatDelegate(delegate);}. All future calls |
| * to the compatibility methods in this class will first check whether the delegate can |
| * handle the method call, and invoke the corresponding method if it can. |
| * </p> |
| * |
| * @deprecated Use {@link android.support.v4.app.Fragment} instead of the framework |
| * {@link Fragment}. |
| */ |
| @Deprecated |
| public interface PermissionCompatDelegate { |
| |
| /** |
| * Determines whether the delegate should handle |
| * {@link FragmentCompat#requestPermissions(Fragment, String[], int)}, and request |
| * permissions if applicable. If this method returns true, it means that permission |
| * request is successfully handled by the delegate, and platform should not perform any |
| * further requests for permission. |
| * |
| * @param fragment The target fragment. |
| * @param permissions The requested permissions. |
| * @param requestCode Application specific request code to match with a result |
| * reported to {@link OnRequestPermissionsResultCallback#onRequestPermissionsResult( |
| * int, String[], int[])}. |
| * |
| * @return Whether the delegate has handled the permission request. |
| * @see FragmentCompat#requestPermissions(Fragment, String[], int) |
| * |
| * @deprecated Use {@link android.support.v4.app.Fragment} instead of the framework |
| * {@link Fragment}. |
| */ |
| @Deprecated |
| boolean requestPermissions(Fragment fragment, String[] permissions, int requestCode); |
| } |
| |
| static class FragmentCompatBaseImpl implements FragmentCompatImpl { |
| @Override |
| public void setUserVisibleHint(Fragment f, boolean deferStart) { |
| } |
| @Override |
| public void requestPermissions(final Fragment fragment, final String[] permissions, |
| final int requestCode) { |
| Handler handler = new Handler(Looper.getMainLooper()); |
| handler.post(new Runnable() { |
| @Override |
| public void run() { |
| final int[] grantResults = new int[permissions.length]; |
| |
| Context context = fragment.getActivity(); |
| if (context != null) { |
| PackageManager packageManager = context.getPackageManager(); |
| String packageName = context.getPackageName(); |
| |
| final int permissionCount = permissions.length; |
| for (int i = 0; i < permissionCount; i++) { |
| grantResults[i] = packageManager.checkPermission( |
| permissions[i], packageName); |
| } |
| } else { |
| Arrays.fill(grantResults, PackageManager.PERMISSION_DENIED); |
| } |
| |
| ((OnRequestPermissionsResultCallback) fragment).onRequestPermissionsResult( |
| requestCode, permissions, grantResults); |
| } |
| }); |
| } |
| @Override |
| public boolean shouldShowRequestPermissionRationale(Fragment fragment, String permission) { |
| return false; |
| } |
| } |
| |
| @RequiresApi(15) |
| static class FragmentCompatApi15Impl extends FragmentCompatBaseImpl { |
| @Override |
| public void setUserVisibleHint(Fragment f, boolean deferStart) { |
| f.setUserVisibleHint(deferStart); |
| } |
| } |
| |
| @RequiresApi(23) |
| static class FragmentCompatApi23Impl extends FragmentCompatApi15Impl { |
| @Override |
| public void requestPermissions(Fragment fragment, String[] permissions, int requestCode) { |
| fragment.requestPermissions(permissions, requestCode); |
| } |
| |
| @Override |
| public boolean shouldShowRequestPermissionRationale(Fragment fragment, String permission) { |
| return fragment.shouldShowRequestPermissionRationale(permission); |
| } |
| } |
| |
| @RequiresApi(24) |
| static class FragmentCompatApi24Impl extends FragmentCompatApi23Impl { |
| @Override |
| public void setUserVisibleHint(Fragment f, boolean deferStart) { |
| f.setUserVisibleHint(deferStart); |
| } |
| } |
| |
| static final FragmentCompatImpl IMPL; |
| static { |
| if (Build.VERSION.SDK_INT >= 24) { |
| IMPL = new FragmentCompatApi24Impl(); |
| } else if (Build.VERSION.SDK_INT >= 23) { |
| IMPL = new FragmentCompatApi23Impl(); |
| } else if (android.os.Build.VERSION.SDK_INT >= 15) { |
| IMPL = new FragmentCompatApi15Impl(); |
| } else { |
| IMPL = new FragmentCompatBaseImpl(); |
| } |
| } |
| |
| private static PermissionCompatDelegate sDelegate; |
| |
| /** |
| * Sets the permission delegate for {@code FragmentCompat}. Replaces the previously set |
| * delegate. |
| * |
| * @param delegate The delegate to be set. {@code null} to clear the set delegate. |
| * |
| * @deprecated Use {@link android.support.v4.app.Fragment} instead of the framework |
| * {@link Fragment}. |
| */ |
| @Deprecated |
| public static void setPermissionCompatDelegate(PermissionCompatDelegate delegate) { |
| sDelegate = delegate; |
| } |
| |
| /** |
| * @hide |
| * |
| * @deprecated Use {@link android.support.v4.app.Fragment} instead of the framework |
| * {@link Fragment}. |
| */ |
| @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP) |
| @Deprecated |
| public static PermissionCompatDelegate getPermissionCompatDelegate() { |
| return sDelegate; |
| } |
| |
| /** |
| * This interface is the contract for receiving the results for permission requests. |
| * |
| * @deprecated Use {@link android.support.v4.app.Fragment} instead of the framework |
| * {@link Fragment}. |
| */ |
| @Deprecated |
| public interface OnRequestPermissionsResultCallback { |
| |
| /** |
| * Callback for the result from requesting permissions. This method |
| * is invoked for every call on {@link #requestPermissions(android.app.Fragment, |
| * String[], int)} |
| * |
| * @param requestCode The request code passed in {@link #requestPermissions( |
| * android.app.Fragment, String[], int)} |
| * @param permissions The requested permissions. Never null. |
| * @param grantResults The grant results for the corresponding permissions |
| * which is either {@link android.content.pm.PackageManager#PERMISSION_GRANTED} |
| * or {@link android.content.pm.PackageManager#PERMISSION_DENIED}. Never null. |
| * |
| * @see #requestPermissions(android.app.Fragment, String[], int) |
| * |
| * @deprecated Use {@link android.support.v4.app.Fragment} instead of the framework |
| * {@link Fragment}. |
| */ |
| @Deprecated |
| public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, |
| @NonNull int[] grantResults); |
| } |
| |
| /** |
| * Call {@link Fragment#setMenuVisibility(boolean) Fragment.setMenuVisibility(boolean)} |
| * if running on an appropriate version of the platform. |
| * |
| * @deprecated Use {@link android.support.v4.app.Fragment} instead of the framework |
| * {@link Fragment}. |
| */ |
| @Deprecated |
| public static void setMenuVisibility(Fragment f, boolean visible) { |
| f.setMenuVisibility(visible); |
| } |
| |
| /** |
| * Call {@link Fragment#setUserVisibleHint(boolean) setUserVisibleHint(boolean)} |
| * if running on an appropriate version of the platform. |
| * |
| * @deprecated Use {@link android.support.v4.app.Fragment} instead of the framework |
| * {@link Fragment}. |
| */ |
| @Deprecated |
| public static void setUserVisibleHint(Fragment f, boolean deferStart) { |
| IMPL.setUserVisibleHint(f, deferStart); |
| } |
| |
| /** |
| * Requests permissions to be granted to this application. These permissions |
| * must be requested in your manifest, they should not be granted to your app, |
| * and they should have protection level {@link android.content.pm.PermissionInfo |
| * #PROTECTION_DANGEROUS dangerous}, regardless whether they are declared by |
| * the platform or a third-party app. |
| * <p> |
| * Normal permissions {@link android.content.pm.PermissionInfo#PROTECTION_NORMAL} |
| * are granted at install time if requested in the manifest. Signature permissions |
| * {@link android.content.pm.PermissionInfo#PROTECTION_SIGNATURE} are granted at |
| * install time if requested in the manifest and the signature of your app matches |
| * the signature of the app declaring the permissions. |
| * </p> |
| * <p> |
| * If your app does not have the requested permissions the user will be presented |
| * with UI for accepting them. After the user has accepted or rejected the |
| * requested permissions you will receive a callback reporting whether the |
| * permissions were granted or not. Your fragment has to implement {@link |
| * OnRequestPermissionsResultCallback} |
| * and the results of permission requests will be delivered to its |
| * {@link OnRequestPermissionsResultCallback#onRequestPermissionsResult( |
| * int, String[], int[])}. |
| * </p> |
| * <p> |
| * Note that requesting a permission does not guarantee it will be granted and |
| * your app should be able to run without having this permission. |
| * </p> |
| * <p> |
| * This method may start an activity allowing the user to choose which permissions |
| * to grant and which to reject. Hence, you should be prepared that your activity |
| * may be paused and resumed. Further, granting some permissions may require |
| * a restart of you application. In such a case, the system will recreate the |
| * activity stack before delivering the result to your onRequestPermissionsResult( |
| * int, String[], int[]). |
| * </p> |
| * <p> |
| * When checking whether you have a permission you should use {@link |
| * android.support.v4.content.ContextCompat#checkSelfPermission( |
| * android.content.Context, String)}. |
| * </p> |
| * |
| * @param fragment The target fragment. |
| * @param permissions The requested permissions. |
| * @param requestCode Application specific request code to match with a result |
| * reported to {@link OnRequestPermissionsResultCallback#onRequestPermissionsResult( |
| * int, String[], int[])}. |
| * |
| * @see android.support.v4.content.ContextCompat#checkSelfPermission( |
| * android.content.Context, String) |
| * @see #shouldShowRequestPermissionRationale(android.app.Fragment, String) |
| * |
| * @deprecated Use {@link android.support.v4.app.Fragment} instead of the framework |
| * {@link Fragment}. |
| */ |
| @Deprecated |
| public static void requestPermissions(@NonNull Fragment fragment, |
| @NonNull String[] permissions, int requestCode) { |
| if (sDelegate != null && sDelegate.requestPermissions(fragment, permissions, requestCode)) { |
| // Delegate has handled the request. |
| return; |
| } |
| |
| IMPL.requestPermissions(fragment, permissions, requestCode); |
| } |
| |
| /** |
| * Gets whether you should show UI with rationale for requesting a permission. |
| * You should do this only if you do not have the permission and the context in |
| * which the permission is requested does not clearly communicate to the user |
| * what would be the benefit from granting this permission. |
| * <p> |
| * For example, if you write a camera app, requesting the camera permission |
| * would be expected by the user and no rationale for why it is requested is |
| * needed. If however, the app needs location for tagging photos then a non-tech |
| * savvy user may wonder how location is related to taking photos. In this case |
| * you may choose to show UI with rationale of requesting this permission. |
| * </p> |
| * |
| * @param fragment The target fragment. |
| * @param permission A permission your app wants to request. |
| * @return Whether you can show permission rationale UI. |
| * |
| * @see android.support.v4.content.ContextCompat#checkSelfPermission( |
| * android.content.Context, String) |
| * @see #requestPermissions(android.app.Fragment, String[], int) |
| * |
| * @deprecated Use {@link android.support.v4.app.Fragment} instead of the framework |
| * {@link Fragment}. |
| */ |
| @Deprecated |
| public static boolean shouldShowRequestPermissionRationale(@NonNull Fragment fragment, |
| @NonNull String permission) { |
| return IMPL.shouldShowRequestPermissionRationale(fragment, permission); |
| } |
| } |