diff options
10 files changed, 81 insertions, 24 deletions
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcastCallbackExt.kt b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcastCallbackExt.kt index 07abb6b912b6..888f54f4bb34 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcastCallbackExt.kt +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcastCallbackExt.kt @@ -69,8 +69,8 @@ val LocalBluetoothLeBroadcast.onBroadcastStartedOrStopped: Flow<Unit> } .buffer(capacity = Channel.CONFLATED) -/** [Flow] for [BluetoothLeBroadcast.Callback] onPlaybackStarted event */ -val LocalBluetoothLeBroadcast.onPlaybackStarted: Flow<Unit> +/** [Flow] for [BluetoothLeBroadcast.Callback] onBroadcastMetadataChanged event */ +val LocalBluetoothLeBroadcast.onBroadcastMetadataChanged: Flow<Unit> get() = callbackFlow { val listener = @@ -87,7 +87,6 @@ val LocalBluetoothLeBroadcast.onPlaybackStarted: Flow<Unit> } override fun onPlaybackStarted(reason: Int, broadcastId: Int) { - launch { trySend(Unit) } } override fun onPlaybackStopped(reason: Int, broadcastId: Int) { @@ -100,7 +99,9 @@ val LocalBluetoothLeBroadcast.onPlaybackStarted: Flow<Unit> override fun onBroadcastMetadataChanged( broadcastId: Int, metadata: BluetoothLeBroadcastMetadata - ) {} + ) { + trySend(Unit) + } } registerServiceCallBack( ConcurrentUtils.DIRECT_EXECUTOR, diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/bluetooth/qsdialog/AudioSharingInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/bluetooth/qsdialog/AudioSharingInteractorTest.kt index 25f956574274..a11dace0505c 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/bluetooth/qsdialog/AudioSharingInteractorTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/bluetooth/qsdialog/AudioSharingInteractorTest.kt @@ -17,6 +17,7 @@ package com.android.systemui.bluetooth.qsdialog import android.bluetooth.BluetoothLeBroadcast +import android.bluetooth.BluetoothLeBroadcastMetadata import android.testing.TestableLooper import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest @@ -50,6 +51,7 @@ class AudioSharingInteractorTest : SysuiTestCase() { @get:Rule val mockito: MockitoRule = MockitoJUnit.rule() private val kosmos = testKosmos() @Mock private lateinit var localBluetoothLeBroadcast: LocalBluetoothLeBroadcast + @Mock private lateinit var bluetoothLeBroadcastMetadata: BluetoothLeBroadcastMetadata @Captor private lateinit var callbackCaptor: ArgumentCaptor<BluetoothLeBroadcast.Callback> private lateinit var underTest: AudioSharingInteractor @@ -202,7 +204,7 @@ class AudioSharingInteractorTest : SysuiTestCase() { verify(localBluetoothLeBroadcast) .registerServiceCallBack(any(), callbackCaptor.capture()) runCurrent() - callbackCaptor.value.onPlaybackStarted(0, 0) + callbackCaptor.value.onBroadcastMetadataChanged(0, bluetoothLeBroadcastMetadata) runCurrent() assertThat(bluetoothTileDialogAudioSharingRepository.sourceAdded).isTrue() diff --git a/packages/SystemUI/res/layout/audio_sharing_dialog.xml b/packages/SystemUI/res/layout/audio_sharing_dialog.xml index 7534e159beb0..014b7f7b45df 100644 --- a/packages/SystemUI/res/layout/audio_sharing_dialog.xml +++ b/packages/SystemUI/res/layout/audio_sharing_dialog.xml @@ -84,7 +84,7 @@ android:id="@+id/share_audio_button" style="@style/SettingsLibActionButton" android:textColor="?androidprv:attr/textColorOnAccent" - android:background="@drawable/audio_sharing_rounded_bg_ripple" + android:background="@drawable/audio_sharing_rounded_bg_ripple_top" android:layout_marginBottom="4dp" android:layout_width="0dp" android:layout_height="wrap_content" @@ -101,7 +101,7 @@ android:id="@+id/switch_active_button" style="@style/SettingsLibActionButton" android:textColor="?androidprv:attr/textColorOnAccent" - android:background="@drawable/audio_sharing_rounded_bg_ripple" + android:background="@drawable/audio_sharing_rounded_bg_ripple_bottom" android:layout_marginBottom="20dp" android:layout_width="0dp" android:layout_height="wrap_content" diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml index b45aaddef183..405f5b559019 100644 --- a/packages/SystemUI/res/values/strings.xml +++ b/packages/SystemUI/res/values/strings.xml @@ -753,7 +753,7 @@ <!-- QuickSettings: Bluetooth dialog device in audio sharing default summary [CHAR LIMIT=50]--> <string name="quick_settings_bluetooth_device_audio_sharing">Audio Sharing</string> <!-- QuickSettings: Bluetooth dialog device summary for devices that are capable of audio sharing and switching to active[CHAR LIMIT=NONE]--> - <string name="quick_settings_bluetooth_device_audio_sharing_or_switch_active">Tap to switch or share audio</string> + <string name="quick_settings_bluetooth_device_audio_sharing_or_switch_active">Supports audio sharing</string> <!-- QuickSettings: Bluetooth dialog device saved default summary [CHAR LIMIT=NONE]--> <string name="quick_settings_bluetooth_device_saved">Saved</string> <!-- QuickSettings: Accessibility label to disconnect a device [CHAR LIMIT=NONE]--> diff --git a/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/AudioSharingDeviceItemActionInteractorImpl.kt b/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/AudioSharingDeviceItemActionInteractorImpl.kt index 13c72097c06e..4dc2a13480f5 100644 --- a/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/AudioSharingDeviceItemActionInteractorImpl.kt +++ b/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/AudioSharingDeviceItemActionInteractorImpl.kt @@ -27,7 +27,6 @@ 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.flags.Flags.audioSharingQsDialogImprovement import com.android.systemui.animation.DialogTransitionAnimator import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Background @@ -69,7 +68,7 @@ constructor( } deviceItem.type == DeviceItemType.AVAILABLE_AUDIO_SHARING_MEDIA_BLUETOOTH_DEVICE -> { - if (audioSharingQsDialogImprovement()) { + if (audioSharingInteractor.qsDialogImprovementAvailable()) { withContext(mainDispatcher) { delegateFactory .create(deviceItem.cachedBluetoothDevice) diff --git a/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/AudioSharingInteractor.kt b/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/AudioSharingInteractor.kt index 65f110533573..c4f26cd46bf8 100644 --- a/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/AudioSharingInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/AudioSharingInteractor.kt @@ -16,10 +16,13 @@ package com.android.systemui.bluetooth.qsdialog +import android.content.Context +import androidx.annotation.WorkerThread import com.android.settingslib.bluetooth.BluetoothUtils import com.android.settingslib.bluetooth.CachedBluetoothDevice import com.android.settingslib.bluetooth.LocalBluetoothManager -import com.android.settingslib.bluetooth.onPlaybackStarted +import com.android.settingslib.bluetooth.onBroadcastMetadataChanged +import com.android.settingslib.flags.Flags.audioSharingQsDialogImprovement import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Background import javax.inject.Inject @@ -52,6 +55,8 @@ interface AudioSharingInteractor { suspend fun startAudioSharing() suspend fun audioSharingAvailable(): Boolean + + suspend fun qsDialogImprovementAvailable(): Boolean } @SysUISingleton @@ -59,11 +64,14 @@ interface AudioSharingInteractor { class AudioSharingInteractorImpl @Inject constructor( + private val context: Context, private val localBluetoothManager: LocalBluetoothManager?, private val audioSharingRepository: AudioSharingRepository, @Background private val backgroundDispatcher: CoroutineDispatcher, ) : AudioSharingInteractor { + private var previewEnabled: Boolean? = null + override val isAudioSharingOn: Flow<Boolean> = flow { emit(audioSharingAvailable()) } .flatMapLatest { isEnabled -> @@ -93,10 +101,10 @@ constructor( isAudioSharingOn .mapNotNull { audioSharingOn -> if (audioSharingOn) { - // onPlaybackStarted could emit multiple times during one - // audio sharing session, we only perform add source on the - // first time - profile.onPlaybackStarted.firstOrNull() + // onBroadcastMetadataChanged could emit multiple times during one + // audio sharing session, we only perform add source on the first + // time + profile.onBroadcastMetadataChanged.firstOrNull() } else { null } @@ -141,6 +149,20 @@ constructor( override suspend fun audioSharingAvailable(): Boolean { return audioSharingRepository.audioSharingAvailable() } + + override suspend fun qsDialogImprovementAvailable(): Boolean { + return withContext(backgroundDispatcher) { + audioSharingQsDialogImprovement() || isAudioSharingPreviewEnabled() + } + } + + @WorkerThread + private fun isAudioSharingPreviewEnabled(): Boolean { + if (previewEnabled == null) { + previewEnabled = BluetoothUtils.isAudioSharingPreviewEnabled(context.contentResolver) + } + return previewEnabled ?: false + } } @SysUISingleton @@ -160,4 +182,6 @@ class AudioSharingInteractorEmptyImpl @Inject constructor() : AudioSharingIntera override suspend fun startAudioSharing() {} override suspend fun audioSharingAvailable(): Boolean = false + + override suspend fun qsDialogImprovementAvailable(): Boolean = false } diff --git a/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/BluetoothTileDialogViewModel.kt b/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/BluetoothTileDialogViewModel.kt index b255a4f55220..497d8cf2e159 100644 --- a/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/BluetoothTileDialogViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/BluetoothTileDialogViewModel.kt @@ -26,10 +26,10 @@ import android.view.ViewGroup import androidx.annotation.DimenRes import androidx.annotation.StringRes import androidx.annotation.VisibleForTesting +import com.android.app.tracing.coroutines.launchTraced as launch import com.android.internal.jank.InteractionJankMonitor import com.android.internal.logging.UiEventLogger import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcast -import com.android.settingslib.flags.Flags.audioSharingQsDialogImprovement import com.android.systemui.Prefs import com.android.systemui.animation.DialogCuj import com.android.systemui.animation.DialogTransitionAnimator @@ -56,7 +56,6 @@ import kotlinx.coroutines.flow.filterNotNull import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.merge import kotlinx.coroutines.flow.onEach -import com.android.app.tracing.coroutines.launchTraced as launch import kotlinx.coroutines.withContext /** ViewModel for Bluetooth Dialog after clicking on the Bluetooth QS tile. */ @@ -145,7 +144,7 @@ constructor( bluetoothDeviceMetadataInteractor.metadataUpdate, if ( audioSharingInteractor.audioSharingAvailable() && - audioSharingQsDialogImprovement() + audioSharingInteractor.qsDialogImprovementAvailable() ) { audioSharingInteractor.audioSourceStateUpdate } else { @@ -165,7 +164,7 @@ constructor( .launchIn(this) if (audioSharingInteractor.audioSharingAvailable()) { - if (audioSharingQsDialogImprovement()) { + if (audioSharingInteractor.qsDialogImprovementAvailable()) { launch { audioSharingInteractor.handleAudioSourceWhenReady() } } diff --git a/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/dagger/AudioSharingModule.kt b/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/dagger/AudioSharingModule.kt index 8b5fde384837..afe9a1eec0b6 100644 --- a/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/dagger/AudioSharingModule.kt +++ b/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/dagger/AudioSharingModule.kt @@ -55,7 +55,10 @@ interface AudioSharingModule { settingsLibAudioSharingRepository: SettingsLibAudioSharingRepository, @Background backgroundDispatcher: CoroutineDispatcher, ): AudioSharingRepository = - if (Flags.enableLeAudioSharing() && localBluetoothManager != null) { + if ( + (Flags.enableLeAudioSharing() || Flags.audioSharingDeveloperOption()) && + localBluetoothManager != null + ) { AudioSharingRepositoryImpl( localBluetoothManager, settingsLibAudioSharingRepository, @@ -72,7 +75,10 @@ interface AudioSharingModule { impl: Lazy<AudioSharingInteractorImpl>, emptyImpl: Lazy<AudioSharingInteractorEmptyImpl>, ): AudioSharingInteractor = - if (Flags.enableLeAudioSharing() && localBluetoothManager != null) { + if ( + (Flags.enableLeAudioSharing() || Flags.audioSharingDeveloperOption()) && + localBluetoothManager != null + ) { impl.get() } else { emptyImpl.get() @@ -85,7 +91,10 @@ interface AudioSharingModule { audioSharingImpl: Lazy<AudioSharingDeviceItemActionInteractorImpl>, impl: Lazy<DeviceItemActionInteractorImpl>, ): DeviceItemActionInteractor = - if (Flags.enableLeAudioSharing() && localBluetoothManager != null) { + if ( + (Flags.enableLeAudioSharing() || Flags.audioSharingDeveloperOption()) && + localBluetoothManager != null + ) { audioSharingImpl.get() } else { impl.get() @@ -97,7 +106,10 @@ interface AudioSharingModule { localBluetoothManager: LocalBluetoothManager? ): List<DeviceItemFactory> = buildList { add(ActiveMediaDeviceItemFactory()) - if (Flags.enableLeAudioSharing() && localBluetoothManager != null) { + if ( + (Flags.enableLeAudioSharing() || Flags.audioSharingDeveloperOption()) && + localBluetoothManager != null + ) { add(AudioSharingMediaDeviceItemFactory(localBluetoothManager)) add(AvailableAudioSharingMediaDeviceItemFactory(localBluetoothManager)) } @@ -112,7 +124,10 @@ interface AudioSharingModule { localBluetoothManager: LocalBluetoothManager? ): List<DeviceItemType> = buildList { add(DeviceItemType.ACTIVE_MEDIA_BLUETOOTH_DEVICE) - if (Flags.enableLeAudioSharing() && localBluetoothManager != null) { + if ( + (Flags.enableLeAudioSharing() || Flags.audioSharingDeveloperOption()) && + localBluetoothManager != null + ) { add(DeviceItemType.AUDIO_SHARING_MEDIA_BLUETOOTH_DEVICE) add(DeviceItemType.AVAILABLE_AUDIO_SHARING_MEDIA_BLUETOOTH_DEVICE) } diff --git a/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/AudioSharingDeviceItemActionInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/AudioSharingDeviceItemActionInteractorTest.kt index 4d138b488645..5d622eaeb1aa 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/AudioSharingDeviceItemActionInteractorTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/AudioSharingDeviceItemActionInteractorTest.kt @@ -122,9 +122,24 @@ class AudioSharingDeviceItemActionInteractorTest : SysuiTestCase() { @Test @DisableFlags(Flags.FLAG_AUDIO_SHARING_QS_DIALOG_IMPROVEMENT) + fun testOnClick_connectedAudioSharingMediaDevice_flagOff_previewOn_createDialog() { + with(kosmos) { + testScope.runTest { + whenever(BluetoothUtils.isAudioSharingPreviewEnabled(any())).thenReturn(true) + bluetoothTileDialogAudioSharingRepository.setAudioSharingAvailable(true) + actionInteractorImpl.onClick(connectedAudioSharingMediaDeviceItem, dialog) + verify(dialogTransitionAnimator) + .showFromDialog(any(), any(), eq(null), anyBoolean()) + } + } + } + + @Test + @DisableFlags(Flags.FLAG_AUDIO_SHARING_QS_DIALOG_IMPROVEMENT) fun testOnClick_connectedAudioSharingMediaDevice_flagOff_shouldLaunchSettings() { with(kosmos) { testScope.runTest { + whenever(BluetoothUtils.isAudioSharingPreviewEnabled(any())).thenReturn(false) bluetoothTileDialogAudioSharingRepository.setAudioSharingAvailable(true) whenever(cachedBluetoothDevice.device).thenReturn(bluetoothDevice) actionInteractorImpl.onClick(connectedAudioSharingMediaDeviceItem, dialog) diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/bluetooth/qsdialog/AudioSharingInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/bluetooth/qsdialog/AudioSharingInteractorKosmos.kt index 4f4d1da42303..e0c0fbd7f033 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/bluetooth/qsdialog/AudioSharingInteractorKosmos.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/bluetooth/qsdialog/AudioSharingInteractorKosmos.kt @@ -16,12 +16,14 @@ package com.android.systemui.bluetooth.qsdialog +import android.content.applicationContext import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.testDispatcher val Kosmos.audioSharingInteractor: AudioSharingInteractor by Kosmos.Fixture { AudioSharingInteractorImpl( + applicationContext, localBluetoothManager, bluetoothTileDialogAudioSharingRepository, testDispatcher, |