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.core.camera
17 
18 import android.content.ContentResolver
19 import android.net.Uri
20 import androidx.camera.core.ImageCapture
21 import androidx.camera.core.SurfaceRequest
22 import com.google.jetpackcamera.settings.model.AspectRatio
23 import com.google.jetpackcamera.settings.model.CameraAppSettings
24 import com.google.jetpackcamera.settings.model.CaptureMode
25 import com.google.jetpackcamera.settings.model.ConcurrentCameraMode
26 import com.google.jetpackcamera.settings.model.DeviceRotation
27 import com.google.jetpackcamera.settings.model.DynamicRange
28 import com.google.jetpackcamera.settings.model.FlashMode
29 import com.google.jetpackcamera.settings.model.ImageOutputFormat
30 import com.google.jetpackcamera.settings.model.LensFacing
31 import com.google.jetpackcamera.settings.model.LowLightBoost
32 import com.google.jetpackcamera.settings.model.Stabilization
33 import kotlinx.coroutines.channels.ReceiveChannel
34 import kotlinx.coroutines.flow.StateFlow
35 
36 /**
37  * Data layer for camera.
38  */
39 interface CameraUseCase {
40     /**
41      * Initializes the camera.
42      *
43      * @return list of available lenses.
44      */
initializenull45     suspend fun initialize(
46         cameraAppSettings: CameraAppSettings,
47         useCaseMode: UseCaseMode,
48         isDebugMode: Boolean = false
49     )
50 
51     /**
52      * Starts the camera.
53      *
54      * This will start to configure the camera, but frames won't stream until a [SurfaceRequest]
55      * from [getSurfaceRequest] has been fulfilled.
56      *
57      * The camera will run until the calling coroutine is cancelled.
58      */
59     suspend fun runCamera()
60 
61     suspend fun takePicture(onCaptureStarted: (() -> Unit) = {})
62 
63     /**
64      * Takes a picture with the camera. If ignoreUri is set to true, the picture taken will be saved
65      * at the default directory for pictures on device. Otherwise, it will be saved at the uri
66      * location if the uri is not null. If it is null, an error will be thrown.
67      */
takePicturenull68     suspend fun takePicture(
69         onCaptureStarted: (() -> Unit) = {},
70         contentResolver: ContentResolver,
71         imageCaptureUri: Uri?,
72         ignoreUri: Boolean = false
73     ): ImageCapture.OutputFileResults
74 
startVideoRecordingnull75     suspend fun startVideoRecording(
76         videoCaptureUri: Uri?,
77         shouldUseUri: Boolean,
78         onVideoRecord: (OnVideoRecordEvent) -> Unit
79     )
80 
81     fun stopVideoRecording()
82 
83     fun setZoomScale(scale: Float)
84 
85     fun getCurrentCameraState(): StateFlow<CameraState>
86 
87     fun getSurfaceRequest(): StateFlow<SurfaceRequest?>
88 
89     fun getScreenFlashEvents(): ReceiveChannel<ScreenFlashEvent>
90 
91     fun getCurrentSettings(): StateFlow<CameraAppSettings?>
92 
93     fun setFlashMode(flashMode: FlashMode)
94 
95     fun isScreenFlashEnabled(): Boolean
96 
97     suspend fun setAspectRatio(aspectRatio: AspectRatio)
98 
99     suspend fun setLensFacing(lensFacing: LensFacing)
100 
101     suspend fun tapToFocus(x: Float, y: Float)
102 
103     suspend fun setCaptureMode(captureMode: CaptureMode)
104 
105     suspend fun setDynamicRange(dynamicRange: DynamicRange)
106 
107     fun setDeviceRotation(deviceRotation: DeviceRotation)
108 
109     suspend fun setConcurrentCameraMode(concurrentCameraMode: ConcurrentCameraMode)
110 
111     suspend fun setLowLightBoost(lowLightBoost: LowLightBoost)
112 
113     suspend fun setImageFormat(imageFormat: ImageOutputFormat)
114 
115     suspend fun setAudioMuted(isAudioMuted: Boolean)
116 
117     suspend fun setVideoCaptureStabilization(videoCaptureStabilization: Stabilization)
118 
119     suspend fun setPreviewStabilization(previewStabilization: Stabilization)
120 
121     suspend fun setTargetFrameRate(targetFrameRate: Int)
122 
123     /**
124      * Represents the events required for screen flash.
125      */
126     data class ScreenFlashEvent(val type: Type, val onComplete: () -> Unit) {
127         enum class Type {
128             APPLY_UI,
129             CLEAR_UI
130         }
131     }
132 
133     /**
134      * Represents the events for video recording.
135      */
136     sealed interface OnVideoRecordEvent {
137         data class OnVideoRecorded(val savedUri: Uri) : OnVideoRecordEvent
138 
139         data class OnVideoRecordStatus(val audioAmplitude: Double) : OnVideoRecordEvent
140 
141         data class OnVideoRecordError(val error: Throwable?) : OnVideoRecordEvent
142     }
143 
144     enum class UseCaseMode {
145         STANDARD,
146         IMAGE_ONLY,
147         VIDEO_ONLY
148     }
149 }
150 
151 data class CameraState(
152     val zoomScale: Float = 1f,
153     val sessionFirstFrameTimestamp: Long = 0L,
154     val torchEnabled: Boolean = false,
155     val debugInfo: DebugInfo = DebugInfo(null, null)
156 )
157 
158 data class DebugInfo(val logicalCameraId: String?, val physicalCameraId: String?)
159