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

Commit 72948ab5 authored by tim peng's avatar tim peng Committed by Android (Google) Code Review
Browse files

Merge "Update "Play media to" in Sound Settings" into rvc-dev

parents 9454ab07 f392eae2
Loading
Loading
Loading
Loading
+1 −0
Original line number Original line Diff line number Diff line
@@ -45,6 +45,7 @@
        android:title="@string/media_output_title"
        android:title="@string/media_output_title"
        android:dialogTitle="@string/media_output_title"
        android:dialogTitle="@string/media_output_title"
        android:order="-175"
        android:order="-175"
        settings:searchable="false"
        settings:controller="com.android.settings.sound.MediaOutputPreferenceController"/>
        settings:controller="com.android.settings.sound.MediaOutputPreferenceController"/>


    <!-- Call volume -->
    <!-- Call volume -->
+38 −1
Original line number Original line Diff line number Diff line
@@ -20,8 +20,12 @@ import android.bluetooth.BluetoothDevice;
import android.content.Context;
import android.content.Context;
import android.content.Intent;
import android.content.Intent;
import android.media.AudioManager;
import android.media.AudioManager;
import android.media.session.MediaController;
import android.media.session.MediaSessionManager;
import android.media.session.PlaybackState;
import android.text.TextUtils;
import android.text.TextUtils;


import androidx.annotation.Nullable;
import androidx.preference.Preference;
import androidx.preference.Preference;
import androidx.preference.PreferenceScreen;
import androidx.preference.PreferenceScreen;


@@ -43,15 +47,18 @@ import java.util.List;
 */
 */
public class MediaOutputPreferenceController extends AudioSwitchPreferenceController {
public class MediaOutputPreferenceController extends AudioSwitchPreferenceController {


    private MediaController mMediaController;

    public MediaOutputPreferenceController(Context context, String key) {
    public MediaOutputPreferenceController(Context context, String key) {
        super(context, key);
        super(context, key);
        mMediaController = getActiveLocalMediaController();
    }
    }


    @Override
    @Override
    public void displayPreference(PreferenceScreen screen) {
    public void displayPreference(PreferenceScreen screen) {
        super.displayPreference(screen);
        super.displayPreference(screen);


        if (!Utils.isAudioModeOngoingCall(mContext)) {
        if (!Utils.isAudioModeOngoingCall(mContext) && mMediaController != null) {
            mPreference.setVisible(true);
            mPreference.setVisible(true);
        }
        }
    }
    }
@@ -63,6 +70,11 @@ public class MediaOutputPreferenceController extends AudioSwitchPreferenceContro
            return;
            return;
        }
        }


        if (mMediaController == null) {
            // No active local playback
            return;
        }

        if (Utils.isAudioModeOngoingCall(mContext)) {
        if (Utils.isAudioModeOngoingCall(mContext)) {
            // Ongoing call status, switch entry for media will be disabled.
            // Ongoing call status, switch entry for media will be disabled.
            mPreference.setVisible(false);
            mPreference.setVisible(false);
@@ -81,6 +93,9 @@ public class MediaOutputPreferenceController extends AudioSwitchPreferenceContro
                || (connectedHADevices != null && !connectedHADevices.isEmpty()))) {
                || (connectedHADevices != null && !connectedHADevices.isEmpty()))) {
            activeDevice = findActiveDevice();
            activeDevice = findActiveDevice();
        }
        }
        mPreference.setTitle(mContext.getString(R.string.media_output_label_title,
                com.android.settings.Utils.getApplicationLabel(mContext,
                        mMediaController.getPackageName())));
        mPreference.setSummary((activeDevice == null) ?
        mPreference.setSummary((activeDevice == null) ?
                mContext.getText(R.string.media_output_default_summary) :
                mContext.getText(R.string.media_output_default_summary) :
                activeDevice.getAlias());
                activeDevice.getAlias());
@@ -126,4 +141,26 @@ public class MediaOutputPreferenceController extends AudioSwitchPreferenceContro
        }
        }
        return false;
        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 Original line 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 com.google.common.truth.Truth.assertThat;


import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.spy;
@@ -33,7 +34,15 @@ import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothManager;
import android.bluetooth.BluetoothManager;
import android.content.Context;
import android.content.Context;
import android.content.Intent;
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.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.Preference;
import androidx.preference.PreferenceManager;
import androidx.preference.PreferenceManager;
@@ -60,8 +69,10 @@ import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.Shadows;
import org.robolectric.annotation.Config;
import org.robolectric.annotation.Config;
import org.robolectric.shadows.ShadowBluetoothDevice;
import org.robolectric.shadows.ShadowBluetoothDevice;
import org.robolectric.shadows.ShadowPackageManager;


import java.util.ArrayList;
import java.util.ArrayList;
import java.util.List;
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_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_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_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
    @Mock
    private LocalBluetoothManager mLocalManager;
    private LocalBluetoothManager mLocalManager;
@@ -95,6 +108,10 @@ public class MediaOutputPreferenceControllerTest {
    private HearingAidProfile mHearingAidProfile;
    private HearingAidProfile mHearingAidProfile;
    @Mock
    @Mock
    private AudioSwitchPreferenceController.AudioSwitchCallback mAudioSwitchPreferenceCallback;
    private AudioSwitchPreferenceController.AudioSwitchCallback mAudioSwitchPreferenceCallback;
    @Mock
    private MediaSessionManager mMediaSessionManager;
    @Mock
    private MediaController mMediaController;


    private Context mContext;
    private Context mContext;
    private PreferenceScreen mScreen;
    private PreferenceScreen mScreen;
@@ -111,6 +128,13 @@ public class MediaOutputPreferenceControllerTest {
    private MediaOutputPreferenceController mController;
    private MediaOutputPreferenceController mController;
    private List<BluetoothDevice> mProfileConnectedDevices;
    private List<BluetoothDevice> mProfileConnectedDevices;
    private List<BluetoothDevice> mHearingAidActiveDevices;
    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
    @Before
    public void setUp() {
    public void setUp() {
@@ -123,6 +147,23 @@ public class MediaOutputPreferenceControllerTest {
        ShadowBluetoothUtils.sLocalBluetoothManager = mLocalManager;
        ShadowBluetoothUtils.sLocalBluetoothManager = mLocalManager;
        mLocalBluetoothManager = Utils.getLocalBtManager(mContext);
        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.getEventManager()).thenReturn(mBluetoothEventManager);
        when(mLocalBluetoothManager.getProfileManager()).thenReturn(mLocalBluetoothProfileManager);
        when(mLocalBluetoothManager.getProfileManager()).thenReturn(mLocalBluetoothProfileManager);
        when(mLocalBluetoothProfileManager.getA2dpProfile()).thenReturn(mA2dpProfile);
        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
    @Test
    public void click_launch_outputSwitcherSlice() {
    public void click_launch_outputSwitcherSlice() {
        final ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
        final ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
@@ -282,4 +347,16 @@ public class MediaOutputPreferenceControllerTest {


        assertThat(mController.findActiveDevice()).isNull();
        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);
    }
}
}