Migrate lock task policy APIs to coexistence

Bug: 258442693
Bug: 232918480
Test: atest android.devicepolicy.cts.LockTaskTest with flag
enabled/disabled
Change-Id: Ib8d4498ce84db42ad409adc807f20ad25beb3ace

Change-Id: Idb1d2d277f35850c6e24134dcbeb83c3c0001aa1
This commit is contained in:
Kholoud Mohamed
2022-11-28 12:06:01 +00:00
parent ba36010ecb
commit 43fb625fd8
8 changed files with 218 additions and 66 deletions

View File

@@ -16,24 +16,35 @@
package com.android.server.devicepolicy;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.util.Log;
import com.android.modules.utils.TypedXmlPullParser;
import com.android.modules.utils.TypedXmlSerializer;
import org.xmlpull.v1.XmlPullParserException;
import java.io.IOException;
import java.util.Objects;
final class BooleanPolicySerializer extends PolicySerializer<Boolean> {
@Override
void saveToXml(TypedXmlSerializer serializer, String attributeName, Boolean value)
void saveToXml(TypedXmlSerializer serializer, String attributeName, @NonNull Boolean value)
throws IOException {
Objects.requireNonNull(value);
serializer.attributeBoolean(/* namespace= */ null, attributeName, value);
}
@Nullable
@Override
Boolean readFromXml(TypedXmlPullParser parser, String attributeName)
throws XmlPullParserException {
return parser.getAttributeBoolean(/* namespace= */ null, attributeName);
Boolean readFromXml(TypedXmlPullParser parser, String attributeName) {
try {
return parser.getAttributeBoolean(/* namespace= */ null, attributeName);
} catch (XmlPullParserException e) {
Log.e(DevicePolicyEngine.TAG, "Error parsing Boolean policy value", e);
return null;
}
}
}

View File

@@ -12275,8 +12275,38 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
synchronized (getLockObject()) {
enforceCanCallLockTaskLocked(caller);
checkCanExecuteOrThrowUnsafe(DevicePolicyManager.OPERATION_SET_LOCK_TASK_PACKAGES);
final int userHandle = caller.getUserId();
setLockTaskPackagesLocked(userHandle, new ArrayList<>(Arrays.asList(packages)));
}
if (isCoexistenceEnabled(caller)) {
EnforcingAdmin admin = EnforcingAdmin.createEnterpriseEnforcingAdmin(who);
if (packages.length == 0) {
mDevicePolicyEngine.removeLocalPolicy(
PolicyDefinition.LOCK_TASK,
admin,
caller.getUserId());
} else {
LockTaskPolicy currentPolicy = mDevicePolicyEngine.getLocalPolicy(
PolicyDefinition.LOCK_TASK,
caller.getUserId()).getPoliciesSetByAdmins().get(admin);
LockTaskPolicy policy;
if (currentPolicy == null) {
policy = new LockTaskPolicy(Set.of(packages));
} else {
policy = currentPolicy.clone();
policy.setPackages(Set.of(packages));
}
mDevicePolicyEngine.setLocalPolicy(
PolicyDefinition.LOCK_TASK,
EnforcingAdmin.createEnterpriseEnforcingAdmin(who),
policy,
caller.getUserId());
}
} else {
synchronized (getLockObject()) {
final int userHandle = caller.getUserId();
setLockTaskPackagesLocked(userHandle, new ArrayList<>(Arrays.asList(packages)));
}
}
}
@@ -12297,8 +12327,21 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
synchronized (getLockObject()) {
enforceCanCallLockTaskLocked(caller);
final List<String> packages = getUserData(userHandle).mLockTaskPackages;
return packages.toArray(new String[packages.size()]);
}
if (isCoexistenceEnabled(caller)) {
LockTaskPolicy policy = mDevicePolicyEngine.getLocalPolicy(
PolicyDefinition.LOCK_TASK, userHandle).getCurrentResolvedPolicy();
if (policy == null) {
return new String[0];
} else {
return policy.getPackages().toArray(new String[policy.getPackages().size()]);
}
} else {
synchronized (getLockObject()) {
final List<String> packages = getUserData(userHandle).mLockTaskPackages;
return packages.toArray(new String[packages.size()]);
}
}
}
@@ -12314,8 +12357,19 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
}
final int userId = mInjector.userHandleGetCallingUserId();
synchronized (getLockObject()) {
return getUserData(userId).mLockTaskPackages.contains(pkg);
// TODO(b/260560985): This is not the right check, as the flag could be enabled but there
// could be an admin that hasn't targeted U.
if (isCoexistenceFlagEnabled()) {
LockTaskPolicy policy = mDevicePolicyEngine.getLocalPolicy(
PolicyDefinition.LOCK_TASK, userId).getCurrentResolvedPolicy();
if (policy == null) {
return false;
}
return policy.getPackages().contains(pkg);
} else {
synchronized (getLockObject()) {
return getUserData(userId).mLockTaskPackages.contains(pkg);
}
}
}
@@ -12338,7 +12392,28 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
enforceCanCallLockTaskLocked(caller);
enforceCanSetLockTaskFeaturesOnFinancedDevice(caller, flags);
checkCanExecuteOrThrowUnsafe(DevicePolicyManager.OPERATION_SET_LOCK_TASK_FEATURES);
setLockTaskFeaturesLocked(userHandle, flags);
}
if (isCoexistenceEnabled(caller)) {
EnforcingAdmin admin = EnforcingAdmin.createEnterpriseEnforcingAdmin(who);
LockTaskPolicy currentPolicy = mDevicePolicyEngine.getLocalPolicy(
PolicyDefinition.LOCK_TASK,
caller.getUserId()).getPoliciesSetByAdmins().get(admin);
if (currentPolicy == null) {
throw new IllegalArgumentException("Can't set a lock task flags without setting "
+ "lock task packages first.");
}
LockTaskPolicy policy = currentPolicy.clone();
policy.setFlags(flags);
mDevicePolicyEngine.setLocalPolicy(
PolicyDefinition.LOCK_TASK,
EnforcingAdmin.createEnterpriseEnforcingAdmin(who),
policy,
caller.getUserId());
} else {
synchronized (getLockObject()) {
setLockTaskFeaturesLocked(userHandle, flags);
}
}
}
@@ -12356,7 +12431,21 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
final int userHandle = caller.getUserId();
synchronized (getLockObject()) {
enforceCanCallLockTaskLocked(caller);
return getUserData(userHandle).mLockTaskFeatures;
}
if (isCoexistenceEnabled(caller)) {
LockTaskPolicy policy = mDevicePolicyEngine.getLocalPolicy(
PolicyDefinition.LOCK_TASK, userHandle).getCurrentResolvedPolicy();
if (policy == null) {
// We default on the power button menu, in order to be consistent with pre-P
// behaviour.
return DevicePolicyManager.LOCK_TASK_FEATURE_GLOBAL_ACTIONS;
}
return policy.getFlags();
} else {
synchronized (getLockObject()) {
return getUserData(userHandle).mLockTaskFeatures;
}
}
}

View File

@@ -16,24 +16,35 @@
package com.android.server.devicepolicy;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.util.Log;
import com.android.modules.utils.TypedXmlPullParser;
import com.android.modules.utils.TypedXmlSerializer;
import org.xmlpull.v1.XmlPullParserException;
import java.io.IOException;
import java.util.Objects;
final class IntegerPolicySerializer extends PolicySerializer<Integer> {
@Override
void saveToXml(TypedXmlSerializer serializer, String attributeName, Integer value)
void saveToXml(TypedXmlSerializer serializer, String attributeName, @NonNull Integer value)
throws IOException {
Objects.requireNonNull(value);
serializer.attributeInt(/* namespace= */ null, attributeName, value);
}
@Nullable
@Override
Integer readFromXml(TypedXmlPullParser parser, String attributeName)
throws XmlPullParserException {
return parser.getAttributeInt(/* namespace= */ null, attributeName);
Integer readFromXml(TypedXmlPullParser parser, String attributeName) {
try {
return parser.getAttributeInt(/* namespace= */ null, attributeName);
} catch (XmlPullParserException e) {
Log.e(DevicePolicyEngine.TAG, "Error parsing Integer policy value", e);
return null;
}
}
}

View File

@@ -16,7 +16,10 @@
package com.android.server.devicepolicy;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.admin.DevicePolicyManager;
import android.util.Log;
import com.android.modules.utils.TypedXmlPullParser;
import com.android.modules.utils.TypedXmlSerializer;
@@ -24,19 +27,16 @@ import com.android.modules.utils.TypedXmlSerializer;
import org.xmlpull.v1.XmlPullParserException;
import java.io.IOException;
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;
final class LockTaskPolicy {
private Set<String> mPackages;
private int mFlags;
static final int DEFAULT_LOCK_TASK_FLAG = DevicePolicyManager.LOCK_TASK_FEATURE_GLOBAL_ACTIONS;
private Set<String> mPackages = new HashSet<>();
private int mFlags = DEFAULT_LOCK_TASK_FLAG;
LockTaskPolicy(@Nullable Set<String> packages, int flags) {
mPackages = packages;
mFlags = flags;
}
@Nullable
@NonNull
Set<String> getPackages() {
return mPackages;
}
@@ -45,14 +45,33 @@ final class LockTaskPolicy {
return mFlags;
}
void setPackages(Set<String> packages) {
mPackages = packages;
LockTaskPolicy(Set<String> packages) {
Objects.requireNonNull(packages);
mPackages.addAll(packages);
}
private LockTaskPolicy(Set<String> packages, int flags) {
Objects.requireNonNull(packages);
mPackages = new HashSet<>(packages);
mFlags = flags;
}
void setPackages(@NonNull Set<String> packages) {
Objects.requireNonNull(packages);
mPackages = new HashSet<>(packages);
}
void setFlags(int flags) {
mFlags = flags;
}
@Override
public LockTaskPolicy clone() {
LockTaskPolicy policy = new LockTaskPolicy(mPackages);
policy.setFlags(mFlags);
return policy;
}
@Override
public boolean equals(@Nullable Object o) {
if (this == o) return true;
@@ -67,6 +86,11 @@ final class LockTaskPolicy {
return Objects.hash(mPackages, mFlags);
}
@Override
public String toString() {
return "mPackages= " + String.join(", ", mPackages) + "; mFlags= " + mFlags;
}
static final class LockTaskPolicySerializer extends PolicySerializer<LockTaskPolicy> {
private static final String ATTR_PACKAGES = ":packages";
@@ -74,15 +98,17 @@ final class LockTaskPolicy {
private static final String ATTR_FLAGS = ":flags";
@Override
void saveToXml(
TypedXmlSerializer serializer, String attributeNamePrefix, LockTaskPolicy value)
throws IOException {
if (value.mPackages != null) {
serializer.attribute(
/* namespace= */ null,
attributeNamePrefix + ATTR_PACKAGES,
String.join(ATTR_PACKAGES_SEPARATOR, value.mPackages));
void saveToXml(TypedXmlSerializer serializer, String attributeNamePrefix,
@NonNull LockTaskPolicy value) throws IOException {
Objects.requireNonNull(value);
if (value.mPackages == null || value.mPackages.isEmpty()) {
throw new IllegalArgumentException("Error saving LockTaskPolicy to file, lock task "
+ "packages must be present");
}
serializer.attribute(
/* namespace= */ null,
attributeNamePrefix + ATTR_PACKAGES,
String.join(ATTR_PACKAGES_SEPARATOR, value.mPackages));
serializer.attributeInt(
/* namespace= */ null,
attributeNamePrefix + ATTR_FLAGS,
@@ -90,18 +116,24 @@ final class LockTaskPolicy {
}
@Override
LockTaskPolicy readFromXml(TypedXmlPullParser parser, String attributeNamePrefix)
throws XmlPullParserException {
LockTaskPolicy readFromXml(TypedXmlPullParser parser, String attributeNamePrefix) {
String packagesStr = parser.getAttributeValue(
/* namespace= */ null,
attributeNamePrefix + ATTR_PACKAGES);
Set<String> packages = packagesStr == null
? null
: Set.of(packagesStr.split(ATTR_PACKAGES_SEPARATOR));
int flags = parser.getAttributeInt(
/* namespace= */ null,
attributeNamePrefix + ATTR_FLAGS);
return new LockTaskPolicy(packages, flags);
if (packagesStr == null) {
Log.e(DevicePolicyEngine.TAG, "Error parsing LockTask policy value.");
return null;
}
Set<String> packages = Set.of(packagesStr.split(ATTR_PACKAGES_SEPARATOR));
try {
int flags = parser.getAttributeInt(
/* namespace= */ null,
attributeNamePrefix + ATTR_FLAGS);
return new LockTaskPolicy(packages, flags);
} catch (XmlPullParserException e) {
Log.e(DevicePolicyEngine.TAG, "Error parsing LockTask policy value", e);
return null;
}
}
}
}

View File

@@ -25,8 +25,6 @@ import com.android.internal.util.function.QuadFunction;
import com.android.modules.utils.TypedXmlPullParser;
import com.android.modules.utils.TypedXmlSerializer;
import org.xmlpull.v1.XmlPullParserException;
import java.io.IOException;
import java.util.LinkedHashMap;
import java.util.List;
@@ -225,8 +223,8 @@ final class PolicyDefinition<V> {
mPolicySerializer.saveToXml(serializer, attributeName, value);
}
V readPolicyValueFromXml(TypedXmlPullParser parser, String attributeName)
throws XmlPullParserException {
@Nullable
V readPolicyValueFromXml(TypedXmlPullParser parser, String attributeName) {
return mPolicySerializer.readFromXml(parser, attributeName);
}
}

View File

@@ -29,6 +29,7 @@ import android.provider.Settings;
import com.android.server.utils.Slogf;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.CountDownLatch;
@@ -105,9 +106,14 @@ final class PolicyEnforcerCallbacks {
static boolean setLockTask(
@Nullable LockTaskPolicy policy, @NonNull Context context, int userId) {
DevicePolicyManagerService.updateLockTaskPackagesLocked(
context, List.copyOf(policy.getPackages()), userId);
DevicePolicyManagerService.updateLockTaskFeaturesLocked(policy.getFlags(), userId);
List<String> packages = Collections.emptyList();
int flags = LockTaskPolicy.DEFAULT_LOCK_TASK_FLAG;
if (policy != null) {
packages = List.copyOf(policy.getPackages());
flags = policy.getFlags();
}
DevicePolicyManagerService.updateLockTaskPackagesLocked(context, packages, userId);
DevicePolicyManagerService.updateLockTaskFeaturesLocked(flags, userId);
return true;
}

View File

@@ -16,16 +16,15 @@
package com.android.server.devicepolicy;
import android.annotation.NonNull;
import com.android.modules.utils.TypedXmlPullParser;
import com.android.modules.utils.TypedXmlSerializer;
import org.xmlpull.v1.XmlPullParserException;
import java.io.IOException;
abstract class PolicySerializer<V> {
abstract void saveToXml(TypedXmlSerializer serializer, String attributeName, V value)
abstract void saveToXml(TypedXmlSerializer serializer, String attributeName, @NonNull V value)
throws IOException;
abstract V readFromXml(TypedXmlPullParser parser, String attributeName)
throws XmlPullParserException;
abstract V readFromXml(TypedXmlPullParser parser, String attributeName);
}

View File

@@ -40,7 +40,7 @@ final class PolicyState<V> {
private static final String ATTR_RESOLVED_POLICY = "resolved-policy";
private final PolicyDefinition<V> mPolicyDefinition;
private final LinkedHashMap<EnforcingAdmin, V> mAdminsPolicy = new LinkedHashMap<>();
private final LinkedHashMap<EnforcingAdmin, V> mPoliciesSetByAdmins = new LinkedHashMap<>();
private V mCurrentResolvedPolicy;
PolicyState(@NonNull PolicyDefinition<V> policyDefinition) {
@@ -49,13 +49,13 @@ final class PolicyState<V> {
private PolicyState(
@NonNull PolicyDefinition<V> policyDefinition,
@NonNull LinkedHashMap<EnforcingAdmin, V> adminsPolicy,
@NonNull LinkedHashMap<EnforcingAdmin, V> policiesSetByAdmins,
V currentEnforcedPolicy) {
Objects.requireNonNull(policyDefinition);
Objects.requireNonNull(adminsPolicy);
Objects.requireNonNull(policiesSetByAdmins);
mPolicyDefinition = policyDefinition;
mAdminsPolicy.putAll(adminsPolicy);
mPoliciesSetByAdmins.putAll(policiesSetByAdmins);
mCurrentResolvedPolicy = currentEnforcedPolicy;
}
@@ -63,7 +63,7 @@ final class PolicyState<V> {
* Returns {@code true} if the resolved policy has changed, {@code false} otherwise.
*/
boolean setPolicy(@NonNull EnforcingAdmin admin, @NonNull V value) {
mAdminsPolicy.put(Objects.requireNonNull(admin), Objects.requireNonNull(value));
mPoliciesSetByAdmins.put(Objects.requireNonNull(admin), Objects.requireNonNull(value));
return resolvePolicy();
}
@@ -71,15 +71,19 @@ final class PolicyState<V> {
boolean removePolicy(@NonNull EnforcingAdmin admin) {
Objects.requireNonNull(admin);
if (mAdminsPolicy.remove(admin) == null) {
if (mPoliciesSetByAdmins.remove(admin) == null) {
return false;
}
return resolvePolicy();
}
LinkedHashMap<EnforcingAdmin, V> getPoliciesSetByAdmins() {
return mPoliciesSetByAdmins;
}
private boolean resolvePolicy() {
V resolvedPolicy = mPolicyDefinition.resolvePolicy(mAdminsPolicy);
V resolvedPolicy = mPolicyDefinition.resolvePolicy(mPoliciesSetByAdmins);
boolean policyChanged = !Objects.equals(resolvedPolicy, mCurrentResolvedPolicy);
mCurrentResolvedPolicy = resolvedPolicy;
@@ -94,14 +98,16 @@ final class PolicyState<V> {
void saveToXml(TypedXmlSerializer serializer) throws IOException {
mPolicyDefinition.saveToXml(serializer);
mPolicyDefinition.savePolicyValueToXml(
serializer, ATTR_RESOLVED_POLICY, mCurrentResolvedPolicy);
if (mCurrentResolvedPolicy != null) {
mPolicyDefinition.savePolicyValueToXml(
serializer, ATTR_RESOLVED_POLICY, mCurrentResolvedPolicy);
}
for (EnforcingAdmin admin : mAdminsPolicy.keySet()) {
for (EnforcingAdmin admin : mPoliciesSetByAdmins.keySet()) {
serializer.startTag(/* namespace= */ null, TAG_ADMIN_POLICY_ENTRY);
mPolicyDefinition.savePolicyValueToXml(
serializer, ATTR_POLICY_VALUE, mAdminsPolicy.get(admin));
serializer, ATTR_POLICY_VALUE, mPoliciesSetByAdmins.get(admin));
serializer.startTag(/* namespace= */ null, TAG_ENFORCING_ADMIN_ENTRY);
admin.saveToXml(serializer);