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