diff options
4 files changed, 127 insertions, 47 deletions
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 d26f7ab6d78c..0d5faff65aab 100644 --- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputAdapter.java +++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputAdapter.java @@ -22,6 +22,7 @@ import android.graphics.PorterDuff;  import android.graphics.PorterDuffColorFilter;  import android.graphics.drawable.Drawable;  import android.text.SpannableString; +import android.text.TextUtils;  import android.text.style.ForegroundColorSpan;  import android.util.Log;  import android.view.View; @@ -45,6 +46,7 @@ public class MediaOutputAdapter extends MediaOutputBaseAdapter {      private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);      private ViewGroup mConnectedItem; +    private boolean mInclueDynamicGroup;      public MediaOutputAdapter(MediaOutputController controller) {          super(controller); @@ -61,9 +63,21 @@ public class MediaOutputAdapter extends MediaOutputBaseAdapter {      @Override      public void onBindViewHolder(@NonNull MediaDeviceBaseViewHolder viewHolder, int position) {          final int size = mController.getMediaDevices().size(); -        if (mController.isZeroMode() && position == size) { +        if (position == size && mController.isZeroMode()) {              viewHolder.onBind(CUSTOMIZED_ITEM_PAIR_NEW, false /* topMargin */,                      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) {              viewHolder.onBind(((List<MediaDevice>) (mController.getMediaDevices())).get(position),                      position == 0 /* topMargin */, position == (size - 1) /* bottomMargin */); @@ -74,8 +88,9 @@ public class MediaOutputAdapter extends MediaOutputBaseAdapter {      @Override      public int getItemCount() { -        if (mController.isZeroMode()) { -            // Add extra one for "pair new" +        mInclueDynamicGroup = mController.getSelectedMediaDevice().size() > 1; +        if (mController.isZeroMode() || mInclueDynamicGroup) { +            // Add extra one for "pair new" or dynamic group              return mController.getMediaDevices().size() + 1;          }          return mController.getMediaDevices().size(); @@ -107,7 +122,7 @@ public class MediaOutputAdapter extends MediaOutputBaseAdapter {          @Override          void onBind(MediaDevice device, boolean topMargin, boolean bottomMargin) {              super.onBind(device, topMargin, bottomMargin); -            final boolean currentlyConnected = isCurrentlyConnected(device); +            final boolean currentlyConnected = !mInclueDynamicGroup && isCurrentlyConnected(device);              if (currentlyConnected) {                  mConnectedItem = mContainerLayout;              } @@ -167,6 +182,22 @@ public class MediaOutputAdapter extends MediaOutputBaseAdapter {                          Utils.getColorAccentDefaultColor(mContext), PorterDuff.Mode.SRC_IN));                  mTitleIcon.setImageDrawable(d);                  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();              }          } 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 536b7598ce22..f1d4804aa622 100644 --- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseAdapter.java +++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseAdapter.java @@ -19,7 +19,11 @@ package com.android.systemui.media.dialog;  import android.animation.Animator;  import android.animation.AnimatorListenerAdapter;  import android.content.Context; +import android.content.res.ColorStateList; +import android.graphics.PorterDuff; +import android.graphics.PorterDuffColorFilter;  import android.graphics.Typeface; +import android.graphics.drawable.Drawable;  import android.text.TextUtils;  import android.view.LayoutInflater;  import android.view.View; @@ -35,6 +39,7 @@ import android.widget.TextView;  import androidx.annotation.NonNull;  import androidx.recyclerview.widget.RecyclerView; +import com.android.settingslib.bluetooth.BluetoothUtils;  import com.android.settingslib.media.MediaDevice;  import com.android.systemui.Interpolators;  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_GROUP = 2; +    static final int CUSTOMIZED_ITEM_DYNAMIC_GROUP = 3;      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) {              final float delta = (float) (mContext.getResources().getDimensionPixelSize(                      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); +        }      }  } diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputGroupAdapter.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputGroupAdapter.java index ceb4495bd8e8..24e076bb22f1 100644 --- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputGroupAdapter.java +++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputGroupAdapter.java @@ -16,22 +16,17 @@  package com.android.systemui.media.dialog; -import android.content.res.ColorStateList;  import android.graphics.Bitmap;  import android.graphics.Canvas; -import android.graphics.PorterDuff; -import android.graphics.PorterDuffColorFilter;  import android.graphics.drawable.Drawable;  import android.text.TextUtils;  import android.util.Log;  import android.util.TypedValue;  import android.view.View;  import android.view.ViewGroup; -import android.widget.SeekBar;  import androidx.annotation.NonNull; -import com.android.settingslib.bluetooth.BluetoothUtils;  import com.android.settingslib.media.MediaDevice;  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() {              final Drawable drawable = mContext.getDrawable(R.drawable.ic_check_box_blue_24dp)                      .mutate(); @@ -198,16 +165,6 @@ public class MediaOutputGroupAdapter extends MediaOutputBaseAdapter {              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) {              for (MediaDevice device : deviceList) {                  if (TextUtils.equals(device.getId(), targetDevice.getId())) { diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputAdapterTest.java b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputAdapterTest.java index 521888658d68..6e216428992f 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputAdapterTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputAdapterTest.java @@ -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_ID_1 = "test_device_id_1";      private static final String TEST_DEVICE_ID_2 = "test_device_id_2"; +    private static final String TEST_SESSION_NAME = "test_session_name";      // Mock      private MediaOutputController mMediaOutputController = mock(MediaOutputController.class); @@ -102,6 +103,14 @@ public class MediaOutputAdapterTest extends SysuiTestCase {      }      @Test +    public void getItemCount_withDynamicGroup_containExtraOneForGroup() { +        when(mMediaOutputController.getSelectedMediaDevice()).thenReturn(mMediaDevices); +        when(mMediaOutputController.isZeroMode()).thenReturn(false); + +        assertThat(mMediaOutputAdapter.getItemCount()).isEqualTo(mMediaDevices.size() + 1); +    } + +    @Test      public void onBindViewHolder_zeroMode_bindPairNew_verifyView() {          when(mMediaOutputController.isZeroMode()).thenReturn(true);          mMediaOutputAdapter.onBindViewHolder(mViewHolder, 2); @@ -118,6 +127,45 @@ public class MediaOutputAdapterTest extends SysuiTestCase {      }      @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      public void onBindViewHolder_bindConnectedDevice_verifyView() {          mMediaOutputAdapter.onBindViewHolder(mViewHolder, 0);  |