Merge "Add badge colors for dark theme" into rvc-dev am: 78a66d6c36 am: 3e2a0d2682 am: 1c1c47c972 am: c7914e7a94

Change-Id: I344d57b6ace676f599b0919890b9c0c035b062fd
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index d4586cf..1fed828 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -1651,7 +1651,7 @@
         }
         Drawable badge = new LauncherIcons(mContext).getBadgeDrawable(
                 getUserManager().getUserIconBadgeResId(user.getIdentifier()),
-                getUserBadgeColor(user));
+                getUserBadgeColor(user, false));
         return getBadgedDrawable(icon, badge, null, true);
     }
 
@@ -1665,8 +1665,16 @@
         return getBadgedDrawable(drawable, badgeDrawable, badgeLocation, true);
     }
 
-    /** Returns the color of the user's actual badge (not the badge's shadow). */
-    private int getUserBadgeColor(UserHandle user) {
+    /**
+     * Returns the color of the user's actual badge (not the badge's shadow).
+     * @param checkTheme whether to check the theme to determine the badge color. This should be
+     *                   true if the background is determined by the theme. Otherwise, if
+     *                   checkTheme is false, returns the color assuming a light background.
+     */
+    private int getUserBadgeColor(UserHandle user, boolean checkTheme) {
+        if (checkTheme && mContext.getResources().getConfiguration().isNightModeActive()) {
+            return getUserManager().getUserBadgeDarkColor(user.getIdentifier());
+        }
         return getUserManager().getUserBadgeColor(user.getIdentifier());
     }
 
@@ -1680,11 +1688,14 @@
         }
         Drawable badgeForeground = getDrawableForDensity(
                 getUserManager().getUserBadgeResId(user.getIdentifier()), density);
-        badgeForeground.setTint(getUserBadgeColor(user));
+        badgeForeground.setTint(getUserBadgeColor(user, false));
         Drawable badge = new LayerDrawable(new Drawable[] {badgeColor, badgeForeground });
         return badge;
     }
 
+    /**
+     * Returns the badge color based on whether device has dark theme enabled or not.
+     */
     @Override
     public Drawable getUserBadgeForDensityNoBackground(UserHandle user, int density) {
         if (!hasUserBadge(user.getIdentifier())) {
@@ -1693,7 +1704,7 @@
         Drawable badge = getDrawableForDensity(
                 getUserManager().getUserBadgeNoBackgroundResId(user.getIdentifier()), density);
         if (badge != null) {
-            badge.setTint(getUserBadgeColor(user));
+            badge.setTint(getUserBadgeColor(user, true));
         }
         return badge;
     }
diff --git a/core/java/android/os/IUserManager.aidl b/core/java/android/os/IUserManager.aidl
index b10abe7..07363ed 100644
--- a/core/java/android/os/IUserManager.aidl
+++ b/core/java/android/os/IUserManager.aidl
@@ -108,6 +108,7 @@
     int getUserBadgeNoBackgroundResId(int userId);
     int getUserBadgeLabelResId(int userId);
     int getUserBadgeColorResId(int userId);
+    int getUserBadgeDarkColorResId(int userId);
     boolean hasBadge(int userId);
     boolean isUserUnlocked(int userId);
     boolean isUserRunning(int userId);
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index 7912dac..236ea00 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -3663,7 +3663,8 @@
     }
 
     /**
-     * Returns the badge color for the given user (generally to color a profile's icon's badge).
+     * Returns the light theme badge color for the given user (generally to color a profile's
+     * icon's badge).
      *
      * <p>To check whether a badge color is expected for the user, first call {@link #hasBadge}.
      *
@@ -3683,6 +3684,27 @@
     }
 
     /**
+     * Returns the dark theme badge color for the given user (generally to color a profile's icon's
+     * badge).
+     *
+     * <p>To check whether a badge color is expected for the user, first call {@link #hasBadge}.
+     *
+     * @return the color (not the resource ID) to be used for the user's badge
+     * @throws Resources.NotFoundException if no valid badge color exists for this user
+     *
+     * @see #getBadgedIconForUser more information about badging in general
+     * @hide
+     */
+    public @ColorInt int getUserBadgeDarkColor(@UserIdInt int userId) {
+        try {
+            final int resourceId = mService.getUserBadgeDarkColorResId(userId);
+            return Resources.getSystem().getColor(resourceId, null);
+        } catch (RemoteException re) {
+            throw re.rethrowFromSystemServer();
+        }
+    }
+
+    /**
      * Returns the Resource ID of the user's icon badge.
      *
      * @return the Resource ID of the user's icon badge if it has one; otherwise
diff --git a/core/res/res/values/colors.xml b/core/res/res/values/colors.xml
index 831da6f..77ac6db 100644
--- a/core/res/res/values/colors.xml
+++ b/core/res/res/values/colors.xml
@@ -183,6 +183,10 @@
     <color name="profile_badge_2">#ffff6d00</color><!-- Orange -->
     <color name="profile_badge_3">#ff22f033</color><!-- Green -->
 
+    <color name="profile_badge_1_dark">#ff8ab4f8</color><!-- Blue 300-->
+    <color name="profile_badge_2_dark">#fffdd663</color><!-- Orange 300 -->
+    <color name="profile_badge_3_dark">#ff81c995</color><!-- Green 300 -->
+
     <!-- Default instant app badge color -->
     <color name="instant_app_badge">#ff757575</color><!-- Grey -->
 
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 7647068..eda27d7 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -1445,6 +1445,9 @@
   <java-symbol type="color" name="profile_badge_1" />
   <java-symbol type="color" name="profile_badge_2" />
   <java-symbol type="color" name="profile_badge_3" />
+  <java-symbol type="color" name="profile_badge_1_dark" />
+  <java-symbol type="color" name="profile_badge_2_dark" />
+  <java-symbol type="color" name="profile_badge_3_dark" />
   <java-symbol type="color" name="instant_app_badge" />
 
   <java-symbol type="layout" name="action_bar_home" />
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index 82309db..dbc5546 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -1326,6 +1326,9 @@
         return userTypeDetails.getBadgeLabel(badgeIndex);
     }
 
+    /**
+     * @return the color (not the resource ID) to be used for the user's badge in light theme
+     */
     @Override
     public @ColorRes int getUserBadgeColorResId(@UserIdInt int userId) {
         checkManageOrInteractPermissionIfCallerInOtherProfileGroup(userId,
@@ -1333,11 +1336,26 @@
         final UserInfo userInfo = getUserInfoNoChecks(userId);
         final UserTypeDetails userTypeDetails = getUserTypeDetails(userInfo);
         if (userInfo == null || userTypeDetails == null || !userTypeDetails.hasBadge()) {
+            Slog.e(LOG_TAG, "Requested badge dark color for non-badged user " + userId);
+            return Resources.ID_NULL;
+        }
+        return userTypeDetails.getBadgeColor(userInfo.profileBadge);
+    }
+
+    /**
+     * @return the color (not the resource ID) to be used for the user's badge in dark theme
+     */
+    @Override
+    public @ColorRes int getUserBadgeDarkColorResId(@UserIdInt int userId) {
+        checkManageOrInteractPermissionIfCallerInOtherProfileGroup(userId,
+                "getUserBadgeDarkColorResId");
+        final UserInfo userInfo = getUserInfoNoChecks(userId);
+        final UserTypeDetails userTypeDetails = getUserTypeDetails(userInfo);
+        if (userInfo == null || userTypeDetails == null || !userTypeDetails.hasBadge()) {
             Slog.e(LOG_TAG, "Requested badge color for non-badged user " + userId);
             return Resources.ID_NULL;
         }
-        final int badgeIndex = userInfo.profileBadge;
-        return userTypeDetails.getBadgeColor(badgeIndex);
+        return userTypeDetails.getDarkThemeBadgeColor(userInfo.profileBadge);
     }
 
     @Override
diff --git a/services/core/java/com/android/server/pm/UserTypeDetails.java b/services/core/java/com/android/server/pm/UserTypeDetails.java
index 717737f..be6880e 100644
--- a/services/core/java/com/android/server/pm/UserTypeDetails.java
+++ b/services/core/java/com/android/server/pm/UserTypeDetails.java
@@ -116,11 +116,23 @@
      */
     private final @Nullable int[] mBadgeColors;
 
+    /**
+     * Resource ID ({@link ColorRes}) of the colors badge put on icons when in dark theme.
+     * (The value is a resource ID referring to the color; it is not the color value itself).
+     *
+     * <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}.
+     *
+     * <p>Must be set if mIconBadge is set.
+     */
+    private final @Nullable int[] mDarkThemeBadgeColors;
+
     private UserTypeDetails(@NonNull String name, boolean enabled, int maxAllowed,
             @UserInfoFlag int baseType, @UserInfoFlag int defaultUserInfoPropertyFlags, int label,
             int maxAllowedPerParent,
             int iconBadge, int badgePlain, int badgeNoBackground,
             @Nullable int[] badgeLabels, @Nullable int[] badgeColors,
+            @Nullable int[] darkThemeBadgeColors,
             @Nullable Bundle defaultRestrictions) {
         this.mName = name;
         this.mEnabled = enabled;
@@ -136,6 +148,7 @@
         this.mLabel = label;
         this.mBadgeLabels = badgeLabels;
         this.mBadgeColors = badgeColors;
+        this.mDarkThemeBadgeColors = darkThemeBadgeColors;
     }
 
     /**
@@ -222,6 +235,19 @@
         return mBadgeColors[Math.min(badgeIndex, mBadgeColors.length - 1)];
     }
 
+    /**
+     * Returns the Resource ID of the badgeIndexth dark theme badge color, where the badgeIndex is
+     * expected to be the {@link UserInfo#profileBadge} of the user.
+     * If dark theme badge colors haven't been set, use the light theme badge color.
+     * If badgeIndex exceeds the number of colors, returns the color for the highest index.
+     */
+    public @ColorRes int getDarkThemeBadgeColor(int badgeIndex) {
+        if (mDarkThemeBadgeColors == null || mDarkThemeBadgeColors.length == 0 || badgeIndex < 0) {
+            return getBadgeColor(badgeIndex);
+        }
+        return mDarkThemeBadgeColors[Math.min(badgeIndex, mDarkThemeBadgeColors.length - 1)];
+    }
+
     public boolean isProfile() {
         return (mBaseType & UserInfo.FLAG_PROFILE) != 0;
     }
@@ -283,6 +309,8 @@
         pw.println(mBadgeLabels != null ? mBadgeLabels.length : "0(null)");
         pw.print(prefix); pw.print("mBadgeColors.length: ");
         pw.println(mBadgeColors != null ? mBadgeColors.length : "0(null)");
+        pw.print(prefix); pw.print("mDarkThemeBadgeColors.length: ");
+        pw.println(mDarkThemeBadgeColors != null ? mDarkThemeBadgeColors.length : "0(null)");
     }
 
     /** Builder for a {@link UserTypeDetails}; see that class for documentation. */
@@ -298,6 +326,7 @@
         private int mLabel = Resources.ID_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;
@@ -342,6 +371,14 @@
             return this;
         }
 
+        /**
+         * The badge colors when the badge is on a dark background.
+         */
+        public Builder setDarkThemeBadgeColors(@ColorRes int ... darkThemeBadgeColors) {
+            mDarkThemeBadgeColors = darkThemeBadgeColors;
+            return this;
+        }
+
         public Builder setIconBadge(@DrawableRes int badgeIcon) {
             mIconBadge = badgeIcon;
             return this;
@@ -385,10 +422,10 @@
                 Preconditions.checkArgument(mBadgeColors != null && mBadgeColors.length != 0,
                         "UserTypeDetails " + mName + " has badge but no badgeColors.");
             }
-
             return new UserTypeDetails(mName, mEnabled, mMaxAllowed, mBaseType,
                     mDefaultUserInfoPropertyFlags, mLabel, mMaxAllowedPerParent,
                     mIconBadge, mBadgePlain, mBadgeNoBackground, mBadgeLabels, mBadgeColors,
+                    mDarkThemeBadgeColors == null ? mBadgeColors : mDarkThemeBadgeColors,
                     mDefaultRestrictions);
         }
 
diff --git a/services/core/java/com/android/server/pm/UserTypeFactory.java b/services/core/java/com/android/server/pm/UserTypeFactory.java
index 7d45516..2e8a267 100644
--- a/services/core/java/com/android/server/pm/UserTypeFactory.java
+++ b/services/core/java/com/android/server/pm/UserTypeFactory.java
@@ -116,6 +116,10 @@
                         com.android.internal.R.color.profile_badge_1,
                         com.android.internal.R.color.profile_badge_2,
                         com.android.internal.R.color.profile_badge_3)
+                .setDarkThemeBadgeColors(
+                        com.android.internal.R.color.profile_badge_1_dark,
+                        com.android.internal.R.color.profile_badge_2_dark,
+                        com.android.internal.R.color.profile_badge_3_dark)
                 .setDefaultRestrictions(null);
     }
 
@@ -292,6 +296,8 @@
                         setResAttributeArray(parser, builder::setBadgeLabels);
                     } else if (isProfile && "badge-colors".equals(childName)) {
                         setResAttributeArray(parser, builder::setBadgeColors);
+                    } else if (isProfile && "badge-colors-dark".equals(childName)) {
+                        setResAttributeArray(parser, builder::setDarkThemeBadgeColors);
                     } else {
                         Slog.w(LOG_TAG, "Unrecognized tag " + childName + " in "
                                 + parser.getPositionDescription());
diff --git a/services/tests/servicestests/AndroidManifest.xml b/services/tests/servicestests/AndroidManifest.xml
index 8d182cb..f1fc699 100644
--- a/services/tests/servicestests/AndroidManifest.xml
+++ b/services/tests/servicestests/AndroidManifest.xml
@@ -79,6 +79,7 @@
     <uses-permission android:name="android.permission.READ_DREAM_STATE"/>
     <uses-permission android:name="android.permission.WRITE_DREAM_STATE"/>
     <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/>
+    <uses-permission android:name="android.permission.MODIFY_DAY_NIGHT_MODE"/>
 
     <!-- Uses API introduced in O (26) -->
     <uses-sdk android:minSdkVersion="1"
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 6b3ee5a..44bb58f 100644
--- a/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java
@@ -347,6 +347,10 @@
         final int badgeIndex = userInfo.profileBadge;
         assertThat(mUserManager.getUserBadgeColor(userId)).isEqualTo(
                 Resources.getSystem().getColor(userTypeDetails.getBadgeColor(badgeIndex), null));
+        assertThat(mUserManager.getUserBadgeDarkColor(userId)).isEqualTo(
+                Resources.getSystem().getColor(userTypeDetails.getDarkThemeBadgeColor(badgeIndex),
+                        null));
+
         assertThat(mUserManager.getBadgedLabelForUser("Test", asHandle(userId))).isEqualTo(
                 Resources.getSystem().getString(userTypeDetails.getBadgeLabel(badgeIndex), "Test"));