Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2f897917 authored by Esteban Talavera's avatar Esteban Talavera
Browse files

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
parent 9e77aefe
Loading
Loading
Loading
Loading
+4 −8
Original line number Diff line number Diff line
@@ -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.
     * <p>
     * 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}.
     * <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) {
+30 −26
Original line number Diff line number Diff line
@@ -9906,7 +9906,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
    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 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
            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);
    }

    /**