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>
This commit is contained in:
Jasmine Cha
2023-10-03 16:56:43 +08:00
parent 1340427763
commit 9e45469833
7 changed files with 287 additions and 31 deletions

View File

@@ -21,6 +21,8 @@ import static android.media.AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP;
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.VolumeProvider;
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 com.android.settingslib.media.MediaOutputConstants;
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 @@ public class MediaOutputPreferenceControllerTest {
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 @@ public class MediaOutputPreferenceControllerTest {
mScreen.addPreference(mPreference);
mController.displayPreference(mScreen);
mController.setCallback(mAudioSwitchPreferenceCallback);
mSetFlagsRule.initAllFlagsToReleaseConfigDefault();
}
@After
@@ -314,6 +323,7 @@ public class MediaOutputPreferenceControllerTest {
@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();
@@ -325,6 +335,48 @@ public class MediaOutputPreferenceControllerTest {
assertThat(mPreference.getTitle()).isNull();
}
@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();
@@ -349,6 +401,39 @@ public class MediaOutputPreferenceControllerTest {
.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