• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
<lambda>null2  * 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 android.Manifest
19 import android.content.res.Configuration
20 import androidx.compose.foundation.background
21 import androidx.compose.foundation.layout.Column
22 import androidx.compose.foundation.layout.padding
23 import androidx.compose.foundation.rememberScrollState
24 import androidx.compose.foundation.verticalScroll
25 import androidx.compose.material3.ExperimentalMaterial3Api
26 import androidx.compose.material3.MaterialTheme
27 import androidx.compose.material3.Scaffold
28 import androidx.compose.material3.TopAppBarDefaults
29 import androidx.compose.material3.rememberTopAppBarState
30 import androidx.compose.runtime.Composable
31 import androidx.compose.runtime.collectAsState
32 import androidx.compose.runtime.getValue
33 import androidx.compose.ui.Modifier
34 import androidx.compose.ui.input.nestedscroll.nestedScroll
35 import androidx.compose.ui.res.stringResource
36 import androidx.compose.ui.tooling.preview.Preview
37 import androidx.hilt.navigation.compose.hiltViewModel
38 import com.google.accompanist.permissions.ExperimentalPermissionsApi
39 import com.google.accompanist.permissions.rememberMultiplePermissionsState
40 import com.google.jetpackcamera.settings.model.AspectRatio
41 import com.google.jetpackcamera.settings.model.DarkMode
42 import com.google.jetpackcamera.settings.model.FlashMode
43 import com.google.jetpackcamera.settings.model.LensFacing
44 import com.google.jetpackcamera.settings.model.StabilizationMode
45 import com.google.jetpackcamera.settings.model.StreamConfig
46 import com.google.jetpackcamera.settings.model.VideoQuality
47 import com.google.jetpackcamera.settings.ui.AspectRatioSetting
48 import com.google.jetpackcamera.settings.ui.DarkModeSetting
49 import com.google.jetpackcamera.settings.ui.DefaultCameraFacing
50 import com.google.jetpackcamera.settings.ui.FlashModeSetting
51 import com.google.jetpackcamera.settings.ui.MaxVideoDurationSetting
52 import com.google.jetpackcamera.settings.ui.RecordingAudioSetting
53 import com.google.jetpackcamera.settings.ui.SectionHeader
54 import com.google.jetpackcamera.settings.ui.SettingsPageHeader
55 import com.google.jetpackcamera.settings.ui.StabilizationSetting
56 import com.google.jetpackcamera.settings.ui.StreamConfigSetting
57 import com.google.jetpackcamera.settings.ui.TargetFpsSetting
58 import com.google.jetpackcamera.settings.ui.VersionInfo
59 import com.google.jetpackcamera.settings.ui.VideoQualitySetting
60 import com.google.jetpackcamera.settings.ui.theme.SettingsPreviewTheme
61 
62 /**
63  * Screen used for the Settings feature.
64  */
65 
66 @OptIn(ExperimentalPermissionsApi::class)
67 @Composable
68 fun SettingsScreen(
69     versionInfo: VersionInfoHolder,
70     viewModel: SettingsViewModel = hiltViewModel(),
71     onNavigateBack: () -> Unit
72 ) {
73     val settingsUiState by viewModel.settingsUiState.collectAsState()
74 
75     SettingsScreen(
76         uiState = settingsUiState,
77         versionInfo = versionInfo,
78         onNavigateBack = onNavigateBack,
79         setDefaultLensFacing = viewModel::setDefaultLensFacing,
80         setFlashMode = viewModel::setFlashMode,
81         setTargetFrameRate = viewModel::setTargetFrameRate,
82         setAspectRatio = viewModel::setAspectRatio,
83         setCaptureMode = viewModel::setStreamConfig,
84         setAudio = viewModel::setVideoAudio,
85         setStabilizationMode = viewModel::setStabilizationMode,
86         setMaxVideoDuration = viewModel::setMaxVideoDuration,
87         setDarkMode = viewModel::setDarkMode,
88         setVideoQuality = viewModel::setVideoQuality
89     )
90     val permissionStates = rememberMultiplePermissionsState(
91         permissions =
92         listOf(
93             Manifest.permission.CAMERA,
94             Manifest.permission.RECORD_AUDIO
95         )
96     )
97 
98     viewModel.setGrantedPermissions(permissionStates)
99 }
100 
101 @OptIn(ExperimentalMaterial3Api::class)
102 @Composable
SettingsScreennull103 private fun SettingsScreen(
104     uiState: SettingsUiState,
105     versionInfo: VersionInfoHolder,
106     onNavigateBack: () -> Unit = {},
<lambda>null107     setDefaultLensFacing: (LensFacing) -> Unit = {},
<lambda>null108     setFlashMode: (FlashMode) -> Unit = {},
<lambda>null109     setTargetFrameRate: (Int) -> Unit = {},
<lambda>null110     setAspectRatio: (AspectRatio) -> Unit = {},
<lambda>null111     setCaptureMode: (StreamConfig) -> Unit = {},
<lambda>null112     setStabilizationMode: (StabilizationMode) -> Unit = {},
<lambda>null113     setAudio: (Boolean) -> Unit = {},
<lambda>null114     setMaxVideoDuration: (Long) -> Unit = {},
<lambda>null115     setDarkMode: (DarkMode) -> Unit = {},
<lambda>null116     setVideoQuality: (VideoQuality) -> Unit = {}
117 ) {
118     val scrollBehavior = TopAppBarDefaults.pinnedScrollBehavior(
119         rememberTopAppBarState()
120     )
121 
122     Scaffold(
123         modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection),
<lambda>null124         topBar = {
125             SettingsPageHeader(
126                 title = stringResource(id = R.string.settings_title),
127                 navBack = onNavigateBack,
128                 scrollBehavior = scrollBehavior
129             )
130         }
innerPaddingnull131     ) { innerPadding ->
132         Column(
133             modifier = Modifier
134                 .padding(innerPadding)
135                 .verticalScroll(rememberScrollState())
136                 .background(color = MaterialTheme.colorScheme.background)
137         ) {
138             if (uiState is SettingsUiState.Enabled) {
139                 SettingsList(
140                     uiState = uiState,
141                     versionInfo = versionInfo,
142                     setDefaultLensFacing = setDefaultLensFacing,
143                     setFlashMode = setFlashMode,
144                     setTargetFrameRate = setTargetFrameRate,
145                     setAspectRatio = setAspectRatio,
146                     setCaptureMode = setCaptureMode,
147                     setStabilizationMode = setStabilizationMode,
148                     setAudio = setAudio,
149                     setMaxVideoDuration = setMaxVideoDuration,
150                     setDarkMode = setDarkMode,
151                     setVideoQuality = setVideoQuality
152                 )
153             }
154         }
155     }
156 }
157 
158 @Composable
SettingsListnull159 fun SettingsList(
160     uiState: SettingsUiState.Enabled,
161     versionInfo: VersionInfoHolder,
162     setDefaultLensFacing: (LensFacing) -> Unit = {},
<lambda>null163     setFlashMode: (FlashMode) -> Unit = {},
<lambda>null164     setTargetFrameRate: (Int) -> Unit = {},
<lambda>null165     setAspectRatio: (AspectRatio) -> Unit = {},
<lambda>null166     setCaptureMode: (StreamConfig) -> Unit = {},
<lambda>null167     setAudio: (Boolean) -> Unit = {},
<lambda>null168     setStabilizationMode: (StabilizationMode) -> Unit = {},
<lambda>null169     setVideoQuality: (VideoQuality) -> Unit = {},
<lambda>null170     setMaxVideoDuration: (Long) -> Unit = {},
<lambda>null171     setDarkMode: (DarkMode) -> Unit = {}
172 ) {
173     SectionHeader(title = stringResource(id = R.string.section_title_camera_settings))
174 
175     DefaultCameraFacing(
176         lensUiState = uiState.lensFlipUiState,
177         setDefaultLensFacing = setDefaultLensFacing
178     )
179 
180     FlashModeSetting(
181         flashUiState = uiState.flashUiState,
182         setFlashMode = setFlashMode
183     )
184 
185     TargetFpsSetting(
186         fpsUiState = uiState.fpsUiState,
187         setTargetFps = setTargetFrameRate
188     )
189 
190     AspectRatioSetting(
191         aspectRatioUiState = uiState.aspectRatioUiState,
192         setAspectRatio = setAspectRatio
193     )
194 
195     StreamConfigSetting(
196         streamConfigUiState = uiState.streamConfigUiState,
197         setStreamConfig = setCaptureMode
198     )
199 
200     SectionHeader(title = stringResource(R.string.section_title_recording_settings))
201 
202     RecordingAudioSetting(
203         audioUiState = uiState.audioUiState,
204         setDefaultAudio = setAudio
205     )
206 
207     MaxVideoDurationSetting(
208         maxVideoDurationUiState = uiState.maxVideoDurationUiState,
209         setMaxDuration = setMaxVideoDuration
210     )
211 
212     StabilizationSetting(
213         stabilizationUiState = uiState.stabilizationUiState,
214         setStabilizationMode = setStabilizationMode
215     )
216 
217     VideoQualitySetting(
218         videQualityUiState = uiState.videoQualityUiState,
219         setVideoQuality = setVideoQuality
220     )
221 
222     SectionHeader(title = stringResource(id = R.string.section_title_app_settings))
223 
224     DarkModeSetting(
225         darkModeUiState = uiState.darkModeUiState,
226         setDarkMode = setDarkMode
227     )
228 
229     SectionHeader(title = stringResource(id = R.string.section_title_software_info))
230 
231     VersionInfo(
232         versionName = versionInfo.versionName,
233         buildType = versionInfo.buildType
234     )
235 }
236 
237 // will allow you to open stabilization popup or give disabled rationale
238 
239 data class VersionInfoHolder(val versionName: String, val buildType: String)
240 
241 @Preview(name = "Light Mode")
242 @Preview(name = "Dark Mode", uiMode = Configuration.UI_MODE_NIGHT_YES)
243 @Composable
Preview_SettingsScreennull244 private fun Preview_SettingsScreen() {
245     SettingsPreviewTheme {
246         SettingsScreen(
247             uiState = TYPICAL_SETTINGS_UISTATE,
248             versionInfo = VersionInfoHolder(
249                 versionName = "1.0.0",
250                 buildType = "release"
251             )
252         )
253     }
254 }
255