Skip to content

Commit

Permalink
fix: initialize camera before use in SimpleScanActivity.kt
Browse files Browse the repository at this point in the history
ref: use factory methods for CameraView.kt
  • Loading branch information
VaiTon committed Jun 19, 2022
1 parent 8d97da6 commit 6233fa3
Show file tree
Hide file tree
Showing 4 changed files with 89 additions and 87 deletions.
Expand Up @@ -3,9 +3,11 @@ package openfoodfacts.github.scrachx.openfood.features.scan
import android.view.ViewStub
import android.widget.FrameLayout
import androidx.annotation.CallSuper
import androidx.annotation.DrawableRes
import androidx.annotation.LayoutRes
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.isVisible
import openfoodfacts.github.scrachx.openfood.R

abstract class CameraView<T : FrameLayout>(
protected val activity: AppCompatActivity,
Expand Down Expand Up @@ -52,4 +54,33 @@ abstract class CameraView<T : FrameLayout>(
// Default impl
}

companion object {
fun of(activity: AppCompatActivity, viewStub: ViewStub, mlScannerEnabled: Boolean): CameraView<*> {
return if (mlScannerEnabled) {
// Prefer ml kit with fallback
MLKitCameraView(activity, viewStub)
} else {
ZXCameraView(activity, viewStub)
}
}

@DrawableRes
fun getFlashRes(active: Boolean): Int {
return if (active) {
R.drawable.ic_flash_on_white_24dp
} else {
R.drawable.ic_flash_off_white_24dp
}
}

@DrawableRes
fun getAutofocusRes(enabled: Boolean): Int {
return if (enabled) {
R.drawable.ic_baseline_camera_focus_on_24
} else {
R.drawable.ic_baseline_camera_focus_off_24
}
}
}

}
Expand Up @@ -498,7 +498,7 @@ class ContinuousScanActivity : BaseActivity(), IProductView {
cameraState = scannerPrefsRepository.cameraPref.value

// Setup barcode scanner
cameraView = scannerPrefsRepository.buildCameraView(this, binding.cameraPreviewViewStub)
cameraView = CameraView.of(this, binding.cameraPreviewViewStub, scannerPrefsRepository.mlScannerEnabled)

cameraView.attach(cameraState, flashActive, autoFocusActive)
cameraView.barcodeScannedCallback = ::onBarcodeResult
Expand Down Expand Up @@ -614,17 +614,12 @@ class ContinuousScanActivity : BaseActivity(), IProductView {
}

private fun toggleFlash() {
if (flashActive) {
flashActive = false
binding.toggleFlash.setImageResource(R.drawable.ic_flash_off_white_24dp)
flashActive = !flashActive

cameraView.updateFlashSetting(flashActive)
} else {
flashActive = true
binding.toggleFlash.setImageResource(R.drawable.ic_flash_on_white_24dp)
val res = CameraView.getFlashRes(flashActive)

cameraView.updateFlashSetting(flashActive)
}
binding.toggleFlash.setImageResource(res)
cameraView.updateFlashSetting(flashActive)
scannerPrefsRepository.flashPref = flashActive
}

Expand Down Expand Up @@ -670,6 +665,7 @@ class ContinuousScanActivity : BaseActivity(), IProductView {
quickViewBehavior.state = BottomSheetBehavior.STATE_COLLAPSED
}

@Deprecated("Deprecated in Java")
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == ImagesManageActivity.REQUEST_EDIT_IMAGE && (resultCode == RESULT_OK || resultCode == RESULT_CANCELED)) {
Expand Down
Expand Up @@ -6,7 +6,6 @@ import android.content.Intent
import android.hardware.Camera
import android.os.Bundle
import android.text.InputType
import android.util.Log
import android.widget.EditText
import android.widget.FrameLayout
import androidx.activity.viewModels
Expand All @@ -17,13 +16,15 @@ import androidx.lifecycle.flowWithLifecycle
import androidx.lifecycle.lifecycleScope
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.launch
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import logcat.logcat
import openfoodfacts.github.scrachx.openfood.R
import openfoodfacts.github.scrachx.openfood.databinding.ActivitySimpleScanBinding
import openfoodfacts.github.scrachx.openfood.features.scan.CameraView
import openfoodfacts.github.scrachx.openfood.features.scan.MLKitCameraView
import openfoodfacts.github.scrachx.openfood.features.scan.ZXCameraView
import openfoodfacts.github.scrachx.openfood.features.simplescan.SimpleScanActivityContract.Companion.KEY_SCANNED_BARCODE
import openfoodfacts.github.scrachx.openfood.features.simplescan.SimpleScanViewModel.SideEffect.BarcodeDetected
import openfoodfacts.github.scrachx.openfood.features.simplescan.SimpleScanViewModel.SideEffect.ScanTrouble
import openfoodfacts.github.scrachx.openfood.models.CameraState
import java.util.concurrent.atomic.AtomicBoolean

Expand All @@ -43,48 +44,35 @@ class SimpleScanActivity : AppCompatActivity() {

hideSystemUI()

binding.scanFlashBtn.setOnClickListener {
viewModel.changeCameraFlash()
}
binding.scanFlipCameraBtn.setOnClickListener {
viewModel.changeCameraState()
}
binding.scanChangeFocusBtn.setOnClickListener {
viewModel.changeCameraAutoFocus()
}
binding.troubleScanningBtn.setOnClickListener {
viewModel.troubleScanningPressed()
}
binding.scanFlashBtn.setOnClickListener { viewModel.changeCameraFlash() }
binding.scanFlipCameraBtn.setOnClickListener { viewModel.changeCameraState() }
binding.scanChangeFocusBtn.setOnClickListener { viewModel.changeCameraAutoFocus() }
binding.troubleScanningBtn.setOnClickListener { viewModel.troubleScanningPressed() }

lifecycleScope.launch {
viewModel.scannerOptionsFlow
.flowWithLifecycle(lifecycle)
.collect { options ->
Log.d("SimpleScanActivity", "options: $options")
if (!scannerInitialized.getAndSet(true)) {
setupBarcodeScanner(options)
}
applyScannerOptions(options)
}
}
viewModel.scannerOptionsFlow
.flowWithLifecycle(lifecycle)
.onEach(this::updateScanner)
.launchIn(lifecycleScope)

lifecycleScope.launch {
viewModel.sideEffectsFlow
.flowWithLifecycle(lifecycle)
.collect { sideEffect ->
Log.d("SimpleScanActivity", "sideEffect: $sideEffect")
when (sideEffect) {
is SimpleScanViewModel.SideEffect.ScanTrouble -> {
stopScanning()
showManualInputDialog()
}
is SimpleScanViewModel.SideEffect.BarcodeDetected -> {
val intent = Intent().putExtra(KEY_SCANNED_BARCODE, sideEffect.barcode)
setResult(RESULT_OK, intent)
finish()
}
}
}

viewModel.sideEffectsFlow
.flowWithLifecycle(lifecycle)
.onEach(this::onSideEffect)
.launchIn(lifecycleScope)
}

private fun onSideEffect(sideEffect: SimpleScanViewModel.SideEffect) {
logcat { "sideEffect: $sideEffect" }
when (sideEffect) {
is ScanTrouble -> {
stopScanning()
showManualInputDialog()
}
is BarcodeDetected -> {
val intent = Intent().putExtra(KEY_SCANNED_BARCODE, sideEffect.barcode)
setResult(RESULT_OK, intent)
finish()
}
}
}

Expand Down Expand Up @@ -115,14 +103,16 @@ class SimpleScanActivity : AppCompatActivity() {
actionBar?.hide()
}

private fun applyScannerOptions(options: SimpleScanScannerOptions) {
// camera state
cameraView = if (options.mlScannerEnabled) {
MLKitCameraView(this, binding.scanMlView)
} else {
ZXCameraView(this, binding.scanMlView)
private fun updateScanner(options: SimpleScanScannerOptions) {
logcat { "options: $options" }
// If not initialized yet, initialize the scanner
if (!scannerInitialized.getAndSet(true)) {
setupBarcodeScanner(options)
}
applyScannerOptions(options)
}

private fun applyScannerOptions(options: SimpleScanScannerOptions) {
cameraView.toggleCamera(
when (options.cameraState) {
CameraState.Back -> Camera.CameraInfo.CAMERA_FACING_BACK
Expand All @@ -134,26 +124,27 @@ class SimpleScanActivity : AppCompatActivity() {
updateFlashStatus(options.flashEnabled)

// autofocus
val focusIconRes = if (options.autoFocusEnabled) {
R.drawable.ic_baseline_camera_focus_on_24
} else {
R.drawable.ic_baseline_camera_focus_off_24
}
updateAutofocusStatus(options.autoFocusEnabled)
}

private fun updateAutofocusStatus(autoFocusEnabled: Boolean) {
val focusIconRes = CameraView.getAutofocusRes(autoFocusEnabled)

binding.scanChangeFocusBtn.setImageResource(focusIconRes)
cameraView.updateFocusModeSetting(options.autoFocusEnabled)
cameraView.updateFocusModeSetting(autoFocusEnabled)
}


private fun updateFlashStatus(flashEnabled: Boolean) {
val flashIconRes = if (flashEnabled) {
R.drawable.ic_flash_off_white_24dp
} else {
R.drawable.ic_flash_on_white_24dp
}
val flashIconRes = CameraView.getFlashRes(flashEnabled)
binding.scanFlashBtn.setImageResource(flashIconRes)
cameraView.updateFlashSetting(flashEnabled)
}

private fun setupBarcodeScanner(options: SimpleScanScannerOptions) {
// camera state
cameraView = CameraView.of(this, binding.scanMlView, options.mlScannerEnabled)

cameraView.attach(options.cameraState.value, options.flashEnabled, options.autoFocusEnabled)
cameraView.barcodeScannedCallback = { barcode ->
barcode?.let { viewModel.barcodeDetected(it) }
Expand Down

This file was deleted.

0 comments on commit 6233fa3

Please sign in to comment.