diff options
| author | 2024-09-09 17:35:11 +0800 | |
|---|---|---|
| committer | 2024-10-08 10:44:37 +0800 | |
| commit | b51480a5a628c469ec3580f3529e8097df258781 (patch) | |
| tree | fe71edd1484071261b019b4265b7c6a32dd69aa9 | |
| parent | 1d07441d2951a7e2f35a7c43d6c846f9c5fbfd67 (diff) | |
Implement onclick behavior for audio sharing dialog buttons.
Test: atest
Bug: 360759048
Flag: com.android.settingslib.flags.audio_sharing_qs_dialog_improvement
Change-Id: I3449499acd746e10f0c1c09ea45616735838e8b0
19 files changed, 299 insertions, 15 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/AudioSharingButtonViewModel.kt b/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/AudioSharingButtonViewModel.kt index 5213a0e702d2..a6fb1502ed19 100644 --- a/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/AudioSharingButtonViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/AudioSharingButtonViewModel.kt @@ -40,6 +40,7 @@ class AudioSharingButtonViewModel @AssistedInject constructor( private val localBluetoothManager: LocalBluetoothManager?, + private val audioSharingInteractor: AudioSharingInteractor, private val bluetoothStateInteractor: BluetoothStateInteractor, private val deviceItemInteractor: DeviceItemInteractor, ) : ExclusiveActivatable() { @@ -53,9 +54,10 @@ constructor( override suspend fun onActivated(): Nothing { combine( bluetoothStateInteractor.bluetoothStateUpdate, - deviceItemInteractor.deviceItemUpdate - ) { bluetoothState, deviceItem -> - getButtonState(bluetoothState, deviceItem) + deviceItemInteractor.deviceItemUpdate, + audioSharingInteractor.isAudioSharingOn + ) { bluetoothState, deviceItem, audioSharingOn -> + getButtonState(bluetoothState, deviceItem, audioSharingOn) } .collect { mutableButtonState.value = it } awaitCancellation() @@ -63,13 +65,14 @@ constructor( private fun getButtonState( bluetoothState: Boolean, - deviceItem: List<DeviceItem> + deviceItem: List<DeviceItem>, + audioSharingOn: Boolean ): AudioSharingButtonState { return when { // Don't show button when bluetooth is off !bluetoothState -> AudioSharingButtonState.Gone // Show sharing audio when broadcasting - BluetoothUtils.isBroadcasting(localBluetoothManager) -> + audioSharingOn -> AudioSharingButtonState.Visible( R.string.quick_settings_bluetooth_audio_sharing_button_sharing, isActive = true diff --git a/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/AudioSharingDialogDelegate.kt b/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/AudioSharingDialogDelegate.kt index 6b39d8f43b84..3ac942b769f4 100644 --- a/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/AudioSharingDialogDelegate.kt +++ b/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/AudioSharingDialogDelegate.kt @@ -19,6 +19,7 @@ package com.android.systemui.bluetooth.qsdialog import android.os.Bundle import android.widget.Button import android.widget.TextView +import com.android.internal.logging.UiEventLogger import com.android.settingslib.bluetooth.CachedBluetoothDevice import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.res.R @@ -36,6 +37,7 @@ constructor( @Application private val coroutineScope: CoroutineScope, private val viewModelFactory: AudioSharingDialogViewModel.Factory, private val sysuiDialogFactory: SystemUIDialog.Factory, + private val uiEventLogger: UiEventLogger, ) : SystemUIDialog.Delegate { override fun createDialog(): SystemUIDialog = sysuiDialogFactory.create(this) @@ -44,15 +46,33 @@ constructor( with(dialog.layoutInflater.inflate(R.layout.audio_sharing_dialog, null)) { dialog.setView(this) val subtitleTextView = requireViewById<TextView>(R.id.subtitle) + val shareAudioButton = requireViewById<TextView>(R.id.share_audio_button) val switchActiveButton = requireViewById<Button>(R.id.switch_active_button) val job = coroutineScope.launch { - viewModelFactory.create(cachedBluetoothDevice).dialogState.collect { + val viewModel = viewModelFactory.create(cachedBluetoothDevice, this) + viewModel.dialogState.collect { when (it) { is AudioSharingDialogState.Hide -> dialog.dismiss() is AudioSharingDialogState.Show -> { subtitleTextView.text = it.subtitle switchActiveButton.text = it.switchButtonText + switchActiveButton.setOnClickListener { + viewModel.switchActiveClicked() + uiEventLogger.log( + BluetoothTileDialogUiEvent + .AUDIO_SHARING_DIALOG_SWITCH_ACTIVE_CLICKED + ) + dialog.dismiss() + } + shareAudioButton.setOnClickListener { + viewModel.shareAudioClicked() + uiEventLogger.log( + BluetoothTileDialogUiEvent + .AUDIO_SHARING_DIALOG_SHARE_AUDIO_CLICKED + ) + dialog.dismiss() + } } } } diff --git a/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/AudioSharingDialogViewModel.kt b/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/AudioSharingDialogViewModel.kt index 55686aaf87d2..dc970aea7c41 100644 --- a/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/AudioSharingDialogViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/AudioSharingDialogViewModel.kt @@ -25,11 +25,13 @@ import dagger.assisted.Assisted import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject import kotlinx.coroutines.CoroutineDispatcher +import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.flowOn import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.onStart +import kotlinx.coroutines.launch sealed class AudioSharingDialogState { data object Hide : AudioSharingDialogState() @@ -41,10 +43,11 @@ class AudioSharingDialogViewModel @AssistedInject constructor( deviceItemInteractor: DeviceItemInteractor, - audioSharingInteractor: AudioSharingInteractor, + private val audioSharingInteractor: AudioSharingInteractor, private val context: Context, private val localBluetoothManager: LocalBluetoothManager?, @Assisted private val cachedBluetoothDevice: CachedBluetoothDevice, + @Assisted private val coroutineScope: CoroutineScope, @Background private val backgroundDispatcher: CoroutineDispatcher, ) { val dialogState: Flow<AudioSharingDialogState> = @@ -64,6 +67,14 @@ constructor( .flowOn(backgroundDispatcher) .distinctUntilChanged() + fun switchActiveClicked() { + coroutineScope.launch { audioSharingInteractor.switchActive(cachedBluetoothDevice) } + } + + fun shareAudioClicked() { + coroutineScope.launch { audioSharingInteractor.startAudioSharing() } + } + private fun createShowState( cachedBluetoothDevice: CachedBluetoothDevice ): AudioSharingDialogState { @@ -92,6 +103,7 @@ constructor( interface Factory { fun create( cachedBluetoothDevice: CachedBluetoothDevice, + coroutineScope: CoroutineScope ): AudioSharingDialogViewModel } } 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 227ccfea4394..17f5fccf0fb9 100644 --- a/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/AudioSharingInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/AudioSharingInteractor.kt @@ -19,17 +19,26 @@ package com.android.systemui.bluetooth.qsdialog import com.android.settingslib.bluetooth.BluetoothUtils import com.android.settingslib.bluetooth.CachedBluetoothDevice import com.android.settingslib.bluetooth.LocalBluetoothManager +import com.android.settingslib.volume.data.repository.AudioSharingRepository as SettingsLibAudioSharingRepository import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Background import javax.inject.Inject import kotlinx.coroutines.CoroutineDispatcher +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.withContext /** Holds business logic for the audio sharing state. */ interface AudioSharingInteractor { + val isAudioSharingOn: Flow<Boolean> + suspend fun isAvailableAudioSharingMediaBluetoothDevice( cachedBluetoothDevice: CachedBluetoothDevice ): Boolean + + suspend fun switchActive(cachedBluetoothDevice: CachedBluetoothDevice) + + suspend fun startAudioSharing() } @SysUISingleton @@ -37,9 +46,13 @@ class AudioSharingInteractorImpl @Inject constructor( private val localBluetoothManager: LocalBluetoothManager?, + private val audioSharingRepository: AudioSharingRepository, + settingsLibAudioSharingRepository: SettingsLibAudioSharingRepository, @Background private val backgroundDispatcher: CoroutineDispatcher, ) : AudioSharingInteractor { + override val isAudioSharingOn = settingsLibAudioSharingRepository.inAudioSharing + override suspend fun isAvailableAudioSharingMediaBluetoothDevice( cachedBluetoothDevice: CachedBluetoothDevice ): Boolean { @@ -50,11 +63,25 @@ constructor( ) } } + + override suspend fun switchActive(cachedBluetoothDevice: CachedBluetoothDevice) { + audioSharingRepository.setActive(cachedBluetoothDevice) + } + + override suspend fun startAudioSharing() { + audioSharingRepository.startAudioSharing() + } } @SysUISingleton class AudioSharingInteractorEmptyImpl @Inject constructor() : AudioSharingInteractor { + override val isAudioSharingOn: Flow<Boolean> = flowOf(false) + override suspend fun isAvailableAudioSharingMediaBluetoothDevice( cachedBluetoothDevice: CachedBluetoothDevice ) = false + + override suspend fun switchActive(cachedBluetoothDevice: CachedBluetoothDevice) {} + + override suspend fun startAudioSharing() {} } diff --git a/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/AudioSharingRepository.kt b/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/AudioSharingRepository.kt new file mode 100644 index 000000000000..aa9882ee973d --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/AudioSharingRepository.kt @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.bluetooth.qsdialog + +import com.android.settingslib.bluetooth.CachedBluetoothDevice +import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcast +import com.android.settingslib.bluetooth.LocalBluetoothManager +import com.android.systemui.dagger.SysUISingleton +import com.android.systemui.dagger.qualifiers.Background +import kotlinx.coroutines.CoroutineDispatcher +import kotlinx.coroutines.withContext + +interface AudioSharingRepository { + + suspend fun setActive(cachedBluetoothDevice: CachedBluetoothDevice) + + suspend fun startAudioSharing() +} + +@SysUISingleton +class AudioSharingRepositoryImpl( + private val localBluetoothManager: LocalBluetoothManager, + @Background private val backgroundDispatcher: CoroutineDispatcher, +) : AudioSharingRepository { + + private val leAudioBroadcastProfile: LocalBluetoothLeBroadcast? + get() = localBluetoothManager.profileManager?.leAudioBroadcastProfile + + override suspend fun setActive(cachedBluetoothDevice: CachedBluetoothDevice) { + withContext(backgroundDispatcher) { cachedBluetoothDevice.setActive() } + } + + override suspend fun startAudioSharing() { + withContext(backgroundDispatcher) { leAudioBroadcastProfile?.startPrivateBroadcast() } + } +} + +@SysUISingleton +class AudioSharingRepositoryEmptyImpl : AudioSharingRepository { + + override suspend fun setActive(cachedBluetoothDevice: CachedBluetoothDevice) {} + + override suspend fun startAudioSharing() {} +} diff --git a/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/BluetoothTileDialogUiEvent.kt b/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/BluetoothTileDialogUiEvent.kt index 12a6626314cd..aad233fe40ca 100644 --- a/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/BluetoothTileDialogUiEvent.kt +++ b/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/BluetoothTileDialogUiEvent.kt @@ -55,7 +55,11 @@ enum class BluetoothTileDialogUiEvent(val metricId: Int) : UiEventLogger.UiEvent LAUNCH_SETTINGS_NOT_SHARING_CONNECTED_LE_DEVICE_CLICKED(1720), @Deprecated("Use case no longer needed") @UiEvent(doc = "Not broadcasting, having two connected, the active LE audio devices is clicked") - LAUNCH_SETTINGS_NOT_SHARING_ACTIVE_LE_DEVICE_CLICKED(1881); + LAUNCH_SETTINGS_NOT_SHARING_ACTIVE_LE_DEVICE_CLICKED(1881), + @UiEvent(doc = "Clicked on switch active button on audio sharing dialog") + AUDIO_SHARING_DIALOG_SWITCH_ACTIVE_CLICKED(1890), + @UiEvent(doc = "Clicked on share audio button on audio sharing dialog") + AUDIO_SHARING_DIALOG_SHARE_AUDIO_CLICKED(1891); override fun getId() = metricId } 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 3b1cf07adf19..78506323327f 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 @@ -18,12 +18,16 @@ package com.android.systemui.bluetooth.qsdialog.dagger import com.android.settingslib.bluetooth.BluetoothUtils import com.android.settingslib.bluetooth.LocalBluetoothManager +import com.android.settingslib.flags.Flags import com.android.systemui.bluetooth.qsdialog.ActiveMediaDeviceItemFactory import com.android.systemui.bluetooth.qsdialog.AudioSharingDeviceItemActionInteractorImpl import com.android.systemui.bluetooth.qsdialog.AudioSharingInteractor import com.android.systemui.bluetooth.qsdialog.AudioSharingInteractorEmptyImpl import com.android.systemui.bluetooth.qsdialog.AudioSharingInteractorImpl import com.android.systemui.bluetooth.qsdialog.AudioSharingMediaDeviceItemFactory +import com.android.systemui.bluetooth.qsdialog.AudioSharingRepository +import com.android.systemui.bluetooth.qsdialog.AudioSharingRepositoryEmptyImpl +import com.android.systemui.bluetooth.qsdialog.AudioSharingRepositoryImpl import com.android.systemui.bluetooth.qsdialog.AvailableAudioSharingMediaDeviceItemFactory import com.android.systemui.bluetooth.qsdialog.AvailableMediaDeviceItemFactory import com.android.systemui.bluetooth.qsdialog.ConnectedDeviceItemFactory @@ -33,9 +37,11 @@ import com.android.systemui.bluetooth.qsdialog.DeviceItemFactory import com.android.systemui.bluetooth.qsdialog.DeviceItemType import com.android.systemui.bluetooth.qsdialog.SavedDeviceItemFactory import com.android.systemui.dagger.SysUISingleton +import com.android.systemui.dagger.qualifiers.Background import dagger.Lazy import dagger.Module import dagger.Provides +import kotlinx.coroutines.CoroutineDispatcher /** Dagger module for audio sharing code for BT QS dialog */ @Module @@ -44,6 +50,22 @@ interface AudioSharingModule { companion object { @Provides @SysUISingleton + fun provideAudioSharingRepository( + localBluetoothManager: LocalBluetoothManager?, + @Background backgroundDispatcher: CoroutineDispatcher, + ): AudioSharingRepository = + if ( + Flags.enableLeAudioSharing() && + Flags.audioSharingQsDialogImprovement() && + localBluetoothManager != null + ) { + AudioSharingRepositoryImpl(localBluetoothManager, backgroundDispatcher) + } else { + AudioSharingRepositoryEmptyImpl() + } + + @Provides + @SysUISingleton fun provideAudioSharingInteractor( impl: Lazy<AudioSharingInteractorImpl>, emptyImpl: Lazy<AudioSharingInteractorEmptyImpl>, diff --git a/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/AudioSharingButtonViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/AudioSharingButtonViewModelTest.kt index fa9c27e9a438..87a3143c6bb2 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/AudioSharingButtonViewModelTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/AudioSharingButtonViewModelTest.kt @@ -28,7 +28,9 @@ import com.android.systemui.SysuiTestCase import com.android.systemui.coroutines.collectLastValue import com.android.systemui.lifecycle.activateIn import com.android.systemui.res.R +import com.android.systemui.testKosmos import com.android.systemui.util.mockito.whenever +import com.android.systemui.volume.data.repository.audioSharingRepository as SettingsLibAudioSharingRepository import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.MutableSharedFlow @@ -48,6 +50,7 @@ import org.mockito.Mock @RunWith(AndroidJUnit4::class) @TestableLooper.RunWithLooper(setAsMainLooper = true) class AudioSharingButtonViewModelTest : SysuiTestCase() { + private val kosmos = testKosmos() private val testDispatcher = UnconfinedTestDispatcher() private val testScope = TestScope(testDispatcher) private val bluetoothState = MutableStateFlow(false) @@ -69,6 +72,7 @@ class AudioSharingButtonViewModelTest : SysuiTestCase() { audioSharingButtonViewModel = AudioSharingButtonViewModel( localBluetoothManager, + kosmos.audioSharingInteractor, bluetoothStateInteractor, deviceItemInteractor, ) @@ -105,12 +109,12 @@ class AudioSharingButtonViewModelTest : SysuiTestCase() { @Test fun testButtonStateUpdate_isBroadcasting_returnSharingAudio() { testScope.runTest { - whenever(BluetoothUtils.isBroadcasting(localBluetoothManager)).thenReturn(true) - val actual by collectLastValue(audioSharingButtonViewModel.audioSharingButtonStateUpdate) bluetoothState.value = true deviceItemUpdate.emit(listOf()) + kosmos.SettingsLibAudioSharingRepository.setInAudioSharing(true) + runCurrent() assertThat(actual) @@ -126,7 +130,6 @@ class AudioSharingButtonViewModelTest : SysuiTestCase() { @Test fun testButtonStateUpdate_hasSource_returnGone() { testScope.runTest { - whenever(BluetoothUtils.isBroadcasting(localBluetoothManager)).thenReturn(false) whenever(deviceItem.cachedBluetoothDevice).thenReturn(cachedBluetoothDevice) whenever( BluetoothUtils.hasConnectedBroadcastSource( @@ -149,7 +152,6 @@ class AudioSharingButtonViewModelTest : SysuiTestCase() { @Test fun testButtonStateUpdate_hasActiveDevice_returnAudioSharing() { testScope.runTest { - whenever(BluetoothUtils.isBroadcasting(localBluetoothManager)).thenReturn(false) whenever(deviceItem.cachedBluetoothDevice).thenReturn(cachedBluetoothDevice) whenever( BluetoothUtils.hasConnectedBroadcastSource( diff --git a/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/AudioSharingDialogDelegateTest.kt b/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/AudioSharingDialogDelegateTest.kt index 1e0a7db6b688..25b85b514435 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/AudioSharingDialogDelegateTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/AudioSharingDialogDelegateTest.kt @@ -76,11 +76,12 @@ class AudioSharingDialogDelegateTest : SysuiTestCase() { testScope.runTest { val availableDeviceName = "name" whenever(cachedBluetoothDevice.name).thenReturn(availableDeviceName) - val dialog = underTest.createDialog() + val dialog = spy(underTest.createDialog()) dialog.show() runCurrent() val subtitleTextView = dialog.findViewById<TextView>(R.id.subtitle) val switchActiveButton = dialog.findViewById<Button>(R.id.switch_active_button) + val shareAudioButton = dialog.findViewById<Button>(R.id.share_audio_button) val subtitle = context.getString( R.string.quick_settings_bluetooth_audio_sharing_dialog_subtitle, @@ -94,7 +95,11 @@ class AudioSharingDialogDelegateTest : SysuiTestCase() { ) assertThat(subtitleTextView.text).isEqualTo(subtitle) assertThat(switchActiveButton.text).isEqualTo(switchButtonText) - dialog.dismiss() + assertThat(switchActiveButton.hasOnClickListeners()).isTrue() + assertThat(shareAudioButton.hasOnClickListeners()).isTrue() + + switchActiveButton.performClick() + verify(dialog).dismiss() } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/AudioSharingRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/AudioSharingRepositoryTest.kt new file mode 100644 index 000000000000..868afee3972c --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/AudioSharingRepositoryTest.kt @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.systemui.bluetooth.qsdialog + +import android.testing.AndroidTestingRunner +import android.testing.TestableLooper +import androidx.test.filters.SmallTest +import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcast +import com.android.settingslib.bluetooth.LocalBluetoothProfileManager +import com.android.systemui.SysuiTestCase +import com.android.systemui.kosmos.testDispatcher +import com.android.systemui.kosmos.testScope +import com.android.systemui.testKosmos +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.test.runTest +import org.junit.Before +import org.junit.Rule +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.Mock +import org.mockito.junit.MockitoJUnit +import org.mockito.junit.MockitoRule +import org.mockito.kotlin.verify +import org.mockito.kotlin.whenever + +@ExperimentalCoroutinesApi +@SmallTest +@RunWith(AndroidTestingRunner::class) +@TestableLooper.RunWithLooper(setAsMainLooper = true) +class AudioSharingRepositoryTest : SysuiTestCase() { + @get:Rule val mockitoRule: MockitoRule = MockitoJUnit.rule() + @Mock private lateinit var profileManager: LocalBluetoothProfileManager + @Mock private lateinit var leAudioBroadcastProfile: LocalBluetoothLeBroadcast + private val kosmos = testKosmos() + private lateinit var underTest: AudioSharingRepository + + @Before + fun setUp() { + whenever(kosmos.localBluetoothManager.profileManager).thenReturn(profileManager) + whenever(profileManager.leAudioBroadcastProfile).thenReturn(leAudioBroadcastProfile) + underTest = AudioSharingRepositoryImpl(kosmos.localBluetoothManager, kosmos.testDispatcher) + } + + @Test + fun testSwitchActive() = + with(kosmos) { + testScope.runTest { + underTest.setActive(cachedBluetoothDevice) + verify(cachedBluetoothDevice).setActive() + } + } + + @Test + fun testStartAudioSharing() = + with(kosmos) { + testScope.runTest { + underTest.startAudioSharing() + verify(leAudioBroadcastProfile).startPrivateBroadcast() + } + } +} diff --git a/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/AudioSharingButtonViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/bluetooth/qsdialog/AudioSharingButtonViewModelKosmos.kt index df10f03120de..cac4ff3fe52b 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/AudioSharingButtonViewModelKosmos.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/bluetooth/qsdialog/AudioSharingButtonViewModelKosmos.kt @@ -22,6 +22,7 @@ val Kosmos.audioSharingButtonViewModel: AudioSharingButtonViewModel by Kosmos.Fixture { AudioSharingButtonViewModel( localBluetoothManager, + audioSharingInteractor, bluetoothStateInteractor, deviceItemInteractor, ) diff --git a/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/AudioSharingDeviceItemActionInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/bluetooth/qsdialog/AudioSharingDeviceItemActionInteractorKosmos.kt index ea167df839f6..ea167df839f6 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/AudioSharingDeviceItemActionInteractorKosmos.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/bluetooth/qsdialog/AudioSharingDeviceItemActionInteractorKosmos.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/AudioSharingDialogViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/bluetooth/qsdialog/AudioSharingDialogViewModelKosmos.kt index 3ffd771014ba..b8899de8fdc7 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/AudioSharingDialogViewModelKosmos.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/bluetooth/qsdialog/AudioSharingDialogViewModelKosmos.kt @@ -17,11 +17,13 @@ package com.android.systemui.bluetooth.qsdialog import android.content.applicationContext +import com.android.internal.logging.uiEventLogger import com.android.settingslib.bluetooth.CachedBluetoothDevice import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.testDispatcher import com.android.systemui.kosmos.testScope import com.android.systemui.statusbar.phone.systemUIDialogDotFactory +import kotlinx.coroutines.CoroutineScope import org.mockito.kotlin.mock val Kosmos.cachedBluetoothDevice: CachedBluetoothDevice by Kosmos.Fixture { mock {} } @@ -34,6 +36,7 @@ val Kosmos.audioSharingDialogViewModel: AudioSharingDialogViewModel by applicationContext, localBluetoothManager, cachedBluetoothDevice, + testScope.backgroundScope, testDispatcher ) } @@ -42,7 +45,8 @@ val Kosmos.audioSharingDialogViewModelFactory: AudioSharingDialogViewModel.Facto Kosmos.Fixture { object : AudioSharingDialogViewModel.Factory { override fun create( - cachedBluetoothDevice: CachedBluetoothDevice + cachedBluetoothDevice: CachedBluetoothDevice, + coroutineScope: CoroutineScope ): AudioSharingDialogViewModel { return audioSharingDialogViewModel } @@ -56,5 +60,6 @@ val Kosmos.audioSharingDialogDelegate: AudioSharingDialogDelegate by testScope.backgroundScope, audioSharingDialogViewModelFactory, systemUIDialogDotFactory, + uiEventLogger ) } diff --git a/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/AudioSharingInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/bluetooth/qsdialog/AudioSharingInteractorKosmos.kt index 8e473bee1450..26a9fe3f7a6c 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/AudioSharingInteractorKosmos.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/bluetooth/qsdialog/AudioSharingInteractorKosmos.kt @@ -18,11 +18,14 @@ package com.android.systemui.bluetooth.qsdialog import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.testDispatcher +import com.android.systemui.volume.data.repository.audioSharingRepository as settingsLibAudioSharingRepository val Kosmos.audioSharingInteractor: AudioSharingInteractor by Kosmos.Fixture { AudioSharingInteractorImpl( localBluetoothManager, + bluetoothTileDialogAudioSharingRepository, + settingsLibAudioSharingRepository, testDispatcher, ) } diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/bluetooth/qsdialog/AudioSharingRepositoryKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/bluetooth/qsdialog/AudioSharingRepositoryKosmos.kt new file mode 100644 index 000000000000..d15d0e5ac7ff --- /dev/null +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/bluetooth/qsdialog/AudioSharingRepositoryKosmos.kt @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.bluetooth.qsdialog + +import com.android.systemui.kosmos.Kosmos + +val Kosmos.bluetoothTileDialogAudioSharingRepository by + Kosmos.Fixture { FakeAudioSharingRepository() } diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/bluetooth/qsdialog/BluetoothDeviceMetadataInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/bluetooth/qsdialog/BluetoothDeviceMetadataInteractorKosmos.kt index 969e26a8d884..969e26a8d884 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/bluetooth/qsdialog/BluetoothDeviceMetadataInteractorKosmos.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/bluetooth/qsdialog/BluetoothDeviceMetadataInteractorKosmos.kt diff --git a/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/BluetoothStateInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/bluetooth/qsdialog/BluetoothStateInteractorKosmos.kt index aaa918c9ff35..aaa918c9ff35 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/BluetoothStateInteractorKosmos.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/bluetooth/qsdialog/BluetoothStateInteractorKosmos.kt diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/bluetooth/qsdialog/DeviceItemActionInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/bluetooth/qsdialog/DeviceItemActionInteractorKosmos.kt index b5b2f5e3e802..b5b2f5e3e802 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/bluetooth/qsdialog/DeviceItemActionInteractorKosmos.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/bluetooth/qsdialog/DeviceItemActionInteractorKosmos.kt diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/bluetooth/qsdialog/FakeAudioSharingRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/bluetooth/qsdialog/FakeAudioSharingRepository.kt new file mode 100644 index 000000000000..0e5972f3637f --- /dev/null +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/bluetooth/qsdialog/FakeAudioSharingRepository.kt @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.bluetooth.qsdialog + +import com.android.settingslib.bluetooth.CachedBluetoothDevice + +class FakeAudioSharingRepository : AudioSharingRepository { + + override suspend fun setActive(cachedBluetoothDevice: CachedBluetoothDevice) {} + + override suspend fun startAudioSharing() {} +} |