diff options
author | Steve Kondik <shade@chemlab.org> | 2016-02-28 17:20:23 +0000 |
---|---|---|
committer | Steve Kondik <shade@chemlab.org> | 2016-04-14 01:03:49 -0700 |
commit | 57799db3c1757618e00d331fe659ac4058624352 (patch) | |
tree | a60a979b8deaff75f98a57ff2c38cc718899e98a /src/com | |
parent | a78d012468101b86c3937c5d4c6cb6ef48d04745 (diff) | |
download | android_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.java | 92 | ||||
-rw-r--r-- | src/com/android/camera/PhotoModule.java | 59 | ||||
-rw-r--r-- | src/com/android/camera/PhotoUI.java | 1 | ||||
-rw-r--r-- | src/com/android/camera/VideoModule.java | 51 | ||||
-rw-r--r-- | src/com/android/camera/VideoUI.java | 1 |
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; |