diff options
author | Steve Kondik <shade@chemlab.org> | 2013-08-28 14:21:49 +0800 |
---|---|---|
committer | Michael Bestas <mikeioannina@gmail.com> | 2017-01-04 21:57:39 +0200 |
commit | fd4fd3ea606ab548f1d3a0c1a779f83879e94ab6 (patch) | |
tree | b346008ac98c2fc8fa49612c981b6c1a3330d10c | |
parent | 91d77362feead0419c887a723a3a82452af2891b (diff) | |
download | android_packages_apps_Snap-fd4fd3ea606ab548f1d3a0c1a779f83879e94ab6.tar.gz android_packages_apps_Snap-fd4fd3ea606ab548f1d3a0c1a779f83879e94ab6.tar.bz2 android_packages_apps_Snap-fd4fd3ea606ab548f1d3a0c1a779f83879e94ab6.zip |
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.xml | 5 | ||||
-rw-r--r-- | src/com/android/camera/VideoController.java | 2 | ||||
-rw-r--r-- | src/com/android/camera/VideoMenu.java | 2 | ||||
-rw-r--r-- | src/com/android/camera/VideoModule.java | 144 | ||||
-rw-r--r-- | src/com/android/camera/VideoUI.java | 46 |
5 files changed, 189 insertions, 10 deletions
diff --git a/res/values/arrays.xml b/res/values/arrays.xml index c41602370..5237d49f3 100644 --- a/res/values/arrays.xml +++ b/res/values/arrays.xml @@ -791,6 +791,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 cf694a391..a5b92c1f4 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 45e161dee..76aa03287 100644 --- a/src/com/android/camera/VideoMenu.java +++ b/src/com/android/camera/VideoMenu.java @@ -113,6 +113,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, @@ -125,6 +126,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 afb5e8570..90f6f2537 100644 --- a/src/com/android/camera/VideoModule.java +++ b/src/com/android/camera/VideoModule.java @@ -61,6 +61,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; @@ -84,6 +85,7 @@ import java.lang.reflect.Method; public class VideoModule implements CameraModule, VideoController, + FocusOverlayManager.Listener, CameraPreference.OnPreferenceChangedListener, ShutterButton.OnShutterButtonListener, LocationManager.Listener, @@ -123,6 +125,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; @@ -181,6 +185,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; @@ -266,6 +276,7 @@ public class VideoModule implements CameraModule, @Override public void run() { openCamera(); + if (mFocusManager == null) initializeFocusManager(); } } @@ -280,6 +291,7 @@ public class VideoModule implements CameraModule, return; } mParameters = mCameraDevice.getParameters(); + initializeCapabilities(); mPreviewFocused = arePreviewControlsVisible(); } @@ -360,6 +372,10 @@ public class VideoModule implements CameraModule, private String mDefaultAntibanding = null; boolean mUnsupportedProfile = false; + 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 { @@ -568,23 +584,73 @@ public class VideoModule implements CameraModule, mLocationManager.recordLocation(enable); } + @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. @@ -601,7 +667,10 @@ public class VideoModule implements CameraModule, mSnapshotInProgress = true; UsageStatistics.onEvent(UsageStatistics.COMPONENT_CAMERA, UsageStatistics.ACTION_CAPTURE_DONE, "VideoSnapshot"); + + return true; } + return false; } @Override @@ -855,6 +924,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. @@ -1177,6 +1259,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) { @@ -1245,6 +1330,8 @@ public class VideoModule implements CameraModule, throw new RuntimeException("startPreview failed", ex); } mStartPrevPending = false; + + mFocusManager.onPreviewStarted(); } private void onPreviewStarted() { @@ -1256,6 +1343,8 @@ public class VideoModule implements CameraModule, public void stopPreview() { mStopPrevPending = true; + if (mFocusManager != null) mFocusManager.onPreviewStopped(); + if (!mPreviewing) { mStopPrevPending = false; return; @@ -1284,6 +1373,7 @@ public class VideoModule implements CameraModule, mCameraDevice = null; mPreviewing = false; mSnapshotInProgress = false; + mFocusManager.onCameraReleased(); mPreviewFocused = false; mFaceDetectionStarted = false; } @@ -1341,6 +1431,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 @@ -1474,6 +1586,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 @@ -2713,11 +2826,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); @@ -2792,6 +2902,8 @@ public class VideoModule implements CameraModule, // Update UI based on the new parameters. mUI.updateOnScreenIndicators(mParameters, mPreferences); + + mFocusManager.setPreviewSize(videoWidth, videoHeight); } @Override @@ -2892,6 +3004,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()); @@ -2903,6 +3016,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); @@ -2917,6 +3038,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 3c461f213..b76c40f72 100644 --- a/src/com/android/camera/VideoUI.java +++ b/src/com/android/camera/VideoUI.java @@ -44,14 +44,17 @@ 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.CameraManager.CameraProxy; import com.android.camera.CameraPreference.OnPreferenceChangedListener; +import com.android.camera.FocusOverlayManager.FocusUI; import com.android.camera.PhotoUI.SurfaceTextureSizeChangedListener; import com.android.camera.ui.AbstractSettingPopup; import com.android.camera.ui.CameraControls; import com.android.camera.ui.CameraRootView; 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; @@ -65,6 +68,7 @@ import com.android.camera.util.CameraUtil; public class VideoUI implements PieRenderer.PieListener, PreviewGestures.SingleTapListener, CameraRootView.MyDisplayListener, + FocusUI, SurfaceHolder.Callback, PauseButton.OnPauseButtonListener, CameraManager.CameraFaceDetectionCallback{ @@ -398,7 +402,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); mScreenRatio = CameraUtil.determineRatio(ratio); if (mScreenRatio == CameraUtil.RATIO_16_9 @@ -501,6 +505,10 @@ public class VideoUI implements PieRenderer.PieListener, } + if (scaledTextureWidth > 0 && scaledTextureHeight > 0) { + mController.onScreenSizeChanged((int) scaledTextureWidth, + (int) scaledTextureHeight); + } } /** @@ -1274,4 +1282,40 @@ public class VideoUI implements PieRenderer.PieListener, mFaceView.clear(); } } + + // 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); + } } |