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

// Autogenerated from Pigeon (v1.0.9), do not edit directly.
// See also: https://pub.dev/packages/pigeon
// ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import
// @dart = 2.12
import 'dart:async';
import 'dart:typed_data' show Uint8List, Int32List, Int64List, Float64List;
import 'package:flutter/foundation.dart' show WriteBuffer, ReadBuffer;
import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart';

import '../lib/src/android_webview.pigeon.dart';

class _TestWebViewHostApiCodec extends StandardMessageCodec {
  const _TestWebViewHostApiCodec();
}

abstract class TestWebViewHostApi {
  static const MessageCodec<Object?> codec = _TestWebViewHostApiCodec();

  void create(int instanceId, bool useHybridComposition);
  void dispose(int instanceId);
  void loadData(int instanceId, String data, String mimeType, String encoding);
  void loadDataWithBaseUrl(int instanceId, String baseUrl, String data,
      String mimeType, String encoding, String historyUrl);
  void loadUrl(int instanceId, String url, Map<String?, String?> headers);
  void postUrl(int instanceId, String url, Uint8List data);
  String getUrl(int instanceId);
  bool canGoBack(int instanceId);
  bool canGoForward(int instanceId);
  void goBack(int instanceId);
  void goForward(int instanceId);
  void reload(int instanceId);
  void clearCache(int instanceId, bool includeDiskFiles);
  Future<String> evaluateJavascript(int instanceId, String javascriptString);
  String getTitle(int instanceId);
  void scrollTo(int instanceId, int x, int y);
  void scrollBy(int instanceId, int x, int y);
  int getScrollX(int instanceId);
  int getScrollY(int instanceId);
  void setWebContentsDebuggingEnabled(bool enabled);
  void setWebViewClient(int instanceId, int webViewClientInstanceId);
  void addJavaScriptChannel(int instanceId, int javaScriptChannelInstanceId);
  void removeJavaScriptChannel(int instanceId, int javaScriptChannelInstanceId);
  void setDownloadListener(int instanceId, int listenerInstanceId);
  void setWebChromeClient(int instanceId, int clientInstanceId);
  void setBackgroundColor(int instanceId, int color);
  static void setup(TestWebViewHostApi? api,
      {BinaryMessenger? binaryMessenger}) {
    {
      final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
          'dev.flutter.pigeon.WebViewHostApi.create', codec,
          binaryMessenger: binaryMessenger);
      if (api == null) {
        channel.setMockMessageHandler(null);
      } else {
        channel.setMockMessageHandler((Object? message) async {
          assert(message != null,
              'Argument for dev.flutter.pigeon.WebViewHostApi.create was null.');
          final List<Object?> args = (message as List<Object?>?)!;
          final int? arg_instanceId = (args[0] as int?);
          assert(arg_instanceId != null,
              'Argument for dev.flutter.pigeon.WebViewHostApi.create was null, expected non-null int.');
          final bool? arg_useHybridComposition = (args[1] as bool?);
          assert(arg_useHybridComposition != null,
              'Argument for dev.flutter.pigeon.WebViewHostApi.create was null, expected non-null bool.');
          api.create(arg_instanceId!, arg_useHybridComposition!);
          return <Object?, Object?>{};
        });
      }
    }
    {
      final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
          'dev.flutter.pigeon.WebViewHostApi.dispose', codec,
          binaryMessenger: binaryMessenger);
      if (api == null) {
        channel.setMockMessageHandler(null);
      } else {
        channel.setMockMessageHandler((Object? message) async {
          assert(message != null,
              'Argument for dev.flutter.pigeon.WebViewHostApi.dispose was null.');
          final List<Object?> args = (message as List<Object?>?)!;
          final int? arg_instanceId = (args[0] as int?);
          assert(arg_instanceId != null,
              'Argument for dev.flutter.pigeon.WebViewHostApi.dispose was null, expected non-null int.');
          api.dispose(arg_instanceId!);
          return <Object?, Object?>{};
        });
      }
    }
    {
      final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
          'dev.flutter.pigeon.WebViewHostApi.loadData', codec,
          binaryMessenger: binaryMessenger);
      if (api == null) {
        channel.setMockMessageHandler(null);
      } else {
        channel.setMockMessageHandler((Object? message) async {
          assert(message != null,
              'Argument for dev.flutter.pigeon.WebViewHostApi.loadData was null.');
          final List<Object?> args = (message as List<Object?>?)!;
          final int? arg_instanceId = (args[0] as int?);
          assert(arg_instanceId != null,
              'Argument for dev.flutter.pigeon.WebViewHostApi.loadData was null, expected non-null int.');
          final String? arg_data = (args[1] as String?);
          assert(arg_data != null,
              'Argument for dev.flutter.pigeon.WebViewHostApi.loadData was null, expected non-null String.');
          final String? arg_mimeType = (args[2] as String?);
          assert(arg_mimeType != null,
              'Argument for dev.flutter.pigeon.WebViewHostApi.loadData was null, expected non-null String.');
          final String? arg_encoding = (args[3] as String?);
          assert(arg_encoding != null,
              'Argument for dev.flutter.pigeon.WebViewHostApi.loadData was null, expected non-null String.');
          api.loadData(
              arg_instanceId!, arg_data!, arg_mimeType!, arg_encoding!);
          return <Object?, Object?>{};
        });
      }
    }
    {
      final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
          'dev.flutter.pigeon.WebViewHostApi.loadDataWithBaseUrl', codec,
          binaryMessenger: binaryMessenger);
      if (api == null) {
        channel.setMockMessageHandler(null);
      } else {
        channel.setMockMessageHandler((Object? message) async {
          assert(message != null,
              'Argument for dev.flutter.pigeon.WebViewHostApi.loadDataWithBaseUrl was null.');
          final List<Object?> args = (message as List<Object?>?)!;
          final int? arg_instanceId = (args[0] as int?);
          assert(arg_instanceId != null,
              'Argument for dev.flutter.pigeon.WebViewHostApi.loadDataWithBaseUrl was null, expected non-null int.');
          final String? arg_baseUrl = (args[1] as String?);
          assert(arg_baseUrl != null,
              'Argument for dev.flutter.pigeon.WebViewHostApi.loadDataWithBaseUrl was null, expected non-null String.');
          final String? arg_data = (args[2] as String?);
          assert(arg_data != null,
              'Argument for dev.flutter.pigeon.WebViewHostApi.loadDataWithBaseUrl was null, expected non-null String.');
          final String? arg_mimeType = (args[3] as String?);
          assert(arg_mimeType != null,
              'Argument for dev.flutter.pigeon.WebViewHostApi.loadDataWithBaseUrl was null, expected non-null String.');
          final String? arg_encoding = (args[4] as String?);
          assert(arg_encoding != null,
              'Argument for dev.flutter.pigeon.WebViewHostApi.loadDataWithBaseUrl was null, expected non-null String.');
          final String? arg_historyUrl = (args[5] as String?);
          assert(arg_historyUrl != null,
              'Argument for dev.flutter.pigeon.WebViewHostApi.loadDataWithBaseUrl was null, expected non-null String.');
          api.loadDataWithBaseUrl(arg_instanceId!, arg_baseUrl!, arg_data!,
              arg_mimeType!, arg_encoding!, arg_historyUrl!);
          return <Object?, Object?>{};
        });
      }
    }
    {
      final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
          'dev.flutter.pigeon.WebViewHostApi.loadUrl', codec,
          binaryMessenger: binaryMessenger);
      if (api == null) {
        channel.setMockMessageHandler(null);
      } else {
        channel.setMockMessageHandler((Object? message) async {
          assert(message != null,
              'Argument for dev.flutter.pigeon.WebViewHostApi.loadUrl was null.');
          final List<Object?> args = (message as List<Object?>?)!;
          final int? arg_instanceId = (args[0] as int?);
          assert(arg_instanceId != null,
              'Argument for dev.flutter.pigeon.WebViewHostApi.loadUrl was null, expected non-null int.');
          final String? arg_url = (args[1] as String?);
          assert(arg_url != null,
              'Argument for dev.flutter.pigeon.WebViewHostApi.loadUrl was null, expected non-null String.');
          final Map<String?, String?>? arg_headers =
              (args[2] as Map<Object?, Object?>?)?.cast<String?, String?>();
          assert(arg_headers != null,
              'Argument for dev.flutter.pigeon.WebViewHostApi.loadUrl was null, expected non-null Map<String?, String?>.');
          api.loadUrl(arg_instanceId!, arg_url!, arg_headers!);
          return <Object?, Object?>{};
        });
      }
    }
    {
      final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
          'dev.flutter.pigeon.WebViewHostApi.postUrl', codec,
          binaryMessenger: binaryMessenger);
      if (api == null) {
        channel.setMockMessageHandler(null);
      } else {
        channel.setMockMessageHandler((Object? message) async {
          assert(message != null,
              'Argument for dev.flutter.pigeon.WebViewHostApi.postUrl was null.');
          final List<Object?> args = (message as List<Object?>?)!;
          final int? arg_instanceId = (args[0] as int?);
          assert(arg_instanceId != null,
              'Argument for dev.flutter.pigeon.WebViewHostApi.postUrl was null, expected non-null int.');
          final String? arg_url = (args[1] as String?);
          assert(arg_url != null,
              'Argument for dev.flutter.pigeon.WebViewHostApi.postUrl was null, expected non-null String.');
          final Uint8List? arg_data = (args[2] as Uint8List?);
          assert(arg_data != null,
              'Argument for dev.flutter.pigeon.WebViewHostApi.postUrl was null, expected non-null Uint8List.');
          api.postUrl(arg_instanceId!, arg_url!, arg_data!);
          return <Object?, Object?>{};
        });
      }
    }
    {
      final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
          'dev.flutter.pigeon.WebViewHostApi.getUrl', codec,
          binaryMessenger: binaryMessenger);
      if (api == null) {
        channel.setMockMessageHandler(null);
      } else {
        channel.setMockMessageHandler((Object? message) async {
          assert(message != null,
              'Argument for dev.flutter.pigeon.WebViewHostApi.getUrl was null.');
          final List<Object?> args = (message as List<Object?>?)!;
          final int? arg_instanceId = (args[0] as int?);
          assert(arg_instanceId != null,
              'Argument for dev.flutter.pigeon.WebViewHostApi.getUrl was null, expected non-null int.');
          final String output = api.getUrl(arg_instanceId!);
          return <Object?, Object?>{'result': output};
        });
      }
    }
    {
      final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
          'dev.flutter.pigeon.WebViewHostApi.canGoBack', codec,
          binaryMessenger: binaryMessenger);
      if (api == null) {
        channel.setMockMessageHandler(null);
      } else {
        channel.setMockMessageHandler((Object? message) async {
          assert(message != null,
              'Argument for dev.flutter.pigeon.WebViewHostApi.canGoBack was null.');
          final List<Object?> args = (message as List<Object?>?)!;
          final int? arg_instanceId = (args[0] as int?);
          assert(arg_instanceId != null,
              'Argument for dev.flutter.pigeon.WebViewHostApi.canGoBack was null, expected non-null int.');
          final bool output = api.canGoBack(arg_instanceId!);
          return <Object?, Object?>{'result': output};
        });
      }
    }
    {
      final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
          'dev.flutter.pigeon.WebViewHostApi.canGoForward', codec,
          binaryMessenger: binaryMessenger);
      if (api == null) {
        channel.setMockMessageHandler(null);
      } else {
        channel.setMockMessageHandler((Object? message) async {
          assert(message != null,
              'Argument for dev.flutter.pigeon.WebViewHostApi.canGoForward was null.');
          final List<Object?> args = (message as List<Object?>?)!;
          final int? arg_instanceId = (args[0] as int?);
          assert(arg_instanceId != null,
              'Argument for dev.flutter.pigeon.WebViewHostApi.canGoForward was null, expected non-null int.');
          final bool output = api.canGoForward(arg_instanceId!);
          return <Object?, Object?>{'result': output};
        });
      }
    }
    {
      final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
          'dev.flutter.pigeon.WebViewHostApi.goBack', codec,
          binaryMessenger: binaryMessenger);
      if (api == null) {
        channel.setMockMessageHandler(null);
      } else {
        channel.setMockMessageHandler((Object? message) async {
          assert(message != null,
              'Argument for dev.flutter.pigeon.WebViewHostApi.goBack was null.');
          final List<Object?> args = (message as List<Object?>?)!;
          final int? arg_instanceId = (args[0] as int?);
          assert(arg_instanceId != null,
              'Argument for dev.flutter.pigeon.WebViewHostApi.goBack was null, expected non-null int.');
          api.goBack(arg_instanceId!);
          return <Object?, Object?>{};
        });
      }
    }
    {
      final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
          'dev.flutter.pigeon.WebViewHostApi.goForward', codec,
          binaryMessenger: binaryMessenger);
      if (api == null) {
        channel.setMockMessageHandler(null);
      } else {
        channel.setMockMessageHandler((Object? message) async {
          assert(message != null,
              'Argument for dev.flutter.pigeon.WebViewHostApi.goForward was null.');
          final List<Object?> args = (message as List<Object?>?)!;
          final int? arg_instanceId = (args[0] as int?);
          assert(arg_instanceId != null,
              'Argument for dev.flutter.pigeon.WebViewHostApi.goForward was null, expected non-null int.');
          api.goForward(arg_instanceId!);
          return <Object?, Object?>{};
        });
      }
    }
    {
      final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
          'dev.flutter.pigeon.WebViewHostApi.reload', codec,
          binaryMessenger: binaryMessenger);
      if (api == null) {
        channel.setMockMessageHandler(null);
      } else {
        channel.setMockMessageHandler((Object? message) async {
          assert(message != null,
              'Argument for dev.flutter.pigeon.WebViewHostApi.reload was null.');
          final List<Object?> args = (message as List<Object?>?)!;
          final int? arg_instanceId = (args[0] as int?);
          assert(arg_instanceId != null,
              'Argument for dev.flutter.pigeon.WebViewHostApi.reload was null, expected non-null int.');
          api.reload(arg_instanceId!);
          return <Object?, Object?>{};
        });
      }
    }
    {
      final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
          'dev.flutter.pigeon.WebViewHostApi.clearCache', codec,
          binaryMessenger: binaryMessenger);
      if (api == null) {
        channel.setMockMessageHandler(null);
      } else {
        channel.setMockMessageHandler((Object? message) async {
          assert(message != null,
              'Argument for dev.flutter.pigeon.WebViewHostApi.clearCache was null.');
          final List<Object?> args = (message as List<Object?>?)!;
          final int? arg_instanceId = (args[0] as int?);
          assert(arg_instanceId != null,
              'Argument for dev.flutter.pigeon.WebViewHostApi.clearCache was null, expected non-null int.');
          final bool? arg_includeDiskFiles = (args[1] as bool?);
          assert(arg_includeDiskFiles != null,
              'Argument for dev.flutter.pigeon.WebViewHostApi.clearCache was null, expected non-null bool.');
          api.clearCache(arg_instanceId!, arg_includeDiskFiles!);
          return <Object?, Object?>{};
        });
      }
    }
    {
      final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
          'dev.flutter.pigeon.WebViewHostApi.evaluateJavascript', codec,
          binaryMessenger: binaryMessenger);
      if (api == null) {
        channel.setMockMessageHandler(null);
      } else {
        channel.setMockMessageHandler((Object? message) async {
          assert(message != null,
              'Argument for dev.flutter.pigeon.WebViewHostApi.evaluateJavascript was null.');
          final List<Object?> args = (message as List<Object?>?)!;
          final int? arg_instanceId = (args[0] as int?);
          assert(arg_instanceId != null,
              'Argument for dev.flutter.pigeon.WebViewHostApi.evaluateJavascript was null, expected non-null int.');
          final String? arg_javascriptString = (args[1] as String?);
          assert(arg_javascriptString != null,
              'Argument for dev.flutter.pigeon.WebViewHostApi.evaluateJavascript was null, expected non-null String.');
          final String output = await api.evaluateJavascript(
              arg_instanceId!, arg_javascriptString!);
          return <Object?, Object?>{'result': output};
        });
      }
    }
    {
      final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
          'dev.flutter.pigeon.WebViewHostApi.getTitle', codec,
          binaryMessenger: binaryMessenger);
      if (api == null) {
        channel.setMockMessageHandler(null);
      } else {
        channel.setMockMessageHandler((Object? message) async {
          assert(message != null,
              'Argument for dev.flutter.pigeon.WebViewHostApi.getTitle was null.');
          final List<Object?> args = (message as List<Object?>?)!;
          final int? arg_instanceId = (args[0] as int?);
          assert(arg_instanceId != null,
              'Argument for dev.flutter.pigeon.WebViewHostApi.getTitle was null, expected non-null int.');
          final String output = api.getTitle(arg_instanceId!);
          return <Object?, Object?>{'result': output};
        });
      }
    }
    {
      final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
          'dev.flutter.pigeon.WebViewHostApi.scrollTo', codec,
          binaryMessenger: binaryMessenger);
      if (api == null) {
        channel.setMockMessageHandler(null);
      } else {
        channel.setMockMessageHandler((Object? message) async {
          assert(message != null,
              'Argument for dev.flutter.pigeon.WebViewHostApi.scrollTo was null.');
          final List<Object?> args = (message as List<Object?>?)!;
          final int? arg_instanceId = (args[0] as int?);
          assert(arg_instanceId != null,
              'Argument for dev.flutter.pigeon.WebViewHostApi.scrollTo was null, expected non-null int.');
          final int? arg_x = (args[1] as int?);
          assert(arg_x != null,
              'Argument for dev.flutter.pigeon.WebViewHostApi.scrollTo was null, expected non-null int.');
          final int? arg_y = (args[2] as int?);
          assert(arg_y != null,
              'Argument for dev.flutter.pigeon.WebViewHostApi.scrollTo was null, expected non-null int.');
          api.scrollTo(arg_instanceId!, arg_x!, arg_y!);
          return <Object?, Object?>{};
        });
      }
    }
    {
      final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
          'dev.flutter.pigeon.WebViewHostApi.scrollBy', codec,
          binaryMessenger: binaryMessenger);
      if (api == null) {
        channel.setMockMessageHandler(null);
      } else {
        channel.setMockMessageHandler((Object? message) async {
          assert(message != null,
              'Argument for dev.flutter.pigeon.WebViewHostApi.scrollBy was null.');
          final List<Object?> args = (message as List<Object?>?)!;
          final int? arg_instanceId = (args[0] as int?);
          assert(arg_instanceId != null,
              'Argument for dev.flutter.pigeon.WebViewHostApi.scrollBy was null, expected non-null int.');
          final int? arg_x = (args[1] as int?);
          assert(arg_x != null,
              'Argument for dev.flutter.pigeon.WebViewHostApi.scrollBy was null, expected non-null int.');
          final int? arg_y = (args[2] as int?);
          assert(arg_y != null,
              'Argument for dev.flutter.pigeon.WebViewHostApi.scrollBy was null, expected non-null int.');
          api.scrollBy(arg_instanceId!, arg_x!, arg_y!);
          return <Object?, Object?>{};
        });
      }
    }
    {
      final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
          'dev.flutter.pigeon.WebViewHostApi.getScrollX', codec,
          binaryMessenger: binaryMessenger);
      if (api == null) {
        channel.setMockMessageHandler(null);
      } else {
        channel.setMockMessageHandler((Object? message) async {
          assert(message != null,
              'Argument for dev.flutter.pigeon.WebViewHostApi.getScrollX was null.');
          final List<Object?> args = (message as List<Object?>?)!;
          final int? arg_instanceId = (args[0] as int?);
          assert(arg_instanceId != null,
              'Argument for dev.flutter.pigeon.WebViewHostApi.getScrollX was null, expected non-null int.');
          final int output = api.getScrollX(arg_instanceId!);
          return <Object?, Object?>{'result': output};
        });
      }
    }
    {
      final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
          'dev.flutter.pigeon.WebViewHostApi.getScrollY', codec,
          binaryMessenger: binaryMessenger);
      if (api == null) {
        channel.setMockMessageHandler(null);
      } else {
        channel.setMockMessageHandler((Object? message) async {
          assert(message != null,
              'Argument for dev.flutter.pigeon.WebViewHostApi.getScrollY was null.');
          final List<Object?> args = (message as List<Object?>?)!;
          final int? arg_instanceId = (args[0] as int?);
          assert(arg_instanceId != null,
              'Argument for dev.flutter.pigeon.WebViewHostApi.getScrollY was null, expected non-null int.');
          final int output = api.getScrollY(arg_instanceId!);
          return <Object?, Object?>{'result': output};
        });
      }
    }
    {
      final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
          'dev.flutter.pigeon.WebViewHostApi.setWebContentsDebuggingEnabled',
          codec,
          binaryMessenger: binaryMessenger);
      if (api == null) {
        channel.setMockMessageHandler(null);
      } else {
        channel.setMockMessageHandler((Object? message) async {
          assert(message != null,
              'Argument for dev.flutter.pigeon.WebViewHostApi.setWebContentsDebuggingEnabled was null.');
          final List<Object?> args = (message as List<Object?>?)!;
          final bool? arg_enabled = (args[0] as bool?);
          assert(arg_enabled != null,
              'Argument for dev.flutter.pigeon.WebViewHostApi.setWebContentsDebuggingEnabled was null, expected non-null bool.');
          api.setWebContentsDebuggingEnabled(arg_enabled!);
          return <Object?, Object?>{};
        });
      }
    }
    {
      final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
          'dev.flutter.pigeon.WebViewHostApi.setWebViewClient', codec,
          binaryMessenger: binaryMessenger);
      if (api == null) {
        channel.setMockMessageHandler(null);
      } else {
        channel.setMockMessageHandler((Object? message) async {
          assert(message != null,
              'Argument for dev.flutter.pigeon.WebViewHostApi.setWebViewClient was null.');
          final List<Object?> args = (message as List<Object?>?)!;
          final int? arg_instanceId = (args[0] as int?);
          assert(arg_instanceId != null,
              'Argument for dev.flutter.pigeon.WebViewHostApi.setWebViewClient was null, expected non-null int.');
          final int? arg_webViewClientInstanceId = (args[1] as int?);
          assert(arg_webViewClientInstanceId != null,
              'Argument for dev.flutter.pigeon.WebViewHostApi.setWebViewClient was null, expected non-null int.');
          api.setWebViewClient(arg_instanceId!, arg_webViewClientInstanceId!);
          return <Object?, Object?>{};
        });
      }
    }
    {
      final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
          'dev.flutter.pigeon.WebViewHostApi.addJavaScriptChannel', codec,
          binaryMessenger: binaryMessenger);
      if (api == null) {
        channel.setMockMessageHandler(null);
      } else {
        channel.setMockMessageHandler((Object? message) async {
          assert(message != null,
              'Argument for dev.flutter.pigeon.WebViewHostApi.addJavaScriptChannel was null.');
          final List<Object?> args = (message as List<Object?>?)!;
          final int? arg_instanceId = (args[0] as int?);
          assert(arg_instanceId != null,
              'Argument for dev.flutter.pigeon.WebViewHostApi.addJavaScriptChannel was null, expected non-null int.');
          final int? arg_javaScriptChannelInstanceId = (args[1] as int?);
          assert(arg_javaScriptChannelInstanceId != null,
              'Argument for dev.flutter.pigeon.WebViewHostApi.addJavaScriptChannel was null, expected non-null int.');
          api.addJavaScriptChannel(
              arg_instanceId!, arg_javaScriptChannelInstanceId!);
          return <Object?, Object?>{};
        });
      }
    }
    {
      final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
          'dev.flutter.pigeon.WebViewHostApi.removeJavaScriptChannel', codec,
          binaryMessenger: binaryMessenger);
      if (api == null) {
        channel.setMockMessageHandler(null);
      } else {
        channel.setMockMessageHandler((Object? message) async {
          assert(message != null,
              'Argument for dev.flutter.pigeon.WebViewHostApi.removeJavaScriptChannel was null.');
          final List<Object?> args = (message as List<Object?>?)!;
          final int? arg_instanceId = (args[0] as int?);
          assert(arg_instanceId != null,
              'Argument for dev.flutter.pigeon.WebViewHostApi.removeJavaScriptChannel was null, expected non-null int.');
          final int? arg_javaScriptChannelInstanceId = (args[1] as int?);
          assert(arg_javaScriptChannelInstanceId != null,
              'Argument for dev.flutter.pigeon.WebViewHostApi.removeJavaScriptChannel was null, expected non-null int.');
          api.removeJavaScriptChannel(
              arg_instanceId!, arg_javaScriptChannelInstanceId!);
          return <Object?, Object?>{};
        });
      }
    }
    {
      final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
          'dev.flutter.pigeon.WebViewHostApi.setDownloadListener', codec,
          binaryMessenger: binaryMessenger);
      if (api == null) {
        channel.setMockMessageHandler(null);
      } else {
        channel.setMockMessageHandler((Object? message) async {
          assert(message != null,
              'Argument for dev.flutter.pigeon.WebViewHostApi.setDownloadListener was null.');
          final List<Object?> args = (message as List<Object?>?)!;
          final int? arg_instanceId = (args[0] as int?);
          assert(arg_instanceId != null,
              'Argument for dev.flutter.pigeon.WebViewHostApi.setDownloadListener was null, expected non-null int.');
          final int? arg_listenerInstanceId = (args[1] as int?);
          assert(arg_listenerInstanceId != null,
              'Argument for dev.flutter.pigeon.WebViewHostApi.setDownloadListener was null, expected non-null int.');
          api.setDownloadListener(arg_instanceId!, arg_listenerInstanceId!);
          return <Object?, Object?>{};
        });
      }
    }
    {
      final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
          'dev.flutter.pigeon.WebViewHostApi.setWebChromeClient', codec,
          binaryMessenger: binaryMessenger);
      if (api == null) {
        channel.setMockMessageHandler(null);
      } else {
        channel.setMockMessageHandler((Object? message) async {
          assert(message != null,
              'Argument for dev.flutter.pigeon.WebViewHostApi.setWebChromeClient was null.');
          final List<Object?> args = (message as List<Object?>?)!;
          final int? arg_instanceId = (args[0] as int?);
          assert(arg_instanceId != null,
              'Argument for dev.flutter.pigeon.WebViewHostApi.setWebChromeClient was null, expected non-null int.');
          final int? arg_clientInstanceId = (args[1] as int?);
          assert(arg_clientInstanceId != null,
              'Argument for dev.flutter.pigeon.WebViewHostApi.setWebChromeClient was null, expected non-null int.');
          api.setWebChromeClient(arg_instanceId!, arg_clientInstanceId!);
          return <Object?, Object?>{};
        });
      }
    }
    {
      final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
          'dev.flutter.pigeon.WebViewHostApi.setBackgroundColor', codec,
          binaryMessenger: binaryMessenger);
      if (api == null) {
        channel.setMockMessageHandler(null);
      } else {
        channel.setMockMessageHandler((Object? message) async {
          assert(message != null,
              'Argument for dev.flutter.pigeon.WebViewHostApi.setBackgroundColor was null.');
          final List<Object?> args = (message as List<Object?>?)!;
          final int? arg_instanceId = (args[0] as int?);
          assert(arg_instanceId != null,
              'Argument for dev.flutter.pigeon.WebViewHostApi.setBackgroundColor was null, expected non-null int.');
          final int? arg_color = (args[1] as int?);
          assert(arg_color != null,
              'Argument for dev.flutter.pigeon.WebViewHostApi.setBackgroundColor was null, expected non-null int.');
          api.setBackgroundColor(arg_instanceId!, arg_color!);
          return <Object?, Object?>{};
        });
      }
    }
  }
}

class _TestWebSettingsHostApiCodec extends StandardMessageCodec {
  const _TestWebSettingsHostApiCodec();
}

abstract class TestWebSettingsHostApi {
  static const MessageCodec<Object?> codec = _TestWebSettingsHostApiCodec();

  void create(int instanceId, int webViewInstanceId);
  void dispose(int instanceId);
  void setDomStorageEnabled(int instanceId, bool flag);
  void setJavaScriptCanOpenWindowsAutomatically(int instanceId, bool flag);
  void setSupportMultipleWindows(int instanceId, bool support);
  void setJavaScriptEnabled(int instanceId, bool flag);
  void setUserAgentString(int instanceId, String userAgentString);
  void setMediaPlaybackRequiresUserGesture(int instanceId, bool require);
  void setSupportZoom(int instanceId, bool support);
  void setLoadWithOverviewMode(int instanceId, bool overview);
  void setUseWideViewPort(int instanceId, bool use);
  void setDisplayZoomControls(int instanceId, bool enabled);
  void setBuiltInZoomControls(int instanceId, bool enabled);
  static void setup(TestWebSettingsHostApi? api,
      {BinaryMessenger? binaryMessenger}) {
    {
      final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
          'dev.flutter.pigeon.WebSettingsHostApi.create', codec,
          binaryMessenger: binaryMessenger);
      if (api == null) {
        channel.setMockMessageHandler(null);
      } else {
        channel.setMockMessageHandler((Object? message) async {
          assert(message != null,
              'Argument for dev.flutter.pigeon.WebSettingsHostApi.create was null.');
          final List<Object?> args = (message as List<Object?>?)!;
          final int? arg_instanceId = (args[0] as int?);
          assert(arg_instanceId != null,
              'Argument for dev.flutter.pigeon.WebSettingsHostApi.create was null, expected non-null int.');
          final int? arg_webViewInstanceId = (args[1] as int?);
          assert(arg_webViewInstanceId != null,
              'Argument for dev.flutter.pigeon.WebSettingsHostApi.create was null, expected non-null int.');
          api.create(arg_instanceId!, arg_webViewInstanceId!);
          return <Object?, Object?>{};
        });
      }
    }
    {
      final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
          'dev.flutter.pigeon.WebSettingsHostApi.dispose', codec,
          binaryMessenger: binaryMessenger);
      if (api == null) {
        channel.setMockMessageHandler(null);
      } else {
        channel.setMockMessageHandler((Object? message) async {
          assert(message != null,
              'Argument for dev.flutter.pigeon.WebSettingsHostApi.dispose was null.');
          final List<Object?> args = (message as List<Object?>?)!;
          final int? arg_instanceId = (args[0] as int?);
          assert(arg_instanceId != null,
              'Argument for dev.flutter.pigeon.WebSettingsHostApi.dispose was null, expected non-null int.');
          api.dispose(arg_instanceId!);
          return <Object?, Object?>{};
        });
      }
    }
    {
      final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
          'dev.flutter.pigeon.WebSettingsHostApi.setDomStorageEnabled', codec,
          binaryMessenger: binaryMessenger);
      if (api == null) {
        channel.setMockMessageHandler(null);
      } else {
        channel.setMockMessageHandler((Object? message) async {
          assert(message != null,
              'Argument for dev.flutter.pigeon.WebSettingsHostApi.setDomStorageEnabled was null.');
          final List<Object?> args = (message as List<Object?>?)!;
          final int? arg_instanceId = (args[0] as int?);
          assert(arg_instanceId != null,
              'Argument for dev.flutter.pigeon.WebSettingsHostApi.setDomStorageEnabled was null, expected non-null int.');
          final bool? arg_flag = (args[1] as bool?);
          assert(arg_flag != null,
              'Argument for dev.flutter.pigeon.WebSettingsHostApi.setDomStorageEnabled was null, expected non-null bool.');
          api.setDomStorageEnabled(arg_instanceId!, arg_flag!);
          return <Object?, Object?>{};
        });
      }
    }
    {
      final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
          'dev.flutter.pigeon.WebSettingsHostApi.setJavaScriptCanOpenWindowsAutomatically',
          codec,
          binaryMessenger: binaryMessenger);
      if (api == null) {
        channel.setMockMessageHandler(null);
      } else {
        channel.setMockMessageHandler((Object? message) async {
          assert(message != null,
              'Argument for dev.flutter.pigeon.WebSettingsHostApi.setJavaScriptCanOpenWindowsAutomatically was null.');
          final List<Object?> args = (message as List<Object?>?)!;
          final int? arg_instanceId = (args[0] as int?);
          assert(arg_instanceId != null,
              'Argument for dev.flutter.pigeon.WebSettingsHostApi.setJavaScriptCanOpenWindowsAutomatically was null, expected non-null int.');
          final bool? arg_flag = (args[1] as bool?);
          assert(arg_flag != null,
              'Argument for dev.flutter.pigeon.WebSettingsHostApi.setJavaScriptCanOpenWindowsAutomatically was null, expected non-null bool.');
          api.setJavaScriptCanOpenWindowsAutomatically(
              arg_instanceId!, arg_flag!);
          return <Object?, Object?>{};
        });
      }
    }
    {
      final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
          'dev.flutter.pigeon.WebSettingsHostApi.setSupportMultipleWindows',
          codec,
          binaryMessenger: binaryMessenger);
      if (api == null) {
        channel.setMockMessageHandler(null);
      } else {
        channel.setMockMessageHandler((Object? message) async {
          assert(message != null,
              'Argument for dev.flutter.pigeon.WebSettingsHostApi.setSupportMultipleWindows was null.');
          final List<Object?> args = (message as List<Object?>?)!;
          final int? arg_instanceId = (args[0] as int?);
          assert(arg_instanceId != null,
              'Argument for dev.flutter.pigeon.WebSettingsHostApi.setSupportMultipleWindows was null, expected non-null int.');
          final bool? arg_support = (args[1] as bool?);
          assert(arg_support != null,
              'Argument for dev.flutter.pigeon.WebSettingsHostApi.setSupportMultipleWindows was null, expected non-null bool.');
          api.setSupportMultipleWindows(arg_instanceId!, arg_support!);
          return <Object?, Object?>{};
        });
      }
    }
    {
      final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
          'dev.flutter.pigeon.WebSettingsHostApi.setJavaScriptEnabled', codec,
          binaryMessenger: binaryMessenger);
      if (api == null) {
        channel.setMockMessageHandler(null);
      } else {
        channel.setMockMessageHandler((Object? message) async {
          assert(message != null,
              'Argument for dev.flutter.pigeon.WebSettingsHostApi.setJavaScriptEnabled was null.');
          final List<Object?> args = (message as List<Object?>?)!;
          final int? arg_instanceId = (args[0] as int?);
          assert(arg_instanceId != null,
              'Argument for dev.flutter.pigeon.WebSettingsHostApi.setJavaScriptEnabled was null, expected non-null int.');
          final bool? arg_flag = (args[1] as bool?);
          assert(arg_flag != null,
              'Argument for dev.flutter.pigeon.WebSettingsHostApi.setJavaScriptEnabled was null, expected non-null bool.');
          api.setJavaScriptEnabled(arg_instanceId!, arg_flag!);
          return <Object?, Object?>{};
        });
      }
    }
    {
      final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
          'dev.flutter.pigeon.WebSettingsHostApi.setUserAgentString', codec,
          binaryMessenger: binaryMessenger);
      if (api == null) {
        channel.setMockMessageHandler(null);
      } else {
        channel.setMockMessageHandler((Object? message) async {
          assert(message != null,
              'Argument for dev.flutter.pigeon.WebSettingsHostApi.setUserAgentString was null.');
          final List<Object?> args = (message as List<Object?>?)!;
          final int? arg_instanceId = (args[0] as int?);
          assert(arg_instanceId != null,
              'Argument for dev.flutter.pigeon.WebSettingsHostApi.setUserAgentString was null, expected non-null int.');
          final String? arg_userAgentString = (args[1] as String?);
          assert(arg_userAgentString != null,
              'Argument for dev.flutter.pigeon.WebSettingsHostApi.setUserAgentString was null, expected non-null String.');
          api.setUserAgentString(arg_instanceId!, arg_userAgentString!);
          return <Object?, Object?>{};
        });
      }
    }
    {
      final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
          'dev.flutter.pigeon.WebSettingsHostApi.setMediaPlaybackRequiresUserGesture',
          codec,
          binaryMessenger: binaryMessenger);
      if (api == null) {
        channel.setMockMessageHandler(null);
      } else {
        channel.setMockMessageHandler((Object? message) async {
          assert(message != null,
              'Argument for dev.flutter.pigeon.WebSettingsHostApi.setMediaPlaybackRequiresUserGesture was null.');
          final List<Object?> args = (message as List<Object?>?)!;
          final int? arg_instanceId = (args[0] as int?);
          assert(arg_instanceId != null,
              'Argument for dev.flutter.pigeon.WebSettingsHostApi.setMediaPlaybackRequiresUserGesture was null, expected non-null int.');
          final bool? arg_require = (args[1] as bool?);
          assert(arg_require != null,
              'Argument for dev.flutter.pigeon.WebSettingsHostApi.setMediaPlaybackRequiresUserGesture was null, expected non-null bool.');
          api.setMediaPlaybackRequiresUserGesture(
              arg_instanceId!, arg_require!);
          return <Object?, Object?>{};
        });
      }
    }
    {
      final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
          'dev.flutter.pigeon.WebSettingsHostApi.setSupportZoom', codec,
          binaryMessenger: binaryMessenger);
      if (api == null) {
        channel.setMockMessageHandler(null);
      } else {
        channel.setMockMessageHandler((Object? message) async {
          assert(message != null,
              'Argument for dev.flutter.pigeon.WebSettingsHostApi.setSupportZoom was null.');
          final List<Object?> args = (message as List<Object?>?)!;
          final int? arg_instanceId = (args[0] as int?);
          assert(arg_instanceId != null,
              'Argument for dev.flutter.pigeon.WebSettingsHostApi.setSupportZoom was null, expected non-null int.');
          final bool? arg_support = (args[1] as bool?);
          assert(arg_support != null,
              'Argument for dev.flutter.pigeon.WebSettingsHostApi.setSupportZoom was null, expected non-null bool.');
          api.setSupportZoom(arg_instanceId!, arg_support!);
          return <Object?, Object?>{};
        });
      }
    }
    {
      final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
          'dev.flutter.pigeon.WebSettingsHostApi.setLoadWithOverviewMode',
          codec,
          binaryMessenger: binaryMessenger);
      if (api == null) {
        channel.setMockMessageHandler(null);
      } else {
        channel.setMockMessageHandler((Object? message) async {
          assert(message != null,
              'Argument for dev.flutter.pigeon.WebSettingsHostApi.setLoadWithOverviewMode was null.');
          final List<Object?> args = (message as List<Object?>?)!;
          final int? arg_instanceId = (args[0] as int?);
          assert(arg_instanceId != null,
              'Argument for dev.flutter.pigeon.WebSettingsHostApi.setLoadWithOverviewMode was null, expected non-null int.');
          final bool? arg_overview = (args[1] as bool?);
          assert(arg_overview != null,
              'Argument for dev.flutter.pigeon.WebSettingsHostApi.setLoadWithOverviewMode was null, expected non-null bool.');
          api.setLoadWithOverviewMode(arg_instanceId!, arg_overview!);
          return <Object?, Object?>{};
        });
      }
    }
    {
      final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
          'dev.flutter.pigeon.WebSettingsHostApi.setUseWideViewPort', codec,
          binaryMessenger: binaryMessenger);
      if (api == null) {
        channel.setMockMessageHandler(null);
      } else {
        channel.setMockMessageHandler((Object? message) async {
          assert(message != null,
              'Argument for dev.flutter.pigeon.WebSettingsHostApi.setUseWideViewPort was null.');
          final List<Object?> args = (message as List<Object?>?)!;
          final int? arg_instanceId = (args[0] as int?);
          assert(arg_instanceId != null,
              'Argument for dev.flutter.pigeon.WebSettingsHostApi.setUseWideViewPort was null, expected non-null int.');
          final bool? arg_use = (args[1] as bool?);
          assert(arg_use != null,
              'Argument for dev.flutter.pigeon.WebSettingsHostApi.setUseWideViewPort was null, expected non-null bool.');
          api.setUseWideViewPort(arg_instanceId!, arg_use!);
          return <Object?, Object?>{};
        });
      }
    }
    {
      final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
          'dev.flutter.pigeon.WebSettingsHostApi.setDisplayZoomControls', codec,
          binaryMessenger: binaryMessenger);
      if (api == null) {
        channel.setMockMessageHandler(null);
      } else {
        channel.setMockMessageHandler((Object? message) async {
          assert(message != null,
              'Argument for dev.flutter.pigeon.WebSettingsHostApi.setDisplayZoomControls was null.');
          final List<Object?> args = (message as List<Object?>?)!;
          final int? arg_instanceId = (args[0] as int?);
          assert(arg_instanceId != null,
              'Argument for dev.flutter.pigeon.WebSettingsHostApi.setDisplayZoomControls was null, expected non-null int.');
          final bool? arg_enabled = (args[1] as bool?);
          assert(arg_enabled != null,
              'Argument for dev.flutter.pigeon.WebSettingsHostApi.setDisplayZoomControls was null, expected non-null bool.');
          api.setDisplayZoomControls(arg_instanceId!, arg_enabled!);
          return <Object?, Object?>{};
        });
      }
    }
    {
      final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
          'dev.flutter.pigeon.WebSettingsHostApi.setBuiltInZoomControls', codec,
          binaryMessenger: binaryMessenger);
      if (api == null) {
        channel.setMockMessageHandler(null);
      } else {
        channel.setMockMessageHandler((Object? message) async {
          assert(message != null,
              'Argument for dev.flutter.pigeon.WebSettingsHostApi.setBuiltInZoomControls was null.');
          final List<Object?> args = (message as List<Object?>?)!;
          final int? arg_instanceId = (args[0] as int?);
          assert(arg_instanceId != null,
              'Argument for dev.flutter.pigeon.WebSettingsHostApi.setBuiltInZoomControls was null, expected non-null int.');
          final bool? arg_enabled = (args[1] as bool?);
          assert(arg_enabled != null,
              'Argument for dev.flutter.pigeon.WebSettingsHostApi.setBuiltInZoomControls was null, expected non-null bool.');
          api.setBuiltInZoomControls(arg_instanceId!, arg_enabled!);
          return <Object?, Object?>{};
        });
      }
    }
  }
}

class _TestJavaScriptChannelHostApiCodec extends StandardMessageCodec {
  const _TestJavaScriptChannelHostApiCodec();
}

abstract class TestJavaScriptChannelHostApi {
  static const MessageCodec<Object?> codec =
      _TestJavaScriptChannelHostApiCodec();

  void create(int instanceId, String channelName);
  static void setup(TestJavaScriptChannelHostApi? api,
      {BinaryMessenger? binaryMessenger}) {
    {
      final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
          'dev.flutter.pigeon.JavaScriptChannelHostApi.create', codec,
          binaryMessenger: binaryMessenger);
      if (api == null) {
        channel.setMockMessageHandler(null);
      } else {
        channel.setMockMessageHandler((Object? message) async {
          assert(message != null,
              'Argument for dev.flutter.pigeon.JavaScriptChannelHostApi.create was null.');
          final List<Object?> args = (message as List<Object?>?)!;
          final int? arg_instanceId = (args[0] as int?);
          assert(arg_instanceId != null,
              'Argument for dev.flutter.pigeon.JavaScriptChannelHostApi.create was null, expected non-null int.');
          final String? arg_channelName = (args[1] as String?);
          assert(arg_channelName != null,
              'Argument for dev.flutter.pigeon.JavaScriptChannelHostApi.create was null, expected non-null String.');
          api.create(arg_instanceId!, arg_channelName!);
          return <Object?, Object?>{};
        });
      }
    }
  }
}

class _TestWebViewClientHostApiCodec extends StandardMessageCodec {
  const _TestWebViewClientHostApiCodec();
}

abstract class TestWebViewClientHostApi {
  static const MessageCodec<Object?> codec = _TestWebViewClientHostApiCodec();

  void create(int instanceId, bool shouldOverrideUrlLoading);
  static void setup(TestWebViewClientHostApi? api,
      {BinaryMessenger? binaryMessenger}) {
    {
      final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
          'dev.flutter.pigeon.WebViewClientHostApi.create', codec,
          binaryMessenger: binaryMessenger);
      if (api == null) {
        channel.setMockMessageHandler(null);
      } else {
        channel.setMockMessageHandler((Object? message) async {
          assert(message != null,
              'Argument for dev.flutter.pigeon.WebViewClientHostApi.create was null.');
          final List<Object?> args = (message as List<Object?>?)!;
          final int? arg_instanceId = (args[0] as int?);
          assert(arg_instanceId != null,
              'Argument for dev.flutter.pigeon.WebViewClientHostApi.create was null, expected non-null int.');
          final bool? arg_shouldOverrideUrlLoading = (args[1] as bool?);
          assert(arg_shouldOverrideUrlLoading != null,
              'Argument for dev.flutter.pigeon.WebViewClientHostApi.create was null, expected non-null bool.');
          api.create(arg_instanceId!, arg_shouldOverrideUrlLoading!);
          return <Object?, Object?>{};
        });
      }
    }
  }
}

class _TestDownloadListenerHostApiCodec extends StandardMessageCodec {
  const _TestDownloadListenerHostApiCodec();
}

abstract class TestDownloadListenerHostApi {
  static const MessageCodec<Object?> codec =
      _TestDownloadListenerHostApiCodec();

  void create(int instanceId);
  static void setup(TestDownloadListenerHostApi? api,
      {BinaryMessenger? binaryMessenger}) {
    {
      final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
          'dev.flutter.pigeon.DownloadListenerHostApi.create', codec,
          binaryMessenger: binaryMessenger);
      if (api == null) {
        channel.setMockMessageHandler(null);
      } else {
        channel.setMockMessageHandler((Object? message) async {
          assert(message != null,
              'Argument for dev.flutter.pigeon.DownloadListenerHostApi.create was null.');
          final List<Object?> args = (message as List<Object?>?)!;
          final int? arg_instanceId = (args[0] as int?);
          assert(arg_instanceId != null,
              'Argument for dev.flutter.pigeon.DownloadListenerHostApi.create was null, expected non-null int.');
          api.create(arg_instanceId!);
          return <Object?, Object?>{};
        });
      }
    }
  }
}

class _TestWebChromeClientHostApiCodec extends StandardMessageCodec {
  const _TestWebChromeClientHostApiCodec();
}

abstract class TestWebChromeClientHostApi {
  static const MessageCodec<Object?> codec = _TestWebChromeClientHostApiCodec();

  void create(int instanceId, int webViewClientInstanceId);
  static void setup(TestWebChromeClientHostApi? api,
      {BinaryMessenger? binaryMessenger}) {
    {
      final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
          'dev.flutter.pigeon.WebChromeClientHostApi.create', codec,
          binaryMessenger: binaryMessenger);
      if (api == null) {
        channel.setMockMessageHandler(null);
      } else {
        channel.setMockMessageHandler((Object? message) async {
          assert(message != null,
              'Argument for dev.flutter.pigeon.WebChromeClientHostApi.create was null.');
          final List<Object?> args = (message as List<Object?>?)!;
          final int? arg_instanceId = (args[0] as int?);
          assert(arg_instanceId != null,
              'Argument for dev.flutter.pigeon.WebChromeClientHostApi.create was null, expected non-null int.');
          final int? arg_webViewClientInstanceId = (args[1] as int?);
          assert(arg_webViewClientInstanceId != null,
              'Argument for dev.flutter.pigeon.WebChromeClientHostApi.create was null, expected non-null int.');
          api.create(arg_instanceId!, arg_webViewClientInstanceId!);
          return <Object?, Object?>{};
        });
      }
    }
  }
}

class _TestAssetManagerHostApiCodec extends StandardMessageCodec {
  const _TestAssetManagerHostApiCodec();
}

abstract class TestAssetManagerHostApi {
  static const MessageCodec<Object?> codec = _TestAssetManagerHostApiCodec();

  List<String?> list(String path);
  String getAssetFilePathByName(String name);
  static void setup(TestAssetManagerHostApi? api,
      {BinaryMessenger? binaryMessenger}) {
    {
      final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
          'dev.flutter.pigeon.FlutterAssetManagerHostApi.list', codec,
          binaryMessenger: binaryMessenger);
      if (api == null) {
        channel.setMockMessageHandler(null);
      } else {
        channel.setMockMessageHandler((Object? message) async {
          assert(message != null,
              'Argument for dev.flutter.pigeon.FlutterAssetManagerHostApi.list was null.');
          final List<Object?> args = (message as List<Object?>?)!;
          final String? arg_path = (args[0] as String?);
          assert(arg_path != null,
              'Argument for dev.flutter.pigeon.FlutterAssetManagerHostApi.list was null, expected non-null String.');
          final List<String?> output = api.list(arg_path!);
          return <Object?, Object?>{'result': output};
        });
      }
    }
    {
      final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
          'dev.flutter.pigeon.FlutterAssetManagerHostApi.getAssetFilePathByName',
          codec,
          binaryMessenger: binaryMessenger);
      if (api == null) {
        channel.setMockMessageHandler(null);
      } else {
        channel.setMockMessageHandler((Object? message) async {
          assert(message != null,
              'Argument for dev.flutter.pigeon.FlutterAssetManagerHostApi.getAssetFilePathByName was null.');
          final List<Object?> args = (message as List<Object?>?)!;
          final String? arg_name = (args[0] as String?);
          assert(arg_name != null,
              'Argument for dev.flutter.pigeon.FlutterAssetManagerHostApi.getAssetFilePathByName was null, expected non-null String.');
          final String output = api.getAssetFilePathByName(arg_name!);
          return <Object?, Object?>{'result': output};
        });
      }
    }
  }
}
