Navaron Bracke

implement start() for native

@@ -4,13 +4,15 @@ import 'dart:io'; @@ -4,13 +4,15 @@ import 'dart:io';
4 import 'package:flutter/services.dart'; 4 import 'package:flutter/services.dart';
5 import 'package:flutter/widgets.dart'; 5 import 'package:flutter/widgets.dart';
6 import 'package:mobile_scanner/src/enums/barcode_format.dart'; 6 import 'package:mobile_scanner/src/enums/barcode_format.dart';
7 -import 'package:mobile_scanner/src/enums/camera_facing.dart';  
8 import 'package:mobile_scanner/src/enums/mobile_scanner_error_code.dart'; 7 import 'package:mobile_scanner/src/enums/mobile_scanner_error_code.dart';
  8 +import 'package:mobile_scanner/src/enums/mobile_scanner_state.dart';
9 import 'package:mobile_scanner/src/enums/torch_state.dart'; 9 import 'package:mobile_scanner/src/enums/torch_state.dart';
10 import 'package:mobile_scanner/src/mobile_scanner_exception.dart'; 10 import 'package:mobile_scanner/src/mobile_scanner_exception.dart';
11 import 'package:mobile_scanner/src/mobile_scanner_platform_interface.dart'; 11 import 'package:mobile_scanner/src/mobile_scanner_platform_interface.dart';
  12 +import 'package:mobile_scanner/src/mobile_scanner_view_attributes.dart';
12 import 'package:mobile_scanner/src/objects/barcode.dart'; 13 import 'package:mobile_scanner/src/objects/barcode.dart';
13 import 'package:mobile_scanner/src/objects/barcode_capture.dart'; 14 import 'package:mobile_scanner/src/objects/barcode_capture.dart';
  15 +import 'package:mobile_scanner/src/objects/start_options.dart';
14 16
15 /// An implementation of [MobileScannerPlatform] that uses method channels. 17 /// An implementation of [MobileScannerPlatform] that uses method channels.
16 class MethodChannelMobileScanner extends MobileScannerPlatform { 18 class MethodChannelMobileScanner extends MobileScannerPlatform {
@@ -29,8 +31,7 @@ class MethodChannelMobileScanner extends MobileScannerPlatform { @@ -29,8 +31,7 @@ class MethodChannelMobileScanner extends MobileScannerPlatform {
29 Stream<Map<Object?, Object?>>? _eventsStream; 31 Stream<Map<Object?, Object?>>? _eventsStream;
30 32
31 Stream<Map<Object?, Object?>> get eventsStream { 33 Stream<Map<Object?, Object?>> get eventsStream {
32 - _eventsStream ??=  
33 - eventChannel.receiveBroadcastStream().cast<Map<Object?, Object?>>(); 34 + _eventsStream ??= eventChannel.receiveBroadcastStream().cast<Map<Object?, Object?>>();
34 35
35 return _eventsStream!; 36 return _eventsStream!;
36 } 37 }
@@ -200,7 +201,74 @@ class MethodChannelMobileScanner extends MobileScannerPlatform { @@ -200,7 +201,74 @@ class MethodChannelMobileScanner extends MobileScannerPlatform {
200 } 201 }
201 202
202 @override 203 @override
203 - Future<void> start(CameraFacing cameraDirection) {} 204 + Future<MobileScannerViewAttributes> start(StartOptions startOptions) async {
  205 + if (_textureId != null) {
  206 + throw const MobileScannerException(
  207 + errorCode: MobileScannerErrorCode.controllerAlreadyInitialized,
  208 + errorDetails: MobileScannerErrorDetails(
  209 + message: 'The scanner was already started. Call stop() before calling start() again.',
  210 + ),
  211 + );
  212 + }
  213 +
  214 + await _requestCameraPermission();
  215 +
  216 + Map<String, Object?>? startResult;
  217 +
  218 + try {
  219 + startResult = await methodChannel.invokeMapMethod<String, Object?>(
  220 + 'start',
  221 + startOptions.toMap(),
  222 + );
  223 + } on PlatformException catch (error) {
  224 + throw MobileScannerException(
  225 + errorCode: MobileScannerErrorCode.genericError,
  226 + errorDetails: MobileScannerErrorDetails(
  227 + code: error.code,
  228 + details: error.details as Object?,
  229 + message: error.message,
  230 + ),
  231 + );
  232 + }
  233 +
  234 + if (startResult == null) {
  235 + throw const MobileScannerException(
  236 + errorCode: MobileScannerErrorCode.genericError,
  237 + errorDetails: MobileScannerErrorDetails(
  238 + message: 'The start method did not return a view configuration.',
  239 + ),
  240 + );
  241 + }
  242 +
  243 + final int? textureId = startResult['textureId'] as int?;
  244 +
  245 + if (textureId == null) {
  246 + throw const MobileScannerException(
  247 + errorCode: MobileScannerErrorCode.genericError,
  248 + errorDetails: MobileScannerErrorDetails(
  249 + message: 'The start method did not return a texture id.',
  250 + ),
  251 + );
  252 + }
  253 +
  254 + _textureId = textureId;
  255 +
  256 + final bool hasTorch = startResult['torchable'] as bool? ?? false;
  257 +
  258 + final Map<Object?, Object?>? sizeInfo = startResult['size'] as Map<Object?, Object?>?;
  259 + final double? width = sizeInfo?['width'] as double?;
  260 + final double? height = sizeInfo?['height'] as double?;
  261 +
  262 + final Size size;
  263 +
  264 + if (width == null || height == null) {
  265 + size = Size.zero;
  266 + } else {
  267 + size = Size(width, height);
  268 + }
  269 +
  270 + return MobileScannerViewAttributes(hasTorch: hasTorch, size: size);
  271 + }
204 272
205 @override 273 @override
206 Future<void> stop() async { 274 Future<void> stop() async {