• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Copyright (C) 2022 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 
18 package com.android.systemui.keyguard.data.quickaffordance
19 
20 import android.content.Context
21 import com.android.systemui.R
22 import com.android.systemui.animation.Expandable
23 import com.android.systemui.common.coroutine.ChannelExt.trySendWithFailureLogging
24 import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow
25 import com.android.systemui.common.shared.model.ContentDescription
26 import com.android.systemui.common.shared.model.Icon
27 import com.android.systemui.dagger.SysUISingleton
28 import com.android.systemui.dagger.qualifiers.Application
29 import com.android.systemui.keyguard.shared.quickaffordance.ActivationState
30 import com.android.systemui.statusbar.policy.FlashlightController
31 import javax.inject.Inject
32 import kotlinx.coroutines.channels.awaitClose
33 import kotlinx.coroutines.flow.Flow
34 
35 @SysUISingleton
36 class FlashlightQuickAffordanceConfig
37 @Inject
38 constructor(
39     @Application private val context: Context,
40     private val flashlightController: FlashlightController,
41 ) : KeyguardQuickAffordanceConfig {
42 
43     private sealed class FlashlightState {
44 
toLockScreenStatenull45         abstract fun toLockScreenState(): KeyguardQuickAffordanceConfig.LockScreenState
46 
47         object On : FlashlightState() {
48             override fun toLockScreenState(): KeyguardQuickAffordanceConfig.LockScreenState =
49                 KeyguardQuickAffordanceConfig.LockScreenState.Visible(
50                     Icon.Resource(
51                         R.drawable.qs_flashlight_icon_on,
52                         ContentDescription.Resource(R.string.quick_settings_flashlight_label)
53                     ),
54                     ActivationState.Active
55                 )
56         }
57 
58         object OffAvailable : FlashlightState() {
toLockScreenStatenull59             override fun toLockScreenState(): KeyguardQuickAffordanceConfig.LockScreenState =
60                 KeyguardQuickAffordanceConfig.LockScreenState.Visible(
61                     Icon.Resource(
62                         R.drawable.qs_flashlight_icon_off,
63                         ContentDescription.Resource(R.string.quick_settings_flashlight_label)
64                     ),
65                     ActivationState.Inactive
66                 )
67         }
68 
69         object Unavailable : FlashlightState() {
70             override fun toLockScreenState(): KeyguardQuickAffordanceConfig.LockScreenState =
71                 KeyguardQuickAffordanceConfig.LockScreenState.Hidden
72         }
73     }
74 
75     override val key: String
76         get() = BuiltInKeyguardQuickAffordanceKeys.FLASHLIGHT
77 
78     override val pickerName: String
79         get() = context.getString(R.string.quick_settings_flashlight_label)
80 
81     override val pickerIconResourceId: Int
82         get() = R.drawable.ic_flashlight_off
83 
84     override val lockScreenState: Flow<KeyguardQuickAffordanceConfig.LockScreenState> =
<lambda>null85         conflatedCallbackFlow {
86             val flashlightCallback =
87                 object : FlashlightController.FlashlightListener {
88                     override fun onFlashlightChanged(enabled: Boolean) {
89                         trySendWithFailureLogging(
90                             if (enabled) {
91                                 FlashlightState.On.toLockScreenState()
92                             } else {
93                                 FlashlightState.OffAvailable.toLockScreenState()
94                             },
95                             TAG
96                         )
97                     }
98 
99                     override fun onFlashlightError() {
100                         trySendWithFailureLogging(
101                             FlashlightState.OffAvailable.toLockScreenState(),
102                             TAG
103                         )
104                     }
105 
106                     override fun onFlashlightAvailabilityChanged(available: Boolean) {
107                         trySendWithFailureLogging(
108                             if (!available) {
109                                 FlashlightState.Unavailable.toLockScreenState()
110                             } else {
111                                 if (flashlightController.isEnabled) {
112                                     FlashlightState.On.toLockScreenState()
113                                 } else {
114                                     FlashlightState.OffAvailable.toLockScreenState()
115                                 }
116                             },
117                             TAG
118                         )
119                     }
120                 }
121 
122             flashlightController.addCallback(flashlightCallback)
123 
124             awaitClose { flashlightController.removeCallback(flashlightCallback) }
125         }
126 
onTriggerednull127     override fun onTriggered(
128         expandable: Expandable?
129     ): KeyguardQuickAffordanceConfig.OnTriggeredResult {
130         flashlightController.setFlashlight(
131             flashlightController.isAvailable && !flashlightController.isEnabled
132         )
133         return KeyguardQuickAffordanceConfig.OnTriggeredResult.Handled
134     }
135 
getPickerScreenStatenull136     override suspend fun getPickerScreenState(): KeyguardQuickAffordanceConfig.PickerScreenState =
137         if (flashlightController.isAvailable) {
138             KeyguardQuickAffordanceConfig.PickerScreenState.Default()
139         } else {
140             KeyguardQuickAffordanceConfig.PickerScreenState.UnavailableOnDevice
141         }
142 
143     companion object {
144         private const val TAG = "FlashlightQuickAffordanceConfig"
145     }
146 }
147