summaryrefslogtreecommitdiffstats
path: root/src/com
diff options
context:
space:
mode:
authorSteve Kondik <shade@chemlab.org>2016-02-28 17:20:23 +0000
committerSteve Kondik <shade@chemlab.org>2016-04-14 01:03:49 -0700
commit57799db3c1757618e00d331fe659ac4058624352 (patch)
treea60a979b8deaff75f98a57ff2c38cc718899e98a /src/com
parenta78d012468101b86c3937c5d4c6cb6ef48d04745 (diff)
downloadandroid_packages_apps_Snap-57799db3c1757618e00d331fe659ac4058624352.tar.gz
android_packages_apps_Snap-57799db3c1757618e00d331fe659ac4058624352.tar.bz2
android_packages_apps_Snap-57799db3c1757618e00d331fe659ac4058624352.zip
Snap: Improve focusing
* Don't needlessly break touch-to-focus during various modes * Set focus parameters immediately for better UX Change-Id: I39b287562c3d2b62a1d5c8953577e366b11b8e15
Diffstat (limited to 'src/com')
-rw-r--r--src/com/android/camera/FocusOverlayManager.java92
-rw-r--r--src/com/android/camera/PhotoModule.java59
-rw-r--r--src/com/android/camera/PhotoUI.java1
-rw-r--r--src/com/android/camera/VideoModule.java51
-rw-r--r--src/com/android/camera/VideoUI.java1
5 files changed, 176 insertions, 28 deletions
diff --git a/src/com/android/camera/FocusOverlayManager.java b/src/com/android/camera/FocusOverlayManager.java
index 4b2d87c1d..d7005c7fe 100644
--- a/src/com/android/camera/FocusOverlayManager.java
+++ b/src/com/android/camera/FocusOverlayManager.java
@@ -27,6 +27,7 @@ import android.util.Log;
import com.android.camera.ui.focus.CameraCoordinateTransformer;
import com.android.camera.ui.focus.FocusRing;
+import com.android.camera.ui.motion.LinearScale;
import com.android.camera.util.CameraUtil;
import com.android.camera.util.UsageStatistics;
@@ -106,6 +107,7 @@ public class FocusOverlayManager {
public void startFaceDetection();
public void stopFaceDetection();
public void setFocusParameters();
+ public void setFocusRatio(float ratio);
}
private class MainHandler extends Handler {
@@ -262,6 +264,7 @@ public class FocusOverlayManager {
}
public void onAutoFocus(boolean focused, boolean shutterButtonPressed) {
+ updateFocusDistance();
if (mState == STATE_FOCUSING_SNAP_ON_FINISH) {
// Take the picture no matter focus succeeds or fails. No need
// to play the AF sound if we're about to play the shutter
@@ -322,6 +325,7 @@ public class FocusOverlayManager {
mFocusRing.stopFocusAnimations();
mIsAFRunning = false;
}
+ updateFocusDistance();
mPreviousMoving = moving;
}
@@ -593,4 +597,92 @@ public class FocusOverlayManager {
return mTouchAFRunning;
}
+ private static class FocusInfo {
+ public final float near;
+ public final float far;
+ public final float current;
+
+ public FocusInfo(float _near, float _far, float _current) {
+ near = _near;
+ far = _far;
+ current = _current;
+ }
+ }
+
+ private FocusInfo getFocusInfoFromParameters(
+ String currentParam, String minParam, String maxParam) {
+ try {
+ String current = mParameters.get(currentParam);
+ if (current != null) {
+ float min = Float.parseFloat(mParameters.get(minParam));
+ float max = Float.parseFloat(mParameters.get(maxParam));
+ if (!(min == 0.0f && max == 0.0f)) {
+ return new FocusInfo(min, max, Float.parseFloat(current));
+ }
+ }
+ } catch (Exception e) {
+ // skip it
+ }
+ return null;
+ }
+
+ private FocusInfo getFocusInfo() {
+ // focus positon is horrifically buggy on some HALs. try to
+ // make the best of it and attempt a few different techniques
+ // to get an accurate measurement
+
+ // older QCOM (Bacon)
+ FocusInfo info = getFocusInfoFromParameters("current-focus-position",
+ "min-focus-pos-index", "max-focus-pos-index");
+ if (info != null) {
+ return info;
+ }
+
+ // newer QCOM (Crackling)
+ info = getFocusInfoFromParameters("cur-focus-scale",
+ "min-focus-pos-ratio", "max-focus-pos-ratio");
+ if (info != null) {
+ return info;
+ }
+
+ return null;
+ }
+
+ /**
+ * Compute the focus range from the camera characteristics and build
+ * a linear scale model that maps a focus distance to a ratio between
+ * the min and max range.
+ */
+ private LinearScale getDiopterToRatioCalculator(FocusInfo focusInfo) {
+ // From the android documentation:
+ //
+ // 0.0f represents farthest focus, and LENS_INFO_MINIMUM_FOCUS_DISTANCE
+ // represents the nearest focus the device can achieve.
+ //
+ // Example:
+ //
+ // Infinity Hyperfocal Minimum Camera
+ // <----------|-----------------------------| |
+ // [0.0] [0.31] [14.29]
+ if (focusInfo.near == 0.0f && focusInfo.far == 0.0f) {
+ return new LinearScale(0, 0, 0, 0);
+ }
+
+ if (focusInfo.near > focusInfo.far) {
+ return new LinearScale(focusInfo.far, focusInfo.near, 0, 1);
+ }
+
+ return new LinearScale(focusInfo.near, focusInfo.far, 0, 1);
+ }
+
+ private void updateFocusDistance() {
+ final FocusInfo focusInfo = getFocusInfo();
+ if (focusInfo != null) {
+ LinearScale range = getDiopterToRatioCalculator(focusInfo);
+ if (range.isInDomain(focusInfo.current) && (mFocusRing.isPassiveFocusRunning() ||
+ mFocusRing.isActiveFocusRunning())) {
+ mListener.setFocusRatio(range.scale(focusInfo.current));
+ }
+ }
+ }
}
diff --git a/src/com/android/camera/PhotoModule.java b/src/com/android/camera/PhotoModule.java
index dc372a303..65f0d61a9 100644
--- a/src/com/android/camera/PhotoModule.java
+++ b/src/com/android/camera/PhotoModule.java
@@ -141,11 +141,13 @@ public class PhotoModule
private static final int SWITCH_TO_GCAM_MODULE = 12;
private static final int ON_PREVIEW_STARTED = 13;
private static final int UPDATE_GESTURES_UI = 14;
+ private static final int SET_FOCUS_RATIO = 15;
// The subset of parameters we need to update in setCameraParameters().
private static final int UPDATE_PARAM_INITIALIZE = 1;
private static final int UPDATE_PARAM_ZOOM = 2;
private static final int UPDATE_PARAM_PREFERENCE = 4;
+ private static final int UPDATE_PARAM_FOCUS = 8;
private static final int UPDATE_PARAM_ALL = -1;
// This is the delay before we execute onResume tasks when coming
@@ -490,6 +492,11 @@ public class PhotoModule
updateGesturesUI();
break;
}
+
+ case SET_FOCUS_RATIO: {
+ mUI.getFocusRing().setRadiusRatio((Float)msg.obj);
+ break;
+ }
}
}
}
@@ -935,6 +942,14 @@ public class PhotoModule
}
}
+ @Override
+ public void setFocusRatio(float ratio) {
+ mHandler.removeMessages(SET_FOCUS_RATIO);
+ Message m = mHandler.obtainMessage(SET_FOCUS_RATIO);
+ m.obj = ratio;
+ mHandler.sendMessage(m);
+ }
+
// TODO: need to check cached background apps memory and longshot ION memory
private boolean isLongshotNeedCancel() {
if (SECONDARY_SERVER_MEM == 0) {
@@ -1450,6 +1465,8 @@ public class PhotoModule
@Override
public void onAutoFocusMoving(
boolean moving, CameraProxy camera) {
+ mCameraDevice.refreshParameters();
+ mFocusManager.setParameters(mCameraDevice.getParameters());
mFocusManager.onAutoFocusMoving(moving);
}
}
@@ -1665,7 +1682,7 @@ public class PhotoModule
@Override
public void setFocusParameters() {
- setCameraParameters(UPDATE_PARAM_PREFERENCE);
+ setCameraParameters(UPDATE_PARAM_FOCUS);
}
private Location getLocationAccordPictureFormat(String pictureFormat) {
@@ -2524,7 +2541,7 @@ public class PhotoModule
mCameraDevice.cancelAutoFocus();
setCameraState(IDLE);
mFocusManager.setAeAwbLock(false);
- setCameraParameters(UPDATE_PARAM_PREFERENCE);
+ setFocusParameters();
}
}
@@ -3421,7 +3438,7 @@ public class PhotoModule
// initialize focus mode
if ((mManual3AEnabled & MANUAL_FOCUS) == 0) {
mFocusManager.overrideFocusMode(null);
- mParameters.setFocusMode(mFocusManager.getFocusMode(false));
+ updateCameraParametersFocus();
}
// Set picture size.
@@ -3650,25 +3667,33 @@ public class PhotoModule
}
}
- if (mContinuousFocusSupported && ApiHelper.HAS_AUTO_FOCUS_MOVE_CALLBACK) {
- updateAutoFocusMoveCallback();
- }
+ enableAutoFocusMoveCallback();
+
//QCom related parameters updated here.
qcomUpdateCameraParametersPreference();
return doGcamModeSwitch;
}
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
- private void updateAutoFocusMoveCallback() {
- if (mParameters.getFocusMode().equals(CameraUtil.FOCUS_MODE_CONTINUOUS_PICTURE) ||
- mParameters.getFocusMode().equals(CameraUtil.FOCUS_MODE_MW_CONTINUOUS_PICTURE)) {
- mCameraDevice.setAutoFocusMoveCallback(mHandler,
- (CameraAFMoveCallback) mAutoFocusMoveCallback);
- } else {
- mCameraDevice.setAutoFocusMoveCallback(null, null);
+ private void enableAutoFocusMoveCallback() {
+ if (mContinuousFocusSupported && ApiHelper.HAS_AUTO_FOCUS_MOVE_CALLBACK) {
+ if (mParameters.getFocusMode().equals(CameraUtil.FOCUS_MODE_CONTINUOUS_PICTURE)) {
+ mCameraDevice.setAutoFocusMoveCallback(mHandler,
+ (CameraAFMoveCallback) mAutoFocusMoveCallback);
+ } else {
+ mCameraDevice.setAutoFocusMoveCallback(null, null);
+ }
}
}
+ private void updateCameraParametersFocus() {
+ setAutoExposureLockIfSupported();
+ setAutoWhiteBalanceLockIfSupported();
+ setFocusAreasIfSupported();
+ setMeteringAreasIfSupported();
+ mParameters.setFocusMode(mFocusManager.getFocusMode(false));
+ }
+
// We separate the parameters into several subsets, so we can update only
// the subsets actually need updating. The PREFERENCE set needs extra
// locking because the preference can be changed from GLThread as well.
@@ -3691,8 +3716,14 @@ public class PhotoModule
doModeSwitch = updateCameraParametersPreference();
}
- CameraUtil.dumpParameters(mParameters);
+ if ((updateSet & UPDATE_PARAM_FOCUS) != 0) {
+ updateCameraParametersFocus();
+ }
+
mCameraDevice.setParameters(mParameters);
+ mParameters = mCameraDevice.getParameters();
+ mFocusManager.setParameters(mParameters);
+ CameraUtil.dumpParameters(mParameters);
// Switch to gcam module if HDR+ was selected
if (doModeSwitch && !mIsImageCaptureIntent) {
diff --git a/src/com/android/camera/PhotoUI.java b/src/com/android/camera/PhotoUI.java
index c26664c2f..2aaf19d6d 100644
--- a/src/com/android/camera/PhotoUI.java
+++ b/src/com/android/camera/PhotoUI.java
@@ -64,7 +64,6 @@ import com.android.camera.ui.CameraRootView;
import com.android.camera.ui.CountDownView;
import com.android.camera.ui.CountDownView.OnCountDownFinishedListener;
import com.android.camera.ui.FaceView;
-import com.android.camera.ui.FocusIndicator;
import com.android.camera.ui.ListSubMenu;
import com.android.camera.ui.ModuleSwitcher;
import com.android.camera.ui.PieRenderer;
diff --git a/src/com/android/camera/VideoModule.java b/src/com/android/camera/VideoModule.java
index 5121a032f..6a1e3e326 100644
--- a/src/com/android/camera/VideoModule.java
+++ b/src/com/android/camera/VideoModule.java
@@ -96,6 +96,7 @@ public class VideoModule implements CameraModule,
private static final int SHOW_TAP_TO_SNAPSHOT_TOAST = 7;
private static final int SWITCH_CAMERA = 8;
private static final int SWITCH_CAMERA_START_ANIMATION = 9;
+ private static final int SET_FOCUS_RATIO = 10;
private static final int SCREEN_DELAY = 2 * 60 * 1000;
@@ -391,6 +392,11 @@ public class VideoModule implements CameraModule,
break;
}
+ case SET_FOCUS_RATIO: {
+ mUI.getFocusRing().setRadiusRatio((Float)msg.obj);
+ break;
+ }
+
default:
Log.v(TAG, "Unhandled message: " + msg.what);
break;
@@ -546,15 +552,27 @@ public class VideoModule implements CameraModule,
@Override
public void setFocusParameters() {
- if (mFocusAreaSupported)
- mParameters.setFocusAreas(mFocusManager.getFocusAreas());
- if (mMeteringAreaSupported)
- mParameters.setMeteringAreas(mFocusManager.getMeteringAreas());
+ updateCameraParametersFocus();
+ mCameraDevice.setParameters(mParameters);
+ }
+
+ private void updateCameraParametersFocus() {
setAutoExposureLockIfSupported();
setAutoWhiteBalanceLockIfSupported();
- if (mFocusAreaSupported || mMeteringAreaSupported) {
- mParameters.setFocusMode(mFocusManager.getFocusMode(true));
- mCameraDevice.setParameters(mParameters);
+ setFocusAreasIfSupported();
+ setMeteringAreasIfSupported();
+ mParameters.setFocusMode(mFocusManager.getFocusMode(true));
+ }
+
+ private void setFocusAreasIfSupported() {
+ if (mFocusAreaSupported) {
+ mParameters.setFocusAreas(mFocusManager.getFocusAreas());
+ }
+ }
+
+ private void setMeteringAreasIfSupported() {
+ if (mMeteringAreaSupported) {
+ mParameters.setMeteringAreas(mFocusManager.getMeteringAreas());
}
}
@@ -840,14 +858,22 @@ public class VideoModule implements CameraModule,
@Override
public void onAutoFocus(
boolean focused, CameraProxy camera) {
- Log.v(TAG, "AutoFocusCallback, mPaused=" + mPaused);
if (mPaused) return;
- //setCameraState(IDLE);
+ mCameraDevice.refreshParameters();
+ mFocusManager.setParameters(mCameraDevice.getParameters());
mFocusManager.onAutoFocus(focused, false);
}
}
+ @Override
+ public void setFocusRatio(float ratio) {
+ mHandler.removeMessages(SET_FOCUS_RATIO);
+ Message m = mHandler.obtainMessage(SET_FOCUS_RATIO);
+ m.obj = ratio;
+ mHandler.sendMessage(m);
+ }
+
private void readVideoPreferences() {
// The preference stores values from ListPreference and is thus string type for all values.
// We need to convert it to int manually.
@@ -2538,6 +2564,10 @@ public class VideoModule implements CameraModule,
mParameters.setPreviewFrameRate(mProfile.videoFrameRate);
}
+ // Set focus mode
+ mFocusManager.overrideFocusMode(null);
+ updateCameraParametersFocus();
+
forceFlashOffIfSupported(!mPreviewFocused);
videoWidth = mProfile.videoFrameWidth;
videoHeight = mProfile.videoFrameHeight;
@@ -2577,9 +2607,6 @@ public class VideoModule implements CameraModule,
mParameters.setZoom(mZoomValue);
}
- // Set focus mode
- mParameters.setFocusMode(mFocusManager.getFocusMode(true));
-
mParameters.set(CameraUtil.RECORDING_HINT, CameraUtil.TRUE);
// Enable video stabilization. Convenience methods not available in API
diff --git a/src/com/android/camera/VideoUI.java b/src/com/android/camera/VideoUI.java
index 0883f5fac..30ecffbad 100644
--- a/src/com/android/camera/VideoUI.java
+++ b/src/com/android/camera/VideoUI.java
@@ -48,7 +48,6 @@ import com.android.camera.CameraPreference.OnPreferenceChangedListener;
import com.android.camera.ui.AbstractSettingPopup;
import com.android.camera.ui.CameraControls;
import com.android.camera.ui.CameraRootView;
-import com.android.camera.ui.FocusIndicator;
import com.android.camera.ui.ListSubMenu;
import com.android.camera.ui.ModuleSwitcher;
import com.android.camera.ui.PieRenderer;