diff --git a/res/values/strings.xml b/res/values/strings.xml index cbd97727332..9d5072d3ea4 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -11343,6 +11343,9 @@ This device + + Audio sharing + Unavailable during calls diff --git a/src/com/android/settings/sound/MediaOutputPreferenceController.java b/src/com/android/settings/sound/MediaOutputPreferenceController.java index c85789dbed8..e116422c7b9 100644 --- a/src/com/android/settings/sound/MediaOutputPreferenceController.java +++ b/src/com/android/settings/sound/MediaOutputPreferenceController.java @@ -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); + } } diff --git a/tests/robotests/src/com/android/settings/sound/MediaOutputPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/sound/MediaOutputPreferenceControllerTest.java index b9f9b168ac5..5dc602ad490 100644 --- a/tests/robotests/src/com/android/settings/sound/MediaOutputPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/sound/MediaOutputPreferenceControllerTest.java @@ -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 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"