-
-
Notifications
You must be signed in to change notification settings - Fork 529
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix: Ignore additional calls to start() when the controller is starting #1086
Changes from 23 commits
d19f1de
c816b39
47534ae
5b80d2c
14f5346
f81bb29
8236ee6
d1ac119
dbd5250
43e6cb5
5180812
196a4b0
9d1a70f
b5ce229
fd9941c
a57d460
47a0779
53a4134
4d92d5d
3ec0dc1
eda540f
8bc967c
e9b3ad4
d346a45
e967f54
447996d
ed3f54f
f5dd22d
c4bddc3
bb999fe
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -10,6 +10,7 @@ import androidx.camera.core.ExperimentalGetImage | |
import com.google.mlkit.vision.barcode.BarcodeScannerOptions | ||
import dev.steenbakker.mobile_scanner.objects.BarcodeFormats | ||
import dev.steenbakker.mobile_scanner.objects.DetectionSpeed | ||
import dev.steenbakker.mobile_scanner.objects.MobileScannerErrorCodes | ||
import io.flutter.plugin.common.BinaryMessenger | ||
import io.flutter.plugin.common.MethodCall | ||
import io.flutter.plugin.common.MethodChannel | ||
|
@@ -28,7 +29,7 @@ class MobileScannerHandler( | |
|
||
private val analyzeImageErrorCallback: AnalyzerErrorCallback = { | ||
Handler(Looper.getMainLooper()).post { | ||
analyzerResult?.error("MobileScanner", it, null) | ||
analyzerResult?.error(MobileScannerErrorCodes.BARCODE_ERROR, it, null) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. To be consistent with the results from the scanning stream, I used the same barcode error constant |
||
analyzerResult = null | ||
} | ||
} | ||
|
@@ -65,10 +66,7 @@ class MobileScannerHandler( | |
} | ||
|
||
private val errorCallback: MobileScannerErrorCallback = {error: String -> | ||
barcodeHandler.publishEvent(mapOf( | ||
"name" to "error", | ||
"data" to error, | ||
)) | ||
barcodeHandler.publishError(MobileScannerErrorCodes.BARCODE_ERROR, error, null) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is an actual error event now. |
||
} | ||
|
||
private var methodChannel: MethodChannel? = null | ||
|
@@ -106,21 +104,21 @@ class MobileScannerHandler( | |
|
||
@ExperimentalGetImage | ||
override fun onMethodCall(call: MethodCall, result: MethodChannel.Result) { | ||
if (mobileScanner == null) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This check isn't needed. The scanner is set up when attached to the activity |
||
result.error("MobileScanner", "Called ${call.method} before initializing.", null) | ||
return | ||
} | ||
when (call.method) { | ||
"state" -> result.success(permissions.hasCameraPermission(activity)) | ||
"request" -> permissions.requestPermission( | ||
activity, | ||
addPermissionListener, | ||
object: MobileScannerPermissions.ResultCallback { | ||
override fun onResult(errorCode: String?, errorDescription: String?) { | ||
override fun onResult(errorCode: String?) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Plumbing through the new error codes |
||
when(errorCode) { | ||
null -> result.success(true) | ||
MobileScannerPermissions.CAMERA_ACCESS_DENIED -> result.success(false) | ||
else -> result.error(errorCode, errorDescription, null) | ||
MobileScannerErrorCodes.CAMERA_ACCESS_DENIED -> result.success(false) | ||
MobileScannerErrorCodes.CAMERA_PERMISSIONS_REQUEST_ONGOING -> result.error( | ||
MobileScannerErrorCodes.CAMERA_PERMISSIONS_REQUEST_ONGOING, | ||
MobileScannerErrorCodes.CAMERA_PERMISSIONS_REQUEST_ONGOING_MESSAGE, null) | ||
else -> result.error( | ||
MobileScannerErrorCodes.GENERIC_ERROR, MobileScannerErrorCodes.GENERIC_ERROR_MESSAGE, null) | ||
} | ||
} | ||
}) | ||
|
@@ -185,29 +183,29 @@ class MobileScannerHandler( | |
when (it) { | ||
is AlreadyStarted -> { | ||
result.error( | ||
"MobileScanner", | ||
"Called start() while already started", | ||
MobileScannerErrorCodes.ALREADY_STARTED_ERROR, | ||
MobileScannerErrorCodes.ALREADY_STARTED_ERROR_MESSAGE, | ||
null | ||
) | ||
} | ||
is CameraError -> { | ||
result.error( | ||
"MobileScanner", | ||
"Error occurred when setting up camera!", | ||
MobileScannerErrorCodes.CAMERA_ERROR, | ||
MobileScannerErrorCodes.CAMERA_ERROR_MESSAGE, | ||
null | ||
) | ||
} | ||
is NoCamera -> { | ||
result.error( | ||
"MobileScanner", | ||
"No camera found or failed to open camera!", | ||
MobileScannerErrorCodes.NO_CAMERA_ERROR, | ||
MobileScannerErrorCodes.NO_CAMERA_ERROR_MESSAGE, | ||
null | ||
) | ||
} | ||
else -> { | ||
result.error( | ||
"MobileScanner", | ||
"Unknown error occurred.", | ||
MobileScannerErrorCodes.GENERIC_ERROR, | ||
MobileScannerErrorCodes.GENERIC_ERROR_MESSAGE, | ||
null | ||
) | ||
} | ||
|
@@ -252,9 +250,11 @@ class MobileScannerHandler( | |
mobileScanner!!.setScale(call.arguments as Double) | ||
result.success(null) | ||
} catch (e: ZoomWhenStopped) { | ||
result.error("MobileScanner", "Called setScale() while stopped!", null) | ||
result.error( | ||
MobileScannerErrorCodes.SET_SCALE_WHEN_STOPPED_ERROR, MobileScannerErrorCodes.SET_SCALE_WHEN_STOPPED_ERROR_MESSAGE, null) | ||
} catch (e: ZoomNotInRange) { | ||
result.error("MobileScanner", "Scale should be within 0 and 1", null) | ||
result.error( | ||
MobileScannerErrorCodes.GENERIC_ERROR, MobileScannerErrorCodes.INVALID_ZOOM_SCALE_ERROR_MESSAGE, null) | ||
} | ||
} | ||
|
||
|
@@ -263,7 +263,8 @@ class MobileScannerHandler( | |
mobileScanner!!.resetScale() | ||
result.success(null) | ||
} catch (e: ZoomWhenStopped) { | ||
result.error("MobileScanner", "Called resetScale() while stopped!", null) | ||
result.error( | ||
MobileScannerErrorCodes.SET_SCALE_WHEN_STOPPED_ERROR, MobileScannerErrorCodes.SET_SCALE_WHEN_STOPPED_ERROR_MESSAGE, null) | ||
} | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,18 +5,14 @@ import android.app.Activity | |
import android.content.pm.PackageManager | ||
import androidx.core.app.ActivityCompat | ||
import androidx.core.content.ContextCompat | ||
import dev.steenbakker.mobile_scanner.objects.MobileScannerErrorCodes | ||
import io.flutter.plugin.common.PluginRegistry.RequestPermissionsResultListener | ||
|
||
/** | ||
* This class handles the camera permissions for the Mobile Scanner. | ||
*/ | ||
class MobileScannerPermissions { | ||
companion object { | ||
const val CAMERA_ACCESS_DENIED = "CameraAccessDenied" | ||
const val CAMERA_ACCESS_DENIED_MESSAGE = "Camera access permission was denied." | ||
const val CAMERA_PERMISSIONS_REQUEST_ONGOING = "CameraPermissionsRequestOngoing" | ||
const val CAMERA_PERMISSIONS_REQUEST_ONGOING_MESSAGE = "Another request is ongoing and multiple requests cannot be handled at once." | ||
|
||
/** | ||
* When the application's activity is [androidx.fragment.app.FragmentActivity], requestCode can only use the lower 16 bits. | ||
* @see androidx.fragment.app.FragmentActivity.validateRequestPermissionsRequestCode | ||
|
@@ -25,7 +21,7 @@ class MobileScannerPermissions { | |
} | ||
|
||
interface ResultCallback { | ||
fun onResult(errorCode: String?, errorDescription: String?) | ||
fun onResult(errorCode: String?) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The second argument was unused, since we return a bool to the interface |
||
} | ||
|
||
private var listener: RequestPermissionsResultListener? = null | ||
|
@@ -53,25 +49,24 @@ class MobileScannerPermissions { | |
addPermissionListener: (RequestPermissionsResultListener) -> Unit, | ||
callback: ResultCallback) { | ||
if (ongoing) { | ||
callback.onResult( | ||
CAMERA_PERMISSIONS_REQUEST_ONGOING, CAMERA_PERMISSIONS_REQUEST_ONGOING_MESSAGE) | ||
callback.onResult(MobileScannerErrorCodes.CAMERA_PERMISSIONS_REQUEST_ONGOING) | ||
return | ||
} | ||
|
||
if(hasCameraPermission(activity) == 1) { | ||
// Permissions already exist. Call the callback with success. | ||
callback.onResult(null, null) | ||
callback.onResult(null) | ||
return | ||
} | ||
|
||
if(listener == null) { | ||
// Keep track of the listener, so that it can be unregistered later. | ||
listener = MobileScannerPermissionsListener( | ||
object: ResultCallback { | ||
override fun onResult(errorCode: String?, errorDescription: String?) { | ||
override fun onResult(errorCode: String?) { | ||
ongoing = false | ||
listener = null | ||
callback.onResult(errorCode, errorDescription) | ||
callback.onResult(errorCode) | ||
} | ||
} | ||
) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -42,7 +42,10 @@ public class MobileScannerPlugin: NSObject, FlutterPlugin { | |
init(barcodeHandler: BarcodeHandler, registry: FlutterTextureRegistry) { | ||
self.mobileScanner = MobileScanner(registry: registry, mobileScannerCallback: { barcodes, error, image in | ||
if error != nil { | ||
barcodeHandler.publishEvent(["name": "error", "data": error!.localizedDescription]) | ||
barcodeHandler.publishError( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is an actual error event now |
||
FlutterError(code: MobileScannerErrorCodes.BARCODE_ERROR, | ||
message: error?.localizedDescription, | ||
details: nil)) | ||
return | ||
} | ||
|
||
|
@@ -150,20 +153,20 @@ public class MobileScannerPlugin: NSObject, FlutterPlugin { | |
} | ||
} | ||
} catch MobileScannerError.alreadyStarted { | ||
result(FlutterError(code: "MobileScanner", | ||
message: "Called start() while already started!", | ||
result(FlutterError(code: MobileScannerErrorCodes.ALREADY_STARTED_ERROR, | ||
message: MobileScannerErrorCodes.ALREADY_STARTED_ERROR_MESSAGE, | ||
details: nil)) | ||
} catch MobileScannerError.noCamera { | ||
result(FlutterError(code: "MobileScanner", | ||
message: "No camera found or failed to open camera!", | ||
result(FlutterError(code: MobileScannerErrorCodes.NO_CAMERA_ERROR, | ||
message: MobileScannerErrorCodes.NO_CAMERA_ERROR_MESSAGE, | ||
details: nil)) | ||
} catch MobileScannerError.cameraError(let error) { | ||
result(FlutterError(code: "MobileScanner", | ||
message: "Error occured when setting up camera!", | ||
details: error)) | ||
result(FlutterError(code: MobileScannerErrorCodes.CAMERA_ERROR, | ||
message: error.localizedDescription, | ||
details: nil)) | ||
} catch { | ||
result(FlutterError(code: "MobileScanner", | ||
message: "Unknown error occured.", | ||
result(FlutterError(code: MobileScannerErrorCodes.GENERIC_ERROR, | ||
message: MobileScannerErrorCodes.GENERIC_ERROR_MESSAGE, | ||
details: nil)) | ||
} | ||
} | ||
|
@@ -186,25 +189,25 @@ public class MobileScannerPlugin: NSObject, FlutterPlugin { | |
private func setScale(_ call: FlutterMethodCall, _ result: @escaping FlutterResult) { | ||
let scale = call.arguments as? CGFloat | ||
if (scale == nil) { | ||
result(FlutterError(code: "MobileScanner", | ||
message: "You must provide a scale when calling setScale!", | ||
details: nil)) | ||
result(FlutterError(code: MobileScannerErrorCodes.GENERIC_ERROR, | ||
message: MobileScannerErrorCodes.INVALID_ZOOM_SCALE_ERROR_MESSAGE, | ||
details: "The invalid zoom scale was nil.")) | ||
return | ||
} | ||
do { | ||
try mobileScanner.setScale(scale!) | ||
result(nil) | ||
} catch MobileScannerError.zoomWhenStopped { | ||
result(FlutterError(code: "MobileScanner", | ||
message: "Called setScale() while stopped!", | ||
result(FlutterError(code: MobileScannerErrorCodes.SET_SCALE_WHEN_STOPPED_ERROR, | ||
message: MobileScannerErrorCodes.SET_SCALE_WHEN_STOPPED_ERROR_MESSAGE, | ||
details: nil)) | ||
} catch MobileScannerError.zoomError(let error) { | ||
result(FlutterError(code: "MobileScanner", | ||
message: "Error while zooming.", | ||
details: error)) | ||
result(FlutterError(code: MobileScannerErrorCodes.GENERIC_ERROR, | ||
message: error.localizedDescription, | ||
details: nil)) | ||
} catch { | ||
result(FlutterError(code: "MobileScanner", | ||
message: "Error while zooming.", | ||
result(FlutterError(code: MobileScannerErrorCodes.GENERIC_ERROR, | ||
message: MobileScannerErrorCodes.GENERIC_ERROR_MESSAGE, | ||
details: nil)) | ||
} | ||
} | ||
|
@@ -215,16 +218,16 @@ public class MobileScannerPlugin: NSObject, FlutterPlugin { | |
try mobileScanner.resetScale() | ||
result(nil) | ||
} catch MobileScannerError.zoomWhenStopped { | ||
result(FlutterError(code: "MobileScanner", | ||
message: "Called resetScale() while stopped!", | ||
result(FlutterError(code: MobileScannerErrorCodes.SET_SCALE_WHEN_STOPPED_ERROR, | ||
message: MobileScannerErrorCodes.SET_SCALE_WHEN_STOPPED_ERROR_MESSAGE, | ||
details: nil)) | ||
} catch MobileScannerError.zoomError(let error) { | ||
result(FlutterError(code: "MobileScanner", | ||
message: "Error while zooming.", | ||
details: error)) | ||
result(FlutterError(code: MobileScannerErrorCodes.GENERIC_ERROR, | ||
message: error.localizedDescription, | ||
details: nil)) | ||
} catch { | ||
result(FlutterError(code: "MobileScanner", | ||
message: "Error while zooming.", | ||
result(FlutterError(code: MobileScannerErrorCodes.GENERIC_ERROR, | ||
message: MobileScannerErrorCodes.GENERIC_ERROR_MESSAGE, | ||
details: nil)) | ||
} | ||
} | ||
|
@@ -266,7 +269,7 @@ public class MobileScannerPlugin: NSObject, FlutterPlugin { | |
barcodeScannerOptions: scannerOptions, callback: { barcodes, error in | ||
if error != nil { | ||
DispatchQueue.main.async { | ||
result(FlutterError(code: "MobileScanner", | ||
result(FlutterError(code: MobileScannerErrorCodes.BARCODE_ERROR, | ||
message: error?.localizedDescription, | ||
details: nil)) | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Like
publishEvent
above, but forresult.error()