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

Commit d2ed6237 authored by Olivier Nshimiye's avatar Olivier Nshimiye
Browse files

Block the hidden profiles visibility in CrossProfileApps

Remove results about profiles with ProfileApiVisibility set to HIDDEN

Bug: 316362775
Change-Id: I0e268dc38bf63599485541838871742872066393
parent 36d8cd18
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -122,3 +122,10 @@ flag {
    description: "Handle listing of private space apps in settings pages with interleaved content"
    bug: "323212460"
}

flag {
    name: "enable_hiding_profiles"
    namespace: "profile_experiences"
    description: "Allow the use of a profileApiAvailability user property to exclude HIDDEN profiles in API results"
    bug: "316362775"
}
+1 −0
Original line number Diff line number Diff line
@@ -150,4 +150,5 @@ interface IUserManager {
    void setBootUser(int userId);
    @JavaPassthrough(annotation="@android.annotation.RequiresPermission(anyOf = {android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.CREATE_USERS})")
    int getBootUser();
    int[] getProfileIdsExcludingHidden(int userId, boolean enabledOnly);
}
+19 −0
Original line number Diff line number Diff line
@@ -5347,6 +5347,25 @@ public class UserManager {
        return getProfileIds(userId, true /* enabledOnly */);
    }

    /**
     * @return A list of ids of profiles associated with the specified user excluding those with
     * {@link UserProperties#getProfileApiVisibility()} set to hidden. The returned list includes
     * the user itself.
     * @hide
     * @see #getProfileIds(int, boolean)
     */
    @RequiresPermission(anyOf = {
            Manifest.permission.MANAGE_USERS,
            Manifest.permission.CREATE_USERS,
            Manifest.permission.QUERY_USERS}, conditional = true)
    public int[] getProfileIdsExcludingHidden(@UserIdInt int userId, boolean enabled) {
        try {
            return mService.getProfileIdsExcludingHidden(userId, enabled);
        } catch (RemoteException re) {
            throw re.rethrowFromSystemServer();
        }
    }

    /**
     * Returns the device credential owner id of the profile from
     * which this method is called, or userId if called from a user that
+11 −5
Original line number Diff line number Diff line
@@ -49,6 +49,7 @@ import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManagerInternal;
import android.content.pm.ResolveInfo;
import android.content.pm.UserProperties;
import android.os.Binder;
import android.os.Bundle;
import android.os.IBinder;
@@ -268,7 +269,8 @@ public class CrossProfileAppsServiceImpl extends ICrossProfileApps.Stub {
    private boolean canRequestInteractAcrossProfilesUnchecked(String packageName) {
        final int callingUserId = mInjector.getCallingUserId();
        final int[] enabledProfileIds =
                mInjector.getUserManager().getEnabledProfileIds(callingUserId);
                mInjector.getUserManager().getProfileIdsExcludingHidden(
                        callingUserId, /* enabled= */ true);
        if (enabledProfileIds.length < 2) {
            return false;
        }
@@ -350,7 +352,8 @@ public class CrossProfileAppsServiceImpl extends ICrossProfileApps.Stub {
            String packageName, @UserIdInt int userId) {
        return mInjector.withCleanCallingIdentity(() -> {
            final int[] enabledProfileIds =
                    mInjector.getUserManager().getEnabledProfileIds(userId);
                    mInjector.getUserManager().getProfileIdsExcludingHidden(userId, /* enabled= */
                            true);

            List<UserHandle> targetProfiles = new ArrayList<>();
            for (final int profileId : enabledProfileIds) {
@@ -466,7 +469,8 @@ public class CrossProfileAppsServiceImpl extends ICrossProfileApps.Stub {
            return;
        }
        final int[] profileIds =
                mInjector.getUserManager().getProfileIds(userId, /* enabledOnly= */ false);
                mInjector.getUserManager().getProfileIdsExcludingHidden(userId, /* enabled= */
                        false);
        for (int profileId : profileIds) {
            if (!isPackageInstalled(packageName, profileId)) {
                continue;
@@ -632,7 +636,8 @@ public class CrossProfileAppsServiceImpl extends ICrossProfileApps.Stub {
    private boolean canUserAttemptToConfigureInteractAcrossProfiles(
            String packageName, @UserIdInt int userId) {
        final int[] profileIds =
                mInjector.getUserManager().getProfileIds(userId, /* enabledOnly= */ false);
                mInjector.getUserManager().getProfileIdsExcludingHidden(userId, /* enabled= */
                        false);
        if (profileIds.length < 2) {
            return false;
        }
@@ -676,7 +681,8 @@ public class CrossProfileAppsServiceImpl extends ICrossProfileApps.Stub {
    private boolean hasOtherProfileWithPackageInstalled(String packageName, @UserIdInt int userId) {
        return mInjector.withCleanCallingIdentity(() -> {
            final int[] profileIds =
                    mInjector.getUserManager().getProfileIds(userId, /* enabledOnly= */ false);
                    mInjector.getUserManager().getProfileIdsExcludingHidden(userId, /* enabled= */
                            false);
            for (int profileId : profileIds) {
                if (profileId != userId && isPackageInstalled(packageName, profileId)) {
                    return true;
+37 −8
Original line number Diff line number Diff line
@@ -1385,7 +1385,7 @@ public class UserManagerService extends IUserManager.Stub {

    @Override
    public int[] getProfileIds(@UserIdInt int userId, boolean enabledOnly) {
        return getProfileIds(userId, null, enabledOnly);
        return getProfileIds(userId, null, enabledOnly, /* excludeHidden */ false);
    }

    // TODO(b/142482943): Probably @Override and make this accessible in UserManager.
@@ -1397,14 +1397,14 @@ public class UserManagerService extends IUserManager.Stub {
     * If enabledOnly, only returns users that are not {@link UserInfo#FLAG_DISABLED}.
     */
    public int[] getProfileIds(@UserIdInt int userId, @Nullable String userType,
            boolean enabledOnly) {
            boolean enabledOnly, boolean excludeHidden) {
        if (userId != UserHandle.getCallingUserId()) {
            checkQueryOrCreateUsersPermission("getting profiles related to user " + userId);
        }
        final long ident = Binder.clearCallingIdentity();
        try {
            synchronized (mUsersLock) {
                return getProfileIdsLU(userId, userType, enabledOnly).toArray();
                return getProfileIdsLU(userId, userType, enabledOnly, excludeHidden).toArray();
            }
        } finally {
            Binder.restoreCallingIdentity(ident);
@@ -1415,7 +1415,8 @@ public class UserManagerService extends IUserManager.Stub {
    @GuardedBy("mUsersLock")
    private List<UserInfo> getProfilesLU(@UserIdInt int userId, @Nullable String userType,
            boolean enabledOnly, boolean fullInfo) {
        IntArray profileIds = getProfileIdsLU(userId, userType, enabledOnly);
        IntArray profileIds = getProfileIdsLU(userId, userType, enabledOnly, /* excludeHidden */
                false);
        ArrayList<UserInfo> users = new ArrayList<>(profileIds.size());
        for (int i = 0; i < profileIds.size(); i++) {
            int profileId = profileIds.get(i);
@@ -1440,7 +1441,7 @@ public class UserManagerService extends IUserManager.Stub {
     */
    @GuardedBy("mUsersLock")
    private IntArray getProfileIdsLU(@UserIdInt int userId, @Nullable String userType,
            boolean enabledOnly) {
            boolean enabledOnly, boolean excludeHidden) {
        UserInfo user = getUserInfoLU(userId);
        IntArray result = new IntArray(mUsers.size());
        if (user == null) {
@@ -1465,11 +1466,36 @@ public class UserManagerService extends IUserManager.Stub {
            if (userType != null && !userType.equals(profile.userType)) {
                continue;
            }
            if (excludeHidden && isProfileHidden(userId)) {
                continue;
            }
            result.add(profile.id);
        }
        return result;
    }

    /*
     * Returns all the users that are in the same profile group as userId excluding those with
     * {@link UserProperties#getProfileApiVisibility()} set to hidden. The returned list includes
     * the user itself.
     */
    // TODO (b/323011770): Add a permission check to make an exception for App stores if we end
    //  up supporting Private Space on COPE devices
    @Override
    public int[] getProfileIdsExcludingHidden(@UserIdInt int userId, boolean enabledOnly) {
        return getProfileIds(userId, null, enabledOnly, /* excludeHidden */ true);
    }

    private boolean isProfileHidden(int userId) {
        UserProperties userProperties = getUserPropertiesCopy(userId);
        if (android.os.Flags.allowPrivateProfile()
                && android.multiuser.Flags.enableHidingProfiles()) {
            return userProperties.getProfileApiVisibility()
                    == UserProperties.PROFILE_API_VISIBILITY_HIDDEN;
        }
        return false;
    }

    @Override
    public int getCredentialOwnerProfile(@UserIdInt int userId) {
        checkManageUsersPermission("get the credential owner");
@@ -3630,7 +3656,8 @@ public class UserManagerService extends IUserManager.Stub {
                return 0;
            }

            final int userTypeCount = getProfileIds(userId, userType, false).length;
            final int userTypeCount = getProfileIds(userId, userType, false, /* excludeHidden */
                    false).length;
            final int profilesRemovedCount = userTypeCount > 0 && allowedToRemoveOne ? 1 : 0;
            final int usersCountAfterRemoving = getAliveUsersExcludingGuestsCountLU()
                    - profilesRemovedCount;
@@ -5931,7 +5958,8 @@ public class UserManagerService extends IUserManager.Stub {
            }
            userData = mUsers.get(userId);
            isProfile = userData.info.isProfile();
            profileIds = isProfile ? null : getProfileIdsLU(userId, null, false);
            profileIds = isProfile ? null : getProfileIdsLU(userId, null, false, /* excludeHidden */
                    false);
        }

        if (!isProfile) {
@@ -7458,7 +7486,8 @@ public class UserManagerService extends IUserManager.Stub {
        @Override
        public @NonNull int[] getProfileIds(@UserIdInt int userId, boolean enabledOnly) {
            synchronized (mUsersLock) {
                return getProfileIdsLU(userId, null /* userType */, enabledOnly).toArray();
                return getProfileIdsLU(userId, null /* userType */, enabledOnly, /* excludeHidden */
                        false).toArray();
            }
        }

Loading