summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Shaowei Shen <shaoweishen@google.com> 2023-05-05 09:21:12 +0000
committer Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com> 2023-05-05 09:21:12 +0000
commitd850b7714c8c126f65cdf6813b97fa34b51b1fbd (patch)
tree2bdf429cfeac1e7af69d0444837d79dfc680c071
parenta07b2f67144d4b107b792a851daed50b3e7784cb (diff)
parenta937b49da161c7d6dc1dd69ecc64e216235643dd (diff)
Merge "[Output Switcher] Add switch confirm dialog" into udc-dev am: b875795205 am: a937b49da1
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/22952407 Change-Id: Iba80983ab17089e39a4c3c4157a30e06219fafa1 Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
-rw-r--r--packages/SystemUI/res/layout/media_session_end_dialog.xml91
-rw-r--r--packages/SystemUI/res/values/strings.xml4
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputAdapter.java17
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/dialog/MediaSessionReleaseDialog.java89
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputAdapterTest.java19
6 files changed, 226 insertions, 0 deletions
diff --git a/packages/SystemUI/res/layout/media_session_end_dialog.xml b/packages/SystemUI/res/layout/media_session_end_dialog.xml
new file mode 100644
index 000000000000..e1050f65d47a
--- /dev/null
+++ b/packages/SystemUI/res/layout/media_session_end_dialog.xml
@@ -0,0 +1,91 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2023 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.
+ -->
+
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
+ android:id="@+id/end_session_dialog"
+ android:layout_width="@dimen/large_dialog_width"
+ android:layout_height="wrap_content"
+ android:orientation="vertical">
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ style="@style/Widget.SliceView.Panel"
+ android:gravity="center_vertical|center_horizontal"
+ android:layout_marginTop="@dimen/dialog_top_padding"
+ android:layout_marginBottom="@dimen/dialog_bottom_padding"
+ android:orientation="vertical">
+
+ <ImageView
+ android:id="@+id/end_icon"
+ android:gravity="center_vertical|center_horizontal"
+ android:layout_width="36dp"
+ android:layout_height="36dp"
+ android:importantForAccessibility="no"/>
+
+ <TextView
+ android:id="@+id/end_session_dialog_title"
+ android:text="@string/media_output_end_session_dialog_summary"
+ android:layout_marginTop="16dp"
+ android:layout_marginBottom="@dimen/dialog_side_padding"
+ android:layout_marginStart="@dimen/dialog_side_padding"
+ android:layout_marginEnd="@dimen/dialog_bottom_padding"
+ android:ellipsize="end"
+ android:gravity="center_vertical|center_horizontal"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textColor="?android:attr/textColorPrimary"
+ android:fontFamily="@*android:string/config_headlineFontFamilyMedium"
+ android:textSize="24sp"/>
+ </LinearLayout>
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:gravity="end|center_vertical"
+ android:layout_marginTop="8dp"
+ android:layout_marginStart="@dimen/dialog_side_padding"
+ android:layout_marginEnd="@dimen/dialog_side_padding"
+ android:layout_marginBottom="@dimen/dialog_bottom_padding"
+ android:orientation="horizontal">
+ <Button
+ android:id="@+id/cancel_button"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginEnd="8dp"
+ android:text="@string/cancel"
+ android:ellipsize="end"
+ android:layout_gravity="end|center_vertical"
+ android:singleLine="true"
+ style="@style/Widget.Dialog.Button.BorderButton"
+ android:clickable="true"
+ android:focusable="true"/>
+ <Button
+ android:id="@+id/stop_button"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="end|center_vertical"
+ android:text="@string/media_output_end_session_dialog_stop"
+ style="@style/Widget.Dialog.Button"
+ android:singleLine="true"
+ android:ellipsize="end"
+ android:clickable="true"
+ android:focusable="true"/>
+ </LinearLayout>
+</LinearLayout>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index c57fef1c52f7..70fdc2070b7a 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -2684,6 +2684,10 @@
<string name="media_output_group_title_speakers_and_displays">Speakers &amp; Displays</string>
<!-- Title for Suggested Devices group. [CHAR LIMIT=NONE] -->
<string name="media_output_group_title_suggested_device">Suggested Devices</string>
+ <!-- Summary for end session dialog. [CHAR LIMIT=NONE] -->
+ <string name="media_output_end_session_dialog_summary">Stop your shared session to move media to another device</string>
+ <!-- Button text for stopping session [CHAR LIMIT=60] -->
+ <string name="media_output_end_session_dialog_stop">Stop</string>
<!-- Media Output Broadcast Dialog -->
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 f50a7a854169..d46e6b996fa4 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputAdapter.java
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputAdapter.java
@@ -37,6 +37,7 @@ import androidx.annotation.RequiresApi;
import androidx.core.widget.CompoundButtonCompat;
import androidx.recyclerview.widget.RecyclerView;
+import com.android.internal.annotations.VisibleForTesting;
import com.android.settingslib.media.LocalMediaManager.MediaDeviceState;
import com.android.settingslib.media.MediaDevice;
import com.android.systemui.R;
@@ -482,6 +483,14 @@ public class MediaOutputAdapter extends MediaOutputBaseAdapter {
}
private void onItemClick(View view, MediaDevice device) {
+ if (mController.isCurrentOutputDeviceHasSessionOngoing()) {
+ showCustomEndSessionDialog(device);
+ } else {
+ transferOutput(device);
+ }
+ }
+
+ private void transferOutput(MediaDevice device) {
if (mController.isAnyDeviceTransferring()) {
return;
}
@@ -496,6 +505,14 @@ public class MediaOutputAdapter extends MediaOutputBaseAdapter {
notifyDataSetChanged();
}
+ @VisibleForTesting
+ void showCustomEndSessionDialog(MediaDevice device) {
+ MediaSessionReleaseDialog mediaSessionReleaseDialog = new MediaSessionReleaseDialog(
+ mContext, () -> transferOutput(device), mController.getColorButtonBackground(),
+ mController.getColorItemContent());
+ mediaSessionReleaseDialog.show();
+ }
+
private void cancelMuteAwaitConnection() {
mController.cancelMuteAwaitConnection();
notifyDataSetChanged();
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 8e014c61c641..822644b8e573 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java
@@ -783,6 +783,12 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback,
currentConnectedMediaDevice);
}
+ boolean isCurrentOutputDeviceHasSessionOngoing() {
+ MediaDevice currentConnectedMediaDevice = getCurrentConnectedMediaDevice();
+ return currentConnectedMediaDevice != null
+ && (currentConnectedMediaDevice.isHostForOngoingSession());
+ }
+
public boolean isAdvancedLayoutSupported() {
return mFeatureFlags.isEnabled(Flags.OUTPUT_SWITCHER_ADVANCED_LAYOUT);
}
diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaSessionReleaseDialog.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaSessionReleaseDialog.java
new file mode 100644
index 000000000000..2680a2ff4567
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaSessionReleaseDialog.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2023 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.content.res.ColorStateList;
+import android.graphics.ColorFilter;
+import android.graphics.PorterDuff;
+import android.graphics.PorterDuffColorFilter;
+import android.os.Bundle;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.Window;
+import android.view.WindowManager;
+import android.widget.Button;
+import android.widget.ImageView;
+
+import com.android.systemui.R;
+import com.android.systemui.statusbar.phone.SystemUIDialog;
+
+/**
+ * Confirmation dialog for releasing media session
+ */
+
+public class MediaSessionReleaseDialog extends SystemUIDialog {
+
+ private View mDialogView;
+
+ private final Context mContext;
+ private final View.OnClickListener mPositiveButtonListener;
+ private final ColorFilter mButtonColorFilter;
+ private final int mIconColor;
+
+ public MediaSessionReleaseDialog(Context context, Runnable runnable, int buttonColor,
+ int iconColor) {
+ super(context, R.style.Theme_SystemUI_Dialog_Media);
+ mContext = getContext();
+ mPositiveButtonListener = (v) -> {
+ runnable.run();
+ dismiss();
+ };
+ mButtonColorFilter = new PorterDuffColorFilter(
+ buttonColor,
+ PorterDuff.Mode.SRC_IN);
+ mIconColor = iconColor;
+ }
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ mDialogView = LayoutInflater.from(mContext).inflate(R.layout.media_session_end_dialog,
+ null);
+ final Window window = getWindow();
+ window.setType(WindowManager.LayoutParams.TYPE_STATUS_BAR_SUB_PANEL);
+ window.setContentView(mDialogView);
+
+ final WindowManager.LayoutParams lp = window.getAttributes();
+ lp.gravity = Gravity.CENTER;
+ lp.width = (int) (mContext.getResources().getDisplayMetrics().widthPixels * 0.90);
+
+ ImageView headerIcon = mDialogView.requireViewById(R.id.end_icon);
+ headerIcon.setImageDrawable(mContext.getDrawable(R.drawable.media_output_status_failed));
+ headerIcon.setImageTintList(
+ ColorStateList.valueOf(mIconColor));
+
+ Button stopButton = mDialogView.requireViewById(R.id.stop_button);
+ stopButton.setOnClickListener(mPositiveButtonListener);
+ stopButton.getBackground().setColorFilter(mButtonColorFilter);
+
+ Button cancelButton = mDialogView.requireViewById(R.id.cancel_button);
+ cancelButton.setOnClickListener((v) -> dismiss());
+ cancelButton.getBackground().setColorFilter(mButtonColorFilter);
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputAdapterTest.java b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputAdapterTest.java
index 7f7952feb10b..17d2f7bedf30 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputAdapterTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputAdapterTest.java
@@ -26,6 +26,7 @@ import static com.android.settingslib.media.MediaDevice.SelectionBehavior.SELECT
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -34,6 +35,7 @@ import android.app.WallpaperColors;
import android.graphics.Bitmap;
import android.graphics.drawable.Icon;
import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.SeekBar;
@@ -60,6 +62,7 @@ import java.util.stream.Collectors;
@SmallTest
@RunWith(AndroidTestingRunner.class)
+@TestableLooper.RunWithLooper(setAsMainLooper = true)
public class MediaOutputAdapterTest extends SysuiTestCase {
private static final String TEST_DEVICE_NAME_1 = "test_device_name_1";
@@ -613,6 +616,7 @@ public class MediaOutputAdapterTest extends SysuiTestCase {
@Test
public void onItemClick_clickDevice_verifyConnectDevice() {
+ when(mMediaOutputController.isCurrentOutputDeviceHasSessionOngoing()).thenReturn(false);
assertThat(mMediaDevice2.getState()).isEqualTo(
LocalMediaManager.MediaDeviceState.STATE_DISCONNECTED);
mMediaOutputAdapter.onBindViewHolder(mViewHolder, 0);
@@ -623,6 +627,21 @@ public class MediaOutputAdapterTest extends SysuiTestCase {
}
@Test
+ public void onItemClick_clickDeviceWithSessionOngoing_verifyShowsDialog() {
+ when(mMediaOutputController.isCurrentOutputDeviceHasSessionOngoing()).thenReturn(true);
+ assertThat(mMediaDevice2.getState()).isEqualTo(
+ LocalMediaManager.MediaDeviceState.STATE_DISCONNECTED);
+ MediaOutputAdapter.MediaDeviceViewHolder spyMediaDeviceViewHolder = spy(mViewHolder);
+
+ mMediaOutputAdapter.onBindViewHolder(spyMediaDeviceViewHolder, 0);
+ mMediaOutputAdapter.onBindViewHolder(spyMediaDeviceViewHolder, 1);
+ spyMediaDeviceViewHolder.mContainerLayout.performClick();
+
+ verify(mMediaOutputController, never()).connectDevice(mMediaDevice2);
+ verify(spyMediaDeviceViewHolder).showCustomEndSessionDialog(mMediaDevice2);
+ }
+
+ @Test
public void onItemClick_clicksWithMutingExpectedDeviceExist_cancelsMuteAwaitConnection() {
when(mMediaOutputController.isAnyDeviceTransferring()).thenReturn(false);
when(mMediaOutputController.hasMutingExpectedDevice()).thenReturn(true);