blob: 26c442dc1f47673ed6e1255f8856a43a8382675f [file] [log] [blame]
/*
* Copyright (C) 2020 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 android.annotation.NonNull;
import android.annotation.UserIdInt;
import android.app.admin.DeviceAdminInfo;
import android.app.admin.DevicePolicyManager;
import android.content.ComponentName;
import android.os.FileUtils;
import android.os.PersistableBundle;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.DebugUtils;
import android.util.IndentingPrintWriter;
import android.util.TypedXmlPullParser;
import android.util.TypedXmlSerializer;
import android.util.Xml;
import com.android.internal.util.JournaledFile;
import com.android.internal.util.XmlUtils;
import com.android.server.utils.Slogf;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.function.Function;
class DevicePolicyData {
private static final String TAG_ACCEPTED_CA_CERTIFICATES = "accepted-ca-certificate";
private static final String TAG_LOCK_TASK_COMPONENTS = "lock-task-component";
private static final String TAG_LOCK_TASK_FEATURES = "lock-task-features";
private static final String TAG_STATUS_BAR = "statusbar";
private static final String TAG_APPS_SUSPENDED = "apps-suspended";
private static final String TAG_SECONDARY_LOCK_SCREEN = "secondary-lock-screen";
private static final String TAG_DO_NOT_ASK_CREDENTIALS_ON_BOOT =
"do-not-ask-credentials-on-boot";
private static final String TAG_AFFILIATION_ID = "affiliation-id";
private static final String TAG_LAST_SECURITY_LOG_RETRIEVAL = "last-security-log-retrieval";
private static final String TAG_LAST_BUG_REPORT_REQUEST = "last-bug-report-request";
private static final String TAG_LAST_NETWORK_LOG_RETRIEVAL = "last-network-log-retrieval";
private static final String TAG_ADMIN_BROADCAST_PENDING = "admin-broadcast-pending";
private static final String TAG_CURRENT_INPUT_METHOD_SET = "current-ime-set";
private static final String TAG_OWNER_INSTALLED_CA_CERT = "owner-installed-ca-cert";
private static final String TAG_INITIALIZATION_BUNDLE = "initialization-bundle";
private static final String TAG_PASSWORD_VALIDITY = "password-validity";
private static final String TAG_PASSWORD_TOKEN_HANDLE = "password-token";
private static final String TAG_PROTECTED_PACKAGES = "protected-packages";
private static final String ATTR_VALUE = "value";
private static final String ATTR_ALIAS = "alias";
private static final String ATTR_ID = "id";
private static final String ATTR_PERMISSION_PROVIDER = "permission-provider";
private static final String ATTR_NAME = "name";
private static final String ATTR_DISABLED = "disabled";
private static final String ATTR_SETUP_COMPLETE = "setup-complete";
private static final String ATTR_PROVISIONING_STATE = "provisioning-state";
private static final String ATTR_PERMISSION_POLICY = "permission-policy";
private static final String ATTR_DEVICE_PROVISIONING_CONFIG_APPLIED =
"device-provisioning-config-applied";
private static final String ATTR_DEVICE_PAIRED = "device-paired";
private static final String ATTR_NEW_USER_DISCLAIMER = "new-user-disclaimer";
// Values of ATTR_NEW_USER_DISCLAIMER
static final String NEW_USER_DISCLAIMER_SHOWN = "shown";
static final String NEW_USER_DISCLAIMER_NOT_NEEDED = "not_needed";
static final String NEW_USER_DISCLAIMER_NEEDED = "needed";
private static final String ATTR_FACTORY_RESET_FLAGS = "factory-reset-flags";
private static final String ATTR_FACTORY_RESET_REASON = "factory-reset-reason";
// NOTE: must be public because of DebugUtils.flagsToString()
public static final int FACTORY_RESET_FLAG_ON_BOOT = 1;
public static final int FACTORY_RESET_FLAG_WIPE_EXTERNAL_STORAGE = 2;
public static final int FACTORY_RESET_FLAG_WIPE_EUICC = 4;
public static final int FACTORY_RESET_FLAG_WIPE_FACTORY_RESET_PROTECTION = 8;
private static final String TAG = DevicePolicyManagerService.LOG_TAG;
private static final boolean VERBOSE_LOG = false; // DO NOT SUBMIT WITH TRUE
int mFailedPasswordAttempts = 0;
boolean mPasswordValidAtLastCheckpoint = true;
final @UserIdInt int mUserId;
int mPasswordOwner = -1;
long mLastMaximumTimeToLock = -1;
boolean mUserSetupComplete = false;
boolean mPaired = false;
int mUserProvisioningState;
int mPermissionPolicy;
int mFactoryResetFlags;
String mFactoryResetReason;
boolean mDeviceProvisioningConfigApplied = false;
final ArrayMap<ComponentName, ActiveAdmin> mAdminMap = new ArrayMap<>();
final ArrayList<ActiveAdmin> mAdminList = new ArrayList<>();
final ArrayList<ComponentName> mRemovingAdmins = new ArrayList<>();
// TODO(b/35385311): Keep track of metadata in TrustedCertificateStore instead.
final ArraySet<String> mAcceptedCaCertificates = new ArraySet<>();
// This is the list of component allowed to start lock task mode.
List<String> mLockTaskPackages = new ArrayList<>();
// List of packages protected by device owner
List<String> mUserControlDisabledPackages = new ArrayList<>();
// Bitfield of feature flags to be enabled during LockTask mode.
// We default on the power button menu, in order to be consistent with pre-P behaviour.
int mLockTaskFeatures = DevicePolicyManager.LOCK_TASK_FEATURE_GLOBAL_ACTIONS;
boolean mStatusBarDisabled = false;
ComponentName mRestrictionsProvider;
// Map of delegate package to delegation scopes
final ArrayMap<String, List<String>> mDelegationMap = new ArrayMap<>();
boolean mDoNotAskCredentialsOnBoot = false;
Set<String> mAffiliationIds = new ArraySet<>();
long mLastSecurityLogRetrievalTime = -1;
long mLastBugReportRequestTime = -1;
long mLastNetworkLogsRetrievalTime = -1;
boolean mCurrentInputMethodSet = false;
boolean mSecondaryLockscreenEnabled = false;
// TODO(b/35385311): Keep track of metadata in TrustedCertificateStore instead.
Set<String> mOwnerInstalledCaCerts = new ArraySet<>();
// Used for initialization of users created by createAndManageUser.
boolean mAdminBroadcastPending = false;
PersistableBundle mInitBundle = null;
long mPasswordTokenHandle = 0;
// Whether user's apps are suspended. This flag should only be written AFTER all the needed
// apps were suspended or unsuspended.
boolean mAppsSuspended = false;
// Whether it's necessary to show a disclaimer (that the device is managed) after the user
// starts.
String mNewUserDisclaimer = NEW_USER_DISCLAIMER_NOT_NEEDED;
DevicePolicyData(@UserIdInt int userId) {
mUserId = userId;
}
/**
* Serializes DevicePolicyData object as XML.
*/
static boolean store(DevicePolicyData policyData, JournaledFile file, boolean isFdeDevice) {
FileOutputStream stream = null;
File chooseForWrite = null;
try {
chooseForWrite = file.chooseForWrite();
if (VERBOSE_LOG) {
Slogf.v(TAG, "Storing data for user %d on %s ", policyData.mUserId, chooseForWrite);
}
stream = new FileOutputStream(chooseForWrite, false);
TypedXmlSerializer out = Xml.resolveSerializer(stream);
out.startDocument(null, true);
out.startTag(null, "policies");
if (policyData.mRestrictionsProvider != null) {
out.attribute(null, ATTR_PERMISSION_PROVIDER,
policyData.mRestrictionsProvider.flattenToString());
}
if (policyData.mUserSetupComplete) {
if (VERBOSE_LOG) Slogf.v(TAG, "setting %s to true", ATTR_SETUP_COMPLETE);
out.attributeBoolean(null, ATTR_SETUP_COMPLETE, true);
}
if (policyData.mPaired) {
out.attributeBoolean(null, ATTR_DEVICE_PAIRED, true);
}
if (policyData.mDeviceProvisioningConfigApplied) {
out.attributeBoolean(null, ATTR_DEVICE_PROVISIONING_CONFIG_APPLIED, true);
}
if (policyData.mUserProvisioningState != DevicePolicyManager.STATE_USER_UNMANAGED) {
out.attributeInt(null, ATTR_PROVISIONING_STATE, policyData.mUserProvisioningState);
}
if (policyData.mPermissionPolicy != DevicePolicyManager.PERMISSION_POLICY_PROMPT) {
out.attributeInt(null, ATTR_PERMISSION_POLICY, policyData.mPermissionPolicy);
}
if (NEW_USER_DISCLAIMER_NEEDED.equals(policyData.mNewUserDisclaimer)) {
out.attribute(null, ATTR_NEW_USER_DISCLAIMER, policyData.mNewUserDisclaimer);
}
if (policyData.mFactoryResetFlags != 0) {
if (VERBOSE_LOG) {
Slogf.v(TAG, "Storing factory reset flags for user %d: %s", policyData.mUserId,
factoryResetFlagsToString(policyData.mFactoryResetFlags));
}
out.attributeInt(null, ATTR_FACTORY_RESET_FLAGS, policyData.mFactoryResetFlags);
}
if (policyData.mFactoryResetReason != null) {
out.attribute(null, ATTR_FACTORY_RESET_REASON, policyData.mFactoryResetReason);
}
// Serialize delegations.
for (int i = 0; i < policyData.mDelegationMap.size(); ++i) {
final String delegatePackage = policyData.mDelegationMap.keyAt(i);
final List<String> scopes = policyData.mDelegationMap.valueAt(i);
// Every "delegation" tag serializes the information of one delegate-scope pair.
for (String scope : scopes) {
out.startTag(null, "delegation");
out.attribute(null, "delegatePackage", delegatePackage);
out.attribute(null, "scope", scope);
out.endTag(null, "delegation");
}
}
final int n = policyData.mAdminList.size();
for (int i = 0; i < n; i++) {
ActiveAdmin ap = policyData.mAdminList.get(i);
if (ap != null) {
out.startTag(null, "admin");
out.attribute(null, "name", ap.info.getComponent().flattenToString());
ap.writeToXml(out);
out.endTag(null, "admin");
}
}
if (policyData.mPasswordOwner >= 0) {
out.startTag(null, "password-owner");
out.attributeInt(null, "value", policyData.mPasswordOwner);
out.endTag(null, "password-owner");
}
if (policyData.mFailedPasswordAttempts != 0) {
out.startTag(null, "failed-password-attempts");
out.attributeInt(null, "value", policyData.mFailedPasswordAttempts);
out.endTag(null, "failed-password-attempts");
}
// For FDE devices only, we save this flag so we can report on password sufficiency
// before the user enters their password for the first time after a reboot. For
// security reasons, we don't want to store the full set of active password metrics.
if (isFdeDevice) {
out.startTag(null, TAG_PASSWORD_VALIDITY);
out.attributeBoolean(null, ATTR_VALUE, policyData.mPasswordValidAtLastCheckpoint);
out.endTag(null, TAG_PASSWORD_VALIDITY);
}
for (int i = 0; i < policyData.mAcceptedCaCertificates.size(); i++) {
out.startTag(null, TAG_ACCEPTED_CA_CERTIFICATES);
out.attribute(null, ATTR_NAME, policyData.mAcceptedCaCertificates.valueAt(i));
out.endTag(null, TAG_ACCEPTED_CA_CERTIFICATES);
}
for (int i = 0; i < policyData.mLockTaskPackages.size(); i++) {
String component = policyData.mLockTaskPackages.get(i);
out.startTag(null, TAG_LOCK_TASK_COMPONENTS);
out.attribute(null, "name", component);
out.endTag(null, TAG_LOCK_TASK_COMPONENTS);
}
if (policyData.mLockTaskFeatures != DevicePolicyManager.LOCK_TASK_FEATURE_NONE) {
out.startTag(null, TAG_LOCK_TASK_FEATURES);
out.attributeInt(null, ATTR_VALUE, policyData.mLockTaskFeatures);
out.endTag(null, TAG_LOCK_TASK_FEATURES);
}
if (policyData.mSecondaryLockscreenEnabled) {
out.startTag(null, TAG_SECONDARY_LOCK_SCREEN);
out.attributeBoolean(null, ATTR_VALUE, true);
out.endTag(null, TAG_SECONDARY_LOCK_SCREEN);
}
if (policyData.mStatusBarDisabled) {
out.startTag(null, TAG_STATUS_BAR);
out.attributeBoolean(null, ATTR_DISABLED, policyData.mStatusBarDisabled);
out.endTag(null, TAG_STATUS_BAR);
}
if (policyData.mDoNotAskCredentialsOnBoot) {
out.startTag(null, TAG_DO_NOT_ASK_CREDENTIALS_ON_BOOT);
out.endTag(null, TAG_DO_NOT_ASK_CREDENTIALS_ON_BOOT);
}
for (String id : policyData.mAffiliationIds) {
out.startTag(null, TAG_AFFILIATION_ID);
out.attribute(null, ATTR_ID, id);
out.endTag(null, TAG_AFFILIATION_ID);
}
if (policyData.mLastSecurityLogRetrievalTime >= 0) {
out.startTag(null, TAG_LAST_SECURITY_LOG_RETRIEVAL);
out.attributeLong(null, ATTR_VALUE, policyData.mLastSecurityLogRetrievalTime);
out.endTag(null, TAG_LAST_SECURITY_LOG_RETRIEVAL);
}
if (policyData.mLastBugReportRequestTime >= 0) {
out.startTag(null, TAG_LAST_BUG_REPORT_REQUEST);
out.attributeLong(null, ATTR_VALUE, policyData.mLastBugReportRequestTime);
out.endTag(null, TAG_LAST_BUG_REPORT_REQUEST);
}
if (policyData.mLastNetworkLogsRetrievalTime >= 0) {
out.startTag(null, TAG_LAST_NETWORK_LOG_RETRIEVAL);
out.attributeLong(null, ATTR_VALUE, policyData.mLastNetworkLogsRetrievalTime);
out.endTag(null, TAG_LAST_NETWORK_LOG_RETRIEVAL);
}
if (policyData.mAdminBroadcastPending) {
out.startTag(null, TAG_ADMIN_BROADCAST_PENDING);
out.attributeBoolean(null, ATTR_VALUE, policyData.mAdminBroadcastPending);
out.endTag(null, TAG_ADMIN_BROADCAST_PENDING);
}
if (policyData.mInitBundle != null) {
out.startTag(null, TAG_INITIALIZATION_BUNDLE);
policyData.mInitBundle.saveToXml(out);
out.endTag(null, TAG_INITIALIZATION_BUNDLE);
}
if (policyData.mPasswordTokenHandle != 0) {
out.startTag(null, TAG_PASSWORD_TOKEN_HANDLE);
out.attributeLong(null, ATTR_VALUE, policyData.mPasswordTokenHandle);
out.endTag(null, TAG_PASSWORD_TOKEN_HANDLE);
}
if (policyData.mCurrentInputMethodSet) {
out.startTag(null, TAG_CURRENT_INPUT_METHOD_SET);
out.endTag(null, TAG_CURRENT_INPUT_METHOD_SET);
}
for (final String cert : policyData.mOwnerInstalledCaCerts) {
out.startTag(null, TAG_OWNER_INSTALLED_CA_CERT);
out.attribute(null, ATTR_ALIAS, cert);
out.endTag(null, TAG_OWNER_INSTALLED_CA_CERT);
}
for (int i = 0, size = policyData.mUserControlDisabledPackages.size(); i < size; i++) {
String packageName = policyData.mUserControlDisabledPackages.get(i);
out.startTag(null, TAG_PROTECTED_PACKAGES);
out.attribute(null, ATTR_NAME, packageName);
out.endTag(null, TAG_PROTECTED_PACKAGES);
}
if (policyData.mAppsSuspended) {
out.startTag(null, TAG_APPS_SUSPENDED);
out.attributeBoolean(null, ATTR_VALUE, policyData.mAppsSuspended);
out.endTag(null, TAG_APPS_SUSPENDED);
}
out.endTag(null, "policies");
out.endDocument();
stream.flush();
FileUtils.sync(stream);
stream.close();
file.commit();
return true;
} catch (XmlPullParserException | IOException e) {
Slogf.w(TAG, e, "failed writing file %s", chooseForWrite);
try {
if (stream != null) {
stream.close();
}
} catch (IOException ex) {
// Ignore
}
file.rollback();
return false;
}
}
/**
* @param adminInfoSupplier function that queries DeviceAdminInfo from PackageManager
* @param ownerComponent device or profile owner component if any.
*/
static void load(DevicePolicyData policy, boolean isFdeDevice, JournaledFile journaledFile,
Function<ComponentName, DeviceAdminInfo> adminInfoSupplier,
ComponentName ownerComponent) {
FileInputStream stream = null;
File file = journaledFile.chooseForRead();
if (VERBOSE_LOG) Slogf.v(TAG, "Loading data for user %d from %s", policy.mUserId, file);
boolean needsRewrite = false;
try {
stream = new FileInputStream(file);
TypedXmlPullParser parser = Xml.resolvePullParser(stream);
int type;
while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
&& type != XmlPullParser.START_TAG) {
}
String tag = parser.getName();
if (!"policies".equals(tag)) {
throw new XmlPullParserException(
"Settings do not start with policies tag: found " + tag);
}
// Extract the permission provider component name if available
String permissionProvider = parser.getAttributeValue(null, ATTR_PERMISSION_PROVIDER);
if (permissionProvider != null) {
policy.mRestrictionsProvider =
ComponentName.unflattenFromString(permissionProvider);
}
String userSetupComplete = parser.getAttributeValue(null, ATTR_SETUP_COMPLETE);
if (Boolean.toString(true).equals(userSetupComplete)) {
if (VERBOSE_LOG) Slogf.v(TAG, "setting mUserSetupComplete to true");
policy.mUserSetupComplete = true;
}
String paired = parser.getAttributeValue(null, ATTR_DEVICE_PAIRED);
if (Boolean.toString(true).equals(paired)) {
policy.mPaired = true;
}
String deviceProvisioningConfigApplied = parser.getAttributeValue(null,
ATTR_DEVICE_PROVISIONING_CONFIG_APPLIED);
if (Boolean.toString(true).equals(deviceProvisioningConfigApplied)) {
policy.mDeviceProvisioningConfigApplied = true;
}
int provisioningState = parser.getAttributeInt(null, ATTR_PROVISIONING_STATE, -1);
if (provisioningState != -1) {
policy.mUserProvisioningState = provisioningState;
}
int permissionPolicy = parser.getAttributeInt(null, ATTR_PERMISSION_POLICY, -1);
if (permissionPolicy != -1) {
policy.mPermissionPolicy = permissionPolicy;
}
policy.mNewUserDisclaimer = parser.getAttributeValue(null, ATTR_NEW_USER_DISCLAIMER);
policy.mFactoryResetFlags = parser.getAttributeInt(null, ATTR_FACTORY_RESET_FLAGS, 0);
if (VERBOSE_LOG) {
Slogf.v(TAG, "Restored factory reset flags for user %d: %s", policy.mUserId,
factoryResetFlagsToString(policy.mFactoryResetFlags));
}
policy.mFactoryResetReason = parser.getAttributeValue(null, ATTR_FACTORY_RESET_REASON);
int outerDepth = parser.getDepth();
policy.mLockTaskPackages.clear();
policy.mAdminList.clear();
policy.mAdminMap.clear();
policy.mAffiliationIds.clear();
policy.mOwnerInstalledCaCerts.clear();
policy.mUserControlDisabledPackages.clear();
while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
&& (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
continue;
}
tag = parser.getName();
if ("admin".equals(tag)) {
String name = parser.getAttributeValue(null, "name");
try {
DeviceAdminInfo dai = adminInfoSupplier.apply(
ComponentName.unflattenFromString(name));
if (dai != null) {
// b/123415062: If DA, overwrite with the stored policies that were
// agreed by the user to prevent apps from sneaking additional policies
// into updates.
boolean overwritePolicies = !dai.getComponent().equals(ownerComponent);
ActiveAdmin ap = new ActiveAdmin(dai, /* parent */ false);
ap.readFromXml(parser, overwritePolicies);
policy.mAdminMap.put(ap.info.getComponent(), ap);
}
} catch (RuntimeException e) {
Slogf.w(TAG, e, "Failed loading admin %s", name);
}
} else if ("delegation".equals(tag)) {
// Parse delegation info.
final String delegatePackage = parser.getAttributeValue(null,
"delegatePackage");
final String scope = parser.getAttributeValue(null, "scope");
// Get a reference to the scopes list for the delegatePackage.
List<String> scopes = policy.mDelegationMap.get(delegatePackage);
// Or make a new list if none was found.
if (scopes == null) {
scopes = new ArrayList<>();
policy.mDelegationMap.put(delegatePackage, scopes);
}
// Add the new scope to the list of delegatePackage if it's not already there.
if (!scopes.contains(scope)) {
scopes.add(scope);
}
} else if ("failed-password-attempts".equals(tag)) {
policy.mFailedPasswordAttempts = parser.getAttributeInt(null, "value");
} else if ("password-owner".equals(tag)) {
policy.mPasswordOwner = parser.getAttributeInt(null, "value");
} else if (TAG_ACCEPTED_CA_CERTIFICATES.equals(tag)) {
policy.mAcceptedCaCertificates.add(parser.getAttributeValue(null, ATTR_NAME));
} else if (TAG_LOCK_TASK_COMPONENTS.equals(tag)) {
policy.mLockTaskPackages.add(parser.getAttributeValue(null, "name"));
} else if (TAG_LOCK_TASK_FEATURES.equals(tag)) {
policy.mLockTaskFeatures = parser.getAttributeInt(null, ATTR_VALUE);
} else if (TAG_SECONDARY_LOCK_SCREEN.equals(tag)) {
policy.mSecondaryLockscreenEnabled =
parser.getAttributeBoolean(null, ATTR_VALUE, false);
} else if (TAG_STATUS_BAR.equals(tag)) {
policy.mStatusBarDisabled =
parser.getAttributeBoolean(null, ATTR_DISABLED, false);
} else if (TAG_DO_NOT_ASK_CREDENTIALS_ON_BOOT.equals(tag)) {
policy.mDoNotAskCredentialsOnBoot = true;
} else if (TAG_AFFILIATION_ID.equals(tag)) {
policy.mAffiliationIds.add(parser.getAttributeValue(null, ATTR_ID));
} else if (TAG_LAST_SECURITY_LOG_RETRIEVAL.equals(tag)) {
policy.mLastSecurityLogRetrievalTime =
parser.getAttributeLong(null, ATTR_VALUE);
} else if (TAG_LAST_BUG_REPORT_REQUEST.equals(tag)) {
policy.mLastBugReportRequestTime =
parser.getAttributeLong(null, ATTR_VALUE);
} else if (TAG_LAST_NETWORK_LOG_RETRIEVAL.equals(tag)) {
policy.mLastNetworkLogsRetrievalTime =
parser.getAttributeLong(null, ATTR_VALUE);
} else if (TAG_ADMIN_BROADCAST_PENDING.equals(tag)) {
String pending = parser.getAttributeValue(null, ATTR_VALUE);
policy.mAdminBroadcastPending = Boolean.toString(true).equals(pending);
} else if (TAG_INITIALIZATION_BUNDLE.equals(tag)) {
policy.mInitBundle = PersistableBundle.restoreFromXml(parser);
} else if (TAG_PASSWORD_VALIDITY.equals(tag)) {
if (isFdeDevice) {
// This flag is only used for FDE devices
policy.mPasswordValidAtLastCheckpoint =
parser.getAttributeBoolean(null, ATTR_VALUE, false);
}
} else if (TAG_PASSWORD_TOKEN_HANDLE.equals(tag)) {
policy.mPasswordTokenHandle = parser.getAttributeLong(null, ATTR_VALUE);
} else if (TAG_CURRENT_INPUT_METHOD_SET.equals(tag)) {
policy.mCurrentInputMethodSet = true;
} else if (TAG_OWNER_INSTALLED_CA_CERT.equals(tag)) {
policy.mOwnerInstalledCaCerts.add(parser.getAttributeValue(null, ATTR_ALIAS));
} else if (TAG_PROTECTED_PACKAGES.equals(tag)) {
policy.mUserControlDisabledPackages.add(
parser.getAttributeValue(null, ATTR_NAME));
} else if (TAG_APPS_SUSPENDED.equals(tag)) {
policy.mAppsSuspended =
parser.getAttributeBoolean(null, ATTR_VALUE, false);
} else {
Slogf.w(TAG, "Unknown tag: %s", tag);
XmlUtils.skipCurrentTag(parser);
}
}
} catch (FileNotFoundException e) {
// Don't be noisy, this is normal if we haven't defined any policies.
} catch (NullPointerException | NumberFormatException | XmlPullParserException | IOException
| IndexOutOfBoundsException e) {
Slogf.w(TAG, e, "failed parsing %s", file);
}
try {
if (stream != null) {
stream.close();
}
} catch (IOException e) {
// Ignore
}
// Generate a list of admins from the admin map
policy.mAdminList.addAll(policy.mAdminMap.values());
}
void validatePasswordOwner() {
if (mPasswordOwner >= 0) {
boolean haveOwner = false;
for (int i = mAdminList.size() - 1; i >= 0; i--) {
if (mAdminList.get(i).getUid() == mPasswordOwner) {
haveOwner = true;
break;
}
}
if (!haveOwner) {
Slogf.w(TAG, "Previous password owner %s no longer active; disabling",
mPasswordOwner);
mPasswordOwner = -1;
}
}
}
void setDelayedFactoryReset(@NonNull String reason, boolean wipeExtRequested, boolean wipeEuicc,
boolean wipeResetProtectionData) {
mFactoryResetReason = reason;
mFactoryResetFlags = FACTORY_RESET_FLAG_ON_BOOT;
if (wipeExtRequested) {
mFactoryResetFlags |= FACTORY_RESET_FLAG_WIPE_EXTERNAL_STORAGE;
}
if (wipeEuicc) {
mFactoryResetFlags |= FACTORY_RESET_FLAG_WIPE_EUICC;
}
if (wipeResetProtectionData) {
mFactoryResetFlags |= FACTORY_RESET_FLAG_WIPE_FACTORY_RESET_PROTECTION;
}
}
void dump(IndentingPrintWriter pw) {
pw.println();
pw.println("Enabled Device Admins (User " + mUserId + ", provisioningState: "
+ mUserProvisioningState + "):");
final int n = mAdminList.size();
for (int i = 0; i < n; i++) {
ActiveAdmin ap = mAdminList.get(i);
if (ap != null) {
pw.increaseIndent();
pw.print(ap.info.getComponent().flattenToShortString());
pw.println(":");
pw.increaseIndent();
ap.dump(pw);
pw.decreaseIndent();
pw.decreaseIndent();
}
}
if (!mRemovingAdmins.isEmpty()) {
pw.increaseIndent();
pw.println("Removing Device Admins (User " + mUserId + "): " + mRemovingAdmins);
pw.decreaseIndent();
}
pw.println();
pw.increaseIndent();
pw.print("mPasswordOwner="); pw.println(mPasswordOwner);
pw.print("mUserControlDisabledPackages=");
pw.println(mUserControlDisabledPackages);
pw.print("mAppsSuspended="); pw.println(mAppsSuspended);
pw.print("mUserSetupComplete="); pw.println(mUserSetupComplete);
pw.print("mAffiliationIds="); pw.println(mAffiliationIds);
pw.print("mNewUserDisclaimer="); pw.println(mNewUserDisclaimer);
if (mFactoryResetFlags != 0) {
pw.print("mFactoryResetFlags="); pw.print(mFactoryResetFlags);
pw.print(" (");
pw.print(factoryResetFlagsToString(mFactoryResetFlags));
pw.println(')');
}
if (mFactoryResetReason != null) {
pw.print("mFactoryResetReason="); pw.println(mFactoryResetReason);
}
pw.decreaseIndent();
}
static String factoryResetFlagsToString(int flags) {
return DebugUtils.flagsToString(DevicePolicyData.class, "FACTORY_RESET_FLAG_", flags);
}
}