diff options
Diffstat (limited to 'packages/SystemUI/src')
5 files changed, 135 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 d1630ebe8dc8..d26f7ab6d78c 100644 --- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputAdapter.java +++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputAdapter.java @@ -109,34 +109,45 @@ public class MediaOutputAdapter extends MediaOutputBaseAdapter { super.onBind(device, topMargin, bottomMargin); final boolean currentlyConnected = isCurrentlyConnected(device); if (currentlyConnected) { - mConnectedItem = mFrameLayout; + mConnectedItem = mContainerLayout; + } + mBottomDivider.setVisibility(View.GONE); + mCheckBox.setVisibility(View.GONE); + if (currentlyConnected && mController.isActiveRemoteDevice(device)) { + // Init active device layout + mDivider.setVisibility(View.VISIBLE); + mDivider.setTransitionAlpha(1); + mAddIcon.setVisibility(View.VISIBLE); + mAddIcon.setTransitionAlpha(1); + mAddIcon.setOnClickListener(v -> onEndItemClick()); + } else { + // Init non-active device layout + mDivider.setVisibility(View.GONE); + mAddIcon.setVisibility(View.GONE); } if (mController.isTransferring()) { if (device.getState() == MediaDeviceState.STATE_CONNECTING && !mController.hasAdjustVolumeUserRestriction()) { - setTwoLineLayout(device, null /* title */, true /* bFocused */, - false /* showSeekBar*/, true /* showProgressBar */, - false /* showSubtitle */); + setTwoLineLayout(device, true /* bFocused */, false /* showSeekBar*/, + true /* showProgressBar */, false /* showSubtitle */); } else { setSingleLineLayout(getItemTitle(device), false /* bFocused */); } } else { // Set different layout for each device if (device.getState() == MediaDeviceState.STATE_CONNECTING_FAILED) { - setTwoLineLayout(device, null /* title */, false /* bFocused */, - false /* showSeekBar*/, false /* showProgressBar */, + setTwoLineLayout(device, false /* bFocused */, + false /* showSeekBar */, false /* showProgressBar */, true /* showSubtitle */); mSubTitleText.setText(R.string.media_output_dialog_connect_failed); - mFrameLayout.setOnClickListener(v -> onItemClick(v, device)); - } else if (!mController.hasAdjustVolumeUserRestriction() - && currentlyConnected) { - setTwoLineLayout(device, null /* title */, true /* bFocused */, - true /* showSeekBar*/, false /* showProgressBar */, - false /* showSubtitle */); + mContainerLayout.setOnClickListener(v -> onItemClick(v, device)); + } else if (!mController.hasAdjustVolumeUserRestriction() && currentlyConnected) { + setTwoLineLayout(device, true /* bFocused */, true /* showSeekBar */, + false /* showProgressBar */, false /* showSubtitle */); initSeekbar(device); } else { setSingleLineLayout(getItemTitle(device), false /* bFocused */); - mFrameLayout.setOnClickListener(v -> onItemClick(v, device)); + mContainerLayout.setOnClickListener(v -> onItemClick(v, device)); } } } @@ -145,13 +156,17 @@ public class MediaOutputAdapter extends MediaOutputBaseAdapter { void onBind(int customizedItem, boolean topMargin, boolean bottomMargin) { super.onBind(customizedItem, topMargin, bottomMargin); if (customizedItem == CUSTOMIZED_ITEM_PAIR_NEW) { + mCheckBox.setVisibility(View.GONE); + mDivider.setVisibility(View.GONE); + mAddIcon.setVisibility(View.GONE); + mBottomDivider.setVisibility(View.GONE); setSingleLineLayout(mContext.getText(R.string.media_output_dialog_pairing_new), false /* bFocused */); final Drawable d = mContext.getDrawable(R.drawable.ic_add); d.setColorFilter(new PorterDuffColorFilter( Utils.getColorAccentDefaultColor(mContext), PorterDuff.Mode.SRC_IN)); mTitleIcon.setImageDrawable(d); - mFrameLayout.setOnClickListener(v -> onItemClick(CUSTOMIZED_ITEM_PAIR_NEW)); + mContainerLayout.setOnClickListener(v -> onItemClick(CUSTOMIZED_ITEM_PAIR_NEW)); } } @@ -173,5 +188,9 @@ public class MediaOutputAdapter extends MediaOutputBaseAdapter { mController.launchBluetoothPairing(); } } + + private void onEndItemClick() { + mController.launchMediaOutputGroupDialog(); + } } } 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 2d3e77db1ea3..536b7598ce22 100644 --- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseAdapter.java +++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseAdapter.java @@ -24,8 +24,9 @@ import android.text.TextUtils; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; -import android.widget.FrameLayout; +import android.widget.CheckBox; import android.widget.ImageView; +import android.widget.LinearLayout; import android.widget.ProgressBar; import android.widget.RelativeLayout; import android.widget.SeekBar; @@ -44,19 +45,17 @@ import com.android.systemui.R; public abstract class MediaOutputBaseAdapter extends RecyclerView.Adapter<MediaOutputBaseAdapter.MediaDeviceBaseViewHolder> { - private static final String FONT_SELECTED_TITLE = "sans-serif-medium"; - private static final String FONT_TITLE = "sans-serif"; - static final int CUSTOMIZED_ITEM_PAIR_NEW = 1; + static final int CUSTOMIZED_ITEM_GROUP = 2; final MediaOutputController mController; - private boolean mIsDragging; private int mMargin; private boolean mIsAnimating; Context mContext; View mHolderView; + boolean mIsDragging; public MediaOutputBaseAdapter(MediaOutputController controller) { mController = controller; @@ -99,27 +98,33 @@ public abstract class MediaOutputBaseAdapter extends private static final int ANIM_DURATION = 200; - final FrameLayout mFrameLayout; + final LinearLayout mContainerLayout; final TextView mTitleText; final TextView mTwoLineTitleText; final TextView mSubTitleText; final ImageView mTitleIcon; - final ImageView mEndIcon; + final ImageView mAddIcon; final ProgressBar mProgressBar; final SeekBar mSeekBar; final RelativeLayout mTwoLineLayout; + final View mDivider; + final View mBottomDivider; + final CheckBox mCheckBox; MediaDeviceBaseViewHolder(View view) { super(view); - mFrameLayout = view.requireViewById(R.id.device_container); + mContainerLayout = view.requireViewById(R.id.device_container); mTitleText = view.requireViewById(R.id.title); mSubTitleText = view.requireViewById(R.id.subtitle); mTwoLineLayout = view.requireViewById(R.id.two_line_layout); mTwoLineTitleText = view.requireViewById(R.id.two_line_title); mTitleIcon = view.requireViewById(R.id.title_icon); - mEndIcon = view.requireViewById(R.id.end_icon); mProgressBar = view.requireViewById(R.id.volume_indeterminate_progress); mSeekBar = view.requireViewById(R.id.volume_seekbar); + mDivider = view.requireViewById(R.id.end_divider); + mBottomDivider = view.requireViewById(R.id.bottom_divider); + mAddIcon = view.requireViewById(R.id.add_icon); + mCheckBox = view.requireViewById(R.id.check_box); } void onBind(MediaDevice device, boolean topMargin, boolean bottomMargin) { @@ -132,11 +137,11 @@ public abstract class MediaOutputBaseAdapter extends } private void setMargin(boolean topMargin, boolean bottomMargin) { - ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) mFrameLayout + ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) mContainerLayout .getLayoutParams(); params.topMargin = topMargin ? mMargin : 0; params.bottomMargin = bottomMargin ? mMargin : 0; - mFrameLayout.setLayoutParams(params); + mContainerLayout.setLayoutParams(params); } void setSingleLineLayout(CharSequence title, boolean bFocused) { @@ -146,13 +151,26 @@ public abstract class MediaOutputBaseAdapter extends mTitleText.setTranslationY(0); mTitleText.setText(title); if (bFocused) { - mTitleText.setTypeface(Typeface.create(FONT_SELECTED_TITLE, Typeface.NORMAL)); + mTitleText.setTypeface(Typeface.create(mContext.getString( + com.android.internal.R.string.config_headlineFontFamilyMedium), + Typeface.NORMAL)); } else { - mTitleText.setTypeface(Typeface.create(FONT_TITLE, Typeface.NORMAL)); + mTitleText.setTypeface(Typeface.create(mContext.getString( + com.android.internal.R.string.config_headlineFontFamily), Typeface.NORMAL)); } } - void setTwoLineLayout(MediaDevice device, CharSequence title, boolean bFocused, + void setTwoLineLayout(MediaDevice device, boolean bFocused, boolean showSeekBar, + boolean showProgressBar, boolean showSubtitle) { + setTwoLineLayout(device, null, bFocused, showSeekBar, showProgressBar, showSubtitle); + } + + void setTwoLineLayout(CharSequence title, boolean bFocused, boolean showSeekBar, + boolean showProgressBar, boolean showSubtitle) { + setTwoLineLayout(null, title, bFocused, showSeekBar, showProgressBar, showSubtitle); + } + + private void setTwoLineLayout(MediaDevice device, CharSequence title, boolean bFocused, boolean showSeekBar, boolean showProgressBar, boolean showSubtitle) { mTitleText.setVisibility(View.GONE); mTwoLineLayout.setVisibility(View.VISIBLE); @@ -168,18 +186,21 @@ public abstract class MediaOutputBaseAdapter extends } if (bFocused) { - mTwoLineTitleText.setTypeface(Typeface.create(FONT_SELECTED_TITLE, + mTwoLineTitleText.setTypeface(Typeface.create(mContext.getString( + com.android.internal.R.string.config_headlineFontFamilyMedium), Typeface.NORMAL)); } else { - mTwoLineTitleText.setTypeface(Typeface.create(FONT_TITLE, Typeface.NORMAL)); + mTwoLineTitleText.setTypeface(Typeface.create(mContext.getString( + com.android.internal.R.string.config_headlineFontFamily), Typeface.NORMAL)); } } void initSeekbar(MediaDevice device) { mSeekBar.setMax(device.getMaxVolume()); mSeekBar.setMin(0); - if (mSeekBar.getProgress() != device.getCurrentVolume()) { - mSeekBar.setProgress(device.getCurrentVolume()); + final int currentVolume = device.getCurrentVolume(); + if (mSeekBar.getProgress() != currentVolume) { + mSeekBar.setProgress(currentVolume); } mSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { @Override @@ -213,7 +234,9 @@ public abstract class MediaOutputBaseAdapter extends } mIsAnimating = true; // Animation for title text - toTitleText.setTypeface(Typeface.create(FONT_SELECTED_TITLE, Typeface.NORMAL)); + toTitleText.setTypeface(Typeface.create(mContext.getString( + com.android.internal.R.string.config_headlineFontFamilyMedium), + Typeface.NORMAL)); toTitleText.animate() .setDuration(ANIM_DURATION) .translationY(-delta) @@ -234,7 +257,9 @@ public abstract class MediaOutputBaseAdapter extends public void onAnimationEnd(Animator animation) { final TextView fromTitleText = from.requireViewById( R.id.two_line_title); - fromTitleText.setTypeface(Typeface.create(FONT_TITLE, Typeface.NORMAL)); + fromTitleText.setTypeface(Typeface.create(mContext.getString( + com.android.internal.R.string.config_headlineFontFamily), + Typeface.NORMAL)); fromTitleText.animate() .setDuration(ANIM_DURATION) .translationY(delta) diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseDialog.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseDialog.java index 2faf56a5022c..dd9a808fb35b 100644 --- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseDialog.java +++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseDialog.java @@ -119,6 +119,8 @@ public abstract class MediaOutputBaseDialog extends SystemUIDialog implements // Init device list mDevicesRecyclerView.setLayoutManager(mLayoutManager); mDevicesRecyclerView.setAdapter(mAdapter); + // Init header icon + mHeaderIcon.setOnClickListener(v -> onHeaderIconClick()); // Init bottom buttons mDoneButton.setOnClickListener(v -> dismiss()); mStopButton.setOnClickListener(v -> { @@ -218,4 +220,7 @@ public abstract class MediaOutputBaseDialog extends SystemUIDialog implements dismiss(); } } + + void onHeaderIconClick() { + } } 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 b1f1bda25961..b9fa87252125 100644 --- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java +++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java @@ -71,6 +71,8 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback{ private final MediaSessionManager mMediaSessionManager; private final ShadeController mShadeController; private final ActivityStarter mActivityStarter; + private final List<MediaDevice> mGroupMediaDevices = new CopyOnWriteArrayList<>(); + private final boolean mAboveStatusbar; @VisibleForTesting final List<MediaDevice> mMediaDevices = new CopyOnWriteArrayList<>(); @@ -82,13 +84,14 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback{ @Inject public MediaOutputController(@NonNull Context context, String packageName, - MediaSessionManager mediaSessionManager, LocalBluetoothManager + boolean aboveStatusbar, MediaSessionManager mediaSessionManager, LocalBluetoothManager lbm, ShadeController shadeController, ActivityStarter starter) { mContext = context; mPackageName = packageName; mMediaSessionManager = mediaSessionManager; mShadeController = shadeController; mActivityStarter = starter; + mAboveStatusbar = aboveStatusbar; InfoMediaManager imm = new InfoMediaManager(mContext, packageName, null, lbm); mLocalMediaManager = new LocalMediaManager(mContext, lbm, imm, packageName); } @@ -271,6 +274,42 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback{ mMediaDevices.addAll(targetMediaDevices); } + List<MediaDevice> getGroupMediaDevices() { + final List<MediaDevice> selectedDevices = getSelectedMediaDevice(); + final List<MediaDevice> selectableDevices = getSelectableMediaDevice(); + if (mGroupMediaDevices.isEmpty()) { + mGroupMediaDevices.addAll(selectedDevices); + mGroupMediaDevices.addAll(selectableDevices); + return mGroupMediaDevices; + } + // To keep the same list order + final Collection<MediaDevice> sourceDevices = new ArrayList<>(); + final Collection<MediaDevice> targetMediaDevices = new ArrayList<>(); + sourceDevices.addAll(selectedDevices); + sourceDevices.addAll(selectableDevices); + for (MediaDevice originalDevice : mGroupMediaDevices) { + for (MediaDevice newDevice : sourceDevices) { + if (TextUtils.equals(originalDevice.getId(), newDevice.getId())) { + targetMediaDevices.add(newDevice); + sourceDevices.remove(newDevice); + break; + } + } + } + // Add new devices at the end of list if necessary + if (!sourceDevices.isEmpty()) { + targetMediaDevices.addAll(sourceDevices); + } + mGroupMediaDevices.clear(); + mGroupMediaDevices.addAll(targetMediaDevices); + + return mGroupMediaDevices; + } + + void resetGroupMediaDevices() { + mGroupMediaDevices.clear(); + } + void connectDevice(MediaDevice device) { ThreadUtils.postOnBackgroundThread(() -> { mLocalMediaManager.connectDevice(device); @@ -309,15 +348,6 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback{ return mLocalMediaManager.getDeselectableMediaDevice(); } - boolean isDeviceIncluded(Collection<MediaDevice> deviceCollection, MediaDevice targetDevice) { - for (MediaDevice device : deviceCollection) { - if (TextUtils.equals(device.getId(), targetDevice.getId())) { - return true; - } - } - return false; - } - void adjustSessionVolume(String sessionId, int volume) { mLocalMediaManager.adjustSessionVolume(sessionId, volume); } @@ -407,6 +437,16 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback{ mActivityStarter.dismissKeyguardThenExecute(postKeyguardAction, null, true); } + void launchMediaOutputDialog() { + mCallback.dismissDialog(); + new MediaOutputDialog(mContext, mAboveStatusbar, this); + } + + void launchMediaOutputGroupDialog() { + mCallback.dismissDialog(); + new MediaOutputGroupDialog(mContext, mAboveStatusbar, this); + } + boolean isActiveRemoteDevice(@NonNull MediaDevice device) { final List<String> features = device.getFeatures(); return (features.contains(MediaRoute2Info.FEATURE_REMOTE_PLAYBACK) 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 4cdca4cbcf1e..e912b7d1b08f 100644 --- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputDialogFactory.kt +++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputDialogFactory.kt @@ -40,9 +40,8 @@ class MediaOutputDialogFactory @Inject constructor( /** Creates a [MediaOutputDialog] for the given package. */ fun create(packageName: String, aboveStatusBar: Boolean) { mediaOutputDialog?.dismiss() - - mediaOutputDialog = MediaOutputController(context, packageName, mediaSessionManager, lbm, - shadeController, starter).run { + mediaOutputDialog = MediaOutputController(context, packageName, aboveStatusBar, + mediaSessionManager, lbm, shadeController, starter).run { MediaOutputDialog(context, aboveStatusBar, this) } } |