diff options
author | Angus Kong <shkong@google.com> | 2014-06-10 16:07:45 -0700 |
---|---|---|
committer | Ed Heyl <edheyl@google.com> | 2014-06-18 10:24:46 -0700 |
commit | 8097973089420749dcd1ab4974a629c2466b31cc (patch) | |
tree | dede361c4237dde7ff9ab10511afac5cf2cd5ff1 /camera2/portability/src/com/android/ex/camera2 | |
parent | cef46862d6937bc98bf1a6b087c5daa22b5239f3 (diff) | |
download | android_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')
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() + ")"; + } +} |