summaryrefslogtreecommitdiffstats
path: root/camera2/portability/src/com/android/ex/camera2
diff options
context:
space:
mode:
authorAngus Kong <shkong@google.com>2014-06-10 16:07:45 -0700
committerEd Heyl <edheyl@google.com>2014-06-18 10:24:46 -0700
commit8097973089420749dcd1ab4974a629c2466b31cc (patch)
treedede361c4237dde7ff9ab10511afac5cf2cd5ff1 /camera2/portability/src/com/android/ex/camera2
parentcef46862d6937bc98bf1a6b087c5daa22b5239f3 (diff)
downloadandroid_frameworks_ex-8097973089420749dcd1ab4974a629c2466b31cc.tar.gz
android_frameworks_ex-8097973089420749dcd1ab4974a629c2466b31cc.tar.bz2
android_frameworks_ex-8097973089420749dcd1ab4974a629c2466b31cc.zip
Refactor out Camera.Parameters.
Change-Id: Ibc1ddac509381530e887b7491069e6367e9a6088
Diffstat (limited to 'camera2/portability/src/com/android/ex/camera2')
-rw-r--r--camera2/portability/src/com/android/ex/camera2/portability/AndroidCameraCapabilities.java133
-rw-r--r--camera2/portability/src/com/android/ex/camera2/portability/AndroidCameraManagerImpl.java116
-rw-r--r--camera2/portability/src/com/android/ex/camera2/portability/AndroidCameraSettings.java47
-rw-r--r--camera2/portability/src/com/android/ex/camera2/portability/CameraActions.java1
-rw-r--r--camera2/portability/src/com/android/ex/camera2/portability/CameraCapabilities.java202
-rw-r--r--camera2/portability/src/com/android/ex/camera2/portability/CameraManager.java23
-rw-r--r--camera2/portability/src/com/android/ex/camera2/portability/CameraSettings.java377
-rw-r--r--camera2/portability/src/com/android/ex/camera2/portability/Size.java151
8 files changed, 958 insertions, 92 deletions
diff --git a/camera2/portability/src/com/android/ex/camera2/portability/AndroidCameraCapabilities.java b/camera2/portability/src/com/android/ex/camera2/portability/AndroidCameraCapabilities.java
index 38e3f36..fc97efa 100644
--- a/camera2/portability/src/com/android/ex/camera2/portability/AndroidCameraCapabilities.java
+++ b/camera2/portability/src/com/android/ex/camera2/portability/AndroidCameraCapabilities.java
@@ -16,7 +16,6 @@
package com.android.ex.camera2.portability;
-import android.graphics.Point;
import android.hardware.Camera;
import com.android.ex.camera2.portability.debug.Log;
@@ -28,7 +27,7 @@ import java.util.List;
/**
* The subclass of {@link CameraCapabilities} for Android Camera 1 API.
*/
-public class AndroidCameraCapabilities extends CameraCapabilities {
+class AndroidCameraCapabilities extends CameraCapabilities {
private static Log.Tag TAG = new Log.Tag("AndroidCameraCapabilities");
@@ -42,8 +41,12 @@ public class AndroidCameraCapabilities extends CameraCapabilities {
mExposureCompensationStep = p.getExposureCompensationStep();
mMaxNumOfFacesSupported = p.getMaxNumDetectedFaces();
mMaxNumOfMeteringArea = p.getMaxNumMeteringAreas();
+ mPreferredPreviewSizeForVideo = new Size(p.getPreferredPreviewSizeForVideo());
mSupportedPreviewFormats.addAll(p.getSupportedPreviewFormats());
- mSupportedPictureFormats.addAll(p.getSupportedPictureFormats());
+ mSupportedPhotoFormats.addAll(p.getSupportedPictureFormats());
+ mMaxZoomIndex = p.getMaxZoom();
+ mZoomRatioList.addAll(p.getZoomRatios());
+ mMaxZoomRatio = mZoomRatioList.get(mMaxZoomIndex);
buildPreviewFpsRange(p);
buildPreviewSizes(p);
buildVideoSizes(p);
@@ -92,7 +95,7 @@ public class AndroidCameraCapabilities extends CameraCapabilities {
List<Camera.Size> supportedPreviewSizes = p.getSupportedPreviewSizes();
if (supportedPreviewSizes != null) {
for (Camera.Size s : supportedPreviewSizes) {
- mSupportedPreviewSizes.add(new Point(s.width, s.height));
+ mSupportedPreviewSizes.add(new Size(s.width, s.height));
}
}
Collections.sort(mSupportedPreviewSizes, mSizeComparator);
@@ -102,7 +105,7 @@ public class AndroidCameraCapabilities extends CameraCapabilities {
List<Camera.Size> supportedVideoSizes = p.getSupportedVideoSizes();
if (supportedVideoSizes != null) {
for (Camera.Size s : supportedVideoSizes) {
- mSupportedVideoSizes.add(new Point(s.width, s.height));
+ mSupportedVideoSizes.add(new Size(s.width, s.height));
}
}
Collections.sort(mSupportedVideoSizes, mSizeComparator);
@@ -112,10 +115,10 @@ public class AndroidCameraCapabilities extends CameraCapabilities {
List<Camera.Size> supportedPictureSizes = p.getSupportedPictureSizes();
if (supportedPictureSizes != null) {
for (Camera.Size s : supportedPictureSizes) {
- mSupportedPictureSizes.add(new Point(s.width, s.height));
+ mSupportedPhotoSizes.add(new Size(s.width, s.height));
}
}
- Collections.sort(mSupportedPictureSizes, mSizeComparator);
+ Collections.sort(mSupportedPhotoSizes, mSizeComparator);
}
@@ -164,7 +167,10 @@ public class AndroidCameraCapabilities extends CameraCapabilities {
private void buildFlashModes(Camera.Parameters p) {
List<String> supportedFlashModes = p.getSupportedFlashModes();
- if (supportedFlashModes != null) {
+ if (supportedFlashModes == null) {
+ // Camera 1 will return NULL if no flash mode is supported.
+ mSupportedFlashModes.add(FlashMode.NO_FLASH);
+ } else {
for (String flash : supportedFlashModes) {
if (Camera.Parameters.FLASH_MODE_AUTO.equals(flash)) {
mSupportedFlashModes.add(FlashMode.AUTO);
@@ -234,11 +240,12 @@ public class AndroidCameraCapabilities extends CameraCapabilities {
}
}
- private static class SizeComparator implements Comparator<Point> {
+ private static class SizeComparator implements Comparator<Size> {
@Override
- public int compare(Point size1, Point size2) {
- return (size1.x == size2.x ? size1.y - size2.y : size1.x - size2.x);
+ public int compare(Size size1, Size size2) {
+ return (size1.width() == size2.width() ? size1.height() - size2.height() :
+ size1.width() - size2.width());
}
}
@@ -246,6 +253,10 @@ public class AndroidCameraCapabilities extends CameraCapabilities {
@Override
public String stringify(FocusMode focus) {
+ if (focus == null) {
+ return null;
+ }
+
switch (focus) {
case AUTO:
return Camera.Parameters.FOCUS_MODE_AUTO;
@@ -267,19 +278,23 @@ public class AndroidCameraCapabilities extends CameraCapabilities {
@Override
public FocusMode focusModeFromString(String val) {
- if (val.equals(Camera.Parameters.FOCUS_MODE_AUTO)) {
+ if (val == null) {
+ return null;
+ }
+
+ if (Camera.Parameters.FOCUS_MODE_AUTO.equals(val)) {
return FocusMode.AUTO;
- } else if (val.equals(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE)) {
+ } else if (Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE.equals(val)) {
return FocusMode.CONTINUOUS_PICTURE;
- } else if (val.equals(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO)) {
+ } else if (Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO.equals(val)) {
return FocusMode.CONTINUOUS_VIDEO;
- } else if (val.equals(Camera.Parameters.FOCUS_MODE_EDOF)) {
+ } else if (Camera.Parameters.FOCUS_MODE_EDOF.equals(val)) {
return FocusMode.EXTENDED_DOF;
- } else if (val.equals(Camera.Parameters.FOCUS_MODE_FIXED)) {
+ } else if (Camera.Parameters.FOCUS_MODE_FIXED.equals(val)) {
return FocusMode.FIXED;
- } else if (val.equals(Camera.Parameters.FOCUS_MODE_INFINITY)) {
+ } else if (Camera.Parameters.FOCUS_MODE_INFINITY.equals(val)) {
return FocusMode.INFINITY;
- } else if (val.equals(Camera.Parameters.FOCUS_MODE_MACRO)) {
+ } else if (Camera.Parameters.FOCUS_MODE_MACRO.equals(val)) {
return FocusMode.MACRO;
} else {
return null;
@@ -288,7 +303,13 @@ public class AndroidCameraCapabilities extends CameraCapabilities {
@Override
public String stringify(FlashMode flash) {
+ if (flash == null) {
+ return null;
+ }
+
switch (flash) {
+ case NO_FLASH:
+ return null;
case AUTO:
return Camera.Parameters.FLASH_MODE_AUTO;
case OFF:
@@ -305,15 +326,17 @@ public class AndroidCameraCapabilities extends CameraCapabilities {
@Override
public FlashMode flashModeFromString(String val) {
- if (val.equals(Camera.Parameters.FLASH_MODE_AUTO)) {
+ if (val == null) {
+ return FlashMode.NO_FLASH;
+ } else if (Camera.Parameters.FLASH_MODE_AUTO.equals(val)) {
return FlashMode.AUTO;
- } else if (val.equals(Camera.Parameters.FLASH_MODE_OFF)) {
+ } else if (Camera.Parameters.FLASH_MODE_OFF.equals(val)) {
return FlashMode.OFF;
- } else if (val.equals(Camera.Parameters.FLASH_MODE_ON)) {
+ } else if (Camera.Parameters.FLASH_MODE_ON.equals(val)) {
return FlashMode.ON;
- } else if (val.equals(Camera.Parameters.FLASH_MODE_TORCH)) {
+ } else if (Camera.Parameters.FLASH_MODE_TORCH.equals(val)) {
return FlashMode.TORCH;
- } else if (val.equals(Camera.Parameters.FLASH_MODE_RED_EYE)) {
+ } else if (Camera.Parameters.FLASH_MODE_RED_EYE.equals(val)) {
return FlashMode.RED_EYE;
} else {
return null;
@@ -322,6 +345,10 @@ public class AndroidCameraCapabilities extends CameraCapabilities {
@Override
public String stringify(SceneMode scene) {
+ if (scene == null) {
+ return null;
+ }
+
switch (scene) {
case AUTO:
return Camera.Parameters.SCENE_MODE_AUTO;
@@ -363,39 +390,41 @@ public class AndroidCameraCapabilities extends CameraCapabilities {
@Override
public SceneMode sceneModeFromString(String val) {
- if (val.equals(Camera.Parameters.SCENE_MODE_AUTO)) {
+ if (val == null) {
+ return SceneMode.NO_SCENE_MODE;
+ } else if (Camera.Parameters.SCENE_MODE_AUTO.equals(val)) {
return SceneMode.AUTO;
- } else if (val.equals(Camera.Parameters.SCENE_MODE_ACTION)) {
+ } else if (Camera.Parameters.SCENE_MODE_ACTION.equals(val)) {
return SceneMode.ACTION;
- } else if (val.equals(Camera.Parameters.SCENE_MODE_BARCODE)) {
+ } else if (Camera.Parameters.SCENE_MODE_BARCODE.equals(val)) {
return SceneMode.BARCODE;
- } else if (val.equals(Camera.Parameters.SCENE_MODE_BEACH)) {
+ } else if (Camera.Parameters.SCENE_MODE_BEACH.equals(val)) {
return SceneMode.BEACH;
- } else if (val.equals(Camera.Parameters.SCENE_MODE_CANDLELIGHT)) {
+ } else if (Camera.Parameters.SCENE_MODE_CANDLELIGHT.equals(val)) {
return SceneMode.CANDLELIGHT;
- } else if (val.equals(Camera.Parameters.SCENE_MODE_FIREWORKS)) {
+ } else if (Camera.Parameters.SCENE_MODE_FIREWORKS.equals(val)) {
return SceneMode.FIREWORKS;
- } else if (val.equals(Camera.Parameters.SCENE_MODE_HDR)) {
+ } else if (Camera.Parameters.SCENE_MODE_HDR.equals(val)) {
return SceneMode.HDR;
- } else if (val.equals(Camera.Parameters.SCENE_MODE_LANDSCAPE)) {
+ } else if (Camera.Parameters.SCENE_MODE_LANDSCAPE.equals(val)) {
return SceneMode.LANDSCAPE;
- } else if (val.equals(Camera.Parameters.SCENE_MODE_NIGHT)) {
+ } else if (Camera.Parameters.SCENE_MODE_NIGHT.equals(val)) {
return SceneMode.NIGHT;
- } else if (val.equals(Camera.Parameters.SCENE_MODE_NIGHT_PORTRAIT)) {
+ } else if (Camera.Parameters.SCENE_MODE_NIGHT_PORTRAIT.equals(val)) {
return SceneMode.NIGHT_PORTRAIT;
- } else if (val.equals(Camera.Parameters.SCENE_MODE_PARTY)) {
+ } else if (Camera.Parameters.SCENE_MODE_PARTY.equals(val)) {
return SceneMode.PARTY;
- } else if (val.equals(Camera.Parameters.SCENE_MODE_PORTRAIT)) {
+ } else if (Camera.Parameters.SCENE_MODE_PORTRAIT.equals(val)) {
return SceneMode.PORTRAIT;
- } else if (val.equals(Camera.Parameters.SCENE_MODE_SNOW)) {
+ } else if (Camera.Parameters.SCENE_MODE_SNOW.equals(val)) {
return SceneMode.SNOW;
- } else if (val.equals(Camera.Parameters.SCENE_MODE_SPORTS)) {
+ } else if (Camera.Parameters.SCENE_MODE_SPORTS.equals(val)) {
return SceneMode.SPORTS;
- } else if (val.equals(Camera.Parameters.SCENE_MODE_STEADYPHOTO)) {
+ } else if (Camera.Parameters.SCENE_MODE_STEADYPHOTO.equals(val)) {
return SceneMode.STEADYPHOTO;
- } else if (val.equals(Camera.Parameters.SCENE_MODE_SUNSET)) {
+ } else if (Camera.Parameters.SCENE_MODE_SUNSET.equals(val)) {
return SceneMode.SUNSET;
- } else if (val.equals(Camera.Parameters.SCENE_MODE_THEATRE)) {
+ } else if (Camera.Parameters.SCENE_MODE_THEATRE.equals(val)) {
return SceneMode.THEATRE;
} else {
return null;
@@ -404,6 +433,10 @@ public class AndroidCameraCapabilities extends CameraCapabilities {
@Override
public String stringify(WhiteBalance wb) {
+ if (wb == null) {
+ return null;
+ }
+
switch (wb) {
case AUTO:
return Camera.Parameters.WHITE_BALANCE_AUTO;
@@ -427,21 +460,25 @@ public class AndroidCameraCapabilities extends CameraCapabilities {
@Override
public WhiteBalance whiteBalanceFromString(String val) {
- if (val.equals(Camera.Parameters.WHITE_BALANCE_AUTO)) {
+ if (val == null) {
+ return null;
+ }
+
+ if (Camera.Parameters.WHITE_BALANCE_AUTO.equals(val)) {
return WhiteBalance.AUTO;
- } else if (val.equals(Camera.Parameters.WHITE_BALANCE_CLOUDY_DAYLIGHT)) {
+ } else if (Camera.Parameters.WHITE_BALANCE_CLOUDY_DAYLIGHT.equals(val)) {
return WhiteBalance.CLOUDY_DAYLIGHT;
- } else if (val.equals(Camera.Parameters.WHITE_BALANCE_DAYLIGHT)) {
+ } else if (Camera.Parameters.WHITE_BALANCE_DAYLIGHT.equals(val)) {
return WhiteBalance.DAYLIGHT;
- } else if (val.equals(Camera.Parameters.WHITE_BALANCE_FLUORESCENT)) {
+ } else if (Camera.Parameters.WHITE_BALANCE_FLUORESCENT.equals(val)) {
return WhiteBalance.FLUORESCENT;
- } else if (val.equals(Camera.Parameters.WHITE_BALANCE_INCANDESCENT)) {
+ } else if (Camera.Parameters.WHITE_BALANCE_INCANDESCENT.equals(val)) {
return WhiteBalance.INCANDESCENT;
- } else if (val.equals(Camera.Parameters.WHITE_BALANCE_SHADE)) {
+ } else if (Camera.Parameters.WHITE_BALANCE_SHADE.equals(val)) {
return WhiteBalance.SHADE;
- } else if (val.equals(Camera.Parameters.WHITE_BALANCE_TWILIGHT)) {
+ } else if (Camera.Parameters.WHITE_BALANCE_TWILIGHT.equals(val)) {
return WhiteBalance.TWILIGHT;
- } else if (val.equals(Camera.Parameters.WHITE_BALANCE_WARM_FLUORESCENT)) {
+ } else if (Camera.Parameters.WHITE_BALANCE_WARM_FLUORESCENT.equals(val)) {
return WhiteBalance.WARM_FLUORESCENT;
} else {
return null;
diff --git a/camera2/portability/src/com/android/ex/camera2/portability/AndroidCameraManagerImpl.java b/camera2/portability/src/com/android/ex/camera2/portability/AndroidCameraManagerImpl.java
index 16e5b91..a352278 100644
--- a/camera2/portability/src/com/android/ex/camera2/portability/AndroidCameraManagerImpl.java
+++ b/camera2/portability/src/com/android/ex/camera2/portability/AndroidCameraManagerImpl.java
@@ -33,13 +33,11 @@ import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
import android.os.Message;
-import android.os.SystemClock;
import android.view.SurfaceHolder;
import com.android.ex.camera2.portability.debug.Log;
import java.io.IOException;
-import java.util.LinkedList;
/**
* A class to implement {@link CameraManager} of the Android camera framework.
@@ -49,15 +47,13 @@ class AndroidCameraManagerImpl implements CameraManager {
private Parameters mParameters;
private boolean mParametersIsDirty;
+ private AndroidCameraCapabilities mCapabilities;
private final CameraHandler mCameraHandler;
private final HandlerThread mCameraHandlerThread;
private final CameraStateHolder mCameraState;
private final DispatchThread mDispatchThread;
- // Used to retain a copy of Parameters for setting parameters.
- private Parameters mParamsToSet;
-
private Handler mCameraExceptionCallbackHandler;
private CameraExceptionCallback mCameraExceptionCallback =
new CameraExceptionCallback() {
@@ -168,6 +164,8 @@ class AndroidCameraManagerImpl implements CameraManager {
*/
private class CameraHandler extends HistoryHandler {
+ // Used to retain a copy of Parameters for setting parameters.
+ private Parameters mParamsToSet;
private Camera mCamera;
private int mCameraId;
@@ -268,13 +266,13 @@ class AndroidCameraManagerImpl implements CameraManager {
// Get a instance of Camera.Parameters for later use.
mParamsToSet = mCamera.getParameters();
+ mCapabilities = new AndroidCameraCapabilities(mParamsToSet);
mCameraState.setState(CameraStateHolder.CAMERA_IDLE);
if (openCallback != null) {
openCallback.onCameraOpened(
new AndroidCameraProxyImpl(cameraId, mCamera,
- new AndroidCameraCapabilities(mParamsToSet))
- );
+ mCapabilities));
}
} else {
if (openCallback != null) {
@@ -311,8 +309,8 @@ class AndroidCameraManagerImpl implements CameraManager {
mCameraState.setState(CameraStateHolder.CAMERA_IDLE);
if (cbForward != null) {
- cbForward.onCameraOpened(new AndroidCameraProxyImpl(cameraId, mCamera,
- new AndroidCameraCapabilities(mParamsToSet)));
+ cbForward.onCameraOpened(
+ new AndroidCameraProxyImpl(cameraId, mCamera, mCapabilities));
}
break;
}
@@ -420,6 +418,14 @@ class AndroidCameraManagerImpl implements CameraManager {
break;
}
+ case CameraActions.APPLY_SETTINGS: {
+ mParametersIsDirty = true;
+ CameraSettings settings = (CameraSettings) msg.obj;
+ applyToParameters(settings);
+ mCamera.setParameters(mParamsToSet);
+ break;
+ }
+
case CameraActions.SET_PARAMETERS: {
mParametersIsDirty = true;
mParamsToSet.unflatten((String) msg.obj);
@@ -493,6 +499,63 @@ class AndroidCameraManagerImpl implements CameraManager {
}
}
}
+
+ private void applyToParameters(final CameraSettings settings) {
+ final CameraCapabilities.Stringifier stringifier = mCapabilities.getStringifier();
+ Size photoSize = settings.getCurrentPhotoSize();
+ mParamsToSet.setPictureSize(photoSize.width(), photoSize.height());
+ Size previewSize = settings.getCurrentPreviewSize();
+ mParamsToSet.setPreviewSize(previewSize.width(), previewSize.height());
+ if (settings.getPreviewFrameRate() == -1) {
+ mParamsToSet.setPreviewFpsRange(settings.getPreviewFpsRangeMin(),
+ settings.getPreviewFpsRangeMax());
+ } else {
+ mParamsToSet.setPreviewFrameRate(settings.getPreviewFrameRate());
+ }
+ mParamsToSet.setJpegQuality(settings.getPhotoJpegCompressionQuality());
+ if (mCapabilities.supports(CameraCapabilities.Feature.ZOOM)) {
+ // Should use settings.getCurrentZoomRatio() instead here.
+ mParamsToSet.setZoom(settings.getCurrentZoomIndex());
+ }
+ mParamsToSet.setRotation((int) settings.getCurrentPhotoRotationDegrees());
+ mParamsToSet.setExposureCompensation(settings.getExposureCompensationIndex());
+ if (mCapabilities.supports(CameraCapabilities.Feature.AUTO_EXPOSURE_LOCK)) {
+ mParamsToSet.setAutoExposureLock(settings.isAutoExposureLocked());
+ }
+ mParamsToSet.setFocusMode(stringifier.stringify(settings.getCurrentFocusMode()));
+ if (mCapabilities.supports(CameraCapabilities.Feature.AUTO_WHITE_BALANCE_LOCK)) {
+ mParamsToSet.setAutoWhiteBalanceLock(settings.isAutoWhiteBalanceLocked());
+ }
+ if (mCapabilities.supports(CameraCapabilities.Feature.FOCUS_AREA)) {
+ mParamsToSet.setFocusAreas(settings.getFocusAreas());
+ }
+ if (mCapabilities.supports(CameraCapabilities.Feature.METERING_AREA)) {
+ mParamsToSet.setMeteringAreas(settings.getMeteringAreas());
+ }
+ if (settings.getCurrentFlashMode() != CameraCapabilities.FlashMode.NO_FLASH) {
+ mParamsToSet.setFlashMode(stringifier.stringify(settings.getCurrentFlashMode()));
+ }
+ if (settings.getCurrentSceneMode() != CameraCapabilities.SceneMode.NO_SCENE_MODE) {
+ mParamsToSet.setSceneMode(stringifier.stringify(settings.getCurrentSceneMode()));
+ }
+
+ CameraSettings.GpsData gpsData = settings.getGpsData();
+ if (gpsData == null) {
+ mParamsToSet.removeGpsData();
+ } else {
+ mParamsToSet.setGpsTimestamp(gpsData.timeStamp);
+ if (gpsData.processingMethod != null) {
+ // It's a hack since we always use GPS time stamp but does
+ // not use other fields sometimes. Setting processing
+ // method to null means the other fields should not be used.
+ mParamsToSet.setGpsAltitude(gpsData.altitude);
+ mParamsToSet.setGpsLatitude(gpsData.latitude);
+ mParamsToSet.setGpsLongitude(gpsData.longitude);
+ mParamsToSet.setGpsProcessingMethod(gpsData.processingMethod);
+ }
+ }
+
+ }
}
@Override
@@ -802,12 +865,13 @@ class AndroidCameraManagerImpl implements CameraManager {
mCameraState.waitForStates(
CameraStateHolder.CAMERA_IDLE | CameraStateHolder.CAMERA_UNLOCKED);
mCameraHandler.requestTakePicture(ShutterCallbackForward
- .getNewInstance(handler, AndroidCameraProxyImpl.this, shutter),
+ .getNewInstance(handler, AndroidCameraProxyImpl.this, shutter),
PictureCallbackForward
.getNewInstance(handler, AndroidCameraProxyImpl.this, raw),
PictureCallbackForward
.getNewInstance(handler, AndroidCameraProxyImpl.this, post),
- jpegCallback);
+ jpegCallback
+ );
}
});
}
@@ -913,7 +977,35 @@ class AndroidCameraManagerImpl implements CameraManager {
}
@Override
- public void refreshParameters() {
+ public CameraSettings getSettings() {
+ return new AndroidCameraSettings(mCapabilities, getParameters());
+ }
+
+ @Override
+ public boolean applySettings(final CameraSettings settings) {
+ if (settings == null) {
+ Log.v(TAG, "null parameters in applySettings()");
+ return false;
+ }
+ if (!mCapabilities.supports(settings)) {
+ return false;
+ }
+
+ final CameraSettings copyOfSettings = new CameraSettings(settings);
+ mDispatchThread.runJob(new Runnable() {
+ @Override
+ public void run() {
+ mCameraState.waitForStates(
+ CameraStateHolder.CAMERA_IDLE | CameraStateHolder.CAMERA_UNLOCKED);
+ mCameraHandler.obtainMessage(CameraActions.APPLY_SETTINGS, copyOfSettings)
+ .sendToTarget();
+ }
+ });
+ return true;
+ }
+
+ @Override
+ public void refreshSettings() {
mDispatchThread.runJob(new Runnable() {
@Override
public void run() {
diff --git a/camera2/portability/src/com/android/ex/camera2/portability/AndroidCameraSettings.java b/camera2/portability/src/com/android/ex/camera2/portability/AndroidCameraSettings.java
new file mode 100644
index 0000000..3869188
--- /dev/null
+++ b/camera2/portability/src/com/android/ex/camera2/portability/AndroidCameraSettings.java
@@ -0,0 +1,47 @@
+package com.android.ex.camera2.portability;
+
+import android.hardware.Camera;
+
+/**
+ * Created by shkong on 6/2/14.
+ */
+public class AndroidCameraSettings extends CameraSettings {
+
+ public AndroidCameraSettings(CameraCapabilities capabilities, Camera.Parameters params) {
+ CameraCapabilities.Stringifier stringifier = capabilities.getStringifier();
+
+ // Preview
+ Camera.Size paramPreviewSize = params.getPreviewSize();
+ setPreviewSize(new Size(paramPreviewSize.width, paramPreviewSize.height));
+ setPreviewFrameRate(params.getPreviewFrameRate());
+ int[] previewFpsRange = new int[2];
+ params.getPreviewFpsRange(previewFpsRange);
+ setPreviewFpsRange(previewFpsRange[Camera.Parameters.PREVIEW_FPS_MIN_INDEX],
+ previewFpsRange[Camera.Parameters.PREVIEW_FPS_MAX_INDEX]);
+
+
+ // Capture: Focus, flash, zoom, exposure, scene mode.
+ if (capabilities.supports(CameraCapabilities.Feature.ZOOM)) {
+ setZoomRatio(params.getZoomRatios().get(params.getZoom()) / 100f);
+ setZoomIndex(params.getZoom());
+ } else {
+ setZoomRatio(1.0f);
+ setZoomIndex(0);
+ }
+ setExposureCompensationIndex(params.getExposureCompensation());
+ setFlashMode(stringifier.flashModeFromString(params.getFlashMode()));
+ setFocusMode(stringifier.focusModeFromString(params.getFocusMode()));
+ setSceneMode(stringifier.sceneModeFromString(params.getSceneMode()));
+
+ // Video capture.
+ if (capabilities.supports(CameraCapabilities.Feature.VIDEO_STABILIZATION)) {
+ setVideoStabilization(isVideoStabilizationEnabled());
+ }
+
+ // Output: Photo size, compression quality, rotation.
+ setPhotoRotationDegrees(0f);
+ setPhotoJpegCompressionQuality(params.getJpegQuality());
+ Camera.Size paramPictureSize = params.getPictureSize();
+ setPhotoSize(new Size(paramPictureSize.width, paramPictureSize.height));
+ }
+}
diff --git a/camera2/portability/src/com/android/ex/camera2/portability/CameraActions.java b/camera2/portability/src/com/android/ex/camera2/portability/CameraActions.java
index 072d6ce..aae122b 100644
--- a/camera2/portability/src/com/android/ex/camera2/portability/CameraActions.java
+++ b/camera2/portability/src/com/android/ex/camera2/portability/CameraActions.java
@@ -36,6 +36,7 @@ class CameraActions {
public static final int SET_PARAMETERS = 201;
public static final int GET_PARAMETERS = 202;
public static final int REFRESH_PARAMETERS = 203;
+ public static final int APPLY_SETTINGS = 204;
// Focus, Zoom
public static final int AUTO_FOCUS = 301;
public static final int CANCEL_AUTO_FOCUS = 302;
diff --git a/camera2/portability/src/com/android/ex/camera2/portability/CameraCapabilities.java b/camera2/portability/src/com/android/ex/camera2/portability/CameraCapabilities.java
index bcc97e5..7857425 100644
--- a/camera2/portability/src/com/android/ex/camera2/portability/CameraCapabilities.java
+++ b/camera2/portability/src/com/android/ex/camera2/portability/CameraCapabilities.java
@@ -16,8 +16,6 @@
package com.android.ex.camera2.portability;
-import android.graphics.Point;
-
import com.android.ex.camera2.portability.debug.Log;
import java.util.ArrayList;
@@ -27,31 +25,46 @@ import java.util.List;
import java.util.Set;
import java.util.TreeSet;
+/**
+ * This class holds all the static information of a camera's capabilities.
+ * <p>
+ * The design of this class is thread-safe and can be passed around regardless
+ * of which thread using it.
+ * </p>
+ */
public class CameraCapabilities {
- private static Log.Tag TAG = new Log.Tag("CameraCapabilities");
+ private static Log.Tag TAG = new Log.Tag("CamCapabilities");
+
+ /* All internal states are declared final and should be thread-safe. */
protected final ArrayList<int[]> mSupportedPreviewFpsRange = new ArrayList<int[]>();
- protected final ArrayList<Point> mSupportedPreviewSizes = new ArrayList<Point>();
+ protected final ArrayList<Size> mSupportedPreviewSizes = new ArrayList<Size>();
protected final TreeSet<Integer> mSupportedPreviewFormats = new TreeSet<Integer>();
- protected final ArrayList<Point> mSupportedVideoSizes = new ArrayList<Point>();
- protected final ArrayList<Point> mSupportedPictureSizes = new ArrayList<Point>();
- protected final TreeSet<Integer> mSupportedPictureFormats = new TreeSet<Integer>();
+ protected final ArrayList<Size> mSupportedVideoSizes = new ArrayList<Size>();
+ protected final ArrayList<Size> mSupportedPhotoSizes = new ArrayList<Size>();
+ protected final TreeSet<Integer> mSupportedPhotoFormats = new TreeSet<Integer>();
protected final EnumSet<SceneMode> mSupportedSceneModes = EnumSet.noneOf(SceneMode.class);
protected final EnumSet<FlashMode> mSupportedFlashModes = EnumSet.noneOf(FlashMode.class);
protected final EnumSet<FocusMode> mSupportedFocusModes = EnumSet.noneOf(FocusMode.class);
protected final EnumSet<WhiteBalance> mSupportedWhiteBalances =
EnumSet.noneOf(WhiteBalance.class);
protected final EnumSet<Feature> mSupportedFeatures = EnumSet.noneOf(Feature.class);
+ protected Size mPreferredPreviewSizeForVideo;
protected int mMinExposureCompensation;
protected int mMaxExposureCompensation;
protected float mExposureCompensationStep;
protected int mMaxNumOfFacesSupported;
protected int mMaxNumOfFocusAreas;
protected int mMaxNumOfMeteringArea;
+ protected int mMaxZoomRatio;
private final Stringifier mStringifier;
+ protected final ArrayList<Integer> mZoomRatioList = new ArrayList<Integer>();
+ protected int mMaxZoomIndex;
- // Focus modes.
+ /**
+ * Focus modes.
+ */
public enum FocusMode {
/**
* Continuous auto focus mode intended for taking pictures.
@@ -90,9 +103,15 @@ public class CameraCapabilities {
MACRO,
}
- // Flash modes.
+ /**
+ * Flash modes.
+ */
public enum FlashMode {
/**
+ * No flash.
+ */
+ NO_FLASH,
+ /**
* Flash will be fired automatically when required.
* @see {@link android.hardware.Camera.Parameters#FLASH_MODE_OFF}.
*/
@@ -119,8 +138,15 @@ public class CameraCapabilities {
RED_EYE,
}
+ /**
+ * Scene modes.
+ */
public enum SceneMode {
/**
+ * No supported scene mode.
+ */
+ NO_SCENE_MODE,
+ /**
* Scene mode is off.
* @see {@link android.hardware.Camera.Parameters#SCENE_MODE_AUTO}.
*/
@@ -207,7 +233,9 @@ public class CameraCapabilities {
THEATRE,
}
- // White balances.
+ /**
+ * White blances.
+ */
public enum WhiteBalance {
/**
* @see {@link android.hardware.Camera.Parameters#WHITE_BALANCE_AUTO}.
@@ -243,6 +271,9 @@ public class CameraCapabilities {
WARM_FLUORESCENT,
}
+ /**
+ * Features.
+ */
public enum Feature {
/**
* Support zoom-related methods.
@@ -268,6 +299,10 @@ public class CameraCapabilities {
* Support for automatic white balance lock.
*/
AUTO_WHITE_BALANCE_LOCK,
+ /**
+ * Support for video stabilization.
+ */
+ VIDEO_STABILIZATION,
}
/**
@@ -307,7 +342,8 @@ public class CameraCapabilities {
* abstract representation.
*
* @param val The string representation.
- * @return The flash mode represented by the input string.
+ * @return The flash mode represented by the input string. Can be
+ * {@code null}.
*/
FlashMode flashModeFromString(String val);
@@ -349,11 +385,11 @@ public class CameraCapabilities {
}
/**
- * constructor.
- * @param mStringifier The stringifier used by this instance.
+ * Constructor.
+ * @param stringifier The API-specific stringifier for this instance.
*/
- CameraCapabilities(Stringifier mStringifier) {
- this.mStringifier = mStringifier;
+ CameraCapabilities(Stringifier stringifier) {
+ mStringifier = stringifier;
}
/**
@@ -365,26 +401,29 @@ public class CameraCapabilities {
mSupportedPreviewSizes.addAll(src.mSupportedPreviewSizes);
mSupportedPreviewFormats.addAll(src.mSupportedPreviewFormats);
mSupportedVideoSizes.addAll(src.mSupportedVideoSizes);
- mSupportedPictureSizes.addAll(src.mSupportedPictureSizes);
- mSupportedPictureFormats.addAll(src.mSupportedPictureFormats);
+ mSupportedPhotoSizes.addAll(src.mSupportedPhotoSizes);
+ mSupportedPhotoFormats.addAll(src.mSupportedPhotoFormats);
mSupportedSceneModes.addAll(src.mSupportedSceneModes);
mSupportedFlashModes.addAll(src.mSupportedFlashModes);
mSupportedFocusModes.addAll(src.mSupportedFocusModes);
mSupportedWhiteBalances.addAll(src.mSupportedWhiteBalances);
mSupportedFeatures.addAll(src.mSupportedFeatures);
+ mPreferredPreviewSizeForVideo = src.mPreferredPreviewSizeForVideo;
mMaxExposureCompensation = src.mMaxExposureCompensation;
mMinExposureCompensation = src.mMinExposureCompensation;
mExposureCompensationStep = src.mExposureCompensationStep;
mMaxNumOfFacesSupported = src.mMaxNumOfFacesSupported;
mMaxNumOfFocusAreas = src.mMaxNumOfFocusAreas;
+ mMaxNumOfMeteringArea = src.mMaxNumOfMeteringArea;
+ mMaxZoomRatio = src.mMaxZoomRatio;
mStringifier = src.mStringifier;
}
/**
* @return the supported picture formats. See {@link android.graphics.ImageFormat}.
*/
- public Set<Integer> getSupportedPictureFormats() {
- return new TreeSet<Integer>(mSupportedPictureFormats);
+ public Set<Integer> getSupportedPhotoFormats() {
+ return new TreeSet<Integer>(mSupportedPhotoFormats);
}
/**
@@ -398,8 +437,8 @@ public class CameraCapabilities {
/**
* Gets the supported picture sizes.
*/
- public List<Point> getSupportedPictureSizes() {
- return new ArrayList<Point>(mSupportedPictureSizes);
+ public List<Size> getSupportedPhotoSizes() {
+ return new ArrayList<Size>(mSupportedPhotoSizes);
}
@@ -413,21 +452,23 @@ public class CameraCapabilities {
}
/**
- * @return The supported preview sizes. The width and height are stored in
- * Point.x and Point.y respectively and the list is sorted by width then
+ * @return The supported preview sizes. The list is sorted by width then
* height in a descending order.
*/
- public final List<Point> getSupportedPreviewSizes() {
- return new ArrayList<Point>(mSupportedPreviewSizes);
+ public final List<Size> getSupportedPreviewSizes() {
+ return new ArrayList<Size>(mSupportedPreviewSizes);
+ }
+
+ public final Size getPreferredPreviewSizeForVideo() {
+ return new Size(mPreferredPreviewSizeForVideo);
}
/**
* @return The supported video frame sizes that can be used by MediaRecorder.
- * The width and height are stored in Point.x and Point.y respectively and
- * the list is sorted by width then height in a descending order.
+ * The list is sorted by width then height in a descending order.
*/
- public final List<Point> getSupportedVideoSizes() {
- return new ArrayList<Point>(mSupportedVideoSizes);
+ public final List<Size> getSupportedVideoSizes() {
+ return new ArrayList<Size>(mSupportedVideoSizes);
}
/**
@@ -444,6 +485,15 @@ public class CameraCapabilities {
return (scene != null && mSupportedSceneModes.contains(scene));
}
+ public boolean supports(final CameraSettings settings) {
+ if (zoomCheck(settings) && exposureCheck(settings) && focusCheck(settings) &&
+ flashCheck(settings) && photoSizeCheck(settings) && previewSizeCheck(settings) &&
+ videoStabilizationCheck(settings)) {
+ return true;
+ }
+ return false;
+ }
+
/**
* @return The supported flash modes.
*/
@@ -495,6 +545,24 @@ public class CameraCapabilities {
}
/**
+ * @return The maximal supported zoom ratio.
+ */
+ public float getMaxZoomRatio() {
+ return mMaxZoomRatio;
+ }
+
+ // We'll replace these old style methods with new ones.
+ @Deprecated
+ public int getMaxZoomIndex() {
+ return mMaxZoomIndex;
+ }
+
+ @Deprecated
+ public List<Integer> getZoomRatioList() {
+ return new ArrayList<Integer>(mZoomRatioList);
+ }
+
+ /**
* @return The min exposure compensation index. The EV is the compensation
* index multiplied by the step value. If unsupported, both this method and
* {@link #getMaxExposureCompensation()} return 0.
@@ -534,4 +602,80 @@ public class CameraCapabilities {
public Stringifier getStringifier() {
return mStringifier;
}
+
+ private boolean zoomCheck(final CameraSettings settings) {
+ final float ratio = settings.getCurrentZoomRatio();
+ final int index = settings.getCurrentZoomIndex();
+ if (!supports(Feature.ZOOM)) {
+ if (ratio != 1.0f || index != 0) {
+ Log.v(TAG, "Zoom is not supported");
+ return false;
+ }
+ } else {
+ if (settings.getCurrentZoomRatio() > getMaxZoomRatio() ||
+ index > getMaxZoomIndex()) {
+ Log.v(TAG, "Zoom ratio is not supported: ratio = " +
+ settings.getCurrentZoomRatio() + ", index = " + index);
+ return false;
+ }
+ }
+ return true;
+ }
+
+ private boolean exposureCheck(final CameraSettings settings) {
+ final int index = settings.getExposureCompensationIndex();
+ if (index > getMaxExposureCompensation() || index < getMinExposureCompensation()) {
+ Log.v(TAG, "Exposure compensation index is not supported. Min = " +
+ getMinExposureCompensation() + ", max = " + getMaxExposureCompensation() + "," +
+ " setting = " + index);
+ return false;
+ }
+ return true;
+ }
+
+ private boolean focusCheck(final CameraSettings settings) {
+ FocusMode focusMode = settings.getCurrentFocusMode();
+ if (!supports(focusMode)) {
+ Log.v(TAG,
+ "Focus mode not supported:" + (focusMode != null ? focusMode.name() : "null"));
+ return false;
+ }
+ return true;
+ }
+
+ private boolean flashCheck(final CameraSettings settings) {
+ FlashMode flashMode = settings.getCurrentFlashMode();
+ if (!supports(flashMode)) {
+ Log.v(TAG,
+ "Flash mode not supported:" + (flashMode != null ? flashMode.name() : "null"));
+ return false;
+ }
+ return true;
+ }
+
+ private boolean photoSizeCheck(final CameraSettings settings) {
+ Size photoSize = settings.getCurrentPhotoSize();
+ if (mSupportedPhotoSizes.contains(photoSize)) {
+ return true;
+ }
+ Log.v(TAG, "Unsupported photo size:" + photoSize);
+ return false;
+ }
+
+ private boolean previewSizeCheck(final CameraSettings settings) {
+ final Size previewSize = settings.getCurrentPreviewSize();
+ if (mSupportedPreviewSizes.contains(previewSize)) {
+ return true;
+ }
+ Log.v(TAG, "Unsupported preview size:" + previewSize);
+ return false;
+ }
+
+ private boolean videoStabilizationCheck(final CameraSettings settings) {
+ if (!settings.isVideoStabilizationEnabled() || supports(Feature.VIDEO_STABILIZATION)) {
+ return true;
+ }
+ Log.v(TAG, "Video stabilization is not supported");
+ return false;
+ }
}
diff --git a/camera2/portability/src/com/android/ex/camera2/portability/CameraManager.java b/camera2/portability/src/com/android/ex/camera2/portability/CameraManager.java
index 925d501..c0484ab 100644
--- a/camera2/portability/src/com/android/ex/camera2/portability/CameraManager.java
+++ b/camera2/portability/src/com/android/ex/camera2/portability/CameraManager.java
@@ -38,7 +38,6 @@ import android.view.SurfaceHolder;
* TODO: provide callback interfaces for:
* {@code android.hardware.Camera.ErrorCallback},
* {@code android.hardware.Camera.OnZoomChangeListener}, and
- * {@code android.hardware.Camera.Parameters}.
*/
public interface CameraManager {
public static final long CAMERA_OPERATION_TIMEOUT_MS = 2500;
@@ -537,6 +536,7 @@ public interface CameraManager {
*
* @param params The camera parameters to use.
*/
+ @Deprecated
public void setParameters(Camera.Parameters params);
/**
@@ -545,13 +545,30 @@ public interface CameraManager {
* the parameters. If the parameters are already cached, it returns
* immediately.
*/
+ @Deprecated
public Camera.Parameters getParameters();
/**
+ * Gets the current camera settings synchronously.
+ * <p>This method is synchronous since the caller has to wait for the
+ * camera to return the parameters. If the parameters are already
+ * cached, it returns immediately.</p>
+ */
+ public CameraSettings getSettings();
+
+ /**
+ * Applies the settings to the camera device.
+ *
+ * @param settings The settings to use on the device.
+ * @return Whether the settings can be applied.
+ */
+ public boolean applySettings(CameraSettings settings);
+
+ /**
* Forces {@code CameraProxy} to update the cached version of the camera
- * parameters regardless of the dirty bit.
+ * settings regardless of the dirty bit.
*/
- public void refreshParameters();
+ public void refreshSettings();
/**
* Enables/Disables the camera shutter sound.
diff --git a/camera2/portability/src/com/android/ex/camera2/portability/CameraSettings.java b/camera2/portability/src/com/android/ex/camera2/portability/CameraSettings.java
new file mode 100644
index 0000000..9ddac4e
--- /dev/null
+++ b/camera2/portability/src/com/android/ex/camera2/portability/CameraSettings.java
@@ -0,0 +1,377 @@
+package com.android.ex.camera2.portability;
+
+import android.hardware.Camera;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
+
+/**
+ * A class which stores the camera settings.
+ */
+public class CameraSettings {
+
+ protected final Map<String, String> mGeneralSetting = new TreeMap<>();
+ protected final List<Camera.Area> mMeteringAreas = new ArrayList<>();
+ protected final List<Camera.Area> mFocusAreas = new ArrayList<>();
+ protected int mPreviewFpsRangeMin;
+ protected int mPreviewFpsRangeMax;
+ protected int mPreviewFrameRate;
+ protected Size mCurrentPreviewSize;
+ protected Size mCurrentPhotoSize;
+ protected int mJpegCompressQuality;
+ protected float mCurrentZoomRatio;
+ protected int mCurrentZoomIndex;
+ protected float mPhotoRotationDegrees;
+ protected int mExposureCompensationIndex;
+ protected CameraCapabilities.FlashMode mCurrentFlashMode;
+ protected CameraCapabilities.FocusMode mCurrentFocusMode;
+ protected CameraCapabilities.SceneMode mCurrentSceneMode;
+ protected CameraCapabilities.WhiteBalance mWhiteBalance;
+ protected boolean mVideoStabilizationEnabled;
+ protected boolean mAutoExposureLocked;
+ protected boolean mAutoWhiteBalanceLocked;
+ protected GpsData mGpsData;
+
+ /**
+ * An immutable class storing GPS related information.
+ * <p>It's a hack since we always use GPS time stamp but does not use other
+ * fields sometimes. Setting processing method to null means the other
+ * fields should not be used.</p>
+ */
+ public static class GpsData {
+ public final double latitude;
+ public final double longitude;
+ public final double altitude;
+ public final long timeStamp;
+ public final String processingMethod;
+
+ /** Constructor. */
+ public GpsData(double latitude, double longitude, double altitude, long timeStamp,
+ String processingMethod) {
+ this.latitude = latitude;
+ this.longitude = longitude;
+ this.altitude = altitude;
+ this.timeStamp = timeStamp;
+ this.processingMethod = processingMethod;
+ }
+
+ /** Copy constructor. */
+ public GpsData(GpsData src) {
+ this.latitude = src.latitude;
+ this.longitude = src.longitude;
+ this.altitude = src.altitude;
+ this.timeStamp = src.timeStamp;
+ this.processingMethod = src.processingMethod;
+ }
+ }
+
+ protected CameraSettings() {
+ }
+
+ /**
+ * Copy constructor.
+ *
+ * @param src The source settings.
+ * @return The copy of the source.
+ */
+ public CameraSettings(CameraSettings src) {
+ mGeneralSetting.putAll(src.mGeneralSetting);
+ mMeteringAreas.addAll(src.mMeteringAreas);
+ mFocusAreas.addAll(src.mFocusAreas);
+ mPreviewFpsRangeMin = src.mPreviewFpsRangeMin;
+ mPreviewFpsRangeMax = src.mPreviewFpsRangeMax;
+ mPreviewFrameRate = src.mPreviewFrameRate;
+ mCurrentPreviewSize =
+ (src.mCurrentPreviewSize == null ? null : new Size(src.mCurrentPreviewSize));
+ mCurrentPhotoSize =
+ (src.mCurrentPhotoSize == null ? null : new Size(src.mCurrentPhotoSize));
+ mJpegCompressQuality = src.mJpegCompressQuality;
+ mCurrentZoomRatio = src.mCurrentZoomRatio;
+ mCurrentZoomIndex = src.mCurrentZoomIndex;
+ mPhotoRotationDegrees = src.mPhotoRotationDegrees;
+ mExposureCompensationIndex = src.mExposureCompensationIndex;
+ mCurrentFlashMode = src.mCurrentFlashMode;
+ mCurrentFocusMode = src.mCurrentFocusMode;
+ mCurrentSceneMode = src.mCurrentSceneMode;
+ mWhiteBalance = src.mWhiteBalance;
+ mVideoStabilizationEnabled = src.mVideoStabilizationEnabled;
+ mAutoExposureLocked = src.mAutoExposureLocked;
+ mAutoWhiteBalanceLocked = src.mAutoWhiteBalanceLocked;
+ mGpsData = src.mGpsData;
+ }
+
+ /** General setting **/
+ @Deprecated
+ public void setSetting(String key, String value) {
+ mGeneralSetting.put(key, value);
+ }
+
+ /** Preview **/
+
+ /**
+ * Sets the preview FPS range. This call will invalidate prior calls to
+ * {@link #setPreviewFrameRate(int)}.
+ *
+ * @param min The min FPS.
+ * @param max The max FPS.
+ */
+ public void setPreviewFpsRange(int min, int max) {
+ if (min > max) {
+ int temp = max;
+ max = min;
+ min = temp;
+ }
+ mPreviewFpsRangeMax = max;
+ mPreviewFpsRangeMin = min;
+ mPreviewFrameRate = -1;
+ }
+
+ /**
+ * @return The min of the preview FPS range.
+ */
+ public int getPreviewFpsRangeMin() {
+ return mPreviewFpsRangeMin;
+ }
+
+ /**
+ * @return The max of the preview FPS range.
+ */
+ public int getPreviewFpsRangeMax() {
+ return mPreviewFpsRangeMax;
+ }
+
+ /**
+ * Sets the preview FPS. This call will invalidate prior calls to
+ * {@link #setPreviewFpsRange(int, int)}.
+ *
+ * @param frameRate The target frame rate.
+ */
+ public void setPreviewFrameRate(int frameRate) {
+ if (frameRate > 0) {
+ mPreviewFrameRate = frameRate;
+ mPreviewFpsRangeMax = frameRate;
+ mPreviewFpsRangeMin = frameRate;
+ }
+ }
+
+ public int getPreviewFrameRate() {
+ return mPreviewFrameRate;
+ }
+
+ /**
+ * @return The current preview size.
+ */
+ public Size getCurrentPreviewSize() {
+ return new Size(mCurrentPreviewSize);
+ }
+
+ /**
+ * @param previewSize The size to use for preview.
+ */
+ public void setPreviewSize(Size previewSize) {
+ mCurrentPreviewSize = new Size(previewSize);
+ }
+
+ /** Picture **/
+
+ /**
+ * @return The current photo size.
+ */
+ public Size getCurrentPhotoSize() {
+ return new Size(mCurrentPhotoSize);
+ }
+
+ /**
+ * Sets the size for the photo.
+ *
+ * @param photoSize The photo size.
+ */
+ public void setPhotoSize(Size photoSize) {
+ mCurrentPhotoSize = new Size(photoSize);
+ }
+
+ /**
+ * Sets the JPEG compression quality.
+ *
+ * @param quality The quality for JPEG.
+ */
+ public void setPhotoJpegCompressionQuality(int quality) {
+ mJpegCompressQuality = quality;
+ }
+
+ public int getPhotoJpegCompressionQuality() {
+ return mJpegCompressQuality;
+ }
+
+ /** Zoom **/
+
+ /**
+ * @return The current zoom ratio. The min is 1.0f.
+ */
+ public float getCurrentZoomRatio() {
+ return mCurrentZoomRatio;
+ }
+
+ /**
+ * Sets the zoom ratio.
+ * @param ratio The new zoom ratio. Should be in the range between 1.0 to
+ * the value returned from {@link
+ * com.android.camera.cameradevice.CameraCapabilities#getMaxZoomRatio()}.
+ * @throws java.lang.UnsupportedOperationException if the ratio is not
+ * supported.
+ */
+ public void setZoomRatio(float ratio) {
+ mCurrentZoomRatio = ratio;
+ }
+
+ @Deprecated
+ public int getCurrentZoomIndex() {
+ return mCurrentZoomIndex;
+ }
+
+ @Deprecated
+ public void setZoomIndex(int index) {
+ mCurrentZoomIndex = index;
+ }
+
+ /** Transformation **/
+
+ public void setPhotoRotationDegrees(float photoRotationDegrees) {
+ mPhotoRotationDegrees = photoRotationDegrees;
+ }
+
+ public float getCurrentPhotoRotationDegrees() {
+ return mPhotoRotationDegrees;
+ }
+
+ /** Exposure **/
+
+ public void setExposureCompensationIndex(int index) {
+ mExposureCompensationIndex = index;
+ }
+
+ public int getExposureCompensationIndex() {
+ return mExposureCompensationIndex;
+ }
+
+ public void setAutoExposureLock(boolean locked) {
+ mAutoExposureLocked = locked;
+ }
+
+ public boolean isAutoExposureLocked() {
+ return mAutoExposureLocked;
+ }
+
+ public void setMeteringAreas(List<Camera.Area> areas) {
+ mMeteringAreas.clear();
+ if (areas != null) {
+ mMeteringAreas.addAll(areas);
+ }
+ }
+
+ public List<Camera.Area> getMeteringAreas() {
+ return new ArrayList<Camera.Area>(mMeteringAreas);
+ }
+
+ /** Flash **/
+
+ public CameraCapabilities.FlashMode getCurrentFlashMode() {
+ return mCurrentFlashMode;
+ }
+
+ public void setFlashMode(CameraCapabilities.FlashMode flashMode) {
+ mCurrentFlashMode = flashMode;
+ }
+
+ /** Focus **/
+
+ /**
+ * Sets the focus mode.
+ * @param focusMode The focus mode to use.
+ */
+ public void setFocusMode(CameraCapabilities.FocusMode focusMode) {
+ mCurrentFocusMode = focusMode;
+ }
+
+ /**
+ * @return The current focus mode.
+ */
+ public CameraCapabilities.FocusMode getCurrentFocusMode() {
+ return mCurrentFocusMode;
+ }
+
+ /**
+ * @param areas The areas to focus.
+ */
+ public void setFocusAreas(List<Camera.Area> areas) {
+ mFocusAreas.clear();
+ if (areas != null) {
+ mFocusAreas.addAll(areas);
+ }
+ }
+
+ public List<Camera.Area> getFocusAreas() {
+ return new ArrayList<Camera.Area>(mFocusAreas);
+ }
+
+ /** White balance **/
+
+ public void setWhiteBalance(CameraCapabilities.WhiteBalance whiteBalance) {
+ mWhiteBalance = whiteBalance;
+ }
+
+ public CameraCapabilities.WhiteBalance getWhiteBalance() {
+ return mWhiteBalance;
+ }
+
+ public void setAutoWhiteBalanceLock(boolean locked) {
+ mAutoWhiteBalanceLocked = locked;
+ }
+
+ public boolean isAutoWhiteBalanceLocked() {
+ return mAutoWhiteBalanceLocked;
+ }
+
+ /** Scene mode **/
+
+ /**
+ * @return The current scene mode.
+ */
+ public CameraCapabilities.SceneMode getCurrentSceneMode() {
+ return mCurrentSceneMode;
+ }
+
+ /**
+ * Sets the scene mode for capturing.
+ *
+ * @param sceneMode The scene mode to use.
+ * @throws java.lang.UnsupportedOperationException if it's not supported.
+ */
+ public void setSceneMode(CameraCapabilities.SceneMode sceneMode) {
+ mCurrentSceneMode = sceneMode;
+ }
+
+ /** Other Features **/
+
+ public void setVideoStabilization(boolean enabled) {
+ mVideoStabilizationEnabled = enabled;
+ }
+
+ public boolean isVideoStabilizationEnabled() {
+ return mVideoStabilizationEnabled;
+ }
+
+ public void setGpsData(GpsData data) {
+ mGpsData = new GpsData(data);
+ }
+
+ public GpsData getGpsData() {
+ return (mGpsData == null ? null : new GpsData(mGpsData));
+ }
+
+ public void clearGpsData() {
+ mGpsData = null;
+ }
+}
diff --git a/camera2/portability/src/com/android/ex/camera2/portability/Size.java b/camera2/portability/src/com/android/ex/camera2/portability/Size.java
new file mode 100644
index 0000000..9ae21aa
--- /dev/null
+++ b/camera2/portability/src/com/android/ex/camera2/portability/Size.java
@@ -0,0 +1,151 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ex.camera2.portability;
+
+import android.graphics.Point;
+import android.hardware.Camera;
+import android.text.TextUtils;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * An immutable simple size container.
+ */
+public class Size {
+ public static final String DELIMITER = ",";
+
+ /**
+ * An helper method to build a list of this class from a list of
+ * {@link android.hardware.Camera.Size}.
+ *
+ * @param cameraSizes Source.
+ * @return The built list.
+ */
+ public static List<Size> buildListFromCameraSizes(List<Camera.Size> cameraSizes) {
+ ArrayList<Size> list = new ArrayList<Size>(cameraSizes.size());
+ for (Camera.Size cameraSize : cameraSizes) {
+ list.add(new Size(cameraSize));
+ }
+ return list;
+ }
+
+ /**
+ * Encode List of this class as comma-separated list of integers.
+ *
+ * @param sizes List of this class to encode.
+ * @return encoded string.
+ */
+ public static String listToString(List<Size> sizes) {
+ ArrayList<Integer> flatSizes = new ArrayList<>();
+ for (Size s : sizes) {
+ flatSizes.add(s.width());
+ flatSizes.add(s.height());
+ }
+ return TextUtils.join(DELIMITER, flatSizes);
+ }
+
+ /**
+ * Decode comma-separated even-length list of integers into a List of this class.
+ *
+ * @param encodedSizes encoded string.
+ * @return List of this class.
+ */
+ public static List<Size> stringToList(String encodedSizes) {
+ String[] flatSizes = TextUtils.split(encodedSizes, DELIMITER);
+ ArrayList<Size> list = new ArrayList<>();
+ for (int i = 0; i < flatSizes.length; i += 2) {
+ int width = Integer.parseInt(flatSizes[i]);
+ int height = Integer.parseInt(flatSizes[i + 1]);
+ list.add(new Size(width,height));
+ }
+ return list;
+ }
+
+ private final Point val;
+
+ /**
+ * Constructor.
+ */
+ public Size(int width, int height) {
+ val = new Point(width, height);
+ }
+
+ /**
+ * Copy constructor.
+ */
+ public Size(Size other) {
+ if (other == null) {
+ val = new Point(0, 0);
+ } else {
+ val = new Point(other.width(), other.height());
+ }
+ }
+
+ /**
+ * Constructor from a source {@link android.hardware.Camera.Size}.
+ *
+ * @param other The source size.
+ */
+ public Size(Camera.Size other) {
+ if (other == null) {
+ val = new Point(0, 0);
+ } else {
+ val = new Point(other.width, other.height);
+ }
+ }
+
+ /**
+ * Constructor from a source {@link android.graphics.Point}.
+ *
+ * @param p The source size.
+ */
+ public Size(Point p) {
+ if (p == null) {
+ val = new Point(0, 0);
+ } else {
+ val = new Point(p);
+ }
+ }
+
+ public int width() {
+ return val.x;
+ }
+
+ public int height() {
+ return val.y;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (o instanceof Size) {
+ Size other = (Size) o;
+ return val.equals(other.val);
+ }
+ return false;
+ }
+
+ @Override
+ public int hashCode() {
+ return val.hashCode();
+ }
+
+ @Override
+ public String toString() {
+ return "Size: (" + this.width() + " x " + this.height() + ")";
+ }
+}