Merge changes Id3c16654,I57d8730e into udc-dev

* changes:
  Simplify coexistence gating logic
  Migrate setApplicationHidden to the policy engine
This commit is contained in:
Kholoud Mohamed
2023-04-04 11:26:49 +00:00
committed by Android (Google) Code Review
4 changed files with 189 additions and 238 deletions

View File

@@ -23,7 +23,6 @@ import static android.app.admin.PolicyUpdateResult.RESULT_FAILURE_HARDWARE_LIMIT
import static android.app.admin.PolicyUpdateResult.RESULT_POLICY_CLEARED;
import static android.app.admin.PolicyUpdateResult.RESULT_POLICY_SET;
import static android.content.pm.UserProperties.INHERIT_DEVICE_POLICY_FROM_PARENT;
import static android.provider.DeviceConfig.NAMESPACE_DEVICE_POLICY_MANAGER;
import android.Manifest;
import android.annotation.NonNull;
@@ -47,7 +46,6 @@ import android.os.Bundle;
import android.os.Environment;
import android.os.UserHandle;
import android.os.UserManager;
import android.provider.DeviceConfig;
import android.telephony.TelephonyManager;
import android.util.AtomicFile;
import android.util.Log;
@@ -86,9 +84,6 @@ final class DevicePolicyEngine {
DevicePolicyIdentifiers.getIdentifierForUserRestriction(
UserManager.DISALLOW_CELLULAR_2G);
private static final String ENABLE_COEXISTENCE_FLAG = "enable_coexistence";
private static final boolean DEFAULT_ENABLE_COEXISTENCE_FLAG = true;
private final Context mContext;
private final UserManager mUserManager;
@@ -771,28 +766,31 @@ final class DevicePolicyEngine {
Intent intent = new Intent(PolicyUpdateReceiver.ACTION_DEVICE_POLICY_SET_RESULT);
intent.setPackage(admin.getPackageName());
List<ResolveInfo> receivers = mContext.getPackageManager().queryBroadcastReceiversAsUser(
intent,
PackageManager.ResolveInfoFlags.of(PackageManager.GET_RECEIVERS),
admin.getUserId());
if (receivers.isEmpty()) {
Log.i(TAG, "Couldn't find any receivers that handle ACTION_DEVICE_POLICY_SET_RESULT"
+ "in package " + admin.getPackageName());
return;
}
Binder.withCleanCallingIdentity(() -> {
List<ResolveInfo> receivers =
mContext.getPackageManager().queryBroadcastReceiversAsUser(
intent,
PackageManager.ResolveInfoFlags.of(PackageManager.GET_RECEIVERS),
admin.getUserId());
if (receivers.isEmpty()) {
Log.i(TAG, "Couldn't find any receivers that handle ACTION_DEVICE_POLICY_SET_RESULT"
+ "in package " + admin.getPackageName());
return;
}
Bundle extras = new Bundle();
policyDefinition.getPolicyKey().writeToBundle(extras);
extras.putInt(
EXTRA_POLICY_TARGET_USER_ID,
getTargetUser(admin.getUserId(), userId));
extras.putInt(
EXTRA_POLICY_UPDATE_RESULT_KEY,
result);
Bundle extras = new Bundle();
policyDefinition.getPolicyKey().writeToBundle(extras);
extras.putInt(
EXTRA_POLICY_TARGET_USER_ID,
getTargetUser(admin.getUserId(), userId));
extras.putInt(
EXTRA_POLICY_UPDATE_RESULT_KEY,
result);
intent.putExtras(extras);
intent.putExtras(extras);
maybeSendIntentToAdminReceivers(intent, UserHandle.of(admin.getUserId()), receivers);
maybeSendIntentToAdminReceivers(intent, UserHandle.of(admin.getUserId()), receivers);
});
}
// TODO(b/261430877): Finalise the decision on which admins to send the updates to.
@@ -821,27 +819,30 @@ final class DevicePolicyEngine {
Intent intent = new Intent(PolicyUpdateReceiver.ACTION_DEVICE_POLICY_CHANGED);
intent.setPackage(admin.getPackageName());
List<ResolveInfo> receivers = mContext.getPackageManager().queryBroadcastReceiversAsUser(
intent,
PackageManager.ResolveInfoFlags.of(PackageManager.GET_RECEIVERS),
admin.getUserId());
if (receivers.isEmpty()) {
Log.i(TAG, "Couldn't find any receivers that handle ACTION_DEVICE_POLICY_CHANGED"
+ "in package " + admin.getPackageName());
return;
}
Binder.withCleanCallingIdentity(() -> {
List<ResolveInfo> receivers =
mContext.getPackageManager().queryBroadcastReceiversAsUser(
intent,
PackageManager.ResolveInfoFlags.of(PackageManager.GET_RECEIVERS),
admin.getUserId());
if (receivers.isEmpty()) {
Log.i(TAG, "Couldn't find any receivers that handle ACTION_DEVICE_POLICY_CHANGED"
+ "in package " + admin.getPackageName());
return;
}
Bundle extras = new Bundle();
policyDefinition.getPolicyKey().writeToBundle(extras);
extras.putInt(
EXTRA_POLICY_TARGET_USER_ID,
getTargetUser(admin.getUserId(), userId));
extras.putInt(EXTRA_POLICY_UPDATE_RESULT_KEY, reason);
intent.putExtras(extras);
intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
Bundle extras = new Bundle();
policyDefinition.getPolicyKey().writeToBundle(extras);
extras.putInt(
EXTRA_POLICY_TARGET_USER_ID,
getTargetUser(admin.getUserId(), userId));
extras.putInt(EXTRA_POLICY_UPDATE_RESULT_KEY, reason);
intent.putExtras(extras);
intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
maybeSendIntentToAdminReceivers(
intent, UserHandle.of(admin.getUserId()), receivers);
maybeSendIntentToAdminReceivers(
intent, UserHandle.of(admin.getUserId()), receivers);
});
}
private void maybeSendIntentToAdminReceivers(
@@ -1146,38 +1147,6 @@ final class DevicePolicyEngine {
return mEnforcingAdmins.size() > 0;
}
/**
* Returns {@code true} if the coexistence flag is enabled or:
* <ul>
* <li>If the provided package is an admin with existing policies
* <li>A new admin and no other admin have policies set
* <li>More than one admin have policies set
*/
boolean canAdminAddPolicies(String packageName, int userId) {
if (isCoexistenceFlagEnabled()) {
return true;
}
if (mEnforcingAdmins.contains(userId)
&& mEnforcingAdmins.get(userId).stream().anyMatch(admin ->
admin.getPackageName().equals(packageName))) {
return true;
}
int numOfEnforcingAdmins = 0;
for (int i = 0; i < mEnforcingAdmins.size(); i++) {
numOfEnforcingAdmins += mEnforcingAdmins.get(i).size();
}
return numOfEnforcingAdmins == 0 || numOfEnforcingAdmins > 1;
}
private boolean isCoexistenceFlagEnabled() {
return DeviceConfig.getBoolean(
NAMESPACE_DEVICE_POLICY_MANAGER,
ENABLE_COEXISTENCE_FLAG,
DEFAULT_ENABLE_COEXISTENCE_FLAG);
}
private <V> boolean checkFor2gFailure(@NonNull PolicyDefinition<V> policyDefinition,
@NonNull EnforcingAdmin enforcingAdmin) {
if (!policyDefinition.getPolicyKey().getIdentifier().equals(

View File

@@ -836,18 +836,13 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
+ "management app's authentication policy";
private static final String NOT_SYSTEM_CALLER_MSG = "Only the system can %s";
// ENABLE_DEVICE_POLICY_ENGINE_FLAG must be enabled before this could be enabled.
private static final String PERMISSION_BASED_ACCESS_EXPERIMENT_FLAG =
"enable_permission_based_access";
private static final boolean DEFAULT_VALUE_PERMISSION_BASED_ACCESS_FLAG = false;
// This must be enabled before PERMISSION_BASED_ACCESS_EXPERIMENT_FLAG is enabled, the reason
// we're not just relying on PERMISSION_BASED_ACCESS_EXPERIMENT_FLAG to enable the policy engine
// is that we might want to enable it before the permission changes are ready if we want to test
// it on DPCs.
// Once this is enabled, it can no longer be disabled in production
private static final String ENABLE_DEVICE_POLICY_ENGINE_FLAG = "enable_device_policy_engine";
private static final boolean DEFAULT_ENABLE_DEVICE_POLICY_ENGINE_FLAG = false;
private static final String ENABLE_DEVICE_POLICY_ENGINE_FOR_FINANCE_FLAG =
"enable_device_policy_engine";
private static final boolean DEFAULT_ENABLE_DEVICE_POLICY_ENGINE_FOR_FINANCE_FLAG = false;
// TODO(b/265683382) remove the flag after rollout.
private static final String KEEP_PROFILES_RUNNING_FLAG = "enable_keep_profiles_running";
@@ -1414,10 +1409,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
&& (owner.getPackageName().equals(packageName))) {
startOwnerService(userHandle, "package-broadcast");
}
if (shouldMigrateToDevicePolicyEngine()) {
migratePoliciesToDevicePolicyEngine();
}
if (isDevicePolicyEngineEnabled()) {
if (isPermissionCheckFlagEnabled()) {
mDevicePolicyEngine.handlePackageChanged(packageName, userHandle);
}
// Persist updates if the removed package was an admin or delegate.
@@ -2121,7 +2113,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
mUserManagerInternal.addUserLifecycleListener(new UserLifecycleListener());
mDeviceManagementResourcesProvider.load();
if (isDevicePolicyEngineEnabled()) {
if (isPermissionCheckFlagEnabled()) {
mDevicePolicyEngine.load();
}
@@ -2617,7 +2609,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
ActiveAdmin profileOwner, boolean newOwner) {
if (newOwner || mInjector.settingsSecureGetIntForUser(
Settings.Secure.UNKNOWN_SOURCES_DEFAULT_REVERSED, 0, userId) != 0) {
if (isDevicePolicyEngineEnabled()) {
if (isPermissionCheckFlagEnabled()) {
mDevicePolicyEngine.setLocalPolicy(
PolicyDefinition.getPolicyDefinitionForUserRestriction(
UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES),
@@ -2645,7 +2637,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
if (defaultRestrictions.equals(admin.defaultEnabledRestrictionsAlreadySet)) {
return; // The same set of default restrictions has been already applied.
}
if (isDevicePolicyEngineEnabled()) {
if (isPermissionCheckFlagEnabled()) {
for (String restriction : defaultRestrictions) {
mDevicePolicyEngine.setLocalPolicy(
PolicyDefinition.getPolicyDefinitionForUserRestriction(restriction),
@@ -3561,7 +3553,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
}
startOwnerService(userId, "start-user");
if (isDevicePolicyEngineEnabled()) {
if (isPermissionCheckFlagEnabled()) {
mDevicePolicyEngine.handleStartUser(userId);
}
}
@@ -3588,7 +3580,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
void handleUnlockUser(int userId) {
startOwnerService(userId, "unlock-user");
if (isDevicePolicyEngineEnabled()) {
if (isPermissionCheckFlagEnabled()) {
mDevicePolicyEngine.handleUnlockUser(userId);
}
}
@@ -3600,7 +3592,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
void handleStopUser(int userId) {
updateNetworkPreferenceForUser(userId, List.of(PreferentialNetworkServiceConfig.DEFAULT));
mDeviceAdminServiceController.stopServicesForUser(userId, /* actionForLog= */ "stop-user");
if (isDevicePolicyEngineEnabled()) {
if (isPermissionCheckFlagEnabled()) {
mDevicePolicyEngine.handleStopUser(userId);
}
}
@@ -3726,11 +3718,6 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
synchronized (getLockObject()) {
checkActiveAdminPrecondition(adminReceiver, info, policy);
mInjector.binderWithCleanCallingIdentity(() -> {
if (!canAddActiveAdminIfPolicyEngineEnabled(
adminReceiver.getPackageName(), userHandle)) {
throw new IllegalStateException("Can't add non-coexistable admin.");
}
final ActiveAdmin existingAdmin
= getActiveAdminUncheckedLocked(adminReceiver, userHandle);
if (!refreshing && existingAdmin != null) {
@@ -7482,7 +7469,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
return;
}
CallerIdentity caller;
if (isPermissionCheckFlagEnabled()) {
if (isPolicyEngineForFinanceFlagEnabled()) {
caller = getCallerIdentity(callerPackageName);
} else {
caller = getCallerIdentity();
@@ -7491,7 +7478,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
boolean calledByProfileOwnerOnOrgOwnedDevice =
isProfileOwnerOfOrganizationOwnedDevice(caller.getUserId());
if (isPermissionCheckFlagEnabled()) {
if (isPolicyEngineForFinanceFlagEnabled()) {
EnforcingAdmin enforcingAdmin = enforcePermissionAndGetEnforcingAdmin(
/*admin=*/ null,
MANAGE_DEVICE_POLICY_WIPE_DATA,
@@ -8848,7 +8835,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
caller = getCallerIdentity(who);
}
if (useDevicePolicyEngine(caller, /* delegateScope= */ null)) {
if (isPermissionCheckFlagEnabled()) {
// The effect of this policy is device-wide.
EnforcingAdmin enforcingAdmin = enforcePermissionAndGetEnforcingAdmin(
who,
@@ -9192,7 +9179,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
final int userHandle = caller.getUserId();
int affectedUserId = parent ? getProfileParentId(userHandle) : userHandle;
synchronized (getLockObject()) {
if (useDevicePolicyEngine(caller, /* delegateScope= */ null)) {
if (isPermissionCheckFlagEnabled()) {
// SUPPORT USES_POLICY_DISABLE_KEYGUARD_FEATURES
EnforcingAdmin admin = enforcePermissionAndGetEnforcingAdmin(
who, MANAGE_DEVICE_POLICY_KEYGUARD, caller.getPackageName(),
@@ -9271,7 +9258,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
synchronized (getLockObject()) {
if (who != null) {
if (useDevicePolicyEngine(caller, /* delegateScope= */ null)) {
if (isPermissionCheckFlagEnabled()) {
EnforcingAdmin admin = getEnforcingAdminForCaller(
who, who.getPackageName());
Integer features = mDevicePolicyEngine.getLocalPolicySetByAdmin(
@@ -9285,7 +9272,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
}
}
if (useDevicePolicyEngine(caller, /* delegateScope= */ null)) {
if (isPermissionCheckFlagEnabled()) {
Integer features = mDevicePolicyEngine.getResolvedPolicy(
PolicyDefinition.KEYGUARD_DISABLED_FEATURES,
affectedUserId);
@@ -11211,14 +11198,14 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
public void addPersistentPreferredActivity(ComponentName who, String callerPackageName,
IntentFilter filter, ComponentName activity) {
CallerIdentity caller;
if (isPermissionCheckFlagEnabled()) {
if (isPolicyEngineForFinanceFlagEnabled()) {
caller = getCallerIdentity(who, callerPackageName);
} else {
caller = getCallerIdentity(who);
}
final int userId = caller.getUserId();
if (useDevicePolicyEngine(caller, /* delegateScope= */ null)) {
if (isPolicyEngineForFinanceFlagEnabled()) {
EnforcingAdmin enforcingAdmin;
if (who == null) {
enforcingAdmin = enforcePermissionAndGetEnforcingAdmin(
@@ -11266,14 +11253,14 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
public void clearPackagePersistentPreferredActivities(ComponentName who,
String callerPackageName, String packageName) {
CallerIdentity caller;
if (isPermissionCheckFlagEnabled()) {
if (isPolicyEngineForFinanceFlagEnabled()) {
caller = getCallerIdentity(who, callerPackageName);
} else {
caller = getCallerIdentity(who);
}
final int userId = caller.getUserId();
if (useDevicePolicyEngine(caller, /* delegateScope= */ null)) {
if (isPolicyEngineForFinanceFlagEnabled()) {
EnforcingAdmin enforcingAdmin;
if (who == null) {
enforcingAdmin = enforcePermissionAndGetEnforcingAdmin(
@@ -11465,7 +11452,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
final CallerIdentity caller = getCallerIdentity(who, callerPackage);
checkCanExecuteOrThrowUnsafe(DevicePolicyManager.OPERATION_SET_APPLICATION_RESTRICTIONS);
if (useDevicePolicyEngine(caller, DELEGATION_APP_RESTRICTIONS)) {
if (isPermissionCheckFlagEnabled()) {
EnforcingAdmin enforcingAdmin = enforcePermissionAndGetEnforcingAdmin(
who,
MANAGE_DEVICE_POLICY_APP_RESTRICTIONS,
@@ -12461,7 +12448,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
final int userId = user.id;
if (isDevicePolicyEngineEnabled()) {
if (isPermissionCheckFlagEnabled()) {
mDevicePolicyEngine.handleUserCreated(user);
}
@@ -12830,7 +12817,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
String packageName) {
final CallerIdentity caller = getCallerIdentity(who, callerPackage);
if (useDevicePolicyEngine(caller, DELEGATION_APP_RESTRICTIONS)) {
if (isPermissionCheckFlagEnabled()) {
EnforcingAdmin enforcingAdmin = enforceCanQueryAndGetEnforcingAdmin(
who,
MANAGE_DEVICE_POLICY_APP_RESTRICTIONS,
@@ -13059,7 +13046,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
boolean parent) {
CallerIdentity caller;
if (isPermissionCheckFlagEnabled()) {
if (isPolicyEngineForFinanceFlagEnabled()) {
caller = getCallerIdentity(who, callerPackage);
} else {
caller = getCallerIdentity(who);
@@ -13071,7 +13058,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
}
checkCanExecuteOrThrowUnsafe(DevicePolicyManager.OPERATION_SET_USER_RESTRICTION);
if (useDevicePolicyEngine(caller, /* delegateScope= */ null)) {
if (isPolicyEngineForFinanceFlagEnabled()) {
int affectedUserId = parent ? getProfileParentId(userId) : userId;
EnforcingAdmin admin = enforcePermissionForUserRestriction(
who,
@@ -13171,14 +13158,14 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
return;
}
int userHandle = caller.getUserId();
checkCanExecuteOrThrowUnsafe(DevicePolicyManager.OPERATION_SET_USER_RESTRICTION);
if (!useDevicePolicyEngine(caller, /* delegateScope= */ null)) {
throw new IllegalStateException("One or more admins are not targeting Android 14.");
if (!isPolicyEngineForFinanceFlagEnabled()) {
throw new IllegalStateException("Feature flag is not enabled.");
}
EnforcingAdmin admin = enforcePermissionForUserRestriction(
/*who=*/ null,
/* who= */ null,
key,
caller.getPackageName(),
caller.getUserId()
@@ -13211,7 +13198,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
}
private void saveUserRestrictionsLocked(int userId) {
if (isDevicePolicyEngineEnabled()) {
if (isPolicyEngineForFinanceFlagEnabled()) {
// User restrictions are handled in the policy engine
return;
}
@@ -13229,6 +13216,10 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
* will be the target user id.
*/
private void pushUserRestrictions(int originatingUserId) {
if (isPolicyEngineForFinanceFlagEnabled()) {
// User restrictions are handled in the policy engine
return;
}
final Bundle global;
final RestrictionsSet local = new RestrictionsSet();
final boolean isDeviceOwner;
@@ -13281,13 +13272,13 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
return null;
}
CallerIdentity caller;
if (isPermissionCheckFlagEnabled()) {
if (isPolicyEngineForFinanceFlagEnabled()) {
caller = getCallerIdentity(who, callerPackage);
} else {
caller = getCallerIdentity(who);
}
if (useDevicePolicyEngine(caller, /* delegateScope= */ null)) {
if (isPolicyEngineForFinanceFlagEnabled()) {
EnforcingAdmin admin = getEnforcingAdminForCaller(who, callerPackage);
return getUserRestrictionsFromPolicyEngine(
admin,
@@ -13475,8 +13466,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
return null;
}
final CallerIdentity caller = getCallerIdentity(callerPackage);
if (!useDevicePolicyEngine(caller, /* delegateScope= */ null)) {
throw new IllegalStateException("One or more admins are not targeting Android 14.");
if (!isPolicyEngineForFinanceFlagEnabled()) {
throw new IllegalStateException("Feature flag is not enabled.");
}
EnforcingAdmin admin = getEnforcingAdminForCaller(/*who=*/ null, caller.getPackageName());
@@ -13544,8 +13535,31 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
Slogf.v(LOG_TAG, "calling pm.setApplicationHiddenSettingAsUser(%s, %b, %d)",
packageName, hidden, userId);
}
result = mInjector.binderWithCleanCallingIdentity(() -> mIPackageManager
.setApplicationHiddenSettingAsUser(packageName, hidden, userId));
if (isPermissionCheckFlagEnabled()) {
EnforcingAdmin admin = getEnforcingAdminForCaller(who, callerPackage);
mDevicePolicyEngine.setLocalPolicy(
PolicyDefinition.APPLICATION_HIDDEN(packageName),
admin,
new BooleanPolicyValue(hidden),
userId);
Boolean resolvedPolicy = mDevicePolicyEngine.getResolvedPolicy(
PolicyDefinition.APPLICATION_HIDDEN(packageName), userId);
result = mInjector.binderWithCleanCallingIdentity(() -> {
try {
// This is a best effort to continue returning the same value that was
// returned before the policy engine migration.
return mInjector.getIPackageManager().getPackageInfo(
packageName, MATCH_UNINSTALLED_PACKAGES, userId) != null
&& (mIPackageManager.getApplicationHiddenSettingAsUser(
packageName, userId) == hidden);
} catch (RemoteException e) {
return false;
}
});
} else {
result = mInjector.binderWithCleanCallingIdentity(() -> mIPackageManager
.setApplicationHiddenSettingAsUser(packageName, hidden, userId));
}
}
DevicePolicyEventLogger
.createEvent(DevicePolicyEnums.SET_APPLICATION_HIDDEN)
@@ -13861,7 +13875,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
boolean uninstallBlocked) {
final CallerIdentity caller = getCallerIdentity(who, callerPackage);
if (useDevicePolicyEngine(caller, DELEGATION_BLOCK_UNINSTALL)) {
if (isPolicyEngineForFinanceFlagEnabled()) {
EnforcingAdmin enforcingAdmin = enforcePermissionAndGetEnforcingAdmin(
who,
MANAGE_DEVICE_POLICY_APPS_CONTROL,
@@ -14415,14 +14429,14 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
throws SecurityException {
Objects.requireNonNull(packages, "packages is null");
CallerIdentity caller;
if (isPermissionCheckFlagEnabled()) {
if (isPolicyEngineForFinanceFlagEnabled()) {
caller = getCallerIdentity(who, callerPackageName);
} else {
caller = getCallerIdentity(who);
}
checkCanExecuteOrThrowUnsafe(DevicePolicyManager.OPERATION_SET_LOCK_TASK_PACKAGES);
if (useDevicePolicyEngine(caller, /* delegateScope= */ null)) {
if (isPolicyEngineForFinanceFlagEnabled()) {
EnforcingAdmin enforcingAdmin;
synchronized (getLockObject()) {
enforcingAdmin = enforceCanCallLockTaskLocked(who, callerPackageName);
@@ -14473,14 +14487,14 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
@Override
public String[] getLockTaskPackages(ComponentName who, String callerPackageName) {
CallerIdentity caller;
if (isPermissionCheckFlagEnabled()) {
if (isPolicyEngineForFinanceFlagEnabled()) {
caller = getCallerIdentity(who, callerPackageName);
} else {
caller = getCallerIdentity(who);
}
final int userHandle = caller.getUserId();
if (useDevicePolicyEngine(caller, /* delegateScope= */ null)) {
if (isPolicyEngineForFinanceFlagEnabled()) {
synchronized (getLockObject()) {
enforceCanQueryLockTaskLocked(who, caller.getPackageName());
}
@@ -14513,8 +14527,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
}
final int userId = mInjector.userHandleGetCallingUserId();
// Is it ok to just check that no active policies exist currently?
if (isDevicePolicyEngineFlagEnabled() && mDevicePolicyEngine.hasActivePolicies()) {
if (isPermissionCheckFlagEnabled()) {
LockTaskPolicy policy = mDevicePolicyEngine.getResolvedPolicy(
PolicyDefinition.LOCK_TASK, userId);
if (policy == null) {
@@ -14540,7 +14553,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
"Cannot use LOCK_TASK_FEATURE_NOTIFICATIONS without LOCK_TASK_FEATURE_HOME");
CallerIdentity caller;
if (isPermissionCheckFlagEnabled()) {
if (isPolicyEngineForFinanceFlagEnabled()) {
caller = getCallerIdentity(who, callerPackageName);
} else {
caller = getCallerIdentity(who);
@@ -14550,7 +14563,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
checkCanExecuteOrThrowUnsafe(DevicePolicyManager.OPERATION_SET_LOCK_TASK_FEATURES);
}
if (useDevicePolicyEngine(caller, /* delegateScope= */ null)) {
if (isPolicyEngineForFinanceFlagEnabled()) {
EnforcingAdmin enforcingAdmin;
synchronized (getLockObject()) {
enforcingAdmin = enforceCanCallLockTaskLocked(who,
@@ -14593,14 +14606,14 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
@Override
public int getLockTaskFeatures(ComponentName who, String callerPackageName) {
CallerIdentity caller;
if (isPermissionCheckFlagEnabled()) {
if (isPolicyEngineForFinanceFlagEnabled()) {
caller = getCallerIdentity(who, callerPackageName);
} else {
caller = getCallerIdentity(who);
}
final int userHandle = caller.getUserId();
if (useDevicePolicyEngine(caller, /* delegateScope= */ null)) {
if (isPolicyEngineForFinanceFlagEnabled()) {
synchronized (getLockObject()) {
enforceCanQueryLockTaskLocked(who, caller.getPackageName());
}
@@ -16360,7 +16373,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
enforcePermissionGrantStateOnFinancedDevice(packageName, permission);
}
}
if (useDevicePolicyEngine(caller, DELEGATION_PERMISSION_GRANT)) {
if (isPermissionCheckFlagEnabled()) {
EnforcingAdmin enforcingAdmin = enforcePermissionAndGetEnforcingAdmin(
admin,
MANAGE_DEVICE_POLICY_RUNTIME_PERMISSIONS,
@@ -17865,11 +17878,6 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
// The removed admin might have disabled camera, so update user
// restrictions.
pushUserRestrictions(userHandle);
// The removed admin might've been stopping the migration if it was targeting pre Android U
if (shouldMigrateToDevicePolicyEngine()) {
migratePoliciesToDevicePolicyEngine();
}
}
@Override
@@ -18547,7 +18555,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
}
final int userId = caller.getUserId();
if (useDevicePolicyEngine(caller, /* delegateScope= */ null)) {
if (isPermissionCheckFlagEnabled()) {
EnforcingAdmin enforcingAdmin = enforcePermissionAndGetEnforcingAdmin(
admin,
MANAGE_DEVICE_POLICY_RESET_PASSWORD,
@@ -18611,7 +18619,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
final int userId = caller.getUserId();
boolean result = false;
if (useDevicePolicyEngine(caller, /* delegateScope= */ null)) {
if (isPermissionCheckFlagEnabled()) {
EnforcingAdmin enforcingAdmin = enforcePermissionAndGetEnforcingAdmin(
admin,
MANAGE_DEVICE_POLICY_RESET_PASSWORD,
@@ -18657,7 +18665,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
}
int userId = caller.getUserId();
if (useDevicePolicyEngine(caller, /* delegateScope= */ null)) {
if (isPermissionCheckFlagEnabled()) {
EnforcingAdmin enforcingAdmin = enforcePermissionAndGetEnforcingAdmin(
admin,
MANAGE_DEVICE_POLICY_RESET_PASSWORD,
@@ -18709,7 +18717,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
boolean result = false;
final String password = passwordOrNull != null ? passwordOrNull : "";
if (useDevicePolicyEngine(caller, /* delegateScope= */ null)) {
if (isPermissionCheckFlagEnabled()) {
EnforcingAdmin enforcingAdmin = enforcePermissionAndGetEnforcingAdmin(
admin,
MANAGE_DEVICE_POLICY_RESET_PASSWORD,
@@ -19898,7 +19906,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
List<String> packages) {
Objects.requireNonNull(packages, "packages is null");
CallerIdentity caller;
if (isPermissionCheckFlagEnabled()) {
if (isPolicyEngineForFinanceFlagEnabled()) {
caller = getCallerIdentity(who, callerPackageName);
} else {
caller = getCallerIdentity(who);
@@ -19906,7 +19914,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
checkCanExecuteOrThrowUnsafe(
DevicePolicyManager.OPERATION_SET_USER_CONTROL_DISABLED_PACKAGES);
if (useDevicePolicyEngine(caller, /* delegateScope= */ null)) {
if (isPolicyEngineForFinanceFlagEnabled()) {
EnforcingAdmin enforcingAdmin = enforcePermissionAndGetEnforcingAdmin(
who,
MANAGE_DEVICE_POLICY_APPS_CONTROL,
@@ -19980,13 +19988,13 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
public List<String> getUserControlDisabledPackages(ComponentName who,
String callerPackageName) {
CallerIdentity caller;
if (isPermissionCheckFlagEnabled()) {
if (isPolicyEngineForFinanceFlagEnabled()) {
caller = getCallerIdentity(who, callerPackageName);
} else {
caller = getCallerIdentity(who);
}
if (useDevicePolicyEngine(caller, /* delegateScope= */ null)) {
if (isPolicyEngineForFinanceFlagEnabled()) {
enforceCanQuery(
MANAGE_DEVICE_POLICY_APPS_CONTROL,
caller.getPackageName(),
@@ -22069,7 +22077,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
}
private void handleFinancedDeviceKioskRoleChange() {
if (!isDevicePolicyEngineEnabled()) {
if (!isPermissionCheckFlagEnabled()) {
return;
}
Slog.i(LOG_TAG, "Handling action " + ACTION_DEVICE_FINANCING_STATE_CHANGED);
@@ -22848,6 +22856,13 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
DEFAULT_VALUE_PERMISSION_BASED_ACCESS_FLAG);
}
private boolean isPolicyEngineForFinanceFlagEnabled() {
return DeviceConfig.getBoolean(
NAMESPACE_DEVICE_POLICY_MANAGER,
ENABLE_DEVICE_POLICY_ENGINE_FOR_FINANCE_FLAG,
DEFAULT_ENABLE_DEVICE_POLICY_ENGINE_FOR_FINANCE_FLAG);
}
private static boolean isKeepProfilesRunningFlagEnabled() {
return DeviceConfig.getBoolean(
NAMESPACE_DEVICE_POLICY_MANAGER,
@@ -23186,36 +23201,9 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
});
}
// TODO(b/266808047): handle DeviceAdmin migration when there is no DPCs on the device
private boolean shouldMigrateToDevicePolicyEngine() {
return mInjector.binderWithCleanCallingIdentity(() -> {
if (!isDevicePolicyEngineFlagEnabled()) {
return false;
}
if (mOwners.isMigratedToPolicyEngine()) {
return false;
}
// We're only checking if existing DPCs are not targeting U, regardless of what
// DeviceAdmins are targeting, as they can access very limited APIs, and we'll ensure
// that these APIs maintain the current behaviour of strictest applies.
boolean hasDPCs = false;
for (UserInfo userInfo : mUserManager.getUsers()) {
List<ComponentName> activeAdmins = getActiveAdmins(userInfo.id);
if (activeAdmins == null) {
continue;
}
for (ComponentName admin : activeAdmins) {
if ((isProfileOwner(admin, userInfo.id) || isDeviceOwner(admin, userInfo.id))) {
if (!mInjector.isChangeEnabled(ENABLE_COEXISTENCE_CHANGE,
admin.getPackageName(), userInfo.id)) {
return false;
}
hasDPCs = true;
}
}
}
return hasDPCs;
});
return mInjector.binderWithCleanCallingIdentity(() ->
isPermissionCheckFlagEnabled() && !mOwners.isMigratedToPolicyEngine());
}
/**
@@ -23429,40 +23417,6 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
return admins;
}
private boolean useDevicePolicyEngine(CallerIdentity caller, @Nullable String delegateScope) {
return isDevicePolicyEngineEnabled();
}
private boolean isDevicePolicyEngineEnabled() {
return isDevicePolicyEngineFlagEnabled() && isPermissionCheckFlagEnabled();
}
private boolean isDevicePolicyEngineFlagEnabled() {
return DeviceConfig.getBoolean(
NAMESPACE_DEVICE_POLICY_MANAGER,
ENABLE_DEVICE_POLICY_ENGINE_FLAG,
DEFAULT_ENABLE_DEVICE_POLICY_ENGINE_FLAG);
}
private boolean hasDPCsNotSupportingCoexistence() {
return mInjector.binderWithCleanCallingIdentity(() -> {
for (UserInfo userInfo : mUserManager.getUsers()) {
List<ComponentName> activeAdmins = getActiveAdmins(userInfo.id);
if (activeAdmins == null) {
continue;
}
for (ComponentName admin : activeAdmins) {
if ((isProfileOwner(admin, userInfo.id) || isDeviceOwner(admin, userInfo.id))
&& !mInjector.isChangeEnabled(ENABLE_COEXISTENCE_CHANGE,
admin.getPackageName(), userInfo.id)) {
return true;
}
}
}
return false;
});
}
// TODO: this can actually accept an EnforcingAdmin that gets created in the permission
// check method.
private boolean isCallerActiveAdminOrDelegate(
@@ -23500,25 +23454,6 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
}
}
// TODO(b/266808047): This will return false for DeviceAdmins not targetting U, which is
// inconsistent with the migration logic that allows migration with old DeviceAdmins.
private boolean canAddActiveAdminIfPolicyEngineEnabled(String packageName, int userId) {
if (!isDevicePolicyEngineFlagEnabled()) {
return true;
}
if (hasDPCsNotSupportingCoexistence()) {
return true;
}
if (mInjector.isChangeEnabled(ENABLE_COEXISTENCE_CHANGE, packageName, userId)) {
// This will always return true unless we turn off coexistence, in which case it will
// return true if no current admins exist, or more than one admin exist
return mDevicePolicyEngine.canAdminAddPolicies(packageName, userId);
}
// Is it ok to just check that no active policies exist currently, or should we return false
// if the policy engine was ever used?
return !mDevicePolicyEngine.hasActivePolicies();
}
@Override
public boolean isDeviceFinanced(String callerPackageName) {
CallerIdentity caller = getCallerIdentity(callerPackageName);

View File

@@ -226,8 +226,7 @@ final class PolicyDefinition<V> {
* Passing in {@code null} for {@code packageName} will return
* {@link #GENERIC_APPLICATION_RESTRICTIONS}.
*/
static PolicyDefinition<Bundle> APPLICATION_RESTRICTIONS(
String packageName) {
static PolicyDefinition<Bundle> APPLICATION_RESTRICTIONS(String packageName) {
if (packageName == null) {
return GENERIC_APPLICATION_RESTRICTIONS;
}
@@ -254,6 +253,34 @@ final class PolicyDefinition<V> {
(Integer value, Context context, Integer userId, PolicyKey policyKey) -> true,
new IntegerPolicySerializer());
// This is saved in the static map sPolicyDefinitions so that we're able to reconstruct the
// actual policy with the correct arguments (i.e. packageName) when reading the policies from
// xml.
static PolicyDefinition<Boolean> GENERIC_APPLICATION_HIDDEN =
new PolicyDefinition<>(
new PackagePolicyKey(
DevicePolicyIdentifiers.APPLICATION_HIDDEN_POLICY),
// TODO(b/276713779): Don't need to take in a resolution mechanism since its
// never used, but might need some refactoring to not always assume a non-null
// mechanism.
TRUE_MORE_RESTRICTIVE,
POLICY_FLAG_LOCAL_ONLY_POLICY,
PolicyEnforcerCallbacks::setApplicationHidden,
new BooleanPolicySerializer());
/**
* Passing in {@code null} for {@code packageName} will return
* {@link #GENERIC_APPLICATION_HIDDEN}.
*/
static PolicyDefinition<Boolean> APPLICATION_HIDDEN(String packageName) {
if (packageName == null) {
return GENERIC_APPLICATION_HIDDEN;
}
return GENERIC_APPLICATION_HIDDEN.createPolicyDefinition(
new PackagePolicyKey(
DevicePolicyIdentifiers.APPLICATION_HIDDEN_POLICY, packageName));
}
private static final Map<String, PolicyDefinition<?>> POLICY_DEFINITIONS = new HashMap<>();
private static Map<String, Integer> USER_RESTRICTION_FLAGS = new HashMap<>();
@@ -272,6 +299,10 @@ final class PolicyDefinition<V> {
GENERIC_APPLICATION_RESTRICTIONS);
POLICY_DEFINITIONS.put(DevicePolicyIdentifiers.RESET_PASSWORD_TOKEN_POLICY,
RESET_PASSWORD_TOKEN);
POLICY_DEFINITIONS.put(DevicePolicyIdentifiers.KEYGUARD_DISABLED_FEATURES_POLICY,
KEYGUARD_DISABLED_FEATURES);
POLICY_DEFINITIONS.put(DevicePolicyIdentifiers.APPLICATION_HIDDEN_POLICY,
GENERIC_APPLICATION_HIDDEN);
// User Restriction Policies
USER_RESTRICTION_FLAGS.put(UserManager.DISALLOW_MODIFY_ACCOUNTS, /* flags= */ 0);

View File

@@ -73,7 +73,7 @@ final class PolicyEnforcerCallbacks {
return Boolean.TRUE.equals(Binder.withCleanCallingIdentity(() -> {
if (!(policyKey instanceof PackagePermissionPolicyKey)) {
throw new IllegalArgumentException("policyKey is not of type "
+ "PermissionGrantStatePolicyKey");
+ "PermissionGrantStatePolicyKey, passed in policyKey is: " + policyKey);
}
PackagePermissionPolicyKey parsedKey = (PackagePermissionPolicyKey) policyKey;
Objects.requireNonNull(parsedKey.getPermissionName());
@@ -165,7 +165,7 @@ final class PolicyEnforcerCallbacks {
try {
if (!(policyKey instanceof IntentFilterPolicyKey)) {
throw new IllegalArgumentException("policyKey is not of type "
+ "IntentFilterPolicyKey");
+ "IntentFilterPolicyKey, passed in policyKey is: " + policyKey);
}
IntentFilterPolicyKey parsedKey =
(IntentFilterPolicyKey) policyKey;
@@ -193,7 +193,7 @@ final class PolicyEnforcerCallbacks {
return Boolean.TRUE.equals(Binder.withCleanCallingIdentity(() -> {
if (!(policyKey instanceof PackagePolicyKey)) {
throw new IllegalArgumentException("policyKey is not of type "
+ "PackagePolicyKey");
+ "PackagePolicyKey, passed in policyKey is: " + policyKey);
}
PackagePolicyKey parsedKey = (PackagePolicyKey) policyKey;
String packageName = Objects.requireNonNull(parsedKey.getPackageName());
@@ -211,7 +211,7 @@ final class PolicyEnforcerCallbacks {
return Boolean.TRUE.equals(Binder.withCleanCallingIdentity(() -> {
if (!(policyKey instanceof UserRestrictionPolicyKey)) {
throw new IllegalArgumentException("policyKey is not of type "
+ "UserRestrictionPolicyKey");
+ "UserRestrictionPolicyKey, passed in policyKey is: " + policyKey);
}
UserRestrictionPolicyKey parsedKey =
(UserRestrictionPolicyKey) policyKey;
@@ -221,4 +221,20 @@ final class PolicyEnforcerCallbacks {
return true;
}));
}
static boolean setApplicationHidden(
@Nullable Boolean hide, @NonNull Context context, int userId,
@NonNull PolicyKey policyKey) {
return Boolean.TRUE.equals(Binder.withCleanCallingIdentity(() -> {
if (!(policyKey instanceof PackagePolicyKey)) {
throw new IllegalArgumentException("policyKey is not of type "
+ "PackagePolicyKey, passed in policyKey is: " + policyKey);
}
PackagePolicyKey parsedKey = (PackagePolicyKey) policyKey;
String packageName = Objects.requireNonNull(parsedKey.getPackageName());
IPackageManager packageManager = AppGlobals.getPackageManager();
return packageManager.setApplicationHiddenSettingAsUser(
packageName, hide != null && hide, userId);
}));
}
}