summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteve Kondik <shade@chemlab.org>2013-08-28 14:21:49 +0800
committerSteve Kondik <shade@chemlab.org>2013-10-18 13:54:23 -0700
commit6063446f5e81b301710043fcb154bab5aa2f3c74 (patch)
treebf7fbd52fc3f6198adee51154a8ee3a06e42e148
parent7119a0cdbbedf9a4f829d0145fd7ceec58986d36 (diff)
downloadandroid_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.java2
-rw-r--r--src/com/android/camera/VideoModule.java129
-rw-r--r--src/com/android/camera/VideoUI.java76
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) {