1 /* <lambda>null2 * Copyright (C) 2024 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.systemui.bluetooth.qsdialog 18 19 import com.android.settingslib.bluetooth.CachedBluetoothDevice 20 import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcast 21 import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcastAssistant 22 import com.android.settingslib.bluetooth.LocalBluetoothManager 23 import com.android.settingslib.bluetooth.onSourceConnectedOrRemoved 24 import com.android.settingslib.volume.data.repository.AudioSharingRepository as SettingsLibAudioSharingRepository 25 import com.android.systemui.dagger.SysUISingleton 26 import com.android.systemui.dagger.qualifiers.Background 27 import kotlinx.coroutines.CoroutineDispatcher 28 import kotlinx.coroutines.flow.Flow 29 import kotlinx.coroutines.flow.MutableStateFlow 30 import kotlinx.coroutines.flow.StateFlow 31 import kotlinx.coroutines.flow.emptyFlow 32 import kotlinx.coroutines.withContext 33 34 interface AudioSharingRepository { 35 val leAudioBroadcastProfile: LocalBluetoothLeBroadcast? 36 37 val audioSourceStateUpdate: Flow<Unit> 38 39 val inAudioSharing: StateFlow<Boolean> 40 41 suspend fun audioSharingAvailable(): Boolean 42 43 suspend fun addSource() 44 45 suspend fun setActive(cachedBluetoothDevice: CachedBluetoothDevice) 46 47 suspend fun startAudioSharing() 48 } 49 50 @SysUISingleton 51 class AudioSharingRepositoryImpl( 52 private val localBluetoothManager: LocalBluetoothManager, 53 private val settingsLibAudioSharingRepository: SettingsLibAudioSharingRepository, 54 @Background private val backgroundDispatcher: CoroutineDispatcher, 55 ) : AudioSharingRepository { 56 57 override val leAudioBroadcastProfile: LocalBluetoothLeBroadcast? 58 get() = localBluetoothManager.profileManager?.leAudioBroadcastProfile 59 60 private val leAudioBroadcastAssistantProfile: LocalBluetoothLeBroadcastAssistant? 61 get() = localBluetoothManager.profileManager?.leAudioBroadcastAssistantProfile 62 63 override val audioSourceStateUpdate: Flow<Unit> = 64 leAudioBroadcastAssistantProfile?.onSourceConnectedOrRemoved ?: emptyFlow() 65 66 override val inAudioSharing: StateFlow<Boolean> = 67 settingsLibAudioSharingRepository.inAudioSharing 68 audioSharingAvailablenull69 override suspend fun audioSharingAvailable(): Boolean { 70 return settingsLibAudioSharingRepository.audioSharingAvailable() 71 } 72 addSourcenull73 override suspend fun addSource() { 74 withContext(backgroundDispatcher) { 75 if (!settingsLibAudioSharingRepository.audioSharingAvailable()) { 76 return@withContext 77 } 78 leAudioBroadcastProfile?.latestBluetoothLeBroadcastMetadata?.let { metadata -> 79 leAudioBroadcastAssistantProfile?.let { 80 it.allConnectedDevices.forEach { sink -> it.addSource(sink, metadata, false) } 81 } 82 } 83 } 84 } 85 setActivenull86 override suspend fun setActive(cachedBluetoothDevice: CachedBluetoothDevice) { 87 withContext(backgroundDispatcher) { 88 if (!settingsLibAudioSharingRepository.audioSharingAvailable()) { 89 return@withContext 90 } 91 cachedBluetoothDevice.setActive() 92 } 93 } 94 startAudioSharingnull95 override suspend fun startAudioSharing() { 96 withContext(backgroundDispatcher) { 97 if (!settingsLibAudioSharingRepository.audioSharingAvailable()) { 98 return@withContext 99 } 100 leAudioBroadcastProfile?.startPrivateBroadcast() 101 } 102 } 103 } 104 105 @SysUISingleton 106 class AudioSharingRepositoryEmptyImpl : AudioSharingRepository { 107 override val leAudioBroadcastProfile: LocalBluetoothLeBroadcast? = null 108 109 override val audioSourceStateUpdate: Flow<Unit> = emptyFlow() 110 111 override val inAudioSharing: StateFlow<Boolean> = MutableStateFlow(false) 112 audioSharingAvailablenull113 override suspend fun audioSharingAvailable(): Boolean = false 114 115 override suspend fun addSource() {} 116 setActivenull117 override suspend fun setActive(cachedBluetoothDevice: CachedBluetoothDevice) {} 118 startAudioSharingnull119 override suspend fun startAudioSharing() {} 120 } 121