From 2f897917fd47c07c11900daf1df75c45154aaff7 Mon Sep 17 00:00:00 2001 From: Esteban Talavera Date: Thu, 26 Jan 2017 10:30:48 +0000 Subject: [PATCH] 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 --- .../app/admin/DevicePolicyManager.java | 12 ++-- .../DevicePolicyManagerService.java | 56 ++++++++++--------- 2 files changed, 34 insertions(+), 34 deletions(-) diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java index 0ff855059f932..5b78ce8837639 100644 --- a/core/java/android/app/admin/DevicePolicyManager.java +++ b/core/java/android/app/admin/DevicePolicyManager.java @@ -7587,8 +7587,8 @@ public class DevicePolicyManager { } /** - * 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. *

* The service must be unexported. Note that the {@link Context} used to obtain this @@ -7634,14 +7634,10 @@ public class DevicePolicyManager { * Returns the list of target users that the calling device or profile owner can use when * calling {@link #bindDeviceAdminServiceAsUser}. *

- * 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: *

*/ public @NonNull List 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 af78154221242..d30a823463110 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 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { private boolean areAllUsersAffiliatedWithDeviceLocked() { final long ident = mInjector.binderClearCallingIdentity(); try { - final List userInfos = mUserManager.getUsers(); + final List 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 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { return Collections.emptyList(); } Preconditions.checkNotNull(admin); - ArrayList 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 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 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); } /**