Merge changes Idb1d2d27,I60837e40
* changes: Migrate lock task policy APIs to coexistence Call device policy engine from DPMS
This commit is contained in:
committed by
Android (Google) Code Review
commit
bed1828b84
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -81,6 +81,7 @@ import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_NUMERIC;
|
||||
import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX;
|
||||
import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_SOMETHING;
|
||||
import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
|
||||
import static android.app.admin.DevicePolicyManager.PERMISSION_GRANT_STATE_GRANTED;
|
||||
import static android.app.admin.DevicePolicyManager.PERSONAL_APPS_NOT_SUSPENDED;
|
||||
import static android.app.admin.DevicePolicyManager.PERSONAL_APPS_SUSPENDED_EXPLICITLY;
|
||||
import static android.app.admin.DevicePolicyManager.PERSONAL_APPS_SUSPENDED_PROFILE_TIMEOUT;
|
||||
@@ -140,6 +141,7 @@ import static android.net.ConnectivityManager.PROFILE_NETWORK_PREFERENCE_DEFAULT
|
||||
import static android.net.ConnectivityManager.PROFILE_NETWORK_PREFERENCE_ENTERPRISE;
|
||||
import static android.net.ConnectivityManager.PROFILE_NETWORK_PREFERENCE_ENTERPRISE_NO_FALLBACK;
|
||||
import static android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK;
|
||||
import static android.provider.DeviceConfig.NAMESPACE_DEVICE_POLICY_MANAGER;
|
||||
import static android.provider.Settings.Global.PRIVATE_DNS_SPECIFIER;
|
||||
import static android.provider.Settings.Secure.MANAGED_PROVISIONING_DPC_DOWNLOADED;
|
||||
import static android.provider.Settings.Secure.USER_SETUP_COMPLETE;
|
||||
@@ -309,6 +311,7 @@ import android.permission.PermissionControllerManager;
|
||||
import android.provider.CalendarContract;
|
||||
import android.provider.ContactsContract.QuickContact;
|
||||
import android.provider.ContactsInternal;
|
||||
import android.provider.DeviceConfig;
|
||||
import android.provider.Settings;
|
||||
import android.provider.Settings.Global;
|
||||
import android.provider.Telephony;
|
||||
@@ -712,6 +715,17 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
|
||||
+ "management app's authentication policy";
|
||||
private static final String NOT_SYSTEM_CALLER_MSG = "Only the system can %s";
|
||||
|
||||
private static final String ENABLE_COEXISTENCE_FLAG = "enable_coexistence";
|
||||
private static final boolean DEFAULT_ENABLE_COEXISTENCE_FLAG = false;
|
||||
|
||||
/**
|
||||
* For apps targeting U+
|
||||
* Enable multiple admins to coexist on the same device.
|
||||
*/
|
||||
@ChangeId
|
||||
@EnabledSince(targetSdkVersion = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
|
||||
static final long ENABLE_COEXISTENCE_CHANGE = 260560985L;
|
||||
|
||||
final Context mContext;
|
||||
final Injector mInjector;
|
||||
final PolicyPathProvider mPathProvider;
|
||||
@@ -795,6 +809,8 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
|
||||
private final DeviceManagementResourcesProvider mDeviceManagementResourcesProvider;
|
||||
private final DevicePolicyManagementRoleObserver mDevicePolicyManagementRoleObserver;
|
||||
|
||||
private final DevicePolicyEngine mDevicePolicyEngine;
|
||||
|
||||
private static final boolean ENABLE_LOCK_GUARD = true;
|
||||
|
||||
/**
|
||||
@@ -1864,6 +1880,8 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
|
||||
mUserData = new SparseArray<>();
|
||||
mOwners = makeOwners(injector, pathProvider);
|
||||
|
||||
mDevicePolicyEngine = new DevicePolicyEngine(mContext);
|
||||
|
||||
if (!mHasFeature) {
|
||||
// Skip the rest of the initialization
|
||||
mSetupContentObserver = null;
|
||||
@@ -1908,6 +1926,9 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
|
||||
mUserManagerInternal.addUserLifecycleListener(new UserLifecycleListener());
|
||||
|
||||
mDeviceManagementResourcesProvider.load();
|
||||
if (isCoexistenceFlagEnabled()) {
|
||||
mDevicePolicyEngine.load();
|
||||
}
|
||||
|
||||
// The binder caches are not enabled until the first invalidation.
|
||||
invalidateBinderCaches();
|
||||
@@ -7951,8 +7972,17 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
|
||||
Preconditions.checkCallAuthorization(isProfileOwnerOnUser0(caller)
|
||||
|| isProfileOwnerOfOrganizationOwnedDevice(caller) || isDefaultDeviceOwner(caller));
|
||||
|
||||
mInjector.binderWithCleanCallingIdentity(() ->
|
||||
mInjector.settingsGlobalPutInt(Global.AUTO_TIME_ZONE, enabled ? 1 : 0));
|
||||
if (isCoexistenceEnabled(caller)) {
|
||||
mDevicePolicyEngine.setGlobalPolicy(
|
||||
PolicyDefinition.AUTO_TIMEZONE,
|
||||
// TODO(b/260573124): add correct enforcing admin when permission changes are
|
||||
// merged.
|
||||
EnforcingAdmin.createEnterpriseEnforcingAdmin(caller.getComponentName()),
|
||||
enabled);
|
||||
} else {
|
||||
mInjector.binderWithCleanCallingIdentity(() ->
|
||||
mInjector.settingsGlobalPutInt(Global.AUTO_TIME_ZONE, enabled ? 1 : 0));
|
||||
}
|
||||
|
||||
DevicePolicyEventLogger
|
||||
.createEvent(DevicePolicyEnums.SET_AUTO_TIME_ZONE)
|
||||
@@ -12245,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)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12267,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()]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12284,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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12308,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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12326,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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13905,6 +14024,20 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
|
||||
if (isFinancedDeviceOwner(caller)) {
|
||||
enforcePermissionGrantStateOnFinancedDevice(packageName, permission);
|
||||
}
|
||||
}
|
||||
if (isCoexistenceEnabled(caller)) {
|
||||
mDevicePolicyEngine.setLocalPolicy(
|
||||
PolicyDefinition.PERMISSION_GRANT(packageName, permission),
|
||||
// TODO(b/260573124): Add correct enforcing admin when permission changes are
|
||||
// merged, and don't forget to handle delegates! Enterprise admins assume
|
||||
// component name isn't null.
|
||||
EnforcingAdmin.createEnterpriseEnforcingAdmin(caller.getComponentName()),
|
||||
grantState,
|
||||
caller.getUserId());
|
||||
// TODO: update javadoc to reflect that callback no longer return success/failure
|
||||
callback.sendResult(Bundle.EMPTY);
|
||||
} else {
|
||||
synchronized (getLockObject()) {
|
||||
long ident = mInjector.binderClearCallingIdentity();
|
||||
try {
|
||||
boolean isPostQAdmin = getTargetSdk(caller.getPackageName(), caller.getUserId())
|
||||
@@ -13921,14 +14054,16 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
|
||||
callback.sendResult(null);
|
||||
return;
|
||||
}
|
||||
if (grantState == DevicePolicyManager.PERMISSION_GRANT_STATE_GRANTED
|
||||
if (grantState == PERMISSION_GRANT_STATE_GRANTED
|
||||
|| grantState == DevicePolicyManager.PERMISSION_GRANT_STATE_DENIED
|
||||
|| grantState == DevicePolicyManager.PERMISSION_GRANT_STATE_DEFAULT) {
|
||||
AdminPermissionControlParams permissionParams =
|
||||
new AdminPermissionControlParams(packageName, permission, grantState,
|
||||
new AdminPermissionControlParams(packageName, permission,
|
||||
grantState,
|
||||
canAdminGrantSensorsPermissionsForUser(caller.getUserId()));
|
||||
mInjector.getPermissionControllerManager(caller.getUserHandle())
|
||||
.setRuntimePermissionGrantStateByDeviceAdmin(caller.getPackageName(),
|
||||
.setRuntimePermissionGrantStateByDeviceAdmin(
|
||||
caller.getPackageName(),
|
||||
permissionParams, mContext.getMainExecutor(),
|
||||
(permissionWasSet) -> {
|
||||
if (isPostQAdmin && !permissionWasSet) {
|
||||
@@ -13947,13 +14082,14 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
|
||||
|
||||
callback.sendResult(Bundle.EMPTY);
|
||||
});
|
||||
}
|
||||
} catch (SecurityException e) {
|
||||
Slogf.e(LOG_TAG, "Could not set permission grant state", e);
|
||||
}
|
||||
} catch (SecurityException e) {
|
||||
Slogf.e(LOG_TAG, "Could not set permission grant state", e);
|
||||
|
||||
callback.sendResult(null);
|
||||
} finally {
|
||||
mInjector.binderRestoreCallingIdentity(ident);
|
||||
callback.sendResult(null);
|
||||
} finally {
|
||||
mInjector.binderRestoreCallingIdentity(ident);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -19017,4 +19153,18 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
|
||||
return result;
|
||||
});
|
||||
}
|
||||
|
||||
// TODO(b/260560985): properly gate coexistence changes
|
||||
private boolean isCoexistenceEnabled(CallerIdentity caller) {
|
||||
return isCoexistenceFlagEnabled()
|
||||
&& mInjector.isChangeEnabled(
|
||||
ENABLE_COEXISTENCE_CHANGE, caller.getPackageName(), caller.getUserId());
|
||||
}
|
||||
|
||||
private boolean isCoexistenceFlagEnabled() {
|
||||
return DeviceConfig.getBoolean(
|
||||
NAMESPACE_DEVICE_POLICY_MANAGER,
|
||||
ENABLE_COEXISTENCE_FLAG,
|
||||
DEFAULT_ENABLE_COEXISTENCE_FLAG);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
@@ -53,7 +54,7 @@ final class PolicyEnforcerCallbacks {
|
||||
static boolean setPermissionGrantState(
|
||||
@Nullable Integer grantState, @NonNull Context context, int userId,
|
||||
@NonNull String[] args) {
|
||||
Binder.withCleanCallingIdentity(() -> {
|
||||
return Boolean.TRUE.equals(Binder.withCleanCallingIdentity(() -> {
|
||||
if (args == null || args.length < 2) {
|
||||
throw new IllegalArgumentException("Package name and permission name must be "
|
||||
+ "provided as arguments");
|
||||
@@ -84,8 +85,7 @@ final class PolicyEnforcerCallbacks {
|
||||
// TODO: add logging
|
||||
return false;
|
||||
}
|
||||
});
|
||||
return true;
|
||||
}));
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@@ -106,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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user