Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4c3d2e1d authored by tim peng's avatar tim peng Committed by Automerger Merge Worker
Browse files

Merge "Update "Play media to" in Sound Settings" into rvc-dev am: 72948ab5

Change-Id: Ie903fe21bb7667904aae3e125966df70e024086e
parents 83a8cd07 72948ab5
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -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 -->
+38 −1
Original line number Diff line number Diff line
@@ -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;
    }
}
+77 −0
Original line number Diff line number Diff line
@@ -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);
    }
}