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.volume.panel.component.volume.domain.interactor 18 19 import android.media.AudioDeviceInfo 20 import android.media.AudioManager 21 import com.android.settingslib.volume.data.repository.AudioRepository 22 import com.android.settingslib.volume.shared.model.AudioStream 23 import com.android.systemui.volume.panel.component.mediaoutput.domain.interactor.MediaOutputInteractor 24 import com.android.systemui.volume.panel.component.mediaoutput.shared.model.MediaDeviceSession 25 import com.android.systemui.volume.panel.component.mediaoutput.shared.model.isTheSameSession 26 import com.android.systemui.volume.panel.component.volume.domain.model.SliderType 27 import com.android.systemui.volume.panel.dagger.scope.VolumePanelScope 28 import com.android.systemui.volume.panel.shared.model.filterData 29 import javax.inject.Inject 30 import kotlinx.coroutines.CoroutineScope 31 import kotlinx.coroutines.coroutineScope 32 import kotlinx.coroutines.flow.SharingStarted 33 import kotlinx.coroutines.flow.StateFlow 34 import kotlinx.coroutines.flow.combineTransform 35 import kotlinx.coroutines.flow.stateIn 36 37 /** Provides volume sliders to show in the Volume Panel. */ 38 @VolumePanelScope 39 class AudioSlidersInteractor 40 @Inject 41 constructor( 42 @VolumePanelScope scope: CoroutineScope, 43 mediaOutputInteractor: MediaOutputInteractor, 44 audioRepository: AudioRepository, 45 ) { 46 47 val volumePanelSliders: StateFlow<List<SliderType>> = 48 combineTransform( 49 mediaOutputInteractor.activeMediaDeviceSessions, 50 mediaOutputInteractor.defaultActiveMediaSession.filterData(), 51 audioRepository.communicationDevice, 52 ) { activeSessions, defaultSession, communicationDevice -> 53 coroutineScope { 54 val viewModels = buildList { 55 if (defaultSession?.isTheSameSession(activeSessions.remote) == true) { 56 addSession(activeSessions.remote) 57 addStream(AudioManager.STREAM_MUSIC) 58 } else { 59 addStream(AudioManager.STREAM_MUSIC) 60 addSession(activeSessions.remote) 61 } 62 63 if (communicationDevice?.type == AudioDeviceInfo.TYPE_BLUETOOTH_SCO) { 64 addStream(AudioManager.STREAM_BLUETOOTH_SCO) 65 } else { 66 addStream(AudioManager.STREAM_VOICE_CALL) 67 } 68 addStream(AudioManager.STREAM_RING) 69 addStream(AudioManager.STREAM_NOTIFICATION) 70 addStream(AudioManager.STREAM_ALARM) 71 } 72 emit(viewModels) 73 } 74 } 75 .stateIn(scope, SharingStarted.Eagerly, emptyList()) 76 77 private fun MutableList<SliderType>.addSession(remoteMediaDeviceSession: MediaDeviceSession?) { 78 if (remoteMediaDeviceSession?.canAdjustVolume == true) { 79 add(SliderType.MediaDeviceCast(remoteMediaDeviceSession)) 80 } 81 } 82 83 private fun MutableList<SliderType>.addStream(stream: Int) { 84 add(SliderType.Stream(AudioStream(stream))) 85 } 86 } 87