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

Commit 395b26be authored by chelseahao's avatar chelseahao Committed by Chelsea Hao
Browse files

Modify channel selection in audio stream media service based on intent data...

Modify channel selection in audio stream media service based on intent data when flag `audioStreamMediaServiceByReceiveState` is turned off.

Flag: com.android.settingslib.flags.audio_stream_play_pause_by_modify_source
Test: atest
Bug: 384976631
Change-Id: Ia80fb83f9b1365ad81c0af8d252c23be17baeb08
parent e38e0586
Loading
Loading
Loading
Loading
+45 −18
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ import static com.android.settingslib.bluetooth.LocalBluetoothLeBroadcastAssista
import static com.android.settingslib.bluetooth.LocalBluetoothLeBroadcastAssistant.LocalBluetoothLeBroadcastSourceState.PAUSED_BY_RECEIVER;
import static com.android.settingslib.bluetooth.LocalBluetoothLeBroadcastAssistant.LocalBluetoothLeBroadcastSourceState.STREAMING;
import static com.android.settingslib.bluetooth.LocalBluetoothLeBroadcastAssistant.UNKNOWN_CHANNEL;
import static com.android.settingslib.bluetooth.LocalBluetoothLeBroadcastAssistant.getLocalSourceStateWithSelectedChannel;

import static java.util.Collections.emptyList;

@@ -277,7 +278,30 @@ public class AudioStreamMediaService extends Service {
                stopSelf();
            } else {
                mStateByDevice = new HashMap<>();
                devices.forEach(d -> mStateByDevice.put(d, STREAMING));
                devices.forEach(d -> {
                    if (mStateByDevice == null) {
                        return;
                    }
                    mStateByDevice.put(d, STREAMING);
                    if (mLocalBtManager != null && mLeBroadcastAssistant != null) {
                        mLeBroadcastAssistant.getAllSources(d).stream().filter(
                                state -> state.getBroadcastId()
                                        == mBroadcastId).findFirst().ifPresent(state -> {
                                    if (mLocalBtManager == null) {
                                        return;
                                    }
                                    var profileManager = mLocalBtManager.getProfileManager();
                                    if (profileManager == null) {
                                        return;
                                    }
                                    mSourceId = state.getSourceId();
                                    var selectedChannel = getLocalSourceStateWithSelectedChannel(
                                            profileManager, d, mSourceId, state).second;
                                    cacheSelectedChannelIndex(selectedChannel, d);
                                }
                        );
                    }
                });
                MediaSession.Token token =
                        getOrCreateLocalMediaSession(intent.getStringExtra(BROADCAST_TITLE));
                startForeground(NOTIFICATION_ID, buildNotification(token));
@@ -333,10 +357,7 @@ public class AudioStreamMediaService extends Service {
        mSourceId = sourceId;
        mStateByDevice = new HashMap<>();
        mStateByDevice.put(device, state);
        if (!selectedChannelIndex.equals(UNKNOWN_CHANNEL)) {
            mSelectedChannelCacheByDevice.put(device, selectedChannelIndex);
            Log.d(TAG, "mSelectedChannelCacheByDevice:" + mSelectedChannelCacheByDevice);
        }
        cacheSelectedChannelIndex(selectedChannelIndex, device);
        MediaSession.Token token = getOrCreateLocalMediaSession(
                getBroadcastName(device, sourceId, programInfo));
        startForeground(NOTIFICATION_ID, buildNotification(token));
@@ -353,10 +374,7 @@ public class AudioStreamMediaService extends Service {
        mSourceId = sourceId;
        mStateByDevice = new HashMap<>();
        mStateByDevice.put(device, state);
        if (!selectedChannelIndex.equals(UNKNOWN_CHANNEL)) {
            mSelectedChannelCacheByDevice.put(device, selectedChannelIndex);
            Log.d(TAG, "mSelectedChannelCacheByDevice:" + mSelectedChannelCacheByDevice);
        }
        cacheSelectedChannelIndex(selectedChannelIndex, device);
        updateMediaSessionAndNotify(device, sourceId, programInfo);
    }

@@ -365,10 +383,7 @@ public class AudioStreamMediaService extends Service {
            Set<Integer> selectedChannelIndex) {
        if (mStateByDevice != null) {
            mStateByDevice.put(device, state);
            if (!selectedChannelIndex.equals(UNKNOWN_CHANNEL)) {
                mSelectedChannelCacheByDevice.put(device, selectedChannelIndex);
                Log.d(TAG, "mSelectedChannelCacheByDevice:" + mSelectedChannelCacheByDevice);
            }
            cacheSelectedChannelIndex(selectedChannelIndex, device);
        }
        if (getDeviceInValidState().isEmpty()) {
            Log.d(TAG, "handleNewDeviceOrState() : no device is in valid state. Stop service.");
@@ -533,14 +548,16 @@ public class AudioStreamMediaService extends Service {
            }
            super.onReceiveStateChanged(sink, sourceId, state);
            if (!mHysteresisModeFixAvailable || mStateByDevice == null
                    || !mStateByDevice.containsKey(sink)) {
                    || !mStateByDevice.containsKey(sink) || mLocalBtManager == null) {
                return;
            }
            var sourceState = LocalBluetoothLeBroadcastAssistant.getLocalSourceState(state);
            boolean streaming = sourceState == STREAMING;
            boolean paused = sourceState == PAUSED;
            var stateWithSelectedChannel = getLocalSourceStateWithSelectedChannel(
                    mLocalBtManager.getProfileManager(), sink, sourceId, state);
            var sourceState = stateWithSelectedChannel.first;
            cacheSelectedChannelIndex(stateWithSelectedChannel.second, sink);
            // Exit early if the state is neither streaming nor paused
            if (!streaming && !paused) {
            if (sourceState != STREAMING && sourceState != PAUSED
                    && sourceState != PAUSED_BY_RECEIVER) {
                return;
            }
            boolean shouldUpdate = mStateByDevice.get(sink) != sourceState;
@@ -737,4 +754,14 @@ public class AudioStreamMediaService extends Service {
                            }
                        });
    }

    private void cacheSelectedChannelIndex(Set<Integer> selectedChannelIndex,
            BluetoothDevice device) {
        if (!selectedChannelIndex.equals(UNKNOWN_CHANNEL)
                && !selectedChannelIndex.isEmpty()) {
            mSelectedChannelCacheByDevice.put(device, selectedChannelIndex);
            Log.d(TAG, "mSelectedChannelCacheByDevice:"
                    + mSelectedChannelCacheByDevice);
        }
    }
}
+42 −0
Original line number Diff line number Diff line
@@ -612,6 +612,27 @@ public class AudioStreamMediaServiceTest {
                eq(SettingsEnums.ACTION_AUDIO_STREAM_NOTIFICATION_MUTE_BUTTON_CLICK), eq(1));
    }

    @Test
    public void byReceiveStateFlagOff_mediaSessionCallback_onPause_modifySource() {
        mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
        mSetFlagsRule.disableFlags(Flags.FLAG_AUDIO_STREAM_MEDIA_SERVICE_BY_RECEIVE_STATE);
        mSetFlagsRule.enableFlags(Flags.FLAG_AUDIO_STREAM_PLAY_PAUSE_BY_MODIFY_SOURCE);

        when(mBroadcastReceiveState.getBroadcastId()).thenReturn(1);
        when(mLeBroadcastAssistant.getAllSources(any())).thenReturn(
                List.of(mBroadcastReceiveState));
        when(mDevice.getAddress()).thenReturn(DEVICE_ADDRESS);
        when(mBroadcastReceiveState.getSourceDevice()).thenReturn(mDevice);

        mAudioStreamMediaService.onCreate();
        mAudioStreamMediaService.onStartCommand(setupIntent(), /* flags= */ 0, /* startId= */ 0);
        assertThat(mAudioStreamMediaService.mMediaSessionCallback).isNotNull();
        mAudioStreamMediaService.mMediaSessionCallback.onPause();

        verify(mVolumeControlProfile, never()).setDeviceVolume(any(), anyInt(), anyBoolean());
        verify(mLeBroadcastAssistant).getSourceMetadata(any(), anyInt());
    }

    @Test
    public void byReceiveStateFlagOn_mediaSessionCallback_onPause_modifySource() {
        mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
@@ -665,6 +686,27 @@ public class AudioStreamMediaServiceTest {
                eq(SettingsEnums.ACTION_AUDIO_STREAM_NOTIFICATION_MUTE_BUTTON_CLICK), eq(0));
    }

    @Test
    public void byReceiveStateFlagOff_mediaSessionCallback_onPlay_modifySource() {
        mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
        mSetFlagsRule.disableFlags(Flags.FLAG_AUDIO_STREAM_MEDIA_SERVICE_BY_RECEIVE_STATE);
        mSetFlagsRule.enableFlags(Flags.FLAG_AUDIO_STREAM_PLAY_PAUSE_BY_MODIFY_SOURCE);

        when(mBroadcastReceiveState.getBroadcastId()).thenReturn(1);
        when(mLeBroadcastAssistant.getAllSources(any())).thenReturn(
                List.of(mBroadcastReceiveState));
        when(mDevice.getAddress()).thenReturn(DEVICE_ADDRESS);
        when(mBroadcastReceiveState.getSourceDevice()).thenReturn(mDevice);

        mAudioStreamMediaService.onCreate();
        mAudioStreamMediaService.onStartCommand(setupIntent(), /* flags= */ 0, /* startId= */ 0);
        assertThat(mAudioStreamMediaService.mMediaSessionCallback).isNotNull();
        mAudioStreamMediaService.mMediaSessionCallback.onPlay();

        verify(mVolumeControlProfile, never()).setDeviceVolume(any(), anyInt(), anyBoolean());
        verify(mLeBroadcastAssistant).getSourceMetadata(any(), anyInt());
    }

    @Test
    public void byReceiveStateFlagOn_mediaSessionCallback_onPlay_modifySource() {
        mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);