1 /*
2  * Copyright (C) 2014 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 
17 package com.android.server.devicepolicy;
18 
19 import static android.app.admin.DevicePolicyManager.DEPRECATE_USERMANAGERINTERNAL_DEVICEPOLICY_DEFAULT;
20 import static android.app.admin.DevicePolicyManager.DEPRECATE_USERMANAGERINTERNAL_DEVICEPOLICY_FLAG;
21 import static android.app.admin.DevicePolicyManager.DEVICE_OWNER_TYPE_DEFAULT;
22 import static android.app.admin.DevicePolicyManager.DEVICE_OWNER_TYPE_FINANCED;
23 
24 import static com.android.server.devicepolicy.DeviceStateCacheImpl.NO_DEVICE_OWNER;
25 
26 import android.annotation.Nullable;
27 import android.app.ActivityManagerInternal;
28 import android.app.AppOpsManagerInternal;
29 import android.app.admin.DevicePolicyManager.DeviceOwnerType;
30 import android.app.admin.SystemUpdateInfo;
31 import android.app.admin.SystemUpdatePolicy;
32 import android.content.ComponentName;
33 import android.content.pm.PackageManager;
34 import android.content.pm.PackageManagerInternal;
35 import android.os.Binder;
36 import android.os.Process;
37 import android.os.UserHandle;
38 import android.os.UserManager;
39 import android.provider.DeviceConfig;
40 import android.util.ArraySet;
41 import android.util.IndentingPrintWriter;
42 import android.util.Pair;
43 import android.util.Slog;
44 import android.util.SparseArray;
45 import android.util.SparseIntArray;
46 
47 import com.android.internal.annotations.GuardedBy;
48 import com.android.internal.annotations.VisibleForTesting;
49 import com.android.server.LocalServices;
50 import com.android.server.devicepolicy.OwnersData.OwnerInfo;
51 import com.android.server.pm.UserManagerInternal;
52 import com.android.server.wm.ActivityTaskManagerInternal;
53 
54 import java.io.File;
55 import java.time.LocalDate;
56 import java.util.ArrayList;
57 import java.util.List;
58 import java.util.Objects;
59 import java.util.Set;
60 
61 /**
62  * Stores and restores state for the Device and Profile owners and related device-wide information.
63  * By definition there can be only one device owner, but there may be a profile owner for each user.
64  *
65  * <p>This class is thread safe, so individual methods can safely be called without locking.
66  * However, caller must still synchronize on their side to ensure integrity between multiple calls.
67  */
68 class Owners {
69     private static final String TAG = "DevicePolicyManagerService";
70 
71     private static final boolean DEBUG = false; // DO NOT SUBMIT WITH TRUE
72 
73     private final UserManager mUserManager;
74     private final UserManagerInternal mUserManagerInternal;
75     private final PackageManagerInternal mPackageManagerInternal;
76     private final ActivityTaskManagerInternal mActivityTaskManagerInternal;
77     private final ActivityManagerInternal mActivityManagerInternal;
78     private final DeviceStateCacheImpl mDeviceStateCache;
79 
80     @GuardedBy("mData")
81     private final OwnersData mData;
82 
83     private boolean mSystemReady;
84 
85     @VisibleForTesting
Owners(UserManager userManager, UserManagerInternal userManagerInternal, PackageManagerInternal packageManagerInternal, ActivityTaskManagerInternal activityTaskManagerInternal, ActivityManagerInternal activityManagerInternal, DeviceStateCacheImpl deviceStateCache, PolicyPathProvider pathProvider)86     Owners(UserManager userManager,
87             UserManagerInternal userManagerInternal,
88             PackageManagerInternal packageManagerInternal,
89             ActivityTaskManagerInternal activityTaskManagerInternal,
90             ActivityManagerInternal activityManagerInternal,
91             DeviceStateCacheImpl deviceStateCache,
92             PolicyPathProvider pathProvider) {
93         mUserManager = userManager;
94         mUserManagerInternal = userManagerInternal;
95         mPackageManagerInternal = packageManagerInternal;
96         mActivityTaskManagerInternal = activityTaskManagerInternal;
97         mActivityManagerInternal = activityManagerInternal;
98         mDeviceStateCache = deviceStateCache;
99         mData = new OwnersData(pathProvider);
100     }
101 
102     /**
103      * Load configuration from the disk.
104      */
load()105     void load() {
106         synchronized (mData) {
107             int[] usersIds =
108                     mUserManager.getAliveUsers().stream().mapToInt(u -> u.id).toArray();
109             mData.load(usersIds);
110 
111             // TODO(b/258213147): Remove
112             if (DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_DEVICE_POLICY_MANAGER,
113                     DEPRECATE_USERMANAGERINTERNAL_DEVICEPOLICY_FLAG,
114                     DEPRECATE_USERMANAGERINTERNAL_DEVICEPOLICY_DEFAULT)) {
115                 if (hasDeviceOwner()) {
116                     int deviceOwnerType = mData.mDeviceOwnerTypes.getOrDefault(
117                             mData.mDeviceOwner.packageName,
118                             /* defaultValue= */ DEVICE_OWNER_TYPE_DEFAULT);
119                     mDeviceStateCache.setDeviceOwnerType(deviceOwnerType);
120                 } else {
121                     mDeviceStateCache.setDeviceOwnerType(NO_DEVICE_OWNER);
122                 }
123                 for (int userId : usersIds) {
124                     mDeviceStateCache.setHasProfileOwner(userId, hasProfileOwner(userId));
125                 }
126             } else {
127                 mUserManagerInternal.setDeviceManaged(hasDeviceOwner());
128                 for (int userId : usersIds) {
129                     mUserManagerInternal.setUserManaged(userId, hasProfileOwner(userId));
130                 }
131             }
132 
133             notifyChangeLocked();
134             pushDeviceOwnerUidToActivityTaskManagerLocked();
135             pushProfileOwnerUidsToActivityTaskManagerLocked();
136         }
137     }
138 
139     // Notify interested parties that things have changed. This does not notify the
140     // ActivityTaskManager.
141     @GuardedBy("mData")
notifyChangeLocked()142     private void notifyChangeLocked() {
143         pushToDevicePolicyManager();
144         pushToPackageManagerLocked();
145         pushToActivityManagerLocked();
146         pushToAppOpsLocked();
147     }
148 
pushToDevicePolicyManager()149     private void pushToDevicePolicyManager() {
150         // Not every change here must invalidate the DPM caches, but there is no harm in
151         // invalidating the caches unnecessarily, provided the invalidation is infrequent.
152         DevicePolicyManagerService.invalidateBinderCaches();
153     }
154 
155     @GuardedBy("mData")
pushToPackageManagerLocked()156     private void pushToPackageManagerLocked() {
157         final SparseArray<String> po = new SparseArray<>();
158         for (int i = mData.mProfileOwners.size() - 1; i >= 0; i--) {
159             po.put(mData.mProfileOwners.keyAt(i), mData.mProfileOwners.valueAt(i).packageName);
160         }
161         final String doPackage = mData.mDeviceOwner != null ? mData.mDeviceOwner.packageName : null;
162         mPackageManagerInternal.setDeviceAndProfileOwnerPackages(
163                 mData.mDeviceOwnerUserId, doPackage, po);
164     }
165 
166     @GuardedBy("mData")
pushDeviceOwnerUidToActivityTaskManagerLocked()167     private void pushDeviceOwnerUidToActivityTaskManagerLocked() {
168         mActivityTaskManagerInternal.setDeviceOwnerUid(getDeviceOwnerUidLocked());
169     }
170 
171     @GuardedBy("mData")
pushProfileOwnerUidsToActivityTaskManagerLocked()172     private void pushProfileOwnerUidsToActivityTaskManagerLocked() {
173         mActivityTaskManagerInternal.setProfileOwnerUids(getProfileOwnerUidsLocked());
174     }
175 
176     @GuardedBy("mData")
pushToActivityManagerLocked()177     private void pushToActivityManagerLocked() {
178         mActivityManagerInternal.setDeviceOwnerUid(getDeviceOwnerUidLocked());
179 
180         final ArraySet<Integer> profileOwners = new ArraySet<>();
181         for (int poi = mData.mProfileOwners.size() - 1; poi >= 0; poi--) {
182             final int userId = mData.mProfileOwners.keyAt(poi);
183             final int profileOwnerUid = mPackageManagerInternal.getPackageUid(
184                     mData.mProfileOwners.valueAt(poi).packageName,
185                     PackageManager.MATCH_ALL | PackageManager.MATCH_KNOWN_PACKAGES,
186                     userId);
187             if (profileOwnerUid >= 0) {
188                 profileOwners.add(profileOwnerUid);
189             }
190         }
191         mActivityManagerInternal.setProfileOwnerUid(profileOwners);
192     }
193 
194     @GuardedBy("mData")
getDeviceOwnerUidLocked()195     int getDeviceOwnerUidLocked() {
196         if (mData.mDeviceOwner != null) {
197             return mPackageManagerInternal.getPackageUid(mData.mDeviceOwner.packageName,
198                     PackageManager.MATCH_ALL | PackageManager.MATCH_KNOWN_PACKAGES,
199                     mData.mDeviceOwnerUserId);
200         } else {
201             return Process.INVALID_UID;
202         }
203     }
204 
205     @GuardedBy("mData")
getProfileOwnerUidsLocked()206     Set<Integer> getProfileOwnerUidsLocked() {
207         Set<Integer> uids = new ArraySet<>();
208         for (int i = 0; i < mData.mProfileOwners.size(); i++) {
209             int userId = mData.mProfileOwners.keyAt(i);
210             OwnerInfo info = mData.mProfileOwners.valueAt(i);
211             uids.add(mPackageManagerInternal.getPackageUid(info.packageName,
212                     PackageManager.MATCH_ALL | PackageManager.MATCH_KNOWN_PACKAGES,
213                     userId));
214         }
215         return uids;
216     }
217 
getDeviceOwnerPackageName()218     String getDeviceOwnerPackageName() {
219         synchronized (mData) {
220             return mData.mDeviceOwner != null ? mData.mDeviceOwner.packageName : null;
221         }
222     }
223 
getDeviceOwnerUserId()224     int getDeviceOwnerUserId() {
225         synchronized (mData) {
226             return mData.mDeviceOwnerUserId;
227         }
228     }
229 
230     @Nullable
getDeviceOwnerUserIdAndComponent()231     Pair<Integer, ComponentName> getDeviceOwnerUserIdAndComponent() {
232         synchronized (mData) {
233             if (mData.mDeviceOwner == null) {
234                 return null;
235             } else {
236                 return Pair.create(mData.mDeviceOwnerUserId, mData.mDeviceOwner.admin);
237             }
238         }
239     }
240 
getDeviceOwnerComponent()241     ComponentName getDeviceOwnerComponent() {
242         synchronized (mData) {
243             return mData.mDeviceOwner != null ? mData.mDeviceOwner.admin : null;
244         }
245     }
246 
getDeviceOwnerRemoteBugreportUri()247     String getDeviceOwnerRemoteBugreportUri() {
248         synchronized (mData) {
249             return mData.mDeviceOwner != null ? mData.mDeviceOwner.remoteBugreportUri : null;
250         }
251     }
252 
getDeviceOwnerRemoteBugreportHash()253     String getDeviceOwnerRemoteBugreportHash() {
254         synchronized (mData) {
255             return mData.mDeviceOwner != null ? mData.mDeviceOwner.remoteBugreportHash : null;
256         }
257     }
258 
setDeviceOwner(ComponentName admin, int userId)259     void setDeviceOwner(ComponentName admin, int userId) {
260         if (userId < 0) {
261             Slog.e(TAG, "Invalid user id for device owner user: " + userId);
262             return;
263         }
264         synchronized (mData) {
265             // A device owner is allowed to access device identifiers. Even though this flag
266             // is not currently checked for device owner, it is set to true here so that it is
267             // semantically compatible with the meaning of this flag.
268             mData.mDeviceOwner = new OwnerInfo(admin, /* remoteBugreportUri =*/ null,
269                     /* remoteBugreportHash =*/ null, /* isOrganizationOwnedDevice =*/ true);
270             mData.mDeviceOwnerUserId = userId;
271 
272             // TODO(b/258213147): Remove
273             if (DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_DEVICE_POLICY_MANAGER,
274                     DEPRECATE_USERMANAGERINTERNAL_DEVICEPOLICY_FLAG,
275                     DEPRECATE_USERMANAGERINTERNAL_DEVICEPOLICY_DEFAULT)) {
276                 int deviceOwnerType = mData.mDeviceOwnerTypes.getOrDefault(
277                         mData.mDeviceOwner.packageName,
278                         /* defaultValue= */ DEVICE_OWNER_TYPE_DEFAULT);
279                 mDeviceStateCache.setDeviceOwnerType(deviceOwnerType);
280             } else {
281                 mUserManagerInternal.setDeviceManaged(true);
282             }
283 
284             notifyChangeLocked();
285             pushDeviceOwnerUidToActivityTaskManagerLocked();
286         }
287     }
288 
clearDeviceOwner()289     void clearDeviceOwner() {
290         synchronized (mData) {
291             mData.mDeviceOwnerTypes.remove(mData.mDeviceOwner.packageName);
292             mData.mDeviceOwner = null;
293             mData.mDeviceOwnerUserId = UserHandle.USER_NULL;
294 
295             // TODO(b/258213147): Remove
296             if (DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_DEVICE_POLICY_MANAGER,
297                     DEPRECATE_USERMANAGERINTERNAL_DEVICEPOLICY_FLAG,
298                     DEPRECATE_USERMANAGERINTERNAL_DEVICEPOLICY_DEFAULT)) {
299                 mDeviceStateCache.setDeviceOwnerType(NO_DEVICE_OWNER);
300             } else {
301                 mUserManagerInternal.setDeviceManaged(false);
302             }
303             notifyChangeLocked();
304             pushDeviceOwnerUidToActivityTaskManagerLocked();
305         }
306     }
307 
setProfileOwner(ComponentName admin, int userId)308     void setProfileOwner(ComponentName admin, int userId) {
309         synchronized (mData) {
310             // For a newly set PO, there's no need for migration.
311             mData.mProfileOwners.put(userId, new OwnerInfo(admin,
312                     /* remoteBugreportUri =*/ null, /* remoteBugreportHash =*/ null,
313                     /* isOrganizationOwnedDevice =*/ false));
314 
315             // TODO(b/258213147): Remove
316             if (DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_DEVICE_POLICY_MANAGER,
317                     DEPRECATE_USERMANAGERINTERNAL_DEVICEPOLICY_FLAG,
318                     DEPRECATE_USERMANAGERINTERNAL_DEVICEPOLICY_DEFAULT)) {
319                 mDeviceStateCache.setHasProfileOwner(userId, true);
320             } else {
321                 mUserManagerInternal.setUserManaged(userId, true);
322             }
323             notifyChangeLocked();
324             pushProfileOwnerUidsToActivityTaskManagerLocked();
325         }
326     }
327 
removeProfileOwner(int userId)328     void removeProfileOwner(int userId) {
329         synchronized (mData) {
330             mData.mProfileOwners.remove(userId);
331             // TODO(b/258213147): Remove
332             if (DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_DEVICE_POLICY_MANAGER,
333                     DEPRECATE_USERMANAGERINTERNAL_DEVICEPOLICY_FLAG,
334                     DEPRECATE_USERMANAGERINTERNAL_DEVICEPOLICY_DEFAULT)) {
335                 mDeviceStateCache.setHasProfileOwner(userId, false);
336             } else {
337                 mUserManagerInternal.setUserManaged(userId, false);
338             }
339             notifyChangeLocked();
340             pushProfileOwnerUidsToActivityTaskManagerLocked();
341         }
342     }
343 
transferProfileOwner(ComponentName target, int userId)344     void transferProfileOwner(ComponentName target, int userId) {
345         synchronized (mData) {
346             final OwnerInfo ownerInfo = mData.mProfileOwners.get(userId);
347             final OwnerInfo newOwnerInfo = new OwnerInfo(target,
348                     ownerInfo.remoteBugreportUri, ownerInfo.remoteBugreportHash,
349                     ownerInfo.isOrganizationOwnedDevice);
350             mData.mProfileOwners.put(userId, newOwnerInfo);
351             notifyChangeLocked();
352             pushProfileOwnerUidsToActivityTaskManagerLocked();
353         }
354     }
355 
transferDeviceOwnership(ComponentName target)356     void transferDeviceOwnership(ComponentName target) {
357         synchronized (mData) {
358             Integer previousDeviceOwnerType = mData.mDeviceOwnerTypes.remove(
359                     mData.mDeviceOwner.packageName);
360             mData.mDeviceOwner = new OwnerInfo(target,
361                     mData.mDeviceOwner.remoteBugreportUri,
362                     mData.mDeviceOwner.remoteBugreportHash,
363                     mData.mDeviceOwner.isOrganizationOwnedDevice);
364 
365             if (previousDeviceOwnerType != null) {
366                 mData.mDeviceOwnerTypes.put(
367                         mData.mDeviceOwner.packageName, previousDeviceOwnerType);
368             }
369             notifyChangeLocked();
370             pushDeviceOwnerUidToActivityTaskManagerLocked();
371         }
372     }
373 
getProfileOwnerComponent(int userId)374     ComponentName getProfileOwnerComponent(int userId) {
375         synchronized (mData) {
376             OwnerInfo profileOwner = mData.mProfileOwners.get(userId);
377             return profileOwner != null ? profileOwner.admin : null;
378         }
379     }
380 
getProfileOwnerPackage(int userId)381     String getProfileOwnerPackage(int userId) {
382         synchronized (mData) {
383             OwnerInfo profileOwner = mData.mProfileOwners.get(userId);
384             return profileOwner != null ? profileOwner.packageName : null;
385         }
386     }
387 
388     /**
389      * Returns true if {@code userId} has a profile owner and that profile owner is on an
390      * organization-owned device, as indicated by the provisioning flow.
391      */
isProfileOwnerOfOrganizationOwnedDevice(int userId)392     boolean isProfileOwnerOfOrganizationOwnedDevice(int userId) {
393         synchronized (mData) {
394             OwnerInfo profileOwner = mData.mProfileOwners.get(userId);
395             return profileOwner != null ? profileOwner.isOrganizationOwnedDevice : false;
396         }
397     }
398 
getProfileOwnerKeys()399     Set<Integer> getProfileOwnerKeys() {
400         synchronized (mData) {
401             return mData.mProfileOwners.keySet();
402         }
403     }
404 
listAllOwners()405     List<OwnerShellData> listAllOwners() {
406         List<OwnerShellData> owners = new ArrayList<>();
407         synchronized (mData) {
408             if (mData.mDeviceOwner != null) {
409                 owners.add(OwnerShellData.forDeviceOwner(mData.mDeviceOwnerUserId,
410                         mData.mDeviceOwner.admin));
411             }
412             for (int i = 0; i < mData.mProfileOwners.size(); i++) {
413                 int userId = mData.mProfileOwners.keyAt(i);
414                 OwnerInfo info = mData.mProfileOwners.valueAt(i);
415                 owners.add(OwnerShellData.forUserProfileOwner(userId, info.admin));
416             }
417         }
418         return owners;
419     }
420 
421 
getSystemUpdatePolicy()422     SystemUpdatePolicy getSystemUpdatePolicy() {
423         synchronized (mData) {
424             return mData.mSystemUpdatePolicy;
425         }
426     }
427 
setSystemUpdatePolicy(SystemUpdatePolicy systemUpdatePolicy)428     void setSystemUpdatePolicy(SystemUpdatePolicy systemUpdatePolicy) {
429         synchronized (mData) {
430             mData.mSystemUpdatePolicy = systemUpdatePolicy;
431         }
432     }
433 
clearSystemUpdatePolicy()434     void clearSystemUpdatePolicy() {
435         synchronized (mData) {
436             mData.mSystemUpdatePolicy = null;
437         }
438     }
439 
getSystemUpdateFreezePeriodRecord()440     Pair<LocalDate, LocalDate> getSystemUpdateFreezePeriodRecord() {
441         synchronized (mData) {
442             return new Pair<>(mData.mSystemUpdateFreezeStart,
443                     mData.mSystemUpdateFreezeEnd);
444         }
445     }
446 
getSystemUpdateFreezePeriodRecordAsString()447     String getSystemUpdateFreezePeriodRecordAsString() {
448         synchronized (mData) {
449             return mData.getSystemUpdateFreezePeriodRecordAsString();
450         }
451     }
452 
453     /**
454      * Returns {@code true} if the freeze period record is changed, {@code false} otherwise.
455      */
setSystemUpdateFreezePeriodRecord(LocalDate start, LocalDate end)456     boolean setSystemUpdateFreezePeriodRecord(LocalDate start, LocalDate end) {
457         boolean changed = false;
458         synchronized (mData) {
459             if (!Objects.equals(mData.mSystemUpdateFreezeStart, start)) {
460                 mData.mSystemUpdateFreezeStart = start;
461                 changed = true;
462             }
463             if (!Objects.equals(mData.mSystemUpdateFreezeEnd, end)) {
464                 mData.mSystemUpdateFreezeEnd = end;
465                 changed = true;
466             }
467         }
468         return changed;
469     }
470 
hasDeviceOwner()471     boolean hasDeviceOwner() {
472         synchronized (mData) {
473             return mData.mDeviceOwner != null;
474         }
475     }
476 
isDeviceOwnerUserId(int userId)477     boolean isDeviceOwnerUserId(int userId) {
478         synchronized (mData) {
479             return mData.mDeviceOwner != null && mData.mDeviceOwnerUserId == userId;
480         }
481     }
482 
isDefaultDeviceOwnerUserId(int userId)483     boolean isDefaultDeviceOwnerUserId(int userId) {
484         synchronized (mData) {
485             return mData.mDeviceOwner != null
486                     && mData.mDeviceOwnerUserId == userId
487                     && getDeviceOwnerType(getDeviceOwnerPackageName()) == DEVICE_OWNER_TYPE_DEFAULT;
488         }
489     }
490 
isFinancedDeviceOwnerUserId(int userId)491     boolean isFinancedDeviceOwnerUserId(int userId) {
492         synchronized (mData) {
493             return mData.mDeviceOwner != null
494                     && mData.mDeviceOwnerUserId == userId
495                     && getDeviceOwnerType(getDeviceOwnerPackageName())
496                         == DEVICE_OWNER_TYPE_FINANCED;
497         }
498     }
499 
hasProfileOwner(int userId)500     boolean hasProfileOwner(int userId) {
501         synchronized (mData) {
502             return getProfileOwnerComponent(userId) != null;
503         }
504     }
505 
506     /** Sets the remote bugreport uri and hash, and also writes to the file. */
setDeviceOwnerRemoteBugreportUriAndHash(String remoteBugreportUri, String remoteBugreportHash)507     void setDeviceOwnerRemoteBugreportUriAndHash(String remoteBugreportUri,
508             String remoteBugreportHash) {
509         synchronized (mData) {
510             if (mData.mDeviceOwner != null) {
511                 mData.mDeviceOwner.remoteBugreportUri = remoteBugreportUri;
512                 mData.mDeviceOwner.remoteBugreportHash = remoteBugreportHash;
513             }
514             writeDeviceOwner();
515         }
516     }
517 
518     /** Set whether the profile owner manages an organization-owned device, then write to file. */
setProfileOwnerOfOrganizationOwnedDevice(int userId, boolean isOrganizationOwnedDevice)519     void setProfileOwnerOfOrganizationOwnedDevice(int userId, boolean isOrganizationOwnedDevice) {
520         synchronized (mData) {
521             OwnerInfo profileOwner = mData.mProfileOwners.get(userId);
522             if (profileOwner != null) {
523                 profileOwner.isOrganizationOwnedDevice = isOrganizationOwnedDevice;
524             } else {
525                 Slog.e(TAG, String.format(
526                         "No profile owner for user %d to set org-owned flag.", userId));
527             }
528             writeProfileOwner(userId);
529         }
530     }
531 
setDeviceOwnerType(String packageName, @DeviceOwnerType int deviceOwnerType, boolean isAdminTestOnly)532     void setDeviceOwnerType(String packageName, @DeviceOwnerType int deviceOwnerType,
533             boolean isAdminTestOnly) {
534         synchronized (mData) {
535             if (!hasDeviceOwner()) {
536                 Slog.e(TAG, "Attempting to set a device owner type when there is no device owner");
537                 return;
538             } else if (!isAdminTestOnly && isDeviceOwnerTypeSetForDeviceOwner(packageName)) {
539                 Slog.e(TAG, "Setting the device owner type more than once is only allowed"
540                         + " for test only admins");
541                 return;
542             }
543 
544             mData.mDeviceOwnerTypes.put(packageName, deviceOwnerType);
545             writeDeviceOwner();
546         }
547     }
548 
549     @DeviceOwnerType
getDeviceOwnerType(String packageName)550     int getDeviceOwnerType(String packageName) {
551         synchronized (mData) {
552             if (isDeviceOwnerTypeSetForDeviceOwner(packageName)) {
553                 return mData.mDeviceOwnerTypes.get(packageName);
554             }
555             return DEVICE_OWNER_TYPE_DEFAULT;
556         }
557     }
558 
isDeviceOwnerTypeSetForDeviceOwner(String packageName)559     boolean isDeviceOwnerTypeSetForDeviceOwner(String packageName) {
560         synchronized (mData) {
561             return !mData.mDeviceOwnerTypes.isEmpty()
562                     && mData.mDeviceOwnerTypes.containsKey(packageName);
563         }
564     }
565 
writeDeviceOwner()566     void writeDeviceOwner() {
567         synchronized (mData) {
568             pushToDevicePolicyManager();
569             mData.writeDeviceOwner();
570         }
571     }
572 
writeProfileOwner(int userId)573     void writeProfileOwner(int userId) {
574         synchronized (mData) {
575             pushToDevicePolicyManager();
576             mData.writeProfileOwner(userId);
577         }
578     }
579 
580     /**
581      * Saves the given {@link SystemUpdateInfo} if it is different from the existing one, or if
582      * none exists.
583      *
584      * @return Whether the saved system update information has changed.
585      */
saveSystemUpdateInfo(@ullable SystemUpdateInfo newInfo)586     boolean saveSystemUpdateInfo(@Nullable SystemUpdateInfo newInfo) {
587         synchronized (mData) {
588             // Check if we already have the same update information.
589             if (Objects.equals(newInfo, mData.mSystemUpdateInfo)) {
590                 return false;
591             }
592 
593             mData.mSystemUpdateInfo = newInfo;
594             mData.writeDeviceOwner();
595             return true;
596         }
597     }
598 
599     @Nullable
getSystemUpdateInfo()600     public SystemUpdateInfo getSystemUpdateInfo() {
601         synchronized (mData) {
602             return mData.mSystemUpdateInfo;
603         }
604     }
605 
markMigrationToPolicyEngine()606     void markMigrationToPolicyEngine() {
607         synchronized (mData) {
608             mData.mMigratedToPolicyEngine = true;
609             mData.writeDeviceOwner();
610         }
611     }
612 
isMigratedToPolicyEngine()613     boolean isMigratedToPolicyEngine() {
614         synchronized (mData) {
615             return mData.mMigratedToPolicyEngine;
616         }
617     }
618 
markSecurityLoggingMigrated()619     void markSecurityLoggingMigrated() {
620         synchronized (mData) {
621             mData.mSecurityLoggingMigrated = true;
622             mData.writeDeviceOwner();
623         }
624     }
625 
markPostUpgradeMigration()626     void markPostUpgradeMigration() {
627         synchronized (mData) {
628             mData.mPoliciesMigratedPostUpdate = true;
629             mData.writeDeviceOwner();
630         }
631     }
632 
isSecurityLoggingMigrated()633     boolean isSecurityLoggingMigrated() {
634         synchronized (mData) {
635             return mData.mSecurityLoggingMigrated;
636         }
637     }
638 
isRequiredPasswordComplexityMigrated()639     boolean isRequiredPasswordComplexityMigrated() {
640         synchronized (mData) {
641             return mData.mRequiredPasswordComplexityMigrated;
642         }
643     }
644 
markRequiredPasswordComplexityMigrated()645     void markRequiredPasswordComplexityMigrated() {
646         synchronized (mData) {
647             mData.mRequiredPasswordComplexityMigrated = true;
648             mData.writeDeviceOwner();
649         }
650 
651     }
652 
isSuspendedPackagesMigrated()653     boolean isSuspendedPackagesMigrated() {
654         synchronized (mData) {
655             return mData.mSuspendedPackagesMigrated;
656         }
657     }
658 
markSuspendedPackagesMigrated()659     void markSuspendedPackagesMigrated() {
660         synchronized (mData) {
661             mData.mSuspendedPackagesMigrated = true;
662             mData.writeDeviceOwner();
663         }
664     }
665 
isMigratedPostUpdate()666     boolean isMigratedPostUpdate() {
667         synchronized (mData) {
668             return mData.mPoliciesMigratedPostUpdate;
669         }
670     }
671 
672     @GuardedBy("mData")
pushToAppOpsLocked()673     void pushToAppOpsLocked() {
674         if (!mSystemReady) {
675             return;
676         }
677         final long ident = Binder.clearCallingIdentity();
678         try {
679             final SparseIntArray owners = new SparseIntArray();
680             if (mData.mDeviceOwner != null) {
681                 final int uid = getDeviceOwnerUidLocked();
682                 if (uid >= 0) {
683                     owners.put(mData.mDeviceOwnerUserId, uid);
684                 }
685             }
686             if (mData.mProfileOwners != null) {
687                 for (int poi = mData.mProfileOwners.size() - 1; poi >= 0; poi--) {
688                     final int uid = mPackageManagerInternal.getPackageUid(
689                             mData.mProfileOwners.valueAt(poi).packageName,
690                             PackageManager.MATCH_ALL | PackageManager.MATCH_KNOWN_PACKAGES,
691                             mData.mProfileOwners.keyAt(poi));
692                     if (uid >= 0) {
693                         owners.put(mData.mProfileOwners.keyAt(poi), uid);
694                     }
695                 }
696             }
697             AppOpsManagerInternal appops = LocalServices.getService(AppOpsManagerInternal.class);
698             if (appops != null) {
699                 appops.setDeviceAndProfileOwners(owners.size() > 0 ? owners : null);
700             }
701         } finally {
702             Binder.restoreCallingIdentity(ident);
703         }
704     }
705 
systemReady()706     public void systemReady() {
707         synchronized (mData) {
708             mSystemReady = true;
709             pushToActivityManagerLocked();
710             pushToAppOpsLocked();
711         }
712     }
713 
dump(IndentingPrintWriter pw)714     public void dump(IndentingPrintWriter pw) {
715         synchronized (mData) {
716             mData.dump(pw);
717         }
718     }
719 
720     @VisibleForTesting
getDeviceOwnerFile()721     File getDeviceOwnerFile() {
722         return mData.getDeviceOwnerFile();
723     }
724 
725     @VisibleForTesting
getProfileOwnerFile(int userId)726     File getProfileOwnerFile(int userId) {
727         return mData.getProfileOwnerFile(userId);
728     }
729 }
730