diff options
author | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2023-12-01 09:17:20 +0000 |
---|---|---|
committer | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2023-12-01 09:17:20 +0000 |
commit | 3f97fd3cf0c0602edbac8cd3de2747824341b262 (patch) | |
tree | cd30a3fea91cbeed1a31bdc176c410b3403a458d | |
parent | 70085a2cd478ee9143c09e6fe9dcc2f932ab5c45 (diff) | |
parent | b92caa923149217d2059d0ee76e880f9c7e5a5d5 (diff) | |
download | base-3f97fd3cf0c0602edbac8cd3de2747824341b262.tar.gz |
Snap for 11166233 from b92caa923149217d2059d0ee76e880f9c7e5a5d5 to mainline-healthfitness-release
Change-Id: Ide974089c3f47e1d712264cc08e4bccff02374fc
23 files changed, 450 insertions, 34 deletions
diff --git a/core/api/system-current.txt b/core/api/system-current.txt index e0e5a7c8a76e..b75ef2eaa555 100644 --- a/core/api/system-current.txt +++ b/core/api/system-current.txt @@ -4116,10 +4116,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 } } @@ -10968,6 +10976,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); @@ -10976,6 +10985,7 @@ package android.os { method @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public android.os.PersistableBundle getSeedAccountOptions(); method @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public String getSeedAccountType(); method @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.CREATE_USERS}) public long[] getSerialNumbersOfUsers(boolean); + method @NonNull public android.graphics.drawable.Drawable getUserBadge(); method @NonNull @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.CREATE_USERS}) public java.util.List<android.os.UserHandle> getUserHandles(boolean); method @Nullable @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.GET_ACCOUNTS_PRIVILEGED}) public android.graphics.Bitmap getUserIcon(); method @NonNull @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.QUERY_USERS, android.Manifest.permission.INTERACT_ACROSS_USERS}, conditional=true) public android.content.pm.UserProperties getUserProperties(@NonNull android.os.UserHandle); diff --git a/core/java/android/content/pm/UserProperties.java b/core/java/android/content/pm/UserProperties.java index 2669040403ea..e85b289ca497 100644 --- a/core/java/android/content/pm/UserProperties.java +++ b/core/java/android/content/pm/UserProperties.java @@ -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,6 +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_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 = @@ -76,6 +79,10 @@ public final class UserProperties implements Parcelable { INDEX_MEDIA_SHARED_WITH_PARENT, INDEX_CREDENTIAL_SHAREABLE_WITH_PARENT, INDEX_DELETE_APP_WITH_PARENT, + INDEX_ALWAYS_VISIBLE, + INDEX_SHOW_IN_QUIET_MODE, + INDEX_SHOW_IN_SHARING_SURFACES, + INDEX_AUTH_ALWAYS_REQUIRED_TO_DISABLE_QUIET_MODE, }) @Retention(RetentionPolicy.SOURCE) private @interface PropertyIndex { @@ -91,6 +98,10 @@ public final class UserProperties implements Parcelable { private static final int INDEX_MEDIA_SHARED_WITH_PARENT = 8; 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_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; @@ -276,6 +287,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 @@ -329,6 +415,8 @@ public final class UserProperties implements Parcelable { setShowInLauncher(orig.getShowInLauncher()); setMediaSharedWithParent(orig.isMediaSharedWithParent()); setCredentialShareableWithParent(orig.isCredentialShareableWithParent()); + setShowInQuietMode(orig.getShowInQuietMode()); + setShowInSharingSurfaces(orig.getShowInSharingSurfaces()); } /** @@ -405,6 +493,61 @@ public final class UserProperties implements Parcelable { private @ShowInSettings int mShowInSettings; /** + * 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. + * + * <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}. + * + * @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. + * + * @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. + */ + @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 ShowInSharingSurfaces"); + } + /** @hide */ + public void setShowInSharingSurfaces(@ShowInSharingSurfaces int showInSharingSurfaces) { + this.mShowInSharingSurfaces = showInSharingSurfaces; + setPresent(INDEX_SHOW_IN_SHARING_SURFACES); + } + private int mShowInSharingSurfaces; + + /** * Returns whether a profile should be started when its parent starts (unless in quiet mode). * This only applies for users that have parents (i.e. for profiles). * @hide @@ -700,6 +843,12 @@ public final class UserProperties implements Parcelable { case ATTR_SHOW_IN_SETTINGS: setShowInSettings(parser.getAttributeInt(i)); break; + 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)); break; @@ -750,6 +899,13 @@ public final class UserProperties implements Parcelable { if (isPresent(INDEX_SHOW_IN_SETTINGS)) { serializer.attributeInt(null, ATTR_SHOW_IN_SETTINGS, mShowInSettings); } + 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, mInheritDevicePolicy); @@ -792,6 +948,8 @@ public final class UserProperties implements Parcelable { dest.writeInt(mShowInLauncher); dest.writeBoolean(mStartWithParent); dest.writeInt(mShowInSettings); + dest.writeInt(mShowInQuietMode); + dest.writeInt(mShowInSharingSurfaces); dest.writeInt(mInheritDevicePolicy); dest.writeBoolean(mUseParentsContacts); dest.writeBoolean(mUpdateCrossProfileIntentFiltersOnOTA); @@ -813,6 +971,8 @@ public final class UserProperties implements Parcelable { mShowInLauncher = source.readInt(); mStartWithParent = source.readBoolean(); mShowInSettings = source.readInt(); + mShowInQuietMode = source.readInt(); + mShowInSharingSurfaces = source.readInt(); mInheritDevicePolicy = source.readInt(); mUseParentsContacts = source.readBoolean(); mUpdateCrossProfileIntentFiltersOnOTA = source.readBoolean(); @@ -848,6 +1008,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 @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; @@ -876,6 +1040,19 @@ public final class UserProperties implements Parcelable { return this; } + /** 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; + } + + /** Sets the value for {@link #mInheritDevicePolicy}*/ public Builder setInheritDevicePolicy( @InheritDevicePolicy int inheritRestrictionsDevicePolicy) { @@ -932,6 +1109,8 @@ public final class UserProperties implements Parcelable { mShowInLauncher, mStartWithParent, mShowInSettings, + mShowInQuietMode, + mShowInSharingSurfaces, mInheritDevicePolicy, mUseParentsContacts, mUpdateCrossProfileIntentFiltersOnOTA, @@ -948,6 +1127,8 @@ public final class UserProperties implements Parcelable { @ShowInLauncher int showInLauncher, boolean startWithParent, @ShowInSettings int showInSettings, + @ShowInQuietMode int showInQuietMode, + @ShowInSharingSurfaces int showInSharingSurfaces, @InheritDevicePolicy int inheritDevicePolicy, boolean useParentsContacts, boolean updateCrossProfileIntentFiltersOnOTA, @CrossProfileIntentFilterAccessControlLevel int crossProfileIntentFilterAccessControl, @@ -959,6 +1140,8 @@ public final class UserProperties implements Parcelable { setShowInLauncher(showInLauncher); setStartWithParent(startWithParent); setShowInSettings(showInSettings); + setShowInQuietMode(showInQuietMode); + setShowInSharingSurfaces(showInSharingSurfaces); setInheritDevicePolicy(inheritDevicePolicy); setUseParentsContacts(useParentsContacts); setUpdateCrossProfileIntentFiltersOnOTA(updateCrossProfileIntentFiltersOnOTA); diff --git a/core/java/android/os/IUserManager.aidl b/core/java/android/os/IUserManager.aidl index 8e1d2d6c97e6..4f4676950cf0 100644 --- a/core/java/android/os/IUserManager.aidl +++ b/core/java/android/os/IUserManager.aidl @@ -129,6 +129,7 @@ interface IUserManager { int getUserBadgeColorResId(int userId); int getUserBadgeDarkColorResId(int userId); boolean hasBadge(int userId); + int getProfileLabelResId(int userId); boolean isUserUnlocked(int userId); boolean isUserRunning(int userId); boolean isUserForeground(int userId); diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java index 84f1880213b8..683bc3189c43 100644 --- a/core/java/android/os/UserManager.java +++ b/core/java/android/os/UserManager.java @@ -16,6 +16,7 @@ package android.os; +import static android.app.admin.DevicePolicyResources.Drawables.Style.SOLID_COLORED; import static android.app.admin.DevicePolicyResources.Strings.Core.WORK_PROFILE_BADGED_LABEL; import static android.app.admin.DevicePolicyResources.UNDEFINED; @@ -5393,6 +5394,38 @@ public class UserManager { } /** + * Retrieves a user badge associated with the current context user. This is only + * applicable to profile users since non-profile users do not have badges. + * + * @return A {@link Drawable} user badge corresponding to the context user + * @throws android.content.res.Resources.NotFoundException if the user is not a profile or + * does not have a badge defined. + * @hide + */ + @SystemApi + @UserHandleAware( + requiresAnyOfPermissionsIfNotCallerProfileGroup = { + Manifest.permission.MANAGE_USERS, + Manifest.permission.INTERACT_ACROSS_USERS}) + @SuppressLint("UnflaggedApi") // b/306636213 + public @NonNull Drawable getUserBadge() { + if (!isProfile(mUserId)) { + throw new Resources.NotFoundException("No badge found for this user."); + } + if (isManagedProfile(mUserId)) { + DevicePolicyManager dpm = mContext.getSystemService(DevicePolicyManager.class); + return dpm.getResources().getDrawable( + android.app.admin.DevicePolicyResources.Drawables.WORK_PROFILE_ICON_BADGE, + SOLID_COLORED, () -> getDefaultUserBadge(mUserId)); + } + return getDefaultUserBadge(mUserId); + } + + private Drawable getDefaultUserBadge(@UserIdInt int userId) { + return mContext.getResources().getDrawable(getUserBadgeResId(userId), mContext.getTheme()); + } + + /** * If the target user is a profile of the calling user or the caller * is itself a profile, then this returns a copy of the label with * badging for accessibility services like talkback. E.g. passing in "Email" @@ -5434,6 +5467,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). * Returns false for any other type of user. diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml index 698a717090d3..7a73bee4fb53 100644 --- a/core/res/res/values-ar/strings.xml +++ b/core/res/res/values-ar/strings.xml @@ -1687,7 +1687,7 @@ <string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"إزالة"</string> <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"هل تريد رفع مستوى الصوت فوق المستوى الموصى به؟\n\nقد يضر سماع صوت عالٍ لفترات طويلة بسمعك."</string> <string name="csd_dose_reached_warning" product="default" msgid="491875107583931974">"هل تريد مواصلة الاستماع بصوت عالٍ؟\n\nكان مستوى صوت سمّاعة الرأس مرتفعًا لمدة أطول مما يُنصَح به، وقد يضر هذا بسمعك."</string> - <string name="csd_momentary_exposure_warning" product="default" msgid="7730840903435405501">"تم رصد صوت مرتفع\n\nكان مستوى صوت سمّاعة الرأس مرتفعًا لمدة أطول مما يُنصَح به، وقد يضر هذا بسمعك."</string> + <string name="csd_momentary_exposure_warning" product="default" msgid="7730840903435405501">"تم رصد صوت مرتفع\n\nكان مستوى صوت سمّاعة الرأس أعلى من المستوى الذي يُنصَح به، ما قد يضرّ بسمعك."</string> <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"هل تريد استخدام اختصار \"سهولة الاستخدام\"؟"</string> <string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"عند تفعيل الاختصار، يؤدي الضغط على زرّي التحكّم في مستوى الصوت معًا لمدة 3 ثوانٍ إلى تفعيل إحدى ميزات إمكانية الوصول."</string> <string name="accessibility_shortcut_multiple_service_warning_title" msgid="3135860819356676426">"هل تريد تفعيل الاختصار لميزات إمكانية الوصول؟"</string> diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml index 7ecd38e38426..e960ff0a2e2e 100644 --- a/core/res/res/values-es/strings.xml +++ b/core/res/res/values-es/strings.xml @@ -1684,7 +1684,7 @@ <string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"Quitar"</string> <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"¿Quieres subir el volumen por encima del nivel recomendado?\n\nEscuchar sonidos fuertes durante mucho tiempo puede dañar los oídos."</string> <string name="csd_dose_reached_warning" product="default" msgid="491875107583931974">"¿Seguir escuchando a un volumen alto?\n\nEl volumen de los auriculares ha estado alto durante más tiempo del recomendado, lo que puede dañar tu audición."</string> - <string name="csd_momentary_exposure_warning" product="default" msgid="7730840903435405501">"Sonido alto detectado\n\nEl volumen de los auriculares está más alto de lo recomendado, lo que puede dañar tu audición."</string> + <string name="csd_momentary_exposure_warning" product="default" msgid="7730840903435405501">"Volumen alto detectado\n\nEl volumen de los auriculares está más alto de lo recomendado, lo que puede dañar tu audición."</string> <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"¿Utilizar acceso directo de accesibilidad?"</string> <string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"Si el acceso directo está activado, pulsa los dos botones de volumen durante 3 segundos para iniciar una función de accesibilidad."</string> <string name="accessibility_shortcut_multiple_service_warning_title" msgid="3135860819356676426">"¿Quieres activar el acceso directo a las funciones de accesibilidad?"</string> diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml index 30aa88e9c183..6735f0b69892 100644 --- a/core/res/res/values-hi/strings.xml +++ b/core/res/res/values-hi/strings.xml @@ -1939,7 +1939,7 @@ <string name="language_selection_title" msgid="52674936078683285">"भाषा जोड़ें"</string> <string name="country_selection_title" msgid="5221495687299014379">"क्षेत्र प्राथमिकता"</string> <string name="search_language_hint" msgid="7004225294308793583">"भाषा का नाम लिखें"</string> - <string name="language_picker_section_suggested" msgid="6556199184638990447">"दिए गए सुझाव"</string> + <string name="language_picker_section_suggested" msgid="6556199184638990447">"सुझाई गई भाषाएं"</string> <string name="language_picker_regions_section_suggested" msgid="6080131515268225316">"सुझाए गए देश/इलाके"</string> <string name="language_picker_section_suggested_bilingual" msgid="5932198319583556613">"सुझाई गई भाषाएं"</string> <string name="region_picker_section_suggested_bilingual" msgid="704607569328224133">"सुझाए गए इलाके"</string> diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml index 7aa4eb7c88de..afb451a4b667 100644 --- a/core/res/res/values-in/strings.xml +++ b/core/res/res/values-in/strings.xml @@ -1240,7 +1240,7 @@ <string name="unsupported_display_size_show" msgid="980129850974919375">"Selalu tampilkan"</string> <string name="unsupported_compile_sdk_message" msgid="7326293500707890537">"<xliff:g id="APP_NAME">%1$s</xliff:g> dibuat untuk versi OS Android yang tidak kompatibel dan mungkin berperilaku tak terduga. Versi aplikasi yang diupdate mungkin tersedia."</string> <string name="unsupported_compile_sdk_show" msgid="1601210057960312248">"Selalu tampilkan"</string> - <string name="unsupported_compile_sdk_check_update" msgid="1103639989147664456">"Periksa apakah ada update"</string> + <string name="unsupported_compile_sdk_check_update" msgid="1103639989147664456">"Periksa update"</string> <string name="smv_application" msgid="3775183542777792638">"Apl <xliff:g id="APPLICATION">%1$s</xliff:g> (proses <xliff:g id="PROCESS">%2$s</xliff:g>) telah melanggar kebijakan StrictMode yang diberlakukannya sendiri."</string> <string name="smv_process" msgid="1398801497130695446">"Proses <xliff:g id="PROCESS">%1$s</xliff:g> telah melanggar kebijakan StrictMode yang diberlakukan secara otomatis."</string> <string name="android_upgrading_title" product="default" msgid="7279077384220829683">"Mengupdate ponsel…"</string> @@ -1974,7 +1974,7 @@ <string name="app_streaming_blocked_message_for_settings_dialog" product="tablet" msgid="3286849551133045896">"Setelan ini tidak dapat diakses di <xliff:g id="DEVICE">%1$s</xliff:g>. Coba di tablet."</string> <string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"Setelan ini tidak dapat diakses di <xliff:g id="DEVICE">%1$s</xliff:g>. Coba di ponsel."</string> <string name="deprecated_target_sdk_message" msgid="5246906284426844596">"Aplikasi ini dibuat untuk versi lama Android. Aplikasi mungkin tidak berfungsi dengan baik dan tidak menyertakan perlindungan privasi dan keamanan terbaru. Periksa update, atau hubungi developer aplikasi."</string> - <string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Periksa apakah ada update"</string> + <string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Periksa update"</string> <string name="deprecated_abi_message" msgid="6820548011196218091">"Aplikasi ini tidak kompatibel dengan versi terbaru Android. Periksa update atau hubungi developer aplikasi."</string> <string name="new_sms_notification_title" msgid="6528758221319927107">"Ada pesan baru"</string> <string name="new_sms_notification_content" msgid="3197949934153460639">"Buka aplikasi SMS untuk melihat"</string> diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml index a5b2b853fddd..ae4cdfda8c38 100644 --- a/core/res/res/values/strings.xml +++ b/core/res/res/values/strings.xml @@ -6295,4 +6295,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> diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index 2425d367e1db..a4ad258cca88 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -1074,6 +1074,13 @@ <java-symbol type="string" name="managed_profile_label_badge_2" /> <java-symbol type="string" name="managed_profile_label_badge_3" /> <java-symbol type="string" name="clone_profile_label_badge" /> + <java-symbol type="string" name="profile_label_private" /> + <java-symbol type="string" name="profile_label_clone" /> + <java-symbol type="string" name="profile_label_work" /> + <java-symbol type="string" name="profile_label_work_2" /> + <java-symbol type="string" name="profile_label_work_3" /> + <java-symbol type="string" name="profile_label_test" /> + <java-symbol type="string" name="profile_label_communal" /> <java-symbol type="string" name="mediasize_unknown_portrait" /> <java-symbol type="string" name="mediasize_unknown_landscape" /> <java-symbol type="string" name="mediasize_iso_a0" /> diff --git a/packages/SettingsLib/res/values-lv/strings.xml b/packages/SettingsLib/res/values-lv/strings.xml index 807df3a3f91d..bf159c5df2b4 100644 --- a/packages/SettingsLib/res/values-lv/strings.xml +++ b/packages/SettingsLib/res/values-lv/strings.xml @@ -260,9 +260,9 @@ <string name="keep_screen_on_summary" msgid="1510731514101925829">"Uzlādes laikā ekrāns nekad nepārslēgsies miega režīmā"</string> <string name="bt_hci_snoop_log" msgid="7291287955649081448">"Iespējot Bluetooth HCI analizētāja žurnālu"</string> <string name="bt_hci_snoop_log_summary" msgid="6808538971394092284">"Tvert Bluetooth paketes. (Pārslēgt Bluetooth pēc šī iestatījuma mainīšanas.)"</string> - <string name="oem_unlock_enable" msgid="5334869171871566731">"OEM atbloķēšana"</string> + <string name="oem_unlock_enable" msgid="5334869171871566731">"OAR atbloķēšana"</string> <string name="oem_unlock_enable_summary" msgid="5857388174390953829">"Atļaut palaišanas ielādētāja atbloķēšanu"</string> - <string name="confirm_enable_oem_unlock_title" msgid="8249318129774367535">"Vai atļaut OEM atbloķēšanu?"</string> + <string name="confirm_enable_oem_unlock_title" msgid="8249318129774367535">"Vai atļaut OAR atbloķēšanu?"</string> <string name="confirm_enable_oem_unlock_text" msgid="854131050791011970">"BRĪDINĀJUMS. Kamēr šis iestatījums būs ieslēgts, ierīces aizsardzības funkcijas nedarbosies."</string> <string name="mock_location_app" msgid="6269380172542248304">"Atlasīt imitētas atrašanās vietas lietotni"</string> <string name="mock_location_app_not_set" msgid="6972032787262831155">"Nav iestatīta imitētas atrašanās vietas lietotne"</string> diff --git a/packages/SoundPicker/res/values-ro/strings.xml b/packages/SoundPicker/res/values-ro/strings.xml index 58b5aeb4dca8..01a2a1ad6bfa 100644 --- a/packages/SoundPicker/res/values-ro/strings.xml +++ b/packages/SoundPicker/res/values-ro/strings.xml @@ -19,7 +19,7 @@ <string name="ringtone_default" msgid="798836092118824500">"Ton de apel prestabilit"</string> <string name="notification_sound_default" msgid="8133121186242636840">"Sunet de notificare prestabilit"</string> <string name="alarm_sound_default" msgid="4787646764557462649">"Sunet de alarmă prestabilit"</string> - <string name="add_ringtone_text" msgid="6642389991738337529">"Adaugă un ton de sonerie"</string> + <string name="add_ringtone_text" msgid="6642389991738337529">"Adaugă un ton de apel"</string> <string name="add_alarm_text" msgid="3545497316166999225">"Adaugă o alarmă"</string> <string name="add_notification_text" msgid="4431129543300614788">"Adaugă o notificare"</string> <string name="delete_ringtone_text" msgid="201443984070732499">"Șterge"</string> diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml index cb3bbd6375f0..4fe456617d6e 100644 --- a/packages/SystemUI/res/values-nb/strings.xml +++ b/packages/SystemUI/res/values-nb/strings.xml @@ -479,7 +479,7 @@ <string name="volume_odi_captions_hint_disable" msgid="2518846326748183407">"deaktiver"</string> <string name="sound_settings" msgid="8874581353127418308">"Lyd og vibrering"</string> <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"Innstillinger"</string> - <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"Senk volumet til et tryggere nivå"</string> + <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"Volumet er senket til et tryggere nivå"</string> <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"Volumet på hodetelefonene har vært høyt lenger enn anbefalt"</string> <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"Volumet på hodetelefonene har overskredet sikkerhetsgrensen for denne uken"</string> <string name="csd_button_keep_listening" product="default" msgid="4093794049149286784">"Fortsett å lytte"</string> @@ -1127,7 +1127,7 @@ <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Trykk på og hold inne snarveien"</string> <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Avbryt"</string> <string name="rear_display_bottom_sheet_confirm" msgid="1507591562761552899">"Bytt skjerm nå"</string> - <string name="rear_display_folded_bottom_sheet_title" msgid="3930008746560711990">"Brett ut telefonen"</string> + <string name="rear_display_folded_bottom_sheet_title" msgid="3930008746560711990">"Åpne telefonen"</string> <string name="rear_display_unfolded_bottom_sheet_title" msgid="6291111173057304055">"Vil du bytte skjerm?"</string> <string name="rear_display_folded_bottom_sheet_description" msgid="6842767125783222695">"Bruk baksidekameraet for å få høyere oppløsning"</string> <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Brett ut telefonen for å få høyere oppløsning"</string> diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml index c9e41766a2f0..d903e3dfbc4e 100644 --- a/packages/SystemUI/res/values-pt-rPT/strings.xml +++ b/packages/SystemUI/res/values-pt-rPT/strings.xml @@ -1038,7 +1038,7 @@ <string name="person_available" msgid="2318599327472755472">"Disponível"</string> <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Ocorreu um problema ao ler o medidor da bateria"</string> <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Toque para obter mais informações"</string> - <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Nenhum alarme defin."</string> + <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Nenhum alarme definido"</string> <string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Sensor de impressões digitais"</string> <string name="accessibility_authenticate_hint" msgid="798914151813205721">"autenticar"</string> <string name="accessibility_enter_hint" msgid="2617864063504824834">"entrar no dispositivo"</string> diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml index 6a6def074986..87a7786a8551 100644 --- a/packages/SystemUI/res/values-ro/strings.xml +++ b/packages/SystemUI/res/values-ro/strings.xml @@ -105,7 +105,7 @@ <string name="screenrecord_permission_dialog_continue" msgid="5811122652514424967">"Începe înregistrarea"</string> <string name="screenrecord_audio_label" msgid="6183558856175159629">"Înregistrează audio"</string> <string name="screenrecord_device_audio_label" msgid="9016927171280567791">"Conținutul audio de la dispozitiv"</string> - <string name="screenrecord_device_audio_description" msgid="4922694220572186193">"Sunetul de la dispozitiv, precum muzică, apeluri și tonuri de sonerie"</string> + <string name="screenrecord_device_audio_description" msgid="4922694220572186193">"Sunetul de la dispozitiv, precum muzică, apeluri și tonuri de apel"</string> <string name="screenrecord_mic_label" msgid="2111264835791332350">"Microfon"</string> <string name="screenrecord_device_audio_and_mic_label" msgid="1831323771978646841">"Conținutul audio de la dispozitiv și microfon"</string> <string name="screenrecord_continue" msgid="4055347133700593164">"Începe"</string> diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml index d868e88c65ba..f43851c09c35 100644 --- a/packages/SystemUI/res/values-vi/strings.xml +++ b/packages/SystemUI/res/values-vi/strings.xml @@ -795,7 +795,7 @@ <string name="mobile_data_text_format" msgid="6806501540022589786">"<xliff:g id="ID_1">%1$s</xliff:g> — <xliff:g id="ID_2">%2$s</xliff:g>"</string> <string name="mobile_carrier_text_format" msgid="8912204177152950766">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="MOBILE_DATA_TYPE">%2$s</xliff:g>"</string> <string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi đang tắt"</string> - <string name="bt_is_off" msgid="7436344904889461591">"Bluetooth tắt"</string> + <string name="bt_is_off" msgid="7436344904889461591">"Bluetooth đang tắt"</string> <string name="dnd_is_off" msgid="3185706903793094463">"Không làm phiền tắt"</string> <string name="dnd_is_on" msgid="7009368176361546279">"Chế độ Không làm phiền đang bật"</string> <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Không làm phiền đã được một quy tắc tự động (<xliff:g id="ID_1">%s</xliff:g>) bật."</string> diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java index b03fb31fbb1e..bea6a2f5c22c 100644 --- a/services/core/java/com/android/server/pm/UserManagerService.java +++ b/services/core/java/com/android/server/pm/UserManagerService.java @@ -1877,6 +1877,19 @@ public class UserManagerService extends IUserManager.Stub { return userTypeDetails.getBadgeNoBackground(); } + @Override + public @StringRes int getProfileLabelResId(@UserIdInt int userId) { + checkQueryOrInteractPermissionIfCallerInOtherProfileGroup(userId, + "getProfileLabelResId"); + final UserInfo userInfo = getUserInfoNoChecks(userId); + final UserTypeDetails userTypeDetails = getUserTypeDetails(userInfo); + if (userInfo == null || userTypeDetails == null) { + return Resources.ID_NULL; + } + final int userIndex = userInfo.profileBadge; + return userTypeDetails.getLabel(userIndex); + } + public boolean isProfile(@UserIdInt int userId) { checkQueryOrInteractPermissionIfCallerInOtherProfileGroup(userId, "isProfile"); return isProfileUnchecked(userId); diff --git a/services/core/java/com/android/server/pm/UserTypeDetails.java b/services/core/java/com/android/server/pm/UserTypeDetails.java index 6065372e1ea0..f97daebd0bea 100644 --- a/services/core/java/com/android/server/pm/UserTypeDetails.java +++ b/services/core/java/com/android/server/pm/UserTypeDetails.java @@ -54,8 +54,15 @@ public final class UserTypeDetails { /** Whether users of this type can be created. */ private final boolean mEnabled; - // TODO(b/142482943): Currently unused and not set. Hook this up. - private final int mLabel; + /** + * Resource IDs ({@link StringRes}) of the user's labels. This might be used to label a + * user/profile in tabbed views, etc. + * The values are resource IDs referring to the strings not the strings themselves. + * + * <p>This is an array because, in general, there may be multiple users of the same user type. + * In this case, the user is indexed according to its {@link UserInfo#profileBadge}. + */ + private final @Nullable int[] mLabels; /** * Maximum number of this user type allowed on the device. @@ -157,8 +164,8 @@ public final class UserTypeDetails { private final @NonNull UserProperties mDefaultUserProperties; private UserTypeDetails(@NonNull String name, boolean enabled, int maxAllowed, - @UserInfoFlag int baseType, @UserInfoFlag int defaultUserInfoPropertyFlags, int label, - int maxAllowedPerParent, + @UserInfoFlag int baseType, @UserInfoFlag int defaultUserInfoPropertyFlags, + @Nullable int[] labels, int maxAllowedPerParent, int iconBadge, int badgePlain, int badgeNoBackground, @Nullable int[] badgeLabels, @Nullable int[] badgeColors, @Nullable int[] darkThemeBadgeColors, @@ -177,11 +184,10 @@ public final class UserTypeDetails { this.mDefaultSystemSettings = defaultSystemSettings; this.mDefaultSecureSettings = defaultSecureSettings; this.mDefaultCrossProfileIntentFilters = defaultCrossProfileIntentFilters; - this.mIconBadge = iconBadge; this.mBadgePlain = badgePlain; this.mBadgeNoBackground = badgeNoBackground; - this.mLabel = label; + this.mLabels = labels; this.mBadgeLabels = badgeLabels; this.mBadgeColors = badgeColors; this.mDarkThemeBadgeColors = darkThemeBadgeColors; @@ -229,9 +235,16 @@ public final class UserTypeDetails { return mDefaultUserInfoPropertyFlags | mBaseType; } - // TODO(b/142482943) Hook this up; it is currently unused. - public int getLabel() { - return mLabel; + /** + * Returns the resource ID corresponding to the badgeIndexth label name where the badgeIndex is + * expected to be the {@link UserInfo#profileBadge} of the user. If badgeIndex exceeds the + * number of labels, returns the label for the highest index. + */ + public @StringRes int getLabel(int badgeIndex) { + if (mLabels == null || mLabels.length == 0 || badgeIndex < 0) { + return Resources.ID_NULL; + } + return mLabels[Math.min(badgeIndex, mLabels.length - 1)]; } /** Returns whether users of this user type should be badged. */ @@ -348,7 +361,6 @@ public final class UserTypeDetails { pw.print(prefix); pw.print("mMaxAllowedPerParent: "); pw.println(mMaxAllowedPerParent); pw.print(prefix); pw.print("mDefaultUserInfoFlags: "); pw.println(UserInfo.flagsToString(mDefaultUserInfoPropertyFlags)); - pw.print(prefix); pw.print("mLabel: "); pw.println(mLabel); mDefaultUserProperties.println(pw, prefix); final String restrictionsPrefix = prefix + " "; @@ -381,6 +393,8 @@ public final class UserTypeDetails { pw.println(mBadgeColors != null ? mBadgeColors.length : "0(null)"); pw.print(prefix); pw.print("mDarkThemeBadgeColors.length: "); pw.println(mDarkThemeBadgeColors != null ? mDarkThemeBadgeColors.length : "0(null)"); + pw.print(prefix); pw.print("mLabels.length: "); + pw.println(mLabels != null ? mLabels.length : "0(null)"); } /** Builder for a {@link UserTypeDetails}; see that class for documentation. */ @@ -397,13 +411,14 @@ public final class UserTypeDetails { private @Nullable List<DefaultCrossProfileIntentFilter> mDefaultCrossProfileIntentFilters = null; private int mEnabled = 1; - private int mLabel = Resources.ID_NULL; + private @Nullable int[] mLabels = null; private @Nullable int[] mBadgeLabels = null; private @Nullable int[] mBadgeColors = null; private @Nullable int[] mDarkThemeBadgeColors = null; private @DrawableRes int mIconBadge = Resources.ID_NULL; private @DrawableRes int mBadgePlain = Resources.ID_NULL; private @DrawableRes int mBadgeNoBackground = Resources.ID_NULL; + private @DrawableRes int mStatusBarIcon = Resources.ID_NULL; // Default UserProperties cannot be null but for efficiency we don't initialize it now. // If it isn't set explicitly, {@link UserProperties.Builder#build()} will be used. private @Nullable UserProperties mDefaultUserProperties = null; @@ -471,8 +486,9 @@ public final class UserTypeDetails { return this; } - public Builder setLabel(int label) { - mLabel = label; + /** Returns labels */ + public Builder setLabels(@StringRes int ... labels) { + mLabels = labels; return this; } @@ -545,7 +561,7 @@ public final class UserTypeDetails { mMaxAllowed, mBaseType, mDefaultUserInfoPropertyFlags, - mLabel, + mLabels, mMaxAllowedPerParent, mIconBadge, mBadgePlain, diff --git a/services/core/java/com/android/server/pm/UserTypeFactory.java b/services/core/java/com/android/server/pm/UserTypeFactory.java index a814ca46fa5e..aa1ae2fed0db 100644 --- a/services/core/java/com/android/server/pm/UserTypeFactory.java +++ b/services/core/java/com/android/server/pm/UserTypeFactory.java @@ -49,6 +49,7 @@ import android.os.UserManager; import android.util.ArrayMap; import android.util.Slog; +import com.android.internal.R; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.XmlUtils; @@ -123,7 +124,7 @@ public final class UserTypeFactory { .setName(USER_TYPE_PROFILE_CLONE) .setBaseType(FLAG_PROFILE) .setMaxAllowedPerParent(1) - .setLabel(0) + .setLabels(R.string.profile_label_clone) .setIconBadge(com.android.internal.R.drawable.ic_clone_icon_badge) .setBadgePlain(com.android.internal.R.drawable.ic_clone_badge) // Clone doesn't use BadgeNoBackground, so just set to BadgePlain as a placeholder. @@ -148,6 +149,10 @@ public final class UserTypeFactory { UserProperties.CROSS_PROFILE_INTENT_FILTER_ACCESS_LEVEL_SYSTEM) .setCrossProfileIntentResolutionStrategy(UserProperties .CROSS_PROFILE_INTENT_RESOLUTION_STRATEGY_NO_FILTERING) + .setShowInQuietMode( + UserProperties.SHOW_IN_QUIET_MODE_DEFAULT) + .setShowInSharingSurfaces( + UserProperties.SHOW_IN_SHARING_SURFACES_WITH_PARENT) .setMediaSharedWithParent(true) .setCredentialShareableWithParent(true) .setDeleteAppWithParent(true)); @@ -163,7 +168,10 @@ public final class UserTypeFactory { .setBaseType(FLAG_PROFILE) .setDefaultUserInfoPropertyFlags(FLAG_MANAGED_PROFILE) .setMaxAllowedPerParent(1) - .setLabel(0) + .setLabels( + R.string.profile_label_work, + R.string.profile_label_work_2, + R.string.profile_label_work_3) .setIconBadge(com.android.internal.R.drawable.ic_corp_icon_badge_case) .setBadgePlain(com.android.internal.R.drawable.ic_corp_badge_case) .setBadgeNoBackground(com.android.internal.R.drawable.ic_corp_badge_no_background) @@ -186,6 +194,10 @@ public final class UserTypeFactory { .setStartWithParent(true) .setShowInLauncher(UserProperties.SHOW_IN_LAUNCHER_SEPARATE) .setShowInSettings(UserProperties.SHOW_IN_SETTINGS_SEPARATE) + .setShowInQuietMode( + UserProperties.SHOW_IN_QUIET_MODE_PAUSED) + .setShowInSharingSurfaces( + UserProperties.SHOW_IN_SHARING_SURFACES_SEPARATE) .setCredentialShareableWithParent(true)); } @@ -201,7 +213,10 @@ public final class UserTypeFactory { .setName(USER_TYPE_PROFILE_TEST) .setBaseType(FLAG_PROFILE) .setMaxAllowedPerParent(2) - .setLabel(0) + .setLabels( + R.string.profile_label_test, + R.string.profile_label_test, + R.string.profile_label_test) .setIconBadge(com.android.internal.R.drawable.ic_test_icon_badge_experiment) .setBadgePlain(com.android.internal.R.drawable.ic_test_badge_experiment) .setBadgeNoBackground(com.android.internal.R.drawable.ic_test_badge_no_background) diff --git a/services/core/java/com/android/server/pm/dex/ArtStatsLogUtils.java b/services/core/java/com/android/server/pm/dex/ArtStatsLogUtils.java index d0c346a63889..57f4a5ddb2bd 100644 --- a/services/core/java/com/android/server/pm/dex/ArtStatsLogUtils.java +++ b/services/core/java/com/android/server/pm/dex/ArtStatsLogUtils.java @@ -337,7 +337,8 @@ public class ArtStatsLogUtils { 0, // deprecated, used to be durationIncludingSleepMs 0, // optimizedPackagesCount 0, // packagesDependingOnBootClasspathCount - 0); // totalPackagesCount + 0, // totalPackagesCount + ArtStatsLog.BACKGROUND_DEXOPT_JOB_ENDED__PASS__PASS_UNKNOWN); } } } diff --git a/services/tests/servicestests/src/com/android/server/pm/UserManagerServiceUserPropertiesTest.java b/services/tests/servicestests/src/com/android/server/pm/UserManagerServiceUserPropertiesTest.java index 2675f05ed8fe..29ff7732da7e 100644 --- a/services/tests/servicestests/src/com/android/server/pm/UserManagerServiceUserPropertiesTest.java +++ b/services/tests/servicestests/src/com/android/server/pm/UserManagerServiceUserPropertiesTest.java @@ -60,6 +60,8 @@ public class UserManagerServiceUserPropertiesTest { .setShowInLauncher(21) .setStartWithParent(false) .setShowInSettings(45) + .setShowInSharingSurfaces(78) + .setShowInQuietMode(12) .setInheritDevicePolicy(67) .setUseParentsContacts(false) .setCrossProfileIntentFilterAccessControl(10) @@ -71,6 +73,8 @@ public class UserManagerServiceUserPropertiesTest { final UserProperties actualProps = new UserProperties(defaultProps); actualProps.setShowInLauncher(14); actualProps.setShowInSettings(32); + actualProps.setShowInSharingSurfaces(46); + actualProps.setShowInQuietMode(27); actualProps.setInheritDevicePolicy(51); actualProps.setUseParentsContacts(true); actualProps.setCrossProfileIntentFilterAccessControl(20); @@ -223,6 +227,10 @@ public class UserManagerServiceUserPropertiesTest { assertThat(expected.getShowInLauncher()).isEqualTo(actual.getShowInLauncher()); assertThat(expected.getStartWithParent()).isEqualTo(actual.getStartWithParent()); assertThat(expected.getShowInSettings()).isEqualTo(actual.getShowInSettings()); + assertThat(expected.getShowInSharingSurfaces()).isEqualTo( + actual.getShowInSharingSurfaces()); + assertThat(expected.getShowInQuietMode()) + .isEqualTo(actual.getShowInQuietMode()); assertThat(expected.getInheritDevicePolicy()).isEqualTo(actual.getInheritDevicePolicy()); assertThat(expected.getUseParentsContacts()).isEqualTo(actual.getUseParentsContacts()); assertThat(expected.getCrossProfileIntentFilterAccessControl()) diff --git a/services/tests/servicestests/src/com/android/server/pm/UserManagerServiceUserTypeTest.java b/services/tests/servicestests/src/com/android/server/pm/UserManagerServiceUserTypeTest.java index ff9a79e61fe0..fe2bf38f65ea 100644 --- a/services/tests/servicestests/src/com/android/server/pm/UserManagerServiceUserTypeTest.java +++ b/services/tests/servicestests/src/com/android/server/pm/UserManagerServiceUserTypeTest.java @@ -90,6 +90,8 @@ public class UserManagerServiceUserTypeTest { .setMediaSharedWithParent(true) .setCredentialShareableWithParent(false) .setShowInSettings(900) + .setShowInSharingSurfaces(20) + .setShowInQuietMode(30) .setInheritDevicePolicy(340) .setDeleteAppWithParent(true); @@ -104,8 +106,8 @@ public class UserManagerServiceUserTypeTest { .setIconBadge(28) .setBadgePlain(29) .setBadgeNoBackground(30) - .setLabel(31) .setMaxAllowedPerParent(32) + .setLabels(34, 35, 36) .setDefaultRestrictions(restrictions) .setDefaultSystemSettings(systemSettings) .setDefaultSecureSettings(secureSettings) @@ -120,8 +122,10 @@ public class UserManagerServiceUserTypeTest { assertEquals(28, type.getIconBadge()); assertEquals(29, type.getBadgePlain()); assertEquals(30, type.getBadgeNoBackground()); - assertEquals(31, type.getLabel()); assertEquals(32, type.getMaxAllowedPerParent()); + assertEquals(34, type.getLabel(0)); + assertEquals(35, type.getLabel(1)); + assertEquals(36, type.getLabel(2)); assertTrue(UserRestrictionsUtils.areEqual(restrictions, type.getDefaultRestrictions())); assertNotSame(restrictions, type.getDefaultRestrictions()); @@ -157,6 +161,9 @@ public class UserManagerServiceUserTypeTest { assertTrue(type.getDefaultUserPropertiesReference().isMediaSharedWithParent()); assertFalse(type.getDefaultUserPropertiesReference().isCredentialShareableWithParent()); assertEquals(900, type.getDefaultUserPropertiesReference().getShowInSettings()); + assertEquals(20, type.getDefaultUserPropertiesReference().getShowInSharingSurfaces()); + assertEquals(30, + type.getDefaultUserPropertiesReference().getShowInQuietMode()); assertEquals(340, type.getDefaultUserPropertiesReference() .getInheritDevicePolicy()); assertTrue(type.getDefaultUserPropertiesReference().getDeleteAppWithParent()); @@ -193,7 +200,7 @@ public class UserManagerServiceUserTypeTest { assertEquals(Resources.ID_NULL, type.getBadgeNoBackground()); assertEquals(Resources.ID_NULL, type.getBadgeLabel(0)); assertEquals(Resources.ID_NULL, type.getBadgeColor(0)); - assertEquals(Resources.ID_NULL, type.getLabel()); + assertEquals(Resources.ID_NULL, type.getLabel(0)); assertTrue(type.getDefaultRestrictions().isEmpty()); assertTrue(type.getDefaultSystemSettings().isEmpty()); assertTrue(type.getDefaultSecureSettings().isEmpty()); @@ -210,6 +217,10 @@ public class UserManagerServiceUserTypeTest { props.getCrossProfileIntentResolutionStrategy()); assertFalse(props.isMediaSharedWithParent()); assertFalse(props.isCredentialShareableWithParent()); + assertFalse(props.getDeleteAppWithParent()); + assertEquals(UserProperties.SHOW_IN_LAUNCHER_SEPARATE, props.getShowInSharingSurfaces()); + assertEquals(UserProperties.SHOW_IN_QUIET_MODE_PAUSED, + props.getShowInQuietMode()); assertFalse(type.hasBadge()); } @@ -298,8 +309,12 @@ public class UserManagerServiceUserTypeTest { .setCredentialShareableWithParent(true) .setShowInSettings(20) .setInheritDevicePolicy(21) + .setDeleteAppWithParent(true) + .setShowInSharingSurfaces(22) + .setShowInQuietMode(24) .setDeleteAppWithParent(true); + final ArrayMap<String, UserTypeDetails.Builder> builders = new ArrayMap<>(); builders.put(userTypeAosp1, new UserTypeDetails.Builder() .setName(userTypeAosp1) @@ -338,6 +353,9 @@ public class UserManagerServiceUserTypeTest { assertEquals(20, aospType.getDefaultUserPropertiesReference().getShowInSettings()); assertEquals(21, aospType.getDefaultUserPropertiesReference() .getInheritDevicePolicy()); + assertEquals(22, aospType.getDefaultUserPropertiesReference().getShowInSharingSurfaces()); + assertEquals(24, + aospType.getDefaultUserPropertiesReference().getShowInQuietMode()); assertTrue(aospType.getDefaultUserPropertiesReference().getDeleteAppWithParent()); // userTypeAosp2 should be modified. @@ -379,6 +397,10 @@ public class UserManagerServiceUserTypeTest { assertFalse(aospType.getDefaultUserPropertiesReference() .isCredentialShareableWithParent()); assertEquals(23, aospType.getDefaultUserPropertiesReference().getShowInSettings()); + assertEquals(22, + aospType.getDefaultUserPropertiesReference().getShowInSharingSurfaces()); + assertEquals(24, + aospType.getDefaultUserPropertiesReference().getShowInQuietMode()); assertEquals(450, aospType.getDefaultUserPropertiesReference() .getInheritDevicePolicy()); assertFalse(aospType.getDefaultUserPropertiesReference() diff --git a/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java b/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java index 6bcda3fbcf43..2f51d9450c2b 100644 --- a/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java +++ b/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java @@ -21,6 +21,7 @@ import static com.google.common.truth.Truth.assertWithMessage; import static org.junit.Assert.fail; import static org.junit.Assume.assumeTrue; +import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertThrows; import android.annotation.UserIdInt; @@ -30,6 +31,7 @@ import android.content.pm.PackageManager; import android.content.pm.UserInfo; import android.content.pm.UserProperties; import android.content.res.Resources; +import android.graphics.drawable.Drawable; import android.os.Bundle; import android.os.UserHandle; import android.os.UserManager; @@ -207,6 +209,9 @@ public final class UserManagerTest { .isEqualTo(cloneUserProperties.isCredentialShareableWithParent()); assertThrows(SecurityException.class, cloneUserProperties::getDeleteAppWithParent); + compareDrawables(mUserManager.getUserBadge(), + Resources.getSystem().getDrawable(userTypeDetails.getBadgePlain())); + // Verify clone user parent assertThat(mUserManager.getProfileParent(mainUserId)).isNull(); UserInfo parentProfileInfo = mUserManager.getProfileParent(userInfo.id); @@ -216,6 +221,45 @@ public final class UserManagerTest { assertThat(mUserManager.getProfileParent(mainUserId)).isNull(); } + @Test + public void testCommunalProfile() throws Exception { + assumeTrue("Device doesn't support communal profiles ", + mUserManager.isUserTypeEnabled(UserManager.USER_TYPE_PROFILE_COMMUNAL)); + + // Create communal profile if needed + if (mUserManager.getCommunalProfile() == null) { + Slog.i(TAG, "Attempting to create a communal profile for a test"); + createUser("Communal", UserManager.USER_TYPE_PROFILE_COMMUNAL, /*flags*/ 0); + } + final UserHandle communal = mUserManager.getCommunalProfile(); + assertWithMessage("Couldn't create communal profile").that(communal).isNotNull(); + + final UserTypeDetails userTypeDetails = + UserTypeFactory.getUserTypes().get(UserManager.USER_TYPE_PROFILE_COMMUNAL); + assertWithMessage("No communal user type on device").that(userTypeDetails).isNotNull(); + + // Test that only one communal profile can be created + final UserInfo secondCommunalProfile = + createUser("Communal", UserManager.USER_TYPE_PROFILE_COMMUNAL, /*flags*/ 0); + assertThat(secondCommunalProfile).isNull(); + + // Verify that communal profile doesn't have a parent + assertThat(mUserManager.getProfileParent(communal.getIdentifier())).isNull(); + + // Make sure that, when switching users, the communal profile remains visible. + final boolean isStarted = mActivityManager.startProfile(communal); + assertWithMessage("Unable to start communal profile").that(isStarted).isTrue(); + final UserManager umCommunal = (UserManager) mContext.createPackageContextAsUser( + "android", 0, communal).getSystemService(Context.USER_SERVICE); + final int originalCurrent = ActivityManager.getCurrentUser(); + final UserInfo testUser = createUser("TestUser", /* flags= */ 0); + assertWithMessage("Communal profile not visible").that(umCommunal.isUserVisible()).isTrue(); + switchUser(testUser.id); + assertWithMessage("Communal profile not visible").that(umCommunal.isUserVisible()).isTrue(); + switchUser(originalCurrent); + assertWithMessage("Communal profile not visible").that(umCommunal.isUserVisible()).isTrue(); + } + @MediumTest @Test public void testAdd2Users() throws Exception { @@ -804,6 +848,9 @@ public final class UserManagerTest { assertThat(mUserManager.getUserBadgeNoBackgroundResId(userId)) .isEqualTo(userTypeDetails.getBadgeNoBackground()); + compareDrawables(mUserManager.getUserBadge(), + Resources.getSystem().getDrawable(userTypeDetails.getBadgePlain())); + final int badgeIndex = userInfo.profileBadge; assertThat(mUserManager.getUserBadgeColor(userId)).isEqualTo( Resources.getSystem().getColor(userTypeDetails.getBadgeColor(badgeIndex), null)); @@ -1554,4 +1601,10 @@ public final class UserManagerTest { .getBoolean(com.android.internal.R.bool.config_isMainUserPermanentAdmin); } + private void compareDrawables(Drawable actual, Drawable expected) { + assertEquals(actual.getIntrinsicWidth(), expected.getIntrinsicWidth()); + assertEquals(actual.getIntrinsicHeight(), expected.getIntrinsicHeight()); + assertEquals(actual.getLevel(), expected.getLevel()); + } + } |