Merge "[Output Switcher] Refactor MediaOutputAdapter" into tm-qpr-dev

This commit is contained in:
Shaowei Shen
2022-08-30 09:14:57 +00:00
committed by Android (Google) Code Review
5 changed files with 121 additions and 180 deletions

View File

@@ -1182,7 +1182,6 @@
<item name="shutdown_scrim_behind_alpha" format="float" type="dimen">0.95</item>
<!-- Output switcher panel related dimensions -->
<dimen name="media_output_dialog_list_margin">12dp</dimen>
<dimen name="media_output_dialog_list_max_height">355dp</dimen>
<dimen name="media_output_dialog_header_album_icon_size">72dp</dimen>
<dimen name="media_output_dialog_header_back_icon_size">32dp</dimen>

View File

@@ -16,6 +16,7 @@
package com.android.systemui.media.dialog;
import android.annotation.DrawableRes;
import android.content.res.ColorStateList;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
@@ -42,9 +43,6 @@ public class MediaOutputAdapter extends MediaOutputBaseAdapter {
private static final String TAG = "MediaOutputAdapter";
private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
private ViewGroup mConnectedItem;
private boolean mIncludeDynamicGroup;
public MediaOutputAdapter(MediaOutputController controller) {
super(controller);
setHasStableIds(true);
@@ -102,141 +100,90 @@ public class MediaOutputAdapter extends MediaOutputBaseAdapter {
void onBind(MediaDevice device, boolean topMargin, boolean bottomMargin, int position) {
super.onBind(device, topMargin, bottomMargin, position);
boolean isMutingExpectedDeviceExist = mController.hasMutingExpectedDevice();
final boolean currentlyConnected = !mIncludeDynamicGroup
&& isCurrentlyConnected(device);
final boolean currentlyConnected = isCurrentlyConnected(device);
boolean isCurrentSeekbarInvisible = mSeekBar.getVisibility() == View.GONE;
if (currentlyConnected) {
mConnectedItem = mContainerLayout;
}
mCheckBox.setVisibility(View.GONE);
mStatusIcon.setVisibility(View.GONE);
mEndTouchArea.setVisibility(View.GONE);
mEndTouchArea.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO);
mContainerLayout.setOnClickListener(null);
mContainerLayout.setContentDescription(null);
mTitleText.setTextColor(mController.getColorItemContent());
mSubTitleText.setTextColor(mController.getColorItemContent());
mTwoLineTitleText.setTextColor(mController.getColorItemContent());
mSeekBar.getProgressDrawable().setColorFilter(
new PorterDuffColorFilter(mController.getColorSeekbarProgress(),
PorterDuff.Mode.SRC_IN));
if (mCurrentActivePosition == position) {
mCurrentActivePosition = -1;
}
if (mController.isTransferring()) {
if (mController.isAnyDeviceTransferring()) {
if (device.getState() == MediaDeviceState.STATE_CONNECTING
&& !mController.hasAdjustVolumeUserRestriction()) {
setUpDeviceIcon(device);
mProgressBar.getIndeterminateDrawable().setColorFilter(
new PorterDuffColorFilter(
mController.getColorItemContent(),
PorterDuff.Mode.SRC_IN));
setSingleLineLayout(getItemTitle(device), true /* bFocused */,
false /* showSeekBar*/,
true /* showProgressBar */, false /* showStatus */);
updateProgressBarColor();
setSingleLineLayout(getItemTitle(device), false /* showSeekBar*/,
true /* showProgressBar */, false /* showCheckBox */,
false /* showEndTouchArea */);
} else {
setUpDeviceIcon(device);
setSingleLineLayout(getItemTitle(device), false /* bFocused */);
setSingleLineLayout(getItemTitle(device));
}
} else {
// Set different layout for each device
if (device.isMutingExpectedDevice()
&& !mController.isCurrentConnectedDeviceRemote()) {
mTitleIcon.setImageDrawable(
mContext.getDrawable(R.drawable.media_output_icon_volume));
mTitleIcon.setColorFilter(mController.getColorItemContent());
mTitleText.setTextColor(mController.getColorItemContent());
setSingleLineLayout(getItemTitle(device), true /* bFocused */,
false /* showSeekBar */,
false /* showProgressBar */, false /* showStatus */);
updateTitleIcon(R.drawable.media_output_icon_volume,
mController.getColorItemContent());
initMutingExpectedDevice();
mCurrentActivePosition = position;
mContainerLayout.setOnClickListener(v -> onItemClick(v, device));
updateContainerClickListener(v -> onItemClick(v, device));
setSingleLineLayout(getItemTitle(device));
} else if (device.getState() == MediaDeviceState.STATE_CONNECTING_FAILED) {
setUpDeviceIcon(device);
mStatusIcon.setImageDrawable(
mContext.getDrawable(R.drawable.media_output_status_failed));
mStatusIcon.setColorFilter(mController.getColorItemContent());
setTwoLineLayout(device, false /* bFocused */,
false /* showSeekBar */, false /* showProgressBar */,
true /* showSubtitle */, true /* showStatus */);
updateConnectionFailedStatusIcon();
mSubTitleText.setText(R.string.media_output_dialog_connect_failed);
mContainerLayout.setOnClickListener(v -> onItemClick(v, device));
updateContainerClickListener(v -> onItemClick(v, device));
setTwoLineLayout(device, false /* bFocused */, false /* showSeekBar */,
false /* showProgressBar */, true /* showSubtitle */,
true /* showStatus */);
} else if (device.getState() == MediaDeviceState.STATE_GROUPING) {
setUpDeviceIcon(device);
mProgressBar.getIndeterminateDrawable().setColorFilter(
new PorterDuffColorFilter(
mController.getColorItemContent(),
PorterDuff.Mode.SRC_IN));
setSingleLineLayout(getItemTitle(device), true /* bFocused */,
false /* showSeekBar*/,
true /* showProgressBar */, false /* showStatus */);
updateProgressBarColor();
setSingleLineLayout(getItemTitle(device), false /* showSeekBar*/,
true /* showProgressBar */, false /* showCheckBox */,
false /* showEndTouchArea */);
} else if (mController.getSelectedMediaDevice().size() > 1
&& isDeviceIncluded(mController.getSelectedMediaDevice(), device)) {
boolean isDeviceDeselectable = isDeviceIncluded(
mController.getDeselectableMediaDevice(), device);
mTitleText.setTextColor(mController.getColorItemContent());
mTitleIcon.setImageDrawable(
mContext.getDrawable(R.drawable.media_output_icon_volume));
mTitleIcon.setColorFilter(mController.getColorItemContent());
setSingleLineLayout(getItemTitle(device), true /* bFocused */,
true /* showSeekBar */,
false /* showProgressBar */, false /* showStatus */);
updateTitleIcon(R.drawable.media_output_icon_volume,
mController.getColorItemContent());
updateGroupableCheckBox(true, isDeviceDeselectable, device);
updateEndClickArea(device, isDeviceDeselectable);
setUpContentDescriptionForView(mContainerLayout, false, device);
mCheckBox.setOnCheckedChangeListener(null);
mCheckBox.setVisibility(View.VISIBLE);
mCheckBox.setChecked(true);
mCheckBox.setOnCheckedChangeListener(isDeviceDeselectable
? (buttonView, isChecked) -> onGroupActionTriggered(false, device)
: null);
mCheckBox.setEnabled(isDeviceDeselectable);
setCheckBoxColor(mCheckBox, mController.getColorItemContent());
setSingleLineLayout(getItemTitle(device), true /* showSeekBar */,
false /* showProgressBar */, true /* showCheckBox */,
true /* showEndTouchArea */);
initSeekbar(device, isCurrentSeekbarInvisible);
mEndTouchArea.setVisibility(View.VISIBLE);
mEndTouchArea.setOnClickListener(null);
mEndTouchArea.setOnClickListener(
isDeviceDeselectable ? (v) -> mCheckBox.performClick() : null);
mEndTouchArea.setImportantForAccessibility(
View.IMPORTANT_FOR_ACCESSIBILITY_YES);
setUpContentDescriptionForView(mEndTouchArea, true, device);
} else if (!mController.hasAdjustVolumeUserRestriction()
&& currentlyConnected) {
if (isMutingExpectedDeviceExist
&& !mController.isCurrentConnectedDeviceRemote()) {
// mark as disconnected and set special click listener
setUpDeviceIcon(device);
setSingleLineLayout(getItemTitle(device), false /* bFocused */);
mContainerLayout.setOnClickListener(v -> cancelMuteAwaitConnection());
updateContainerClickListener(v -> cancelMuteAwaitConnection());
setSingleLineLayout(getItemTitle(device));
} else {
mTitleIcon.setImageDrawable(
mContext.getDrawable(R.drawable.media_output_icon_volume));
mTitleIcon.setColorFilter(mController.getColorItemContent());
mTitleText.setTextColor(mController.getColorItemContent());
setSingleLineLayout(getItemTitle(device), true /* bFocused */,
true /* showSeekBar */,
false /* showProgressBar */, false /* showStatus */);
initSeekbar(device, isCurrentSeekbarInvisible);
updateTitleIcon(R.drawable.media_output_icon_volume,
mController.getColorItemContent());
setUpContentDescriptionForView(mContainerLayout, false, device);
mCurrentActivePosition = position;
setSingleLineLayout(getItemTitle(device), true /* showSeekBar */,
false /* showProgressBar */, false /* showCheckBox */,
false /* showEndTouchArea */);
initSeekbar(device, isCurrentSeekbarInvisible);
}
} else if (isDeviceIncluded(mController.getSelectableMediaDevice(), device)) {
setUpDeviceIcon(device);
mCheckBox.setOnCheckedChangeListener(null);
mCheckBox.setVisibility(View.VISIBLE);
mCheckBox.setChecked(false);
mCheckBox.setOnCheckedChangeListener(
(buttonView, isChecked) -> onGroupActionTriggered(true, device));
mEndTouchArea.setVisibility(View.VISIBLE);
mContainerLayout.setOnClickListener(v -> onGroupActionTriggered(true, device));
setCheckBoxColor(mCheckBox, mController.getColorItemContent());
setSingleLineLayout(getItemTitle(device), false /* bFocused */,
false /* showSeekBar */,
false /* showProgressBar */, false /* showStatus */);
updateGroupableCheckBox(false, true, device);
updateContainerClickListener(v -> onGroupActionTriggered(true, device));
setSingleLineLayout(getItemTitle(device), false /* showSeekBar */,
false /* showProgressBar */, true /* showCheckBox */,
true /* showEndTouchArea */);
} else {
setUpDeviceIcon(device);
setSingleLineLayout(getItemTitle(device), false /* bFocused */);
mContainerLayout.setOnClickListener(v -> onItemClick(v, device));
setSingleLineLayout(getItemTitle(device));
updateContainerClickListener(v -> onItemClick(v, device));
}
}
}
@@ -248,15 +195,56 @@ public class MediaOutputAdapter extends MediaOutputBaseAdapter {
ColorStateList(states, colors));
}
private void updateConnectionFailedStatusIcon() {
mStatusIcon.setImageDrawable(
mContext.getDrawable(R.drawable.media_output_status_failed));
mStatusIcon.setColorFilter(mController.getColorItemContent());
}
private void updateProgressBarColor() {
mProgressBar.getIndeterminateDrawable().setColorFilter(
new PorterDuffColorFilter(
mController.getColorItemContent(),
PorterDuff.Mode.SRC_IN));
}
public void updateEndClickArea(MediaDevice device, boolean isDeviceDeselectable) {
mEndTouchArea.setOnClickListener(null);
mEndTouchArea.setOnClickListener(
isDeviceDeselectable ? (v) -> mCheckBox.performClick() : null);
mEndTouchArea.setImportantForAccessibility(
View.IMPORTANT_FOR_ACCESSIBILITY_YES);
setUpContentDescriptionForView(mEndTouchArea, true, device);
}
private void updateGroupableCheckBox(boolean isSelected, boolean isGroupable,
MediaDevice device) {
mCheckBox.setOnCheckedChangeListener(null);
mCheckBox.setChecked(isSelected);
mCheckBox.setOnCheckedChangeListener(
isGroupable ? (buttonView, isChecked) -> onGroupActionTriggered(!isSelected,
device) : null);
mCheckBox.setEnabled(isGroupable);
setCheckBoxColor(mCheckBox, mController.getColorItemContent());
}
private void updateTitleIcon(@DrawableRes int id, int color) {
mTitleIcon.setImageDrawable(mContext.getDrawable(id));
mTitleIcon.setColorFilter(color);
}
private void updateContainerClickListener(View.OnClickListener listener) {
mContainerLayout.setOnClickListener(listener);
}
@Override
void onBind(int customizedItem, boolean topMargin, boolean bottomMargin) {
if (customizedItem == CUSTOMIZED_ITEM_PAIR_NEW) {
mTitleText.setTextColor(mController.getColorItemContent());
mCheckBox.setVisibility(View.GONE);
setSingleLineLayout(mContext.getText(R.string.media_output_dialog_pairing_new),
false /* bFocused */);
final Drawable d = mContext.getDrawable(R.drawable.ic_add);
mTitleIcon.setImageDrawable(d);
setSingleLineLayout(mContext.getText(R.string.media_output_dialog_pairing_new));
final Drawable addDrawable = mContext.getDrawable(R.drawable.ic_add);
mTitleIcon.setImageDrawable(addDrawable);
mTitleIcon.setColorFilter(mController.getColorItemContent());
mContainerLayout.setOnClickListener(mController::launchBluetoothPairing);
}
@@ -273,7 +261,7 @@ public class MediaOutputAdapter extends MediaOutputBaseAdapter {
}
private void onItemClick(View view, MediaDevice device) {
if (mController.isTransferring()) {
if (mController.isAnyDeviceTransferring()) {
return;
}
if (isCurrentlyConnected(device)) {

View File

@@ -63,8 +63,6 @@ public abstract class MediaOutputBaseAdapter extends
protected final MediaOutputController mController;
private int mMargin;
Context mContext;
View mHolderView;
boolean mIsDragging;
@@ -82,8 +80,6 @@ public abstract class MediaOutputBaseAdapter extends
public MediaDeviceBaseViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup,
int viewType) {
mContext = viewGroup.getContext();
mMargin = mContext.getResources().getDimensionPixelSize(
R.dimen.media_output_dialog_list_margin);
mHolderView = LayoutInflater.from(mContext).inflate(R.layout.media_output_list_item,
viewGroup, false);
@@ -168,16 +164,28 @@ public abstract class MediaOutputBaseAdapter extends
void onBind(MediaDevice device, boolean topMargin, boolean bottomMargin, int position) {
mDeviceId = device.getId();
mCheckBox.setVisibility(View.GONE);
mStatusIcon.setVisibility(View.GONE);
mEndTouchArea.setVisibility(View.GONE);
mEndTouchArea.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO);
mContainerLayout.setOnClickListener(null);
mContainerLayout.setContentDescription(null);
mTitleText.setTextColor(mController.getColorItemContent());
mSubTitleText.setTextColor(mController.getColorItemContent());
mTwoLineTitleText.setTextColor(mController.getColorItemContent());
mSeekBar.getProgressDrawable().setColorFilter(
new PorterDuffColorFilter(mController.getColorSeekbarProgress(),
PorterDuff.Mode.SRC_IN));
}
abstract void onBind(int customizedItem, boolean topMargin, boolean bottomMargin);
void setSingleLineLayout(CharSequence title, boolean bFocused) {
setSingleLineLayout(title, bFocused, false, false, false);
void setSingleLineLayout(CharSequence title) {
setSingleLineLayout(title, false, false, false, false);
}
void setSingleLineLayout(CharSequence title, boolean bFocused, boolean showSeekBar,
boolean showProgressBar, boolean showStatus) {
void setSingleLineLayout(CharSequence title, boolean showSeekBar,
boolean showProgressBar, boolean showCheckBox, boolean showEndTouchArea) {
mTwoLineLayout.setVisibility(View.GONE);
boolean isActive = showSeekBar || showProgressBar;
if (!mCornerAnimator.isRunning()) {
@@ -188,10 +196,6 @@ public abstract class MediaOutputBaseAdapter extends
.mutate() : mContext.getDrawable(
R.drawable.media_output_item_background)
.mutate();
backgroundDrawable.setColorFilter(new PorterDuffColorFilter(
isActive ? mController.getColorConnectedItemBackground()
: mController.getColorItemBackground(),
PorterDuff.Mode.SRC_IN));
mItemLayout.setBackground(backgroundDrawable);
if (showSeekBar) {
final ClipDrawable clipDrawable =
@@ -201,27 +205,21 @@ public abstract class MediaOutputBaseAdapter extends
(GradientDrawable) clipDrawable.getDrawable();
progressDrawable.setCornerRadius(mController.getActiveRadius());
}
} else {
mItemLayout.getBackground().setColorFilter(new PorterDuffColorFilter(
isActive ? mController.getColorConnectedItemBackground()
: mController.getColorItemBackground(),
PorterDuff.Mode.SRC_IN));
}
mItemLayout.getBackground().setColorFilter(new PorterDuffColorFilter(
isActive ? mController.getColorConnectedItemBackground()
: mController.getColorItemBackground(),
PorterDuff.Mode.SRC_IN));
mProgressBar.setVisibility(showProgressBar ? View.VISIBLE : View.GONE);
mSeekBar.setAlpha(1);
mSeekBar.setVisibility(showSeekBar ? View.VISIBLE : View.GONE);
if (!showSeekBar) {
mSeekBar.resetVolume();
}
mStatusIcon.setVisibility(showStatus ? View.VISIBLE : View.GONE);
mTitleText.setText(title);
mTitleText.setVisibility(View.VISIBLE);
}
void setTwoLineLayout(MediaDevice device, boolean bFocused, boolean showSeekBar,
boolean showProgressBar, boolean showSubtitle) {
setTwoLineLayout(device, null, bFocused, showSeekBar, showProgressBar, showSubtitle,
false);
mCheckBox.setVisibility(showCheckBox ? View.VISIBLE : View.GONE);
mEndTouchArea.setVisibility(showEndTouchArea ? View.VISIBLE : View.GONE);
}
void setTwoLineLayout(MediaDevice device, boolean bFocused, boolean showSeekBar,
@@ -230,12 +228,6 @@ public abstract class MediaOutputBaseAdapter extends
showStatus);
}
void setTwoLineLayout(CharSequence title, boolean bFocused, boolean showSeekBar,
boolean showProgressBar, boolean showSubtitle) {
setTwoLineLayout(null, title, bFocused, showSeekBar, showProgressBar, showSubtitle,
false);
}
private void setTwoLineLayout(MediaDevice device, CharSequence title, boolean bFocused,
boolean showSeekBar, boolean showProgressBar, boolean showSubtitle,
boolean showStatus) {
@@ -254,20 +246,11 @@ public abstract class MediaOutputBaseAdapter extends
mProgressBar.setVisibility(showProgressBar ? View.VISIBLE : View.GONE);
mSubTitleText.setVisibility(showSubtitle ? View.VISIBLE : View.GONE);
mTwoLineTitleText.setTranslationY(0);
if (device == null) {
mTwoLineTitleText.setText(title);
} else {
mTwoLineTitleText.setText(getItemTitle(device));
}
if (bFocused) {
mTwoLineTitleText.setTypeface(Typeface.create(mContext.getString(
com.android.internal.R.string.config_headlineFontFamilyMedium),
Typeface.NORMAL));
} else {
mTwoLineTitleText.setTypeface(Typeface.create(mContext.getString(
com.android.internal.R.string.config_headlineFontFamily), Typeface.NORMAL));
}
mTwoLineTitleText.setText(device == null ? title : getItemTitle(device));
mTwoLineTitleText.setTypeface(Typeface.create(mContext.getString(
bFocused ? com.android.internal.R.string.config_headlineFontFamilyMedium
: com.android.internal.R.string.config_headlineFontFamily),
Typeface.NORMAL));
}
void initSeekbar(MediaDevice device, boolean isCurrentSeekbarInvisible) {
@@ -327,35 +310,6 @@ public abstract class MediaOutputBaseAdapter extends
mItemLayout.setBackground(backgroundDrawable);
}
void initSessionSeekbar() {
disableSeekBar();
mSeekBar.setMax(mController.getSessionVolumeMax());
mSeekBar.setMin(0);
final int currentVolume = mController.getSessionVolume();
if (mSeekBar.getProgress() != currentVolume) {
mSeekBar.setProgress(currentVolume, true);
}
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 void animateCornerAndVolume(int fromProgress, int toProgress) {
final GradientDrawable layoutBackgroundDrawable =
(GradientDrawable) mItemLayout.getBackground();

View File

@@ -421,7 +421,7 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback,
device.getId());
boolean isSelectedDeviceInGroup = getSelectedMediaDevice().size() > 1
&& getSelectedMediaDevice().contains(device);
return (!hasAdjustVolumeUserRestriction() && isConnected && !isTransferring())
return (!hasAdjustVolumeUserRestriction() && isConnected && !isAnyDeviceTransferring())
|| isSelectedDeviceInGroup;
}
@@ -726,7 +726,7 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback,
UserHandle.of(UserHandle.myUserId()));
}
boolean isTransferring() {
boolean isAnyDeviceTransferring() {
synchronized (mMediaDevicesLock) {
for (MediaDevice device : mMediaDevices) {
if (device.getState() == LocalMediaManager.MediaDeviceState.STATE_CONNECTING) {

View File

@@ -78,7 +78,7 @@ public class MediaOutputAdapterTest extends SysuiTestCase {
when(mMediaOutputController.getMediaDevices()).thenReturn(mMediaDevices);
when(mMediaOutputController.hasAdjustVolumeUserRestriction()).thenReturn(false);
when(mMediaOutputController.isTransferring()).thenReturn(false);
when(mMediaOutputController.isAnyDeviceTransferring()).thenReturn(false);
when(mMediaOutputController.getDeviceIconCompat(mMediaDevice1)).thenReturn(mIconCompat);
when(mMediaOutputController.getDeviceIconCompat(mMediaDevice2)).thenReturn(mIconCompat);
when(mMediaOutputController.getCurrentConnectedMediaDevice()).thenReturn(mMediaDevice1);
@@ -208,7 +208,7 @@ public class MediaOutputAdapterTest extends SysuiTestCase {
@Test
public void onBindViewHolder_inTransferring_bindTransferringDevice_verifyView() {
when(mMediaOutputController.isTransferring()).thenReturn(true);
when(mMediaOutputController.isAnyDeviceTransferring()).thenReturn(true);
when(mMediaDevice1.getState()).thenReturn(
LocalMediaManager.MediaDeviceState.STATE_CONNECTING);
mMediaOutputAdapter.onBindViewHolder(mViewHolder, 0);
@@ -224,7 +224,7 @@ public class MediaOutputAdapterTest extends SysuiTestCase {
@Test
public void onBindViewHolder_inTransferring_bindNonTransferringDevice_verifyView() {
when(mMediaOutputController.isTransferring()).thenReturn(true);
when(mMediaOutputController.isAnyDeviceTransferring()).thenReturn(true);
when(mMediaDevice2.getState()).thenReturn(
LocalMediaManager.MediaDeviceState.STATE_CONNECTING);
mMediaOutputAdapter.onBindViewHolder(mViewHolder, 0);