diff --git a/android/src/main/java/com/mrousavy/camera/CameraView.kt b/android/src/main/java/com/mrousavy/camera/CameraView.kt index 2d7e8fb5ee..4eea054f06 100644 --- a/android/src/main/java/com/mrousavy/camera/CameraView.kt +++ b/android/src/main/java/com/mrousavy/camera/CameraView.kt @@ -68,7 +68,6 @@ import kotlin.math.min class CameraView(context: Context) : FrameLayout(context) { companion object { const val TAG = "CameraView" - const val TAG_PERF = "CameraView.performance" private val propsThatRequireSessionReconfiguration = arrayListOf("cameraId", "format", "fps", "hdr", "lowLightBoost", "photo", "video", "enableFrameProcessor") private val arrayListOfZoom = arrayListOf("zoom") @@ -101,6 +100,10 @@ class CameraView(context: Context) : FrameLayout(context) { private var isMounted = false private val cameraManager = context.getSystemService(Context.CAMERA_SERVICE) as CameraManager + // session + private var cameraSession: CameraCaptureSession? = null + private val previewView = SurfaceView(context) + public var frameProcessor: FrameProcessor? = null private val inputRotation: Int @@ -128,6 +131,23 @@ class CameraView(context: Context) : FrameLayout(context) { private var maxZoom: Float = 1f init { + this.installHierarchyFitter() + previewView.layoutParams = LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT) + previewView.holder.addCallback(object : SurfaceHolder.Callback { + override fun surfaceCreated(holder: SurfaceHolder) { + Log.i(TAG, "PreviewView Surface created!") + if (cameraId != null) configureSession() + } + + override fun surfaceChanged(holder: SurfaceHolder, format: Int, width: Int, height: Int) { + Log.i(TAG, "PreviewView Surface resized!") + } + + override fun surfaceDestroyed(holder: SurfaceHolder) { + Log.i(TAG, "PreviewView Surface destroyed!") + } + }) + addView(previewView) } override fun onConfigurationChanged(newConfig: Configuration?) { @@ -163,7 +183,7 @@ class CameraView(context: Context) : FrameLayout(context) { // TODO: updateLifecycleState() } if (shouldReconfigureSession) { - configureSession() + // configureSession() } if (shouldReconfigureZoom) { val zoomClamped = max(min(zoom, maxZoom), minZoom) @@ -185,7 +205,6 @@ class CameraView(context: Context) : FrameLayout(context) { * Configures the camera capture session. This should only be called when the camera device changes. */ private fun configureSession() { - val startTime = System.currentTimeMillis() Log.i(TAG, "Configuring session...") if (ContextCompat.checkSelfPermission(context, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) { throw CameraPermissionError() @@ -222,6 +241,7 @@ class CameraView(context: Context) : FrameLayout(context) { val characteristics = cameraManager.getCameraCharacteristics(camera.id) val isMirrored = characteristics.get(CameraCharacteristics.LENS_FACING) == CameraCharacteristics.LENS_FACING_FRONT + // Setting up Video / Frame Processor imageReader.setOnImageAvailableListener({ reader -> Log.d(TAG, "New Image available!") val image = reader.acquireNextImage() @@ -233,12 +253,15 @@ class CameraView(context: Context) : FrameLayout(context) { }, CameraQueues.videoQueue.handler) val frameProcessorOutput = SurfaceOutput(imageReader.surface, isMirrored) - val outputs = listOf(frameProcessorOutput) - val session = camera.createCaptureSession(SessionType.REGULAR, outputs, CameraQueues.cameraQueue) + val previewOutput = SurfaceOutput(previewView.holder.surface, isMirrored) + val outputs = listOf(frameProcessorOutput, previewOutput) + cameraSession = camera.createCaptureSession(SessionType.REGULAR, outputs, CameraQueues.cameraQueue) + // Start Video / Frame Processor val captureRequest = camera.createCaptureRequest(CameraDevice.TEMPLATE_MANUAL) captureRequest.addTarget(imageReader.surface) - session.setRepeatingRequest(captureRequest.build(), null, null) + captureRequest.addTarget(previewView.holder.surface) + cameraSession!!.setRepeatingRequest(captureRequest.build(), null, null) Log.i(TAG, "Successfully configured Camera Session!") invokeOnInitialized() diff --git a/android/src/main/java/com/mrousavy/camera/CameraViewModule.kt b/android/src/main/java/com/mrousavy/camera/CameraViewModule.kt index bdeb7f0594..3eebed6b32 100644 --- a/android/src/main/java/com/mrousavy/camera/CameraViewModule.kt +++ b/android/src/main/java/com/mrousavy/camera/CameraViewModule.kt @@ -146,7 +146,7 @@ class CameraViewModule(reactContext: ReactApplicationContext): ReactContextBaseJ val devices = Arguments.createArray() manager.cameraIdList.forEach { cameraId -> - val device = CameraDevice(manager, cameraId) + val device = CameraDeviceDetails(manager, cameraId) devices.pushMap(device.toMap()) } promise.resolve(devices) diff --git a/android/src/main/java/com/mrousavy/camera/utils/CameraDeviceDetails.kt b/android/src/main/java/com/mrousavy/camera/utils/CameraDeviceDetails.kt index 8d1dab901b..f293301e01 100644 --- a/android/src/main/java/com/mrousavy/camera/utils/CameraDeviceDetails.kt +++ b/android/src/main/java/com/mrousavy/camera/utils/CameraDeviceDetails.kt @@ -19,8 +19,8 @@ import com.mrousavy.camera.parsers.parseVideoStabilizationMode import kotlin.math.PI import kotlin.math.atan -class CameraDeviceDetails(private val cameraManager: CameraManager, private val cameraDevice: CameraDevice) { - private val characteristics = cameraManager.getCameraCharacteristics(cameraDevice.id) +class CameraDeviceDetails(private val cameraManager: CameraManager, private val cameraId: String) { + private val characteristics = cameraManager.getCameraCharacteristics(cameraId) private val hardwareLevel = characteristics.get(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL) ?: CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY private val capabilities = characteristics.get(CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES) ?: IntArray(0) private val extensions = getSupportedExtensions() @@ -35,7 +35,7 @@ class CameraDeviceDetails(private val cameraManager: CameraManager, private val private val focalLengths = characteristics.get(CameraCharacteristics.LENS_INFO_AVAILABLE_FOCAL_LENGTHS) ?: FloatArray(0) private val sensorSize = characteristics.get(CameraCharacteristics.SENSOR_INFO_PHYSICAL_SIZE)!! private val name = (if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) characteristics.get(CameraCharacteristics.INFO_VERSION) - else null) ?: "${parseLensFacing(lensFacing)} (${cameraDevice.id})" + else null) ?: "${parseLensFacing(lensFacing)} (${cameraId})" // "formats" (all possible configurations for this device) private val zoomRange = (if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) characteristics.get(CameraCharacteristics.CONTROL_ZOOM_RATIO_RANGE) @@ -56,7 +56,7 @@ class CameraDeviceDetails(private val cameraManager: CameraManager, private val // get extensions (HDR, Night Mode, ..) private fun getSupportedExtensions(): List { return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { - val extensions = cameraManager.getCameraExtensionCharacteristics(cameraDevice.id) + val extensions = cameraManager.getCameraExtensionCharacteristics(cameraId) extensions.supportedExtensions } else { emptyList() @@ -193,7 +193,7 @@ class CameraDeviceDetails(private val cameraManager: CameraManager, private val // convert to React Native JS object (map) fun toMap(): ReadableMap { val map = Arguments.createMap() - map.putString("id", cameraDevice.id) + map.putString("id", cameraId) map.putArray("devices", getDeviceTypes()) map.putString("position", parseLensFacing(lensFacing)) map.putString("name", name)