[image_picker] Migrate to null-safety (#3524)

Migrate image_picker to null-safety
diff --git a/packages/image_picker/image_picker/CHANGELOG.md b/packages/image_picker/image_picker/CHANGELOG.md
index 1a09758..c6b29f2 100644
--- a/packages/image_picker/image_picker/CHANGELOG.md
+++ b/packages/image_picker/image_picker/CHANGELOG.md
@@ -1,3 +1,9 @@
+## 0.7.0-nullsafety
+* Migrate to nullsafety
+* Breaking Changes:
+    * Removed the deprecated methods: `ImagePicker.pickImage`, `ImagePicker.pickVideo`,
+`ImagePicker.retrieveLostData`
+
 ## 0.6.7+22
 
 * iOS: update XCUITests to separate each test session.
diff --git a/packages/image_picker/image_picker/example/lib/main.dart b/packages/image_picker/image_picker/example/lib/main.dart
index 73327ef..54e3a1a 100755
--- a/packages/image_picker/image_picker/example/lib/main.dart
+++ b/packages/image_picker/image_picker/example/lib/main.dart
@@ -29,60 +29,63 @@
 }
 
 class MyHomePage extends StatefulWidget {
-  MyHomePage({Key key, this.title}) : super(key: key);
+  MyHomePage({Key? key, this.title}) : super(key: key);
 
-  final String title;
+  final String? title;
 
   @override
   _MyHomePageState createState() => _MyHomePageState();
 }
 
 class _MyHomePageState extends State<MyHomePage> {
-  PickedFile _imageFile;
+  PickedFile? _imageFile;
   dynamic _pickImageError;
   bool isVideo = false;
-  VideoPlayerController _controller;
-  VideoPlayerController _toBeDisposed;
-  String _retrieveDataError;
+  VideoPlayerController? _controller;
+  VideoPlayerController? _toBeDisposed;
+  String? _retrieveDataError;
 
   final ImagePicker _picker = ImagePicker();
   final TextEditingController maxWidthController = TextEditingController();
   final TextEditingController maxHeightController = TextEditingController();
   final TextEditingController qualityController = TextEditingController();
 
-  Future<void> _playVideo(PickedFile file) async {
+  Future<void> _playVideo(PickedFile? file) async {
     if (file != null && mounted) {
       await _disposeVideoController();
+      late VideoPlayerController controller;
       if (kIsWeb) {
-        _controller = VideoPlayerController.network(file.path);
-        // In web, most browsers won't honor a programmatic call to .play
-        // if the video has a sound track (and is not muted).
-        // Mute the video so it auto-plays in web!
-        // This is not needed if the call to .play is the result of user
-        // interaction (clicking on a "play" button, for example).
-        await _controller.setVolume(0.0);
+        controller = VideoPlayerController.network(file.path);
       } else {
-        _controller = VideoPlayerController.file(File(file.path));
-        await _controller.setVolume(1.0);
+        controller = VideoPlayerController.file(File(file.path));
       }
-      await _controller.initialize();
-      await _controller.setLooping(true);
-      await _controller.play();
+      _controller = controller;
+      // In web, most browsers won't honor a programmatic call to .play
+      // if the video has a sound track (and is not muted).
+      // Mute the video so it auto-plays in web!
+      // This is not needed if the call to .play is the result of user
+      // interaction (clicking on a "play" button, for example).
+      final double volume = kIsWeb ? 0.0 : 1.0;
+      await controller.setVolume(volume);
+      await controller.initialize();
+      await controller.setLooping(true);
+      await controller.play();
       setState(() {});
     }
   }
 
-  void _onImageButtonPressed(ImageSource source, {BuildContext context}) async {
+  void _onImageButtonPressed(ImageSource source,
+      {BuildContext? context}) async {
     if (_controller != null) {
-      await _controller.setVolume(0.0);
+      await _controller!.setVolume(0.0);
     }
     if (isVideo) {
-      final PickedFile file = await _picker.getVideo(
+      final PickedFile? file = await _picker.getVideo(
           source: source, maxDuration: const Duration(seconds: 10));
       await _playVideo(file);
     } else {
-      await _displayPickImageDialog(context,
-          (double maxWidth, double maxHeight, int quality) async {
+      await _displayPickImageDialog(context!,
+          (double? maxWidth, double? maxHeight, int? quality) async {
         try {
           final pickedFile = await _picker.getImage(
             source: source,
@@ -105,8 +108,8 @@
   @override
   void deactivate() {
     if (_controller != null) {
-      _controller.setVolume(0.0);
-      _controller.pause();
+      _controller!.setVolume(0.0);
+      _controller!.pause();
     }
     super.deactivate();
   }
@@ -122,14 +125,14 @@
 
   Future<void> _disposeVideoController() async {
     if (_toBeDisposed != null) {
-      await _toBeDisposed.dispose();
+      await _toBeDisposed!.dispose();
     }
     _toBeDisposed = _controller;
     _controller = null;
   }
 
   Widget _previewVideo() {
-    final Text retrieveError = _getRetrieveErrorWidget();
+    final Text? retrieveError = _getRetrieveErrorWidget();
     if (retrieveError != null) {
       return retrieveError;
     }
@@ -146,7 +149,7 @@
   }
 
   Widget _previewImage() {
-    final Text retrieveError = _getRetrieveErrorWidget();
+    final Text? retrieveError = _getRetrieveErrorWidget();
     if (retrieveError != null) {
       return retrieveError;
     }
@@ -154,10 +157,10 @@
       if (kIsWeb) {
         // Why network?
         // See https://pub.dev/packages/image_picker#getting-ready-for-the-web-platform
-        return Image.network(_imageFile.path);
+        return Image.network(_imageFile!.path);
       } else {
         return Semantics(
-            child: Image.file(File(_imageFile.path)),
+            child: Image.file(File(_imageFile!.path)),
             label: 'image_picker_example_picked_image');
       }
     } else if (_pickImageError != null) {
@@ -189,7 +192,7 @@
         });
       }
     } else {
-      _retrieveDataError = response.exception.code;
+      _retrieveDataError = response.exception!.code;
     }
   }
 
@@ -197,7 +200,7 @@
   Widget build(BuildContext context) {
     return Scaffold(
       appBar: AppBar(
-        title: Text(widget.title),
+        title: Text(widget.title!),
       ),
       body: Center(
         child: !kIsWeb && defaultTargetPlatform == TargetPlatform.android
@@ -288,9 +291,9 @@
     );
   }
 
-  Text _getRetrieveErrorWidget() {
+  Text? _getRetrieveErrorWidget() {
     if (_retrieveDataError != null) {
-      final Text result = Text(_retrieveDataError);
+      final Text result = Text(_retrieveDataError!);
       _retrieveDataError = null;
       return result;
     }
@@ -336,13 +339,13 @@
               TextButton(
                   child: const Text('PICK'),
                   onPressed: () {
-                    double width = maxWidthController.text.isNotEmpty
+                    double? width = maxWidthController.text.isNotEmpty
                         ? double.parse(maxWidthController.text)
                         : null;
-                    double height = maxHeightController.text.isNotEmpty
+                    double? height = maxHeightController.text.isNotEmpty
                         ? double.parse(maxHeightController.text)
                         : null;
-                    int quality = qualityController.text.isNotEmpty
+                    int? quality = qualityController.text.isNotEmpty
                         ? int.parse(qualityController.text)
                         : null;
                     onPick(width, height, quality);
@@ -355,27 +358,27 @@
 }
 
 typedef void OnPickImageCallback(
-    double maxWidth, double maxHeight, int quality);
+    double? maxWidth, double? maxHeight, int? quality);
 
 class AspectRatioVideo extends StatefulWidget {
   AspectRatioVideo(this.controller);
 
-  final VideoPlayerController controller;
+  final VideoPlayerController? controller;
 
   @override
   AspectRatioVideoState createState() => AspectRatioVideoState();
 }
 
 class AspectRatioVideoState extends State<AspectRatioVideo> {
-  VideoPlayerController get controller => widget.controller;
+  VideoPlayerController? get controller => widget.controller;
   bool initialized = false;
 
   void _onVideoControllerUpdate() {
     if (!mounted) {
       return;
     }
-    if (initialized != controller.value.initialized) {
-      initialized = controller.value.initialized;
+    if (initialized != controller!.value.isInitialized) {
+      initialized = controller!.value.isInitialized;
       setState(() {});
     }
   }
@@ -383,12 +386,12 @@
   @override
   void initState() {
     super.initState();
-    controller.addListener(_onVideoControllerUpdate);
+    controller!.addListener(_onVideoControllerUpdate);
   }
 
   @override
   void dispose() {
-    controller.removeListener(_onVideoControllerUpdate);
+    controller!.removeListener(_onVideoControllerUpdate);
     super.dispose();
   }
 
@@ -397,8 +400,8 @@
     if (initialized) {
       return Center(
         child: AspectRatio(
-          aspectRatio: controller.value?.aspectRatio,
-          child: VideoPlayer(controller),
+          aspectRatio: controller!.value.aspectRatio,
+          child: VideoPlayer(controller!),
         ),
       );
     } else {
diff --git a/packages/image_picker/image_picker/example/pubspec.yaml b/packages/image_picker/image_picker/example/pubspec.yaml
index 0ff2f28..44364a1 100755
--- a/packages/image_picker/image_picker/example/pubspec.yaml
+++ b/packages/image_picker/image_picker/example/pubspec.yaml
@@ -3,24 +3,23 @@
 author: Flutter Team <flutter-dev@googlegroups.com>
 
 dependencies:
-  video_player: ^0.10.3
+  video_player: ^2.0.0-nullsafety.7
   flutter:
     sdk: flutter
-  flutter_plugin_android_lifecycle: ^1.0.2
+  flutter_plugin_android_lifecycle: ^2.0.0-nullsafety.2
   image_picker:
     path: ../
-  image_picker_for_web: ^0.1.0
 
 dev_dependencies:
   flutter_driver:
     sdk: flutter
   integration_test:
     path: ../../../integration_test
-  pedantic: ^1.8.0
+  pedantic: ^1.10.0
 
 flutter:
   uses-material-design: true
 
 environment:
-  sdk: ">=2.0.0-dev.28.0 <3.0.0"
+  sdk: ">=2.12.0-0 <3.0.0"
   flutter: ">=1.10.0 <2.0.0"
diff --git a/packages/image_picker/image_picker/integration_test/old_image_picker_test.dart b/packages/image_picker/image_picker/integration_test/old_image_picker_test.dart
index d21a4e0..76c971c 100644
--- a/packages/image_picker/image_picker/integration_test/old_image_picker_test.dart
+++ b/packages/image_picker/image_picker/integration_test/old_image_picker_test.dart
@@ -1,3 +1,5 @@
+// @dart=2.9
+
 import 'package:integration_test/integration_test.dart';
 
 void main() {
diff --git a/packages/image_picker/image_picker/lib/image_picker.dart b/packages/image_picker/image_picker/lib/image_picker.dart
index 5c0683c..2231510 100755
--- a/packages/image_picker/image_picker/lib/image_picker.dart
+++ b/packages/image_picker/image_picker/lib/image_picker.dart
@@ -5,7 +5,6 @@
 // ignore_for_file: deprecated_member_use, deprecated_member_use_from_same_package
 
 import 'dart:async';
-import 'dart:io';
 
 import 'package:flutter/foundation.dart';
 
@@ -18,7 +17,6 @@
         ImageSource,
         CameraDevice,
         LostData,
-        LostDataResponse,
         PickedFile,
         RetrieveType;
 
@@ -29,46 +27,6 @@
   @visibleForTesting
   static ImagePickerPlatform get platform => ImagePickerPlatform.instance;
 
-  /// Returns a [File] object pointing to the image that was picked.
-  ///
-  /// The returned [File] is intended to be used within a single APP session. Do not save the file path and use it across sessions.
-  ///
-  /// The `source` argument controls where the image comes from. This can
-  /// be either [ImageSource.camera] or [ImageSource.gallery].
-  ///
-  /// If specified, the image will be at most `maxWidth` wide and
-  /// `maxHeight` tall. Otherwise the image will be returned at it's
-  /// original width and height.
-  /// The `imageQuality` argument modifies the quality of the image, ranging from 0-100
-  /// where 100 is the original/max quality. If `imageQuality` is null, the image with
-  /// the original quality will be returned. Compression is only supportted for certain
-  /// image types such as JPEG. If compression is not supported for the image that is picked,
-  /// an warning message will be logged.
-  ///
-  /// Use `preferredCameraDevice` to specify the camera to use when the `source` is [ImageSource.camera].
-  /// The `preferredCameraDevice` is ignored when `source` is [ImageSource.gallery]. It is also ignored if the chosen camera is not supported on the device.
-  /// Defaults to [CameraDevice.rear].
-  ///
-  /// In Android, the MainActivity can be destroyed for various reasons. If that happens, the result will be lost
-  /// in this call. You can then call [retrieveLostData] when your app relaunches to retrieve the lost data.
-  @Deprecated('Use imagePicker.getImage() method instead.')
-  static Future<File> pickImage(
-      {@required ImageSource source,
-      double maxWidth,
-      double maxHeight,
-      int imageQuality,
-      CameraDevice preferredCameraDevice = CameraDevice.rear}) async {
-    String path = await platform.pickImagePath(
-      source: source,
-      maxWidth: maxWidth,
-      maxHeight: maxHeight,
-      imageQuality: imageQuality,
-      preferredCameraDevice: preferredCameraDevice,
-    );
-
-    return path == null ? null : File(path);
-  }
-
   /// Returns a [PickedFile] object wrapping the image that was picked.
   ///
   /// The returned [PickedFile] is intended to be used within a single APP session. Do not save the file path and use it across sessions.
@@ -96,11 +54,11 @@
   ///
   /// In Android, the MainActivity can be destroyed for various reasons. If that happens, the result will be lost
   /// in this call. You can then call [getLostData] when your app relaunches to retrieve the lost data.
-  Future<PickedFile> getImage({
-    @required ImageSource source,
-    double maxWidth,
-    double maxHeight,
-    int imageQuality,
+  Future<PickedFile?> getImage({
+    required ImageSource source,
+    double? maxWidth,
+    double? maxHeight,
+    int? imageQuality,
     CameraDevice preferredCameraDevice = CameraDevice.rear,
   }) {
     return platform.pickImage(
@@ -112,36 +70,6 @@
     );
   }
 
-  /// Returns a [File] object pointing to the video that was picked.
-  ///
-  /// The returned [File] is intended to be used within a single APP session. Do not save the file path and use it across sessions.
-  ///
-  /// The [source] argument controls where the video comes from. This can
-  /// be either [ImageSource.camera] or [ImageSource.gallery].
-  ///
-  /// The [maxDuration] argument specifies the maximum duration of the captured video. If no [maxDuration] is specified,
-  /// the maximum duration will be infinite.
-  ///
-  /// Use `preferredCameraDevice` to specify the camera to use when the `source` is [ImageSource.camera].
-  /// The `preferredCameraDevice` is ignored when `source` is [ImageSource.gallery]. It is also ignored if the chosen camera is not supported on the device.
-  /// Defaults to [CameraDevice.rear].
-  ///
-  /// In Android, the MainActivity can be destroyed for various fo reasons. If that happens, the result will be lost
-  /// in this call. You can then call [retrieveLostData] when your app relaunches to retrieve the lost data.
-  @Deprecated('Use imagePicker.getVideo() method instead.')
-  static Future<File> pickVideo(
-      {@required ImageSource source,
-      CameraDevice preferredCameraDevice = CameraDevice.rear,
-      Duration maxDuration}) async {
-    String path = await platform.pickVideoPath(
-      source: source,
-      preferredCameraDevice: preferredCameraDevice,
-      maxDuration: maxDuration,
-    );
-
-    return path == null ? null : File(path);
-  }
-
   /// Returns a [PickedFile] object wrapping the video that was picked.
   ///
   /// The returned [PickedFile] is intended to be used within a single APP session. Do not save the file path and use it across sessions.
@@ -158,10 +86,10 @@
   ///
   /// In Android, the MainActivity can be destroyed for various fo reasons. If that happens, the result will be lost
   /// in this call. You can then call [getLostData] when your app relaunches to retrieve the lost data.
-  Future<PickedFile> getVideo({
-    @required ImageSource source,
+  Future<PickedFile?> getVideo({
+    required ImageSource source,
     CameraDevice preferredCameraDevice = CameraDevice.rear,
-    Duration maxDuration,
+    Duration? maxDuration,
   }) {
     return platform.pickVideo(
       source: source,
@@ -170,23 +98,6 @@
     );
   }
 
-  /// Retrieve the lost image file when [pickImage] or [pickVideo] failed because the  MainActivity is destroyed. (Android only)
-  ///
-  /// Image or video can be lost if the MainActivity is destroyed. And there is no guarantee that the MainActivity is always alive.
-  /// Call this method to retrieve the lost data and process the data according to your APP's business logic.
-  ///
-  /// Returns a [LostDataResponse] if successfully retrieved the lost data. The [LostDataResponse] can represent either a
-  /// successful image/video selection, or a failure.
-  ///
-  /// Calling this on a non-Android platform will throw [UnimplementedError] exception.
-  ///
-  /// See also:
-  /// * [LostDataResponse], for what's included in the response.
-  /// * [Android Activity Lifecycle](https://developer.android.com/reference/android/app/Activity.html), for more information on MainActivity destruction.
-  static Future<LostDataResponse> retrieveLostData() {
-    return platform.retrieveLostDataAsDartIoFile();
-  }
-
   /// Retrieve the lost [PickedFile] when [selectImage] or [selectVideo] failed because the  MainActivity is destroyed. (Android only)
   ///
   /// Image or video can be lost if the MainActivity is destroyed. And there is no guarantee that the MainActivity is always alive.
diff --git a/packages/image_picker/image_picker/pubspec.yaml b/packages/image_picker/image_picker/pubspec.yaml
index 075c906..75f9dca 100755
--- a/packages/image_picker/image_picker/pubspec.yaml
+++ b/packages/image_picker/image_picker/pubspec.yaml
@@ -2,7 +2,7 @@
 description: Flutter plugin for selecting images from the Android and iOS image
   library, and taking new pictures with the camera.
 homepage: https://github.com/flutter/plugins/tree/master/packages/image_picker/image_picker
-version: 0.6.7+22
+version: 0.7.0-nullsafety
 
 flutter:
   plugin:
@@ -16,19 +16,19 @@
 dependencies:
   flutter:
     sdk: flutter
-  flutter_plugin_android_lifecycle: ^1.0.2
-  image_picker_platform_interface: ^1.1.0
+  flutter_plugin_android_lifecycle: ^2.0.0-nullsafety.2
+  image_picker_platform_interface: ^2.0.0-nullsafety
 
 dev_dependencies:
-  video_player: ^0.10.3
+  video_player: ^2.0.0-nullsafety.7
   flutter_test:
     sdk: flutter
   integration_test:
     path: ../../integration_test
-  mockito: ^4.1.3
+  mockito: ^5.0.0-nullsafety.7
   pedantic: ^1.8.0
   plugin_platform_interface: ^1.0.3
 
 environment:
-  sdk: ">=2.1.0 <3.0.0"
+  sdk: ">=2.12.0-0 <3.0.0"
   flutter: ">=1.10.0"
diff --git a/packages/image_picker/image_picker/test/image_picker_test.dart b/packages/image_picker/image_picker/test/image_picker_test.dart
index 7172975..0508d25 100644
--- a/packages/image_picker/image_picker/test/image_picker_test.dart
+++ b/packages/image_picker/image_picker/test/image_picker_test.dart
@@ -310,7 +310,7 @@
         });
         final LostData response = await picker.getLostData();
         expect(response.type, RetrieveType.image);
-        expect(response.file.path, '/example/path');
+        expect(response.file!.path, '/example/path');
       });
 
       test('retrieveLostData get error response', () async {
@@ -323,8 +323,8 @@
         });
         final LostData response = await picker.getLostData();
         expect(response.type, RetrieveType.video);
-        expect(response.exception.code, 'test_error_code');
-        expect(response.exception.message, 'test_error_message');
+        expect(response.exception!.code, 'test_error_code');
+        expect(response.exception!.message, 'test_error_message');
       });
 
       test('retrieveLostData get null response', () async {
diff --git a/packages/image_picker/image_picker/test/old_image_picker_test.dart b/packages/image_picker/image_picker/test/old_image_picker_test.dart
deleted file mode 100644
index 8d4e068..0000000
--- a/packages/image_picker/image_picker/test/old_image_picker_test.dart
+++ /dev/null
@@ -1,340 +0,0 @@
-// Copyright 2019 The Flutter Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// ignore_for_file: deprecated_member_use, deprecated_member_use_from_same_package
-
-import 'package:flutter/services.dart';
-import 'package:flutter_test/flutter_test.dart';
-import 'package:image_picker/image_picker.dart';
-
-void main() {
-  TestWidgetsFlutterBinding.ensureInitialized();
-
-  group('$ImagePicker', () {
-    const MethodChannel channel =
-        MethodChannel('plugins.flutter.io/image_picker');
-
-    final List<MethodCall> log = <MethodCall>[];
-
-    setUp(() {
-      channel.setMockMethodCallHandler((MethodCall methodCall) async {
-        log.add(methodCall);
-        return '';
-      });
-
-      log.clear();
-    });
-
-    group('#pickImage', () {
-      test('passes the image source argument correctly', () async {
-        await ImagePicker.pickImage(source: ImageSource.camera);
-        await ImagePicker.pickImage(source: ImageSource.gallery);
-
-        expect(
-          log,
-          <Matcher>[
-            isMethodCall('pickImage', arguments: <String, dynamic>{
-              'source': 0,
-              'maxWidth': null,
-              'maxHeight': null,
-              'imageQuality': null,
-              'cameraDevice': 0
-            }),
-            isMethodCall('pickImage', arguments: <String, dynamic>{
-              'source': 1,
-              'maxWidth': null,
-              'maxHeight': null,
-              'imageQuality': null,
-              'cameraDevice': 0
-            }),
-          ],
-        );
-      });
-
-      test('passes the width and height arguments correctly', () async {
-        await ImagePicker.pickImage(source: ImageSource.camera);
-        await ImagePicker.pickImage(
-          source: ImageSource.camera,
-          maxWidth: 10.0,
-        );
-        await ImagePicker.pickImage(
-          source: ImageSource.camera,
-          maxHeight: 10.0,
-        );
-        await ImagePicker.pickImage(
-          source: ImageSource.camera,
-          maxWidth: 10.0,
-          maxHeight: 20.0,
-        );
-        await ImagePicker.pickImage(
-            source: ImageSource.camera, maxWidth: 10.0, imageQuality: 70);
-        await ImagePicker.pickImage(
-            source: ImageSource.camera, maxHeight: 10.0, imageQuality: 70);
-        await ImagePicker.pickImage(
-            source: ImageSource.camera,
-            maxWidth: 10.0,
-            maxHeight: 20.0,
-            imageQuality: 70);
-
-        expect(
-          log,
-          <Matcher>[
-            isMethodCall('pickImage', arguments: <String, dynamic>{
-              'source': 0,
-              'maxWidth': null,
-              'maxHeight': null,
-              'imageQuality': null,
-              'cameraDevice': 0
-            }),
-            isMethodCall('pickImage', arguments: <String, dynamic>{
-              'source': 0,
-              'maxWidth': 10.0,
-              'maxHeight': null,
-              'imageQuality': null,
-              'cameraDevice': 0
-            }),
-            isMethodCall('pickImage', arguments: <String, dynamic>{
-              'source': 0,
-              'maxWidth': null,
-              'maxHeight': 10.0,
-              'imageQuality': null,
-              'cameraDevice': 0
-            }),
-            isMethodCall('pickImage', arguments: <String, dynamic>{
-              'source': 0,
-              'maxWidth': 10.0,
-              'maxHeight': 20.0,
-              'imageQuality': null,
-              'cameraDevice': 0
-            }),
-            isMethodCall('pickImage', arguments: <String, dynamic>{
-              'source': 0,
-              'maxWidth': 10.0,
-              'maxHeight': null,
-              'imageQuality': 70,
-              'cameraDevice': 0
-            }),
-            isMethodCall('pickImage', arguments: <String, dynamic>{
-              'source': 0,
-              'maxWidth': null,
-              'maxHeight': 10.0,
-              'imageQuality': 70,
-              'cameraDevice': 0
-            }),
-            isMethodCall('pickImage', arguments: <String, dynamic>{
-              'source': 0,
-              'maxWidth': 10.0,
-              'maxHeight': 20.0,
-              'imageQuality': 70,
-              'cameraDevice': 0
-            }),
-          ],
-        );
-      });
-
-      test('does not accept a negative width or height argument', () {
-        expect(
-          ImagePicker.pickImage(source: ImageSource.camera, maxWidth: -1.0),
-          throwsArgumentError,
-        );
-
-        expect(
-          ImagePicker.pickImage(source: ImageSource.camera, maxHeight: -1.0),
-          throwsArgumentError,
-        );
-      });
-
-      test('handles a null image path response gracefully', () async {
-        channel.setMockMethodCallHandler((MethodCall methodCall) => null);
-
-        expect(
-            await ImagePicker.pickImage(source: ImageSource.gallery), isNull);
-        expect(await ImagePicker.pickImage(source: ImageSource.camera), isNull);
-      });
-
-      test('camera position defaults to back', () async {
-        await ImagePicker.pickImage(source: ImageSource.camera);
-
-        expect(
-          log,
-          <Matcher>[
-            isMethodCall('pickImage', arguments: <String, dynamic>{
-              'source': 0,
-              'maxWidth': null,
-              'maxHeight': null,
-              'imageQuality': null,
-              'cameraDevice': 0,
-            }),
-          ],
-        );
-      });
-
-      test('camera position can set to front', () async {
-        await ImagePicker.pickImage(
-            source: ImageSource.camera,
-            preferredCameraDevice: CameraDevice.front);
-
-        expect(
-          log,
-          <Matcher>[
-            isMethodCall('pickImage', arguments: <String, dynamic>{
-              'source': 0,
-              'maxWidth': null,
-              'maxHeight': null,
-              'imageQuality': null,
-              'cameraDevice': 1,
-            }),
-          ],
-        );
-      });
-    });
-
-    group('#pickVideo', () {
-      test('passes the image source argument correctly', () async {
-        await ImagePicker.pickVideo(source: ImageSource.camera);
-        await ImagePicker.pickVideo(source: ImageSource.gallery);
-
-        expect(
-          log,
-          <Matcher>[
-            isMethodCall('pickVideo', arguments: <String, dynamic>{
-              'source': 0,
-              'cameraDevice': 0,
-              'maxDuration': null,
-            }),
-            isMethodCall('pickVideo', arguments: <String, dynamic>{
-              'source': 1,
-              'cameraDevice': 0,
-              'maxDuration': null,
-            }),
-          ],
-        );
-      });
-
-      test('passes the duration argument correctly', () async {
-        await ImagePicker.pickVideo(source: ImageSource.camera);
-        await ImagePicker.pickVideo(
-            source: ImageSource.camera,
-            maxDuration: const Duration(seconds: 10));
-        await ImagePicker.pickVideo(
-            source: ImageSource.camera,
-            maxDuration: const Duration(minutes: 1));
-        await ImagePicker.pickVideo(
-            source: ImageSource.camera, maxDuration: const Duration(hours: 1));
-        expect(
-          log,
-          <Matcher>[
-            isMethodCall('pickVideo', arguments: <String, dynamic>{
-              'source': 0,
-              'maxDuration': null,
-              'cameraDevice': 0,
-            }),
-            isMethodCall('pickVideo', arguments: <String, dynamic>{
-              'source': 0,
-              'maxDuration': 10,
-              'cameraDevice': 0,
-            }),
-            isMethodCall('pickVideo', arguments: <String, dynamic>{
-              'source': 0,
-              'maxDuration': 60,
-              'cameraDevice': 0,
-            }),
-            isMethodCall('pickVideo', arguments: <String, dynamic>{
-              'source': 0,
-              'maxDuration': 3600,
-              'cameraDevice': 0,
-            }),
-          ],
-        );
-      });
-
-      test('handles a null video path response gracefully', () async {
-        channel.setMockMethodCallHandler((MethodCall methodCall) => null);
-
-        expect(
-            await ImagePicker.pickVideo(source: ImageSource.gallery), isNull);
-        expect(await ImagePicker.pickVideo(source: ImageSource.camera), isNull);
-      });
-
-      test('camera position defaults to back', () async {
-        await ImagePicker.pickVideo(source: ImageSource.camera);
-
-        expect(
-          log,
-          <Matcher>[
-            isMethodCall('pickVideo', arguments: <String, dynamic>{
-              'source': 0,
-              'cameraDevice': 0,
-              'maxDuration': null,
-            }),
-          ],
-        );
-      });
-
-      test('camera position can set to front', () async {
-        await ImagePicker.pickVideo(
-            source: ImageSource.camera,
-            preferredCameraDevice: CameraDevice.front);
-
-        expect(
-          log,
-          <Matcher>[
-            isMethodCall('pickVideo', arguments: <String, dynamic>{
-              'source': 0,
-              'maxDuration': null,
-              'cameraDevice': 1,
-            }),
-          ],
-        );
-      });
-    });
-
-    group('#retrieveLostData', () {
-      test('retrieveLostData get success response', () async {
-        channel.setMockMethodCallHandler((MethodCall methodCall) async {
-          return <String, String>{
-            'type': 'image',
-            'path': '/example/path',
-          };
-        });
-        final LostDataResponse response = await ImagePicker.retrieveLostData();
-        expect(response.type, RetrieveType.image);
-        expect(response.file.path, '/example/path');
-      });
-
-      test('retrieveLostData get error response', () async {
-        channel.setMockMethodCallHandler((MethodCall methodCall) async {
-          return <String, String>{
-            'type': 'video',
-            'errorCode': 'test_error_code',
-            'errorMessage': 'test_error_message',
-          };
-        });
-        final LostDataResponse response = await ImagePicker.retrieveLostData();
-        expect(response.type, RetrieveType.video);
-        expect(response.exception.code, 'test_error_code');
-        expect(response.exception.message, 'test_error_message');
-      });
-
-      test('retrieveLostData get null response', () async {
-        channel.setMockMethodCallHandler((MethodCall methodCall) async {
-          return null;
-        });
-        expect((await ImagePicker.retrieveLostData()).isEmpty, true);
-      });
-
-      test('retrieveLostData get both path and error should throw', () async {
-        channel.setMockMethodCallHandler((MethodCall methodCall) async {
-          return <String, String>{
-            'type': 'video',
-            'errorCode': 'test_error_code',
-            'errorMessage': 'test_error_message',
-            'path': '/example/path',
-          };
-        });
-        expect(ImagePicker.retrieveLostData(), throwsAssertionError);
-      });
-    });
-  });
-}