Merge "send broadcast to admins on financed role changing" into udc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
24fa99c448
@@ -8049,6 +8049,7 @@ package android.app.admin {
|
|||||||
field public static final String ACTION_APPLICATION_DELEGATION_SCOPES_CHANGED = "android.app.action.APPLICATION_DELEGATION_SCOPES_CHANGED";
|
field public static final String ACTION_APPLICATION_DELEGATION_SCOPES_CHANGED = "android.app.action.APPLICATION_DELEGATION_SCOPES_CHANGED";
|
||||||
field public static final String ACTION_CHECK_POLICY_COMPLIANCE = "android.app.action.CHECK_POLICY_COMPLIANCE";
|
field public static final String ACTION_CHECK_POLICY_COMPLIANCE = "android.app.action.CHECK_POLICY_COMPLIANCE";
|
||||||
field public static final String ACTION_DEVICE_ADMIN_SERVICE = "android.app.action.DEVICE_ADMIN_SERVICE";
|
field public static final String ACTION_DEVICE_ADMIN_SERVICE = "android.app.action.DEVICE_ADMIN_SERVICE";
|
||||||
|
field public static final String ACTION_DEVICE_FINANCING_STATE_CHANGED = "android.app.admin.action.DEVICE_FINANCING_STATE_CHANGED";
|
||||||
field public static final String ACTION_DEVICE_OWNER_CHANGED = "android.app.action.DEVICE_OWNER_CHANGED";
|
field public static final String ACTION_DEVICE_OWNER_CHANGED = "android.app.action.DEVICE_OWNER_CHANGED";
|
||||||
field public static final String ACTION_DEVICE_POLICY_RESOURCE_UPDATED = "android.app.action.DEVICE_POLICY_RESOURCE_UPDATED";
|
field public static final String ACTION_DEVICE_POLICY_RESOURCE_UPDATED = "android.app.action.DEVICE_POLICY_RESOURCE_UPDATED";
|
||||||
field public static final String ACTION_GET_PROVISIONING_MODE = "android.app.action.GET_PROVISIONING_MODE";
|
field public static final String ACTION_GET_PROVISIONING_MODE = "android.app.action.GET_PROVISIONING_MODE";
|
||||||
|
|||||||
@@ -57,6 +57,7 @@ import static com.android.internal.util.function.pooled.PooledLambda.obtainMessa
|
|||||||
|
|
||||||
import android.Manifest.permission;
|
import android.Manifest.permission;
|
||||||
import android.accounts.Account;
|
import android.accounts.Account;
|
||||||
|
import android.annotation.BroadcastBehavior;
|
||||||
import android.annotation.CallbackExecutor;
|
import android.annotation.CallbackExecutor;
|
||||||
import android.annotation.ColorInt;
|
import android.annotation.ColorInt;
|
||||||
import android.annotation.IntDef;
|
import android.annotation.IntDef;
|
||||||
@@ -3998,6 +3999,27 @@ public class DevicePolicyManager {
|
|||||||
public static final String EXTRA_RESOURCE_IDS =
|
public static final String EXTRA_RESOURCE_IDS =
|
||||||
"android.app.extra.RESOURCE_IDS";
|
"android.app.extra.RESOURCE_IDS";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Broadcast Action: Broadcast sent to indicate that the device financing state has changed.
|
||||||
|
*
|
||||||
|
* <p>This occurs when, for example, a financing kiosk app has been added or removed.
|
||||||
|
*
|
||||||
|
* <p>To query the current device financing state see {@link #isDeviceFinanced}.
|
||||||
|
*
|
||||||
|
* <p>This will be delivered to the following apps if they include a receiver for this action
|
||||||
|
* in their manifest:
|
||||||
|
* <ul>
|
||||||
|
* <li>Device owner admins.
|
||||||
|
* <li>Organization-owned profile owner admins
|
||||||
|
* <li>The supervision app
|
||||||
|
* <li>The device management role holder
|
||||||
|
* </ul>
|
||||||
|
*/
|
||||||
|
@SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION)
|
||||||
|
@BroadcastBehavior(explicitOnly = true, includeBackground = true)
|
||||||
|
public static final String ACTION_DEVICE_FINANCING_STATE_CHANGED =
|
||||||
|
"android.app.admin.action.DEVICE_FINANCING_STATE_CHANGED";
|
||||||
|
|
||||||
/** Allow the user to choose whether to enable MTE on the device. */
|
/** Allow the user to choose whether to enable MTE on the device. */
|
||||||
public static final int MTE_NOT_CONTROLLED_BY_POLICY = 0;
|
public static final int MTE_NOT_CONTROLLED_BY_POLICY = 0;
|
||||||
|
|
||||||
|
|||||||
@@ -95,6 +95,7 @@ import static android.app.admin.DeviceAdminReceiver.ACTION_COMPLIANCE_ACKNOWLEDG
|
|||||||
import static android.app.admin.DeviceAdminReceiver.EXTRA_TRANSFER_OWNERSHIP_ADMIN_EXTRAS_BUNDLE;
|
import static android.app.admin.DeviceAdminReceiver.EXTRA_TRANSFER_OWNERSHIP_ADMIN_EXTRAS_BUNDLE;
|
||||||
import static android.app.admin.DevicePolicyIdentifiers.AUTO_TIMEZONE_POLICY;
|
import static android.app.admin.DevicePolicyIdentifiers.AUTO_TIMEZONE_POLICY;
|
||||||
import static android.app.admin.DevicePolicyManager.ACTION_CHECK_POLICY_COMPLIANCE;
|
import static android.app.admin.DevicePolicyManager.ACTION_CHECK_POLICY_COMPLIANCE;
|
||||||
|
import static android.app.admin.DevicePolicyManager.ACTION_DEVICE_FINANCING_STATE_CHANGED;
|
||||||
import static android.app.admin.DevicePolicyManager.ACTION_DEVICE_POLICY_RESOURCE_UPDATED;
|
import static android.app.admin.DevicePolicyManager.ACTION_DEVICE_POLICY_RESOURCE_UPDATED;
|
||||||
import static android.app.admin.DevicePolicyManager.ACTION_MANAGED_PROFILE_PROVISIONED;
|
import static android.app.admin.DevicePolicyManager.ACTION_MANAGED_PROFILE_PROVISIONED;
|
||||||
import static android.app.admin.DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE;
|
import static android.app.admin.DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE;
|
||||||
@@ -15440,7 +15441,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
|
|||||||
Slogf.i(LOG_TAG, "Sending %s broadcast to manifest receivers.", intent.getAction());
|
Slogf.i(LOG_TAG, "Sending %s broadcast to manifest receivers.", intent.getAction());
|
||||||
broadcastIntentToCrossProfileManifestReceivers(
|
broadcastIntentToCrossProfileManifestReceivers(
|
||||||
intent, parentHandle, requiresPermission);
|
intent, parentHandle, requiresPermission);
|
||||||
broadcastIntentToDevicePolicyManagerRoleHolder(intent, parentHandle);
|
broadcastExplicitIntentToRoleHolder(
|
||||||
|
intent, RoleManager.ROLE_DEVICE_POLICY_MANAGEMENT, parentHandle);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -15481,36 +15483,6 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void broadcastIntentToDevicePolicyManagerRoleHolder(
|
|
||||||
Intent intent, UserHandle userHandle) {
|
|
||||||
final int userId = userHandle.getIdentifier();
|
|
||||||
final String packageName = getDevicePolicyManagementRoleHolderPackageName(mContext);
|
|
||||||
if (packageName == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
final Intent packageIntent = new Intent(intent)
|
|
||||||
.setPackage(packageName);
|
|
||||||
final List<ResolveInfo> receivers = mIPackageManager.queryIntentReceivers(
|
|
||||||
packageIntent,
|
|
||||||
/* resolvedType= */ null,
|
|
||||||
STOCK_PM_FLAGS,
|
|
||||||
userId).getList();
|
|
||||||
if (receivers.isEmpty()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
for (ResolveInfo receiver : receivers) {
|
|
||||||
final Intent componentIntent = new Intent(packageIntent)
|
|
||||||
.setComponent(receiver.getComponentInfo().getComponentName())
|
|
||||||
.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
|
|
||||||
mContext.sendBroadcastAsUser(componentIntent, userHandle);
|
|
||||||
}
|
|
||||||
} catch (RemoteException ex) {
|
|
||||||
Slogf.w(LOG_TAG, "Cannot get list of broadcast receivers for %s because: %s.",
|
|
||||||
intent.getAction(), ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks whether the package {@code packageName} has the {@code MODIFY_QUIET_MODE}
|
* Checks whether the package {@code packageName} has the {@code MODIFY_QUIET_MODE}
|
||||||
* permission granted for the user {@code userId}.
|
* permission granted for the user {@code userId}.
|
||||||
@@ -20718,7 +20690,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
|
|||||||
|
|
||||||
private void maybeInstallDevicePolicyManagementRoleHolderInUser(int targetUserId) {
|
private void maybeInstallDevicePolicyManagementRoleHolderInUser(int targetUserId) {
|
||||||
String devicePolicyManagerRoleHolderPackageName =
|
String devicePolicyManagerRoleHolderPackageName =
|
||||||
getDevicePolicyManagementRoleHolderPackageName(mContext);
|
getRoleHolderPackageName(mContext, RoleManager.ROLE_DEVICE_POLICY_MANAGEMENT);
|
||||||
if (devicePolicyManagerRoleHolderPackageName == null) {
|
if (devicePolicyManagerRoleHolderPackageName == null) {
|
||||||
Slogf.d(LOG_TAG, "No device policy management role holder specified.");
|
Slogf.d(LOG_TAG, "No device policy management role holder specified.");
|
||||||
return;
|
return;
|
||||||
@@ -20744,14 +20716,24 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If multiple packages hold the role, returns the first package in the list.
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
private String getRoleHolderPackageName(Context context, String role) {
|
||||||
|
return getRoleHolderPackageNameOnUser(context, role, Process.myUserHandle());
|
||||||
|
}
|
||||||
|
|
||||||
private String getDevicePolicyManagementRoleHolderPackageName(Context context) {
|
/**
|
||||||
|
* If multiple packages hold the role, returns the first package in the list.
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
private String getRoleHolderPackageNameOnUser(Context context, String role, UserHandle user) {
|
||||||
RoleManager roleManager = context.getSystemService(RoleManager.class);
|
RoleManager roleManager = context.getSystemService(RoleManager.class);
|
||||||
|
|
||||||
// Calling identity needs to be cleared as this method is used in the permissions checks.
|
// Calling identity needs to be cleared as this method is used in the permissions checks.
|
||||||
return mInjector.binderWithCleanCallingIdentity(() -> {
|
return mInjector.binderWithCleanCallingIdentity(() -> {
|
||||||
List<String> roleHolders =
|
List<String> roleHolders = roleManager.getRoleHoldersAsUser(role, user);
|
||||||
roleManager.getRoleHolders(RoleManager.ROLE_DEVICE_POLICY_MANAGEMENT);
|
|
||||||
if (roleHolders.isEmpty()) {
|
if (roleHolders.isEmpty()) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -20762,7 +20744,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
|
|||||||
private boolean isCallerDevicePolicyManagementRoleHolder(CallerIdentity caller) {
|
private boolean isCallerDevicePolicyManagementRoleHolder(CallerIdentity caller) {
|
||||||
int callerUid = caller.getUid();
|
int callerUid = caller.getUid();
|
||||||
String devicePolicyManagementRoleHolderPackageName =
|
String devicePolicyManagementRoleHolderPackageName =
|
||||||
getDevicePolicyManagementRoleHolderPackageName(mContext);
|
getRoleHolderPackageName(mContext, RoleManager.ROLE_DEVICE_POLICY_MANAGEMENT);
|
||||||
int roleHolderUid = mInjector.getPackageManagerInternal().getPackageUid(
|
int roleHolderUid = mInjector.getPackageManagerInternal().getPackageUid(
|
||||||
devicePolicyManagementRoleHolderPackageName, 0, caller.getUserId());
|
devicePolicyManagementRoleHolderPackageName, 0, caller.getUserId());
|
||||||
|
|
||||||
@@ -21830,15 +21812,23 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void register() {
|
public void register() {
|
||||||
mRm.addOnRoleHoldersChangedListenerAsUser(mExecutor, this, UserHandle.SYSTEM);
|
mRm.addOnRoleHoldersChangedListenerAsUser(mExecutor, this, UserHandle.ALL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onRoleHoldersChanged(@NonNull String roleName, @NonNull UserHandle user) {
|
public void onRoleHoldersChanged(@NonNull String roleName, @NonNull UserHandle user) {
|
||||||
if (!RoleManager.ROLE_DEVICE_POLICY_MANAGEMENT.equals(roleName)) {
|
if (RoleManager.ROLE_DEVICE_POLICY_MANAGEMENT.equals(roleName)) {
|
||||||
|
handleDevicePolicyManagementRoleChange(user);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
String newRoleHolder = getRoleHolder();
|
if (RoleManager.ROLE_FINANCED_DEVICE_KIOSK.equals(roleName)) {
|
||||||
|
handleFinancedDeviceKioskRoleChange();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handleDevicePolicyManagementRoleChange(UserHandle user) {
|
||||||
|
String newRoleHolder = getDeviceManagementRoleHolder(user);
|
||||||
if (isDefaultRoleHolder(newRoleHolder)) {
|
if (isDefaultRoleHolder(newRoleHolder)) {
|
||||||
Slogf.i(LOG_TAG,
|
Slogf.i(LOG_TAG,
|
||||||
"onRoleHoldersChanged: Default role holder is set, returning early");
|
"onRoleHoldersChanged: Default role holder is set, returning early");
|
||||||
@@ -21873,9 +21863,42 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getRoleHolder() {
|
private void handleFinancedDeviceKioskRoleChange() {
|
||||||
return DevicePolicyManagerService.this.getDevicePolicyManagementRoleHolderPackageName(
|
if (!isDevicePolicyEngineEnabled()) {
|
||||||
mContext);
|
return;
|
||||||
|
}
|
||||||
|
Slog.i(LOG_TAG, "Handling action " + ACTION_DEVICE_FINANCING_STATE_CHANGED);
|
||||||
|
Intent intent = new Intent(ACTION_DEVICE_FINANCING_STATE_CHANGED);
|
||||||
|
mInjector.binderWithCleanCallingIdentity(() -> {
|
||||||
|
for (UserInfo userInfo : mUserManager.getUsers()) {
|
||||||
|
UserHandle user = userInfo.getUserHandle();
|
||||||
|
broadcastExplicitIntentToRoleHolder(
|
||||||
|
intent, RoleManager.ROLE_SYSTEM_SUPERVISION, user);
|
||||||
|
broadcastExplicitIntentToRoleHolder(
|
||||||
|
intent, RoleManager.ROLE_DEVICE_POLICY_MANAGEMENT, user);
|
||||||
|
ActiveAdmin admin = getDeviceOrProfileOwnerAdminLocked(user.getIdentifier());
|
||||||
|
if (admin == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!isProfileOwnerOfOrganizationOwnedDevice(
|
||||||
|
admin.info.getComponent(), user.getIdentifier())
|
||||||
|
&& !isDeviceOwner(admin)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// Don't send the broadcast twice if the DPC is the same package as the
|
||||||
|
// DMRH
|
||||||
|
if (admin.info.getPackageName().equals(getDeviceManagementRoleHolder(user))) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
broadcastExplicitIntentToPackage(
|
||||||
|
intent, admin.info.getPackageName(), admin.getUserHandle());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getDeviceManagementRoleHolder(UserHandle user) {
|
||||||
|
return DevicePolicyManagerService.this.getRoleHolderPackageNameOnUser(
|
||||||
|
mContext, RoleManager.ROLE_DEVICE_POLICY_MANAGEMENT, user);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isDefaultRoleHolder(String packageName) {
|
private boolean isDefaultRoleHolder(String packageName) {
|
||||||
@@ -21935,6 +21958,40 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void broadcastExplicitIntentToRoleHolder(
|
||||||
|
Intent intent, String role, UserHandle userHandle) {
|
||||||
|
String packageName = getRoleHolderPackageNameOnUser(mContext, role, userHandle);
|
||||||
|
if (packageName == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
broadcastExplicitIntentToPackage(intent, packageName, userHandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void broadcastExplicitIntentToPackage(
|
||||||
|
Intent intent, String packageName, UserHandle userHandle) {
|
||||||
|
int userId = userHandle.getIdentifier();
|
||||||
|
if (packageName == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Intent packageIntent = new Intent(intent)
|
||||||
|
.setPackage(packageName);
|
||||||
|
List<ResolveInfo> receivers = mContext.getPackageManager().queryBroadcastReceiversAsUser(
|
||||||
|
packageIntent,
|
||||||
|
PackageManager.ResolveInfoFlags.of(PackageManager.GET_RECEIVERS),
|
||||||
|
userId);
|
||||||
|
if (receivers.isEmpty()) {
|
||||||
|
Slog.i(LOG_TAG, "Found no receivers to handle intent " + intent
|
||||||
|
+ " in package " + packageName);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (ResolveInfo receiver : receivers) {
|
||||||
|
Intent componentIntent = new Intent(packageIntent)
|
||||||
|
.setComponent(receiver.getComponentInfo().getComponentName())
|
||||||
|
.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
|
||||||
|
mContext.sendBroadcastAsUser(componentIntent, userHandle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<UserHandle> getPolicyManagedProfiles(@NonNull UserHandle user) {
|
public List<UserHandle> getPolicyManagedProfiles(@NonNull UserHandle user) {
|
||||||
Preconditions.checkCallAuthorization(hasCallingOrSelfPermission(
|
Preconditions.checkCallAuthorization(hasCallingOrSelfPermission(
|
||||||
|
|||||||
Reference in New Issue
Block a user