• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.dialog.domain.interactor
18 
19 import android.util.SparseArray
20 import androidx.core.util.keyIterator
21 import com.android.systemui.plugins.VolumeDialogController
22 import com.android.systemui.volume.dialog.dagger.scope.VolumeDialogPlugin
23 import com.android.systemui.volume.dialog.dagger.scope.VolumeDialogPluginScope
24 import com.android.systemui.volume.dialog.data.repository.VolumeDialogStateRepository
25 import com.android.systemui.volume.dialog.domain.model.VolumeDialogEventModel
26 import com.android.systemui.volume.dialog.shared.model.VolumeDialogCsdWarningModel
27 import com.android.systemui.volume.dialog.shared.model.VolumeDialogSafetyWarningModel
28 import com.android.systemui.volume.dialog.shared.model.VolumeDialogStateModel
29 import com.android.systemui.volume.dialog.shared.model.VolumeDialogStreamModel
30 import javax.inject.Inject
31 import kotlin.time.Duration.Companion.milliseconds
32 import kotlinx.coroutines.CoroutineScope
33 import kotlinx.coroutines.flow.Flow
34 import kotlinx.coroutines.flow.launchIn
35 import kotlinx.coroutines.flow.onEach
36 
37 /**
38  * Exposes [VolumeDialogController.getState] in the [volumeDialogState].
39  *
40  * @see [VolumeDialogController]
41  */
42 @VolumeDialogPluginScope
43 class VolumeDialogStateInteractor
44 @Inject
45 constructor(
46     volumeDialogCallbacksInteractor: VolumeDialogCallbacksInteractor,
47     private val volumeDialogController: VolumeDialogController,
48     private val volumeDialogStateRepository: VolumeDialogStateRepository,
49     @VolumeDialogPlugin private val coroutineScope: CoroutineScope,
50 ) {
51 
52     init {
53         volumeDialogCallbacksInteractor.event
54             .onEach { event ->
55                 when (event) {
56                     is VolumeDialogEventModel.StateChanged -> {
57                         volumeDialogStateRepository.updateState { oldState ->
58                             event.state.copyIntoModel(oldState)
59                         }
60                     }
61                     is VolumeDialogEventModel.AccessibilityModeChanged -> {
62                         volumeDialogStateRepository.updateState { oldState ->
63                             oldState.copy(shouldShowA11ySlider = event.showA11yStream)
64                         }
65                     }
66                     is VolumeDialogEventModel.ShowSafetyWarning -> {
67                         setSafetyWarning(VolumeDialogSafetyWarningModel.Visible(event.flags))
68                     }
69                     is VolumeDialogEventModel.ShowCsdWarning -> {
70                         setCsdWarning(
71                             VolumeDialogCsdWarningModel.Visible(
72                                 warning = event.csdWarning,
73                                 duration = event.durationMs.milliseconds,
74                             )
75                         )
76                     }
77                     is VolumeDialogEventModel.SubscribedToEvents -> {
78                         volumeDialogController.getState()
79                     }
80                     else -> {
81                         // do nothing
82                     }
83                 }
84             }
85             .launchIn(coroutineScope)
86     }
87 
88     val volumeDialogState: Flow<VolumeDialogStateModel> = volumeDialogStateRepository.state
89 
90     fun setSafetyWarning(model: VolumeDialogSafetyWarningModel) {
91         volumeDialogStateRepository.updateState { it.copy(isShowingSafetyWarning = model) }
92     }
93 
94     fun setCsdWarning(model: VolumeDialogCsdWarningModel) {
95         volumeDialogStateRepository.updateState { it.copy(isShowingCsdWarning = model) }
96     }
97 
98     fun setHovering(isHovering: Boolean) {
99         volumeDialogStateRepository.updateState { it.copy(isHovering = isHovering) }
100     }
101 
102     /** Returns a copy of [model] filled with the values from [VolumeDialogController.State]. */
103     private fun VolumeDialogController.State.copyIntoModel(
104         model: VolumeDialogStateModel
105     ): VolumeDialogStateModel {
106         return model.copy(
107             streamModels =
108                 states.mapToMap { stream, streamState ->
109                     VolumeDialogStreamModel(
110                         stream = stream,
111                         isActive = stream == activeStream,
112                         legacyState = streamState,
113                     )
114                 },
115             ringerModeInternal = ringerModeInternal,
116             ringerModeExternal = ringerModeExternal,
117             zenMode = zenMode,
118             effectsSuppressor = effectsSuppressor,
119             effectsSuppressorName = effectsSuppressorName,
120             activeStream = activeStream,
121             disallowAlarms = disallowAlarms,
122             disallowMedia = disallowMedia,
123             disallowSystem = disallowSystem,
124             disallowRinger = disallowRinger,
125         )
126     }
127 }
128 
mapToMapnull129 private fun <INPUT, OUTPUT> SparseArray<INPUT>.mapToMap(
130     map: (Int, INPUT) -> OUTPUT
131 ): Map<Int, OUTPUT> {
132     val resultMap = mutableMapOf<Int, OUTPUT>()
133     for (key in keyIterator()) {
134         val mappedValue: OUTPUT = map(key, get(key)!!)
135         resultMap[key] = mappedValue
136     }
137     return resultMap
138 }
139