Show the output switcher when no media is playing
- Support output switcher for system routing.
- Add an new string to indicate the device that
audio will output to.
Bug: 284227163
Test: device/host atest
atest MediaOutputPreferenceControllerTest
atest AudioOutputSwitchPreferenceControllerTest
atest MediaOutputIndicatorSliceTest
Change-Id: I94bcf84e7e93b3e4f5db1d95d5380a54a3e0c460
Signed-off-by: Jasmine Cha <chajasmine@google.com>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 7998c1e..6ed0d82 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -10927,6 +10927,9 @@
<!-- Title with application label for media output settings. [CHAR LIMIT=NONE] -->
<string name="media_output_label_title">Play <xliff:g id="label" example="Music Player">%s</xliff:g> on</string>
+ <!-- Title for media output settings without media is playing -->
+ <string name="media_output_title_without_playing">Audio will play on</string>
+
<!-- Summary for media output default settings. (this device) [CHAR LIMIT=30] -->
<string name="media_output_default_summary">This device</string>
diff --git a/src/com/android/settings/media/MediaOutputIndicatorSlice.java b/src/com/android/settings/media/MediaOutputIndicatorSlice.java
index e2232e7..bb075c2 100644
--- a/src/com/android/settings/media/MediaOutputIndicatorSlice.java
+++ b/src/com/android/settings/media/MediaOutputIndicatorSlice.java
@@ -17,6 +17,7 @@
package com.android.settings.media;
import static com.android.settings.slices.CustomSliceRegistry.MEDIA_OUTPUT_INDICATOR_SLICE_URI;
+import static com.android.settingslib.media.flags.Flags.enableOutputSwitcherForSystemRouting;
import android.annotation.ColorInt;
import android.content.Context;
@@ -58,7 +59,12 @@
}
final IconCompat icon = IconCompat.createWithResource(mContext,
com.android.internal.R.drawable.ic_settings_bluetooth);
- final CharSequence title = mContext.getString(R.string.media_output_label_title,
+ final int stringRes = enableOutputSwitcherForSystemRouting()
+ ? (getWorker().getActiveLocalMediaController() != null
+ ? R.string.media_output_label_title
+ : R.string.media_output_title_without_playing)
+ : R.string.media_output_label_title;
+ final CharSequence title = mContext.getString(stringRes,
Utils.getApplicationLabel(mContext, getWorker().getPackageName()));
final SliceAction primarySliceAction = SliceAction.create(
getBroadcastIntent(mContext), icon, ListBuilder.ICON_IMAGE, title);
@@ -117,28 +123,36 @@
// 2. worker is not null
// 3. Available devices are more than 0
// 4. The local media session is active and the state is playing.
+ // - if !enableOutputSwitcherForSystemRouting(), (4) will be bypass.
return getWorker() != null
&& !com.android.settingslib.Utils.isAudioModeOngoingCall(mContext)
&& getWorker().getMediaDevices().size() > 0
- && getWorker().getActiveLocalMediaController() != null;
+ && (enableOutputSwitcherForSystemRouting()
+ ? true : getWorker().getActiveLocalMediaController() != null);
}
@Override
public void onNotifyChange(Intent intent) {
final MediaController mediaController = getWorker().getActiveLocalMediaController();
- if (mediaController == null) {
+ // Launch media output dialog
+ if (enableOutputSwitcherForSystemRouting() && mediaController == null) {
+ mContext.sendBroadcast(new Intent()
+ .setPackage(MediaOutputConstants.SYSTEMUI_PACKAGE_NAME)
+ .setAction(MediaOutputConstants.ACTION_LAUNCH_SYSTEM_MEDIA_OUTPUT_DIALOG));
+ } else if (mediaController != null) {
+ mContext.sendBroadcast(new Intent()
+ .setPackage(MediaOutputConstants.SYSTEMUI_PACKAGE_NAME)
+ .setAction(MediaOutputConstants.ACTION_LAUNCH_MEDIA_OUTPUT_DIALOG)
+ .putExtra(MediaOutputConstants.KEY_MEDIA_SESSION_TOKEN,
+ mediaController.getSessionToken())
+ .putExtra(MediaOutputConstants.EXTRA_PACKAGE_NAME,
+ mediaController.getPackageName()));
+ } else {
Log.d(TAG, "No active local media controller");
return;
}
- // Launch media output dialog
- mContext.sendBroadcast(new Intent()
- .setPackage(MediaOutputConstants.SYSTEMUI_PACKAGE_NAME)
- .setAction(MediaOutputConstants.ACTION_LAUNCH_MEDIA_OUTPUT_DIALOG)
- .putExtra(MediaOutputConstants.KEY_MEDIA_SESSION_TOKEN,
- mediaController.getSessionToken())
- .putExtra(MediaOutputConstants.EXTRA_PACKAGE_NAME,
- mediaController.getPackageName()));
+
// Dismiss volume panel
mContext.sendBroadcast(new Intent()
.setPackage(MediaOutputConstants.SETTINGS_PACKAGE_NAME)
diff --git a/src/com/android/settings/sound/AudioSwitchPreferenceController.java b/src/com/android/settings/sound/AudioSwitchPreferenceController.java
index 6475257..b570b2d 100644
--- a/src/com/android/settings/sound/AudioSwitchPreferenceController.java
+++ b/src/com/android/settings/sound/AudioSwitchPreferenceController.java
@@ -18,6 +18,9 @@
import static android.media.AudioManager.STREAM_DEVICES_CHANGED_ACTION;
+import static com.android.settingslib.media.flags.Flags.enableOutputSwitcherForSystemRouting;
+
+import android.annotation.Nullable;
import android.bluetooth.BluetoothDevice;
import android.content.BroadcastReceiver;
import android.content.Context;
@@ -28,6 +31,8 @@
import android.media.AudioDeviceInfo;
import android.media.AudioManager;
import android.media.MediaRouter;
+import android.media.session.MediaController;
+import android.media.session.MediaSessionManager;
import android.os.Handler;
import android.os.Looper;
import android.util.FeatureFlagUtils;
@@ -79,6 +84,8 @@
private final WiredHeadsetBroadcastReceiver mReceiver;
private final Handler mHandler;
private LocalBluetoothManager mLocalBluetoothManager;
+ @Nullable private MediaSessionManager.OnActiveSessionsChangedListener mSessionListener;
+ @Nullable private MediaSessionManager mMediaSessionManager;
public interface AudioSwitchCallback {
void onPreferenceDataChanged(ListPreference preference);
@@ -107,6 +114,14 @@
return;
}
mProfileManager = mLocalBluetoothManager.getProfileManager();
+
+ if (enableOutputSwitcherForSystemRouting()) {
+ mMediaSessionManager = context.getSystemService(MediaSessionManager.class);
+ mSessionListener = new SessionChangeListener();
+ } else {
+ mMediaSessionManager = null;
+ mSessionListener = null;
+ }
}
/**
@@ -329,13 +344,27 @@
// Register for misc other intent broadcasts.
IntentFilter intentFilter = new IntentFilter(Intent.ACTION_HEADSET_PLUG);
intentFilter.addAction(STREAM_DEVICES_CHANGED_ACTION);
- mContext.registerReceiver(mReceiver, intentFilter);
+
+ if (enableOutputSwitcherForSystemRouting()) {
+ mContext.registerReceiver(mReceiver, intentFilter, Context.RECEIVER_NOT_EXPORTED);
+ if (mMediaSessionManager != null) {
+ mMediaSessionManager.addOnActiveSessionsChangedListener(
+ mSessionListener, null, mHandler);
+ }
+ } else {
+ mContext.registerReceiver(mReceiver, intentFilter);
+ }
}
private void unregister() {
mLocalBluetoothManager.getEventManager().unregisterCallback(this);
mAudioManager.unregisterAudioDeviceCallback(mAudioManagerAudioDeviceCallback);
mContext.unregisterReceiver(mReceiver);
+ if (enableOutputSwitcherForSystemRouting()) {
+ if (mMediaSessionManager != null) {
+ mMediaSessionManager.removeOnActiveSessionsChangedListener(mSessionListener);
+ }
+ }
}
/** Notifications of audio device connection and disconnection events. */
@@ -362,4 +391,12 @@
}
}
}
+
+ private class SessionChangeListener
+ implements MediaSessionManager.OnActiveSessionsChangedListener {
+ @Override
+ public void onActiveSessionsChanged(List<MediaController> controllers) {
+ updateState(mPreference);
+ }
+ }
}
diff --git a/src/com/android/settings/sound/MediaOutputPreferenceController.java b/src/com/android/settings/sound/MediaOutputPreferenceController.java
index 758f7e3..47be7fe 100644
--- a/src/com/android/settings/sound/MediaOutputPreferenceController.java
+++ b/src/com/android/settings/sound/MediaOutputPreferenceController.java
@@ -16,6 +16,9 @@
package com.android.settings.sound;
+import static com.android.settingslib.media.flags.Flags.enableOutputSwitcherForSystemRouting;
+
+import android.annotation.Nullable;
import android.bluetooth.BluetoothDevice;
import android.content.Context;
import android.content.Intent;
@@ -46,21 +49,22 @@
*/
public class MediaOutputPreferenceController extends AudioSwitchPreferenceController {
- private MediaController mMediaController;
+ private static final String TAG = "MediaOutputPreferenceController";
+ @Nullable private MediaController mMediaController;
+ private MediaSessionManager mMediaSessionManager;
public MediaOutputPreferenceController(Context context, String key) {
super(context, key);
- mMediaController = MediaOutputUtils.getActiveLocalMediaController(context.getSystemService(
- MediaSessionManager.class));
+ mMediaSessionManager = context.getSystemService(MediaSessionManager.class);
+ mMediaController = MediaOutputUtils.getActiveLocalMediaController(mMediaSessionManager);
}
@Override
public void displayPreference(PreferenceScreen screen) {
super.displayPreference(screen);
- if (!Utils.isAudioModeOngoingCall(mContext) && mMediaController != null) {
- mPreference.setVisible(true);
- }
+ mPreference.setVisible(!Utils.isAudioModeOngoingCall(mContext)
+ && (enableOutputSwitcherForSystemRouting() ? true : mMediaController != null));
}
@Override
@@ -70,11 +74,16 @@
return;
}
- if (mMediaController == null) {
- // No active local playback
- return;
+ if (enableOutputSwitcherForSystemRouting()) {
+ mMediaController = MediaOutputUtils.getActiveLocalMediaController(mMediaSessionManager);
+ } else {
+ if (mMediaController == null) {
+ // No active local playback
+ return;
+ }
}
+
if (Utils.isAudioModeOngoingCall(mContext)) {
// Ongoing call status, switch entry for media will be disabled.
mPreference.setVisible(false);
@@ -95,9 +104,14 @@
|| (connectedLeAudioDevices != null && !connectedLeAudioDevices.isEmpty()))) {
activeDevice = findActiveDevice();
}
- mPreference.setTitle(mContext.getString(R.string.media_output_label_title,
- com.android.settings.Utils.getApplicationLabel(mContext,
- mMediaController.getPackageName())));
+
+ if (mMediaController == null) {
+ mPreference.setTitle(mContext.getString(R.string.media_output_title_without_playing));
+ } else {
+ mPreference.setTitle(mContext.getString(R.string.media_output_label_title,
+ com.android.settings.Utils.getApplicationLabel(mContext,
+ mMediaController.getPackageName())));
+ }
mPreference.setSummary((activeDevice == null) ?
mContext.getText(R.string.media_output_default_summary) :
activeDevice.getAlias());
@@ -145,13 +159,19 @@
@Override
public boolean handlePreferenceTreeClick(Preference preference) {
if (TextUtils.equals(preference.getKey(), getPreferenceKey())) {
- mContext.sendBroadcast(new Intent()
- .setAction(MediaOutputConstants.ACTION_LAUNCH_MEDIA_OUTPUT_DIALOG)
- .setPackage(MediaOutputConstants.SYSTEMUI_PACKAGE_NAME)
- .putExtra(MediaOutputConstants.EXTRA_PACKAGE_NAME,
- mMediaController.getPackageName())
- .putExtra(MediaOutputConstants.KEY_MEDIA_SESSION_TOKEN,
- mMediaController.getSessionToken()));
+ if (enableOutputSwitcherForSystemRouting() && mMediaController == null) {
+ mContext.sendBroadcast(new Intent()
+ .setAction(MediaOutputConstants.ACTION_LAUNCH_SYSTEM_MEDIA_OUTPUT_DIALOG)
+ .setPackage(MediaOutputConstants.SYSTEMUI_PACKAGE_NAME));
+ } else if (mMediaController != null) {
+ mContext.sendBroadcast(new Intent()
+ .setAction(MediaOutputConstants.ACTION_LAUNCH_MEDIA_OUTPUT_DIALOG)
+ .setPackage(MediaOutputConstants.SYSTEMUI_PACKAGE_NAME)
+ .putExtra(MediaOutputConstants.EXTRA_PACKAGE_NAME,
+ mMediaController.getPackageName())
+ .putExtra(MediaOutputConstants.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 a91f627..652bd03 100644
--- a/tests/robotests/src/com/android/settings/media/MediaOutputIndicatorSliceTest.java
+++ b/tests/robotests/src/com/android/settings/media/MediaOutputIndicatorSliceTest.java
@@ -18,6 +18,7 @@
package com.android.settings.media;
import static com.android.settings.slices.CustomSliceRegistry.MEDIA_OUTPUT_INDICATOR_SLICE_URI;
+import static com.android.settingslib.media.flags.Flags.FLAG_ENABLE_OUTPUT_SWITCHER_FOR_SYSTEM_ROUTING;
import static com.google.common.truth.Truth.assertThat;
@@ -38,6 +39,7 @@
import android.media.session.MediaSession;
import android.net.Uri;
import android.os.Process;
+import android.platform.test.flag.junit.SetFlagsRule;
import android.text.TextUtils;
import androidx.slice.Slice;
@@ -55,6 +57,7 @@
import org.junit.Before;
import org.junit.Ignore;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
@@ -96,6 +99,9 @@
@Mock
private Drawable mTestDrawable;
+ @Rule
+ public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
+
private Context mContext;
private MediaOutputIndicatorSlice mMediaOutputIndicatorSlice;
private AudioManager mAudioManager;
@@ -255,6 +261,34 @@
}
@Test
+ public void onNotifyChange_withoutMediaControllerFlagEnabled_verifyIntentExtra() {
+ mSetFlagsRule.enableFlags(FLAG_ENABLE_OUTPUT_SWITCHER_FOR_SYSTEM_ROUTING);
+ doReturn(null).when(sMediaOutputIndicatorWorker)
+ .getActiveLocalMediaController();
+ ArgumentCaptor<Intent> argument = ArgumentCaptor.forClass(Intent.class);
+
+ mMediaOutputIndicatorSlice.onNotifyChange(null);
+ verify(mContext, times(2)).sendBroadcast(argument.capture());
+ List<Intent> intentList = argument.getAllValues();
+ Intent intent = intentList.get(0);
+
+ assertThat(intent.getAction()).isEqualTo(
+ MediaOutputConstants.ACTION_LAUNCH_SYSTEM_MEDIA_OUTPUT_DIALOG);
+ assertThat(TextUtils.equals(MediaOutputConstants.SYSTEMUI_PACKAGE_NAME,
+ intent.getPackage())).isTrue();
+ }
+
+ @Test
+ public void onNotifyChange_withoutMediaControllerFlagDisabled_doNothing() {
+ mSetFlagsRule.disableFlags(FLAG_ENABLE_OUTPUT_SWITCHER_FOR_SYSTEM_ROUTING);
+ doReturn(null).when(sMediaOutputIndicatorWorker)
+ .getActiveLocalMediaController();
+
+ mMediaOutputIndicatorSlice.onNotifyChange(null);
+ }
+
+
+ @Test
public void isVisible_allConditionMatched_returnTrue() {
mAudioManager.setMode(AudioManager.MODE_NORMAL);
mDevices.add(mDevice1);
@@ -268,6 +302,7 @@
@Test
public void isVisible_noActiveSession_returnFalse() {
+ mSetFlagsRule.disableFlags(FLAG_ENABLE_OUTPUT_SWITCHER_FOR_SYSTEM_ROUTING);
mAudioManager.setMode(AudioManager.MODE_NORMAL);
mDevices.add(mDevice1);
@@ -278,6 +313,19 @@
assertThat(mMediaOutputIndicatorSlice.isVisible()).isFalse();
}
+ @Test
+ public void isVisible_noActiveSession_returnTrue() {
+ mSetFlagsRule.enableFlags(FLAG_ENABLE_OUTPUT_SWITCHER_FOR_SYSTEM_ROUTING);
+ mAudioManager.setMode(AudioManager.MODE_NORMAL);
+ mDevices.add(mDevice1);
+
+ when(sMediaOutputIndicatorWorker.getMediaDevices()).thenReturn(mDevices);
+ doReturn(mMediaController).when(sMediaOutputIndicatorWorker)
+ .getActiveLocalMediaController();
+
+ assertThat(mMediaOutputIndicatorSlice.isVisible()).isTrue();
+ }
+
private void initPackage() {
mShadowPackageManager = Shadows.shadowOf(mContext.getPackageManager());
mAppInfo = new ApplicationInfo();
diff --git a/tests/robotests/src/com/android/settings/sound/AudioOutputSwitchPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/sound/AudioOutputSwitchPreferenceControllerTest.java
index 151d1f2..a272d9c 100644
--- a/tests/robotests/src/com/android/settings/sound/AudioOutputSwitchPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/sound/AudioOutputSwitchPreferenceControllerTest.java
@@ -21,10 +21,12 @@
import static com.android.settings.core.BasePreferenceController.AVAILABLE;
import static com.android.settings.core.BasePreferenceController.CONDITIONALLY_UNAVAILABLE;
+import static com.android.settingslib.media.flags.Flags.FLAG_ENABLE_OUTPUT_SWITCHER_FOR_SYSTEM_ROUTING;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
@@ -38,6 +40,8 @@
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.media.AudioManager;
+import android.media.session.MediaSessionManager;
+import android.platform.test.flag.junit.SetFlagsRule;
import android.util.FeatureFlagUtils;
import androidx.preference.ListPreference;
@@ -61,6 +65,7 @@
import org.junit.After;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
@@ -113,6 +118,9 @@
@Mock
private CachedBluetoothDevice mCachedBluetoothDeviceR;
+ @Rule
+ public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
+
private Context mContext;
private PreferenceScreen mScreen;
private ListPreference mPreference;
@@ -238,6 +246,7 @@
@Test
public void onStart_shouldRegisterCallbackAndRegisterReceiver() {
+ mSetFlagsRule.disableFlags(FLAG_ENABLE_OUTPUT_SWITCHER_FOR_SYSTEM_ROUTING);
mController.onStart();
verify(mLocalBluetoothManager.getEventManager()).registerCallback(
@@ -248,6 +257,7 @@
@Test
public void onStop_shouldUnregisterCallbackAndUnregisterReceiver() {
+ mSetFlagsRule.disableFlags(FLAG_ENABLE_OUTPUT_SWITCHER_FOR_SYSTEM_ROUTING);
mController.onStart();
mController.onStop();
@@ -257,6 +267,45 @@
verify(mLocalBluetoothManager).setForegroundActivity(null);
}
+ @Test
+ public void onStart_shouldRegisterCallbackAndRegisterReceiverWithDefaultMediaOutput() {
+ MediaSessionManager mediaSessionManager =
+ spy(mContext.getSystemService(MediaSessionManager.class));
+ mSetFlagsRule.enableFlags(FLAG_ENABLE_OUTPUT_SWITCHER_FOR_SYSTEM_ROUTING);
+ when(mContext.getSystemService(MediaSessionManager.class)).thenReturn(mediaSessionManager);
+ mController = new AudioSwitchPreferenceControllerTestable(mContext, TEST_KEY);
+
+ mController.onStart();
+
+ verify(mLocalBluetoothManager.getEventManager()).registerCallback(
+ any(BluetoothCallback.class));
+ verify(mContext).registerReceiver(any(BroadcastReceiver.class), any(IntentFilter.class),
+ eq(Context.RECEIVER_NOT_EXPORTED));
+ verify(mLocalBluetoothManager).setForegroundActivity(mContext);
+ verify(mediaSessionManager).addOnActiveSessionsChangedListener(
+ any(MediaSessionManager.OnActiveSessionsChangedListener.class), any(), any());
+ }
+
+
+ @Test
+ public void onStop_shouldUnregisterCallbackAndUnregisterReceiverWithDefaultMediaOutput() {
+ MediaSessionManager mediaSessionManager =
+ spy(mContext.getSystemService(MediaSessionManager.class));
+ mSetFlagsRule.enableFlags(FLAG_ENABLE_OUTPUT_SWITCHER_FOR_SYSTEM_ROUTING);
+ when(mContext.getSystemService(MediaSessionManager.class)).thenReturn(mediaSessionManager);
+ mController = new AudioSwitchPreferenceControllerTestable(mContext, TEST_KEY);
+ mController.onStart();
+
+ mController.onStop();
+
+ verify(mLocalBluetoothManager.getEventManager()).unregisterCallback(
+ any(BluetoothCallback.class));
+ verify(mContext).unregisterReceiver(any(BroadcastReceiver.class));
+ verify(mLocalBluetoothManager).setForegroundActivity(null);
+ verify(mediaSessionManager).removeOnActiveSessionsChangedListener(
+ any(MediaSessionManager.OnActiveSessionsChangedListener.class));
+ }
+
/**
* Audio stream output to bluetooth sco headset which is the subset of all sco device.
* isStreamFromOutputDevice should return true.
diff --git a/tests/robotests/src/com/android/settings/sound/MediaOutputPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/sound/MediaOutputPreferenceControllerTest.java
index 5a92a08..b9f9b16 100644
--- a/tests/robotests/src/com/android/settings/sound/MediaOutputPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/sound/MediaOutputPreferenceControllerTest.java
@@ -21,6 +21,8 @@
import static android.media.AudioSystem.DEVICE_OUT_EARPIECE;
import static android.media.AudioSystem.DEVICE_OUT_HEARING_AID;
+import static com.android.settingslib.media.flags.Flags.FLAG_ENABLE_OUTPUT_SWITCHER_FOR_SYSTEM_ROUTING;
+
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
@@ -45,6 +47,7 @@
import android.media.session.MediaController;
import android.media.session.MediaSessionManager;
import android.media.session.PlaybackState;
+import android.platform.test.flag.junit.SetFlagsRule;
import androidx.preference.Preference;
import androidx.preference.PreferenceManager;
@@ -66,6 +69,7 @@
import org.junit.After;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
@@ -103,6 +107,9 @@
private static final String TEST_PACKAGE_NAME = "com.test.packagename";
private static final String TEST_APPLICATION_LABEL = "APP Test Label";
+ @Rule
+ public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
+
@Mock
private LocalBluetoothManager mLocalManager;
@Mock
@@ -227,6 +234,8 @@
mScreen.addPreference(mPreference);
mController.displayPreference(mScreen);
mController.setCallback(mAudioSwitchPreferenceCallback);
+
+ mSetFlagsRule.initAllFlagsToReleaseConfigDefault();
}
@After
@@ -314,6 +323,7 @@
@Test
public void updateState_noActiveLocalPlayback_noTitle() {
+ mSetFlagsRule.disableFlags(FLAG_ENABLE_OUTPUT_SWITCHER_FOR_SYSTEM_ROUTING);
mPlaybackState = new PlaybackState.Builder()
.setState(PlaybackState.STATE_NONE, 0, 1)
.build();
@@ -326,6 +336,48 @@
}
@Test
+ public void updateState_noActiveLocalPlayback_checkTitle() {
+ mSetFlagsRule.enableFlags(FLAG_ENABLE_OUTPUT_SWITCHER_FOR_SYSTEM_ROUTING);
+ mPlaybackState = new PlaybackState.Builder()
+ .setState(PlaybackState.STATE_NONE, 0, 1)
+ .build();
+ when(mMediaController.getPlaybackState()).thenReturn(mPlaybackState);
+ mController = new MediaOutputPreferenceController(mContext, TEST_KEY);
+ mController.displayPreference(mScreen);
+
+ mController.updateState(mPreference);
+
+ assertThat(mPreference.getTitle().toString()).isEqualTo(
+ mContext.getString(R.string.media_output_title_without_playing,
+ TEST_APPLICATION_LABEL));
+ }
+
+ @Test
+ public void updateState_withNullMediaController_noTitle() {
+ mSetFlagsRule.disableFlags(FLAG_ENABLE_OUTPUT_SWITCHER_FOR_SYSTEM_ROUTING);
+ mMediaControllers.clear();
+ mController = new MediaOutputPreferenceController(mContext, TEST_KEY);
+
+ mController.updateState(mPreference);
+
+ assertThat(mPreference.getTitle()).isNull();
+ }
+
+ @Test
+ public void updateState_withNullMediaController_checkTitle() {
+ mSetFlagsRule.enableFlags(FLAG_ENABLE_OUTPUT_SWITCHER_FOR_SYSTEM_ROUTING);
+ mMediaControllers.clear();
+ mController = new MediaOutputPreferenceController(mContext, TEST_KEY);
+ mController.displayPreference(mScreen);
+
+ mController.updateState(mPreference);
+
+ assertThat(mPreference.getTitle().toString()).isEqualTo(
+ mContext.getString(R.string.media_output_title_without_playing,
+ TEST_APPLICATION_LABEL));
+ }
+
+ @Test
public void updateState_withActiveLocalPlayback_checkTitle() {
initPackage();
mShadowPackageManager.addPackage(mPackageInfo, mPackageStats);
@@ -349,6 +401,39 @@
.isEqualTo(MediaOutputConstants.ACTION_LAUNCH_MEDIA_OUTPUT_DIALOG);
}
+ @Test
+ public void handlePreferenceTreeClick_WithNoLocalPlaybackFlagEnabled_verifyIntentExtra() {
+ mSetFlagsRule.enableFlags(FLAG_ENABLE_OUTPUT_SWITCHER_FOR_SYSTEM_ROUTING);
+ final ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
+ mPlaybackState = new PlaybackState.Builder()
+ .setState(PlaybackState.STATE_NONE, 0, 1)
+ .build();
+ when(mMediaController.getPlaybackState()).thenReturn(mPlaybackState);
+ mController = new MediaOutputPreferenceController(mContext, TEST_KEY);
+ mPreference.setKey(TEST_KEY);
+
+ mController.handlePreferenceTreeClick(mPreference);
+
+ verify(mContext).sendBroadcast(intentCaptor.capture());
+ assertThat(intentCaptor.getValue().getAction())
+ .isEqualTo(MediaOutputConstants.ACTION_LAUNCH_SYSTEM_MEDIA_OUTPUT_DIALOG);
+ }
+
+ @Test
+ public void handlePreferenceTreeClick_WithNullControllerFlagEnabled_verifyIntentExtra() {
+ mSetFlagsRule.enableFlags(FLAG_ENABLE_OUTPUT_SWITCHER_FOR_SYSTEM_ROUTING);
+ final ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
+ mMediaControllers.clear();
+ mController = new MediaOutputPreferenceController(mContext, TEST_KEY);
+ mPreference.setKey(TEST_KEY);
+
+ mController.handlePreferenceTreeClick(mPreference);
+
+ verify(mContext).sendBroadcast(intentCaptor.capture());
+ assertThat(intentCaptor.getValue().getAction())
+ .isEqualTo(MediaOutputConstants.ACTION_LAUNCH_SYSTEM_MEDIA_OUTPUT_DIALOG);
+ }
+
/**
* Default status
* Preference should be invisible