Skip to content
This repository has been archived by the owner on Mar 8, 2024. It is now read-only.

Commit

Permalink
fix/#13. Added a boolean to record when the camera is opening. This e…
Browse files Browse the repository at this point in the history
…nables us to check and not start the camera again if it is currently opening. Added tests which check the new behavioural changes.
  • Loading branch information
alistairsykes committed May 8, 2019
1 parent 87daf06 commit 161e2d0
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,10 @@ class BarcodeScanner internal constructor(
Timber.d("Attempted Camera2Source.start(), which has already been started")
return
}
if (cameraSource.isOpening()) {
Timber.d("Attempted Camera2Source.start(), which is currently opening")
return
}

frameProcessor.barcodes.observeForever(barcodesObserver)
startCameraSource()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ internal class Camera2Source(

@VisibleForTesting
internal var cameraDevice: CameraDevice? = null
@VisibleForTesting
internal var cameraOpening = false
var requestedFacing = CameraCharacteristics.LENS_FACING_BACK

constructor(context: Context) : this(
Expand All @@ -29,17 +31,20 @@ internal class Camera2Source(

fun isStarted() = cameraDevice != null

fun isOpening() = cameraOpening

fun release() {
cameraDevice?.close()
cameraDevice = null
cameraOpening = false
}

@RequiresPermission(android.Manifest.permission.CAMERA)
fun start(
surfaces: List<Surface>,
listener: OnCameraReadyListener?
) {
if (cameraDevice != null) return
if (cameraDevice != null || cameraOpening) return

val cameraId = selectCamera()
if (cameraId == null) {
Expand All @@ -48,8 +53,10 @@ internal class Camera2Source(
listener?.onCameraFailure(exception)
return
}
cameraOpening = true
cameraManager.openCamera(cameraId, object : CameraDevice.StateCallback() {
override fun onOpened(camera: CameraDevice) {
cameraOpening = false
cameraDevice = camera
listener?.onCameraReady()
createCaptureSession(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,38 @@ internal class BarcodeScannerTest {
verify(barcodeScanner).startCameraSource()
}

@Test
fun cameraIsStarted__start__resumeProcessing_doesntAddObserver_doesntStartCameraSource() {
doNothing().whenever(barcodeScanner).startCameraSource()

// GIVEN
whenever(cameraSource.isStarted()).thenReturn(true)

// WHEN
barcodeScanner.start()

// THEN
assertFalse(barcodeScanner.pauseProcessing)
verify(frameProcessor.barcodes, never()).observeForever(any())
verify(barcodeScanner, never()).startCameraSource()
}

@Test
fun cameraIsOpening__start__resumeProcessing_doesntAddObserver_doesntStartCameraSource() {
doNothing().whenever(barcodeScanner).startCameraSource()

// GIVEN
whenever(cameraSource.isOpening()).thenReturn(true)

// WHEN
barcodeScanner.start()

// THEN
assertFalse(barcodeScanner.pauseProcessing)
verify(frameProcessor.barcodes, never()).observeForever(any())
verify(barcodeScanner, never()).startCameraSource()
}

@Test
fun processingResumed__resume__resumeProcessing() {
// GIVEN
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,30 @@ internal class Camera2SourceTest {
assertTrue(result)
}

@Test
fun nothing__isOpening__false() {
// GIVEN
// nothing

// WHEN
val result = cameraSource.isOpening()

// THEN
assertFalse(result)
}

@Test
fun cameraOpening__isOpening__true() {
// GIVEN
cameraSource.cameraOpening = true

// WHEN
val result = cameraSource.isOpening()

// THEN
assertTrue(result)
}

@Test
fun cameraDevice__release__closesCameraDevice() {
// GIVEN
Expand All @@ -83,6 +107,7 @@ internal class Camera2SourceTest {
// THEN
verify(cameraDevice).close()
assertNull(cameraSource.cameraDevice)
assertFalse(cameraSource.cameraOpening)
}

@Test
Expand All @@ -99,6 +124,20 @@ internal class Camera2SourceTest {
)
}

@Test
fun cameraOpening__start__doesNothing() {
// GIVEN
cameraSource.cameraOpening = true

// WHEN
cameraSource.start(mock(), mock())

// THEN
verify(cameraManager, never()).openCamera(
any(), any(), anyOrNull<Handler>()
)
}

@Test
fun noCameraId__start__error() {
// GIVEN
Expand All @@ -115,7 +154,7 @@ internal class Camera2SourceTest {
}

@Test
fun cameraId__start__opensCamera() {
fun cameraId__start__setsOpening_opensCamera() {
// GIVEN
val cameraId = "some id"
doReturn(cameraId).whenever(cameraSource).selectCamera()
Expand All @@ -124,13 +163,14 @@ internal class Camera2SourceTest {
cameraSource.start(mock(), mock())

// THEN
assertTrue(cameraSource.cameraOpening)
verify(cameraManager).openCamera(
eq(cameraId), any(), anyOrNull<Handler>()
)
}

@Test
fun cameraId_cameraOpened__start__setCameraDevice_callListener_createSession() {
fun cameraId_cameraOpened__start__setsNotOpening_setCameraDevice_callListener_createSession() {
doNothing().whenever(cameraSource).createCaptureSession(any(), any())

// GIVEN
Expand All @@ -147,6 +187,7 @@ internal class Camera2SourceTest {
cameraSource.start(surfaces, listener)

// THEN
assertFalse(cameraSource.cameraOpening)
verify(cameraSource).cameraDevice = cameraDevice
verify(listener).onCameraReady()
verify(cameraSource).createCaptureSession(surfaces, listener)
Expand Down

0 comments on commit 161e2d0

Please sign in to comment.