mirror of
https://github.com/Yubico/yubioath-flutter.git
synced 2024-12-23 18:22:39 +03:00
Merge PR #280.
This commit is contained in:
commit
10c207c337
@ -2,7 +2,7 @@ group 'com.yubico.authenticator.flutter_plugins.qrscanner_zxing'
|
||||
version '1.0'
|
||||
|
||||
buildscript {
|
||||
ext.kotlin_version = '1.7.10'
|
||||
ext.kotlin_version = '1.7.20'
|
||||
repositories {
|
||||
google()
|
||||
mavenCentral()
|
||||
|
@ -149,7 +149,7 @@ internal class QRScannerView(
|
||||
imageAnalysis = null
|
||||
cameraExecutor.shutdown()
|
||||
methodChannel.setMethodCallHandler(null)
|
||||
Log.d(TAG, "View disposed")
|
||||
Log.v(TAG, "dispose()")
|
||||
}
|
||||
|
||||
private val methodChannel: MethodChannel = MethodChannel(binaryMessenger, CHANNEL_NAME)
|
||||
@ -166,12 +166,16 @@ internal class QRScannerView(
|
||||
}
|
||||
}
|
||||
|
||||
Log.v(TAG, "marginPct: $marginPct")
|
||||
|
||||
if (context is Activity) {
|
||||
permissionsGranted = allPermissionsGranted(context)
|
||||
|
||||
if (!permissionsGranted) {
|
||||
Log.v(TAG, "permissionsGranted = false -> requesting permission")
|
||||
requestPermissionsFromUser(context)
|
||||
} else {
|
||||
Log.v(TAG, "permissionsGranted = true -> binding use cases")
|
||||
bindUseCases(context)
|
||||
}
|
||||
|
||||
@ -293,10 +297,15 @@ internal class QRScannerView(
|
||||
it.setHints(mapOf(DecodeHintType.POSSIBLE_FORMATS to listOf(BarcodeFormat.QR_CODE)))
|
||||
}
|
||||
|
||||
private fun ByteBuffer.toByteArray(): ByteArray {
|
||||
var analyzedImagesCount = 0
|
||||
|
||||
private fun ByteBuffer.toByteArray(lastRowPadding: Int): ByteArray {
|
||||
rewind()
|
||||
val data = ByteArray(remaining())
|
||||
get(data)
|
||||
val size = remaining()
|
||||
val paddedSize = size + lastRowPadding
|
||||
val data = ByteArray(paddedSize)
|
||||
get(data, 0, size)
|
||||
data.fill(0, size, paddedSize)
|
||||
return data
|
||||
}
|
||||
|
||||
@ -307,13 +316,58 @@ internal class QRScannerView(
|
||||
return
|
||||
}
|
||||
|
||||
val buffer = imageProxy.planes[0].buffer
|
||||
val intArray = buffer.toByteArray().map { it.toInt() }.toIntArray()
|
||||
val plane0 = imageProxy.planes[0]
|
||||
|
||||
val source: LuminanceSource =
|
||||
RGBLuminanceSource(imageProxy.width, imageProxy.height, intArray)
|
||||
if (analyzedImagesCount == 0) {
|
||||
Log.v(TAG, "First image received for analysis:")
|
||||
Log.v(TAG, " Image format: ${imageProxy.format}")
|
||||
Log.v(TAG, " WxH: ${imageProxy.width}x${imageProxy.height}")
|
||||
|
||||
val fullSize = BinaryBitmap(HybridBinarizer(source))
|
||||
for (indexedPlane in imageProxy.planes.withIndex()) {
|
||||
val index = indexedPlane.index
|
||||
val plane = indexedPlane.value
|
||||
|
||||
try {
|
||||
Log.v(TAG, " plane[$index].rowStride: ${plane.rowStride} ")
|
||||
} catch (_: UnsupportedOperationException) {
|
||||
Log.v(TAG, " plane[$index].rowStride: Unsupported Operation")
|
||||
}
|
||||
try {
|
||||
Log.v(TAG, " plane[$index].pixelStride: ${plane.pixelStride}")
|
||||
} catch (_: UnsupportedOperationException) {
|
||||
Log.v(TAG, " plane[$index].pixelStride: Unsupported Operation")
|
||||
}
|
||||
|
||||
Log.v(TAG, " plane[$index].buffer.size: ${plane.buffer.toByteArray(0).size}")
|
||||
}
|
||||
}
|
||||
|
||||
val buffer = plane0.buffer
|
||||
val rowStride = plane0.rowStride
|
||||
|
||||
// the new array has to pad extra size for situation when rowStride > image width
|
||||
val intArray =
|
||||
buffer.toByteArray(rowStride - imageProxy.width).map { it.toInt() }.toIntArray()
|
||||
|
||||
val planeLuminanceSource =
|
||||
RGBLuminanceSource(rowStride, imageProxy.height, intArray)
|
||||
|
||||
val luminanceSource =
|
||||
if (rowStride > imageProxy.width && planeLuminanceSource.isCropSupported) {
|
||||
if (analyzedImagesCount == 0) {
|
||||
Log.v(
|
||||
TAG, " row stride greater than image -> "+
|
||||
"cropping luminance source of size " +
|
||||
"${plane0.rowStride}x${imageProxy.height} to " +
|
||||
"${imageProxy.width}x${imageProxy.height}"
|
||||
)
|
||||
}
|
||||
planeLuminanceSource.crop(0, 0, imageProxy.width, imageProxy.height)
|
||||
} else {
|
||||
planeLuminanceSource
|
||||
}
|
||||
|
||||
val fullSize = BinaryBitmap(HybridBinarizer(luminanceSource))
|
||||
|
||||
val bitmapToProcess = if (marginPct != null) {
|
||||
val shorterDim = min(imageProxy.width, imageProxy.height)
|
||||
@ -321,6 +375,9 @@ internal class QRScannerView(
|
||||
val cropWH = shorterDim - 2.0 * cropMargin
|
||||
val cropT = (imageProxy.height - cropWH) / 2.0
|
||||
val cropL = (imageProxy.width - cropWH) / 2.0
|
||||
if(analyzedImagesCount == 0) {
|
||||
Log.v(TAG, " bitmap l:t:w:h $cropL:$cropT:$cropWH:$cropWH")
|
||||
}
|
||||
fullSize.crop(
|
||||
cropL.toInt(),
|
||||
cropT.toInt(),
|
||||
@ -328,18 +385,31 @@ internal class QRScannerView(
|
||||
cropWH.toInt()
|
||||
)
|
||||
} else {
|
||||
if(analyzedImagesCount == 0) {
|
||||
Log.v(
|
||||
TAG,
|
||||
" bitmap l:t:w:h 0:0:${imageProxy.width}:${imageProxy.height} (full size)"
|
||||
)
|
||||
}
|
||||
fullSize
|
||||
}
|
||||
|
||||
val result: com.google.zxing.Result = multiFormatReader.decode(bitmapToProcess)
|
||||
analysisPaused = true // pause
|
||||
Log.d(TAG, "Analysis result: ${result.text}")
|
||||
Log.v(TAG, "Analysis result: ${result.text}")
|
||||
listener.invoke(Result.success(result.text))
|
||||
} catch (_: NotFoundException) {
|
||||
// ignored: no code was found
|
||||
if (analyzedImagesCount == 0) {
|
||||
Log.v(TAG, " No QR code found (NotFoundException)")
|
||||
}
|
||||
} finally {
|
||||
// important call
|
||||
imageProxy.close()
|
||||
analyzedImagesCount++
|
||||
|
||||
if (analyzedImagesCount % 50 == 0) {
|
||||
Log.v(TAG, "Count of analyzed images so far: $analyzedImagesCount")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -348,14 +418,14 @@ internal class QRScannerView(
|
||||
private var cameraOpened: Boolean = false
|
||||
|
||||
override fun onChanged(t: CameraState) {
|
||||
Log.d(TAG, "Camera state changed to ${t.type}")
|
||||
Log.v(TAG, "Camera state changed to ${t.type}")
|
||||
|
||||
if (t.type == CameraState.Type.OPEN) {
|
||||
cameraOpened = true
|
||||
}
|
||||
|
||||
if (cameraOpened && t.type == CameraState.Type.CLOSED) {
|
||||
Log.d(TAG, "Camera closed")
|
||||
Log.v(TAG, "Camera closed")
|
||||
val stateChangedIntent =
|
||||
Intent("com.yubico.authenticator.QRScannerView.CameraClosed")
|
||||
context.sendBroadcast(stateChangedIntent)
|
||||
|
@ -26,7 +26,7 @@ apply plugin: 'kotlin-android'
|
||||
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
|
||||
|
||||
android {
|
||||
compileSdkVersion flutter.compileSdkVersion
|
||||
compileSdkVersion 33
|
||||
ndkVersion flutter.ndkVersion
|
||||
|
||||
compileOptions {
|
||||
@ -48,7 +48,7 @@ android {
|
||||
// You can update the following values to match your application needs.
|
||||
// For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-build-configuration.
|
||||
minSdkVersion 21
|
||||
targetSdkVersion flutter.targetSdkVersion
|
||||
targetSdkVersion 33
|
||||
versionCode flutterVersionCode.toInteger()
|
||||
versionName flutterVersionName
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
package="com.yubico.authenticator.flutter_plugins.qrscanner_zxing_example">
|
||||
<application
|
||||
android:label="qrscanner_zxing_example"
|
||||
android:name="${applicationName}"
|
||||
android:name=".App"
|
||||
android:icon="@mipmap/ic_launcher">
|
||||
<activity
|
||||
android:name=".MainActivity"
|
||||
|
@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright (C) 2022 Yubico.
|
||||
*
|
||||
* 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.yubico.authenticator.flutter_plugins.qrscanner_zxing_example
|
||||
|
||||
import android.os.StrictMode
|
||||
import io.flutter.app.FlutterApplication
|
||||
|
||||
class App : FlutterApplication() {
|
||||
init {
|
||||
if (BuildConfig.DEBUG) {
|
||||
StrictMode.enableDefaults()
|
||||
}
|
||||
}
|
||||
}
|
@ -1,12 +1,12 @@
|
||||
buildscript {
|
||||
ext.kotlin_version = '1.6.10'
|
||||
ext.kotlin_version = '1.7.20'
|
||||
repositories {
|
||||
google()
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:7.1.2'
|
||||
classpath 'com.android.tools.build:gradle:7.1.3'
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user