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

Commit c3447450 authored by timhypeng's avatar timhypeng Committed by tim peng
Browse files

Add dynamic item in output switcher if it is available

-Add extra item for dynamic group if getSelectedMediaDevice() > 1
-Move common method to base class

Bug: 171455839
Test: atest MediaOutputAdapterTest MediaOutputControllerTest MediaOutputBaseDialogTest MediaOutputDialogTest MediaOutputGroupAdapterTest MediaOutputGroupDialogTest
Merged-In: I5990df864cb7c5795e2d1a1cd404807d265b4cc3
Change-Id: I5990df864cb7c5795e2d1a1cd404807d265b4cc3
parent 083c9899
Loading
Loading
Loading
Loading
+35 −4
Original line number Original line Diff line number Diff line
@@ -22,6 +22,7 @@ import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.graphics.PorterDuffColorFilter;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.Drawable;
import android.text.SpannableString;
import android.text.SpannableString;
import android.text.TextUtils;
import android.text.style.ForegroundColorSpan;
import android.text.style.ForegroundColorSpan;
import android.util.Log;
import android.util.Log;
import android.view.View;
import android.view.View;
@@ -45,6 +46,7 @@ public class MediaOutputAdapter extends MediaOutputBaseAdapter {
    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);


    private ViewGroup mConnectedItem;
    private ViewGroup mConnectedItem;
    private boolean mInclueDynamicGroup;


    public MediaOutputAdapter(MediaOutputController controller) {
    public MediaOutputAdapter(MediaOutputController controller) {
        super(controller);
        super(controller);
@@ -61,9 +63,21 @@ public class MediaOutputAdapter extends MediaOutputBaseAdapter {
    @Override
    @Override
    public void onBindViewHolder(@NonNull MediaDeviceBaseViewHolder viewHolder, int position) {
    public void onBindViewHolder(@NonNull MediaDeviceBaseViewHolder viewHolder, int position) {
        final int size = mController.getMediaDevices().size();
        final int size = mController.getMediaDevices().size();
        if (mController.isZeroMode() && position == size) {
        if (position == size && mController.isZeroMode()) {
            viewHolder.onBind(CUSTOMIZED_ITEM_PAIR_NEW, false /* topMargin */,
            viewHolder.onBind(CUSTOMIZED_ITEM_PAIR_NEW, false /* topMargin */,
                    true /* bottomMargin */);
                    true /* bottomMargin */);
        } else if (mInclueDynamicGroup) {
            if (position == 0) {
                viewHolder.onBind(CUSTOMIZED_ITEM_DYNAMIC_GROUP, true /* topMargin */,
                        false /* bottomMargin */);
            } else {
                // When group item is added at the first(position == 0), devices will be added from
                // the second item(position == 1). It means that the index of device list starts
                // from "position - 1".
                viewHolder.onBind(((List<MediaDevice>) (mController.getMediaDevices()))
                                .get(position - 1),
                        false /* topMargin */, position == size /* bottomMargin */);
            }
        } else if (position < size) {
        } else if (position < size) {
            viewHolder.onBind(((List<MediaDevice>) (mController.getMediaDevices())).get(position),
            viewHolder.onBind(((List<MediaDevice>) (mController.getMediaDevices())).get(position),
                    position == 0 /* topMargin */, position == (size - 1) /* bottomMargin */);
                    position == 0 /* topMargin */, position == (size - 1) /* bottomMargin */);
@@ -74,8 +88,9 @@ public class MediaOutputAdapter extends MediaOutputBaseAdapter {


    @Override
    @Override
    public int getItemCount() {
    public int getItemCount() {
        if (mController.isZeroMode()) {
        mInclueDynamicGroup = mController.getSelectedMediaDevice().size() > 1;
            // Add extra one for "pair new"
        if (mController.isZeroMode() || mInclueDynamicGroup) {
            // Add extra one for "pair new" or dynamic group
            return mController.getMediaDevices().size() + 1;
            return mController.getMediaDevices().size() + 1;
        }
        }
        return mController.getMediaDevices().size();
        return mController.getMediaDevices().size();
@@ -107,7 +122,7 @@ public class MediaOutputAdapter extends MediaOutputBaseAdapter {
        @Override
        @Override
        void onBind(MediaDevice device, boolean topMargin, boolean bottomMargin) {
        void onBind(MediaDevice device, boolean topMargin, boolean bottomMargin) {
            super.onBind(device, topMargin, bottomMargin);
            super.onBind(device, topMargin, bottomMargin);
            final boolean currentlyConnected = isCurrentlyConnected(device);
            final boolean currentlyConnected = !mInclueDynamicGroup && isCurrentlyConnected(device);
            if (currentlyConnected) {
            if (currentlyConnected) {
                mConnectedItem = mContainerLayout;
                mConnectedItem = mContainerLayout;
            }
            }
@@ -167,6 +182,22 @@ public class MediaOutputAdapter extends MediaOutputBaseAdapter {
                        Utils.getColorAccentDefaultColor(mContext), PorterDuff.Mode.SRC_IN));
                        Utils.getColorAccentDefaultColor(mContext), PorterDuff.Mode.SRC_IN));
                mTitleIcon.setImageDrawable(d);
                mTitleIcon.setImageDrawable(d);
                mContainerLayout.setOnClickListener(v -> onItemClick(CUSTOMIZED_ITEM_PAIR_NEW));
                mContainerLayout.setOnClickListener(v -> onItemClick(CUSTOMIZED_ITEM_PAIR_NEW));
            } else if (customizedItem == CUSTOMIZED_ITEM_DYNAMIC_GROUP) {
                mConnectedItem = mContainerLayout;
                mBottomDivider.setVisibility(View.GONE);
                mCheckBox.setVisibility(View.GONE);
                mDivider.setVisibility(View.VISIBLE);
                mDivider.setTransitionAlpha(1);
                mAddIcon.setVisibility(View.VISIBLE);
                mAddIcon.setTransitionAlpha(1);
                mAddIcon.setOnClickListener(v -> onEndItemClick());
                mTitleIcon.setImageDrawable(getSpeakerDrawable());
                final CharSequence sessionName = mController.getSessionName();
                final CharSequence title = TextUtils.isEmpty(sessionName)
                        ? mContext.getString(R.string.media_output_dialog_group) : sessionName;
                setTwoLineLayout(title, true /* bFocused */, true /* showSeekBar */,
                        false /* showProgressBar */, false /* showSubtitle */);
                initSessionSeekbar();
            }
            }
        }
        }


+44 −0
Original line number Original line Diff line number Diff line
@@ -19,7 +19,11 @@ package com.android.systemui.media.dialog;
import android.animation.Animator;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorListenerAdapter;
import android.content.Context;
import android.content.Context;
import android.content.res.ColorStateList;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.graphics.Typeface;
import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
import android.text.TextUtils;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View;
@@ -35,6 +39,7 @@ import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.RecyclerView;


import com.android.settingslib.bluetooth.BluetoothUtils;
import com.android.settingslib.media.MediaDevice;
import com.android.settingslib.media.MediaDevice;
import com.android.systemui.Interpolators;
import com.android.systemui.Interpolators;
import com.android.systemui.R;
import com.android.systemui.R;
@@ -47,6 +52,7 @@ public abstract class MediaOutputBaseAdapter extends


    static final int CUSTOMIZED_ITEM_PAIR_NEW = 1;
    static final int CUSTOMIZED_ITEM_PAIR_NEW = 1;
    static final int CUSTOMIZED_ITEM_GROUP = 2;
    static final int CUSTOMIZED_ITEM_GROUP = 2;
    static final int CUSTOMIZED_ITEM_DYNAMIC_GROUP = 3;


    final MediaOutputController mController;
    final MediaOutputController mController;


@@ -223,6 +229,34 @@ public abstract class MediaOutputBaseAdapter extends
            });
            });
        }
        }


        void initSessionSeekbar() {
            mSeekBar.setMax(mController.getSessionVolumeMax());
            mSeekBar.setMin(0);
            final int currentVolume = mController.getSessionVolume();
            if (mSeekBar.getProgress() != currentVolume) {
                mSeekBar.setProgress(currentVolume);
            }
            mSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
                @Override
                public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                    if (!fromUser) {
                        return;
                    }
                    mController.adjustSessionVolume(progress);
                }

                @Override
                public void onStartTrackingTouch(SeekBar seekBar) {
                    mIsDragging = true;
                }

                @Override
                public void onStopTrackingTouch(SeekBar seekBar) {
                    mIsDragging = false;
                }
            });
        }

        void playSwitchingAnim(@NonNull View from, @NonNull View to) {
        void playSwitchingAnim(@NonNull View from, @NonNull View to) {
            final float delta = (float) (mContext.getResources().getDimensionPixelSize(
            final float delta = (float) (mContext.getResources().getDimensionPixelSize(
                    R.dimen.media_output_dialog_title_anim_y_delta));
                    R.dimen.media_output_dialog_title_anim_y_delta));
@@ -274,5 +308,15 @@ public abstract class MediaOutputBaseAdapter extends
                        }
                        }
                    });
                    });
        }
        }

        Drawable getSpeakerDrawable() {
            final Drawable drawable = mContext.getDrawable(R.drawable.ic_speaker_group_black_24dp)
                    .mutate();
            final ColorStateList list = mContext.getResources().getColorStateList(
                    R.color.advanced_icon_color, mContext.getTheme());
            drawable.setColorFilter(new PorterDuffColorFilter(list.getDefaultColor(),
                    PorterDuff.Mode.SRC_IN));
            return BluetoothUtils.buildAdvancedDrawable(mContext, drawable);
        }
    }
    }
}
}
+0 −43
Original line number Original line Diff line number Diff line
@@ -16,22 +16,17 @@


package com.android.systemui.media.dialog;
package com.android.systemui.media.dialog;


import android.content.res.ColorStateList;
import android.graphics.Bitmap;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Canvas;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.Drawable;
import android.text.TextUtils;
import android.text.TextUtils;
import android.util.Log;
import android.util.Log;
import android.util.TypedValue;
import android.util.TypedValue;
import android.view.View;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewGroup;
import android.widget.SeekBar;


import androidx.annotation.NonNull;
import androidx.annotation.NonNull;


import com.android.settingslib.bluetooth.BluetoothUtils;
import com.android.settingslib.media.MediaDevice;
import com.android.settingslib.media.MediaDevice;
import com.android.systemui.R;
import com.android.systemui.R;


@@ -155,34 +150,6 @@ public class MediaOutputGroupAdapter extends MediaOutputBaseAdapter {
            }
            }
        }
        }


        private void initSessionSeekbar() {
            mSeekBar.setMax(mController.getSessionVolumeMax());
            mSeekBar.setMin(0);
            final int currentVolume = mController.getSessionVolume();
            if (mSeekBar.getProgress() != currentVolume) {
                mSeekBar.setProgress(currentVolume);
            }
            mSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
                @Override
                public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                    if (!fromUser) {
                        return;
                    }
                    mController.adjustSessionVolume(progress);
                }

                @Override
                public void onStartTrackingTouch(SeekBar seekBar) {
                    mIsDragging = true;
                }

                @Override
                public void onStopTrackingTouch(SeekBar seekBar) {
                    mIsDragging = false;
                }
            });
        }

        private Drawable getDisabledCheckboxDrawable() {
        private Drawable getDisabledCheckboxDrawable() {
            final Drawable drawable = mContext.getDrawable(R.drawable.ic_check_box_blue_24dp)
            final Drawable drawable = mContext.getDrawable(R.drawable.ic_check_box_blue_24dp)
                    .mutate();
                    .mutate();
@@ -198,16 +165,6 @@ public class MediaOutputGroupAdapter extends MediaOutputBaseAdapter {
            return drawable;
            return drawable;
        }
        }


        private Drawable getSpeakerDrawable() {
            final Drawable drawable = mContext.getDrawable(R.drawable.ic_speaker_group_black_24dp)
                    .mutate();
            final ColorStateList list = mContext.getResources().getColorStateList(
                            R.color.advanced_icon_color, mContext.getTheme());
            drawable.setColorFilter(new PorterDuffColorFilter(list.getDefaultColor(),
                    PorterDuff.Mode.SRC_IN));
            return BluetoothUtils.buildAdvancedDrawable(mContext, drawable);
        }

        private boolean isDeviceIncluded(List<MediaDevice> deviceList, MediaDevice targetDevice) {
        private boolean isDeviceIncluded(List<MediaDevice> deviceList, MediaDevice targetDevice) {
            for (MediaDevice device : deviceList) {
            for (MediaDevice device : deviceList) {
                if (TextUtils.equals(device.getId(), targetDevice.getId())) {
                if (TextUtils.equals(device.getId(), targetDevice.getId())) {
+48 −0
Original line number Original line Diff line number Diff line
@@ -50,6 +50,7 @@ public class MediaOutputAdapterTest extends SysuiTestCase {
    private static final String TEST_DEVICE_NAME_2 = "test_device_name_2";
    private static final String TEST_DEVICE_NAME_2 = "test_device_name_2";
    private static final String TEST_DEVICE_ID_1 = "test_device_id_1";
    private static final String TEST_DEVICE_ID_1 = "test_device_id_1";
    private static final String TEST_DEVICE_ID_2 = "test_device_id_2";
    private static final String TEST_DEVICE_ID_2 = "test_device_id_2";
    private static final String TEST_SESSION_NAME = "test_session_name";


    // Mock
    // Mock
    private MediaOutputController mMediaOutputController = mock(MediaOutputController.class);
    private MediaOutputController mMediaOutputController = mock(MediaOutputController.class);
@@ -101,6 +102,14 @@ public class MediaOutputAdapterTest extends SysuiTestCase {
        assertThat(mMediaOutputAdapter.getItemCount()).isEqualTo(mMediaDevices.size() + 1);
        assertThat(mMediaOutputAdapter.getItemCount()).isEqualTo(mMediaDevices.size() + 1);
    }
    }


    @Test
    public void getItemCount_withDynamicGroup_containExtraOneForGroup() {
        when(mMediaOutputController.getSelectedMediaDevice()).thenReturn(mMediaDevices);
        when(mMediaOutputController.isZeroMode()).thenReturn(false);

        assertThat(mMediaOutputAdapter.getItemCount()).isEqualTo(mMediaDevices.size() + 1);
    }

    @Test
    @Test
    public void onBindViewHolder_zeroMode_bindPairNew_verifyView() {
    public void onBindViewHolder_zeroMode_bindPairNew_verifyView() {
        when(mMediaOutputController.isZeroMode()).thenReturn(true);
        when(mMediaOutputController.isZeroMode()).thenReturn(true);
@@ -117,6 +126,45 @@ public class MediaOutputAdapterTest extends SysuiTestCase {
                R.string.media_output_dialog_pairing_new));
                R.string.media_output_dialog_pairing_new));
    }
    }


    @Test
    public void onBindViewHolder_bindGroup_withSessionName_verifyView() {
        when(mMediaOutputController.getSelectedMediaDevice()).thenReturn(mMediaDevices);
        when(mMediaOutputController.isZeroMode()).thenReturn(false);
        when(mMediaOutputController.getSessionName()).thenReturn(TEST_SESSION_NAME);
        mMediaOutputAdapter.getItemCount();
        mMediaOutputAdapter.onBindViewHolder(mViewHolder, 0);

        assertThat(mViewHolder.mSeekBar.getVisibility()).isEqualTo(View.VISIBLE);
        assertThat(mViewHolder.mDivider.getVisibility()).isEqualTo(View.VISIBLE);
        assertThat(mViewHolder.mAddIcon.getVisibility()).isEqualTo(View.VISIBLE);
        assertThat(mViewHolder.mTwoLineLayout.getVisibility()).isEqualTo(View.VISIBLE);
        assertThat(mViewHolder.mTitleText.getVisibility()).isEqualTo(View.GONE);
        assertThat(mViewHolder.mProgressBar.getVisibility()).isEqualTo(View.GONE);
        assertThat(mViewHolder.mCheckBox.getVisibility()).isEqualTo(View.GONE);
        assertThat(mViewHolder.mBottomDivider.getVisibility()).isEqualTo(View.GONE);
        assertThat(mViewHolder.mTwoLineTitleText.getText()).isEqualTo(TEST_SESSION_NAME);
    }

    @Test
    public void onBindViewHolder_bindGroup_noSessionName_verifyView() {
        when(mMediaOutputController.getSelectedMediaDevice()).thenReturn(mMediaDevices);
        when(mMediaOutputController.isZeroMode()).thenReturn(false);
        when(mMediaOutputController.getSessionName()).thenReturn(null);
        mMediaOutputAdapter.getItemCount();
        mMediaOutputAdapter.onBindViewHolder(mViewHolder, 0);

        assertThat(mViewHolder.mSeekBar.getVisibility()).isEqualTo(View.VISIBLE);
        assertThat(mViewHolder.mDivider.getVisibility()).isEqualTo(View.VISIBLE);
        assertThat(mViewHolder.mAddIcon.getVisibility()).isEqualTo(View.VISIBLE);
        assertThat(mViewHolder.mTwoLineLayout.getVisibility()).isEqualTo(View.VISIBLE);
        assertThat(mViewHolder.mTitleText.getVisibility()).isEqualTo(View.GONE);
        assertThat(mViewHolder.mProgressBar.getVisibility()).isEqualTo(View.GONE);
        assertThat(mViewHolder.mCheckBox.getVisibility()).isEqualTo(View.GONE);
        assertThat(mViewHolder.mBottomDivider.getVisibility()).isEqualTo(View.GONE);
        assertThat(mViewHolder.mTwoLineTitleText.getText()).isEqualTo(mContext.getString(
                R.string.media_output_dialog_group));
    }

    @Test
    @Test
    public void onBindViewHolder_bindConnectedDevice_verifyView() {
    public void onBindViewHolder_bindConnectedDevice_verifyView() {
        mMediaOutputAdapter.onBindViewHolder(mViewHolder, 0);
        mMediaOutputAdapter.onBindViewHolder(mViewHolder, 0);