Expand camera platform interface to support pausing the camera preview. (#4191)

diff --git a/packages/camera/camera_platform_interface/CHANGELOG.md b/packages/camera/camera_platform_interface/CHANGELOG.md
index 49214d2..6567d00 100644
--- a/packages/camera/camera_platform_interface/CHANGELOG.md
+++ b/packages/camera/camera_platform_interface/CHANGELOG.md
@@ -1,3 +1,7 @@
+## 2.1.0
+
+* Introduces interface methods for pausing and resuming the camera preview.
+
 ## 2.0.1
 
 * Update platform_plugin_interface version requirement.
diff --git a/packages/camera/camera_platform_interface/lib/src/method_channel/method_channel_camera.dart b/packages/camera/camera_platform_interface/lib/src/method_channel/method_channel_camera.dart
index c6c363a..f932f25 100644
--- a/packages/camera/camera_platform_interface/lib/src/method_channel/method_channel_camera.dart
+++ b/packages/camera/camera_platform_interface/lib/src/method_channel/method_channel_camera.dart
@@ -400,6 +400,22 @@
   }
 
   @override
+  Future<void> pausePreview(int cameraId) async {
+    await _channel.invokeMethod<double>(
+      'pausePreview',
+      <String, dynamic>{'cameraId': cameraId},
+    );
+  }
+
+  @override
+  Future<void> resumePreview(int cameraId) async {
+    await _channel.invokeMethod<double>(
+      'resumePreview',
+      <String, dynamic>{'cameraId': cameraId},
+    );
+  }
+
+  @override
   Widget buildPreview(int cameraId) {
     return Texture(textureId: cameraId);
   }
diff --git a/packages/camera/camera_platform_interface/lib/src/platform_interface/camera_platform.dart b/packages/camera/camera_platform_interface/lib/src/platform_interface/camera_platform.dart
index 4437d3b..9e84e8f 100644
--- a/packages/camera/camera_platform_interface/lib/src/platform_interface/camera_platform.dart
+++ b/packages/camera/camera_platform_interface/lib/src/platform_interface/camera_platform.dart
@@ -235,6 +235,16 @@
     throw UnimplementedError('setZoomLevel() is not implemented.');
   }
 
+  /// Pause the active preview on the current frame for the selected camera.
+  Future<void> pausePreview(int cameraId) {
+    throw UnimplementedError('pausePreview() is not implemented.');
+  }
+
+  /// Resume the paused preview for the selected camera.
+  Future<void> resumePreview(int cameraId) {
+    throw UnimplementedError('pausePreview() is not implemented.');
+  }
+
   /// Returns a widget showing a live camera preview.
   Widget buildPreview(int cameraId) {
     throw UnimplementedError('buildView() has not been implemented.');
diff --git a/packages/camera/camera_platform_interface/pubspec.yaml b/packages/camera/camera_platform_interface/pubspec.yaml
index def0601..d691afd 100644
--- a/packages/camera/camera_platform_interface/pubspec.yaml
+++ b/packages/camera/camera_platform_interface/pubspec.yaml
@@ -4,7 +4,7 @@
 issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+camera%22
 # NOTE: We strongly prefer non-breaking changes, even at the expense of a
 # less-clean API. See https://flutter.dev/go/platform-interface-breaking-changes
-version: 2.0.1
+version: 2.1.0
 
 environment:
   sdk: '>=2.12.0 <3.0.0'
diff --git a/packages/camera/camera_platform_interface/test/camera_platform_interface_test.dart b/packages/camera/camera_platform_interface/test/camera_platform_interface_test.dart
index c8f38ef..750c272 100644
--- a/packages/camera/camera_platform_interface/test/camera_platform_interface_test.dart
+++ b/packages/camera/camera_platform_interface/test/camera_platform_interface_test.dart
@@ -408,6 +408,32 @@
         throwsUnimplementedError,
       );
     });
+
+    test(
+        'Default implementation of pausePreview() should throw unimplemented error',
+        () {
+      // Arrange
+      final cameraPlatform = ExtendsCameraPlatform();
+
+      // Act & Assert
+      expect(
+        () => cameraPlatform.pausePreview(1),
+        throwsUnimplementedError,
+      );
+    });
+
+    test(
+        'Default implementation of resumePreview() should throw unimplemented error',
+        () {
+      // Arrange
+      final cameraPlatform = ExtendsCameraPlatform();
+
+      // Act & Assert
+      expect(
+        () => cameraPlatform.resumePreview(1),
+        throwsUnimplementedError,
+      );
+    });
   });
 }
 
diff --git a/packages/camera/camera_platform_interface/test/method_channel/method_channel_camera_test.dart b/packages/camera/camera_platform_interface/test/method_channel/method_channel_camera_test.dart
index 8a61854..ec71aa1 100644
--- a/packages/camera/camera_platform_interface/test/method_channel/method_channel_camera_test.dart
+++ b/packages/camera/camera_platform_interface/test/method_channel/method_channel_camera_test.dart
@@ -923,6 +923,38 @@
               arguments: {'cameraId': cameraId}),
         ]);
       });
+
+      test('Should pause the camera preview', () async {
+        // Arrange
+        MethodChannelMock channel = MethodChannelMock(
+          channelName: 'plugins.flutter.io/camera',
+          methods: {'pausePreview': null},
+        );
+
+        // Act
+        await camera.pausePreview(cameraId);
+
+        // Assert
+        expect(channel.log, <Matcher>[
+          isMethodCall('pausePreview', arguments: {'cameraId': cameraId}),
+        ]);
+      });
+
+      test('Should resume the camera preview', () async {
+        // Arrange
+        MethodChannelMock channel = MethodChannelMock(
+          channelName: 'plugins.flutter.io/camera',
+          methods: {'resumePreview': null},
+        );
+
+        // Act
+        await camera.resumePreview(cameraId);
+
+        // Assert
+        expect(channel.log, <Matcher>[
+          isMethodCall('resumePreview', arguments: {'cameraId': cameraId}),
+        ]);
+      });
     });
   });
 }