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

Commit c1a5a7c9 authored by Haijie Hong's avatar Haijie Hong
Browse files

Disable media output switcher in Settings when audio sharing

Bug: 327080094
Test: atest MediaOutputPreferenceControllerTest
Change-Id: I1e81d507c5c92c2b6f21494551931b359d5043cb
parent 42be6f6e
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -11241,6 +11241,9 @@
    <!-- Summary for media output default settings. (this device) [CHAR LIMIT=30] -->
    <string name="media_output_default_summary">This device</string>
    <!-- Summary for media output when audio sharing. [CHAR LIMIT=NONE] -->
    <string name="media_output_audio_sharing">Audio sharing</string>
    <!-- Summary for media output settings when device is in ongoing call state. -->
    <string name="media_out_summary_ongoing_call_state">Unavailable during calls</string>
+85 −4
Original line number Diff line number Diff line
@@ -19,6 +19,8 @@ package com.android.settings.sound;
import static com.android.settingslib.media.flags.Flags.enableOutputSwitcherForSystemRouting;

import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothLeBroadcast;
import android.bluetooth.BluetoothLeBroadcastMetadata;
import android.content.Context;
import android.content.Intent;
import android.media.AudioManager;
@@ -26,6 +28,7 @@ import android.media.session.MediaController;
import android.media.session.MediaSessionManager;
import android.text.TextUtils;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.preference.Preference;
import androidx.preference.PreferenceScreen;
@@ -35,6 +38,8 @@ import com.android.settings.media.MediaOutputUtils;
import com.android.settingslib.Utils;
import com.android.settingslib.bluetooth.A2dpProfile;
import com.android.settingslib.bluetooth.HearingAidProfile;
import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcast;
import com.android.settingslib.bluetooth.LocalBluetoothManager;
import com.android.settingslib.media.MediaOutputConstants;

import java.util.List;
@@ -53,10 +58,74 @@ public class MediaOutputPreferenceController extends AudioSwitchPreferenceContro
    @Nullable private MediaController mMediaController;
    private MediaSessionManager mMediaSessionManager;

    @Nullable private LocalBluetoothLeBroadcast mLocalBluetoothLeBroadcast;

    private final BluetoothLeBroadcast.Callback mBroadcastCallback =
            new BluetoothLeBroadcast.Callback() {
                @Override
                public void onBroadcastStarted(int reason, int broadcastId) {
                    updateState(mPreference);
                }

                @Override
                public void onBroadcastStartFailed(int reason) {
                    updateState(mPreference);
                }

                @Override
                public void onBroadcastStopped(int reason, int broadcastId) {
                    updateState(mPreference);
                }

                @Override
                public void onBroadcastStopFailed(int reason) {
                    updateState(mPreference);
                }

                @Override
                public void onPlaybackStarted(int reason, int broadcastId) {}

                @Override
                public void onPlaybackStopped(int reason, int broadcastId) {}

                @Override
                public void onBroadcastUpdated(int reason, int broadcastId) {}

                @Override
                public void onBroadcastUpdateFailed(int reason, int broadcastId) {}

                @Override
                public void onBroadcastMetadataChanged(
                        int broadcastId, @NonNull BluetoothLeBroadcastMetadata metadata) {}
            };

    public MediaOutputPreferenceController(Context context, String key) {
        super(context, key);
        mMediaSessionManager = context.getSystemService(MediaSessionManager.class);
        mMediaController = MediaOutputUtils.getActiveLocalMediaController(mMediaSessionManager);
        LocalBluetoothManager localBluetoothManager =
                com.android.settings.bluetooth.Utils.getLocalBtManager(mContext);
        if (localBluetoothManager != null) {
            mLocalBluetoothLeBroadcast =
                    localBluetoothManager.getProfileManager().getLeAudioBroadcastProfile();
        }
    }

    @Override
    public void onStart() {
        super.onStart();
        if (mLocalBluetoothLeBroadcast != null) {
            mLocalBluetoothLeBroadcast.registerServiceCallBack(
                    mContext.getMainExecutor(), mBroadcastCallback);
        }
    }

    @Override
    public void onStop() {
        super.onStop();
        if (mLocalBluetoothLeBroadcast != null) {
            mLocalBluetoothLeBroadcast.unregisterServiceCallBack(mBroadcastCallback);
        }
    }

    @Override
@@ -83,7 +152,7 @@ public class MediaOutputPreferenceController extends AudioSwitchPreferenceContro
            }
        }


        mPreference.setEnabled(true);
        if (Utils.isAudioModeOngoingCall(mContext)) {
            // Ongoing call status, switch entry for media will be disabled.
            mPreference.setVisible(false);
@@ -112,9 +181,15 @@ public class MediaOutputPreferenceController extends AudioSwitchPreferenceContro
                    com.android.settings.Utils.getApplicationLabel(mContext,
                    mMediaController.getPackageName())));
        }
        mPreference.setSummary((activeDevice == null) ?
                mContext.getText(R.string.media_output_default_summary) :
                activeDevice.getAlias());
        if (isDeviceBroadcasting()) {
            mPreference.setSummary(R.string.media_output_audio_sharing);
            mPreference.setEnabled(false);
        } else {
            mPreference.setSummary(
                    (activeDevice == null)
                            ? mContext.getText(R.string.media_output_default_summary)
                            : activeDevice.getAlias());
        }
    }

    @Override
@@ -176,4 +251,10 @@ public class MediaOutputPreferenceController extends AudioSwitchPreferenceContro
        }
        return false;
    }

    private boolean isDeviceBroadcasting() {
        return com.android.settingslib.flags.Flags.enableLeAudioSharing()
                && mLocalBluetoothLeBroadcast != null
                && mLocalBluetoothLeBroadcast.isEnabled(null);
    }
}
+26 −0
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ 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.android.settingslib.flags.Flags.FLAG_ENABLE_LE_AUDIO_SHARING;

import static com.google.common.truth.Truth.assertThat;

@@ -35,6 +36,7 @@ import static org.mockito.Mockito.when;

import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothLeBroadcast;
import android.bluetooth.BluetoothManager;
import android.content.Context;
import android.content.Intent;
@@ -63,6 +65,7 @@ import com.android.settingslib.bluetooth.CachedBluetoothDevice;
import com.android.settingslib.bluetooth.CachedBluetoothDeviceManager;
import com.android.settingslib.bluetooth.HearingAidProfile;
import com.android.settingslib.bluetooth.LeAudioProfile;
import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcast;
import com.android.settingslib.bluetooth.LocalBluetoothManager;
import com.android.settingslib.bluetooth.LocalBluetoothProfileManager;
import com.android.settingslib.media.MediaOutputConstants;
@@ -123,6 +126,8 @@ public class MediaOutputPreferenceControllerTest {
    @Mock
    private LeAudioProfile mLeAudioProfile;
    @Mock
    private LocalBluetoothLeBroadcast mLocalBluetoothLeBroadcast;
    @Mock
    private AudioSwitchPreferenceController.AudioSwitchCallback mAudioSwitchPreferenceCallback;
    @Mock
    private MediaSessionManager mMediaSessionManager;
@@ -194,6 +199,8 @@ public class MediaOutputPreferenceControllerTest {
        when(mLocalBluetoothProfileManager.getA2dpProfile()).thenReturn(mA2dpProfile);
        when(mLocalBluetoothProfileManager.getHearingAidProfile()).thenReturn(mHearingAidProfile);
        when(mLocalBluetoothProfileManager.getLeAudioProfile()).thenReturn(mLeAudioProfile);
        when(mLocalBluetoothProfileManager.getLeAudioBroadcastProfile())
                .thenReturn(mLocalBluetoothLeBroadcast);

        mBluetoothManager = mContext.getSystemService(BluetoothManager.class);
        mBluetoothAdapter = mBluetoothManager.getAdapter();
@@ -243,6 +250,25 @@ public class MediaOutputPreferenceControllerTest {
        ShadowBluetoothUtils.reset();
    }

    /** Device start broadcasting so Preference summary should become "Audio Sharing" */
    @Test
    public void audioSharingStart_changeSummary() {
        mSetFlagsRule.enableFlags(FLAG_ENABLE_LE_AUDIO_SHARING);
        mController.onStart();
        ArgumentCaptor<BluetoothLeBroadcast.Callback> broadcastCallbackCaptor =
                ArgumentCaptor.forClass(BluetoothLeBroadcast.Callback.class);
        mShadowAudioManager.setOutputDevice(DEVICE_OUT_BLUETOOTH_A2DP);
        mAudioManager.setMode(AudioManager.MODE_NORMAL);
        when(mLocalBluetoothLeBroadcast.isEnabled(null)).thenReturn(true);
        verify(mLocalBluetoothLeBroadcast)
                .registerServiceCallBack(any(), broadcastCallbackCaptor.capture());
        BluetoothLeBroadcast.Callback callback = broadcastCallbackCaptor.getValue();

        callback.onBroadcastStarted(0, 0);
        assertThat(mPreference.getSummary().toString())
                .isEqualTo(mContext.getText(R.string.media_output_audio_sharing).toString());
    }

    /**
     * A2DP Bluetooth device(s) are connected, but no device is set as activated
     * Preference summary should be "This device"