1 /* 2 * Copyright (C) 2021 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.permissioncontroller.permission.utils.v31; 18 19 import android.Manifest; 20 import android.app.admin.DevicePolicyManager; 21 import android.app.admin.ManagedSubscriptionsPolicy; 22 import android.content.Context; 23 import android.os.UserHandle; 24 import android.os.UserManager; 25 import android.util.ArraySet; 26 27 import com.android.modules.utils.build.SdkLevel; 28 import com.android.permissioncontroller.permission.utils.PermissionMapping; 29 30 /** 31 * A class for dealing with permissions that the admin may not grant in certain configurations. 32 */ 33 public final class AdminRestrictedPermissionsUtils { 34 /** 35 * A set of permissions that the Profile Owner cannot grant and that the Device Owner 36 * could potentially grant (depending on opt-out state). 37 */ 38 private static final ArraySet<String> ADMIN_RESTRICTED_SENSORS_PERMISSIONS = new ArraySet<>(); 39 40 static { 41 ADMIN_RESTRICTED_SENSORS_PERMISSIONS.add(Manifest.permission.ACCESS_FINE_LOCATION); 42 ADMIN_RESTRICTED_SENSORS_PERMISSIONS.add(Manifest.permission.ACCESS_BACKGROUND_LOCATION); 43 ADMIN_RESTRICTED_SENSORS_PERMISSIONS.add(Manifest.permission.ACCESS_COARSE_LOCATION); 44 ADMIN_RESTRICTED_SENSORS_PERMISSIONS.add(Manifest.permission.CAMERA); 45 ADMIN_RESTRICTED_SENSORS_PERMISSIONS.add(Manifest.permission.RECORD_AUDIO); 46 ADMIN_RESTRICTED_SENSORS_PERMISSIONS.add(Manifest.permission.ACTIVITY_RECOGNITION); 47 ADMIN_RESTRICTED_SENSORS_PERMISSIONS.add(Manifest.permission.BODY_SENSORS); 48 // New S permissions - do not add unless running on S and above. 49 if (SdkLevel.isAtLeastS()) { 50 ADMIN_RESTRICTED_SENSORS_PERMISSIONS.add(Manifest.permission.BACKGROUND_CAMERA); 51 ADMIN_RESTRICTED_SENSORS_PERMISSIONS.add(Manifest.permission.RECORD_BACKGROUND_AUDIO); 52 } 53 // New T permissions - do not add unless running on T and above. 54 if (SdkLevel.isAtLeastT()) { 55 ADMIN_RESTRICTED_SENSORS_PERMISSIONS.add(Manifest.permission.BODY_SENSORS_BACKGROUND); 56 } 57 58 } 59 60 /** Adds a new permission to the list of admin restricted permissions. */ addAdminRestrictedPermission(String permission)61 public static void addAdminRestrictedPermission(String permission) { 62 ADMIN_RESTRICTED_SENSORS_PERMISSIONS.add(permission); 63 } 64 65 /** 66 * Returns true if the admin may grant this permission, false otherwise. 67 */ mayAdminGrantPermission(Context context, String permission, int userId)68 public static boolean mayAdminGrantPermission(Context context, String permission, int userId) { 69 if (!SdkLevel.isAtLeastS()) { 70 return true; 71 } 72 Context userContext = context.createContextAsUser(UserHandle.of(userId), /* flags= */0); 73 DevicePolicyManager dpm = userContext.getSystemService(DevicePolicyManager.class); 74 UserManager um = userContext.getSystemService(UserManager.class); 75 if (um.isManagedProfile(userId) && Manifest.permission.READ_SMS.equals(permission)) { 76 return mayManagedProfileAdminGrantReadSms(dpm); 77 } 78 if (!ADMIN_RESTRICTED_SENSORS_PERMISSIONS.contains(permission)) { 79 return true; 80 } 81 82 return dpm.canAdminGrantSensorsPermissions(); 83 } 84 85 /** 86 * Returns true if the admin may grant this permission, false otherwise. 87 */ mayAdminGrantPermission(String permission, String permissionGroup, boolean canAdminGrantSensorsPermissions, boolean isManagedProfile, DevicePolicyManager dpm)88 public static boolean mayAdminGrantPermission(String permission, String permissionGroup, 89 boolean canAdminGrantSensorsPermissions, boolean isManagedProfile, 90 DevicePolicyManager dpm) { 91 if (!SdkLevel.isAtLeastS()) { 92 return true; 93 } 94 if (isManagedProfile && Manifest.permission.READ_SMS.equals(permission)) { 95 return mayManagedProfileAdminGrantReadSms(dpm); 96 } 97 boolean isAdminRestrictedSensorPermissionGroup = permissionGroup != null 98 && PermissionMapping.getPlatformPermissionNamesOfGroup(permissionGroup).stream() 99 .anyMatch(ADMIN_RESTRICTED_SENSORS_PERMISSIONS::contains); 100 if (!ADMIN_RESTRICTED_SENSORS_PERMISSIONS.contains(permission) 101 && !isAdminRestrictedSensorPermissionGroup) { 102 return true; 103 } 104 105 return canAdminGrantSensorsPermissions; 106 } 107 mayManagedProfileAdminGrantReadSms(DevicePolicyManager dpm)108 private static boolean mayManagedProfileAdminGrantReadSms(DevicePolicyManager dpm) { 109 return SdkLevel.isAtLeastU() && dpm.isOrganizationOwnedDeviceWithManagedProfile() 110 && dpm.getManagedSubscriptionsPolicy().getPolicyType() 111 == ManagedSubscriptionsPolicy.TYPE_ALL_MANAGED_SUBSCRIPTIONS; 112 } 113 } 114