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