Add base Control class, add easy setters and CameraOptions APIs (#105)

pull/112/head
Mattia Iavarone 7 years ago committed by GitHub
parent 33162f0e31
commit 3bc6d96ac3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 76
      cameraview/src/androidTest/java/com/otaliastudios/cameraview/CameraOptions1Test.java
  2. 45
      cameraview/src/androidTest/java/com/otaliastudios/cameraview/CameraViewTest.java
  3. 4
      cameraview/src/main/java/com/otaliastudios/cameraview/CameraListener.java
  4. 77
      cameraview/src/main/java/com/otaliastudios/cameraview/CameraOptions.java
  5. 31
      cameraview/src/main/java/com/otaliastudios/cameraview/CameraView.java
  6. 2
      cameraview/src/main/options/com/otaliastudios/cameraview/Audio.java
  7. 8
      cameraview/src/main/options/com/otaliastudios/cameraview/Control.java
  8. 2
      cameraview/src/main/options/com/otaliastudios/cameraview/Facing.java
  9. 2
      cameraview/src/main/options/com/otaliastudios/cameraview/Flash.java
  10. 2
      cameraview/src/main/options/com/otaliastudios/cameraview/Grid.java
  11. 2
      cameraview/src/main/options/com/otaliastudios/cameraview/Hdr.java
  12. 2
      cameraview/src/main/options/com/otaliastudios/cameraview/SessionType.java
  13. 2
      cameraview/src/main/options/com/otaliastudios/cameraview/VideoQuality.java
  14. 2
      cameraview/src/main/options/com/otaliastudios/cameraview/WhiteBalance.java
  15. 35
      demo/src/main/java/com/otaliastudios/cameraview/demo/Control.java

@ -9,6 +9,7 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
@ -109,25 +110,6 @@ public class CameraOptions1Test extends BaseTest {
}
}
@Test
public void testFacing() {
Set<Integer> supported = new HashSet<>();
Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
for (int i = 0, count = Camera.getNumberOfCameras(); i < count; i++) {
Camera.getCameraInfo(i, cameraInfo);
supported.add(cameraInfo.facing);
}
CameraOptions o = new CameraOptions(mock(Camera.Parameters.class), false);
Mapper m = new Mapper.Mapper1();
Set<Facing> s = o.getSupportedFacing();
assertEquals(o.getSupportedFacing().size(), supported.size());
for (Facing facing : s) {
assertTrue(supported.contains(m.<Integer>map(facing)));
assertTrue(o.supports(facing));
}
}
@Test
public void testGestureActions() {
Camera.Parameters params = mock(Camera.Parameters.class);
@ -145,6 +127,41 @@ public class CameraOptions1Test extends BaseTest {
assertFalse(o.supports(GestureAction.EXPOSURE_CORRECTION));
}
@Test
public void testAlwaysSupportedControls() {
// Grid, VideoQuality, SessionType and Audio are always supported.
Camera.Parameters params = mock(Camera.Parameters.class);
CameraOptions o = new CameraOptions(params, false);
Collection<Grid> grids = o.getSupportedControls(Grid.class);
Collection<VideoQuality> video = o.getSupportedControls(VideoQuality.class);
Collection<SessionType> sessions = o.getSupportedControls(SessionType.class);
Collection<Audio> audio = o.getSupportedControls(Audio.class);
assertEquals(grids.size(), Grid.values().length);
assertEquals(video.size(), VideoQuality.values().length);
assertEquals(sessions.size(), SessionType.values().length);
assertEquals(audio.size(), Audio.values().length);
}
@Test
public void testFacing() {
Set<Integer> supported = new HashSet<>();
Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
for (int i = 0, count = Camera.getNumberOfCameras(); i < count; i++) {
Camera.getCameraInfo(i, cameraInfo);
supported.add(cameraInfo.facing);
}
CameraOptions o = new CameraOptions(mock(Camera.Parameters.class), false);
Mapper m = new Mapper.Mapper1();
Collection<Facing> s = o.getSupportedControls(Facing.class);
assertEquals(s.size(), supported.size());
for (Facing facing : s) {
assertTrue(supported.contains(m.<Integer>map(facing)));
assertTrue(o.supports(facing));
}
}
@Test
public void testWhiteBalance() {
Camera.Parameters params = mock(Camera.Parameters.class);
@ -155,9 +172,10 @@ public class CameraOptions1Test extends BaseTest {
));
CameraOptions o = new CameraOptions(params, false);
assertEquals(o.getSupportedWhiteBalance().size(), 2);
assertTrue(o.getSupportedWhiteBalance().contains(WhiteBalance.AUTO));
assertTrue(o.getSupportedWhiteBalance().contains(WhiteBalance.CLOUDY));
Collection<WhiteBalance> w = o.getSupportedControls(WhiteBalance.class);
assertEquals(w.size(), 2);
assertTrue(w.contains(WhiteBalance.AUTO));
assertTrue(w.contains(WhiteBalance.CLOUDY));
assertTrue(o.supports(WhiteBalance.AUTO));
assertTrue(o.supports(WhiteBalance.CLOUDY));
}
@ -172,9 +190,10 @@ public class CameraOptions1Test extends BaseTest {
));
CameraOptions o = new CameraOptions(params, false);
assertEquals(o.getSupportedFlash().size(), 2);
assertTrue(o.getSupportedFlash().contains(Flash.AUTO));
assertTrue(o.getSupportedFlash().contains(Flash.TORCH));
Collection<Flash> f = o.getSupportedControls(Flash.class);
assertEquals(f.size(), 2);
assertTrue(f.contains(Flash.AUTO));
assertTrue(f.contains(Flash.TORCH));
assertTrue(o.supports(Flash.AUTO));
assertTrue(o.supports(Flash.TORCH));
}
@ -189,9 +208,10 @@ public class CameraOptions1Test extends BaseTest {
));
CameraOptions o = new CameraOptions(params, false);
assertEquals(o.getSupportedHdr().size(), 2);
assertTrue(o.getSupportedHdr().contains(Hdr.OFF));
assertTrue(o.getSupportedHdr().contains(Hdr.ON));
Collection<Hdr> h = o.getSupportedControls(Hdr.class);
assertEquals(h.size(), 2);
assertTrue(h.contains(Hdr.OFF));
assertTrue(h.contains(Hdr.ON));
assertTrue(o.supports(Hdr.OFF));
assertTrue(o.supports(Hdr.ON));
}

@ -471,34 +471,23 @@ public class CameraViewTest extends BaseTest {
@Test
public void testSetFlash() {
cameraView.setFlash(Flash.TORCH);
cameraView.set(Flash.TORCH);
assertEquals(cameraView.getFlash(), Flash.TORCH);
cameraView.setFlash(Flash.OFF);
assertEquals(cameraView.getFlash(), Flash.OFF);
}
@Test
public void testToggleFlash() {
cameraView.setFlash(Flash.OFF);
cameraView.toggleFlash();
assertEquals(cameraView.getFlash(), Flash.ON);
cameraView.toggleFlash();
assertEquals(cameraView.getFlash(), Flash.AUTO);
cameraView.toggleFlash();
cameraView.set(Flash.OFF);
assertEquals(cameraView.getFlash(), Flash.OFF);
}
@Test
public void testSetFacing() {
cameraView.setFacing(Facing.FRONT);
cameraView.set(Facing.FRONT);
assertEquals(cameraView.getFacing(), Facing.FRONT);
cameraView.setFacing(Facing.BACK);
cameraView.set(Facing.BACK);
assertEquals(cameraView.getFacing(), Facing.BACK);
}
@Test
public void testToggleFacing() {
cameraView.setFacing(Facing.FRONT);
cameraView.set(Facing.FRONT);
cameraView.toggleFacing();
assertEquals(cameraView.getFacing(), Facing.BACK);
cameraView.toggleFacing();
@ -507,49 +496,49 @@ public class CameraViewTest extends BaseTest {
@Test
public void testSetGrid() {
cameraView.setGrid(Grid.DRAW_3X3);
cameraView.set(Grid.DRAW_3X3);
assertEquals(cameraView.getGrid(), Grid.DRAW_3X3);
cameraView.setGrid(Grid.OFF);
cameraView.set(Grid.OFF);
assertEquals(cameraView.getGrid(), Grid.OFF);
}
@Test
public void testSetWhiteBalance() {
cameraView.setWhiteBalance(WhiteBalance.CLOUDY);
cameraView.set(WhiteBalance.CLOUDY);
assertEquals(cameraView.getWhiteBalance(), WhiteBalance.CLOUDY);
cameraView.setWhiteBalance(WhiteBalance.AUTO);
cameraView.set(WhiteBalance.AUTO);
assertEquals(cameraView.getWhiteBalance(), WhiteBalance.AUTO);
}
@Test
public void testSessionType() {
cameraView.setSessionType(SessionType.VIDEO);
cameraView.set(SessionType.VIDEO);
assertEquals(cameraView.getSessionType(), SessionType.VIDEO);
cameraView.setSessionType(SessionType.PICTURE);
cameraView.set(SessionType.PICTURE);
assertEquals(cameraView.getSessionType(), SessionType.PICTURE);
}
@Test
public void testHdr() {
cameraView.setHdr(Hdr.ON);
cameraView.set(Hdr.ON);
assertEquals(cameraView.getHdr(), Hdr.ON);
cameraView.setHdr(Hdr.OFF);
cameraView.set(Hdr.OFF);
assertEquals(cameraView.getHdr(), Hdr.OFF);
}
@Test
public void testAudio() {
cameraView.setAudio(Audio.ON);
cameraView.set(Audio.ON);
assertEquals(cameraView.getAudio(), Audio.ON);
cameraView.setAudio(Audio.OFF);
cameraView.set(Audio.OFF);
assertEquals(cameraView.getAudio(), Audio.OFF);
}
@Test
public void testVideoQuality() {
cameraView.setVideoQuality(VideoQuality.MAX_1080P);
cameraView.set(VideoQuality.MAX_1080P);
assertEquals(cameraView.getVideoQuality(), VideoQuality.MAX_1080P);
cameraView.setVideoQuality(VideoQuality.LOWEST);
cameraView.set(VideoQuality.LOWEST);
assertEquals(cameraView.getVideoQuality(), VideoQuality.LOWEST);
}

@ -60,7 +60,7 @@ public abstract class CameraListener {
*/
@UiThread
public void onPictureTaken(byte[] jpeg) {
// TODO v2: use a PictureResult.
}
@ -76,7 +76,7 @@ public abstract class CameraListener {
*/
@UiThread
public void onVideoTaken(File video) {
// TODO v2: use a VideoResult.
}

@ -6,6 +6,9 @@ import android.hardware.Camera;
import android.hardware.camera2.CameraCharacteristics;
import android.support.annotation.NonNull;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
@ -100,46 +103,13 @@ public class CameraOptions {
/**
* Shorthand for getSupportedFacing().contains(value).
* Shorthand for getSupported*().contains(value).
*
* @param facing value
* @param control value to check
* @return whether it's supported
*/
public boolean supports(Facing facing) {
return getSupportedFacing().contains(facing);
}
/**
* Shorthand for getSupportedFlash().contains(value).
*
* @param flash value
* @return whether it's supported
*/
public boolean supports(Flash flash) {
return getSupportedFlash().contains(flash);
}
/**
* Shorthand for getSupportedWhiteBalance().contains(value).
*
* @param whiteBalance value
* @return whether it's supported
*/
public boolean supports(WhiteBalance whiteBalance) {
return getSupportedWhiteBalance().contains(whiteBalance);
}
/**
* Shorthand for getSupportedHdr().contains(value).
*
* @param hdr value
* @return whether it's supported
*/
public boolean supports(Hdr hdr) {
return getSupportedHdr().contains(hdr);
public boolean supports(Control control) {
return getSupportedControls(control.getClass()).contains(control);
}
@ -166,6 +136,31 @@ public class CameraOptions {
return false;
}
@SuppressWarnings("unchecked")
public <T extends Control> Collection<T> getSupportedControls(@NonNull Class<T> controlClass) {
if (controlClass.equals(Audio.class)) {
return (Collection<T>) Arrays.asList(Audio.values());
} else if (controlClass.equals(Facing.class)) {
return (Collection<T>) getSupportedFacing();
} else if (controlClass.equals(Flash.class)) {
return (Collection<T>) getSupportedFlash();
} else if (controlClass.equals(Grid.class)) {
return (Collection<T>) Arrays.asList(Grid.values());
} else if (controlClass.equals(Hdr.class)) {
return (Collection<T>) getSupportedHdr();
} else if (controlClass.equals(SessionType.class)) {
return (Collection<T>) Arrays.asList(SessionType.values());
} else if (controlClass.equals(VideoQuality.class)) {
return (Collection<T>) Arrays.asList(VideoQuality.values());
} else if (controlClass.equals(WhiteBalance.class)) {
return (Collection<T>) getSupportedWhiteBalance();
}
// Unrecognized control.
return Collections.emptyList();
}
/**
* Set of supported picture sizes for the currently opened camera.
*
@ -173,9 +168,11 @@ public class CameraOptions {
*/
@NonNull
public Set<Size> getSupportedPictureSizes() {
// TODO v2: return a Collection
return Collections.unmodifiableSet(supportedPictureSizes);
}
/**
* Set of supported picture aspect ratios for the currently opened camera.
*
@ -183,9 +180,11 @@ public class CameraOptions {
*/
@NonNull
public Set<AspectRatio> getSupportedPictureAspectRatios() {
// TODO v2: return a Collection
return Collections.unmodifiableSet(supportedPictureAspectRatio);
}
/**
* Set of supported facing values.
*
@ -195,6 +194,7 @@ public class CameraOptions {
*/
@NonNull
public Set<Facing> getSupportedFacing() {
// TODO v2: return a Collection
return Collections.unmodifiableSet(supportedFacing);
}
@ -210,6 +210,7 @@ public class CameraOptions {
*/
@NonNull
public Set<Flash> getSupportedFlash() {
// TODO v2: return a Collection
return Collections.unmodifiableSet(supportedFlash);
}
@ -226,6 +227,7 @@ public class CameraOptions {
*/
@NonNull
public Set<WhiteBalance> getSupportedWhiteBalance() {
// TODO v2: return a Collection
return Collections.unmodifiableSet(supportedWhiteBalance);
}
@ -239,6 +241,7 @@ public class CameraOptions {
*/
@NonNull
public Set<Hdr> getSupportedHdr() {
// TODO v2: return a Collection
return Collections.unmodifiableSet(supportedHdr);
}

@ -619,6 +619,34 @@ public class CameraView extends FrameLayout {
//region Public APIs for controls
/**
* Shorthand for the appropriate set* method.
* For example, if control is a {@link Grid}, this calls {@link #setGrid(Grid)}.
*
* @param control desired value
*/
public void set(Control control) {
if (control instanceof Audio) {
setAudio((Audio) control);
} else if (control instanceof Facing) {
setFacing((Facing) control);
} else if (control instanceof Flash) {
setFlash((Flash) control);
} else if (control instanceof Grid) {
setGrid((Grid) control);
} else if (control instanceof Hdr) {
setHdr((Hdr) control);
} else if (control instanceof SessionType) {
setSessionType((SessionType) control);
} else if (control instanceof VideoQuality) {
setVideoQuality((VideoQuality) control);
} else if (control instanceof WhiteBalance) {
setWhiteBalance((WhiteBalance) control);
}
}
/**
* Returns a {@link CameraOptions} instance holding supported options for this camera
* session. This might change over time. It's better to hold a reference from
@ -786,6 +814,7 @@ public class CameraView extends FrameLayout {
return mCameraController.getLocation();
}
/**
* Sets desired white balance to current camera session.
*
@ -819,7 +848,7 @@ public class CameraView extends FrameLayout {
*
* @param facing a facing value.
*/
public void setFacing(final Facing facing) {
public void setFacing(Facing facing) {
mCameraController.setFacing(facing);
}

@ -6,7 +6,7 @@ package com.otaliastudios.cameraview;
*
* @see CameraView#setAudio(Audio)
*/
public enum Audio {
public enum Audio implements Control {
/**
* No Audio.

@ -0,0 +1,8 @@
package com.otaliastudios.cameraview;
/**
* Base interface for controls like {@link Audio},
* {@link Facing}, {@link Flash} and so on.
*/
public interface Control {
}

@ -6,7 +6,7 @@ package com.otaliastudios.cameraview;
*
* @see CameraView#setFacing(Facing)
*/
public enum Facing {
public enum Facing implements Control {
/**
* Back-facing camera sensor.

@ -6,7 +6,7 @@ package com.otaliastudios.cameraview;
*
* @see CameraView#setFlash(Flash)
*/
public enum Flash {
public enum Flash implements Control {
/**
* Flash is always off.

@ -6,7 +6,7 @@ package com.otaliastudios.cameraview;
*
* @see CameraView#setGrid(Grid)
*/
public enum Grid {
public enum Grid implements Control {
/**

@ -6,7 +6,7 @@ package com.otaliastudios.cameraview;
*
* @see CameraView#setHdr(Hdr)
*/
public enum Hdr {
public enum Hdr implements Control {
/**
* No HDR.

@ -9,7 +9,7 @@ package com.otaliastudios.cameraview;
*
* @see CameraView#setSessionType(SessionType)
*/
public enum SessionType {
public enum SessionType implements Control {
/**
* Session optimized to capture pictures.

@ -6,7 +6,7 @@ package com.otaliastudios.cameraview;
*
* @see CameraView#setVideoQuality(VideoQuality)
*/
public enum VideoQuality {
public enum VideoQuality implements Control {
/**

@ -7,7 +7,7 @@ package com.otaliastudios.cameraview;
*
* @see CameraView#setWhiteBalance(WhiteBalance)
*/
public enum WhiteBalance {
public enum WhiteBalance implements Control {
/**
* Automatic white balance selection (AWB).

@ -10,6 +10,7 @@ import com.otaliastudios.cameraview.Flash;
import com.otaliastudios.cameraview.Gesture;
import com.otaliastudios.cameraview.GestureAction;
import com.otaliastudios.cameraview.Grid;
import com.otaliastudios.cameraview.Hdr;
import com.otaliastudios.cameraview.SessionType;
import com.otaliastudios.cameraview.VideoQuality;
import com.otaliastudios.cameraview.WhiteBalance;
@ -32,6 +33,7 @@ public enum Control {
WHITE_BALANCE("White balance", false),
GRID("Grid", true),
VIDEO_QUALITY("Video quality", false),
HDR("Hdr", false),
AUDIO("Audio", true),
PINCH("Pinch gesture", false),
HSCROLL("Horizontal scroll gesture", false),
@ -71,13 +73,14 @@ public enum Control {
list.add(i);
}
return list;
case SESSION: return Arrays.asList(SessionType.values());
case CROP_OUTPUT: return Arrays.asList(true, false);
case FLASH: return options.getSupportedFlash();
case WHITE_BALANCE: return options.getSupportedWhiteBalance();
case GRID: return Arrays.asList(Grid.values());
case VIDEO_QUALITY: return Arrays.asList(VideoQuality.values());
case AUDIO: return Arrays.asList(Audio.values());
case SESSION: return options.getSupportedControls(SessionType.class);
case FLASH: return options.getSupportedControls(Flash.class);
case WHITE_BALANCE: return options.getSupportedControls(WhiteBalance.class);
case HDR: return options.getSupportedControls(Hdr.class);
case GRID: return options.getSupportedControls(Grid.class);
case VIDEO_QUALITY: return options.getSupportedControls(VideoQuality.class);
case AUDIO: return options.getSupportedControls(Audio.class);
case PINCH:
case HSCROLL:
case VSCROLL:
@ -114,6 +117,7 @@ public enum Control {
case GRID: return view.getGrid();
case VIDEO_QUALITY: return view.getVideoQuality();
case AUDIO: return view.getAudio();
case HDR: return view.getHdr();
case PINCH: return view.getGestureAction(Gesture.PINCH);
case HSCROLL: return view.getGestureAction(Gesture.SCROLL_HORIZONTAL);
case VSCROLL: return view.getGestureAction(Gesture.SCROLL_VERTICAL);
@ -134,25 +138,16 @@ public enum Control {
camera.setLayoutParams(camera.getLayoutParams());
break;
case SESSION:
camera.setSessionType((SessionType) value);
break;
case CROP_OUTPUT:
camera.setCropOutput((boolean) value);
break;
case FLASH:
camera.setFlash((Flash) value);
break;
case WHITE_BALANCE:
camera.setWhiteBalance((WhiteBalance) value);
break;
case GRID:
camera.setGrid((Grid) value);
break;
case VIDEO_QUALITY:
camera.setVideoQuality((VideoQuality) value);
break;
case AUDIO:
camera.setAudio((Audio) value);
case HDR:
camera.set((com.otaliastudios.cameraview.Control) value);
break;
case CROP_OUTPUT:
camera.setCropOutput((boolean) value);
break;
case PINCH:
camera.mapGesture(Gesture.PINCH, (GestureAction) value);

Loading…
Cancel
Save