[webview_flutter] Migrate main package to fully federated architecture. (#4366)

diff --git a/packages/webview_flutter/webview_flutter/android/build.gradle b/packages/webview_flutter/webview_flutter/android/build.gradle
deleted file mode 100644
index 4a16431..0000000
--- a/packages/webview_flutter/webview_flutter/android/build.gradle
+++ /dev/null
@@ -1,57 +0,0 @@
-group 'io.flutter.plugins.webviewflutter'
-version '1.0-SNAPSHOT'
-
-buildscript {
-    repositories {
-        google()
-        mavenCentral()
-    }
-
-    dependencies {
-        classpath 'com.android.tools.build:gradle:3.3.0'
-    }
-}
-
-rootProject.allprojects {
-    repositories {
-        google()
-        mavenCentral()
-    }
-}
-
-apply plugin: 'com.android.library'
-
-android {
-    compileSdkVersion 29
-
-    defaultConfig {
-        minSdkVersion 19
-        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
-    }
-
-    lintOptions {
-        disable 'InvalidPackage'
-        disable 'GradleDependency'
-    }
-
-    dependencies {
-        implementation 'androidx.annotation:annotation:1.0.0'
-        implementation 'androidx.webkit:webkit:1.0.0'
-        testImplementation 'junit:junit:4.12'
-        testImplementation 'org.mockito:mockito-inline:3.11.1'
-        testImplementation 'androidx.test:core:1.3.0'
-    }
-
-
-    testOptions {
-        unitTests.includeAndroidResources = true
-        unitTests.returnDefaultValues = true
-        unitTests.all {
-            testLogging {
-               events "passed", "skipped", "failed", "standardOut", "standardError"
-               outputs.upToDateWhen {false}
-               showStandardStreams = true
-            }
-        }
-    }
-}
diff --git a/packages/webview_flutter/webview_flutter/android/settings.gradle b/packages/webview_flutter/webview_flutter/android/settings.gradle
deleted file mode 100644
index 5be7a4b..0000000
--- a/packages/webview_flutter/webview_flutter/android/settings.gradle
+++ /dev/null
@@ -1 +0,0 @@
-rootProject.name = 'webview_flutter'
diff --git a/packages/webview_flutter/webview_flutter/android/src/main/AndroidManifest.xml b/packages/webview_flutter/webview_flutter/android/src/main/AndroidManifest.xml
deleted file mode 100644
index a087f2c..0000000
--- a/packages/webview_flutter/webview_flutter/android/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-<manifest package="io.flutter.plugins.webviewflutter">
-</manifest>
diff --git a/packages/webview_flutter/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/DisplayListenerProxy.java b/packages/webview_flutter/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/DisplayListenerProxy.java
deleted file mode 100644
index 31e3fe0..0000000
--- a/packages/webview_flutter/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/DisplayListenerProxy.java
+++ /dev/null
@@ -1,147 +0,0 @@
-// Copyright 2013 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.
-
-package io.flutter.plugins.webviewflutter;
-
-import static android.hardware.display.DisplayManager.DisplayListener;
-
-import android.annotation.TargetApi;
-import android.hardware.display.DisplayManager;
-import android.os.Build;
-import android.util.Log;
-import java.lang.reflect.Field;
-import java.util.ArrayList;
-
-/**
- * Works around an Android WebView bug by filtering some DisplayListener invocations.
- *
- * <p>Older Android WebView versions had assumed that when {@link DisplayListener#onDisplayChanged}
- * is invoked, the display ID it is provided is of a valid display. However it turns out that when a
- * display is removed Android may call onDisplayChanged with the ID of the removed display, in this
- * case the Android WebView code tries to fetch and use the display with this ID and crashes with an
- * NPE.
- *
- * <p>This issue was fixed in the Android WebView code in
- * https://chromium-review.googlesource.com/517913 which is available starting WebView version
- * 58.0.3029.125 however older webviews in the wild still have this issue.
- *
- * <p>Since Flutter removes virtual displays whenever a platform view is resized the webview crash
- * is more likely to happen than other apps. And users were reporting this issue see:
- * https://github.com/flutter/flutter/issues/30420
- *
- * <p>This class works around the webview bug by unregistering the WebView's DisplayListener, and
- * instead registering its own DisplayListener which delegates the callbacks to the WebView's
- * listener unless it's a onDisplayChanged for an invalid display.
- *
- * <p>I did not find a clean way to get a handle of the WebView's DisplayListener so I'm using
- * reflection to fetch all registered listeners before and after initializing a webview. In the
- * first initialization of a webview within the process the difference between the lists is the
- * webview's display listener.
- */
-@TargetApi(Build.VERSION_CODES.KITKAT)
-class DisplayListenerProxy {
-  private static final String TAG = "DisplayListenerProxy";
-
-  private ArrayList<DisplayListener> listenersBeforeWebView;
-
-  /** Should be called prior to the webview's initialization. */
-  void onPreWebViewInitialization(DisplayManager displayManager) {
-    listenersBeforeWebView = yoinkDisplayListeners(displayManager);
-  }
-
-  /** Should be called after the webview's initialization. */
-  void onPostWebViewInitialization(final DisplayManager displayManager) {
-    final ArrayList<DisplayListener> webViewListeners = yoinkDisplayListeners(displayManager);
-    // We recorded the list of listeners prior to initializing webview, any new listeners we see
-    // after initializing the webview are listeners added by the webview.
-    webViewListeners.removeAll(listenersBeforeWebView);
-
-    if (webViewListeners.isEmpty()) {
-      // The Android WebView registers a single display listener per process (even if there
-      // are multiple WebView instances) so this list is expected to be non-empty only the
-      // first time a webview is initialized.
-      // Note that in an add2app scenario if the application had instantiated a non Flutter
-      // WebView prior to instantiating the Flutter WebView we are not able to get a reference
-      // to the WebView's display listener and can't work around the bug.
-      //
-      // This means that webview resizes in add2app Flutter apps with a non Flutter WebView
-      // running on a system with a webview prior to 58.0.3029.125 may crash (the Android's
-      // behavior seems to be racy so it doesn't always happen).
-      return;
-    }
-
-    for (DisplayListener webViewListener : webViewListeners) {
-      // Note that while DisplayManager.unregisterDisplayListener throws when given an
-      // unregistered listener, this isn't an issue as the WebView code never calls
-      // unregisterDisplayListener.
-      displayManager.unregisterDisplayListener(webViewListener);
-
-      // We never explicitly unregister this listener as the webview's listener is never
-      // unregistered (it's released when the process is terminated).
-      displayManager.registerDisplayListener(
-          new DisplayListener() {
-            @Override
-            public void onDisplayAdded(int displayId) {
-              for (DisplayListener webViewListener : webViewListeners) {
-                webViewListener.onDisplayAdded(displayId);
-              }
-            }
-
-            @Override
-            public void onDisplayRemoved(int displayId) {
-              for (DisplayListener webViewListener : webViewListeners) {
-                webViewListener.onDisplayRemoved(displayId);
-              }
-            }
-
-            @Override
-            public void onDisplayChanged(int displayId) {
-              if (displayManager.getDisplay(displayId) == null) {
-                return;
-              }
-              for (DisplayListener webViewListener : webViewListeners) {
-                webViewListener.onDisplayChanged(displayId);
-              }
-            }
-          },
-          null);
-    }
-  }
-
-  @SuppressWarnings({"unchecked", "PrivateApi"})
-  private static ArrayList<DisplayListener> yoinkDisplayListeners(DisplayManager displayManager) {
-    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
-      // We cannot use reflection on Android P, but it shouldn't matter as it shipped
-      // with WebView 66.0.3359.158 and the WebView version the bug this code is working around was
-      // fixed in 61.0.3116.0.
-      return new ArrayList<>();
-    }
-    try {
-      Field displayManagerGlobalField = DisplayManager.class.getDeclaredField("mGlobal");
-      displayManagerGlobalField.setAccessible(true);
-      Object displayManagerGlobal = displayManagerGlobalField.get(displayManager);
-      Field displayListenersField =
-          displayManagerGlobal.getClass().getDeclaredField("mDisplayListeners");
-      displayListenersField.setAccessible(true);
-      ArrayList<Object> delegates =
-          (ArrayList<Object>) displayListenersField.get(displayManagerGlobal);
-
-      Field listenerField = null;
-      ArrayList<DisplayManager.DisplayListener> listeners = new ArrayList<>();
-      for (Object delegate : delegates) {
-        if (listenerField == null) {
-          listenerField = delegate.getClass().getField("mListener");
-          listenerField.setAccessible(true);
-        }
-        DisplayManager.DisplayListener listener =
-            (DisplayManager.DisplayListener) listenerField.get(delegate);
-        listeners.add(listener);
-      }
-      return listeners;
-    } catch (NoSuchFieldException | IllegalAccessException e) {
-      Log.w(TAG, "Could not extract WebView's display listeners. " + e);
-      return new ArrayList<>();
-    }
-  }
-}
diff --git a/packages/webview_flutter/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterCookieManager.java b/packages/webview_flutter/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterCookieManager.java
deleted file mode 100644
index df3f21d..0000000
--- a/packages/webview_flutter/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterCookieManager.java
+++ /dev/null
@@ -1,56 +0,0 @@
-// Copyright 2013 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.
-
-package io.flutter.plugins.webviewflutter;
-
-import android.os.Build;
-import android.os.Build.VERSION_CODES;
-import android.webkit.CookieManager;
-import android.webkit.ValueCallback;
-import io.flutter.plugin.common.BinaryMessenger;
-import io.flutter.plugin.common.MethodCall;
-import io.flutter.plugin.common.MethodChannel;
-import io.flutter.plugin.common.MethodChannel.MethodCallHandler;
-import io.flutter.plugin.common.MethodChannel.Result;
-
-class FlutterCookieManager implements MethodCallHandler {
-  private final MethodChannel methodChannel;
-
-  FlutterCookieManager(BinaryMessenger messenger) {
-    methodChannel = new MethodChannel(messenger, "plugins.flutter.io/cookie_manager");
-    methodChannel.setMethodCallHandler(this);
-  }
-
-  @Override
-  public void onMethodCall(MethodCall methodCall, Result result) {
-    switch (methodCall.method) {
-      case "clearCookies":
-        clearCookies(result);
-        break;
-      default:
-        result.notImplemented();
-    }
-  }
-
-  void dispose() {
-    methodChannel.setMethodCallHandler(null);
-  }
-
-  private static void clearCookies(final Result result) {
-    CookieManager cookieManager = CookieManager.getInstance();
-    final boolean hasCookies = cookieManager.hasCookies();
-    if (Build.VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP) {
-      cookieManager.removeAllCookies(
-          new ValueCallback<Boolean>() {
-            @Override
-            public void onReceiveValue(Boolean value) {
-              result.success(hasCookies);
-            }
-          });
-    } else {
-      cookieManager.removeAllCookie();
-      result.success(hasCookies);
-    }
-  }
-}
diff --git a/packages/webview_flutter/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterDownloadListener.java b/packages/webview_flutter/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterDownloadListener.java
deleted file mode 100644
index cfad4e3..0000000
--- a/packages/webview_flutter/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterDownloadListener.java
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright 2013 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.
-
-package io.flutter.plugins.webviewflutter;
-
-import android.webkit.DownloadListener;
-import android.webkit.WebView;
-
-/** DownloadListener to notify the {@link FlutterWebViewClient} of download starts */
-public class FlutterDownloadListener implements DownloadListener {
-  private final FlutterWebViewClient webViewClient;
-  private WebView webView;
-
-  public FlutterDownloadListener(FlutterWebViewClient webViewClient) {
-    this.webViewClient = webViewClient;
-  }
-
-  /** Sets the {@link WebView} that the result of the navigation delegate will be send to. */
-  public void setWebView(WebView webView) {
-    this.webView = webView;
-  }
-
-  @Override
-  public void onDownloadStart(
-      String url,
-      String userAgent,
-      String contentDisposition,
-      String mimetype,
-      long contentLength) {
-    webViewClient.notifyDownload(webView, url);
-  }
-}
diff --git a/packages/webview_flutter/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebView.java b/packages/webview_flutter/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebView.java
deleted file mode 100644
index 4651a5f..0000000
--- a/packages/webview_flutter/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebView.java
+++ /dev/null
@@ -1,498 +0,0 @@
-// Copyright 2013 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.
-
-package io.flutter.plugins.webviewflutter;
-
-import android.annotation.TargetApi;
-import android.content.Context;
-import android.hardware.display.DisplayManager;
-import android.os.Build;
-import android.os.Handler;
-import android.os.Message;
-import android.view.View;
-import android.webkit.DownloadListener;
-import android.webkit.WebChromeClient;
-import android.webkit.WebResourceRequest;
-import android.webkit.WebStorage;
-import android.webkit.WebView;
-import android.webkit.WebViewClient;
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.annotation.VisibleForTesting;
-import io.flutter.plugin.common.MethodCall;
-import io.flutter.plugin.common.MethodChannel;
-import io.flutter.plugin.common.MethodChannel.MethodCallHandler;
-import io.flutter.plugin.common.MethodChannel.Result;
-import io.flutter.plugin.platform.PlatformView;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-
-public class FlutterWebView implements PlatformView, MethodCallHandler {
-
-  private static final String JS_CHANNEL_NAMES_FIELD = "javascriptChannelNames";
-  private final WebView webView;
-  private final MethodChannel methodChannel;
-  private final FlutterWebViewClient flutterWebViewClient;
-  private final Handler platformThreadHandler;
-
-  // Verifies that a url opened by `Window.open` has a secure url.
-  private class FlutterWebChromeClient extends WebChromeClient {
-
-    @Override
-    public boolean onCreateWindow(
-        final WebView view, boolean isDialog, boolean isUserGesture, Message resultMsg) {
-      final WebViewClient webViewClient =
-          new WebViewClient() {
-            @TargetApi(Build.VERSION_CODES.LOLLIPOP)
-            @Override
-            public boolean shouldOverrideUrlLoading(
-                @NonNull WebView view, @NonNull WebResourceRequest request) {
-              final String url = request.getUrl().toString();
-              if (!flutterWebViewClient.shouldOverrideUrlLoading(
-                  FlutterWebView.this.webView, request)) {
-                webView.loadUrl(url);
-              }
-              return true;
-            }
-
-            @Override
-            public boolean shouldOverrideUrlLoading(WebView view, String url) {
-              if (!flutterWebViewClient.shouldOverrideUrlLoading(
-                  FlutterWebView.this.webView, url)) {
-                webView.loadUrl(url);
-              }
-              return true;
-            }
-          };
-
-      final WebView newWebView = new WebView(view.getContext());
-      newWebView.setWebViewClient(webViewClient);
-
-      final WebView.WebViewTransport transport = (WebView.WebViewTransport) resultMsg.obj;
-      transport.setWebView(newWebView);
-      resultMsg.sendToTarget();
-
-      return true;
-    }
-
-    @Override
-    public void onProgressChanged(WebView view, int progress) {
-      flutterWebViewClient.onLoadingProgress(progress);
-    }
-  }
-
-  @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
-  @SuppressWarnings("unchecked")
-  FlutterWebView(
-      final Context context,
-      MethodChannel methodChannel,
-      Map<String, Object> params,
-      View containerView) {
-
-    DisplayListenerProxy displayListenerProxy = new DisplayListenerProxy();
-    DisplayManager displayManager =
-        (DisplayManager) context.getSystemService(Context.DISPLAY_SERVICE);
-    displayListenerProxy.onPreWebViewInitialization(displayManager);
-
-    this.methodChannel = methodChannel;
-    this.methodChannel.setMethodCallHandler(this);
-
-    flutterWebViewClient = new FlutterWebViewClient(methodChannel);
-
-    FlutterDownloadListener flutterDownloadListener =
-        new FlutterDownloadListener(flutterWebViewClient);
-    webView =
-        createWebView(
-            new WebViewBuilder(context, containerView),
-            params,
-            new FlutterWebChromeClient(),
-            flutterDownloadListener);
-    flutterDownloadListener.setWebView(webView);
-
-    displayListenerProxy.onPostWebViewInitialization(displayManager);
-
-    platformThreadHandler = new Handler(context.getMainLooper());
-
-    Map<String, Object> settings = (Map<String, Object>) params.get("settings");
-    if (settings != null) {
-      applySettings(settings);
-    }
-
-    if (params.containsKey(JS_CHANNEL_NAMES_FIELD)) {
-      List<String> names = (List<String>) params.get(JS_CHANNEL_NAMES_FIELD);
-      if (names != null) {
-        registerJavaScriptChannelNames(names);
-      }
-    }
-
-    Integer autoMediaPlaybackPolicy = (Integer) params.get("autoMediaPlaybackPolicy");
-    if (autoMediaPlaybackPolicy != null) {
-      updateAutoMediaPlaybackPolicy(autoMediaPlaybackPolicy);
-    }
-    if (params.containsKey("userAgent")) {
-      String userAgent = (String) params.get("userAgent");
-      updateUserAgent(userAgent);
-    }
-    if (params.containsKey("initialUrl")) {
-      String url = (String) params.get("initialUrl");
-      webView.loadUrl(url);
-    }
-  }
-
-  /**
-   * Creates a {@link android.webkit.WebView} and configures it according to the supplied
-   * parameters.
-   *
-   * <p>The {@link WebView} is configured with the following predefined settings:
-   *
-   * <ul>
-   *   <li>always enable the DOM storage API;
-   *   <li>always allow JavaScript to automatically open windows;
-   *   <li>always allow support for multiple windows;
-   *   <li>always use the {@link FlutterWebChromeClient} as web Chrome client.
-   * </ul>
-   *
-   * <p><strong>Important:</strong> This method is visible for testing purposes only and should
-   * never be called from outside this class.
-   *
-   * @param webViewBuilder a {@link WebViewBuilder} which is responsible for building the {@link
-   *     WebView}.
-   * @param params creation parameters received over the method channel.
-   * @param webChromeClient an implementation of WebChromeClient This value may be null.
-   * @return The new {@link android.webkit.WebView} object.
-   */
-  @VisibleForTesting
-  static WebView createWebView(
-      WebViewBuilder webViewBuilder,
-      Map<String, Object> params,
-      WebChromeClient webChromeClient,
-      @Nullable DownloadListener downloadListener) {
-    boolean usesHybridComposition = Boolean.TRUE.equals(params.get("usesHybridComposition"));
-    webViewBuilder
-        .setUsesHybridComposition(usesHybridComposition)
-        .setDomStorageEnabled(true) // Always enable DOM storage API.
-        .setJavaScriptCanOpenWindowsAutomatically(
-            true) // Always allow automatically opening of windows.
-        .setSupportMultipleWindows(true) // Always support multiple windows.
-        .setWebChromeClient(webChromeClient)
-        .setDownloadListener(
-            downloadListener); // Always use {@link FlutterWebChromeClient} as web Chrome client.
-
-    return webViewBuilder.build();
-  }
-
-  @Override
-  public View getView() {
-    return webView;
-  }
-
-  // @Override
-  // This is overriding a method that hasn't rolled into stable Flutter yet. Including the
-  // annotation would cause compile time failures in versions of Flutter too old to include the new
-  // method. However leaving it raw like this means that the method will be ignored in old versions
-  // of Flutter but used as an override anyway wherever it's actually defined.
-  // TODO(mklim): Add the @Override annotation once flutter/engine#9727 rolls to stable.
-  public void onInputConnectionUnlocked() {
-    if (webView instanceof InputAwareWebView) {
-      ((InputAwareWebView) webView).unlockInputConnection();
-    }
-  }
-
-  // @Override
-  // This is overriding a method that hasn't rolled into stable Flutter yet. Including the
-  // annotation would cause compile time failures in versions of Flutter too old to include the new
-  // method. However leaving it raw like this means that the method will be ignored in old versions
-  // of Flutter but used as an override anyway wherever it's actually defined.
-  // TODO(mklim): Add the @Override annotation once flutter/engine#9727 rolls to stable.
-  public void onInputConnectionLocked() {
-    if (webView instanceof InputAwareWebView) {
-      ((InputAwareWebView) webView).lockInputConnection();
-    }
-  }
-
-  // @Override
-  // This is overriding a method that hasn't rolled into stable Flutter yet. Including the
-  // annotation would cause compile time failures in versions of Flutter too old to include the new
-  // method. However leaving it raw like this means that the method will be ignored in old versions
-  // of Flutter but used as an override anyway wherever it's actually defined.
-  // TODO(mklim): Add the @Override annotation once stable passes v1.10.9.
-  public void onFlutterViewAttached(View flutterView) {
-    if (webView instanceof InputAwareWebView) {
-      ((InputAwareWebView) webView).setContainerView(flutterView);
-    }
-  }
-
-  // @Override
-  // This is overriding a method that hasn't rolled into stable Flutter yet. Including the
-  // annotation would cause compile time failures in versions of Flutter too old to include the new
-  // method. However leaving it raw like this means that the method will be ignored in old versions
-  // of Flutter but used as an override anyway wherever it's actually defined.
-  // TODO(mklim): Add the @Override annotation once stable passes v1.10.9.
-  public void onFlutterViewDetached() {
-    if (webView instanceof InputAwareWebView) {
-      ((InputAwareWebView) webView).setContainerView(null);
-    }
-  }
-
-  @Override
-  public void onMethodCall(MethodCall methodCall, Result result) {
-    switch (methodCall.method) {
-      case "loadUrl":
-        loadUrl(methodCall, result);
-        break;
-      case "updateSettings":
-        updateSettings(methodCall, result);
-        break;
-      case "canGoBack":
-        canGoBack(result);
-        break;
-      case "canGoForward":
-        canGoForward(result);
-        break;
-      case "goBack":
-        goBack(result);
-        break;
-      case "goForward":
-        goForward(result);
-        break;
-      case "reload":
-        reload(result);
-        break;
-      case "currentUrl":
-        currentUrl(result);
-        break;
-      case "evaluateJavascript":
-        evaluateJavaScript(methodCall, result);
-        break;
-      case "addJavascriptChannels":
-        addJavaScriptChannels(methodCall, result);
-        break;
-      case "removeJavascriptChannels":
-        removeJavaScriptChannels(methodCall, result);
-        break;
-      case "clearCache":
-        clearCache(result);
-        break;
-      case "getTitle":
-        getTitle(result);
-        break;
-      case "scrollTo":
-        scrollTo(methodCall, result);
-        break;
-      case "scrollBy":
-        scrollBy(methodCall, result);
-        break;
-      case "getScrollX":
-        getScrollX(result);
-        break;
-      case "getScrollY":
-        getScrollY(result);
-        break;
-      default:
-        result.notImplemented();
-    }
-  }
-
-  @SuppressWarnings("unchecked")
-  private void loadUrl(MethodCall methodCall, Result result) {
-    Map<String, Object> request = (Map<String, Object>) methodCall.arguments;
-    String url = (String) request.get("url");
-    Map<String, String> headers = (Map<String, String>) request.get("headers");
-    if (headers == null) {
-      headers = Collections.emptyMap();
-    }
-    webView.loadUrl(url, headers);
-    result.success(null);
-  }
-
-  private void canGoBack(Result result) {
-    result.success(webView.canGoBack());
-  }
-
-  private void canGoForward(Result result) {
-    result.success(webView.canGoForward());
-  }
-
-  private void goBack(Result result) {
-    if (webView.canGoBack()) {
-      webView.goBack();
-    }
-    result.success(null);
-  }
-
-  private void goForward(Result result) {
-    if (webView.canGoForward()) {
-      webView.goForward();
-    }
-    result.success(null);
-  }
-
-  private void reload(Result result) {
-    webView.reload();
-    result.success(null);
-  }
-
-  private void currentUrl(Result result) {
-    result.success(webView.getUrl());
-  }
-
-  @SuppressWarnings("unchecked")
-  private void updateSettings(MethodCall methodCall, Result result) {
-    applySettings((Map<String, Object>) methodCall.arguments);
-    result.success(null);
-  }
-
-  @TargetApi(Build.VERSION_CODES.KITKAT)
-  private void evaluateJavaScript(MethodCall methodCall, final Result result) {
-    String jsString = (String) methodCall.arguments;
-    if (jsString == null) {
-      throw new UnsupportedOperationException("JavaScript string cannot be null");
-    }
-    webView.evaluateJavascript(
-        jsString,
-        new android.webkit.ValueCallback<String>() {
-          @Override
-          public void onReceiveValue(String value) {
-            result.success(value);
-          }
-        });
-  }
-
-  @SuppressWarnings("unchecked")
-  private void addJavaScriptChannels(MethodCall methodCall, Result result) {
-    List<String> channelNames = (List<String>) methodCall.arguments;
-    registerJavaScriptChannelNames(channelNames);
-    result.success(null);
-  }
-
-  @SuppressWarnings("unchecked")
-  private void removeJavaScriptChannels(MethodCall methodCall, Result result) {
-    List<String> channelNames = (List<String>) methodCall.arguments;
-    for (String channelName : channelNames) {
-      webView.removeJavascriptInterface(channelName);
-    }
-    result.success(null);
-  }
-
-  private void clearCache(Result result) {
-    webView.clearCache(true);
-    WebStorage.getInstance().deleteAllData();
-    result.success(null);
-  }
-
-  private void getTitle(Result result) {
-    result.success(webView.getTitle());
-  }
-
-  private void scrollTo(MethodCall methodCall, Result result) {
-    Map<String, Object> request = methodCall.arguments();
-    int x = (int) request.get("x");
-    int y = (int) request.get("y");
-
-    webView.scrollTo(x, y);
-
-    result.success(null);
-  }
-
-  private void scrollBy(MethodCall methodCall, Result result) {
-    Map<String, Object> request = methodCall.arguments();
-    int x = (int) request.get("x");
-    int y = (int) request.get("y");
-
-    webView.scrollBy(x, y);
-    result.success(null);
-  }
-
-  private void getScrollX(Result result) {
-    result.success(webView.getScrollX());
-  }
-
-  private void getScrollY(Result result) {
-    result.success(webView.getScrollY());
-  }
-
-  private void applySettings(Map<String, Object> settings) {
-    for (String key : settings.keySet()) {
-      switch (key) {
-        case "jsMode":
-          Integer mode = (Integer) settings.get(key);
-          if (mode != null) {
-            updateJsMode(mode);
-          }
-          break;
-        case "hasNavigationDelegate":
-          final boolean hasNavigationDelegate = (boolean) settings.get(key);
-
-          final WebViewClient webViewClient =
-              flutterWebViewClient.createWebViewClient(hasNavigationDelegate);
-
-          webView.setWebViewClient(webViewClient);
-          break;
-        case "debuggingEnabled":
-          final boolean debuggingEnabled = (boolean) settings.get(key);
-
-          if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
-            webView.setWebContentsDebuggingEnabled(debuggingEnabled);
-          }
-          break;
-        case "hasProgressTracking":
-          flutterWebViewClient.hasProgressTracking = (boolean) settings.get(key);
-          break;
-        case "gestureNavigationEnabled":
-          break;
-        case "userAgent":
-          updateUserAgent((String) settings.get(key));
-          break;
-        case "allowsInlineMediaPlayback":
-          // no-op inline media playback is always allowed on Android.
-          break;
-        default:
-          throw new IllegalArgumentException("Unknown WebView setting: " + key);
-      }
-    }
-  }
-
-  private void updateJsMode(int mode) {
-    switch (mode) {
-      case 0: // disabled
-        webView.getSettings().setJavaScriptEnabled(false);
-        break;
-      case 1: // unrestricted
-        webView.getSettings().setJavaScriptEnabled(true);
-        break;
-      default:
-        throw new IllegalArgumentException("Trying to set unknown JavaScript mode: " + mode);
-    }
-  }
-
-  private void updateAutoMediaPlaybackPolicy(int mode) {
-    // This is the index of the AutoMediaPlaybackPolicy enum, index 1 is always_allow, for all
-    // other values we require a user gesture.
-    boolean requireUserGesture = mode != 1;
-    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
-      webView.getSettings().setMediaPlaybackRequiresUserGesture(requireUserGesture);
-    }
-  }
-
-  private void registerJavaScriptChannelNames(List<String> channelNames) {
-    for (String channelName : channelNames) {
-      webView.addJavascriptInterface(
-          new JavaScriptChannel(methodChannel, channelName, platformThreadHandler), channelName);
-    }
-  }
-
-  private void updateUserAgent(String userAgent) {
-    webView.getSettings().setUserAgentString(userAgent);
-  }
-
-  @Override
-  public void dispose() {
-    methodChannel.setMethodCallHandler(null);
-    if (webView instanceof InputAwareWebView) {
-      ((InputAwareWebView) webView).dispose();
-    }
-    webView.destroy();
-  }
-}
diff --git a/packages/webview_flutter/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebViewClient.java b/packages/webview_flutter/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebViewClient.java
deleted file mode 100644
index 260ef8e..0000000
--- a/packages/webview_flutter/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebViewClient.java
+++ /dev/null
@@ -1,323 +0,0 @@
-// Copyright 2013 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.
-
-package io.flutter.plugins.webviewflutter;
-
-import android.annotation.SuppressLint;
-import android.annotation.TargetApi;
-import android.graphics.Bitmap;
-import android.os.Build;
-import android.util.Log;
-import android.view.KeyEvent;
-import android.webkit.WebResourceError;
-import android.webkit.WebResourceRequest;
-import android.webkit.WebView;
-import android.webkit.WebViewClient;
-import androidx.annotation.NonNull;
-import androidx.annotation.RequiresApi;
-import androidx.webkit.WebResourceErrorCompat;
-import androidx.webkit.WebViewClientCompat;
-import io.flutter.plugin.common.MethodChannel;
-import java.util.HashMap;
-import java.util.Locale;
-import java.util.Map;
-
-// We need to use WebViewClientCompat to get
-// shouldOverrideUrlLoading(WebView view, WebResourceRequest request)
-// invoked by the webview on older Android devices, without it pages that use iframes will
-// be broken when a navigationDelegate is set on Android version earlier than N.
-class FlutterWebViewClient {
-  private static final String TAG = "FlutterWebViewClient";
-  private final MethodChannel methodChannel;
-  private boolean hasNavigationDelegate;
-  boolean hasProgressTracking;
-
-  FlutterWebViewClient(MethodChannel methodChannel) {
-    this.methodChannel = methodChannel;
-  }
-
-  static String errorCodeToString(int errorCode) {
-    switch (errorCode) {
-      case WebViewClient.ERROR_AUTHENTICATION:
-        return "authentication";
-      case WebViewClient.ERROR_BAD_URL:
-        return "badUrl";
-      case WebViewClient.ERROR_CONNECT:
-        return "connect";
-      case WebViewClient.ERROR_FAILED_SSL_HANDSHAKE:
-        return "failedSslHandshake";
-      case WebViewClient.ERROR_FILE:
-        return "file";
-      case WebViewClient.ERROR_FILE_NOT_FOUND:
-        return "fileNotFound";
-      case WebViewClient.ERROR_HOST_LOOKUP:
-        return "hostLookup";
-      case WebViewClient.ERROR_IO:
-        return "io";
-      case WebViewClient.ERROR_PROXY_AUTHENTICATION:
-        return "proxyAuthentication";
-      case WebViewClient.ERROR_REDIRECT_LOOP:
-        return "redirectLoop";
-      case WebViewClient.ERROR_TIMEOUT:
-        return "timeout";
-      case WebViewClient.ERROR_TOO_MANY_REQUESTS:
-        return "tooManyRequests";
-      case WebViewClient.ERROR_UNKNOWN:
-        return "unknown";
-      case WebViewClient.ERROR_UNSAFE_RESOURCE:
-        return "unsafeResource";
-      case WebViewClient.ERROR_UNSUPPORTED_AUTH_SCHEME:
-        return "unsupportedAuthScheme";
-      case WebViewClient.ERROR_UNSUPPORTED_SCHEME:
-        return "unsupportedScheme";
-    }
-
-    final String message =
-        String.format(Locale.getDefault(), "Could not find a string for errorCode: %d", errorCode);
-    throw new IllegalArgumentException(message);
-  }
-
-  @TargetApi(Build.VERSION_CODES.LOLLIPOP)
-  boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
-    if (!hasNavigationDelegate) {
-      return false;
-    }
-    notifyOnNavigationRequest(
-        request.getUrl().toString(), request.getRequestHeaders(), view, request.isForMainFrame());
-    // We must make a synchronous decision here whether to allow the navigation or not,
-    // if the Dart code has set a navigation delegate we want that delegate to decide whether
-    // to navigate or not, and as we cannot get a response from the Dart delegate synchronously we
-    // return true here to block the navigation, if the Dart delegate decides to allow the
-    // navigation the plugin will later make an addition loadUrl call for this url.
-    //
-    // Since we cannot call loadUrl for a subframe, we currently only allow the delegate to stop
-    // navigations that target the main frame, if the request is not for the main frame
-    // we just return false to allow the navigation.
-    //
-    // For more details see: https://github.com/flutter/flutter/issues/25329#issuecomment-464863209
-    return request.isForMainFrame();
-  }
-
-  boolean shouldOverrideUrlLoading(WebView view, String url) {
-    if (!hasNavigationDelegate) {
-      return false;
-    }
-    // This version of shouldOverrideUrlLoading is only invoked by the webview on devices with
-    // webview versions  earlier than 67(it is also invoked when hasNavigationDelegate is false).
-    // On these devices we cannot tell whether the navigation is targeted to the main frame or not.
-    // We proceed assuming that the navigation is targeted to the main frame. If the page had any
-    // frames they will be loaded in the main frame instead.
-    Log.w(
-        TAG,
-        "Using a navigationDelegate with an old webview implementation, pages with frames or iframes will not work");
-    notifyOnNavigationRequest(url, null, view, true);
-    return true;
-  }
-
-  /**
-   * Notifies the Flutter code that a download should start when a navigation delegate is set.
-   *
-   * @param view the webView the result of the navigation delegate will be send to.
-   * @param url the download url
-   * @return A boolean whether or not the request is forwarded to the Flutter code.
-   */
-  boolean notifyDownload(WebView view, String url) {
-    if (!hasNavigationDelegate) {
-      return false;
-    }
-
-    notifyOnNavigationRequest(url, null, view, true);
-    return true;
-  }
-
-  private void onPageStarted(WebView view, String url) {
-    Map<String, Object> args = new HashMap<>();
-    args.put("url", url);
-    methodChannel.invokeMethod("onPageStarted", args);
-  }
-
-  private void onPageFinished(WebView view, String url) {
-    Map<String, Object> args = new HashMap<>();
-    args.put("url", url);
-    methodChannel.invokeMethod("onPageFinished", args);
-  }
-
-  void onLoadingProgress(int progress) {
-    if (hasProgressTracking) {
-      Map<String, Object> args = new HashMap<>();
-      args.put("progress", progress);
-      methodChannel.invokeMethod("onProgress", args);
-    }
-  }
-
-  private void onWebResourceError(
-      final int errorCode, final String description, final String failingUrl) {
-    final Map<String, Object> args = new HashMap<>();
-    args.put("errorCode", errorCode);
-    args.put("description", description);
-    args.put("errorType", FlutterWebViewClient.errorCodeToString(errorCode));
-    args.put("failingUrl", failingUrl);
-    methodChannel.invokeMethod("onWebResourceError", args);
-  }
-
-  private void notifyOnNavigationRequest(
-      String url, Map<String, String> headers, WebView webview, boolean isMainFrame) {
-    HashMap<String, Object> args = new HashMap<>();
-    args.put("url", url);
-    args.put("isForMainFrame", isMainFrame);
-    if (isMainFrame) {
-      methodChannel.invokeMethod(
-          "navigationRequest", args, new OnNavigationRequestResult(url, headers, webview));
-    } else {
-      methodChannel.invokeMethod("navigationRequest", args);
-    }
-  }
-
-  // This method attempts to avoid using WebViewClientCompat due to bug
-  // https://bugs.chromium.org/p/chromium/issues/detail?id=925887. Also, see
-  // https://github.com/flutter/flutter/issues/29446.
-  WebViewClient createWebViewClient(boolean hasNavigationDelegate) {
-    this.hasNavigationDelegate = hasNavigationDelegate;
-
-    if (!hasNavigationDelegate || android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
-      return internalCreateWebViewClient();
-    }
-
-    return internalCreateWebViewClientCompat();
-  }
-
-  private WebViewClient internalCreateWebViewClient() {
-    return new WebViewClient() {
-      @TargetApi(Build.VERSION_CODES.N)
-      @Override
-      public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
-        return FlutterWebViewClient.this.shouldOverrideUrlLoading(view, request);
-      }
-
-      @Override
-      public void onPageStarted(WebView view, String url, Bitmap favicon) {
-        FlutterWebViewClient.this.onPageStarted(view, url);
-      }
-
-      @Override
-      public void onPageFinished(WebView view, String url) {
-        FlutterWebViewClient.this.onPageFinished(view, url);
-      }
-
-      @TargetApi(Build.VERSION_CODES.M)
-      @Override
-      public void onReceivedError(
-          WebView view, WebResourceRequest request, WebResourceError error) {
-        if (request.isForMainFrame()) {
-          FlutterWebViewClient.this.onWebResourceError(
-              error.getErrorCode(), error.getDescription().toString(), request.getUrl().toString());
-        }
-      }
-
-      @Override
-      public void onReceivedError(
-          WebView view, int errorCode, String description, String failingUrl) {
-        FlutterWebViewClient.this.onWebResourceError(errorCode, description, failingUrl);
-      }
-
-      @Override
-      public void onUnhandledKeyEvent(WebView view, KeyEvent event) {
-        // Deliberately empty. Occasionally the webview will mark events as having failed to be
-        // handled even though they were handled. We don't want to propagate those as they're not
-        // truly lost.
-      }
-    };
-  }
-
-  private WebViewClientCompat internalCreateWebViewClientCompat() {
-    return new WebViewClientCompat() {
-      @Override
-      public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
-        return FlutterWebViewClient.this.shouldOverrideUrlLoading(view, request);
-      }
-
-      @Override
-      public boolean shouldOverrideUrlLoading(WebView view, String url) {
-        return FlutterWebViewClient.this.shouldOverrideUrlLoading(view, url);
-      }
-
-      @Override
-      public void onPageStarted(WebView view, String url, Bitmap favicon) {
-        FlutterWebViewClient.this.onPageStarted(view, url);
-      }
-
-      @Override
-      public void onPageFinished(WebView view, String url) {
-        FlutterWebViewClient.this.onPageFinished(view, url);
-      }
-
-      // This method is only called when the WebViewFeature.RECEIVE_WEB_RESOURCE_ERROR feature is
-      // enabled. The deprecated method is called when a device doesn't support this.
-      @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
-      @SuppressLint("RequiresFeature")
-      @Override
-      public void onReceivedError(
-          @NonNull WebView view,
-          @NonNull WebResourceRequest request,
-          @NonNull WebResourceErrorCompat error) {
-        if (request.isForMainFrame()) {
-          FlutterWebViewClient.this.onWebResourceError(
-              error.getErrorCode(), error.getDescription().toString(), request.getUrl().toString());
-        }
-      }
-
-      @Override
-      public void onReceivedError(
-          WebView view, int errorCode, String description, String failingUrl) {
-        FlutterWebViewClient.this.onWebResourceError(errorCode, description, failingUrl);
-      }
-
-      @Override
-      public void onUnhandledKeyEvent(WebView view, KeyEvent event) {
-        // Deliberately empty. Occasionally the webview will mark events as having failed to be
-        // handled even though they were handled. We don't want to propagate those as they're not
-        // truly lost.
-      }
-    };
-  }
-
-  private static class OnNavigationRequestResult implements MethodChannel.Result {
-    private final String url;
-    private final Map<String, String> headers;
-    private final WebView webView;
-
-    private OnNavigationRequestResult(String url, Map<String, String> headers, WebView webView) {
-      this.url = url;
-      this.headers = headers;
-      this.webView = webView;
-    }
-
-    @Override
-    public void success(Object shouldLoad) {
-      Boolean typedShouldLoad = (Boolean) shouldLoad;
-      if (typedShouldLoad) {
-        loadUrl();
-      }
-    }
-
-    @Override
-    public void error(String errorCode, String s1, Object o) {
-      throw new IllegalStateException("navigationRequest calls must succeed");
-    }
-
-    @Override
-    public void notImplemented() {
-      throw new IllegalStateException(
-          "navigationRequest must be implemented by the webview method channel");
-    }
-
-    private void loadUrl() {
-      if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
-        webView.loadUrl(url, headers);
-      } else {
-        webView.loadUrl(url);
-      }
-    }
-  }
-}
diff --git a/packages/webview_flutter/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebViewFactory.java b/packages/webview_flutter/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebViewFactory.java
deleted file mode 100644
index 8fe5810..0000000
--- a/packages/webview_flutter/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebViewFactory.java
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright 2013 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.
-
-package io.flutter.plugins.webviewflutter;
-
-import android.content.Context;
-import android.view.View;
-import io.flutter.plugin.common.BinaryMessenger;
-import io.flutter.plugin.common.MethodChannel;
-import io.flutter.plugin.common.StandardMessageCodec;
-import io.flutter.plugin.platform.PlatformView;
-import io.flutter.plugin.platform.PlatformViewFactory;
-import java.util.Map;
-
-public final class FlutterWebViewFactory extends PlatformViewFactory {
-  private final BinaryMessenger messenger;
-  private final View containerView;
-
-  FlutterWebViewFactory(BinaryMessenger messenger, View containerView) {
-    super(StandardMessageCodec.INSTANCE);
-    this.messenger = messenger;
-    this.containerView = containerView;
-  }
-
-  @SuppressWarnings("unchecked")
-  @Override
-  public PlatformView create(Context context, int id, Object args) {
-    Map<String, Object> params = (Map<String, Object>) args;
-    MethodChannel methodChannel = new MethodChannel(messenger, "plugins.flutter.io/webview_" + id);
-    return new FlutterWebView(context, methodChannel, params, containerView);
-  }
-}
diff --git a/packages/webview_flutter/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/InputAwareWebView.java b/packages/webview_flutter/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/InputAwareWebView.java
deleted file mode 100644
index 51b2a38..0000000
--- a/packages/webview_flutter/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/InputAwareWebView.java
+++ /dev/null
@@ -1,233 +0,0 @@
-// Copyright 2013 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.
-
-package io.flutter.plugins.webviewflutter;
-
-import static android.content.Context.INPUT_METHOD_SERVICE;
-
-import android.content.Context;
-import android.graphics.Rect;
-import android.os.Build;
-import android.util.Log;
-import android.view.View;
-import android.view.inputmethod.InputMethodManager;
-import android.webkit.WebView;
-import android.widget.ListPopupWindow;
-
-/**
- * A WebView subclass that mirrors the same implementation hacks that the system WebView does in
- * order to correctly create an InputConnection.
- *
- * <p>These hacks are only needed in Android versions below N and exist to create an InputConnection
- * on the WebView's dedicated input, or IME, thread. The majority of this proxying logic is in
- * {@link #checkInputConnectionProxy}.
- *
- * <p>See also {@link ThreadedInputConnectionProxyAdapterView}.
- */
-final class InputAwareWebView extends WebView {
-  private static final String TAG = "InputAwareWebView";
-  private View threadedInputConnectionProxyView;
-  private ThreadedInputConnectionProxyAdapterView proxyAdapterView;
-  private View containerView;
-
-  InputAwareWebView(Context context, View containerView) {
-    super(context);
-    this.containerView = containerView;
-  }
-
-  void setContainerView(View containerView) {
-    this.containerView = containerView;
-
-    if (proxyAdapterView == null) {
-      return;
-    }
-
-    Log.w(TAG, "The containerView has changed while the proxyAdapterView exists.");
-    if (containerView != null) {
-      setInputConnectionTarget(proxyAdapterView);
-    }
-  }
-
-  /**
-   * Set our proxy adapter view to use its cached input connection instead of creating new ones.
-   *
-   * <p>This is used to avoid losing our input connection when the virtual display is resized.
-   */
-  void lockInputConnection() {
-    if (proxyAdapterView == null) {
-      return;
-    }
-
-    proxyAdapterView.setLocked(true);
-  }
-
-  /** Sets the proxy adapter view back to its default behavior. */
-  void unlockInputConnection() {
-    if (proxyAdapterView == null) {
-      return;
-    }
-
-    proxyAdapterView.setLocked(false);
-  }
-
-  /** Restore the original InputConnection, if needed. */
-  void dispose() {
-    resetInputConnection();
-  }
-
-  /**
-   * Creates an InputConnection from the IME thread when needed.
-   *
-   * <p>We only need to create a {@link ThreadedInputConnectionProxyAdapterView} and create an
-   * InputConnectionProxy on the IME thread when WebView is doing the same thing. So we rely on the
-   * system calling this method for WebView's proxy view in order to know when we need to create our
-   * own.
-   *
-   * <p>This method would normally be called for any View that used the InputMethodManager. We rely
-   * on flutter/engine filtering the calls we receive down to the ones in our hierarchy and the
-   * system WebView in order to know whether or not the system WebView expects an InputConnection on
-   * the IME thread.
-   */
-  @Override
-  public boolean checkInputConnectionProxy(final View view) {
-    // Check to see if the view param is WebView's ThreadedInputConnectionProxyView.
-    View previousProxy = threadedInputConnectionProxyView;
-    threadedInputConnectionProxyView = view;
-    if (previousProxy == view) {
-      // This isn't a new ThreadedInputConnectionProxyView. Ignore it.
-      return super.checkInputConnectionProxy(view);
-    }
-    if (containerView == null) {
-      Log.e(
-          TAG,
-          "Can't create a proxy view because there's no container view. Text input may not work.");
-      return super.checkInputConnectionProxy(view);
-    }
-
-    // We've never seen this before, so we make the assumption that this is WebView's
-    // ThreadedInputConnectionProxyView. We are making the assumption that the only view that could
-    // possibly be interacting with the IMM here is WebView's ThreadedInputConnectionProxyView.
-    proxyAdapterView =
-        new ThreadedInputConnectionProxyAdapterView(
-            /*containerView=*/ containerView,
-            /*targetView=*/ view,
-            /*imeHandler=*/ view.getHandler());
-    setInputConnectionTarget(/*targetView=*/ proxyAdapterView);
-    return super.checkInputConnectionProxy(view);
-  }
-
-  /**
-   * Ensure that input creation happens back on {@link #containerView}'s thread once this view no
-   * longer has focus.
-   *
-   * <p>The logic in {@link #checkInputConnectionProxy} forces input creation to happen on Webview's
-   * thread for all connections. We undo it here so users will be able to go back to typing in
-   * Flutter UIs as expected.
-   */
-  @Override
-  public void clearFocus() {
-    super.clearFocus();
-    resetInputConnection();
-  }
-
-  /**
-   * Ensure that input creation happens back on {@link #containerView}.
-   *
-   * <p>The logic in {@link #checkInputConnectionProxy} forces input creation to happen on Webview's
-   * thread for all connections. We undo it here so users will be able to go back to typing in
-   * Flutter UIs as expected.
-   */
-  private void resetInputConnection() {
-    if (proxyAdapterView == null) {
-      // No need to reset the InputConnection to the default thread if we've never changed it.
-      return;
-    }
-    if (containerView == null) {
-      Log.e(TAG, "Can't reset the input connection to the container view because there is none.");
-      return;
-    }
-    setInputConnectionTarget(/*targetView=*/ containerView);
-  }
-
-  /**
-   * This is the crucial trick that gets the InputConnection creation to happen on the correct
-   * thread pre Android N.
-   * https://cs.chromium.org/chromium/src/content/public/android/java/src/org/chromium/content/browser/input/ThreadedInputConnectionFactory.java?l=169&rcl=f0698ee3e4483fad5b0c34159276f71cfaf81f3a
-   *
-   * <p>{@code targetView} should have a {@link View#getHandler} method with the thread that future
-   * InputConnections should be created on.
-   */
-  private void setInputConnectionTarget(final View targetView) {
-    if (containerView == null) {
-      Log.e(
-          TAG,
-          "Can't set the input connection target because there is no containerView to use as a handler.");
-      return;
-    }
-
-    targetView.requestFocus();
-    containerView.post(
-        new Runnable() {
-          @Override
-          public void run() {
-            InputMethodManager imm =
-                (InputMethodManager) getContext().getSystemService(INPUT_METHOD_SERVICE);
-            // This is a hack to make InputMethodManager believe that the target view now has focus.
-            // As a result, InputMethodManager will think that targetView is focused, and will call
-            // getHandler() of the view when creating input connection.
-
-            // Step 1: Set targetView as InputMethodManager#mNextServedView. This does not affect
-            // the real window focus.
-            targetView.onWindowFocusChanged(true);
-
-            // Step 2: Have InputMethodManager focus in on targetView. As a result, IMM will call
-            // onCreateInputConnection() on targetView on the same thread as
-            // targetView.getHandler(). It will also call subsequent InputConnection methods on this
-            // thread. This is the IME thread in cases where targetView is our proxyAdapterView.
-            imm.isActive(containerView);
-          }
-        });
-  }
-
-  @Override
-  protected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) {
-    // This works around a crash when old (<67.0.3367.0) Chromium versions are used.
-
-    // Prior to Chromium 67.0.3367 the following sequence happens when a select drop down is shown
-    // on tablets:
-    //
-    //  - WebView is calling ListPopupWindow#show
-    //  - buildDropDown is invoked, which sets mDropDownList to a DropDownListView.
-    //  - showAsDropDown is invoked - resulting in mDropDownList being added to the window and is
-    //    also synchronously performing the following sequence:
-    //    - WebView's focus change listener is loosing focus (as mDropDownList got it)
-    //    - WebView is hiding all popups (as it lost focus)
-    //    - WebView's SelectPopupDropDown#hide is invoked.
-    //    - DropDownPopupWindow#dismiss is invoked setting mDropDownList to null.
-    //  - mDropDownList#setSelection is invoked and is throwing a NullPointerException (as we just set mDropDownList to null).
-    //
-    // To workaround this, we drop the problematic focus lost call.
-    // See more details on: https://github.com/flutter/flutter/issues/54164
-    //
-    // We don't do this after Android P as it shipped with a new enough WebView version, and it's
-    // better to not do this on all future Android versions in case DropDownListView's code changes.
-    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.P
-        && isCalledFromListPopupWindowShow()
-        && !focused) {
-      return;
-    }
-    super.onFocusChanged(focused, direction, previouslyFocusedRect);
-  }
-
-  private boolean isCalledFromListPopupWindowShow() {
-    StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace();
-    for (StackTraceElement stackTraceElement : stackTraceElements) {
-      if (stackTraceElement.getClassName().equals(ListPopupWindow.class.getCanonicalName())
-          && stackTraceElement.getMethodName().equals("show")) {
-        return true;
-      }
-    }
-    return false;
-  }
-}
diff --git a/packages/webview_flutter/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/JavaScriptChannel.java b/packages/webview_flutter/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/JavaScriptChannel.java
deleted file mode 100644
index 4d59635..0000000
--- a/packages/webview_flutter/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/JavaScriptChannel.java
+++ /dev/null
@@ -1,58 +0,0 @@
-// Copyright 2013 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.
-
-package io.flutter.plugins.webviewflutter;
-
-import android.os.Handler;
-import android.os.Looper;
-import android.webkit.JavascriptInterface;
-import io.flutter.plugin.common.MethodChannel;
-import java.util.HashMap;
-
-/**
- * Added as a JavaScript interface to the WebView for any JavaScript channel that the Dart code sets
- * up.
- *
- * <p>Exposes a single method named `postMessage` to JavaScript, which sends a message over a method
- * channel to the Dart code.
- */
-class JavaScriptChannel {
-  private final MethodChannel methodChannel;
-  private final String javaScriptChannelName;
-  private final Handler platformThreadHandler;
-
-  /**
-   * @param methodChannel the Flutter WebView method channel to which JS messages are sent
-   * @param javaScriptChannelName the name of the JavaScript channel, this is sent over the method
-   *     channel with each message to let the Dart code know which JavaScript channel the message
-   *     was sent through
-   */
-  JavaScriptChannel(
-      MethodChannel methodChannel, String javaScriptChannelName, Handler platformThreadHandler) {
-    this.methodChannel = methodChannel;
-    this.javaScriptChannelName = javaScriptChannelName;
-    this.platformThreadHandler = platformThreadHandler;
-  }
-
-  // Suppressing unused warning as this is invoked from JavaScript.
-  @SuppressWarnings("unused")
-  @JavascriptInterface
-  public void postMessage(final String message) {
-    Runnable postMessageRunnable =
-        new Runnable() {
-          @Override
-          public void run() {
-            HashMap<String, String> arguments = new HashMap<>();
-            arguments.put("channel", javaScriptChannelName);
-            arguments.put("message", message);
-            methodChannel.invokeMethod("javascriptChannelMessage", arguments);
-          }
-        };
-    if (platformThreadHandler.getLooper() == Looper.myLooper()) {
-      postMessageRunnable.run();
-    } else {
-      platformThreadHandler.post(postMessageRunnable);
-    }
-  }
-}
diff --git a/packages/webview_flutter/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/ThreadedInputConnectionProxyAdapterView.java b/packages/webview_flutter/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/ThreadedInputConnectionProxyAdapterView.java
deleted file mode 100644
index 1c865c9..0000000
--- a/packages/webview_flutter/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/ThreadedInputConnectionProxyAdapterView.java
+++ /dev/null
@@ -1,112 +0,0 @@
-// Copyright 2013 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.
-
-package io.flutter.plugins.webviewflutter;
-
-import android.os.Handler;
-import android.os.IBinder;
-import android.view.View;
-import android.view.inputmethod.EditorInfo;
-import android.view.inputmethod.InputConnection;
-
-/**
- * A fake View only exposed to InputMethodManager.
- *
- * <p>This follows a similar flow to Chromium's WebView (see
- * https://cs.chromium.org/chromium/src/content/public/android/java/src/org/chromium/content/browser/input/ThreadedInputConnectionProxyView.java).
- * WebView itself bounces its InputConnection around several different threads. We follow its logic
- * here to get the same working connection.
- *
- * <p>This exists solely to forward input creation to WebView's ThreadedInputConnectionProxyView on
- * the IME thread. The way that this is created in {@link
- * InputAwareWebView#checkInputConnectionProxy} guarantees that we have a handle to
- * ThreadedInputConnectionProxyView and {@link #onCreateInputConnection} is always called on the IME
- * thread. We delegate to ThreadedInputConnectionProxyView there to get WebView's input connection.
- */
-final class ThreadedInputConnectionProxyAdapterView extends View {
-  final Handler imeHandler;
-  final IBinder windowToken;
-  final View containerView;
-  final View rootView;
-  final View targetView;
-
-  private boolean triggerDelayed = true;
-  private boolean isLocked = false;
-  private InputConnection cachedConnection;
-
-  ThreadedInputConnectionProxyAdapterView(View containerView, View targetView, Handler imeHandler) {
-    super(containerView.getContext());
-    this.imeHandler = imeHandler;
-    this.containerView = containerView;
-    this.targetView = targetView;
-    windowToken = containerView.getWindowToken();
-    rootView = containerView.getRootView();
-    setFocusable(true);
-    setFocusableInTouchMode(true);
-    setVisibility(VISIBLE);
-  }
-
-  /** Returns whether or not this is currently asynchronously acquiring an input connection. */
-  boolean isTriggerDelayed() {
-    return triggerDelayed;
-  }
-
-  /** Sets whether or not this should use its previously cached input connection. */
-  void setLocked(boolean locked) {
-    isLocked = locked;
-  }
-
-  /**
-   * This is expected to be called on the IME thread. See the setup required for this in {@link
-   * InputAwareWebView#checkInputConnectionProxy(View)}.
-   *
-   * <p>Delegates to ThreadedInputConnectionProxyView to get WebView's input connection.
-   */
-  @Override
-  public InputConnection onCreateInputConnection(final EditorInfo outAttrs) {
-    triggerDelayed = false;
-    InputConnection inputConnection =
-        (isLocked) ? cachedConnection : targetView.onCreateInputConnection(outAttrs);
-    triggerDelayed = true;
-    cachedConnection = inputConnection;
-    return inputConnection;
-  }
-
-  @Override
-  public boolean checkInputConnectionProxy(View view) {
-    return true;
-  }
-
-  @Override
-  public boolean hasWindowFocus() {
-    // None of our views here correctly report they have window focus because of how we're embedding
-    // the platform view inside of a virtual display.
-    return true;
-  }
-
-  @Override
-  public View getRootView() {
-    return rootView;
-  }
-
-  @Override
-  public boolean onCheckIsTextEditor() {
-    return true;
-  }
-
-  @Override
-  public boolean isFocused() {
-    return true;
-  }
-
-  @Override
-  public IBinder getWindowToken() {
-    return windowToken;
-  }
-
-  @Override
-  public Handler getHandler() {
-    return imeHandler;
-  }
-}
diff --git a/packages/webview_flutter/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/WebViewBuilder.java b/packages/webview_flutter/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/WebViewBuilder.java
deleted file mode 100644
index d3cd1d5..0000000
--- a/packages/webview_flutter/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/WebViewBuilder.java
+++ /dev/null
@@ -1,155 +0,0 @@
-// Copyright 2013 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.
-
-package io.flutter.plugins.webviewflutter;
-
-import android.content.Context;
-import android.view.View;
-import android.webkit.DownloadListener;
-import android.webkit.WebChromeClient;
-import android.webkit.WebSettings;
-import android.webkit.WebView;
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-
-/** Builder used to create {@link android.webkit.WebView} objects. */
-public class WebViewBuilder {
-
-  /** Factory used to create a new {@link android.webkit.WebView} instance. */
-  static class WebViewFactory {
-
-    /**
-     * Creates a new {@link android.webkit.WebView} instance.
-     *
-     * @param context an Activity Context to access application assets. This value cannot be null.
-     * @param usesHybridComposition If {@code false} a {@link InputAwareWebView} instance is
-     *     returned.
-     * @param containerView must be supplied when the {@code useHybridComposition} parameter is set
-     *     to {@code false}. Used to create an InputConnection on the WebView's dedicated input, or
-     *     IME, thread (see also {@link InputAwareWebView})
-     * @return A new instance of the {@link android.webkit.WebView} object.
-     */
-    static WebView create(Context context, boolean usesHybridComposition, View containerView) {
-      return usesHybridComposition
-          ? new WebView(context)
-          : new InputAwareWebView(context, containerView);
-    }
-  }
-
-  private final Context context;
-  private final View containerView;
-
-  private boolean enableDomStorage;
-  private boolean javaScriptCanOpenWindowsAutomatically;
-  private boolean supportMultipleWindows;
-  private boolean usesHybridComposition;
-  private WebChromeClient webChromeClient;
-  private DownloadListener downloadListener;
-
-  /**
-   * Constructs a new {@link WebViewBuilder} object with a custom implementation of the {@link
-   * WebViewFactory} object.
-   *
-   * @param context an Activity Context to access application assets. This value cannot be null.
-   * @param containerView must be supplied when the {@code useHybridComposition} parameter is set to
-   *     {@code false}. Used to create an InputConnection on the WebView's dedicated input, or IME,
-   *     thread (see also {@link InputAwareWebView})
-   */
-  WebViewBuilder(@NonNull final Context context, View containerView) {
-    this.context = context;
-    this.containerView = containerView;
-  }
-
-  /**
-   * Sets whether the DOM storage API is enabled. The default value is {@code false}.
-   *
-   * @param flag {@code true} is {@link android.webkit.WebView} should use the DOM storage API.
-   * @return This builder. This value cannot be {@code null}.
-   */
-  public WebViewBuilder setDomStorageEnabled(boolean flag) {
-    this.enableDomStorage = flag;
-    return this;
-  }
-
-  /**
-   * Sets whether JavaScript is allowed to open windows automatically. This applies to the
-   * JavaScript function {@code window.open()}. The default value is {@code false}.
-   *
-   * @param flag {@code true} if JavaScript is allowed to open windows automatically.
-   * @return This builder. This value cannot be {@code null}.
-   */
-  public WebViewBuilder setJavaScriptCanOpenWindowsAutomatically(boolean flag) {
-    this.javaScriptCanOpenWindowsAutomatically = flag;
-    return this;
-  }
-
-  /**
-   * Sets whether the {@link WebView} supports multiple windows. If set to {@code true}, {@link
-   * WebChromeClient#onCreateWindow} must be implemented by the host application. The default is
-   * {@code false}.
-   *
-   * @param flag {@code true} if multiple windows are supported.
-   * @return This builder. This value cannot be {@code null}.
-   */
-  public WebViewBuilder setSupportMultipleWindows(boolean flag) {
-    this.supportMultipleWindows = flag;
-    return this;
-  }
-
-  /**
-   * Sets whether the hybrid composition should be used.
-   *
-   * <p>If set to {@code true} a standard {@link WebView} is created. If set to {@code false} the
-   * {@link WebViewBuilder} will create a {@link InputAwareWebView} to workaround issues using the
-   * {@link WebView} on Android versions below N.
-   *
-   * @param flag {@code true} if uses hybrid composition. The default is {@code false}.
-   * @return This builder. This value cannot be {@code null}
-   */
-  public WebViewBuilder setUsesHybridComposition(boolean flag) {
-    this.usesHybridComposition = flag;
-    return this;
-  }
-
-  /**
-   * Sets the chrome handler. This is an implementation of WebChromeClient for use in handling
-   * JavaScript dialogs, favicons, titles, and the progress. This will replace the current handler.
-   *
-   * @param webChromeClient an implementation of WebChromeClient This value may be null.
-   * @return This builder. This value cannot be {@code null}.
-   */
-  public WebViewBuilder setWebChromeClient(@Nullable WebChromeClient webChromeClient) {
-    this.webChromeClient = webChromeClient;
-    return this;
-  }
-
-  /**
-   * Registers the interface to be used when content can not be handled by the rendering engine, and
-   * should be downloaded instead. This will replace the current handler.
-   *
-   * @param downloadListener an implementation of DownloadListener This value may be null.
-   * @return This builder. This value cannot be {@code null}.
-   */
-  public WebViewBuilder setDownloadListener(@Nullable DownloadListener downloadListener) {
-    this.downloadListener = downloadListener;
-    return this;
-  }
-
-  /**
-   * Build the {@link android.webkit.WebView} using the current settings.
-   *
-   * @return The {@link android.webkit.WebView} using the current settings.
-   */
-  public WebView build() {
-    WebView webView = WebViewFactory.create(context, usesHybridComposition, containerView);
-
-    WebSettings webSettings = webView.getSettings();
-    webSettings.setDomStorageEnabled(enableDomStorage);
-    webSettings.setJavaScriptCanOpenWindowsAutomatically(javaScriptCanOpenWindowsAutomatically);
-    webSettings.setSupportMultipleWindows(supportMultipleWindows);
-    webView.setWebChromeClient(webChromeClient);
-    webView.setDownloadListener(downloadListener);
-    return webView;
-  }
-}
diff --git a/packages/webview_flutter/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/WebViewFlutterPlugin.java b/packages/webview_flutter/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/WebViewFlutterPlugin.java
deleted file mode 100644
index 268d35a..0000000
--- a/packages/webview_flutter/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/WebViewFlutterPlugin.java
+++ /dev/null
@@ -1,73 +0,0 @@
-// Copyright 2013 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.
-
-package io.flutter.plugins.webviewflutter;
-
-import io.flutter.embedding.engine.plugins.FlutterPlugin;
-import io.flutter.plugin.common.BinaryMessenger;
-
-/**
- * Java platform implementation of the webview_flutter plugin.
- *
- * <p>Register this in an add to app scenario to gracefully handle activity and context changes.
- *
- * <p>Call {@link #registerWith(Registrar)} to use the stable {@code io.flutter.plugin.common}
- * package instead.
- */
-public class WebViewFlutterPlugin implements FlutterPlugin {
-
-  private FlutterCookieManager flutterCookieManager;
-
-  /**
-   * Add an instance of this to {@link io.flutter.embedding.engine.plugins.PluginRegistry} to
-   * register it.
-   *
-   * <p>THIS PLUGIN CODE PATH DEPENDS ON A NEWER VERSION OF FLUTTER THAN THE ONE DEFINED IN THE
-   * PUBSPEC.YAML. Text input will fail on some Android devices unless this is used with at least
-   * flutter/flutter@1d4d63ace1f801a022ea9ec737bf8c15395588b9. Use the V1 embedding with {@link
-   * #registerWith(Registrar)} to use this plugin with older Flutter versions.
-   *
-   * <p>Registration should eventually be handled automatically by v2 of the
-   * GeneratedPluginRegistrant. https://github.com/flutter/flutter/issues/42694
-   */
-  public WebViewFlutterPlugin() {}
-
-  /**
-   * Registers a plugin implementation that uses the stable {@code io.flutter.plugin.common}
-   * package.
-   *
-   * <p>Calling this automatically initializes the plugin. However plugins initialized this way
-   * won't react to changes in activity or context, unlike {@link CameraPlugin}.
-   */
-  @SuppressWarnings("deprecation")
-  public static void registerWith(io.flutter.plugin.common.PluginRegistry.Registrar registrar) {
-    registrar
-        .platformViewRegistry()
-        .registerViewFactory(
-            "plugins.flutter.io/webview",
-            new FlutterWebViewFactory(registrar.messenger(), registrar.view()));
-    new FlutterCookieManager(registrar.messenger());
-  }
-
-  @Override
-  public void onAttachedToEngine(FlutterPluginBinding binding) {
-    BinaryMessenger messenger = binding.getBinaryMessenger();
-    binding
-        .getPlatformViewRegistry()
-        .registerViewFactory(
-            "plugins.flutter.io/webview",
-            new FlutterWebViewFactory(messenger, /*containerView=*/ null));
-    flutterCookieManager = new FlutterCookieManager(messenger);
-  }
-
-  @Override
-  public void onDetachedFromEngine(FlutterPluginBinding binding) {
-    if (flutterCookieManager == null) {
-      return;
-    }
-
-    flutterCookieManager.dispose();
-    flutterCookieManager = null;
-  }
-}
diff --git a/packages/webview_flutter/webview_flutter/android/src/test/java/io/flutter/plugins/webviewflutter/FlutterDownloadListenerTest.java b/packages/webview_flutter/webview_flutter/android/src/test/java/io/flutter/plugins/webviewflutter/FlutterDownloadListenerTest.java
deleted file mode 100644
index 2c91858..0000000
--- a/packages/webview_flutter/webview_flutter/android/src/test/java/io/flutter/plugins/webviewflutter/FlutterDownloadListenerTest.java
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright 2013 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.
-
-package io.flutter.plugins.webviewflutter;
-
-import static org.mockito.ArgumentMatchers.anyString;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.ArgumentMatchers.nullable;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-
-import android.webkit.WebView;
-import org.junit.Before;
-import org.junit.Test;
-
-public class FlutterDownloadListenerTest {
-  private FlutterWebViewClient webViewClient;
-  private WebView webView;
-
-  @Before
-  public void before() {
-    webViewClient = mock(FlutterWebViewClient.class);
-    webView = mock(WebView.class);
-  }
-
-  @Test
-  public void onDownloadStart_should_notify_webViewClient() {
-    String url = "testurl.com";
-    FlutterDownloadListener downloadListener = new FlutterDownloadListener(webViewClient);
-    downloadListener.onDownloadStart(url, "test", "inline", "data/text", 0);
-    verify(webViewClient).notifyDownload(nullable(WebView.class), eq(url));
-  }
-
-  @Test
-  public void onDownloadStart_should_pass_webView() {
-    FlutterDownloadListener downloadListener = new FlutterDownloadListener(webViewClient);
-    downloadListener.setWebView(webView);
-    downloadListener.onDownloadStart("testurl.com", "test", "inline", "data/text", 0);
-    verify(webViewClient).notifyDownload(eq(webView), anyString());
-  }
-}
diff --git a/packages/webview_flutter/webview_flutter/android/src/test/java/io/flutter/plugins/webviewflutter/FlutterWebViewClientTest.java b/packages/webview_flutter/webview_flutter/android/src/test/java/io/flutter/plugins/webviewflutter/FlutterWebViewClientTest.java
deleted file mode 100644
index 86346ac..0000000
--- a/packages/webview_flutter/webview_flutter/android/src/test/java/io/flutter/plugins/webviewflutter/FlutterWebViewClientTest.java
+++ /dev/null
@@ -1,60 +0,0 @@
-// Copyright 2013 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.
-
-package io.flutter.plugins.webviewflutter;
-
-import static org.junit.Assert.assertEquals;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoInteractions;
-
-import android.webkit.WebView;
-import io.flutter.plugin.common.MethodChannel;
-import java.util.HashMap;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.ArgumentCaptor;
-
-public class FlutterWebViewClientTest {
-
-  MethodChannel mockMethodChannel;
-  WebView mockWebView;
-
-  @Before
-  public void before() {
-    mockMethodChannel = mock(MethodChannel.class);
-    mockWebView = mock(WebView.class);
-  }
-
-  @Test
-  public void notify_download_should_notifyOnNavigationRequest_when_navigationDelegate_is_set() {
-    final String url = "testurl.com";
-
-    FlutterWebViewClient client = new FlutterWebViewClient(mockMethodChannel);
-    client.createWebViewClient(true);
-
-    client.notifyDownload(mockWebView, url);
-    ArgumentCaptor<Object> argumentCaptor = ArgumentCaptor.forClass(Object.class);
-    verify(mockMethodChannel)
-        .invokeMethod(
-            eq("navigationRequest"), argumentCaptor.capture(), any(MethodChannel.Result.class));
-    HashMap<String, Object> map = (HashMap<String, Object>) argumentCaptor.getValue();
-    assertEquals(map.get("url"), url);
-    assertEquals(map.get("isForMainFrame"), true);
-  }
-
-  @Test
-  public void
-      notify_download_should_not_notifyOnNavigationRequest_when_navigationDelegate_is_not_set() {
-    final String url = "testurl.com";
-
-    FlutterWebViewClient client = new FlutterWebViewClient(mockMethodChannel);
-    client.createWebViewClient(false);
-
-    client.notifyDownload(mockWebView, url);
-    verifyNoInteractions(mockMethodChannel);
-  }
-}
diff --git a/packages/webview_flutter/webview_flutter/android/src/test/java/io/flutter/plugins/webviewflutter/FlutterWebViewTest.java b/packages/webview_flutter/webview_flutter/android/src/test/java/io/flutter/plugins/webviewflutter/FlutterWebViewTest.java
deleted file mode 100644
index 56d9db1..0000000
--- a/packages/webview_flutter/webview_flutter/android/src/test/java/io/flutter/plugins/webviewflutter/FlutterWebViewTest.java
+++ /dev/null
@@ -1,66 +0,0 @@
-// Copyright 2013 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.
-
-package io.flutter.plugins.webviewflutter;
-
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyBoolean;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.webkit.DownloadListener;
-import android.webkit.WebChromeClient;
-import android.webkit.WebView;
-import java.util.HashMap;
-import java.util.Map;
-import org.junit.Before;
-import org.junit.Test;
-
-public class FlutterWebViewTest {
-  private WebChromeClient mockWebChromeClient;
-  private DownloadListener mockDownloadListener;
-  private WebViewBuilder mockWebViewBuilder;
-  private WebView mockWebView;
-
-  @Before
-  public void before() {
-    mockWebChromeClient = mock(WebChromeClient.class);
-    mockWebViewBuilder = mock(WebViewBuilder.class);
-    mockWebView = mock(WebView.class);
-    mockDownloadListener = mock(DownloadListener.class);
-
-    when(mockWebViewBuilder.setDomStorageEnabled(anyBoolean())).thenReturn(mockWebViewBuilder);
-    when(mockWebViewBuilder.setJavaScriptCanOpenWindowsAutomatically(anyBoolean()))
-        .thenReturn(mockWebViewBuilder);
-    when(mockWebViewBuilder.setSupportMultipleWindows(anyBoolean())).thenReturn(mockWebViewBuilder);
-    when(mockWebViewBuilder.setUsesHybridComposition(anyBoolean())).thenReturn(mockWebViewBuilder);
-    when(mockWebViewBuilder.setWebChromeClient(any(WebChromeClient.class)))
-        .thenReturn(mockWebViewBuilder);
-    when(mockWebViewBuilder.setDownloadListener(any(DownloadListener.class)))
-        .thenReturn(mockWebViewBuilder);
-
-    when(mockWebViewBuilder.build()).thenReturn(mockWebView);
-  }
-
-  @Test
-  public void createWebView_should_create_webview_with_default_configuration() {
-    FlutterWebView.createWebView(
-        mockWebViewBuilder, createParameterMap(false), mockWebChromeClient, mockDownloadListener);
-
-    verify(mockWebViewBuilder, times(1)).setDomStorageEnabled(true);
-    verify(mockWebViewBuilder, times(1)).setJavaScriptCanOpenWindowsAutomatically(true);
-    verify(mockWebViewBuilder, times(1)).setSupportMultipleWindows(true);
-    verify(mockWebViewBuilder, times(1)).setUsesHybridComposition(false);
-    verify(mockWebViewBuilder, times(1)).setWebChromeClient(mockWebChromeClient);
-  }
-
-  private Map<String, Object> createParameterMap(boolean usesHybridComposition) {
-    Map<String, Object> params = new HashMap<>();
-    params.put("usesHybridComposition", usesHybridComposition);
-
-    return params;
-  }
-}
diff --git a/packages/webview_flutter/webview_flutter/android/src/test/java/io/flutter/plugins/webviewflutter/WebViewBuilderTest.java b/packages/webview_flutter/webview_flutter/android/src/test/java/io/flutter/plugins/webviewflutter/WebViewBuilderTest.java
deleted file mode 100644
index 423cb21..0000000
--- a/packages/webview_flutter/webview_flutter/android/src/test/java/io/flutter/plugins/webviewflutter/WebViewBuilderTest.java
+++ /dev/null
@@ -1,104 +0,0 @@
-// Copyright 2013 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.
-
-package io.flutter.plugins.webviewflutter;
-
-import static org.junit.Assert.assertNotNull;
-import static org.mockito.Mockito.*;
-
-import android.content.Context;
-import android.view.View;
-import android.webkit.DownloadListener;
-import android.webkit.WebChromeClient;
-import android.webkit.WebSettings;
-import android.webkit.WebView;
-import io.flutter.plugins.webviewflutter.WebViewBuilder.WebViewFactory;
-import java.io.IOException;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.MockedStatic;
-import org.mockito.MockedStatic.Verification;
-
-public class WebViewBuilderTest {
-  private Context mockContext;
-  private View mockContainerView;
-  private WebView mockWebView;
-  private MockedStatic<WebViewFactory> mockedStaticWebViewFactory;
-
-  @Before
-  public void before() {
-    mockContext = mock(Context.class);
-    mockContainerView = mock(View.class);
-    mockWebView = mock(WebView.class);
-    mockedStaticWebViewFactory = mockStatic(WebViewFactory.class);
-
-    mockedStaticWebViewFactory
-        .when(
-            new Verification() {
-              @Override
-              public void apply() {
-                WebViewFactory.create(mockContext, false, mockContainerView);
-              }
-            })
-        .thenReturn(mockWebView);
-  }
-
-  @After
-  public void after() {
-    mockedStaticWebViewFactory.close();
-  }
-
-  @Test
-  public void ctor_test() {
-    WebViewBuilder builder = new WebViewBuilder(mockContext, mockContainerView);
-
-    assertNotNull(builder);
-  }
-
-  @Test
-  public void build_should_set_values() throws IOException {
-    WebSettings mockWebSettings = mock(WebSettings.class);
-    WebChromeClient mockWebChromeClient = mock(WebChromeClient.class);
-    DownloadListener mockDownloadListener = mock(DownloadListener.class);
-
-    when(mockWebView.getSettings()).thenReturn(mockWebSettings);
-
-    WebViewBuilder builder =
-        new WebViewBuilder(mockContext, mockContainerView)
-            .setDomStorageEnabled(true)
-            .setJavaScriptCanOpenWindowsAutomatically(true)
-            .setSupportMultipleWindows(true)
-            .setWebChromeClient(mockWebChromeClient)
-            .setDownloadListener(mockDownloadListener);
-
-    WebView webView = builder.build();
-
-    assertNotNull(webView);
-    verify(mockWebSettings).setDomStorageEnabled(true);
-    verify(mockWebSettings).setJavaScriptCanOpenWindowsAutomatically(true);
-    verify(mockWebSettings).setSupportMultipleWindows(true);
-    verify(mockWebView).setWebChromeClient(mockWebChromeClient);
-    verify(mockWebView).setDownloadListener(mockDownloadListener);
-  }
-
-  @Test
-  public void build_should_use_default_values() throws IOException {
-    WebSettings mockWebSettings = mock(WebSettings.class);
-    WebChromeClient mockWebChromeClient = mock(WebChromeClient.class);
-
-    when(mockWebView.getSettings()).thenReturn(mockWebSettings);
-
-    WebViewBuilder builder = new WebViewBuilder(mockContext, mockContainerView);
-
-    WebView webView = builder.build();
-
-    assertNotNull(webView);
-    verify(mockWebSettings).setDomStorageEnabled(false);
-    verify(mockWebSettings).setJavaScriptCanOpenWindowsAutomatically(false);
-    verify(mockWebSettings).setSupportMultipleWindows(false);
-    verify(mockWebView).setWebChromeClient(null);
-    verify(mockWebView).setDownloadListener(null);
-  }
-}
diff --git a/packages/webview_flutter/webview_flutter/android/src/test/java/io/flutter/plugins/webviewflutter/WebViewTest.java b/packages/webview_flutter/webview_flutter/android/src/test/java/io/flutter/plugins/webviewflutter/WebViewTest.java
deleted file mode 100644
index 131a5a3..0000000
--- a/packages/webview_flutter/webview_flutter/android/src/test/java/io/flutter/plugins/webviewflutter/WebViewTest.java
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright 2013 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.
-
-package io.flutter.plugins.webviewflutter;
-
-import static org.junit.Assert.assertEquals;
-
-import android.webkit.WebViewClient;
-import org.junit.Test;
-
-public class WebViewTest {
-  @Test
-  public void errorCodes() {
-    assertEquals(
-        FlutterWebViewClient.errorCodeToString(WebViewClient.ERROR_AUTHENTICATION),
-        "authentication");
-    assertEquals(FlutterWebViewClient.errorCodeToString(WebViewClient.ERROR_BAD_URL), "badUrl");
-    assertEquals(FlutterWebViewClient.errorCodeToString(WebViewClient.ERROR_CONNECT), "connect");
-    assertEquals(
-        FlutterWebViewClient.errorCodeToString(WebViewClient.ERROR_FAILED_SSL_HANDSHAKE),
-        "failedSslHandshake");
-    assertEquals(FlutterWebViewClient.errorCodeToString(WebViewClient.ERROR_FILE), "file");
-    assertEquals(
-        FlutterWebViewClient.errorCodeToString(WebViewClient.ERROR_FILE_NOT_FOUND), "fileNotFound");
-    assertEquals(
-        FlutterWebViewClient.errorCodeToString(WebViewClient.ERROR_HOST_LOOKUP), "hostLookup");
-    assertEquals(FlutterWebViewClient.errorCodeToString(WebViewClient.ERROR_IO), "io");
-    assertEquals(
-        FlutterWebViewClient.errorCodeToString(WebViewClient.ERROR_PROXY_AUTHENTICATION),
-        "proxyAuthentication");
-    assertEquals(
-        FlutterWebViewClient.errorCodeToString(WebViewClient.ERROR_REDIRECT_LOOP), "redirectLoop");
-    assertEquals(FlutterWebViewClient.errorCodeToString(WebViewClient.ERROR_TIMEOUT), "timeout");
-    assertEquals(
-        FlutterWebViewClient.errorCodeToString(WebViewClient.ERROR_TOO_MANY_REQUESTS),
-        "tooManyRequests");
-    assertEquals(FlutterWebViewClient.errorCodeToString(WebViewClient.ERROR_UNKNOWN), "unknown");
-    assertEquals(
-        FlutterWebViewClient.errorCodeToString(WebViewClient.ERROR_UNSAFE_RESOURCE),
-        "unsafeResource");
-    assertEquals(
-        FlutterWebViewClient.errorCodeToString(WebViewClient.ERROR_UNSUPPORTED_AUTH_SCHEME),
-        "unsupportedAuthScheme");
-    assertEquals(
-        FlutterWebViewClient.errorCodeToString(WebViewClient.ERROR_UNSUPPORTED_SCHEME),
-        "unsupportedScheme");
-  }
-}
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 0e128ca..a6211b2 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
@@ -18,6 +18,8 @@
 void main() {
   IntegrationTestWidgetsFlutterBinding.ensureInitialized();
 
+  const bool _skipDueToIssue86757 = true;
+
   // TODO(bparrishMines): skipped due to https://github.com/flutter/flutter/issues/86757.
   testWidgets('initialUrl', (WidgetTester tester) async {
     final Completer<WebViewController> controllerCompleter =
@@ -37,7 +39,7 @@
     final WebViewController controller = await controllerCompleter.future;
     final String? currentUrl = await controller.currentUrl();
     expect(currentUrl, 'https://flutter.dev/');
-  }, skip: true);
+  }, skip: _skipDueToIssue86757);
 
   // TODO(bparrishMines): skipped due to https://github.com/flutter/flutter/issues/86757.
   testWidgets('loadUrl', (WidgetTester tester) async {
@@ -59,7 +61,7 @@
     await controller.loadUrl('https://www.google.com/');
     final String? currentUrl = await controller.currentUrl();
     expect(currentUrl, 'https://www.google.com/');
-  }, skip: true);
+  }, skip: _skipDueToIssue86757);
 
   // TODO(bparrishMines): skipped due to https://github.com/flutter/flutter/issues/86757.
   testWidgets('loadUrl with headers', (WidgetTester tester) async {
@@ -101,7 +103,7 @@
     final String content = await controller
         .evaluateJavascript('document.documentElement.innerText');
     expect(content.contains('flutter_test_header'), isTrue);
-  }, skip: Platform.isAndroid);
+  }, skip: Platform.isAndroid && _skipDueToIssue86757);
 
   // TODO(bparrishMines): skipped due to https://github.com/flutter/flutter/issues/86757.
   testWidgets('JavaScriptChannel', (WidgetTester tester) async {
@@ -150,7 +152,7 @@
     // https://github.com/flutter/flutter/issues/66318
     await controller.evaluateJavascript('Echo.postMessage("hello");1;');
     expect(messagesReceived, equals(<String>['hello']));
-  }, skip: Platform.isAndroid);
+  }, skip: Platform.isAndroid && _skipDueToIssue86757);
 
   testWidgets('resize webview', (WidgetTester tester) async {
     final String resizeTest = '''
@@ -328,7 +330,7 @@
 
     final String customUserAgent2 = await _getUserAgent(controller);
     expect(customUserAgent2, defaultPlatformUserAgent);
-  }, skip: Platform.isAndroid);
+  }, skip: Platform.isAndroid && _skipDueToIssue86757);
 
   group('Video playback policy', () {
     late String videoTestBase64;
@@ -877,7 +879,7 @@
       scrollPosY = await controller.getScrollY();
       expect(scrollPosX, X_SCROLL * 2);
       expect(scrollPosY, Y_SCROLL * 2);
-    }, skip: Platform.isAndroid);
+    }, skip: Platform.isAndroid && _skipDueToIssue86757);
   });
 
   group('SurfaceAndroidWebView', () {
@@ -956,7 +958,7 @@
       scrollPosY = await controller.getScrollY();
       expect(X_SCROLL * 2, scrollPosX);
       expect(Y_SCROLL * 2, scrollPosY);
-    }, skip: true);
+    }, skip: !Platform.isAndroid || _skipDueToIssue86757);
 
     // TODO(bparrishMines): skipped due to https://github.com/flutter/flutter/issues/86757.
     testWidgets('inputs are scrolled into view when focused',
@@ -1062,7 +1064,7 @@
           lastInputClientRectRelativeToViewport['right'] <=
               viewportRectRelativeToViewport['right'],
           isTrue);
-    }, skip: true);
+    }, skip: !Platform.isAndroid || _skipDueToIssue86757);
   });
 
   group('NavigationDelegate', () {
@@ -1332,7 +1334,7 @@
     expect(currentUrl, 'https://flutter.dev/');
   },
       // Flaky on Android: https://github.com/flutter/flutter/issues/86757
-      skip: Platform.isAndroid);
+      skip: Platform.isAndroid && _skipDueToIssue86757);
 
   // TODO(bparrishMines): skipped due to https://github.com/flutter/flutter/issues/86757.
   testWidgets(
@@ -1373,7 +1375,7 @@
       await pageLoaded.future;
       expect(controller.currentUrl(), completion('https://flutter.dev/'));
     },
-    skip: true,
+    skip: _skipDueToIssue86757,
   );
 
   testWidgets(
diff --git a/packages/webview_flutter/webview_flutter/ios/Assets/.gitkeep b/packages/webview_flutter/webview_flutter/ios/Assets/.gitkeep
deleted file mode 100644
index e69de29..0000000
--- a/packages/webview_flutter/webview_flutter/ios/Assets/.gitkeep
+++ /dev/null
diff --git a/packages/webview_flutter/webview_flutter/ios/Classes/FLTCookieManager.h b/packages/webview_flutter/webview_flutter/ios/Classes/FLTCookieManager.h
deleted file mode 100644
index 8fe3318..0000000
--- a/packages/webview_flutter/webview_flutter/ios/Classes/FLTCookieManager.h
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright 2013 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.
-
-#import <Flutter/Flutter.h>
-#import <WebKit/WebKit.h>
-
-NS_ASSUME_NONNULL_BEGIN
-
-@interface FLTCookieManager : NSObject <FlutterPlugin>
-
-@end
-
-NS_ASSUME_NONNULL_END
diff --git a/packages/webview_flutter/webview_flutter/ios/Classes/FLTCookieManager.m b/packages/webview_flutter/webview_flutter/ios/Classes/FLTCookieManager.m
deleted file mode 100644
index eb7c856..0000000
--- a/packages/webview_flutter/webview_flutter/ios/Classes/FLTCookieManager.m
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright 2013 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.
-
-#import "FLTCookieManager.h"
-
-@implementation FLTCookieManager {
-}
-
-+ (void)registerWithRegistrar:(NSObject<FlutterPluginRegistrar> *)registrar {
-  FLTCookieManager *instance = [[FLTCookieManager alloc] init];
-
-  FlutterMethodChannel *channel =
-      [FlutterMethodChannel methodChannelWithName:@"plugins.flutter.io/cookie_manager"
-                                  binaryMessenger:[registrar messenger]];
-  [registrar addMethodCallDelegate:instance channel:channel];
-}
-
-- (void)handleMethodCall:(FlutterMethodCall *)call result:(FlutterResult)result {
-  if ([[call method] isEqualToString:@"clearCookies"]) {
-    [self clearCookies:result];
-  } else {
-    result(FlutterMethodNotImplemented);
-  }
-}
-
-- (void)clearCookies:(FlutterResult)result {
-  NSSet<NSString *> *websiteDataTypes = [NSSet setWithObject:WKWebsiteDataTypeCookies];
-  WKWebsiteDataStore *dataStore = [WKWebsiteDataStore defaultDataStore];
-
-  void (^deleteAndNotify)(NSArray<WKWebsiteDataRecord *> *) =
-      ^(NSArray<WKWebsiteDataRecord *> *cookies) {
-        BOOL hasCookies = cookies.count > 0;
-        [dataStore removeDataOfTypes:websiteDataTypes
-                      forDataRecords:cookies
-                   completionHandler:^{
-                     result(@(hasCookies));
-                   }];
-      };
-
-  [dataStore fetchDataRecordsOfTypes:websiteDataTypes completionHandler:deleteAndNotify];
-}
-
-@end
diff --git a/packages/webview_flutter/webview_flutter/ios/Classes/FLTWKNavigationDelegate.h b/packages/webview_flutter/webview_flutter/ios/Classes/FLTWKNavigationDelegate.h
deleted file mode 100644
index 31edadc..0000000
--- a/packages/webview_flutter/webview_flutter/ios/Classes/FLTWKNavigationDelegate.h
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright 2013 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.
-
-#import <Flutter/Flutter.h>
-#import <WebKit/WebKit.h>
-
-NS_ASSUME_NONNULL_BEGIN
-
-@interface FLTWKNavigationDelegate : NSObject <WKNavigationDelegate>
-
-- (instancetype)initWithChannel:(FlutterMethodChannel*)channel;
-
-/**
- * Whether to delegate navigation decisions over the method channel.
- */
-@property(nonatomic, assign) BOOL hasDartNavigationDelegate;
-
-@end
-
-NS_ASSUME_NONNULL_END
diff --git a/packages/webview_flutter/webview_flutter/ios/Classes/FLTWKNavigationDelegate.m b/packages/webview_flutter/webview_flutter/ios/Classes/FLTWKNavigationDelegate.m
deleted file mode 100644
index 8b7ee7d..0000000
--- a/packages/webview_flutter/webview_flutter/ios/Classes/FLTWKNavigationDelegate.m
+++ /dev/null
@@ -1,116 +0,0 @@
-// Copyright 2013 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.
-
-#import "FLTWKNavigationDelegate.h"
-
-@implementation FLTWKNavigationDelegate {
-  FlutterMethodChannel *_methodChannel;
-}
-
-- (instancetype)initWithChannel:(FlutterMethodChannel *)channel {
-  self = [super init];
-  if (self) {
-    _methodChannel = channel;
-  }
-  return self;
-}
-
-#pragma mark - WKNavigationDelegate conformance
-
-- (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation {
-  [_methodChannel invokeMethod:@"onPageStarted" arguments:@{@"url" : webView.URL.absoluteString}];
-}
-
-- (void)webView:(WKWebView *)webView
-    decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction
-                    decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {
-  if (!self.hasDartNavigationDelegate) {
-    decisionHandler(WKNavigationActionPolicyAllow);
-    return;
-  }
-  NSDictionary *arguments = @{
-    @"url" : navigationAction.request.URL.absoluteString,
-    @"isForMainFrame" : @(navigationAction.targetFrame.isMainFrame)
-  };
-  [_methodChannel invokeMethod:@"navigationRequest"
-                     arguments:arguments
-                        result:^(id _Nullable result) {
-                          if ([result isKindOfClass:[FlutterError class]]) {
-                            NSLog(@"navigationRequest has unexpectedly completed with an error, "
-                                  @"allowing navigation.");
-                            decisionHandler(WKNavigationActionPolicyAllow);
-                            return;
-                          }
-                          if (result == FlutterMethodNotImplemented) {
-                            NSLog(@"navigationRequest was unexepectedly not implemented: %@, "
-                                  @"allowing navigation.",
-                                  result);
-                            decisionHandler(WKNavigationActionPolicyAllow);
-                            return;
-                          }
-                          if (![result isKindOfClass:[NSNumber class]]) {
-                            NSLog(@"navigationRequest unexpectedly returned a non boolean value: "
-                                  @"%@, allowing navigation.",
-                                  result);
-                            decisionHandler(WKNavigationActionPolicyAllow);
-                            return;
-                          }
-                          NSNumber *typedResult = result;
-                          decisionHandler([typedResult boolValue] ? WKNavigationActionPolicyAllow
-                                                                  : WKNavigationActionPolicyCancel);
-                        }];
-}
-
-- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation {
-  [_methodChannel invokeMethod:@"onPageFinished" arguments:@{@"url" : webView.URL.absoluteString}];
-}
-
-+ (id)errorCodeToString:(NSUInteger)code {
-  switch (code) {
-    case WKErrorUnknown:
-      return @"unknown";
-    case WKErrorWebContentProcessTerminated:
-      return @"webContentProcessTerminated";
-    case WKErrorWebViewInvalidated:
-      return @"webViewInvalidated";
-    case WKErrorJavaScriptExceptionOccurred:
-      return @"javaScriptExceptionOccurred";
-    case WKErrorJavaScriptResultTypeIsUnsupported:
-      return @"javaScriptResultTypeIsUnsupported";
-  }
-
-  return [NSNull null];
-}
-
-- (void)onWebResourceError:(NSError *)error {
-  [_methodChannel invokeMethod:@"onWebResourceError"
-                     arguments:@{
-                       @"errorCode" : @(error.code),
-                       @"domain" : error.domain,
-                       @"description" : error.description,
-                       @"errorType" : [FLTWKNavigationDelegate errorCodeToString:error.code],
-                     }];
-}
-
-- (void)webView:(WKWebView *)webView
-    didFailNavigation:(WKNavigation *)navigation
-            withError:(NSError *)error {
-  [self onWebResourceError:error];
-}
-
-- (void)webView:(WKWebView *)webView
-    didFailProvisionalNavigation:(WKNavigation *)navigation
-                       withError:(NSError *)error {
-  [self onWebResourceError:error];
-}
-
-- (void)webViewWebContentProcessDidTerminate:(WKWebView *)webView {
-  NSError *contentProcessTerminatedError =
-      [[NSError alloc] initWithDomain:WKErrorDomain
-                                 code:WKErrorWebContentProcessTerminated
-                             userInfo:nil];
-  [self onWebResourceError:contentProcessTerminatedError];
-}
-
-@end
diff --git a/packages/webview_flutter/webview_flutter/ios/Classes/FLTWKProgressionDelegate.h b/packages/webview_flutter/webview_flutter/ios/Classes/FLTWKProgressionDelegate.h
deleted file mode 100644
index 96af4ef..0000000
--- a/packages/webview_flutter/webview_flutter/ios/Classes/FLTWKProgressionDelegate.h
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright 2013 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.
-
-#import <Flutter/Flutter.h>
-#import <Foundation/Foundation.h>
-#import <WebKit/WebKit.h>
-
-NS_ASSUME_NONNULL_BEGIN
-
-@interface FLTWKProgressionDelegate : NSObject
-
-- (instancetype)initWithWebView:(WKWebView *)webView channel:(FlutterMethodChannel *)channel;
-
-- (void)stopObservingProgress:(WKWebView *)webView;
-
-@end
-
-NS_ASSUME_NONNULL_END
diff --git a/packages/webview_flutter/webview_flutter/ios/Classes/FLTWKProgressionDelegate.m b/packages/webview_flutter/webview_flutter/ios/Classes/FLTWKProgressionDelegate.m
deleted file mode 100644
index 8e7af46..0000000
--- a/packages/webview_flutter/webview_flutter/ios/Classes/FLTWKProgressionDelegate.m
+++ /dev/null
@@ -1,41 +0,0 @@
-// Copyright 2013 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.
-
-#import "FLTWKProgressionDelegate.h"
-
-NSString *const FLTWKEstimatedProgressKeyPath = @"estimatedProgress";
-
-@implementation FLTWKProgressionDelegate {
-  FlutterMethodChannel *_methodChannel;
-}
-
-- (instancetype)initWithWebView:(WKWebView *)webView channel:(FlutterMethodChannel *)channel {
-  self = [super init];
-  if (self) {
-    _methodChannel = channel;
-    [webView addObserver:self
-              forKeyPath:FLTWKEstimatedProgressKeyPath
-                 options:NSKeyValueObservingOptionNew
-                 context:nil];
-  }
-  return self;
-}
-
-- (void)stopObservingProgress:(WKWebView *)webView {
-  [webView removeObserver:self forKeyPath:FLTWKEstimatedProgressKeyPath];
-}
-
-- (void)observeValueForKeyPath:(NSString *)keyPath
-                      ofObject:(id)object
-                        change:(NSDictionary<NSKeyValueChangeKey, id> *)change
-                       context:(void *)context {
-  if ([keyPath isEqualToString:FLTWKEstimatedProgressKeyPath]) {
-    NSNumber *newValue =
-        change[NSKeyValueChangeNewKey] ?: 0;          // newValue is anywhere between 0.0 and 1.0
-    int newValueAsInt = [newValue floatValue] * 100;  // Anywhere between 0 and 100
-    [_methodChannel invokeMethod:@"onProgress" arguments:@{@"progress" : @(newValueAsInt)}];
-  }
-}
-
-@end
diff --git a/packages/webview_flutter/webview_flutter/ios/Classes/FLTWebViewFlutterPlugin.h b/packages/webview_flutter/webview_flutter/ios/Classes/FLTWebViewFlutterPlugin.h
deleted file mode 100644
index 2a80c7d..0000000
--- a/packages/webview_flutter/webview_flutter/ios/Classes/FLTWebViewFlutterPlugin.h
+++ /dev/null
@@ -1,8 +0,0 @@
-// Copyright 2013 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.
-
-#import <Flutter/Flutter.h>
-
-@interface FLTWebViewFlutterPlugin : NSObject <FlutterPlugin>
-@end
diff --git a/packages/webview_flutter/webview_flutter/ios/Classes/FLTWebViewFlutterPlugin.m b/packages/webview_flutter/webview_flutter/ios/Classes/FLTWebViewFlutterPlugin.m
deleted file mode 100644
index 9f01416..0000000
--- a/packages/webview_flutter/webview_flutter/ios/Classes/FLTWebViewFlutterPlugin.m
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright 2013 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.
-
-#import "FLTWebViewFlutterPlugin.h"
-#import "FLTCookieManager.h"
-#import "FlutterWebView.h"
-
-@implementation FLTWebViewFlutterPlugin
-
-+ (void)registerWithRegistrar:(NSObject<FlutterPluginRegistrar>*)registrar {
-  FLTWebViewFactory* webviewFactory =
-      [[FLTWebViewFactory alloc] initWithMessenger:registrar.messenger];
-  [registrar registerViewFactory:webviewFactory withId:@"plugins.flutter.io/webview"];
-  [FLTCookieManager registerWithRegistrar:registrar];
-}
-
-@end
diff --git a/packages/webview_flutter/webview_flutter/ios/Classes/FlutterWebView.h b/packages/webview_flutter/webview_flutter/ios/Classes/FlutterWebView.h
deleted file mode 100644
index 6e795f7..0000000
--- a/packages/webview_flutter/webview_flutter/ios/Classes/FlutterWebView.h
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright 2013 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.
-
-#import <Flutter/Flutter.h>
-#import <WebKit/WebKit.h>
-
-NS_ASSUME_NONNULL_BEGIN
-
-@interface FLTWebViewController : NSObject <FlutterPlatformView, WKUIDelegate>
-
-- (instancetype)initWithFrame:(CGRect)frame
-               viewIdentifier:(int64_t)viewId
-                    arguments:(id _Nullable)args
-              binaryMessenger:(NSObject<FlutterBinaryMessenger>*)messenger;
-
-- (UIView*)view;
-@end
-
-@interface FLTWebViewFactory : NSObject <FlutterPlatformViewFactory>
-- (instancetype)initWithMessenger:(NSObject<FlutterBinaryMessenger>*)messenger;
-@end
-
-/**
- * The WkWebView used for the plugin.
- *
- * This class overrides some methods in `WKWebView` to serve the needs for the plugin.
- */
-@interface FLTWKWebView : WKWebView
-@end
-
-NS_ASSUME_NONNULL_END
diff --git a/packages/webview_flutter/webview_flutter/ios/Classes/FlutterWebView.m b/packages/webview_flutter/webview_flutter/ios/Classes/FlutterWebView.m
deleted file mode 100644
index 1604f27..0000000
--- a/packages/webview_flutter/webview_flutter/ios/Classes/FlutterWebView.m
+++ /dev/null
@@ -1,475 +0,0 @@
-// Copyright 2013 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.
-
-#import "FlutterWebView.h"
-#import "FLTWKNavigationDelegate.h"
-#import "FLTWKProgressionDelegate.h"
-#import "JavaScriptChannelHandler.h"
-
-@implementation FLTWebViewFactory {
-  NSObject<FlutterBinaryMessenger>* _messenger;
-}
-
-- (instancetype)initWithMessenger:(NSObject<FlutterBinaryMessenger>*)messenger {
-  self = [super init];
-  if (self) {
-    _messenger = messenger;
-  }
-  return self;
-}
-
-- (NSObject<FlutterMessageCodec>*)createArgsCodec {
-  return [FlutterStandardMessageCodec sharedInstance];
-}
-
-- (NSObject<FlutterPlatformView>*)createWithFrame:(CGRect)frame
-                                   viewIdentifier:(int64_t)viewId
-                                        arguments:(id _Nullable)args {
-  FLTWebViewController* webviewController = [[FLTWebViewController alloc] initWithFrame:frame
-                                                                         viewIdentifier:viewId
-                                                                              arguments:args
-                                                                        binaryMessenger:_messenger];
-  return webviewController;
-}
-
-@end
-
-@implementation FLTWKWebView
-
-- (void)setFrame:(CGRect)frame {
-  [super setFrame:frame];
-  self.scrollView.contentInset = UIEdgeInsetsZero;
-  // We don't want the contentInsets to be adjusted by iOS, flutter should always take control of
-  // webview's contentInsets.
-  // self.scrollView.contentInset = UIEdgeInsetsZero;
-  if (@available(iOS 11, *)) {
-    // Above iOS 11, adjust contentInset to compensate the adjustedContentInset so the sum will
-    // always be 0.
-    if (UIEdgeInsetsEqualToEdgeInsets(self.scrollView.adjustedContentInset, UIEdgeInsetsZero)) {
-      return;
-    }
-    UIEdgeInsets insetToAdjust = self.scrollView.adjustedContentInset;
-    self.scrollView.contentInset = UIEdgeInsetsMake(-insetToAdjust.top, -insetToAdjust.left,
-                                                    -insetToAdjust.bottom, -insetToAdjust.right);
-  }
-}
-
-@end
-
-@implementation FLTWebViewController {
-  FLTWKWebView* _webView;
-  int64_t _viewId;
-  FlutterMethodChannel* _channel;
-  NSString* _currentUrl;
-  // The set of registered JavaScript channel names.
-  NSMutableSet* _javaScriptChannelNames;
-  FLTWKNavigationDelegate* _navigationDelegate;
-  FLTWKProgressionDelegate* _progressionDelegate;
-}
-
-- (instancetype)initWithFrame:(CGRect)frame
-               viewIdentifier:(int64_t)viewId
-                    arguments:(id _Nullable)args
-              binaryMessenger:(NSObject<FlutterBinaryMessenger>*)messenger {
-  if (self = [super init]) {
-    _viewId = viewId;
-
-    NSString* channelName = [NSString stringWithFormat:@"plugins.flutter.io/webview_%lld", viewId];
-    _channel = [FlutterMethodChannel methodChannelWithName:channelName binaryMessenger:messenger];
-    _javaScriptChannelNames = [[NSMutableSet alloc] init];
-
-    WKUserContentController* userContentController = [[WKUserContentController alloc] init];
-    if ([args[@"javascriptChannelNames"] isKindOfClass:[NSArray class]]) {
-      NSArray* javaScriptChannelNames = args[@"javascriptChannelNames"];
-      [_javaScriptChannelNames addObjectsFromArray:javaScriptChannelNames];
-      [self registerJavaScriptChannels:_javaScriptChannelNames controller:userContentController];
-    }
-
-    NSDictionary<NSString*, id>* settings = args[@"settings"];
-
-    WKWebViewConfiguration* configuration = [[WKWebViewConfiguration alloc] init];
-    [self applyConfigurationSettings:settings toConfiguration:configuration];
-    configuration.userContentController = userContentController;
-    [self updateAutoMediaPlaybackPolicy:args[@"autoMediaPlaybackPolicy"]
-                        inConfiguration:configuration];
-
-    _webView = [[FLTWKWebView alloc] initWithFrame:frame configuration:configuration];
-    _navigationDelegate = [[FLTWKNavigationDelegate alloc] initWithChannel:_channel];
-    _webView.UIDelegate = self;
-    _webView.navigationDelegate = _navigationDelegate;
-    __weak __typeof__(self) weakSelf = self;
-    [_channel setMethodCallHandler:^(FlutterMethodCall* call, FlutterResult result) {
-      [weakSelf onMethodCall:call result:result];
-    }];
-
-    if (@available(iOS 11.0, *)) {
-      _webView.scrollView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
-      if (@available(iOS 13.0, *)) {
-        _webView.scrollView.automaticallyAdjustsScrollIndicatorInsets = NO;
-      }
-    }
-
-    [self applySettings:settings];
-    // TODO(amirh): return an error if apply settings failed once it's possible to do so.
-    // https://github.com/flutter/flutter/issues/36228
-
-    NSString* initialUrl = args[@"initialUrl"];
-    if ([initialUrl isKindOfClass:[NSString class]]) {
-      [self loadUrl:initialUrl];
-    }
-  }
-  return self;
-}
-
-- (void)dealloc {
-  if (_progressionDelegate != nil) {
-    [_progressionDelegate stopObservingProgress:_webView];
-  }
-}
-
-- (UIView*)view {
-  return _webView;
-}
-
-- (void)onMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result {
-  if ([[call method] isEqualToString:@"updateSettings"]) {
-    [self onUpdateSettings:call result:result];
-  } else if ([[call method] isEqualToString:@"loadUrl"]) {
-    [self onLoadUrl:call result:result];
-  } else if ([[call method] isEqualToString:@"canGoBack"]) {
-    [self onCanGoBack:call result:result];
-  } else if ([[call method] isEqualToString:@"canGoForward"]) {
-    [self onCanGoForward:call result:result];
-  } else if ([[call method] isEqualToString:@"goBack"]) {
-    [self onGoBack:call result:result];
-  } else if ([[call method] isEqualToString:@"goForward"]) {
-    [self onGoForward:call result:result];
-  } else if ([[call method] isEqualToString:@"reload"]) {
-    [self onReload:call result:result];
-  } else if ([[call method] isEqualToString:@"currentUrl"]) {
-    [self onCurrentUrl:call result:result];
-  } else if ([[call method] isEqualToString:@"evaluateJavascript"]) {
-    [self onEvaluateJavaScript:call result:result];
-  } else if ([[call method] isEqualToString:@"addJavascriptChannels"]) {
-    [self onAddJavaScriptChannels:call result:result];
-  } else if ([[call method] isEqualToString:@"removeJavascriptChannels"]) {
-    [self onRemoveJavaScriptChannels:call result:result];
-  } else if ([[call method] isEqualToString:@"clearCache"]) {
-    [self clearCache:result];
-  } else if ([[call method] isEqualToString:@"getTitle"]) {
-    [self onGetTitle:result];
-  } else if ([[call method] isEqualToString:@"scrollTo"]) {
-    [self onScrollTo:call result:result];
-  } else if ([[call method] isEqualToString:@"scrollBy"]) {
-    [self onScrollBy:call result:result];
-  } else if ([[call method] isEqualToString:@"getScrollX"]) {
-    [self getScrollX:call result:result];
-  } else if ([[call method] isEqualToString:@"getScrollY"]) {
-    [self getScrollY:call result:result];
-  } else {
-    result(FlutterMethodNotImplemented);
-  }
-}
-
-- (void)onUpdateSettings:(FlutterMethodCall*)call result:(FlutterResult)result {
-  NSString* error = [self applySettings:[call arguments]];
-  if (error == nil) {
-    result(nil);
-    return;
-  }
-  result([FlutterError errorWithCode:@"updateSettings_failed" message:error details:nil]);
-}
-
-- (void)onLoadUrl:(FlutterMethodCall*)call result:(FlutterResult)result {
-  if (![self loadRequest:[call arguments]]) {
-    result([FlutterError
-        errorWithCode:@"loadUrl_failed"
-              message:@"Failed parsing the URL"
-              details:[NSString stringWithFormat:@"Request was: '%@'", [call arguments]]]);
-  } else {
-    result(nil);
-  }
-}
-
-- (void)onCanGoBack:(FlutterMethodCall*)call result:(FlutterResult)result {
-  BOOL canGoBack = [_webView canGoBack];
-  result(@(canGoBack));
-}
-
-- (void)onCanGoForward:(FlutterMethodCall*)call result:(FlutterResult)result {
-  BOOL canGoForward = [_webView canGoForward];
-  result(@(canGoForward));
-}
-
-- (void)onGoBack:(FlutterMethodCall*)call result:(FlutterResult)result {
-  [_webView goBack];
-  result(nil);
-}
-
-- (void)onGoForward:(FlutterMethodCall*)call result:(FlutterResult)result {
-  [_webView goForward];
-  result(nil);
-}
-
-- (void)onReload:(FlutterMethodCall*)call result:(FlutterResult)result {
-  [_webView reload];
-  result(nil);
-}
-
-- (void)onCurrentUrl:(FlutterMethodCall*)call result:(FlutterResult)result {
-  _currentUrl = [[_webView URL] absoluteString];
-  result(_currentUrl);
-}
-
-- (void)onEvaluateJavaScript:(FlutterMethodCall*)call result:(FlutterResult)result {
-  NSString* jsString = [call arguments];
-  if (!jsString) {
-    result([FlutterError errorWithCode:@"evaluateJavaScript_failed"
-                               message:@"JavaScript String cannot be null"
-                               details:nil]);
-    return;
-  }
-  [_webView evaluateJavaScript:jsString
-             completionHandler:^(_Nullable id evaluateResult, NSError* _Nullable error) {
-               if (error) {
-                 result([FlutterError
-                     errorWithCode:@"evaluateJavaScript_failed"
-                           message:@"Failed evaluating JavaScript"
-                           details:[NSString stringWithFormat:@"JavaScript string was: '%@'\n%@",
-                                                              jsString, error]]);
-               } else {
-                 result([NSString stringWithFormat:@"%@", evaluateResult]);
-               }
-             }];
-}
-
-- (void)onAddJavaScriptChannels:(FlutterMethodCall*)call result:(FlutterResult)result {
-  NSArray* channelNames = [call arguments];
-  NSSet* channelNamesSet = [[NSSet alloc] initWithArray:channelNames];
-  [_javaScriptChannelNames addObjectsFromArray:channelNames];
-  [self registerJavaScriptChannels:channelNamesSet
-                        controller:_webView.configuration.userContentController];
-  result(nil);
-}
-
-- (void)onRemoveJavaScriptChannels:(FlutterMethodCall*)call result:(FlutterResult)result {
-  // WkWebView does not support removing a single user script, so instead we remove all
-  // user scripts, all message handlers. And re-register channels that shouldn't be removed.
-  [_webView.configuration.userContentController removeAllUserScripts];
-  for (NSString* channelName in _javaScriptChannelNames) {
-    [_webView.configuration.userContentController removeScriptMessageHandlerForName:channelName];
-  }
-
-  NSArray* channelNamesToRemove = [call arguments];
-  for (NSString* channelName in channelNamesToRemove) {
-    [_javaScriptChannelNames removeObject:channelName];
-  }
-
-  [self registerJavaScriptChannels:_javaScriptChannelNames
-                        controller:_webView.configuration.userContentController];
-  result(nil);
-}
-
-- (void)clearCache:(FlutterResult)result {
-  NSSet* cacheDataTypes = [WKWebsiteDataStore allWebsiteDataTypes];
-  WKWebsiteDataStore* dataStore = [WKWebsiteDataStore defaultDataStore];
-  NSDate* dateFrom = [NSDate dateWithTimeIntervalSince1970:0];
-  [dataStore removeDataOfTypes:cacheDataTypes
-                 modifiedSince:dateFrom
-             completionHandler:^{
-               result(nil);
-             }];
-}
-
-- (void)onGetTitle:(FlutterResult)result {
-  NSString* title = _webView.title;
-  result(title);
-}
-
-- (void)onScrollTo:(FlutterMethodCall*)call result:(FlutterResult)result {
-  NSDictionary* arguments = [call arguments];
-  int x = [arguments[@"x"] intValue];
-  int y = [arguments[@"y"] intValue];
-
-  _webView.scrollView.contentOffset = CGPointMake(x, y);
-  result(nil);
-}
-
-- (void)onScrollBy:(FlutterMethodCall*)call result:(FlutterResult)result {
-  CGPoint contentOffset = _webView.scrollView.contentOffset;
-
-  NSDictionary* arguments = [call arguments];
-  int x = [arguments[@"x"] intValue] + contentOffset.x;
-  int y = [arguments[@"y"] intValue] + contentOffset.y;
-
-  _webView.scrollView.contentOffset = CGPointMake(x, y);
-  result(nil);
-}
-
-- (void)getScrollX:(FlutterMethodCall*)call result:(FlutterResult)result {
-  int offsetX = _webView.scrollView.contentOffset.x;
-  result(@(offsetX));
-}
-
-- (void)getScrollY:(FlutterMethodCall*)call result:(FlutterResult)result {
-  int offsetY = _webView.scrollView.contentOffset.y;
-  result(@(offsetY));
-}
-
-// Returns nil when successful, or an error message when one or more keys are unknown.
-- (NSString*)applySettings:(NSDictionary<NSString*, id>*)settings {
-  NSMutableArray<NSString*>* unknownKeys = [[NSMutableArray alloc] init];
-  for (NSString* key in settings) {
-    if ([key isEqualToString:@"jsMode"]) {
-      NSNumber* mode = settings[key];
-      [self updateJsMode:mode];
-    } else if ([key isEqualToString:@"hasNavigationDelegate"]) {
-      NSNumber* hasDartNavigationDelegate = settings[key];
-      _navigationDelegate.hasDartNavigationDelegate = [hasDartNavigationDelegate boolValue];
-    } else if ([key isEqualToString:@"hasProgressTracking"]) {
-      NSNumber* hasProgressTrackingValue = settings[key];
-      bool hasProgressTracking = [hasProgressTrackingValue boolValue];
-      if (hasProgressTracking) {
-        _progressionDelegate = [[FLTWKProgressionDelegate alloc] initWithWebView:_webView
-                                                                         channel:_channel];
-      }
-    } else if ([key isEqualToString:@"debuggingEnabled"]) {
-      // no-op debugging is always enabled on iOS.
-    } else if ([key isEqualToString:@"gestureNavigationEnabled"]) {
-      NSNumber* allowsBackForwardNavigationGestures = settings[key];
-      _webView.allowsBackForwardNavigationGestures =
-          [allowsBackForwardNavigationGestures boolValue];
-    } else if ([key isEqualToString:@"userAgent"]) {
-      NSString* userAgent = settings[key];
-      [self updateUserAgent:[userAgent isEqual:[NSNull null]] ? nil : userAgent];
-    } else {
-      [unknownKeys addObject:key];
-    }
-  }
-  if ([unknownKeys count] == 0) {
-    return nil;
-  }
-  return [NSString stringWithFormat:@"webview_flutter: unknown setting keys: {%@}",
-                                    [unknownKeys componentsJoinedByString:@", "]];
-}
-
-- (void)applyConfigurationSettings:(NSDictionary<NSString*, id>*)settings
-                   toConfiguration:(WKWebViewConfiguration*)configuration {
-  NSAssert(configuration != _webView.configuration,
-           @"configuration needs to be updated before webView.configuration.");
-  for (NSString* key in settings) {
-    if ([key isEqualToString:@"allowsInlineMediaPlayback"]) {
-      NSNumber* allowsInlineMediaPlayback = settings[key];
-      configuration.allowsInlineMediaPlayback = [allowsInlineMediaPlayback boolValue];
-    }
-  }
-}
-
-- (void)updateJsMode:(NSNumber*)mode {
-  WKPreferences* preferences = [[_webView configuration] preferences];
-  switch ([mode integerValue]) {
-    case 0:  // disabled
-      [preferences setJavaScriptEnabled:NO];
-      break;
-    case 1:  // unrestricted
-      [preferences setJavaScriptEnabled:YES];
-      break;
-    default:
-      NSLog(@"webview_flutter: unknown JavaScript mode: %@", mode);
-  }
-}
-
-- (void)updateAutoMediaPlaybackPolicy:(NSNumber*)policy
-                      inConfiguration:(WKWebViewConfiguration*)configuration {
-  switch ([policy integerValue]) {
-    case 0:  // require_user_action_for_all_media_types
-      if (@available(iOS 10.0, *)) {
-        configuration.mediaTypesRequiringUserActionForPlayback = WKAudiovisualMediaTypeAll;
-      } else {
-        configuration.requiresUserActionForMediaPlayback = true;
-      }
-      break;
-    case 1:  // always_allow
-      if (@available(iOS 10.0, *)) {
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wdeprecated-declarations"
-        configuration.mediaTypesRequiringUserActionForPlayback = WKAudiovisualMediaTypeNone;
-#pragma clang diagnostic pop
-      } else {
-        configuration.requiresUserActionForMediaPlayback = false;
-      }
-      break;
-    default:
-      NSLog(@"webview_flutter: unknown auto media playback policy: %@", policy);
-  }
-}
-
-- (bool)loadRequest:(NSDictionary<NSString*, id>*)request {
-  if (!request) {
-    return false;
-  }
-
-  NSString* url = request[@"url"];
-  if ([url isKindOfClass:[NSString class]]) {
-    id headers = request[@"headers"];
-    if ([headers isKindOfClass:[NSDictionary class]]) {
-      return [self loadUrl:url withHeaders:headers];
-    } else {
-      return [self loadUrl:url];
-    }
-  }
-
-  return false;
-}
-
-- (bool)loadUrl:(NSString*)url {
-  return [self loadUrl:url withHeaders:[NSMutableDictionary dictionary]];
-}
-
-- (bool)loadUrl:(NSString*)url withHeaders:(NSDictionary<NSString*, NSString*>*)headers {
-  NSURL* nsUrl = [NSURL URLWithString:url];
-  if (!nsUrl) {
-    return false;
-  }
-  NSMutableURLRequest* request = [NSMutableURLRequest requestWithURL:nsUrl];
-  [request setAllHTTPHeaderFields:headers];
-  [_webView loadRequest:request];
-  return true;
-}
-
-- (void)registerJavaScriptChannels:(NSSet*)channelNames
-                        controller:(WKUserContentController*)userContentController {
-  for (NSString* channelName in channelNames) {
-    FLTJavaScriptChannel* channel =
-        [[FLTJavaScriptChannel alloc] initWithMethodChannel:_channel
-                                      javaScriptChannelName:channelName];
-    [userContentController addScriptMessageHandler:channel name:channelName];
-    NSString* wrapperSource = [NSString
-        stringWithFormat:@"window.%@ = webkit.messageHandlers.%@;", channelName, channelName];
-    WKUserScript* wrapperScript =
-        [[WKUserScript alloc] initWithSource:wrapperSource
-                               injectionTime:WKUserScriptInjectionTimeAtDocumentStart
-                            forMainFrameOnly:NO];
-    [userContentController addUserScript:wrapperScript];
-  }
-}
-
-- (void)updateUserAgent:(NSString*)userAgent {
-  [_webView setCustomUserAgent:userAgent];
-}
-
-#pragma mark WKUIDelegate
-
-- (WKWebView*)webView:(WKWebView*)webView
-    createWebViewWithConfiguration:(WKWebViewConfiguration*)configuration
-               forNavigationAction:(WKNavigationAction*)navigationAction
-                    windowFeatures:(WKWindowFeatures*)windowFeatures {
-  if (!navigationAction.targetFrame.isMainFrame) {
-    [webView loadRequest:navigationAction.request];
-  }
-
-  return nil;
-}
-
-@end
diff --git a/packages/webview_flutter/webview_flutter/ios/Classes/JavaScriptChannelHandler.h b/packages/webview_flutter/webview_flutter/ios/Classes/JavaScriptChannelHandler.h
deleted file mode 100644
index a0a5ec6..0000000
--- a/packages/webview_flutter/webview_flutter/ios/Classes/JavaScriptChannelHandler.h
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright 2013 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.
-
-#import <Flutter/Flutter.h>
-#import <WebKit/WebKit.h>
-
-NS_ASSUME_NONNULL_BEGIN
-
-@interface FLTJavaScriptChannel : NSObject <WKScriptMessageHandler>
-
-- (instancetype)initWithMethodChannel:(FlutterMethodChannel*)methodChannel
-                javaScriptChannelName:(NSString*)javaScriptChannelName;
-
-@end
-
-NS_ASSUME_NONNULL_END
diff --git a/packages/webview_flutter/webview_flutter/ios/Classes/JavaScriptChannelHandler.m b/packages/webview_flutter/webview_flutter/ios/Classes/JavaScriptChannelHandler.m
deleted file mode 100644
index ec9a363..0000000
--- a/packages/webview_flutter/webview_flutter/ios/Classes/JavaScriptChannelHandler.m
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright 2013 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.
-
-#import "JavaScriptChannelHandler.h"
-
-@implementation FLTJavaScriptChannel {
-  FlutterMethodChannel* _methodChannel;
-  NSString* _javaScriptChannelName;
-}
-
-- (instancetype)initWithMethodChannel:(FlutterMethodChannel*)methodChannel
-                javaScriptChannelName:(NSString*)javaScriptChannelName {
-  self = [super init];
-  NSAssert(methodChannel != nil, @"methodChannel must not be null.");
-  NSAssert(javaScriptChannelName != nil, @"javaScriptChannelName must not be null.");
-  if (self) {
-    _methodChannel = methodChannel;
-    _javaScriptChannelName = javaScriptChannelName;
-  }
-  return self;
-}
-
-- (void)userContentController:(WKUserContentController*)userContentController
-      didReceiveScriptMessage:(WKScriptMessage*)message {
-  NSAssert(_methodChannel != nil, @"Can't send a message to an unitialized JavaScript channel.");
-  NSAssert(_javaScriptChannelName != nil,
-           @"Can't send a message to an unitialized JavaScript channel.");
-  NSDictionary* arguments = @{
-    @"channel" : _javaScriptChannelName,
-    @"message" : [NSString stringWithFormat:@"%@", message.body]
-  };
-  [_methodChannel invokeMethod:@"javascriptChannelMessage" arguments:arguments];
-}
-
-@end
diff --git a/packages/webview_flutter/webview_flutter/ios/webview_flutter.podspec b/packages/webview_flutter/webview_flutter/ios/webview_flutter.podspec
deleted file mode 100644
index 2e02199..0000000
--- a/packages/webview_flutter/webview_flutter/ios/webview_flutter.podspec
+++ /dev/null
@@ -1,23 +0,0 @@
-#
-# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html
-#
-Pod::Spec.new do |s|
-  s.name             = 'webview_flutter'
-  s.version          = '0.0.1'
-  s.summary          = 'A WebView Plugin for Flutter.'
-  s.description      = <<-DESC
-A Flutter plugin that provides a WebView widget.
-Downloaded by pub (not CocoaPods).
-                       DESC
-  s.homepage         = 'https://github.com/flutter/plugins'
-  s.license          = { :type => 'BSD', :file => '../LICENSE' }
-  s.author           = { 'Flutter Dev Team' => 'flutter-dev@googlegroups.com' }
-  s.source           = { :http => 'https://github.com/flutter/plugins/tree/master/packages/webview_flutter' }
-  s.documentation_url = 'https://pub.dev/packages/webview_flutter'
-  s.source_files = 'Classes/**/*'
-  s.public_header_files = 'Classes/**/*.h'
-  s.dependency 'Flutter'
-
-  s.platform = :ios, '9.0'
-  s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', 'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'i386' }
-end
diff --git a/packages/webview_flutter/webview_flutter/lib/platform_interface.dart b/packages/webview_flutter/webview_flutter/lib/platform_interface.dart
index 92aa87b..aa7b3a0 100644
--- a/packages/webview_flutter/webview_flutter/lib/platform_interface.dart
+++ b/packages/webview_flutter/webview_flutter/lib/platform_interface.dart
@@ -2,547 +2,23 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-import 'dart:async';
-
-import 'package:flutter/foundation.dart';
-import 'package:flutter/gestures.dart';
-import 'package:flutter/widgets.dart';
-
-import 'webview_flutter.dart';
-
-/// Interface for callbacks made by [WebViewPlatformController].
-///
-/// The webview plugin implements this class, and passes an instance to the [WebViewPlatformController].
-/// [WebViewPlatformController] is notifying this handler on events that happened on the platform's webview.
-abstract class WebViewPlatformCallbacksHandler {
-  /// Invoked by [WebViewPlatformController] when a JavaScript channel message is received.
-  void onJavaScriptChannelMessage(String channel, String message);
-
-  /// Invoked by [WebViewPlatformController] when a navigation request is pending.
-  ///
-  /// If true is returned the navigation is allowed, otherwise it is blocked.
-  FutureOr<bool> onNavigationRequest(
-      {required String url, required bool isForMainFrame});
-
-  /// Invoked by [WebViewPlatformController] when a page has started loading.
-  void onPageStarted(String url);
-
-  /// Invoked by [WebViewPlatformController] when a page has finished loading.
-  void onPageFinished(String url);
-
-  /// Invoked by [WebViewPlatformController] when a page is loading.
-  /// /// Only works when [WebSettings.hasProgressTracking] is set to `true`.
-  void onProgress(int progress);
-
-  /// Report web resource loading error to the host application.
-  void onWebResourceError(WebResourceError error);
-}
-
-/// Possible error type categorizations used by [WebResourceError].
-enum WebResourceErrorType {
-  /// User authentication failed on server.
-  authentication,
-
-  /// Malformed URL.
-  badUrl,
-
-  /// Failed to connect to the server.
-  connect,
-
-  /// Failed to perform SSL handshake.
-  failedSslHandshake,
-
-  /// Generic file error.
-  file,
-
-  /// File not found.
-  fileNotFound,
-
-  /// Server or proxy hostname lookup failed.
-  hostLookup,
-
-  /// Failed to read or write to the server.
-  io,
-
-  /// User authentication failed on proxy.
-  proxyAuthentication,
-
-  /// Too many redirects.
-  redirectLoop,
-
-  /// Connection timed out.
-  timeout,
-
-  /// Too many requests during this load.
-  tooManyRequests,
-
-  /// Generic error.
-  unknown,
-
-  /// Resource load was canceled by Safe Browsing.
-  unsafeResource,
-
-  /// Unsupported authentication scheme (not basic or digest).
-  unsupportedAuthScheme,
-
-  /// Unsupported URI scheme.
-  unsupportedScheme,
-
-  /// The web content process was terminated.
-  webContentProcessTerminated,
-
-  /// The web view was invalidated.
-  webViewInvalidated,
-
-  /// A JavaScript exception occurred.
-  javaScriptExceptionOccurred,
-
-  /// The result of JavaScript execution could not be returned.
-  javaScriptResultTypeIsUnsupported,
-}
-
-/// Error returned in `WebView.onWebResourceError` when a web resource loading error has occurred.
-class WebResourceError {
-  /// Creates a new [WebResourceError]
-  ///
-  /// A user should not need to instantiate this class, but will receive one in
-  /// [WebResourceErrorCallback].
-  WebResourceError({
-    required this.errorCode,
-    required this.description,
-    this.domain,
-    this.errorType,
-    this.failingUrl,
-  })  : assert(errorCode != null),
-        assert(description != null);
-
-  /// Raw code of the error from the respective platform.
-  ///
-  /// On Android, the error code will be a constant from a
-  /// [WebViewClient](https://developer.android.com/reference/android/webkit/WebViewClient#summary) and
-  /// will have a corresponding [errorType].
-  ///
-  /// On iOS, the error code will be a constant from `NSError.code` in
-  /// Objective-C. See
-  /// https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/ErrorHandlingCocoa/ErrorObjectsDomains/ErrorObjectsDomains.html
-  /// for more information on error handling on iOS. Some possible error codes
-  /// can be found at https://developer.apple.com/documentation/webkit/wkerrorcode?language=objc.
-  final int errorCode;
-
-  /// The domain of where to find the error code.
-  ///
-  /// This field is only available on iOS and represents a "domain" from where
-  /// the [errorCode] is from. This value is taken directly from an `NSError`
-  /// in Objective-C. See
-  /// https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/ErrorHandlingCocoa/ErrorObjectsDomains/ErrorObjectsDomains.html
-  /// for more information on error handling on iOS.
-  final String? domain;
-
-  /// Description of the error that can be used to communicate the problem to the user.
-  final String description;
-
-  /// The type this error can be categorized as.
-  ///
-  /// This will never be `null` on Android, but can be `null` on iOS.
-  final WebResourceErrorType? errorType;
-
-  /// Gets the URL for which the resource request was made.
-  ///
-  /// This value is not provided on iOS. Alternatively, you can keep track of
-  /// the last values provided to [WebViewPlatformController.loadUrl].
-  final String? failingUrl;
-}
-
-/// Interface for talking to the webview's platform implementation.
-///
-/// An instance implementing this interface is passed to the `onWebViewPlatformCreated` callback that is
-/// passed to [WebViewPlatformBuilder#onWebViewPlatformCreated].
-///
-/// Platform implementations that live in a separate package should extend this class rather than
-/// implement it as webview_flutter does not consider newly added methods to be breaking changes.
-/// Extending this class (using `extends`) ensures that the subclass will get the default
-/// implementation, while platform implementations that `implements` this interface will be broken
-/// by newly added [WebViewPlatformController] methods.
-abstract class WebViewPlatformController {
-  /// Creates a new WebViewPlatform.
-  ///
-  /// Callbacks made by the WebView will be delegated to `handler`.
-  ///
-  /// The `handler` parameter must not be null.
-  WebViewPlatformController(WebViewPlatformCallbacksHandler handler);
-
-  /// Loads the specified URL.
-  ///
-  /// If `headers` is not null and the URL is an HTTP URL, the key value paris in `headers` will
-  /// be added as key value pairs of HTTP headers for the request.
-  ///
-  /// `url` must not be null.
-  ///
-  /// Throws an ArgumentError if `url` is not a valid URL string.
-  Future<void> loadUrl(
-    String url,
-    Map<String, String>? headers,
-  ) {
-    throw UnimplementedError(
-        "WebView loadUrl is not implemented on the current platform");
-  }
-
-  /// Updates the webview settings.
-  ///
-  /// Any non null field in `settings` will be set as the new setting value.
-  /// All null fields in `settings` are ignored.
-  Future<void> updateSettings(WebSettings setting) {
-    throw UnimplementedError(
-        "WebView updateSettings is not implemented on the current platform");
-  }
-
-  /// Accessor to the current URL that the WebView is displaying.
-  ///
-  /// If no URL was ever loaded, returns `null`.
-  Future<String?> currentUrl() {
-    throw UnimplementedError(
-        "WebView currentUrl is not implemented on the current platform");
-  }
-
-  /// Checks whether there's a back history item.
-  Future<bool> canGoBack() {
-    throw UnimplementedError(
-        "WebView canGoBack is not implemented on the current platform");
-  }
-
-  /// Checks whether there's a forward history item.
-  Future<bool> canGoForward() {
-    throw UnimplementedError(
-        "WebView canGoForward is not implemented on the current platform");
-  }
-
-  /// Goes back in the history of this WebView.
-  ///
-  /// If there is no back history item this is a no-op.
-  Future<void> goBack() {
-    throw UnimplementedError(
-        "WebView goBack is not implemented on the current platform");
-  }
-
-  /// Goes forward in the history of this WebView.
-  ///
-  /// If there is no forward history item this is a no-op.
-  Future<void> goForward() {
-    throw UnimplementedError(
-        "WebView goForward is not implemented on the current platform");
-  }
-
-  /// Reloads the current URL.
-  Future<void> reload() {
-    throw UnimplementedError(
-        "WebView reload is not implemented on the current platform");
-  }
-
-  /// Clears all caches used by the [WebView].
-  ///
-  /// The following caches are cleared:
-  ///	1. Browser HTTP Cache.
-  ///	2. [Cache API](https://developers.google.com/web/fundamentals/instant-and-offline/web-storage/cache-api) caches.
-  ///    These are not yet supported in iOS WkWebView. Service workers tend to use this cache.
-  ///	3. Application cache.
-  ///	4. Local Storage.
-  Future<void> clearCache() {
-    throw UnimplementedError(
-        "WebView clearCache is not implemented on the current platform");
-  }
-
-  /// Evaluates a JavaScript expression in the context of the current page.
-  ///
-  /// The Future completes with an error if a JavaScript error occurred, or if the type of the
-  /// evaluated expression is not supported(e.g on iOS not all non primitive type can be evaluated).
-  Future<String> evaluateJavascript(String javascriptString) {
-    throw UnimplementedError(
-        "WebView evaluateJavascript is not implemented on the current platform");
-  }
-
-  /// Adds new JavaScript channels to the set of enabled channels.
-  ///
-  /// For each value in this list the platform's webview should make sure that a corresponding
-  /// property with a postMessage method is set on `window`. For example for a JavaScript channel
-  /// named `Foo` it should be possible for JavaScript code executing in the webview to do
-  ///
-  /// ```javascript
-  /// Foo.postMessage('hello');
-  /// ```
-  ///
-  /// See also: [CreationParams.javascriptChannelNames].
-  Future<void> addJavascriptChannels(Set<String> javascriptChannelNames) {
-    throw UnimplementedError(
-        "WebView addJavascriptChannels is not implemented on the current platform");
-  }
-
-  /// Removes JavaScript channel names from the set of enabled channels.
-  ///
-  /// This disables channels that were previously enabled by [addJavaScriptChannels] or through
-  /// [CreationParams.javascriptChannelNames].
-  Future<void> removeJavascriptChannels(Set<String> javascriptChannelNames) {
-    throw UnimplementedError(
-        "WebView removeJavascriptChannels is not implemented on the current platform");
-  }
-
-  /// Returns the title of the currently loaded page.
-  Future<String?> getTitle() {
-    throw UnimplementedError(
-        "WebView getTitle is not implemented on the current platform");
-  }
-
-  /// Set the scrolled position of this view.
-  ///
-  /// The parameters `x` and `y` specify the position to scroll to in WebView pixels.
-  Future<void> scrollTo(int x, int y) {
-    throw UnimplementedError(
-        "WebView scrollTo is not implemented on the current platform");
-  }
-
-  /// Move the scrolled position of this view.
-  ///
-  /// The parameters `x` and `y` specify the amount of WebView pixels to scroll by.
-  Future<void> scrollBy(int x, int y) {
-    throw UnimplementedError(
-        "WebView scrollBy is not implemented on the current platform");
-  }
-
-  /// Return the horizontal scroll position of this view.
-  ///
-  /// Scroll position is measured from left.
-  Future<int> getScrollX() {
-    throw UnimplementedError(
-        "WebView getScrollX is not implemented on the current platform");
-  }
-
-  /// Return the vertical scroll position of this view.
-  ///
-  /// Scroll position is measured from top.
-  Future<int> getScrollY() {
-    throw UnimplementedError(
-        "WebView getScrollY is not implemented on the current platform");
-  }
-}
-
-/// A single setting for configuring a WebViewPlatform which may be absent.
-class WebSetting<T> {
-  /// Constructs an absent setting instance.
-  ///
-  /// The [isPresent] field for the instance will be false.
-  ///
-  /// Accessing [value] for an absent instance will throw.
-  WebSetting.absent()
-      : _value = null,
-        isPresent = false;
-
-  /// Constructs a setting of the given `value`.
-  ///
-  /// The [isPresent] field for the instance will be true.
-  WebSetting.of(T value)
-      : _value = value,
-        isPresent = true;
-
-  final T? _value;
-
-  /// The setting's value.
-  ///
-  /// Throws if [WebSetting.isPresent] is false.
-  T get value {
-    if (!isPresent) {
-      throw StateError('Cannot access a value of an absent WebSetting');
-    }
-    assert(isPresent);
-    // The intention of this getter is to return T whether it is nullable or
-    // not whereas _value is of type T? since _value can be null even when
-    // T is not nullable (when isPresent == false).
-    //
-    // We promote _value to T using `as T` instead of `!` operator to handle
-    // the case when _value is legitimately null (and T is a nullable type).
-    // `!` operator would always throw if _value is null.
-    return _value as T;
-  }
-
-  /// True when this web setting instance contains a value.
-  ///
-  /// When false the [WebSetting.value] getter throws.
-  final bool isPresent;
-
-  @override
-  bool operator ==(Object other) {
-    if (other.runtimeType != runtimeType) return false;
-    final WebSetting<T> typedOther = other as WebSetting<T>;
-    return typedOther.isPresent == isPresent && typedOther._value == _value;
-  }
-
-  @override
-  int get hashCode => hashValues(_value, isPresent);
-}
-
-/// Settings for configuring a WebViewPlatform.
-///
-/// Initial settings are passed as part of [CreationParams], settings updates are sent with
-/// [WebViewPlatform#updateSettings].
-///
-/// The `userAgent` parameter must not be null.
-class WebSettings {
-  /// Construct an instance with initial settings. Future setting changes can be
-  /// sent with [WebviewPlatform#updateSettings].
-  ///
-  /// The `userAgent` parameter must not be null.
-  WebSettings({
-    this.javascriptMode,
-    this.hasNavigationDelegate,
-    this.hasProgressTracking,
-    this.debuggingEnabled,
-    this.gestureNavigationEnabled,
-    this.allowsInlineMediaPlayback,
-    required this.userAgent,
-  }) : assert(userAgent != null);
-
-  /// The JavaScript execution mode to be used by the webview.
-  final JavascriptMode? javascriptMode;
-
-  /// Whether the [WebView] has a [NavigationDelegate] set.
-  final bool? hasNavigationDelegate;
-
-  /// Whether the [WebView] should track page loading progress.
-  /// See also: [WebViewPlatformCallbacksHandler.onProgress] to get the progress.
-  final bool? hasProgressTracking;
-
-  /// Whether to enable the platform's webview content debugging tools.
-  ///
-  /// See also: [WebView.debuggingEnabled].
-  final bool? debuggingEnabled;
-
-  /// Whether to play HTML5 videos inline or use the native full-screen controller on iOS.
-  ///
-  /// This will have no effect on Android.
-  final bool? allowsInlineMediaPlayback;
-
-  /// The value used for the HTTP `User-Agent:` request header.
-  ///
-  /// If [userAgent.value] is null the platform's default user agent should be used.
-  ///
-  /// An absent value ([userAgent.isPresent] is false) represents no change to this setting from the
-  /// last time it was set.
-  ///
-  /// See also [WebView.userAgent].
-  final WebSetting<String?> userAgent;
-
-  /// Whether to allow swipe based navigation in iOS.
-  ///
-  /// See also: [WebView.gestureNavigationEnabled]
-  final bool? gestureNavigationEnabled;
-
-  @override
-  String toString() {
-    return 'WebSettings(javascriptMode: $javascriptMode, hasNavigationDelegate: $hasNavigationDelegate, hasProgressTracking: $hasProgressTracking, debuggingEnabled: $debuggingEnabled, gestureNavigationEnabled: $gestureNavigationEnabled, userAgent: $userAgent, allowsInlineMediaPlayback: $allowsInlineMediaPlayback)';
-  }
-}
-
-/// Configuration to use when creating a new [WebViewPlatformController].
-///
-/// The `autoMediaPlaybackPolicy` parameter must not be null.
-class CreationParams {
-  /// Constructs an instance to use when creating a new
-  /// [WebViewPlatformController].
-  ///
-  /// The `autoMediaPlaybackPolicy` parameter must not be null.
-  CreationParams({
-    this.initialUrl,
-    this.webSettings,
-    this.javascriptChannelNames = const <String>{},
-    this.userAgent,
-    this.autoMediaPlaybackPolicy =
-        AutoMediaPlaybackPolicy.require_user_action_for_all_media_types,
-  }) : assert(autoMediaPlaybackPolicy != null);
-
-  /// The initialUrl to load in the webview.
-  ///
-  /// When null the webview will be created without loading any page.
-  final String? initialUrl;
-
-  /// The initial [WebSettings] for the new webview.
-  ///
-  /// This can later be updated with [WebViewPlatformController.updateSettings].
-  final WebSettings? webSettings;
-
-  /// The initial set of JavaScript channels that are configured for this webview.
-  ///
-  /// For each value in this set the platform's webview should make sure that a corresponding
-  /// property with a postMessage method is set on `window`. For example for a JavaScript channel
-  /// named `Foo` it should be possible for JavaScript code executing in the webview to do
-  ///
-  /// ```javascript
-  /// Foo.postMessage('hello');
-  /// ```
-  // TODO(amirh): describe what should happen when postMessage is called once that code is migrated
-  // to PlatformWebView.
-  final Set<String> javascriptChannelNames;
-
-  /// The value used for the HTTP User-Agent: request header.
-  ///
-  /// When null the platform's webview default is used for the User-Agent header.
-  final String? userAgent;
-
-  /// Which restrictions apply on automatic media playback.
-  final AutoMediaPlaybackPolicy autoMediaPlaybackPolicy;
-
-  @override
-  String toString() {
-    return '$runtimeType(initialUrl: $initialUrl, settings: $webSettings, javascriptChannelNames: $javascriptChannelNames, UserAgent: $userAgent)';
-  }
-}
-
-/// Signature for callbacks reporting that a [WebViewPlatformController] was created.
-///
-/// See also the `onWebViewPlatformCreated` argument for [WebViewPlatform.build].
-typedef WebViewPlatformCreatedCallback = void Function(
-    WebViewPlatformController? webViewPlatformController);
-
-/// Interface for a platform implementation of a WebView.
-///
-/// [WebView.platform] controls the builder that is used by [WebView].
-/// [AndroidWebViewPlatform] and [CupertinoWebViewPlatform] are the default implementations
-/// for Android and iOS respectively.
-abstract class WebViewPlatform {
-  /// Builds a new WebView.
-  ///
-  /// Returns a Widget tree that embeds the created webview.
-  ///
-  /// `creationParams` are the initial parameters used to setup the webview.
-  ///
-  /// `webViewPlatformHandler` will be used for handling callbacks that are made by the created
-  /// [WebViewPlatformController].
-  ///
-  /// `onWebViewPlatformCreated` will be invoked after the platform specific [WebViewPlatformController]
-  /// implementation is created with the [WebViewPlatformController] instance as a parameter.
-  ///
-  /// `gestureRecognizers` specifies which gestures should be consumed by the web view.
-  /// It is possible for other gesture recognizers to be competing with the web view on pointer
-  /// events, e.g if the web view is inside a [ListView] the [ListView] will want to handle
-  /// vertical drags. The web view will claim gestures that are recognized by any of the
-  /// recognizers on this list.
-  /// When `gestureRecognizers` is empty or null, the web view will only handle pointer events for gestures that
-  /// were not claimed by any other gesture recognizer.
-  ///
-  /// `webViewPlatformHandler` must not be null.
-  Widget build({
-    required BuildContext context,
-    // TODO(amirh): convert this to be the actual parameters.
-    // I'm starting without it as the PR is starting to become pretty big.
-    // I'll followup with the conversion PR.
-    required CreationParams creationParams,
-    required WebViewPlatformCallbacksHandler webViewPlatformCallbacksHandler,
-    WebViewPlatformCreatedCallback? onWebViewPlatformCreated,
-    Set<Factory<OneSequenceGestureRecognizer>>? gestureRecognizers,
-  });
-
-  /// Clears all cookies for all [WebView] instances.
-  ///
-  /// Returns true if cookies were present before clearing, else false.
-  Future<bool> clearCookies() {
-    throw UnimplementedError(
-        "WebView clearCookies is not implemented on the current platform");
-  }
-}
+/// Re-export the classes from the webview_flutter_platform_interface through
+/// the `platform_interface.dart` file so we don't accidentally break any
+/// non-endorsed existing implementations of the interface.
+export 'package:webview_flutter_platform_interface/webview_flutter_platform_interface.dart'
+    show
+        AutoMediaPlaybackPolicy,
+        CreationParams,
+        JavascriptChannel,
+        JavascriptChannelRegistry,
+        JavascriptMessage,
+        JavascriptMode,
+        JavascriptMessageHandler,
+        WebViewPlatform,
+        WebViewPlatformCallbacksHandler,
+        WebViewPlatformController,
+        WebViewPlatformCreatedCallback,
+        WebSetting,
+        WebSettings,
+        WebResourceError,
+        WebResourceErrorType;
diff --git a/packages/webview_flutter/webview_flutter/lib/src/webview.dart b/packages/webview_flutter/webview_flutter/lib/src/webview.dart
new file mode 100644
index 0000000..7699cc4
--- /dev/null
+++ b/packages/webview_flutter/webview_flutter/lib/src/webview.dart
@@ -0,0 +1,681 @@
+// Copyright 2013 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.
+
+import 'dart:async';
+
+import 'package:flutter/foundation.dart';
+import 'package:flutter/gestures.dart';
+import 'package:flutter/rendering.dart';
+import 'package:flutter/widgets.dart';
+import 'package:webview_flutter_android/webview_android.dart';
+import 'package:webview_flutter_wkwebview/webview_flutter_wkwebview.dart';
+
+import '../platform_interface.dart';
+
+/// Optional callback invoked when a web view is first created. [controller] is
+/// the [WebViewController] for the created web view.
+typedef void WebViewCreatedCallback(WebViewController controller);
+
+/// Information about a navigation action that is about to be executed.
+class NavigationRequest {
+  NavigationRequest._({required this.url, required this.isForMainFrame});
+
+  /// The URL that will be loaded if the navigation is executed.
+  final String url;
+
+  /// Whether the navigation request is to be loaded as the main frame.
+  final bool isForMainFrame;
+
+  @override
+  String toString() {
+    return '$runtimeType(url: $url, isForMainFrame: $isForMainFrame)';
+  }
+}
+
+/// A decision on how to handle a navigation request.
+enum NavigationDecision {
+  /// Prevent the navigation from taking place.
+  prevent,
+
+  /// Allow the navigation to take place.
+  navigate,
+}
+
+/// Decides how to handle a specific navigation request.
+///
+/// The returned [NavigationDecision] determines how the navigation described by
+/// `navigation` should be handled.
+///
+/// See also: [WebView.navigationDelegate].
+typedef FutureOr<NavigationDecision> NavigationDelegate(
+    NavigationRequest navigation);
+
+/// Signature for when a [WebView] has started loading a page.
+typedef void PageStartedCallback(String url);
+
+/// Signature for when a [WebView] has finished loading a page.
+typedef void PageFinishedCallback(String url);
+
+/// Signature for when a [WebView] is loading a page.
+typedef void PageLoadingCallback(int progress);
+
+/// Signature for when a [WebView] has failed to load a resource.
+typedef void WebResourceErrorCallback(WebResourceError error);
+
+/// A web view widget for showing html content.
+///
+/// There is a known issue that on iOS 13.4 and 13.5, other flutter widgets covering
+/// the `WebView` is not able to block the `WebView` from receiving touch events.
+/// See https://github.com/flutter/flutter/issues/53490.
+class WebView extends StatefulWidget {
+  /// Creates a new web view.
+  ///
+  /// The web view can be controlled using a `WebViewController` that is passed to the
+  /// `onWebViewCreated` callback once the web view is created.
+  ///
+  /// The `javascriptMode` and `autoMediaPlaybackPolicy` parameters must not be null.
+  const WebView({
+    Key? key,
+    this.onWebViewCreated,
+    this.initialUrl,
+    this.javascriptMode = JavascriptMode.disabled,
+    this.javascriptChannels,
+    this.navigationDelegate,
+    this.gestureRecognizers,
+    this.onPageStarted,
+    this.onPageFinished,
+    this.onProgress,
+    this.onWebResourceError,
+    this.debuggingEnabled = false,
+    this.gestureNavigationEnabled = false,
+    this.userAgent,
+    this.initialMediaPlaybackPolicy =
+        AutoMediaPlaybackPolicy.require_user_action_for_all_media_types,
+    this.allowsInlineMediaPlayback = false,
+  })  : assert(javascriptMode != null),
+        assert(initialMediaPlaybackPolicy != null),
+        assert(allowsInlineMediaPlayback != null),
+        super(key: key);
+
+  static WebViewPlatform? _platform;
+
+  /// Sets a custom [WebViewPlatform].
+  ///
+  /// This property can be set to use a custom platform implementation for WebViews.
+  ///
+  /// Setting `platform` doesn't affect [WebView]s that were already created.
+  ///
+  /// The default value is [AndroidWebView] on Android and [CupertinoWebView] on iOS.
+  static set platform(WebViewPlatform? platform) {
+    _platform = platform;
+  }
+
+  /// The WebView platform that's used by this WebView.
+  ///
+  /// The default value is [AndroidWebView] on Android and [CupertinoWebView] on iOS.
+  static WebViewPlatform get platform {
+    if (_platform == null) {
+      switch (defaultTargetPlatform) {
+        case TargetPlatform.android:
+          _platform = AndroidWebView();
+          break;
+        case TargetPlatform.iOS:
+          _platform = CupertinoWebView();
+          break;
+        default:
+          throw UnsupportedError(
+              "Trying to use the default webview implementation for $defaultTargetPlatform but there isn't a default one");
+      }
+    }
+    return _platform!;
+  }
+
+  /// If not null invoked once the web view is created.
+  final WebViewCreatedCallback? onWebViewCreated;
+
+  /// Which gestures should be consumed by the web view.
+  ///
+  /// It is possible for other gesture recognizers to be competing with the web view on pointer
+  /// events, e.g if the web view is inside a [ListView] the [ListView] will want to handle
+  /// vertical drags. The web view will claim gestures that are recognized by any of the
+  /// recognizers on this list.
+  ///
+  /// When this set is empty or null, the web view will only handle pointer events for gestures that
+  /// were not claimed by any other gesture recognizer.
+  final Set<Factory<OneSequenceGestureRecognizer>>? gestureRecognizers;
+
+  /// The initial URL to load.
+  final String? initialUrl;
+
+  /// Whether Javascript execution is enabled.
+  final JavascriptMode javascriptMode;
+
+  /// The set of [JavascriptChannel]s available to JavaScript code running in the web view.
+  ///
+  /// For each [JavascriptChannel] in the set, a channel object is made available for the
+  /// JavaScript code in a window property named [JavascriptChannel.name].
+  /// The JavaScript code can then call `postMessage` on that object to send a message that will be
+  /// passed to [JavascriptChannel.onMessageReceived].
+  ///
+  /// For example for the following JavascriptChannel:
+  ///
+  /// ```dart
+  /// JavascriptChannel(name: 'Print', onMessageReceived: (JavascriptMessage message) { print(message.message); });
+  /// ```
+  ///
+  /// JavaScript code can call:
+  ///
+  /// ```javascript
+  /// Print.postMessage('Hello');
+  /// ```
+  ///
+  /// To asynchronously invoke the message handler which will print the message to standard output.
+  ///
+  /// Adding a new JavaScript channel only takes affect after the next page is loaded.
+  ///
+  /// Set values must not be null. A [JavascriptChannel.name] cannot be the same for multiple
+  /// channels in the list.
+  ///
+  /// A null value is equivalent to an empty set.
+  final Set<JavascriptChannel>? javascriptChannels;
+
+  /// A delegate function that decides how to handle navigation actions.
+  ///
+  /// When a navigation is initiated by the WebView (e.g when a user clicks a link)
+  /// this delegate is called and has to decide how to proceed with the navigation.
+  ///
+  /// See [NavigationDecision] for possible decisions the delegate can take.
+  ///
+  /// When null all navigation actions are allowed.
+  ///
+  /// Caveats on Android:
+  ///
+  ///   * Navigation actions targeted to the main frame can be intercepted,
+  ///     navigation actions targeted to subframes are allowed regardless of the value
+  ///     returned by this delegate.
+  ///   * Setting a navigationDelegate makes the WebView treat all navigations as if they were
+  ///     triggered by a user gesture, this disables some of Chromium's security mechanisms.
+  ///     A navigationDelegate should only be set when loading trusted content.
+  ///   * On Android WebView versions earlier than 67(most devices running at least Android L+ should have
+  ///     a later version):
+  ///     * When a navigationDelegate is set pages with frames are not properly handled by the
+  ///       webview, and frames will be opened in the main frame.
+  ///     * When a navigationDelegate is set HTTP requests do not include the HTTP referer header.
+  final NavigationDelegate? navigationDelegate;
+
+  /// Controls whether inline playback of HTML5 videos is allowed on iOS.
+  ///
+  /// This field is ignored on Android because Android allows it by default.
+  ///
+  /// By default `allowsInlineMediaPlayback` is false.
+  final bool allowsInlineMediaPlayback;
+
+  /// Invoked when a page starts loading.
+  final PageStartedCallback? onPageStarted;
+
+  /// Invoked when a page has finished loading.
+  ///
+  /// This is invoked only for the main frame.
+  ///
+  /// When [onPageFinished] is invoked on Android, the page being rendered may
+  /// not be updated yet.
+  ///
+  /// When invoked on iOS or Android, any Javascript code that is embedded
+  /// directly in the HTML has been loaded and code injected with
+  /// [WebViewController.evaluateJavascript] can assume this.
+  final PageFinishedCallback? onPageFinished;
+
+  /// Invoked when a page is loading.
+  final PageLoadingCallback? onProgress;
+
+  /// Invoked when a web resource has failed to load.
+  ///
+  /// This callback is only called for the main page.
+  final WebResourceErrorCallback? onWebResourceError;
+
+  /// Controls whether WebView debugging is enabled.
+  ///
+  /// Setting this to true enables [WebView debugging on Android](https://developers.google.com/web/tools/chrome-devtools/remote-debugging/).
+  ///
+  /// WebView debugging is enabled by default in dev builds on iOS.
+  ///
+  /// To debug WebViews on iOS:
+  /// - Enable developer options (Open Safari, go to Preferences -> Advanced and make sure "Show Develop Menu in Menubar" is on.)
+  /// - From the Menu-bar (of Safari) select Develop -> iPhone Simulator -> <your webview page>
+  ///
+  /// By default `debuggingEnabled` is false.
+  final bool debuggingEnabled;
+
+  /// A Boolean value indicating whether horizontal swipe gestures will trigger back-forward list navigations.
+  ///
+  /// This only works on iOS.
+  ///
+  /// By default `gestureNavigationEnabled` is false.
+  final bool gestureNavigationEnabled;
+
+  /// The value used for the HTTP User-Agent: request header.
+  ///
+  /// When null the platform's webview default is used for the User-Agent header.
+  ///
+  /// When the [WebView] is rebuilt with a different `userAgent`, the page reloads and the request uses the new User Agent.
+  ///
+  /// When [WebViewController.goBack] is called after changing `userAgent` the previous `userAgent` value is used until the page is reloaded.
+  ///
+  /// This field is ignored on iOS versions prior to 9 as the platform does not support a custom
+  /// user agent.
+  ///
+  /// By default `userAgent` is null.
+  final String? userAgent;
+
+  /// Which restrictions apply on automatic media playback.
+  ///
+  /// This initial value is applied to the platform's webview upon creation. Any following
+  /// changes to this parameter are ignored (as long as the state of the [WebView] is preserved).
+  ///
+  /// The default policy is [AutoMediaPlaybackPolicy.require_user_action_for_all_media_types].
+  final AutoMediaPlaybackPolicy initialMediaPlaybackPolicy;
+
+  @override
+  State<StatefulWidget> createState() => _WebViewState();
+}
+
+class _WebViewState extends State<WebView> {
+  final Completer<WebViewController> _controller =
+      Completer<WebViewController>();
+
+  late JavascriptChannelRegistry _javascriptChannelRegistry;
+  late _PlatformCallbacksHandler _platformCallbacksHandler;
+
+  @override
+  Widget build(BuildContext context) {
+    return WebView.platform.build(
+      context: context,
+      onWebViewPlatformCreated: _onWebViewPlatformCreated,
+      webViewPlatformCallbacksHandler: _platformCallbacksHandler,
+      javascriptChannelRegistry: _javascriptChannelRegistry,
+      gestureRecognizers: widget.gestureRecognizers,
+      creationParams: _creationParamsfromWidget(widget),
+    );
+  }
+
+  @override
+  void initState() {
+    super.initState();
+    _assertJavascriptChannelNamesAreUnique();
+    _platformCallbacksHandler = _PlatformCallbacksHandler(widget);
+    _javascriptChannelRegistry =
+        JavascriptChannelRegistry(widget.javascriptChannels);
+  }
+
+  @override
+  void didUpdateWidget(WebView oldWidget) {
+    super.didUpdateWidget(oldWidget);
+    _assertJavascriptChannelNamesAreUnique();
+    _controller.future.then((WebViewController controller) {
+      _platformCallbacksHandler._widget = widget;
+      controller._updateWidget(widget);
+    });
+  }
+
+  void _onWebViewPlatformCreated(WebViewPlatformController? webViewPlatform) {
+    final WebViewController controller = WebViewController._(
+      widget,
+      webViewPlatform!,
+      _javascriptChannelRegistry,
+    );
+    _controller.complete(controller);
+    if (widget.onWebViewCreated != null) {
+      widget.onWebViewCreated!(controller);
+    }
+  }
+
+  void _assertJavascriptChannelNamesAreUnique() {
+    if (widget.javascriptChannels == null ||
+        widget.javascriptChannels!.isEmpty) {
+      return;
+    }
+    assert(_extractChannelNames(widget.javascriptChannels).length ==
+        widget.javascriptChannels!.length);
+  }
+}
+
+CreationParams _creationParamsfromWidget(WebView widget) {
+  return CreationParams(
+    initialUrl: widget.initialUrl,
+    webSettings: _webSettingsFromWidget(widget),
+    javascriptChannelNames: _extractChannelNames(widget.javascriptChannels),
+    userAgent: widget.userAgent,
+    autoMediaPlaybackPolicy: widget.initialMediaPlaybackPolicy,
+  );
+}
+
+WebSettings _webSettingsFromWidget(WebView widget) {
+  return WebSettings(
+    javascriptMode: widget.javascriptMode,
+    hasNavigationDelegate: widget.navigationDelegate != null,
+    hasProgressTracking: widget.onProgress != null,
+    debuggingEnabled: widget.debuggingEnabled,
+    gestureNavigationEnabled: widget.gestureNavigationEnabled,
+    allowsInlineMediaPlayback: widget.allowsInlineMediaPlayback,
+    userAgent: WebSetting<String?>.of(widget.userAgent),
+  );
+}
+
+// This method assumes that no fields in `currentValue` are null.
+WebSettings _clearUnchangedWebSettings(
+    WebSettings currentValue, WebSettings newValue) {
+  assert(currentValue.javascriptMode != null);
+  assert(currentValue.hasNavigationDelegate != null);
+  assert(currentValue.hasProgressTracking != null);
+  assert(currentValue.debuggingEnabled != null);
+  assert(currentValue.userAgent != null);
+  assert(newValue.javascriptMode != null);
+  assert(newValue.hasNavigationDelegate != null);
+  assert(newValue.debuggingEnabled != null);
+  assert(newValue.userAgent != null);
+
+  JavascriptMode? javascriptMode;
+  bool? hasNavigationDelegate;
+  bool? hasProgressTracking;
+  bool? debuggingEnabled;
+  WebSetting<String?> userAgent = WebSetting.absent();
+  if (currentValue.javascriptMode != newValue.javascriptMode) {
+    javascriptMode = newValue.javascriptMode;
+  }
+  if (currentValue.hasNavigationDelegate != newValue.hasNavigationDelegate) {
+    hasNavigationDelegate = newValue.hasNavigationDelegate;
+  }
+  if (currentValue.hasProgressTracking != newValue.hasProgressTracking) {
+    hasProgressTracking = newValue.hasProgressTracking;
+  }
+  if (currentValue.debuggingEnabled != newValue.debuggingEnabled) {
+    debuggingEnabled = newValue.debuggingEnabled;
+  }
+  if (currentValue.userAgent != newValue.userAgent) {
+    userAgent = newValue.userAgent;
+  }
+
+  return WebSettings(
+    javascriptMode: javascriptMode,
+    hasNavigationDelegate: hasNavigationDelegate,
+    hasProgressTracking: hasProgressTracking,
+    debuggingEnabled: debuggingEnabled,
+    userAgent: userAgent,
+  );
+}
+
+Set<String> _extractChannelNames(Set<JavascriptChannel>? channels) {
+  final Set<String> channelNames = channels == null
+      ? <String>{}
+      : channels.map((JavascriptChannel channel) => channel.name).toSet();
+  return channelNames;
+}
+
+class _PlatformCallbacksHandler implements WebViewPlatformCallbacksHandler {
+  _PlatformCallbacksHandler(this._widget);
+
+  WebView _widget;
+
+  @override
+  FutureOr<bool> onNavigationRequest({
+    required String url,
+    required bool isForMainFrame,
+  }) async {
+    final NavigationRequest request =
+        NavigationRequest._(url: url, isForMainFrame: isForMainFrame);
+    final bool allowNavigation = _widget.navigationDelegate == null ||
+        await _widget.navigationDelegate!(request) ==
+            NavigationDecision.navigate;
+    return allowNavigation;
+  }
+
+  @override
+  void onPageStarted(String url) {
+    if (_widget.onPageStarted != null) {
+      _widget.onPageStarted!(url);
+    }
+  }
+
+  @override
+  void onPageFinished(String url) {
+    if (_widget.onPageFinished != null) {
+      _widget.onPageFinished!(url);
+    }
+  }
+
+  @override
+  void onProgress(int progress) {
+    if (_widget.onProgress != null) {
+      _widget.onProgress!(progress);
+    }
+  }
+
+  void onWebResourceError(WebResourceError error) {
+    if (_widget.onWebResourceError != null) {
+      _widget.onWebResourceError!(error);
+    }
+  }
+}
+
+/// Controls a [WebView].
+///
+/// A [WebViewController] instance can be obtained by setting the [WebView.onWebViewCreated]
+/// callback for a [WebView] widget.
+class WebViewController {
+  WebViewController._(
+    this._widget,
+    this._webViewPlatformController,
+    this._javascriptChannelRegistry,
+  ) : assert(_webViewPlatformController != null) {
+    _settings = _webSettingsFromWidget(_widget);
+  }
+
+  final WebViewPlatformController _webViewPlatformController;
+  final JavascriptChannelRegistry _javascriptChannelRegistry;
+
+  late WebSettings _settings;
+
+  WebView _widget;
+
+  /// Loads the specified URL.
+  ///
+  /// If `headers` is not null and the URL is an HTTP URL, the key value paris in `headers` will
+  /// be added as key value pairs of HTTP headers for the request.
+  ///
+  /// `url` must not be null.
+  ///
+  /// Throws an ArgumentError if `url` is not a valid URL string.
+  Future<void> loadUrl(
+    String url, {
+    Map<String, String>? headers,
+  }) async {
+    assert(url != null);
+    _validateUrlString(url);
+    return _webViewPlatformController.loadUrl(url, headers);
+  }
+
+  /// Accessor to the current URL that the WebView is displaying.
+  ///
+  /// If [WebView.initialUrl] was never specified, returns `null`.
+  /// Note that this operation is asynchronous, and it is possible that the
+  /// current URL changes again by the time this function returns (in other
+  /// words, by the time this future completes, the WebView may be displaying a
+  /// different URL).
+  Future<String?> currentUrl() {
+    return _webViewPlatformController.currentUrl();
+  }
+
+  /// Checks whether there's a back history item.
+  ///
+  /// Note that this operation is asynchronous, and it is possible that the "canGoBack" state has
+  /// changed by the time the future completed.
+  Future<bool> canGoBack() {
+    return _webViewPlatformController.canGoBack();
+  }
+
+  /// Checks whether there's a forward history item.
+  ///
+  /// Note that this operation is asynchronous, and it is possible that the "canGoForward" state has
+  /// changed by the time the future completed.
+  Future<bool> canGoForward() {
+    return _webViewPlatformController.canGoForward();
+  }
+
+  /// Goes back in the history of this WebView.
+  ///
+  /// If there is no back history item this is a no-op.
+  Future<void> goBack() {
+    return _webViewPlatformController.goBack();
+  }
+
+  /// Goes forward in the history of this WebView.
+  ///
+  /// If there is no forward history item this is a no-op.
+  Future<void> goForward() {
+    return _webViewPlatformController.goForward();
+  }
+
+  /// Reloads the current URL.
+  Future<void> reload() {
+    return _webViewPlatformController.reload();
+  }
+
+  /// Clears all caches used by the [WebView].
+  ///
+  /// The following caches are cleared:
+  ///	1. Browser HTTP Cache.
+  ///	2. [Cache API](https://developers.google.com/web/fundamentals/instant-and-offline/web-storage/cache-api) caches.
+  ///    These are not yet supported in iOS WkWebView. Service workers tend to use this cache.
+  ///	3. Application cache.
+  ///	4. Local Storage.
+  ///
+  /// Note: Calling this method also triggers a reload.
+  Future<void> clearCache() async {
+    await _webViewPlatformController.clearCache();
+    return reload();
+  }
+
+  Future<void> _updateJavascriptChannels(
+      Set<JavascriptChannel>? newChannels) async {
+    final Set<String> currentChannels =
+        _javascriptChannelRegistry.channels.keys.toSet();
+    final Set<String> newChannelNames = _extractChannelNames(newChannels);
+    final Set<String> channelsToAdd =
+        newChannelNames.difference(currentChannels);
+    final Set<String> channelsToRemove =
+        currentChannels.difference(newChannelNames);
+    if (channelsToRemove.isNotEmpty) {
+      await _webViewPlatformController
+          .removeJavascriptChannels(channelsToRemove);
+    }
+    if (channelsToAdd.isNotEmpty) {
+      await _webViewPlatformController.addJavascriptChannels(channelsToAdd);
+    }
+    _javascriptChannelRegistry.updateJavascriptChannelsFromSet(newChannels);
+  }
+
+  Future<void> _updateWidget(WebView widget) async {
+    _widget = widget;
+    await _updateSettings(_webSettingsFromWidget(widget));
+    await _updateJavascriptChannels(widget.javascriptChannels);
+  }
+
+  Future<void> _updateSettings(WebSettings newSettings) {
+    final WebSettings update =
+        _clearUnchangedWebSettings(_settings, newSettings);
+    _settings = newSettings;
+    return _webViewPlatformController.updateSettings(update);
+  }
+
+  /// Evaluates a JavaScript expression in the context of the current page.
+  ///
+  /// On Android returns the evaluation result as a JSON formatted string.
+  ///
+  /// On iOS depending on the value type the return value would be one of:
+  ///
+  ///  - For primitive JavaScript types: the value string formatted (e.g JavaScript 100 returns '100').
+  ///  - For JavaScript arrays of supported types: a string formatted NSArray(e.g '(1,2,3), note that the string for NSArray is formatted and might contain newlines and extra spaces.').
+  ///  - Other non-primitive types are not supported on iOS and will complete the Future with an error.
+  ///
+  /// The Future completes with an error if a JavaScript error occurred, or on iOS, if the type of the
+  /// evaluated expression is not supported as described above.
+  ///
+  /// When evaluating Javascript in a [WebView], it is best practice to wait for
+  /// the [WebView.onPageFinished] callback. This guarantees all the Javascript
+  /// embedded in the main frame HTML has been loaded.
+  Future<String> evaluateJavascript(String javascriptString) {
+    if (_settings.javascriptMode == JavascriptMode.disabled) {
+      return Future<String>.error(FlutterError(
+          'JavaScript mode must be enabled/unrestricted when calling evaluateJavascript.'));
+    }
+    // TODO(amirh): remove this on when the invokeMethod update makes it to stable Flutter.
+    // https://github.com/flutter/flutter/issues/26431
+    // ignore: strong_mode_implicit_dynamic_method
+    return _webViewPlatformController.evaluateJavascript(javascriptString);
+  }
+
+  /// Returns the title of the currently loaded page.
+  Future<String?> getTitle() {
+    return _webViewPlatformController.getTitle();
+  }
+
+  /// Sets the WebView's content scroll position.
+  ///
+  /// The parameters `x` and `y` specify the scroll position in WebView pixels.
+  Future<void> scrollTo(int x, int y) {
+    return _webViewPlatformController.scrollTo(x, y);
+  }
+
+  /// Move the scrolled position of this view.
+  ///
+  /// The parameters `x` and `y` specify the amount of WebView pixels to scroll by horizontally and vertically respectively.
+  Future<void> scrollBy(int x, int y) {
+    return _webViewPlatformController.scrollBy(x, y);
+  }
+
+  /// Return the horizontal scroll position, in WebView pixels, of this view.
+  ///
+  /// Scroll position is measured from left.
+  Future<int> getScrollX() {
+    return _webViewPlatformController.getScrollX();
+  }
+
+  /// Return the vertical scroll position, in WebView pixels, of this view.
+  ///
+  /// Scroll position is measured from top.
+  Future<int> getScrollY() {
+    return _webViewPlatformController.getScrollY();
+  }
+}
+
+/// Manages cookies pertaining to all [WebView]s.
+class CookieManager {
+  /// Creates a [CookieManager] -- returns the instance if it's already been called.
+  factory CookieManager() {
+    return _instance ??= CookieManager._();
+  }
+
+  CookieManager._();
+
+  static CookieManager? _instance;
+
+  /// Clears all cookies for all [WebView] instances.
+  ///
+  /// This is a no op on iOS version smaller than 9.
+  ///
+  /// Returns true if cookies were present before clearing, else false.
+  Future<bool> clearCookies() => WebView.platform.clearCookies();
+}
+
+// Throws an ArgumentError if `url` is not a valid URL string.
+void _validateUrlString(String url) {
+  try {
+    final Uri uri = Uri.parse(url);
+    if (uri.scheme.isEmpty) {
+      throw ArgumentError('Missing scheme in URL string: "$url"');
+    }
+  } on FormatException catch (e) {
+    throw ArgumentError(e);
+  }
+}
diff --git a/packages/webview_flutter/webview_flutter/lib/src/webview_android.dart b/packages/webview_flutter/webview_flutter/lib/src/webview_android.dart
deleted file mode 100644
index ca1440d..0000000
--- a/packages/webview_flutter/webview_flutter/lib/src/webview_android.dart
+++ /dev/null
@@ -1,60 +0,0 @@
-// Copyright 2013 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.
-
-import 'dart:async';
-
-import 'package:flutter/foundation.dart';
-import 'package:flutter/gestures.dart';
-import 'package:flutter/services.dart';
-import 'package:flutter/widgets.dart';
-
-import '../platform_interface.dart';
-import 'webview_method_channel.dart';
-
-/// Builds an Android webview.
-///
-/// This is used as the default implementation for [WebView.platform] on Android. It uses
-/// an [AndroidView] to embed the webview in the widget hierarchy, and uses a method channel to
-/// communicate with the platform code.
-class AndroidWebView implements WebViewPlatform {
-  @override
-  Widget build({
-    required BuildContext context,
-    required CreationParams creationParams,
-    required WebViewPlatformCallbacksHandler webViewPlatformCallbacksHandler,
-    WebViewPlatformCreatedCallback? onWebViewPlatformCreated,
-    Set<Factory<OneSequenceGestureRecognizer>>? gestureRecognizers,
-  }) {
-    assert(webViewPlatformCallbacksHandler != null);
-    return GestureDetector(
-      // We prevent text selection by intercepting the long press event.
-      // This is a temporary stop gap due to issues with text selection on Android:
-      // https://github.com/flutter/flutter/issues/24585 - the text selection
-      // dialog is not responding to touch events.
-      // https://github.com/flutter/flutter/issues/24584 - the text selection
-      // handles are not showing.
-      // TODO(amirh): remove this when the issues above are fixed.
-      onLongPress: () {},
-      excludeFromSemantics: true,
-      child: AndroidView(
-        viewType: 'plugins.flutter.io/webview',
-        onPlatformViewCreated: (int id) {
-          if (onWebViewPlatformCreated == null) {
-            return;
-          }
-          onWebViewPlatformCreated(MethodChannelWebViewPlatform(
-              id, webViewPlatformCallbacksHandler));
-        },
-        gestureRecognizers: gestureRecognizers,
-        layoutDirection: Directionality.maybeOf(context) ?? TextDirection.rtl,
-        creationParams:
-            MethodChannelWebViewPlatform.creationParamsToMap(creationParams),
-        creationParamsCodec: const StandardMessageCodec(),
-      ),
-    );
-  }
-
-  @override
-  Future<bool> clearCookies() => MethodChannelWebViewPlatform.clearCookies();
-}
diff --git a/packages/webview_flutter/webview_flutter/lib/src/webview_cupertino.dart b/packages/webview_flutter/webview_flutter/lib/src/webview_cupertino.dart
deleted file mode 100644
index 8d4be38..0000000
--- a/packages/webview_flutter/webview_flutter/lib/src/webview_cupertino.dart
+++ /dev/null
@@ -1,47 +0,0 @@
-// Copyright 2013 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.
-
-import 'dart:async';
-
-import 'package:flutter/foundation.dart';
-import 'package:flutter/gestures.dart';
-import 'package:flutter/services.dart';
-import 'package:flutter/widgets.dart';
-
-import '../platform_interface.dart';
-import 'webview_method_channel.dart';
-
-/// Builds an iOS webview.
-///
-/// This is used as the default implementation for [WebView.platform] on iOS. It uses
-/// a [UiKitView] to embed the webview in the widget hierarchy, and uses a method channel to
-/// communicate with the platform code.
-class CupertinoWebView implements WebViewPlatform {
-  @override
-  Widget build({
-    required BuildContext context,
-    required CreationParams creationParams,
-    required WebViewPlatformCallbacksHandler webViewPlatformCallbacksHandler,
-    WebViewPlatformCreatedCallback? onWebViewPlatformCreated,
-    Set<Factory<OneSequenceGestureRecognizer>>? gestureRecognizers,
-  }) {
-    return UiKitView(
-      viewType: 'plugins.flutter.io/webview',
-      onPlatformViewCreated: (int id) {
-        if (onWebViewPlatformCreated == null) {
-          return;
-        }
-        onWebViewPlatformCreated(
-            MethodChannelWebViewPlatform(id, webViewPlatformCallbacksHandler));
-      },
-      gestureRecognizers: gestureRecognizers,
-      creationParams:
-          MethodChannelWebViewPlatform.creationParamsToMap(creationParams),
-      creationParamsCodec: const StandardMessageCodec(),
-    );
-  }
-
-  @override
-  Future<bool> clearCookies() => MethodChannelWebViewPlatform.clearCookies();
-}
diff --git a/packages/webview_flutter/webview_flutter/lib/src/webview_method_channel.dart b/packages/webview_flutter/webview_flutter/lib/src/webview_method_channel.dart
deleted file mode 100644
index 05831a9..0000000
--- a/packages/webview_flutter/webview_flutter/lib/src/webview_method_channel.dart
+++ /dev/null
@@ -1,216 +0,0 @@
-// Copyright 2013 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.
-
-import 'dart:async';
-
-import 'package:flutter/services.dart';
-
-import '../platform_interface.dart';
-
-/// A [WebViewPlatformController] that uses a method channel to control the webview.
-class MethodChannelWebViewPlatform implements WebViewPlatformController {
-  /// Constructs an instance that will listen for webviews broadcasting to the
-  /// given [id], using the given [WebViewPlatformCallbacksHandler].
-  MethodChannelWebViewPlatform(int id, this._platformCallbacksHandler)
-      : assert(_platformCallbacksHandler != null),
-        _channel = MethodChannel('plugins.flutter.io/webview_$id') {
-    _channel.setMethodCallHandler(_onMethodCall);
-  }
-
-  final WebViewPlatformCallbacksHandler _platformCallbacksHandler;
-
-  final MethodChannel _channel;
-
-  static const MethodChannel _cookieManagerChannel =
-      MethodChannel('plugins.flutter.io/cookie_manager');
-
-  Future<bool?> _onMethodCall(MethodCall call) async {
-    switch (call.method) {
-      case 'javascriptChannelMessage':
-        final String channel = call.arguments['channel']!;
-        final String message = call.arguments['message']!;
-        _platformCallbacksHandler.onJavaScriptChannelMessage(channel, message);
-        return true;
-      case 'navigationRequest':
-        return await _platformCallbacksHandler.onNavigationRequest(
-          url: call.arguments['url']!,
-          isForMainFrame: call.arguments['isForMainFrame']!,
-        );
-      case 'onPageFinished':
-        _platformCallbacksHandler.onPageFinished(call.arguments['url']!);
-        return null;
-      case 'onProgress':
-        _platformCallbacksHandler.onProgress(call.arguments['progress']);
-        return null;
-      case 'onPageStarted':
-        _platformCallbacksHandler.onPageStarted(call.arguments['url']!);
-        return null;
-      case 'onWebResourceError':
-        _platformCallbacksHandler.onWebResourceError(
-          WebResourceError(
-            errorCode: call.arguments['errorCode']!,
-            description: call.arguments['description']!,
-            // iOS doesn't support `failingUrl`.
-            failingUrl: call.arguments['failingUrl'],
-            domain: call.arguments['domain'],
-            errorType: call.arguments['errorType'] == null
-                ? null
-                : WebResourceErrorType.values.firstWhere(
-                    (WebResourceErrorType type) {
-                      return type.toString() ==
-                          '$WebResourceErrorType.${call.arguments['errorType']}';
-                    },
-                  ),
-          ),
-        );
-        return null;
-    }
-
-    throw MissingPluginException(
-      '${call.method} was invoked but has no handler',
-    );
-  }
-
-  @override
-  Future<void> loadUrl(
-    String url,
-    Map<String, String>? headers,
-  ) async {
-    assert(url != null);
-    return _channel.invokeMethod<void>('loadUrl', <String, dynamic>{
-      'url': url,
-      'headers': headers,
-    });
-  }
-
-  @override
-  Future<String?> currentUrl() => _channel.invokeMethod<String>('currentUrl');
-
-  @override
-  Future<bool> canGoBack() =>
-      _channel.invokeMethod<bool>("canGoBack").then((result) => result!);
-
-  @override
-  Future<bool> canGoForward() =>
-      _channel.invokeMethod<bool>("canGoForward").then((result) => result!);
-
-  @override
-  Future<void> goBack() => _channel.invokeMethod<void>("goBack");
-
-  @override
-  Future<void> goForward() => _channel.invokeMethod<void>("goForward");
-
-  @override
-  Future<void> reload() => _channel.invokeMethod<void>("reload");
-
-  @override
-  Future<void> clearCache() => _channel.invokeMethod<void>("clearCache");
-
-  @override
-  Future<void> updateSettings(WebSettings settings) async {
-    final Map<String, dynamic> updatesMap = _webSettingsToMap(settings);
-    if (updatesMap.isNotEmpty) {
-      await _channel.invokeMethod<void>('updateSettings', updatesMap);
-    }
-  }
-
-  @override
-  Future<String> evaluateJavascript(String javascriptString) {
-    return _channel
-        .invokeMethod<String>('evaluateJavascript', javascriptString)
-        .then((result) => result!);
-  }
-
-  @override
-  Future<void> addJavascriptChannels(Set<String> javascriptChannelNames) {
-    return _channel.invokeMethod<void>(
-        'addJavascriptChannels', javascriptChannelNames.toList());
-  }
-
-  @override
-  Future<void> removeJavascriptChannels(Set<String> javascriptChannelNames) {
-    return _channel.invokeMethod<void>(
-        'removeJavascriptChannels', javascriptChannelNames.toList());
-  }
-
-  @override
-  Future<String?> getTitle() => _channel.invokeMethod<String>("getTitle");
-
-  @override
-  Future<void> scrollTo(int x, int y) {
-    return _channel.invokeMethod<void>('scrollTo', <String, int>{
-      'x': x,
-      'y': y,
-    });
-  }
-
-  @override
-  Future<void> scrollBy(int x, int y) {
-    return _channel.invokeMethod<void>('scrollBy', <String, int>{
-      'x': x,
-      'y': y,
-    });
-  }
-
-  @override
-  Future<int> getScrollX() =>
-      _channel.invokeMethod<int>("getScrollX").then((result) => result!);
-
-  @override
-  Future<int> getScrollY() =>
-      _channel.invokeMethod<int>("getScrollY").then((result) => result!);
-
-  /// Method channel implementation for [WebViewPlatform.clearCookies].
-  static Future<bool> clearCookies() {
-    return _cookieManagerChannel
-        .invokeMethod<bool>('clearCookies')
-        .then<bool>((dynamic result) => result!);
-  }
-
-  static Map<String, dynamic> _webSettingsToMap(WebSettings? settings) {
-    final Map<String, dynamic> map = <String, dynamic>{};
-    void _addIfNonNull(String key, dynamic value) {
-      if (value == null) {
-        return;
-      }
-      map[key] = value;
-    }
-
-    void _addSettingIfPresent<T>(String key, WebSetting<T> setting) {
-      if (!setting.isPresent) {
-        return;
-      }
-      map[key] = setting.value;
-    }
-
-    _addIfNonNull('jsMode', settings!.javascriptMode?.index);
-    _addIfNonNull('hasNavigationDelegate', settings.hasNavigationDelegate);
-    _addIfNonNull('hasProgressTracking', settings.hasProgressTracking);
-    _addIfNonNull('debuggingEnabled', settings.debuggingEnabled);
-    _addIfNonNull(
-        'gestureNavigationEnabled', settings.gestureNavigationEnabled);
-    _addIfNonNull(
-        'allowsInlineMediaPlayback', settings.allowsInlineMediaPlayback);
-    _addSettingIfPresent('userAgent', settings.userAgent);
-    return map;
-  }
-
-  /// Converts a [CreationParams] object to a map as expected by `platform_views` channel.
-  ///
-  /// This is used for the `creationParams` argument of the platform views created by
-  /// [AndroidWebViewBuilder] and [CupertinoWebViewBuilder].
-  static Map<String, dynamic> creationParamsToMap(
-    CreationParams creationParams, {
-    bool usesHybridComposition = false,
-  }) {
-    return <String, dynamic>{
-      'initialUrl': creationParams.initialUrl,
-      'settings': _webSettingsToMap(creationParams.webSettings),
-      'javascriptChannelNames': creationParams.javascriptChannelNames.toList(),
-      'userAgent': creationParams.userAgent,
-      'autoMediaPlaybackPolicy': creationParams.autoMediaPlaybackPolicy.index,
-      'usesHybridComposition': usesHybridComposition,
-    };
-  }
-}
diff --git a/packages/webview_flutter/webview_flutter/lib/webview_flutter.dart b/packages/webview_flutter/webview_flutter/lib/webview_flutter.dart
index 398ac87..ba38771 100644
--- a/packages/webview_flutter/webview_flutter/lib/webview_flutter.dart
+++ b/packages/webview_flutter/webview_flutter/lib/webview_flutter.dart
@@ -2,833 +2,9 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-import 'dart:async';
-import 'dart:io';
+export 'package:webview_flutter_android/webview_android.dart';
+export 'package:webview_flutter_android/webview_surface_android.dart';
+export 'package:webview_flutter_wkwebview/webview_flutter_wkwebview.dart';
 
-import 'package:flutter/foundation.dart';
-import 'package:flutter/gestures.dart';
-import 'package:flutter/rendering.dart';
-import 'package:flutter/services.dart';
-import 'package:flutter/widgets.dart';
-
-import 'platform_interface.dart';
-import 'src/webview_android.dart';
-import 'src/webview_cupertino.dart';
-import 'src/webview_method_channel.dart';
-
-/// Optional callback invoked when a web view is first created. [controller] is
-/// the [WebViewController] for the created web view.
-typedef void WebViewCreatedCallback(WebViewController controller);
-
-/// Describes the state of JavaScript support in a given web view.
-enum JavascriptMode {
-  /// JavaScript execution is disabled.
-  disabled,
-
-  /// JavaScript execution is not restricted.
-  unrestricted,
-}
-
-/// A message that was sent by JavaScript code running in a [WebView].
-class JavascriptMessage {
-  /// Constructs a JavaScript message object.
-  ///
-  /// The `message` parameter must not be null.
-  const JavascriptMessage(this.message) : assert(message != null);
-
-  /// The contents of the message that was sent by the JavaScript code.
-  final String message;
-}
-
-/// Callback type for handling messages sent from Javascript running in a web view.
-typedef void JavascriptMessageHandler(JavascriptMessage message);
-
-/// Information about a navigation action that is about to be executed.
-class NavigationRequest {
-  NavigationRequest._({required this.url, required this.isForMainFrame});
-
-  /// The URL that will be loaded if the navigation is executed.
-  final String url;
-
-  /// Whether the navigation request is to be loaded as the main frame.
-  final bool isForMainFrame;
-
-  @override
-  String toString() {
-    return '$runtimeType(url: $url, isForMainFrame: $isForMainFrame)';
-  }
-}
-
-/// A decision on how to handle a navigation request.
-enum NavigationDecision {
-  /// Prevent the navigation from taking place.
-  prevent,
-
-  /// Allow the navigation to take place.
-  navigate,
-}
-
-/// Android [WebViewPlatform] that uses [AndroidViewSurface] to build the [WebView] widget.
-///
-/// To use this, set [WebView.platform] to an instance of this class.
-///
-/// This implementation uses hybrid composition to render the [WebView] on
-/// Android. It solves multiple issues related to accessibility and interaction
-/// with the [WebView] at the cost of some performance on Android versions below
-/// 10. See https://github.com/flutter/flutter/wiki/Hybrid-Composition for more
-/// information.
-class SurfaceAndroidWebView extends AndroidWebView {
-  @override
-  Widget build({
-    required BuildContext context,
-    required CreationParams creationParams,
-    WebViewPlatformCreatedCallback? onWebViewPlatformCreated,
-    Set<Factory<OneSequenceGestureRecognizer>>? gestureRecognizers,
-    required WebViewPlatformCallbacksHandler webViewPlatformCallbacksHandler,
-  }) {
-    assert(Platform.isAndroid);
-    assert(webViewPlatformCallbacksHandler != null);
-    return PlatformViewLink(
-      viewType: 'plugins.flutter.io/webview',
-      surfaceFactory: (
-        BuildContext context,
-        PlatformViewController controller,
-      ) {
-        return AndroidViewSurface(
-          controller: controller as AndroidViewController,
-          gestureRecognizers: gestureRecognizers ??
-              const <Factory<OneSequenceGestureRecognizer>>{},
-          hitTestBehavior: PlatformViewHitTestBehavior.opaque,
-        );
-      },
-      onCreatePlatformView: (PlatformViewCreationParams params) {
-        return PlatformViewsService.initSurfaceAndroidView(
-          id: params.id,
-          viewType: 'plugins.flutter.io/webview',
-          // WebView content is not affected by the Android view's layout direction,
-          // we explicitly set it here so that the widget doesn't require an ambient
-          // directionality.
-          layoutDirection: TextDirection.rtl,
-          creationParams: MethodChannelWebViewPlatform.creationParamsToMap(
-            creationParams,
-            usesHybridComposition: true,
-          ),
-          creationParamsCodec: const StandardMessageCodec(),
-        )
-          ..addOnPlatformViewCreatedListener(params.onPlatformViewCreated)
-          ..addOnPlatformViewCreatedListener((int id) {
-            if (onWebViewPlatformCreated == null) {
-              return;
-            }
-            onWebViewPlatformCreated(
-              MethodChannelWebViewPlatform(id, webViewPlatformCallbacksHandler),
-            );
-          })
-          ..create();
-      },
-    );
-  }
-}
-
-/// Decides how to handle a specific navigation request.
-///
-/// The returned [NavigationDecision] determines how the navigation described by
-/// `navigation` should be handled.
-///
-/// See also: [WebView.navigationDelegate].
-typedef FutureOr<NavigationDecision> NavigationDelegate(
-    NavigationRequest navigation);
-
-/// Signature for when a [WebView] has started loading a page.
-typedef void PageStartedCallback(String url);
-
-/// Signature for when a [WebView] has finished loading a page.
-typedef void PageFinishedCallback(String url);
-
-/// Signature for when a [WebView] is loading a page.
-typedef void PageLoadingCallback(int progress);
-
-/// Signature for when a [WebView] has failed to load a resource.
-typedef void WebResourceErrorCallback(WebResourceError error);
-
-/// Specifies possible restrictions on automatic media playback.
-///
-/// This is typically used in [WebView.initialMediaPlaybackPolicy].
-// The method channel implementation is marshalling this enum to the value's index, so the order
-// is important.
-enum AutoMediaPlaybackPolicy {
-  /// Starting any kind of media playback requires a user action.
-  ///
-  /// For example: JavaScript code cannot start playing media unless the code was executed
-  /// as a result of a user action (like a touch event).
-  require_user_action_for_all_media_types,
-
-  /// Starting any kind of media playback is always allowed.
-  ///
-  /// For example: JavaScript code that's triggered when the page is loaded can start playing
-  /// video or audio.
-  always_allow,
-}
-
-final RegExp _validChannelNames = RegExp('^[a-zA-Z_][a-zA-Z0-9_]*\$');
-
-/// A named channel for receiving messaged from JavaScript code running inside a web view.
-class JavascriptChannel {
-  /// Constructs a Javascript channel.
-  ///
-  /// The parameters `name` and `onMessageReceived` must not be null.
-  JavascriptChannel({
-    required this.name,
-    required this.onMessageReceived,
-  })  : assert(name != null),
-        assert(onMessageReceived != null),
-        assert(_validChannelNames.hasMatch(name));
-
-  /// The channel's name.
-  ///
-  /// Passing this channel object as part of a [WebView.javascriptChannels] adds a channel object to
-  /// the Javascript window object's property named `name`.
-  ///
-  /// The name must start with a letter or underscore(_), followed by any combination of those
-  /// characters plus digits.
-  ///
-  /// Note that any JavaScript existing `window` property with this name will be overriden.
-  ///
-  /// See also [WebView.javascriptChannels] for more details on the channel registration mechanism.
-  final String name;
-
-  /// A callback that's invoked when a message is received through the channel.
-  final JavascriptMessageHandler onMessageReceived;
-}
-
-/// A web view widget for showing html content.
-///
-/// There is a known issue that on iOS 13.4 and 13.5, other flutter widgets covering
-/// the `WebView` is not able to block the `WebView` from receiving touch events.
-/// See https://github.com/flutter/flutter/issues/53490.
-class WebView extends StatefulWidget {
-  /// Creates a new web view.
-  ///
-  /// The web view can be controlled using a `WebViewController` that is passed to the
-  /// `onWebViewCreated` callback once the web view is created.
-  ///
-  /// The `javascriptMode` and `autoMediaPlaybackPolicy` parameters must not be null.
-  const WebView({
-    Key? key,
-    this.onWebViewCreated,
-    this.initialUrl,
-    this.javascriptMode = JavascriptMode.disabled,
-    this.javascriptChannels,
-    this.navigationDelegate,
-    this.gestureRecognizers,
-    this.onPageStarted,
-    this.onPageFinished,
-    this.onProgress,
-    this.onWebResourceError,
-    this.debuggingEnabled = false,
-    this.gestureNavigationEnabled = false,
-    this.userAgent,
-    this.initialMediaPlaybackPolicy =
-        AutoMediaPlaybackPolicy.require_user_action_for_all_media_types,
-    this.allowsInlineMediaPlayback = false,
-  })  : assert(javascriptMode != null),
-        assert(initialMediaPlaybackPolicy != null),
-        assert(allowsInlineMediaPlayback != null),
-        super(key: key);
-
-  static WebViewPlatform? _platform;
-
-  /// Sets a custom [WebViewPlatform].
-  ///
-  /// This property can be set to use a custom platform implementation for WebViews.
-  ///
-  /// Setting `platform` doesn't affect [WebView]s that were already created.
-  ///
-  /// The default value is [AndroidWebView] on Android and [CupertinoWebView] on iOS.
-  static set platform(WebViewPlatform? platform) {
-    _platform = platform;
-  }
-
-  /// The WebView platform that's used by this WebView.
-  ///
-  /// The default value is [AndroidWebView] on Android and [CupertinoWebView] on iOS.
-  static WebViewPlatform get platform {
-    if (_platform == null) {
-      switch (defaultTargetPlatform) {
-        case TargetPlatform.android:
-          _platform = AndroidWebView();
-          break;
-        case TargetPlatform.iOS:
-          _platform = CupertinoWebView();
-          break;
-        default:
-          throw UnsupportedError(
-              "Trying to use the default webview implementation for $defaultTargetPlatform but there isn't a default one");
-      }
-    }
-    return _platform!;
-  }
-
-  /// If not null invoked once the web view is created.
-  final WebViewCreatedCallback? onWebViewCreated;
-
-  /// Which gestures should be consumed by the web view.
-  ///
-  /// It is possible for other gesture recognizers to be competing with the web view on pointer
-  /// events, e.g if the web view is inside a [ListView] the [ListView] will want to handle
-  /// vertical drags. The web view will claim gestures that are recognized by any of the
-  /// recognizers on this list.
-  ///
-  /// When this set is empty or null, the web view will only handle pointer events for gestures that
-  /// were not claimed by any other gesture recognizer.
-  final Set<Factory<OneSequenceGestureRecognizer>>? gestureRecognizers;
-
-  /// The initial URL to load.
-  final String? initialUrl;
-
-  /// Whether Javascript execution is enabled.
-  final JavascriptMode javascriptMode;
-
-  /// The set of [JavascriptChannel]s available to JavaScript code running in the web view.
-  ///
-  /// For each [JavascriptChannel] in the set, a channel object is made available for the
-  /// JavaScript code in a window property named [JavascriptChannel.name].
-  /// The JavaScript code can then call `postMessage` on that object to send a message that will be
-  /// passed to [JavascriptChannel.onMessageReceived].
-  ///
-  /// For example for the following JavascriptChannel:
-  ///
-  /// ```dart
-  /// JavascriptChannel(name: 'Print', onMessageReceived: (JavascriptMessage message) { print(message.message); });
-  /// ```
-  ///
-  /// JavaScript code can call:
-  ///
-  /// ```javascript
-  /// Print.postMessage('Hello');
-  /// ```
-  ///
-  /// To asynchronously invoke the message handler which will print the message to standard output.
-  ///
-  /// Adding a new JavaScript channel only takes affect after the next page is loaded.
-  ///
-  /// Set values must not be null. A [JavascriptChannel.name] cannot be the same for multiple
-  /// channels in the list.
-  ///
-  /// A null value is equivalent to an empty set.
-  final Set<JavascriptChannel>? javascriptChannels;
-
-  /// A delegate function that decides how to handle navigation actions.
-  ///
-  /// When a navigation is initiated by the WebView (e.g when a user clicks a link)
-  /// this delegate is called and has to decide how to proceed with the navigation.
-  ///
-  /// See [NavigationDecision] for possible decisions the delegate can take.
-  ///
-  /// When null all navigation actions are allowed.
-  ///
-  /// Caveats on Android:
-  ///
-  ///   * Navigation actions targeted to the main frame can be intercepted,
-  ///     navigation actions targeted to subframes are allowed regardless of the value
-  ///     returned by this delegate.
-  ///   * Setting a navigationDelegate makes the WebView treat all navigations as if they were
-  ///     triggered by a user gesture, this disables some of Chromium's security mechanisms.
-  ///     A navigationDelegate should only be set when loading trusted content.
-  ///   * On Android WebView versions earlier than 67(most devices running at least Android L+ should have
-  ///     a later version):
-  ///     * When a navigationDelegate is set pages with frames are not properly handled by the
-  ///       webview, and frames will be opened in the main frame.
-  ///     * When a navigationDelegate is set HTTP requests do not include the HTTP referer header.
-  final NavigationDelegate? navigationDelegate;
-
-  /// Controls whether inline playback of HTML5 videos is allowed on iOS.
-  ///
-  /// This field is ignored on Android because Android allows it by default.
-  ///
-  /// By default `allowsInlineMediaPlayback` is false.
-  final bool allowsInlineMediaPlayback;
-
-  /// Invoked when a page starts loading.
-  final PageStartedCallback? onPageStarted;
-
-  /// Invoked when a page has finished loading.
-  ///
-  /// This is invoked only for the main frame.
-  ///
-  /// When [onPageFinished] is invoked on Android, the page being rendered may
-  /// not be updated yet.
-  ///
-  /// When invoked on iOS or Android, any Javascript code that is embedded
-  /// directly in the HTML has been loaded and code injected with
-  /// [WebViewController.evaluateJavascript] can assume this.
-  final PageFinishedCallback? onPageFinished;
-
-  /// Invoked when a page is loading.
-  final PageLoadingCallback? onProgress;
-
-  /// Invoked when a web resource has failed to load.
-  ///
-  /// This callback is only called for the main page.
-  final WebResourceErrorCallback? onWebResourceError;
-
-  /// Controls whether WebView debugging is enabled.
-  ///
-  /// Setting this to true enables [WebView debugging on Android](https://developers.google.com/web/tools/chrome-devtools/remote-debugging/).
-  ///
-  /// WebView debugging is enabled by default in dev builds on iOS.
-  ///
-  /// To debug WebViews on iOS:
-  /// - Enable developer options (Open Safari, go to Preferences -> Advanced and make sure "Show Develop Menu in Menubar" is on.)
-  /// - From the Menu-bar (of Safari) select Develop -> iPhone Simulator -> <your webview page>
-  ///
-  /// By default `debuggingEnabled` is false.
-  final bool debuggingEnabled;
-
-  /// A Boolean value indicating whether horizontal swipe gestures will trigger back-forward list navigations.
-  ///
-  /// This only works on iOS.
-  ///
-  /// By default `gestureNavigationEnabled` is false.
-  final bool gestureNavigationEnabled;
-
-  /// The value used for the HTTP User-Agent: request header.
-  ///
-  /// When null the platform's webview default is used for the User-Agent header.
-  ///
-  /// When the [WebView] is rebuilt with a different `userAgent`, the page reloads and the request uses the new User Agent.
-  ///
-  /// When [WebViewController.goBack] is called after changing `userAgent` the previous `userAgent` value is used until the page is reloaded.
-  ///
-  /// This field is ignored on iOS versions prior to 9 as the platform does not support a custom
-  /// user agent.
-  ///
-  /// By default `userAgent` is null.
-  final String? userAgent;
-
-  /// Which restrictions apply on automatic media playback.
-  ///
-  /// This initial value is applied to the platform's webview upon creation. Any following
-  /// changes to this parameter are ignored (as long as the state of the [WebView] is preserved).
-  ///
-  /// The default policy is [AutoMediaPlaybackPolicy.require_user_action_for_all_media_types].
-  final AutoMediaPlaybackPolicy initialMediaPlaybackPolicy;
-
-  @override
-  State<StatefulWidget> createState() => _WebViewState();
-}
-
-class _WebViewState extends State<WebView> {
-  final Completer<WebViewController> _controller =
-      Completer<WebViewController>();
-
-  late _PlatformCallbacksHandler _platformCallbacksHandler;
-
-  @override
-  Widget build(BuildContext context) {
-    return WebView.platform.build(
-      context: context,
-      onWebViewPlatformCreated: _onWebViewPlatformCreated,
-      webViewPlatformCallbacksHandler: _platformCallbacksHandler,
-      gestureRecognizers: widget.gestureRecognizers,
-      creationParams: _creationParamsfromWidget(widget),
-    );
-  }
-
-  @override
-  void initState() {
-    super.initState();
-    _assertJavascriptChannelNamesAreUnique();
-    _platformCallbacksHandler = _PlatformCallbacksHandler(widget);
-  }
-
-  @override
-  void didUpdateWidget(WebView oldWidget) {
-    super.didUpdateWidget(oldWidget);
-    _assertJavascriptChannelNamesAreUnique();
-    _controller.future.then((WebViewController controller) {
-      _platformCallbacksHandler._widget = widget;
-      controller._updateWidget(widget);
-    });
-  }
-
-  void _onWebViewPlatformCreated(WebViewPlatformController? webViewPlatform) {
-    final WebViewController controller = WebViewController._(
-        widget, webViewPlatform!, _platformCallbacksHandler);
-    _controller.complete(controller);
-    if (widget.onWebViewCreated != null) {
-      widget.onWebViewCreated!(controller);
-    }
-  }
-
-  void _assertJavascriptChannelNamesAreUnique() {
-    if (widget.javascriptChannels == null ||
-        widget.javascriptChannels!.isEmpty) {
-      return;
-    }
-    assert(_extractChannelNames(widget.javascriptChannels).length ==
-        widget.javascriptChannels!.length);
-  }
-}
-
-CreationParams _creationParamsfromWidget(WebView widget) {
-  return CreationParams(
-    initialUrl: widget.initialUrl,
-    webSettings: _webSettingsFromWidget(widget),
-    javascriptChannelNames: _extractChannelNames(widget.javascriptChannels),
-    userAgent: widget.userAgent,
-    autoMediaPlaybackPolicy: widget.initialMediaPlaybackPolicy,
-  );
-}
-
-WebSettings _webSettingsFromWidget(WebView widget) {
-  return WebSettings(
-    javascriptMode: widget.javascriptMode,
-    hasNavigationDelegate: widget.navigationDelegate != null,
-    hasProgressTracking: widget.onProgress != null,
-    debuggingEnabled: widget.debuggingEnabled,
-    gestureNavigationEnabled: widget.gestureNavigationEnabled,
-    allowsInlineMediaPlayback: widget.allowsInlineMediaPlayback,
-    userAgent: WebSetting<String?>.of(widget.userAgent),
-  );
-}
-
-// This method assumes that no fields in `currentValue` are null.
-WebSettings _clearUnchangedWebSettings(
-    WebSettings currentValue, WebSettings newValue) {
-  assert(currentValue.javascriptMode != null);
-  assert(currentValue.hasNavigationDelegate != null);
-  assert(currentValue.hasProgressTracking != null);
-  assert(currentValue.debuggingEnabled != null);
-  assert(currentValue.userAgent != null);
-  assert(newValue.javascriptMode != null);
-  assert(newValue.hasNavigationDelegate != null);
-  assert(newValue.debuggingEnabled != null);
-  assert(newValue.userAgent != null);
-
-  JavascriptMode? javascriptMode;
-  bool? hasNavigationDelegate;
-  bool? hasProgressTracking;
-  bool? debuggingEnabled;
-  WebSetting<String?> userAgent = WebSetting.absent();
-  if (currentValue.javascriptMode != newValue.javascriptMode) {
-    javascriptMode = newValue.javascriptMode;
-  }
-  if (currentValue.hasNavigationDelegate != newValue.hasNavigationDelegate) {
-    hasNavigationDelegate = newValue.hasNavigationDelegate;
-  }
-  if (currentValue.hasProgressTracking != newValue.hasProgressTracking) {
-    hasProgressTracking = newValue.hasProgressTracking;
-  }
-  if (currentValue.debuggingEnabled != newValue.debuggingEnabled) {
-    debuggingEnabled = newValue.debuggingEnabled;
-  }
-  if (currentValue.userAgent != newValue.userAgent) {
-    userAgent = newValue.userAgent;
-  }
-
-  return WebSettings(
-    javascriptMode: javascriptMode,
-    hasNavigationDelegate: hasNavigationDelegate,
-    hasProgressTracking: hasProgressTracking,
-    debuggingEnabled: debuggingEnabled,
-    userAgent: userAgent,
-  );
-}
-
-Set<String> _extractChannelNames(Set<JavascriptChannel>? channels) {
-  final Set<String> channelNames = channels == null
-      ? <String>{}
-      : channels.map((JavascriptChannel channel) => channel.name).toSet();
-  return channelNames;
-}
-
-class _PlatformCallbacksHandler implements WebViewPlatformCallbacksHandler {
-  _PlatformCallbacksHandler(this._widget) {
-    _updateJavascriptChannelsFromSet(_widget.javascriptChannels);
-  }
-
-  WebView _widget;
-
-  // Maps a channel name to a channel.
-  final Map<String, JavascriptChannel> _javascriptChannels =
-      <String, JavascriptChannel>{};
-
-  @override
-  void onJavaScriptChannelMessage(String channel, String message) {
-    _javascriptChannels[channel]!.onMessageReceived(JavascriptMessage(message));
-  }
-
-  @override
-  FutureOr<bool> onNavigationRequest({
-    required String url,
-    required bool isForMainFrame,
-  }) async {
-    final NavigationRequest request =
-        NavigationRequest._(url: url, isForMainFrame: isForMainFrame);
-    final bool allowNavigation = _widget.navigationDelegate == null ||
-        await _widget.navigationDelegate!(request) ==
-            NavigationDecision.navigate;
-    return allowNavigation;
-  }
-
-  @override
-  void onPageStarted(String url) {
-    if (_widget.onPageStarted != null) {
-      _widget.onPageStarted!(url);
-    }
-  }
-
-  @override
-  void onPageFinished(String url) {
-    if (_widget.onPageFinished != null) {
-      _widget.onPageFinished!(url);
-    }
-  }
-
-  @override
-  void onProgress(int progress) {
-    if (_widget.onProgress != null) {
-      _widget.onProgress!(progress);
-    }
-  }
-
-  void onWebResourceError(WebResourceError error) {
-    if (_widget.onWebResourceError != null) {
-      _widget.onWebResourceError!(error);
-    }
-  }
-
-  void _updateJavascriptChannelsFromSet(Set<JavascriptChannel>? channels) {
-    _javascriptChannels.clear();
-    if (channels == null) {
-      return;
-    }
-    for (JavascriptChannel channel in channels) {
-      _javascriptChannels[channel.name] = channel;
-    }
-  }
-}
-
-/// Controls a [WebView].
-///
-/// A [WebViewController] instance can be obtained by setting the [WebView.onWebViewCreated]
-/// callback for a [WebView] widget.
-class WebViewController {
-  WebViewController._(
-    this._widget,
-    this._webViewPlatformController,
-    this._platformCallbacksHandler,
-  ) : assert(_webViewPlatformController != null) {
-    _settings = _webSettingsFromWidget(_widget);
-  }
-
-  final WebViewPlatformController _webViewPlatformController;
-
-  final _PlatformCallbacksHandler _platformCallbacksHandler;
-
-  late WebSettings _settings;
-
-  WebView _widget;
-
-  /// Loads the specified URL.
-  ///
-  /// If `headers` is not null and the URL is an HTTP URL, the key value paris in `headers` will
-  /// be added as key value pairs of HTTP headers for the request.
-  ///
-  /// `url` must not be null.
-  ///
-  /// Throws an ArgumentError if `url` is not a valid URL string.
-  Future<void> loadUrl(
-    String url, {
-    Map<String, String>? headers,
-  }) async {
-    assert(url != null);
-    _validateUrlString(url);
-    return _webViewPlatformController.loadUrl(url, headers);
-  }
-
-  /// Accessor to the current URL that the WebView is displaying.
-  ///
-  /// If [WebView.initialUrl] was never specified, returns `null`.
-  /// Note that this operation is asynchronous, and it is possible that the
-  /// current URL changes again by the time this function returns (in other
-  /// words, by the time this future completes, the WebView may be displaying a
-  /// different URL).
-  Future<String?> currentUrl() {
-    return _webViewPlatformController.currentUrl();
-  }
-
-  /// Checks whether there's a back history item.
-  ///
-  /// Note that this operation is asynchronous, and it is possible that the "canGoBack" state has
-  /// changed by the time the future completed.
-  Future<bool> canGoBack() {
-    return _webViewPlatformController.canGoBack();
-  }
-
-  /// Checks whether there's a forward history item.
-  ///
-  /// Note that this operation is asynchronous, and it is possible that the "canGoForward" state has
-  /// changed by the time the future completed.
-  Future<bool> canGoForward() {
-    return _webViewPlatformController.canGoForward();
-  }
-
-  /// Goes back in the history of this WebView.
-  ///
-  /// If there is no back history item this is a no-op.
-  Future<void> goBack() {
-    return _webViewPlatformController.goBack();
-  }
-
-  /// Goes forward in the history of this WebView.
-  ///
-  /// If there is no forward history item this is a no-op.
-  Future<void> goForward() {
-    return _webViewPlatformController.goForward();
-  }
-
-  /// Reloads the current URL.
-  Future<void> reload() {
-    return _webViewPlatformController.reload();
-  }
-
-  /// Clears all caches used by the [WebView].
-  ///
-  /// The following caches are cleared:
-  ///	1. Browser HTTP Cache.
-  ///	2. [Cache API](https://developers.google.com/web/fundamentals/instant-and-offline/web-storage/cache-api) caches.
-  ///    These are not yet supported in iOS WkWebView. Service workers tend to use this cache.
-  ///	3. Application cache.
-  ///	4. Local Storage.
-  ///
-  /// Note: Calling this method also triggers a reload.
-  Future<void> clearCache() async {
-    await _webViewPlatformController.clearCache();
-    return reload();
-  }
-
-  Future<void> _updateWidget(WebView widget) async {
-    _widget = widget;
-    await _updateSettings(_webSettingsFromWidget(widget));
-    await _updateJavascriptChannels(widget.javascriptChannels);
-  }
-
-  Future<void> _updateSettings(WebSettings newSettings) {
-    final WebSettings update =
-        _clearUnchangedWebSettings(_settings, newSettings);
-    _settings = newSettings;
-    return _webViewPlatformController.updateSettings(update);
-  }
-
-  Future<void> _updateJavascriptChannels(
-      Set<JavascriptChannel>? newChannels) async {
-    final Set<String> currentChannels =
-        _platformCallbacksHandler._javascriptChannels.keys.toSet();
-    final Set<String> newChannelNames = _extractChannelNames(newChannels);
-    final Set<String> channelsToAdd =
-        newChannelNames.difference(currentChannels);
-    final Set<String> channelsToRemove =
-        currentChannels.difference(newChannelNames);
-    if (channelsToRemove.isNotEmpty) {
-      await _webViewPlatformController
-          .removeJavascriptChannels(channelsToRemove);
-    }
-    if (channelsToAdd.isNotEmpty) {
-      await _webViewPlatformController.addJavascriptChannels(channelsToAdd);
-    }
-    _platformCallbacksHandler._updateJavascriptChannelsFromSet(newChannels);
-  }
-
-  /// Evaluates a JavaScript expression in the context of the current page.
-  ///
-  /// On Android returns the evaluation result as a JSON formatted string.
-  ///
-  /// On iOS depending on the value type the return value would be one of:
-  ///
-  ///  - For primitive JavaScript types: the value string formatted (e.g JavaScript 100 returns '100').
-  ///  - For JavaScript arrays of supported types: a string formatted NSArray(e.g '(1,2,3), note that the string for NSArray is formatted and might contain newlines and extra spaces.').
-  ///  - Other non-primitive types are not supported on iOS and will complete the Future with an error.
-  ///
-  /// The Future completes with an error if a JavaScript error occurred, or on iOS, if the type of the
-  /// evaluated expression is not supported as described above.
-  ///
-  /// When evaluating Javascript in a [WebView], it is best practice to wait for
-  /// the [WebView.onPageFinished] callback. This guarantees all the Javascript
-  /// embedded in the main frame HTML has been loaded.
-  Future<String> evaluateJavascript(String javascriptString) {
-    if (_settings.javascriptMode == JavascriptMode.disabled) {
-      return Future<String>.error(FlutterError(
-          'JavaScript mode must be enabled/unrestricted when calling evaluateJavascript.'));
-    }
-    // TODO(amirh): remove this on when the invokeMethod update makes it to stable Flutter.
-    // https://github.com/flutter/flutter/issues/26431
-    // ignore: strong_mode_implicit_dynamic_method
-    return _webViewPlatformController.evaluateJavascript(javascriptString);
-  }
-
-  /// Returns the title of the currently loaded page.
-  Future<String?> getTitle() {
-    return _webViewPlatformController.getTitle();
-  }
-
-  /// Sets the WebView's content scroll position.
-  ///
-  /// The parameters `x` and `y` specify the scroll position in WebView pixels.
-  Future<void> scrollTo(int x, int y) {
-    return _webViewPlatformController.scrollTo(x, y);
-  }
-
-  /// Move the scrolled position of this view.
-  ///
-  /// The parameters `x` and `y` specify the amount of WebView pixels to scroll by horizontally and vertically respectively.
-  Future<void> scrollBy(int x, int y) {
-    return _webViewPlatformController.scrollBy(x, y);
-  }
-
-  /// Return the horizontal scroll position, in WebView pixels, of this view.
-  ///
-  /// Scroll position is measured from left.
-  Future<int> getScrollX() {
-    return _webViewPlatformController.getScrollX();
-  }
-
-  /// Return the vertical scroll position, in WebView pixels, of this view.
-  ///
-  /// Scroll position is measured from top.
-  Future<int> getScrollY() {
-    return _webViewPlatformController.getScrollY();
-  }
-}
-
-/// Manages cookies pertaining to all [WebView]s.
-class CookieManager {
-  /// Creates a [CookieManager] -- returns the instance if it's already been called.
-  factory CookieManager() {
-    return _instance ??= CookieManager._();
-  }
-
-  CookieManager._();
-
-  static CookieManager? _instance;
-
-  /// Clears all cookies for all [WebView] instances.
-  ///
-  /// This is a no op on iOS version smaller than 9.
-  ///
-  /// Returns true if cookies were present before clearing, else false.
-  Future<bool> clearCookies() => WebView.platform.clearCookies();
-}
-
-// Throws an ArgumentError if `url` is not a valid URL string.
-void _validateUrlString(String url) {
-  try {
-    final Uri uri = Uri.parse(url);
-    if (uri.scheme.isEmpty) {
-      throw ArgumentError('Missing scheme in URL string: "$url"');
-    }
-  } on FormatException catch (e) {
-    throw ArgumentError(e);
-  }
-}
+export 'platform_interface.dart';
+export 'src/webview.dart';
diff --git a/packages/webview_flutter/webview_flutter/pubspec.yaml b/packages/webview_flutter/webview_flutter/pubspec.yaml
index 393a66e..985f317 100644
--- a/packages/webview_flutter/webview_flutter/pubspec.yaml
+++ b/packages/webview_flutter/webview_flutter/pubspec.yaml
@@ -12,14 +12,16 @@
   plugin:
     platforms:
       android:
-        package: io.flutter.plugins.webviewflutter
-        pluginClass: WebViewFlutterPlugin
+        default_package: webview_flutter_android
       ios:
-        pluginClass: FLTWebViewFlutterPlugin
+        default_package: webview_flutter_wkwebview
 
 dependencies:
   flutter:
     sdk: flutter
+  webview_flutter_platform_interface: ^1.0.0
+  webview_flutter_android: ^2.0.13
+  webview_flutter_wkwebview: ^2.0.13
 
 dev_dependencies:
   flutter_driver:
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 5efee6d..f7d0926 100644
--- a/packages/webview_flutter/webview_flutter/test/webview_flutter_test.dart
+++ b/packages/webview_flutter/webview_flutter/test/webview_flutter_test.dart
@@ -10,7 +10,7 @@
 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.dart';
+import 'package:webview_flutter_platform_interface/webview_flutter_platform_interface.dart';
 import 'package:webview_flutter/webview_flutter.dart';
 
 typedef void VoidCallback();
@@ -1175,6 +1175,7 @@
     BuildContext? context,
     CreationParams? creationParams,
     required WebViewPlatformCallbacksHandler webViewPlatformCallbacksHandler,
+    required JavascriptChannelRegistry javascriptChannelRegistry,
     WebViewPlatformCreatedCallback? onWebViewPlatformCreated,
     Set<Factory<OneSequenceGestureRecognizer>>? gestureRecognizers,
   }) {