1 /*
2  * 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 package com.google.jetpackcamera.feature.preview
17 
18 import com.google.jetpackcamera.core.camera.CameraUseCase
19 import kotlinx.coroutines.CoroutineScope
20 import kotlinx.coroutines.flow.MutableStateFlow
21 import kotlinx.coroutines.flow.StateFlow
22 import kotlinx.coroutines.launch
23 
24 private const val TAG = "ScreenFlash"
25 
26 /**
27  * Contains the UI state maintaining logic for screen flash feature.
28  */
29 // TODO: Add this to ViewModelScoped so that it can be injected automatically. However, the current
30 //  ViewModel and Hilt APIs probably don't support injecting the viewModelScope.
31 class ScreenFlash(
32     private val cameraUseCase: CameraUseCase,
33     private val scope: CoroutineScope
34 ) {
35     data class ScreenFlashUiState(
36         val enabled: Boolean = false,
<lambda>null37         val onChangeComplete: () -> Unit = {},
38         // restored during CLEAR_UI event
39         val screenBrightnessToRestore: Float? = null
40     )
41 
42     private val _screenFlashUiState: MutableStateFlow<ScreenFlashUiState> =
43         MutableStateFlow(ScreenFlashUiState())
44     val screenFlashUiState: StateFlow<ScreenFlashUiState> = _screenFlashUiState
45 
46     init {
<lambda>null47         scope.launch {
48             for (event in cameraUseCase.getScreenFlashEvents()) {
49                 _screenFlashUiState.emit(
50                     when (event.type) {
51                         CameraUseCase.ScreenFlashEvent.Type.APPLY_UI ->
52                             screenFlashUiState.value.copy(
53                                 enabled = true,
54                                 onChangeComplete = event.onComplete
55                             )
56 
57                         CameraUseCase.ScreenFlashEvent.Type.CLEAR_UI ->
58                             screenFlashUiState.value.copy(
59                                 enabled = false,
60                                 onChangeComplete = {
61                                     event.onComplete()
62                                     // reset ui state on CLEAR_UI event completion
63                                     scope.launch {
64                                         _screenFlashUiState.emit(
65                                             ScreenFlashUiState()
66                                         )
67                                     }
68                                 }
69                             )
70                     }
71                 )
72             }
73         }
74     }
75 
76     /**
77      * Sets the screenBrightness value to the value right before APPLY_UI event for the next
78      * CLEAR_UI event, will be set to unknown (null) again after CLEAR_UI event is completed.
79      */
setClearUiScreenBrightnessnull80     fun setClearUiScreenBrightness(brightness: Float) {
81         scope.launch {
82             _screenFlashUiState.emit(
83                 screenFlashUiState.value.copy(screenBrightnessToRestore = brightness)
84             )
85         }
86     }
87 }
88