summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteve Kondik <shade@chemlab.org>2013-08-28 14:21:49 +0800
committerMichael Bestas <mikeioannina@gmail.com>2015-09-20 20:02:05 +0300
commiteaae37ffbc5c216e43540cf0a561a82384631796 (patch)
treeddd4b74389f85f85c874e77a876b114c669e1b74
parent58d454bd4ef24aa8e71bcb6ab3b4349902561256 (diff)
downloadandroid_packages_apps_Snap-eaae37ffbc5c216e43540cf0a561a82384631796.zip
android_packages_apps_Snap-eaae37ffbc5c216e43540cf0a561a82384631796.tar.gz
android_packages_apps_Snap-eaae37ffbc5c216e43540cf0a561a82384631796.tar.bz2
camera: Touch focus support for camcorder
* Available when video snapshots are not supported. * Original from CodeAurora Forum. Sultanxda: Adapted to Snapdragon Camera Change-Id: I232c178430db08e7366aa9f91b4926d07e7c225d
-rw-r--r--res/values/arrays.xml5
-rw-r--r--src/com/android/camera/VideoController.java2
-rw-r--r--src/com/android/camera/VideoMenu.java2
-rw-r--r--src/com/android/camera/VideoModule.java144
-rw-r--r--src/com/android/camera/VideoUI.java55
5 files changed, 198 insertions, 10 deletions
diff --git a/res/values/arrays.xml b/res/values/arrays.xml
index 0008847..19bc5ec 100644
--- a/res/values/arrays.xml
+++ b/res/values/arrays.xml
@@ -747,6 +747,11 @@
<item>auto</item>
</string-array>
+ <string-array name="pref_video_focusmode_default_array" translatable="false">
+ <item>continuous-video</item>
+ <item>auto</item>
+ </string-array>
+
<!-- Icons for exposure compensation -->
<array name="pref_camera_exposure_icons" translatable="false">
<item>@drawable/ic_exposure_n3</item>
diff --git a/src/com/android/camera/VideoController.java b/src/com/android/camera/VideoController.java
index cf694a3..a5b92c1 100644
--- a/src/com/android/camera/VideoController.java
+++ b/src/com/android/camera/VideoController.java
@@ -40,4 +40,6 @@ public interface VideoController extends OnShutterButtonListener, OnPauseButtonL
// Callbacks for camera preview UI events.
public void onPreviewUIReady();
public void onPreviewUIDestroyed();
+
+ public void onScreenSizeChanged(int width, int height);
}
diff --git a/src/com/android/camera/VideoMenu.java b/src/com/android/camera/VideoMenu.java
index 08491a6..5d71cf6 100644
--- a/src/com/android/camera/VideoMenu.java
+++ b/src/com/android/camera/VideoMenu.java
@@ -110,6 +110,7 @@ public class VideoMenu extends MenuController
mOtherKeys1 = new String[] {
CameraSettings.KEY_VIDEOCAMERA_FLASH_MODE,
CameraSettings.KEY_VIDEO_QUALITY,
+ CameraSettings.KEY_FOCUS_TIME,
CameraSettings.KEY_RECORD_LOCATION,
CameraSettings.KEY_CAMERA_SAVEPATH,
CameraSettings.KEY_EXPOSURE,
@@ -121,6 +122,7 @@ public class VideoMenu extends MenuController
mOtherKeys2 = new String[] {
CameraSettings.KEY_VIDEOCAMERA_FLASH_MODE,
CameraSettings.KEY_VIDEO_QUALITY,
+ CameraSettings.KEY_FOCUS_TIME,
CameraSettings.KEY_RECORD_LOCATION,
CameraSettings.KEY_CAMERA_SAVEPATH,
CameraSettings.KEY_EXPOSURE,
diff --git a/src/com/android/camera/VideoModule.java b/src/com/android/camera/VideoModule.java
index 0352ac7..c7ceee1 100644
--- a/src/com/android/camera/VideoModule.java
+++ b/src/com/android/camera/VideoModule.java
@@ -59,6 +59,7 @@ import android.widget.Toast;
import android.media.EncoderCapabilities;
import android.media.EncoderCapabilities.VideoEncoderCap;
+import com.android.camera.CameraManager.CameraAFCallback;
import com.android.camera.CameraManager.CameraPictureCallback;
import com.android.camera.CameraManager.CameraProxy;
import com.android.camera.app.OrientationManager;
@@ -80,6 +81,7 @@ import java.util.HashMap;
public class VideoModule implements CameraModule,
VideoController,
+ FocusOverlayManager.Listener,
CameraPreference.OnPreferenceChangedListener,
ShutterButton.OnShutterButtonListener,
MediaRecorder.OnErrorListener,
@@ -112,6 +114,8 @@ public class VideoModule implements CameraModule,
private boolean mPaused;
private int mCameraId;
private Parameters mParameters;
+ private boolean mFocusAreaSupported;
+ private boolean mMeteringAreaSupported;
private boolean mIsInReviewMode;
private boolean mSnapshotInProgress = false;
@@ -170,6 +174,12 @@ public class VideoModule implements CameraModule,
private int mDesiredPreviewHeight;
private ContentResolver mContentResolver;
+ private final AutoFocusCallback mAutoFocusCallback =
+ new AutoFocusCallback();
+
+ // This handles everything about focus.
+ private FocusOverlayManager mFocusManager;
+
private LocationManager mLocationManager;
private OrientationManager mOrientationManager;
private int mPendingSwitchCameraId;
@@ -232,6 +242,7 @@ public class VideoModule implements CameraModule,
@Override
public void run() {
openCamera();
+ if (mFocusManager == null) initializeFocusManager();
}
}
@@ -246,6 +257,7 @@ public class VideoModule implements CameraModule,
return;
}
mParameters = mCameraDevice.getParameters();
+ initializeCapabilities();
mPreviewFocused = arePreviewControlsVisible();
}
@@ -319,6 +331,10 @@ public class VideoModule implements CameraModule,
private boolean mUnsupportedHFRVideoCodec = false;
private String mDefaultAntibanding = null;
+ public void onScreenSizeChanged(int width, int height) {
+ 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 {
@@ -489,23 +505,73 @@ public class VideoModule implements CameraModule,
mPendingSwitchCameraId = -1;
}
+ @Override
+ public void autoFocus() {
+ Log.e(TAG, "start autoFocus.");
+ mCameraDevice.autoFocus(mHandler, mAutoFocusCallback);
+ }
+
+ @Override
+ public void cancelAutoFocus() {
+ if (null != mCameraDevice) {
+ mCameraDevice.cancelAutoFocus();
+ setFocusParameters();
+ }
+ }
+
+ @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) {
+ mParameters.setFocusMode(mFocusManager.getFocusMode());
+ mCameraDevice.setParameters(mParameters);
+ }
+ }
+
// SingleTapListener
// Preview area is touched. Take a picture.
@Override
public void onSingleTapUp(View view, int x, int y) {
if (mMediaRecorderPausing) return;
- takeASnapshot();
+ boolean snapped = takeASnapshot();
+ if (!snapped) {
+ // 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);
+ }
+ }
}
- private void takeASnapshot() {
+ private boolean takeASnapshot() {
// Only take snapshots if video snapshot is supported by device
if (CameraUtil.isVideoSnapshotSupported(mParameters) && !mIsVideoCaptureIntent) {
if (!mMediaRecorderRecording || mPaused || mSnapshotInProgress) {
- return;
+ return false;
}
MediaSaveService s = mActivity.getMediaSaveService();
if (s == null || s.isQueueFull()) {
- return;
+ return false;
}
// Set rotation and gps data.
@@ -522,7 +588,10 @@ public class VideoModule implements CameraModule,
mSnapshotInProgress = true;
UsageStatistics.onEvent(UsageStatistics.COMPONENT_CAMERA,
UsageStatistics.ACTION_CAPTURE_DONE, "VideoSnapshot");
+
+ return true;
}
+ return false;
}
@Override
@@ -762,6 +831,19 @@ public class VideoModule implements CameraModule,
}
}
+ private final class AutoFocusCallback
+ implements CameraAFCallback {
+ @Override
+ public void onAutoFocus(
+ boolean focused, CameraProxy camera) {
+ Log.v(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.
@@ -1032,6 +1114,9 @@ public class VideoModule implements CameraModule,
private void setDisplayOrientation() {
mDisplayRotation = CameraUtil.getDisplayRotation(mActivity);
mCameraDisplayOrientation = CameraUtil.getDisplayOrientation(mDisplayRotation, mCameraId);
+ if (mFocusManager != null) {
+ mFocusManager.setDisplayOrientation(mCameraDisplayOrientation);
+ }
mUI.setDisplayOrientation(mCameraDisplayOrientation);
// Change the camera display orientation
if (mCameraDevice != null) {
@@ -1093,6 +1178,8 @@ public class VideoModule implements CameraModule,
throw new RuntimeException("startPreview failed", ex);
}
mStartPrevPending = false;
+
+ mFocusManager.onPreviewStarted();
}
private void onPreviewStarted() {
@@ -1103,6 +1190,8 @@ public class VideoModule implements CameraModule,
public void stopPreview() {
mStopPrevPending = true;
+ if (mFocusManager != null) mFocusManager.onPreviewStopped();
+
if (!mPreviewing) {
mStopPrevPending = false;
return;
@@ -1125,6 +1214,7 @@ public class VideoModule implements CameraModule,
mCameraDevice = null;
mPreviewing = false;
mSnapshotInProgress = false;
+ mFocusManager.onCameraReleased();
mPreviewFocused = false;
}
@@ -1174,6 +1264,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_video_focusmode_default_array);
+ mFocusManager = new FocusOverlayManager(mPreferences, defaultFocusModes,
+ mParameters, this, mirror,
+ mActivity.getMainLooper(), mUI);
+ }
}
@Override
@@ -1306,6 +1418,7 @@ public class VideoModule implements CameraModule,
}
private void setupMediaRecorderPreviewDisplay() {
+ mFocusManager.resetTouchFocus();
// Nothing to do here if using SurfaceTexture.
if (!ApiHelper.HAS_SURFACE_TEXTURE_RECORDING) {
// We stop the preview here before unlocking the device because we
@@ -2406,11 +2519,8 @@ public class VideoModule implements CameraModule,
mParameters.setZoom(mZoomValue);
}
- // Set continuous autofocus.
- List<String> supportedFocus = mParameters.getSupportedFocusModes();
- if (isSupported(Parameters.FOCUS_MODE_CONTINUOUS_VIDEO, supportedFocus)) {
- mParameters.setFocusMode(Parameters.FOCUS_MODE_CONTINUOUS_VIDEO);
- }
+ // Set focus mode
+ mParameters.setFocusMode(mFocusManager.getFocusMode());
mParameters.set(CameraUtil.RECORDING_HINT, CameraUtil.TRUE);
@@ -2472,6 +2582,8 @@ public class VideoModule implements CameraModule,
// Update UI based on the new parameters.
mUI.updateOnScreenIndicators(mParameters, mPreferences);
+
+ mFocusManager.setPreviewSize(videoWidth, videoHeight);
}
@Override
@@ -2555,6 +2667,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());
@@ -2565,6 +2678,14 @@ public class VideoModule implements CameraModule,
resizeForPreviewAspectRatio();
initializeVideoControl();
+ CameraInfo info = CameraHolder.instance().getCameraInfo()[mCameraId];
+ boolean mirror = (info.facing == CameraInfo.CAMERA_FACING_FRONT);
+ mParameters = mCameraDevice.getParameters();
+ mFocusManager.setMirror(mirror);
+ mFocusManager.setParameters(mParameters);
+
+ initializeCapabilities();
+
// From onResume
mZoomValue = 0;
mUI.initializeZoom(mParameters);
@@ -2579,6 +2700,11 @@ public class VideoModule implements CameraModule,
mUI.showTimeLapseUI(mCaptureTimeLapse);
}
+ private void initializeCapabilities() {
+ mFocusAreaSupported = CameraUtil.isFocusAreaSupported(mParameters);
+ mMeteringAreaSupported = CameraUtil.isMeteringAreaSupported(mParameters);
+ }
+
// Preview texture has been copied. Now camera can be released and the
// animation can be started.
@Override
diff --git a/src/com/android/camera/VideoUI.java b/src/com/android/camera/VideoUI.java
index daab24a..2e1d300 100644
--- a/src/com/android/camera/VideoUI.java
+++ b/src/com/android/camera/VideoUI.java
@@ -42,11 +42,14 @@ import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.PopupWindow;
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.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;
@@ -59,6 +62,7 @@ import com.android.camera.util.CameraUtil;
public class VideoUI implements PieRenderer.PieListener,
PreviewGestures.SingleTapListener,
CameraRootView.MyDisplayListener,
+ FocusUI,
SurfaceHolder.Callback,
PauseButton.OnPauseButtonListener {
private static final String TAG = "CAM_VideoUI";
@@ -332,7 +336,7 @@ public class VideoUI implements PieRenderer.PieListener,
private void layoutPreview(float ratio) {
FrameLayout.LayoutParams lp = null;
- float scaledTextureWidth, scaledTextureHeight;
+ float scaledTextureWidth = 0.0f, scaledTextureHeight = 0.0f;
int rotation = CameraUtil.getDisplayRotation(mActivity);
if (mScreenRatio == CameraUtil.RATIO_16_9
&& CameraUtil.determinCloseRatio(ratio) == CameraUtil.RATIO_4_3) {
@@ -412,6 +416,11 @@ public class VideoUI implements PieRenderer.PieListener,
mSurfaceView.setLayoutParams(lp);
mSurfaceView.requestLayout();
}
+
+ if (scaledTextureWidth > 0 && scaledTextureHeight > 0) {
+ mController.onScreenSizeChanged((int) scaledTextureWidth,
+ (int) scaledTextureHeight);
+ }
}
/**
@@ -1131,4 +1140,48 @@ public class VideoUI implements PieRenderer.PieListener,
public void adjustOrientation() {
setOrientation(mOrientation, false);
}
+
+ // 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() {
+ }
}