Profile owners on a user can communicate with device owners
Allow device owners and profile owners on a user
to communicate with each other, rather than restricting
it to device owners and managed profile owners as it is
at the moment
Bug: 34429083
Test: runtest -c com.android.server.devicepolicy.DevicePolicyManagerTest frameworks-services
Test: cts-tradefed run cts -a armeabi-v7a --module DevicePolicyManager --test com.android.cts.devicepolicy.DeviceOwnerPlusManagedProfileTest
Change-Id: I81561a9838c3ccb623354a1b718da2fc6a5af1fe
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 0ff8550..5b78ce8 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -7587,8 +7587,8 @@
}
/**
- * Called by a device owner to bind to a service from a profile owner of a managed profile or
- * vice versa. See {@link #getBindDeviceAdminTargetUsers} for a definition of which
+ * Called by a device owner to bind to a service from a profile owner or vice versa.
+ * See {@link #getBindDeviceAdminTargetUsers} for a definition of which
* device/profile owners are allowed to bind to services of another profile/device owner.
* <p>
* The service must be unexported. Note that the {@link Context} used to obtain this
@@ -7634,14 +7634,10 @@
* Returns the list of target users that the calling device or profile owner can use when
* calling {@link #bindDeviceAdminServiceAsUser}.
* <p>
- * A device owner can bind to a service from a profile owner of a managed profile and
- * vice versa, provided that:
+ * A device owner can bind to a service from a profile owner and vice versa, provided that:
* <ul>
* <li>Both belong to the same package name.
- * <li>The managed profile is a profile of the user where the device owner is set.
- * See {@link UserManager#getUserProfiles()}
- * <li>Both users are affiliated.
- * See {@link #setAffiliationIds}.
+ * <li>Both users are affiliated. See {@link #setAffiliationIds}.
* </ul>
*/
public @NonNull List<UserHandle> getBindDeviceAdminTargetUsers(@NonNull ComponentName admin) {
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index af78154..d30a823 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -9906,7 +9906,7 @@
private boolean areAllUsersAffiliatedWithDeviceLocked() {
final long ident = mInjector.binderClearCallingIdentity();
try {
- final List<UserInfo> userInfos = mUserManager.getUsers();
+ final List<UserInfo> userInfos = mUserManager.getUsers(/*excludeDying=*/ true);
for (int i = 0; i < userInfos.size(); i++) {
int userId = userInfos.get(i).id;
if (!isUserAffiliatedWithDeviceLocked(userId)) {
@@ -10314,47 +10314,51 @@
return Collections.emptyList();
}
Preconditions.checkNotNull(admin);
- ArrayList<UserHandle> targetUsers = new ArrayList<>();
synchronized (this) {
- ActiveAdmin callingOwner = getActiveAdminForCallerLocked(
- admin, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
+ getActiveAdminForCallerLocked(admin, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
final int callingUserId = mInjector.userHandleGetCallingUserId();
- final boolean isCallerDeviceOwner = isDeviceOwner(callingOwner);
- final boolean isCallerManagedProfile = isManagedProfile(callingUserId);
- if ((!isCallerDeviceOwner && !isCallerManagedProfile)
- || !isUserAffiliatedWithDeviceLocked(callingUserId)) {
- return targetUsers;
- }
-
final long callingIdentity = mInjector.binderClearCallingIdentity();
try {
- String callingOwnerPackage = callingOwner.info.getComponent().getPackageName();
- for (int userId : mUserManager.getProfileIdsWithDisabled(callingUserId)) {
- if (userId == callingUserId) {
- continue;
+ ArrayList<UserHandle> targetUsers = new ArrayList<>();
+ if (!isDeviceOwner(admin, callingUserId)) {
+ // Profile owners can only bind to the device owner.
+ if (canUserBindToDeviceOwnerLocked(callingUserId)) {
+ targetUsers.add(UserHandle.of(mOwners.getDeviceOwnerUserId()));
}
-
- // We only allow the device owner and a managed profile owner to bind to each
- // other.
- if ((isCallerManagedProfile && userId == mOwners.getDeviceOwnerUserId())
- || (isCallerDeviceOwner && isManagedProfile(userId))) {
- String targetOwnerPackage = getOwnerPackageNameForUserLocked(userId);
-
- // Both must be the same package and be affiliated in order to bind.
- if (callingOwnerPackage.equals(targetOwnerPackage)
- && isUserAffiliatedWithDeviceLocked(userId)) {
+ } else {
+ // Caller is the device owner: Look for profile owners that it can bind to.
+ final List<UserInfo> userInfos = mUserManager.getUsers(/*excludeDying=*/ true);
+ for (int i = 0; i < userInfos.size(); i++) {
+ final int userId = userInfos.get(i).id;
+ if (userId != callingUserId && canUserBindToDeviceOwnerLocked(userId)) {
targetUsers.add(UserHandle.of(userId));
}
}
}
+
+ return targetUsers;
} finally {
mInjector.binderRestoreCallingIdentity(callingIdentity);
}
}
+ }
- return targetUsers;
+ private boolean canUserBindToDeviceOwnerLocked(int userId) {
+ // There has to be a device owner, under another user id.
+ if (!mOwners.hasDeviceOwner() || userId == mOwners.getDeviceOwnerUserId()) {
+ return false;
+ }
+
+ // The user must have a profile owner that belongs to the same package as the device owner.
+ if (!mOwners.hasProfileOwner(userId) || !TextUtils.equals(
+ mOwners.getDeviceOwnerPackageName(), mOwners.getProfileOwnerPackage(userId))) {
+ return false;
+ }
+
+ // The user must be affiliated.
+ return isUserAffiliatedWithDeviceLocked(userId);
}
/**