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 package com.google.jetpackcamera.settings
17
18 import com.google.jetpackcamera.settings.DisabledRationale.DeviceUnsupportedRationale
19 import com.google.jetpackcamera.settings.DisabledRationale.LensUnsupportedRationale
20 import com.google.jetpackcamera.settings.model.AspectRatio
21 import com.google.jetpackcamera.settings.model.CaptureMode
22 import com.google.jetpackcamera.settings.model.DEFAULT_CAMERA_APP_SETTINGS
23 import com.google.jetpackcamera.settings.model.DarkMode
24 import com.google.jetpackcamera.settings.model.FlashMode
25 import com.google.jetpackcamera.settings.model.LensFacing
26 import com.google.jetpackcamera.settings.model.Stabilization
27 import com.google.jetpackcamera.settings.ui.DEVICE_UNSUPPORTED_TAG
28 import com.google.jetpackcamera.settings.ui.FPS_UNSUPPORTED_TAG
29 import com.google.jetpackcamera.settings.ui.LENS_UNSUPPORTED_TAG
30 import com.google.jetpackcamera.settings.ui.STABILIZATION_UNSUPPORTED_TAG
31
32 /**
33 * Defines the current state of the [SettingsScreen].
34 */
35 sealed interface SettingsUiState {
36 data object Disabled : SettingsUiState
37 data class Enabled(
38 val aspectRatioUiState: AspectRatioUiState,
39 val captureModeUiState: CaptureModeUiState,
40 val darkModeUiState: DarkModeUiState,
41 val flashUiState: FlashUiState,
42 val fpsUiState: FpsUiState,
43 val lensFlipUiState: FlipLensUiState,
44 val stabilizationUiState: StabilizationUiState
45 ) : SettingsUiState
46 }
47
48 /** State for the individual options on Popup dialog settings */
49 sealed interface SingleSelectableState {
50 data object Selectable : SingleSelectableState
51 data class Disabled(val disabledRationale: DisabledRationale) : SingleSelectableState
52 }
53
54 /** Contains information on why a setting is disabled */
55 // TODO(b/360921588): Display information on UI regarding disabled rationale
56 sealed interface DisabledRationale {
57 val affectedSettingNameResId: Int
58 val reasonTextResId: Int
59 val testTag: String
60
61 /**
62 * Text will be [affectedSettingNameResId] is [R.string.device_unsupported]
63 */
64 data class DeviceUnsupportedRationale(override val affectedSettingNameResId: Int) :
65 DisabledRationale {
66 override val reasonTextResId: Int = R.string.device_unsupported
67 override val testTag = DEVICE_UNSUPPORTED_TAG
68 }
69
70 data class FpsUnsupportedRationale(
71 override val affectedSettingNameResId: Int,
72 val currentFps: Int
73 ) : DisabledRationale {
74 override val reasonTextResId: Int = R.string.fps_unsupported
75 override val testTag = FPS_UNSUPPORTED_TAG
76 }
77
78 data class StabilizationUnsupportedRationale(override val affectedSettingNameResId: Int) :
79 DisabledRationale {
80 override val reasonTextResId = R.string.stabilization_unsupported
81 override val testTag = STABILIZATION_UNSUPPORTED_TAG
82 }
83
84 sealed interface LensUnsupportedRationale : DisabledRationale {
85 data class FrontLensUnsupportedRationale(override val affectedSettingNameResId: Int) :
86 LensUnsupportedRationale {
87 override val reasonTextResId: Int = R.string.front_lens_unsupported
88 override val testTag = LENS_UNSUPPORTED_TAG
89 }
90
91 data class RearLensUnsupportedRationale(override val affectedSettingNameResId: Int) :
92 LensUnsupportedRationale {
93 override val reasonTextResId: Int = R.string.rear_lens_unsupported
94 override val testTag = LENS_UNSUPPORTED_TAG
95 }
96 }
97 }
98
getLensUnsupportedRationalenull99 fun getLensUnsupportedRationale(
100 lensFacing: LensFacing,
101 affectedSettingNameResId: Int
102 ): LensUnsupportedRationale {
103 return when (lensFacing) {
104 LensFacing.BACK -> LensUnsupportedRationale.RearLensUnsupportedRationale(
105 affectedSettingNameResId
106 )
107
108 LensFacing.FRONT -> LensUnsupportedRationale.FrontLensUnsupportedRationale(
109 affectedSettingNameResId
110 )
111 }
112 }
113
114 /* Settings that currently have constraints **/
115
116 sealed interface FpsUiState {
117 data class Enabled(
118 val currentSelection: Int,
119 val fpsAutoState: SingleSelectableState,
120 val fpsFifteenState: SingleSelectableState,
121 val fpsThirtyState: SingleSelectableState,
122 val fpsSixtyState: SingleSelectableState,
123 // Contains text like "Selected FPS only supported by rear lens"
124 val additionalContext: String = ""
125 ) : FpsUiState
126
127 // FPS selection completely disabled. Cannot open dialog.
128 data class Disabled(val disabledRationale: DisabledRationale) : FpsUiState
129 }
130
131 sealed interface FlipLensUiState {
132 val currentLensFacing: LensFacing
133
134 data class Enabled(
135 override val currentLensFacing: LensFacing
136 ) : FlipLensUiState
137
138 data class Disabled(
139 override val currentLensFacing: LensFacing,
140 val disabledRationale: DisabledRationale
141 ) : FlipLensUiState
142 }
143
144 sealed interface StabilizationUiState {
145 data class Enabled(
146 val currentPreviewStabilization: Stabilization,
147 val currentVideoStabilization: Stabilization,
148 val stabilizationOnState: SingleSelectableState,
149 val stabilizationHighQualityState: SingleSelectableState,
150 // Contains text like "Selected stabilization mode only supported by rear lens"
151 val additionalContext: String = ""
152 ) : StabilizationUiState
153
154 // Stabilization selection completely disabled. Cannot open dialog.
155 data class Disabled(val disabledRationale: DisabledRationale) : StabilizationUiState
156 }
157
158 /* Settings that don't currently depend on constraints */
159
160 // this could be constrained w/ a check to see if a torch is available?
161 sealed interface FlashUiState {
162 data class Enabled(
163 val currentFlashMode: FlashMode,
164 val additionalContext: String = ""
165 ) : FlashUiState
166 }
167
168 sealed interface AspectRatioUiState {
169 data class Enabled(
170 val currentAspectRatio: AspectRatio,
171 val additionalContext: String = ""
172 ) : AspectRatioUiState
173 }
174
175 sealed interface CaptureModeUiState {
176 data class Enabled(
177 val currentCaptureMode: CaptureMode,
178 val additionalContext: String = ""
179 ) : CaptureModeUiState
180 }
181
182 sealed interface DarkModeUiState {
183 data class Enabled(
184 val currentDarkMode: DarkMode,
185 val additionalContext: String = ""
186 ) : DarkModeUiState
187 }
188
189 /**
190 * Settings Ui State for testing, based on Typical System Constraints.
191 * @see[com.google.jetpackcamera.settings.model.SystemConstraints]
192 */
193 val TYPICAL_SETTINGS_UISTATE = SettingsUiState.Enabled(
194 aspectRatioUiState = AspectRatioUiState.Enabled(DEFAULT_CAMERA_APP_SETTINGS.aspectRatio),
195 captureModeUiState = CaptureModeUiState.Enabled(DEFAULT_CAMERA_APP_SETTINGS.captureMode),
196 darkModeUiState = DarkModeUiState.Enabled(DEFAULT_CAMERA_APP_SETTINGS.darkMode),
197 flashUiState =
198 FlashUiState.Enabled(currentFlashMode = DEFAULT_CAMERA_APP_SETTINGS.flashMode),
199 fpsUiState = FpsUiState.Enabled(
200 currentSelection = DEFAULT_CAMERA_APP_SETTINGS.targetFrameRate,
201 fpsAutoState = SingleSelectableState.Selectable,
202 fpsFifteenState = SingleSelectableState.Selectable,
203 fpsThirtyState = SingleSelectableState.Selectable,
204 fpsSixtyState = SingleSelectableState.Disabled(
205 DeviceUnsupportedRationale(R.string.fps_rationale_prefix)
206 )
207 ),
208 lensFlipUiState = FlipLensUiState.Enabled(DEFAULT_CAMERA_APP_SETTINGS.cameraLensFacing),
209 stabilizationUiState =
210 StabilizationUiState.Disabled(
211 DeviceUnsupportedRationale(R.string.stabilization_rationale_prefix)
212 )
213 )
214