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