From 9f617d330cd49563afc0b82269f5f3fe56054fa3 Mon Sep 17 00:00:00 2001
From: tanay <tanay@neotia.in>
Date: Mon, 24 Aug 2020 11:48:50 -0400
Subject: [PATCH] Add AndroidInAppWebViewOption for using Hybrid Composition

---
 android/src/main/AndroidManifest.xml |  4 +-
 lib/src/in_app_webview.dart          | 81 +++++++++++++++++-----------
 lib/src/webview_options.dart         |  8 +++
 3 files changed, 61 insertions(+), 32 deletions(-)

diff --git a/android/src/main/AndroidManifest.xml b/android/src/main/AndroidManifest.xml
index d0d8adfc..a7309e1e 100755
--- a/android/src/main/AndroidManifest.xml
+++ b/android/src/main/AndroidManifest.xml
@@ -5,6 +5,8 @@
         <activity android:theme="@style/AppTheme" android:name="com.pichillilorenzo.flutter_inappwebview.InAppBrowser.InAppBrowserActivity" android:configChanges="orientation|screenSize"></activity>
         <activity android:theme="@style/ThemeTransparent" android:name="com.pichillilorenzo.flutter_inappwebview.ChromeCustomTabs.ChromeCustomTabsActivity" android:configChanges="orientation|screenSize"></activity>
         <receiver android:name="com.pichillilorenzo.flutter_inappwebview.ChromeCustomTabs.ActionBroadcastReceiver" />
+        <meta-data
+            android:name="io.flutter.embedded_views_preview"
+            android:value="true" />
     </application>
-
 </manifest>
\ No newline at end of file
diff --git a/lib/src/in_app_webview.dart b/lib/src/in_app_webview.dart
index 19462ba9..43696ec4 100755
--- a/lib/src/in_app_webview.dart
+++ b/lib/src/in_app_webview.dart
@@ -340,37 +340,56 @@ class _InAppWebViewState extends State<InAppWebView> {
   @override
   Widget build(BuildContext context) {
     if (defaultTargetPlatform == TargetPlatform.android) {
-      return PlatformViewLink(
-        viewType: 'com.pichillilorenzo/flutter_inappwebview',
-        surfaceFactory: (
-            BuildContext context,
-            PlatformViewController controller,
-            ) {
-          return AndroidViewSurface(
-            controller: controller,
-            gestureRecognizers: widget.gestureRecognizers ?? const <Factory<OneSequenceGestureRecognizer>>{},
-            hitTestBehavior: PlatformViewHitTestBehavior.opaque,
-          );
-        },
-        onCreatePlatformView: (PlatformViewCreationParams params) {
-          return PlatformViewsService.initSurfaceAndroidView(
-            id: params.id,
-            viewType: 'com.pichillilorenzo/flutter_inappwebview',
-            layoutDirection: TextDirection.rtl,
-            creationParams: <String, dynamic>{
-              'initialUrl': '${Uri.parse(widget.initialUrl)}',
-              'initialFile': widget.initialFile,
-              'initialData': widget.initialData?.toMap(),
-              'initialHeaders': widget.initialHeaders,
-              'initialOptions': widget.initialOptions?.toMap() ?? {}
-            },
-            creationParamsCodec: const StandardMessageCodec(),
-          )
-            ..addOnPlatformViewCreatedListener(params.onPlatformViewCreated)
-            ..addOnPlatformViewCreatedListener((id) => _onPlatformViewCreated(id))
-            ..create();
-        },
-      );
+      if (widget.initialOptions.android.useHybridComposition) {
+        return PlatformViewLink(
+          viewType: 'com.pichillilorenzo/flutter_inappwebview',
+          surfaceFactory: (
+              BuildContext context,
+              PlatformViewController controller,
+              ) {
+            return AndroidViewSurface(
+              controller: controller,
+              gestureRecognizers: widget.gestureRecognizers ?? const <Factory<OneSequenceGestureRecognizer>>{},
+              hitTestBehavior: PlatformViewHitTestBehavior.opaque,
+            );
+          },
+          onCreatePlatformView: (PlatformViewCreationParams params) {
+            return PlatformViewsService.initSurfaceAndroidView(
+              id: params.id,
+              viewType: 'com.pichillilorenzo/flutter_inappwebview',
+              layoutDirection: TextDirection.rtl,
+              creationParams: <String, dynamic>{
+                'initialUrl': '${Uri.parse(widget.initialUrl)}',
+                'initialFile': widget.initialFile,
+                'initialData': widget.initialData?.toMap(),
+                'initialHeaders': widget.initialHeaders,
+                'initialOptions': widget.initialOptions?.toMap() ?? {}
+              },
+              creationParamsCodec: const StandardMessageCodec(),
+            )
+              ..addOnPlatformViewCreatedListener(params.onPlatformViewCreated)
+              ..addOnPlatformViewCreatedListener((id) => _onPlatformViewCreated(id))
+              ..create();
+          },
+        );
+      } else {
+        return AndroidView(
+          viewType: 'com.pichillilorenzo/flutter_inappwebview',
+          onPlatformViewCreated: _onPlatformViewCreated,
+          gestureRecognizers: widget.gestureRecognizers,
+          layoutDirection: TextDirection.rtl,
+          creationParams: <String, dynamic>{
+            'initialUrl': '${Uri.parse(widget.initialUrl)}',
+            'initialFile': widget.initialFile,
+            'initialData': widget.initialData?.toMap(),
+            'initialHeaders': widget.initialHeaders,
+            'initialOptions': widget.initialOptions?.toMap() ?? {},
+            'contextMenu': widget.contextMenu?.toMap() ?? {},
+            'windowId': widget.windowId
+          },
+          creationParamsCodec: const StandardMessageCodec(),
+        );
+      }
     } else if (defaultTargetPlatform == TargetPlatform.iOS) {
       return UiKitView(
         viewType: 'com.pichillilorenzo/flutter_inappwebview',
diff --git a/lib/src/webview_options.dart b/lib/src/webview_options.dart
index 506dd7c0..046f9908 100755
--- a/lib/src/webview_options.dart
+++ b/lib/src/webview_options.dart
@@ -470,6 +470,11 @@ class AndroidInAppWebViewOptions
   ///If the url request of a subframe matches the regular expression, then the request of that subframe is canceled.
   String regexToCancelSubFramesLoading;
 
+  ///Set to `true` to enable Flutter's new Hybrid Composition. The default value is `false`.
+  ///Hybrid Composition is supported starting with Flutter v1.20.
+  ///**NOTE**: It is recommended to use Hybrid Composition only on Android 10+ for a release app, as it can cause framerate drops on animations in Android 9 and lower.
+  bool useHybridComposition;
+
   ///Set to `true` to be able to listen at the [WebView.androidShouldInterceptRequest] event. The default value is `false`.
   bool useShouldInterceptRequest;
 
@@ -556,6 +561,7 @@ class AndroidInAppWebViewOptions
     this.initialScale = 0,
     this.supportMultipleWindows = false,
     this.regexToCancelSubFramesLoading,
+    this.useHybridComposition = false,
     this.useShouldInterceptRequest = false,
     this.useOnRenderProcessGone = false,
     this.overScrollMode = AndroidOverScrollMode.OVER_SCROLL_IF_CONTENT_SCROLLS,
@@ -613,6 +619,7 @@ class AndroidInAppWebViewOptions
       "thirdPartyCookiesEnabled": thirdPartyCookiesEnabled,
       "hardwareAcceleration": hardwareAcceleration,
       "supportMultipleWindows": supportMultipleWindows,
+      "useHybridComposition": useHybridComposition,
       "regexToCancelSubFramesLoading": regexToCancelSubFramesLoading,
       "useShouldInterceptRequest": useShouldInterceptRequest,
       "useOnRenderProcessGone": useOnRenderProcessGone,
@@ -676,6 +683,7 @@ class AndroidInAppWebViewOptions
     options.supportMultipleWindows = map["supportMultipleWindows"];
     options.regexToCancelSubFramesLoading =
         map["regexToCancelSubFramesLoading"];
+    options.useHybridComposition = map["useHybridComposition"];
     options.useShouldInterceptRequest = map["useShouldInterceptRequest"];
     options.useOnRenderProcessGone = map["useOnRenderProcessGone"];
     options.overScrollMode =