Skip to content

Commit

Permalink
Merge branch 'master' of github.com:dmitry-zaitsev/Fotoapparat
Browse files Browse the repository at this point in the history
  • Loading branch information
dmitry-zaitsev committed May 24, 2017
2 parents 5d23779 + ada26d7 commit a1b3c27
Show file tree
Hide file tree
Showing 11 changed files with 385 additions and 25 deletions.
4 changes: 1 addition & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -128,13 +128,11 @@ repositories {
maven { url 'https://jitpack.io' }
}
compile 'io.fotoapparat.fotoapparat:library:x.y.z'
compile 'io.fotoapparat.fotoapparat:library:1.0.0'
```

Camera permission will be automatically added to your `AndroidManifest.xml`. Do not forget to request this permission on Marshmallow and higher.

We are currently working for a stable release, so for now use `-SNAPSHOT` in the version code above.


## Credits

Expand Down
18 changes: 18 additions & 0 deletions fotoapparat/src/main/java/io/fotoapparat/Fotoapparat.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import io.fotoapparat.result.CapabilitiesResult;
import io.fotoapparat.result.PhotoResult;
import io.fotoapparat.routine.AutoFocusRoutine;
import io.fotoapparat.routine.CheckAvailabilityRoutine;
import io.fotoapparat.routine.ConfigurePreviewStreamRoutine;
import io.fotoapparat.routine.StartCameraRoutine;
import io.fotoapparat.routine.StopCameraRoutine;
Expand All @@ -35,6 +36,7 @@ public class Fotoapparat {
private final CapabilitiesProvider capabilitiesProvider;
private final TakePictureRoutine takePictureRoutine;
private final AutoFocusRoutine autoFocusRoutine;
private final CheckAvailabilityRoutine checkAvailabilityRoutine;
private final Executor executor;

private boolean started = false;
Expand All @@ -46,6 +48,7 @@ public class Fotoapparat {
CapabilitiesProvider capabilitiesProvider,
TakePictureRoutine takePictureRoutine,
AutoFocusRoutine autoFocusRoutine,
CheckAvailabilityRoutine checkAvailabilityRoutine,
Executor executor) {
this.startCameraRoutine = startCameraRoutine;
this.stopCameraRoutine = stopCameraRoutine;
Expand All @@ -54,6 +57,7 @@ public class Fotoapparat {
this.capabilitiesProvider = capabilitiesProvider;
this.takePictureRoutine = takePictureRoutine;
this.autoFocusRoutine = autoFocusRoutine;
this.checkAvailabilityRoutine = checkAvailabilityRoutine;
this.executor = executor;
}

Expand Down Expand Up @@ -119,6 +123,11 @@ static Fotoapparat create(FotoapparatBuilder builder) {

AutoFocusRoutine autoFocusRoutine = new AutoFocusRoutine(cameraDevice);

CheckAvailabilityRoutine checkAvailabilityRoutine = new CheckAvailabilityRoutine(
cameraDevice,
builder.lensPositionSelector
);

return new Fotoapparat(
startCameraRoutine,
stopCameraRoutine,
Expand All @@ -127,10 +136,19 @@ static Fotoapparat create(FotoapparatBuilder builder) {
capabilitiesProvider,
takePictureRoutine,
autoFocusRoutine,
checkAvailabilityRoutine,
SERIAL_EXECUTOR
);
}

/**
* @return {@code true} if camera for this {@link Fotoapparat} is available. {@code false} if
* it is not available.
*/
public boolean isAvailable() {
return checkAvailabilityRoutine.isAvailable();
}

/**
* Provides camera capabilities asynchronously, returns immediately.
*
Expand Down
77 changes: 77 additions & 0 deletions fotoapparat/src/main/java/io/fotoapparat/FotoapparatSwitcher.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package io.fotoapparat;

import android.support.annotation.NonNull;

/**
* Switches between different instances of {@link Fotoapparat}. Convenient when you want to allow
* user to switch between different cameras or configurations.
* <p>
* This class is not thread safe. Consider using it from a single thread.
*/
public class FotoapparatSwitcher {

@NonNull
private Fotoapparat fotoapparat;

private boolean started = false;

private FotoapparatSwitcher(@NonNull Fotoapparat fotoapparat) {
this.fotoapparat = fotoapparat;
}

/**
* @return {@link FotoapparatSwitcher} with given {@link Fotoapparat} used by default.
*/
public static FotoapparatSwitcher withDefault(@NonNull Fotoapparat fotoapparat) {
return new FotoapparatSwitcher(fotoapparat);
}

/**
* Starts {@link Fotoapparat} associated with this switcher. Every new {@link Fotoapparat} will
* be started automatically until {@link #stop()} is called.
*
* @throws IllegalStateException if switcher is already started.
*/
public void start() {
fotoapparat.start();

started = true;
}

/**
* Stops currently used {@link Fotoapparat}.
*
* @throws IllegalStateException if switcher is already stopped.
*/
public void stop() {
fotoapparat.stop();

started = false;
}

/**
* Switches to another {@link Fotoapparat}. If switcher is already started then previously used
* {@link Fotoapparat} will be stopped automatically and new {@link Fotoapparat} will be
* started.
*
* @param fotoapparat new {@link Fotoapparat} to use.
* @throws NullPointerException if given {@link Fotoapparat} is {@code null}.
*/
public void switchTo(@NonNull Fotoapparat fotoapparat) {
if (started) {
this.fotoapparat.stop();
fotoapparat.start();
}

this.fotoapparat = fotoapparat;
}

/**
* @return currently used instance of {@link Fotoapparat}.
*/
@NonNull
public Fotoapparat getCurrentFotoapparat() {
return fotoapparat;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,11 @@ public static SelectorFunction<LensPosition> external() {
return lensPosition(LensPosition.EXTERNAL);
}

private static SelectorFunction<LensPosition> lensPosition(final LensPosition position) {
/**
* @return {@link SelectorFunction} which provides the given camera if it is available.
* Otherwise provides {@code null}.
*/
public static SelectorFunction<LensPosition> lensPosition(final LensPosition position) {
return Selectors.single(position);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package io.fotoapparat.routine;

import io.fotoapparat.hardware.CameraDevice;
import io.fotoapparat.parameter.LensPosition;
import io.fotoapparat.parameter.selector.SelectorFunction;

/**
* Checks whether {@link LensPosition} provided by {@link SelectorFunction} is available or not.
*/
public class CheckAvailabilityRoutine {

private final CameraDevice cameraDevice;
private final SelectorFunction<LensPosition> lensPositionSelector;

public CheckAvailabilityRoutine(CameraDevice cameraDevice,
SelectorFunction<LensPosition> lensPositionSelector) {
this.cameraDevice = cameraDevice;
this.lensPositionSelector = lensPositionSelector;
}

/**
* @return {@code true} if selected lens position is available. {@code false} if it is not
* available.
*/
public boolean isAvailable() {
return selectedLensPosition() != null;
}

private LensPosition selectedLensPosition() {
return lensPositionSelector.select(cameraDevice.getAvailableLensPositions());
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
package io.fotoapparat;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InOrder;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;

import static junit.framework.Assert.assertSame;
import static org.mockito.Mockito.inOrder;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyZeroInteractions;

@RunWith(MockitoJUnitRunner.class)
public class FotoapparatSwitcherTest {

@Mock
Fotoapparat fotoapparatA;
@Mock
Fotoapparat fotoapparatB;

FotoapparatSwitcher testee;

@Before
public void setUp() throws Exception {
testee = FotoapparatSwitcher.withDefault(fotoapparatA);
}

@Test
public void start_Default() throws Exception {
// When
testee.start();

// Then
verify(fotoapparatA).start();
}

@Test
public void stop_Default() throws Exception {
// When
testee.stop();

// Then
verify(fotoapparatA).stop();
}

@Test
public void getCurrentFotoapparat() throws Exception {
// When
Fotoapparat result = testee.getCurrentFotoapparat();

// Then
assertSame(fotoapparatA, result);
}

@Test
public void switchTo() throws Exception {
// Given
testee.switchTo(fotoapparatB);

// When
Fotoapparat result = testee.getCurrentFotoapparat();

// Then
assertSame(fotoapparatB, result);

verifyZeroInteractions(fotoapparatA);
verifyZeroInteractions(fotoapparatB);
}

@Test
public void switchTo_AlreadyStarted() throws Exception {
// Given
testee.start();

// When
testee.switchTo(fotoapparatB);

// Then
InOrder inOrder = inOrder(fotoapparatA, fotoapparatB);

inOrder.verify(fotoapparatA).stop();
inOrder.verify(fotoapparatB).start();
}

}
33 changes: 33 additions & 0 deletions fotoapparat/src/test/java/io/fotoapparat/FotoapparatTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import io.fotoapparat.result.CapabilitiesResult;
import io.fotoapparat.result.PhotoResult;
import io.fotoapparat.routine.AutoFocusRoutine;
import io.fotoapparat.routine.CheckAvailabilityRoutine;
import io.fotoapparat.routine.ConfigurePreviewStreamRoutine;
import io.fotoapparat.routine.StartCameraRoutine;
import io.fotoapparat.routine.StopCameraRoutine;
Expand All @@ -22,6 +23,8 @@

import static io.fotoapparat.test.TestUtils.immediateFuture;
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertTrue;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.inOrder;
import static org.mockito.Mockito.verify;
Expand Down Expand Up @@ -54,6 +57,8 @@ public class FotoapparatTest {
TakePictureRoutine takePictureRoutine;
@Mock
AutoFocusRoutine autoFocusRoutine;
@Mock
CheckAvailabilityRoutine checkAvailabilityRoutine;

Fotoapparat testee;

Expand All @@ -67,6 +72,7 @@ public void setUp() throws Exception {
capabilitiesProvider,
takePictureRoutine,
autoFocusRoutine,
checkAvailabilityRoutine,
new ImmediateExecutor()
);
}
Expand Down Expand Up @@ -212,4 +218,31 @@ public void ensureNonNullContext() throws Exception {
// Then
// Expect exception
}

@Test
public void isAvailable_Yes() throws Exception {
// Given
given(checkAvailabilityRoutine.isAvailable())
.willReturn(true);

// When
boolean result = testee.isAvailable();

// Then
assertTrue(result);
}

@Test
public void isAvailable_No() throws Exception {
// Given
given(checkAvailabilityRoutine.isAvailable())
.willReturn(false);

// When
boolean result = testee.isAvailable();

// Then
assertFalse(result);
}

}
Loading

0 comments on commit a1b3c27

Please sign in to comment.