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.util.IndentingPrintWriter;
22 import android.util.SparseBooleanArray;
23 import android.util.SparseIntArray;
24 
25 import com.android.internal.annotations.GuardedBy;
26 
27 /**
28  * Implementation of {@link DevicePolicyCache}, to which {@link DevicePolicyManagerService} pushes
29  * policies.
30  *
31  * TODO Move other copies of policies into this class too.
32  */
33 public class DevicePolicyCacheImpl extends DevicePolicyCache {
34     /**
35      * Lock object. For simplicity we just always use this as the lock. We could use each object
36      * as a lock object to make it more fine-grained, but that'd make copy-paste error-prone.
37      */
38     private final Object mLock = new Object();
39 
40     @GuardedBy("mLock")
41     private final SparseBooleanArray mScreenCaptureDisabled = new SparseBooleanArray();
42 
43     @GuardedBy("mLock")
44     private final SparseIntArray mPasswordQuality = new SparseIntArray();
45 
46     @GuardedBy("mLock")
47     private final SparseIntArray mPermissionPolicy = new SparseIntArray();
48 
49     /** Maps to {@code ActiveAdmin.mAdminCanGrantSensorsPermissions}.
50      *
51      * <p>For users affiliated with the device, they inherit the policy from {@code DO} so
52      * it will map to the {@code DO}'s policy. Otherwise it will map to the admin of the requesting
53      * user.
54      */
55     @GuardedBy("mLock")
56     private final SparseBooleanArray mCanGrantSensorsPermissions = new SparseBooleanArray();
57 
onUserRemoved(int userHandle)58     public void onUserRemoved(int userHandle) {
59         synchronized (mLock) {
60             mScreenCaptureDisabled.delete(userHandle);
61             mPasswordQuality.delete(userHandle);
62             mPermissionPolicy.delete(userHandle);
63             mCanGrantSensorsPermissions.delete(userHandle);
64         }
65     }
66 
67     @Override
isScreenCaptureAllowed(int userHandle, boolean ownerCanAddInternalSystemWindow)68     public boolean isScreenCaptureAllowed(int userHandle, boolean ownerCanAddInternalSystemWindow) {
69         synchronized (mLock) {
70             return !mScreenCaptureDisabled.get(userHandle) || ownerCanAddInternalSystemWindow;
71         }
72     }
73 
setScreenCaptureAllowed(int userHandle, boolean allowed)74     public void setScreenCaptureAllowed(int userHandle, boolean allowed) {
75         synchronized (mLock) {
76             mScreenCaptureDisabled.put(userHandle, !allowed);
77         }
78     }
79 
80     @Override
getPasswordQuality(@serIdInt int userHandle)81     public int getPasswordQuality(@UserIdInt int userHandle) {
82         synchronized (mLock) {
83             return mPasswordQuality.get(userHandle,
84                     DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED);
85         }
86     }
87 
88     /** Updat the password quality cache for the given user */
setPasswordQuality(int userHandle, int quality)89     public void setPasswordQuality(int userHandle, int quality) {
90         synchronized (mLock) {
91             mPasswordQuality.put(userHandle, quality);
92         }
93     }
94 
95     @Override
getPermissionPolicy(@serIdInt int userHandle)96     public int getPermissionPolicy(@UserIdInt int userHandle) {
97         synchronized (mLock) {
98             return mPermissionPolicy.get(userHandle,
99                     DevicePolicyManager.PERMISSION_POLICY_PROMPT);
100         }
101     }
102 
103     /** Update the permission policy for the given user. */
setPermissionPolicy(@serIdInt int userHandle, int policy)104     public void setPermissionPolicy(@UserIdInt int userHandle, int policy) {
105         synchronized (mLock) {
106             mPermissionPolicy.put(userHandle, policy);
107         }
108     }
109 
110     @Override
canAdminGrantSensorsPermissionsForUser(@serIdInt int userId)111     public boolean canAdminGrantSensorsPermissionsForUser(@UserIdInt int userId) {
112         synchronized (mLock) {
113             return mCanGrantSensorsPermissions.get(userId, false);
114         }
115     }
116 
117     /** Sets ahmin control over permission grants for user. */
setAdminCanGrantSensorsPermissions(@serIdInt int userId, boolean canGrant)118     public void setAdminCanGrantSensorsPermissions(@UserIdInt int userId, boolean canGrant) {
119         synchronized (mLock) {
120             mCanGrantSensorsPermissions.put(userId, canGrant);
121         }
122     }
123 
124     /** Dump content */
dump(IndentingPrintWriter pw)125     public void dump(IndentingPrintWriter pw) {
126         pw.println("Device policy cache:");
127         pw.increaseIndent();
128         pw.println("Screen capture disabled: " + mScreenCaptureDisabled.toString());
129         pw.println("Password quality: " + mPasswordQuality.toString());
130         pw.println("Permission policy: " + mPermissionPolicy.toString());
131         pw.println("Admin can grant sensors permission: "
132                 + mCanGrantSensorsPermissions.toString());
133         pw.decreaseIndent();
134     }
135 }
136