1 /* 2 * Copyright (C) 2018 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.settingslib; 18 19 import android.app.admin.DevicePolicyManager; 20 import android.content.ComponentName; 21 import android.content.Context; 22 import android.content.Intent; 23 import android.content.pm.PackageManager; 24 import android.os.Build; 25 import android.os.UserHandle; 26 import android.os.UserManager; 27 import android.provider.Settings; 28 29 import androidx.annotation.Nullable; 30 import androidx.annotation.RequiresApi; 31 32 import java.util.Objects; 33 34 /** 35 * Utility class to host methods usable in adding a restricted padlock icon and showing admin 36 * support message dialog. 37 */ 38 public class RestrictedLockUtils { 39 /** 40 * Gets EnforcedAdmin from DevicePolicyManager 41 */ 42 @RequiresApi(Build.VERSION_CODES.M) getProfileOrDeviceOwner(Context context, UserHandle user)43 public static EnforcedAdmin getProfileOrDeviceOwner(Context context, UserHandle user) { 44 return getProfileOrDeviceOwner(context, null, user); 45 } 46 47 /** 48 * Gets EnforcedAdmin from DevicePolicyManager 49 */ 50 @RequiresApi(Build.VERSION_CODES.M) getProfileOrDeviceOwner( Context context, String enforcedRestriction, UserHandle user)51 public static EnforcedAdmin getProfileOrDeviceOwner( 52 Context context, String enforcedRestriction, UserHandle user) { 53 if (user == null) { 54 return null; 55 } 56 final DevicePolicyManager dpm = (DevicePolicyManager) context.getSystemService( 57 Context.DEVICE_POLICY_SERVICE); 58 if (dpm == null) { 59 return null; 60 } 61 62 Context userContext; 63 try { 64 userContext = context.createPackageContextAsUser(context.getPackageName(), 0, user); 65 } catch (PackageManager.NameNotFoundException e) { 66 throw new IllegalStateException(e); 67 } 68 69 ComponentName adminComponent = userContext.getSystemService( 70 DevicePolicyManager.class).getProfileOwner(); 71 if (adminComponent != null) { 72 return new EnforcedAdmin(adminComponent, enforcedRestriction, user); 73 } 74 if (Objects.equals(dpm.getDeviceOwnerUser(), user)) { 75 adminComponent = dpm.getDeviceOwnerComponentOnAnyUser(); 76 if (adminComponent != null) { 77 return new EnforcedAdmin(adminComponent, enforcedRestriction, user); 78 } 79 } 80 return null; 81 } 82 83 /** 84 * Sends the intent to trigger the {@code android.settings.ShowAdminSupportDetailsDialog}. 85 */ 86 @RequiresApi(Build.VERSION_CODES.M) sendShowAdminSupportDetailsIntent(Context context, EnforcedAdmin admin)87 public static void sendShowAdminSupportDetailsIntent(Context context, EnforcedAdmin admin) { 88 final Intent intent = getShowAdminSupportDetailsIntent(context, admin); 89 int targetUserId = UserHandle.myUserId(); 90 if (admin != null) { 91 if (admin.user != null 92 && isCurrentUserOrProfile(context, admin.user.getIdentifier())) { 93 targetUserId = admin.user.getIdentifier(); 94 } 95 intent.putExtra(DevicePolicyManager.EXTRA_RESTRICTION, admin.enforcedRestriction); 96 } 97 context.startActivityAsUser(intent, UserHandle.of(targetUserId)); 98 } 99 100 /** 101 * Gets the intent to trigger the {@code android.settings.ShowAdminSupportDetailsDialog}. 102 */ getShowAdminSupportDetailsIntent(Context context, EnforcedAdmin admin)103 public static Intent getShowAdminSupportDetailsIntent(Context context, EnforcedAdmin admin) { 104 final Intent intent = new Intent(Settings.ACTION_SHOW_ADMIN_SUPPORT_DETAILS); 105 if (admin != null) { 106 if (admin.component != null) { 107 intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN, admin.component); 108 } 109 intent.putExtra(Intent.EXTRA_USER, admin.user); 110 } 111 return intent; 112 } 113 114 /** 115 * Shows restricted setting dialog. 116 */ 117 @RequiresApi(Build.VERSION_CODES.TIRAMISU) sendShowRestrictedSettingDialogIntent(Context context, String packageName, int uid)118 public static void sendShowRestrictedSettingDialogIntent(Context context, 119 String packageName, int uid) { 120 final Intent intent = getShowRestrictedSettingsIntent(packageName, uid); 121 context.startActivity(intent); 122 } 123 124 /** 125 * Gets restricted settings dialog intent. 126 */ getShowRestrictedSettingsIntent(String packageName, int uid)127 private static Intent getShowRestrictedSettingsIntent(String packageName, int uid) { 128 final Intent intent = new Intent(Settings.ACTION_SHOW_RESTRICTED_SETTING_DIALOG); 129 intent.putExtra(Intent.EXTRA_PACKAGE_NAME, packageName); 130 intent.putExtra(Intent.EXTRA_UID, uid); 131 return intent; 132 } 133 134 /** 135 * Checks if current user is profile or not 136 */ 137 @RequiresApi(Build.VERSION_CODES.M) isCurrentUserOrProfile(Context context, int userId)138 public static boolean isCurrentUserOrProfile(Context context, int userId) { 139 UserManager um = context.getSystemService(UserManager.class); 140 return um.getUserProfiles().contains(UserHandle.of(userId)); 141 } 142 143 /** 144 * A admin for the restriction enforced. 145 */ 146 public static class EnforcedAdmin { 147 @Nullable 148 public ComponentName component = null; 149 /** 150 * The restriction enforced by admin. It could be any user restriction or policy like 151 * {@link DevicePolicyManager#POLICY_DISABLE_CAMERA}. 152 */ 153 @Nullable 154 public String enforcedRestriction = null; 155 @Nullable 156 public UserHandle user = null; 157 158 /** 159 * We use this to represent the case where a policy is enforced by multiple admins. 160 */ 161 public static final EnforcedAdmin MULTIPLE_ENFORCED_ADMIN = new EnforcedAdmin(); 162 163 /** 164 * The restriction enforced by admin with restriction. 165 */ createDefaultEnforcedAdminWithRestriction( String enforcedRestriction)166 public static EnforcedAdmin createDefaultEnforcedAdminWithRestriction( 167 String enforcedRestriction) { 168 final EnforcedAdmin enforcedAdmin = new EnforcedAdmin(); 169 enforcedAdmin.enforcedRestriction = enforcedRestriction; 170 return enforcedAdmin; 171 } 172 EnforcedAdmin(ComponentName component, UserHandle user)173 public EnforcedAdmin(ComponentName component, UserHandle user) { 174 this.component = component; 175 this.user = user; 176 } 177 EnforcedAdmin(ComponentName component, String enforcedRestriction, UserHandle user)178 public EnforcedAdmin(ComponentName component, String enforcedRestriction, UserHandle user) { 179 this.component = component; 180 this.enforcedRestriction = enforcedRestriction; 181 this.user = user; 182 } 183 EnforcedAdmin(EnforcedAdmin other)184 public EnforcedAdmin(EnforcedAdmin other) { 185 if (other == null) { 186 throw new IllegalArgumentException(); 187 } 188 this.component = other.component; 189 this.enforcedRestriction = other.enforcedRestriction; 190 this.user = other.user; 191 } 192 EnforcedAdmin()193 public EnforcedAdmin() {} 194 195 /** 196 * Combines two {@link EnforcedAdmin} into one: if one of them is null, then just return 197 * the other. If both of them are the same, then return that. Otherwise return the symbolic 198 * {@link #MULTIPLE_ENFORCED_ADMIN} 199 */ combine(EnforcedAdmin admin1, EnforcedAdmin admin2)200 public static EnforcedAdmin combine(EnforcedAdmin admin1, EnforcedAdmin admin2) { 201 if (admin1 == null) { 202 return admin2; 203 } 204 if (admin2 == null) { 205 return admin1; 206 } 207 if (admin1.equals(admin2)) { 208 return admin1; 209 } 210 if (!admin1.enforcedRestriction.equals(admin2.enforcedRestriction)) { 211 throw new IllegalArgumentException( 212 "Admins with different restriction cannot be combined"); 213 } 214 return MULTIPLE_ENFORCED_ADMIN; 215 } 216 217 @Override equals(Object o)218 public boolean equals(Object o) { 219 if (this == o) return true; 220 if (o == null || getClass() != o.getClass()) return false; 221 EnforcedAdmin that = (EnforcedAdmin) o; 222 return Objects.equals(user, that.user) 223 && Objects.equals(component, that.component) 224 && Objects.equals(enforcedRestriction, that.enforcedRestriction); 225 } 226 227 @Override hashCode()228 public int hashCode() { 229 return Objects.hash(component, enforcedRestriction, user); 230 } 231 232 @Override toString()233 public String toString() { 234 return "EnforcedAdmin{" 235 + "component=" + component 236 + ", enforcedRestriction='" + enforcedRestriction 237 + ", user=" + user 238 + '}'; 239 } 240 } 241 } 242