diff --git a/demo/src/main/res/layout-land/activity_main.xml b/demo/src/main/res/layout-land/activity_main.xml index 1b02cd1f..c16b5667 100644 --- a/demo/src/main/res/layout-land/activity_main.xml +++ b/demo/src/main/res/layout-land/activity_main.xml @@ -13,6 +13,7 @@ --> + android:adjustViewBounds="true" + app:focusMode="continuousPicture"/> diff --git a/demo/src/main/res/layout/activity_main.xml b/demo/src/main/res/layout/activity_main.xml index e2e75894..2926d6a5 100644 --- a/demo/src/main/res/layout/activity_main.xml +++ b/demo/src/main/res/layout/activity_main.xml @@ -13,6 +13,7 @@ --> + android:adjustViewBounds="true" + app:focusMode="continuousPicture"/> diff --git a/library/src/androidTest/AndroidManifest.xml b/library/src/androidTest/AndroidManifest.xml index 809e31e6..8e76376a 100644 --- a/library/src/androidTest/AndroidManifest.xml +++ b/library/src/androidTest/AndroidManifest.xml @@ -15,6 +15,8 @@ xmlns:android="http://schemas.android.com/apk/res/android"> + + diff --git a/library/src/androidTest/java/com/google/android/cameraview/CameraViewActivity.java b/library/src/androidTest/java/com/google/android/cameraview/CameraViewActivity.java index 8c04d3e2..eef098ac 100644 --- a/library/src/androidTest/java/com/google/android/cameraview/CameraViewActivity.java +++ b/library/src/androidTest/java/com/google/android/cameraview/CameraViewActivity.java @@ -16,6 +16,8 @@ package com.google.android.cameraview; +import com.google.android.cameraview.test.R; + import android.app.Activity; import android.os.Bundle; diff --git a/library/src/androidTest/java/com/google/android/cameraview/CameraViewTest.java b/library/src/androidTest/java/com/google/android/cameraview/CameraViewTest.java index a8feba19..02f84aeb 100644 --- a/library/src/androidTest/java/com/google/android/cameraview/CameraViewTest.java +++ b/library/src/androidTest/java/com/google/android/cameraview/CameraViewTest.java @@ -16,6 +16,8 @@ package com.google.android.cameraview; +import com.google.android.cameraview.test.R; + import org.hamcrest.Matcher; import org.hamcrest.core.IsAnything; import org.junit.After; @@ -202,6 +204,21 @@ public void check(View view, NoMatchingViewException noViewFoundException) { }); } + @Test + public void testFocusMode() { + onView(withId(R.id.camera)) + .check(new ViewAssertion() { + @Override + public void check(View view, NoMatchingViewException noViewFoundException) { + CameraView cameraView = (CameraView) view; + assertThat(cameraView.getFocusMode(), is(CameraView.FOCUS_MODE_OFF)); + cameraView.setFocusMode(CameraView.FOCUS_MODE_CONTINUOUS_PICTURE); + assertThat(cameraView.getFocusMode(), + is(CameraView.FOCUS_MODE_CONTINUOUS_PICTURE)); + } + }); + } + /** * Wait for a camera to open. */ diff --git a/library/src/main/base/com/google/android/cameraview/CameraViewImpl.java b/library/src/main/base/com/google/android/cameraview/CameraViewImpl.java index f01966df..50159cdf 100644 --- a/library/src/main/base/com/google/android/cameraview/CameraViewImpl.java +++ b/library/src/main/base/com/google/android/cameraview/CameraViewImpl.java @@ -42,6 +42,10 @@ public CameraViewImpl(Callback callback) { abstract int getDisplayOrientation(); + abstract void setFocusMode(int focusMode); + + abstract int getFocusMode(); + interface Callback { void onCameraOpened(); diff --git a/library/src/main/base/com/google/android/cameraview/Constants.java b/library/src/main/base/com/google/android/cameraview/Constants.java new file mode 100644 index 00000000..9af66748 --- /dev/null +++ b/library/src/main/base/com/google/android/cameraview/Constants.java @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.android.cameraview; + + +interface Constants { + + int FOCUS_MODE_OFF = 0; + int FOCUS_MODE_AUTO = 1; + int FOCUS_MODE_MACRO = 2; + int FOCUS_MODE_CONTINUOUS_PICTURE = 3; + int FOCUS_MODE_CONTINUOUS_VIDEO = 4; + int FOCUS_MODE_EDOF = 5; + +} diff --git a/library/src/main/camera1/com/google/android/cameraview/Camera1.java b/library/src/main/camera1/com/google/android/cameraview/Camera1.java index f18efe2f..363a6c77 100644 --- a/library/src/main/camera1/com/google/android/cameraview/Camera1.java +++ b/library/src/main/camera1/com/google/android/cameraview/Camera1.java @@ -54,6 +54,8 @@ class Camera1 extends CameraViewImpl { private boolean mShowingPreview; + private int mFocusMode; + private static class PreviewInfo { SurfaceTexture surface; int width; @@ -69,8 +71,7 @@ void configure(SurfaceTexture s, int w, int h) { private final TextureView.SurfaceTextureListener mSurfaceTextureListener = new TextureView.SurfaceTextureListener() { - @Override - public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) { + private void reconfigurePreview(SurfaceTexture surface, int width, int height) { mPreviewInfo.configure(surface, width, height); if (mCamera != null) { setUpPreview(); @@ -78,13 +79,14 @@ public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int hei } } + @Override + public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) { + reconfigurePreview(surface, width, height); + } + @Override public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) { - mPreviewInfo.configure(surface, width, height); - if (mCamera != null) { - setUpPreview(); - adjustPreviewSize(); - } + reconfigurePreview(surface, width, height); } @Override @@ -172,6 +174,22 @@ int getDisplayOrientation() { return mDisplayOrientation; } + @Override + void setFocusMode(int focusMode) { + if (mFocusMode != focusMode) { + mFocusMode = focusMode; + if (mCamera != null) { + mCameraParameters.setFocusMode(Camera1Constants.convertFocusMode(focusMode)); + mCamera.setParameters(mCameraParameters); + } + } + } + + @Override + int getFocusMode() { + return mFocusMode; + } + /** * This rewrites {@link #mCameraId} and {@link #mCameraInfo}. */ @@ -232,6 +250,7 @@ private void adjustPreviewSize() { mCamera.stopPreview(); } mCameraParameters.setPreviewSize(size.getWidth(), size.getHeight()); + mCameraParameters.setFocusMode(Camera1Constants.convertFocusMode(mFocusMode)); mCamera.setParameters(mCameraParameters); if (mShowingPreview) { mCamera.startPreview(); diff --git a/library/src/main/camera1/com/google/android/cameraview/Camera1Constants.java b/library/src/main/camera1/com/google/android/cameraview/Camera1Constants.java new file mode 100644 index 00000000..77514a00 --- /dev/null +++ b/library/src/main/camera1/com/google/android/cameraview/Camera1Constants.java @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.android.cameraview; + + +import android.hardware.Camera; +import android.support.v4.util.SparseArrayCompat; + +@SuppressWarnings("deprecation") +class Camera1Constants { + + private static SparseArrayCompat sFocusModesMap; + + static String convertFocusMode(int focusMode) { + if (sFocusModesMap == null) { + sFocusModesMap = new SparseArrayCompat<>(); + sFocusModesMap.put(Constants.FOCUS_MODE_OFF, Camera.Parameters.FOCUS_MODE_FIXED); + sFocusModesMap.put(Constants.FOCUS_MODE_AUTO, Camera.Parameters.FOCUS_MODE_AUTO); + sFocusModesMap.put(Constants.FOCUS_MODE_MACRO, Camera.Parameters.FOCUS_MODE_MACRO); + sFocusModesMap.put(Constants.FOCUS_MODE_CONTINUOUS_PICTURE, + Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE); + sFocusModesMap.put(Constants.FOCUS_MODE_CONTINUOUS_VIDEO, + Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO); + sFocusModesMap.put(Constants.FOCUS_MODE_EDOF, Camera.Parameters.FOCUS_MODE_EDOF); + } + return sFocusModesMap.get(focusMode); + } + +} diff --git a/library/src/main/java/com/google/android/cameraview/CameraView.java b/library/src/main/java/com/google/android/cameraview/CameraView.java index 68335655..a2f67012 100644 --- a/library/src/main/java/com/google/android/cameraview/CameraView.java +++ b/library/src/main/java/com/google/android/cameraview/CameraView.java @@ -20,16 +20,32 @@ import android.content.Context; import android.content.res.TypedArray; import android.os.Build; +import android.support.annotation.IntDef; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.util.AttributeSet; import android.view.TextureView; import android.widget.FrameLayout; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; public class CameraView extends FrameLayout { + public static final int FOCUS_MODE_OFF = Constants.FOCUS_MODE_OFF; + public static final int FOCUS_MODE_AUTO = Constants.FOCUS_MODE_AUTO; + public static final int FOCUS_MODE_MACRO = Constants.FOCUS_MODE_MACRO; + public static final int FOCUS_MODE_CONTINUOUS_PICTURE = Constants.FOCUS_MODE_CONTINUOUS_PICTURE; + public static final int FOCUS_MODE_CONTINUOUS_VIDEO = Constants.FOCUS_MODE_CONTINUOUS_VIDEO; + public static final int FOCUS_MODE_EDOF = Constants.FOCUS_MODE_EDOF; + + @IntDef({FOCUS_MODE_OFF, FOCUS_MODE_AUTO, FOCUS_MODE_MACRO, FOCUS_MODE_CONTINUOUS_PICTURE, + FOCUS_MODE_CONTINUOUS_VIDEO, FOCUS_MODE_EDOF}) + @Retention(RetentionPolicy.SOURCE) + public @interface FocusMode { + } + private final CameraViewImpl mImpl; private final CallbackBridge mCallbacks; @@ -63,6 +79,8 @@ public CameraView(Context context, AttributeSet attrs, int defStyleAttr) { TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CameraView, defStyleAttr, R.style.Widget_CameraView); mAdjustViewBounds = a.getBoolean(R.styleable.CameraView_android_adjustViewBounds, false); + //noinspection WrongConstant + setFocusMode(a.getInt(R.styleable.CameraView_focusMode, FOCUS_MODE_OFF)); a.recycle(); } @@ -210,6 +228,29 @@ public AspectRatio getAspectRatio() { return mImpl.getAspectRatio(); } + /** + * Sets the focus mode. + * + * @param focusMode The focus mode. Must be one of {@link #FOCUS_MODE_OFF}, + * {@link #FOCUS_MODE_AUTO}, {@link #FOCUS_MODE_MACRO}, + * {@link #FOCUS_MODE_CONTINUOUS_PICTURE}, + * {@link #FOCUS_MODE_CONTINUOUS_VIDEO}, and {@link #FOCUS_MODE_EDOF}. + */ + public void setFocusMode(@FocusMode int focusMode) { + mImpl.setFocusMode(focusMode); + } + + /** + * Gets the current focus mode. + * + * @return The current focus mode. + */ + @FocusMode + public int getFocusMode() { + //noinspection WrongConstant + return mImpl.getFocusMode(); + } + private class CallbackBridge implements CameraViewImpl.Callback { private final ArrayList mCallbacks = new ArrayList<>(); diff --git a/library/src/main/res/values/attrs.xml b/library/src/main/res/values/attrs.xml index e2ad2a02..cde4347e 100644 --- a/library/src/main/res/values/attrs.xml +++ b/library/src/main/res/values/attrs.xml @@ -14,5 +14,13 @@ + + + + + + + + diff --git a/library/src/main/res/values/styles.xml b/library/src/main/res/values/styles.xml index 7ffe735b..6da519d8 100644 --- a/library/src/main/res/values/styles.xml +++ b/library/src/main/res/values/styles.xml @@ -15,6 +15,7 @@