1 /* 2 * Copyright 2022 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 17 package androidx.camera.camera2.pipe.integration.impl 18 19 import android.hardware.camera2.CameraCaptureSession 20 import android.hardware.camera2.CameraDevice 21 import android.os.Build 22 import android.view.Surface 23 import androidx.annotation.RequiresApi 24 import androidx.camera.camera2.pipe.core.Log 25 import androidx.camera.core.impl.SessionConfig 26 import kotlinx.atomicfu.AtomicRef 27 import kotlinx.atomicfu.atomic 28 29 /** 30 * A application-level single-instance repository for Camera Interop callbacks. It supplies 31 * camera-pipe with internal callbacks on CameraX initialization. During runtime, before a camera 32 * graph is created, CameraX updates these internal callbacks with Camera Interop callbacks so that 33 * they may be triggered in camera-pipe. 34 */ 35 public class CameraInteropStateCallbackRepository { 36 37 private val _deviceStateCallback = CameraInteropDeviceStateCallback() 38 private val _sessionStateCallback = CameraInteropSessionStateCallback() 39 40 /** 41 * Called after merging all sessionConfigs from CameraX useCases and UseCases supplied by Camera 42 * Interop. If the Interop has any callbacks, they would be contained in the sessionConfig. 43 * CameraInteropStateCallbackRepository would store these callbacks to be triggered by 44 * camera-pipe. 45 * 46 * @param sessionConfig the final merged sessionConfig used to create camera graph 47 */ updateCallbacksnull48 public fun updateCallbacks(sessionConfig: SessionConfig) { 49 _deviceStateCallback.updateCallbacks(sessionConfig) 50 _sessionStateCallback.updateCallbacks(sessionConfig) 51 } 52 53 public val deviceStateCallback: CameraInteropDeviceStateCallback 54 get() = _deviceStateCallback 55 56 public val sessionStateCallback: CameraInteropSessionStateCallback 57 get() = _sessionStateCallback 58 59 public class CameraInteropDeviceStateCallback : CameraDevice.StateCallback() { 60 61 private var callbacks: AtomicRef<List<CameraDevice.StateCallback>> = atomic(listOf()) 62 updateCallbacksnull63 internal fun updateCallbacks(sessionConfig: SessionConfig) { 64 callbacks.value = sessionConfig.deviceStateCallbacks.toList() 65 } 66 onOpenednull67 override fun onOpened(cameraDevice: CameraDevice) { 68 for (callback in callbacks.value) { 69 callback.onOpened(cameraDevice) 70 } 71 } 72 onClosednull73 override fun onClosed(cameraDevice: CameraDevice) { 74 for (callback in callbacks.value) { 75 callback.onClosed(cameraDevice) 76 } 77 } 78 onDisconnectednull79 override fun onDisconnected(cameraDevice: CameraDevice) { 80 for (callback in callbacks.value) { 81 callback.onDisconnected(cameraDevice) 82 } 83 } 84 onErrornull85 override fun onError(cameraDevice: CameraDevice, errorCode: Int) { 86 for (callback in callbacks.value) { 87 callback.onError(cameraDevice, errorCode) 88 } 89 } 90 } 91 92 public class CameraInteropSessionStateCallback : CameraCaptureSession.StateCallback() { 93 94 private var callbacks: AtomicRef<List<CameraCaptureSession.StateCallback>> = 95 atomic(listOf()) 96 updateCallbacksnull97 internal fun updateCallbacks(sessionConfig: SessionConfig) { 98 callbacks.value = sessionConfig.sessionStateCallbacks.toList() 99 } 100 onConfigurednull101 override fun onConfigured(session: CameraCaptureSession) { 102 for (callback in callbacks.value) { 103 callback.onConfigured(session) 104 } 105 } 106 onConfigureFailednull107 override fun onConfigureFailed(session: CameraCaptureSession) { 108 for (callback in callbacks.value) { 109 callback.onConfigureFailed(session) 110 } 111 } 112 onReadynull113 override fun onReady(session: CameraCaptureSession) { 114 for (callback in callbacks.value) { 115 callback.onReady(session) 116 } 117 } 118 onActivenull119 override fun onActive(session: CameraCaptureSession) { 120 for (callback in callbacks.value) { 121 callback.onActive(session) 122 } 123 } 124 onCaptureQueueEmptynull125 override fun onCaptureQueueEmpty(session: CameraCaptureSession) { 126 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { 127 Api26CompatImpl.onCaptureQueueEmpty(session, callbacks) 128 } else { 129 Log.error { "onCaptureQueueEmpty called for unsupported OS version." } 130 } 131 } 132 onClosednull133 override fun onClosed(session: CameraCaptureSession) { 134 for (callback in callbacks.value) { 135 callback.onClosed(session) 136 } 137 } 138 onSurfacePreparednull139 override fun onSurfacePrepared(session: CameraCaptureSession, surface: Surface) { 140 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { 141 Api23CompatImpl.onSurfacePrepared(session, surface, callbacks) 142 } else { 143 Log.error { "onSurfacePrepared called for unsupported OS version." } 144 } 145 } 146 147 @RequiresApi(Build.VERSION_CODES.M) 148 private object Api23CompatImpl { 149 @JvmStatic onSurfacePreparednull150 fun onSurfacePrepared( 151 session: CameraCaptureSession, 152 surface: Surface, 153 callbacks: AtomicRef<List<CameraCaptureSession.StateCallback>> 154 ) { 155 for (callback in callbacks.value) { 156 callback.onSurfacePrepared(session, surface) 157 } 158 } 159 } 160 161 @RequiresApi(Build.VERSION_CODES.O) 162 private object Api26CompatImpl { 163 @JvmStatic onCaptureQueueEmptynull164 fun onCaptureQueueEmpty( 165 session: CameraCaptureSession, 166 callbacks: AtomicRef<List<CameraCaptureSession.StateCallback>> 167 ) { 168 for (callback in callbacks.value) { 169 callback.onCaptureQueueEmpty(session) 170 } 171 } 172 } 173 } 174 } 175