From 46157ec917ce84f9737ed6bc27e11a322903d05a Mon Sep 17 00:00:00 2001 From: Seifer Date: Tue, 26 Jun 2018 18:20:06 +0300 Subject: [PATCH 1/8] Update gradle to 4.4 and plugin to 3.1.3 + use SDK 27 --- build.gradle | 9 ++++----- demo/build.gradle | 14 ++++++-------- gradle/wrapper/gradle-wrapper.properties | 4 ++-- library/build.gradle | 11 +++++------ 4 files changed, 17 insertions(+), 21 deletions(-) diff --git a/build.gradle b/build.gradle index 6c49c87e..25bfb300 100644 --- a/build.gradle +++ b/build.gradle @@ -6,7 +6,7 @@ buildscript { google() } dependencies { - classpath 'com.android.tools.build:gradle:3.0.1' + classpath 'com.android.tools.build:gradle:3.1.3' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files @@ -25,9 +25,8 @@ task clean(type: Delete) { } ext { - buildToolsVersion = '26.0.2' - compileSdkVersion = 26 + compileSdkVersion = 27 minSdkVersion = 14 - targetSdkVersion = 26 - supportLibraryVersion = '26.0.1' + targetSdkVersion = 27 + supportLibraryVersion = '27.1.1' } diff --git a/demo/build.gradle b/demo/build.gradle index 17730712..fa5b3d58 100644 --- a/demo/build.gradle +++ b/demo/build.gradle @@ -17,8 +17,6 @@ apply plugin: 'com.android.application' android { compileSdkVersion rootProject.ext.compileSdkVersion - buildToolsVersion rootProject.ext.buildToolsVersion - defaultConfig { applicationId 'com.google.android.cameraview.demo' minSdkVersion rootProject.ext.minSdkVersion @@ -37,16 +35,16 @@ android { } dependencies { - compile fileTree(dir: 'libs', include: ['*.jar']) - compile "com.android.support:design:$supportLibraryVersion" - compile project(':library') + implementation fileTree(dir: 'libs', include: ['*.jar']) + implementation "com.android.support:design:$supportLibraryVersion" + implementation project(':library') // Tests - testCompile 'junit:junit:4.12' - androidTestCompile('com.android.support.test:runner:0.5') { + testImplementation 'junit:junit:4.12' + androidTestImplementation('com.android.support.test:runner:0.5') { exclude module: 'support-annotations' } - androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2') { + androidTestImplementation('com.android.support.test.espresso:espresso-core:2.2.2') { exclude module: 'support-annotations' } } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 0efaa852..06fa3c12 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Tue Sep 06 09:02:59 JST 2016 +#Tue Jun 26 17:51:35 EEST 2018 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-4.4-all.zip diff --git a/library/build.gradle b/library/build.gradle index 30b53bd8..09ff6a9b 100644 --- a/library/build.gradle +++ b/library/build.gradle @@ -16,7 +16,6 @@ apply plugin: 'com.android.library' android { compileSdkVersion rootProject.ext.compileSdkVersion - buildToolsVersion rootProject.ext.buildToolsVersion defaultConfig { minSdkVersion rootProject.ext.minSdkVersion @@ -39,15 +38,15 @@ android { } dependencies { - compile "com.android.support:support-annotations:$supportLibraryVersion" - compile "com.android.support:support-v4:$supportLibraryVersion" + api "com.android.support:support-annotations:$supportLibraryVersion" + api "com.android.support:support-v4:$supportLibraryVersion" // Tests - testCompile 'junit:junit:4.12' - androidTestCompile('com.android.support.test:runner:0.5') { + testImplementation 'junit:junit:4.12' + androidTestImplementation('com.android.support.test:runner:0.5') { exclude module: 'support-annotations' } - androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2') { + androidTestImplementation('com.android.support.test.espresso:espresso-core:2.2.2') { exclude module: 'support-annotations' } } From 16a42aeeda9a135d7476fe477cc0d01adb20d0a9 Mon Sep 17 00:00:00 2001 From: Seifer Date: Tue, 26 Jun 2018 18:21:46 +0300 Subject: [PATCH 2/8] Add default constructors for CameraView --- .../com/google/android/cameraview/CameraView.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) 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 43297b6f..46233b51 100644 --- a/library/src/main/java/com/google/android/cameraview/CameraView.java +++ b/library/src/main/java/com/google/android/cameraview/CameraView.java @@ -82,14 +82,26 @@ public class CameraView extends FrameLayout { private final DisplayOrientationDetector mDisplayOrientationDetector; + public CameraView(Context context) { + this(context, null, false); + } + public CameraView(Context context, boolean fallbackToOldApi) { this(context, null, fallbackToOldApi); } + public CameraView(Context context, AttributeSet attrs) { + this(context, attrs, 0, false); + } + public CameraView(Context context, AttributeSet attrs, boolean fallbackToOldApi) { this(context, attrs, 0, fallbackToOldApi); } + public CameraView(Context context, AttributeSet attrs, int defStyleAttr) { + this(context, attrs, defStyleAttr, false); + } + @SuppressWarnings("WrongConstant") public CameraView(Context context, AttributeSet attrs, int defStyleAttr, boolean fallbackToOldApi) { super(context, attrs, defStyleAttr); From 0bde0541f29d584e543d22b35cace3611f1ed2d1 Mon Sep 17 00:00:00 2001 From: Seifer Date: Tue, 26 Jun 2018 20:38:39 +0300 Subject: [PATCH 3/8] Allow Camera2 legacy hardware level for testing --- .../com/google/android/cameraview/Camera2.java | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/library/src/main/api21/com/google/android/cameraview/Camera2.java b/library/src/main/api21/com/google/android/cameraview/Camera2.java index 585d1c9f..5bb2cc87 100644 --- a/library/src/main/api21/com/google/android/cameraview/Camera2.java +++ b/library/src/main/api21/com/google/android/cameraview/Camera2.java @@ -240,6 +240,16 @@ public void onImageAvailable(ImageReader reader) { private Rect mInitialCropRegion; + /** + * AllowLegacy used for testing to let chooseCameraIdByFacing() pass through + * INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY check. + * This is useful when we want to enable Camera2 usage on emulators, that always return + * level=LEGACY + * + * Set true to allow hardware legacy level + */ + private boolean mAllowLegacy = false; + Camera2(Callback callback, PreviewImpl preview, Context context) { super(callback, preview); mCameraManager = (CameraManager) context.getSystemService(Context.CAMERA_SERVICE); @@ -591,7 +601,8 @@ private boolean chooseCameraIdByFacing() { Integer level = characteristics.get( CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL); if (level == null || - level == CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY) { + (level == CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY && + !mAllowLegacy)) { continue; } Integer internal = characteristics.get(CameraCharacteristics.LENS_FACING); @@ -610,7 +621,8 @@ private boolean chooseCameraIdByFacing() { Integer level = mCameraCharacteristics.get( CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL); if (level == null || - level == CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY) { + (level == CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY && + !mAllowLegacy)) { return false; } Integer internal = mCameraCharacteristics.get(CameraCharacteristics.LENS_FACING); From 1c6fa3d8a8692d1479aca897d30a71dad49c66c9 Mon Sep 17 00:00:00 2001 From: Seifer Date: Tue, 26 Jun 2018 20:42:52 +0300 Subject: [PATCH 4/8] Introduce Gravity attribute for CameraView Gravity allows to center preview with Fill/Fit effect in case CameraView size/ratio is not the same as supported by camera size/ratio --- .../com/google/android/cameraview/Constants.java | 3 +++ library/src/main/res/values/attrs.xml | 16 ++++++++++++++++ library/src/main/res/values/public.xml | 1 + library/src/main/res/values/styles.xml | 1 + 4 files changed, 21 insertions(+) diff --git a/library/src/main/base/com/google/android/cameraview/Constants.java b/library/src/main/base/com/google/android/cameraview/Constants.java index 4fe1b878..cab90b20 100644 --- a/library/src/main/base/com/google/android/cameraview/Constants.java +++ b/library/src/main/base/com/google/android/cameraview/Constants.java @@ -39,4 +39,7 @@ public interface Constants { int WB_FLUORESCENT = 4; int WB_INCANDESCENT = 5; + int GRAVITY_NONE = 0; + int GRAVITY_CENTER_FILL = 1; + int GRAVITY_CENTER_FIT = 2; } diff --git a/library/src/main/res/values/attrs.xml b/library/src/main/res/values/attrs.xml index 7ac245d8..03241b8c 100644 --- a/library/src/main/res/values/attrs.xml +++ b/library/src/main/res/values/attrs.xml @@ -54,5 +54,21 @@ --> + + + + + + + + + + diff --git a/library/src/main/res/values/public.xml b/library/src/main/res/values/public.xml index 84966fa6..d3cc0155 100644 --- a/library/src/main/res/values/public.xml +++ b/library/src/main/res/values/public.xml @@ -16,6 +16,7 @@ + diff --git a/library/src/main/res/values/styles.xml b/library/src/main/res/values/styles.xml index 6ded7168..d21f3062 100644 --- a/library/src/main/res/values/styles.xml +++ b/library/src/main/res/values/styles.xml @@ -19,6 +19,7 @@ 4:3 true auto + none From a1de678462d1185fd71f0fdd183c9e4b61364681 Mon Sep 17 00:00:00 2001 From: Seifer Date: Thu, 28 Jun 2018 21:03:33 +0300 Subject: [PATCH 5/8] Add gravity property to CameraView --- .../google/android/cameraview/CameraView.java | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) 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 46233b51..67409443 100644 --- a/library/src/main/java/com/google/android/cameraview/CameraView.java +++ b/library/src/main/java/com/google/android/cameraview/CameraView.java @@ -72,12 +72,24 @@ public class CameraView extends FrameLayout { public @interface Flash { } + public static final int GRAVITY_NONE = Constants.GRAVITY_NONE; + + public static final int GRAVITY_CENTER_FILL = Constants.GRAVITY_CENTER_FILL; + + public static final int GRAVITY_CENTER_FIT = Constants.GRAVITY_CENTER_FIT; + + @IntDef({GRAVITY_NONE, GRAVITY_CENTER_FILL, GRAVITY_CENTER_FIT}) + public @interface Gravity { + } + CameraViewImpl mImpl; private final CallbackBridge mCallbacks; private boolean mAdjustViewBounds; + private int mGravity = GRAVITY_NONE; + private Context mContext; private final DisplayOrientationDetector mDisplayOrientationDetector; @@ -231,6 +243,7 @@ protected Parcelable onSaveInstanceState() { state.zoom = getZoom(); state.whiteBalance = getWhiteBalance(); state.scanning = getScanning(); + state.gravity = getGravity(); return state; } @@ -250,6 +263,7 @@ protected void onRestoreInstanceState(Parcelable state) { setZoom(ss.zoom); setWhiteBalance(ss.whiteBalance); setScanning(ss.scanning); + setGravity(ss.gravity); } public void setUsingCamera2Api(boolean useCamera2) { @@ -456,6 +470,15 @@ public int getFlash() { return mImpl.getFlash(); } + public void setGravity(@Gravity int gravity) { + mGravity = gravity; + } + + @Gravity + public int getGravity() { + return mGravity; + } + public void setFocusDepth(float value) { mImpl.setFocusDepth(value); } @@ -603,6 +626,9 @@ protected static class SavedState extends BaseSavedState { boolean scanning; + @Gravity + int gravity; + @SuppressWarnings("WrongConstant") public SavedState(Parcel source, ClassLoader loader) { super(source); @@ -614,6 +640,7 @@ public SavedState(Parcel source, ClassLoader loader) { zoom = source.readFloat(); whiteBalance = source.readInt(); scanning = source.readByte() != 0; + gravity = source.readInt(); } public SavedState(Parcelable superState) { @@ -631,6 +658,7 @@ public void writeToParcel(Parcel out, int flags) { out.writeFloat(zoom); out.writeInt(whiteBalance); out.writeByte((byte) (scanning ? 1 : 0)); + out.writeInt(gravity); } public static final Creator CREATOR From 0dc3a74af75b40d20d7560594f37036373d6caeb Mon Sep 17 00:00:00 2001 From: Seifer Date: Thu, 28 Jun 2018 21:06:38 +0300 Subject: [PATCH 6/8] Implement CameraView gravity behavior for CenterFit and CenterFill `adjustViewBounds` doesn't affect gravity behavior when CameraView's width & height = match_parent --- .../google/android/cameraview/CameraView.java | 67 ++++++++++++++++++- 1 file changed, 66 insertions(+), 1 deletion(-) 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 67409443..97a4895e 100644 --- a/library/src/main/java/com/google/android/cameraview/CameraView.java +++ b/library/src/main/java/com/google/android/cameraview/CameraView.java @@ -219,7 +219,11 @@ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { ratio = ratio.inverse(); } assert ratio != null; - if (height < width * ratio.getY() / ratio.getX()) { + boolean widthPriority = height < width * ratio.getY() / ratio.getX(); + if (mGravity == GRAVITY_CENTER_FIT) { + widthPriority = !widthPriority; + } + if (widthPriority) { mImpl.getView().measure( MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(width * ratio.getY() / ratio.getX(), @@ -232,6 +236,67 @@ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { } } + @Override + protected void onLayout(boolean changed, int left, int top, int right, int bottom) { + View preview = getView(); + if (null == preview) { + return; + } + + if (mGravity == GRAVITY_NONE) { + super.onLayout(changed, left, top, right, bottom); + return; + } + + float width = right - left; + float height = bottom - top; + float ratio = getAspectRatio().toFloat(); + int correctHeight = (int)width; + int correctWidth = (int)height; + + if (mGravity == GRAVITY_CENTER_FILL) { + if (mDisplayOrientationDetector.getLastKnownDisplayOrientation() % 180 != 0) { + if (ratio * height < width) { + correctHeight = (int) (width / ratio); + correctWidth = (int) width; + } else { + correctWidth = (int) (height * ratio); + correctHeight = (int) height; + } + } else { + if (ratio * width > height) { + correctHeight = (int) (width * ratio); + correctWidth = (int) width; + } else { + correctWidth = (int) (height / ratio); + correctHeight = (int) height; + } + } + } else if (mGravity == GRAVITY_CENTER_FIT) { + if (mDisplayOrientationDetector.getLastKnownDisplayOrientation() % 180 != 0) { + if (ratio * height > width) { + correctHeight = (int) (width / ratio); + correctWidth = (int) width; + } else { + correctWidth = (int) (height * ratio); + correctHeight = (int) height; + } + } else { + if (ratio * width < height) { + correctHeight = (int) (width * ratio); + correctWidth = (int) width; + } else { + correctWidth = (int) (height / ratio); + correctHeight = (int) height; + } + } + } + + int paddingX = (int) ((width - correctWidth) / 2); + int paddingY = (int) ((height - correctHeight) / 2); + preview.layout(paddingX, paddingY, correctWidth + paddingX, correctHeight + paddingY); + } + @Override protected Parcelable onSaveInstanceState() { SavedState state = new SavedState(super.onSaveInstanceState()); From 8bdee42ba4a0a12917d088d7f1c18a9abdc20519 Mon Sep 17 00:00:00 2001 From: Seifer Date: Thu, 28 Jun 2018 21:07:52 +0300 Subject: [PATCH 7/8] Ensure CameraView attributes loaded from the style --- .../google/android/cameraview/CameraView.java | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) 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 97a4895e..17fd2957 100644 --- a/library/src/main/java/com/google/android/cameraview/CameraView.java +++ b/library/src/main/java/com/google/android/cameraview/CameraView.java @@ -18,6 +18,7 @@ import android.app.Activity; import android.content.Context; +import android.content.res.TypedArray; import android.media.CamcorderProfile; import android.os.Build; import android.os.Parcel; @@ -122,7 +123,6 @@ public CameraView(Context context, AttributeSet attrs, int defStyleAttr, boolean mDisplayOrientationDetector = null; return; } - mAdjustViewBounds = true; mContext = context; // Internal setup @@ -136,6 +136,22 @@ public CameraView(Context context, AttributeSet attrs, int defStyleAttr, boolean mImpl = new Camera2Api23(mCallbacks, preview, context); } + // Attributes + TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CameraView, defStyleAttr, + R.style.Widget_CameraView); + mAdjustViewBounds = a.getBoolean(R.styleable.CameraView_android_adjustViewBounds, false); + setFacing(a.getInt(R.styleable.CameraView_facing, FACING_BACK)); + String aspectRatio = a.getString(R.styleable.CameraView_aspectRatio); + if (aspectRatio != null) { + setAspectRatio(AspectRatio.parse(aspectRatio)); + } else { + setAspectRatio(Constants.DEFAULT_ASPECT_RATIO); + } + setAutoFocus(a.getBoolean(R.styleable.CameraView_autoFocus, true)); + setFlash(a.getInt(R.styleable.CameraView_flash, FLASH_AUTO)); + setGravity(a.getInt(R.styleable.CameraView_gravity, GRAVITY_NONE)); + a.recycle(); + // Display orientation detector mDisplayOrientationDetector = new DisplayOrientationDetector(context) { @Override From ceb65eabbf27123ff79e65930a2c315c5d51f626 Mon Sep 17 00:00:00 2001 From: Seifer Date: Thu, 28 Jun 2018 21:08:18 +0300 Subject: [PATCH 8/8] Update portrait example to demonstrate gravity usage --- demo/src/main/res/layout/activity_main.xml | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/demo/src/main/res/layout/activity_main.xml b/demo/src/main/res/layout/activity_main.xml index 2acca63e..edc1739f 100644 --- a/demo/src/main/res/layout/activity_main.xml +++ b/demo/src/main/res/layout/activity_main.xml @@ -21,15 +21,25 @@ android:background="@color/primary" tools:context=".MainActivity"> + + android:layout_height="match_parent" + android:layout_margin="16dp" + android:scaleType="centerCrop" + android:background="@android:color/black" + app:gravity="centerFill"/> + + + + + + + + + +