// 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.

// TODO(bparrishMines): Replace unused callback methods in constructors with
// variables once automatic garbage collection is fully implemented. See
// https://github.com/flutter/flutter/issues/107199.
// ignore_for_file: avoid_unused_constructor_parameters

// TODO(a14n): remove this import once Flutter 3.1 or later reaches stable (including flutter/flutter#104231)
// ignore: unnecessary_import
import 'dart:typed_data';
import 'dart:ui';

import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart' show BinaryMessenger;
import 'package:flutter/widgets.dart' show AndroidViewSurface;

import 'android_webview.pigeon.dart';
import 'android_webview_api_impls.dart';
import 'instance_manager.dart';

/// Root of the Java class hierarchy.
///
/// See https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html.
class JavaObject with Copyable {
  /// Constructs a [JavaObject] without creating the associated Java object.
  ///
  /// This should only be used by subclasses created by this library or to
  /// create copies.
  JavaObject.detached({
    BinaryMessenger? binaryMessenger,
    InstanceManager? instanceManager,
  }) : _api = JavaObjectHostApiImpl(
          binaryMessenger: binaryMessenger,
          instanceManager: instanceManager,
        );

  /// Global instance of [InstanceManager].
  static final InstanceManager globalInstanceManager = InstanceManager(
    onWeakReferenceRemoved: (_) {},
  );

  /// Pigeon Host Api implementation for [JavaObject].
  final JavaObjectHostApiImpl _api;

  /// Release the reference to a native Java instance.
  static void dispose(JavaObject instance) {
    instance._api.instanceManager.removeWeakReference(instance);
  }

  @override
  JavaObject copy() {
    return JavaObject.detached();
  }
}

/// An Android View that displays web pages.
///
/// **Basic usage**
/// In most cases, we recommend using a standard web browser, like Chrome, to
/// deliver content to the user. To learn more about web browsers, read the
/// guide on invoking a browser with
/// [url_launcher](https://pub.dev/packages/url_launcher).
///
/// WebView objects allow you to display web content as part of your widget
/// layout, but lack some of the features of fully-developed browsers. A WebView
/// is useful when you need increased control over the UI and advanced
/// configuration options that will allow you to embed web pages in a
/// specially-designed environment for your app.
///
/// To learn more about WebView and alternatives for serving web content, read
/// the documentation on
/// [Web-based content](https://developer.android.com/guide/webapps).
///
/// When a [WebView] is no longer needed [release] must be called.
class WebView extends JavaObject {
  /// Constructs a new WebView.
  WebView({this.useHybridComposition = false}) : super.detached() {
    api.createFromInstance(this);
  }

  /// Constructs a [WebView] without creating the associated Java object.
  ///
  /// This should only be used by subclasses created by this library or to
  /// create copies.
  WebView.detached({this.useHybridComposition = false}) : super.detached();

  /// Pigeon Host Api implementation for [WebView].
  @visibleForTesting
  static WebViewHostApiImpl api = WebViewHostApiImpl();

  WebViewClient? _currentWebViewClient;

  /// Whether the [WebView] will be rendered with an [AndroidViewSurface].
  ///
  /// This implementation uses hybrid composition to render the WebView Widget.
  /// This comes at the cost of some performance on Android versions below 10.
  /// See
  /// https://flutter.dev/docs/development/platform-integration/platform-views#performance
  /// for more information.
  ///
  /// Defaults to false.
  final bool useHybridComposition;

  /// The [WebSettings] object used to control the settings for this WebView.
  late final WebSettings settings = WebSettings(this);

  /// Enables debugging of web contents (HTML / CSS / JavaScript) loaded into any WebViews of this application.
  ///
  /// This flag can be enabled in order to facilitate debugging of web layouts
  /// and JavaScript code running inside WebViews. Please refer to [WebView]
  /// documentation for the debugging guide. The default is false.
  static Future<void> setWebContentsDebuggingEnabled(bool enabled) {
    return api.setWebContentsDebuggingEnabled(enabled);
  }

  /// Loads the given data into this WebView using a 'data' scheme URL.
  ///
  /// Note that JavaScript's same origin policy means that script running in a
  /// page loaded using this method will be unable to access content loaded
  /// using any scheme other than 'data', including 'http(s)'. To avoid this
  /// restriction, use [loadDataWithBaseURL()] with an appropriate base URL.
  ///
  /// The [encoding] parameter specifies whether the data is base64 or URL
  /// encoded. If the data is base64 encoded, the value of the encoding
  /// parameter must be `'base64'`. HTML can be encoded with
  /// `base64.encode(bytes)` like so:
  /// ```dart
  /// import 'dart:convert';
  ///
  /// final unencodedHtml = '''
  ///   <html><body>'%28' is the code for '('</body></html>
  /// ''';
  /// final encodedHtml = base64.encode(utf8.encode(unencodedHtml));
  /// print(encodedHtml);
  /// ```
  ///
  /// The [mimeType] parameter specifies the format of the data. If WebView
  /// can't handle the specified MIME type, it will download the data. If
  /// `null`, defaults to 'text/html'.
  Future<void> loadData({
    required String data,
    String? mimeType,
    String? encoding,
  }) {
    return api.loadDataFromInstance(
      this,
      data,
      mimeType,
      encoding,
    );
  }

  /// Loads the given data into this WebView.
  ///
  /// The [baseUrl] is used as base URL for the content. It is used  both to
  /// resolve relative URLs and when applying JavaScript's same origin policy.
  ///
  /// The [historyUrl] is used for the history entry.
  ///
  /// The [mimeType] parameter specifies the format of the data. If WebView
  /// can't handle the specified MIME type, it will download the data. If
  /// `null`, defaults to 'text/html'.
  ///
  /// Note that content specified in this way can access local device files (via
  /// 'file' scheme URLs) only if baseUrl specifies a scheme other than 'http',
  /// 'https', 'ftp', 'ftps', 'about' or 'javascript'.
  ///
  /// If the base URL uses the data scheme, this method is equivalent to calling
  /// [loadData] and the [historyUrl] is ignored, and the data will be treated
  /// as part of a data: URL, including the requirement that the content be
  /// URL-encoded or base64 encoded. If the base URL uses any other scheme, then
  /// the data will be loaded into the WebView as a plain string (i.e. not part
  /// of a data URL) and any URL-encoded entities in the string will not be
  /// decoded.
  ///
  /// Note that the [baseUrl] is sent in the 'Referer' HTTP header when
  /// requesting subresources (images, etc.) of the page loaded using this
  /// method.
  ///
  /// If a valid HTTP or HTTPS base URL is not specified in [baseUrl], then
  /// content loaded using this method will have a `window.origin` value of
  /// `"null"`. This must not be considered to be a trusted origin by the
  /// application or by any JavaScript code running inside the WebView (for
  /// example, event sources in DOM event handlers or web messages), because
  /// malicious content can also create frames with a null origin. If you need
  /// to identify the main frame's origin in a trustworthy way, you should use a
  /// valid HTTP or HTTPS base URL to set the origin.
  Future<void> loadDataWithBaseUrl({
    String? baseUrl,
    required String data,
    String? mimeType,
    String? encoding,
    String? historyUrl,
  }) {
    return api.loadDataWithBaseUrlFromInstance(
      this,
      baseUrl,
      data,
      mimeType,
      encoding,
      historyUrl,
    );
  }

  /// Loads the given URL with additional HTTP headers, specified as a map from name to value.
  ///
  /// Note that if this map contains any of the headers that are set by default
  /// by this WebView, such as those controlling caching, accept types or the
  /// User-Agent, their values may be overridden by this WebView's defaults.
  ///
  /// Also see compatibility note on [evaluateJavascript].
  Future<void> loadUrl(String url, Map<String, String> headers) {
    return api.loadUrlFromInstance(this, url, headers);
  }

  /// Loads the URL with postData using "POST" method into this WebView.
  ///
  /// If url is not a network URL, it will be loaded with [loadUrl] instead, ignoring the postData param.
  Future<void> postUrl(String url, Uint8List data) {
    return api.postUrlFromInstance(this, url, data);
  }

  /// Gets the URL for the current page.
  ///
  /// This is not always the same as the URL passed to
  /// [WebViewClient.onPageStarted] because although the load for that URL has
  /// begun, the current page may not have changed.
  ///
  /// Returns null if no page has been loaded.
  Future<String?> getUrl() {
    return api.getUrlFromInstance(this);
  }

  /// Whether this WebView has a back history item.
  Future<bool> canGoBack() {
    return api.canGoBackFromInstance(this);
  }

  /// Whether this WebView has a forward history item.
  Future<bool> canGoForward() {
    return api.canGoForwardFromInstance(this);
  }

  /// Goes back in the history of this WebView.
  Future<void> goBack() {
    return api.goBackFromInstance(this);
  }

  /// Goes forward in the history of this WebView.
  Future<void> goForward() {
    return api.goForwardFromInstance(this);
  }

  /// Reloads the current URL.
  Future<void> reload() {
    return api.reloadFromInstance(this);
  }

  /// Clears the resource cache.
  ///
  /// Note that the cache is per-application, so this will clear the cache for
  /// all WebViews used.
  Future<void> clearCache(bool includeDiskFiles) {
    return api.clearCacheFromInstance(this, includeDiskFiles);
  }

  // TODO(bparrishMines): Update documentation once addJavascriptInterface is added.
  /// Asynchronously evaluates JavaScript in the context of the currently displayed page.
  ///
  /// If non-null, the returned value will be any result returned from that
  /// execution.
  ///
  /// Compatibility note. Applications targeting Android versions N or later,
  /// JavaScript state from an empty WebView is no longer persisted across
  /// navigations like [loadUrl]. For example, global variables and functions
  /// defined before calling [loadUrl]) will not exist in the loaded page.
  Future<String?> evaluateJavascript(String javascriptString) {
    return api.evaluateJavascriptFromInstance(
      this,
      javascriptString,
    );
  }

  // TODO(bparrishMines): Update documentation when WebViewClient.onReceivedTitle is added.
  /// Gets the title for the current page.
  ///
  /// Returns null if no page has been loaded.
  Future<String?> getTitle() {
    return api.getTitleFromInstance(this);
  }

  // TODO(bparrishMines): Update documentation when onScrollChanged is added.
  /// Set the scrolled position of your view.
  Future<void> scrollTo(int x, int y) {
    return api.scrollToFromInstance(this, x, y);
  }

  // TODO(bparrishMines): Update documentation when onScrollChanged is added.
  /// Move the scrolled position of your view.
  Future<void> scrollBy(int x, int y) {
    return api.scrollByFromInstance(this, x, y);
  }

  /// Return the scrolled left position of this view.
  ///
  /// This is the left edge of the displayed part of your view. You do not
  /// need to draw any pixels farther left, since those are outside of the frame
  /// of your view on screen.
  Future<int> getScrollX() {
    return api.getScrollXFromInstance(this);
  }

  /// Return the scrolled top position of this view.
  ///
  /// This is the top edge of the displayed part of your view. You do not need
  /// to draw any pixels above it, since those are outside of the frame of your
  /// view on screen.
  Future<int> getScrollY() {
    return api.getScrollYFromInstance(this);
  }

  /// Returns the X and Y scroll position of this view.
  Future<Offset> getScrollPosition() {
    return api.getScrollPositionFromInstance(this);
  }

  /// Sets the [WebViewClient] that will receive various notifications and requests.
  ///
  /// This will replace the current handler.
  Future<void> setWebViewClient(WebViewClient webViewClient) {
    _currentWebViewClient = webViewClient;
    WebViewClient.api.createFromInstance(webViewClient);
    return api.setWebViewClientFromInstance(this, webViewClient);
  }

  /// Injects the supplied [JavascriptChannel] into this WebView.
  ///
  /// The object is injected into all frames of the web page, including all the
  /// iframes, using the supplied name. This allows the object's methods to
  /// be accessed from JavaScript.
  ///
  /// Note that injected objects will not appear in JavaScript until the page is
  /// next (re)loaded. JavaScript should be enabled before injecting the object.
  /// For example:
  ///
  /// ```dart
  /// webview.settings.setJavaScriptEnabled(true);
  /// webView.addJavascriptChannel(JavScriptChannel("injectedObject"));
  /// webView.loadUrl("about:blank", <String, String>{});
  /// webView.loadUrl("javascript:injectedObject.postMessage("Hello, World!")", <String, String>{});
  /// ```
  ///
  /// **Important**
  /// * Because the object is exposed to all the frames, any frame could obtain
  /// the object name and call methods on it. There is no way to tell the
  /// calling frame's origin from the app side, so the app must not assume that
  /// the caller is trustworthy unless the app can guarantee that no third party
  /// content is ever loaded into the WebView even inside an iframe.
  Future<void> addJavaScriptChannel(JavaScriptChannel javaScriptChannel) {
    JavaScriptChannel.api.createFromInstance(javaScriptChannel);
    return api.addJavaScriptChannelFromInstance(this, javaScriptChannel);
  }

  /// Removes a previously injected [JavaScriptChannel] from this WebView.
  ///
  /// Note that the removal will not be reflected in JavaScript until the page
  /// is next (re)loaded. See [addJavaScriptChannel].
  Future<void> removeJavaScriptChannel(JavaScriptChannel javaScriptChannel) {
    JavaScriptChannel.api.createFromInstance(javaScriptChannel);
    return api.removeJavaScriptChannelFromInstance(this, javaScriptChannel);
  }

  /// 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.
  Future<void> setDownloadListener(DownloadListener? listener) async {
    await Future.wait(<Future<void>>[
      if (listener != null) DownloadListener.api.createFromInstance(listener),
      api.setDownloadListenerFromInstance(this, listener)
    ]);
  }

  /// 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.
  Future<void> setWebChromeClient(WebChromeClient? client) async {
    // WebView requires a WebViewClient because of a bug fix that makes
    // calls to WebViewClient.requestLoading/WebViewClient.urlLoading when a new
    // window is opened. This is to make sure a url opened by `Window.open` has
    // a secure url.
    assert(
      _currentWebViewClient != null,
      "Can't set a WebChromeClient without setting a WebViewClient first.",
    );
    await Future.wait(<Future<void>>[
      if (client != null)
        WebChromeClient.api.createFromInstance(client, _currentWebViewClient!),
      api.setWebChromeClientFromInstance(this, client),
    ]);
  }

  /// Sets the background color of this WebView.
  Future<void> setBackgroundColor(Color color) {
    return api.setBackgroundColorFromInstance(this, color.value);
  }

  /// Releases all resources used by the [WebView].
  ///
  /// Any methods called after [release] will throw an exception.
  Future<void> release() {
    _currentWebViewClient = null;
    WebSettings.api.disposeFromInstance(settings);
    return api.disposeFromInstance(this);
  }

  @override
  WebView copy() {
    return WebView.detached(useHybridComposition: useHybridComposition);
  }
}

/// Manages cookies globally for all webviews.
class CookieManager {
  CookieManager._();

  static CookieManager? _instance;

  /// Gets the globally set CookieManager instance.
  static CookieManager get instance => _instance ??= CookieManager._();

  /// Setter for the singleton value, for testing purposes only.
  @visibleForTesting
  static set instance(CookieManager value) => _instance = value;

  /// Pigeon Host Api implementation for [CookieManager].
  @visibleForTesting
  static CookieManagerHostApi api = CookieManagerHostApi();

  /// Sets a single cookie (key-value pair) for the given URL. Any existing
  /// cookie with the same host, path and name will be replaced with the new
  /// cookie. The cookie being set will be ignored if it is expired. To set
  /// multiple cookies, your application should invoke this method multiple
  /// times.
  ///
  /// The value parameter must follow the format of the Set-Cookie HTTP
  /// response header defined by RFC6265bis. This is a key-value pair of the
  /// form "key=value", optionally followed by a list of cookie attributes
  /// delimited with semicolons (ex. "key=value; Max-Age=123"). Please consult
  /// the RFC specification for a list of valid attributes.
  ///
  /// Note: if specifying a value containing the "Secure" attribute, url must
  /// use the "https://" scheme.
  ///
  /// Params:
  /// url – the URL for which the cookie is to be set
  /// value – the cookie as a string, using the format of the 'Set-Cookie' HTTP response header
  Future<void> setCookie(String url, String value) => api.setCookie(url, value);

  /// Removes all cookies.
  ///
  /// The returned future resolves to true if any cookies were removed.
  Future<bool> clearCookies() => api.clearCookies();
}

/// Manages settings state for a [WebView].
///
/// When a WebView is first created, it obtains a set of default settings. These
/// default settings will be returned from any getter call. A WebSettings object
/// obtained from [WebView.settings] is tied to the life of the WebView. If a
/// WebView has been destroyed, any method call on [WebSettings] will throw an
/// Exception.
class WebSettings extends JavaObject {
  /// Constructs a [WebSettings].
  ///
  /// This constructor is only used for testing. An instance should be obtained
  /// with [WebView.settings].
  @visibleForTesting
  WebSettings(WebView webView) : super.detached() {
    api.createFromInstance(this, webView);
  }

  /// Constructs a [WebSettings] without creating the associated Java object.
  ///
  /// This should only be used by subclasses created by this library or to
  /// create copies.
  WebSettings.detached() : super.detached();

  /// Pigeon Host Api implementation for [WebSettings].
  @visibleForTesting
  static WebSettingsHostApiImpl api = WebSettingsHostApiImpl();

  /// Sets whether the DOM storage API is enabled.
  ///
  /// The default value is false.
  Future<void> setDomStorageEnabled(bool flag) {
    return api.setDomStorageEnabledFromInstance(this, flag);
  }

  /// Tells JavaScript to open windows automatically.
  ///
  /// This applies to the JavaScript function `window.open()`. The default is
  /// false.
  Future<void> setJavaScriptCanOpenWindowsAutomatically(bool flag) {
    return api.setJavaScriptCanOpenWindowsAutomaticallyFromInstance(
      this,
      flag,
    );
  }

  // TODO(bparrishMines): Update documentation when WebChromeClient.onCreateWindow is added.
  /// Sets whether the WebView should supports multiple windows.
  ///
  /// The default is false.
  Future<void> setSupportMultipleWindows(bool support) {
    return api.setSupportMultipleWindowsFromInstance(this, support);
  }

  /// Tells the WebView to enable JavaScript execution.
  ///
  /// The default is false.
  Future<void> setJavaScriptEnabled(bool flag) {
    return api.setJavaScriptEnabledFromInstance(this, flag);
  }

  /// Sets the WebView's user-agent string.
  ///
  /// If the string is empty, the system default value will be used. Note that
  /// starting from KITKAT Android version, changing the user-agent while
  /// loading a web page causes WebView to initiate loading once again.
  Future<void> setUserAgentString(String? userAgentString) {
    return api.setUserAgentStringFromInstance(this, userAgentString);
  }

  /// Sets whether the WebView requires a user gesture to play media.
  ///
  /// The default is true.
  Future<void> setMediaPlaybackRequiresUserGesture(bool require) {
    return api.setMediaPlaybackRequiresUserGestureFromInstance(this, require);
  }

  // TODO(bparrishMines): Update documentation when WebView.zoomIn and WebView.zoomOut are added.
  /// Sets whether the WebView should support zooming using its on-screen zoom controls and gestures.
  ///
  /// The particular zoom mechanisms that should be used can be set with
  /// [setBuiltInZoomControls].
  ///
  /// The default is true.
  Future<void> setSupportZoom(bool support) {
    return api.setSupportZoomFromInstance(this, support);
  }

  /// Sets whether the WebView loads pages in overview mode, that is, zooms out the content to fit on screen by width.
  ///
  /// This setting is taken into account when the content width is greater than
  /// the width of the WebView control, for example, when [setUseWideViewPort]
  /// is enabled.
  ///
  /// The default is false.
  Future<void> setLoadWithOverviewMode(bool overview) {
    return api.setLoadWithOverviewModeFromInstance(this, overview);
  }

  /// Sets whether the WebView should enable support for the "viewport" HTML meta tag or should use a wide viewport.
  ///
  /// When the value of the setting is false, the layout width is always set to
  /// the width of the WebView control in device-independent (CSS) pixels. When
  /// the value is true and the page contains the viewport meta tag, the value
  /// of the width specified in the tag is used. If the page does not contain
  /// the tag or does not provide a width, then a wide viewport will be used.
  Future<void> setUseWideViewPort(bool use) {
    return api.setUseWideViewPortFromInstance(this, use);
  }

  // TODO(bparrishMines): Update documentation when ZoomButtonsController is added.
  /// Sets whether the WebView should display on-screen zoom controls when using the built-in zoom mechanisms.
  ///
  /// See [setBuiltInZoomControls]. The default is true. However, on-screen zoom
  /// controls are deprecated in Android so it's recommended to set this to
  /// false.
  Future<void> setDisplayZoomControls(bool enabled) {
    return api.setDisplayZoomControlsFromInstance(this, enabled);
  }

  // TODO(bparrishMines): Update documentation when ZoomButtonsController is added.
  /// Sets whether the WebView should use its built-in zoom mechanisms.
  ///
  /// The built-in zoom mechanisms comprise on-screen zoom controls, which are
  /// displayed over the WebView's content, and the use of a pinch gesture to
  /// control zooming. Whether or not these on-screen controls are displayed can
  /// be set with [setDisplayZoomControls]. The default is false.
  ///
  /// The built-in mechanisms are the only currently supported zoom mechanisms,
  /// so it is recommended that this setting is always enabled. However,
  /// on-screen zoom controls are deprecated in Android so it's recommended to
  /// disable [setDisplayZoomControls].
  Future<void> setBuiltInZoomControls(bool enabled) {
    return api.setBuiltInZoomControlsFromInstance(this, enabled);
  }

  /// Enables or disables file access within WebView.
  ///
  /// This enables or disables file system access only. Assets and resources are
  /// still accessible using file:///android_asset and file:///android_res. The
  /// default value is true for apps targeting Build.VERSION_CODES.Q and below,
  /// and false when targeting Build.VERSION_CODES.R and above.
  Future<void> setAllowFileAccess(bool enabled) {
    return api.setAllowFileAccessFromInstance(this, enabled);
  }

  @override
  WebSettings copy() {
    return WebSettings.detached();
  }
}

/// Exposes a channel to receive calls from javaScript.
///
/// See [WebView.addJavaScriptChannel].
class JavaScriptChannel extends JavaObject {
  /// Constructs a [JavaScriptChannel].
  JavaScriptChannel(
    this.channelName, {
    void Function(String message)? postMessage,
  }) : super.detached() {
    AndroidWebViewFlutterApis.instance.ensureSetUp();
  }

  /// Constructs a [JavaScriptChannel] without creating the associated Java
  /// object.
  ///
  /// This should only be used by subclasses created by this library or to
  /// create copies.
  JavaScriptChannel.detached(
    this.channelName, {
    void Function(String message)? postMessage,
  }) : super.detached();

  /// Pigeon Host Api implementation for [JavaScriptChannel].
  @visibleForTesting
  static JavaScriptChannelHostApiImpl api = JavaScriptChannelHostApiImpl();

  /// Used to identify this object to receive messages from javaScript.
  final String channelName;

  /// Callback method when javaScript calls `postMessage` on the object instance passed.
  void postMessage(String message) {}

  @override
  JavaScriptChannel copy() {
    return JavaScriptChannel.detached(channelName, postMessage: postMessage);
  }
}

/// Receive various notifications and requests for [WebView].
class WebViewClient extends JavaObject {
  /// Constructs a [WebViewClient].
  WebViewClient({
    this.shouldOverrideUrlLoading = true,
    void Function(WebView webView, String url)? onPageStarted,
    void Function(WebView webView, String url)? onPageFinished,
    void Function(
      WebView webView,
      WebResourceRequest request,
      WebResourceError error,
    )?
        onReceivedRequestError,
    void Function(
      WebView webView,
      int errorCode,
      String description,
      String failingUrl,
    )?
        onReceivedError,
    void Function(WebView webView, WebResourceRequest request)? requestLoading,
    void Function(WebView webView, String url)? urlLoading,
  }) : super.detached() {
    AndroidWebViewFlutterApis.instance.ensureSetUp();
  }

  /// Constructs a [WebViewClient] without creating the associated Java object.
  ///
  /// This should only be used by subclasses created by this library or to
  /// create copies.
  WebViewClient.detached({
    this.shouldOverrideUrlLoading = true,
    void Function(WebView webView, String url)? onPageStarted,
    void Function(WebView webView, String url)? onPageFinished,
    void Function(
      WebView webView,
      WebResourceRequest request,
      WebResourceError error,
    )?
        onReceivedRequestError,
    void Function(
      WebView webView,
      int errorCode,
      String description,
      String failingUrl,
    )?
        onReceivedError,
    void Function(WebView webView, WebResourceRequest request)? requestLoading,
    void Function(WebView webView, String url)? urlLoading,
  }) : super.detached();

  /// User authentication failed on server.
  ///
  /// See https://developer.android.com/reference/android/webkit/WebViewClient#ERROR_AUTHENTICATION
  static const int errorAuthentication = -4;

  /// Malformed URL.
  ///
  /// See https://developer.android.com/reference/android/webkit/WebViewClient#ERROR_BAD_URL
  static const int errorBadUrl = -12;

  /// Failed to connect to the server.
  ///
  /// See https://developer.android.com/reference/android/webkit/WebViewClient#ERROR_CONNECT
  static const int errorConnect = -6;

  /// Failed to perform SSL handshake.
  ///
  /// See https://developer.android.com/reference/android/webkit/WebViewClient#ERROR_FAILED_SSL_HANDSHAKE
  static const int errorFailedSslHandshake = -11;

  /// Generic file error.
  ///
  /// See https://developer.android.com/reference/android/webkit/WebViewClient#ERROR_FILE
  static const int errorFile = -13;

  /// File not found.
  ///
  /// See https://developer.android.com/reference/android/webkit/WebViewClient#ERROR_FILE_NOT_FOUND
  static const int errorFileNotFound = -14;

  /// Server or proxy hostname lookup failed.
  ///
  /// See https://developer.android.com/reference/android/webkit/WebViewClient#ERROR_HOST_LOOKUP
  static const int errorHostLookup = -2;

  /// Failed to read or write to the server.
  ///
  /// See https://developer.android.com/reference/android/webkit/WebViewClient#ERROR_IO
  static const int errorIO = -7;

  /// User authentication failed on proxy.
  ///
  /// See https://developer.android.com/reference/android/webkit/WebViewClient#ERROR_PROXY_AUTHENTICATION
  static const int errorProxyAuthentication = -5;

  /// Too many redirects.
  ///
  /// See https://developer.android.com/reference/android/webkit/WebViewClient#ERROR_REDIRECT_LOOP
  static const int errorRedirectLoop = -9;

  /// Connection timed out.
  ///
  /// See https://developer.android.com/reference/android/webkit/WebViewClient#ERROR_TIMEOUT
  static const int errorTimeout = -8;

  /// Too many requests during this load.
  ///
  /// See https://developer.android.com/reference/android/webkit/WebViewClient#ERROR_TOO_MANY_REQUESTS
  static const int errorTooManyRequests = -15;

  /// Generic error.
  ///
  /// See https://developer.android.com/reference/android/webkit/WebViewClient#ERROR_UNKNOWN
  static const int errorUnknown = -1;

  /// Resource load was canceled by Safe Browsing.
  ///
  /// See https://developer.android.com/reference/android/webkit/WebViewClient#ERROR_UNSAFE_RESOURCE
  static const int errorUnsafeResource = -16;

  /// Unsupported authentication scheme (not basic or digest).
  ///
  /// See https://developer.android.com/reference/android/webkit/WebViewClient#ERROR_UNSUPPORTED_AUTH_SCHEME
  static const int errorUnsupportedAuthScheme = -3;

  /// Unsupported URI scheme.
  ///
  /// See https://developer.android.com/reference/android/webkit/WebViewClient#ERROR_UNSUPPORTED_SCHEME
  static const int errorUnsupportedScheme = -10;

  /// Pigeon Host Api implementation for [WebViewClient].
  @visibleForTesting
  static WebViewClientHostApiImpl api = WebViewClientHostApiImpl();

  /// Whether loading a url should be overridden.
  ///
  /// In Java, `shouldOverrideUrlLoading()` and `shouldOverrideRequestLoading()`
  /// callbacks must synchronously return a boolean. This sets the default
  /// return value.
  ///
  /// Setting [shouldOverrideUrlLoading] to true causes the current [WebView] to
  /// abort loading the URL, while returning false causes the [WebView] to
  /// continue loading the URL as usual. [requestLoading] or [urlLoading] will
  /// still be called either way.
  ///
  /// Defaults to true.
  final bool shouldOverrideUrlLoading;

  /// Notify the host application that a page has started loading.
  ///
  /// This method is called once for each main frame load so a page with iframes
  /// or framesets will call onPageStarted one time for the main frame. This
  /// also means that [onPageStarted] will not be called when the contents of an
  /// embedded frame changes, i.e. clicking a link whose target is an iframe, it
  /// will also not be called for fragment navigations (navigations to
  /// #fragment_id).
  void onPageStarted(WebView webView, String url) {}

  // TODO(bparrishMines): Update documentation when WebView.postVisualStateCallback is added.
  /// Notify the host application that a page has finished loading.
  ///
  /// This method is called only for main frame. Receiving an [onPageFinished]
  /// callback does not guarantee that the next frame drawn by WebView will
  /// reflect the state of the DOM at this point.
  void onPageFinished(WebView webView, String url) {}

  /// Report web resource loading error to the host application.
  ///
  /// These errors usually indicate inability to connect to the server. Note
  /// that unlike the deprecated version of the callback, the new version will
  /// be called for any resource (iframe, image, etc.), not just for the main
  /// page. Thus, it is recommended to perform minimum required work in this
  /// callback.
  void onReceivedRequestError(
    WebView webView,
    WebResourceRequest request,
    WebResourceError error,
  ) {}

  /// Report an error to the host application.
  ///
  /// These errors are unrecoverable (i.e. the main resource is unavailable).
  /// The errorCode parameter corresponds to one of the error* constants.
  @Deprecated('Only called on Android version < 23.')
  void onReceivedError(
    WebView webView,
    int errorCode,
    String description,
    String failingUrl,
  ) {}

  // TODO(bparrishMines): Update documentation once synchronous url handling is supported.
  /// When a URL is about to be loaded in the current [WebView].
  ///
  /// If a [WebViewClient] is not provided, by default [WebView] will ask
  /// Activity Manager to choose the proper handler for the URL. If a
  /// [WebViewClient] is provided, setting [shouldOverrideUrlLoading] to true
  /// causes the current [WebView] to abort loading the URL, while returning
  /// false causes the [WebView] to continue loading the URL as usual.
  void requestLoading(WebView webView, WebResourceRequest request) {}

  // TODO(bparrishMines): Update documentation once synchronous url handling is supported.
  /// When a URL is about to be loaded in the current [WebView].
  ///
  /// If a [WebViewClient] is not provided, by default [WebView] will ask
  /// Activity Manager to choose the proper handler for the URL. If a
  /// [WebViewClient] is provided, setting [shouldOverrideUrlLoading] to true
  /// causes the current [WebView] to abort loading the URL, while returning
  /// false causes the [WebView] to continue loading the URL as usual.
  void urlLoading(WebView webView, String url) {}

  @override
  WebViewClient copy() {
    return WebViewClient.detached(
      shouldOverrideUrlLoading: shouldOverrideUrlLoading,
      onPageStarted: onPageStarted,
      onPageFinished: onPageFinished,
      onReceivedRequestError: onReceivedRequestError,
      onReceivedError: onReceivedError,
      requestLoading: requestLoading,
      urlLoading: urlLoading,
    );
  }
}

/// The interface to be used when content can not be handled by the rendering
/// engine for [WebView], and should be downloaded instead.
class DownloadListener extends JavaObject {
  /// Constructs a [DownloadListener].
  DownloadListener({
    void Function(
      String url,
      String userAgent,
      String contentDisposition,
      String mimetype,
      int contentLength,
    )?
        onDownloadStart,
  }) : super.detached() {
    AndroidWebViewFlutterApis.instance.ensureSetUp();
  }

  /// Constructs a [DownloadListener] without creating the associated Java
  /// object.
  ///
  /// This should only be used by subclasses created by this library or to
  /// create copies.
  DownloadListener.detached({
    void Function(
      String url,
      String userAgent,
      String contentDisposition,
      String mimetype,
      int contentLength,
    )?
        onDownloadStart,
  }) : super.detached();

  /// Pigeon Host Api implementation for [DownloadListener].
  @visibleForTesting
  static DownloadListenerHostApiImpl api = DownloadListenerHostApiImpl();

  /// Notify the host application that a file should be downloaded.
  void onDownloadStart(
    String url,
    String userAgent,
    String contentDisposition,
    String mimetype,
    int contentLength,
  ) {}

  @override
  DownloadListener copy() {
    return DownloadListener(onDownloadStart: onDownloadStart);
  }
}

/// Handles JavaScript dialogs, favicons, titles, and the progress for [WebView].
class WebChromeClient extends JavaObject {
  /// Constructs a [WebChromeClient].
  WebChromeClient({
    void Function(WebView webView, int progress)? onProgressChanged,
  }) : super.detached() {
    AndroidWebViewFlutterApis.instance.ensureSetUp();
  }

  /// Constructs a [WebChromeClient] without creating the associated Java
  /// object.
  ///
  /// This should only be used by subclasses created by this library or to
  /// create copies.
  WebChromeClient.detached({
    void Function(WebView webView, int progress)? onProgressChanged,
  }) : super.detached();

  /// Pigeon Host Api implementation for [WebChromeClient].
  @visibleForTesting
  static WebChromeClientHostApiImpl api = WebChromeClientHostApiImpl();

  /// Notify the host application that a file should be downloaded.
  void onProgressChanged(WebView webView, int progress) {}

  @override
  WebChromeClient copy() {
    return WebChromeClient.detached(onProgressChanged: onProgressChanged);
  }
}

/// Encompasses parameters to the [WebViewClient.requestLoading] method.
class WebResourceRequest {
  /// Constructs a [WebResourceRequest].
  WebResourceRequest({
    required this.url,
    required this.isForMainFrame,
    required this.isRedirect,
    required this.hasGesture,
    required this.method,
    required this.requestHeaders,
  });

  /// The URL for which the resource request was made.
  final String url;

  /// Whether the request was made in order to fetch the main frame's document.
  final bool isForMainFrame;

  /// Whether the request was a result of a server-side redirect.
  ///
  /// Only supported on Android version >= 24.
  final bool? isRedirect;

  /// Whether a gesture (such as a click) was associated with the request.
  final bool hasGesture;

  /// The method associated with the request, for example "GET".
  final String method;

  /// The headers associated with the request.
  final Map<String, String> requestHeaders;
}

/// Encapsulates information about errors occurred during loading of web resources.
///
/// See [WebViewClient.onReceivedRequestError].
class WebResourceError {
  /// Constructs a [WebResourceError].
  WebResourceError({
    required this.errorCode,
    required this.description,
  });

  /// The integer code of the error (e.g. [WebViewClient.errorAuthentication].
  final int errorCode;

  /// Describes the error.
  final String description;
}

/// Manages Flutter assets that are part of Android's app bundle.
class FlutterAssetManager {
  /// Constructs the [FlutterAssetManager].
  const FlutterAssetManager();

  /// Pigeon Host Api implementation for [FlutterAssetManager].
  @visibleForTesting
  static FlutterAssetManagerHostApi api = FlutterAssetManagerHostApi();

  /// Lists all assets at the given path.
  ///
  /// The assets are returned as a `List<String>`. The `List<String>` only
  /// contains files which are direct childs
  Future<List<String?>> list(String path) => api.list(path);

  /// Gets the relative file path to the Flutter asset with the given name.
  Future<String> getAssetFilePathByName(String name) =>
      api.getAssetFilePathByName(name);
}

/// Manages the JavaScript storage APIs provided by the [WebView].
///
/// Wraps [WebStorage](https://developer.android.com/reference/android/webkit/WebStorage).
class WebStorage extends JavaObject {
  /// Constructs a [WebStorage].
  ///
  /// This constructor is only used for testing. An instance should be obtained
  /// with [WebStorage.instance].
  @visibleForTesting
  WebStorage() : super.detached() {
    AndroidWebViewFlutterApis.instance.ensureSetUp();
    api.createFromInstance(this);
  }

  /// Constructs a [WebStorage] without creating the associated Java object.
  ///
  /// This should only be used by subclasses created by this library or to
  /// create copies.
  WebStorage.detached() : super.detached();

  /// Pigeon Host Api implementation for [WebStorage].
  @visibleForTesting
  static WebStorageHostApiImpl api = WebStorageHostApiImpl();

  /// The singleton instance of this class.
  static WebStorage instance = WebStorage();

  /// Clears all storage currently being used by the JavaScript storage APIs.
  Future<void> deleteAllData() {
    return api.deleteAllDataFromInstance(this);
  }

  @override
  WebStorage copy() {
    return WebStorage.detached();
  }
}
