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

Commit 68b05f70 authored by Olivier Nshimiye's avatar Olivier Nshimiye
Browse files

Add more user properties & details to the profile creation

Add profileTabLabel userTypeDetail and its getter API
Refactor the hideInUiInQuietMode property to be multivalue
Add showInSharingSurfaces property

Bug: 307515481
Test: atest UserManagerServiceUserPropertiesTest
Test: atest UserManagerServiceUserTypeTest
Test: atest FrameworksServicesTests:UserManagerTest

Change-Id: Ied17e437c7d02ae07b8ab2e989dc7dc87ea9e589
parent 952dc1a5
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -4198,10 +4198,18 @@ package android.content.pm {
  public final class UserProperties implements android.os.Parcelable {
    method public int describeContents();
    method public int getShowInQuietMode();
    method public int getShowInSharingSurfaces();
    method public boolean isCredentialShareableWithParent();
    method public boolean isMediaSharedWithParent();
    method public void writeToParcel(@NonNull android.os.Parcel, int);
    field @NonNull public static final android.os.Parcelable.Creator<android.content.pm.UserProperties> CREATOR;
    field public static final int SHOW_IN_QUIET_MODE_DEFAULT = 2; // 0x2
    field public static final int SHOW_IN_QUIET_MODE_HIDDEN = 1; // 0x1
    field public static final int SHOW_IN_QUIET_MODE_PAUSED = 0; // 0x0
    field public static final int SHOW_IN_SHARING_SURFACES_NO = 2; // 0x2
    field public static final int SHOW_IN_SHARING_SURFACES_SEPARATE = 1; // 0x1
    field public static final int SHOW_IN_SHARING_SURFACES_WITH_PARENT = 0; // 0x0
  }
}
@@ -10559,6 +10567,7 @@ package android.os {
    method @NonNull public java.util.List<android.os.UserHandle> getEnabledProfiles();
    method @Nullable @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.CREATE_USERS, android.Manifest.permission.QUERY_USERS}) public android.os.UserHandle getMainUser();
    method @Nullable @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.CREATE_USERS, android.Manifest.permission.QUERY_USERS}) public android.os.UserHandle getPreviousForegroundUser();
    method @NonNull public String getProfileLabel();
    method @Nullable @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.INTERACT_ACROSS_USERS}) public android.os.UserHandle getProfileParent(@NonNull android.os.UserHandle);
    method @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.CREATE_USERS, android.Manifest.permission.QUERY_USERS}) public int getRemainingCreatableProfileCount(@NonNull String);
    method @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.CREATE_USERS, android.Manifest.permission.QUERY_USERS}) public int getRemainingCreatableUserCount(@NonNull String);
+163 −44
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ package android.content.pm;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SuppressLint;
import android.annotation.SystemApi;
import android.annotation.TestApi;
import android.os.Parcel;
@@ -49,7 +50,8 @@ public final class UserProperties implements Parcelable {
    private static final String ATTR_SHOW_IN_LAUNCHER = "showInLauncher";
    private static final String ATTR_START_WITH_PARENT = "startWithParent";
    private static final String ATTR_SHOW_IN_SETTINGS = "showInSettings";
    private static final String ATTR_HIDE_IN_SETTINGS_IN_QUIET_MODE = "hideInSettingsInQuietMode";
    private static final String ATTR_SHOW_IN_QUIET_MODE = "showInQuietMode";
    private static final String ATTR_SHOW_IN_SHARING_SURFACES = "showInSharingSurfaces";
    private static final String ATTR_INHERIT_DEVICE_POLICY = "inheritDevicePolicy";
    private static final String ATTR_USE_PARENTS_CONTACTS = "useParentsContacts";
    private static final String ATTR_UPDATE_CROSS_PROFILE_INTENT_FILTERS_ON_OTA =
@@ -81,7 +83,8 @@ public final class UserProperties implements Parcelable {
            INDEX_CREDENTIAL_SHAREABLE_WITH_PARENT,
            INDEX_DELETE_APP_WITH_PARENT,
            INDEX_ALWAYS_VISIBLE,
            INDEX_HIDE_IN_SETTINGS_IN_QUIET_MODE,
            INDEX_SHOW_IN_QUIET_MODE,
            INDEX_SHOW_IN_SHARING_SURFACES,
            INDEX_AUTH_ALWAYS_REQUIRED_TO_DISABLE_QUIET_MODE,
    })
    @Retention(RetentionPolicy.SOURCE)
@@ -99,8 +102,9 @@ public final class UserProperties implements Parcelable {
    private static final int INDEX_CREDENTIAL_SHAREABLE_WITH_PARENT = 9;
    private static final int INDEX_DELETE_APP_WITH_PARENT = 10;
    private static final int INDEX_ALWAYS_VISIBLE = 11;
    private static final int INDEX_HIDE_IN_SETTINGS_IN_QUIET_MODE = 12;
    private static final int INDEX_SHOW_IN_QUIET_MODE = 12;
    private static final int INDEX_AUTH_ALWAYS_REQUIRED_TO_DISABLE_QUIET_MODE = 13;
    private static final int INDEX_SHOW_IN_SHARING_SURFACES = 14;
    /** A bit set, mapping each PropertyIndex to whether it is present (1) or absent (0). */
    private long mPropertiesPresent = 0;

@@ -286,6 +290,81 @@ public final class UserProperties implements Parcelable {
     */
    public static final int CROSS_PROFILE_INTENT_RESOLUTION_STRATEGY_NO_FILTERING = 1;

    /**
     * Possible values for the profile visibility when in quiet mode. This affects the profile data
     * and apps surfacing in Settings, sharing surfaces, and file picker surfaces. It signifies
     * whether the profile data and apps will be shown or not.
     *
     * @hide
     */
    @Retention(RetentionPolicy.SOURCE)
    @IntDef(prefix = "SHOW_IN_QUIET_MODE_",
            value = {
                    SHOW_IN_QUIET_MODE_PAUSED,
                    SHOW_IN_QUIET_MODE_HIDDEN,
                    SHOW_IN_QUIET_MODE_DEFAULT,
            }
    )
    public @interface ShowInQuietMode {
    }

    /**
     * Indicates that the profile should still be visible in quiet mode but should be shown as
     * paused (e.g. by greying out its icons).
     */
    @SuppressLint("UnflaggedApi") // b/306636213
    public static final int SHOW_IN_QUIET_MODE_PAUSED = 0;
    /**
     * Indicates that the profile should not be visible when the profile is in quiet mode.
     * For example, the profile should not be shown in tabbed views in Settings, files sharing
     * surfaces etc when in quiet mode.
     */
    @SuppressLint("UnflaggedApi") // b/306636213
    public static final int SHOW_IN_QUIET_MODE_HIDDEN = 1;
    /**
     * Indicates that quiet mode should not have any effect on the profile visibility. If the
     * profile is meant to be visible, it will remain visible and vice versa.
     */
    @SuppressLint("UnflaggedApi") // b/306636213
    public static final int SHOW_IN_QUIET_MODE_DEFAULT = 2;

    /**
     * Possible values for the profile apps visibility in sharing surfaces. This indicates the
     * profile data and apps should be shown in separate tabs or mixed with its parent user's data
     * and apps in sharing surfaces and file picker surfaces.
     *
     * @hide
     */
    @Retention(RetentionPolicy.SOURCE)
    @IntDef(prefix = "SHOW_IN_SHARING_SURFACES_",
            value = {
                    SHOW_IN_SHARING_SURFACES_SEPARATE,
                    SHOW_IN_SHARING_SURFACES_WITH_PARENT,
                    SHOW_IN_SHARING_SURFACES_NO,
            }
    )
    public @interface ShowInSharingSurfaces {
    }

    /**
     * Indicates that the profile data and apps should be shown in sharing surfaces intermixed with
     * parent user's data and apps.
     */
    @SuppressLint("UnflaggedApi") // b/306636213
    public static final int SHOW_IN_SHARING_SURFACES_WITH_PARENT = SHOW_IN_LAUNCHER_WITH_PARENT;

    /**
     * Indicates that the profile data and apps should be shown in sharing surfaces separate from
     * parent user's data and apps.
     */
    @SuppressLint("UnflaggedApi") // b/306636213
    public static final int SHOW_IN_SHARING_SURFACES_SEPARATE = SHOW_IN_LAUNCHER_SEPARATE;

    /**
     * Indicates that the profile data and apps should not be shown in sharing surfaces at all.
     */
    @SuppressLint("UnflaggedApi") // b/306636213
    public static final int SHOW_IN_SHARING_SURFACES_NO = SHOW_IN_LAUNCHER_NO;

    /**
     * Creates a UserProperties (intended for the SystemServer) that stores a reference to the given
@@ -331,7 +410,6 @@ public final class UserProperties implements Parcelable {
        if (hasManagePermission) {
            // Add items that require MANAGE_USERS or stronger.
            setShowInSettings(orig.getShowInSettings());
            setHideInSettingsInQuietMode(orig.getHideInSettingsInQuietMode());
            setUseParentsContacts(orig.getUseParentsContacts());
            setAuthAlwaysRequiredToDisableQuietMode(
                    orig.isAuthAlwaysRequiredToDisableQuietMode());
@@ -343,6 +421,8 @@ public final class UserProperties implements Parcelable {
        setShowInLauncher(orig.getShowInLauncher());
        setMediaSharedWithParent(orig.isMediaSharedWithParent());
        setCredentialShareableWithParent(orig.isCredentialShareableWithParent());
        setShowInQuietMode(orig.getShowInQuietMode());
        setShowInSharingSurfaces(orig.getShowInSharingSurfaces());
    }

    /**
@@ -419,40 +499,59 @@ public final class UserProperties implements Parcelable {
    private @ShowInSettings int mShowInSettings;

    /**
     * Returns whether a user should be shown in the Settings app depending on the quiet mode.
     * This is generally inapplicable for non-profile users.
     *
     * <p> {@link #getShowInSettings()} returns whether / how a user should be shown in Settings.
     * However, if this behaviour should be changed based on the quiet mode of the user, then this
     * property can be used. If the property is not set then the user is shown in the Settings app
     * irrespective of whether the user is in quiet mode or not. If the property is set, then the
     * user is shown in the Settings app only if the user is not in the quiet mode. Please note that
     * this property takes effect only if {@link #getShowInSettings()} does not return
     * {@link #SHOW_IN_SETTINGS_NO}.
     *
     * <p> The caller must have {@link android.Manifest.permission#MANAGE_USERS} to query this
     * property.
     * Returns whether a user should be shown in the Settings and sharing surfaces depending on the
     * {@link android.os.UserManager#requestQuietModeEnabled(boolean, android.os.UserHandle)
     * quiet mode}. This is only applicable to profile users since the quiet mode concept is only
     * applicable to profile users.
     *
     * @return true if a profile should be shown in the Settings only when the user is not in the
     * quiet mode.
     * <p> Please note that, in Settings, this property takes effect only if
     * {@link #getShowInSettings()} does not return {@link #SHOW_IN_SETTINGS_NO}.
     * Also note that in Sharing surfaces this property takes effect only if
     * {@link #getShowInSharingSurfaces()} does not return {@link #SHOW_IN_SHARING_SURFACES_NO}.
     *
     * See also {@link #getShowInSettings()}, {@link #setShowInSettings(int)},
     * {@link ShowInSettings}
     * @return One of {@link #SHOW_IN_QUIET_MODE_HIDDEN},
     *         {@link #SHOW_IN_QUIET_MODE_PAUSED}, or
     *         {@link #SHOW_IN_QUIET_MODE_DEFAULT} depending on whether the profile should be
     *         shown in quiet mode or not.
     */
    @SuppressLint("UnflaggedApi") // b/306636213
    public @ShowInQuietMode int getShowInQuietMode() {
        // NOTE: Launcher currently does not make use of this property.
        if (isPresent(INDEX_SHOW_IN_QUIET_MODE)) return mShowInQuietMode;
        if (mDefaultProperties != null) return mDefaultProperties.mShowInQuietMode;
        throw new SecurityException(
                "You don't have permission to query ShowInQuietMode");
    }
    /** @hide */
    public void setShowInQuietMode(@ShowInQuietMode int showInQuietMode) {
        this.mShowInQuietMode = showInQuietMode;
        setPresent(INDEX_SHOW_IN_QUIET_MODE);
    }
    private int mShowInQuietMode;

    /**
     * Returns whether a user's data and apps should be shown in sharing surfaces in a separate tab
     * or mixed with the parent user's data/apps. This is only applicable to profile users.
     *
     * @hide
     * @return One of {@link #SHOW_IN_SHARING_SURFACES_NO},
     *         {@link #SHOW_IN_SHARING_SURFACES_SEPARATE}, or
     *         {@link #SHOW_IN_SHARING_SURFACES_WITH_PARENT} depending on whether the profile
     *         should be shown separate from its parent's data, mixed with the parent's data, or
     *         not shown at all.
     */
    public boolean getHideInSettingsInQuietMode() {
        if (isPresent(INDEX_HIDE_IN_SETTINGS_IN_QUIET_MODE)) return mHideInSettingsInQuietMode;
        if (mDefaultProperties != null) return mDefaultProperties.mHideInSettingsInQuietMode;
    @SuppressLint("UnflaggedApi") // b/306636213
    public @ShowInSharingSurfaces int getShowInSharingSurfaces() {
        if (isPresent(INDEX_SHOW_IN_SHARING_SURFACES)) return mShowInSharingSurfaces;
        if (mDefaultProperties != null) return mDefaultProperties.mShowInSharingSurfaces;
        throw new SecurityException(
                "You don't have permission to query HideInSettingsInQuietMode");
                "You don't have permission to query ShowInSharingSurfaces");
    }
    /** @hide */
    public void setHideInSettingsInQuietMode(boolean hideInSettingsInQuietMode) {
        this.mHideInSettingsInQuietMode = hideInSettingsInQuietMode;
        setPresent(INDEX_HIDE_IN_SETTINGS_IN_QUIET_MODE);
    public void setShowInSharingSurfaces(@ShowInSharingSurfaces int showInSharingSurfaces) {
        this.mShowInSharingSurfaces = showInSharingSurfaces;
        setPresent(INDEX_SHOW_IN_SHARING_SURFACES);
    }
    private boolean mHideInSettingsInQuietMode;
    private int mShowInSharingSurfaces;

    /**
     * Returns whether a profile should be started when its parent starts (unless in quiet mode).
@@ -799,8 +898,11 @@ public final class UserProperties implements Parcelable {
                case ATTR_SHOW_IN_SETTINGS:
                    setShowInSettings(parser.getAttributeInt(i));
                    break;
                case ATTR_HIDE_IN_SETTINGS_IN_QUIET_MODE:
                    setHideInSettingsInQuietMode(parser.getAttributeBoolean(i));
                case ATTR_SHOW_IN_QUIET_MODE:
                    setShowInQuietMode(parser.getAttributeInt(i));
                    break;
                case ATTR_SHOW_IN_SHARING_SURFACES:
                    setShowInSharingSurfaces(parser.getAttributeInt(i));
                    break;
                case ATTR_INHERIT_DEVICE_POLICY:
                    setInheritDevicePolicy(parser.getAttributeInt(i));
@@ -858,9 +960,12 @@ public final class UserProperties implements Parcelable {
        if (isPresent(INDEX_SHOW_IN_SETTINGS)) {
            serializer.attributeInt(null, ATTR_SHOW_IN_SETTINGS, mShowInSettings);
        }
        if (isPresent(INDEX_HIDE_IN_SETTINGS_IN_QUIET_MODE)) {
            serializer.attributeBoolean(null, ATTR_HIDE_IN_SETTINGS_IN_QUIET_MODE,
                    mHideInSettingsInQuietMode);
        if (isPresent(INDEX_SHOW_IN_QUIET_MODE)) {
            serializer.attributeInt(null, ATTR_SHOW_IN_QUIET_MODE,
                    mShowInQuietMode);
        }
        if (isPresent(INDEX_SHOW_IN_SHARING_SURFACES)) {
            serializer.attributeInt(null, ATTR_SHOW_IN_SHARING_SURFACES, mShowInSharingSurfaces);
        }
        if (isPresent(INDEX_INHERIT_DEVICE_POLICY)) {
            serializer.attributeInt(null, ATTR_INHERIT_DEVICE_POLICY,
@@ -912,7 +1017,8 @@ public final class UserProperties implements Parcelable {
        dest.writeInt(mShowInLauncher);
        dest.writeBoolean(mStartWithParent);
        dest.writeInt(mShowInSettings);
        dest.writeBoolean(mHideInSettingsInQuietMode);
        dest.writeInt(mShowInQuietMode);
        dest.writeInt(mShowInSharingSurfaces);
        dest.writeInt(mInheritDevicePolicy);
        dest.writeBoolean(mUseParentsContacts);
        dest.writeBoolean(mUpdateCrossProfileIntentFiltersOnOTA);
@@ -936,7 +1042,8 @@ public final class UserProperties implements Parcelable {
        mShowInLauncher = source.readInt();
        mStartWithParent = source.readBoolean();
        mShowInSettings = source.readInt();
        mHideInSettingsInQuietMode = source.readBoolean();
        mShowInQuietMode = source.readInt();
        mShowInSharingSurfaces = source.readInt();
        mInheritDevicePolicy = source.readInt();
        mUseParentsContacts = source.readBoolean();
        mUpdateCrossProfileIntentFiltersOnOTA = source.readBoolean();
@@ -974,7 +1081,10 @@ public final class UserProperties implements Parcelable {
        private @ShowInLauncher int mShowInLauncher = SHOW_IN_LAUNCHER_WITH_PARENT;
        private boolean mStartWithParent = false;
        private @ShowInSettings int mShowInSettings = SHOW_IN_SETTINGS_WITH_PARENT;
        private boolean mHideInSettingsInQuietMode = false;
        private @ShowInQuietMode int mShowInQuietMode =
                SHOW_IN_QUIET_MODE_PAUSED;
        private @ShowInSharingSurfaces int mShowInSharingSurfaces =
                SHOW_IN_SHARING_SURFACES_SEPARATE;
        private @InheritDevicePolicy int mInheritDevicePolicy = INHERIT_DEVICE_POLICY_NO;
        private boolean mUseParentsContacts = false;
        private boolean mUpdateCrossProfileIntentFiltersOnOTA = false;
@@ -1005,9 +1115,15 @@ public final class UserProperties implements Parcelable {
            return this;
        }

        /** Sets the value for {@link #mHideInSettingsInQuietMode} */
        public Builder setHideInSettingsInQuietMode(boolean hideInSettingsInQuietMode) {
            mHideInSettingsInQuietMode = hideInSettingsInQuietMode;
        /** Sets the value for {@link #mShowInQuietMode} */
        public Builder setShowInQuietMode(@ShowInQuietMode int showInQuietMode) {
            mShowInQuietMode = showInQuietMode;
            return this;
        }

        /** Sets the value for {@link #mShowInSharingSurfaces}. */
        public Builder setShowInSharingSurfaces(@ShowInSharingSurfaces int showInSharingSurfaces) {
            mShowInSharingSurfaces = showInSharingSurfaces;
            return this;
        }

@@ -1081,7 +1197,8 @@ public final class UserProperties implements Parcelable {
                    mShowInLauncher,
                    mStartWithParent,
                    mShowInSettings,
                    mHideInSettingsInQuietMode,
                    mShowInQuietMode,
                    mShowInSharingSurfaces,
                    mInheritDevicePolicy,
                    mUseParentsContacts,
                    mUpdateCrossProfileIntentFiltersOnOTA,
@@ -1100,7 +1217,8 @@ public final class UserProperties implements Parcelable {
            @ShowInLauncher int showInLauncher,
            boolean startWithParent,
            @ShowInSettings int showInSettings,
            boolean hideInSettingsInQuietMode,
            @ShowInQuietMode int showInQuietMode,
            @ShowInSharingSurfaces int showInSharingSurfaces,
            @InheritDevicePolicy int inheritDevicePolicy,
            boolean useParentsContacts, boolean updateCrossProfileIntentFiltersOnOTA,
            @CrossProfileIntentFilterAccessControlLevel int crossProfileIntentFilterAccessControl,
@@ -1114,7 +1232,8 @@ public final class UserProperties implements Parcelable {
        setShowInLauncher(showInLauncher);
        setStartWithParent(startWithParent);
        setShowInSettings(showInSettings);
        setHideInSettingsInQuietMode(hideInSettingsInQuietMode);
        setShowInQuietMode(showInQuietMode);
        setShowInSharingSurfaces(showInSharingSurfaces);
        setInheritDevicePolicy(inheritDevicePolicy);
        setUseParentsContacts(useParentsContacts);
        setUpdateCrossProfileIntentFiltersOnOTA(updateCrossProfileIntentFiltersOnOTA);
+1 −0
Original line number Diff line number Diff line
@@ -131,6 +131,7 @@ interface IUserManager {
    int getUserBadgeDarkColorResId(int userId);
    int getUserStatusBarIconResId(int userId);
    boolean hasBadge(int userId);
    int getProfileLabelResId(int userId);
    boolean isUserUnlocked(int userId);
    boolean isUserRunning(int userId);
    boolean isUserForeground(int userId);
+38 −0
Original line number Diff line number Diff line
@@ -5693,6 +5693,44 @@ public class UserManager {
        }
    }

    /**
     * Returns the string/label that should be used to represent the context user. For example,
     * this string can represent a profile in tabbed views. This is only applicable to
     * {@link #isProfile() profile users}. This string is translated to the device default language.
     *
     * @return String representing the label for the context user.
     *
     * @throws android.content.res.Resources.NotFoundException if the user does not have a label
     * defined.
     *
     * @hide
     */
    @SystemApi
    @SuppressLint("UnflaggedApi") // b/306636213
    @UserHandleAware(
            requiresAnyOfPermissionsIfNotCallerProfileGroup = {
                    Manifest.permission.MANAGE_USERS,
                    Manifest.permission.QUERY_USERS,
                    Manifest.permission.INTERACT_ACROSS_USERS})
    public @NonNull String getProfileLabel() {
        if (isManagedProfile(mUserId)) {
            DevicePolicyManager dpm = mContext.getSystemService(DevicePolicyManager.class);
            return dpm.getResources().getString(
                    android.app.admin.DevicePolicyResources.Strings.Core.RESOLVER_WORK_TAB,
                    () -> getDefaultProfileLabel(mUserId));
        }
        return getDefaultProfileLabel(mUserId);
    }

    private String getDefaultProfileLabel(int userId) {
        try {
            final int resourceId = mService.getProfileLabelResId(userId);
            return Resources.getSystem().getString(resourceId);
        } catch (RemoteException re) {
            throw re.rethrowFromSystemServer();
        }
    }

    /**
     * If the user is a {@link UserManager#isProfile profile}, checks if the user
     * shares media with its parent user (the user that created this profile).
+16 −0
Original line number Diff line number Diff line
@@ -6350,4 +6350,20 @@ ul.</string>
    <string name="keyboard_layout_notification_multiple_selected_title">Physical keyboards configured</string>
    <!-- Notification message when multiple keyboards with selected layouts have been connected the first time simultaneously [CHAR LIMIT=NOTIF_BODY] -->
    <string name="keyboard_layout_notification_multiple_selected_message">Tap to view keyboards</string>

    <!-- Private profile label on a screen. This can be used as a tab label for this profile in tabbed views and can be used to represent the profile in sharing surfaces, etc. [CHAR LIMIT=20] -->
    <string name="profile_label_private">Private</string>
    <!-- Clone profile label on a screen. This can be used as a tab label for this profile in tabbed views and can be used to represent the profile in sharing surfaces, etc. [CHAR LIMIT=20] -->
    <string name="profile_label_clone">Clone</string>
    <!-- Work profile label on a screen. This can be used as a tab label for this profile in tabbed views and can be used to represent the profile in sharing surfaces, etc. [CHAR LIMIT=20] -->
    <string name="profile_label_work">Work</string>
    <!-- 2nd Work profile label on a screen in case a device has more than one work profiles. This can be used as a tab label for this profile in tabbed views and can be used to represent the profile in sharing surfaces, etc. [CHAR LIMIT=20] -->
    <string name="profile_label_work_2">Work 2</string>
    <!-- 3rd Work profile label on a screen in case a device has more than two work profiles. This can be used as a tab label for this profile in tabbed views and can be used to represent the profile in sharing surfaces, etc. [CHAR LIMIT=20] -->
    <string name="profile_label_work_3">Work 3</string>
    <!-- Test profile label on a screen. This can be used as a tab label for this profile in tabbed views and can be used to represent the profile in sharing surfaces, etc. [CHAR LIMIT=20]  -->
    <string name="profile_label_test">Test</string>
    <!-- Communal profile label on a screen. This can be used as a tab label for this profile in tabbed views and can be used to represent the profile in sharing surfaces, etc. [CHAR LIMIT=20] -->
    <string name="profile_label_communal">Communal</string>

</resources>
Loading