1 /*
2  * Copyright (C) 2023 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.qs.tiles.impl.flashlight.domain.interactor
18 
19 import android.os.UserHandle
20 import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow
21 import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger
22 import com.android.systemui.qs.tiles.base.interactor.QSTileDataInteractor
23 import com.android.systemui.qs.tiles.impl.flashlight.domain.model.FlashlightTileModel
24 import com.android.systemui.statusbar.policy.FlashlightController
25 import javax.inject.Inject
26 import kotlinx.coroutines.channels.awaitClose
27 import kotlinx.coroutines.flow.Flow
28 import kotlinx.coroutines.flow.flowOf
29 
30 /** Observes flashlight state changes providing the [FlashlightTileModel]. */
31 class FlashlightTileDataInteractor
32 @Inject
33 constructor(
34     private val flashlightController: FlashlightController,
35 ) : QSTileDataInteractor<FlashlightTileModel> {
36 
tileDatanull37     override fun tileData(
38         user: UserHandle,
39         triggers: Flow<DataUpdateTrigger>
40     ): Flow<FlashlightTileModel> = conflatedCallbackFlow {
41         val callback =
42             object : FlashlightController.FlashlightListener {
43                 override fun onFlashlightChanged(enabled: Boolean) {
44                     trySend(FlashlightTileModel.FlashlightAvailable(enabled))
45                 }
46                 override fun onFlashlightError() {
47                     trySend(FlashlightTileModel.FlashlightAvailable(false))
48                 }
49                 override fun onFlashlightAvailabilityChanged(available: Boolean) {
50                     trySend(
51                         if (available)
52                             FlashlightTileModel.FlashlightAvailable(flashlightController.isEnabled)
53                         else FlashlightTileModel.FlashlightTemporarilyUnavailable
54                     )
55                 }
56             }
57         flashlightController.addCallback(callback)
58         awaitClose { flashlightController.removeCallback(callback) }
59     }
60 
61     /**
62      * Used to determine if the tile should be displayed. Not to be confused with the availability
63      * in the data model above. This flow signals whether the tile should be shown or hidden.
64      */
availabilitynull65     override fun availability(user: UserHandle): Flow<Boolean> =
66         flowOf(flashlightController.hasFlashlight())
67 }
68