Update OutputSwitcher from MediaOutputSlice to MediaOutputDialog in Settings

-Update entry point at media indicator in volume panel
-Update entry point at remote media slice in volume panel
-Update entry point at remote volume group in Sound Settings
-Update entry point at media output preference in Sound Settings
-Hide Media output dialog when the caller is not active

Bug: 155822415
Test: make -j50 RunSettingsRoboTests
Merged-In: Ib6c86067522925c439f336644e4d027dbae3379c
Change-Id: Ib6c86067522925c439f336644e4d027dbae3379c
diff --git a/src/com/android/settings/media/MediaOutputIndicatorSlice.java b/src/com/android/settings/media/MediaOutputIndicatorSlice.java
index 305c7df..401a0a6 100644
--- a/src/com/android/settings/media/MediaOutputIndicatorSlice.java
+++ b/src/com/android/settings/media/MediaOutputIndicatorSlice.java
@@ -66,11 +66,11 @@
         final int requestCode = TextUtils.isEmpty(getWorker().getPackageName())
                 ? 0
                 : getWorker().getPackageName().hashCode();
-        final PendingIntent primaryActionIntent = PendingIntent.getActivity(mContext,
-                requestCode,
-                getMediaOutputSliceIntent(), FLAG_UPDATE_CURRENT);
+        final PendingIntent primaryBroadcastIntent = PendingIntent.getBroadcast(mContext,
+                requestCode, getMediaOutputDialogIntent(), FLAG_UPDATE_CURRENT);
         final SliceAction primarySliceAction = SliceAction.createDeeplink(
-                primaryActionIntent, icon, ListBuilder.ICON_IMAGE, title);
+                primaryBroadcastIntent, icon, ListBuilder.ICON_IMAGE, title);
+
         @ColorInt final int color = Utils.getColorAccentDefaultColor(mContext);
         // To set an empty icon to indent the row
         final ListBuilder listBuilder = new ListBuilder(mContext, getUri(), ListBuilder.INFINITY)
@@ -84,12 +84,11 @@
     }
 
     @VisibleForTesting
-    Intent getMediaOutputSliceIntent() {
+    Intent getMediaOutputDialogIntent() {
         final MediaController mediaController = getWorker().getActiveLocalMediaController();
         final Intent intent = new Intent()
-                .setPackage(Utils.SETTINGS_PACKAGE_NAME)
-                .setAction(MediaOutputSliceConstants.ACTION_MEDIA_OUTPUT)
-                .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+                .setPackage(MediaOutputSliceConstants.SYSTEMUI_PACKAGE_NAME)
+                .setAction(MediaOutputSliceConstants.ACTION_LAUNCH_MEDIA_OUTPUT_DIALOG);
         if (mediaController != null) {
             intent.putExtra(MediaOutputSliceConstants.KEY_MEDIA_SESSION_TOKEN,
                     mediaController.getSessionToken());
diff --git a/src/com/android/settings/media/RemoteMediaSlice.java b/src/com/android/settings/media/RemoteMediaSlice.java
index 4198269..1ca33b1 100644
--- a/src/com/android/settings/media/RemoteMediaSlice.java
+++ b/src/com/android/settings/media/RemoteMediaSlice.java
@@ -133,8 +133,7 @@
                     .setTitle(isMediaOutputDisabled ? spannableTitle : outputTitle)
                     .setSubtitle(info.getName())
                     .setTitleItem(emptyIcon, ListBuilder.ICON_IMAGE)
-                    .setPrimaryAction(getMediaOutputSliceAction(
-                            info.getClientPackageName(), isMediaOutputDisabled)));
+                    .setPrimaryAction(getMediaOutputDialogAction(info, isMediaOutputDisabled)));
         }
         return listBuilder.build();
     }
@@ -167,23 +166,23 @@
         return primarySliceAction;
     }
 
-    private SliceAction getMediaOutputSliceAction(
-            String packageName, boolean isMediaOutputDisabled) {
+    private SliceAction getMediaOutputDialogAction(RoutingSessionInfo info,
+            boolean isMediaOutputDisabled) {
         final Intent intent = new Intent()
                 .setAction(isMediaOutputDisabled
-                        ? ""
-                        : MediaOutputSliceConstants.ACTION_MEDIA_OUTPUT)
-                .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
-                .putExtra(MediaOutputSliceConstants.EXTRA_PACKAGE_NAME, packageName);
+                        ? "" : MediaOutputSliceConstants.ACTION_LAUNCH_MEDIA_OUTPUT_DIALOG)
+                .setPackage(MediaOutputSliceConstants.SYSTEMUI_PACKAGE_NAME)
+                .putExtra(MediaOutputSliceConstants.EXTRA_PACKAGE_NAME,
+                        info.getClientPackageName());
         final IconCompat icon = IconCompat.createWithResource(mContext,
                 R.drawable.ic_volume_remote);
-        final int requestCode = TextUtils.isEmpty(packageName) ? 0 : packageName.hashCode();
-        final PendingIntent primaryActionIntent = PendingIntent.getActivity(mContext,
-                requestCode, intent, 0 /* flags */);
+
+        final PendingIntent primaryBroadcastIntent = PendingIntent.getBroadcast(mContext,
+                0 /* requestCode */, intent, 0 /* flags */);
         final SliceAction primarySliceAction = SliceAction.createDeeplink(
-                primaryActionIntent, icon, ListBuilder.ICON_IMAGE,
+                primaryBroadcastIntent, icon, ListBuilder.ICON_IMAGE,
                 mContext.getString(R.string.media_output_label_title,
-                        Utils.getApplicationLabel(mContext, packageName)));
+                        Utils.getApplicationLabel(mContext, info.getClientPackageName())));
         return primarySliceAction;
     }
 
diff --git a/src/com/android/settings/notification/RemoteVolumeGroupController.java b/src/com/android/settings/notification/RemoteVolumeGroupController.java
index bb62a56..4dd497f 100644
--- a/src/com/android/settings/notification/RemoteVolumeGroupController.java
+++ b/src/com/android/settings/notification/RemoteVolumeGroupController.java
@@ -32,6 +32,7 @@
 import com.android.settings.core.BasePreferenceController;
 import com.android.settingslib.core.lifecycle.LifecycleObserver;
 import com.android.settingslib.core.lifecycle.events.OnDestroy;
+import com.android.settingslib.core.lifecycle.events.OnPause;
 import com.android.settingslib.media.LocalMediaManager;
 import com.android.settingslib.media.MediaDevice;
 import com.android.settingslib.media.MediaOutputSliceConstants;
@@ -45,7 +46,7 @@
  * {@link com.android.settings.notification.RemoteVolumeSeekBarPreference}
  **/
 public class RemoteVolumeGroupController extends BasePreferenceController implements
-        Preference.OnPreferenceChangeListener, LifecycleObserver, OnDestroy,
+        Preference.OnPreferenceChangeListener, LifecycleObserver, OnDestroy, OnPause,
         LocalMediaManager.DeviceCallback {
 
     private static final String KEY_REMOTE_VOLUME_GROUP = "remote_media_group";
@@ -97,6 +98,14 @@
     }
 
     @Override
+    public void onPause() {
+        // Media output dialog should not show when onPause
+        mContext.sendBroadcast(new Intent()
+                .setAction(MediaOutputSliceConstants.ACTION_DISMISS_MEDIA_OUTPUT_DIALOG)
+                .setPackage(MediaOutputSliceConstants.SYSTEMUI_PACKAGE_NAME));
+    }
+
+    @Override
     public void onDestroy() {
         mLocalMediaManager.unregisterCallback(this);
         mLocalMediaManager.stopScan();
@@ -159,11 +168,11 @@
             if (TextUtils.equals(info.getId(),
                     preference.getKey().substring(SWITCHER_PREFIX.length()))) {
                 final Intent intent = new Intent()
-                        .setAction(MediaOutputSliceConstants.ACTION_MEDIA_OUTPUT)
-                        .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
+                        .setAction(MediaOutputSliceConstants.ACTION_LAUNCH_MEDIA_OUTPUT_DIALOG)
+                        .setPackage(MediaOutputSliceConstants.SYSTEMUI_PACKAGE_NAME)
                         .putExtra(MediaOutputSliceConstants.EXTRA_PACKAGE_NAME,
                                 info.getClientPackageName());
-                mContext.startActivity(intent);
+                mContext.sendBroadcast(intent);
                 return true;
             }
         }
diff --git a/src/com/android/settings/panel/VolumePanel.java b/src/com/android/settings/panel/VolumePanel.java
index d45bfd1..7c34a7c 100644
--- a/src/com/android/settings/panel/VolumePanel.java
+++ b/src/com/android/settings/panel/VolumePanel.java
@@ -16,6 +16,8 @@
 
 package com.android.settings.panel;
 
+import static androidx.lifecycle.Lifecycle.Event.ON_PAUSE;
+
 import static com.android.settings.slices.CustomSliceRegistry.MEDIA_OUTPUT_INDICATOR_SLICE_URI;
 import static com.android.settings.slices.CustomSliceRegistry.REMOTE_MEDIA_SLICE_URI;
 import static com.android.settings.slices.CustomSliceRegistry.VOLUME_ALARM_URI;
@@ -29,12 +31,19 @@
 import android.net.Uri;
 import android.provider.Settings;
 
+import androidx.lifecycle.LifecycleObserver;
+import androidx.lifecycle.OnLifecycleEvent;
+
 import com.android.settings.R;
+import com.android.settingslib.media.MediaOutputSliceConstants;
 
 import java.util.ArrayList;
 import java.util.List;
 
-public class VolumePanel implements PanelContent {
+/**
+ * Panel data class for Volume settings.
+ */
+public class VolumePanel implements PanelContent, LifecycleObserver {
 
     private final Context mContext;
 
@@ -46,6 +55,15 @@
         mContext = context.getApplicationContext();
     }
 
+    /** Invoked when the panel is paused. */
+    @OnLifecycleEvent(ON_PAUSE)
+    public void onPause() {
+        // Media output dialog should not show when onPause
+        mContext.sendBroadcast(new Intent()
+                .setAction(MediaOutputSliceConstants.ACTION_DISMISS_MEDIA_OUTPUT_DIALOG)
+                .setPackage(MediaOutputSliceConstants.SYSTEMUI_PACKAGE_NAME));
+    }
+
     @Override
     public CharSequence getTitle() {
         return mContext.getText(R.string.sound_settings);
diff --git a/src/com/android/settings/sound/MediaOutputPreferenceController.java b/src/com/android/settings/sound/MediaOutputPreferenceController.java
index da92b2b..914a9de 100644
--- a/src/com/android/settings/sound/MediaOutputPreferenceController.java
+++ b/src/com/android/settings/sound/MediaOutputPreferenceController.java
@@ -33,6 +33,8 @@
 import com.android.settingslib.Utils;
 import com.android.settingslib.bluetooth.A2dpProfile;
 import com.android.settingslib.bluetooth.HearingAidProfile;
+import com.android.settingslib.core.lifecycle.LifecycleObserver;
+import com.android.settingslib.core.lifecycle.events.OnStop;
 import com.android.settingslib.media.MediaOutputSliceConstants;
 
 import java.util.List;
@@ -45,7 +47,8 @@
  * - Media stream captured by remote device
  * - During a call.
  */
-public class MediaOutputPreferenceController extends AudioSwitchPreferenceController {
+public class MediaOutputPreferenceController extends AudioSwitchPreferenceController
+        implements LifecycleObserver, OnStop {
 
     private MediaController mMediaController;
 
@@ -64,6 +67,15 @@
     }
 
     @Override
+    public void onStop() {
+        super.onStop();
+        // Media output dialog should not show when onStop
+        mContext.sendBroadcast(new Intent()
+                .setAction(MediaOutputSliceConstants.ACTION_DISMISS_MEDIA_OUTPUT_DIALOG)
+                .setPackage(MediaOutputSliceConstants.SYSTEMUI_PACKAGE_NAME));
+    }
+
+    @Override
     public void updateState(Preference preference) {
         if (preference == null) {
             // In case UI is not ready.
@@ -133,10 +145,13 @@
     @Override
     public boolean handlePreferenceTreeClick(Preference preference) {
         if (TextUtils.equals(preference.getKey(), getPreferenceKey())) {
-            final Intent intent = new Intent()
-                    .setAction(MediaOutputSliceConstants.ACTION_MEDIA_OUTPUT)
-                    .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-            mContext.startActivity(intent);
+            mContext.sendBroadcast(new Intent()
+                    .setAction(MediaOutputSliceConstants.ACTION_LAUNCH_MEDIA_OUTPUT_DIALOG)
+                    .setPackage(MediaOutputSliceConstants.SYSTEMUI_PACKAGE_NAME)
+                    .putExtra(MediaOutputSliceConstants.EXTRA_PACKAGE_NAME,
+                            mMediaController.getPackageName())
+                    .putExtra(MediaOutputSliceConstants.KEY_MEDIA_SESSION_TOKEN,
+                            mMediaController.getSessionToken()));
             return true;
         }
         return false;
diff --git a/tests/robotests/src/com/android/settings/media/MediaOutputIndicatorSliceTest.java b/tests/robotests/src/com/android/settings/media/MediaOutputIndicatorSliceTest.java
index 28620e9..21ab883 100644
--- a/tests/robotests/src/com/android/settings/media/MediaOutputIndicatorSliceTest.java
+++ b/tests/robotests/src/com/android/settings/media/MediaOutputIndicatorSliceTest.java
@@ -208,12 +208,14 @@
         when(mMediaController.getPackageName()).thenReturn(TEST_PACKAGE_NAME);
         doReturn(mMediaController).when(sMediaOutputIndicatorWorker)
                 .getActiveLocalMediaController();
-        final Intent intent = mMediaOutputIndicatorSlice.getMediaOutputSliceIntent();
+        final Intent intent = mMediaOutputIndicatorSlice.getMediaOutputDialogIntent();
 
         assertThat(TextUtils.equals(TEST_PACKAGE_NAME, intent.getStringExtra(
                 MediaOutputSliceConstants.EXTRA_PACKAGE_NAME))).isTrue();
-        assertThat(MediaOutputSliceConstants.ACTION_MEDIA_OUTPUT).isEqualTo(intent.getAction());
-        assertThat(TextUtils.equals(Utils.SETTINGS_PACKAGE_NAME, intent.getPackage())).isTrue();
+        assertThat(MediaOutputSliceConstants.ACTION_LAUNCH_MEDIA_OUTPUT_DIALOG).isEqualTo(
+                intent.getAction());
+        assertThat(TextUtils.equals(MediaOutputSliceConstants.SYSTEMUI_PACKAGE_NAME,
+                intent.getPackage())).isTrue();
         assertThat(mToken == intent.getExtras().getParcelable(
                 MediaOutputSliceConstants.KEY_MEDIA_SESSION_TOKEN)).isTrue();
     }
@@ -222,12 +224,14 @@
     public void getMediaOutputSliceIntent_withoutActiveLocalMedia_verifyIntentExtra() {
         doReturn(mMediaController).when(sMediaOutputIndicatorWorker)
                 .getActiveLocalMediaController();
-        final Intent intent = mMediaOutputIndicatorSlice.getMediaOutputSliceIntent();
+        final Intent intent = mMediaOutputIndicatorSlice.getMediaOutputDialogIntent();
 
         assertThat(TextUtils.isEmpty(intent.getStringExtra(
                 MediaOutputSliceConstants.EXTRA_PACKAGE_NAME))).isTrue();
-        assertThat(MediaOutputSliceConstants.ACTION_MEDIA_OUTPUT).isEqualTo(intent.getAction());
-        assertThat(TextUtils.equals(Utils.SETTINGS_PACKAGE_NAME, intent.getPackage())).isTrue();
+        assertThat(MediaOutputSliceConstants.ACTION_LAUNCH_MEDIA_OUTPUT_DIALOG).isEqualTo(
+                intent.getAction());
+        assertThat(TextUtils.equals(MediaOutputSliceConstants.SYSTEMUI_PACKAGE_NAME,
+                intent.getPackage())).isTrue();
         assertThat(intent.getExtras().getParcelable(
                 MediaOutputSliceConstants.KEY_MEDIA_SESSION_TOKEN) == null).isTrue();
     }
diff --git a/tests/robotests/src/com/android/settings/sound/MediaOutputPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/sound/MediaOutputPreferenceControllerTest.java
index 49928db..9bee0a1 100644
--- a/tests/robotests/src/com/android/settings/sound/MediaOutputPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/sound/MediaOutputPreferenceControllerTest.java
@@ -299,9 +299,9 @@
 
         mPreference.setKey(TEST_KEY);
         mController.handlePreferenceTreeClick(mPreference);
-        verify(mContext).startActivity(intentCaptor.capture());
+        verify(mContext).sendBroadcast(intentCaptor.capture());
         assertThat(intentCaptor.getValue().getAction())
-                .isEqualTo(MediaOutputSliceConstants.ACTION_MEDIA_OUTPUT);
+                .isEqualTo(MediaOutputSliceConstants.ACTION_LAUNCH_MEDIA_OUTPUT_DIALOG);
     }
 
     /**