diff options
Diffstat (limited to 'packages/SystemUI/src')
-rw-r--r-- | packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputGroupAdapter.java | 220 | ||||
-rw-r--r-- | packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputGroupDialog.java | 88 |
2 files changed, 308 insertions, 0 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputGroupAdapter.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputGroupAdapter.java new file mode 100644 index 000000000000..ceb4495bd8e8 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputGroupAdapter.java @@ -0,0 +1,220 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +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; + +import java.util.List; + +/** + * Adapter for media output dynamic group dialog. + */ +public class MediaOutputGroupAdapter extends MediaOutputBaseAdapter { + + private static final String TAG = "MediaOutputGroupAdapter"; + private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); + + private final List<MediaDevice> mGroupMediaDevices; + + public MediaOutputGroupAdapter(MediaOutputController controller) { + super(controller); + mGroupMediaDevices = controller.getGroupMediaDevices(); + } + + @Override + public MediaDeviceBaseViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, + int viewType) { + super.onCreateViewHolder(viewGroup, viewType); + + return new GroupViewHolder(mHolderView); + } + + @Override + public void onBindViewHolder(@NonNull MediaDeviceBaseViewHolder viewHolder, int position) { + // Add "Group" + if (position == 0) { + viewHolder.onBind(CUSTOMIZED_ITEM_GROUP, true /* topMargin */, + false /* bottomMargin */); + return; + } + // Add available devices + final int newPosition = position - 1; + final int size = mGroupMediaDevices.size(); + if (newPosition < size) { + viewHolder.onBind(mGroupMediaDevices.get(newPosition), false /* topMargin */, + newPosition == (size - 1) /* bottomMargin */); + return; + } + if (DEBUG) { + Log.d(TAG, "Incorrect position: " + position); + } + } + + @Override + public int getItemCount() { + // Require extra item for group volume operation + return mGroupMediaDevices.size() + 1; + } + + @Override + CharSequence getItemTitle(MediaDevice device) { + return super.getItemTitle(device); + } + + class GroupViewHolder extends MediaDeviceBaseViewHolder { + + GroupViewHolder(View view) { + super(view); + } + + @Override + void onBind(MediaDevice device, boolean topMargin, boolean bottomMargin) { + super.onBind(device, topMargin, bottomMargin); + mDivider.setVisibility(View.GONE); + mAddIcon.setVisibility(View.GONE); + mBottomDivider.setVisibility(View.GONE); + mCheckBox.setVisibility(View.VISIBLE); + mCheckBox.setOnCheckedChangeListener((buttonView, isChecked) -> { + onCheckBoxClicked(isChecked, device); + }); + setTwoLineLayout(device, false /* bFocused */, true /* showSeekBar */, + false /* showProgressBar */, false /* showSubtitle*/); + initSeekbar(device); + final List<MediaDevice> selectedDevices = mController.getSelectedMediaDevice(); + if (isDeviceIncluded(mController.getSelectableMediaDevice(), device)) { + mCheckBox.setButtonDrawable(R.drawable.ic_check_box); + mCheckBox.setChecked(false); + mCheckBox.setEnabled(true); + } else if (isDeviceIncluded(selectedDevices, device)) { + if (selectedDevices.size() == 1 || !isDeviceIncluded( + mController.getDeselectableMediaDevice(), device)) { + mCheckBox.setButtonDrawable(getDisabledCheckboxDrawable()); + mCheckBox.setChecked(true); + mCheckBox.setEnabled(false); + } else { + mCheckBox.setButtonDrawable(R.drawable.ic_check_box); + mCheckBox.setChecked(true); + mCheckBox.setEnabled(true); + } + } + } + + @Override + void onBind(int customizedItem, boolean topMargin, boolean bottomMargin) { + super.onBind(customizedItem, topMargin, bottomMargin); + if (customizedItem == CUSTOMIZED_ITEM_GROUP) { + setTwoLineLayout(mContext.getText(R.string.media_output_dialog_group), + true /* bFocused */, true /* showSeekBar */, false /* showProgressBar */, + false /* showSubtitle*/); + mTitleIcon.setImageDrawable(getSpeakerDrawable()); + mBottomDivider.setVisibility(View.VISIBLE); + mCheckBox.setVisibility(View.GONE); + mDivider.setVisibility(View.GONE); + mAddIcon.setVisibility(View.GONE); + initSessionSeekbar(); + } + } + + private void onCheckBoxClicked(boolean isChecked, MediaDevice device) { + if (isChecked && isDeviceIncluded(mController.getSelectableMediaDevice(), device)) { + mController.addDeviceToPlayMedia(device); + } else if (!isChecked && isDeviceIncluded(mController.getDeselectableMediaDevice(), + device)) { + mController.removeDeviceFromPlayMedia(device); + } + } + + 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(); + final Bitmap checkbox = Bitmap.createBitmap(drawable.getIntrinsicWidth(), + drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888); + final Canvas canvas = new Canvas(checkbox); + TypedValue value = new TypedValue(); + mContext.getTheme().resolveAttribute(android.R.attr.disabledAlpha, value, true); + drawable.setAlpha((int) (value.getFloat() * 255)); + drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight()); + drawable.draw(canvas); + + 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())) { + return true; + } + } + return false; + } + } +} diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputGroupDialog.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputGroupDialog.java new file mode 100644 index 000000000000..407930492fbe --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputGroupDialog.java @@ -0,0 +1,88 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.media.dialog; + +import android.content.Context; +import android.os.Bundle; +import android.view.View; +import android.view.WindowManager; + +import androidx.core.graphics.drawable.IconCompat; + +import com.android.systemui.R; + +/** + * Dialog for media output group. + */ +public class MediaOutputGroupDialog extends MediaOutputBaseDialog { + + MediaOutputGroupDialog(Context context, boolean aboveStatusbar, MediaOutputController + mediaOutputController) { + super(context, mediaOutputController); + mMediaOutputController.resetGroupMediaDevices(); + mAdapter = new MediaOutputGroupAdapter(mMediaOutputController); + if (!aboveStatusbar) { + getWindow().setType(WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY); + } + show(); + } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + } + + @Override + int getHeaderIconRes() { + return R.drawable.ic_arrow_back; + } + + @Override + IconCompat getHeaderIcon() { + return null; + } + + @Override + int getHeaderIconSize() { + return mContext.getResources().getDimensionPixelSize( + R.dimen.media_output_dialog_header_back_icon_size); + } + + @Override + CharSequence getHeaderText() { + return mContext.getString(R.string.media_output_dialog_add_output); + } + + @Override + CharSequence getHeaderSubtitle() { + final int size = mMediaOutputController.getSelectedMediaDevice().size(); + if (size == 1) { + return mContext.getText(R.string.media_output_dialog_single_device); + } + return mContext.getString(R.string.media_output_dialog_multiple_devices, size); + } + + @Override + int getStopButtonVisibility() { + return View.VISIBLE; + } + + @Override + void onHeaderIconClick() { + mMediaOutputController.launchMediaOutputDialog(); + } +} |