summaryrefslogtreecommitdiff
path: root/packages/SystemUI/src
diff options
context:
space:
mode:
Diffstat (limited to 'packages/SystemUI/src')
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputGroupAdapter.java220
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputGroupDialog.java88
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();
+ }
+}