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 package com.android.server.devicepolicy; 17 18 import static android.app.admin.DevicePolicyManager.CONTENT_PROTECTION_DISABLED; 19 import static android.app.admin.DevicePolicyManager.ContentProtectionPolicy; 20 21 import android.annotation.Nullable; 22 import android.annotation.UserIdInt; 23 import android.app.admin.DevicePolicyCache; 24 import android.app.admin.DevicePolicyManager; 25 import android.os.UserHandle; 26 import android.util.ArrayMap; 27 import android.util.IndentingPrintWriter; 28 import android.util.SparseIntArray; 29 30 import com.android.internal.annotations.GuardedBy; 31 32 import java.util.HashSet; 33 import java.util.Map; 34 import java.util.Set; 35 36 /** 37 * Implementation of {@link DevicePolicyCache}, to which {@link DevicePolicyManagerService} pushes 38 * policies. 39 * 40 * TODO Move other copies of policies into this class too. 41 */ 42 public class DevicePolicyCacheImpl extends DevicePolicyCache { 43 /** 44 * Lock object. For simplicity we just always use this as the lock. We could use each object 45 * as a lock object to make it more fine-grained, but that'd make copy-paste error-prone. 46 */ 47 private final Object mLock = new Object(); 48 49 /** 50 * Indicates if screen capture is disallowed on a specific user or all users if 51 * it contains {@link UserHandle#USER_ALL}. 52 */ 53 @GuardedBy("mLock") 54 private final Set<Integer> mScreenCaptureDisallowedUsers = new HashSet<>(); 55 56 @GuardedBy("mLock") 57 private final SparseIntArray mPasswordQuality = new SparseIntArray(); 58 59 @GuardedBy("mLock") 60 private final SparseIntArray mPermissionPolicy = new SparseIntArray(); 61 62 @GuardedBy("mLock") 63 private ArrayMap<String, String> mLauncherShortcutOverrides = new ArrayMap<>(); 64 65 /** Maps to {@code ActiveAdmin.mAdminCanGrantSensorsPermissions}. */ 66 private volatile boolean mCanGrantSensorsPermissions = false; 67 68 @GuardedBy("mLock") 69 private final SparseIntArray mContentProtectionPolicy = new SparseIntArray(); 70 onUserRemoved(int userHandle)71 public void onUserRemoved(int userHandle) { 72 synchronized (mLock) { 73 mPasswordQuality.delete(userHandle); 74 mPermissionPolicy.delete(userHandle); 75 mContentProtectionPolicy.delete(userHandle); 76 } 77 } 78 79 @Override isScreenCaptureAllowed(int userHandle)80 public boolean isScreenCaptureAllowed(int userHandle) { 81 // This won't work if resolution mechanism is not strictest applies, but it's ok for now. 82 synchronized (mLock) { 83 return !mScreenCaptureDisallowedUsers.contains(userHandle) 84 && !mScreenCaptureDisallowedUsers.contains(UserHandle.USER_ALL); 85 } 86 } 87 setScreenCaptureDisallowedUser(int userHandle, boolean disallowed)88 public void setScreenCaptureDisallowedUser(int userHandle, boolean disallowed) { 89 synchronized (mLock) { 90 if (disallowed) { 91 mScreenCaptureDisallowedUsers.add(userHandle); 92 } else { 93 mScreenCaptureDisallowedUsers.remove(userHandle); 94 } 95 } 96 } 97 98 @Override getPasswordQuality(@serIdInt int userHandle)99 public int getPasswordQuality(@UserIdInt int userHandle) { 100 synchronized (mLock) { 101 return mPasswordQuality.get(userHandle, 102 DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED); 103 } 104 } 105 106 /** Updat the password quality cache for the given user */ setPasswordQuality(int userHandle, int quality)107 public void setPasswordQuality(int userHandle, int quality) { 108 synchronized (mLock) { 109 mPasswordQuality.put(userHandle, quality); 110 } 111 } 112 113 @Override getPermissionPolicy(@serIdInt int userHandle)114 public int getPermissionPolicy(@UserIdInt int userHandle) { 115 synchronized (mLock) { 116 return mPermissionPolicy.get(userHandle, 117 DevicePolicyManager.PERMISSION_POLICY_PROMPT); 118 } 119 } 120 121 /** Update the permission policy for the given user. */ setPermissionPolicy(@serIdInt int userHandle, int policy)122 public void setPermissionPolicy(@UserIdInt int userHandle, int policy) { 123 synchronized (mLock) { 124 mPermissionPolicy.put(userHandle, policy); 125 } 126 } 127 128 @Override getContentProtectionPolicy(@serIdInt int userId)129 public @ContentProtectionPolicy int getContentProtectionPolicy(@UserIdInt int userId) { 130 synchronized (mLock) { 131 return mContentProtectionPolicy.get(userId, CONTENT_PROTECTION_DISABLED); 132 } 133 } 134 135 /** Update the content protection policy for the given user. */ setContentProtectionPolicy(@serIdInt int userId, @Nullable Integer value)136 public void setContentProtectionPolicy(@UserIdInt int userId, @Nullable Integer value) { 137 synchronized (mLock) { 138 if (value == null) { 139 mContentProtectionPolicy.delete(userId); 140 } else { 141 mContentProtectionPolicy.put(userId, value); 142 } 143 } 144 } 145 146 @Override canAdminGrantSensorsPermissions()147 public boolean canAdminGrantSensorsPermissions() { 148 return mCanGrantSensorsPermissions; 149 } 150 151 /** Sets admin control over permission grants. */ setAdminCanGrantSensorsPermissions(boolean canGrant)152 public void setAdminCanGrantSensorsPermissions(boolean canGrant) { 153 mCanGrantSensorsPermissions = canGrant; 154 } 155 156 @Override getLauncherShortcutOverrides()157 public Map<String, String> getLauncherShortcutOverrides() { 158 synchronized (mLock) { 159 return new ArrayMap<>(mLauncherShortcutOverrides); 160 } 161 } 162 163 /** 164 * Sets a map of packages names to package names, for which all launcher shortcuts which 165 * match a key package name should be modified to launch the corresponding value package 166 * name in the managed profile. The overridden shortcut should be badged accordingly. 167 */ setLauncherShortcutOverrides(ArrayMap<String, String> launcherShortcutOverrides)168 public void setLauncherShortcutOverrides(ArrayMap<String, String> launcherShortcutOverrides) { 169 synchronized (mLock) { 170 mLauncherShortcutOverrides = new ArrayMap<>(launcherShortcutOverrides); 171 } 172 } 173 174 /** Dump content */ dump(IndentingPrintWriter pw)175 public void dump(IndentingPrintWriter pw) { 176 synchronized (mLock) { 177 pw.println("Device policy cache:"); 178 pw.increaseIndent(); 179 pw.println("Screen capture disallowed users: " + mScreenCaptureDisallowedUsers); 180 pw.println("Password quality: " + mPasswordQuality); 181 pw.println("Permission policy: " + mPermissionPolicy); 182 pw.println("Content protection policy: " + mContentProtectionPolicy); 183 pw.println("Admin can grant sensors permission: " + mCanGrantSensorsPermissions); 184 pw.print("Shortcuts overrides: "); 185 pw.println(mLauncherShortcutOverrides); 186 pw.decreaseIndent(); 187 } 188 } 189 } 190