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 * Get 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 * Get 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 * Send 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 getShowAdminSupportDetailsIntent(Context context, EnforcedAdmin admin)100 public static Intent getShowAdminSupportDetailsIntent(Context context, EnforcedAdmin admin) { 101 final Intent intent = new Intent(Settings.ACTION_SHOW_ADMIN_SUPPORT_DETAILS); 102 if (admin != null) { 103 if (admin.component != null) { 104 intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN, admin.component); 105 } 106 intent.putExtra(Intent.EXTRA_USER, admin.user); 107 } 108 return intent; 109 } 110 111 /** 112 * Check if current user is profile or not 113 */ 114 @RequiresApi(Build.VERSION_CODES.M) isCurrentUserOrProfile(Context context, int userId)115 public static boolean isCurrentUserOrProfile(Context context, int userId) { 116 UserManager um = context.getSystemService(UserManager.class); 117 return um.getUserProfiles().contains(UserHandle.of(userId)); 118 } 119 120 public static class EnforcedAdmin { 121 @Nullable 122 public ComponentName component = null; 123 /** 124 * The restriction enforced by admin. It could be any user restriction or policy like 125 * {@link DevicePolicyManager#POLICY_DISABLE_CAMERA}. 126 */ 127 @Nullable 128 public String enforcedRestriction = null; 129 @Nullable 130 public UserHandle user = null; 131 132 // We use this to represent the case where a policy is enforced by multiple admins. 133 public final static EnforcedAdmin MULTIPLE_ENFORCED_ADMIN = new EnforcedAdmin(); 134 createDefaultEnforcedAdminWithRestriction( String enforcedRestriction)135 public static EnforcedAdmin createDefaultEnforcedAdminWithRestriction( 136 String enforcedRestriction) { 137 EnforcedAdmin enforcedAdmin = new EnforcedAdmin(); 138 enforcedAdmin.enforcedRestriction = enforcedRestriction; 139 return enforcedAdmin; 140 } 141 EnforcedAdmin(ComponentName component, UserHandle user)142 public EnforcedAdmin(ComponentName component, UserHandle user) { 143 this.component = component; 144 this.user = user; 145 } 146 EnforcedAdmin(ComponentName component, String enforcedRestriction, UserHandle user)147 public EnforcedAdmin(ComponentName component, String enforcedRestriction, UserHandle user) { 148 this.component = component; 149 this.enforcedRestriction = enforcedRestriction; 150 this.user = user; 151 } 152 EnforcedAdmin(EnforcedAdmin other)153 public EnforcedAdmin(EnforcedAdmin other) { 154 if (other == null) { 155 throw new IllegalArgumentException(); 156 } 157 this.component = other.component; 158 this.enforcedRestriction = other.enforcedRestriction; 159 this.user = other.user; 160 } 161 EnforcedAdmin()162 public EnforcedAdmin() { 163 } 164 165 /** 166 * Combines two {@link EnforcedAdmin} into one: if one of them is null, then just return 167 * the other. If both of them are the same, then return that. Otherwise return the symbolic 168 * {@link #MULTIPLE_ENFORCED_ADMIN} 169 */ combine(EnforcedAdmin admin1, EnforcedAdmin admin2)170 public static EnforcedAdmin combine(EnforcedAdmin admin1, EnforcedAdmin admin2) { 171 if (admin1 == null) { 172 return admin2; 173 } 174 if (admin2 == null) { 175 return admin1; 176 } 177 if (admin1.equals(admin2)) { 178 return admin1; 179 } 180 if (!admin1.enforcedRestriction.equals(admin2.enforcedRestriction)) { 181 throw new IllegalArgumentException( 182 "Admins with different restriction cannot be combined"); 183 } 184 return MULTIPLE_ENFORCED_ADMIN; 185 } 186 187 @Override equals(Object o)188 public boolean equals(Object o) { 189 if (this == o) return true; 190 if (o == null || getClass() != o.getClass()) return false; 191 EnforcedAdmin that = (EnforcedAdmin) o; 192 return Objects.equals(user, that.user) && 193 Objects.equals(component, that.component) && 194 Objects.equals(enforcedRestriction, that.enforcedRestriction); 195 } 196 197 @Override hashCode()198 public int hashCode() { 199 return Objects.hash(component, enforcedRestriction, user); 200 } 201 202 @Override toString()203 public String toString() { 204 return "EnforcedAdmin{" + 205 "component=" + component + 206 ", enforcedRestriction='" + enforcedRestriction + 207 ", user=" + user + 208 '}'; 209 } 210 } 211 } 212