Merge "Update "Play media to" in Sound Settings" into rvc-dev am: 72948ab538
am: c56346d085
am: 8978d69743
Change-Id: I9c76e6a480cbd9ff41754aa52c7cac29210f33a5
This commit is contained in:
@@ -45,6 +45,7 @@
|
||||
android:title="@string/media_output_title"
|
||||
android:dialogTitle="@string/media_output_title"
|
||||
android:order="-175"
|
||||
settings:searchable="false"
|
||||
settings:controller="com.android.settings.sound.MediaOutputPreferenceController"/>
|
||||
|
||||
<!-- Call volume -->
|
||||
|
@@ -20,8 +20,12 @@ import android.bluetooth.BluetoothDevice;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.media.AudioManager;
|
||||
import android.media.session.MediaController;
|
||||
import android.media.session.MediaSessionManager;
|
||||
import android.media.session.PlaybackState;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.PreferenceScreen;
|
||||
|
||||
@@ -43,15 +47,18 @@ import java.util.List;
|
||||
*/
|
||||
public class MediaOutputPreferenceController extends AudioSwitchPreferenceController {
|
||||
|
||||
private MediaController mMediaController;
|
||||
|
||||
public MediaOutputPreferenceController(Context context, String key) {
|
||||
super(context, key);
|
||||
mMediaController = getActiveLocalMediaController();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void displayPreference(PreferenceScreen screen) {
|
||||
super.displayPreference(screen);
|
||||
|
||||
if (!Utils.isAudioModeOngoingCall(mContext)) {
|
||||
if (!Utils.isAudioModeOngoingCall(mContext) && mMediaController != null) {
|
||||
mPreference.setVisible(true);
|
||||
}
|
||||
}
|
||||
@@ -63,6 +70,11 @@ public class MediaOutputPreferenceController extends AudioSwitchPreferenceContro
|
||||
return;
|
||||
}
|
||||
|
||||
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);
|
||||
@@ -81,6 +93,9 @@ public class MediaOutputPreferenceController extends AudioSwitchPreferenceContro
|
||||
|| (connectedHADevices != null && !connectedHADevices.isEmpty()))) {
|
||||
activeDevice = findActiveDevice();
|
||||
}
|
||||
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());
|
||||
@@ -126,4 +141,26 @@ public class MediaOutputPreferenceController extends AudioSwitchPreferenceContro
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
MediaController getActiveLocalMediaController() {
|
||||
final MediaSessionManager mMediaSessionManager = mContext.getSystemService(
|
||||
MediaSessionManager.class);
|
||||
|
||||
for (MediaController controller : mMediaSessionManager.getActiveSessions(null)) {
|
||||
final MediaController.PlaybackInfo pi = controller.getPlaybackInfo();
|
||||
if (pi == null) {
|
||||
return null;
|
||||
}
|
||||
final PlaybackState playbackState = controller.getPlaybackState();
|
||||
if (playbackState == null) {
|
||||
return null;
|
||||
}
|
||||
if (pi.getPlaybackType() == MediaController.PlaybackInfo.PLAYBACK_TYPE_LOCAL
|
||||
&& playbackState.getState() == PlaybackState.STATE_PLAYING) {
|
||||
return controller;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@@ -22,6 +22,7 @@ import static android.media.AudioSystem.DEVICE_OUT_HEARING_AID;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.spy;
|
||||
@@ -33,7 +34,15 @@ import android.bluetooth.BluetoothDevice;
|
||||
import android.bluetooth.BluetoothManager;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageStats;
|
||||
import android.media.AudioAttributes;
|
||||
import android.media.AudioManager;
|
||||
import android.media.VolumeProvider;
|
||||
import android.media.session.MediaController;
|
||||
import android.media.session.MediaSessionManager;
|
||||
import android.media.session.PlaybackState;
|
||||
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.PreferenceManager;
|
||||
@@ -60,8 +69,10 @@ import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
import org.robolectric.Shadows;
|
||||
import org.robolectric.annotation.Config;
|
||||
import org.robolectric.shadows.ShadowBluetoothDevice;
|
||||
import org.robolectric.shadows.ShadowPackageManager;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@@ -82,6 +93,8 @@ public class MediaOutputPreferenceControllerTest {
|
||||
private static final String TEST_DEVICE_ADDRESS_2 = "00:B2:B2:B2:B2:B2";
|
||||
private static final String TEST_DEVICE_ADDRESS_3 = "00:C3:C3:C3:C3:C3";
|
||||
private static final String TEST_DEVICE_ADDRESS_4 = "00:D4:D4:D4:D4:D4";
|
||||
private static final String TEST_PACKAGE_NAME = "com.test.packagename";
|
||||
private static final String TEST_APPLICATION_LABEL = "APP Test Label";
|
||||
|
||||
@Mock
|
||||
private LocalBluetoothManager mLocalManager;
|
||||
@@ -95,6 +108,10 @@ public class MediaOutputPreferenceControllerTest {
|
||||
private HearingAidProfile mHearingAidProfile;
|
||||
@Mock
|
||||
private AudioSwitchPreferenceController.AudioSwitchCallback mAudioSwitchPreferenceCallback;
|
||||
@Mock
|
||||
private MediaSessionManager mMediaSessionManager;
|
||||
@Mock
|
||||
private MediaController mMediaController;
|
||||
|
||||
private Context mContext;
|
||||
private PreferenceScreen mScreen;
|
||||
@@ -111,6 +128,13 @@ public class MediaOutputPreferenceControllerTest {
|
||||
private MediaOutputPreferenceController mController;
|
||||
private List<BluetoothDevice> mProfileConnectedDevices;
|
||||
private List<BluetoothDevice> mHearingAidActiveDevices;
|
||||
private List<MediaController> mMediaControllers = new ArrayList<>();
|
||||
private MediaController.PlaybackInfo mPlaybackInfo;
|
||||
private PlaybackState mPlaybackState;
|
||||
private ShadowPackageManager mShadowPackageManager;
|
||||
private ApplicationInfo mAppInfo;
|
||||
private PackageInfo mPackageInfo;
|
||||
private PackageStats mPackageStats;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
@@ -123,6 +147,23 @@ public class MediaOutputPreferenceControllerTest {
|
||||
ShadowBluetoothUtils.sLocalBluetoothManager = mLocalManager;
|
||||
mLocalBluetoothManager = Utils.getLocalBtManager(mContext);
|
||||
|
||||
when(mContext.getSystemService(MediaSessionManager.class)).thenReturn(mMediaSessionManager);
|
||||
when(mMediaSessionManager.getActiveSessions(any())).thenReturn(mMediaControllers);
|
||||
when(mMediaController.getPackageName()).thenReturn(TEST_PACKAGE_NAME);
|
||||
mPlaybackInfo = new MediaController.PlaybackInfo(
|
||||
MediaController.PlaybackInfo.PLAYBACK_TYPE_LOCAL,
|
||||
VolumeProvider.VOLUME_CONTROL_ABSOLUTE,
|
||||
100,
|
||||
10,
|
||||
new AudioAttributes.Builder().setUsage(AudioAttributes.USAGE_MEDIA).build(),
|
||||
null);
|
||||
mPlaybackState = new PlaybackState.Builder()
|
||||
.setState(PlaybackState.STATE_PLAYING, 0, 1)
|
||||
.build();
|
||||
when(mMediaController.getPlaybackInfo()).thenReturn(mPlaybackInfo);
|
||||
when(mMediaController.getPlaybackState()).thenReturn(mPlaybackState);
|
||||
mMediaControllers.add(mMediaController);
|
||||
|
||||
when(mLocalBluetoothManager.getEventManager()).thenReturn(mBluetoothEventManager);
|
||||
when(mLocalBluetoothManager.getProfileManager()).thenReturn(mLocalBluetoothProfileManager);
|
||||
when(mLocalBluetoothProfileManager.getA2dpProfile()).thenReturn(mA2dpProfile);
|
||||
@@ -226,6 +267,30 @@ public class MediaOutputPreferenceControllerTest {
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateState_noActiveLocalPlayback_noTitle() {
|
||||
mPlaybackState = new PlaybackState.Builder()
|
||||
.setState(PlaybackState.STATE_NONE, 0, 1)
|
||||
.build();
|
||||
when(mMediaController.getPlaybackState()).thenReturn(mPlaybackState);
|
||||
mController = new MediaOutputPreferenceController(mContext, TEST_KEY);
|
||||
|
||||
mController.updateState(mPreference);
|
||||
|
||||
assertThat(mPreference.getTitle()).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateState_withActiveLocalPlayback_checkTitle() {
|
||||
initPackage();
|
||||
mShadowPackageManager.addPackage(mPackageInfo, mPackageStats);
|
||||
|
||||
mController.updateState(mPreference);
|
||||
|
||||
assertThat(mPreference.getTitle()).isEqualTo(
|
||||
mContext.getString(R.string.media_output_label_title, TEST_APPLICATION_LABEL));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void click_launch_outputSwitcherSlice() {
|
||||
final ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
|
||||
@@ -282,4 +347,16 @@ public class MediaOutputPreferenceControllerTest {
|
||||
|
||||
assertThat(mController.findActiveDevice()).isNull();
|
||||
}
|
||||
|
||||
private void initPackage() {
|
||||
mShadowPackageManager = Shadows.shadowOf(mContext.getPackageManager());
|
||||
mAppInfo = new ApplicationInfo();
|
||||
mAppInfo.flags = ApplicationInfo.FLAG_INSTALLED;
|
||||
mAppInfo.packageName = TEST_PACKAGE_NAME;
|
||||
mAppInfo.name = TEST_APPLICATION_LABEL;
|
||||
mPackageInfo = new PackageInfo();
|
||||
mPackageInfo.packageName = TEST_PACKAGE_NAME;
|
||||
mPackageInfo.applicationInfo = mAppInfo;
|
||||
mPackageStats = new PackageStats(TEST_PACKAGE_NAME);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user