1 /*
2  * Copyright (C) 2019 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.DevicePolicyManager;
20 import android.app.admin.DeviceStateCache;
21 import android.util.IndentingPrintWriter;
22 
23 import com.android.internal.annotations.GuardedBy;
24 
25 import java.util.Map;
26 import java.util.concurrent.ConcurrentHashMap;
27 import java.util.concurrent.atomic.AtomicInteger;
28 
29 /**
30  * Implementation of {@link DeviceStateCache}, to which {@link DevicePolicyManagerService} pushes
31  * device state.
32  *
33  */
34 public class DeviceStateCacheImpl extends DeviceStateCache {
35     /**
36      * Lock object. For simplicity we just always use this as the lock. We could use each object
37      * as a lock object to make it more fine-grained, but that'd make copy-paste error-prone.
38      */
39     private final Object mLock = new Object();
40 
41     public static final int NO_DEVICE_OWNER = -1;
42 
43     private AtomicInteger mDeviceOwnerType = new AtomicInteger(NO_DEVICE_OWNER);
44     private Map<Integer, Boolean> mHasProfileOwner = new ConcurrentHashMap<>();
45     private Map<Integer, Boolean> mAffiliationWithDevice = new ConcurrentHashMap<>();
46 
47 
48     @GuardedBy("mLock")
49     private boolean mIsDeviceProvisioned = false;
50 
51     @Override
isDeviceProvisioned()52     public boolean isDeviceProvisioned() {
53         return mIsDeviceProvisioned;
54     }
55 
56     /** Update the device provisioned flag for USER_SYSTEM */
setDeviceProvisioned(boolean provisioned)57     public void setDeviceProvisioned(boolean provisioned) {
58         synchronized (mLock) {
59             mIsDeviceProvisioned = provisioned;
60         }
61     }
62 
setDeviceOwnerType(int deviceOwnerType)63     void setDeviceOwnerType(int deviceOwnerType) {
64         mDeviceOwnerType.set(deviceOwnerType);
65     }
66 
setHasProfileOwner(int userId, boolean hasProfileOwner)67     void setHasProfileOwner(int userId, boolean hasProfileOwner) {
68         if (hasProfileOwner) {
69             mHasProfileOwner.put(userId, true);
70         } else {
71             mHasProfileOwner.remove(userId);
72         }
73     }
74 
setHasAffiliationWithDevice(int userId, Boolean hasAffiliateProfileOwner)75     void setHasAffiliationWithDevice(int userId, Boolean hasAffiliateProfileOwner) {
76         if (hasAffiliateProfileOwner) {
77             mAffiliationWithDevice.put(userId, true);
78         } else {
79             mAffiliationWithDevice.remove(userId);
80         }
81     }
82 
83     @Override
hasAffiliationWithDevice(int userId)84     public boolean hasAffiliationWithDevice(int userId) {
85         return mAffiliationWithDevice.getOrDefault(userId, false);
86     }
87 
88     @Override
isUserOrganizationManaged(@serIdInt int userHandle)89     public boolean isUserOrganizationManaged(@UserIdInt int userHandle) {
90         if (mHasProfileOwner.getOrDefault(userHandle, false)
91                 || hasEnterpriseDeviceOwner()) {
92             return true;
93         }
94 
95         // TODO: Support role holder override
96         return false;
97     }
98 
hasEnterpriseDeviceOwner()99     private boolean hasEnterpriseDeviceOwner() {
100         return mDeviceOwnerType.get() == DevicePolicyManager.DEVICE_OWNER_TYPE_DEFAULT;
101     }
102 
103     /** Dump content */
dump(IndentingPrintWriter pw)104     public void dump(IndentingPrintWriter pw) {
105         pw.println("Device state cache:");
106         pw.increaseIndent();
107         pw.println("Device provisioned: " + mIsDeviceProvisioned);
108         pw.println("Device Owner Type: " + mDeviceOwnerType.get());
109         pw.println("Has PO:");
110         for (Integer id : mHasProfileOwner.keySet()) {
111             pw.println("User " + id + ": " + mHasProfileOwner.get(id));
112         }
113         pw.decreaseIndent();
114     }
115 }
116