[webview_flutter]Add zoom to android webview (#3325)

diff --git a/packages/webview_flutter/webview_flutter/AUTHORS b/packages/webview_flutter/webview_flutter/AUTHORS
index 493a0b4..85628e4 100644
--- a/packages/webview_flutter/webview_flutter/AUTHORS
+++ b/packages/webview_flutter/webview_flutter/AUTHORS
@@ -64,3 +64,5 @@
 Anton Borries <mail@antonborri.es>
 Alex Li <google@alexv525.com>
 Rahul Raj <64.rahulraj@gmail.com>
+Nick Bradshaw <nickalasb@gmail.com>
+Antonino Di Natale <gyorgio88@gmail.com>
diff --git a/packages/webview_flutter/webview_flutter/CHANGELOG.md b/packages/webview_flutter/webview_flutter/CHANGELOG.md
index b499cba..8f48268 100644
--- a/packages/webview_flutter/webview_flutter/CHANGELOG.md
+++ b/packages/webview_flutter/webview_flutter/CHANGELOG.md
@@ -1,3 +1,7 @@
+## 2.3.0
+
+* Add ability to enable/disable zoom functionality.
+
 ## 2.2.0
 
 * Added `runJavascript` and `runJavascriptForResult` to supersede `evaluateJavascript`.
diff --git a/packages/webview_flutter/webview_flutter/example/integration_test/webview_flutter_test.dart b/packages/webview_flutter/webview_flutter/example/integration_test/webview_flutter_test.dart
index 9279f31..69ddcc6 100644
--- a/packages/webview_flutter/webview_flutter/example/integration_test/webview_flutter_test.dart
+++ b/packages/webview_flutter/webview_flutter/example/integration_test/webview_flutter_test.dart
@@ -11,9 +11,9 @@
 import 'package:flutter/services.dart';
 import 'package:flutter/widgets.dart';
 import 'package:flutter_test/flutter_test.dart';
+import 'package:integration_test/integration_test.dart';
 import 'package:webview_flutter/platform_interface.dart';
 import 'package:webview_flutter/webview_flutter.dart';
-import 'package:integration_test/integration_test.dart';
 
 void main() {
   IntegrationTestWidgetsFlutterBinding.ensureInitialized();
diff --git a/packages/webview_flutter/webview_flutter/example/lib/main.dart b/packages/webview_flutter/webview_flutter/example/lib/main.dart
index 2fd2087..b660ce3 100644
--- a/packages/webview_flutter/webview_flutter/example/lib/main.dart
+++ b/packages/webview_flutter/webview_flutter/example/lib/main.dart
@@ -7,6 +7,7 @@
 import 'dart:async';
 import 'dart:convert';
 import 'dart:io';
+
 import 'package:flutter/material.dart';
 import 'package:webview_flutter/webview_flutter.dart';
 
diff --git a/packages/webview_flutter/webview_flutter/lib/src/webview.dart b/packages/webview_flutter/webview_flutter/lib/src/webview.dart
index 410a995..442999d 100644
--- a/packages/webview_flutter/webview_flutter/lib/src/webview.dart
+++ b/packages/webview_flutter/webview_flutter/lib/src/webview.dart
@@ -90,6 +90,7 @@
     this.debuggingEnabled = false,
     this.gestureNavigationEnabled = false,
     this.userAgent,
+    this.zoomEnabled = true,
     this.initialMediaPlaybackPolicy =
         AutoMediaPlaybackPolicy.require_user_action_for_all_media_types,
     this.allowsInlineMediaPlayback = false,
@@ -268,6 +269,12 @@
   /// By default `userAgent` is null.
   final String? userAgent;
 
+  /// A Boolean value indicating whether the WebView should support zooming
+  /// using its on-screen zoom controls and gestures.
+  ///
+  /// By default 'zoomEnabled' is true
+  final bool zoomEnabled;
+
   /// Which restrictions apply on automatic media playback.
   ///
   /// This initial value is applied to the platform's webview upon creation. Any following
@@ -359,6 +366,7 @@
     gestureNavigationEnabled: widget.gestureNavigationEnabled,
     allowsInlineMediaPlayback: widget.allowsInlineMediaPlayback,
     userAgent: WebSetting<String?>.of(widget.userAgent),
+    zoomEnabled: widget.zoomEnabled,
   );
 }
 
@@ -374,12 +382,14 @@
   assert(newValue.hasNavigationDelegate != null);
   assert(newValue.debuggingEnabled != null);
   assert(newValue.userAgent != null);
+  assert(newValue.zoomEnabled != null);
 
   JavascriptMode? javascriptMode;
   bool? hasNavigationDelegate;
   bool? hasProgressTracking;
   bool? debuggingEnabled;
   WebSetting<String?> userAgent = WebSetting.absent();
+  bool? zoomEnabled;
   if (currentValue.javascriptMode != newValue.javascriptMode) {
     javascriptMode = newValue.javascriptMode;
   }
@@ -395,6 +405,9 @@
   if (currentValue.userAgent != newValue.userAgent) {
     userAgent = newValue.userAgent;
   }
+  if (currentValue.zoomEnabled != newValue.zoomEnabled) {
+    zoomEnabled = newValue.zoomEnabled;
+  }
 
   return WebSettings(
     javascriptMode: javascriptMode,
@@ -402,6 +415,7 @@
     hasProgressTracking: hasProgressTracking,
     debuggingEnabled: debuggingEnabled,
     userAgent: userAgent,
+    zoomEnabled: zoomEnabled,
   );
 }
 
diff --git a/packages/webview_flutter/webview_flutter/pubspec.yaml b/packages/webview_flutter/webview_flutter/pubspec.yaml
index 95a86fa..c7ac2e0 100644
--- a/packages/webview_flutter/webview_flutter/pubspec.yaml
+++ b/packages/webview_flutter/webview_flutter/pubspec.yaml
@@ -2,7 +2,7 @@
 description: A Flutter plugin that provides a WebView widget on Android and iOS.
 repository: https://github.com/flutter/plugins/tree/master/packages/webview_flutter/webview_flutter
 issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+webview%22
-version: 2.2.0
+version: 2.3.0
 
 environment:
   sdk: ">=2.14.0 <3.0.0"
@@ -19,8 +19,8 @@
 dependencies:
   flutter:
     sdk: flutter
-  webview_flutter_platform_interface: ^1.2.0
   webview_flutter_android: ^2.2.0
+  webview_flutter_platform_interface: ^1.2.0
   webview_flutter_wkwebview: ^2.2.0
 
 dev_dependencies:
diff --git a/packages/webview_flutter/webview_flutter/test/webview_flutter_test.dart b/packages/webview_flutter/webview_flutter/test/webview_flutter_test.dart
index 8d0f754..e325f68 100644
--- a/packages/webview_flutter/webview_flutter/test/webview_flutter_test.dart
+++ b/packages/webview_flutter/webview_flutter/test/webview_flutter_test.dart
@@ -10,8 +10,8 @@
 import 'package:flutter/src/gestures/recognizer.dart';
 import 'package:flutter/widgets.dart';
 import 'package:flutter_test/flutter_test.dart';
-import 'package:webview_flutter_platform_interface/webview_flutter_platform_interface.dart';
 import 'package:webview_flutter/webview_flutter.dart';
+import 'package:webview_flutter_platform_interface/webview_flutter_platform_interface.dart';
 
 typedef void VoidCallback();
 
@@ -915,6 +915,50 @@
     });
   });
 
+  group('zoomEnabled', () {
+    testWidgets('Enable zoom', (WidgetTester tester) async {
+      await tester.pumpWidget(const WebView(
+        zoomEnabled: true,
+      ));
+
+      final FakePlatformWebView platformWebView =
+          fakePlatformViewsController.lastCreatedView!;
+
+      expect(platformWebView.zoomEnabled, isTrue);
+    });
+
+    testWidgets('defaults to true', (WidgetTester tester) async {
+      await tester.pumpWidget(const WebView());
+
+      final FakePlatformWebView platformWebView =
+          fakePlatformViewsController.lastCreatedView!;
+
+      expect(platformWebView.zoomEnabled, isTrue);
+    });
+
+    testWidgets('can be changed', (WidgetTester tester) async {
+      final GlobalKey key = GlobalKey();
+      await tester.pumpWidget(WebView(key: key));
+
+      final FakePlatformWebView platformWebView =
+          fakePlatformViewsController.lastCreatedView!;
+
+      await tester.pumpWidget(WebView(
+        key: key,
+        zoomEnabled: true,
+      ));
+
+      expect(platformWebView.zoomEnabled, isTrue);
+
+      await tester.pumpWidget(WebView(
+        key: key,
+        zoomEnabled: false,
+      ));
+
+      expect(platformWebView.zoomEnabled, isFalse);
+    });
+  });
+
   group('Custom platform implementation', () {
     setUpAll(() {
       WebView.platform = MyWebViewPlatform();
@@ -944,6 +988,7 @@
               debuggingEnabled: false,
               userAgent: WebSetting<String?>.of(null),
               gestureNavigationEnabled: true,
+              zoomEnabled: true,
             ),
           )));
     });
@@ -1011,6 +1056,7 @@
         params['settings']['hasNavigationDelegate'] ?? false;
     debuggingEnabled = params['settings']['debuggingEnabled'];
     userAgent = params['settings']['userAgent'];
+    zoomEnabled = params['settings']['zoomEnabled'] ?? true;
     channel = MethodChannel(
         'plugins.flutter.io/webview_$id', const StandardMethodCodec());
     channel.setMockMethodCallHandler(onMethodCall);
@@ -1030,6 +1076,7 @@
   bool? hasNavigationDelegate;
   bool? debuggingEnabled;
   String? userAgent;
+  bool? zoomEnabled;
 
   String? lastRunJavaScriptString;
 
@@ -1050,6 +1097,9 @@
           debuggingEnabled = call.arguments['debuggingEnabled'];
         }
         userAgent = call.arguments['userAgent'];
+        if (call.arguments['zoomEnabled'] != null) {
+          zoomEnabled = call.arguments['zoomEnabled'];
+        }
         break;
       case 'canGoBack':
         return Future<bool>.sync(() => currentPosition > 0);
@@ -1307,7 +1357,8 @@
         _webSettings!.debuggingEnabled == webSettings.debuggingEnabled &&
         _webSettings!.gestureNavigationEnabled ==
             webSettings.gestureNavigationEnabled &&
-        _webSettings!.userAgent == webSettings.userAgent;
+        _webSettings!.userAgent == webSettings.userAgent &&
+        _webSettings!.zoomEnabled == webSettings.zoomEnabled;
   }
 }