Extract OwnersData from Owners.
This change is intended to allow processing owners data during policy version upgrade. Owners currently has a lot of side effects like calls to other services, which doesn't allow it to be used as is. This change extracts "pure" data object from Onwers, which just holds the values and knows how to serialize/deserialize itself, which can be used for upgrade. Bug: 218639412 Test: atest com.android.server.devicepolicy Change-Id: I7a79cafee4ff4437c55bb21d65adeb6815da2d0b
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,583 @@
|
||||
/*
|
||||
* Copyright (C) 2022 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.android.server.devicepolicy;
|
||||
|
||||
import static android.app.admin.DevicePolicyManager.DEVICE_OWNER_TYPE_DEFAULT;
|
||||
|
||||
import android.annotation.Nullable;
|
||||
import android.app.admin.SystemUpdateInfo;
|
||||
import android.app.admin.SystemUpdatePolicy;
|
||||
import android.content.ComponentName;
|
||||
import android.os.Environment;
|
||||
import android.os.UserHandle;
|
||||
import android.util.ArrayMap;
|
||||
import android.util.AtomicFile;
|
||||
import android.util.IndentingPrintWriter;
|
||||
import android.util.Log;
|
||||
import android.util.Slog;
|
||||
import android.util.TypedXmlPullParser;
|
||||
import android.util.TypedXmlSerializer;
|
||||
import android.util.Xml;
|
||||
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
|
||||
import libcore.io.IoUtils;
|
||||
|
||||
import org.xmlpull.v1.XmlPullParserException;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.time.LocalDate;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
class OwnersData {
|
||||
private static final String TAG = "DevicePolicyManagerService";
|
||||
|
||||
private static final boolean DEBUG = false; // DO NOT SUBMIT WITH TRUE
|
||||
|
||||
// XML storing device owner info, system update policy and pending OTA update information.
|
||||
private static final String DEVICE_OWNER_XML = "device_owner_2.xml";
|
||||
private static final String PROFILE_OWNER_XML = "profile_owner.xml";
|
||||
|
||||
private static final String TAG_ROOT = "root";
|
||||
private static final String TAG_DEVICE_OWNER = "device-owner";
|
||||
private static final String TAG_SYSTEM_UPDATE_POLICY = "system-update-policy";
|
||||
private static final String TAG_FREEZE_PERIOD_RECORD = "freeze-record";
|
||||
private static final String TAG_PENDING_OTA_INFO = "pending-ota-info";
|
||||
private static final String TAG_PROFILE_OWNER = "profile-owner";
|
||||
// Holds "context" for device-owner, this must not be show up before device-owner.
|
||||
private static final String TAG_DEVICE_OWNER_CONTEXT = "device-owner-context";
|
||||
private static final String TAG_DEVICE_OWNER_TYPE = "device-owner-type";
|
||||
private static final String TAG_DEVICE_OWNER_PROTECTED_PACKAGES =
|
||||
"device-owner-protected-packages";
|
||||
|
||||
private static final String ATTR_NAME = "name";
|
||||
private static final String ATTR_PACKAGE = "package";
|
||||
private static final String ATTR_COMPONENT_NAME = "component";
|
||||
private static final String ATTR_SIZE = "size";
|
||||
private static final String ATTR_REMOTE_BUGREPORT_URI = "remoteBugreportUri";
|
||||
private static final String ATTR_REMOTE_BUGREPORT_HASH = "remoteBugreportHash";
|
||||
private static final String ATTR_USERID = "userId";
|
||||
private static final String ATTR_FREEZE_RECORD_START = "start";
|
||||
private static final String ATTR_FREEZE_RECORD_END = "end";
|
||||
// Legacy attribute, its presence would mean the profile owner associated with it is
|
||||
// managing a profile on an organization-owned device.
|
||||
private static final String ATTR_CAN_ACCESS_DEVICE_IDS = "canAccessDeviceIds";
|
||||
// New attribute for profile owner of organization-owned device.
|
||||
private static final String ATTR_PROFILE_OWNER_OF_ORG_OWNED_DEVICE =
|
||||
"isPoOrganizationOwnedDevice";
|
||||
private static final String ATTR_DEVICE_OWNER_TYPE_VALUE = "value";
|
||||
|
||||
// Internal state for the device owner package.
|
||||
OwnerInfo mDeviceOwner;
|
||||
int mDeviceOwnerUserId = UserHandle.USER_NULL;
|
||||
|
||||
// Device owner type for a managed device.
|
||||
final ArrayMap<String, Integer> mDeviceOwnerTypes = new ArrayMap<>();
|
||||
|
||||
final ArrayMap<String, List<String>> mDeviceOwnerProtectedPackages = new ArrayMap<>();
|
||||
|
||||
|
||||
// Internal state for the profile owner packages.
|
||||
final ArrayMap<Integer, OwnerInfo> mProfileOwners = new ArrayMap<>();
|
||||
|
||||
// Local system update policy controllable by device owner.
|
||||
SystemUpdatePolicy mSystemUpdatePolicy;
|
||||
LocalDate mSystemUpdateFreezeStart;
|
||||
LocalDate mSystemUpdateFreezeEnd;
|
||||
|
||||
// Pending OTA info if there is one.
|
||||
@Nullable
|
||||
SystemUpdateInfo mSystemUpdateInfo;
|
||||
private final Injector mInjector;
|
||||
|
||||
OwnersData(Injector injector) {
|
||||
mInjector = injector;
|
||||
}
|
||||
|
||||
void load(int[] allUsers) {
|
||||
new DeviceOwnerReadWriter().readFromFileLocked();
|
||||
|
||||
for (int userId : allUsers) {
|
||||
new ProfileOwnerReadWriter(userId).readFromFileLocked();
|
||||
}
|
||||
|
||||
OwnerInfo profileOwner = mProfileOwners.get(mDeviceOwnerUserId);
|
||||
ComponentName admin = profileOwner != null ? profileOwner.admin : null;
|
||||
if (mDeviceOwner != null && admin != null) {
|
||||
Slog.w(TAG, String.format("User %d has both DO and PO, which is not supported",
|
||||
mDeviceOwnerUserId));
|
||||
}
|
||||
}
|
||||
|
||||
void writeDeviceOwner() {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "Writing to device owner file");
|
||||
}
|
||||
new DeviceOwnerReadWriter().writeToFileLocked();
|
||||
}
|
||||
|
||||
void writeProfileOwner(int userId) {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "Writing to profile owner file for user " + userId);
|
||||
}
|
||||
new ProfileOwnerReadWriter(userId).writeToFileLocked();
|
||||
}
|
||||
|
||||
void dump(IndentingPrintWriter pw) {
|
||||
boolean needBlank = false;
|
||||
if (mDeviceOwner != null) {
|
||||
pw.println("Device Owner: ");
|
||||
pw.increaseIndent();
|
||||
mDeviceOwner.dump(pw);
|
||||
pw.println("User ID: " + mDeviceOwnerUserId);
|
||||
pw.decreaseIndent();
|
||||
needBlank = true;
|
||||
}
|
||||
if (mSystemUpdatePolicy != null) {
|
||||
if (needBlank) {
|
||||
pw.println();
|
||||
}
|
||||
pw.println("System Update Policy: " + mSystemUpdatePolicy);
|
||||
needBlank = true;
|
||||
}
|
||||
if (mProfileOwners != null) {
|
||||
for (Map.Entry<Integer, OwnerInfo> entry : mProfileOwners.entrySet()) {
|
||||
if (needBlank) {
|
||||
pw.println();
|
||||
}
|
||||
pw.println("Profile Owner (User " + entry.getKey() + "): ");
|
||||
pw.increaseIndent();
|
||||
entry.getValue().dump(pw);
|
||||
pw.decreaseIndent();
|
||||
needBlank = true;
|
||||
}
|
||||
}
|
||||
if (mSystemUpdateInfo != null) {
|
||||
if (needBlank) {
|
||||
pw.println();
|
||||
}
|
||||
pw.println("Pending System Update: " + mSystemUpdateInfo);
|
||||
needBlank = true;
|
||||
}
|
||||
if (mSystemUpdateFreezeStart != null || mSystemUpdateFreezeEnd != null) {
|
||||
if (needBlank) {
|
||||
pw.println();
|
||||
}
|
||||
pw.println("System update freeze record: "
|
||||
+ getSystemUpdateFreezePeriodRecordAsString());
|
||||
needBlank = true;
|
||||
}
|
||||
}
|
||||
|
||||
String getSystemUpdateFreezePeriodRecordAsString() {
|
||||
StringBuilder freezePeriodRecord = new StringBuilder();
|
||||
freezePeriodRecord.append("start: ");
|
||||
if (mSystemUpdateFreezeStart != null) {
|
||||
freezePeriodRecord.append(mSystemUpdateFreezeStart.toString());
|
||||
} else {
|
||||
freezePeriodRecord.append("null");
|
||||
}
|
||||
freezePeriodRecord.append("; end: ");
|
||||
if (mSystemUpdateFreezeEnd != null) {
|
||||
freezePeriodRecord.append(mSystemUpdateFreezeEnd.toString());
|
||||
} else {
|
||||
freezePeriodRecord.append("null");
|
||||
}
|
||||
return freezePeriodRecord.toString();
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
File getDeviceOwnerFile() {
|
||||
return new File(mInjector.environmentGetDataSystemDirectory(), DEVICE_OWNER_XML);
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
File getProfileOwnerFile(int userId) {
|
||||
return new File(mInjector.environmentGetUserSystemDirectory(userId), PROFILE_OWNER_XML);
|
||||
}
|
||||
|
||||
private abstract static class FileReadWriter {
|
||||
private final File mFile;
|
||||
|
||||
protected FileReadWriter(File file) {
|
||||
mFile = file;
|
||||
}
|
||||
|
||||
abstract boolean shouldWrite();
|
||||
|
||||
void writeToFileLocked() {
|
||||
if (!shouldWrite()) {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "No need to write to " + mFile);
|
||||
}
|
||||
// No contents, remove the file.
|
||||
if (mFile.exists()) {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "Deleting existing " + mFile);
|
||||
}
|
||||
if (!mFile.delete()) {
|
||||
Slog.e(TAG, "Failed to remove " + mFile.getPath());
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "Writing to " + mFile);
|
||||
}
|
||||
|
||||
final AtomicFile f = new AtomicFile(mFile);
|
||||
FileOutputStream outputStream = null;
|
||||
try {
|
||||
outputStream = f.startWrite();
|
||||
final TypedXmlSerializer out = Xml.resolveSerializer(outputStream);
|
||||
|
||||
// Root tag
|
||||
out.startDocument(null, true);
|
||||
out.startTag(null, TAG_ROOT);
|
||||
|
||||
// Actual content
|
||||
writeInner(out);
|
||||
|
||||
// Close root
|
||||
out.endTag(null, TAG_ROOT);
|
||||
out.endDocument();
|
||||
out.flush();
|
||||
|
||||
// Commit the content.
|
||||
f.finishWrite(outputStream);
|
||||
outputStream = null;
|
||||
|
||||
} catch (IOException e) {
|
||||
Slog.e(TAG, "Exception when writing", e);
|
||||
if (outputStream != null) {
|
||||
f.failWrite(outputStream);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void readFromFileLocked() {
|
||||
if (!mFile.exists()) {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "" + mFile + " doesn't exist");
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "Reading from " + mFile);
|
||||
}
|
||||
final AtomicFile f = new AtomicFile(mFile);
|
||||
InputStream input = null;
|
||||
try {
|
||||
input = f.openRead();
|
||||
final TypedXmlPullParser parser = Xml.resolvePullParser(input);
|
||||
|
||||
int type;
|
||||
int depth = 0;
|
||||
while ((type = parser.next()) != TypedXmlPullParser.END_DOCUMENT) {
|
||||
switch (type) {
|
||||
case TypedXmlPullParser.START_TAG:
|
||||
depth++;
|
||||
break;
|
||||
case TypedXmlPullParser.END_TAG:
|
||||
depth--;
|
||||
// fallthrough
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
// Check the root tag
|
||||
final String tag = parser.getName();
|
||||
if (depth == 1) {
|
||||
if (!TAG_ROOT.equals(tag)) {
|
||||
Slog.e(TAG, "Invalid root tag: " + tag);
|
||||
return;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
// readInner() will only see START_TAG at depth >= 2.
|
||||
if (!readInner(parser, depth, tag)) {
|
||||
return; // Error
|
||||
}
|
||||
}
|
||||
} catch (XmlPullParserException | IOException e) {
|
||||
Slog.e(TAG, "Error parsing owners information file", e);
|
||||
} finally {
|
||||
IoUtils.closeQuietly(input);
|
||||
}
|
||||
}
|
||||
|
||||
abstract void writeInner(TypedXmlSerializer out) throws IOException;
|
||||
|
||||
abstract boolean readInner(TypedXmlPullParser parser, int depth, String tag);
|
||||
}
|
||||
|
||||
private class DeviceOwnerReadWriter extends FileReadWriter {
|
||||
|
||||
protected DeviceOwnerReadWriter() {
|
||||
super(getDeviceOwnerFile());
|
||||
}
|
||||
|
||||
@Override
|
||||
boolean shouldWrite() {
|
||||
return (mDeviceOwner != null) || (mSystemUpdatePolicy != null)
|
||||
|| (mSystemUpdateInfo != null);
|
||||
}
|
||||
|
||||
@Override
|
||||
void writeInner(TypedXmlSerializer out) throws IOException {
|
||||
if (mDeviceOwner != null) {
|
||||
mDeviceOwner.writeToXml(out, TAG_DEVICE_OWNER);
|
||||
out.startTag(null, TAG_DEVICE_OWNER_CONTEXT);
|
||||
out.attributeInt(null, ATTR_USERID, mDeviceOwnerUserId);
|
||||
out.endTag(null, TAG_DEVICE_OWNER_CONTEXT);
|
||||
|
||||
}
|
||||
|
||||
if (!mDeviceOwnerTypes.isEmpty()) {
|
||||
for (ArrayMap.Entry<String, Integer> entry : mDeviceOwnerTypes.entrySet()) {
|
||||
out.startTag(null, TAG_DEVICE_OWNER_TYPE);
|
||||
out.attribute(null, ATTR_PACKAGE, entry.getKey());
|
||||
out.attributeInt(null, ATTR_DEVICE_OWNER_TYPE_VALUE, entry.getValue());
|
||||
out.endTag(null, TAG_DEVICE_OWNER_TYPE);
|
||||
}
|
||||
}
|
||||
|
||||
if (!mDeviceOwnerProtectedPackages.isEmpty()) {
|
||||
for (ArrayMap.Entry<String, List<String>> entry :
|
||||
mDeviceOwnerProtectedPackages.entrySet()) {
|
||||
List<String> protectedPackages = entry.getValue();
|
||||
|
||||
out.startTag(null, TAG_DEVICE_OWNER_PROTECTED_PACKAGES);
|
||||
out.attribute(null, ATTR_PACKAGE, entry.getKey());
|
||||
out.attributeInt(null, ATTR_SIZE, protectedPackages.size());
|
||||
for (int i = 0, size = protectedPackages.size(); i < size; i++) {
|
||||
out.attribute(null, ATTR_NAME + i, protectedPackages.get(i));
|
||||
}
|
||||
out.endTag(null, TAG_DEVICE_OWNER_PROTECTED_PACKAGES);
|
||||
}
|
||||
}
|
||||
|
||||
if (mSystemUpdatePolicy != null) {
|
||||
out.startTag(null, TAG_SYSTEM_UPDATE_POLICY);
|
||||
mSystemUpdatePolicy.saveToXml(out);
|
||||
out.endTag(null, TAG_SYSTEM_UPDATE_POLICY);
|
||||
}
|
||||
|
||||
if (mSystemUpdateInfo != null) {
|
||||
mSystemUpdateInfo.writeToXml(out, TAG_PENDING_OTA_INFO);
|
||||
}
|
||||
|
||||
if (mSystemUpdateFreezeStart != null || mSystemUpdateFreezeEnd != null) {
|
||||
out.startTag(null, TAG_FREEZE_PERIOD_RECORD);
|
||||
if (mSystemUpdateFreezeStart != null) {
|
||||
out.attribute(
|
||||
null, ATTR_FREEZE_RECORD_START, mSystemUpdateFreezeStart.toString());
|
||||
}
|
||||
if (mSystemUpdateFreezeEnd != null) {
|
||||
out.attribute(null, ATTR_FREEZE_RECORD_END, mSystemUpdateFreezeEnd.toString());
|
||||
}
|
||||
out.endTag(null, TAG_FREEZE_PERIOD_RECORD);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
boolean readInner(TypedXmlPullParser parser, int depth, String tag) {
|
||||
if (depth > 2) {
|
||||
return true; // Ignore
|
||||
}
|
||||
switch (tag) {
|
||||
case TAG_DEVICE_OWNER:
|
||||
mDeviceOwner = OwnerInfo.readFromXml(parser);
|
||||
mDeviceOwnerUserId = UserHandle.USER_SYSTEM; // Set default
|
||||
break;
|
||||
case TAG_DEVICE_OWNER_CONTEXT: {
|
||||
mDeviceOwnerUserId =
|
||||
parser.getAttributeInt(null, ATTR_USERID, mDeviceOwnerUserId);
|
||||
break;
|
||||
}
|
||||
case TAG_SYSTEM_UPDATE_POLICY:
|
||||
mSystemUpdatePolicy = SystemUpdatePolicy.restoreFromXml(parser);
|
||||
break;
|
||||
case TAG_PENDING_OTA_INFO:
|
||||
mSystemUpdateInfo = SystemUpdateInfo.readFromXml(parser);
|
||||
break;
|
||||
case TAG_FREEZE_PERIOD_RECORD:
|
||||
String startDate = parser.getAttributeValue(null, ATTR_FREEZE_RECORD_START);
|
||||
String endDate = parser.getAttributeValue(null, ATTR_FREEZE_RECORD_END);
|
||||
if (startDate != null && endDate != null) {
|
||||
mSystemUpdateFreezeStart = LocalDate.parse(startDate);
|
||||
mSystemUpdateFreezeEnd = LocalDate.parse(endDate);
|
||||
if (mSystemUpdateFreezeStart.isAfter(mSystemUpdateFreezeEnd)) {
|
||||
Slog.e(TAG, "Invalid system update freeze record loaded");
|
||||
mSystemUpdateFreezeStart = null;
|
||||
mSystemUpdateFreezeEnd = null;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case TAG_DEVICE_OWNER_TYPE:
|
||||
String packageName = parser.getAttributeValue(null, ATTR_PACKAGE);
|
||||
int deviceOwnerType = parser.getAttributeInt(
|
||||
null, ATTR_DEVICE_OWNER_TYPE_VALUE, DEVICE_OWNER_TYPE_DEFAULT);
|
||||
mDeviceOwnerTypes.put(packageName, deviceOwnerType);
|
||||
break;
|
||||
case TAG_DEVICE_OWNER_PROTECTED_PACKAGES:
|
||||
packageName = parser.getAttributeValue(null, ATTR_PACKAGE);
|
||||
int protectedPackagesSize = parser.getAttributeInt(null, ATTR_SIZE, 0);
|
||||
List<String> protectedPackages = new ArrayList<>();
|
||||
for (int i = 0; i < protectedPackagesSize; i++) {
|
||||
protectedPackages.add(parser.getAttributeValue(null, ATTR_NAME + i));
|
||||
}
|
||||
mDeviceOwnerProtectedPackages.put(packageName, protectedPackages);
|
||||
break;
|
||||
default:
|
||||
Slog.e(TAG, "Unexpected tag: " + tag);
|
||||
return false;
|
||||
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
private class ProfileOwnerReadWriter extends FileReadWriter {
|
||||
private final int mUserId;
|
||||
|
||||
ProfileOwnerReadWriter(int userId) {
|
||||
super(getProfileOwnerFile(userId));
|
||||
mUserId = userId;
|
||||
}
|
||||
|
||||
@Override
|
||||
boolean shouldWrite() {
|
||||
return mProfileOwners.get(mUserId) != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
void writeInner(TypedXmlSerializer out) throws IOException {
|
||||
final OwnerInfo profileOwner = mProfileOwners.get(mUserId);
|
||||
if (profileOwner != null) {
|
||||
profileOwner.writeToXml(out, TAG_PROFILE_OWNER);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
boolean readInner(TypedXmlPullParser parser, int depth, String tag) {
|
||||
if (depth > 2) {
|
||||
return true; // Ignore
|
||||
}
|
||||
switch (tag) {
|
||||
case TAG_PROFILE_OWNER:
|
||||
mProfileOwners.put(mUserId, OwnerInfo.readFromXml(parser));
|
||||
break;
|
||||
default:
|
||||
Slog.e(TAG, "Unexpected tag: " + tag);
|
||||
return false;
|
||||
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
static class OwnerInfo {
|
||||
public final String name;
|
||||
public final String packageName;
|
||||
public final ComponentName admin;
|
||||
public String remoteBugreportUri;
|
||||
public String remoteBugreportHash;
|
||||
public boolean isOrganizationOwnedDevice;
|
||||
|
||||
OwnerInfo(String name, ComponentName admin, String remoteBugreportUri,
|
||||
String remoteBugreportHash, boolean isOrganizationOwnedDevice) {
|
||||
this.name = name;
|
||||
this.admin = admin;
|
||||
this.packageName = admin.getPackageName();
|
||||
this.remoteBugreportUri = remoteBugreportUri;
|
||||
this.remoteBugreportHash = remoteBugreportHash;
|
||||
this.isOrganizationOwnedDevice = isOrganizationOwnedDevice;
|
||||
}
|
||||
|
||||
public void writeToXml(TypedXmlSerializer out, String tag) throws IOException {
|
||||
out.startTag(null, tag);
|
||||
if (name != null) {
|
||||
out.attribute(null, ATTR_NAME, name);
|
||||
}
|
||||
if (admin != null) {
|
||||
out.attribute(null, ATTR_COMPONENT_NAME, admin.flattenToString());
|
||||
}
|
||||
if (remoteBugreportUri != null) {
|
||||
out.attribute(null, ATTR_REMOTE_BUGREPORT_URI, remoteBugreportUri);
|
||||
}
|
||||
if (remoteBugreportHash != null) {
|
||||
out.attribute(null, ATTR_REMOTE_BUGREPORT_HASH, remoteBugreportHash);
|
||||
}
|
||||
if (isOrganizationOwnedDevice) {
|
||||
out.attributeBoolean(
|
||||
null, ATTR_PROFILE_OWNER_OF_ORG_OWNED_DEVICE, isOrganizationOwnedDevice);
|
||||
}
|
||||
out.endTag(null, tag);
|
||||
}
|
||||
|
||||
public static OwnerInfo readFromXml(TypedXmlPullParser parser) {
|
||||
final String name = parser.getAttributeValue(null, ATTR_NAME);
|
||||
final String componentName = parser.getAttributeValue(null, ATTR_COMPONENT_NAME);
|
||||
final String remoteBugreportUri =
|
||||
parser.getAttributeValue(null, ATTR_REMOTE_BUGREPORT_URI);
|
||||
final String remoteBugreportHash =
|
||||
parser.getAttributeValue(null, ATTR_REMOTE_BUGREPORT_HASH);
|
||||
final String canAccessDeviceIdsStr =
|
||||
parser.getAttributeValue(null, ATTR_CAN_ACCESS_DEVICE_IDS);
|
||||
final boolean canAccessDeviceIds = "true".equals(canAccessDeviceIdsStr);
|
||||
final String isOrgOwnedDeviceStr =
|
||||
parser.getAttributeValue(null, ATTR_PROFILE_OWNER_OF_ORG_OWNED_DEVICE);
|
||||
final boolean isOrgOwnedDevice =
|
||||
"true".equals(isOrgOwnedDeviceStr) | canAccessDeviceIds;
|
||||
|
||||
if (componentName == null) {
|
||||
Slog.e(TAG, "Owner component not found");
|
||||
return null;
|
||||
}
|
||||
final ComponentName admin = ComponentName.unflattenFromString(componentName);
|
||||
if (admin == null) {
|
||||
Slog.e(TAG, "Owner component not parsable: " + componentName);
|
||||
return null;
|
||||
}
|
||||
|
||||
return new OwnerInfo(
|
||||
name, admin, remoteBugreportUri, remoteBugreportHash, isOrgOwnedDevice);
|
||||
}
|
||||
|
||||
public void dump(IndentingPrintWriter pw) {
|
||||
pw.println("admin=" + admin);
|
||||
pw.println("name=" + name);
|
||||
pw.println("package=" + packageName);
|
||||
pw.println("isOrganizationOwnedDevice=" + isOrganizationOwnedDevice);
|
||||
}
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
static class Injector {
|
||||
File environmentGetDataSystemDirectory() {
|
||||
return Environment.getDataSystemDirectory();
|
||||
}
|
||||
|
||||
File environmentGetUserSystemDirectory(int userId) {
|
||||
return Environment.getUserSystemDirectory(userId);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -75,7 +75,7 @@ public class DevicePolicyManagerServiceTestable extends DevicePolicyManagerServi
|
||||
services.activityManagerInternal, new MockInjector(services));
|
||||
}
|
||||
|
||||
static class MockInjector extends Injector {
|
||||
static class MockInjector extends OwnersData.Injector {
|
||||
private final MockSystemServices mServices;
|
||||
|
||||
private MockInjector(MockSystemServices services) {
|
||||
|
||||
Reference in New Issue
Block a user