• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.LowLightBoostState
32 import com.google.jetpackcamera.settings.model.StabilizationMode
33 import com.google.jetpackcamera.settings.model.StreamConfig
34 import com.google.jetpackcamera.settings.model.VideoQuality
35 import kotlinx.coroutines.channels.ReceiveChannel
36 import kotlinx.coroutines.flow.StateFlow
37 
38 /**
39  * Data layer for camera.
40  */
41 interface CameraUseCase {
42     /**
43      * Initializes the camera.
44      *
45      * @return list of available lenses.
46      */
initializenull47     suspend fun initialize(
48         cameraAppSettings: CameraAppSettings,
49         isDebugMode: Boolean = false,
50         cameraPropertiesJSONCallback: (result: String) -> Unit
51     )
52 
53     /**
54      * Starts the camera.
55      *
56      * This will start to configure the camera, but frames won't stream until a [SurfaceRequest]
57      * from [getSurfaceRequest] has been fulfilled.
58      *
59      * The camera will run until the calling coroutine is cancelled.
60      */
61     suspend fun runCamera()
62 
63     suspend fun takePicture(onCaptureStarted: (() -> Unit) = {})
64 
65     /**
66      * Takes a picture with the camera. If ignoreUri is set to true, the picture taken will be saved
67      * at the default directory for pictures on device. Otherwise, it will be saved at the uri
68      * location if the uri is not null. If it is null, an error will be thrown.
69      */
takePicturenull70     suspend fun takePicture(
71         onCaptureStarted: (() -> Unit) = {},
72         contentResolver: ContentResolver,
73         imageCaptureUri: Uri?,
74         ignoreUri: Boolean = false
75     ): ImageCapture.OutputFileResults
76 
startVideoRecordingnull77     suspend fun startVideoRecording(
78         videoCaptureUri: Uri?,
79         shouldUseUri: Boolean,
80         onVideoRecord: (OnVideoRecordEvent) -> Unit
81     )
82 
83     suspend fun pauseVideoRecording()
84 
85     suspend fun resumeVideoRecording()
86 
87     suspend fun stopVideoRecording()
88 
89     fun setZoomScale(scale: Float)
90 
91     fun getCurrentCameraState(): StateFlow<CameraState>
92 
93     fun getSurfaceRequest(): StateFlow<SurfaceRequest?>
94 
95     fun getScreenFlashEvents(): ReceiveChannel<ScreenFlashEvent>
96 
97     fun getCurrentSettings(): StateFlow<CameraAppSettings?>
98 
99     fun setFlashMode(flashMode: FlashMode)
100 
101     fun isScreenFlashEnabled(): Boolean
102 
103     suspend fun setAspectRatio(aspectRatio: AspectRatio)
104 
105     suspend fun setVideoQuality(videoQuality: VideoQuality)
106 
107     suspend fun setLensFacing(lensFacing: LensFacing)
108 
109     suspend fun tapToFocus(x: Float, y: Float)
110 
111     suspend fun setStreamConfig(streamConfig: StreamConfig)
112 
113     suspend fun setDynamicRange(dynamicRange: DynamicRange)
114 
115     fun setDeviceRotation(deviceRotation: DeviceRotation)
116 
117     suspend fun setConcurrentCameraMode(concurrentCameraMode: ConcurrentCameraMode)
118 
119     suspend fun setImageFormat(imageFormat: ImageOutputFormat)
120 
121     suspend fun setAudioEnabled(isAudioEnabled: Boolean)
122 
123     suspend fun setStabilizationMode(stabilizationMode: StabilizationMode)
124 
125     suspend fun setTargetFrameRate(targetFrameRate: Int)
126 
127     suspend fun setMaxVideoDuration(durationInMillis: Long)
128 
129     suspend fun setCaptureMode(captureMode: CaptureMode)
130 
131     /**
132      * Represents the events required for screen flash.
133      */
134     data class ScreenFlashEvent(val type: Type, val onComplete: () -> Unit) {
135         enum class Type {
136             APPLY_UI,
137             CLEAR_UI
138         }
139     }
140 
141     /**
142      * Represents the events for video recording.
143      */
144 
145     sealed interface OnVideoRecordEvent {
146         data class OnVideoRecorded(val savedUri: Uri) : OnVideoRecordEvent
147 
148         data class OnVideoRecordError(val error: Throwable) : OnVideoRecordEvent
149     }
150 }
151 
152 sealed interface VideoRecordingState {
153 
154     /**
155      * [PendingRecording][androidx.camera.video.PendingRecording] has not yet started but is about to.
156      * This state may be used as a signal to start processes just before the recording actually starts.
157      */
158     data object Starting : VideoRecordingState
159 
160     /**
161      * Camera is not currently recording a video
162      */
163     data class Inactive(val finalElapsedTimeNanos: Long = 0) : VideoRecordingState
164 
165     /**
166      * Camera is currently active; paused, stopping, or recording a video
167      */
168     sealed interface Active : VideoRecordingState {
169         val maxDurationMillis: Long
170         val audioAmplitude: Double
171         val elapsedTimeNanos: Long
172 
173         data class Recording(
174             override val maxDurationMillis: Long,
175             override val audioAmplitude: Double,
176             override val elapsedTimeNanos: Long
177         ) : Active
178 
179         data class Paused(
180             override val maxDurationMillis: Long,
181             override val audioAmplitude: Double,
182             override val elapsedTimeNanos: Long
183         ) : Active
184     }
185 }
186 
187 data class CameraState(
188     val videoRecordingState: VideoRecordingState = VideoRecordingState.Inactive(),
189     val zoomScale: Float = 1f,
190     val sessionFirstFrameTimestamp: Long = 0L,
191     val torchEnabled: Boolean = false,
192     val stabilizationMode: StabilizationMode = StabilizationMode.OFF,
193     val lowLightBoostState: LowLightBoostState = LowLightBoostState.INACTIVE,
194     val debugInfo: DebugInfo = DebugInfo(null, null),
195     val videoQualityInfo: VideoQualityInfo = VideoQualityInfo(VideoQuality.UNSPECIFIED, 0, 0)
196 )
197 
198 data class DebugInfo(val logicalCameraId: String?, val physicalCameraId: String?)
199 
200 data class VideoQualityInfo(val quality: VideoQuality, val width: Int, val height: Int)
201