diff --git a/README.md b/README.md index 253037dc..d99ff508 100644 --- a/README.md +++ b/README.md @@ -165,7 +165,7 @@ Make sure you can react to different camera events by setting up a `CameraListen camera.setCameraListener(new CameraListener() { @Override - public void onCameraOpened() {} + public void onCameraOpened(CameraOptions options) {} @Override public void onCameraClosed() {} @@ -250,7 +250,7 @@ This means that part of the preview is hidden, and the image output will contain |[`cameraSessionType`](#camerasessiontype)|`setSessionType()`|`picture` `video`|`picture`| |[`cameraFacing`](#camerafacing)|`setFacing()`|`back` `front`|`back`| |[`cameraFlash`](#cameraflash)|`setFlash()`|`off` `on` `auto` `torch`|`off`| -|[`cameraFocus`](#camerafocus)|`setFocus()`|`off` `continuous` `tap` `tapWithMarker`|`continuous`| +|[`cameraFocus`](#camerafocus)|`setFocus()`|`fixed` `continuous` `tap` `tapWithMarker`|`continuous`| |[`cameraZoomMode`](#camerazoommode)|`setZoom()`|`off` `pinch`|`off`| |[`cameraGrid`](#cameragrid)|`setGrid()`|`off` `grid3x3` `grid4x4` `phi`|`off`| |[`cameraCropOutput`](#cameracropoutput)|`setCropOutput()`|`true` `false`|`false`| @@ -297,7 +297,7 @@ cameraView.setFlash(CameraKit.Constants.FLASH_TORCH); Focus behavior. Can be off, continuous (camera continuously tries to adapt its focus), tap (focus is driven by the user tap) and tapWithMarker (a marker is drawn on screen to indicate focusing). ```java -cameraView.setFocus(CameraKit.Constants.FOCUS_OFF); +cameraView.setFocus(CameraKit.Constants.FOCUS_FIXED); cameraView.setFocus(CameraKit.Constants.FOCUS_CONTINUOUS); cameraView.setFocus(CameraKit.Constants.FOCUS_TAP); cameraView.setFocus(CameraKit.Constants.FOCUS_TAP_WITH_MARKER); diff --git a/camerakit/src/main/api16/com/flurgle/camerakit/Camera1.java b/camerakit/src/main/api16/com/flurgle/camerakit/Camera1.java index 8fecf547..f947c01f 100644 --- a/camerakit/src/main/api16/com/flurgle/camerakit/Camera1.java +++ b/camerakit/src/main/api16/com/flurgle/camerakit/Camera1.java @@ -10,7 +10,6 @@ import android.os.Handler; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.util.Log; -import android.view.MotionEvent; import android.view.SurfaceHolder; import java.io.File; @@ -20,7 +19,7 @@ import java.util.Collections; import java.util.List; import static com.flurgle.camerakit.CameraKit.Constants.FOCUS_CONTINUOUS; -import static com.flurgle.camerakit.CameraKit.Constants.FOCUS_OFF; +import static com.flurgle.camerakit.CameraKit.Constants.FOCUS_FIXED; import static com.flurgle.camerakit.CameraKit.Constants.FOCUS_TAP; import static com.flurgle.camerakit.CameraKit.Constants.FOCUS_TAP_WITH_MARKER; import static com.flurgle.camerakit.CameraKit.Constants.SESSION_TYPE_PICTURE; @@ -36,6 +35,7 @@ class Camera1 extends CameraImpl { private int mCameraId; private Camera mCamera; private ExtraProperties mExtraProperties; + private CameraOptions mOptions; private Size mPreviewSize; private Size mCaptureSize; private MediaRecorder mMediaRecorder; @@ -49,7 +49,7 @@ class Camera1 extends CameraImpl { private double mLongitude; private Handler mFocusHandler = new Handler(); - private ConstantMapper.MapperImpl mMapper = new ConstantMapper.Mapper1(); + private MapperImpl mMapper = new MapperImpl.Mapper1(); private boolean mIsSetup = false; private boolean mIsCapturingImage = false; private boolean mIsCapturingVideo = false; @@ -143,6 +143,8 @@ class Camera1 extends CameraImpl { // Set parameters that might have been set before the camera was opened. synchronized (mLock) { Camera.Parameters params = mCamera.getParameters(); + mExtraProperties = new ExtraProperties(params); + mOptions = new CameraOptions(params); mergeFocus(params, CameraKit.Defaults.DEFAULT_FOCUS); mergeFlash(params, CameraKit.Defaults.DEFAULT_FLASH); mergeLocation(params, 0d, 0d); @@ -154,8 +156,7 @@ class Camera1 extends CameraImpl { // Try starting preview. mCamera.setDisplayOrientation(computeSensorToDisplayOffset()); // <- not allowed during preview if (shouldSetup()) setup(); - collectExtraProperties(); - mCameraCallbacks.dispatchOnCameraOpened(); + mCameraCallbacks.dispatchOnCameraOpened(mOptions); } } @@ -169,6 +170,8 @@ class Camera1 extends CameraImpl { mCamera.release(); mCameraCallbacks.dispatchOnCameraClosed(); } + mExtraProperties = null; + mOptions = null; mCamera = null; mPreviewSize = null; mCaptureSize = null; @@ -262,10 +265,8 @@ class Camera1 extends CameraImpl { } private boolean mergeWhiteBalance(Camera.Parameters params, @WhiteBalance int oldWhiteBalance) { - List supported = params.getSupportedWhiteBalance(); - String internal = mMapper.mapWhiteBalance(mWhiteBalance); - if (supported != null && supported.contains(internal)) { - params.setWhiteBalance(internal); + if (mOptions.getSupportedWhiteBalance().contains(mWhiteBalance)) { + params.setWhiteBalance((String) mMapper.mapWhiteBalance(mWhiteBalance)); return true; } mWhiteBalance = oldWhiteBalance; @@ -286,10 +287,8 @@ class Camera1 extends CameraImpl { private boolean mergeFlash(Camera.Parameters params, @Flash int oldFlash) { - List flashes = params.getSupportedFlashModes(); - String internalFlash = mMapper.mapFlash(mFlash); - if (flashes != null && flashes.contains(internalFlash)) { - params.setFlashMode(internalFlash); + if (mOptions.getSupportedFlash().contains(mFlash)) { + params.setFlashMode((String) mMapper.mapFlash(mFlash)); return true; } mFlash = oldFlash; @@ -311,30 +310,34 @@ class Camera1 extends CameraImpl { private boolean mergeFocus(Camera.Parameters params, @Focus int oldFocus) { - final List modes = params.getSupportedFocusModes(); + if (!mOptions.getSupportedFocus().contains(mFocus)) { + mFocus = oldFocus; + return false; + } + switch (mFocus) { case FOCUS_CONTINUOUS: + params.setFocusMode((String) mMapper.mapFocus(FOCUS_CONTINUOUS)); + return true; + case FOCUS_TAP: case FOCUS_TAP_WITH_MARKER: - if (modes.contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE)) { - params.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE); + // We are sure camera supports auto focus. + // Now we must just find a fallback, because FOCUS_AUTO is used only on tap. + if (mOptions.getSupportedFocus().contains(FOCUS_CONTINUOUS)) { + params.setFocusMode((String) mMapper.mapFocus(FOCUS_CONTINUOUS)); return true; } - mFocus = oldFocus; - return false; + // Don't break. - case FOCUS_OFF: - if (modes.contains(Camera.Parameters.FOCUS_MODE_FIXED)) { - params.setFocusMode(Camera.Parameters.FOCUS_MODE_FIXED); - return true; - } else if (modes.contains(Camera.Parameters.FOCUS_MODE_INFINITY)) { - params.setFocusMode(Camera.Parameters.FOCUS_MODE_INFINITY); - return true; - } else if (modes.contains(Camera.Parameters.FOCUS_MODE_AUTO)) { - params.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO); + case FOCUS_FIXED: + if (mOptions.getSupportedFocus().contains(FOCUS_FIXED)) { + params.setFocusMode((String) mMapper.mapFocus(FOCUS_FIXED)); return true; } } + + mFocus = oldFocus; return false; } @@ -370,8 +373,7 @@ class Camera1 extends CameraImpl { if (mIsCapturingImage) return; if (!isCameraOpened()) return; if (mSessionType == SESSION_TYPE_VIDEO && mIsCapturingVideo) { - Camera.Parameters parameters = mCamera.getParameters(); - if (!parameters.isVideoSnapshotSupported()) return; + if (!mOptions.isVideoSnapshotSupported()) return; } // Set boolean to wait for image callback @@ -380,10 +382,10 @@ class Camera1 extends CameraImpl { final boolean exifFlip = computeExifFlip(); final int sensorToDisplay = computeSensorToDisplayOffset(); synchronized (mLock) { - Camera.Parameters parameters = mCamera.getParameters(); + Camera.Parameters params = mCamera.getParameters(); Log.e(TAG, "Setting exif rotation to "+exifRotation); - parameters.setRotation(exifRotation); - mCamera.setParameters(parameters); + params.setRotation(exifRotation); + mCamera.setParameters(params); } // Is the final picture (decoded respecting EXIF) consistent with CameraView orientation? // We must consider exifOrientation to bring back the picture in the sensor world. @@ -469,6 +471,12 @@ class Camera1 extends CameraImpl { return mExtraProperties; } + @Nullable + @Override + CameraOptions getCameraOptions() { + return mOptions; + } + // Internal: @@ -539,13 +547,6 @@ class Camera1 extends CameraImpl { } - private void collectExtraProperties() { - Camera.Parameters params = mCamera.getParameters(); - mExtraProperties = new ExtraProperties(params.getVerticalViewAngle(), - params.getHorizontalViewAngle()); - } - - // ----------------- // Video recording stuff. @@ -661,7 +662,7 @@ class Camera1 extends CameraImpl { if (!isCameraOpened()) return false; synchronized (mLock) { Camera.Parameters params = mCamera.getParameters(); - if (!params.isZoomSupported()) return false; + if (!mOptions.isZoomSupported()) return false; float max = params.getMaxZoom(); params.setZoom((int) (zoom * max)); mCamera.setParameters(params); @@ -680,15 +681,15 @@ class Camera1 extends CameraImpl { List meteringAreas2 = computeMeteringAreas(x, y); List meteringAreas1 = meteringAreas2.subList(0, 1); synchronized (mLock) { - Camera.Parameters parameters = mCamera.getParameters(); - boolean autofocusSupported = parameters.getSupportedFocusModes().contains(Camera.Parameters.FOCUS_MODE_AUTO); + Camera.Parameters params = mCamera.getParameters(); + boolean autofocusSupported = params.getSupportedFocusModes().contains(Camera.Parameters.FOCUS_MODE_AUTO); if (autofocusSupported) { - int maxAF = parameters.getMaxNumFocusAreas(); - int maxAE = parameters.getMaxNumMeteringAreas(); - if (maxAF > 0) parameters.setFocusAreas(maxAF > 1 ? meteringAreas2 : meteringAreas1); - if (maxAE > 0) parameters.setMeteringAreas(maxAE > 1 ? meteringAreas2 : meteringAreas1); - parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO); - mCamera.setParameters(parameters); + int maxAF = params.getMaxNumFocusAreas(); + int maxAE = params.getMaxNumMeteringAreas(); + if (maxAF > 0) params.setFocusAreas(maxAF > 1 ? meteringAreas2 : meteringAreas1); + if (maxAE > 0) params.setMeteringAreas(maxAE > 1 ? meteringAreas2 : meteringAreas1); + params.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO); + mCamera.setParameters(params); mCameraCallbacks.dispatchOnFocusStart(x, y); mCamera.autoFocus(new Camera.AutoFocusCallback() { @Override @@ -711,12 +712,10 @@ class Camera1 extends CameraImpl { mCamera.cancelAutoFocus(); synchronized (mLock) { Camera.Parameters params = mCamera.getParameters(); - if (!params.getFocusMode().equals(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE)) { - params.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE); - params.setFocusAreas(null); - params.setMeteringAreas(null); - mCamera.setParameters(params); - } + params.setFocusAreas(null); + params.setMeteringAreas(null); + mergeFocus(params, mFocus); // Revert to internal focus (CONTINUOUS_PICTURE if present). + mCamera.setParameters(params); } } }, DELAY_MILLIS_BEFORE_RESETTING_FOCUS); diff --git a/camerakit/src/main/api16/com/flurgle/camerakit/ConstantMapper.java b/camerakit/src/main/api16/com/flurgle/camerakit/MapperImpl.java similarity index 51% rename from camerakit/src/main/api16/com/flurgle/camerakit/ConstantMapper.java rename to camerakit/src/main/api16/com/flurgle/camerakit/MapperImpl.java index 59d6a173..192a0f33 100644 --- a/camerakit/src/main/api16/com/flurgle/camerakit/ConstantMapper.java +++ b/camerakit/src/main/api16/com/flurgle/camerakit/MapperImpl.java @@ -8,21 +8,22 @@ import android.util.SparseIntArray; import java.util.Map; -public class ConstantMapper { +abstract class MapperImpl { - static abstract class MapperImpl { - - MapperImpl() {} - - abstract T mapFlash(@Flash int internalConstant); - abstract T mapFacing(@Facing int internalConstant); - abstract T mapWhiteBalance(@WhiteBalance int internalConstant); - } + abstract T mapFlash(@Flash int internalConstant); + abstract T mapFacing(@Facing int internalConstant); + abstract T mapWhiteBalance(@WhiteBalance int internalConstant); + abstract T mapFocus(@Focus int internalConstant); + @Flash abstract int unmapFlash(T cameraConstant); + @Facing abstract int unmapFacing(T cameraConstant); + @WhiteBalance abstract int unmapWhiteBalance(T cameraConstant); + @Focus abstract int unmapFocus(T cameraConstant); static class Mapper1 extends MapperImpl { private static final SparseArrayCompat FLASH = new SparseArrayCompat<>(); private static final SparseArrayCompat WB = new SparseArrayCompat<>(); private static final SparseArrayCompat FACING = new SparseArrayCompat<>(); + private static final SparseArrayCompat FOCUS = new SparseArrayCompat<>(); static { FLASH.put(CameraKit.Constants.FLASH_OFF, Camera.Parameters.FLASH_MODE_OFF); @@ -36,6 +37,10 @@ public class ConstantMapper { WB.put(CameraKit.Constants.WHITE_BALANCE_FLUORESCENT, Camera.Parameters.WHITE_BALANCE_FLUORESCENT); WB.put(CameraKit.Constants.WHITE_BALANCE_DAYLIGHT, Camera.Parameters.WHITE_BALANCE_DAYLIGHT); WB.put(CameraKit.Constants.WHITE_BALANCE_CLOUDY, Camera.Parameters.WHITE_BALANCE_CLOUDY_DAYLIGHT); + FOCUS.put(CameraKit.Constants.FOCUS_FIXED, Camera.Parameters.FOCUS_MODE_FIXED); + FOCUS.put(CameraKit.Constants.FOCUS_CONTINUOUS, Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE); + FOCUS.put(CameraKit.Constants.FOCUS_TAP, Camera.Parameters.FOCUS_MODE_AUTO); + FOCUS.put(CameraKit.Constants.FOCUS_TAP_WITH_MARKER, Camera.Parameters.FOCUS_MODE_AUTO); } @Override @@ -52,6 +57,32 @@ public class ConstantMapper { T mapWhiteBalance(int internalConstant) { return (T) WB.get(internalConstant, null); } + + @Override + T mapFocus(@Focus int internalConstant) { + return (T) FOCUS.get(internalConstant, null); + } + + @Override + int unmapFlash(T cameraConstant) { + return FLASH.keyAt(FLASH.indexOfValue((String) cameraConstant)); + } + + @Override + int unmapFacing(T cameraConstant) { + return FACING.keyAt(FACING.indexOfValue((Integer) cameraConstant)); + } + + @Override + int unmapWhiteBalance(T cameraConstant) { + return WB.keyAt(WB.indexOfValue((String) cameraConstant)); + } + + // This will ignore FOCUS_TAP_WITH_MARKER but it's fine + @Override + int unmapFocus(T cameraConstant) { + return FOCUS.keyAt(FOCUS.indexOfValue((String) cameraConstant)); + } } static class Mapper2 extends MapperImpl { @@ -70,6 +101,31 @@ public class ConstantMapper { T mapFlash(@Flash int internalConstant) { return null; } + + @Override + int unmapFlash(T cameraConstant) { + return 0; + } + + @Override + int unmapFacing(T cameraConstant) { + return 0; + } + + @Override + int unmapWhiteBalance(T cameraConstant) { + return 0; + } + + @Override + T mapFocus(@Focus int internalConstant) { + return null; + } + + @Override + int unmapFocus(T cameraConstant) { + return 0; + } } } diff --git a/camerakit/src/main/api21/com/flurgle/camerakit/Camera2.java b/camerakit/src/main/api21/com/flurgle/camerakit/Camera2.java index f2c184be..6804628f 100644 --- a/camerakit/src/main/api21/com/flurgle/camerakit/Camera2.java +++ b/camerakit/src/main/api21/com/flurgle/camerakit/Camera2.java @@ -11,8 +11,6 @@ import android.hardware.camera2.params.StreamConfigurationMap; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.util.Log; -import android.util.SizeF; -import android.view.MotionEvent; import java.io.File; import java.util.ArrayList; @@ -33,7 +31,7 @@ class Camera2 extends CameraImpl { private Size mCaptureSize; private Size mPreviewSize; - private ConstantMapper.MapperImpl mMapper = new ConstantMapper.Mapper2(); + private MapperImpl mMapper = new MapperImpl.Mapper2(); private final HashMap mExtraPropertiesMap = new HashMap<>(); @@ -64,22 +62,8 @@ class Camera2 extends CameraImpl { @SuppressWarnings("ConstantConditions") int orientation = characteristics.get(CameraCharacteristics.LENS_FACING); if (orientation == CameraCharacteristics.LENS_FACING_BACK) { - float[] maxFocus = characteristics.get( - CameraCharacteristics.LENS_INFO_AVAILABLE_FOCAL_LENGTHS); - if (maxFocus == null) { - continue; - } - SizeF size = characteristics.get( - CameraCharacteristics.SENSOR_INFO_PHYSICAL_SIZE); - if (size == null) { - continue; - } - float w = size.getWidth(); - float h = size.getHeight(); - mExtraPropertiesMap.put(cameraId, new ExtraProperties( - (float) Math.toDegrees(2*Math.atan(w/(maxFocus[0]*2))), - (float) Math.toDegrees(2*Math.atan(h/(maxFocus[0]*2))) - )); + ExtraProperties props = new ExtraProperties(characteristics); + mExtraPropertiesMap.put(cameraId, props); } } } catch (CameraAccessException e) { @@ -274,6 +258,13 @@ class Camera2 extends CameraImpl { } // Internal + + @Nullable + @Override + CameraOptions getCameraOptions() { + return null; + } + private List getAvailableCaptureResolutions() { List output = new ArrayList<>(); diff --git a/camerakit/src/main/base/com/flurgle/camerakit/CameraImpl.java b/camerakit/src/main/base/com/flurgle/camerakit/CameraImpl.java index be14d3a3..1ae3dd63 100644 --- a/camerakit/src/main/base/com/flurgle/camerakit/CameraImpl.java +++ b/camerakit/src/main/base/com/flurgle/camerakit/CameraImpl.java @@ -51,8 +51,8 @@ abstract class CameraImpl implements PreviewImpl.SurfaceCallback { abstract void startFocus(float x, float y); - @Nullable - abstract ExtraProperties getExtraProperties(); + @Nullable abstract ExtraProperties getExtraProperties(); + @Nullable abstract CameraOptions getCameraOptions(); @Facing final int getFacing() { diff --git a/camerakit/src/main/base/com/flurgle/camerakit/CameraOptions.java b/camerakit/src/main/base/com/flurgle/camerakit/CameraOptions.java new file mode 100644 index 00000000..1c67599b --- /dev/null +++ b/camerakit/src/main/base/com/flurgle/camerakit/CameraOptions.java @@ -0,0 +1,91 @@ +package com.flurgle.camerakit; + + +import android.annotation.TargetApi; +import android.hardware.Camera; +import android.hardware.camera2.CameraCharacteristics; + +import java.util.ArrayList; +import java.util.List; + +/** + * Options telling you what is available and what is not. + */ +@SuppressWarnings("deprecation") +public class CameraOptions { + + private List supportedWhiteBalance = new ArrayList<>(5); + private List supportedFacing = new ArrayList<>(2); + private List supportedFlash = new ArrayList<>(3); + private List supportedFocus = new ArrayList<>(3); + + private boolean zoomSupported; + private boolean videoSnapshotSupported; + + CameraOptions(Camera.Parameters params) { + List strings; + MapperImpl mapper = new MapperImpl.Mapper1(); + + // Facing + Camera.CameraInfo cameraInfo = new Camera.CameraInfo(); + for (int i = 0, count = Camera.getNumberOfCameras(); i < count; i++) { + Camera.getCameraInfo(i, cameraInfo); + supportedFacing.add(mapper.unmapFacing(cameraInfo.facing)); + } + + // WB + strings = params.getSupportedWhiteBalance(); + if (strings != null) { + for (String string : strings) { + supportedWhiteBalance.add(mapper.unmapWhiteBalance(string)); + } + } + + // Flash + strings = params.getSupportedFlashModes(); + if (strings != null) { + for (String string : strings) { + supportedFlash.add(mapper.unmapFlash(string)); + } + } + + // Focus + strings = params.getSupportedFocusModes(); // Never null. + for (String string : strings) { + supportedFocus.add(mapper.unmapFocus(string)); + } + + zoomSupported = params.isZoomSupported(); + videoSnapshotSupported = params.isVideoSnapshotSupported(); + + + + } + + @TargetApi(21) + CameraOptions(CameraCharacteristics params) {} + + public List getSupportedFacing() { + return supportedFacing; + } + + public List getSupportedFlash() { + return supportedFlash; + } + + public List getSupportedWhiteBalance() { + return supportedWhiteBalance; + } + + public List getSupportedFocus() { + return supportedFocus; + } + + public boolean isZoomSupported() { + return zoomSupported; + } + + public boolean isVideoSnapshotSupported() { + return videoSnapshotSupported; + } +} diff --git a/camerakit/src/main/base/com/flurgle/camerakit/ExtraProperties.java b/camerakit/src/main/base/com/flurgle/camerakit/ExtraProperties.java index b8d16d86..1750a2bd 100644 --- a/camerakit/src/main/base/com/flurgle/camerakit/ExtraProperties.java +++ b/camerakit/src/main/base/com/flurgle/camerakit/ExtraProperties.java @@ -1,14 +1,38 @@ package com.flurgle.camerakit; + +import android.annotation.TargetApi; +import android.hardware.Camera; +import android.hardware.camera2.CameraCharacteristics; +import android.util.SizeF; + /** * Simple pojo containing various camera properties. */ +@SuppressWarnings("deprecation") public class ExtraProperties { - public final float verticalViewingAngle; - public final float horizontalViewingAngle; - public ExtraProperties(float verticalViewingAngle, float horizontalViewingAngle) { - this.verticalViewingAngle = verticalViewingAngle; - this.horizontalViewingAngle = horizontalViewingAngle; + float verticalViewingAngle; + float horizontalViewingAngle; + + ExtraProperties(Camera.Parameters params) { + verticalViewingAngle = params.getVerticalViewAngle(); + horizontalViewingAngle = params.getHorizontalViewAngle(); + } + + @TargetApi(21) + ExtraProperties(CameraCharacteristics chars) { + float[] maxFocus = chars.get(CameraCharacteristics.LENS_INFO_AVAILABLE_FOCAL_LENGTHS); + SizeF size = chars.get(CameraCharacteristics.SENSOR_INFO_PHYSICAL_SIZE); + verticalViewingAngle = (float) Math.toDegrees(2 * Math.atan(size.getWidth() / (maxFocus[0] * 2))); + horizontalViewingAngle = (float) Math.toDegrees(2 * Math.atan(size.getHeight() / (maxFocus[0] * 2))); + } + + public float getHorizontalViewingAngle() { + return horizontalViewingAngle; + } + + public float getVerticalViewingAngle() { + return verticalViewingAngle; } } diff --git a/camerakit/src/main/java/com/flurgle/camerakit/CameraKit.java b/camerakit/src/main/java/com/flurgle/camerakit/CameraKit.java index 0abbde84..7c2d1c6a 100644 --- a/camerakit/src/main/java/com/flurgle/camerakit/CameraKit.java +++ b/camerakit/src/main/java/com/flurgle/camerakit/CameraKit.java @@ -18,7 +18,7 @@ public class CameraKit { public static final int FLASH_AUTO = 2; public static final int FLASH_TORCH = 3; - public static final int FOCUS_OFF = 0; + public static final int FOCUS_FIXED = 0; public static final int FOCUS_CONTINUOUS = 1; public static final int FOCUS_TAP = 2; public static final int FOCUS_TAP_WITH_MARKER = 3; diff --git a/camerakit/src/main/java/com/flurgle/camerakit/CameraListener.java b/camerakit/src/main/java/com/flurgle/camerakit/CameraListener.java index 9fddcb07..7449325a 100644 --- a/camerakit/src/main/java/com/flurgle/camerakit/CameraListener.java +++ b/camerakit/src/main/java/com/flurgle/camerakit/CameraListener.java @@ -7,17 +7,26 @@ import java.io.File; public abstract class CameraListener { - public void onCameraOpened() { + /** + * Notifies that the camera was opened. + * The {@link CameraOptions} object collects all supported options by the current camera. + * + * @param options camera supported options + */ + public void onCameraOpened(CameraOptions options) { } + public void onCameraClosed() { } + public void onPictureTaken(byte[] jpeg) { } + public void onVideoTaken(File video) { diff --git a/camerakit/src/main/java/com/flurgle/camerakit/CameraUtils.java b/camerakit/src/main/java/com/flurgle/camerakit/CameraUtils.java index a13b5edf..d4d9994a 100644 --- a/camerakit/src/main/java/com/flurgle/camerakit/CameraUtils.java +++ b/camerakit/src/main/java/com/flurgle/camerakit/CameraUtils.java @@ -5,6 +5,7 @@ import android.content.pm.PackageManager; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Matrix; +import android.hardware.Camera; import android.os.Handler; import android.support.annotation.UiThread; import android.support.media.ExifInterface; @@ -34,6 +35,25 @@ public class CameraUtils { } + /** + * Determines whether the device has a valid camera sensor with the given + * Facing value, so that a session can be started. + * + * @param context a valid context + * @param facing either {@link CameraKit.Constants#FACING_BACK} or {@link CameraKit.Constants#FACING_FRONT} + * @return true if such sensor exists + */ + public static boolean hasCameraFacing(Context context, @Facing int facing) { + int internal = new MapperImpl.Mapper1().mapFacing(facing); + Camera.CameraInfo cameraInfo = new Camera.CameraInfo(); + for (int i = 0, count = Camera.getNumberOfCameras(); i < count; i++) { + Camera.getCameraInfo(i, cameraInfo); + if (cameraInfo.facing == internal) return true; + } + return false; + } + + /** * Decodes an input byte array and outputs a Bitmap that is ready to be displayed. * The difference with {@link android.graphics.BitmapFactory#decodeByteArray(byte[], int, int)} diff --git a/camerakit/src/main/java/com/flurgle/camerakit/CameraView.java b/camerakit/src/main/java/com/flurgle/camerakit/CameraView.java index e7b08368..e6c563b8 100644 --- a/camerakit/src/main/java/com/flurgle/camerakit/CameraView.java +++ b/camerakit/src/main/java/com/flurgle/camerakit/CameraView.java @@ -477,6 +477,19 @@ public class CameraView extends FrameLayout implements LifecycleObserver { } + /** + * 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 + * {@link CameraListener#onCameraOpened(CameraOptions)}. + * + * @return an options map, or null if camera was not opened + */ + @Nullable + public CameraOptions getCameraOptions() { + return mCameraImpl.getCameraOptions(); + } + + /** * If present, returns a collection of extra properties from the current camera * session. @@ -648,7 +661,7 @@ public class CameraView extends FrameLayout implements LifecycleObserver { /** * Toggles the flash mode between {@link CameraKit.Constants#FLASH_OFF}, * {@link CameraKit.Constants#FLASH_ON}, {@link CameraKit.Constants#FLASH_AUTO} and - * {@link CameraKit.Constants#FOCUS_OFF}, in this order. + * {@link CameraKit.Constants#FOCUS_FIXED}, in this order. * * @return the new flash value */ @@ -692,13 +705,14 @@ public class CameraView extends FrameLayout implements LifecycleObserver { * Sets the current focus behavior. * * @see CameraKit.Constants#FOCUS_CONTINUOUS - * @see CameraKit.Constants#FOCUS_OFF + * @see CameraKit.Constants#FOCUS_FIXED * @see CameraKit.Constants#FOCUS_TAP * @see CameraKit.Constants#FOCUS_TAP_WITH_MARKER * @param focus a Focus value. */ public void setFocus(@Focus int focus) { + // TODO we are not sure this focus is supported at this point, yet we enable the layout! mFocusMarkerLayout.setEnabled(focus == CameraKit.Constants.FOCUS_TAP_WITH_MARKER); if (focus == CameraKit.Constants.FOCUS_TAP_WITH_MARKER) { focus = CameraKit.Constants.FOCUS_TAP; @@ -1067,12 +1081,12 @@ public class CameraView extends FrameLayout implements LifecycleObserver { } - public void dispatchOnCameraOpened() { + public void dispatchOnCameraOpened(final CameraOptions options) { uiHandler.post(new Runnable() { @Override public void run() { for (CameraListener listener : mListeners) { - listener.onCameraOpened(); + listener.onCameraOpened(options); } } }); diff --git a/camerakit/src/main/res/values/attrs.xml b/camerakit/src/main/res/values/attrs.xml index 6d120e05..2ecffb0e 100644 --- a/camerakit/src/main/res/values/attrs.xml +++ b/camerakit/src/main/res/values/attrs.xml @@ -16,7 +16,7 @@ - + diff --git a/camerakit/src/main/types/com/flurgle/camerakit/Focus.java b/camerakit/src/main/types/com/flurgle/camerakit/Focus.java index ee0b31aa..84201d15 100644 --- a/camerakit/src/main/types/com/flurgle/camerakit/Focus.java +++ b/camerakit/src/main/types/com/flurgle/camerakit/Focus.java @@ -6,11 +6,11 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import static com.flurgle.camerakit.CameraKit.Constants.FOCUS_TAP; -import static com.flurgle.camerakit.CameraKit.Constants.FOCUS_OFF; +import static com.flurgle.camerakit.CameraKit.Constants.FOCUS_FIXED; import static com.flurgle.camerakit.CameraKit.Constants.FOCUS_CONTINUOUS; import static com.flurgle.camerakit.CameraKit.Constants.FOCUS_TAP_WITH_MARKER; @Retention(RetentionPolicy.SOURCE) -@IntDef({FOCUS_CONTINUOUS, FOCUS_TAP, FOCUS_OFF, FOCUS_TAP_WITH_MARKER}) +@IntDef({FOCUS_CONTINUOUS, FOCUS_TAP, FOCUS_FIXED, FOCUS_TAP_WITH_MARKER}) public @interface Focus { } \ No newline at end of file