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