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

Commit a34f0e01 authored by shaoweishen's avatar shaoweishen
Browse files

[Output Switcher] Extract color from album

Extract and save color scheme from album.
When update devices, set stored color to the item.

Bug: 203071942
Test: Verify on device
Change-Id: If84872ba5cbbe074878ae1b93ffdb06f2422a7b4
parent b72330ce
Loading
Loading
Loading
Loading
+25 −8
Original line number Diff line number Diff line
@@ -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.text.TextUtils;
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 @@ public class MediaOutputAdapter extends MediaOutputBaseAdapter {
            }
            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 @@ public class MediaOutputAdapter extends MediaOutputBaseAdapter {
            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 @@ public class MediaOutputAdapter extends MediaOutputBaseAdapter {
                    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 @@ public class MediaOutputAdapter extends MediaOutputBaseAdapter {
                    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 @@ public class MediaOutputAdapter extends MediaOutputBaseAdapter {
                    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 @@ public class MediaOutputAdapter extends MediaOutputBaseAdapter {
                    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 class MediaOutputAdapter extends MediaOutputBaseAdapter {
            }
        }

        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 */);
+10 −1
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package com.android.systemui.media.dialog;

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 @@ public abstract class MediaOutputBaseAdapter extends
    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 @@ public abstract class MediaOutputBaseAdapter extends
        return null;
    }

    void updateColorScheme(WallpaperColors wallpaperColors, boolean isDarkTheme) {
        mController.setCurrentColorScheme(wallpaperColors, isDarkTheme);
    }

    CharSequence getItemTitle(MediaDevice device) {
        return device.getName();
    }
@@ -105,6 +110,10 @@ public abstract class MediaOutputBaseAdapter extends
        return mCurrentActivePosition;
    }

    public MediaOutputController getController() {
        return mController;
    }

    /**
     * ViewHolder for binding device view.
     */
+26 −2
Original line number Diff line number Diff line
@@ -19,8 +19,14 @@ package com.android.systemui.media.dialog;
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 @@ public abstract class MediaOutputBaseDialog extends SystemUIDialog implements
    private Button mDoneButton;
    private Button mStopButton;
    private int mListMaxHeight;
    private WallpaperColors mWallpaperColors;

    MediaOutputBaseAdapter mAdapter;

@@ -161,6 +168,7 @@ public abstract class MediaOutputBaseDialog extends SystemUIDialog implements
        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 @@ public abstract class MediaOutputBaseDialog extends SystemUIDialog implements
            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 @@ public abstract class MediaOutputBaseDialog extends SystemUIDialog implements
        }
        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 {
+49 −8
Original line number Diff line number Diff line
@@ -19,10 +19,10 @@ package com.android.systemui.media.dialog;
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.media.MediaDevice;
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 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback {
    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 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback {
        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 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback {
    }

    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 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback {
        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()) {
+5 −1
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@ import static org.mockito.Mockito.verify;
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 @@ public class MediaOutputBaseDialogTest extends SysuiTestCase {

    @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);