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.content.pm.UserInfo;
31 import android.os.Binder;
32 import android.os.Environment;
33 import android.os.Process;
34 import android.os.UserHandle;
35 import android.os.UserManager;
36 import android.util.ArrayMap;
37 import android.util.ArraySet;
38 import android.util.AtomicFile;
39 import android.util.IndentingPrintWriter;
40 import android.util.Log;
41 import android.util.Pair;
42 import android.util.Slog;
43 import android.util.SparseArray;
44 import android.util.SparseIntArray;
45 import android.util.TypedXmlPullParser;
46 import android.util.TypedXmlSerializer;
47 import android.util.Xml;
48 
49 import com.android.internal.annotations.VisibleForTesting;
50 import com.android.server.LocalServices;
51 import com.android.server.pm.UserManagerInternal;
52 import com.android.server.wm.ActivityTaskManagerInternal;
53 
54 import libcore.io.IoUtils;
55 
56 import org.xmlpull.v1.XmlPullParserException;
57 
58 import java.io.File;
59 import java.io.FileOutputStream;
60 import java.io.IOException;
61 import java.io.InputStream;
62 import java.time.LocalDate;
63 import java.util.ArrayList;
64 import java.util.Collections;
65 import java.util.List;
66 import java.util.Map;
67 import java.util.Objects;
68 import java.util.Set;
69 
70 /**
71  * Stores and restores state for the Device and Profile owners and related device-wide information.
72  * By definition there can be only one device owner, but there may be a profile owner for each user.
73  *
74  * <p>This class is thread safe, so individual methods can safely be called without locking.
75  * However, caller must still synchronize on their side to ensure integrity between multiple calls.
76  */
77 class Owners {
78     private static final String TAG = "DevicePolicyManagerService";
79 
80     private static final boolean DEBUG = false; // DO NOT SUBMIT WITH TRUE
81 
82     private static final String DEVICE_OWNER_XML_LEGACY = "device_owner.xml";
83 
84     // XML storing device owner info, system update policy and pending OTA update information.
85     private static final String DEVICE_OWNER_XML = "device_owner_2.xml";
86 
87     private static final String PROFILE_OWNER_XML = "profile_owner.xml";
88 
89     private static final String TAG_ROOT = "root";
90 
91     private static final String TAG_DEVICE_OWNER = "device-owner";
92     private static final String TAG_DEVICE_INITIALIZER = "device-initializer";
93     private static final String TAG_SYSTEM_UPDATE_POLICY = "system-update-policy";
94     private static final String TAG_FREEZE_PERIOD_RECORD = "freeze-record";
95     private static final String TAG_PENDING_OTA_INFO = "pending-ota-info";
96     private static final String TAG_PROFILE_OWNER = "profile-owner";
97     // Holds "context" for device-owner, this must not be show up before device-owner.
98     private static final String TAG_DEVICE_OWNER_CONTEXT = "device-owner-context";
99     private static final String TAG_DEVICE_OWNER_TYPE = "device-owner-type";
100     private static final String TAG_DEVICE_OWNER_PROTECTED_PACKAGES =
101             "device-owner-protected-packages";
102 
103     private static final String ATTR_NAME = "name";
104     private static final String ATTR_PACKAGE = "package";
105     private static final String ATTR_COMPONENT_NAME = "component";
106     private static final String ATTR_SIZE = "size";
107     private static final String ATTR_REMOTE_BUGREPORT_URI = "remoteBugreportUri";
108     private static final String ATTR_REMOTE_BUGREPORT_HASH = "remoteBugreportHash";
109     private static final String ATTR_USERID = "userId";
110     private static final String ATTR_USER_RESTRICTIONS_MIGRATED = "userRestrictionsMigrated";
111     private static final String ATTR_FREEZE_RECORD_START = "start";
112     private static final String ATTR_FREEZE_RECORD_END = "end";
113     // Legacy attribute, its presence would mean the profile owner associated with it is
114     // managing a profile on an organization-owned device.
115     private static final String ATTR_CAN_ACCESS_DEVICE_IDS = "canAccessDeviceIds";
116     // New attribute for profile owner of organization-owned device.
117     private static final String ATTR_PROFILE_OWNER_OF_ORG_OWNED_DEVICE =
118             "isPoOrganizationOwnedDevice";
119     private static final String ATTR_DEVICE_OWNER_TYPE_VALUE = "value";
120 
121     private final UserManager mUserManager;
122     private final UserManagerInternal mUserManagerInternal;
123     private final PackageManagerInternal mPackageManagerInternal;
124     private final ActivityTaskManagerInternal mActivityTaskManagerInternal;
125     private final ActivityManagerInternal mActivityManagerInternal;
126 
127     private boolean mSystemReady;
128 
129     // Internal state for the device owner package.
130     private OwnerInfo mDeviceOwner;
131 
132     // Device owner type for a managed device.
133     private final ArrayMap<String, Integer> mDeviceOwnerTypes = new ArrayMap<>();
134 
135     private final ArrayMap<String, List<String>> mDeviceOwnerProtectedPackages = new ArrayMap<>();
136 
137     private int mDeviceOwnerUserId = UserHandle.USER_NULL;
138 
139     // Internal state for the profile owner packages.
140     private final ArrayMap<Integer, OwnerInfo> mProfileOwners = new ArrayMap<>();
141 
142     // Local system update policy controllable by device owner.
143     private SystemUpdatePolicy mSystemUpdatePolicy;
144     private LocalDate mSystemUpdateFreezeStart;
145     private LocalDate mSystemUpdateFreezeEnd;
146 
147     // Pending OTA info if there is one.
148     @Nullable
149     private SystemUpdateInfo mSystemUpdateInfo;
150 
151     private final Object mLock = new Object();
152     private final Injector mInjector;
153 
Owners(UserManager userManager, UserManagerInternal userManagerInternal, PackageManagerInternal packageManagerInternal, ActivityTaskManagerInternal activityTaskManagerInternal, ActivityManagerInternal activitykManagerInternal)154     public Owners(UserManager userManager,
155             UserManagerInternal userManagerInternal,
156             PackageManagerInternal packageManagerInternal,
157             ActivityTaskManagerInternal activityTaskManagerInternal,
158             ActivityManagerInternal activitykManagerInternal) {
159         this(userManager, userManagerInternal, packageManagerInternal,
160                 activityTaskManagerInternal, activitykManagerInternal, new Injector());
161     }
162 
163     @VisibleForTesting
Owners(UserManager userManager, UserManagerInternal userManagerInternal, PackageManagerInternal packageManagerInternal, ActivityTaskManagerInternal activityTaskManagerInternal, ActivityManagerInternal activityManagerInternal, Injector injector)164     Owners(UserManager userManager,
165             UserManagerInternal userManagerInternal,
166             PackageManagerInternal packageManagerInternal,
167             ActivityTaskManagerInternal activityTaskManagerInternal,
168             ActivityManagerInternal activityManagerInternal,
169             Injector injector) {
170         mUserManager = userManager;
171         mUserManagerInternal = userManagerInternal;
172         mPackageManagerInternal = packageManagerInternal;
173         mActivityTaskManagerInternal = activityTaskManagerInternal;
174         mActivityManagerInternal = activityManagerInternal;
175         mInjector = injector;
176     }
177 
178     /**
179      * Load configuration from the disk.
180      */
load()181     void load() {
182         synchronized (mLock) {
183             // First, try to read from the legacy file.
184             final File legacy = getLegacyConfigFile();
185 
186             final List<UserInfo> users = mUserManager.getAliveUsers();
187 
188             if (readLegacyOwnerFileLocked(legacy)) {
189                 if (DEBUG) {
190                     Log.d(TAG, "Legacy config file found.");
191                 }
192 
193                 // Legacy file exists, write to new files and remove the legacy one.
194                 writeDeviceOwner();
195                 for (int userId : getProfileOwnerKeys()) {
196                     writeProfileOwner(userId);
197                 }
198                 if (DEBUG) {
199                     Log.d(TAG, "Deleting legacy config file");
200                 }
201                 if (!legacy.delete()) {
202                     Slog.e(TAG, "Failed to remove the legacy setting file");
203                 }
204             } else {
205                 // No legacy file, read from the new format files.
206                 new DeviceOwnerReadWriter().readFromFileLocked();
207 
208                 for (UserInfo ui : users) {
209                     new ProfileOwnerReadWriter(ui.id).readFromFileLocked();
210                 }
211             }
212             mUserManagerInternal.setDeviceManaged(hasDeviceOwner());
213             for (UserInfo ui : users) {
214                 mUserManagerInternal.setUserManaged(ui.id, hasProfileOwner(ui.id));
215             }
216             if (hasDeviceOwner() && hasProfileOwner(getDeviceOwnerUserId())) {
217                 Slog.w(TAG, String.format("User %d has both DO and PO, which is not supported",
218                         getDeviceOwnerUserId()));
219             }
220             pushToPackageManagerLocked();
221             pushToActivityTaskManagerLocked();
222             pushToActivityManagerLocked();
223             pushToAppOpsLocked();
224 
225             for (ArrayMap.Entry<String, List<String>> entry :
226                     mDeviceOwnerProtectedPackages.entrySet()) {
227                 mPackageManagerInternal.setDeviceOwnerProtectedPackages(
228                         entry.getKey(), entry.getValue());
229             }
230         }
231     }
232 
pushToPackageManagerLocked()233     private void pushToPackageManagerLocked() {
234         final SparseArray<String> po = new SparseArray<>();
235         for (int i = mProfileOwners.size() - 1; i >= 0; i--) {
236             po.put(mProfileOwners.keyAt(i), mProfileOwners.valueAt(i).packageName);
237         }
238         mPackageManagerInternal.setDeviceAndProfileOwnerPackages(
239                 mDeviceOwnerUserId, (mDeviceOwner != null ? mDeviceOwner.packageName : null),
240                 po);
241     }
242 
pushToActivityTaskManagerLocked()243     private void pushToActivityTaskManagerLocked() {
244         mActivityTaskManagerInternal.setDeviceOwnerUid(getDeviceOwnerUidLocked());
245     }
246 
pushToActivityManagerLocked()247     private void pushToActivityManagerLocked() {
248         mActivityManagerInternal.setDeviceOwnerUid(getDeviceOwnerUidLocked());
249 
250         final ArraySet<Integer> profileOwners = new ArraySet<>();
251         for (int poi = mProfileOwners.size() - 1; poi >= 0; poi--) {
252             final int userId = mProfileOwners.keyAt(poi);
253             final int profileOwnerUid = mPackageManagerInternal.getPackageUid(
254                     mProfileOwners.valueAt(poi).packageName,
255                     PackageManager.MATCH_ALL | PackageManager.MATCH_KNOWN_PACKAGES,
256                     userId);
257             if (profileOwnerUid >= 0) {
258                 profileOwners.add(profileOwnerUid);
259             }
260         }
261         mActivityManagerInternal.setProfileOwnerUid(profileOwners);
262     }
263 
getDeviceOwnerUidLocked()264     int getDeviceOwnerUidLocked() {
265         if (mDeviceOwner != null) {
266             return mPackageManagerInternal.getPackageUid(mDeviceOwner.packageName,
267                     PackageManager.MATCH_ALL | PackageManager.MATCH_KNOWN_PACKAGES,
268                     mDeviceOwnerUserId);
269         } else {
270             return Process.INVALID_UID;
271         }
272     }
273 
getDeviceOwnerPackageName()274     String getDeviceOwnerPackageName() {
275         synchronized (mLock) {
276             return mDeviceOwner != null ? mDeviceOwner.packageName : null;
277         }
278     }
279 
getDeviceOwnerUserId()280     int getDeviceOwnerUserId() {
281         synchronized (mLock) {
282             return mDeviceOwnerUserId;
283         }
284     }
285 
286     @Nullable
getDeviceOwnerUserIdAndComponent()287     Pair<Integer, ComponentName> getDeviceOwnerUserIdAndComponent() {
288         synchronized (mLock) {
289             if (mDeviceOwner == null) {
290                 return null;
291             } else {
292                 return Pair.create(mDeviceOwnerUserId, mDeviceOwner.admin);
293             }
294         }
295     }
296 
getDeviceOwnerName()297     String getDeviceOwnerName() {
298         synchronized (mLock) {
299             return mDeviceOwner != null ? mDeviceOwner.name : null;
300         }
301     }
302 
getDeviceOwnerComponent()303     ComponentName getDeviceOwnerComponent() {
304         synchronized (mLock) {
305             return mDeviceOwner != null ? mDeviceOwner.admin : null;
306         }
307     }
308 
getDeviceOwnerRemoteBugreportUri()309     String getDeviceOwnerRemoteBugreportUri() {
310         synchronized (mLock) {
311             return mDeviceOwner != null ? mDeviceOwner.remoteBugreportUri : null;
312         }
313     }
314 
getDeviceOwnerRemoteBugreportHash()315     String getDeviceOwnerRemoteBugreportHash() {
316         synchronized (mLock) {
317             return mDeviceOwner != null ? mDeviceOwner.remoteBugreportHash : null;
318         }
319     }
320 
setDeviceOwner(ComponentName admin, String ownerName, int userId)321     void setDeviceOwner(ComponentName admin, String ownerName, int userId) {
322         if (userId < 0) {
323             Slog.e(TAG, "Invalid user id for device owner user: " + userId);
324             return;
325         }
326         synchronized (mLock) {
327             // For a newly set DO, there's no need for migration.
328             setDeviceOwnerWithRestrictionsMigrated(admin, ownerName, userId,
329                     /* userRestrictionsMigrated =*/ true);
330         }
331     }
332 
333     // Note this should be only called during migration.  Normally when DO is set,
334     // userRestrictionsMigrated should always be true.
setDeviceOwnerWithRestrictionsMigrated(ComponentName admin, String ownerName, int userId, boolean userRestrictionsMigrated)335     void setDeviceOwnerWithRestrictionsMigrated(ComponentName admin, String ownerName, int userId,
336             boolean userRestrictionsMigrated) {
337         synchronized (mLock) {
338             // A device owner is allowed to access device identifiers. Even though this flag
339             // is not currently checked for device owner, it is set to true here so that it is
340             // semantically compatible with the meaning of this flag.
341             mDeviceOwner = new OwnerInfo(ownerName, admin, userRestrictionsMigrated,
342                     /* remoteBugreportUri =*/ null, /* remoteBugreportHash =*/
343                     null, /* isOrganizationOwnedDevice =*/true);
344             mDeviceOwnerUserId = userId;
345 
346             mUserManagerInternal.setDeviceManaged(true);
347             pushToPackageManagerLocked();
348             pushToActivityTaskManagerLocked();
349             pushToActivityManagerLocked();
350             pushToAppOpsLocked();
351         }
352     }
353 
clearDeviceOwner()354     void clearDeviceOwner() {
355         synchronized (mLock) {
356             mDeviceOwnerTypes.remove(mDeviceOwner.packageName);
357             List<String> protectedPackages =
358                     mDeviceOwnerProtectedPackages.remove(mDeviceOwner.packageName);
359             if (protectedPackages != null) {
360                 mPackageManagerInternal.setDeviceOwnerProtectedPackages(
361                         mDeviceOwner.packageName, new ArrayList<>());
362             }
363             mDeviceOwner = null;
364             mDeviceOwnerUserId = UserHandle.USER_NULL;
365 
366             mUserManagerInternal.setDeviceManaged(false);
367             pushToPackageManagerLocked();
368             pushToActivityTaskManagerLocked();
369             pushToActivityManagerLocked();
370             pushToAppOpsLocked();
371         }
372     }
373 
setProfileOwner(ComponentName admin, String ownerName, int userId)374     void setProfileOwner(ComponentName admin, String ownerName, int userId) {
375         synchronized (mLock) {
376             // For a newly set PO, there's no need for migration.
377             mProfileOwners.put(userId, new OwnerInfo(ownerName, admin,
378                     /* userRestrictionsMigrated =*/ true, /* remoteBugreportUri =*/ null,
379                     /* remoteBugreportHash =*/ null, /* isOrganizationOwnedDevice =*/ false));
380             mUserManagerInternal.setUserManaged(userId, true);
381             pushToPackageManagerLocked();
382             pushToActivityManagerLocked();
383             pushToAppOpsLocked();
384         }
385     }
386 
removeProfileOwner(int userId)387     void removeProfileOwner(int userId) {
388         synchronized (mLock) {
389             mProfileOwners.remove(userId);
390             mUserManagerInternal.setUserManaged(userId, false);
391             pushToPackageManagerLocked();
392             pushToActivityManagerLocked();
393             pushToAppOpsLocked();
394         }
395     }
396 
transferProfileOwner(ComponentName target, int userId)397     void transferProfileOwner(ComponentName target, int userId) {
398         synchronized (mLock) {
399             final OwnerInfo ownerInfo = mProfileOwners.get(userId);
400             final OwnerInfo newOwnerInfo = new OwnerInfo(target.getPackageName(), target,
401                     ownerInfo.userRestrictionsMigrated, ownerInfo.remoteBugreportUri,
402                     ownerInfo.remoteBugreportHash, /* isOrganizationOwnedDevice =*/
403                     ownerInfo.isOrganizationOwnedDevice);
404             mProfileOwners.put(userId, newOwnerInfo);
405             pushToPackageManagerLocked();
406             pushToActivityManagerLocked();
407             pushToAppOpsLocked();
408         }
409     }
410 
transferDeviceOwnership(ComponentName target)411     void transferDeviceOwnership(ComponentName target) {
412         synchronized (mLock) {
413             Integer previousDeviceOwnerType = mDeviceOwnerTypes.remove(mDeviceOwner.packageName);
414             List<String> previousProtectedPackages =
415                     mDeviceOwnerProtectedPackages.remove(mDeviceOwner.packageName);
416             if (previousProtectedPackages != null) {
417                 mPackageManagerInternal.setDeviceOwnerProtectedPackages(
418                         mDeviceOwner.packageName, new ArrayList<>());
419             }
420             // We don't set a name because it's not used anyway.
421             // See DevicePolicyManagerService#getDeviceOwnerName
422             mDeviceOwner = new OwnerInfo(null, target,
423                     mDeviceOwner.userRestrictionsMigrated, mDeviceOwner.remoteBugreportUri,
424                     mDeviceOwner.remoteBugreportHash, /* isOrganizationOwnedDevice =*/
425                     mDeviceOwner.isOrganizationOwnedDevice);
426             if (previousDeviceOwnerType != null) {
427                 mDeviceOwnerTypes.put(mDeviceOwner.packageName, previousDeviceOwnerType);
428             }
429             if (previousProtectedPackages != null) {
430                 mDeviceOwnerProtectedPackages.put(
431                         mDeviceOwner.packageName, previousProtectedPackages);
432             }
433             pushToPackageManagerLocked();
434             pushToActivityTaskManagerLocked();
435             pushToActivityManagerLocked();
436             pushToAppOpsLocked();
437         }
438     }
439 
getProfileOwnerComponent(int userId)440     ComponentName getProfileOwnerComponent(int userId) {
441         synchronized (mLock) {
442             OwnerInfo profileOwner = mProfileOwners.get(userId);
443             return profileOwner != null ? profileOwner.admin : null;
444         }
445     }
446 
getProfileOwnerName(int userId)447     String getProfileOwnerName(int userId) {
448         synchronized (mLock) {
449             OwnerInfo profileOwner = mProfileOwners.get(userId);
450             return profileOwner != null ? profileOwner.name : null;
451         }
452     }
453 
getProfileOwnerPackage(int userId)454     String getProfileOwnerPackage(int userId) {
455         synchronized (mLock) {
456             OwnerInfo profileOwner = mProfileOwners.get(userId);
457             return profileOwner != null ? profileOwner.packageName : null;
458         }
459     }
460 
461     /**
462      * Returns true if {@code userId} has a profile owner and that profile owner is on an
463      * organization-owned device, as indicated by the provisioning flow.
464      */
isProfileOwnerOfOrganizationOwnedDevice(int userId)465     boolean isProfileOwnerOfOrganizationOwnedDevice(int userId) {
466         synchronized (mLock) {
467             OwnerInfo profileOwner = mProfileOwners.get(userId);
468             return profileOwner != null ? profileOwner.isOrganizationOwnedDevice : false;
469         }
470     }
471 
getProfileOwnerKeys()472     Set<Integer> getProfileOwnerKeys() {
473         synchronized (mLock) {
474             return mProfileOwners.keySet();
475         }
476     }
477 
listAllOwners()478     List<OwnerShellData> listAllOwners() {
479         List<OwnerShellData> owners = new ArrayList<>();
480         synchronized (mLock) {
481             if (mDeviceOwner != null) {
482                 owners.add(OwnerShellData.forDeviceOwner(mDeviceOwnerUserId, mDeviceOwner.admin));
483             }
484             for (int i = 0; i < mProfileOwners.size(); i++) {
485                 int userId = mProfileOwners.keyAt(i);
486                 OwnerInfo info = mProfileOwners.valueAt(i);
487                 owners.add(OwnerShellData.forUserProfileOwner(userId, info.admin));
488             }
489         }
490         return owners;
491     }
492 
493 
getSystemUpdatePolicy()494     SystemUpdatePolicy getSystemUpdatePolicy() {
495         synchronized (mLock) {
496             return mSystemUpdatePolicy;
497         }
498     }
499 
setSystemUpdatePolicy(SystemUpdatePolicy systemUpdatePolicy)500     void setSystemUpdatePolicy(SystemUpdatePolicy systemUpdatePolicy) {
501         synchronized (mLock) {
502             mSystemUpdatePolicy = systemUpdatePolicy;
503         }
504     }
505 
clearSystemUpdatePolicy()506     void clearSystemUpdatePolicy() {
507         synchronized (mLock) {
508             mSystemUpdatePolicy = null;
509         }
510     }
511 
getSystemUpdateFreezePeriodRecord()512     Pair<LocalDate, LocalDate> getSystemUpdateFreezePeriodRecord() {
513         synchronized (mLock) {
514             return new Pair<>(mSystemUpdateFreezeStart, mSystemUpdateFreezeEnd);
515         }
516     }
517 
getSystemUpdateFreezePeriodRecordAsString()518     String getSystemUpdateFreezePeriodRecordAsString() {
519         StringBuilder freezePeriodRecord = new StringBuilder();
520         freezePeriodRecord.append("start: ");
521         if (mSystemUpdateFreezeStart != null) {
522             freezePeriodRecord.append(mSystemUpdateFreezeStart.toString());
523         } else {
524             freezePeriodRecord.append("null");
525         }
526         freezePeriodRecord.append("; end: ");
527         if (mSystemUpdateFreezeEnd != null) {
528             freezePeriodRecord.append(mSystemUpdateFreezeEnd.toString());
529         } else {
530             freezePeriodRecord.append("null");
531         }
532         return freezePeriodRecord.toString();
533     }
534 
535     /**
536      * Returns {@code true} if the freeze period record is changed, {@code false} otherwise.
537      */
setSystemUpdateFreezePeriodRecord(LocalDate start, LocalDate end)538     boolean setSystemUpdateFreezePeriodRecord(LocalDate start, LocalDate end) {
539         boolean changed = false;
540         synchronized (mLock) {
541             if (!Objects.equals(mSystemUpdateFreezeStart, start)) {
542                 mSystemUpdateFreezeStart = start;
543                 changed = true;
544             }
545             if (!Objects.equals(mSystemUpdateFreezeEnd, end)) {
546                 mSystemUpdateFreezeEnd = end;
547                 changed = true;
548             }
549         }
550         return changed;
551     }
552 
hasDeviceOwner()553     boolean hasDeviceOwner() {
554         synchronized (mLock) {
555             return mDeviceOwner != null;
556         }
557     }
558 
isDeviceOwnerUserId(int userId)559     boolean isDeviceOwnerUserId(int userId) {
560         synchronized (mLock) {
561             return mDeviceOwner != null && mDeviceOwnerUserId == userId;
562         }
563     }
564 
hasProfileOwner(int userId)565     boolean hasProfileOwner(int userId) {
566         synchronized (mLock) {
567             return getProfileOwnerComponent(userId) != null;
568         }
569     }
570 
571     /**
572      * @return true if user restrictions need to be migrated for DO.
573      */
getDeviceOwnerUserRestrictionsNeedsMigration()574     boolean getDeviceOwnerUserRestrictionsNeedsMigration() {
575         synchronized (mLock) {
576             return mDeviceOwner != null && !mDeviceOwner.userRestrictionsMigrated;
577         }
578     }
579 
580     /**
581      * @return true if user restrictions need to be migrated for PO.
582      */
getProfileOwnerUserRestrictionsNeedsMigration(int userId)583     boolean getProfileOwnerUserRestrictionsNeedsMigration(int userId) {
584         synchronized (mLock) {
585             OwnerInfo profileOwner = mProfileOwners.get(userId);
586             return profileOwner != null && !profileOwner.userRestrictionsMigrated;
587         }
588     }
589 
590     /** Sets the user restrictions migrated flag, and also writes to the file. */
setDeviceOwnerUserRestrictionsMigrated()591     void setDeviceOwnerUserRestrictionsMigrated() {
592         synchronized (mLock) {
593             if (mDeviceOwner != null) {
594                 mDeviceOwner.userRestrictionsMigrated = true;
595             }
596             writeDeviceOwner();
597         }
598     }
599 
600     /** Sets the remote bugreport uri and hash, and also writes to the file. */
setDeviceOwnerRemoteBugreportUriAndHash(String remoteBugreportUri, String remoteBugreportHash)601     void setDeviceOwnerRemoteBugreportUriAndHash(String remoteBugreportUri,
602             String remoteBugreportHash) {
603         synchronized (mLock) {
604             if (mDeviceOwner != null) {
605                 mDeviceOwner.remoteBugreportUri = remoteBugreportUri;
606                 mDeviceOwner.remoteBugreportHash = remoteBugreportHash;
607             }
608             writeDeviceOwner();
609         }
610     }
611 
612     /** Sets the user restrictions migrated flag, and also writes to the file. */
setProfileOwnerUserRestrictionsMigrated(int userId)613     void setProfileOwnerUserRestrictionsMigrated(int userId) {
614         synchronized (mLock) {
615             OwnerInfo profileOwner = mProfileOwners.get(userId);
616             if (profileOwner != null) {
617                 profileOwner.userRestrictionsMigrated = true;
618             }
619             writeProfileOwner(userId);
620         }
621     }
622 
623     /**
624      * Sets the indicator that the profile owner manages an organization-owned device,
625      * then write to file.
626      */
markProfileOwnerOfOrganizationOwnedDevice(int userId)627     void markProfileOwnerOfOrganizationOwnedDevice(int userId) {
628         synchronized (mLock) {
629             OwnerInfo profileOwner = mProfileOwners.get(userId);
630             if (profileOwner != null) {
631                 profileOwner.isOrganizationOwnedDevice = true;
632             } else {
633                 Slog.e(TAG, String.format(
634                         "No profile owner for user %d to set as org-owned.", userId));
635             }
636             writeProfileOwner(userId);
637         }
638     }
639 
setDeviceOwnerType(String packageName, @DeviceOwnerType int deviceOwnerType)640     void setDeviceOwnerType(String packageName, @DeviceOwnerType int deviceOwnerType) {
641         synchronized (mLock) {
642             if (!hasDeviceOwner()) {
643                 Slog.e(TAG, "Attempting to set a device owner type when there is no device owner");
644                 return;
645             } else if (isDeviceOwnerTypeSetForDeviceOwner(packageName)) {
646                 Slog.e(TAG, "Device owner type for " + packageName + " has already been set");
647                 return;
648             }
649 
650             mDeviceOwnerTypes.put(packageName, deviceOwnerType);
651             writeDeviceOwner();
652         }
653     }
654 
655     @DeviceOwnerType
getDeviceOwnerType(String packageName)656     int getDeviceOwnerType(String packageName) {
657         synchronized (mLock) {
658             if (isDeviceOwnerTypeSetForDeviceOwner(packageName)) {
659                 return mDeviceOwnerTypes.get(packageName);
660             }
661             return DEVICE_OWNER_TYPE_DEFAULT;
662         }
663     }
664 
isDeviceOwnerTypeSetForDeviceOwner(String packageName)665     boolean isDeviceOwnerTypeSetForDeviceOwner(String packageName) {
666         synchronized (mLock) {
667             return !mDeviceOwnerTypes.isEmpty() && mDeviceOwnerTypes.containsKey(packageName);
668         }
669     }
670 
setDeviceOwnerProtectedPackages(String packageName, List<String> protectedPackages)671     void setDeviceOwnerProtectedPackages(String packageName, List<String> protectedPackages) {
672         synchronized (mLock) {
673             if (!hasDeviceOwner()) {
674                 Slog.e(TAG,
675                         "Attempting to set device owner protected packages when there is no "
676                                 + "device owner");
677                 return;
678             } else if (!mDeviceOwner.packageName.equals(packageName)) {
679                 Slog.e(TAG, "Attempting to set device owner protected packages when the provided "
680                         + "package name " + packageName
681                         + " does not match the device owner package name");
682                 return;
683             }
684 
685             mDeviceOwnerProtectedPackages.put(packageName, protectedPackages);
686             mPackageManagerInternal.setDeviceOwnerProtectedPackages(packageName, protectedPackages);
687             writeDeviceOwner();
688         }
689     }
690 
getDeviceOwnerProtectedPackages(String packageName)691     List<String> getDeviceOwnerProtectedPackages(String packageName) {
692         synchronized (mLock) {
693             return mDeviceOwnerProtectedPackages.containsKey(packageName)
694                     ? mDeviceOwnerProtectedPackages.get(packageName) : Collections.emptyList();
695         }
696     }
697 
readLegacyOwnerFileLocked(File file)698     private boolean readLegacyOwnerFileLocked(File file) {
699         if (!file.exists()) {
700             // Already migrated or the device has no owners.
701             return false;
702         }
703         try {
704             InputStream input = new AtomicFile(file).openRead();
705             TypedXmlPullParser parser = Xml.resolvePullParser(input);
706             int type;
707             while ((type = parser.next()) != TypedXmlPullParser.END_DOCUMENT) {
708                 if (type != TypedXmlPullParser.START_TAG) {
709                     continue;
710                 }
711 
712                 String tag = parser.getName();
713                 if (tag.equals(TAG_DEVICE_OWNER)) {
714                     String name = parser.getAttributeValue(null, ATTR_NAME);
715                     String packageName = parser.getAttributeValue(null, ATTR_PACKAGE);
716                     mDeviceOwner = new OwnerInfo(name, packageName,
717                             /* userRestrictionsMigrated =*/ false, /* remoteBugreportUri =*/ null,
718                             /* remoteBugreportHash =*/ null, /* isOrganizationOwnedDevice =*/ true);
719                     mDeviceOwnerUserId = UserHandle.USER_SYSTEM;
720                 } else if (tag.equals(TAG_DEVICE_INITIALIZER)) {
721                     // Deprecated tag
722                 } else if (tag.equals(TAG_PROFILE_OWNER)) {
723                     String profileOwnerPackageName = parser.getAttributeValue(null, ATTR_PACKAGE);
724                     String profileOwnerName = parser.getAttributeValue(null, ATTR_NAME);
725                     String profileOwnerComponentStr =
726                             parser.getAttributeValue(null, ATTR_COMPONENT_NAME);
727                     int userId = parser.getAttributeInt(null, ATTR_USERID);
728                     OwnerInfo profileOwnerInfo = null;
729                     if (profileOwnerComponentStr != null) {
730                         ComponentName admin = ComponentName.unflattenFromString(
731                                 profileOwnerComponentStr);
732                         if (admin != null) {
733                             profileOwnerInfo = new OwnerInfo(profileOwnerName, admin,
734                                     /* userRestrictionsMigrated =*/ false, null,
735                                     null, /* isOrganizationOwnedDevice =*/ false);
736                         } else {
737                             // This shouldn't happen but switch from package name -> component name
738                             // might have written bad device owner files. b/17652534
739                             Slog.e(TAG, "Error parsing device-owner file. Bad component name " +
740                                     profileOwnerComponentStr);
741                         }
742                     }
743                     if (profileOwnerInfo == null) {
744                         profileOwnerInfo = new OwnerInfo(profileOwnerName, profileOwnerPackageName,
745                                 /* userRestrictionsMigrated =*/ false,
746                                 /* remoteBugreportUri =*/ null, /* remoteBugreportHash =*/
747                                 null, /* isOrganizationOwnedDevice =*/ false);
748                     }
749                     mProfileOwners.put(userId, profileOwnerInfo);
750                 } else if (TAG_SYSTEM_UPDATE_POLICY.equals(tag)) {
751                     mSystemUpdatePolicy = SystemUpdatePolicy.restoreFromXml(parser);
752                 } else {
753                     throw new XmlPullParserException(
754                             "Unexpected tag in device owner file: " + tag);
755                 }
756             }
757             input.close();
758         } catch (XmlPullParserException | IOException e) {
759             Slog.e(TAG, "Error parsing device-owner file", e);
760         }
761         return true;
762     }
763 
writeDeviceOwner()764     void writeDeviceOwner() {
765         synchronized (mLock) {
766             if (DEBUG) {
767                 Log.d(TAG, "Writing to device owner file");
768             }
769             new DeviceOwnerReadWriter().writeToFileLocked();
770         }
771     }
772 
writeProfileOwner(int userId)773     void writeProfileOwner(int userId) {
774         synchronized (mLock) {
775             if (DEBUG) {
776                 Log.d(TAG, "Writing to profile owner file for user " + userId);
777             }
778             new ProfileOwnerReadWriter(userId).writeToFileLocked();
779         }
780     }
781 
782     /**
783      * Saves the given {@link SystemUpdateInfo} if it is different from the existing one, or if
784      * none exists.
785      *
786      * @return Whether the saved system update information has changed.
787      */
saveSystemUpdateInfo(@ullable SystemUpdateInfo newInfo)788     boolean saveSystemUpdateInfo(@Nullable SystemUpdateInfo newInfo) {
789         synchronized (mLock) {
790             // Check if we already have the same update information.
791             if (Objects.equals(newInfo, mSystemUpdateInfo)) {
792                 return false;
793             }
794 
795             mSystemUpdateInfo = newInfo;
796             new DeviceOwnerReadWriter().writeToFileLocked();
797             return true;
798         }
799     }
800 
801     @Nullable
getSystemUpdateInfo()802     public SystemUpdateInfo getSystemUpdateInfo() {
803         synchronized (mLock) {
804             return mSystemUpdateInfo;
805         }
806     }
807 
pushToAppOpsLocked()808     void pushToAppOpsLocked() {
809         if (!mSystemReady) {
810             return;
811         }
812         final long ident = Binder.clearCallingIdentity();
813         try {
814             final SparseIntArray owners = new SparseIntArray();
815             if (mDeviceOwner != null) {
816                 final int uid = getDeviceOwnerUidLocked();
817                 if (uid >= 0) {
818                     owners.put(mDeviceOwnerUserId, uid);
819                 }
820             }
821             if (mProfileOwners != null) {
822                 for (int poi = mProfileOwners.size() - 1; poi >= 0; poi--) {
823                     final int uid = mPackageManagerInternal.getPackageUid(
824                             mProfileOwners.valueAt(poi).packageName,
825                             PackageManager.MATCH_ALL | PackageManager.MATCH_KNOWN_PACKAGES,
826                             mProfileOwners.keyAt(poi));
827                     if (uid >= 0) {
828                         owners.put(mProfileOwners.keyAt(poi), uid);
829                     }
830                 }
831             }
832             AppOpsManagerInternal appops = LocalServices.getService(AppOpsManagerInternal.class);
833             if (appops != null) {
834                 appops.setDeviceAndProfileOwners(owners.size() > 0 ? owners : null);
835             }
836         } finally {
837             Binder.restoreCallingIdentity(ident);
838         }
839     }
840 
systemReady()841     public void systemReady() {
842         synchronized (mLock) {
843             mSystemReady = true;
844             pushToActivityManagerLocked();
845             pushToAppOpsLocked();
846         }
847     }
848 
849     private abstract static class FileReadWriter {
850         private final File mFile;
851 
FileReadWriter(File file)852         protected FileReadWriter(File file) {
853             mFile = file;
854         }
855 
shouldWrite()856         abstract boolean shouldWrite();
857 
writeToFileLocked()858         void writeToFileLocked() {
859             if (!shouldWrite()) {
860                 if (DEBUG) {
861                     Log.d(TAG, "No need to write to " + mFile);
862                 }
863                 // No contents, remove the file.
864                 if (mFile.exists()) {
865                     if (DEBUG) {
866                         Log.d(TAG, "Deleting existing " + mFile);
867                     }
868                     if (!mFile.delete()) {
869                         Slog.e(TAG, "Failed to remove " + mFile.getPath());
870                     }
871                 }
872                 return;
873             }
874             if (DEBUG) {
875                 Log.d(TAG, "Writing to " + mFile);
876             }
877 
878             final AtomicFile f = new AtomicFile(mFile);
879             FileOutputStream outputStream = null;
880             try {
881                 outputStream = f.startWrite();
882                 final TypedXmlSerializer out = Xml.resolveSerializer(outputStream);
883 
884                 // Root tag
885                 out.startDocument(null, true);
886                 out.startTag(null, TAG_ROOT);
887 
888                 // Actual content
889                 writeInner(out);
890 
891                 // Close root
892                 out.endTag(null, TAG_ROOT);
893                 out.endDocument();
894                 out.flush();
895 
896                 // Commit the content.
897                 f.finishWrite(outputStream);
898                 outputStream = null;
899 
900             } catch (IOException e) {
901                 Slog.e(TAG, "Exception when writing", e);
902                 if (outputStream != null) {
903                     f.failWrite(outputStream);
904                 }
905             }
906         }
907 
readFromFileLocked()908         void readFromFileLocked() {
909             if (!mFile.exists()) {
910                 if (DEBUG) {
911                     Log.d(TAG, "" + mFile + " doesn't exist");
912                 }
913                 return;
914             }
915             if (DEBUG) {
916                 Log.d(TAG, "Reading from " + mFile);
917             }
918             final AtomicFile f = new AtomicFile(mFile);
919             InputStream input = null;
920             try {
921                 input = f.openRead();
922                 final TypedXmlPullParser parser = Xml.resolvePullParser(input);
923 
924                 int type;
925                 int depth = 0;
926                 while ((type = parser.next()) != TypedXmlPullParser.END_DOCUMENT) {
927                     switch (type) {
928                         case TypedXmlPullParser.START_TAG:
929                             depth++;
930                             break;
931                         case TypedXmlPullParser.END_TAG:
932                             depth--;
933                             // fallthrough
934                         default:
935                             continue;
936                     }
937                     // Check the root tag
938                     final String tag = parser.getName();
939                     if (depth == 1) {
940                         if (!TAG_ROOT.equals(tag)) {
941                             Slog.e(TAG, "Invalid root tag: " + tag);
942                             return;
943                         }
944                         continue;
945                     }
946                     // readInner() will only see START_TAG at depth >= 2.
947                     if (!readInner(parser, depth, tag)) {
948                         return; // Error
949                     }
950                 }
951             } catch (XmlPullParserException | IOException e) {
952                 Slog.e(TAG, "Error parsing owners information file", e);
953             } finally {
954                 IoUtils.closeQuietly(input);
955             }
956         }
957 
writeInner(TypedXmlSerializer out)958         abstract void writeInner(TypedXmlSerializer out) throws IOException;
959 
readInner(TypedXmlPullParser parser, int depth, String tag)960         abstract boolean readInner(TypedXmlPullParser parser, int depth, String tag);
961     }
962 
963     private class DeviceOwnerReadWriter extends FileReadWriter {
964 
DeviceOwnerReadWriter()965         protected DeviceOwnerReadWriter() {
966             super(getDeviceOwnerFile());
967         }
968 
969         @Override
shouldWrite()970         boolean shouldWrite() {
971             return (mDeviceOwner != null) || (mSystemUpdatePolicy != null)
972                     || (mSystemUpdateInfo != null);
973         }
974 
975         @Override
writeInner(TypedXmlSerializer out)976         void writeInner(TypedXmlSerializer out) throws IOException {
977             if (mDeviceOwner != null) {
978                 mDeviceOwner.writeToXml(out, TAG_DEVICE_OWNER);
979                 out.startTag(null, TAG_DEVICE_OWNER_CONTEXT);
980                 out.attributeInt(null, ATTR_USERID, mDeviceOwnerUserId);
981                 out.endTag(null, TAG_DEVICE_OWNER_CONTEXT);
982 
983             }
984 
985             if (!mDeviceOwnerTypes.isEmpty()) {
986                 for (ArrayMap.Entry<String, Integer> entry : mDeviceOwnerTypes.entrySet()) {
987                     out.startTag(null, TAG_DEVICE_OWNER_TYPE);
988                     out.attribute(null, ATTR_PACKAGE, entry.getKey());
989                     out.attributeInt(null, ATTR_DEVICE_OWNER_TYPE_VALUE, entry.getValue());
990                     out.endTag(null, TAG_DEVICE_OWNER_TYPE);
991                 }
992             }
993 
994             if (!mDeviceOwnerProtectedPackages.isEmpty()) {
995                 for (ArrayMap.Entry<String, List<String>> entry :
996                         mDeviceOwnerProtectedPackages.entrySet()) {
997                     List<String> protectedPackages = entry.getValue();
998 
999                     out.startTag(null, TAG_DEVICE_OWNER_PROTECTED_PACKAGES);
1000                     out.attribute(null, ATTR_PACKAGE, entry.getKey());
1001                     out.attributeInt(null, ATTR_SIZE, protectedPackages.size());
1002                     for (int i = 0, size = protectedPackages.size(); i < size; i++) {
1003                         out.attribute(null, ATTR_NAME + i, protectedPackages.get(i));
1004                     }
1005                     out.endTag(null, TAG_DEVICE_OWNER_PROTECTED_PACKAGES);
1006                 }
1007             }
1008 
1009             if (mSystemUpdatePolicy != null) {
1010                 out.startTag(null, TAG_SYSTEM_UPDATE_POLICY);
1011                 mSystemUpdatePolicy.saveToXml(out);
1012                 out.endTag(null, TAG_SYSTEM_UPDATE_POLICY);
1013             }
1014 
1015             if (mSystemUpdateInfo != null) {
1016                 mSystemUpdateInfo.writeToXml(out, TAG_PENDING_OTA_INFO);
1017             }
1018 
1019             if (mSystemUpdateFreezeStart != null || mSystemUpdateFreezeEnd != null) {
1020                 out.startTag(null, TAG_FREEZE_PERIOD_RECORD);
1021                 if (mSystemUpdateFreezeStart != null) {
1022                     out.attribute(null, ATTR_FREEZE_RECORD_START,
1023                             mSystemUpdateFreezeStart.toString());
1024                 }
1025                 if (mSystemUpdateFreezeEnd != null) {
1026                     out.attribute(null, ATTR_FREEZE_RECORD_END, mSystemUpdateFreezeEnd.toString());
1027                 }
1028                 out.endTag(null, TAG_FREEZE_PERIOD_RECORD);
1029             }
1030         }
1031 
1032         @Override
readInner(TypedXmlPullParser parser, int depth, String tag)1033         boolean readInner(TypedXmlPullParser parser, int depth, String tag) {
1034             if (depth > 2) {
1035                 return true; // Ignore
1036             }
1037             switch (tag) {
1038                 case TAG_DEVICE_OWNER:
1039                     mDeviceOwner = OwnerInfo.readFromXml(parser);
1040                     mDeviceOwnerUserId = UserHandle.USER_SYSTEM; // Set default
1041                     break;
1042                 case TAG_DEVICE_OWNER_CONTEXT: {
1043                     mDeviceOwnerUserId = parser.getAttributeInt(null, ATTR_USERID,
1044                             mDeviceOwnerUserId);
1045                     break;
1046                 }
1047                 case TAG_DEVICE_INITIALIZER:
1048                     // Deprecated tag
1049                     break;
1050                 case TAG_SYSTEM_UPDATE_POLICY:
1051                     mSystemUpdatePolicy = SystemUpdatePolicy.restoreFromXml(parser);
1052                     break;
1053                 case TAG_PENDING_OTA_INFO:
1054                     mSystemUpdateInfo = SystemUpdateInfo.readFromXml(parser);
1055                     break;
1056                 case TAG_FREEZE_PERIOD_RECORD:
1057                     String startDate = parser.getAttributeValue(null, ATTR_FREEZE_RECORD_START);
1058                     String endDate = parser.getAttributeValue(null, ATTR_FREEZE_RECORD_END);
1059                     if (startDate != null && endDate != null) {
1060                         mSystemUpdateFreezeStart = LocalDate.parse(startDate);
1061                         mSystemUpdateFreezeEnd = LocalDate.parse(endDate);
1062                         if (mSystemUpdateFreezeStart.isAfter(mSystemUpdateFreezeEnd)) {
1063                             Slog.e(TAG, "Invalid system update freeze record loaded");
1064                             mSystemUpdateFreezeStart = null;
1065                             mSystemUpdateFreezeEnd = null;
1066                         }
1067                     }
1068                     break;
1069                 case TAG_DEVICE_OWNER_TYPE:
1070                     String packageName = parser.getAttributeValue(null, ATTR_PACKAGE);
1071                     int deviceOwnerType = parser.getAttributeInt(null, ATTR_DEVICE_OWNER_TYPE_VALUE,
1072                             DEVICE_OWNER_TYPE_DEFAULT);
1073                     mDeviceOwnerTypes.put(packageName, deviceOwnerType);
1074                     break;
1075                 case TAG_DEVICE_OWNER_PROTECTED_PACKAGES:
1076                     packageName = parser.getAttributeValue(null, ATTR_PACKAGE);
1077                     int protectedPackagesSize = parser.getAttributeInt(null, ATTR_SIZE, 0);
1078                     List<String> protectedPackages = new ArrayList<>();
1079                     for (int i = 0; i < protectedPackagesSize; i++) {
1080                         protectedPackages.add(parser.getAttributeValue(null, ATTR_NAME + i));
1081                     }
1082                     mDeviceOwnerProtectedPackages.put(packageName, protectedPackages);
1083                     break;
1084                 default:
1085                     Slog.e(TAG, "Unexpected tag: " + tag);
1086                     return false;
1087 
1088             }
1089             return true;
1090         }
1091     }
1092 
1093     private class ProfileOwnerReadWriter extends FileReadWriter {
1094         private final int mUserId;
1095 
ProfileOwnerReadWriter(int userId)1096         ProfileOwnerReadWriter(int userId) {
1097             super(getProfileOwnerFile(userId));
1098             mUserId = userId;
1099         }
1100 
1101         @Override
shouldWrite()1102         boolean shouldWrite() {
1103             return mProfileOwners.get(mUserId) != null;
1104         }
1105 
1106         @Override
writeInner(TypedXmlSerializer out)1107         void writeInner(TypedXmlSerializer out) throws IOException {
1108             final OwnerInfo profileOwner = mProfileOwners.get(mUserId);
1109             if (profileOwner != null) {
1110                 profileOwner.writeToXml(out, TAG_PROFILE_OWNER);
1111             }
1112         }
1113 
1114         @Override
readInner(TypedXmlPullParser parser, int depth, String tag)1115         boolean readInner(TypedXmlPullParser parser, int depth, String tag) {
1116             if (depth > 2) {
1117                 return true; // Ignore
1118             }
1119             switch (tag) {
1120                 case TAG_PROFILE_OWNER:
1121                     mProfileOwners.put(mUserId, OwnerInfo.readFromXml(parser));
1122                     break;
1123                 default:
1124                     Slog.e(TAG, "Unexpected tag: " + tag);
1125                     return false;
1126 
1127             }
1128             return true;
1129         }
1130     }
1131 
1132     static class OwnerInfo {
1133         public final String name;
1134         public final String packageName;
1135         public final ComponentName admin;
1136         public boolean userRestrictionsMigrated;
1137         public String remoteBugreportUri;
1138         public String remoteBugreportHash;
1139         public boolean isOrganizationOwnedDevice;
1140 
OwnerInfo(String name, String packageName, boolean userRestrictionsMigrated, String remoteBugreportUri, String remoteBugreportHash, boolean isOrganizationOwnedDevice)1141         public OwnerInfo(String name, String packageName, boolean userRestrictionsMigrated,
1142                 String remoteBugreportUri, String remoteBugreportHash,
1143                 boolean isOrganizationOwnedDevice) {
1144             this.name = name;
1145             this.packageName = packageName;
1146             this.admin = new ComponentName(packageName, "");
1147             this.userRestrictionsMigrated = userRestrictionsMigrated;
1148             this.remoteBugreportUri = remoteBugreportUri;
1149             this.remoteBugreportHash = remoteBugreportHash;
1150             this.isOrganizationOwnedDevice = isOrganizationOwnedDevice;
1151         }
1152 
OwnerInfo(String name, ComponentName admin, boolean userRestrictionsMigrated, String remoteBugreportUri, String remoteBugreportHash, boolean isOrganizationOwnedDevice)1153         public OwnerInfo(String name, ComponentName admin, boolean userRestrictionsMigrated,
1154                 String remoteBugreportUri, String remoteBugreportHash,
1155                 boolean isOrganizationOwnedDevice) {
1156             this.name = name;
1157             this.admin = admin;
1158             this.packageName = admin.getPackageName();
1159             this.userRestrictionsMigrated = userRestrictionsMigrated;
1160             this.remoteBugreportUri = remoteBugreportUri;
1161             this.remoteBugreportHash = remoteBugreportHash;
1162             this.isOrganizationOwnedDevice = isOrganizationOwnedDevice;
1163         }
1164 
writeToXml(TypedXmlSerializer out, String tag)1165         public void writeToXml(TypedXmlSerializer out, String tag) throws IOException {
1166             out.startTag(null, tag);
1167             out.attribute(null, ATTR_PACKAGE, packageName);
1168             if (name != null) {
1169                 out.attribute(null, ATTR_NAME, name);
1170             }
1171             if (admin != null) {
1172                 out.attribute(null, ATTR_COMPONENT_NAME, admin.flattenToString());
1173             }
1174             out.attributeBoolean(null, ATTR_USER_RESTRICTIONS_MIGRATED, userRestrictionsMigrated);
1175             if (remoteBugreportUri != null) {
1176                 out.attribute(null, ATTR_REMOTE_BUGREPORT_URI, remoteBugreportUri);
1177             }
1178             if (remoteBugreportHash != null) {
1179                 out.attribute(null, ATTR_REMOTE_BUGREPORT_HASH, remoteBugreportHash);
1180             }
1181             if (isOrganizationOwnedDevice) {
1182                 out.attributeBoolean(null, ATTR_PROFILE_OWNER_OF_ORG_OWNED_DEVICE,
1183                         isOrganizationOwnedDevice);
1184             }
1185             out.endTag(null, tag);
1186         }
1187 
readFromXml(TypedXmlPullParser parser)1188         public static OwnerInfo readFromXml(TypedXmlPullParser parser) {
1189             final String packageName = parser.getAttributeValue(null, ATTR_PACKAGE);
1190             final String name = parser.getAttributeValue(null, ATTR_NAME);
1191             final String componentName =
1192                     parser.getAttributeValue(null, ATTR_COMPONENT_NAME);
1193             final String userRestrictionsMigratedStr =
1194                     parser.getAttributeValue(null, ATTR_USER_RESTRICTIONS_MIGRATED);
1195             final boolean userRestrictionsMigrated =
1196                     ("true".equals(userRestrictionsMigratedStr));
1197             final String remoteBugreportUri = parser.getAttributeValue(null,
1198                     ATTR_REMOTE_BUGREPORT_URI);
1199             final String remoteBugreportHash = parser.getAttributeValue(null,
1200                     ATTR_REMOTE_BUGREPORT_HASH);
1201             final String canAccessDeviceIdsStr =
1202                     parser.getAttributeValue(null, ATTR_CAN_ACCESS_DEVICE_IDS);
1203             final boolean canAccessDeviceIds =
1204                     ("true".equals(canAccessDeviceIdsStr));
1205             final String isOrgOwnedDeviceStr =
1206                     parser.getAttributeValue(null, ATTR_PROFILE_OWNER_OF_ORG_OWNED_DEVICE);
1207             final boolean isOrgOwnedDevice =
1208                     ("true".equals(isOrgOwnedDeviceStr)) | canAccessDeviceIds;
1209 
1210             // Has component name?  If so, return [name, component]
1211             if (componentName != null) {
1212                 final ComponentName admin = ComponentName.unflattenFromString(componentName);
1213                 if (admin != null) {
1214                     return new OwnerInfo(name, admin, userRestrictionsMigrated,
1215                             remoteBugreportUri, remoteBugreportHash, isOrgOwnedDevice);
1216                 } else {
1217                     // This shouldn't happen but switch from package name -> component name
1218                     // might have written bad device owner files. b/17652534
1219                     Slog.e(TAG, "Error parsing owner file. Bad component name " +
1220                             componentName);
1221                 }
1222             }
1223 
1224             // Else, build with [name, package]
1225             return new OwnerInfo(name, packageName, userRestrictionsMigrated, remoteBugreportUri,
1226                     remoteBugreportHash, isOrgOwnedDevice);
1227         }
1228 
dump(IndentingPrintWriter pw)1229         public void dump(IndentingPrintWriter pw) {
1230             pw.println("admin=" + admin);
1231             pw.println("name=" + name);
1232             pw.println("package=" + packageName);
1233             pw.println("isOrganizationOwnedDevice=" + isOrganizationOwnedDevice);
1234         }
1235     }
1236 
dump(IndentingPrintWriter pw)1237     public void dump(IndentingPrintWriter pw) {
1238         boolean needBlank = false;
1239         if (mDeviceOwner != null) {
1240             pw.println("Device Owner: ");
1241             pw.increaseIndent();
1242             mDeviceOwner.dump(pw);
1243             pw.println("User ID: " + mDeviceOwnerUserId);
1244             pw.decreaseIndent();
1245             needBlank = true;
1246         }
1247         if (mSystemUpdatePolicy != null) {
1248             if (needBlank) {
1249                 pw.println();
1250             }
1251             pw.println("System Update Policy: " + mSystemUpdatePolicy);
1252             needBlank = true;
1253         }
1254         if (mProfileOwners != null) {
1255             for (Map.Entry<Integer, OwnerInfo> entry : mProfileOwners.entrySet()) {
1256                 if (needBlank) {
1257                     pw.println();
1258                 }
1259                 pw.println("Profile Owner (User " + entry.getKey() + "): ");
1260                 pw.increaseIndent();
1261                 entry.getValue().dump(pw);
1262                 pw.decreaseIndent();
1263                 needBlank = true;
1264             }
1265         }
1266         if (mSystemUpdateInfo != null) {
1267             if (needBlank) {
1268                 pw.println();
1269             }
1270             pw.println("Pending System Update: " + mSystemUpdateInfo);
1271             needBlank = true;
1272         }
1273         if (mSystemUpdateFreezeStart != null || mSystemUpdateFreezeEnd != null) {
1274             if (needBlank) {
1275                 pw.println();
1276             }
1277             pw.println("System update freeze record: "
1278                     + getSystemUpdateFreezePeriodRecordAsString());
1279             needBlank = true;
1280         }
1281     }
1282 
1283     @VisibleForTesting
getLegacyConfigFile()1284     File getLegacyConfigFile() {
1285         return new File(mInjector.environmentGetDataSystemDirectory(), DEVICE_OWNER_XML_LEGACY);
1286     }
1287 
1288     @VisibleForTesting
getDeviceOwnerFile()1289     File getDeviceOwnerFile() {
1290         return new File(mInjector.environmentGetDataSystemDirectory(), DEVICE_OWNER_XML);
1291     }
1292 
1293     @VisibleForTesting
getProfileOwnerFile(int userId)1294     File getProfileOwnerFile(int userId) {
1295         return new File(mInjector.environmentGetUserSystemDirectory(userId), PROFILE_OWNER_XML);
1296     }
1297 
1298     @VisibleForTesting
1299     public static class Injector {
environmentGetDataSystemDirectory()1300         File environmentGetDataSystemDirectory() {
1301             return Environment.getDataSystemDirectory();
1302         }
1303 
environmentGetUserSystemDirectory(int userId)1304         File environmentGetUserSystemDirectory(int userId) {
1305             return Environment.getUserSystemDirectory(userId);
1306         }
1307     }
1308 }
1309