Home | History | Annotate | Download | only in util
      1 /*
      2  * Copyright (C) 2015 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 com.android.contacts.util;
     18 
     19 import android.Manifest.permission;
     20 import android.app.AppOpsManager;
     21 import android.content.BroadcastReceiver;
     22 import android.content.Context;
     23 import android.content.Intent;
     24 import android.content.IntentFilter;
     25 import android.content.pm.PackageManager;
     26 import android.os.Process;
     27 import android.support.v4.content.ContextCompat;
     28 import android.support.v4.content.LocalBroadcastManager;
     29 
     30 /**
     31  * Utility class to help with runtime permissions.
     32  */
     33 public class PermissionsUtil {
     34     // Each permission in this list is a cherry-picked permission from a particular permission
     35     // group. Granting a permission group enables access to all permissions in that group so we
     36     // only need to check a single permission in each group.
     37     // Note: This assumes that the app has correctly requested for all the relevant permissions
     38     // in its Manifest file.
     39     public static final String PHONE = permission.CALL_PHONE;
     40     public static final String CONTACTS = permission.READ_CONTACTS;
     41     public static final String LOCATION = permission.ACCESS_FINE_LOCATION;
     42 
     43     public static boolean hasPhonePermissions(Context context) {
     44         return hasPermission(context, PHONE);
     45     }
     46 
     47     public static boolean hasContactsPermissions(Context context) {
     48         return hasPermission(context, CONTACTS);
     49     }
     50 
     51     public static boolean hasLocationPermissions(Context context) {
     52         return hasPermission(context, LOCATION);
     53     }
     54 
     55     public static boolean hasPermission(Context context, String permission) {
     56         return ContextCompat.checkSelfPermission(context, permission)
     57                 == PackageManager.PERMISSION_GRANTED;
     58     }
     59 
     60     public static boolean hasAppOp(Context context, String appOp) {
     61         final AppOpsManager appOpsManager =
     62                 (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
     63         final int mode = appOpsManager.checkOpNoThrow(appOp, Process.myUid(),
     64                 context.getPackageName());
     65         return mode == AppOpsManager.MODE_ALLOWED;
     66     }
     67 
     68     /**
     69      * Rudimentary methods wrapping the use of a LocalBroadcastManager to simplify the process
     70      * of notifying other classes when a particular fragment is notified that a permission is
     71      * granted.
     72      *
     73      * To be notified when a permission has been granted, create a new broadcast receiver
     74      * and register it using {@link #registerPermissionReceiver(Context, BroadcastReceiver, String)}
     75      *
     76      * E.g.
     77      *
     78      * final BroadcastReceiver receiver = new BroadcastReceiver() {
     79      *     @Override
     80      *     public void onReceive(Context context, Intent intent) {
     81      *         refreshContactsView();
     82      *     }
     83      * }
     84      *
     85      * PermissionsUtil.registerPermissionReceiver(getActivity(), receiver, READ_CONTACTS);
     86      *
     87      * If you register to listen for multiple permissions, you can identify which permission was
     88      * granted by inspecting {@link Intent#getAction()}.
     89      *
     90      * In the fragment that requests for the permission, be sure to call
     91      * {@link #notifyPermissionGranted(Context, String)} when the permission is granted so that
     92      * any interested listeners are notified of the change.
     93      */
     94     public static void registerPermissionReceiver(Context context, BroadcastReceiver receiver,
     95             String permission) {
     96         final IntentFilter filter = new IntentFilter(permission);
     97         LocalBroadcastManager.getInstance(context).registerReceiver(receiver, filter);
     98     }
     99 
    100     public static void unregisterPermissionReceiver(Context context, BroadcastReceiver receiver) {
    101         LocalBroadcastManager.getInstance(context).unregisterReceiver(receiver);
    102     }
    103 
    104     public static void notifyPermissionGranted(Context context, String permission) {
    105         final Intent intent = new Intent(permission);
    106         LocalBroadcastManager.getInstance(context).sendBroadcast(intent);
    107     }
    108 }
    109