1 /* 2 * Copyright (C) 2022 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 package com.android.server.devicepolicy; 17 18 import static android.app.admin.DevicePolicyManager.DEVICE_OWNER_TYPE_DEFAULT; 19 20 import android.annotation.Nullable; 21 import android.app.admin.SystemUpdateInfo; 22 import android.app.admin.SystemUpdatePolicy; 23 import android.app.admin.flags.Flags; 24 import android.content.ComponentName; 25 import android.os.UserHandle; 26 import android.util.ArrayMap; 27 import android.util.AtomicFile; 28 import android.util.IndentingPrintWriter; 29 import android.util.Log; 30 import android.util.Slog; 31 import android.util.Xml; 32 33 import com.android.internal.annotations.VisibleForTesting; 34 import com.android.modules.utils.TypedXmlPullParser; 35 import com.android.modules.utils.TypedXmlSerializer; 36 37 import libcore.io.IoUtils; 38 39 import org.xmlpull.v1.XmlPullParserException; 40 41 import java.io.File; 42 import java.io.FileOutputStream; 43 import java.io.IOException; 44 import java.io.InputStream; 45 import java.time.LocalDate; 46 import java.util.ArrayList; 47 import java.util.List; 48 import java.util.Map; 49 50 class OwnersData { 51 private static final String TAG = "DevicePolicyManagerService"; 52 53 private static final boolean DEBUG = false; // DO NOT SUBMIT WITH TRUE 54 55 // XML storing device owner info, system update policy and pending OTA update information. 56 private static final String DEVICE_OWNER_XML = "device_owner_2.xml"; 57 private static final String PROFILE_OWNER_XML = "profile_owner.xml"; 58 59 private static final String TAG_ROOT = "root"; 60 private static final String TAG_DEVICE_OWNER = "device-owner"; 61 private static final String TAG_SYSTEM_UPDATE_POLICY = "system-update-policy"; 62 private static final String TAG_FREEZE_PERIOD_RECORD = "freeze-record"; 63 private static final String TAG_PENDING_OTA_INFO = "pending-ota-info"; 64 private static final String TAG_PROFILE_OWNER = "profile-owner"; 65 // Holds "context" for device-owner, this must not be show up before device-owner. 66 private static final String TAG_DEVICE_OWNER_CONTEXT = "device-owner-context"; 67 private static final String TAG_DEVICE_OWNER_TYPE = "device-owner-type"; 68 private static final String TAG_DEVICE_OWNER_PROTECTED_PACKAGES = 69 "device-owner-protected-packages"; 70 private static final String TAG_POLICY_ENGINE_MIGRATION = "policy-engine-migration"; 71 72 private static final String ATTR_NAME = "name"; 73 private static final String ATTR_PACKAGE = "package"; 74 private static final String ATTR_COMPONENT_NAME = "component"; 75 private static final String ATTR_SIZE = "size"; 76 private static final String ATTR_REMOTE_BUGREPORT_URI = "remoteBugreportUri"; 77 private static final String ATTR_REMOTE_BUGREPORT_HASH = "remoteBugreportHash"; 78 private static final String ATTR_USERID = "userId"; 79 private static final String ATTR_FREEZE_RECORD_START = "start"; 80 private static final String ATTR_FREEZE_RECORD_END = "end"; 81 // Legacy attribute, its presence would mean the profile owner associated with it is 82 // managing a profile on an organization-owned device. 83 private static final String ATTR_CAN_ACCESS_DEVICE_IDS = "canAccessDeviceIds"; 84 // New attribute for profile owner of organization-owned device. 85 private static final String ATTR_PROFILE_OWNER_OF_ORG_OWNED_DEVICE = 86 "isPoOrganizationOwnedDevice"; 87 private static final String ATTR_DEVICE_OWNER_TYPE_VALUE = "value"; 88 89 private static final String ATTR_MIGRATED_TO_POLICY_ENGINE = "migratedToPolicyEngine"; 90 private static final String ATTR_SECURITY_LOG_MIGRATED = "securityLogMigrated"; 91 private static final String ATTR_REQUIRED_PASSWORD_COMPLEXITY_MIGRATED = 92 "passwordComplexityMigrated"; 93 private static final String ATTR_SUSPENDED_PACKAGES_MIGRATED = "suspendedPackagesMigrated"; 94 private static final String ATTR_RESET_PASSWORD_WITH_TOKEN_MIGRATED = 95 "resetPasswordWithTokenMigrated"; 96 private static final String ATTR_MEMORY_TAGGING_MIGRATED = 97 "memoryTaggingMigrated"; 98 private static final String ATTR_SET_KEYGUARD_DISABLED_FEATURES_MIGRATED = 99 "setKeyguardDisabledFeaturesMigrated"; 100 101 private static final String ATTR_MIGRATED_POST_UPGRADE = "migratedPostUpgrade"; 102 103 // Internal state for the device owner package. 104 OwnerInfo mDeviceOwner; 105 int mDeviceOwnerUserId = UserHandle.USER_NULL; 106 107 // Device owner type for a managed device. 108 final ArrayMap<String, Integer> mDeviceOwnerTypes = new ArrayMap<>(); 109 110 /** @deprecated moved to {@link ActiveAdmin#protectedPackages}. */ 111 @Deprecated 112 @Nullable 113 ArrayMap<String, List<String>> mDeviceOwnerProtectedPackages; 114 115 // Internal state for the profile owner packages. 116 final ArrayMap<Integer, OwnerInfo> mProfileOwners = new ArrayMap<>(); 117 118 // Local system update policy controllable by device owner. 119 SystemUpdatePolicy mSystemUpdatePolicy; 120 LocalDate mSystemUpdateFreezeStart; 121 LocalDate mSystemUpdateFreezeEnd; 122 123 // Pending OTA info if there is one. 124 @Nullable 125 SystemUpdateInfo mSystemUpdateInfo; 126 private final PolicyPathProvider mPathProvider; 127 128 boolean mMigratedToPolicyEngine = false; 129 boolean mSecurityLoggingMigrated = false; 130 boolean mRequiredPasswordComplexityMigrated = false; 131 boolean mSuspendedPackagesMigrated = false; 132 boolean mResetPasswordWithTokenMigrated = false; 133 boolean mMemoryTaggingMigrated = false; 134 boolean mSetKeyguardDisabledFeaturesMigrated = false; 135 136 boolean mPoliciesMigratedPostUpdate = false; 137 OwnersData(PolicyPathProvider pathProvider)138 OwnersData(PolicyPathProvider pathProvider) { 139 mPathProvider = pathProvider; 140 } 141 load(int[] allUsers)142 void load(int[] allUsers) { 143 new DeviceOwnerReadWriter().readFromFileLocked(); 144 145 for (int userId : allUsers) { 146 new ProfileOwnerReadWriter(userId).readFromFileLocked(); 147 } 148 149 OwnerInfo profileOwner = mProfileOwners.get(mDeviceOwnerUserId); 150 ComponentName admin = profileOwner != null ? profileOwner.admin : null; 151 if (mDeviceOwner != null && admin != null) { 152 Slog.w(TAG, String.format("User %d has both DO and PO, which is not supported", 153 mDeviceOwnerUserId)); 154 } 155 } 156 157 /** 158 * @return true upon success, false otherwise. 159 */ writeDeviceOwner()160 boolean writeDeviceOwner() { 161 if (DEBUG) { 162 Log.d(TAG, "Writing to device owner file"); 163 } 164 return new DeviceOwnerReadWriter().writeToFileLocked(); 165 } 166 167 /** 168 * @return true upon success, false otherwise. 169 */ writeProfileOwner(int userId)170 boolean writeProfileOwner(int userId) { 171 if (DEBUG) { 172 Log.d(TAG, "Writing to profile owner file for user " + userId); 173 } 174 return new ProfileOwnerReadWriter(userId).writeToFileLocked(); 175 } 176 dump(IndentingPrintWriter pw)177 void dump(IndentingPrintWriter pw) { 178 boolean needBlank = false; 179 if (mDeviceOwner != null) { 180 pw.println("Device Owner: "); 181 pw.increaseIndent(); 182 mDeviceOwner.dump(pw); 183 pw.println("User ID: " + mDeviceOwnerUserId); 184 pw.decreaseIndent(); 185 needBlank = true; 186 } 187 if (mSystemUpdatePolicy != null) { 188 if (needBlank) { 189 pw.println(); 190 } 191 pw.println("System Update Policy: " + mSystemUpdatePolicy); 192 needBlank = true; 193 } 194 if (mProfileOwners != null) { 195 for (Map.Entry<Integer, OwnerInfo> entry : mProfileOwners.entrySet()) { 196 if (needBlank) { 197 pw.println(); 198 } 199 pw.println("Profile Owner (User " + entry.getKey() + "): "); 200 pw.increaseIndent(); 201 entry.getValue().dump(pw); 202 pw.decreaseIndent(); 203 needBlank = true; 204 } 205 } 206 if (mSystemUpdateInfo != null) { 207 if (needBlank) { 208 pw.println(); 209 } 210 pw.println("Pending System Update: " + mSystemUpdateInfo); 211 needBlank = true; 212 } 213 if (mSystemUpdateFreezeStart != null || mSystemUpdateFreezeEnd != null) { 214 if (needBlank) { 215 pw.println(); 216 } 217 pw.println("System update freeze record: " 218 + getSystemUpdateFreezePeriodRecordAsString()); 219 needBlank = true; 220 } 221 } 222 getSystemUpdateFreezePeriodRecordAsString()223 String getSystemUpdateFreezePeriodRecordAsString() { 224 StringBuilder freezePeriodRecord = new StringBuilder(); 225 freezePeriodRecord.append("start: "); 226 if (mSystemUpdateFreezeStart != null) { 227 freezePeriodRecord.append(mSystemUpdateFreezeStart.toString()); 228 } else { 229 freezePeriodRecord.append("null"); 230 } 231 freezePeriodRecord.append("; end: "); 232 if (mSystemUpdateFreezeEnd != null) { 233 freezePeriodRecord.append(mSystemUpdateFreezeEnd.toString()); 234 } else { 235 freezePeriodRecord.append("null"); 236 } 237 return freezePeriodRecord.toString(); 238 } 239 240 @VisibleForTesting getDeviceOwnerFile()241 File getDeviceOwnerFile() { 242 return new File(mPathProvider.getDataSystemDirectory(), DEVICE_OWNER_XML); 243 } 244 245 @VisibleForTesting getProfileOwnerFile(int userId)246 File getProfileOwnerFile(int userId) { 247 return new File(mPathProvider.getUserSystemDirectory(userId), PROFILE_OWNER_XML); 248 } 249 250 private abstract static class FileReadWriter { 251 private final File mFile; 252 FileReadWriter(File file)253 protected FileReadWriter(File file) { 254 mFile = file; 255 } 256 shouldWrite()257 abstract boolean shouldWrite(); 258 writeToFileLocked()259 boolean writeToFileLocked() { 260 if (!shouldWrite()) { 261 if (DEBUG) { 262 Log.d(TAG, "No need to write to " + mFile); 263 } 264 // No contents, remove the file. 265 if (mFile.exists()) { 266 if (DEBUG) { 267 Log.d(TAG, "Deleting existing " + mFile); 268 } 269 if (!mFile.delete()) { 270 Slog.e(TAG, "Failed to remove " + mFile.getPath()); 271 } 272 } 273 return true; 274 } 275 if (DEBUG) { 276 Log.d(TAG, "Writing to " + mFile); 277 } 278 279 final AtomicFile f = new AtomicFile(mFile); 280 FileOutputStream outputStream = null; 281 try { 282 outputStream = f.startWrite(); 283 final TypedXmlSerializer out = Xml.resolveSerializer(outputStream); 284 285 // Root tag 286 out.startDocument(null, true); 287 out.startTag(null, TAG_ROOT); 288 289 // Actual content 290 writeInner(out); 291 292 // Close root 293 out.endTag(null, TAG_ROOT); 294 out.endDocument(); 295 out.flush(); 296 297 // Commit the content. 298 f.finishWrite(outputStream); 299 outputStream = null; 300 301 } catch (IOException e) { 302 Slog.e(TAG, "Exception when writing", e); 303 if (outputStream != null) { 304 f.failWrite(outputStream); 305 } 306 return false; 307 } 308 return true; 309 } 310 readFromFileLocked()311 void readFromFileLocked() { 312 if (!mFile.exists()) { 313 if (DEBUG) { 314 Log.d(TAG, "" + mFile + " doesn't exist"); 315 } 316 return; 317 } 318 if (DEBUG) { 319 Log.d(TAG, "Reading from " + mFile); 320 } 321 final AtomicFile f = new AtomicFile(mFile); 322 InputStream input = null; 323 try { 324 input = f.openRead(); 325 final TypedXmlPullParser parser = Xml.resolvePullParser(input); 326 327 int type; 328 int depth = 0; 329 while ((type = parser.next()) != TypedXmlPullParser.END_DOCUMENT) { 330 switch (type) { 331 case TypedXmlPullParser.START_TAG: 332 depth++; 333 break; 334 case TypedXmlPullParser.END_TAG: 335 depth--; 336 // fallthrough 337 default: 338 continue; 339 } 340 // Check the root tag 341 final String tag = parser.getName(); 342 if (depth == 1) { 343 if (!TAG_ROOT.equals(tag)) { 344 Slog.e(TAG, "Invalid root tag: " + tag); 345 return; 346 } 347 continue; 348 } 349 // readInner() will only see START_TAG at depth >= 2. 350 if (!readInner(parser, depth, tag)) { 351 return; // Error 352 } 353 } 354 } catch (XmlPullParserException | IOException e) { 355 Slog.e(TAG, "Error parsing owners information file", e); 356 } finally { 357 IoUtils.closeQuietly(input); 358 } 359 } 360 writeInner(TypedXmlSerializer out)361 abstract void writeInner(TypedXmlSerializer out) throws IOException; 362 readInner(TypedXmlPullParser parser, int depth, String tag)363 abstract boolean readInner(TypedXmlPullParser parser, int depth, String tag); 364 } 365 366 private class DeviceOwnerReadWriter extends FileReadWriter { 367 DeviceOwnerReadWriter()368 protected DeviceOwnerReadWriter() { 369 super(getDeviceOwnerFile()); 370 } 371 372 @Override shouldWrite()373 boolean shouldWrite() { 374 return true; 375 } 376 377 @Override writeInner(TypedXmlSerializer out)378 void writeInner(TypedXmlSerializer out) throws IOException { 379 if (mDeviceOwner != null) { 380 mDeviceOwner.writeToXml(out, TAG_DEVICE_OWNER); 381 out.startTag(null, TAG_DEVICE_OWNER_CONTEXT); 382 out.attributeInt(null, ATTR_USERID, mDeviceOwnerUserId); 383 out.endTag(null, TAG_DEVICE_OWNER_CONTEXT); 384 385 } 386 387 if (!mDeviceOwnerTypes.isEmpty()) { 388 for (ArrayMap.Entry<String, Integer> entry : mDeviceOwnerTypes.entrySet()) { 389 out.startTag(null, TAG_DEVICE_OWNER_TYPE); 390 out.attribute(null, ATTR_PACKAGE, entry.getKey()); 391 out.attributeInt(null, ATTR_DEVICE_OWNER_TYPE_VALUE, entry.getValue()); 392 out.endTag(null, TAG_DEVICE_OWNER_TYPE); 393 } 394 } 395 396 if (mSystemUpdatePolicy != null) { 397 out.startTag(null, TAG_SYSTEM_UPDATE_POLICY); 398 mSystemUpdatePolicy.saveToXml(out); 399 out.endTag(null, TAG_SYSTEM_UPDATE_POLICY); 400 } 401 402 if (mSystemUpdateInfo != null) { 403 mSystemUpdateInfo.writeToXml(out, TAG_PENDING_OTA_INFO); 404 } 405 406 if (mSystemUpdateFreezeStart != null || mSystemUpdateFreezeEnd != null) { 407 out.startTag(null, TAG_FREEZE_PERIOD_RECORD); 408 if (mSystemUpdateFreezeStart != null) { 409 out.attribute( 410 null, ATTR_FREEZE_RECORD_START, mSystemUpdateFreezeStart.toString()); 411 } 412 if (mSystemUpdateFreezeEnd != null) { 413 out.attribute(null, ATTR_FREEZE_RECORD_END, mSystemUpdateFreezeEnd.toString()); 414 } 415 out.endTag(null, TAG_FREEZE_PERIOD_RECORD); 416 } 417 418 out.startTag(null, TAG_POLICY_ENGINE_MIGRATION); 419 out.attributeBoolean(null, ATTR_MIGRATED_TO_POLICY_ENGINE, mMigratedToPolicyEngine); 420 out.attributeBoolean(null, ATTR_MIGRATED_POST_UPGRADE, mPoliciesMigratedPostUpdate); 421 out.attributeBoolean(null, ATTR_SECURITY_LOG_MIGRATED, mSecurityLoggingMigrated); 422 423 if (Flags.unmanagedModeMigration()) { 424 out.attributeBoolean(null, ATTR_REQUIRED_PASSWORD_COMPLEXITY_MIGRATED, 425 mRequiredPasswordComplexityMigrated); 426 } 427 if (Flags.suspendPackagesCoexistence()) { 428 out.attributeBoolean(null, ATTR_SUSPENDED_PACKAGES_MIGRATED, 429 mSuspendedPackagesMigrated); 430 431 } 432 if (Flags.resetPasswordWithTokenCoexistence()) { 433 out.attributeBoolean(null, ATTR_RESET_PASSWORD_WITH_TOKEN_MIGRATED, 434 mResetPasswordWithTokenMigrated); 435 } 436 out.attributeBoolean(null, ATTR_MEMORY_TAGGING_MIGRATED, 437 mMemoryTaggingMigrated); 438 if (Flags.setKeyguardDisabledFeaturesCoexistence()) { 439 out.attributeBoolean(null, ATTR_SET_KEYGUARD_DISABLED_FEATURES_MIGRATED, 440 mSetKeyguardDisabledFeaturesMigrated); 441 } 442 out.endTag(null, TAG_POLICY_ENGINE_MIGRATION); 443 444 } 445 446 @Override readInner(TypedXmlPullParser parser, int depth, String tag)447 boolean readInner(TypedXmlPullParser parser, int depth, String tag) { 448 if (depth > 2) { 449 return true; // Ignore 450 } 451 switch (tag) { 452 case TAG_DEVICE_OWNER: 453 mDeviceOwner = OwnerInfo.readFromXml(parser); 454 mDeviceOwnerUserId = UserHandle.USER_SYSTEM; // Set default 455 break; 456 case TAG_DEVICE_OWNER_CONTEXT: { 457 mDeviceOwnerUserId = 458 parser.getAttributeInt(null, ATTR_USERID, mDeviceOwnerUserId); 459 break; 460 } 461 case TAG_SYSTEM_UPDATE_POLICY: 462 mSystemUpdatePolicy = SystemUpdatePolicy.restoreFromXml(parser); 463 break; 464 case TAG_PENDING_OTA_INFO: 465 mSystemUpdateInfo = SystemUpdateInfo.readFromXml(parser); 466 break; 467 case TAG_FREEZE_PERIOD_RECORD: 468 String startDate = parser.getAttributeValue(null, ATTR_FREEZE_RECORD_START); 469 String endDate = parser.getAttributeValue(null, ATTR_FREEZE_RECORD_END); 470 if (startDate != null && endDate != null) { 471 mSystemUpdateFreezeStart = LocalDate.parse(startDate); 472 mSystemUpdateFreezeEnd = LocalDate.parse(endDate); 473 if (mSystemUpdateFreezeStart.isAfter(mSystemUpdateFreezeEnd)) { 474 Slog.e(TAG, "Invalid system update freeze record loaded"); 475 mSystemUpdateFreezeStart = null; 476 mSystemUpdateFreezeEnd = null; 477 } 478 } 479 break; 480 case TAG_DEVICE_OWNER_TYPE: 481 String packageName = parser.getAttributeValue(null, ATTR_PACKAGE); 482 int deviceOwnerType = parser.getAttributeInt( 483 null, ATTR_DEVICE_OWNER_TYPE_VALUE, DEVICE_OWNER_TYPE_DEFAULT); 484 mDeviceOwnerTypes.put(packageName, deviceOwnerType); 485 break; 486 // Deprecated fields below. 487 case TAG_DEVICE_OWNER_PROTECTED_PACKAGES: 488 packageName = parser.getAttributeValue(null, ATTR_PACKAGE); 489 int protectedPackagesSize = parser.getAttributeInt(null, ATTR_SIZE, 0); 490 List<String> protectedPackages = new ArrayList<>(); 491 for (int i = 0; i < protectedPackagesSize; i++) { 492 protectedPackages.add(parser.getAttributeValue(null, ATTR_NAME + i)); 493 } 494 if (mDeviceOwnerProtectedPackages == null) { 495 mDeviceOwnerProtectedPackages = new ArrayMap<>(); 496 } 497 mDeviceOwnerProtectedPackages.put(packageName, protectedPackages); 498 break; 499 case TAG_POLICY_ENGINE_MIGRATION: 500 mMigratedToPolicyEngine = parser.getAttributeBoolean( 501 null, ATTR_MIGRATED_TO_POLICY_ENGINE, false); 502 mPoliciesMigratedPostUpdate = parser.getAttributeBoolean( 503 null, ATTR_MIGRATED_POST_UPGRADE, false); 504 mSecurityLoggingMigrated = 505 parser.getAttributeBoolean(null, ATTR_SECURITY_LOG_MIGRATED, false); 506 mRequiredPasswordComplexityMigrated = Flags.unmanagedModeMigration() 507 && parser.getAttributeBoolean(null, 508 ATTR_REQUIRED_PASSWORD_COMPLEXITY_MIGRATED, false); 509 mSuspendedPackagesMigrated = Flags.suspendPackagesCoexistence() 510 && parser.getAttributeBoolean(null, 511 ATTR_SUSPENDED_PACKAGES_MIGRATED, false); 512 mResetPasswordWithTokenMigrated = Flags.resetPasswordWithTokenCoexistence() 513 && parser.getAttributeBoolean(null, 514 ATTR_RESET_PASSWORD_WITH_TOKEN_MIGRATED, false); 515 mMemoryTaggingMigrated = parser.getAttributeBoolean(null, 516 ATTR_MEMORY_TAGGING_MIGRATED, false); 517 mSetKeyguardDisabledFeaturesMigrated = 518 Flags.setKeyguardDisabledFeaturesCoexistence() 519 && parser.getAttributeBoolean(null, 520 ATTR_SET_KEYGUARD_DISABLED_FEATURES_MIGRATED, false); 521 break; 522 default: 523 Slog.e(TAG, "Unexpected tag: " + tag); 524 return false; 525 526 } 527 return true; 528 } 529 } 530 531 private class ProfileOwnerReadWriter extends FileReadWriter { 532 private final int mUserId; 533 ProfileOwnerReadWriter(int userId)534 ProfileOwnerReadWriter(int userId) { 535 super(getProfileOwnerFile(userId)); 536 mUserId = userId; 537 } 538 539 @Override shouldWrite()540 boolean shouldWrite() { 541 return mProfileOwners.get(mUserId) != null; 542 } 543 544 @Override writeInner(TypedXmlSerializer out)545 void writeInner(TypedXmlSerializer out) throws IOException { 546 final OwnerInfo profileOwner = mProfileOwners.get(mUserId); 547 if (profileOwner != null) { 548 profileOwner.writeToXml(out, TAG_PROFILE_OWNER); 549 } 550 } 551 552 @Override readInner(TypedXmlPullParser parser, int depth, String tag)553 boolean readInner(TypedXmlPullParser parser, int depth, String tag) { 554 if (depth > 2) { 555 return true; // Ignore 556 } 557 switch (tag) { 558 case TAG_PROFILE_OWNER: 559 mProfileOwners.put(mUserId, OwnerInfo.readFromXml(parser)); 560 break; 561 default: 562 Slog.e(TAG, "Unexpected tag: " + tag); 563 return false; 564 565 } 566 return true; 567 } 568 } 569 570 static class OwnerInfo { 571 public final String packageName; 572 public final ComponentName admin; 573 public String remoteBugreportUri; 574 public String remoteBugreportHash; 575 public boolean isOrganizationOwnedDevice; 576 OwnerInfo(ComponentName admin, String remoteBugreportUri, String remoteBugreportHash, boolean isOrganizationOwnedDevice)577 OwnerInfo(ComponentName admin, String remoteBugreportUri, 578 String remoteBugreportHash, boolean isOrganizationOwnedDevice) { 579 this.admin = admin; 580 this.packageName = admin.getPackageName(); 581 this.remoteBugreportUri = remoteBugreportUri; 582 this.remoteBugreportHash = remoteBugreportHash; 583 this.isOrganizationOwnedDevice = isOrganizationOwnedDevice; 584 } 585 writeToXml(TypedXmlSerializer out, String tag)586 public void writeToXml(TypedXmlSerializer out, String tag) throws IOException { 587 out.startTag(null, tag); 588 if (admin != null) { 589 out.attribute(null, ATTR_COMPONENT_NAME, admin.flattenToString()); 590 } 591 if (remoteBugreportUri != null) { 592 out.attribute(null, ATTR_REMOTE_BUGREPORT_URI, remoteBugreportUri); 593 } 594 if (remoteBugreportHash != null) { 595 out.attribute(null, ATTR_REMOTE_BUGREPORT_HASH, remoteBugreportHash); 596 } 597 if (isOrganizationOwnedDevice) { 598 out.attributeBoolean( 599 null, ATTR_PROFILE_OWNER_OF_ORG_OWNED_DEVICE, isOrganizationOwnedDevice); 600 } 601 out.endTag(null, tag); 602 } 603 readFromXml(TypedXmlPullParser parser)604 public static OwnerInfo readFromXml(TypedXmlPullParser parser) { 605 final String componentName = parser.getAttributeValue(null, ATTR_COMPONENT_NAME); 606 final String remoteBugreportUri = 607 parser.getAttributeValue(null, ATTR_REMOTE_BUGREPORT_URI); 608 final String remoteBugreportHash = 609 parser.getAttributeValue(null, ATTR_REMOTE_BUGREPORT_HASH); 610 final String canAccessDeviceIdsStr = 611 parser.getAttributeValue(null, ATTR_CAN_ACCESS_DEVICE_IDS); 612 final boolean canAccessDeviceIds = "true".equals(canAccessDeviceIdsStr); 613 final String isOrgOwnedDeviceStr = 614 parser.getAttributeValue(null, ATTR_PROFILE_OWNER_OF_ORG_OWNED_DEVICE); 615 final boolean isOrgOwnedDevice = 616 "true".equals(isOrgOwnedDeviceStr) | canAccessDeviceIds; 617 618 if (componentName == null) { 619 Slog.e(TAG, "Owner component not found"); 620 return null; 621 } 622 final ComponentName admin = ComponentName.unflattenFromString(componentName); 623 if (admin == null) { 624 Slog.e(TAG, "Owner component not parsable: " + componentName); 625 return null; 626 } 627 628 return new OwnerInfo(admin, remoteBugreportUri, remoteBugreportHash, isOrgOwnedDevice); 629 } 630 dump(IndentingPrintWriter pw)631 public void dump(IndentingPrintWriter pw) { 632 pw.println("admin=" + admin); 633 pw.println("package=" + packageName); 634 pw.println("isOrganizationOwnedDevice=" + isOrganizationOwnedDevice); 635 } 636 } 637 } 638