summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorByunghun Jeon <bjeon@codeaurora.org>2016-03-09 17:54:54 -0800
committerSteve Kondik <steve@cyngn.com>2016-08-25 21:55:20 -0700
commit59906a8b182d0f30309f476a96c8c510cb59d1c5 (patch)
tree21208f3da1c72e68246bd0029623ce438c661a8c
parent7ed01dab6670828bd4005a525eef03ed7a19b97f (diff)
downloadandroid_packages_apps_Snap-59906a8b182d0f30309f476a96c8c510cb59d1c5.tar.gz
android_packages_apps_Snap-59906a8b182d0f30309f476a96c8c510cb59d1c5.tar.bz2
android_packages_apps_Snap-59906a8b182d0f30309f476a96c8c510cb59d1c5.zip
SnapdragonCamera: Camera2 add touch to focus
Add touch to focus to Camera2 CRs-Fixed: 989750 Change-Id: I5c7c85dcc12eefb11e5f1b5e6a823a327b2647e4
-rw-r--r--src/com/android/camera/CaptureModule.java128
-rw-r--r--src/com/android/camera/CaptureUI.java20
-rw-r--r--src/com/android/camera/FocusStateListener.java66
-rw-r--r--src/com/android/camera/util/CameraUtil.java25
4 files changed, 232 insertions, 7 deletions
diff --git a/src/com/android/camera/CaptureModule.java b/src/com/android/camera/CaptureModule.java
index 7362a6582..41a26c59d 100644
--- a/src/com/android/camera/CaptureModule.java
+++ b/src/com/android/camera/CaptureModule.java
@@ -26,6 +26,7 @@ import android.content.Context;
import android.content.Intent;
import android.content.res.Configuration;
import android.graphics.ImageFormat;
+import android.graphics.Point;
import android.graphics.Rect;
import android.hardware.camera2.CameraAccessException;
import android.hardware.camera2.CameraCaptureSession;
@@ -36,6 +37,7 @@ import android.hardware.camera2.CameraMetadata;
import android.hardware.camera2.CaptureRequest;
import android.hardware.camera2.CaptureResult;
import android.hardware.camera2.TotalCaptureResult;
+import android.hardware.camera2.params.MeteringRectangle;
import android.hardware.camera2.params.StreamConfigurationMap;
import android.media.CameraProfile;
import android.media.Image;
@@ -118,6 +120,10 @@ public class CaptureModule implements CameraModule, PhotoController,
ORIENTATIONS.append(Surface.ROTATION_270, 180);
}
+ MeteringRectangle[][] mAFRegions = new MeteringRectangle[MAX_NUM_CAM][];
+ private int mLastResultAFState = -1;
+ private Rect[] mCropRegion = new Rect[MAX_NUM_CAM];
+ private boolean mAutoFocusSupported;
// The degrees of the device rotated clockwise from its natural orientation.
private int mOrientation = OrientationEventListener.ORIENTATION_UNKNOWN;
private int mJpegQuality;
@@ -137,7 +143,7 @@ public class CaptureModule implements CameraModule, PhotoController,
private CameraCharacteristics[] mCharacteristics = new CameraCharacteristics[MAX_NUM_CAM];
private List<Integer> mCharacteristicsIndex;
private float mZoomValue = 1f;
-
+ private FocusStateListener mFocusStateListener;
private LocationManager mLocationManager;
/**
* A {@link CameraCaptureSession } for camera preview.
@@ -273,6 +279,8 @@ public class CaptureModule implements CameraModule, PhotoController,
public void onCaptureProgressed(CameraCaptureSession session,
CaptureRequest request,
CaptureResult partialResult) {
+ int id = (int) partialResult.getRequest().getTag();
+ if (id == getMainCameraId()) updateFocusStateChange(partialResult);
process(partialResult);
}
@@ -280,6 +288,8 @@ public class CaptureModule implements CameraModule, PhotoController,
public void onCaptureCompleted(CameraCaptureSession session,
CaptureRequest request,
TotalCaptureResult result) {
+ int id = (int) result.getRequest().getTag();
+ if (id == getMainCameraId()) updateFocusStateChange(result);
process(result);
}
};
@@ -562,6 +572,7 @@ public class CaptureModule implements CameraModule, PhotoController,
mContentResolver = mActivity.getContentResolver();
mUI = new CaptureUI(activity, this, parent);
mUI.initializeControlByIntent();
+ mFocusStateListener = new FocusStateListener(mUI);
mLocationManager = new LocationManager(mActivity, mUI);
Storage.setSaveSDCard(
mPreferences.getString(CameraSettings.KEY_CAMERA_SAVEPATH, "0").equals("1"));
@@ -609,6 +620,26 @@ public class CaptureModule implements CameraModule, PhotoController,
}
}
+ private void autoFocusTrigger(int id) {
+ Log.d(TAG, "autoFocusTrigger " + id);
+ try {
+ CaptureRequest.Builder builder = mCameraDevice[id].createCaptureRequest(CameraDevice
+ .TEMPLATE_PREVIEW);
+ builder.setTag(id);
+ builder.addTarget(getPreviewSurface(id));
+
+ builder.set(CaptureRequest.CONTROL_MODE, CaptureRequest.CONTROL_MODE_AUTO);
+ builder.set(CaptureRequest.CONTROL_AF_MODE, CameraMetadata.CONTROL_AF_MODE_AUTO);
+ builder.set(CaptureRequest.CONTROL_AF_TRIGGER, CaptureRequest.CONTROL_AF_TRIGGER_START);
+ applyWhiteBalance(builder);
+ applyZoom(builder, id);
+ applyAFRegions(builder, id);
+ mCaptureSession[id].capture(builder.build(), mCaptureCallback, mCameraHandler);
+ } catch (CameraAccessException e) {
+ e.printStackTrace();
+ }
+ }
+
/**
* Capture a still picture. This method should be called when we get a response in
* {@link #mCaptureCallback} from both {@link #lockFocus()}.
@@ -719,6 +750,8 @@ public class CaptureModule implements CameraModule, PhotoController,
mOnImageAvailableListener, mImageAvailableHandler);
mCameraId[i] = cameraId;
}
+ mAutoFocusSupported = CameraUtil.isAutoFocusSupported(mCharacteristics,
+ mCharacteristicsIndex);
} catch (CameraAccessException e) {
e.printStackTrace();
} catch (NullPointerException e) {
@@ -1009,7 +1042,42 @@ public class CaptureModule implements CameraModule, PhotoController,
@Override
public void onSingleTapUp(View view, int x, int y) {
+ if (mPaused || mCameraDevice == null || !mFirstTimeInitialized || !mAutoFocusSupported ||
+ !isStatePreview()) {
+ return;
+ }
+ mUI.setFocusPosition(x, y);
+ mUI.onFocusStarted();
+ switch (MODE) {
+ case DUAL_MODE:
+ triggerFocusAtPoint(x, y, BAYER_ID);
+ triggerFocusAtPoint(x, y, MONO_ID);
+ break;
+ case BAYER_MODE:
+ triggerFocusAtPoint(x, y, BAYER_ID);
+ break;
+ case MONO_MODE:
+ triggerFocusAtPoint(x, y, MONO_ID);
+ break;
+ }
+ }
+
+ private int getMainCameraId() {
+ switch (MODE) {
+ case DUAL_MODE:
+ case BAYER_MODE:
+ return BAYER_ID;
+ case MONO_MODE:
+ return MONO_ID;
+ }
+ return 0;
+ }
+ private boolean isStatePreview() {
+ for (int i = 0; i < mState.length; i++) {
+ if (mState[i] != STATE_PREVIEW) return false;
+ }
+ return true;
}
@Override
@@ -1185,6 +1253,7 @@ public class CaptureModule implements CameraModule, PhotoController,
}
public Rect cropRegionForZoom(int id) {
+ Log.d(TAG, "cropRegionForZoom " + id);
Rect activeRegion = mCharacteristics[id].get(CameraCharacteristics
.SENSOR_INFO_ACTIVE_ARRAY_SIZE);
Rect cropRegion = new Rect();
@@ -1194,7 +1263,8 @@ public class CaptureModule implements CameraModule, PhotoController,
int xDelta = (int) (activeRegion.width() / (2 * mZoomValue));
int yDelta = (int) (activeRegion.height() / (2 * mZoomValue));
cropRegion.set(xCenter - xDelta, yCenter - yDelta, xCenter + xDelta, yCenter + yDelta);
- return cropRegion;
+ mCropRegion[id] = cropRegion;
+ return mCropRegion[id];
}
private void applyZoom(CaptureRequest.Builder request, int id) {
@@ -1255,6 +1325,10 @@ public class CaptureModule implements CameraModule, PhotoController,
request.set(CaptureRequest.JPEG_QUALITY, (byte) mJpegQuality);
}
+ private void applyAFRegions(CaptureRequest.Builder request, int id) {
+ request.set(CaptureRequest.CONTROL_AF_REGIONS, mAFRegions[id]);
+ }
+
private void applyWhiteBalance(CaptureRequest.Builder request) {
String value = readSetting(CameraSettings.KEY_WHITE_BALANCE);
switch (value) {
@@ -1320,6 +1394,56 @@ public class CaptureModule implements CameraModule, PhotoController,
mUI.enableShutter(!full);
}
+ public void triggerFocusAtPoint(float x, float y, int id) {
+ Point p;
+ if (id == getMainCameraId()) {
+ p = mUI.getSurfaceViewSize();
+ } else {
+ p = mUI.getSurfaceView2Size();
+ }
+ int width = p.x;
+ int height = p.y;
+ x = x / width;
+ y = y / height;
+ mAFRegions[id] = afRectangle(x, y, mCropRegion[id]);
+ autoFocusTrigger(id);
+ }
+
+ private MeteringRectangle[] afRectangle(float x, float y, Rect cropRegion) {
+ int side = Math.max(cropRegion.width(), cropRegion.height()) / 8;
+ int xCenter = (int) (cropRegion.left + x * cropRegion.width());
+ int yCenter = (int) (cropRegion.top + y * cropRegion.height());
+ Rect meteringRegion = new Rect(xCenter - side / 2, yCenter - side / 2, xCenter +
+ side / 2, yCenter + side / 2);
+
+ meteringRegion.left = CameraUtil.clamp(meteringRegion.left, cropRegion.left, cropRegion
+ .right);
+ meteringRegion.top = CameraUtil.clamp(meteringRegion.top, cropRegion.top, cropRegion
+ .bottom);
+ meteringRegion.right = CameraUtil.clamp(meteringRegion.right, cropRegion.left, cropRegion
+ .right);
+ meteringRegion.bottom = CameraUtil.clamp(meteringRegion.bottom, cropRegion.top,
+ cropRegion.bottom);
+ MeteringRectangle[] meteringRectangle = new MeteringRectangle[1];
+ meteringRectangle[0] = new MeteringRectangle(meteringRegion, 1);
+ return meteringRectangle;
+ }
+
+ private void updateFocusStateChange(CaptureResult result) {
+ final int resultAFState = result.get(CaptureResult.CONTROL_AF_STATE);
+
+ // Report state change when AF state has changed.
+ if (resultAFState != mLastResultAFState && mFocusStateListener != null) {
+ mActivity.runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ mFocusStateListener.onFocusStatusUpdate(resultAFState);
+ }
+ });
+ }
+ mLastResultAFState = resultAFState;
+ }
+
/**
* Compares two {@code Size}s based on their areas.
*/
diff --git a/src/com/android/camera/CaptureUI.java b/src/com/android/camera/CaptureUI.java
index 01b66fb70..a6accae7b 100644
--- a/src/com/android/camera/CaptureUI.java
+++ b/src/com/android/camera/CaptureUI.java
@@ -281,6 +281,12 @@ public class CaptureUI implements PieListener,
public void onCameraOpened(CameraCharacteristics[] characteristics,
List<Integer> characteristicsIndex, PreferenceGroup prefGroup,
OnPreferenceChangedListener listener) {
+ if (mPieRenderer == null) {
+ mPieRenderer = new PieRenderer(mActivity);
+ mPieRenderer.setPieListener(this);
+ mRenderOverlay.addRenderer(mPieRenderer);
+ }
+
if (mMenu == null) {
mMenu = new CaptureMenu(mActivity, this);
mMenu.setListener(listener);
@@ -686,7 +692,7 @@ public class CaptureUI implements PieListener,
// focus UI implementation
private FocusIndicator getFocusIndicator() {
- return null;
+ return mPieRenderer;
}
@Override
@@ -780,6 +786,18 @@ public class CaptureUI implements PieListener,
}
}
+ public Point getSurfaceViewSize() {
+ Point point = new Point();
+ if (mSurfaceView != null) point.set(mSurfaceView.getWidth(), mSurfaceView.getHeight());
+ return point;
+ }
+
+ public Point getSurfaceView2Size() {
+ Point point = new Point();
+ if (mSurfaceView2 != null) point.set(mSurfaceView2.getWidth(), mSurfaceView2.getHeight());
+ return point;
+ }
+
public int getOrientation() {
return mOrientation;
}
diff --git a/src/com/android/camera/FocusStateListener.java b/src/com/android/camera/FocusStateListener.java
new file mode 100644
index 000000000..42edd5c34
--- /dev/null
+++ b/src/com/android/camera/FocusStateListener.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2016, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package com.android.camera;
+
+import android.hardware.camera2.CaptureResult;
+
+public class FocusStateListener {
+ private CaptureUI mUI;
+
+ public FocusStateListener(CaptureUI ui) {
+ mUI = ui;
+ }
+
+ public void onFocusStatusUpdate(int focusState) {
+ switch (focusState) {
+ case CaptureResult.CONTROL_AF_STATE_ACTIVE_SCAN:
+ mUI.onFocusStarted();
+ break;
+ case CaptureResult.CONTROL_AF_STATE_FOCUSED_LOCKED:
+ mUI.onFocusSucceeded(true);
+ break;
+ case CaptureResult.CONTROL_AF_STATE_NOT_FOCUSED_LOCKED:
+ mUI.onFocusFailed(true);
+ break;
+ case CaptureResult.CONTROL_AF_STATE_PASSIVE_FOCUSED:
+ mUI.onFocusSucceeded(true);
+ break;
+ case CaptureResult.CONTROL_AF_STATE_PASSIVE_SCAN:
+ mUI.onFocusStarted();
+ break;
+ case CaptureResult.CONTROL_AF_STATE_PASSIVE_UNFOCUSED:
+ mUI.onFocusFailed(true);
+ break;
+ case CaptureResult.CONTROL_AF_STATE_INACTIVE:
+ mUI.clearFocus();
+ break;
+ }
+ }
+}
diff --git a/src/com/android/camera/util/CameraUtil.java b/src/com/android/camera/util/CameraUtil.java
index 6527649cf..a83714f6a 100644
--- a/src/com/android/camera/util/CameraUtil.java
+++ b/src/com/android/camera/util/CameraUtil.java
@@ -1226,13 +1226,30 @@ public class CameraUtil {
public static boolean isZoomSupported(CameraCharacteristics[] characteristics, List<Integer>
characteristicsIndex) {
- boolean supported = true;
+ for (int i = 0; i < characteristicsIndex.size(); i++) {
+ if (!isZoomSupported(characteristics[characteristicsIndex.get(i)]))
+ return false;
+ }
+ return true;
+ }
+ public static boolean isZoomSupported(CameraCharacteristics characteristic) {
+ return characteristic.get(CameraCharacteristics
+ .SCALER_AVAILABLE_MAX_DIGITAL_ZOOM) > 1f;
+ }
+
+ public static boolean isAutoFocusSupported(CameraCharacteristics[] characteristics, List<Integer>
+ characteristicsIndex) {
for (int i = 0; i < characteristicsIndex.size(); i++) {
- if (characteristics[characteristicsIndex.get(i)].get(CameraCharacteristics
- .SCALER_AVAILABLE_MAX_DIGITAL_ZOOM) <= 1f)
+ if (!isAutoFocusSupported(characteristics[characteristicsIndex.get(i)]))
return false;
}
- return supported;
+ return true;
+ }
+
+ public static boolean isAutoFocusSupported(CameraCharacteristics characteristic) {
+ Integer maxAfRegions = characteristic.get(
+ CameraCharacteristics.CONTROL_MAX_REGIONS_AF);
+ return maxAfRegions != null && maxAfRegions > 0;
}
}