Loading packages/SystemUI/multivalentTests/src/com/android/systemui/volume/ui/navigation/VolumeNavigatorTest.kt 0 → 100644 +95 −0 Original line number Diff line number Diff line /* * 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.volume.ui.navigation import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.internal.logging.uiEventLoggerFake import com.android.systemui.SysuiTestCase import com.android.systemui.coroutines.collectLastValue import com.android.systemui.kosmos.testDispatcher import com.android.systemui.kosmos.testScope import com.android.systemui.plugins.ActivityStarter import com.android.systemui.plugins.activityStarter import com.android.systemui.testKosmos import com.android.systemui.volume.domain.model.VolumePanelRoute import com.android.systemui.volume.panel.domain.interactor.volumePanelGlobalStateInteractor import com.android.systemui.volume.panel.ui.viewmodel.volumePanelViewModelFactory import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.test.runCurrent import kotlinx.coroutines.test.runTest import org.junit.Test import org.junit.runner.RunWith import org.mockito.ArgumentMatchers.anyBoolean import org.mockito.ArgumentMatchers.anyInt import org.mockito.kotlin.any import org.mockito.kotlin.mock import org.mockito.kotlin.whenever @OptIn(ExperimentalCoroutinesApi::class) @SmallTest @RunWith(AndroidJUnit4::class) class VolumeNavigatorTest : SysuiTestCase() { private val kosmos = testKosmos() private val underTest: VolumeNavigator = with(kosmos) { VolumeNavigator( testScope.backgroundScope, testDispatcher, mock {}, activityStarter, volumePanelViewModelFactory, mock { on { create(any(), anyInt(), anyBoolean(), any()) }.thenReturn(mock {}) on { applicationContext }.thenReturn(context) }, uiEventLoggerFake, volumePanelGlobalStateInteractor, ) } @Test fun showNewVolumePanel_keyguardLocked_notShown() = with(kosmos) { testScope.runTest { val panelState by collectLastValue(volumePanelGlobalStateInteractor.globalState) underTest.openVolumePanel(VolumePanelRoute.COMPOSE_VOLUME_PANEL) runCurrent() assertThat(panelState!!.isVisible).isFalse() } } @Test fun showNewVolumePanel_keyguardUnlocked_shown() = with(kosmos) { testScope.runTest { whenever(activityStarter.dismissKeyguardThenExecute(any(), any(), anyBoolean())) .then { (it.arguments[0] as ActivityStarter.OnDismissAction).onDismiss() } val panelState by collectLastValue(volumePanelGlobalStateInteractor.globalState) underTest.openVolumePanel(VolumePanelRoute.COMPOSE_VOLUME_PANEL) runCurrent() assertThat(panelState!!.isVisible).isTrue() } } } packages/SystemUI/src/com/android/systemui/volume/domain/interactor/AudioOutputInteractor.kt +23 −22 Original line number Diff line number Diff line Loading @@ -18,8 +18,6 @@ package com.android.systemui.volume.domain.interactor import android.bluetooth.BluetoothAdapter import android.media.AudioDeviceInfo import android.media.AudioDeviceInfo.TYPE_WIRED_HEADPHONES import android.media.AudioDeviceInfo.TYPE_WIRED_HEADSET import com.android.settingslib.bluetooth.CachedBluetoothDevice import com.android.settingslib.bluetooth.LocalBluetoothManager import com.android.settingslib.media.BluetoothMediaDevice Loading Loading @@ -81,27 +79,29 @@ constructor( val isInAudioSharing: Flow<Boolean> = audioSharingRepository.inAudioSharing private fun AudioDeviceInfo.toAudioOutputDevice(): AudioOutputDevice { if (type == TYPE_WIRED_HEADPHONES || type == TYPE_WIRED_HEADSET) { return AudioOutputDevice.Wired( name = productName.toString(), icon = deviceIconInteractor.loadIcon(type), if ( BluetoothAdapter.checkBluetoothAddress(address) && localBluetoothManager != null && bluetoothAdapter != null ) { val remoteDevice = bluetoothAdapter.getRemoteDevice(address) localBluetoothManager.cachedDeviceManager.findDevice(remoteDevice)?.let { device: CachedBluetoothDevice -> return AudioOutputDevice.Bluetooth( name = device.name, icon = deviceIconInteractor.loadIcon(device), cachedBluetoothDevice = device, ) } val cachedBluetoothDevice: CachedBluetoothDevice? = if (address.isEmpty() || localBluetoothManager == null || bluetoothAdapter == null) { null } else { val remoteDevice = bluetoothAdapter.getRemoteDevice(address) localBluetoothManager.cachedDeviceManager.findDevice(remoteDevice) } return cachedBluetoothDevice?.let { AudioOutputDevice.Bluetooth( name = it.name, icon = deviceIconInteractor.loadIcon(it), cachedBluetoothDevice = it, // Built-in device has an empty address if (address.isNotEmpty()) { return AudioOutputDevice.Wired( name = productName.toString(), icon = deviceIconInteractor.loadIcon(type), ) } ?: AudioOutputDevice.BuiltIn( return AudioOutputDevice.BuiltIn( name = productName.toString(), icon = deviceIconInteractor.loadIcon(type), ) Loading @@ -115,7 +115,8 @@ constructor( icon = icon, cachedBluetoothDevice = cachedDevice, ) deviceType == MediaDeviceType.TYPE_3POINT5_MM_AUDIO_DEVICE -> deviceType == MediaDeviceType.TYPE_3POINT5_MM_AUDIO_DEVICE || deviceType == MediaDeviceType.TYPE_USB_C_AUDIO_DEVICE -> AudioOutputDevice.Wired( name = name, icon = icon, Loading packages/SystemUI/src/com/android/systemui/volume/ui/navigation/VolumeNavigator.kt +3 −3 Original line number Diff line number Diff line Loading @@ -98,12 +98,12 @@ constructor( private fun showNewVolumePanel() { activityStarter.dismissKeyguardThenExecute( { /* action = */ { volumePanelGlobalStateInteractor.setVisible(true) false }, {}, true /* cancel = */ {}, /* afterKeyguardGone = */ true, ) } Loading packages/SystemUI/tests/utils/src/com/android/systemui/volume/data/repository/TestAudioDevicesFactory.kt +6 −3 Original line number Diff line number Diff line Loading @@ -33,19 +33,22 @@ object TestAudioDevicesFactory { ) } fun wiredDevice(deviceName: String = "wired"): AudioDeviceInfo { fun wiredDevice( deviceName: String = "wired", deviceAddress: String = "card=1;device=0", ): AudioDeviceInfo { return AudioDeviceInfo( AudioDevicePort.createForTesting( AudioDeviceInfo.TYPE_WIRED_HEADPHONES, deviceName, "", deviceAddress, ) ) } fun bluetoothDevice( deviceName: String = "bt", deviceAddress: String = "test_address", deviceAddress: String = "00:43:A8:23:10:F0", ): AudioDeviceInfo { return AudioDeviceInfo( AudioDevicePort.createForTesting( Loading Loading
packages/SystemUI/multivalentTests/src/com/android/systemui/volume/ui/navigation/VolumeNavigatorTest.kt 0 → 100644 +95 −0 Original line number Diff line number Diff line /* * 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.volume.ui.navigation import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.internal.logging.uiEventLoggerFake import com.android.systemui.SysuiTestCase import com.android.systemui.coroutines.collectLastValue import com.android.systemui.kosmos.testDispatcher import com.android.systemui.kosmos.testScope import com.android.systemui.plugins.ActivityStarter import com.android.systemui.plugins.activityStarter import com.android.systemui.testKosmos import com.android.systemui.volume.domain.model.VolumePanelRoute import com.android.systemui.volume.panel.domain.interactor.volumePanelGlobalStateInteractor import com.android.systemui.volume.panel.ui.viewmodel.volumePanelViewModelFactory import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.test.runCurrent import kotlinx.coroutines.test.runTest import org.junit.Test import org.junit.runner.RunWith import org.mockito.ArgumentMatchers.anyBoolean import org.mockito.ArgumentMatchers.anyInt import org.mockito.kotlin.any import org.mockito.kotlin.mock import org.mockito.kotlin.whenever @OptIn(ExperimentalCoroutinesApi::class) @SmallTest @RunWith(AndroidJUnit4::class) class VolumeNavigatorTest : SysuiTestCase() { private val kosmos = testKosmos() private val underTest: VolumeNavigator = with(kosmos) { VolumeNavigator( testScope.backgroundScope, testDispatcher, mock {}, activityStarter, volumePanelViewModelFactory, mock { on { create(any(), anyInt(), anyBoolean(), any()) }.thenReturn(mock {}) on { applicationContext }.thenReturn(context) }, uiEventLoggerFake, volumePanelGlobalStateInteractor, ) } @Test fun showNewVolumePanel_keyguardLocked_notShown() = with(kosmos) { testScope.runTest { val panelState by collectLastValue(volumePanelGlobalStateInteractor.globalState) underTest.openVolumePanel(VolumePanelRoute.COMPOSE_VOLUME_PANEL) runCurrent() assertThat(panelState!!.isVisible).isFalse() } } @Test fun showNewVolumePanel_keyguardUnlocked_shown() = with(kosmos) { testScope.runTest { whenever(activityStarter.dismissKeyguardThenExecute(any(), any(), anyBoolean())) .then { (it.arguments[0] as ActivityStarter.OnDismissAction).onDismiss() } val panelState by collectLastValue(volumePanelGlobalStateInteractor.globalState) underTest.openVolumePanel(VolumePanelRoute.COMPOSE_VOLUME_PANEL) runCurrent() assertThat(panelState!!.isVisible).isTrue() } } }
packages/SystemUI/src/com/android/systemui/volume/domain/interactor/AudioOutputInteractor.kt +23 −22 Original line number Diff line number Diff line Loading @@ -18,8 +18,6 @@ package com.android.systemui.volume.domain.interactor import android.bluetooth.BluetoothAdapter import android.media.AudioDeviceInfo import android.media.AudioDeviceInfo.TYPE_WIRED_HEADPHONES import android.media.AudioDeviceInfo.TYPE_WIRED_HEADSET import com.android.settingslib.bluetooth.CachedBluetoothDevice import com.android.settingslib.bluetooth.LocalBluetoothManager import com.android.settingslib.media.BluetoothMediaDevice Loading Loading @@ -81,27 +79,29 @@ constructor( val isInAudioSharing: Flow<Boolean> = audioSharingRepository.inAudioSharing private fun AudioDeviceInfo.toAudioOutputDevice(): AudioOutputDevice { if (type == TYPE_WIRED_HEADPHONES || type == TYPE_WIRED_HEADSET) { return AudioOutputDevice.Wired( name = productName.toString(), icon = deviceIconInteractor.loadIcon(type), if ( BluetoothAdapter.checkBluetoothAddress(address) && localBluetoothManager != null && bluetoothAdapter != null ) { val remoteDevice = bluetoothAdapter.getRemoteDevice(address) localBluetoothManager.cachedDeviceManager.findDevice(remoteDevice)?.let { device: CachedBluetoothDevice -> return AudioOutputDevice.Bluetooth( name = device.name, icon = deviceIconInteractor.loadIcon(device), cachedBluetoothDevice = device, ) } val cachedBluetoothDevice: CachedBluetoothDevice? = if (address.isEmpty() || localBluetoothManager == null || bluetoothAdapter == null) { null } else { val remoteDevice = bluetoothAdapter.getRemoteDevice(address) localBluetoothManager.cachedDeviceManager.findDevice(remoteDevice) } return cachedBluetoothDevice?.let { AudioOutputDevice.Bluetooth( name = it.name, icon = deviceIconInteractor.loadIcon(it), cachedBluetoothDevice = it, // Built-in device has an empty address if (address.isNotEmpty()) { return AudioOutputDevice.Wired( name = productName.toString(), icon = deviceIconInteractor.loadIcon(type), ) } ?: AudioOutputDevice.BuiltIn( return AudioOutputDevice.BuiltIn( name = productName.toString(), icon = deviceIconInteractor.loadIcon(type), ) Loading @@ -115,7 +115,8 @@ constructor( icon = icon, cachedBluetoothDevice = cachedDevice, ) deviceType == MediaDeviceType.TYPE_3POINT5_MM_AUDIO_DEVICE -> deviceType == MediaDeviceType.TYPE_3POINT5_MM_AUDIO_DEVICE || deviceType == MediaDeviceType.TYPE_USB_C_AUDIO_DEVICE -> AudioOutputDevice.Wired( name = name, icon = icon, Loading
packages/SystemUI/src/com/android/systemui/volume/ui/navigation/VolumeNavigator.kt +3 −3 Original line number Diff line number Diff line Loading @@ -98,12 +98,12 @@ constructor( private fun showNewVolumePanel() { activityStarter.dismissKeyguardThenExecute( { /* action = */ { volumePanelGlobalStateInteractor.setVisible(true) false }, {}, true /* cancel = */ {}, /* afterKeyguardGone = */ true, ) } Loading
packages/SystemUI/tests/utils/src/com/android/systemui/volume/data/repository/TestAudioDevicesFactory.kt +6 −3 Original line number Diff line number Diff line Loading @@ -33,19 +33,22 @@ object TestAudioDevicesFactory { ) } fun wiredDevice(deviceName: String = "wired"): AudioDeviceInfo { fun wiredDevice( deviceName: String = "wired", deviceAddress: String = "card=1;device=0", ): AudioDeviceInfo { return AudioDeviceInfo( AudioDevicePort.createForTesting( AudioDeviceInfo.TYPE_WIRED_HEADPHONES, deviceName, "", deviceAddress, ) ) } fun bluetoothDevice( deviceName: String = "bt", deviceAddress: String = "test_address", deviceAddress: String = "00:43:A8:23:10:F0", ): AudioDeviceInfo { return AudioDeviceInfo( AudioDevicePort.createForTesting( Loading