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