Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a67c924d authored by chelseahao's avatar chelseahao
Browse files

Use `audioSharingInteractor.audioSharingAvailable` instead of calling BluetoothUtils.

Also fix a minor bug: previously the dialog only listen to `onAclConnectionStateChanged` when a device is disconnecting as we assume that `onProfileConnectionStateChanged` must be triggered right after if the device is connecting, however this is not true for BLE devices as they don't have profiles. We should remove that restriction.

Test: atest
Bug: b/360759048 b/358276696
Flag: com.android.settingslib.flags.enable_le_audio_sharing
Change-Id: Ibc6c9f3801722daa1be5556ded18061c64d0ddfb
parent 067646f5
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -63,6 +63,10 @@ constructor(
            logger.logDeviceClickInAudioSharingWhenEnabled(inAudioSharing)

            when {
                deviceItem.type == DeviceItemType.AUDIO_SHARING_MEDIA_BLUETOOTH_DEVICE -> {
                    // Do nothing if the device is in audio sharing session
                    uiEventLogger.log(BluetoothTileDialogUiEvent.AUDIO_SHARING_DEVICE_CLICKED)
                }
                deviceItem.type ==
                    DeviceItemType.AVAILABLE_AUDIO_SHARING_MEDIA_BLUETOOTH_DEVICE -> {
                    if (audioSharingQsDialogImprovement()) {
+1 −3
Original line number Diff line number Diff line
@@ -44,9 +44,6 @@ constructor(
                        disconnect()
                        uiEventLogger.log(BluetoothTileDialogUiEvent.ACTIVE_DEVICE_DISCONNECT)
                    }
                    DeviceItemType.AUDIO_SHARING_MEDIA_BLUETOOTH_DEVICE -> {
                        uiEventLogger.log(BluetoothTileDialogUiEvent.AUDIO_SHARING_DEVICE_CLICKED)
                    }
                    DeviceItemType.AVAILABLE_MEDIA_BLUETOOTH_DEVICE -> {
                        setActive()
                        uiEventLogger.log(BluetoothTileDialogUiEvent.CONNECTED_DEVICE_SET_ACTIVE)
@@ -61,6 +58,7 @@ constructor(
                        connect()
                        uiEventLogger.log(BluetoothTileDialogUiEvent.SAVED_DEVICE_CONNECT)
                    }
                    DeviceItemType.AUDIO_SHARING_MEDIA_BLUETOOTH_DEVICE,
                    DeviceItemType.AVAILABLE_AUDIO_SHARING_MEDIA_BLUETOOTH_DEVICE -> {
                        // Do nothing. Should already be handled in
                        // AudioSharingDeviceItemActionInteractor.
+20 −3
Original line number Diff line number Diff line
@@ -42,8 +42,16 @@ abstract class DeviceItemFactory {
        context: Context,
        cachedDevice: CachedBluetoothDevice,
        audioManager: AudioManager,
        audioSharingAvailable: Boolean,
    ): Boolean

    // Overloaded that defaults audioSharingAvailable to false
    fun isFilterMatched(
        context: Context,
        cachedDevice: CachedBluetoothDevice,
        audioManager: AudioManager,
    ): Boolean = isFilterMatched(context, cachedDevice, audioManager, false)

    abstract fun create(context: Context, cachedDevice: CachedBluetoothDevice): DeviceItem

    companion object {
@@ -80,6 +88,7 @@ internal open class ActiveMediaDeviceItemFactory : DeviceItemFactory() {
        context: Context,
        cachedDevice: CachedBluetoothDevice,
        audioManager: AudioManager,
        audioSharingAvailable: Boolean,
    ): Boolean {
        return BluetoothUtils.isActiveMediaDevice(cachedDevice) &&
            BluetoothUtils.isAvailableMediaBluetoothDevice(cachedDevice, audioManager)
@@ -105,8 +114,9 @@ internal class AudioSharingMediaDeviceItemFactory(
        context: Context,
        cachedDevice: CachedBluetoothDevice,
        audioManager: AudioManager,
        audioSharingAvailable: Boolean,
    ): Boolean {
        return BluetoothUtils.isAudioSharingEnabled() &&
        return audioSharingAvailable &&
            BluetoothUtils.hasConnectedBroadcastSource(cachedDevice, localBluetoothManager)
    }

@@ -131,9 +141,10 @@ internal class AvailableAudioSharingMediaDeviceItemFactory(
        context: Context,
        cachedDevice: CachedBluetoothDevice,
        audioManager: AudioManager,
        audioSharingAvailable: Boolean,
    ): Boolean {
        return BluetoothUtils.isAudioSharingEnabled() &&
            super.isFilterMatched(context, cachedDevice, audioManager) &&
        return audioSharingAvailable &&
            super.isFilterMatched(context, cachedDevice, audioManager, true) &&
            BluetoothUtils.isAvailableAudioSharingMediaBluetoothDevice(
                cachedDevice,
                localBluetoothManager,
@@ -160,6 +171,7 @@ internal class ActiveHearingDeviceItemFactory : ActiveMediaDeviceItemFactory() {
        context: Context,
        cachedDevice: CachedBluetoothDevice,
        audioManager: AudioManager,
        audioSharingAvailable: Boolean,
    ): Boolean {
        return BluetoothUtils.isActiveMediaDevice(cachedDevice) &&
            BluetoothUtils.isAvailableHearingDevice(cachedDevice)
@@ -171,6 +183,7 @@ open class AvailableMediaDeviceItemFactory : DeviceItemFactory() {
        context: Context,
        cachedDevice: CachedBluetoothDevice,
        audioManager: AudioManager,
        audioSharingAvailable: Boolean,
    ): Boolean {
        return !BluetoothUtils.isActiveMediaDevice(cachedDevice) &&
            BluetoothUtils.isAvailableMediaBluetoothDevice(cachedDevice, audioManager)
@@ -195,6 +208,7 @@ internal class AvailableHearingDeviceItemFactory : AvailableMediaDeviceItemFacto
        context: Context,
        cachedDevice: CachedBluetoothDevice,
        audioManager: AudioManager,
        audioSharingAvailable: Boolean,
    ): Boolean {
        return !BluetoothUtils.isActiveMediaDevice(cachedDevice) &&
            BluetoothUtils.isAvailableHearingDevice(cachedDevice)
@@ -206,6 +220,7 @@ internal class ConnectedDeviceItemFactory : DeviceItemFactory() {
        context: Context,
        cachedDevice: CachedBluetoothDevice,
        audioManager: AudioManager,
        audioSharingAvailable: Boolean,
    ): Boolean {
        return if (Flags.enableHideExclusivelyManagedBluetoothDevice()) {
            !BluetoothUtils.isExclusivelyManagedBluetoothDevice(context, cachedDevice.device) &&
@@ -234,6 +249,7 @@ internal open class SavedDeviceItemFactory : DeviceItemFactory() {
        context: Context,
        cachedDevice: CachedBluetoothDevice,
        audioManager: AudioManager,
        audioSharingAvailable: Boolean,
    ): Boolean {
        return if (Flags.enableHideExclusivelyManagedBluetoothDevice()) {
            !BluetoothUtils.isExclusivelyManagedBluetoothDevice(context, cachedDevice.device) &&
@@ -263,6 +279,7 @@ internal class SavedHearingDeviceItemFactory : SavedDeviceItemFactory() {
        context: Context,
        cachedDevice: CachedBluetoothDevice,
        audioManager: AudioManager,
        audioSharingAvailable: Boolean,
    ): Boolean {
        return if (Flags.enableHideExclusivelyManagedBluetoothDevice()) {
            !BluetoothUtils.isExclusivelyManagedBluetoothDevice(
+19 −13
Original line number Diff line number Diff line
@@ -50,6 +50,7 @@ class DeviceItemInteractor
@Inject
constructor(
    private val bluetoothTileDialogRepository: BluetoothTileDialogRepository,
    private val audioSharingInteractor: AudioSharingInteractor,
    private val audioManager: AudioManager,
    private val bluetoothAdapter: BluetoothAdapter? = BluetoothAdapter.getDefaultAdapter(),
    private val localBluetoothManager: LocalBluetoothManager?,
@@ -76,7 +77,7 @@ constructor(
                    object : BluetoothCallback {
                        override fun onActiveDeviceChanged(
                            activeDevice: CachedBluetoothDevice?,
                            bluetoothProfile: Int
                            bluetoothProfile: Int,
                        ) {
                            super.onActiveDeviceChanged(activeDevice, bluetoothProfile)
                            logger.logActiveDeviceChanged(activeDevice?.address, bluetoothProfile)
@@ -86,32 +87,29 @@ constructor(
                        override fun onProfileConnectionStateChanged(
                            cachedDevice: CachedBluetoothDevice,
                            state: Int,
                            bluetoothProfile: Int
                            bluetoothProfile: Int,
                        ) {
                            super.onProfileConnectionStateChanged(
                                cachedDevice,
                                state,
                                bluetoothProfile
                                bluetoothProfile,
                            )
                            logger.logProfileConnectionStateChanged(
                                cachedDevice.address,
                                state.toString(),
                                bluetoothProfile
                                bluetoothProfile,
                            )
                            trySendWithFailureLogging(Unit, TAG, "onProfileConnectionStateChanged")
                        }

                        override fun onAclConnectionStateChanged(
                            cachedDevice: CachedBluetoothDevice,
                            state: Int
                            state: Int,
                        ) {
                            super.onAclConnectionStateChanged(cachedDevice, state)
                            // Listen only when a device is disconnecting
                            if (state == 0) {
                            trySendWithFailureLogging(Unit, TAG, "onAclConnectionStateChanged")
                        }
                    }
                    }
                localBluetoothManager?.eventManager?.registerCallback(listener)
                awaitClose { localBluetoothManager?.eventManager?.unregisterCallback(listener) }
            }
@@ -121,11 +119,19 @@ constructor(
    internal suspend fun updateDeviceItems(context: Context, trigger: DeviceFetchTrigger) {
        withContext(backgroundDispatcher) {
            val start = systemClock.elapsedRealtime()
            val audioSharingAvailable = audioSharingInteractor.audioSharingAvailable()
            val deviceItems =
                bluetoothTileDialogRepository.cachedDevices
                    .mapNotNull { cachedDevice ->
                        deviceItemFactoryList
                            .firstOrNull { it.isFilterMatched(context, cachedDevice, audioManager) }
                            .firstOrNull {
                                it.isFilterMatched(
                                    context,
                                    cachedDevice,
                                    audioManager,
                                    audioSharingAvailable,
                                )
                            }
                            ?.create(context, cachedDevice)
                    }
                    .sort(deviceItemDisplayPriority, bluetoothAdapter?.mostRecentlyConnectedDevices)
@@ -136,13 +142,13 @@ constructor(
                logger.logDeviceFetch(
                    JobStatus.FINISHED,
                    trigger,
                    systemClock.elapsedRealtime() - start
                    systemClock.elapsedRealtime() - start,
                )
            } else {
                logger.logDeviceFetch(
                    JobStatus.CANCELLED,
                    trigger,
                    systemClock.elapsedRealtime() - start
                    systemClock.elapsedRealtime() - start,
                )
            }
        }
@@ -150,7 +156,7 @@ constructor(

    private fun List<DeviceItem>.sort(
        displayPriority: List<DeviceItemType>,
        mostRecentlyConnectedDevices: List<BluetoothDevice>?
        mostRecentlyConnectedDevices: List<BluetoothDevice>?,
    ): List<DeviceItem> {
        return this.sortedWith(
            compareBy<DeviceItem> { displayPriority.indexOf(it.type) }
+23 −0
Original line number Diff line number Diff line
@@ -63,6 +63,7 @@ class AudioSharingDeviceItemActionInteractorTest : SysuiTestCase() {
    private lateinit var mockitoSession: StaticMockitoSession
    private lateinit var connectedAudioSharingMediaDeviceItem: DeviceItem
    private lateinit var connectedMediaDeviceItem: DeviceItem
    private lateinit var inAudioSharingMediaDeviceItem: DeviceItem
    @Mock private lateinit var dialog: SystemUIDialog
    @Mock private lateinit var leAudioProfile: LeAudioProfile
    @Mock private lateinit var bluetoothDevice: BluetoothDevice
@@ -80,6 +81,15 @@ class AudioSharingDeviceItemActionInteractorTest : SysuiTestCase() {
                iconWithDescription = null,
                background = null,
            )
        inAudioSharingMediaDeviceItem =
            DeviceItem(
                type = DeviceItemType.AUDIO_SHARING_MEDIA_BLUETOOTH_DEVICE,
                cachedBluetoothDevice = kosmos.cachedBluetoothDevice,
                deviceName = DEVICE_NAME,
                connectionSummary = DEVICE_CONNECTION_SUMMARY,
                iconWithDescription = null,
                background = null,
            )
        connectedAudioSharingMediaDeviceItem =
            DeviceItem(
                type = DeviceItemType.AVAILABLE_AUDIO_SHARING_MEDIA_BLUETOOTH_DEVICE,
@@ -130,6 +140,19 @@ class AudioSharingDeviceItemActionInteractorTest : SysuiTestCase() {
        }
    }

    @Test
    fun testOnClick_inAudioSharingMediaDevice_doNothing() {
        with(kosmos) {
            testScope.runTest {
                bluetoothTileDialogAudioSharingRepository.setAudioSharingAvailable(true)
                actionInteractorImpl.onClick(inAudioSharingMediaDeviceItem, dialog)

                verify(dialogTransitionAnimator, never())
                    .showFromDialog(any(), any(), eq(null), anyBoolean())
            }
        }
    }

    @Test
    fun testOnClick_inAudioSharing_clickedDeviceHasSource_shouldNotLaunchSettings() {
        with(kosmos) {
Loading