diff --git a/feature/external-credential/src/main/java/com/simprints/feature/externalcredential/screens/scanocr/ExternalCredentialScanOcrFragment.kt b/feature/external-credential/src/main/java/com/simprints/feature/externalcredential/screens/scanocr/ExternalCredentialScanOcrFragment.kt index 6a55b6e4a2..162bf50e8b 100644 --- a/feature/external-credential/src/main/java/com/simprints/feature/externalcredential/screens/scanocr/ExternalCredentialScanOcrFragment.kt +++ b/feature/external-credential/src/main/java/com/simprints/feature/externalcredential/screens/scanocr/ExternalCredentialScanOcrFragment.kt @@ -19,6 +19,7 @@ import androidx.core.view.isVisible import androidx.fragment.app.Fragment import androidx.fragment.app.activityViewModels import androidx.fragment.app.viewModels +import androidx.lifecycle.Lifecycle import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.lifecycleScope @@ -38,6 +39,7 @@ import com.simprints.feature.externalcredential.screens.scanocr.usecase.ProvideC import com.simprints.feature.externalcredential.screens.search.model.ScannedCredential import com.simprints.infra.logging.LoggingConstants.CrashReportTag.MULTI_FACTOR_ID import com.simprints.infra.logging.Simber +import com.simprints.infra.uibase.camera.qrscan.CameraFocusManager import com.simprints.infra.uibase.navigation.navigateSafely import com.simprints.infra.uibase.view.applySystemBarInsets import com.simprints.infra.uibase.view.fadeIn @@ -97,6 +99,9 @@ internal class ExternalCredentialScanOcrFragment : Fragment(R.layout.fragment_ex @Inject lateinit var provideCameraListenerUseCase: ProvideCameraListenerUseCase + @Inject + lateinit var cameraFocusManagerFactory: CameraFocusManager.Factory + @Inject @DispatcherBG lateinit var bgDispatcher: CoroutineDispatcher @@ -114,7 +119,10 @@ internal class ExternalCredentialScanOcrFragment : Fragment(R.layout.fragment_ex super.onResume() val currentPermission = requireActivity().getCurrentPermissionStatus(CAMERA) when (currentPermission) { - PermissionStatus.Granted -> initializeFragment() + PermissionStatus.Granted -> { + initializeFragment() + } + PermissionStatus.Denied -> { // Permission dialog was already displayed, and user denied permissions. Showing rationale so to avoid constantly-appearing // system dialog. @@ -167,8 +175,13 @@ internal class ExternalCredentialScanOcrFragment : Fragment(R.layout.fragment_ex } } - ScanOcrState.NotScanning -> renderInitialState() - ScanOcrState.Complete -> animateCompletionState() + ScanOcrState.NotScanning -> { + renderInitialState() + } + + ScanOcrState.Complete -> { + animateCompletionState() + } } } @@ -198,6 +211,13 @@ internal class ExternalCredentialScanOcrFragment : Fragment(R.layout.fragment_ex onImageCaptureReady = { capture -> imageCapture = capture }, + onCameraReady = { camera -> + if (lifecycle.currentState == Lifecycle.State.RESUMED) { + val cameraFocusManager = cameraFocusManagerFactory.create(MULTI_FACTOR_ID) + cameraFocusManager.setUpFocusOnTap(binding.preview, camera) + cameraFocusManager.setUpAutoFocus(binding.preview, camera) + } + }, ) cameraProviderFuture.addListener(cameraListener, ContextCompat.getMainExecutor(requireContext())) } diff --git a/feature/external-credential/src/main/java/com/simprints/feature/externalcredential/screens/scanocr/usecase/ProvideCameraListenerUseCase.kt b/feature/external-credential/src/main/java/com/simprints/feature/externalcredential/screens/scanocr/usecase/ProvideCameraListenerUseCase.kt index 8e0f1c09aa..fb9d8ceb22 100644 --- a/feature/external-credential/src/main/java/com/simprints/feature/externalcredential/screens/scanocr/usecase/ProvideCameraListenerUseCase.kt +++ b/feature/external-credential/src/main/java/com/simprints/feature/externalcredential/screens/scanocr/usecase/ProvideCameraListenerUseCase.kt @@ -1,6 +1,7 @@ package com.simprints.feature.externalcredential.screens.scanocr.usecase import androidx.camera.core.AspectRatio +import androidx.camera.core.Camera import androidx.camera.core.CameraSelector import androidx.camera.core.ImageAnalysis import androidx.camera.core.ImageCapture @@ -21,6 +22,7 @@ internal class ProvideCameraListenerUseCase @Inject constructor() { viewLifecycleOwner: LifecycleOwner, onImageAnalysisReady: (ImageAnalysis) -> Unit, onImageCaptureReady: (ImageCapture) -> Unit, + onCameraReady: (Camera) -> Unit, ) = Runnable { val cameraProvider = cameraProviderFuture.get() val aspectRatio = AspectRatio.RATIO_16_9 @@ -48,9 +50,10 @@ internal class ProvideCameraListenerUseCase @Inject constructor() { try { cameraProvider.unbindAll() - cameraProvider.bindToLifecycle(viewLifecycleOwner, cameraSelector, preview, imageCapture, imageAnalysis) + val camera = cameraProvider.bindToLifecycle(viewLifecycleOwner, cameraSelector, preview, imageCapture, imageAnalysis) onImageAnalysisReady(imageAnalysis) onImageCaptureReady(imageCapture) + onCameraReady(camera) } catch (e: Exception) { Simber.e("Camera binding failed in OCR", e, MULTI_FACTOR_ID) }