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 androidx.datastore.core.DataStore 19 import com.google.jetpackcamera.settings.AspectRatio as AspectRatioProto 20 import com.google.jetpackcamera.settings.CaptureMode as CaptureModeProto 21 import com.google.jetpackcamera.settings.DarkMode as DarkModeProto 22 import com.google.jetpackcamera.settings.FlashMode as FlashModeProto 23 import com.google.jetpackcamera.settings.PreviewStabilization as PreviewStabilizationProto 24 import com.google.jetpackcamera.settings.VideoStabilization as VideoStabilizationProto 25 import com.google.jetpackcamera.settings.model.AspectRatio 26 import com.google.jetpackcamera.settings.model.CameraAppSettings 27 import com.google.jetpackcamera.settings.model.CaptureMode 28 import com.google.jetpackcamera.settings.model.DarkMode 29 import com.google.jetpackcamera.settings.model.DynamicRange 30 import com.google.jetpackcamera.settings.model.DynamicRange.Companion.toProto 31 import com.google.jetpackcamera.settings.model.FlashMode 32 import com.google.jetpackcamera.settings.model.ImageOutputFormat 33 import com.google.jetpackcamera.settings.model.ImageOutputFormat.Companion.toProto 34 import com.google.jetpackcamera.settings.model.LensFacing 35 import com.google.jetpackcamera.settings.model.LensFacing.Companion.toProto 36 import com.google.jetpackcamera.settings.model.Stabilization 37 import javax.inject.Inject 38 import kotlinx.coroutines.flow.first 39 import kotlinx.coroutines.flow.map 40 41 const val TARGET_FPS_15 = 15 42 const val TARGET_FPS_60 = 60 43 44 /** 45 * Implementation of [SettingsRepository] with locally stored settings. 46 */ 47 class LocalSettingsRepository @Inject constructor( 48 private val jcaSettings: DataStore<JcaSettings> 49 ) : SettingsRepository { 50 51 override val defaultCameraAppSettings = jcaSettings.data 52 .map { 53 CameraAppSettings( 54 cameraLensFacing = LensFacing.fromProto(it.defaultLensFacing), 55 darkMode = when (it.darkModeStatus) { 56 DarkModeProto.DARK_MODE_DARK -> DarkMode.DARK 57 DarkModeProto.DARK_MODE_LIGHT -> DarkMode.LIGHT 58 DarkModeProto.DARK_MODE_SYSTEM -> DarkMode.SYSTEM 59 else -> DarkMode.SYSTEM 60 }, 61 flashMode = when (it.flashModeStatus) { 62 FlashModeProto.FLASH_MODE_AUTO -> FlashMode.AUTO 63 FlashModeProto.FLASH_MODE_ON -> FlashMode.ON 64 FlashModeProto.FLASH_MODE_OFF -> FlashMode.OFF 65 else -> FlashMode.OFF 66 }, 67 aspectRatio = AspectRatio.fromProto(it.aspectRatioStatus), 68 previewStabilization = Stabilization.fromProto(it.stabilizePreview), 69 videoCaptureStabilization = Stabilization.fromProto(it.stabilizeVideo), 70 targetFrameRate = it.targetFrameRate, 71 captureMode = when (it.captureModeStatus) { 72 CaptureModeProto.CAPTURE_MODE_SINGLE_STREAM -> CaptureMode.SINGLE_STREAM 73 CaptureModeProto.CAPTURE_MODE_MULTI_STREAM -> CaptureMode.MULTI_STREAM 74 else -> CaptureMode.MULTI_STREAM 75 }, 76 dynamicRange = DynamicRange.fromProto(it.dynamicRangeStatus), 77 imageFormat = ImageOutputFormat.fromProto(it.imageFormatStatus) 78 ) 79 } 80 81 override suspend fun getCurrentDefaultCameraAppSettings(): CameraAppSettings = 82 defaultCameraAppSettings.first() 83 84 override suspend fun updateDefaultLensFacing(lensFacing: LensFacing) { 85 jcaSettings.updateData { currentSettings -> 86 currentSettings.toBuilder() 87 .setDefaultLensFacing(lensFacing.toProto()) 88 .build() 89 } 90 } 91 92 override suspend fun updateDarkModeStatus(darkMode: DarkMode) { 93 val newStatus = when (darkMode) { 94 DarkMode.DARK -> DarkModeProto.DARK_MODE_DARK 95 DarkMode.LIGHT -> DarkModeProto.DARK_MODE_LIGHT 96 DarkMode.SYSTEM -> DarkModeProto.DARK_MODE_SYSTEM 97 } 98 jcaSettings.updateData { currentSettings -> 99 currentSettings.toBuilder() 100 .setDarkModeStatus(newStatus) 101 .build() 102 } 103 } 104 105 override suspend fun updateFlashModeStatus(flashMode: FlashMode) { 106 val newStatus = when (flashMode) { 107 FlashMode.AUTO -> FlashModeProto.FLASH_MODE_AUTO 108 FlashMode.ON -> FlashModeProto.FLASH_MODE_ON 109 FlashMode.OFF -> FlashModeProto.FLASH_MODE_OFF 110 } 111 jcaSettings.updateData { currentSettings -> 112 currentSettings.toBuilder() 113 .setFlashModeStatus(newStatus) 114 .build() 115 } 116 } 117 118 override suspend fun updateTargetFrameRate(targetFrameRate: Int) { 119 jcaSettings.updateData { currentSettings -> 120 currentSettings.toBuilder() 121 .setTargetFrameRate(targetFrameRate) 122 .build() 123 } 124 } 125 126 override suspend fun updateAspectRatio(aspectRatio: AspectRatio) { 127 val newStatus = when (aspectRatio) { 128 AspectRatio.NINE_SIXTEEN -> AspectRatioProto.ASPECT_RATIO_NINE_SIXTEEN 129 AspectRatio.THREE_FOUR -> AspectRatioProto.ASPECT_RATIO_THREE_FOUR 130 AspectRatio.ONE_ONE -> AspectRatioProto.ASPECT_RATIO_ONE_ONE 131 } 132 jcaSettings.updateData { currentSettings -> 133 currentSettings.toBuilder() 134 .setAspectRatioStatus(newStatus) 135 .build() 136 } 137 } 138 139 override suspend fun updateCaptureMode(captureMode: CaptureMode) { 140 val newStatus = when (captureMode) { 141 CaptureMode.MULTI_STREAM -> CaptureModeProto.CAPTURE_MODE_MULTI_STREAM 142 CaptureMode.SINGLE_STREAM -> CaptureModeProto.CAPTURE_MODE_SINGLE_STREAM 143 } 144 jcaSettings.updateData { currentSettings -> 145 currentSettings.toBuilder() 146 .setCaptureModeStatus(newStatus) 147 .build() 148 } 149 } 150 151 override suspend fun updatePreviewStabilization(stabilization: Stabilization) { 152 val newStatus = when (stabilization) { 153 Stabilization.ON -> PreviewStabilizationProto.PREVIEW_STABILIZATION_ON 154 Stabilization.OFF -> PreviewStabilizationProto.PREVIEW_STABILIZATION_OFF 155 else -> PreviewStabilizationProto.PREVIEW_STABILIZATION_UNDEFINED 156 } 157 jcaSettings.updateData { currentSettings -> 158 currentSettings.toBuilder() 159 .setStabilizePreview(newStatus) 160 .build() 161 } 162 } 163 164 override suspend fun updateVideoStabilization(stabilization: Stabilization) { 165 val newStatus = when (stabilization) { 166 Stabilization.ON -> VideoStabilizationProto.VIDEO_STABILIZATION_ON 167 Stabilization.OFF -> VideoStabilizationProto.VIDEO_STABILIZATION_OFF 168 else -> VideoStabilizationProto.VIDEO_STABILIZATION_UNDEFINED 169 } 170 jcaSettings.updateData { currentSettings -> 171 currentSettings.toBuilder() 172 .setStabilizeVideo(newStatus) 173 .build() 174 } 175 } 176 177 override suspend fun updateDynamicRange(dynamicRange: DynamicRange) { 178 jcaSettings.updateData { currentSettings -> 179 currentSettings.toBuilder() 180 .setDynamicRangeStatus(dynamicRange.toProto()) 181 .build() 182 } 183 } 184 185 override suspend fun updateImageFormat(imageFormat: ImageOutputFormat) { 186 jcaSettings.updateData { currentSettings -> 187 currentSettings.toBuilder() 188 .setImageFormatStatus(imageFormat.toProto()) 189 .build() 190 } 191 } 192 } 193