Merge "[Output Switcher] Extract color from album"
diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputAdapter.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputAdapter.java
index 196dbf1..5b29719 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputAdapter.java
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputAdapter.java
@@ -16,6 +16,7 @@
 
 package com.android.systemui.media.dialog;
 
+import android.content.res.ColorStateList;
 import android.graphics.PorterDuff;
 import android.graphics.PorterDuffColorFilter;
 import android.graphics.drawable.Drawable;
@@ -23,8 +24,10 @@
 import android.util.Log;
 import android.view.View;
 import android.view.ViewGroup;
+import android.widget.CheckBox;
 
 import androidx.annotation.NonNull;
+import androidx.core.widget.CompoundButtonCompat;
 
 import com.android.settingslib.Utils;
 import com.android.settingslib.media.LocalMediaManager.MediaDeviceState;
@@ -100,8 +103,10 @@
             }
             mCheckBox.setVisibility(View.GONE);
             mStatusIcon.setVisibility(View.GONE);
-            mTitleText.setTextColor(Utils.getColorStateListDefaultColor(mContext,
-                    R.color.media_dialog_inactive_item_main_content));
+            mTitleText.setTextColor(mController.getColorInactiveItem());
+            mSeekBar.getProgressDrawable().setColorFilter(
+                    new PorterDuffColorFilter(mController.getColorSeekbarProgress(),
+                            PorterDuff.Mode.SRC_IN));
             if (mCurrentActivePosition == position) {
                 mCurrentActivePosition = -1;
             }
@@ -117,6 +122,10 @@
             if (mController.isTransferring()) {
                 if (device.getState() == MediaDeviceState.STATE_CONNECTING
                         && !mController.hasAdjustVolumeUserRestriction()) {
+                    mProgressBar.getIndeterminateDrawable().setColorFilter(
+                            new PorterDuffColorFilter(
+                                    mController.getColorInactiveItem(),
+                                    PorterDuff.Mode.SRC_IN));
                     setSingleLineLayout(getItemTitle(device), true /* bFocused */,
                             false /* showSeekBar*/,
                             true /* showProgressBar */, false /* showStatus */);
@@ -130,6 +139,7 @@
                     mTitleIcon.setAlpha(DEVICE_CONNECTED_ALPHA);
                     mStatusIcon.setImageDrawable(
                             mContext.getDrawable(R.drawable.media_output_status_failed));
+                    mStatusIcon.setColorFilter(mController.getColorInactiveItem());
                     setTwoLineLayout(device, false /* bFocused */,
                             false /* showSeekBar */, false /* showProgressBar */,
                             true /* showSubtitle */, true /* showStatus */);
@@ -137,8 +147,7 @@
                     mContainerLayout.setOnClickListener(v -> onItemClick(v, device));
                 } else if (mController.getSelectedMediaDevice().size() > 1
                         && isDeviceIncluded(mController.getSelectedMediaDevice(), device)) {
-                    mTitleText.setTextColor(Utils.getColorStateListDefaultColor(mContext,
-                            R.color.media_dialog_active_item_main_content));
+                    mTitleText.setTextColor(mController.getColorActiveItem());
                     setSingleLineLayout(getItemTitle(device), true /* bFocused */,
                             true /* showSeekBar */,
                             false /* showProgressBar */, false /* showStatus */);
@@ -147,12 +156,13 @@
                     mCheckBox.setOnCheckedChangeListener((buttonView, isChecked) -> {
                         onCheckBoxClicked(false, device);
                     });
+                    setCheckBoxColor(mCheckBox, mController.getColorActiveItem());
                     initSessionSeekbar();
                 } else if (!mController.hasAdjustVolumeUserRestriction() && currentlyConnected) {
                     mStatusIcon.setImageDrawable(
                             mContext.getDrawable(R.drawable.media_output_status_check));
-                    mTitleText.setTextColor(Utils.getColorStateListDefaultColor(mContext,
-                            R.color.media_dialog_active_item_main_content));
+                    mStatusIcon.setColorFilter(mController.getColorActiveItem());
+                    mTitleText.setTextColor(mController.getColorActiveItem());
                     setSingleLineLayout(getItemTitle(device), true /* bFocused */,
                             true /* showSeekBar */,
                             false /* showProgressBar */, true /* showStatus */);
@@ -164,6 +174,7 @@
                     mCheckBox.setOnCheckedChangeListener((buttonView, isChecked) -> {
                         onCheckBoxClicked(true, device);
                     });
+                    setCheckBoxColor(mCheckBox, mController.getColorInactiveItem());
                     setSingleLineLayout(getItemTitle(device), false /* bFocused */,
                             false /* showSeekBar */,
                             false /* showProgressBar */, false /* showStatus */);
@@ -175,11 +186,17 @@
             }
         }
 
+        public void setCheckBoxColor(CheckBox checkBox, int color) {
+            int[][] states = {{android.R.attr.state_checked}, {}};
+            int[] colors = {color, color};
+            CompoundButtonCompat.setButtonTintList(checkBox, new
+                    ColorStateList(states, colors));
+        }
+
         @Override
         void onBind(int customizedItem, boolean topMargin, boolean bottomMargin) {
             if (customizedItem == CUSTOMIZED_ITEM_PAIR_NEW) {
-                mTitleText.setTextColor(Utils.getColorStateListDefaultColor(mContext,
-                        R.color.media_dialog_inactive_item_main_content));
+                mTitleText.setTextColor(mController.getColorInactiveItem());
                 mCheckBox.setVisibility(View.GONE);
                 setSingleLineLayout(mContext.getText(R.string.media_output_dialog_pairing_new),
                         false /* bFocused */);
diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseAdapter.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseAdapter.java
index a8d30d4..85d1795 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseAdapter.java
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseAdapter.java
@@ -18,6 +18,7 @@
 
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
+import android.app.WallpaperColors;
 import android.content.Context;
 import android.graphics.PorterDuff;
 import android.graphics.PorterDuffColorFilter;
@@ -56,7 +57,7 @@
     static final int CUSTOMIZED_ITEM_GROUP = 2;
     static final int CUSTOMIZED_ITEM_DYNAMIC_GROUP = 3;
 
-    final MediaOutputController mController;
+    protected final MediaOutputController mController;
 
     private int mMargin;
     private boolean mIsAnimating;
@@ -84,6 +85,10 @@
         return null;
     }
 
+    void updateColorScheme(WallpaperColors wallpaperColors, boolean isDarkTheme) {
+        mController.setCurrentColorScheme(wallpaperColors, isDarkTheme);
+    }
+
     CharSequence getItemTitle(MediaDevice device) {
         return device.getName();
     }
@@ -105,6 +110,10 @@
         return mCurrentActivePosition;
     }
 
+    public MediaOutputController getController() {
+        return mController;
+    }
+
     /**
      * ViewHolder for binding device view.
      */
diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseDialog.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseDialog.java
index 8731a2c..e55b25f 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseDialog.java
@@ -19,8 +19,14 @@
 import static android.view.WindowInsets.Type.navigationBars;
 import static android.view.WindowInsets.Type.statusBars;
 
+import android.app.WallpaperColors;
 import android.content.Context;
+import android.content.res.Configuration;
+import android.graphics.ColorFilter;
+import android.graphics.PorterDuff;
+import android.graphics.PorterDuffColorFilter;
 import android.graphics.drawable.Drawable;
+import android.graphics.drawable.Icon;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.Looper;
@@ -73,6 +79,7 @@
     private Button mDoneButton;
     private Button mStopButton;
     private int mListMaxHeight;
+    private WallpaperColors mWallpaperColors;
 
     MediaOutputBaseAdapter mAdapter;
 
@@ -161,6 +168,7 @@
         final int iconRes = getHeaderIconRes();
         final IconCompat iconCompat = getHeaderIcon();
         final Drawable appSourceDrawable = getAppSourceIcon();
+        boolean colorSetUpdated = false;
         if (appSourceDrawable != null) {
             mAppResourceIcon.setImageDrawable(appSourceDrawable);
         } else {
@@ -170,8 +178,24 @@
             mHeaderIcon.setVisibility(View.VISIBLE);
             mHeaderIcon.setImageResource(iconRes);
         } else if (iconCompat != null) {
+            Icon icon = iconCompat.toIcon(mContext);
+            Configuration config = mContext.getResources().getConfiguration();
+            int currentNightMode = config.uiMode & Configuration.UI_MODE_NIGHT_MASK;
+            boolean isDarkThemeOn = currentNightMode == Configuration.UI_MODE_NIGHT_YES;
+            WallpaperColors wallpaperColors = WallpaperColors.fromBitmap(icon.getBitmap());
+            colorSetUpdated = !wallpaperColors.equals(mWallpaperColors);
+            if (colorSetUpdated) {
+                mAdapter.updateColorScheme(wallpaperColors, isDarkThemeOn);
+                ColorFilter buttonColorFilter = new PorterDuffColorFilter(
+                        mAdapter.getController().getColorButtonBackground(),
+                        PorterDuff.Mode.SRC_IN);
+                ColorFilter onlineButtonColorFilter = new PorterDuffColorFilter(
+                        mAdapter.getController().getColorInactiveItem(), PorterDuff.Mode.SRC_IN);
+                mDoneButton.getBackground().setColorFilter(buttonColorFilter);
+                mStopButton.getBackground().setColorFilter(onlineButtonColorFilter);
+            }
             mHeaderIcon.setVisibility(View.VISIBLE);
-            mHeaderIcon.setImageIcon(iconCompat.toIcon(mContext));
+            mHeaderIcon.setImageIcon(icon);
         } else {
             mHeaderIcon.setVisibility(View.GONE);
         }
@@ -194,7 +218,7 @@
         }
         if (!mAdapter.isDragging() && !mAdapter.isAnimating()) {
             int currentActivePosition = mAdapter.getCurrentActivePosition();
-            if (!deviceSetChanged && currentActivePosition >= 0
+            if (!colorSetUpdated && !deviceSetChanged && currentActivePosition >= 0
                     && currentActivePosition < mAdapter.getItemCount()) {
                 mAdapter.notifyItemChanged(currentActivePosition);
             } else {
diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java
index 4961711..1c6b7dc 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java
@@ -19,10 +19,10 @@
 import static android.provider.Settings.ACTION_BLUETOOTH_PAIRING_SETTINGS;
 
 import android.app.Notification;
+import android.app.WallpaperColors;
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.PackageManager;
-import android.content.res.ColorStateList;
 import android.graphics.Bitmap;
 import android.graphics.PorterDuff;
 import android.graphics.PorterDuffColorFilter;
@@ -57,6 +57,7 @@
 import com.android.settingslib.utils.ThreadUtils;
 import com.android.systemui.R;
 import com.android.systemui.animation.DialogLaunchAnimator;
+import com.android.systemui.monet.ColorScheme;
 import com.android.systemui.plugins.ActivityStarter;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
 import com.android.systemui.statusbar.notification.collection.notifcollection.CommonNotifCollection;
@@ -103,6 +104,11 @@
     private MediaOutputMetricLogger mMetricLogger;
     private UiEventLogger mUiEventLogger;
 
+    private int mColorActiveItem;
+    private int mColorInactiveItem;
+    private int mColorSeekbarProgress;
+    private int mColorButtonBackground;
+
     @Inject
     public MediaOutputController(@NonNull Context context, String packageName,
             boolean aboveStatusbar, MediaSessionManager mediaSessionManager, LocalBluetoothManager
@@ -125,6 +131,14 @@
         mVolumeAdjustmentForRemoteGroupSessions = mContext.getResources().getBoolean(
                 com.android.internal.R.bool.config_volumeAdjustmentForRemoteGroupSessions);
         mDialogManager = dialogManager;
+        mColorActiveItem = Utils.getColorStateListDefaultColor(mContext,
+                R.color.media_dialog_active_item_main_content);
+        mColorInactiveItem = Utils.getColorStateListDefaultColor(mContext,
+                R.color.media_dialog_inactive_item_main_content);
+        mColorSeekbarProgress = Utils.getColorStateListDefaultColor(mContext,
+                android.R.color.system_accent1_200);
+        mColorButtonBackground = Utils.getColorStateListDefaultColor(mContext,
+                R.color.media_dialog_item_background);
     }
 
     void start(@NonNull Callback cb) {
@@ -264,13 +278,8 @@
     }
 
     void setColorFilter(Drawable drawable, boolean isActive) {
-        final ColorStateList list =
-                mContext.getResources().getColorStateList(
-                        isActive
-                                ? R.color.media_dialog_active_item_main_content
-                                : R.color.media_dialog_inactive_item_main_content,
-                        mContext.getTheme());
-        drawable.setColorFilter(new PorterDuffColorFilter(list.getDefaultColor(),
+        drawable.setColorFilter(new PorterDuffColorFilter(isActive
+                ? mColorActiveItem : mColorInactiveItem,
                 PorterDuff.Mode.SRC_IN));
     }
 
@@ -301,6 +310,38 @@
         return null;
     }
 
+    void setCurrentColorScheme(WallpaperColors wallpaperColors, boolean isDarkTheme) {
+        ColorScheme mCurrentColorScheme = new ColorScheme(wallpaperColors,
+                isDarkTheme);
+        if (isDarkTheme) {
+            mColorActiveItem = mCurrentColorScheme.getNeutral1().get(10);
+            mColorInactiveItem = mCurrentColorScheme.getAccent1().get(2);
+            mColorSeekbarProgress = mCurrentColorScheme.getAccent1().get(3);
+            mColorButtonBackground = mCurrentColorScheme.getAccent1().get(2);
+        } else {
+            mColorActiveItem = mCurrentColorScheme.getNeutral1().get(10);
+            mColorInactiveItem = mCurrentColorScheme.getAccent1().get(7);
+            mColorSeekbarProgress = mCurrentColorScheme.getAccent1().get(3);
+            mColorButtonBackground = mCurrentColorScheme.getAccent2().get(1);
+        }
+    }
+
+    public int getColorActiveItem() {
+        return mColorActiveItem;
+    }
+
+    public int getColorInactiveItem() {
+        return mColorInactiveItem;
+    }
+
+    public int getColorSeekbarProgress() {
+        return mColorSeekbarProgress;
+    }
+
+    public int getColorButtonBackground() {
+        return mColorButtonBackground;
+    }
+
     private void buildMediaDevices(List<MediaDevice> devices) {
         // For the first time building list, to make sure the top device is the connected device.
         if (mMediaDevices.isEmpty()) {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputBaseDialogTest.java b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputBaseDialogTest.java
index 9f542f0..c5c4d79 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputBaseDialogTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputBaseDialogTest.java
@@ -24,6 +24,7 @@
 import static org.mockito.Mockito.when;
 
 import android.content.Context;
+import android.graphics.Bitmap;
 import android.graphics.drawable.Drawable;
 import android.media.session.MediaSessionManager;
 import android.os.Bundle;
@@ -99,7 +100,10 @@
 
     @Test
     public void refresh_withIconCompat_iconIsVisible() {
-        mIconCompat = mock(IconCompat.class);
+        mIconCompat = IconCompat.createWithBitmap(
+                Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888));
+        when(mMediaOutputBaseAdapter.getController()).thenReturn(mMediaOutputController);
+
         mMediaOutputBaseDialogImpl.refresh();
         final ImageView view = mMediaOutputBaseDialogImpl.mDialogView.requireViewById(
                 R.id.header_icon);