Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added ability to disable auto restart preview #389

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 5 additions & 9 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,7 @@ subprojects {
buildscript {
ext {
versions = [
gradle : '4.10.2',
kotlin : '1.3.0',
kotlin : '1.3.50',
code : 1,
name : '1.0.0',
sdk : [
Expand All @@ -19,13 +18,13 @@ buildscript {
],
android: [
buildTools: '28.0.3',
appcompat : '1.0.1',
annotation : '1.0.0',
appcompat : '1.1.0',
annotation : '1.1.0',
exifinterface : '1.0.0'
],
rx : [
rxJava1: '1.3.8',
rxJava2: '2.2.3'
rxJava2: '2.2.12'
],
test : [
junit : '4.12',
Expand All @@ -38,7 +37,7 @@ buildscript {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.3.0'
classpath 'com.android.tools.build:gradle:3.5.1'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:${versions.kotlin}"

classpath 'com.github.dcendents:android-maven-gradle-plugin:2.1'
Expand All @@ -57,6 +56,3 @@ task clean(type: Delete) {
delete rootProject.buildDir
}

task wrapper(type: Wrapper) {
gradleVersion = versions.gradle
}
2 changes: 1 addition & 1 deletion fotoapparat/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ dependencies {
implementation "androidx.annotation:annotation:${versions.android.annotation}"
implementation "androidx.exifinterface:exifinterface:${versions.android.exifinterface}"
implementation "org.jetbrains.kotlin:kotlin-stdlib:${versions.kotlin}"
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.0.0'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.0'
testImplementation "junit:junit:${versions.test.junit}"
testImplementation "org.jetbrains.kotlin:kotlin-test-junit:${versions.kotlin}"
testImplementation "org.mockito:mockito-core:${versions.test.mockito}"
Expand Down
47 changes: 46 additions & 1 deletion fotoapparat/src/main/java/io/fotoapparat/Fotoapparat.kt
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,10 @@ import io.fotoapparat.routine.camera.updateDeviceConfiguration
import io.fotoapparat.routine.capability.getCapabilities
import io.fotoapparat.routine.focus.focus
import io.fotoapparat.routine.parameter.getCurrentParameters
import io.fotoapparat.routine.photo.startPreview
import io.fotoapparat.routine.photo.stopPreview
import io.fotoapparat.routine.photo.takePhoto
import io.fotoapparat.routine.photo.takePhotoRestartPreview
import io.fotoapparat.routine.zoom.updateZoomLevel
import io.fotoapparat.selector.*
import io.fotoapparat.view.CameraRenderer
Expand Down Expand Up @@ -113,15 +116,57 @@ class Fotoapparat
*/
fun takePicture(): PhotoResult {
logger.recordMethod()
return takePicture(restartPreview = true)
}

/**
* Takes picture with ability to disable automatically restart preview, returns immediately.
*
* @return [PhotoResult] which will deliver result asynchronously.
*/
fun takePicture(restartPreview: Boolean): PhotoResult {
logger.recordMethod()

val future = executor.execute(Operation(
cancellable = true,
function = device::takePhoto
function = if(restartPreview) device::takePhotoRestartPreview else device::takePhoto
))

return PhotoResult.fromFuture(future, logger)
}

/**
* Start preview manually, returns immediately.
*
* @return [BooleanResult] which will deliver result asynchronously.
*/
fun startPreview(): BooleanResult {
logger.recordMethod()

val future = executor.execute(Operation(
cancellable = true,
function = device::startPreview
))

return PendingResult.fromFuture(future, logger)
}

/**
* Stop preview manually, returns immediately.
*
* @return [BooleanResult] which will deliver result asynchronously.
*/
fun stopPreview(): BooleanResult {
logger.recordMethod()

val future = executor.execute(Operation(
cancellable = true,
function = device::stopPreview
))

return PendingResult.fromFuture(future, logger)
}

/**
* Provides camera capabilities asynchronously, returns immediately.
*
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
package io.fotoapparat.coroutines

import kotlinx.coroutines.CompletableDeferred
import kotlinx.coroutines.Deferred
import kotlinx.coroutines.*
import kotlinx.coroutines.channels.BroadcastChannel
import kotlinx.coroutines.channels.ConflatedBroadcastChannel

/**
* A [ConflatedBroadcastChannel] which exposes a [getValue] which will [await] for at least one value.
*/
@ExperimentalCoroutinesApi
internal class AwaitBroadcastChannel<T>(
private val channel: ConflatedBroadcastChannel<T> = ConflatedBroadcastChannel(),
private val deferred: CompletableDeferred<Boolean> = CompletableDeferred()
Expand All @@ -31,7 +31,13 @@ internal class AwaitBroadcastChannel<T>(
channel.send(element)
}

override fun cancel(cause: CancellationException?) {
channel.cancel(cause)
deferred.cancel(cause)
}

override fun cancel(cause: Throwable?): Boolean {
return channel.cancel(cause) && deferred.cancel(cause)
deferred.cancel(cause?.message ?:"", cause)
return channel.close(cause)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -125,4 +125,5 @@ private fun notifyOnMainThread(function: () -> Unit) {

typealias CapabilitiesResult = PendingResult<Capabilities>
typealias ParametersResult = PendingResult<CameraParameters>
typealias BooleanResult = PendingResult<Boolean>

Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,14 @@ import kotlinx.coroutines.runBlocking
/**
* Takes a photo.
*/

internal fun Device.takePhoto(): Photo = runBlocking {
val cameraDevice = awaitSelectedCamera()
cameraDevice.takePhoto()
}

internal fun Device.takePhotoRestartPreview(): Photo = runBlocking {
val cameraDevice = awaitSelectedCamera()

cameraDevice.takePhoto().also {
cameraDevice.startPreviewSafely()
Expand All @@ -23,3 +29,16 @@ private fun CameraDevice.startPreviewSafely() {
} catch (ignore: CameraException) {
}
}

internal fun Device.startPreview(): Boolean = runBlocking {
val cameraDevice = awaitSelectedCamera()
cameraDevice.startPreview()
true
}

internal fun Device.stopPreview(): Boolean = runBlocking {
val cameraDevice = awaitSelectedCamera()
cameraDevice.stopPreview()
true
}

Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ internal class TakePhotoRoutineTest {
cameraDevice.takePhoto() willReturn photo

// When
val result = device.takePhoto()
val result = device.takePhotoRestartPreview()

// Then
val inOrder = inOrder(cameraDevice)
Expand All @@ -54,7 +54,7 @@ internal class TakePhotoRoutineTest {
cameraDevice.startPreview() willThrow CameraException("test")

// When
val result = device.takePhoto()
val result = device.takePhotoRestartPreview()

// Then
val inOrder = inOrder(cameraDevice)
Expand Down
2 changes: 1 addition & 1 deletion gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-all.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-all.zip