From 62a153e93f47e2fa8cc4c4725bba5d10d32b39c1 Mon Sep 17 00:00:00 2001 From: shaoweishen Date: Thu, 24 Nov 2022 07:13:34 +0000 Subject: [PATCH] [Output Switcher] Update Volume control in Output Switcher guard this change with flags. Bug: 255126338 Test: verified on device Change-Id: I3c081fd8cb0e7fc55f3b5c7016647fb98ae77e0d --- ...media_output_dialog_seekbar_background.xml | 5 +- .../drawable/media_output_icon_volume_off.xml | 27 +++ .../drawable/media_output_title_icon_area.xml | 25 +++ .../media_output_list_item_advanced.xml | 158 ++++++++++++++++++ packages/SystemUI/res/values/strings.xml | 4 +- .../src/com/android/systemui/flags/Flags.kt | 5 + .../media/dialog/MediaOutputAdapter.java | 36 ++-- .../media/dialog/MediaOutputBaseAdapter.java | 156 ++++++++++++++++- .../MediaOutputBroadcastDialogFactory.kt | 6 +- .../media/dialog/MediaOutputController.java | 13 +- .../media/dialog/MediaOutputDialogFactory.kt | 6 +- .../media/dialog/MediaOutputSeekbar.java | 1 + .../dialog/MediaOutputBaseDialogTest.java | 4 +- .../dialog/MediaOutputControllerTest.java | 18 +- .../media/dialog/MediaOutputDialogTest.java | 4 +- 15 files changed, 426 insertions(+), 42 deletions(-) create mode 100644 packages/SystemUI/res/drawable/media_output_icon_volume_off.xml create mode 100644 packages/SystemUI/res/drawable/media_output_title_icon_area.xml create mode 100644 packages/SystemUI/res/layout/media_output_list_item_advanced.xml diff --git a/packages/SystemUI/res/drawable/media_output_dialog_seekbar_background.xml b/packages/SystemUI/res/drawable/media_output_dialog_seekbar_background.xml index 55dce8f7e66c0..43cf00332f63b 100644 --- a/packages/SystemUI/res/drawable/media_output_dialog_seekbar_background.xml +++ b/packages/SystemUI/res/drawable/media_output_dialog_seekbar_background.xml @@ -17,7 +17,10 @@ - + diff --git a/packages/SystemUI/res/drawable/media_output_icon_volume_off.xml b/packages/SystemUI/res/drawable/media_output_icon_volume_off.xml new file mode 100644 index 0000000000000..f29f44ce8226f --- /dev/null +++ b/packages/SystemUI/res/drawable/media_output_icon_volume_off.xml @@ -0,0 +1,27 @@ + + + + + diff --git a/packages/SystemUI/res/drawable/media_output_title_icon_area.xml b/packages/SystemUI/res/drawable/media_output_title_icon_area.xml new file mode 100644 index 0000000000000..b937937731795 --- /dev/null +++ b/packages/SystemUI/res/drawable/media_output_title_icon_area.xml @@ -0,0 +1,25 @@ + + + + + + \ No newline at end of file diff --git a/packages/SystemUI/res/layout/media_output_list_item_advanced.xml b/packages/SystemUI/res/layout/media_output_list_item_advanced.xml new file mode 100644 index 0000000000000..9d0bfd74af8ee --- /dev/null +++ b/packages/SystemUI/res/layout/media_output_list_item_advanced.xml @@ -0,0 +1,158 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml index 30788cf90e6a3..76816c5765249 100644 --- a/packages/SystemUI/res/values/strings.xml +++ b/packages/SystemUI/res/values/strings.xml @@ -2377,7 +2377,7 @@ Edit controls - + Add outputs Group @@ -2401,6 +2401,8 @@ Available devices for audio output. Volume + + %1$d%% diff --git a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt index 7c05356dd5fcf..a113ff2e3c445 100644 --- a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt +++ b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt @@ -436,6 +436,11 @@ object Flags { val WARN_ON_BLOCKING_BINDER_TRANSACTIONS = unreleasedFlag(2400, "warn_on_blocking_binder_transactions") + // 2500 - output switcher + // TODO(b/261538825): Tracking Bug + @JvmField + val OUTPUT_SWITCHER_ADVANCED_LAYOUT = unreleasedFlag(2500, "output_switcher_advanced_layout") + // TODO(b259590361): Tracking bug val EXPERIMENTAL_FLAG = unreleasedFlag(2, "exp_flag_release") } 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 ee5956105b7be..72d4e947b30fc 100644 --- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputAdapter.java +++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputAdapter.java @@ -16,7 +16,6 @@ package com.android.systemui.media.dialog; -import android.annotation.DrawableRes; import android.content.res.ColorStateList; import android.graphics.PorterDuff; import android.graphics.PorterDuffColorFilter; @@ -122,17 +121,19 @@ public class MediaOutputAdapter extends MediaOutputBaseAdapter { // Set different layout for each device if (device.isMutingExpectedDevice() && !mController.isCurrentConnectedDeviceRemote()) { - updateTitleIcon(R.drawable.media_output_icon_volume, - mController.getColorItemContent()); + if (!mController.isAdvancedLayoutSupported()) { + updateTitleIcon(R.drawable.media_output_icon_volume, + mController.getColorItemContent()); + } initMutingExpectedDevice(); mCurrentActivePosition = position; - updateContainerClickListener(v -> onItemClick(v, device)); + updateFullItemClickListener(v -> onItemClick(v, device)); setSingleLineLayout(getItemTitle(device)); } else if (device.getState() == MediaDeviceState.STATE_CONNECTING_FAILED) { setUpDeviceIcon(device); updateConnectionFailedStatusIcon(); mSubTitleText.setText(R.string.media_output_dialog_connect_failed); - updateContainerClickListener(v -> onItemClick(v, device)); + updateFullItemClickListener(v -> onItemClick(v, device)); setTwoLineLayout(device, false /* bFocused */, false /* showSeekBar */, false /* showProgressBar */, true /* showSubtitle */, true /* showStatus */); @@ -146,8 +147,10 @@ public class MediaOutputAdapter extends MediaOutputBaseAdapter { && isDeviceIncluded(mController.getSelectedMediaDevice(), device)) { boolean isDeviceDeselectable = isDeviceIncluded( mController.getDeselectableMediaDevice(), device); - updateTitleIcon(R.drawable.media_output_icon_volume, - mController.getColorItemContent()); + if (!mController.isAdvancedLayoutSupported()) { + updateTitleIcon(R.drawable.media_output_icon_volume, + mController.getColorItemContent()); + } updateGroupableCheckBox(true, isDeviceDeselectable, device); updateEndClickArea(device, isDeviceDeselectable); setUpContentDescriptionForView(mContainerLayout, false, device); @@ -161,7 +164,7 @@ public class MediaOutputAdapter extends MediaOutputBaseAdapter { && !mController.isCurrentConnectedDeviceRemote()) { // mark as disconnected and set special click listener setUpDeviceIcon(device); - updateContainerClickListener(v -> cancelMuteAwaitConnection()); + updateFullItemClickListener(v -> cancelMuteAwaitConnection()); setSingleLineLayout(getItemTitle(device)); } else { updateTitleIcon(R.drawable.media_output_icon_volume, @@ -176,14 +179,14 @@ public class MediaOutputAdapter extends MediaOutputBaseAdapter { } else if (isDeviceIncluded(mController.getSelectableMediaDevice(), device)) { setUpDeviceIcon(device); updateGroupableCheckBox(false, true, device); - updateContainerClickListener(v -> onGroupActionTriggered(true, device)); + updateFullItemClickListener(v -> onGroupActionTriggered(true, device)); setSingleLineLayout(getItemTitle(device), false /* showSeekBar */, false /* showProgressBar */, true /* showCheckBox */, true /* showEndTouchArea */); } else { setUpDeviceIcon(device); setSingleLineLayout(getItemTitle(device)); - updateContainerClickListener(v -> onItemClick(v, device)); + updateFullItemClickListener(v -> onItemClick(v, device)); } } } @@ -228,13 +231,9 @@ public class MediaOutputAdapter extends MediaOutputBaseAdapter { 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) { + private void updateFullItemClickListener(View.OnClickListener listener) { mContainerLayout.setOnClickListener(listener); + updateIconAreaClickListener(listener); } @Override @@ -246,6 +245,11 @@ public class MediaOutputAdapter extends MediaOutputBaseAdapter { final Drawable addDrawable = mContext.getDrawable(R.drawable.ic_add); mTitleIcon.setImageDrawable(addDrawable); mTitleIcon.setColorFilter(mController.getColorItemContent()); + if (mController.isAdvancedLayoutSupported()) { + mIconAreaLayout.getBackground().setColorFilter( + new PorterDuffColorFilter(mController.getColorItemBackground(), + PorterDuff.Mode.SRC_IN)); + } mContainerLayout.setOnClickListener(mController::launchBluetoothPairing); } } 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 3f7b2261ea52b..8987e7ca9efb4 100644 --- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseAdapter.java +++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseAdapter.java @@ -16,8 +16,11 @@ package com.android.systemui.media.dialog; +import static com.android.systemui.media.dialog.MediaOutputSeekbar.VOLUME_PERCENTAGE_SCALE_SIZE; + import android.animation.Animator; import android.animation.ValueAnimator; +import android.annotation.DrawableRes; import android.app.WallpaperColors; import android.content.Context; import android.graphics.PorterDuff; @@ -80,8 +83,9 @@ public abstract class MediaOutputBaseAdapter extends public MediaDeviceBaseViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int viewType) { mContext = viewGroup.getContext(); - mHolderView = LayoutInflater.from(mContext).inflate(R.layout.media_output_list_item, - viewGroup, false); + mHolderView = LayoutInflater.from(mContext).inflate( + mController.isAdvancedLayoutSupported() ? R.layout.media_output_list_item_advanced + : R.layout.media_output_list_item, viewGroup, false); return null; } @@ -131,9 +135,11 @@ public abstract class MediaOutputBaseAdapter extends final LinearLayout mContainerLayout; final FrameLayout mItemLayout; + final FrameLayout mIconAreaLayout; final TextView mTitleText; final TextView mTwoLineTitleText; final TextView mSubTitleText; + final TextView mVolumeValueText; final ImageView mTitleIcon; final ProgressBar mProgressBar; final MediaOutputSeekbar mSeekBar; @@ -159,6 +165,13 @@ public abstract class MediaOutputBaseAdapter extends mStatusIcon = view.requireViewById(R.id.media_output_item_status); mCheckBox = view.requireViewById(R.id.check_box); mEndTouchArea = view.requireViewById(R.id.end_action_area); + if (mController.isAdvancedLayoutSupported()) { + mVolumeValueText = view.requireViewById(R.id.volume_value); + mIconAreaLayout = view.requireViewById(R.id.icon_area); + } else { + mVolumeValueText = null; + mIconAreaLayout = null; + } initAnimator(); } @@ -170,9 +183,14 @@ public abstract class MediaOutputBaseAdapter extends mEndTouchArea.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO); mContainerLayout.setOnClickListener(null); mContainerLayout.setContentDescription(null); + mTitleIcon.setOnClickListener(null); mTitleText.setTextColor(mController.getColorItemContent()); mSubTitleText.setTextColor(mController.getColorItemContent()); mTwoLineTitleText.setTextColor(mController.getColorItemContent()); + if (mController.isAdvancedLayoutSupported()) { + mIconAreaLayout.setOnClickListener(null); + mVolumeValueText.setTextColor(mController.getColorItemContent()); + } mSeekBar.getProgressDrawable().setColorFilter( new PorterDuffColorFilter(mController.getColorSeekbarProgress(), PorterDuff.Mode.SRC_IN)); @@ -203,13 +221,28 @@ public abstract class MediaOutputBaseAdapter extends .findDrawableByLayerId(android.R.id.progress); final GradientDrawable progressDrawable = (GradientDrawable) clipDrawable.getDrawable(); - progressDrawable.setCornerRadius(mController.getActiveRadius()); + if (mController.isAdvancedLayoutSupported()) { + progressDrawable.setCornerRadii( + new float[]{0, 0, mController.getActiveRadius(), + mController.getActiveRadius(), + mController.getActiveRadius(), + mController.getActiveRadius(), 0, 0}); + } else { + progressDrawable.setCornerRadius(mController.getActiveRadius()); + } } } mItemLayout.getBackground().setColorFilter(new PorterDuffColorFilter( isActive ? mController.getColorConnectedItemBackground() : mController.getColorItemBackground(), PorterDuff.Mode.SRC_IN)); + if (mController.isAdvancedLayoutSupported()) { + mIconAreaLayout.getBackground().setColorFilter(new PorterDuffColorFilter( + showSeekBar ? mController.getColorSeekbarProgress() + : showProgressBar ? 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); @@ -263,42 +296,134 @@ public abstract class MediaOutputBaseAdapter extends final int currentVolume = device.getCurrentVolume(); if (mSeekBar.getVolume() != currentVolume) { if (isCurrentSeekbarInvisible && !mIsInitVolumeFirstTime) { + if (mController.isAdvancedLayoutSupported()) { + updateTitleIcon(currentVolume == 0 ? R.drawable.media_output_icon_volume_off + : R.drawable.media_output_icon_volume, + mController.getColorItemContent()); + } animateCornerAndVolume(mSeekBar.getProgress(), MediaOutputSeekbar.scaleVolumeToProgress(currentVolume)); } else { if (!mVolumeAnimator.isStarted()) { + if (mController.isAdvancedLayoutSupported()) { + int percentage = + (int) ((double) currentVolume * VOLUME_PERCENTAGE_SCALE_SIZE + / (double) mSeekBar.getMax()); + if (percentage == 0) { + updateMutedVolumeIcon(); + } else { + updateUnmutedVolumeIcon(); + } + } mSeekBar.setVolume(currentVolume); } } + } else if (mController.isAdvancedLayoutSupported() && currentVolume == 0) { + mSeekBar.resetVolume(); + updateMutedVolumeIcon(); } if (mIsInitVolumeFirstTime) { mIsInitVolumeFirstTime = false; } + if (mController.isAdvancedLayoutSupported()) { + updateIconAreaClickListener((v) -> { + mSeekBar.resetVolume(); + mController.adjustVolume(device, 0); + updateMutedVolumeIcon(); + }); + } mSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { if (device == null || !fromUser) { return; } - int currentVolume = MediaOutputSeekbar.scaleProgressToVolume(progress); + int progressToVolume = MediaOutputSeekbar.scaleProgressToVolume(progress); int deviceVolume = device.getCurrentVolume(); - if (currentVolume != deviceVolume) { - mController.adjustVolume(device, currentVolume); + if (mController.isAdvancedLayoutSupported()) { + int percentage = + (int) ((double) progressToVolume * VOLUME_PERCENTAGE_SCALE_SIZE + / (double) seekBar.getMax()); + mVolumeValueText.setText(mContext.getResources().getString( + R.string.media_output_dialog_volume_percentage, percentage)); + mVolumeValueText.setVisibility(View.VISIBLE); + } + if (progressToVolume != deviceVolume) { + mController.adjustVolume(device, progressToVolume); + if (mController.isAdvancedLayoutSupported() && deviceVolume == 0) { + updateUnmutedVolumeIcon(); + } } } @Override public void onStartTrackingTouch(SeekBar seekBar) { + if (mController.isAdvancedLayoutSupported()) { + mTitleIcon.setVisibility(View.INVISIBLE); + mVolumeValueText.setVisibility(View.VISIBLE); + } mIsDragging = true; } @Override public void onStopTrackingTouch(SeekBar seekBar) { + if (mController.isAdvancedLayoutSupported()) { + int currentVolume = MediaOutputSeekbar.scaleProgressToVolume( + seekBar.getProgress()); + int percentage = + (int) ((double) currentVolume * VOLUME_PERCENTAGE_SCALE_SIZE + / (double) seekBar.getMax()); + if (percentage == 0) { + seekBar.setProgress(0); + updateMutedVolumeIcon(); + } else { + updateUnmutedVolumeIcon(); + } + mTitleIcon.setVisibility(View.VISIBLE); + mVolumeValueText.setVisibility(View.GONE); + } mIsDragging = false; } }); } + void updateMutedVolumeIcon() { + updateTitleIcon(R.drawable.media_output_icon_volume_off, + mController.getColorItemContent()); + final GradientDrawable iconAreaBackgroundDrawable = + (GradientDrawable) mIconAreaLayout.getBackground(); + iconAreaBackgroundDrawable.setCornerRadius(mController.getActiveRadius()); + } + + void updateUnmutedVolumeIcon() { + updateTitleIcon(R.drawable.media_output_icon_volume, + mController.getColorItemContent()); + final GradientDrawable iconAreaBackgroundDrawable = + (GradientDrawable) mIconAreaLayout.getBackground(); + iconAreaBackgroundDrawable.setCornerRadii(new float[]{ + mController.getActiveRadius(), + mController.getActiveRadius(), + 0, 0, 0, 0, mController.getActiveRadius(), mController.getActiveRadius() + }); + } + + void updateTitleIcon(@DrawableRes int id, int color) { + mTitleIcon.setImageDrawable(mContext.getDrawable(id)); + mTitleIcon.setColorFilter(color); + if (mController.isAdvancedLayoutSupported()) { + mIconAreaLayout.getBackground().setColorFilter( + new PorterDuffColorFilter(mController.getColorSeekbarProgress(), + PorterDuff.Mode.SRC_IN)); + } + } + + void updateIconAreaClickListener(View.OnClickListener listener) { + if (mController.isAdvancedLayoutSupported()) { + mIconAreaLayout.setOnClickListener(listener); + } + mTitleIcon.setOnClickListener(listener); + } + void initMutingExpectedDevice() { disableSeekBar(); final Drawable backgroundDrawable = mContext.getDrawable( @@ -316,11 +441,26 @@ public abstract class MediaOutputBaseAdapter extends final ClipDrawable clipDrawable = (ClipDrawable) ((LayerDrawable) mSeekBar.getProgressDrawable()) .findDrawableByLayerId(android.R.id.progress); - final GradientDrawable progressDrawable = (GradientDrawable) clipDrawable.getDrawable(); + final GradientDrawable targetBackgroundDrawable = + (GradientDrawable) (mController.isAdvancedLayoutSupported() + ? mIconAreaLayout.getBackground() + : clipDrawable.getDrawable()); mCornerAnimator.addUpdateListener(animation -> { float value = (float) animation.getAnimatedValue(); layoutBackgroundDrawable.setCornerRadius(value); - progressDrawable.setCornerRadius(value); + if (mController.isAdvancedLayoutSupported()) { + if (toProgress == 0) { + targetBackgroundDrawable.setCornerRadius(value); + } else { + targetBackgroundDrawable.setCornerRadii(new float[]{ + value, + value, + 0, 0, 0, 0, value, value + }); + } + } else { + targetBackgroundDrawable.setCornerRadius(value); + } }); mVolumeAnimator.setIntValues(fromProgress, toProgress); mVolumeAnimator.start(); diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBroadcastDialogFactory.kt b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBroadcastDialogFactory.kt index 2b5d6fd63995b..cdd00f99fa29f 100644 --- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBroadcastDialogFactory.kt +++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBroadcastDialogFactory.kt @@ -26,6 +26,7 @@ import com.android.internal.logging.UiEventLogger import com.android.settingslib.bluetooth.LocalBluetoothManager import com.android.systemui.animation.DialogLaunchAnimator import com.android.systemui.broadcast.BroadcastSender +import com.android.systemui.flags.FeatureFlags import com.android.systemui.media.nearby.NearbyMediaDevicesManager import com.android.systemui.plugins.ActivityStarter import com.android.systemui.statusbar.notification.collection.notifcollection.CommonNotifCollection @@ -47,7 +48,8 @@ class MediaOutputBroadcastDialogFactory @Inject constructor( private val nearbyMediaDevicesManagerOptional: Optional, private val audioManager: AudioManager, private val powerExemptionManager: PowerExemptionManager, - private val keyGuardManager: KeyguardManager + private val keyGuardManager: KeyguardManager, + private val featureFlags: FeatureFlags ) { var mediaOutputBroadcastDialog: MediaOutputBroadcastDialog? = null @@ -59,7 +61,7 @@ class MediaOutputBroadcastDialogFactory @Inject constructor( val controller = MediaOutputController(context, packageName, mediaSessionManager, lbm, starter, notifCollection, dialogLaunchAnimator, nearbyMediaDevicesManagerOptional, audioManager, - powerExemptionManager, keyGuardManager) + powerExemptionManager, keyGuardManager, featureFlags) val dialog = MediaOutputBroadcastDialog(context, aboveStatusBar, broadcastSender, controller) mediaOutputBroadcastDialog = dialog 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 19b401d806008..ecfc0e6d75740 100644 --- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java +++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java @@ -73,6 +73,8 @@ import com.android.systemui.R; import com.android.systemui.animation.ActivityLaunchAnimator; import com.android.systemui.animation.DialogLaunchAnimator; import com.android.systemui.broadcast.BroadcastSender; +import com.android.systemui.flags.FeatureFlags; +import com.android.systemui.flags.Flags; import com.android.systemui.media.nearby.NearbyMediaDevicesManager; import com.android.systemui.monet.ColorScheme; import com.android.systemui.plugins.ActivityStarter; @@ -147,6 +149,7 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback, private int mColorDialogBackground; private float mInactiveRadius; private float mActiveRadius; + private FeatureFlags mFeatureFlags; public enum BroadcastNotifyDialog { ACTION_FIRST_LAUNCH, @@ -162,7 +165,8 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback, Optional nearbyMediaDevicesManagerOptional, AudioManager audioManager, PowerExemptionManager powerExemptionManager, - KeyguardManager keyGuardManager) { + KeyguardManager keyGuardManager, + FeatureFlags featureFlags) { mContext = context; mPackageName = packageName; mMediaSessionManager = mediaSessionManager; @@ -172,6 +176,7 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback, mAudioManager = audioManager; mPowerExemptionManager = powerExemptionManager; mKeyGuardManager = keyGuardManager; + mFeatureFlags = featureFlags; InfoMediaManager imm = new InfoMediaManager(mContext, packageName, null, lbm); mLocalMediaManager = new LocalMediaManager(mContext, lbm, imm, packageName); mMetricLogger = new MediaOutputMetricLogger(mContext, mPackageName); @@ -599,6 +604,10 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback, currentConnectedMediaDevice); } + public boolean isAdvancedLayoutSupported() { + return mFeatureFlags.isEnabled(Flags.OUTPUT_SWITCHER_ADVANCED_LAYOUT); + } + List getGroupMediaDevices() { final List selectedDevices = getSelectedMediaDevice(); final List selectableDevices = getSelectableMediaDevice(); @@ -792,7 +801,7 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback, MediaOutputController controller = new MediaOutputController(mContext, mPackageName, mMediaSessionManager, mLocalBluetoothManager, mActivityStarter, mNotifCollection, mDialogLaunchAnimator, Optional.of(mNearbyMediaDevicesManager), - mAudioManager, mPowerExemptionManager, mKeyGuardManager); + mAudioManager, mPowerExemptionManager, mKeyGuardManager, mFeatureFlags); MediaOutputBroadcastDialog dialog = new MediaOutputBroadcastDialog(mContext, true, broadcastSender, controller); mDialogLaunchAnimator.showFromView(dialog, mediaOutputDialog); diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputDialogFactory.kt b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputDialogFactory.kt index 543efed8378e9..7dbf876bb3776 100644 --- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputDialogFactory.kt +++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputDialogFactory.kt @@ -31,6 +31,7 @@ import com.android.systemui.broadcast.BroadcastSender import com.android.systemui.media.nearby.NearbyMediaDevicesManager import com.android.systemui.plugins.ActivityStarter import com.android.systemui.statusbar.notification.collection.notifcollection.CommonNotifCollection +import com.android.systemui.flags.FeatureFlags import java.util.Optional import javax.inject.Inject @@ -49,7 +50,8 @@ class MediaOutputDialogFactory @Inject constructor( private val nearbyMediaDevicesManagerOptional: Optional, private val audioManager: AudioManager, private val powerExemptionManager: PowerExemptionManager, - private val keyGuardManager: KeyguardManager + private val keyGuardManager: KeyguardManager, + private val featureFlags: FeatureFlags ) { companion object { private const val INTERACTION_JANK_TAG = "media_output" @@ -65,7 +67,7 @@ class MediaOutputDialogFactory @Inject constructor( context, packageName, mediaSessionManager, lbm, starter, notifCollection, dialogLaunchAnimator, nearbyMediaDevicesManagerOptional, audioManager, - powerExemptionManager, keyGuardManager) + powerExemptionManager, keyGuardManager, featureFlags) val dialog = MediaOutputDialog(context, aboveStatusBar, broadcastSender, controller, uiEventLogger) mediaOutputDialog = dialog diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputSeekbar.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputSeekbar.java index 4ff79d6890374..253c3c7134853 100644 --- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputSeekbar.java +++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputSeekbar.java @@ -26,6 +26,7 @@ import android.widget.SeekBar; */ public class MediaOutputSeekbar extends SeekBar { private static final int SCALE_SIZE = 1000; + public static final int VOLUME_PERCENTAGE_SCALE_SIZE = 100000; public MediaOutputSeekbar(Context context, AttributeSet attrs) { super(context, attrs); 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 9be201e99b2b6..094d69a9d3921 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 @@ -51,6 +51,7 @@ import com.android.systemui.R; import com.android.systemui.SysuiTestCase; import com.android.systemui.animation.DialogLaunchAnimator; import com.android.systemui.broadcast.BroadcastSender; +import com.android.systemui.flags.FeatureFlags; import com.android.systemui.media.nearby.NearbyMediaDevicesManager; import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.statusbar.notification.collection.notifcollection.CommonNotifCollection; @@ -89,6 +90,7 @@ public class MediaOutputBaseDialogTest extends SysuiTestCase { private final AudioManager mAudioManager = mock(AudioManager.class); private PowerExemptionManager mPowerExemptionManager = mock(PowerExemptionManager.class); private KeyguardManager mKeyguardManager = mock(KeyguardManager.class); + private FeatureFlags mFlags = mock(FeatureFlags.class); private List mMediaControllers = new ArrayList<>(); private MediaOutputBaseDialogImpl mMediaOutputBaseDialogImpl; @@ -121,7 +123,7 @@ public class MediaOutputBaseDialogTest extends SysuiTestCase { mMediaSessionManager, mLocalBluetoothManager, mStarter, mNotifCollection, mDialogLaunchAnimator, Optional.of(mNearbyMediaDevicesManager), mAudioManager, mPowerExemptionManager, - mKeyguardManager); + mKeyguardManager, mFlags); mMediaOutputBaseDialogImpl = new MediaOutputBaseDialogImpl(mContext, mBroadcastSender, mMediaOutputController); mMediaOutputBaseDialogImpl.onCreate(new Bundle()); diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputControllerTest.java index cb31fde26bf26..c544c0e02d34c 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputControllerTest.java @@ -62,6 +62,7 @@ import com.android.systemui.R; import com.android.systemui.SysuiTestCase; import com.android.systemui.animation.ActivityLaunchAnimator; import com.android.systemui.animation.DialogLaunchAnimator; +import com.android.systemui.flags.FeatureFlags; import com.android.systemui.media.nearby.NearbyMediaDevicesManager; import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.statusbar.notification.collection.NotificationEntry; @@ -110,6 +111,7 @@ public class MediaOutputControllerTest extends SysuiTestCase { private PowerExemptionManager mPowerExemptionManager = mock(PowerExemptionManager.class); private CommonNotifCollection mNotifCollection = mock(CommonNotifCollection.class); private final DialogLaunchAnimator mDialogLaunchAnimator = mock(DialogLaunchAnimator.class); + private FeatureFlags mFlags = mock(FeatureFlags.class); private final ActivityLaunchAnimator.Controller mActivityLaunchAnimatorController = mock( ActivityLaunchAnimator.Controller.class); private final NearbyMediaDevicesManager mNearbyMediaDevicesManager = mock( @@ -141,7 +143,7 @@ public class MediaOutputControllerTest extends SysuiTestCase { mMediaSessionManager, mLocalBluetoothManager, mStarter, mNotifCollection, mDialogLaunchAnimator, Optional.of(mNearbyMediaDevicesManager), mAudioManager, mPowerExemptionManager, - mKeyguardManager); + mKeyguardManager, mFlags); mLocalMediaManager = spy(mMediaOutputController.mLocalMediaManager); mMediaOutputController.mLocalMediaManager = mLocalMediaManager; MediaDescription.Builder builder = new MediaDescription.Builder(); @@ -194,7 +196,7 @@ public class MediaOutputControllerTest extends SysuiTestCase { mMediaSessionManager, mLocalBluetoothManager, mStarter, mNotifCollection, mDialogLaunchAnimator, Optional.of(mNearbyMediaDevicesManager), mAudioManager, mPowerExemptionManager, - mKeyguardManager); + mKeyguardManager, mFlags); mMediaOutputController.start(mCb); @@ -224,7 +226,7 @@ public class MediaOutputControllerTest extends SysuiTestCase { mMediaSessionManager, mLocalBluetoothManager, mStarter, mNotifCollection, mDialogLaunchAnimator, Optional.of(mNearbyMediaDevicesManager), mAudioManager, mPowerExemptionManager, - mKeyguardManager); + mKeyguardManager, mFlags); mMediaOutputController.start(mCb); @@ -318,7 +320,7 @@ public class MediaOutputControllerTest extends SysuiTestCase { mMediaSessionManager, mLocalBluetoothManager, mStarter, mNotifCollection, mDialogLaunchAnimator, Optional.of(mNearbyMediaDevicesManager), mAudioManager, mPowerExemptionManager, - mKeyguardManager); + mKeyguardManager, mFlags); testMediaOutputController.start(mCb); reset(mCb); @@ -341,7 +343,7 @@ public class MediaOutputControllerTest extends SysuiTestCase { mMediaSessionManager, mLocalBluetoothManager, mStarter, mNotifCollection, mDialogLaunchAnimator, Optional.of(mNearbyMediaDevicesManager), mAudioManager, mPowerExemptionManager, - mKeyguardManager); + mKeyguardManager, mFlags); testMediaOutputController.start(mCb); reset(mCb); @@ -377,7 +379,7 @@ public class MediaOutputControllerTest extends SysuiTestCase { mMediaSessionManager, mLocalBluetoothManager, mStarter, mNotifCollection, mDialogLaunchAnimator, Optional.of(mNearbyMediaDevicesManager), mAudioManager, mPowerExemptionManager, - mKeyguardManager); + mKeyguardManager, mFlags); LocalMediaManager testLocalMediaManager = spy(testMediaOutputController.mLocalMediaManager); testMediaOutputController.mLocalMediaManager = testLocalMediaManager; @@ -394,7 +396,7 @@ public class MediaOutputControllerTest extends SysuiTestCase { mMediaSessionManager, mLocalBluetoothManager, mStarter, mNotifCollection, mDialogLaunchAnimator, Optional.of(mNearbyMediaDevicesManager), mAudioManager, mPowerExemptionManager, - mKeyguardManager); + mKeyguardManager, mFlags); LocalMediaManager testLocalMediaManager = spy(testMediaOutputController.mLocalMediaManager); testMediaOutputController.mLocalMediaManager = testLocalMediaManager; @@ -671,7 +673,7 @@ public class MediaOutputControllerTest extends SysuiTestCase { mMediaSessionManager, mLocalBluetoothManager, mStarter, mNotifCollection, mDialogLaunchAnimator, Optional.of(mNearbyMediaDevicesManager), mAudioManager, mPowerExemptionManager, - mKeyguardManager); + mKeyguardManager, mFlags); assertThat(mMediaOutputController.getNotificationIcon()).isNull(); } diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputDialogTest.java b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputDialogTest.java index bae3569cdc935..31866a8df7e50 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputDialogTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputDialogTest.java @@ -50,6 +50,7 @@ import com.android.systemui.R; import com.android.systemui.SysuiTestCase; import com.android.systemui.animation.DialogLaunchAnimator; import com.android.systemui.broadcast.BroadcastSender; +import com.android.systemui.flags.FeatureFlags; import com.android.systemui.media.nearby.NearbyMediaDevicesManager; import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.statusbar.notification.collection.notifcollection.CommonNotifCollection; @@ -93,6 +94,7 @@ public class MediaOutputDialogTest extends SysuiTestCase { private final AudioManager mAudioManager = mock(AudioManager.class); private PowerExemptionManager mPowerExemptionManager = mock(PowerExemptionManager.class); private KeyguardManager mKeyguardManager = mock(KeyguardManager.class); + private FeatureFlags mFlags = mock(FeatureFlags.class); private List mMediaControllers = new ArrayList<>(); private MediaOutputDialog mMediaOutputDialog; @@ -115,7 +117,7 @@ public class MediaOutputDialogTest extends SysuiTestCase { mMediaSessionManager, mLocalBluetoothManager, mStarter, mNotifCollection, mDialogLaunchAnimator, Optional.of(mNearbyMediaDevicesManager), mAudioManager, mPowerExemptionManager, - mKeyguardManager); + mKeyguardManager, mFlags); mMediaOutputController.mLocalMediaManager = mLocalMediaManager; mMediaOutputDialog = new MediaOutputDialog(mContext, false, mBroadcastSender, mMediaOutputController, mUiEventLogger);