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

Commit 02c8990b authored by Kenny Guy's avatar Kenny Guy
Browse files

Allow overriding max profile in debugable builds.

Support a system property on debugable builds to
override the max number of managed profiles to
allow easier dogfooding of multiple profiles.
Support 3 different badge colours for managed profiles.

Bug: 30473760
Test: runtest -c com.android.server.pm.UserManagerServiceCreateProfileTest frameworks-services
Test: runtest -c com.android.server.pm.UserManagerServiceUserInfoTest frameworks-services
Test: manual - attempting to create 2 profiles with adb fails, passes once I set the property.
Change-Id: Ie7fb19048a04a01572666f229283152254d0ffc3
parent c66cc516
Loading
Loading
Loading
Loading
+58 −25
Original line number Diff line number Diff line
@@ -58,9 +58,11 @@ import android.content.res.Resources;
import android.content.res.XmlResourceParser;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Rect;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.LayerDrawable;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
@@ -81,6 +83,7 @@ import android.view.Display;
import dalvik.system.VMRuntime;

import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.os.SomeArgs;
import com.android.internal.util.Preconditions;
import com.android.internal.util.UserIcons;
@@ -1174,22 +1177,22 @@ public class ApplicationPackageManager extends PackageManager {
        return getApplicationLogo(getApplicationInfo(packageName, sDefaultFlags));
    }

    @Override
    public Drawable getManagedUserBadgedDrawable(Drawable drawable, Rect badgeLocation,
            int badgeDensity) {
        Drawable badgeDrawable = getDrawableForDensity(
            com.android.internal.R.drawable.ic_corp_badge, badgeDensity);
        return getBadgedDrawable(drawable, badgeDrawable, badgeLocation, true);
    }

    @Override
    public Drawable getUserBadgedIcon(Drawable icon, UserHandle user) {
        final int badgeResId = getBadgeResIdForUser(user.getIdentifier());
        if (badgeResId == 0) {
        if (!isManagedProfile(user.getIdentifier())) {
            return icon;
        }
        Drawable badgeIcon = getDrawable("system", badgeResId, null);
        return getBadgedDrawable(icon, badgeIcon, null, true);
        Drawable badgeShadow = getDrawable("system",
                com.android.internal.R.drawable.ic_corp_icon_badge_shadow, null);
        Drawable badgeColor = getDrawable("system",
                com.android.internal.R.drawable.ic_corp_icon_badge_color, null);
        badgeColor.setTint(getUserBadgeColor(user));
        Drawable badgeForeground = getDrawable("system",
                com.android.internal.R.drawable.ic_corp_icon_badge_case, null);

        Drawable badge = new LayerDrawable(
                new Drawable[] {badgeShadow, badgeColor, badgeForeground });
        return getBadgedDrawable(icon, badge, null, true);
    }

    @Override
@@ -1202,16 +1205,53 @@ public class ApplicationPackageManager extends PackageManager {
        return getBadgedDrawable(drawable, badgeDrawable, badgeLocation, true);
    }

    // Should have enough colors to cope with UserManagerService.getMaxManagedProfiles()
    @VisibleForTesting
    public static final int[] CORP_BADGE_COLORS = new int[] {
        com.android.internal.R.color.profile_badge_1,
        com.android.internal.R.color.profile_badge_2,
        com.android.internal.R.color.profile_badge_3
    };

    @VisibleForTesting
    public static final int[] CORP_BADGE_LABEL_RES_ID = new int[] {
        com.android.internal.R.string.managed_profile_label_badge,
        com.android.internal.R.string.managed_profile_label_badge_2,
        com.android.internal.R.string.managed_profile_label_badge_3
    };

    private int getUserBadgeColor(UserHandle user) {
        int badge = getUserManager().getManagedProfileBadge(user.getIdentifier());
        if (badge < 0) {
            badge = 0;
        }
        int resourceId = CORP_BADGE_COLORS[badge % CORP_BADGE_COLORS.length];
        return Resources.getSystem().getColor(resourceId, null);
    }

    @Override
    public Drawable getUserBadgeForDensity(UserHandle user, int density) {
        return getManagedProfileIconForDensity(user, com.android.internal.R.drawable.ic_corp_badge,
                density);
        Drawable badgeColor = getManagedProfileIconForDensity(user,
                com.android.internal.R.drawable.ic_corp_badge_color, density);
        if (badgeColor == null) {
            return null;
        }
        badgeColor.setTint(getUserBadgeColor(user));
        Drawable badgeForeground = getDrawableForDensity(
                com.android.internal.R.drawable.ic_corp_badge_case, density);
        Drawable badge = new LayerDrawable(
                new Drawable[] {badgeColor, badgeForeground });
        return badge;
    }

    @Override
    public Drawable getUserBadgeForDensityNoBackground(UserHandle user, int density) {
        return getManagedProfileIconForDensity(user,
        Drawable badge = getManagedProfileIconForDensity(user,
                com.android.internal.R.drawable.ic_corp_badge_no_background, density);
        if (badge != null) {
            badge.setTint(getUserBadgeColor(user));
        }
        return badge;
    }

    private Drawable getDrawableForDensity(int drawableId, int density) {
@@ -1231,8 +1271,9 @@ public class ApplicationPackageManager extends PackageManager {
    @Override
    public CharSequence getUserBadgedLabel(CharSequence label, UserHandle user) {
        if (isManagedProfile(user.getIdentifier())) {
            return Resources.getSystem().getString(
                    com.android.internal.R.string.managed_profile_label_badge, label);
            int badge = getUserManager().getManagedProfileBadge(user.getIdentifier());
            int resourceId = CORP_BADGE_LABEL_RES_ID[badge % CORP_BADGE_LABEL_RES_ID.length];
            return Resources.getSystem().getString(resourceId, label);
        }
        return label;
    }
@@ -2355,14 +2396,6 @@ public class ApplicationPackageManager extends PackageManager {
        return drawable;
    }

    private int getBadgeResIdForUser(int userId) {
        // Return the framework-provided badge.
        if (isManagedProfile(userId)) {
            return com.android.internal.R.drawable.ic_corp_icon_badge;
        }
        return 0;
    }

    private boolean isManagedProfile(int userId) {
        return getUserManager().isManagedProfile(userId);
    }
+0 −26
Original line number Diff line number Diff line
@@ -4521,32 +4521,6 @@ public abstract class PackageManager {
    public abstract Drawable getApplicationLogo(String packageName)
            throws NameNotFoundException;

    /**
     * Returns a managed-user-style badged copy of the given drawable allowing the user to
     * distinguish it from the original drawable.
     * The caller can specify the location in the bounds of the drawable to be
     * badged where the badge should be applied as well as the density of the
     * badge to be used.
     * <p>
     * If the original drawable is a BitmapDrawable and the backing bitmap is
     * mutable as per {@link android.graphics.Bitmap#isMutable()}, the badging
     * is performed in place and the original drawable is returned.
     * </p>
     *
     * @param drawable The drawable to badge.
     * @param badgeLocation Where in the bounds of the badged drawable to place
     *         the badge. If it's {@code null}, the badge is applied on top of the entire
     *         drawable being badged.
     * @param badgeDensity The optional desired density for the badge as per
     *         {@link android.util.DisplayMetrics#densityDpi}. If it's not positive,
     *         the density of the display is used.
     * @return A drawable that combines the original drawable and a badge as
     *         determined by the system.
     * @hide
     */
    public abstract Drawable getManagedUserBadgedDrawable(Drawable drawable, Rect badgeLocation,
        int badgeDensity);

    /**
     * If the target user is a managed profile, then this returns a badged copy of the given icon
     * to be able to distinguish it from the original icon. For badging an arbitrary drawable use
+5 −0
Original line number Diff line number Diff line
@@ -109,6 +109,8 @@ public class UserInfo implements Parcelable {
     */
    public int profileGroupId;
    public int restrictedProfileParentId;
    /** Which profile badge color/label to use. */
    public int profileBadge;

    /** User is only partially created. */
    public boolean partial;
@@ -233,6 +235,7 @@ public class UserInfo implements Parcelable {
        profileGroupId = orig.profileGroupId;
        restrictedProfileParentId = orig.restrictedProfileParentId;
        guestToRemove = orig.guestToRemove;
        profileBadge = orig.profileBadge;
    }

    public UserHandle getUserHandle() {
@@ -261,6 +264,7 @@ public class UserInfo implements Parcelable {
        dest.writeInt(profileGroupId);
        dest.writeInt(guestToRemove ? 1 : 0);
        dest.writeInt(restrictedProfileParentId);
        dest.writeInt(profileBadge);
    }

    public static final Parcelable.Creator<UserInfo> CREATOR
@@ -286,5 +290,6 @@ public class UserInfo implements Parcelable {
        profileGroupId = source.readInt();
        guestToRemove = source.readInt() != 0;
        restrictedProfileParentId = source.readInt();
        profileBadge = source.readInt();
    }
}
+1 −0
Original line number Diff line number Diff line
@@ -86,4 +86,5 @@ interface IUserManager {
    UserInfo createProfileForUserEvenWhenDisallowed(in String name, int flags, int userHandle,
            in String[] disallowedPackages);
    boolean isUserUnlockingOrUnlocked(int userId);
    int getManagedProfileBadge(int userId);
}
+17 −0
Original line number Diff line number Diff line
@@ -947,6 +947,23 @@ public class UserManager {
        }
    }

    /**
     * Gets badge for a managed profile.
     * Requires {@link android.Manifest.permission#MANAGE_USERS} permission, otherwise the caller
     * must be in the same profile group of specified user.
     *
     * @return which badge to use for the managed profile badge id will be less than
     *         UserManagerService.getMaxManagedProfiles()
     * @hide
     */
    public int getManagedProfileBadge(@UserIdInt int userId) {
        try {
            return mService.getManagedProfileBadge(userId);
        } catch (RemoteException re) {
            throw re.rethrowFromSystemServer();
        }
    }

    /**
     * Checks if the calling app is running as an ephemeral user.
     *
Loading