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