diff options
| author | Steve Kondik <shade@chemlab.org> | 2013-08-28 14:21:49 +0800 |
|---|---|---|
| committer | Steve Kondik <shade@chemlab.org> | 2013-10-18 13:54:23 -0700 |
| commit | 6063446f5e81b301710043fcb154bab5aa2f3c74 (patch) | |
| tree | bf7fbd52fc3f6198adee51154a8ee3a06e42e148 | |
| parent | 7119a0cdbbedf9a4f829d0145fd7ceec58986d36 (diff) | |
| download | android_packages_apps_Gallery2-6063446f5e81b301710043fcb154bab5aa2f3c74.tar.gz android_packages_apps_Gallery2-6063446f5e81b301710043fcb154bab5aa2f3c74.tar.bz2 android_packages_apps_Gallery2-6063446f5e81b301710043fcb154bab5aa2f3c74.zip | |
camera: Touch focus support for camcorder
* Available when video snapshots are not supported.
* Original from CodeAurora Forum.
Change-Id: I232c178430db08e7366aa9f91b4926d07e7c225d
| -rw-r--r-- | src/com/android/camera/VideoController.java | 2 | ||||
| -rw-r--r-- | src/com/android/camera/VideoModule.java | 129 | ||||
| -rw-r--r-- | src/com/android/camera/VideoUI.java | 76 |
3 files changed, 203 insertions, 4 deletions
diff --git a/src/com/android/camera/VideoController.java b/src/com/android/camera/VideoController.java index 474f521de..f2601c104 100644 --- a/src/com/android/camera/VideoController.java +++ b/src/com/android/camera/VideoController.java @@ -33,4 +33,6 @@ public interface VideoController extends OnShutterButtonListener { public void onSingleTapUp(View view, int x, int y); public void stopPreview(); + + public void onScreenSizeChanged(int width, int height, int previewWidth, int previewHeight); } diff --git a/src/com/android/camera/VideoModule.java b/src/com/android/camera/VideoModule.java index 88cdd7257..50e006781 100644 --- a/src/com/android/camera/VideoModule.java +++ b/src/com/android/camera/VideoModule.java @@ -72,6 +72,7 @@ import java.util.List; public class VideoModule implements CameraModule, VideoController, + FocusOverlayManager.Listener, CameraPreference.OnPreferenceChangedListener, ShutterButton.OnShutterButtonListener, MediaRecorder.OnErrorListener, @@ -112,6 +113,8 @@ public class VideoModule implements CameraModule, private boolean mPaused; private int mCameraId; private Parameters mParameters; + private boolean mFocusAreaSupported; + private boolean mMeteringAreaSupported; private Boolean mCameraOpened = false; @@ -178,8 +181,14 @@ public class VideoModule implements CameraModule, private LocationManager mLocationManager; + private final AutoFocusCallback mAutoFocusCallback = + new AutoFocusCallback(); + private int mPendingSwitchCameraId; + // This handles everything about focus. + private FocusOverlayManager mFocusManager; + private final Handler mHandler = new MainHandler(); private VideoUI mUI; // The degrees of the device rotated clockwise from its natural orientation. @@ -225,6 +234,7 @@ public class VideoModule implements CameraModule, @Override public void run() { openCamera(); + if (mFocusManager == null) initializeFocusManager(); } } @@ -247,6 +257,10 @@ public class VideoModule implements CameraModule, } } mParameters = mActivity.mCameraDevice.getParameters(); + + mFocusAreaSupported = Util.isFocusAreaSupported(mParameters); + mMeteringAreaSupported = Util.isMeteringAreaSupported(mParameters); + } catch (CameraHardwareException e) { mActivity.mOpenCameraFail = true; } catch (CameraDisabledException e) { @@ -254,6 +268,10 @@ public class VideoModule implements CameraModule, } } + public void onScreenSizeChanged(int width, int height, int previewWidth, int previewHeight) { + if (mFocusManager != null) mFocusManager.setPreviewSize(width, height); + } + // This Handler is used to post message back onto the main thread of the // application private class MainHandler extends Handler { @@ -464,10 +482,55 @@ public class VideoModule implements CameraModule, } } + @Override + public void autoFocus() { + Log.e(TAG, "start autoFocus."); + mActivity.mCameraDevice.autoFocus(mAutoFocusCallback); + } + + @Override + public void cancelAutoFocus() { + mActivity.mCameraDevice.cancelAutoFocus(); + } + + @Override + public boolean capture() { + return true; + } + + @Override + public void startFaceDetection() { + } + + @Override + public void stopFaceDetection() { + } + + @Override + public void setFocusParameters() { + if (mFocusAreaSupported) + mParameters.setFocusAreas(mFocusManager.getFocusAreas()); + if (mMeteringAreaSupported) + mParameters.setMeteringAreas(mFocusManager.getMeteringAreas()); + if (mFocusAreaSupported || mMeteringAreaSupported) + mActivity.mCameraDevice.setParameters(mParameters); + } + // SingleTapListener // Preview area is touched. Take a picture. @Override public void onSingleTapUp(View view, int x, int y) { + if (!mParameters.isVideoSnapshotSupported()) { + // Do not trigger touch focus if popup window is opened. + if (mUI.removeTopLevelPopup()) + return; + + // Check if metering area or focus area is supported. + if (mFocusAreaSupported || mMeteringAreaSupported) { + mFocusManager.onSingleTapUp(x, y); + } + } + if (mMediaRecorderRecording && effectsActive()) { new RotateTextToast(mActivity, R.string.disable_video_snapshot_hint, mOrientation).show(); @@ -499,6 +562,7 @@ public class VideoModule implements CameraModule, mSnapshotInProgress = true; UsageStatistics.onEvent(UsageStatistics.COMPONENT_CAMERA, UsageStatistics.ACTION_CAPTURE_DONE, "VideoSnapshot"); + } @Override @@ -660,6 +724,19 @@ public class VideoModule implements CameraModule, mUI.setShutterPressed(pressed); } + private final class AutoFocusCallback + implements android.hardware.Camera.AutoFocusCallback { + @Override + public void onAutoFocus( + boolean focused, android.hardware.Camera camera) { + Log.e(TAG, "AutoFocusCallback, mPaused=" + mPaused); + if (mPaused) return; + + //setCameraState(IDLE); + mFocusManager.onAutoFocus(focused, false); + } + } + 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. @@ -858,6 +935,10 @@ public class VideoModule implements CameraModule, // We need to consider display rotation ourselves. mCameraDisplayOrientation = Util.getDisplayOrientation(mDisplayRotation, mCameraId); } + if (mFocusManager != null) { + int mDisplayOrientation = Util.getDisplayOrientation(mDisplayRotation, mCameraId); + mFocusManager.setDisplayOrientation(mDisplayOrientation); + } // GLRoot also uses the DisplayRotation, and needs to be told to layout to update mActivity.getGLRoot().requestLayoutContentPane(); } @@ -893,6 +974,7 @@ public class VideoModule implements CameraModule, try { if (!effectsActive()) { + mFocusManager.setAeAwbLock(false); // Unlock AE and AWB. if (ApiHelper.HAS_SURFACE_TEXTURE) { SurfaceTexture texture = mActivity.getScreenNailTextureForPreviewSize( mCameraId, mCameraDisplayOrientation, mParameters); @@ -928,6 +1010,7 @@ public class VideoModule implements CameraModule, } }); } + mFocusManager.onPreviewStarted(); } @@ -940,6 +1023,7 @@ public class VideoModule implements CameraModule, public void stopPreview() { mActivity.mCameraDevice.stopPreview(); mPreviewing = false; + if (mFocusManager != null) mFocusManager.onPreviewStopped(); } // Closing the effects out. Will shut down the effects graph. @@ -1006,6 +1090,7 @@ public class VideoModule implements CameraModule, mActivity.mCameraDevice = null; mPreviewing = false; mSnapshotInProgress = false; + mFocusManager.onCameraReleased(); } private void releasePreviewResources() { @@ -1068,6 +1153,28 @@ public class VideoModule implements CameraModule, @Override public void onPauseAfterSuper() { + if (mFocusManager != null) mFocusManager.removeMessages(); + } + + /** + * The focus manager is the first UI related element to get initialized, + * and it requires the RenderOverlay, so initialize it here + */ + private void initializeFocusManager() { + // Create FocusManager object. startPreview needs it. + // if mFocusManager not null, reuse it + // otherwise create a new instance + if (mFocusManager != null) { + mFocusManager.removeMessages(); + } else { + CameraInfo info = CameraHolder.instance().getCameraInfo()[mCameraId]; + boolean mirror = (info.facing == CameraInfo.CAMERA_FACING_FRONT); + String[] defaultFocusModes = mActivity.getResources().getStringArray( + R.array.pref_camera_focusmode_default_array); + mFocusManager = new FocusOverlayManager(mPreferences, defaultFocusModes, + mParameters, this, mirror, + mActivity.getMainLooper(), mUI); + } } @Override @@ -1157,6 +1264,7 @@ public class VideoModule implements CameraModule, } private void setupMediaRecorderPreviewDisplay() { + mFocusManager.resetTouchFocus(); // Nothing to do here if using SurfaceTexture. if (!ApiHelper.HAS_SURFACE_TEXTURE) { mMediaRecorder.setPreviewDisplay(mUI.getSurfaceHolder().getSurface()); @@ -1718,9 +1826,7 @@ public class VideoModule implements CameraModule, mActivity.mCameraDevice.lock(); mActivity.mCameraDevice.waitDone(); if ((ApiHelper.HAS_SURFACE_TEXTURE && - !ApiHelper.HAS_SURFACE_TEXTURE_RECORDING) || - !mActivity.getResources().getBoolean( - R.bool.useVideoSnapshotWorkaround)) { + !ApiHelper.HAS_SURFACE_TEXTURE_RECORDING)) { stopPreview(); // Switch back to use SurfaceTexture for preview. ((CameraScreenNail) mActivity.mCameraScreenNail).setOneTimeOnFrameDrawnListener( @@ -1974,6 +2080,11 @@ public class VideoModule implements CameraModule, mParameters = mActivity.mCameraDevice.getParameters(); updateCameraScreenNailSize(mDesiredPreviewWidth, mDesiredPreviewHeight); + + CameraScreenNail screenNail = (CameraScreenNail) mActivity.mCameraScreenNail; + int width = screenNail.getWidth(); + int height = screenNail.getHeight(); + mFocusManager.setPreviewSize(width, height); } private void updateCameraScreenNailSize(int width, int height) { @@ -1998,6 +2109,8 @@ public class VideoModule implements CameraModule, if (mStartPreviewThread == null && screenNail.getSurfaceTexture() == null) { screenNail.acquireSurfaceTexture(); } + + mFocusManager.setPreviewSize(width, height); } @Override @@ -2160,6 +2273,7 @@ public class VideoModule implements CameraModule, closeCamera(); mUI.collapseCameraControls(); + if (mFocusManager != null) mFocusManager.removeMessages(); // Restart the camera and initialize the UI. From onCreate. mPreferences.setLocalId(mActivity, mCameraId); CameraSettings.upgradeLocalPreferences(mPreferences.getLocal()); @@ -2170,6 +2284,15 @@ public class VideoModule implements CameraModule, resizeForPreviewAspectRatio(); initializeVideoControl(); + CameraInfo info = CameraHolder.instance().getCameraInfo()[mCameraId]; + boolean mirror = (info.facing == CameraInfo.CAMERA_FACING_FRONT); + mParameters = mActivity.mCameraDevice.getParameters(); + mFocusManager.setMirror(mirror); + mFocusManager.setParameters(mParameters); + + mFocusAreaSupported = Util.isFocusAreaSupported(mParameters); + mMeteringAreaSupported = Util.isMeteringAreaSupported(mParameters); + // From onResume mUI.initializeZoom(mParameters); mUI.setOrientationIndicator(0, false); diff --git a/src/com/android/camera/VideoUI.java b/src/com/android/camera/VideoUI.java index b649a9a06..c4765eaab 100644 --- a/src/com/android/camera/VideoUI.java +++ b/src/com/android/camera/VideoUI.java @@ -30,9 +30,12 @@ import android.widget.FrameLayout.LayoutParams; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.TextView; +import android.view.View.OnLayoutChangeListener; import com.android.camera.CameraPreference.OnPreferenceChangedListener; +import com.android.camera.FocusOverlayManager.FocusUI; import com.android.camera.ui.AbstractSettingPopup; +import com.android.camera.ui.FocusIndicator; import com.android.camera.ui.PieRenderer; import com.android.camera.ui.PreviewSurfaceView; import com.android.camera.ui.RenderOverlay; @@ -45,7 +48,8 @@ import java.util.List; public class VideoUI implements SurfaceHolder.Callback, PieRenderer.PieListener, PreviewGestures.SingleTapListener, - PreviewGestures.SwipeListener { + PreviewGestures.SwipeListener, + FocusUI { private final static String TAG = "CAM_VideoUI"; // module fields private CameraActivity mActivity; @@ -78,6 +82,9 @@ public class VideoUI implements SurfaceHolder.Callback, PieRenderer.PieListener, private List<Integer> mZoomRatios; private View mPreviewThumb; + private int mPreviewWidth = 0; + private int mPreviewHeight = 0; + public VideoUI(CameraActivity activity, VideoController controller, View parent) { mActivity = activity; mController = controller; @@ -90,6 +97,27 @@ public class VideoUI implements SurfaceHolder.Callback, PieRenderer.PieListener, initializeOverlay(); } + private OnLayoutChangeListener mLayoutListener = new OnLayoutChangeListener() { + @Override + public void onLayoutChange(View v, int left, int top, int right, + int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) { + int width = right - left; + int height = bottom - top; + // Full-screen screennail + int w = width; + int h = height; + if (Util.getDisplayRotation(mActivity) % 180 != 0) { + w = height; + h = width; + } + if (mPreviewWidth != width || mPreviewHeight != height) { + mPreviewWidth = width; + mPreviewHeight = height; + mController.onScreenSizeChanged(width, height, w, h); + } + } + }; + private void initializeControlByIntent() { mBlocker = mActivity.findViewById(R.id.blocker); mMenu = mActivity.findViewById(R.id.menu); @@ -236,6 +264,8 @@ public class VideoUI implements SurfaceHolder.Callback, PieRenderer.PieListener, mActivity.gotoGallery(); } }); + + mRootView.addOnLayoutChangeListener(mLayoutListener); } public void setPrefChangedListener(OnPreferenceChangedListener listener) { @@ -524,6 +554,50 @@ public class VideoUI implements SurfaceHolder.Callback, PieRenderer.PieListener, } } + // implement focusUI interface + private FocusIndicator getFocusIndicator() { + return mPieRenderer; + } + + @Override + public boolean hasFaces() { + return false; + } + + @Override + public void clearFocus() { + FocusIndicator indicator = getFocusIndicator(); + if (indicator != null) indicator.clear(); + } + + @Override + public void setFocusPosition(int x, int y) { + mPieRenderer.setFocus(x, y); + } + + @Override + public void onFocusStarted(){ + getFocusIndicator().showStart(); + } + + @Override + public void onFocusSucceeded(boolean timeOut) { + getFocusIndicator().showSuccess(timeOut); + } + + @Override + public void onFocusFailed(boolean timeOut) { + getFocusIndicator().showFail(timeOut); + } + + @Override + public void pauseFaceDetection() { + } + + @Override + public void resumeFaceDetection() { + } + @Override public void onSwipe(int direction) { if (direction == PreviewGestures.DIR_UP) { |
