Loading res/values/strings.xml +3 −0 Original line number Diff line number Diff line Loading @@ -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> src/com/android/settings/sound/MediaOutputPreferenceController.java +85 −4 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading @@ -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; Loading @@ -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 Loading @@ -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); Loading Loading @@ -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 Loading Loading @@ -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); } } tests/robotests/src/com/android/settings/sound/MediaOutputPreferenceControllerTest.java +26 −0 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -123,6 +126,8 @@ public class MediaOutputPreferenceControllerTest { @Mock private LeAudioProfile mLeAudioProfile; @Mock private LocalBluetoothLeBroadcast mLocalBluetoothLeBroadcast; @Mock private AudioSwitchPreferenceController.AudioSwitchCallback mAudioSwitchPreferenceCallback; @Mock private MediaSessionManager mMediaSessionManager; Loading Loading @@ -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(); Loading Loading @@ -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" Loading Loading
res/values/strings.xml +3 −0 Original line number Diff line number Diff line Loading @@ -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>
src/com/android/settings/sound/MediaOutputPreferenceController.java +85 −4 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading @@ -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; Loading @@ -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 Loading @@ -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); Loading Loading @@ -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 Loading Loading @@ -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); } }
tests/robotests/src/com/android/settings/sound/MediaOutputPreferenceControllerTest.java +26 −0 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -123,6 +126,8 @@ public class MediaOutputPreferenceControllerTest { @Mock private LeAudioProfile mLeAudioProfile; @Mock private LocalBluetoothLeBroadcast mLocalBluetoothLeBroadcast; @Mock private AudioSwitchPreferenceController.AudioSwitchCallback mAudioSwitchPreferenceCallback; @Mock private MediaSessionManager mMediaSessionManager; Loading Loading @@ -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(); Loading Loading @@ -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" Loading