diff --git a/core/camera/src/main/java/com/google/jetpackcamera/core/camera/CameraEvent.kt b/core/camera/src/main/java/com/google/jetpackcamera/core/camera/CameraEvent.kt index 0fe8cc672..8f68b1759 100644 --- a/core/camera/src/main/java/com/google/jetpackcamera/core/camera/CameraEvent.kt +++ b/core/camera/src/main/java/com/google/jetpackcamera/core/camera/CameraEvent.kt @@ -18,7 +18,7 @@ package com.google.jetpackcamera.core.camera /** * An event that can be sent to the camera coroutine. */ -sealed interface CameraEvent { +internal sealed interface CameraEvent { /** * Represents a focus metering event, that the camera can act on. diff --git a/core/camera/src/main/java/com/google/jetpackcamera/core/camera/CameraState.kt b/core/camera/src/main/java/com/google/jetpackcamera/core/camera/CameraState.kt index 91f6203ab..b258a5084 100644 --- a/core/camera/src/main/java/com/google/jetpackcamera/core/camera/CameraState.kt +++ b/core/camera/src/main/java/com/google/jetpackcamera/core/camera/CameraState.kt @@ -21,6 +21,23 @@ import com.google.jetpackcamera.model.LowLightBoostState import com.google.jetpackcamera.model.StabilizationMode import com.google.jetpackcamera.model.VideoQuality +/** + * Represents the state of the camera. + * + * @param videoRecordingState The current state of video recording. + * @param zoomRatios A map of [LensFacing] to the current zoom ratio. This value is updated from + * the camera's [android.hardware.camera2.TotalCaptureResult] or [androidx.camera.core.ZoomState]. + * @param linearZoomScales A map of [LensFacing] to the current linear zoom scale. + * @param sessionFirstFrameTimestamp The timestamp of the first frame of the current camera session. + * @param isTorchEnabled Whether the torch is currently enabled. + * @param isCameraRunning Whether the camera is currently running. + * @param stabilizationMode The current video stabilization mode. This value is updated from the + * camera's [android.hardware.camera2.TotalCaptureResult]. + * @param lowLightBoostState The current state of the low light boost feature. + * @param debugInfo Information for debugging purposes. + * @param videoQualityInfo Information about the current video quality. + * @param focusState The current focus state of the camera. + */ data class CameraState( val videoRecordingState: VideoRecordingState = VideoRecordingState.Inactive(), val zoomRatios: Map = mapOf(), @@ -35,59 +52,126 @@ data class CameraState( val focusState: FocusState = FocusState.Unspecified ) +/** + * Contains debugging information about the camera. + * + * @param logicalCameraId The ID of the logical camera. This value is derived from the session's + * [CameraDevice.getId()](https://developer.android.com/reference/android/hardware/camera2/CameraDevice#getId()). + * @param physicalCameraId The ID of the physical camera. This value is derived from the + * [TotalCaptureResult] of the current session. + */ data class DebugInfo(val logicalCameraId: String?, val physicalCameraId: String?) /** - * Represents the UI state of an autofocus event + * Represents the UI state of an autofocus event. */ sealed interface FocusState { - + /** + * The camera's focus is in an unspecified state. + */ data object Unspecified : FocusState + /** + * The camera's focus has been explicitly set. + * + * @param x The x-coordinate of the focus point. + * @param y The y-coordinate of the focus point. + * @param status The status of the focus operation. + */ data class Specified( val x: Float, val y: Float, val status: Status ) : FocusState + /** + * Represents the status of a focus operation. + */ enum class Status { + /** + * The focus operation is in progress. + */ RUNNING, + + /** + * The focus operation completed successfully. + */ SUCCESS, + + /** + * The focus operation failed. + */ FAILURE, + + /** + * The focus operation was cancelled. + */ CANCELLED } } +/** + * Contains information about the video quality. + * + * @param quality The selected video quality. + * @param width The width of the video in pixels. + * @param height The height of the video in pixels. + */ data class VideoQualityInfo(val quality: VideoQuality, val width: Int, val height: Int) +/** + * Represents the state of video recording. + */ sealed interface VideoRecordingState { /** * Indicates that a [PendingRecording][androidx.camera.video.PendingRecording] is about to start. * This state may be used as a signal to start processes just before the recording actually starts. + * + * @param initialRecordingSettings The initial settings for the recording. */ data class Starting(val initialRecordingSettings: InitialRecordingSettings? = null) : VideoRecordingState /** - * Camera is not currently recording a video + * Camera is not currently recording a video. + * + * @param finalElapsedTimeNanos The final elapsed time of the recording in nanoseconds. This is + * not an error but the actual duration of the video. */ data class Inactive(val finalElapsedTimeNanos: Long = 0) : VideoRecordingState /** - * Camera is currently active; paused, stopping, or recording a video + * Camera is currently active; paused, stopping, or recording a video. */ sealed interface Active : VideoRecordingState { + /** + * The maximum duration of the recording in milliseconds. + */ val maxDurationMillis: Long + + /** + * The current amplitude of the audio being recorded. + */ val audioAmplitude: Double + + /** + * The elapsed time of the recording in nanoseconds. + */ val elapsedTimeNanos: Long + /** + * The camera is currently recording. + */ data class Recording( override val maxDurationMillis: Long, override val audioAmplitude: Double, override val elapsedTimeNanos: Long ) : Active + /** + * The camera is currently paused. + */ data class Paused( override val maxDurationMillis: Long, override val audioAmplitude: Double, @@ -100,7 +184,17 @@ sealed interface VideoRecordingState { * Represents the events for video recording. */ sealed interface OnVideoRecordEvent { + /** + * The video was recorded successfully. + * + * @param savedUri The [Uri] of the saved video. + */ data class OnVideoRecorded(val savedUri: Uri) : OnVideoRecordEvent + /** + * An error occurred while recording the video. + * + * @param error The [Throwable] that caused the error. + */ data class OnVideoRecordError(val error: Throwable) : OnVideoRecordEvent } diff --git a/core/camera/src/main/java/com/google/jetpackcamera/core/camera/CameraSystem.kt b/core/camera/src/main/java/com/google/jetpackcamera/core/camera/CameraSystem.kt index 362bafd49..4fd0e6fb5 100644 --- a/core/camera/src/main/java/com/google/jetpackcamera/core/camera/CameraSystem.kt +++ b/core/camera/src/main/java/com/google/jetpackcamera/core/camera/CameraSystem.kt @@ -62,12 +62,20 @@ interface CameraSystem { */ suspend fun runCamera() + /** + * Takes a picture with the camera. + * + * @param onCaptureStarted A callback that is invoked when the capture starts. + */ suspend fun takePicture(onCaptureStarted: (() -> Unit) = {}) /** - * Takes a picture with the camera. If ignoreUri is set to true, the picture taken will be saved - * at the default directory for pictures on device. Otherwise, it will be saved at the uri - * location if the uri is not null. If it is null, an error will be thrown. + * Takes a picture with the camera and saves it to a specified [SaveLocation]. + * + * @param contentResolver The [ContentResolver] to use for saving the image. + * @param saveLocation The location to save the captured image. + * @param onCaptureStarted A callback that is invoked when the capture starts. + * @return An [ImageCapture.OutputFileResults] object containing the result of the capture. */ suspend fun takePicture( contentResolver: ContentResolver, @@ -75,63 +83,187 @@ interface CameraSystem { onCaptureStarted: (() -> Unit) = {} ): ImageCapture.OutputFileResults + /** + * Starts video recording. + * + * @param saveLocation The location to save the recorded video. + * @param onVideoRecord A callback to handle video recording events. + */ suspend fun startVideoRecording( saveLocation: SaveLocation, onVideoRecord: (OnVideoRecordEvent) -> Unit ) + /** + * Pauses the current video recording. + */ suspend fun pauseVideoRecording() + /** + * Resumes the current video recording. + */ suspend fun resumeVideoRecording() + /** + * Stops the current video recording. + */ suspend fun stopVideoRecording() + /** + * Sets the zoom ratio for the camera. + * + * @param newZoomState The new zoom state to apply. + */ fun changeZoomRatio(newZoomState: CameraZoomRatio) + /** + * Sets the test pattern for the camera. + * + * @param newTestPattern The new test pattern to apply. + */ fun setTestPattern(newTestPattern: TestPattern) + /** + * Returns a [StateFlow] of the current [CameraState]. + */ fun getCurrentCameraState(): StateFlow + /** + * Returns a [StateFlow] of the current [CameraSystemConstraints]. + */ fun getSystemConstraints(): StateFlow + /** + * Returns a [StateFlow] of the current [SurfaceRequest]. + */ fun getSurfaceRequest(): StateFlow + /** + * Returns a [ReceiveChannel] for [ScreenFlashEvent]s. + */ fun getScreenFlashEvents(): ReceiveChannel + /** + * Returns a [StateFlow] of the current [CameraAppSettings]. + */ fun getCurrentSettings(): StateFlow + /** + * Sets the flash mode for the camera. + * + * @param flashMode The [FlashMode] to set. + */ fun setFlashMode(flashMode: FlashMode) + /** + * Returns whether screen flash is currently enabled. + */ fun isScreenFlashEnabled(): Boolean + /** + * Sets the aspect ratio for the camera. + * + * @param aspectRatio The [AspectRatio] to set. + */ suspend fun setAspectRatio(aspectRatio: AspectRatio) + /** + * Sets the video quality for the camera. + * + * @param videoQuality The [VideoQuality] to set. + */ suspend fun setVideoQuality(videoQuality: VideoQuality) + /** + * Sets the low light boost priority. + * + * @param lowLightBoostPriority The [LowLightBoostPriority] to set. + */ suspend fun setLowLightBoostPriority(lowLightBoostPriority: LowLightBoostPriority) + /** + * Sets the lens facing for the camera. + * + * @param lensFacing The [LensFacing] to set. + */ suspend fun setLensFacing(lensFacing: LensFacing) + /** + * Initiates a tap-to-focus action at the specified coordinates. + * + * @param x The x-coordinate of the focus point, normalized from 0.0 to 1.0. + * @param y The y-coordinate of the focus point, normalized from 0.0 to 1.0. + */ suspend fun tapToFocus(x: Float, y: Float) + /** + * Sets the stream configuration for the camera. + * + * @param streamConfig The [StreamConfig] to set. + */ suspend fun setStreamConfig(streamConfig: StreamConfig) + /** + * Sets the dynamic range for the camera. + * + * @param dynamicRange The [DynamicRange] to set. + */ suspend fun setDynamicRange(dynamicRange: DynamicRange) + /** + * Sets the device rotation. + * + * @param deviceRotation The [DeviceRotation] to set. + */ fun setDeviceRotation(deviceRotation: DeviceRotation) + /** + * Sets the concurrent camera mode. + * + * @param concurrentCameraMode The [ConcurrentCameraMode] to set. + */ suspend fun setConcurrentCameraMode(concurrentCameraMode: ConcurrentCameraMode) + /** + * Sets the image output format. + * + * @param imageFormat The [ImageOutputFormat] to set. + */ suspend fun setImageFormat(imageFormat: ImageOutputFormat) + /** + * Sets whether audio is enabled for video recording. + * + * @param isAudioEnabled Whether audio should be enabled. + */ suspend fun setAudioEnabled(isAudioEnabled: Boolean) + /** + * Sets the video stabilization mode. + * + * @param stabilizationMode The [StabilizationMode] to set. + */ suspend fun setStabilizationMode(stabilizationMode: StabilizationMode) + /** + * Sets the target frame rate for video recording. + * + * @param targetFrameRate The target frame rate in frames per second. + */ suspend fun setTargetFrameRate(targetFrameRate: Int) + /** + * Sets the maximum video duration. + * + * @param durationInMillis The maximum duration in milliseconds. + */ suspend fun setMaxVideoDuration(durationInMillis: Long) + /** + * Sets the capture mode for the camera. + * + * @param captureMode The [CaptureMode] to set. + */ suspend fun setCaptureMode(captureMode: CaptureMode) /** diff --git a/core/camera/src/main/java/com/google/jetpackcamera/core/camera/SurfaceToSensorMeteringPointFactory.kt b/core/camera/src/main/java/com/google/jetpackcamera/core/camera/SurfaceToSensorMeteringPointFactory.kt index 27279c470..367ecfecd 100644 --- a/core/camera/src/main/java/com/google/jetpackcamera/core/camera/SurfaceToSensorMeteringPointFactory.kt +++ b/core/camera/src/main/java/com/google/jetpackcamera/core/camera/SurfaceToSensorMeteringPointFactory.kt @@ -31,7 +31,7 @@ import androidx.camera.core.MeteringPointFactory * @param sensorToBufferTransform The transform from sensor coordinates to buffer coordinates. */ @SuppressLint("RestrictedApi") -class SurfaceToSensorMeteringPointFactory( +internal class SurfaceToSensorMeteringPointFactory( private val sensorRect: Rect, private val sensorToBufferTransform: Matrix ) : MeteringPointFactory(Rational(sensorRect.width(), sensorRect.height())) { diff --git a/core/camera/src/main/java/com/google/jetpackcamera/core/camera/VideoCaptureControlEvent.kt b/core/camera/src/main/java/com/google/jetpackcamera/core/camera/VideoCaptureControlEvent.kt index cf998eb64..20096e105 100644 --- a/core/camera/src/main/java/com/google/jetpackcamera/core/camera/VideoCaptureControlEvent.kt +++ b/core/camera/src/main/java/com/google/jetpackcamera/core/camera/VideoCaptureControlEvent.kt @@ -20,7 +20,7 @@ import com.google.jetpackcamera.model.SaveLocation /** * Represents events that control video capture operations. */ -sealed interface VideoCaptureControlEvent { +internal sealed interface VideoCaptureControlEvent { /** * Starts video recording. diff --git a/core/camera/src/main/java/com/google/jetpackcamera/core/camera/effects/EGLSpecV14ES3.kt b/core/camera/src/main/java/com/google/jetpackcamera/core/camera/effects/EGLSpecV14ES3.kt index bf6e3ca2a..45105d06c 100644 --- a/core/camera/src/main/java/com/google/jetpackcamera/core/camera/effects/EGLSpecV14ES3.kt +++ b/core/camera/src/main/java/com/google/jetpackcamera/core/camera/effects/EGLSpecV14ES3.kt @@ -20,7 +20,7 @@ import android.opengl.EGLConfig import android.opengl.EGLContext import androidx.graphics.opengl.egl.EGLSpec -val EGLSpec.Companion.V14ES3: EGLSpec +internal val EGLSpec.Companion.V14ES3: EGLSpec get() = object : EGLSpec by V14 { private val contextAttributes = intArrayOf( diff --git a/core/camera/src/main/java/com/google/jetpackcamera/core/camera/effects/GLDebug.kt b/core/camera/src/main/java/com/google/jetpackcamera/core/camera/effects/GLDebug.kt index d9e3fe178..6cd878741 100644 --- a/core/camera/src/main/java/com/google/jetpackcamera/core/camera/effects/GLDebug.kt +++ b/core/camera/src/main/java/com/google/jetpackcamera/core/camera/effects/GLDebug.kt @@ -15,7 +15,7 @@ */ package com.google.jetpackcamera.core.camera.effects -object GLDebug { +internal object GLDebug { init { System.loadLibrary("opengl_debug_lib") } diff --git a/core/camera/src/main/java/com/google/jetpackcamera/core/camera/effects/ShaderCopy.kt b/core/camera/src/main/java/com/google/jetpackcamera/core/camera/effects/ShaderCopy.kt index 0677b2319..659d24c78 100644 --- a/core/camera/src/main/java/com/google/jetpackcamera/core/camera/effects/ShaderCopy.kt +++ b/core/camera/src/main/java/com/google/jetpackcamera/core/camera/effects/ShaderCopy.kt @@ -33,7 +33,7 @@ import java.nio.ByteBuffer import java.nio.ByteOrder import java.nio.FloatBuffer -class ShaderCopy(private val dynamicRange: DynamicRange) : RenderCallbacks { +internal class ShaderCopy(private val dynamicRange: DynamicRange) : RenderCallbacks { // Called on worker thread only private var externalTextureId: Int = -1 diff --git a/core/camera/src/main/java/com/google/jetpackcamera/core/camera/effects/SingleSurfaceForcingEffect.kt b/core/camera/src/main/java/com/google/jetpackcamera/core/camera/effects/SingleSurfaceForcingEffect.kt index 625b2fca9..1a81e030c 100644 --- a/core/camera/src/main/java/com/google/jetpackcamera/core/camera/effects/SingleSurfaceForcingEffect.kt +++ b/core/camera/src/main/java/com/google/jetpackcamera/core/camera/effects/SingleSurfaceForcingEffect.kt @@ -30,7 +30,7 @@ private const val TARGETS = * * Used as a workaround to force the above 3 use cases to use a single camera stream. */ -class SingleSurfaceForcingEffect(coroutineScope: CoroutineScope) : CameraEffect( +internal class SingleSurfaceForcingEffect(coroutineScope: CoroutineScope) : CameraEffect( TARGETS, Runnable::run, CopyingSurfaceProcessor(coroutineScope), diff --git a/core/camera/src/main/java/com/google/jetpackcamera/core/camera/effects/processors/CopyingSurfaceProcessor.kt b/core/camera/src/main/java/com/google/jetpackcamera/core/camera/effects/processors/CopyingSurfaceProcessor.kt index 9f354613d..9af5f7b6c 100644 --- a/core/camera/src/main/java/com/google/jetpackcamera/core/camera/effects/processors/CopyingSurfaceProcessor.kt +++ b/core/camera/src/main/java/com/google/jetpackcamera/core/camera/effects/processors/CopyingSurfaceProcessor.kt @@ -51,7 +51,7 @@ private const val TIMESTAMP_UNINITIALIZED = -1L * This is a [SurfaceProcessor] that passes on the same content from the input * surface to the output surface. Used to make a copies of surfaces. */ -class CopyingSurfaceProcessor(coroutineScope: CoroutineScope) : SurfaceProcessor { +internal class CopyingSurfaceProcessor(coroutineScope: CoroutineScope) : SurfaceProcessor { private val inputSurfaceFlow = MutableStateFlow(null) private val outputSurfaceFlow = MutableStateFlow(null)