Switch from stepwise index-based zoom to a ratio-based scale
This brings the app up to date with the removal of the deprecated zoom methods
in the portability layer's CameraSettings class.
Bug: 17016658
Change-Id: Icb9f773188f7481d9af991d71feaff86379f5525
diff --git a/src/com/android/camera/CaptureModuleUI.java b/src/com/android/camera/CaptureModuleUI.java
index d00e7f7..bbb7c60 100644
--- a/src/com/android/camera/CaptureModuleUI.java
+++ b/src/com/android/camera/CaptureModuleUI.java
@@ -70,9 +70,8 @@
/** Set up listener to receive zoom changes from View and send to module. */
private final OnZoomChangedListener mZoomChancedListener = new OnZoomChangedListener() {
@Override
- public void onZoomValueChanged(int index) {
- float zoomValue = ((float) PreviewOverlay.ZOOM_MIN_FACTOR + (float) index) / 100;
- mModule.setZoom(zoomValue);
+ public void onZoomValueChanged(float ratio) {
+ mModule.setZoom(ratio);
}
@Override
diff --git a/src/com/android/camera/PhotoController.java b/src/com/android/camera/PhotoController.java
index d1e045a..d95a0fc 100644
--- a/src/com/android/camera/PhotoController.java
+++ b/src/com/android/camera/PhotoController.java
@@ -32,8 +32,7 @@
// Switching between cameras.
public static final int SWITCHING_CAMERA = 4;
- // returns the actual set zoom value
- public int onZoomChanged(int requestedZoom);
+ public void onZoomChanged(float requestedZoom);
public boolean isImageCaptureIntent();
diff --git a/src/com/android/camera/PhotoModule.java b/src/com/android/camera/PhotoModule.java
index 45002f2..f59173c 100644
--- a/src/com/android/camera/PhotoModule.java
+++ b/src/com/android/camera/PhotoModule.java
@@ -151,7 +151,7 @@
// needed to be updated in mUpdateSet.
private int mUpdateSet;
- private int mZoomValue; // The current zoom value.
+ private float mZoomValue; // The current zoom ratio.
private int mTimerDuration;
/** Set when a volume button is clicked to take photo */
private boolean mVolumeButtonClickedFlag = false;
@@ -1084,15 +1084,10 @@
int orientation = Exif.getOrientation(exif);
- float zoomValue = 0f;
+ float zoomValue = 1.0f;
if (mCameraCapabilities.supports(CameraCapabilities.Feature.ZOOM)) {
- int zoomIndex = mCameraSettings.getCurrentZoomIndex();
- List<Integer> zoomRatios = mCameraCapabilities.getZoomRatioList();
- if (zoomRatios != null && zoomIndex < zoomRatios.size()) {
- zoomValue = 0.01f * zoomRatios.get(zoomIndex);
- }
+ zoomValue = mCameraSettings.getCurrentZoomRatio();
}
-
boolean hdrOn = CameraCapabilities.SceneMode.HDR == mSceneMode;
String flashSetting =
mActivity.getSettingsManager().getString(mAppController.getCameraScope(),
@@ -1360,7 +1355,7 @@
initializeCapabilities();
// Reset zoom value index.
- mZoomValue = 0;
+ mZoomValue = 1.0f;
if (mFocusManager == null) {
initializeFocusManager();
}
@@ -1583,7 +1578,7 @@
requestCameraOpen();
mJpegPictureCallbackTime = 0;
- mZoomValue = 0;
+ mZoomValue = 1.0f;
mOnResumeTime = SystemClock.uptimeMillis();
checkDisplayRotation();
@@ -2009,7 +2004,7 @@
private void updateCameraParametersZoom() {
// Set zoom.
if (mCameraCapabilities.supports(CameraCapabilities.Feature.ZOOM)) {
- mCameraSettings.setZoomIndex(mZoomValue);
+ mCameraSettings.setZoomRatio(mZoomValue);
}
}
@@ -2299,25 +2294,19 @@
mCameraCapabilities.supports(CameraCapabilities.FocusMode.CONTINUOUS_PICTURE);
}
- // TODO: Use zoomRatio device API rather than deprecated zoomIndex
@Override
- public int onZoomChanged(int index) {
+ public void onZoomChanged(float ratio) {
// Not useful to change zoom value when the activity is paused.
if (mPaused) {
- return index;
+ return;
}
- mZoomValue = index;
+ mZoomValue = ratio;
if (mCameraSettings == null || mCameraDevice == null) {
- return index;
+ return;
}
// Set zoom parameters asynchronously
- mCameraSettings.setZoomIndex(mZoomValue);
+ mCameraSettings.setZoomRatio(mZoomValue);
mCameraDevice.applySettings(mCameraSettings);
- CameraSettings settings = mCameraDevice.getSettings();
- if (settings != null) {
- return settings.getCurrentZoomIndex();
- }
- return index;
}
@Override
diff --git a/src/com/android/camera/PhotoUI.java b/src/com/android/camera/PhotoUI.java
index e7be5be..c40a418 100644
--- a/src/com/android/camera/PhotoUI.java
+++ b/src/com/android/camera/PhotoUI.java
@@ -69,8 +69,7 @@
private final FaceView mFaceView = null;
private DecodeImageForReview mDecodeTaskForReview = null;
- private int mZoomMax;
- private List<Integer> mZoomRatios;
+ private float mZoomMax;
private int mPreviewWidth = 0;
private int mPreviewHeight = 0;
@@ -450,12 +449,11 @@
!capabilities.supports(CameraCapabilities.Feature.ZOOM)) {
return;
}
- mZoomMax = capabilities.getMaxZoomIndex();
- mZoomRatios = capabilities.getZoomRatioList();
+ mZoomMax = capabilities.getMaxZoomRatio();
// Currently we use immediate zoom for fast zooming to get better UX and
// there is no plan to take advantage of the smooth zoom.
// TODO: Need to setup a path to AppUI to do this
- mPreviewOverlay.setupZoom(mZoomMax, settings.getCurrentZoomIndex(), mZoomRatios,
+ mPreviewOverlay.setupZoom(mZoomMax, settings.getCurrentZoomRatio(),
new ZoomChangeListener());
}
@@ -501,8 +499,8 @@
private class ZoomChangeListener implements PreviewOverlay.OnZoomChangedListener {
@Override
- public void onZoomValueChanged(int index) {
- mController.onZoomChanged(index);
+ public void onZoomValueChanged(float ratio) {
+ mController.onZoomChanged(ratio);
}
@Override
diff --git a/src/com/android/camera/VideoController.java b/src/com/android/camera/VideoController.java
index 5e17f49..b754eae 100644
--- a/src/com/android/camera/VideoController.java
+++ b/src/com/android/camera/VideoController.java
@@ -28,7 +28,7 @@
public boolean isVideoCaptureIntent();
public boolean isInReviewMode();
- public int onZoomChanged(int index);
+ public void onZoomChanged(float ratio);
public void onSingleTapUp(View view, int x, int y);
diff --git a/src/com/android/camera/VideoModule.java b/src/com/android/camera/VideoModule.java
index 6fe83d2..8b2c4fe 100644
--- a/src/com/android/camera/VideoModule.java
+++ b/src/com/android/camera/VideoModule.java
@@ -182,7 +182,7 @@
// The degrees of the device rotated clockwise from its natural orientation.
private int mOrientation = OrientationEventListener.ORIENTATION_UNKNOWN;
- private int mZoomValue; // The current zoom value.
+ private float mZoomValue; // The current zoom ratio.
private final MediaSaver.OnMediaSavedListener mOnVideoSavedListener =
new MediaSaver.OnMediaSavedListener() {
@@ -876,35 +876,22 @@
* Returns current Zoom value, with 1.0 as the value for no zoom.
*/
private float currentZoomValue() {
- float zoomValue = 1.0f;
- if (mCameraCapabilities.supports(CameraCapabilities.Feature.ZOOM)) {
- int zoomIndex = mCameraSettings.getCurrentZoomIndex();
- List<Integer> zoomRatios = mCameraCapabilities.getZoomRatioList();
- if (zoomRatios != null && zoomIndex < zoomRatios.size()) {
- zoomValue = 0.01f * zoomRatios.get(zoomIndex);
- }
- }
- return zoomValue;
+ return mCameraSettings.getCurrentZoomRatio();
}
@Override
- public int onZoomChanged(int index) {
+ public void onZoomChanged(float ratio) {
// Not useful to change zoom value when the activity is paused.
if (mPaused) {
- return index;
+ return;
}
- mZoomValue = index;
+ mZoomValue = ratio;
if (mCameraSettings == null || mCameraDevice == null) {
- return index;
+ return;
}
// Set zoom parameters asynchronously
- mCameraSettings.setZoomIndex(mZoomValue);
+ mCameraSettings.setZoomRatio(mZoomValue);
mCameraDevice.applySettings(mCameraSettings);
- CameraSettings settings = mCameraDevice.getSettings();
- if (settings != null) {
- return settings.getCurrentZoomIndex();
- }
- return index;
}
private void startPreview() {
@@ -1585,7 +1572,7 @@
// Set zoom.
if (mCameraCapabilities.supports(CameraCapabilities.Feature.ZOOM)) {
- mCameraSettings.setZoomIndex(mZoomValue);
+ mCameraSettings.setZoomRatio(mZoomValue);
}
updateFocusParameters();
@@ -1660,7 +1647,7 @@
mPaused = false;
installIntentFilter();
mAppController.setShutterEnabled(false);
- mZoomValue = 0;
+ mZoomValue = 1.0f;
showVideoSnapshotUI(false);
@@ -1760,7 +1747,7 @@
}
// From onResume
- mZoomValue = 0;
+ mZoomValue = 1.0f;
mUI.setOrientationIndicator(0, false);
// Start switch camera animation. Post a message because
diff --git a/src/com/android/camera/VideoUI.java b/src/com/android/camera/VideoUI.java
index a91f038..112a8b1 100644
--- a/src/com/android/camera/VideoUI.java
+++ b/src/com/android/camera/VideoUI.java
@@ -57,8 +57,7 @@
private RotateLayout mRecordingTimeRect;
private boolean mRecordingStarted = false;
private final VideoController mController;
- private int mZoomMax;
- private List<Integer> mZoomRatios;
+ private float mZoomMax;
private float mAspectRatio = UNSET;
private final AnimationManager mAnimationManager;
@@ -213,12 +212,11 @@
}
public void initializeZoom(CameraSettings settings, CameraCapabilities capabilities) {
- mZoomMax = capabilities.getMaxZoomIndex();
- mZoomRatios = capabilities.getZoomRatioList();
+ mZoomMax = capabilities.getMaxZoomRatio();
// Currently we use immediate zoom for fast zooming to get better UX and
// there is no plan to take advantage of the smooth zoom.
// TODO: setup zoom through App UI.
- mPreviewOverlay.setupZoom(mZoomMax, settings.getCurrentZoomIndex(), mZoomRatios,
+ mPreviewOverlay.setupZoom(mZoomMax, settings.getCurrentZoomRatio(),
new ZoomChangeListener());
}
@@ -277,8 +275,8 @@
private class ZoomChangeListener implements PreviewOverlay.OnZoomChangedListener {
@Override
- public void onZoomValueChanged(int index) {
- mController.onZoomChanged(index);
+ public void onZoomValueChanged(float ratio) {
+ mController.onZoomChanged(ratio);
}
@Override
diff --git a/src/com/android/camera/ui/PreviewOverlay.java b/src/com/android/camera/ui/PreviewOverlay.java
index 2a29a64..ba0e697 100644
--- a/src/com/android/camera/ui/PreviewOverlay.java
+++ b/src/com/android/camera/ui/PreviewOverlay.java
@@ -22,6 +22,7 @@
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
+import android.os.SystemClock;
import android.util.AttributeSet;
import android.view.GestureDetector;
import android.view.MotionEvent;
@@ -48,10 +49,15 @@
public class PreviewOverlay extends View
implements PreviewStatusListener.PreviewAreaChangedListener {
+ public static final float ZOOM_MIN_RATIO = 1.0f;
+
private static final Log.Tag TAG = new Log.Tag("PreviewOverlay");
- public static final int ZOOM_MIN_FACTOR = 100;
+ /** Minimum time between calls to zoom listener. */
+ private static final long ZOOM_MINIMUM_WAIT_MILLIS = 33;
+ /** Next time zoom change should be sent to listener. */
+ private long mDelayZoomCallUntilMillis = 0;
private final ZoomGestureDetector mScaleDetector;
private final ZoomProcessor mZoomProcessor = new ZoomProcessor();
private GestureDetector mGestureDetector = null;
@@ -73,9 +79,9 @@
/**
* This gets called when scale gesture changes the zoom value.
*
- * @param index index of the list of supported zoom ratios
+ * @param ratio zoom ratio, [1.0f,maximum]
*/
- void onZoomValueChanged(int index); // only for immediate zoom
+ void onZoomValueChanged(float ratio); // only for immediate zoom
}
public interface OnPreviewTouchedListener {
@@ -91,31 +97,17 @@
}
/**
- * This sets up the zoom listener and zoom related parameters.
- *
- * @param zoomMax max zoom index
- * @param zoom current zoom index
- * @param zoomRatios a list of zoom ratios
- * @param zoomChangeListener a listener that receives callbacks when zoom changes
- */
- public void setupZoom(int zoomMax, int zoom, List<Integer> zoomRatios,
- OnZoomChangedListener zoomChangeListener) {
- mZoomListener = zoomChangeListener;
- mZoomProcessor.setupZoom(zoomMax, zoom, zoomRatios);
- }
-
- /**
* This sets up the zoom listener and zoom related parameters when
* the range of zoom ratios is continuous.
*
- * @param zoomMaxRatio max zoom ratio
- * @param zoom current zoom index
+ * @param zoomMaxRatio max zoom ratio, [1.0f,+Inf)
+ * @param zoom current zoom ratio, [1.0f,zoomMaxRatio]
* @param zoomChangeListener a listener that receives callbacks when zoom changes
*/
- public void setupZoom(float zoomMaxRatio, int zoom, OnZoomChangedListener zoomChangeListener) {
+ public void setupZoom(float zoomMaxRatio, float zoom,
+ OnZoomChangedListener zoomChangeListener) {
mZoomListener = zoomChangeListener;
- int zoomMax = ((int) zoomMaxRatio * 100) - ZOOM_MIN_FACTOR;
- mZoomProcessor.setupZoom(zoomMax, zoom, null);
+ mZoomProcessor.setupZoom(zoomMaxRatio, zoom);
}
@Override
@@ -240,12 +232,10 @@
// Diameter of Zoom UI donut hole as fraction of Zoom UI diameter.
private static final float ZOOM_UI_DONUT = 0.25f;
- final private int mMinIndex = 0;
- private int mMaxIndex;
- // Discrete Zoom level [mMinIndex,mMaxIndex].
- private int mCurrentIndex;
+ private final float mMinRatio = 1.0f;
+ private float mMaxRatio;
// Continuous Zoom level [0,1].
- private float mCurrentFraction;
+ private float mCurrentRatio;
private double mFingerAngle; // in radians.
private final Paint mPaint;
private int mCenterX;
@@ -267,19 +257,14 @@
mPaint.setStrokeCap(Paint.Cap.ROUND);
}
- // Set maximum Zoom Index from Module.
- public void setZoomMax(int zoomMaxIndex) {
- mMaxIndex = zoomMaxIndex;
+ // Set maximum zoom ratio from Module.
+ public void setZoomMax(float zoomMaxRatio) {
+ mMaxRatio = zoomMaxRatio;
}
- // Set current Zoom Index from Module.
- public void setZoom(int index) {
- mCurrentIndex = index;
- mCurrentFraction = (float) index / (mMaxIndex - mMinIndex);
- }
-
- public void setZoomValue(int value) {
- // Do nothing because we are not display text value in current UI.
+ // Set current zoom ratio from Module.
+ public void setZoom(float ratio) {
+ mCurrentRatio = ratio;
}
public void layout(int l, int t, int r, int b) {
@@ -308,7 +293,8 @@
mCenterY + mOuterRadius * (float) Math.sin(mFingerAngle), mPaint);
// Draw Zoom progress.
mPaint.setAlpha(255);
- float zoomRadius = mInnerRadius + mCurrentFraction * (mOuterRadius - mInnerRadius);
+ float fillRatio = (mCurrentRatio - mMinRatio) / (mMaxRatio - mMinRatio);
+ float zoomRadius = mInnerRadius + fillRatio * (mOuterRadius - mInnerRadius);
canvas.drawLine(mCenterX + mInnerRadius * (float) Math.cos(mFingerAngle),
mCenterY - mInnerRadius * (float) Math.sin(mFingerAngle),
mCenterX + zoomRadius * (float) Math.cos(mFingerAngle),
@@ -322,13 +308,21 @@
@Override
public boolean onScale(ScaleGestureDetector detector) {
final float sf = detector.getScaleFactor();
- mCurrentFraction = (0.33f + mCurrentFraction) * sf * sf - 0.33f;
- if (mCurrentFraction < 0.0f) mCurrentFraction = 0.0f;
- if (mCurrentFraction > 1.0f) mCurrentFraction = 1.0f;
- int newIndex = mMinIndex + (int) (mCurrentFraction * (mMaxIndex - mMinIndex));
- if (mZoomListener != null && newIndex != mCurrentIndex) {
- mZoomListener.onZoomValueChanged(newIndex);
- mCurrentIndex = newIndex;
+ mCurrentRatio = (0.33f + mCurrentRatio) * sf * sf - 0.33f;
+ if (mCurrentRatio < mMinRatio) mCurrentRatio = mMinRatio;
+ if (mCurrentRatio > mMaxRatio) mCurrentRatio = mMaxRatio;
+
+ // Only call the listener with a certain frequency. This is
+ // necessary because these listeners will make repeated
+ // applySettings() calls into the portability layer, and doing this
+ // too often can back up its handler and result in visible lag in
+ // updating the zoom level and other controls.
+ long now = SystemClock.uptimeMillis();
+ if (now > mDelayZoomCallUntilMillis) {
+ if (mZoomListener != null) {
+ mZoomListener.onZoomValueChanged(mCurrentRatio);
+ }
+ mDelayZoomCallUntilMillis = now + ZOOM_MINIMUM_WAIT_MILLIS;
}
mFingerAngle = mScaleDetector.getAngle();
invalidate();
@@ -379,8 +373,7 @@
invalidate();
}
- private void setupZoom(int zoomMax, int zoom, List<Integer> zoomRatios) {
- mZoomRatios = zoomRatios;
+ private void setupZoom(float zoomMax, float zoom) {
setZoomMax(zoomMax);
setZoom(zoom);
}