diff --git a/.cirrus.yml b/.cirrus.yml index da354c5a9b22..9776d9a2ab31 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -197,6 +197,10 @@ task: - export CIRRUS_CHANGE_MESSAGE="" - export CIRRUS_COMMIT_MESSAGE="" - ./script/tool_runner.sh lint-android # must come after build-examples + stable_channel_conditional_script: + - if [[ "$CHANNEL" == "stable" ]]; then + - dart ./ci/stable_conditional.dart + - fi native_unit_test_script: # Unsetting CIRRUS_CHANGE_MESSAGE and CIRRUS_COMMIT_MESSAGE as they # might include non-ASCII characters which makes Gradle crash. diff --git a/ci/stable_conditional.dart b/ci/stable_conditional.dart new file mode 100644 index 000000000000..76643532bc9d --- /dev/null +++ b/ci/stable_conditional.dart @@ -0,0 +1,67 @@ +// 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. +// +// stable_conditional.dart +// +// Performs simple find and replace operations for conditional compilation +// before executing stable channel tests. +// +// Example input: +// int main() { +// // FLUTTER_STABLE_CONDITIONAL_IF_NOT_STABLE +// printf("hello world\n"); +// // FLUTTER_STABLE_CONDITIONAL_ELSE +// // printf("goodbye world\n"); +// // FLUTTER_STABLE_CONDITIONAL_ENDIF +// } +// +// Example output: +// int main() { +// printf("goodbye world\n"); +// } + +import 'dart:convert' show LineSplitter; +import 'dart:io' show FileSystemEntity, File; + +final List _filesToProcess = [ + 'packages/android_intent/android/src/test/java/io/flutter/plugins/androidintent/MethodCallHandlerImplTest.java', + 'packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/DartMessengerTest.java', + 'packages/quick_actions/quick_actions/android/src/test/java/io/flutter/plugins/quickactions/QuickActionsTest.java', + 'packages/url_launcher/url_launcher/android/src/test/java/io/flutter/plugins/urllauncher/MethodCallHandlerImplTest.java', +]; + +final RegExp _replacer = RegExp( + r'^\s*// FLUTTER_STABLE_CONDITIONAL_IF_NOT_STABLE(.*?)^\s*// FLUTTER_STABLE_CONDITIONAL_ELSE(.*?)^\s*// FLUTTER_STABLE_CONDITIONAL_ENDIF', + multiLine: true, + dotAll: true); +final RegExp _commentRemover = RegExp(r'^(\s*)\/\/\s*(.*)'); +const String _newline = '\n'; + +void _process(FileSystemEntity entity) { + const LineSplitter splitter = LineSplitter(); + final String text = File(entity.path).readAsStringSync(); + String replaced = ''; + int index = 0; + for (final RegExpMatch match in _replacer.allMatches(text)) { + replaced += text.substring(index, match.start); + for (final String line in splitter.convert(match.group(2)!)) { + final RegExpMatch? commentRemoverMatch = _commentRemover.firstMatch(line); + if (commentRemoverMatch != null) { + replaced += commentRemoverMatch.group(1)! + + commentRemoverMatch.group(2)! + + _newline; + } + } + index = match.end; + } + if (replaced.isNotEmpty) { + replaced += text.substring(index, text.length); + File(entity.path).writeAsStringSync(replaced); + print('modified: ${entity.path}'); + } +} + +void main(List args) { + _filesToProcess.map((String path) => File(path)).forEach(_process); +} diff --git a/packages/android_intent/android/src/test/java/io/flutter/plugins/androidintent/MethodCallHandlerImplTest.java b/packages/android_intent/android/src/test/java/io/flutter/plugins/androidintent/MethodCallHandlerImplTest.java index 0ea03a0690f1..012cc9be9711 100644 --- a/packages/android_intent/android/src/test/java/io/flutter/plugins/androidintent/MethodCallHandlerImplTest.java +++ b/packages/android_intent/android/src/test/java/io/flutter/plugins/androidintent/MethodCallHandlerImplTest.java @@ -55,7 +55,11 @@ public void startListening_registersChannel() { methodCallHandler.startListening(messenger); verify(messenger, times(1)) - .setMessageHandler(eq(CHANNEL_NAME), any(BinaryMessageHandler.class)); + // FLUTTER_STABLE_CONDITIONAL_IF_NOT_STABLE + .setMessageHandler(eq(CHANNEL_NAME), any(BinaryMessageHandler.class), eq(null)); + // FLUTTER_STABLE_CONDITIONAL_ELSE + // .setMessageHandler(eq(CHANNEL_NAME), any(BinaryMessageHandler.class)); + // FLUTTER_STABLE_CONDITIONAL_ENDIF } @Test @@ -67,9 +71,15 @@ public void startListening_unregistersExistingChannel() { methodCallHandler.startListening(secondMessenger); // Unregisters the first and then registers the second. - verify(firstMessenger, times(1)).setMessageHandler(CHANNEL_NAME, null); + // FLUTTER_STABLE_CONDITIONAL_IF_NOT_STABLE + verify(firstMessenger, times(1)).setMessageHandler(CHANNEL_NAME, null, null); verify(secondMessenger, times(1)) - .setMessageHandler(eq(CHANNEL_NAME), any(BinaryMessageHandler.class)); + .setMessageHandler(eq(CHANNEL_NAME), any(BinaryMessageHandler.class), eq(null)); + // FLUTTER_STABLE_CONDITIONAL_ELSE + // verify(firstMessenger, times(1)).setMessageHandler(CHANNEL_NAME, null); + // verify(secondMessenger, times(1)) + // .setMessageHandler(eq(CHANNEL_NAME), any(BinaryMessageHandler.class)); + // FLUTTER_STABLE_CONDITIONAL_ENDIF } @Test @@ -79,7 +89,11 @@ public void stopListening_unregistersExistingChannel() { methodCallHandler.stopListening(); - verify(messenger, times(1)).setMessageHandler(CHANNEL_NAME, null); + // FLUTTER_STABLE_CONDITIONAL_IF_NOT_STABLE + verify(messenger, times(1)).setMessageHandler(CHANNEL_NAME, null, null); + // FLUTTER_STABLE_CONDITIONAL_ELSE + // verify(messenger, times(1)).setMessageHandler(CHANNEL_NAME, null); + // FLUTTER_STABLE_CONDITIONAL_ENDIF } @Test @@ -88,7 +102,11 @@ public void stopListening_doesNothingWhenUnset() { methodCallHandler.stopListening(); - verify(messenger, never()).setMessageHandler(CHANNEL_NAME, null); + // FLUTTER_STABLE_CONDITIONAL_IF_NOT_STABLE + verify(messenger, never()).setMessageHandler(CHANNEL_NAME, null, null); + // FLUTTER_STABLE_CONDITIONAL_ELSE + // verify(messenger, never()).setMessageHandler(CHANNEL_NAME, null); + // FLUTTER_STABLE_CONDITIONAL_ENDIF } @Test diff --git a/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/DartMessengerTest.java b/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/DartMessengerTest.java index 0a2fc43d03cb..1ce04d6cc104 100644 --- a/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/DartMessengerTest.java +++ b/packages/camera/camera/android/src/test/java/io/flutter/plugins/camera/DartMessengerTest.java @@ -12,6 +12,7 @@ import android.os.Handler; import androidx.annotation.NonNull; +import androidx.annotation.Nullable; import io.flutter.embedding.engine.systemchannels.PlatformChannel; import io.flutter.plugin.common.BinaryMessenger; import io.flutter.plugin.common.MethodCall; @@ -31,6 +32,15 @@ public class DartMessengerTest { private static class FakeBinaryMessenger implements BinaryMessenger { private final List sentMessages = new ArrayList<>(); + // TODO(aaclarke): Remove when https://github.com/flutter/engine/pull/29147 is on stable. + // FLUTTER_STABLE_CONDITIONAL_IF_NOT_STABLE + @Override + public BinaryMessenger.TaskQueue makeBackgroundTaskQueue() { + return null; + } + // FLUTTER_STABLE_CONDITIONAL_ELSE + // FLUTTER_STABLE_CONDITIONAL_ENDIF + @Override public void send(@NonNull String channel, ByteBuffer message) { sentMessages.add(message); @@ -41,8 +51,17 @@ public void send(@NonNull String channel, ByteBuffer message, BinaryReply callba send(channel, message); } + // TODO(aaclarke): Remove when https://github.com/flutter/engine/pull/29147 is on stable. + // FLUTTER_STABLE_CONDITIONAL_IF_NOT_STABLE @Override - public void setMessageHandler(@NonNull String channel, BinaryMessageHandler handler) {} + public void setMessageHandler( + @NonNull String channel, + BinaryMessageHandler handler, + @Nullable BinaryMessenger.TaskQueue taskQueue) {} + // FLUTTER_STABLE_CONDITIONAL_ELSE + // @Override + // public void setMessageHandler(@NonNull String channel, BinaryMessageHandler handler) {} + // FLUTTER_STABLE_CONDITIONAL_ENDIF List getMessages() { return new ArrayList<>(sentMessages); diff --git a/packages/quick_actions/quick_actions/android/src/test/java/io/flutter/plugins/quickactions/QuickActionsTest.java b/packages/quick_actions/quick_actions/android/src/test/java/io/flutter/plugins/quickactions/QuickActionsTest.java index 208a119efafe..2b6fb495f7c4 100644 --- a/packages/quick_actions/quick_actions/android/src/test/java/io/flutter/plugins/quickactions/QuickActionsTest.java +++ b/packages/quick_actions/quick_actions/android/src/test/java/io/flutter/plugins/quickactions/QuickActionsTest.java @@ -33,6 +33,15 @@ public class QuickActionsTest { private static class TestBinaryMessenger implements BinaryMessenger { public MethodCall lastMethodCall; + // TODO(aaclarke): Remove when https://github.com/flutter/engine/pull/29147 is on stable. + // FLUTTER_STABLE_CONDITIONAL_IF_NOT_STABLE + @Override + public BinaryMessenger.TaskQueue makeBackgroundTaskQueue() { + return null; + } + // FLUTTER_STABLE_CONDITIONAL_ELSE + // FLUTTER_STABLE_CONDITIONAL_ENDIF + @Override public void send(@NonNull String channel, @Nullable ByteBuffer message) { send(channel, message, null); @@ -49,10 +58,21 @@ public void send( } } + // TODO(aaclarke): Remove when https://github.com/flutter/engine/pull/29147 is on stable. + // FLUTTER_STABLE_CONDITIONAL_IF_NOT_STABLE @Override - public void setMessageHandler(@NonNull String channel, @Nullable BinaryMessageHandler handler) { + public void setMessageHandler( + @NonNull String channel, + @Nullable BinaryMessageHandler handler, + @Nullable BinaryMessenger.TaskQueue taskQueue) { // Do nothing. } + // FLUTTER_STABLE_CONDITIONAL_ELSE + // @Override + // public void setMessageHandler( + // @NonNull String channel, + // @Nullable BinaryMessageHandler handler) {} + // FLUTTER_STABLE_CONDITIONAL_ENDIF } static final int SUPPORTED_BUILD = 25; diff --git a/packages/url_launcher/url_launcher/android/src/test/java/io/flutter/plugins/urllauncher/MethodCallHandlerImplTest.java b/packages/url_launcher/url_launcher/android/src/test/java/io/flutter/plugins/urllauncher/MethodCallHandlerImplTest.java index 5e0811399ac6..6b544c7611c5 100644 --- a/packages/url_launcher/url_launcher/android/src/test/java/io/flutter/plugins/urllauncher/MethodCallHandlerImplTest.java +++ b/packages/url_launcher/url_launcher/android/src/test/java/io/flutter/plugins/urllauncher/MethodCallHandlerImplTest.java @@ -44,7 +44,11 @@ public void startListening_registersChannel() { methodCallHandler.startListening(messenger); verify(messenger, times(1)) - .setMessageHandler(eq(CHANNEL_NAME), any(BinaryMessageHandler.class)); + // FLUTTER_STABLE_CONDITIONAL_IF_NOT_STABLE + .setMessageHandler(eq(CHANNEL_NAME), any(BinaryMessageHandler.class), eq(null)); + // FLUTTER_STABLE_CONDITIONAL_ELSE + // .setMessageHandler(eq(CHANNEL_NAME), any(BinaryMessageHandler.class)); + // FLUTTER_STABLE_CONDITIONAL_ENDIF } @Test @@ -56,9 +60,15 @@ public void startListening_unregistersExistingChannel() { methodCallHandler.startListening(secondMessenger); // Unregisters the first and then registers the second. - verify(firstMessenger, times(1)).setMessageHandler(CHANNEL_NAME, null); + // FLUTTER_STABLE_CONDITIONAL_IF_NOT_STABLE + verify(firstMessenger, times(1)).setMessageHandler(CHANNEL_NAME, null, null); verify(secondMessenger, times(1)) - .setMessageHandler(eq(CHANNEL_NAME), any(BinaryMessageHandler.class)); + .setMessageHandler(eq(CHANNEL_NAME), any(BinaryMessageHandler.class), eq(null)); + // FLUTTER_STABLE_CONDITIONAL_ELSE + // verify(firstMessenger, times(1)).setMessageHandler(CHANNEL_NAME, null); + // verify(secondMessenger, times(1)) + // .setMessageHandler(eq(CHANNEL_NAME), any(BinaryMessageHandler.class)); + // FLUTTER_STABLE_CONDITIONAL_ENDIF } @Test @@ -68,7 +78,11 @@ public void stopListening_unregistersExistingChannel() { methodCallHandler.stopListening(); - verify(messenger, times(1)).setMessageHandler(CHANNEL_NAME, null); + // FLUTTER_STABLE_CONDITIONAL_IF_NOT_STABLE + verify(messenger, times(1)).setMessageHandler(CHANNEL_NAME, null, null); + // FLUTTER_STABLE_CONDITIONAL_ELSE + // verify(messenger, times(1)).setMessageHandler(CHANNEL_NAME, null); + // FLUTTER_STABLE_CONDITIONAL_ENDIF } @Test @@ -77,7 +91,11 @@ public void stopListening_doesNothingWhenUnset() { methodCallHandler.stopListening(); - verify(messenger, never()).setMessageHandler(CHANNEL_NAME, null); + // FLUTTER_STABLE_CONDITIONAL_IF_NOT_STABLE + verify(messenger, never()).setMessageHandler(CHANNEL_NAME, null, null); + // FLUTTER_STABLE_CONDITIONAL_ELSE + // verify(messenger, never()).setMessageHandler(CHANNEL_NAME, null); + // FLUTTER_STABLE_CONDITIONAL_ENDIF } @Test diff --git a/packages/url_launcher/url_launcher_web/example/integration_test/url_launcher_web_test.mocks.dart b/packages/url_launcher/url_launcher_web/example/integration_test/url_launcher_web_test.mocks.dart index 9cd0196f51db..24d694ffa0cc 100644 --- a/packages/url_launcher/url_launcher_web/example/integration_test/url_launcher_web_test.mocks.dart +++ b/packages/url_launcher/url_launcher_web/example/integration_test/url_launcher_web_test.mocks.dart @@ -1,57 +1,54 @@ -// 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. - -// Mocks generated by Mockito 5.0.2 from annotations +// Mocks generated by Mockito 5.0.16 from annotations // in regular_integration_tests/integration_test/url_launcher_web_test.dart. // Do not manually edit this file. -import 'dart:async' as _i4; +import 'dart:async' as _i3; import 'dart:html' as _i2; -import 'dart:math' as _i5; -import 'dart:web_sql' as _i3; +import 'dart:math' as _i4; import 'package:mockito/mockito.dart' as _i1; +// ignore_for_file: avoid_redundant_argument_values +// ignore_for_file: avoid_setters_without_getters // ignore_for_file: comment_references +// ignore_for_file: implementation_imports +// ignore_for_file: invalid_use_of_visible_for_testing_member +// ignore_for_file: prefer_const_constructors // ignore_for_file: unnecessary_parenthesis +// ignore_for_file: camel_case_types -class _FakeDocument extends _i1.Fake implements _i2.Document {} - -class _FakeLocation extends _i1.Fake implements _i2.Location {} +class _FakeDocument_0 extends _i1.Fake implements _i2.Document {} -class _FakeConsole extends _i1.Fake implements _i2.Console {} +class _FakeLocation_1 extends _i1.Fake implements _i2.Location {} -class _FakeHistory extends _i1.Fake implements _i2.History {} +class _FakeConsole_2 extends _i1.Fake implements _i2.Console {} -class _FakeStorage extends _i1.Fake implements _i2.Storage {} +class _FakeHistory_3 extends _i1.Fake implements _i2.History {} -class _FakeNavigator extends _i1.Fake implements _i2.Navigator {} +class _FakeStorage_4 extends _i1.Fake implements _i2.Storage {} -class _FakePerformance extends _i1.Fake implements _i2.Performance {} +class _FakeNavigator_5 extends _i1.Fake implements _i2.Navigator {} -class _FakeEvents extends _i1.Fake implements _i2.Events {} +class _FakePerformance_6 extends _i1.Fake implements _i2.Performance {} -class _FakeType extends _i1.Fake implements Type {} +class _FakeEvents_7 extends _i1.Fake implements _i2.Events {} -class _FakeWindowBase extends _i1.Fake implements _i2.WindowBase {} +class _FakeWindowBase_8 extends _i1.Fake implements _i2.WindowBase {} -class _FakeFileSystem extends _i1.Fake implements _i2.FileSystem {} +class _FakeFileSystem_9 extends _i1.Fake implements _i2.FileSystem {} -class _FakeStylePropertyMapReadonly extends _i1.Fake +class _FakeStylePropertyMapReadonly_10 extends _i1.Fake implements _i2.StylePropertyMapReadonly {} -class _FakeMediaQueryList extends _i1.Fake implements _i2.MediaQueryList {} - -class _FakeEntry extends _i1.Fake implements _i2.Entry {} +class _FakeMediaQueryList_11 extends _i1.Fake implements _i2.MediaQueryList {} -class _FakeSqlDatabase extends _i1.Fake implements _i3.SqlDatabase {} +class _FakeEntry_12 extends _i1.Fake implements _i2.Entry {} -class _FakeGeolocation extends _i1.Fake implements _i2.Geolocation {} +class _FakeGeolocation_13 extends _i1.Fake implements _i2.Geolocation {} -class _FakeMediaStream extends _i1.Fake implements _i2.MediaStream {} +class _FakeMediaStream_14 extends _i1.Fake implements _i2.MediaStream {} -class _FakeRelatedApplication extends _i1.Fake +class _FakeRelatedApplication_15 extends _i1.Fake implements _i2.RelatedApplication {} /// A class which mocks [Window]. @@ -63,37 +60,52 @@ class MockWindow extends _i1.Mock implements _i2.Window { } @override - _i4.Future get animationFrame => + _i3.Future get animationFrame => (super.noSuchMethod(Invocation.getter(#animationFrame), - returnValue: Future.value(0)) as _i4.Future); + returnValue: Future.value(0)) as _i3.Future); @override _i2.Document get document => (super.noSuchMethod(Invocation.getter(#document), - returnValue: _FakeDocument()) as _i2.Document); + returnValue: _FakeDocument_0()) as _i2.Document); @override _i2.Location get location => (super.noSuchMethod(Invocation.getter(#location), - returnValue: _FakeLocation()) as _i2.Location); + returnValue: _FakeLocation_1()) as _i2.Location); @override set location(_i2.LocationBase? value) => super.noSuchMethod(Invocation.setter(#location, value), returnValueForMissingStub: null); @override _i2.Console get console => (super.noSuchMethod(Invocation.getter(#console), - returnValue: _FakeConsole()) as _i2.Console); + returnValue: _FakeConsole_2()) as _i2.Console); + @override + set defaultStatus(String? value) => + super.noSuchMethod(Invocation.setter(#defaultStatus, value), + returnValueForMissingStub: null); + @override + set defaultstatus(String? value) => + super.noSuchMethod(Invocation.setter(#defaultstatus, value), + returnValueForMissingStub: null); @override num get devicePixelRatio => (super.noSuchMethod(Invocation.getter(#devicePixelRatio), returnValue: 0) as num); @override _i2.History get history => (super.noSuchMethod(Invocation.getter(#history), - returnValue: _FakeHistory()) as _i2.History); + returnValue: _FakeHistory_3()) as _i2.History); @override _i2.Storage get localStorage => (super.noSuchMethod(Invocation.getter(#localStorage), - returnValue: _FakeStorage()) as _i2.Storage); + returnValue: _FakeStorage_4()) as _i2.Storage); + @override + set name(String? value) => super.noSuchMethod(Invocation.setter(#name, value), + returnValueForMissingStub: null); @override _i2.Navigator get navigator => (super.noSuchMethod(Invocation.getter(#navigator), - returnValue: _FakeNavigator()) as _i2.Navigator); + returnValue: _FakeNavigator_5()) as _i2.Navigator); + @override + set opener(_i2.WindowBase? value) => + super.noSuchMethod(Invocation.setter(#opener, value), + returnValueForMissingStub: null); @override int get outerHeight => (super.noSuchMethod(Invocation.getter(#outerHeight), returnValue: 0) @@ -105,353 +117,357 @@ class MockWindow extends _i1.Mock implements _i2.Window { @override _i2.Performance get performance => (super.noSuchMethod(Invocation.getter(#performance), - returnValue: _FakePerformance()) as _i2.Performance); + returnValue: _FakePerformance_6()) as _i2.Performance); @override _i2.Storage get sessionStorage => (super.noSuchMethod(Invocation.getter(#sessionStorage), - returnValue: _FakeStorage()) as _i2.Storage); + returnValue: _FakeStorage_4()) as _i2.Storage); @override - _i4.Stream<_i2.Event> get onContentLoaded => + set status(String? value) => + super.noSuchMethod(Invocation.setter(#status, value), + returnValueForMissingStub: null); + @override + _i3.Stream<_i2.Event> get onContentLoaded => (super.noSuchMethod(Invocation.getter(#onContentLoaded), - returnValue: Stream<_i2.Event>.empty()) as _i4.Stream<_i2.Event>); + returnValue: Stream<_i2.Event>.empty()) as _i3.Stream<_i2.Event>); @override - _i4.Stream<_i2.Event> get onAbort => + _i3.Stream<_i2.Event> get onAbort => (super.noSuchMethod(Invocation.getter(#onAbort), - returnValue: Stream<_i2.Event>.empty()) as _i4.Stream<_i2.Event>); + returnValue: Stream<_i2.Event>.empty()) as _i3.Stream<_i2.Event>); @override - _i4.Stream<_i2.Event> get onBlur => + _i3.Stream<_i2.Event> get onBlur => (super.noSuchMethod(Invocation.getter(#onBlur), - returnValue: Stream<_i2.Event>.empty()) as _i4.Stream<_i2.Event>); + returnValue: Stream<_i2.Event>.empty()) as _i3.Stream<_i2.Event>); @override - _i4.Stream<_i2.Event> get onCanPlay => + _i3.Stream<_i2.Event> get onCanPlay => (super.noSuchMethod(Invocation.getter(#onCanPlay), - returnValue: Stream<_i2.Event>.empty()) as _i4.Stream<_i2.Event>); + returnValue: Stream<_i2.Event>.empty()) as _i3.Stream<_i2.Event>); @override - _i4.Stream<_i2.Event> get onCanPlayThrough => + _i3.Stream<_i2.Event> get onCanPlayThrough => (super.noSuchMethod(Invocation.getter(#onCanPlayThrough), - returnValue: Stream<_i2.Event>.empty()) as _i4.Stream<_i2.Event>); + returnValue: Stream<_i2.Event>.empty()) as _i3.Stream<_i2.Event>); @override - _i4.Stream<_i2.Event> get onChange => + _i3.Stream<_i2.Event> get onChange => (super.noSuchMethod(Invocation.getter(#onChange), - returnValue: Stream<_i2.Event>.empty()) as _i4.Stream<_i2.Event>); + returnValue: Stream<_i2.Event>.empty()) as _i3.Stream<_i2.Event>); @override - _i4.Stream<_i2.MouseEvent> get onClick => + _i3.Stream<_i2.MouseEvent> get onClick => (super.noSuchMethod(Invocation.getter(#onClick), returnValue: Stream<_i2.MouseEvent>.empty()) - as _i4.Stream<_i2.MouseEvent>); + as _i3.Stream<_i2.MouseEvent>); @override - _i4.Stream<_i2.MouseEvent> get onContextMenu => + _i3.Stream<_i2.MouseEvent> get onContextMenu => (super.noSuchMethod(Invocation.getter(#onContextMenu), returnValue: Stream<_i2.MouseEvent>.empty()) - as _i4.Stream<_i2.MouseEvent>); + as _i3.Stream<_i2.MouseEvent>); @override - _i4.Stream<_i2.Event> get onDoubleClick => + _i3.Stream<_i2.Event> get onDoubleClick => (super.noSuchMethod(Invocation.getter(#onDoubleClick), - returnValue: Stream<_i2.Event>.empty()) as _i4.Stream<_i2.Event>); + returnValue: Stream<_i2.Event>.empty()) as _i3.Stream<_i2.Event>); @override - _i4.Stream<_i2.DeviceMotionEvent> get onDeviceMotion => + _i3.Stream<_i2.DeviceMotionEvent> get onDeviceMotion => (super.noSuchMethod(Invocation.getter(#onDeviceMotion), returnValue: Stream<_i2.DeviceMotionEvent>.empty()) - as _i4.Stream<_i2.DeviceMotionEvent>); + as _i3.Stream<_i2.DeviceMotionEvent>); @override - _i4.Stream<_i2.DeviceOrientationEvent> get onDeviceOrientation => + _i3.Stream<_i2.DeviceOrientationEvent> get onDeviceOrientation => (super.noSuchMethod(Invocation.getter(#onDeviceOrientation), returnValue: Stream<_i2.DeviceOrientationEvent>.empty()) - as _i4.Stream<_i2.DeviceOrientationEvent>); + as _i3.Stream<_i2.DeviceOrientationEvent>); @override - _i4.Stream<_i2.MouseEvent> get onDrag => + _i3.Stream<_i2.MouseEvent> get onDrag => (super.noSuchMethod(Invocation.getter(#onDrag), returnValue: Stream<_i2.MouseEvent>.empty()) - as _i4.Stream<_i2.MouseEvent>); + as _i3.Stream<_i2.MouseEvent>); @override - _i4.Stream<_i2.MouseEvent> get onDragEnd => + _i3.Stream<_i2.MouseEvent> get onDragEnd => (super.noSuchMethod(Invocation.getter(#onDragEnd), returnValue: Stream<_i2.MouseEvent>.empty()) - as _i4.Stream<_i2.MouseEvent>); + as _i3.Stream<_i2.MouseEvent>); @override - _i4.Stream<_i2.MouseEvent> get onDragEnter => + _i3.Stream<_i2.MouseEvent> get onDragEnter => (super.noSuchMethod(Invocation.getter(#onDragEnter), returnValue: Stream<_i2.MouseEvent>.empty()) - as _i4.Stream<_i2.MouseEvent>); + as _i3.Stream<_i2.MouseEvent>); @override - _i4.Stream<_i2.MouseEvent> get onDragLeave => + _i3.Stream<_i2.MouseEvent> get onDragLeave => (super.noSuchMethod(Invocation.getter(#onDragLeave), returnValue: Stream<_i2.MouseEvent>.empty()) - as _i4.Stream<_i2.MouseEvent>); + as _i3.Stream<_i2.MouseEvent>); @override - _i4.Stream<_i2.MouseEvent> get onDragOver => + _i3.Stream<_i2.MouseEvent> get onDragOver => (super.noSuchMethod(Invocation.getter(#onDragOver), returnValue: Stream<_i2.MouseEvent>.empty()) - as _i4.Stream<_i2.MouseEvent>); + as _i3.Stream<_i2.MouseEvent>); @override - _i4.Stream<_i2.MouseEvent> get onDragStart => + _i3.Stream<_i2.MouseEvent> get onDragStart => (super.noSuchMethod(Invocation.getter(#onDragStart), returnValue: Stream<_i2.MouseEvent>.empty()) - as _i4.Stream<_i2.MouseEvent>); + as _i3.Stream<_i2.MouseEvent>); @override - _i4.Stream<_i2.MouseEvent> get onDrop => + _i3.Stream<_i2.MouseEvent> get onDrop => (super.noSuchMethod(Invocation.getter(#onDrop), returnValue: Stream<_i2.MouseEvent>.empty()) - as _i4.Stream<_i2.MouseEvent>); + as _i3.Stream<_i2.MouseEvent>); @override - _i4.Stream<_i2.Event> get onDurationChange => + _i3.Stream<_i2.Event> get onDurationChange => (super.noSuchMethod(Invocation.getter(#onDurationChange), - returnValue: Stream<_i2.Event>.empty()) as _i4.Stream<_i2.Event>); + returnValue: Stream<_i2.Event>.empty()) as _i3.Stream<_i2.Event>); @override - _i4.Stream<_i2.Event> get onEmptied => + _i3.Stream<_i2.Event> get onEmptied => (super.noSuchMethod(Invocation.getter(#onEmptied), - returnValue: Stream<_i2.Event>.empty()) as _i4.Stream<_i2.Event>); + returnValue: Stream<_i2.Event>.empty()) as _i3.Stream<_i2.Event>); @override - _i4.Stream<_i2.Event> get onEnded => + _i3.Stream<_i2.Event> get onEnded => (super.noSuchMethod(Invocation.getter(#onEnded), - returnValue: Stream<_i2.Event>.empty()) as _i4.Stream<_i2.Event>); + returnValue: Stream<_i2.Event>.empty()) as _i3.Stream<_i2.Event>); @override - _i4.Stream<_i2.Event> get onError => + _i3.Stream<_i2.Event> get onError => (super.noSuchMethod(Invocation.getter(#onError), - returnValue: Stream<_i2.Event>.empty()) as _i4.Stream<_i2.Event>); + returnValue: Stream<_i2.Event>.empty()) as _i3.Stream<_i2.Event>); @override - _i4.Stream<_i2.Event> get onFocus => + _i3.Stream<_i2.Event> get onFocus => (super.noSuchMethod(Invocation.getter(#onFocus), - returnValue: Stream<_i2.Event>.empty()) as _i4.Stream<_i2.Event>); + returnValue: Stream<_i2.Event>.empty()) as _i3.Stream<_i2.Event>); @override - _i4.Stream<_i2.Event> get onHashChange => + _i3.Stream<_i2.Event> get onHashChange => (super.noSuchMethod(Invocation.getter(#onHashChange), - returnValue: Stream<_i2.Event>.empty()) as _i4.Stream<_i2.Event>); + returnValue: Stream<_i2.Event>.empty()) as _i3.Stream<_i2.Event>); @override - _i4.Stream<_i2.Event> get onInput => + _i3.Stream<_i2.Event> get onInput => (super.noSuchMethod(Invocation.getter(#onInput), - returnValue: Stream<_i2.Event>.empty()) as _i4.Stream<_i2.Event>); + returnValue: Stream<_i2.Event>.empty()) as _i3.Stream<_i2.Event>); @override - _i4.Stream<_i2.Event> get onInvalid => + _i3.Stream<_i2.Event> get onInvalid => (super.noSuchMethod(Invocation.getter(#onInvalid), - returnValue: Stream<_i2.Event>.empty()) as _i4.Stream<_i2.Event>); + returnValue: Stream<_i2.Event>.empty()) as _i3.Stream<_i2.Event>); @override - _i4.Stream<_i2.KeyboardEvent> get onKeyDown => + _i3.Stream<_i2.KeyboardEvent> get onKeyDown => (super.noSuchMethod(Invocation.getter(#onKeyDown), returnValue: Stream<_i2.KeyboardEvent>.empty()) - as _i4.Stream<_i2.KeyboardEvent>); + as _i3.Stream<_i2.KeyboardEvent>); @override - _i4.Stream<_i2.KeyboardEvent> get onKeyPress => + _i3.Stream<_i2.KeyboardEvent> get onKeyPress => (super.noSuchMethod(Invocation.getter(#onKeyPress), returnValue: Stream<_i2.KeyboardEvent>.empty()) - as _i4.Stream<_i2.KeyboardEvent>); + as _i3.Stream<_i2.KeyboardEvent>); @override - _i4.Stream<_i2.KeyboardEvent> get onKeyUp => + _i3.Stream<_i2.KeyboardEvent> get onKeyUp => (super.noSuchMethod(Invocation.getter(#onKeyUp), returnValue: Stream<_i2.KeyboardEvent>.empty()) - as _i4.Stream<_i2.KeyboardEvent>); + as _i3.Stream<_i2.KeyboardEvent>); @override - _i4.Stream<_i2.Event> get onLoad => + _i3.Stream<_i2.Event> get onLoad => (super.noSuchMethod(Invocation.getter(#onLoad), - returnValue: Stream<_i2.Event>.empty()) as _i4.Stream<_i2.Event>); + returnValue: Stream<_i2.Event>.empty()) as _i3.Stream<_i2.Event>); @override - _i4.Stream<_i2.Event> get onLoadedData => + _i3.Stream<_i2.Event> get onLoadedData => (super.noSuchMethod(Invocation.getter(#onLoadedData), - returnValue: Stream<_i2.Event>.empty()) as _i4.Stream<_i2.Event>); + returnValue: Stream<_i2.Event>.empty()) as _i3.Stream<_i2.Event>); @override - _i4.Stream<_i2.Event> get onLoadedMetadata => + _i3.Stream<_i2.Event> get onLoadedMetadata => (super.noSuchMethod(Invocation.getter(#onLoadedMetadata), - returnValue: Stream<_i2.Event>.empty()) as _i4.Stream<_i2.Event>); + returnValue: Stream<_i2.Event>.empty()) as _i3.Stream<_i2.Event>); @override - _i4.Stream<_i2.Event> get onLoadStart => + _i3.Stream<_i2.Event> get onLoadStart => (super.noSuchMethod(Invocation.getter(#onLoadStart), - returnValue: Stream<_i2.Event>.empty()) as _i4.Stream<_i2.Event>); + returnValue: Stream<_i2.Event>.empty()) as _i3.Stream<_i2.Event>); @override - _i4.Stream<_i2.MessageEvent> get onMessage => + _i3.Stream<_i2.MessageEvent> get onMessage => (super.noSuchMethod(Invocation.getter(#onMessage), returnValue: Stream<_i2.MessageEvent>.empty()) - as _i4.Stream<_i2.MessageEvent>); + as _i3.Stream<_i2.MessageEvent>); @override - _i4.Stream<_i2.MouseEvent> get onMouseDown => + _i3.Stream<_i2.MouseEvent> get onMouseDown => (super.noSuchMethod(Invocation.getter(#onMouseDown), returnValue: Stream<_i2.MouseEvent>.empty()) - as _i4.Stream<_i2.MouseEvent>); + as _i3.Stream<_i2.MouseEvent>); @override - _i4.Stream<_i2.MouseEvent> get onMouseEnter => + _i3.Stream<_i2.MouseEvent> get onMouseEnter => (super.noSuchMethod(Invocation.getter(#onMouseEnter), returnValue: Stream<_i2.MouseEvent>.empty()) - as _i4.Stream<_i2.MouseEvent>); + as _i3.Stream<_i2.MouseEvent>); @override - _i4.Stream<_i2.MouseEvent> get onMouseLeave => + _i3.Stream<_i2.MouseEvent> get onMouseLeave => (super.noSuchMethod(Invocation.getter(#onMouseLeave), returnValue: Stream<_i2.MouseEvent>.empty()) - as _i4.Stream<_i2.MouseEvent>); + as _i3.Stream<_i2.MouseEvent>); @override - _i4.Stream<_i2.MouseEvent> get onMouseMove => + _i3.Stream<_i2.MouseEvent> get onMouseMove => (super.noSuchMethod(Invocation.getter(#onMouseMove), returnValue: Stream<_i2.MouseEvent>.empty()) - as _i4.Stream<_i2.MouseEvent>); + as _i3.Stream<_i2.MouseEvent>); @override - _i4.Stream<_i2.MouseEvent> get onMouseOut => + _i3.Stream<_i2.MouseEvent> get onMouseOut => (super.noSuchMethod(Invocation.getter(#onMouseOut), returnValue: Stream<_i2.MouseEvent>.empty()) - as _i4.Stream<_i2.MouseEvent>); + as _i3.Stream<_i2.MouseEvent>); @override - _i4.Stream<_i2.MouseEvent> get onMouseOver => + _i3.Stream<_i2.MouseEvent> get onMouseOver => (super.noSuchMethod(Invocation.getter(#onMouseOver), returnValue: Stream<_i2.MouseEvent>.empty()) - as _i4.Stream<_i2.MouseEvent>); + as _i3.Stream<_i2.MouseEvent>); @override - _i4.Stream<_i2.MouseEvent> get onMouseUp => + _i3.Stream<_i2.MouseEvent> get onMouseUp => (super.noSuchMethod(Invocation.getter(#onMouseUp), returnValue: Stream<_i2.MouseEvent>.empty()) - as _i4.Stream<_i2.MouseEvent>); + as _i3.Stream<_i2.MouseEvent>); @override - _i4.Stream<_i2.WheelEvent> get onMouseWheel => + _i3.Stream<_i2.WheelEvent> get onMouseWheel => (super.noSuchMethod(Invocation.getter(#onMouseWheel), returnValue: Stream<_i2.WheelEvent>.empty()) - as _i4.Stream<_i2.WheelEvent>); + as _i3.Stream<_i2.WheelEvent>); @override - _i4.Stream<_i2.Event> get onOffline => + _i3.Stream<_i2.Event> get onOffline => (super.noSuchMethod(Invocation.getter(#onOffline), - returnValue: Stream<_i2.Event>.empty()) as _i4.Stream<_i2.Event>); + returnValue: Stream<_i2.Event>.empty()) as _i3.Stream<_i2.Event>); @override - _i4.Stream<_i2.Event> get onOnline => + _i3.Stream<_i2.Event> get onOnline => (super.noSuchMethod(Invocation.getter(#onOnline), - returnValue: Stream<_i2.Event>.empty()) as _i4.Stream<_i2.Event>); + returnValue: Stream<_i2.Event>.empty()) as _i3.Stream<_i2.Event>); @override - _i4.Stream<_i2.Event> get onPageHide => + _i3.Stream<_i2.Event> get onPageHide => (super.noSuchMethod(Invocation.getter(#onPageHide), - returnValue: Stream<_i2.Event>.empty()) as _i4.Stream<_i2.Event>); + returnValue: Stream<_i2.Event>.empty()) as _i3.Stream<_i2.Event>); @override - _i4.Stream<_i2.Event> get onPageShow => + _i3.Stream<_i2.Event> get onPageShow => (super.noSuchMethod(Invocation.getter(#onPageShow), - returnValue: Stream<_i2.Event>.empty()) as _i4.Stream<_i2.Event>); + returnValue: Stream<_i2.Event>.empty()) as _i3.Stream<_i2.Event>); @override - _i4.Stream<_i2.Event> get onPause => + _i3.Stream<_i2.Event> get onPause => (super.noSuchMethod(Invocation.getter(#onPause), - returnValue: Stream<_i2.Event>.empty()) as _i4.Stream<_i2.Event>); + returnValue: Stream<_i2.Event>.empty()) as _i3.Stream<_i2.Event>); @override - _i4.Stream<_i2.Event> get onPlay => + _i3.Stream<_i2.Event> get onPlay => (super.noSuchMethod(Invocation.getter(#onPlay), - returnValue: Stream<_i2.Event>.empty()) as _i4.Stream<_i2.Event>); + returnValue: Stream<_i2.Event>.empty()) as _i3.Stream<_i2.Event>); @override - _i4.Stream<_i2.Event> get onPlaying => + _i3.Stream<_i2.Event> get onPlaying => (super.noSuchMethod(Invocation.getter(#onPlaying), - returnValue: Stream<_i2.Event>.empty()) as _i4.Stream<_i2.Event>); + returnValue: Stream<_i2.Event>.empty()) as _i3.Stream<_i2.Event>); @override - _i4.Stream<_i2.PopStateEvent> get onPopState => + _i3.Stream<_i2.PopStateEvent> get onPopState => (super.noSuchMethod(Invocation.getter(#onPopState), returnValue: Stream<_i2.PopStateEvent>.empty()) - as _i4.Stream<_i2.PopStateEvent>); + as _i3.Stream<_i2.PopStateEvent>); @override - _i4.Stream<_i2.Event> get onProgress => + _i3.Stream<_i2.Event> get onProgress => (super.noSuchMethod(Invocation.getter(#onProgress), - returnValue: Stream<_i2.Event>.empty()) as _i4.Stream<_i2.Event>); + returnValue: Stream<_i2.Event>.empty()) as _i3.Stream<_i2.Event>); @override - _i4.Stream<_i2.Event> get onRateChange => + _i3.Stream<_i2.Event> get onRateChange => (super.noSuchMethod(Invocation.getter(#onRateChange), - returnValue: Stream<_i2.Event>.empty()) as _i4.Stream<_i2.Event>); + returnValue: Stream<_i2.Event>.empty()) as _i3.Stream<_i2.Event>); @override - _i4.Stream<_i2.Event> get onReset => + _i3.Stream<_i2.Event> get onReset => (super.noSuchMethod(Invocation.getter(#onReset), - returnValue: Stream<_i2.Event>.empty()) as _i4.Stream<_i2.Event>); + returnValue: Stream<_i2.Event>.empty()) as _i3.Stream<_i2.Event>); @override - _i4.Stream<_i2.Event> get onResize => + _i3.Stream<_i2.Event> get onResize => (super.noSuchMethod(Invocation.getter(#onResize), - returnValue: Stream<_i2.Event>.empty()) as _i4.Stream<_i2.Event>); + returnValue: Stream<_i2.Event>.empty()) as _i3.Stream<_i2.Event>); @override - _i4.Stream<_i2.Event> get onScroll => + _i3.Stream<_i2.Event> get onScroll => (super.noSuchMethod(Invocation.getter(#onScroll), - returnValue: Stream<_i2.Event>.empty()) as _i4.Stream<_i2.Event>); + returnValue: Stream<_i2.Event>.empty()) as _i3.Stream<_i2.Event>); @override - _i4.Stream<_i2.Event> get onSearch => + _i3.Stream<_i2.Event> get onSearch => (super.noSuchMethod(Invocation.getter(#onSearch), - returnValue: Stream<_i2.Event>.empty()) as _i4.Stream<_i2.Event>); + returnValue: Stream<_i2.Event>.empty()) as _i3.Stream<_i2.Event>); @override - _i4.Stream<_i2.Event> get onSeeked => + _i3.Stream<_i2.Event> get onSeeked => (super.noSuchMethod(Invocation.getter(#onSeeked), - returnValue: Stream<_i2.Event>.empty()) as _i4.Stream<_i2.Event>); + returnValue: Stream<_i2.Event>.empty()) as _i3.Stream<_i2.Event>); @override - _i4.Stream<_i2.Event> get onSeeking => + _i3.Stream<_i2.Event> get onSeeking => (super.noSuchMethod(Invocation.getter(#onSeeking), - returnValue: Stream<_i2.Event>.empty()) as _i4.Stream<_i2.Event>); + returnValue: Stream<_i2.Event>.empty()) as _i3.Stream<_i2.Event>); @override - _i4.Stream<_i2.Event> get onSelect => + _i3.Stream<_i2.Event> get onSelect => (super.noSuchMethod(Invocation.getter(#onSelect), - returnValue: Stream<_i2.Event>.empty()) as _i4.Stream<_i2.Event>); + returnValue: Stream<_i2.Event>.empty()) as _i3.Stream<_i2.Event>); @override - _i4.Stream<_i2.Event> get onStalled => + _i3.Stream<_i2.Event> get onStalled => (super.noSuchMethod(Invocation.getter(#onStalled), - returnValue: Stream<_i2.Event>.empty()) as _i4.Stream<_i2.Event>); + returnValue: Stream<_i2.Event>.empty()) as _i3.Stream<_i2.Event>); @override - _i4.Stream<_i2.StorageEvent> get onStorage => + _i3.Stream<_i2.StorageEvent> get onStorage => (super.noSuchMethod(Invocation.getter(#onStorage), returnValue: Stream<_i2.StorageEvent>.empty()) - as _i4.Stream<_i2.StorageEvent>); + as _i3.Stream<_i2.StorageEvent>); @override - _i4.Stream<_i2.Event> get onSubmit => + _i3.Stream<_i2.Event> get onSubmit => (super.noSuchMethod(Invocation.getter(#onSubmit), - returnValue: Stream<_i2.Event>.empty()) as _i4.Stream<_i2.Event>); + returnValue: Stream<_i2.Event>.empty()) as _i3.Stream<_i2.Event>); @override - _i4.Stream<_i2.Event> get onSuspend => + _i3.Stream<_i2.Event> get onSuspend => (super.noSuchMethod(Invocation.getter(#onSuspend), - returnValue: Stream<_i2.Event>.empty()) as _i4.Stream<_i2.Event>); + returnValue: Stream<_i2.Event>.empty()) as _i3.Stream<_i2.Event>); @override - _i4.Stream<_i2.Event> get onTimeUpdate => + _i3.Stream<_i2.Event> get onTimeUpdate => (super.noSuchMethod(Invocation.getter(#onTimeUpdate), - returnValue: Stream<_i2.Event>.empty()) as _i4.Stream<_i2.Event>); + returnValue: Stream<_i2.Event>.empty()) as _i3.Stream<_i2.Event>); @override - _i4.Stream<_i2.TouchEvent> get onTouchCancel => + _i3.Stream<_i2.TouchEvent> get onTouchCancel => (super.noSuchMethod(Invocation.getter(#onTouchCancel), returnValue: Stream<_i2.TouchEvent>.empty()) - as _i4.Stream<_i2.TouchEvent>); + as _i3.Stream<_i2.TouchEvent>); @override - _i4.Stream<_i2.TouchEvent> get onTouchEnd => + _i3.Stream<_i2.TouchEvent> get onTouchEnd => (super.noSuchMethod(Invocation.getter(#onTouchEnd), returnValue: Stream<_i2.TouchEvent>.empty()) - as _i4.Stream<_i2.TouchEvent>); + as _i3.Stream<_i2.TouchEvent>); @override - _i4.Stream<_i2.TouchEvent> get onTouchMove => + _i3.Stream<_i2.TouchEvent> get onTouchMove => (super.noSuchMethod(Invocation.getter(#onTouchMove), returnValue: Stream<_i2.TouchEvent>.empty()) - as _i4.Stream<_i2.TouchEvent>); + as _i3.Stream<_i2.TouchEvent>); @override - _i4.Stream<_i2.TouchEvent> get onTouchStart => + _i3.Stream<_i2.TouchEvent> get onTouchStart => (super.noSuchMethod(Invocation.getter(#onTouchStart), returnValue: Stream<_i2.TouchEvent>.empty()) - as _i4.Stream<_i2.TouchEvent>); + as _i3.Stream<_i2.TouchEvent>); @override - _i4.Stream<_i2.TransitionEvent> get onTransitionEnd => + _i3.Stream<_i2.TransitionEvent> get onTransitionEnd => (super.noSuchMethod(Invocation.getter(#onTransitionEnd), returnValue: Stream<_i2.TransitionEvent>.empty()) - as _i4.Stream<_i2.TransitionEvent>); + as _i3.Stream<_i2.TransitionEvent>); @override - _i4.Stream<_i2.Event> get onUnload => + _i3.Stream<_i2.Event> get onUnload => (super.noSuchMethod(Invocation.getter(#onUnload), - returnValue: Stream<_i2.Event>.empty()) as _i4.Stream<_i2.Event>); + returnValue: Stream<_i2.Event>.empty()) as _i3.Stream<_i2.Event>); @override - _i4.Stream<_i2.Event> get onVolumeChange => + _i3.Stream<_i2.Event> get onVolumeChange => (super.noSuchMethod(Invocation.getter(#onVolumeChange), - returnValue: Stream<_i2.Event>.empty()) as _i4.Stream<_i2.Event>); + returnValue: Stream<_i2.Event>.empty()) as _i3.Stream<_i2.Event>); @override - _i4.Stream<_i2.Event> get onWaiting => + _i3.Stream<_i2.Event> get onWaiting => (super.noSuchMethod(Invocation.getter(#onWaiting), - returnValue: Stream<_i2.Event>.empty()) as _i4.Stream<_i2.Event>); + returnValue: Stream<_i2.Event>.empty()) as _i3.Stream<_i2.Event>); @override - _i4.Stream<_i2.AnimationEvent> get onAnimationEnd => + _i3.Stream<_i2.AnimationEvent> get onAnimationEnd => (super.noSuchMethod(Invocation.getter(#onAnimationEnd), returnValue: Stream<_i2.AnimationEvent>.empty()) - as _i4.Stream<_i2.AnimationEvent>); + as _i3.Stream<_i2.AnimationEvent>); @override - _i4.Stream<_i2.AnimationEvent> get onAnimationIteration => + _i3.Stream<_i2.AnimationEvent> get onAnimationIteration => (super.noSuchMethod(Invocation.getter(#onAnimationIteration), returnValue: Stream<_i2.AnimationEvent>.empty()) - as _i4.Stream<_i2.AnimationEvent>); + as _i3.Stream<_i2.AnimationEvent>); @override - _i4.Stream<_i2.AnimationEvent> get onAnimationStart => + _i3.Stream<_i2.AnimationEvent> get onAnimationStart => (super.noSuchMethod(Invocation.getter(#onAnimationStart), returnValue: Stream<_i2.AnimationEvent>.empty()) - as _i4.Stream<_i2.AnimationEvent>); + as _i3.Stream<_i2.AnimationEvent>); @override - _i4.Stream<_i2.Event> get onBeforeUnload => + _i3.Stream<_i2.Event> get onBeforeUnload => (super.noSuchMethod(Invocation.getter(#onBeforeUnload), - returnValue: Stream<_i2.Event>.empty()) as _i4.Stream<_i2.Event>); + returnValue: Stream<_i2.Event>.empty()) as _i3.Stream<_i2.Event>); @override - _i4.Stream<_i2.WheelEvent> get onWheel => + _i3.Stream<_i2.WheelEvent> get onWheel => (super.noSuchMethod(Invocation.getter(#onWheel), returnValue: Stream<_i2.WheelEvent>.empty()) - as _i4.Stream<_i2.WheelEvent>); + as _i3.Stream<_i2.WheelEvent>); @override int get pageXOffset => (super.noSuchMethod(Invocation.getter(#pageXOffset), returnValue: 0) @@ -468,18 +484,12 @@ class MockWindow extends _i1.Mock implements _i2.Window { (super.noSuchMethod(Invocation.getter(#scrollY), returnValue: 0) as int); @override _i2.Events get on => - (super.noSuchMethod(Invocation.getter(#on), returnValue: _FakeEvents()) + (super.noSuchMethod(Invocation.getter(#on), returnValue: _FakeEvents_7()) as _i2.Events); @override - int get hashCode => - (super.noSuchMethod(Invocation.getter(#hashCode), returnValue: 0) as int); - @override - Type get runtimeType => (super.noSuchMethod(Invocation.getter(#runtimeType), - returnValue: _FakeType()) as Type); - @override _i2.WindowBase open(String? url, String? name, [String? options]) => (super.noSuchMethod(Invocation.method(#open, [url, name, options]), - returnValue: _FakeWindowBase()) as _i2.WindowBase); + returnValue: _FakeWindowBase_8()) as _i2.WindowBase); @override int requestAnimationFrame(_i2.FrameRequestCallback? callback) => (super.noSuchMethod(Invocation.method(#requestAnimationFrame, [callback]), @@ -489,25 +499,32 @@ class MockWindow extends _i1.Mock implements _i2.Window { super.noSuchMethod(Invocation.method(#cancelAnimationFrame, [id]), returnValueForMissingStub: null); @override - _i4.Future<_i2.FileSystem> requestFileSystem(int? size, + _i3.Future<_i2.FileSystem> requestFileSystem(int? size, {bool? persistent = false}) => (super.noSuchMethod( Invocation.method( #requestFileSystem, [size], {#persistent: persistent}), - returnValue: Future.value(_FakeFileSystem())) - as _i4.Future<_i2.FileSystem>); + returnValue: Future<_i2.FileSystem>.value(_FakeFileSystem_9())) + as _i3.Future<_i2.FileSystem>); + @override + void alert([String? message]) => + super.noSuchMethod(Invocation.method(#alert, [message]), + returnValueForMissingStub: null); @override void cancelIdleCallback(int? handle) => super.noSuchMethod(Invocation.method(#cancelIdleCallback, [handle]), returnValueForMissingStub: null); @override + void close() => super.noSuchMethod(Invocation.method(#close, []), + returnValueForMissingStub: null); + @override bool confirm([String? message]) => (super.noSuchMethod(Invocation.method(#confirm, [message]), returnValue: false) as bool); @override - _i4.Future fetch(dynamic input, [Map? init]) => + _i3.Future fetch(dynamic input, [Map? init]) => (super.noSuchMethod(Invocation.method(#fetch, [input, init]), - returnValue: Future.value(null)) as _i4.Future); + returnValue: Future.value()) as _i3.Future); @override bool find(String? string, bool? caseSensitive, bool? backwards, bool? wrap, bool? wholeWord, bool? searchInFrames, bool? showDialog) => @@ -527,7 +544,7 @@ class MockWindow extends _i1.Mock implements _i2.Window { _i2.Element? element, String? pseudoElement) => (super.noSuchMethod( Invocation.method(#getComputedStyleMap, [element, pseudoElement]), - returnValue: _FakeStylePropertyMapReadonly()) + returnValue: _FakeStylePropertyMapReadonly_10()) as _i2.StylePropertyMapReadonly); @override List<_i2.CssRule> getMatchedCssRules( @@ -538,7 +555,7 @@ class MockWindow extends _i1.Mock implements _i2.Window { @override _i2.MediaQueryList matchMedia(String? query) => (super.noSuchMethod(Invocation.method(#matchMedia, [query]), - returnValue: _FakeMediaQueryList()) as _i2.MediaQueryList); + returnValue: _FakeMediaQueryList_11()) as _i2.MediaQueryList); @override void moveBy(int? x, int? y) => super.noSuchMethod(Invocation.method(#moveBy, [x, y]), @@ -550,6 +567,9 @@ class MockWindow extends _i1.Mock implements _i2.Window { Invocation.method(#postMessage, [message, targetOrigin, transfer]), returnValueForMissingStub: null); @override + void print() => super.noSuchMethod(Invocation.method(#print, []), + returnValueForMissingStub: null); + @override int requestIdleCallback(_i2.IdleRequestCallback? callback, [Map? options]) => (super.noSuchMethod( @@ -564,9 +584,37 @@ class MockWindow extends _i1.Mock implements _i2.Window { super.noSuchMethod(Invocation.method(#resizeTo, [x, y]), returnValueForMissingStub: null); @override - _i4.Future<_i2.Entry> resolveLocalFileSystemUrl(String? url) => + void scroll( + [dynamic options_OR_x, + dynamic y, + Map? scrollOptions]) => + super.noSuchMethod( + Invocation.method(#scroll, [options_OR_x, y, scrollOptions]), + returnValueForMissingStub: null); + @override + void scrollBy( + [dynamic options_OR_x, + dynamic y, + Map? scrollOptions]) => + super.noSuchMethod( + Invocation.method(#scrollBy, [options_OR_x, y, scrollOptions]), + returnValueForMissingStub: null); + @override + void scrollTo( + [dynamic options_OR_x, + dynamic y, + Map? scrollOptions]) => + super.noSuchMethod( + Invocation.method(#scrollTo, [options_OR_x, y, scrollOptions]), + returnValueForMissingStub: null); + @override + void stop() => super.noSuchMethod(Invocation.method(#stop, []), + returnValueForMissingStub: null); + @override + _i3.Future<_i2.Entry> resolveLocalFileSystemUrl(String? url) => (super.noSuchMethod(Invocation.method(#resolveLocalFileSystemUrl, [url]), - returnValue: Future.value(_FakeEntry())) as _i4.Future<_i2.Entry>); + returnValue: Future<_i2.Entry>.value(_FakeEntry_12())) + as _i3.Future<_i2.Entry>); @override String atob(String? atob) => (super.noSuchMethod(Invocation.method(#atob, [atob]), returnValue: '') @@ -576,18 +624,10 @@ class MockWindow extends _i1.Mock implements _i2.Window { (super.noSuchMethod(Invocation.method(#btoa, [btoa]), returnValue: '') as String); @override - void moveTo(_i5.Point? p) => + void moveTo(_i4.Point? p) => super.noSuchMethod(Invocation.method(#moveTo, [p]), returnValueForMissingStub: null); @override - _i3.SqlDatabase openDatabase(String? name, String? version, - String? displayName, int? estimatedSize, - [_i2.DatabaseCallback? creationCallback]) => - (super.noSuchMethod( - Invocation.method(#openDatabase, - [name, version, displayName, estimatedSize, creationCallback]), - returnValue: _FakeSqlDatabase()) as _i3.SqlDatabase); - @override void addEventListener(String? type, _i2.EventListener? listener, [bool? useCapture]) => super.noSuchMethod( @@ -604,13 +644,7 @@ class MockWindow extends _i1.Mock implements _i2.Window { (super.noSuchMethod(Invocation.method(#dispatchEvent, [event]), returnValue: false) as bool); @override - bool operator ==(Object? other) => - (super.noSuchMethod(Invocation.method(#==, [other]), returnValue: false) - as bool); - @override - String toString() => - (super.noSuchMethod(Invocation.method(#toString, []), returnValue: '') - as String); + String toString() => super.toString(); } /// A class which mocks [Navigator]. @@ -628,7 +662,7 @@ class MockNavigator extends _i1.Mock implements _i2.Navigator { @override _i2.Geolocation get geolocation => (super.noSuchMethod(Invocation.getter(#geolocation), - returnValue: _FakeGeolocation()) as _i2.Geolocation); + returnValue: _FakeGeolocation_13()) as _i2.Geolocation); @override String get vendor => (super.noSuchMethod(Invocation.getter(#vendor), returnValue: '') @@ -658,69 +692,63 @@ class MockNavigator extends _i1.Mock implements _i2.Navigator { (super.noSuchMethod(Invocation.getter(#userAgent), returnValue: '') as String); @override - int get hashCode => - (super.noSuchMethod(Invocation.getter(#hashCode), returnValue: 0) as int); - @override - Type get runtimeType => (super.noSuchMethod(Invocation.getter(#runtimeType), - returnValue: _FakeType()) as Type); - @override List<_i2.Gamepad?> getGamepads() => (super.noSuchMethod(Invocation.method(#getGamepads, []), returnValue: <_i2.Gamepad?>[]) as List<_i2.Gamepad?>); @override - _i4.Future<_i2.MediaStream> getUserMedia( + _i3.Future<_i2.MediaStream> getUserMedia( {dynamic audio = false, dynamic video = false}) => (super.noSuchMethod( Invocation.method(#getUserMedia, [], {#audio: audio, #video: video}), returnValue: - Future.value(_FakeMediaStream())) as _i4.Future<_i2.MediaStream>); + Future<_i2.MediaStream>.value(_FakeMediaStream_14())) as _i3 + .Future<_i2.MediaStream>); @override - _i4.Future getBattery() => + void cancelKeyboardLock() => + super.noSuchMethod(Invocation.method(#cancelKeyboardLock, []), + returnValueForMissingStub: null); + @override + _i3.Future getBattery() => (super.noSuchMethod(Invocation.method(#getBattery, []), - returnValue: Future.value(null)) as _i4.Future); + returnValue: Future.value()) as _i3.Future); @override - _i4.Future<_i2.RelatedApplication> getInstalledRelatedApps() => + _i3.Future<_i2.RelatedApplication> getInstalledRelatedApps() => (super.noSuchMethod(Invocation.method(#getInstalledRelatedApps, []), - returnValue: Future.value(_FakeRelatedApplication())) - as _i4.Future<_i2.RelatedApplication>); + returnValue: Future<_i2.RelatedApplication>.value( + _FakeRelatedApplication_15())) + as _i3.Future<_i2.RelatedApplication>); @override - _i4.Future getVRDisplays() => + _i3.Future getVRDisplays() => (super.noSuchMethod(Invocation.method(#getVRDisplays, []), - returnValue: Future.value(null)) as _i4.Future); + returnValue: Future.value()) as _i3.Future); @override void registerProtocolHandler(String? scheme, String? url, String? title) => super.noSuchMethod( Invocation.method(#registerProtocolHandler, [scheme, url, title]), returnValueForMissingStub: null); @override - _i4.Future requestKeyboardLock([List? keyCodes]) => + _i3.Future requestKeyboardLock([List? keyCodes]) => (super.noSuchMethod(Invocation.method(#requestKeyboardLock, [keyCodes]), - returnValue: Future.value(null)) as _i4.Future); + returnValue: Future.value()) as _i3.Future); @override - _i4.Future requestMidiAccess([Map? options]) => + _i3.Future requestMidiAccess([Map? options]) => (super.noSuchMethod(Invocation.method(#requestMidiAccess, [options]), - returnValue: Future.value(null)) as _i4.Future); + returnValue: Future.value()) as _i3.Future); @override - _i4.Future requestMediaKeySystemAccess(String? keySystem, + _i3.Future requestMediaKeySystemAccess(String? keySystem, List>? supportedConfigurations) => (super.noSuchMethod( Invocation.method(#requestMediaKeySystemAccess, [keySystem, supportedConfigurations]), - returnValue: Future.value(null)) as _i4.Future); + returnValue: Future.value()) as _i3.Future); @override bool sendBeacon(String? url, Object? data) => (super.noSuchMethod(Invocation.method(#sendBeacon, [url, data]), returnValue: false) as bool); @override - _i4.Future share([Map? data]) => + _i3.Future share([Map? data]) => (super.noSuchMethod(Invocation.method(#share, [data]), - returnValue: Future.value(null)) as _i4.Future); + returnValue: Future.value()) as _i3.Future); @override - bool operator ==(Object? other) => - (super.noSuchMethod(Invocation.method(#==, [other]), returnValue: false) - as bool); - @override - String toString() => - (super.noSuchMethod(Invocation.method(#toString, []), returnValue: '') - as String); + String toString() => super.toString(); } diff --git a/packages/url_launcher/url_launcher_web/example/pubspec.yaml b/packages/url_launcher/url_launcher_web/example/pubspec.yaml index 7c00c33550a8..872bc8873b5c 100644 --- a/packages/url_launcher/url_launcher_web/example/pubspec.yaml +++ b/packages/url_launcher/url_launcher_web/example/pubspec.yaml @@ -10,7 +10,7 @@ dependencies: sdk: flutter dev_dependencies: - build_runner: ^1.10.0 + build_runner: ^2.1.1 mockito: ^5.0.0 url_launcher_web: path: ../ diff --git a/packages/webview_flutter/webview_flutter_android/generatePigeons.sh b/packages/webview_flutter/webview_flutter_android/generatePigeons.sh new file mode 100755 index 000000000000..d866473636cc --- /dev/null +++ b/packages/webview_flutter/webview_flutter_android/generatePigeons.sh @@ -0,0 +1,8 @@ +# 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. + +flutter pub run pigeon \ +--input pigeons/android_webview.dart \ +--dart_out lib/src/android_webview.pigeon.dart \ +--dart_test_out test/android_webview.pigeon.dart diff --git a/packages/webview_flutter/webview_flutter_android/lib/src/android_webview.dart b/packages/webview_flutter/webview_flutter_android/lib/src/android_webview.dart new file mode 100644 index 000000000000..1ddd6f3d9f0f --- /dev/null +++ b/packages/webview_flutter/webview_flutter_android/lib/src/android_webview.dart @@ -0,0 +1,648 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:flutter/foundation.dart'; +import 'package:flutter/widgets.dart' show AndroidViewSurface; + +import 'android_webview_api_impls.dart'; + +// TODO(bparrishMines): This can be removed once pigeon supports null values: https://github.com/flutter/flutter/issues/59118 +// Workaround to represent null Strings since pigeon doesn't support null +// values. +const String _nullStringIdentifier = ''; + +/// 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). +class WebView { + /// Constructs a new WebView. + WebView({this.useHybridComposition = false}) { + api.createFromInstance(this); + } + + /// Pigeon Host Api implementation for [WebView]. + @visibleForTesting + static WebViewHostApiImpl api = WebViewHostApiImpl(); + + WebViewClient? _currentWebViewClient; + DownloadListener? _currentDownloadListener; + WebChromeClient? _currentWebChromeClient; + Set _javaScriptChannels = {}; + + /// 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 setWebContentsDebuggingEnabled(bool enabled) { + return api.setWebContentsDebuggingEnabled(enabled); + } + + /// 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 loadUrl(String url, Map headers) { + return api.loadUrlFromInstance(this, url, headers); + } + + /// 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 getUrl() async { + final String result = await api.getUrlFromInstance(this); + if (result == _nullStringIdentifier) return null; + return result; + } + + /// Whether this WebView has a back history item. + Future canGoBack() { + return api.canGoBackFromInstance(this); + } + + /// Whether this WebView has a forward history item. + Future canGoForward() { + return api.canGoForwardFromInstance(this); + } + + /// Goes back in the history of this WebView. + Future goBack() { + return api.goBackFromInstance(this); + } + + /// Goes forward in the history of this WebView. + Future goForward() { + return api.goForwardFromInstance(this); + } + + /// Reloads the current URL. + Future 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 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 evaluateJavascript(String javascriptString) async { + final String result = await api.evaluateJavascriptFromInstance( + this, + javascriptString, + ); + if (result == _nullStringIdentifier) return null; + return result; + } + + // 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 getTitle() async { + final String result = await api.getTitleFromInstance(this); + if (result == _nullStringIdentifier) return null; + return result; + } + + // TODO(bparrishMines): Update documentation when onScrollChanged is added. + /// Set the scrolled position of your view. + Future 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 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 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 getScrollY() { + return api.getScrollYFromInstance(this); + } + + /// Sets the [WebViewClient] that will receive various notifications and requests. + /// + /// This will replace the current handler. + Future setWebViewClient(WebViewClient webViewClient) { + final WebViewClient? currentWebViewClient = _currentWebViewClient; + + if (webViewClient == currentWebViewClient) { + return Future.value(); + } + + if (currentWebViewClient != null) { + WebViewClient.api.disposeFromInstance(currentWebViewClient); + } + + WebViewClient.api.createFromInstance(webViewClient); + _currentWebViewClient = 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", {}); + /// webView.loadUrl("javascript:injectedObject.postMessage("Hello, World!")", {}); + /// ``` + /// + /// **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 addJavaScriptChannel(JavaScriptChannel javaScriptChannel) { + JavaScriptChannel.api.createFromInstance(javaScriptChannel); + _javaScriptChannels.add(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 removeJavaScriptChannel(JavaScriptChannel javaScriptChannel) { + _javaScriptChannels.remove(javaScriptChannel); + api.removeJavaScriptChannelFromInstance(this, javaScriptChannel); + return JavaScriptChannel.api.disposeFromInstance(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 setDownloadListener(DownloadListener listener) { + final DownloadListener? currentDownloadListener = _currentDownloadListener; + + if (listener == currentDownloadListener) { + return Future.value(); + } + + if (currentDownloadListener != null) { + DownloadListener.api.disposeFromInstance(currentDownloadListener); + } + + DownloadListener.api.createFromInstance(listener); + _currentDownloadListener = listener; + return 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 setWebChromeClient(WebChromeClient client) { + final WebChromeClient? currentWebChromeClient = _currentWebChromeClient; + + if (client == currentWebChromeClient) { + return Future.value(); + } + + if (currentWebChromeClient != null) { + WebChromeClient.api.disposeFromInstance(currentWebChromeClient); + } + + final WebViewClient? currentWebViewClient = _currentWebViewClient; + assert( + currentWebViewClient != null, + "Can't set a WebChromeClient without setting a WebViewClient first.", + ); + + WebChromeClient.api.createFromInstance(client, currentWebViewClient!); + _currentWebChromeClient = client; + return api.setWebChromeClientFromInstance(this, client); + } +} + +/// 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 { + /// Constructs a [WebSettings]. + /// + /// This constructor is only used for testing. An instance should be obtained + /// with [WebView.settings]. + @visibleForTesting + WebSettings(WebView webView) { + api.createFromInstance(this, webView); + } + + /// 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 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 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 setSupportMultipleWindows(bool support) { + return api.setSupportZoomFromInstance(this, support); + } + + /// Tells the WebView to enable JavaScript execution. + /// + /// The default is false. + Future 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 setUserAgentString(String userAgentString) { + return api.setUserAgentStringFromInstance(this, userAgentString); + } + + /// Sets whether the WebView requires a user gesture to play media. + /// + /// The default is true. + Future 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 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 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 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 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 setBuiltInZoomControls(bool enabled) { + return api.setBuiltInZoomControlsFromInstance(this, enabled); + } +} + +/// Exposes a channel to receive calls from javaScript. +/// +/// See [WebView.addJavaScriptChannel]. +abstract class JavaScriptChannel { + /// Constructs a [JavaScriptChannel]. + JavaScriptChannel(this.channelName); + + /// 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) {} +} + +/// Receive various notifications and requests for [WebView]. +abstract class WebViewClient { + /// Constructs a [WebViewClient]. + WebViewClient({this.shouldOverrideUrlLoading = true}); + + /// User authentication failed on server. + static const int errorAuthentication = 0xfffffffc; + + /// Malformed URL. + static const int errorBadUrl = 0xfffffff4; + + /// Failed to connect to the server. + static const int errorConnect = 0xfffffffa; + + /// Failed to perform SSL handshake. + static const int errorFailedSslHandshake = 0xfffffff5; + + /// Generic file error. + static const int errorFile = 0xfffffff3; + + /// File not found. + static const int errorFileNotFound = 0xfffffff2; + + /// Server or proxy hostname lookup failed. + static const int errorHostLookup = 0xfffffffe; + + /// Failed to read or write to the server. + static const int errorIO = 0xfffffff9; + + /// User authentication failed on proxy. + static const int errorProxyAuthentication = 0xfffffffb; + + /// Too many redirects. + static const int errorRedirectLoop = 0xfffffff7; + + /// Connection timed out. + static const int errorTimeout = 0xfffffff8; + + /// Too many requests during this load. + static const int errorTooManyRequests = 0xfffffff1; + + /// Generic error. + static const int errorUnknown = 0xffffffff; + + /// Resource load was canceled by Safe Browsing. + static const int errorUnsafeResource = 0xfffffff0; + + /// Unsupported authentication scheme (not basic or digest). + static const int errorUnsupportedAuthScheme = 0xfffffffd; + + /// Unsupported URI scheme. + static const int errorUnsupportedScheme = 0xfffffff6; + + /// 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) {} +} + +/// The interface to be used when content can not be handled by the rendering engine for [WebView], and should be downloaded instead. +abstract class DownloadListener { + /// 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, + ); +} + +/// Handles JavaScript dialogs, favicons, titles, and the progress for [WebView]. +abstract class WebChromeClient { + /// 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); +} + +/// 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, + }); + + /// Gets the URL for which the resource request was made. + final String url; + + /// Gets whether the request was made in order to fetch the main frame's document. + final isForMainFrame; + + /// Gets whether the request was a result of a server-side redirect. + /// + /// Only supported on Android version >= 24. + final bool? isRedirect; + + /// Gets whether a gesture (such as a click) was associated with the request. + final bool hasGesture; + + /// Gets the method associated with the request, for example "GET". + final String method; + + /// Gets the headers associated with the request. + final Map 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; +} diff --git a/packages/webview_flutter/webview_flutter_android/lib/src/android_webview.pigeon.dart b/packages/webview_flutter/webview_flutter_android/lib/src/android_webview.pigeon.dart new file mode 100644 index 000000000000..81ec7c7bf80e --- /dev/null +++ b/packages/webview_flutter/webview_flutter_android/lib/src/android_webview.pigeon.dart @@ -0,0 +1,1601 @@ +// 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.7), 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, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, unused_shown_name +// @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'; + +class WebResourceRequestData { + String? url; + bool? isForMainFrame; + bool? isRedirect; + bool? hasGesture; + String? method; + Map? requestHeaders; + + Object encode() { + final Map pigeonMap = {}; + pigeonMap['url'] = url; + pigeonMap['isForMainFrame'] = isForMainFrame; + pigeonMap['isRedirect'] = isRedirect; + pigeonMap['hasGesture'] = hasGesture; + pigeonMap['method'] = method; + pigeonMap['requestHeaders'] = requestHeaders; + return pigeonMap; + } + + static WebResourceRequestData decode(Object message) { + final Map pigeonMap = message as Map; + return WebResourceRequestData() + ..url = pigeonMap['url'] as String? + ..isForMainFrame = pigeonMap['isForMainFrame'] as bool? + ..isRedirect = pigeonMap['isRedirect'] as bool? + ..hasGesture = pigeonMap['hasGesture'] as bool? + ..method = pigeonMap['method'] as String? + ..requestHeaders = (pigeonMap['requestHeaders'] as Map?) + ?.cast(); + } +} + +class WebResourceErrorData { + int? errorCode; + String? description; + + Object encode() { + final Map pigeonMap = {}; + pigeonMap['errorCode'] = errorCode; + pigeonMap['description'] = description; + return pigeonMap; + } + + static WebResourceErrorData decode(Object message) { + final Map pigeonMap = message as Map; + return WebResourceErrorData() + ..errorCode = pigeonMap['errorCode'] as int? + ..description = pigeonMap['description'] as String?; + } +} + +class _WebViewHostApiCodec extends StandardMessageCodec { + const _WebViewHostApiCodec(); +} + +class WebViewHostApi { + /// Constructor for [WebViewHostApi]. The [binaryMessenger] named argument is + /// available for dependency injection. If it is left null, the default + /// BinaryMessenger will be used which routes to the host platform. + WebViewHostApi({BinaryMessenger? binaryMessenger}) + : _binaryMessenger = binaryMessenger; + + final BinaryMessenger? _binaryMessenger; + + static const MessageCodec codec = _WebViewHostApiCodec(); + + Future create(int arg_instanceId, bool arg_useHybridComposition) async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.WebViewHostApi.create', codec, + binaryMessenger: _binaryMessenger); + final Map? replyMap = + await channel.send([arg_instanceId, arg_useHybridComposition]) + as Map?; + if (replyMap == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + details: null, + ); + } else if (replyMap['error'] != null) { + final Map error = + (replyMap['error'] as Map?)!; + throw PlatformException( + code: (error['code'] as String?)!, + message: error['message'] as String?, + details: error['details'], + ); + } else { + return; + } + } + + Future dispose(int arg_instanceId) async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.WebViewHostApi.dispose', codec, + binaryMessenger: _binaryMessenger); + final Map? replyMap = + await channel.send([arg_instanceId]) as Map?; + if (replyMap == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + details: null, + ); + } else if (replyMap['error'] != null) { + final Map error = + (replyMap['error'] as Map?)!; + throw PlatformException( + code: (error['code'] as String?)!, + message: error['message'] as String?, + details: error['details'], + ); + } else { + return; + } + } + + Future loadUrl(int arg_instanceId, String arg_url, + Map arg_headers) async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.WebViewHostApi.loadUrl', codec, + binaryMessenger: _binaryMessenger); + final Map? replyMap = + await channel.send([arg_instanceId, arg_url, arg_headers]) + as Map?; + if (replyMap == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + details: null, + ); + } else if (replyMap['error'] != null) { + final Map error = + (replyMap['error'] as Map?)!; + throw PlatformException( + code: (error['code'] as String?)!, + message: error['message'] as String?, + details: error['details'], + ); + } else { + return; + } + } + + Future getUrl(int arg_instanceId) async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.WebViewHostApi.getUrl', codec, + binaryMessenger: _binaryMessenger); + final Map? replyMap = + await channel.send([arg_instanceId]) as Map?; + if (replyMap == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + details: null, + ); + } else if (replyMap['error'] != null) { + final Map error = + (replyMap['error'] as Map?)!; + throw PlatformException( + code: (error['code'] as String?)!, + message: error['message'] as String?, + details: error['details'], + ); + } else { + return (replyMap['result'] as String?)!; + } + } + + Future canGoBack(int arg_instanceId) async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.WebViewHostApi.canGoBack', codec, + binaryMessenger: _binaryMessenger); + final Map? replyMap = + await channel.send([arg_instanceId]) as Map?; + if (replyMap == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + details: null, + ); + } else if (replyMap['error'] != null) { + final Map error = + (replyMap['error'] as Map?)!; + throw PlatformException( + code: (error['code'] as String?)!, + message: error['message'] as String?, + details: error['details'], + ); + } else { + return (replyMap['result'] as bool?)!; + } + } + + Future canGoForward(int arg_instanceId) async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.WebViewHostApi.canGoForward', codec, + binaryMessenger: _binaryMessenger); + final Map? replyMap = + await channel.send([arg_instanceId]) as Map?; + if (replyMap == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + details: null, + ); + } else if (replyMap['error'] != null) { + final Map error = + (replyMap['error'] as Map?)!; + throw PlatformException( + code: (error['code'] as String?)!, + message: error['message'] as String?, + details: error['details'], + ); + } else { + return (replyMap['result'] as bool?)!; + } + } + + Future goBack(int arg_instanceId) async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.WebViewHostApi.goBack', codec, + binaryMessenger: _binaryMessenger); + final Map? replyMap = + await channel.send([arg_instanceId]) as Map?; + if (replyMap == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + details: null, + ); + } else if (replyMap['error'] != null) { + final Map error = + (replyMap['error'] as Map?)!; + throw PlatformException( + code: (error['code'] as String?)!, + message: error['message'] as String?, + details: error['details'], + ); + } else { + return; + } + } + + Future goForward(int arg_instanceId) async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.WebViewHostApi.goForward', codec, + binaryMessenger: _binaryMessenger); + final Map? replyMap = + await channel.send([arg_instanceId]) as Map?; + if (replyMap == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + details: null, + ); + } else if (replyMap['error'] != null) { + final Map error = + (replyMap['error'] as Map?)!; + throw PlatformException( + code: (error['code'] as String?)!, + message: error['message'] as String?, + details: error['details'], + ); + } else { + return; + } + } + + Future reload(int arg_instanceId) async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.WebViewHostApi.reload', codec, + binaryMessenger: _binaryMessenger); + final Map? replyMap = + await channel.send([arg_instanceId]) as Map?; + if (replyMap == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + details: null, + ); + } else if (replyMap['error'] != null) { + final Map error = + (replyMap['error'] as Map?)!; + throw PlatformException( + code: (error['code'] as String?)!, + message: error['message'] as String?, + details: error['details'], + ); + } else { + return; + } + } + + Future clearCache(int arg_instanceId, bool arg_includeDiskFiles) async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.WebViewHostApi.clearCache', codec, + binaryMessenger: _binaryMessenger); + final Map? replyMap = + await channel.send([arg_instanceId, arg_includeDiskFiles]) + as Map?; + if (replyMap == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + details: null, + ); + } else if (replyMap['error'] != null) { + final Map error = + (replyMap['error'] as Map?)!; + throw PlatformException( + code: (error['code'] as String?)!, + message: error['message'] as String?, + details: error['details'], + ); + } else { + return; + } + } + + Future evaluateJavascript( + int arg_instanceId, String arg_javascriptString) async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.WebViewHostApi.evaluateJavascript', codec, + binaryMessenger: _binaryMessenger); + final Map? replyMap = + await channel.send([arg_instanceId, arg_javascriptString]) + as Map?; + if (replyMap == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + details: null, + ); + } else if (replyMap['error'] != null) { + final Map error = + (replyMap['error'] as Map?)!; + throw PlatformException( + code: (error['code'] as String?)!, + message: error['message'] as String?, + details: error['details'], + ); + } else { + return (replyMap['result'] as String?)!; + } + } + + Future getTitle(int arg_instanceId) async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.WebViewHostApi.getTitle', codec, + binaryMessenger: _binaryMessenger); + final Map? replyMap = + await channel.send([arg_instanceId]) as Map?; + if (replyMap == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + details: null, + ); + } else if (replyMap['error'] != null) { + final Map error = + (replyMap['error'] as Map?)!; + throw PlatformException( + code: (error['code'] as String?)!, + message: error['message'] as String?, + details: error['details'], + ); + } else { + return (replyMap['result'] as String?)!; + } + } + + Future scrollTo(int arg_instanceId, int arg_x, int arg_y) async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.WebViewHostApi.scrollTo', codec, + binaryMessenger: _binaryMessenger); + final Map? replyMap = await channel + .send([arg_instanceId, arg_x, arg_y]) as Map?; + if (replyMap == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + details: null, + ); + } else if (replyMap['error'] != null) { + final Map error = + (replyMap['error'] as Map?)!; + throw PlatformException( + code: (error['code'] as String?)!, + message: error['message'] as String?, + details: error['details'], + ); + } else { + return; + } + } + + Future scrollBy(int arg_instanceId, int arg_x, int arg_y) async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.WebViewHostApi.scrollBy', codec, + binaryMessenger: _binaryMessenger); + final Map? replyMap = await channel + .send([arg_instanceId, arg_x, arg_y]) as Map?; + if (replyMap == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + details: null, + ); + } else if (replyMap['error'] != null) { + final Map error = + (replyMap['error'] as Map?)!; + throw PlatformException( + code: (error['code'] as String?)!, + message: error['message'] as String?, + details: error['details'], + ); + } else { + return; + } + } + + Future getScrollX(int arg_instanceId) async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.WebViewHostApi.getScrollX', codec, + binaryMessenger: _binaryMessenger); + final Map? replyMap = + await channel.send([arg_instanceId]) as Map?; + if (replyMap == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + details: null, + ); + } else if (replyMap['error'] != null) { + final Map error = + (replyMap['error'] as Map?)!; + throw PlatformException( + code: (error['code'] as String?)!, + message: error['message'] as String?, + details: error['details'], + ); + } else { + return (replyMap['result'] as int?)!; + } + } + + Future getScrollY(int arg_instanceId) async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.WebViewHostApi.getScrollY', codec, + binaryMessenger: _binaryMessenger); + final Map? replyMap = + await channel.send([arg_instanceId]) as Map?; + if (replyMap == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + details: null, + ); + } else if (replyMap['error'] != null) { + final Map error = + (replyMap['error'] as Map?)!; + throw PlatformException( + code: (error['code'] as String?)!, + message: error['message'] as String?, + details: error['details'], + ); + } else { + return (replyMap['result'] as int?)!; + } + } + + Future setWebContentsDebuggingEnabled(bool arg_enabled) async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.WebViewHostApi.setWebContentsDebuggingEnabled', + codec, + binaryMessenger: _binaryMessenger); + final Map? replyMap = + await channel.send([arg_enabled]) as Map?; + if (replyMap == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + details: null, + ); + } else if (replyMap['error'] != null) { + final Map error = + (replyMap['error'] as Map?)!; + throw PlatformException( + code: (error['code'] as String?)!, + message: error['message'] as String?, + details: error['details'], + ); + } else { + return; + } + } + + Future setWebViewClient( + int arg_instanceId, int arg_webViewClientInstanceId) async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.WebViewHostApi.setWebViewClient', codec, + binaryMessenger: _binaryMessenger); + final Map? replyMap = await channel + .send([arg_instanceId, arg_webViewClientInstanceId]) + as Map?; + if (replyMap == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + details: null, + ); + } else if (replyMap['error'] != null) { + final Map error = + (replyMap['error'] as Map?)!; + throw PlatformException( + code: (error['code'] as String?)!, + message: error['message'] as String?, + details: error['details'], + ); + } else { + return; + } + } + + Future addJavaScriptChannel( + int arg_instanceId, int arg_javaScriptChannelInstanceId) async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.WebViewHostApi.addJavaScriptChannel', codec, + binaryMessenger: _binaryMessenger); + final Map? replyMap = await channel + .send([arg_instanceId, arg_javaScriptChannelInstanceId]) + as Map?; + if (replyMap == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + details: null, + ); + } else if (replyMap['error'] != null) { + final Map error = + (replyMap['error'] as Map?)!; + throw PlatformException( + code: (error['code'] as String?)!, + message: error['message'] as String?, + details: error['details'], + ); + } else { + return; + } + } + + Future removeJavaScriptChannel( + int arg_instanceId, int arg_javaScriptChannelInstanceId) async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.WebViewHostApi.removeJavaScriptChannel', codec, + binaryMessenger: _binaryMessenger); + final Map? replyMap = await channel + .send([arg_instanceId, arg_javaScriptChannelInstanceId]) + as Map?; + if (replyMap == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + details: null, + ); + } else if (replyMap['error'] != null) { + final Map error = + (replyMap['error'] as Map?)!; + throw PlatformException( + code: (error['code'] as String?)!, + message: error['message'] as String?, + details: error['details'], + ); + } else { + return; + } + } + + Future setDownloadListener( + int arg_instanceId, int arg_listenerInstanceId) async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.WebViewHostApi.setDownloadListener', codec, + binaryMessenger: _binaryMessenger); + final Map? replyMap = + await channel.send([arg_instanceId, arg_listenerInstanceId]) + as Map?; + if (replyMap == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + details: null, + ); + } else if (replyMap['error'] != null) { + final Map error = + (replyMap['error'] as Map?)!; + throw PlatformException( + code: (error['code'] as String?)!, + message: error['message'] as String?, + details: error['details'], + ); + } else { + return; + } + } + + Future setWebChromeClient( + int arg_instanceId, int arg_clientInstanceId) async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.WebViewHostApi.setWebChromeClient', codec, + binaryMessenger: _binaryMessenger); + final Map? replyMap = + await channel.send([arg_instanceId, arg_clientInstanceId]) + as Map?; + if (replyMap == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + details: null, + ); + } else if (replyMap['error'] != null) { + final Map error = + (replyMap['error'] as Map?)!; + throw PlatformException( + code: (error['code'] as String?)!, + message: error['message'] as String?, + details: error['details'], + ); + } else { + return; + } + } +} + +class _WebSettingsHostApiCodec extends StandardMessageCodec { + const _WebSettingsHostApiCodec(); +} + +class WebSettingsHostApi { + /// Constructor for [WebSettingsHostApi]. The [binaryMessenger] named argument is + /// available for dependency injection. If it is left null, the default + /// BinaryMessenger will be used which routes to the host platform. + WebSettingsHostApi({BinaryMessenger? binaryMessenger}) + : _binaryMessenger = binaryMessenger; + + final BinaryMessenger? _binaryMessenger; + + static const MessageCodec codec = _WebSettingsHostApiCodec(); + + Future create(int arg_instanceId, int arg_webViewInstanceId) async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.WebSettingsHostApi.create', codec, + binaryMessenger: _binaryMessenger); + final Map? replyMap = + await channel.send([arg_instanceId, arg_webViewInstanceId]) + as Map?; + if (replyMap == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + details: null, + ); + } else if (replyMap['error'] != null) { + final Map error = + (replyMap['error'] as Map?)!; + throw PlatformException( + code: (error['code'] as String?)!, + message: error['message'] as String?, + details: error['details'], + ); + } else { + return; + } + } + + Future dispose(int arg_instanceId) async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.WebSettingsHostApi.dispose', codec, + binaryMessenger: _binaryMessenger); + final Map? replyMap = + await channel.send([arg_instanceId]) as Map?; + if (replyMap == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + details: null, + ); + } else if (replyMap['error'] != null) { + final Map error = + (replyMap['error'] as Map?)!; + throw PlatformException( + code: (error['code'] as String?)!, + message: error['message'] as String?, + details: error['details'], + ); + } else { + return; + } + } + + Future setDomStorageEnabled(int arg_instanceId, bool arg_flag) async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.WebSettingsHostApi.setDomStorageEnabled', codec, + binaryMessenger: _binaryMessenger); + final Map? replyMap = await channel + .send([arg_instanceId, arg_flag]) as Map?; + if (replyMap == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + details: null, + ); + } else if (replyMap['error'] != null) { + final Map error = + (replyMap['error'] as Map?)!; + throw PlatformException( + code: (error['code'] as String?)!, + message: error['message'] as String?, + details: error['details'], + ); + } else { + return; + } + } + + Future setJavaScriptCanOpenWindowsAutomatically( + int arg_instanceId, bool arg_flag) async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.WebSettingsHostApi.setJavaScriptCanOpenWindowsAutomatically', + codec, + binaryMessenger: _binaryMessenger); + final Map? replyMap = await channel + .send([arg_instanceId, arg_flag]) as Map?; + if (replyMap == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + details: null, + ); + } else if (replyMap['error'] != null) { + final Map error = + (replyMap['error'] as Map?)!; + throw PlatformException( + code: (error['code'] as String?)!, + message: error['message'] as String?, + details: error['details'], + ); + } else { + return; + } + } + + Future setSupportMultipleWindows( + int arg_instanceId, bool arg_support) async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.WebSettingsHostApi.setSupportMultipleWindows', + codec, + binaryMessenger: _binaryMessenger); + final Map? replyMap = await channel + .send([arg_instanceId, arg_support]) as Map?; + if (replyMap == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + details: null, + ); + } else if (replyMap['error'] != null) { + final Map error = + (replyMap['error'] as Map?)!; + throw PlatformException( + code: (error['code'] as String?)!, + message: error['message'] as String?, + details: error['details'], + ); + } else { + return; + } + } + + Future setJavaScriptEnabled(int arg_instanceId, bool arg_flag) async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.WebSettingsHostApi.setJavaScriptEnabled', codec, + binaryMessenger: _binaryMessenger); + final Map? replyMap = await channel + .send([arg_instanceId, arg_flag]) as Map?; + if (replyMap == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + details: null, + ); + } else if (replyMap['error'] != null) { + final Map error = + (replyMap['error'] as Map?)!; + throw PlatformException( + code: (error['code'] as String?)!, + message: error['message'] as String?, + details: error['details'], + ); + } else { + return; + } + } + + Future setUserAgentString( + int arg_instanceId, String arg_userAgentString) async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.WebSettingsHostApi.setUserAgentString', codec, + binaryMessenger: _binaryMessenger); + final Map? replyMap = + await channel.send([arg_instanceId, arg_userAgentString]) + as Map?; + if (replyMap == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + details: null, + ); + } else if (replyMap['error'] != null) { + final Map error = + (replyMap['error'] as Map?)!; + throw PlatformException( + code: (error['code'] as String?)!, + message: error['message'] as String?, + details: error['details'], + ); + } else { + return; + } + } + + Future setMediaPlaybackRequiresUserGesture( + int arg_instanceId, bool arg_require) async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.WebSettingsHostApi.setMediaPlaybackRequiresUserGesture', + codec, + binaryMessenger: _binaryMessenger); + final Map? replyMap = await channel + .send([arg_instanceId, arg_require]) as Map?; + if (replyMap == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + details: null, + ); + } else if (replyMap['error'] != null) { + final Map error = + (replyMap['error'] as Map?)!; + throw PlatformException( + code: (error['code'] as String?)!, + message: error['message'] as String?, + details: error['details'], + ); + } else { + return; + } + } + + Future setSupportZoom(int arg_instanceId, bool arg_support) async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.WebSettingsHostApi.setSupportZoom', codec, + binaryMessenger: _binaryMessenger); + final Map? replyMap = await channel + .send([arg_instanceId, arg_support]) as Map?; + if (replyMap == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + details: null, + ); + } else if (replyMap['error'] != null) { + final Map error = + (replyMap['error'] as Map?)!; + throw PlatformException( + code: (error['code'] as String?)!, + message: error['message'] as String?, + details: error['details'], + ); + } else { + return; + } + } + + Future setLoadWithOverviewMode( + int arg_instanceId, bool arg_overview) async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.WebSettingsHostApi.setLoadWithOverviewMode', codec, + binaryMessenger: _binaryMessenger); + final Map? replyMap = await channel + .send([arg_instanceId, arg_overview]) as Map?; + if (replyMap == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + details: null, + ); + } else if (replyMap['error'] != null) { + final Map error = + (replyMap['error'] as Map?)!; + throw PlatformException( + code: (error['code'] as String?)!, + message: error['message'] as String?, + details: error['details'], + ); + } else { + return; + } + } + + Future setUseWideViewPort(int arg_instanceId, bool arg_use) async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.WebSettingsHostApi.setUseWideViewPort', codec, + binaryMessenger: _binaryMessenger); + final Map? replyMap = await channel + .send([arg_instanceId, arg_use]) as Map?; + if (replyMap == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + details: null, + ); + } else if (replyMap['error'] != null) { + final Map error = + (replyMap['error'] as Map?)!; + throw PlatformException( + code: (error['code'] as String?)!, + message: error['message'] as String?, + details: error['details'], + ); + } else { + return; + } + } + + Future setDisplayZoomControls( + int arg_instanceId, bool arg_enabled) async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.WebSettingsHostApi.setDisplayZoomControls', codec, + binaryMessenger: _binaryMessenger); + final Map? replyMap = await channel + .send([arg_instanceId, arg_enabled]) as Map?; + if (replyMap == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + details: null, + ); + } else if (replyMap['error'] != null) { + final Map error = + (replyMap['error'] as Map?)!; + throw PlatformException( + code: (error['code'] as String?)!, + message: error['message'] as String?, + details: error['details'], + ); + } else { + return; + } + } + + Future setBuiltInZoomControls( + int arg_instanceId, bool arg_enabled) async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.WebSettingsHostApi.setBuiltInZoomControls', codec, + binaryMessenger: _binaryMessenger); + final Map? replyMap = await channel + .send([arg_instanceId, arg_enabled]) as Map?; + if (replyMap == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + details: null, + ); + } else if (replyMap['error'] != null) { + final Map error = + (replyMap['error'] as Map?)!; + throw PlatformException( + code: (error['code'] as String?)!, + message: error['message'] as String?, + details: error['details'], + ); + } else { + return; + } + } +} + +class _JavaScriptChannelHostApiCodec extends StandardMessageCodec { + const _JavaScriptChannelHostApiCodec(); +} + +class JavaScriptChannelHostApi { + /// Constructor for [JavaScriptChannelHostApi]. The [binaryMessenger] named argument is + /// available for dependency injection. If it is left null, the default + /// BinaryMessenger will be used which routes to the host platform. + JavaScriptChannelHostApi({BinaryMessenger? binaryMessenger}) + : _binaryMessenger = binaryMessenger; + + final BinaryMessenger? _binaryMessenger; + + static const MessageCodec codec = _JavaScriptChannelHostApiCodec(); + + Future create(int arg_instanceId, String arg_channelName) async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.JavaScriptChannelHostApi.create', codec, + binaryMessenger: _binaryMessenger); + final Map? replyMap = + await channel.send([arg_instanceId, arg_channelName]) + as Map?; + if (replyMap == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + details: null, + ); + } else if (replyMap['error'] != null) { + final Map error = + (replyMap['error'] as Map?)!; + throw PlatformException( + code: (error['code'] as String?)!, + message: error['message'] as String?, + details: error['details'], + ); + } else { + return; + } + } + + Future dispose(int arg_instanceId) async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.JavaScriptChannelHostApi.dispose', codec, + binaryMessenger: _binaryMessenger); + final Map? replyMap = + await channel.send([arg_instanceId]) as Map?; + if (replyMap == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + details: null, + ); + } else if (replyMap['error'] != null) { + final Map error = + (replyMap['error'] as Map?)!; + throw PlatformException( + code: (error['code'] as String?)!, + message: error['message'] as String?, + details: error['details'], + ); + } else { + return; + } + } +} + +class _JavaScriptChannelFlutterApiCodec extends StandardMessageCodec { + const _JavaScriptChannelFlutterApiCodec(); +} + +abstract class JavaScriptChannelFlutterApi { + static const MessageCodec codec = + _JavaScriptChannelFlutterApiCodec(); + + void postMessage(int instanceId, String message); + static void setup(JavaScriptChannelFlutterApi? api) { + { + const BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.JavaScriptChannelFlutterApi.postMessage', codec); + if (api == null) { + channel.setMessageHandler(null); + } else { + channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.JavaScriptChannelFlutterApi.postMessage was null.'); + final List args = (message as List?)!; + final int? arg_instanceId = args[0] as int?; + assert(arg_instanceId != null, + 'Argument for dev.flutter.pigeon.JavaScriptChannelFlutterApi.postMessage was null, expected non-null int.'); + final String? arg_message = args[1] as String?; + assert(arg_message != null, + 'Argument for dev.flutter.pigeon.JavaScriptChannelFlutterApi.postMessage was null, expected non-null String.'); + api.postMessage(arg_instanceId!, arg_message!); + return; + }); + } + } + } +} + +class _WebViewClientHostApiCodec extends StandardMessageCodec { + const _WebViewClientHostApiCodec(); +} + +class WebViewClientHostApi { + /// Constructor for [WebViewClientHostApi]. The [binaryMessenger] named argument is + /// available for dependency injection. If it is left null, the default + /// BinaryMessenger will be used which routes to the host platform. + WebViewClientHostApi({BinaryMessenger? binaryMessenger}) + : _binaryMessenger = binaryMessenger; + + final BinaryMessenger? _binaryMessenger; + + static const MessageCodec codec = _WebViewClientHostApiCodec(); + + Future create( + int arg_instanceId, bool arg_shouldOverrideUrlLoading) async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.WebViewClientHostApi.create', codec, + binaryMessenger: _binaryMessenger); + final Map? replyMap = await channel + .send([arg_instanceId, arg_shouldOverrideUrlLoading]) + as Map?; + if (replyMap == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + details: null, + ); + } else if (replyMap['error'] != null) { + final Map error = + (replyMap['error'] as Map?)!; + throw PlatformException( + code: (error['code'] as String?)!, + message: error['message'] as String?, + details: error['details'], + ); + } else { + return; + } + } + + Future dispose(int arg_instanceId) async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.WebViewClientHostApi.dispose', codec, + binaryMessenger: _binaryMessenger); + final Map? replyMap = + await channel.send([arg_instanceId]) as Map?; + if (replyMap == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + details: null, + ); + } else if (replyMap['error'] != null) { + final Map error = + (replyMap['error'] as Map?)!; + throw PlatformException( + code: (error['code'] as String?)!, + message: error['message'] as String?, + details: error['details'], + ); + } else { + return; + } + } +} + +class _WebViewClientFlutterApiCodec extends StandardMessageCodec { + const _WebViewClientFlutterApiCodec(); + @override + void writeValue(WriteBuffer buffer, Object? value) { + if (value is WebResourceErrorData) { + buffer.putUint8(128); + writeValue(buffer, value.encode()); + } else if (value is WebResourceRequestData) { + buffer.putUint8(129); + writeValue(buffer, value.encode()); + } else if (value is WebResourceRequestData) { + buffer.putUint8(130); + writeValue(buffer, value.encode()); + } else { + super.writeValue(buffer, value); + } + } + + @override + Object? readValueOfType(int type, ReadBuffer buffer) { + switch (type) { + case 128: + return WebResourceErrorData.decode(readValue(buffer)!); + + case 129: + return WebResourceRequestData.decode(readValue(buffer)!); + + case 130: + return WebResourceRequestData.decode(readValue(buffer)!); + + default: + return super.readValueOfType(type, buffer); + } + } +} + +abstract class WebViewClientFlutterApi { + static const MessageCodec codec = _WebViewClientFlutterApiCodec(); + + void onPageStarted(int instanceId, int webViewInstanceId, String url); + void onPageFinished(int instanceId, int webViewInstanceId, String url); + void onReceivedRequestError(int instanceId, int webViewInstanceId, + WebResourceRequestData request, WebResourceErrorData error); + void onReceivedError(int instanceId, int webViewInstanceId, int errorCode, + String description, String failingUrl); + void requestLoading( + int instanceId, int webViewInstanceId, WebResourceRequestData request); + void urlLoading(int instanceId, int webViewInstanceId, String url); + static void setup(WebViewClientFlutterApi? api) { + { + const BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.WebViewClientFlutterApi.onPageStarted', codec); + if (api == null) { + channel.setMessageHandler(null); + } else { + channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.WebViewClientFlutterApi.onPageStarted was null.'); + final List args = (message as List?)!; + final int? arg_instanceId = args[0] as int?; + assert(arg_instanceId != null, + 'Argument for dev.flutter.pigeon.WebViewClientFlutterApi.onPageStarted was null, expected non-null int.'); + final int? arg_webViewInstanceId = args[1] as int?; + assert(arg_webViewInstanceId != null, + 'Argument for dev.flutter.pigeon.WebViewClientFlutterApi.onPageStarted was null, expected non-null int.'); + final String? arg_url = args[2] as String?; + assert(arg_url != null, + 'Argument for dev.flutter.pigeon.WebViewClientFlutterApi.onPageStarted was null, expected non-null String.'); + api.onPageStarted(arg_instanceId!, arg_webViewInstanceId!, arg_url!); + return; + }); + } + } + { + const BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.WebViewClientFlutterApi.onPageFinished', codec); + if (api == null) { + channel.setMessageHandler(null); + } else { + channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.WebViewClientFlutterApi.onPageFinished was null.'); + final List args = (message as List?)!; + final int? arg_instanceId = args[0] as int?; + assert(arg_instanceId != null, + 'Argument for dev.flutter.pigeon.WebViewClientFlutterApi.onPageFinished was null, expected non-null int.'); + final int? arg_webViewInstanceId = args[1] as int?; + assert(arg_webViewInstanceId != null, + 'Argument for dev.flutter.pigeon.WebViewClientFlutterApi.onPageFinished was null, expected non-null int.'); + final String? arg_url = args[2] as String?; + assert(arg_url != null, + 'Argument for dev.flutter.pigeon.WebViewClientFlutterApi.onPageFinished was null, expected non-null String.'); + api.onPageFinished(arg_instanceId!, arg_webViewInstanceId!, arg_url!); + return; + }); + } + } + { + const BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.WebViewClientFlutterApi.onReceivedRequestError', + codec); + if (api == null) { + channel.setMessageHandler(null); + } else { + channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.WebViewClientFlutterApi.onReceivedRequestError was null.'); + final List args = (message as List?)!; + final int? arg_instanceId = args[0] as int?; + assert(arg_instanceId != null, + 'Argument for dev.flutter.pigeon.WebViewClientFlutterApi.onReceivedRequestError was null, expected non-null int.'); + final int? arg_webViewInstanceId = args[1] as int?; + assert(arg_webViewInstanceId != null, + 'Argument for dev.flutter.pigeon.WebViewClientFlutterApi.onReceivedRequestError was null, expected non-null int.'); + final WebResourceRequestData? arg_request = + args[2] as WebResourceRequestData?; + assert(arg_request != null, + 'Argument for dev.flutter.pigeon.WebViewClientFlutterApi.onReceivedRequestError was null, expected non-null WebResourceRequestData.'); + final WebResourceErrorData? arg_error = + args[3] as WebResourceErrorData?; + assert(arg_error != null, + 'Argument for dev.flutter.pigeon.WebViewClientFlutterApi.onReceivedRequestError was null, expected non-null WebResourceErrorData.'); + api.onReceivedRequestError(arg_instanceId!, arg_webViewInstanceId!, + arg_request!, arg_error!); + return; + }); + } + } + { + const BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.WebViewClientFlutterApi.onReceivedError', codec); + if (api == null) { + channel.setMessageHandler(null); + } else { + channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.WebViewClientFlutterApi.onReceivedError was null.'); + final List args = (message as List?)!; + final int? arg_instanceId = args[0] as int?; + assert(arg_instanceId != null, + 'Argument for dev.flutter.pigeon.WebViewClientFlutterApi.onReceivedError was null, expected non-null int.'); + final int? arg_webViewInstanceId = args[1] as int?; + assert(arg_webViewInstanceId != null, + 'Argument for dev.flutter.pigeon.WebViewClientFlutterApi.onReceivedError was null, expected non-null int.'); + final int? arg_errorCode = args[2] as int?; + assert(arg_errorCode != null, + 'Argument for dev.flutter.pigeon.WebViewClientFlutterApi.onReceivedError was null, expected non-null int.'); + final String? arg_description = args[3] as String?; + assert(arg_description != null, + 'Argument for dev.flutter.pigeon.WebViewClientFlutterApi.onReceivedError was null, expected non-null String.'); + final String? arg_failingUrl = args[4] as String?; + assert(arg_failingUrl != null, + 'Argument for dev.flutter.pigeon.WebViewClientFlutterApi.onReceivedError was null, expected non-null String.'); + api.onReceivedError(arg_instanceId!, arg_webViewInstanceId!, + arg_errorCode!, arg_description!, arg_failingUrl!); + return; + }); + } + } + { + const BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.WebViewClientFlutterApi.requestLoading', codec); + if (api == null) { + channel.setMessageHandler(null); + } else { + channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.WebViewClientFlutterApi.requestLoading was null.'); + final List args = (message as List?)!; + final int? arg_instanceId = args[0] as int?; + assert(arg_instanceId != null, + 'Argument for dev.flutter.pigeon.WebViewClientFlutterApi.requestLoading was null, expected non-null int.'); + final int? arg_webViewInstanceId = args[1] as int?; + assert(arg_webViewInstanceId != null, + 'Argument for dev.flutter.pigeon.WebViewClientFlutterApi.requestLoading was null, expected non-null int.'); + final WebResourceRequestData? arg_request = + args[2] as WebResourceRequestData?; + assert(arg_request != null, + 'Argument for dev.flutter.pigeon.WebViewClientFlutterApi.requestLoading was null, expected non-null WebResourceRequestData.'); + api.requestLoading( + arg_instanceId!, arg_webViewInstanceId!, arg_request!); + return; + }); + } + } + { + const BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.WebViewClientFlutterApi.urlLoading', codec); + if (api == null) { + channel.setMessageHandler(null); + } else { + channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.WebViewClientFlutterApi.urlLoading was null.'); + final List args = (message as List?)!; + final int? arg_instanceId = args[0] as int?; + assert(arg_instanceId != null, + 'Argument for dev.flutter.pigeon.WebViewClientFlutterApi.urlLoading was null, expected non-null int.'); + final int? arg_webViewInstanceId = args[1] as int?; + assert(arg_webViewInstanceId != null, + 'Argument for dev.flutter.pigeon.WebViewClientFlutterApi.urlLoading was null, expected non-null int.'); + final String? arg_url = args[2] as String?; + assert(arg_url != null, + 'Argument for dev.flutter.pigeon.WebViewClientFlutterApi.urlLoading was null, expected non-null String.'); + api.urlLoading(arg_instanceId!, arg_webViewInstanceId!, arg_url!); + return; + }); + } + } + } +} + +class _DownloadListenerHostApiCodec extends StandardMessageCodec { + const _DownloadListenerHostApiCodec(); +} + +class DownloadListenerHostApi { + /// Constructor for [DownloadListenerHostApi]. The [binaryMessenger] named argument is + /// available for dependency injection. If it is left null, the default + /// BinaryMessenger will be used which routes to the host platform. + DownloadListenerHostApi({BinaryMessenger? binaryMessenger}) + : _binaryMessenger = binaryMessenger; + + final BinaryMessenger? _binaryMessenger; + + static const MessageCodec codec = _DownloadListenerHostApiCodec(); + + Future create(int arg_instanceId) async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.DownloadListenerHostApi.create', codec, + binaryMessenger: _binaryMessenger); + final Map? replyMap = + await channel.send([arg_instanceId]) as Map?; + if (replyMap == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + details: null, + ); + } else if (replyMap['error'] != null) { + final Map error = + (replyMap['error'] as Map?)!; + throw PlatformException( + code: (error['code'] as String?)!, + message: error['message'] as String?, + details: error['details'], + ); + } else { + return; + } + } + + Future dispose(int arg_instanceId) async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.DownloadListenerHostApi.dispose', codec, + binaryMessenger: _binaryMessenger); + final Map? replyMap = + await channel.send([arg_instanceId]) as Map?; + if (replyMap == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + details: null, + ); + } else if (replyMap['error'] != null) { + final Map error = + (replyMap['error'] as Map?)!; + throw PlatformException( + code: (error['code'] as String?)!, + message: error['message'] as String?, + details: error['details'], + ); + } else { + return; + } + } +} + +class _DownloadListenerFlutterApiCodec extends StandardMessageCodec { + const _DownloadListenerFlutterApiCodec(); +} + +abstract class DownloadListenerFlutterApi { + static const MessageCodec codec = _DownloadListenerFlutterApiCodec(); + + void onDownloadStart(int instanceId, String url, String userAgent, + String contentDisposition, String mimetype, int contentLength); + static void setup(DownloadListenerFlutterApi? api) { + { + const BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.DownloadListenerFlutterApi.onDownloadStart', + codec); + if (api == null) { + channel.setMessageHandler(null); + } else { + channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.DownloadListenerFlutterApi.onDownloadStart was null.'); + final List args = (message as List?)!; + final int? arg_instanceId = args[0] as int?; + assert(arg_instanceId != null, + 'Argument for dev.flutter.pigeon.DownloadListenerFlutterApi.onDownloadStart was null, expected non-null int.'); + final String? arg_url = args[1] as String?; + assert(arg_url != null, + 'Argument for dev.flutter.pigeon.DownloadListenerFlutterApi.onDownloadStart was null, expected non-null String.'); + final String? arg_userAgent = args[2] as String?; + assert(arg_userAgent != null, + 'Argument for dev.flutter.pigeon.DownloadListenerFlutterApi.onDownloadStart was null, expected non-null String.'); + final String? arg_contentDisposition = args[3] as String?; + assert(arg_contentDisposition != null, + 'Argument for dev.flutter.pigeon.DownloadListenerFlutterApi.onDownloadStart was null, expected non-null String.'); + final String? arg_mimetype = args[4] as String?; + assert(arg_mimetype != null, + 'Argument for dev.flutter.pigeon.DownloadListenerFlutterApi.onDownloadStart was null, expected non-null String.'); + final int? arg_contentLength = args[5] as int?; + assert(arg_contentLength != null, + 'Argument for dev.flutter.pigeon.DownloadListenerFlutterApi.onDownloadStart was null, expected non-null int.'); + api.onDownloadStart(arg_instanceId!, arg_url!, arg_userAgent!, + arg_contentDisposition!, arg_mimetype!, arg_contentLength!); + return; + }); + } + } + } +} + +class _WebChromeClientHostApiCodec extends StandardMessageCodec { + const _WebChromeClientHostApiCodec(); +} + +class WebChromeClientHostApi { + /// Constructor for [WebChromeClientHostApi]. The [binaryMessenger] named argument is + /// available for dependency injection. If it is left null, the default + /// BinaryMessenger will be used which routes to the host platform. + WebChromeClientHostApi({BinaryMessenger? binaryMessenger}) + : _binaryMessenger = binaryMessenger; + + final BinaryMessenger? _binaryMessenger; + + static const MessageCodec codec = _WebChromeClientHostApiCodec(); + + Future create( + int arg_instanceId, int arg_webViewClientInstanceId) async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.WebChromeClientHostApi.create', codec, + binaryMessenger: _binaryMessenger); + final Map? replyMap = await channel + .send([arg_instanceId, arg_webViewClientInstanceId]) + as Map?; + if (replyMap == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + details: null, + ); + } else if (replyMap['error'] != null) { + final Map error = + (replyMap['error'] as Map?)!; + throw PlatformException( + code: (error['code'] as String?)!, + message: error['message'] as String?, + details: error['details'], + ); + } else { + return; + } + } + + Future dispose(int arg_instanceId) async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.WebChromeClientHostApi.dispose', codec, + binaryMessenger: _binaryMessenger); + final Map? replyMap = + await channel.send([arg_instanceId]) as Map?; + if (replyMap == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + details: null, + ); + } else if (replyMap['error'] != null) { + final Map error = + (replyMap['error'] as Map?)!; + throw PlatformException( + code: (error['code'] as String?)!, + message: error['message'] as String?, + details: error['details'], + ); + } else { + return; + } + } +} + +class _WebChromeClientFlutterApiCodec extends StandardMessageCodec { + const _WebChromeClientFlutterApiCodec(); +} + +abstract class WebChromeClientFlutterApi { + static const MessageCodec codec = _WebChromeClientFlutterApiCodec(); + + void onProgressChanged(int instanceId, int webViewInstanceId, int progress); + static void setup(WebChromeClientFlutterApi? api) { + { + const BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.WebChromeClientFlutterApi.onProgressChanged', + codec); + if (api == null) { + channel.setMessageHandler(null); + } else { + channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.WebChromeClientFlutterApi.onProgressChanged was null.'); + final List args = (message as List?)!; + final int? arg_instanceId = args[0] as int?; + assert(arg_instanceId != null, + 'Argument for dev.flutter.pigeon.WebChromeClientFlutterApi.onProgressChanged was null, expected non-null int.'); + final int? arg_webViewInstanceId = args[1] as int?; + assert(arg_webViewInstanceId != null, + 'Argument for dev.flutter.pigeon.WebChromeClientFlutterApi.onProgressChanged was null, expected non-null int.'); + final int? arg_progress = args[2] as int?; + assert(arg_progress != null, + 'Argument for dev.flutter.pigeon.WebChromeClientFlutterApi.onProgressChanged was null, expected non-null int.'); + api.onProgressChanged( + arg_instanceId!, arg_webViewInstanceId!, arg_progress!); + return; + }); + } + } + } +} diff --git a/packages/webview_flutter/webview_flutter_android/lib/src/android_webview_api_impls.dart b/packages/webview_flutter/webview_flutter_android/lib/src/android_webview_api_impls.dart new file mode 100644 index 000000000000..f909e49bd802 --- /dev/null +++ b/packages/webview_flutter/webview_flutter_android/lib/src/android_webview_api_impls.dart @@ -0,0 +1,622 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:flutter/services.dart'; + +import 'android_webview.dart'; +import 'android_webview.pigeon.dart'; +import 'instance_manager.dart'; + +/// Host api implementation for [WebView]. +class WebViewHostApiImpl extends WebViewHostApi { + /// Constructs a [WebViewHostApiImpl]. + WebViewHostApiImpl({ + BinaryMessenger? binaryMessenger, + InstanceManager? instanceManager, + }) : super(binaryMessenger: binaryMessenger) { + this.instanceManager = instanceManager ?? InstanceManager.instance; + } + + /// Maintains instances stored to communicate with java objects. + late final InstanceManager instanceManager; + + /// Helper method to convert instances ids to objects. + Future createFromInstance(WebView instance) async { + final int? instanceId = instanceManager.tryAddInstance(instance); + if (instanceId != null) { + return create(instanceId, instance.useHybridComposition); + } + } + + /// Helper method to convert instances ids to objects. + Future disposeFromInstance(WebView instance) async { + final int? instanceId = instanceManager.removeInstance(instance); + if (instanceId != null) { + return dispose(instanceId); + } + } + + /// Helper method to convert instances ids to objects. + Future loadUrlFromInstance( + WebView instance, + String url, + Map headers, + ) { + return loadUrl(instanceManager.getInstanceId(instance)!, url, headers); + } + + /// Helper method to convert instances ids to objects. + Future getUrlFromInstance(WebView instance) { + return getUrl(instanceManager.getInstanceId(instance)!); + } + + /// Helper method to convert instances ids to objects. + Future canGoBackFromInstance(WebView instance) { + return canGoBack(instanceManager.getInstanceId(instance)!); + } + + /// Helper method to convert instances ids to objects. + Future canGoForwardFromInstance(WebView instance) { + return canGoForward(instanceManager.getInstanceId(instance)!); + } + + /// Helper method to convert instances ids to objects. + Future goBackFromInstance(WebView instance) { + return goBack(instanceManager.getInstanceId(instance)!); + } + + /// Helper method to convert instances ids to objects. + Future goForwardFromInstance(WebView instance) { + return goForward(instanceManager.getInstanceId(instance)!); + } + + /// Helper method to convert instances ids to objects. + Future reloadFromInstance(WebView instance) { + return reload(instanceManager.getInstanceId(instance)!); + } + + /// Helper method to convert instances ids to objects. + Future clearCacheFromInstance(WebView instance, bool includeDiskFiles) { + return clearCache( + instanceManager.getInstanceId(instance)!, + includeDiskFiles, + ); + } + + /// Helper method to convert instances ids to objects. + Future evaluateJavascriptFromInstance( + WebView instance, + String javascriptString, + ) { + return evaluateJavascript( + instanceManager.getInstanceId(instance)!, javascriptString); + } + + /// Helper method to convert instances ids to objects. + Future getTitleFromInstance(WebView instance) { + return getTitle(instanceManager.getInstanceId(instance)!); + } + + /// Helper method to convert instances ids to objects. + Future scrollToFromInstance(WebView instance, int x, int y) { + return scrollTo(instanceManager.getInstanceId(instance)!, x, y); + } + + /// Helper method to convert instances ids to objects. + Future scrollByFromInstance(WebView instance, int x, int y) { + return scrollBy(instanceManager.getInstanceId(instance)!, x, y); + } + + /// Helper method to convert instances ids to objects. + Future getScrollXFromInstance(WebView instance) { + return getScrollX(instanceManager.getInstanceId(instance)!); + } + + /// Helper method to convert instances ids to objects. + Future getScrollYFromInstance(WebView instance) { + return getScrollY(instanceManager.getInstanceId(instance)!); + } + + /// Helper method to convert instances ids to objects. + Future setWebViewClientFromInstance( + WebView instance, + WebViewClient webViewClient, + ) { + return setWebViewClient( + instanceManager.getInstanceId(instance)!, + instanceManager.getInstanceId(webViewClient)!, + ); + } + + /// Helper method to convert instances ids to objects. + Future addJavaScriptChannelFromInstance( + WebView instance, + JavaScriptChannel javaScriptChannel, + ) { + return addJavaScriptChannel( + instanceManager.getInstanceId(instance)!, + instanceManager.getInstanceId(javaScriptChannel)!, + ); + } + + /// Helper method to convert instances ids to objects. + Future removeJavaScriptChannelFromInstance( + WebView instance, + JavaScriptChannel javaScriptChannel, + ) { + return removeJavaScriptChannel( + instanceManager.getInstanceId(instance)!, + instanceManager.getInstanceId(javaScriptChannel)!, + ); + } + + /// Helper method to convert instances ids to objects. + Future setDownloadListenerFromInstance( + WebView instance, + DownloadListener listener, + ) { + return setDownloadListener( + instanceManager.getInstanceId(instance)!, + instanceManager.getInstanceId(listener)!, + ); + } + + /// Helper method to convert instances ids to objects. + Future setWebChromeClientFromInstance( + WebView instance, + WebChromeClient client, + ) { + return setWebChromeClient( + instanceManager.getInstanceId(instance)!, + instanceManager.getInstanceId(client)!, + ); + } +} + +/// Host api implementation for [WebSettings]. +class WebSettingsHostApiImpl extends WebSettingsHostApi { + /// Constructs a [WebSettingsHostApiImpl]. + WebSettingsHostApiImpl({ + BinaryMessenger? binaryMessenger, + InstanceManager? instanceManager, + }) : super(binaryMessenger: binaryMessenger) { + this.instanceManager = instanceManager ?? InstanceManager.instance; + } + + /// Maintains instances stored to communicate with java objects. + late final InstanceManager instanceManager; + + /// Helper method to convert instances ids to objects. + Future createFromInstance(WebSettings instance, WebView webView) async { + final int? instanceId = instanceManager.tryAddInstance(instance); + if (instanceId != null) { + return create( + instanceId, + instanceManager.getInstanceId(webView)!, + ); + } + } + + /// Helper method to convert instances ids to objects. + Future disposeFromInstance(WebSettings instance) async { + final int? instanceId = instanceManager.removeInstance(instance); + if (instanceId != null) { + return dispose(instanceId); + } + } + + /// Helper method to convert instances ids to objects. + Future setDomStorageEnabledFromInstance( + WebSettings instance, + bool flag, + ) { + return setDomStorageEnabled(instanceManager.getInstanceId(instance)!, flag); + } + + /// Helper method to convert instances ids to objects. + Future setJavaScriptCanOpenWindowsAutomaticallyFromInstance( + WebSettings instance, + bool flag, + ) { + return setJavaScriptCanOpenWindowsAutomatically( + instanceManager.getInstanceId(instance)!, + flag, + ); + } + + /// Helper method to convert instances ids to objects. + Future setSupportMultipleWindowsFromInstance( + WebSettings instance, + bool support, + ) { + return setSupportMultipleWindows( + instanceManager.getInstanceId(instance)!, support); + } + + /// Helper method to convert instances ids to objects. + Future setJavaScriptEnabledFromInstance( + WebSettings instance, + bool flag, + ) { + return setJavaScriptCanOpenWindowsAutomatically( + instanceManager.getInstanceId(instance)!, + flag, + ); + } + + /// Helper method to convert instances ids to objects. + Future setUserAgentStringFromInstance( + WebSettings instance, + String userAgentString, + ) { + return setUserAgentString( + instanceManager.getInstanceId(instance)!, + userAgentString, + ); + } + + /// Helper method to convert instances ids to objects. + Future setMediaPlaybackRequiresUserGestureFromInstance( + WebSettings instance, + bool require, + ) { + return setMediaPlaybackRequiresUserGesture( + instanceManager.getInstanceId(instance)!, + require, + ); + } + + /// Helper method to convert instances ids to objects. + Future setSupportZoomFromInstance( + WebSettings instance, + bool support, + ) { + return setSupportZoom(instanceManager.getInstanceId(instance)!, support); + } + + /// Helper method to convert instances ids to objects. + Future setLoadWithOverviewModeFromInstance( + WebSettings instance, + bool overview, + ) { + return setLoadWithOverviewMode( + instanceManager.getInstanceId(instance)!, + overview, + ); + } + + /// Helper method to convert instances ids to objects. + Future setUseWideViewPortFromInstance( + WebSettings instance, + bool use, + ) { + return setUseWideViewPort(instanceManager.getInstanceId(instance)!, use); + } + + /// Helper method to convert instances ids to objects. + Future setDisplayZoomControlsFromInstance( + WebSettings instance, + bool enabled, + ) { + return setDisplayZoomControls( + instanceManager.getInstanceId(instance)!, + enabled, + ); + } + + /// Helper method to convert instances ids to objects. + Future setBuiltInZoomControlsFromInstance( + WebSettings instance, + bool enabled, + ) { + return setBuiltInZoomControls( + instanceManager.getInstanceId(instance)!, + enabled, + ); + } +} + +/// Host api implementation for [JavaScriptChannel]. +class JavaScriptChannelHostApiImpl extends JavaScriptChannelHostApi { + /// Constructs a [JavaScriptChannelHostApiImpl]. + JavaScriptChannelHostApiImpl({ + BinaryMessenger? binaryMessenger, + InstanceManager? instanceManager, + }) : super(binaryMessenger: binaryMessenger) { + this.instanceManager = instanceManager ?? InstanceManager.instance; + } + + /// Maintains instances stored to communicate with java objects. + late final InstanceManager instanceManager; + + /// Helper method to convert instances ids to objects. + Future createFromInstance(JavaScriptChannel instance) async { + final int? instanceId = instanceManager.tryAddInstance(instance); + if (instanceId != null) { + return create(instanceId, instance.channelName); + } + } + + /// Helper method to convert instances ids to objects. + Future disposeFromInstance(JavaScriptChannel instance) async { + final int? instanceId = instanceManager.removeInstance(instance); + if (instanceId != null) { + return dispose(instanceId); + } + } +} + +/// Flutter api implementation for [JavaScriptChannel]. +class JavaScriptChannelFlutterApiImpl extends JavaScriptChannelFlutterApi { + /// Constructs a [JavaScriptChannelFlutterApiImpl]. + JavaScriptChannelHostApiImpl({InstanceManager? instanceManager}) { + this.instanceManager = instanceManager ?? InstanceManager.instance; + } + + /// Maintains instances stored to communicate with java objects. + late final InstanceManager instanceManager; + + @override + void postMessage(int instanceId, String message) { + final JavaScriptChannel instance = + instanceManager.getInstance(instanceId) as JavaScriptChannel; + instance.postMessage(message); + } +} + +/// Host api implementation for [WebViewClient]. +class WebViewClientHostApiImpl extends WebViewClientHostApi { + /// Constructs a [WebViewClientHostApiImpl]. + WebViewClientHostApiImpl({ + BinaryMessenger? binaryMessenger, + InstanceManager? instanceManager, + }) : super(binaryMessenger: binaryMessenger) { + this.instanceManager = instanceManager ?? InstanceManager.instance; + } + + /// Maintains instances stored to communicate with java objects. + late final InstanceManager instanceManager; + + /// Helper method to convert instances ids to objects. + Future createFromInstance(WebViewClient instance) async { + final int? instanceId = instanceManager.tryAddInstance(instance); + if (instanceId != null) { + return create(instanceId, instance.shouldOverrideUrlLoading); + } + } + + /// Helper method to convert instances ids to objects. + Future disposeFromInstance(WebViewClient instance) async { + final int? instanceId = instanceManager.removeInstance(instance); + if (instanceId != null) { + return dispose(instanceId); + } + } +} + +/// Flutter api implementation for [WebViewClient]. +class WebViewClientFlutterApiImpl extends WebViewClientFlutterApi { + /// Constructs a [WebViewClientFlutterApiImpl]. + WebViewClientFlutterApiImpl({InstanceManager? instanceManager}) { + this.instanceManager = instanceManager ?? InstanceManager.instance; + } + + /// Maintains instances stored to communicate with java objects. + late final InstanceManager instanceManager; + + @override + void onPageFinished(int instanceId, int webViewInstanceId, String url) { + final WebViewClient instance = + instanceManager.getInstance(instanceId) as WebViewClient; + instance.onPageFinished( + instanceManager.getInstance(webViewInstanceId) as WebView, + url, + ); + } + + @override + void onPageStarted(int instanceId, int webViewInstanceId, String url) { + final WebViewClient instance = + instanceManager.getInstance(instanceId) as WebViewClient; + instance.onPageStarted( + instanceManager.getInstance(webViewInstanceId) as WebView, + url, + ); + } + + @override + void onReceivedError( + int instanceId, + int webViewInstanceId, + int errorCode, + String description, + String failingUrl, + ) { + final WebViewClient instance = + instanceManager.getInstance(instanceId) as WebViewClient; + // ignore: deprecated_member_use_from_same_package + instance.onReceivedError( + instanceManager.getInstance(webViewInstanceId) as WebView, + errorCode, + description, + failingUrl, + ); + } + + @override + void onReceivedRequestError( + int instanceId, + int webViewInstanceId, + WebResourceRequestData request, + WebResourceErrorData error, + ) { + final WebViewClient instance = + instanceManager.getInstance(instanceId) as WebViewClient; + instance.onReceivedRequestError( + instanceManager.getInstance(webViewInstanceId) as WebView, + WebResourceRequest( + url: request.url!, + isForMainFrame: request.isForMainFrame!, + isRedirect: request.isRedirect, + hasGesture: request.hasGesture!, + method: request.method!, + requestHeaders: request.requestHeaders!.cast(), + ), + WebResourceError( + errorCode: error.errorCode!, + description: error.description!, + ), + ); + } + + @override + void requestLoading( + int instanceId, + int webViewInstanceId, + WebResourceRequestData request, + ) { + final WebViewClient instance = + instanceManager.getInstance(instanceId) as WebViewClient; + instance.requestLoading( + instanceManager.getInstance(webViewInstanceId) as WebView, + WebResourceRequest( + url: request.url!, + isForMainFrame: request.isForMainFrame!, + isRedirect: request.isRedirect, + hasGesture: request.hasGesture!, + method: request.method!, + requestHeaders: request.requestHeaders!.cast(), + ), + ); + } + + @override + void urlLoading( + int instanceId, + int webViewInstanceId, + String url, + ) { + final WebViewClient instance = + instanceManager.getInstance(instanceId) as WebViewClient; + instance.urlLoading( + instanceManager.getInstance(webViewInstanceId) as WebView, + url, + ); + } +} + +/// Host api implementation for [DownloadListener]. +class DownloadListenerHostApiImpl extends DownloadListenerHostApi { + /// Constructs a [DownloadListenerHostApiImpl]. + DownloadListenerHostApiImpl({ + BinaryMessenger? binaryMessenger, + InstanceManager? instanceManager, + }) : super(binaryMessenger: binaryMessenger) { + this.instanceManager = instanceManager ?? InstanceManager.instance; + } + + /// Maintains instances stored to communicate with java objects. + late final InstanceManager instanceManager; + + /// Helper method to convert instances ids to objects. + Future createFromInstance(DownloadListener instance) async { + final int? instanceId = instanceManager.tryAddInstance(instance); + if (instanceId != null) { + return create(instanceId); + } + } + + /// Helper method to convert instances ids to objects. + Future disposeFromInstance(DownloadListener instance) async { + final int? instanceId = instanceManager.removeInstance(instance); + if (instanceId != null) { + return dispose(instanceId); + } + } +} + +/// Flutter api implementation for [DownloadListener]. +class DownloadListenerFlutterApiImpl extends DownloadListenerFlutterApi { + /// Constructs a [DownloadListenerFlutterApiImpl]. + DownloadListenerFlutterApiImpl({InstanceManager? instanceManager}) { + this.instanceManager = instanceManager ?? InstanceManager.instance; + } + + /// Maintains instances stored to communicate with java objects. + late final InstanceManager instanceManager; + + @override + void onDownloadStart( + int instanceId, + String url, + String userAgent, + String contentDisposition, + String mimetype, + int contentLength, + ) { + final DownloadListener instance = + instanceManager.getInstance(instanceId) as DownloadListener; + instance.onDownloadStart( + url, + userAgent, + contentDisposition, + mimetype, + contentLength, + ); + } +} + +/// Host api implementation for [DownloadListener]. +class WebChromeClientHostApiImpl extends WebChromeClientHostApi { + /// Constructs a [WebChromeClientHostApiImpl]. + WebChromeClientHostApiImpl({ + BinaryMessenger? binaryMessenger, + InstanceManager? instanceManager, + }) : super(binaryMessenger: binaryMessenger) { + this.instanceManager = instanceManager ?? InstanceManager.instance; + } + + /// Maintains instances stored to communicate with java objects. + late final InstanceManager instanceManager; + + /// Helper method to convert instances ids to objects. + Future createFromInstance( + WebChromeClient instance, + WebViewClient webViewClient, + ) async { + final int? instanceId = instanceManager.tryAddInstance(instance); + if (instanceId != null) { + return create(instanceId, instanceManager.getInstanceId(webViewClient)!); + } + } + + /// Helper method to convert instances ids to objects. + Future disposeFromInstance(WebChromeClient instance) async { + final int? instanceId = instanceManager.removeInstance(instance); + if (instanceId != null) { + return dispose(instanceId); + } + } +} + +/// Flutter api implementation for [DownloadListener]. +class WebChromeClientFlutterApiImpl extends WebChromeClientFlutterApi { + /// Constructs a [DownloadListenerFlutterApiImpl]. + WebChromeClientFlutterApiImpl({InstanceManager? instanceManager}) { + this.instanceManager = instanceManager ?? InstanceManager.instance; + } + + /// Maintains instances stored to communicate with java objects. + late final InstanceManager instanceManager; + + @override + void onProgressChanged(int instanceId, int webViewInstanceId, int progress) { + final WebChromeClient instance = + instanceManager.getInstance(instanceId) as WebChromeClient; + instance.onProgressChanged( + instanceManager.getInstance(webViewInstanceId) as WebView, + progress, + ); + } +} diff --git a/packages/webview_flutter/webview_flutter_android/lib/src/instance_manager.dart b/packages/webview_flutter/webview_flutter_android/lib/src/instance_manager.dart new file mode 100644 index 000000000000..94d8bc3253eb --- /dev/null +++ b/packages/webview_flutter/webview_flutter_android/lib/src/instance_manager.dart @@ -0,0 +1,52 @@ +// 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. + +/// Maintains instances stored to communicate with java objects. +class InstanceManager { + Map _instanceIdsToInstances = {}; + Map _instancesToInstanceIds = {}; + + int _nextInstanceId = 0; + + /// Global instance of [InstanceManager]. + static final InstanceManager instance = InstanceManager(); + + /// Attempt to add a new instance. + /// + /// Returns new if [instance] has already been added. Otherwise, it is added + /// with a new instance id. + int? tryAddInstance(Object instance) { + if (_instancesToInstanceIds.containsKey(instance)) { + return null; + } + + final int instanceId = _nextInstanceId++; + _instancesToInstanceIds[instance] = instanceId; + _instanceIdsToInstances[instanceId] = instance; + return instanceId; + } + + /// Remove the instance from the manager. + /// + /// Returns null if the instance is removed. Otherwise, return the instanceId + /// of the removed instance. + int? removeInstance(Object instance) { + final int? instanceId = _instancesToInstanceIds[instance]; + if (instanceId != null) { + _instancesToInstanceIds.remove(instance); + _instanceIdsToInstances.remove(instanceId); + } + return instanceId; + } + + /// Retrieve the Object paired with instanceId. + Object? getInstance(int instanceId) { + return _instanceIdsToInstances[instanceId]; + } + + /// Retrieve the instanceId paired with instance. + int? getInstanceId(Object instance) { + return _instancesToInstanceIds[instance]; + } +} diff --git a/packages/webview_flutter/webview_flutter_android/pigeons/android_webview.dart b/packages/webview_flutter/webview_flutter_android/pigeons/android_webview.dart new file mode 100644 index 000000000000..1877c1b91feb --- /dev/null +++ b/packages/webview_flutter/webview_flutter_android/pigeons/android_webview.dart @@ -0,0 +1,181 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:pigeon/pigeon.dart'; + +class WebResourceRequestData { + String? url; + bool? isForMainFrame; + bool? isRedirect; + bool? hasGesture; + String? method; + Map? requestHeaders; +} + +class WebResourceErrorData { + int? errorCode; + String? description; +} + +@HostApi(dartHostTestHandler: 'TestWebViewHostApi') +abstract class WebViewHostApi { + void create(int instanceId, bool useHybridComposition); + + void dispose(int instanceId); + + void loadUrl( + int instanceId, + String url, + Map headers, + ); + + 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); + + @async + 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); +} + +@HostApi(dartHostTestHandler: 'TestWebSettingsHostApi') +abstract class WebSettingsHostApi { + 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); +} + +@HostApi(dartHostTestHandler: 'TestJavaScriptChannelHostApi') +abstract class JavaScriptChannelHostApi { + void create(int instanceId, String channelName); + + void dispose(int instanceId); +} + +@FlutterApi() +abstract class JavaScriptChannelFlutterApi { + void postMessage(int instanceId, String message); +} + +@HostApi(dartHostTestHandler: 'TestWebViewClientHostApi') +abstract class WebViewClientHostApi { + void create(int instanceId, bool shouldOverrideUrlLoading); + + void dispose(int instanceId); +} + +@FlutterApi() +abstract class WebViewClientFlutterApi { + void onPageStarted(int instanceId, int webViewInstanceId, String url); + + void onPageFinished(int instanceId, int webViewInstanceId, String url); + + void onReceivedRequestError( + int instanceId, + int webViewInstanceId, + WebResourceRequestData request, + WebResourceErrorData error, + ); + + void onReceivedError( + int instanceId, + int webViewInstanceId, + int errorCode, + String description, + String failingUrl, + ); + + void requestLoading( + int instanceId, + int webViewInstanceId, + WebResourceRequestData request, + ); + + void urlLoading(int instanceId, int webViewInstanceId, String url); +} + +@HostApi(dartHostTestHandler: 'TestDownloadListenerHostApi') +abstract class DownloadListenerHostApi { + void create(int instanceId); + void dispose(int instanceId); +} + +@FlutterApi() +abstract class DownloadListenerFlutterApi { + void onDownloadStart( + int instanceId, + String url, + String userAgent, + String contentDisposition, + String mimetype, + int contentLength, + ); +} + +@HostApi(dartHostTestHandler: 'TestWebChromeClientHostApi') +abstract class WebChromeClientHostApi { + void create(int instanceId, int webViewClientInstanceId); + void dispose(int instanceId); +} + +@FlutterApi() +abstract class WebChromeClientFlutterApi { + void onProgressChanged(int instanceId, int webViewInstanceId, int progress); +} diff --git a/packages/webview_flutter/webview_flutter_android/pubspec.yaml b/packages/webview_flutter/webview_flutter_android/pubspec.yaml index 36f186087c08..04511e670d4c 100644 --- a/packages/webview_flutter/webview_flutter_android/pubspec.yaml +++ b/packages/webview_flutter/webview_flutter_android/pubspec.yaml @@ -27,5 +27,6 @@ dev_dependencies: sdk: flutter flutter_test: sdk: flutter + pigeon: 1.0.7 pedantic: ^1.10.0 diff --git a/packages/webview_flutter/webview_flutter_android/test/android_webview.pigeon.dart b/packages/webview_flutter/webview_flutter_android/test/android_webview.pigeon.dart new file mode 100644 index 000000000000..70aa53ca2610 --- /dev/null +++ b/packages/webview_flutter/webview_flutter_android/test/android_webview.pigeon.dart @@ -0,0 +1,1000 @@ +// 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.7), 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, avoid_relative_lib_imports +// @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 codec = _TestWebViewHostApiCodec(); + + void create(int instanceId, bool useHybridComposition); + void dispose(int instanceId); + void loadUrl(int instanceId, String url, Map headers); + 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 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); + static void setup(TestWebViewHostApi? api) { + { + const BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.WebViewHostApi.create', codec); + 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 args = (message as List?)!; + 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 {}; + }); + } + } + { + const BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.WebViewHostApi.dispose', codec); + 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 args = (message as List?)!; + 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 {}; + }); + } + } + { + const BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.WebViewHostApi.loadUrl', codec); + 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 args = (message as List?)!; + 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? arg_headers = + args[2] as Map?; + assert(arg_headers != null, + 'Argument for dev.flutter.pigeon.WebViewHostApi.loadUrl was null, expected non-null Map.'); + api.loadUrl(arg_instanceId!, arg_url!, arg_headers!); + return {}; + }); + } + } + { + const BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.WebViewHostApi.getUrl', codec); + 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 args = (message as List?)!; + 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 {'result': output}; + }); + } + } + { + const BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.WebViewHostApi.canGoBack', codec); + 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 args = (message as List?)!; + 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 {'result': output}; + }); + } + } + { + const BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.WebViewHostApi.canGoForward', codec); + 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 args = (message as List?)!; + 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 {'result': output}; + }); + } + } + { + const BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.WebViewHostApi.goBack', codec); + 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 args = (message as List?)!; + 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 {}; + }); + } + } + { + const BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.WebViewHostApi.goForward', codec); + 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 args = (message as List?)!; + 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 {}; + }); + } + } + { + const BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.WebViewHostApi.reload', codec); + 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 args = (message as List?)!; + 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 {}; + }); + } + } + { + const BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.WebViewHostApi.clearCache', codec); + 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 args = (message as List?)!; + 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 {}; + }); + } + } + { + const BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.WebViewHostApi.evaluateJavascript', codec); + 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 args = (message as List?)!; + 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 {'result': output}; + }); + } + } + { + const BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.WebViewHostApi.getTitle', codec); + 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 args = (message as List?)!; + 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 {'result': output}; + }); + } + } + { + const BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.WebViewHostApi.scrollTo', codec); + 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 args = (message as List?)!; + 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 {}; + }); + } + } + { + const BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.WebViewHostApi.scrollBy', codec); + 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 args = (message as List?)!; + 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 {}; + }); + } + } + { + const BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.WebViewHostApi.getScrollX', codec); + 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 args = (message as List?)!; + 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 {'result': output}; + }); + } + } + { + const BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.WebViewHostApi.getScrollY', codec); + 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 args = (message as List?)!; + 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 {'result': output}; + }); + } + } + { + const BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.WebViewHostApi.setWebContentsDebuggingEnabled', + codec); + 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 args = (message as List?)!; + 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 {}; + }); + } + } + { + const BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.WebViewHostApi.setWebViewClient', codec); + 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 args = (message as List?)!; + 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 {}; + }); + } + } + { + const BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.WebViewHostApi.addJavaScriptChannel', codec); + 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 args = (message as List?)!; + 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 {}; + }); + } + } + { + const BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.WebViewHostApi.removeJavaScriptChannel', codec); + 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 args = (message as List?)!; + 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 {}; + }); + } + } + { + const BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.WebViewHostApi.setDownloadListener', codec); + 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 args = (message as List?)!; + 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 {}; + }); + } + } + { + const BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.WebViewHostApi.setWebChromeClient', codec); + 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 args = (message as List?)!; + 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 {}; + }); + } + } + } +} + +class _TestWebSettingsHostApiCodec extends StandardMessageCodec { + const _TestWebSettingsHostApiCodec(); +} + +abstract class TestWebSettingsHostApi { + static const MessageCodec 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) { + { + const BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.WebSettingsHostApi.create', codec); + 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 args = (message as List?)!; + 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 {}; + }); + } + } + { + const BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.WebSettingsHostApi.dispose', codec); + 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 args = (message as List?)!; + 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 {}; + }); + } + } + { + const BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.WebSettingsHostApi.setDomStorageEnabled', codec); + 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 args = (message as List?)!; + 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 {}; + }); + } + } + { + const BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.WebSettingsHostApi.setJavaScriptCanOpenWindowsAutomatically', + codec); + 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 args = (message as List?)!; + 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 {}; + }); + } + } + { + const BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.WebSettingsHostApi.setSupportMultipleWindows', + codec); + 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 args = (message as List?)!; + 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 {}; + }); + } + } + { + const BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.WebSettingsHostApi.setJavaScriptEnabled', codec); + 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 args = (message as List?)!; + 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 {}; + }); + } + } + { + const BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.WebSettingsHostApi.setUserAgentString', codec); + 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 args = (message as List?)!; + 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 {}; + }); + } + } + { + const BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.WebSettingsHostApi.setMediaPlaybackRequiresUserGesture', + codec); + 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 args = (message as List?)!; + 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 {}; + }); + } + } + { + const BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.WebSettingsHostApi.setSupportZoom', codec); + 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 args = (message as List?)!; + 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 {}; + }); + } + } + { + const BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.WebSettingsHostApi.setLoadWithOverviewMode', + codec); + 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 args = (message as List?)!; + 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 {}; + }); + } + } + { + const BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.WebSettingsHostApi.setUseWideViewPort', codec); + 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 args = (message as List?)!; + 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 {}; + }); + } + } + { + const BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.WebSettingsHostApi.setDisplayZoomControls', + codec); + 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 args = (message as List?)!; + 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 {}; + }); + } + } + { + const BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.WebSettingsHostApi.setBuiltInZoomControls', + codec); + 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 args = (message as List?)!; + 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 {}; + }); + } + } + } +} + +class _TestJavaScriptChannelHostApiCodec extends StandardMessageCodec { + const _TestJavaScriptChannelHostApiCodec(); +} + +abstract class TestJavaScriptChannelHostApi { + static const MessageCodec codec = + _TestJavaScriptChannelHostApiCodec(); + + void create(int instanceId, String channelName); + void dispose(int instanceId); + static void setup(TestJavaScriptChannelHostApi? api) { + { + const BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.JavaScriptChannelHostApi.create', codec); + 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 args = (message as List?)!; + 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 {}; + }); + } + } + { + const BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.JavaScriptChannelHostApi.dispose', codec); + if (api == null) { + channel.setMockMessageHandler(null); + } else { + channel.setMockMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.JavaScriptChannelHostApi.dispose was null.'); + final List args = (message as List?)!; + final int? arg_instanceId = args[0] as int?; + assert(arg_instanceId != null, + 'Argument for dev.flutter.pigeon.JavaScriptChannelHostApi.dispose was null, expected non-null int.'); + api.dispose(arg_instanceId!); + return {}; + }); + } + } + } +} + +class _TestWebViewClientHostApiCodec extends StandardMessageCodec { + const _TestWebViewClientHostApiCodec(); +} + +abstract class TestWebViewClientHostApi { + static const MessageCodec codec = _TestWebViewClientHostApiCodec(); + + void create(int instanceId, bool shouldOverrideUrlLoading); + void dispose(int instanceId); + static void setup(TestWebViewClientHostApi? api) { + { + const BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.WebViewClientHostApi.create', codec); + 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 args = (message as List?)!; + 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 {}; + }); + } + } + { + const BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.WebViewClientHostApi.dispose', codec); + if (api == null) { + channel.setMockMessageHandler(null); + } else { + channel.setMockMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.WebViewClientHostApi.dispose was null.'); + final List args = (message as List?)!; + final int? arg_instanceId = args[0] as int?; + assert(arg_instanceId != null, + 'Argument for dev.flutter.pigeon.WebViewClientHostApi.dispose was null, expected non-null int.'); + api.dispose(arg_instanceId!); + return {}; + }); + } + } + } +} + +class _TestDownloadListenerHostApiCodec extends StandardMessageCodec { + const _TestDownloadListenerHostApiCodec(); +} + +abstract class TestDownloadListenerHostApi { + static const MessageCodec codec = + _TestDownloadListenerHostApiCodec(); + + void create(int instanceId); + void dispose(int instanceId); + static void setup(TestDownloadListenerHostApi? api) { + { + const BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.DownloadListenerHostApi.create', codec); + 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 args = (message as List?)!; + 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 {}; + }); + } + } + { + const BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.DownloadListenerHostApi.dispose', codec); + if (api == null) { + channel.setMockMessageHandler(null); + } else { + channel.setMockMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.DownloadListenerHostApi.dispose was null.'); + final List args = (message as List?)!; + final int? arg_instanceId = args[0] as int?; + assert(arg_instanceId != null, + 'Argument for dev.flutter.pigeon.DownloadListenerHostApi.dispose was null, expected non-null int.'); + api.dispose(arg_instanceId!); + return {}; + }); + } + } + } +} + +class _TestWebChromeClientHostApiCodec extends StandardMessageCodec { + const _TestWebChromeClientHostApiCodec(); +} + +abstract class TestWebChromeClientHostApi { + static const MessageCodec codec = _TestWebChromeClientHostApiCodec(); + + void create(int instanceId, int webViewClientInstanceId); + void dispose(int instanceId); + static void setup(TestWebChromeClientHostApi? api) { + { + const BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.WebChromeClientHostApi.create', codec); + 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 args = (message as List?)!; + 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 {}; + }); + } + } + { + const BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.WebChromeClientHostApi.dispose', codec); + if (api == null) { + channel.setMockMessageHandler(null); + } else { + channel.setMockMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.WebChromeClientHostApi.dispose was null.'); + final List args = (message as List?)!; + final int? arg_instanceId = args[0] as int?; + assert(arg_instanceId != null, + 'Argument for dev.flutter.pigeon.WebChromeClientHostApi.dispose was null, expected non-null int.'); + api.dispose(arg_instanceId!); + return {}; + }); + } + } + } +} diff --git a/packages/webview_flutter/webview_flutter_android/test/android_webview_test.dart b/packages/webview_flutter/webview_flutter_android/test/android_webview_test.dart new file mode 100644 index 000000000000..462670abdb83 --- /dev/null +++ b/packages/webview_flutter/webview_flutter_android/test/android_webview_test.dart @@ -0,0 +1,373 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:flutter_test/flutter_test.dart'; +import 'package:webview_flutter_android/src/android_webview.dart'; +import 'package:webview_flutter_android/src/android_webview_api_impls.dart'; +import 'package:webview_flutter_android/src/instance_manager.dart'; + +import 'android_webview.pigeon.dart'; + +void main() { + TestWidgetsFlutterBinding.ensureInitialized(); + + group('Android WebView', () { + group('$WebView', () { + setUpAll(() { + TestWebViewHostApi.setup(TestWebViewHostApiImpl()); + }); + + setUp(() { + WebView.api = WebViewHostApiImpl(instanceManager: InstanceManager()); + }); + + test('create', () { + final WebView webView = WebView(); + expect(WebView.api.instanceManager.getInstanceId(webView), isNotNull); + }); + }); + + group('$WebSettings', () { + setUpAll(() { + TestWebViewHostApi.setup(TestWebViewHostApiImpl()); + TestWebSettingsHostApi.setup(TestWebSettingsHostApiImpl()); + }); + + setUp(() { + final InstanceManager instanceManager = InstanceManager(); + WebView.api = WebViewHostApiImpl(instanceManager: instanceManager); + WebSettings.api = WebSettingsHostApiImpl( + instanceManager: instanceManager, + ); + }); + + test('create', () { + final WebView webView = WebView(); + final WebSettings webSettings = WebSettings(webView); + expect( + WebSettings.api.instanceManager.getInstanceId(webSettings), + isNotNull, + ); + }); + }); + + group('$JavaScriptChannel', () { + setUpAll(() { + TestWebViewHostApi.setup(TestWebViewHostApiImpl()); + TestJavaScriptChannelHostApi.setup(TestJavaScriptChannelHostApiImpl()); + }); + + setUp(() { + final InstanceManager instanceManager = InstanceManager(); + WebView.api = WebViewHostApiImpl(instanceManager: instanceManager); + JavaScriptChannel.api = JavaScriptChannelHostApiImpl( + instanceManager: instanceManager, + ); + }); + + test('create', () { + final WebView webView = WebView(); + final JavaScriptChannel channel = TestJavaScriptChannel('myChannel'); + + webView.addJavaScriptChannel(channel); + expect( + JavaScriptChannel.api.instanceManager.getInstanceId(channel), + isNotNull, + ); + + webView.removeJavaScriptChannel(channel); + expect( + JavaScriptChannel.api.instanceManager.getInstanceId(channel), + isNull, + ); + }); + }); + + group('$WebViewClient', () { + setUpAll(() { + TestWebViewHostApi.setup(TestWebViewHostApiImpl()); + TestWebViewClientHostApi.setup(TestWebViewClientHostApiImpl()); + }); + + setUp(() { + final InstanceManager instanceManager = InstanceManager(); + WebView.api = WebViewHostApiImpl(instanceManager: instanceManager); + WebViewClient.api = WebViewClientHostApiImpl( + instanceManager: instanceManager, + ); + }); + + test('create', () { + final WebView webView = WebView(); + final WebViewClient webViewClient1 = TestWebViewClient(); + final WebViewClient webViewClient2 = TestWebViewClient(); + + webView.setWebViewClient(webViewClient1); + expect( + WebViewClient.api.instanceManager.getInstanceId(webViewClient1), + isNotNull, + ); + + webView.setWebViewClient(webViewClient2); + expect( + WebViewClient.api.instanceManager.getInstanceId(webViewClient1), + isNull, + ); + }); + }); + + group('$DownloadListener', () { + setUpAll(() { + TestWebViewHostApi.setup(TestWebViewHostApiImpl()); + TestDownloadListenerHostApi.setup(TestDownloadListenerHostApiImpl()); + }); + + setUp(() { + final InstanceManager instanceManager = InstanceManager(); + WebView.api = WebViewHostApiImpl(instanceManager: instanceManager); + DownloadListener.api = DownloadListenerHostApiImpl( + instanceManager: instanceManager, + ); + }); + + test('create', () { + final WebView webView = WebView(); + final DownloadListener downloadListener1 = TestDownloadListener(); + final DownloadListener downloadListener2 = TestDownloadListener(); + + webView.setDownloadListener(downloadListener1); + expect( + DownloadListener.api.instanceManager.getInstanceId(downloadListener1), + isNotNull, + ); + + webView.setDownloadListener(downloadListener2); + expect( + DownloadListener.api.instanceManager.getInstanceId(downloadListener1), + isNull, + ); + }); + }); + + group('$WebChromeClient', () { + setUpAll(() { + TestWebViewHostApi.setup(TestWebViewHostApiImpl()); + TestWebViewClientHostApi.setup(TestWebViewClientHostApiImpl()); + TestWebChromeClientHostApi.setup(TestWebChromeClientHostApiImpl()); + }); + + setUp(() { + final InstanceManager instanceManager = InstanceManager(); + WebView.api = WebViewHostApiImpl(instanceManager: instanceManager); + WebViewClient.api = WebViewClientHostApiImpl( + instanceManager: instanceManager, + ); + WebChromeClient.api = WebChromeClientHostApiImpl( + instanceManager: instanceManager, + ); + }); + + test('create', () { + final WebView webView = WebView(); + webView.setWebViewClient(TestWebViewClient()); + + final WebChromeClient webChromeClient1 = TestWebChromeClient(); + final WebChromeClient webChromeClient2 = TestWebChromeClient(); + + webView.setWebChromeClient(webChromeClient1); + expect( + WebChromeClient.api.instanceManager.getInstanceId(webChromeClient1), + isNotNull, + ); + + webView.setWebChromeClient(webChromeClient2); + expect( + WebChromeClient.api.instanceManager.getInstanceId(webChromeClient1), + isNull, + ); + }); + }); + }); +} + +class TestJavaScriptChannel extends JavaScriptChannel { + TestJavaScriptChannel(String channelName) : super(channelName); + + @override + void postMessage(String message) {} +} + +class TestWebViewClient extends WebViewClient {} + +class TestDownloadListener extends DownloadListener { + @override + void onDownloadStart( + String url, + String userAgent, + String contentDisposition, + String mimetype, + int contentLength, + ) {} +} + +class TestWebChromeClient extends WebChromeClient { + @override + void onProgressChanged(WebView webView, int progress) {} +} + +class TestWebViewHostApiImpl extends TestWebViewHostApi { + @override + void addJavaScriptChannel(int instanceId, int javaScriptChannelInstanceId) {} + + @override + bool canGoBack(int instanceId) { + throw UnimplementedError(); + } + + @override + bool canGoForward(int instanceId) { + throw UnimplementedError(); + } + + @override + void clearCache(int instanceId, bool includeDiskFiles) {} + + @override + void create(int instanceId, bool useHybridComposition) {} + + @override + void dispose(int instanceId) {} + + @override + Future evaluateJavascript(int instanceId, String javascriptString) { + throw UnimplementedError(); + } + + @override + int getScrollX(int instanceId) { + throw UnimplementedError(); + } + + @override + int getScrollY(int instanceId) { + throw UnimplementedError(); + } + + @override + String getTitle(int instanceId) { + throw UnimplementedError(); + } + + @override + String getUrl(int instanceId) { + throw UnimplementedError(); + } + + @override + void goBack(int instanceId) {} + + @override + void goForward(int instanceId) {} + + @override + void loadUrl(int instanceId, String url, Map headers) {} + + @override + void reload(int instanceId) {} + + @override + void removeJavaScriptChannel( + int instanceId, int javaScriptChannelInstanceId) {} + + @override + void scrollBy(int instanceId, int x, int y) {} + + @override + void scrollTo(int instanceId, int x, int y) {} + + @override + void setDownloadListener(int instanceId, int listenerInstanceId) {} + + @override + void setWebContentsDebuggingEnabled(bool enabled) {} + + @override + void setWebViewClient(int instanceId, int webViewClientInstanceId) {} + + @override + void setWebChromeClient(int instanceId, int clientInstanceId) {} +} + +class TestWebSettingsHostApiImpl extends TestWebSettingsHostApi { + @override + void create(int instanceId, int webViewInstanceId) {} + + @override + void dispose(int instanceId) {} + + @override + void setBuiltInZoomControls(int instanceId, bool enabled) {} + + @override + void setDisplayZoomControls(int instanceId, bool enabled) {} + + @override + void setDomStorageEnabled(int instanceId, bool flag) {} + + @override + void setJavaScriptCanOpenWindowsAutomatically(int instanceId, bool flag) {} + + @override + void setJavaScriptEnabled(int instanceId, bool flag) {} + + @override + void setLoadWithOverviewMode(int instanceId, bool overview) {} + + @override + void setMediaPlaybackRequiresUserGesture(int instanceId, bool require) {} + + @override + void setSupportMultipleWindows(int instanceId, bool support) {} + + @override + void setSupportZoom(int instanceId, bool support) {} + + @override + void setUseWideViewPort(int instanceId, bool use) {} + + @override + void setUserAgentString(int instanceId, String userAgentString) {} +} + +class TestJavaScriptChannelHostApiImpl extends TestJavaScriptChannelHostApi { + @override + void create(int instanceId, String channelName) {} + + @override + void dispose(int instanceId) {} +} + +class TestWebViewClientHostApiImpl extends TestWebViewClientHostApi { + @override + void create(int instanceId, bool shouldOverrideUrlLoading) {} + + @override + void dispose(int instanceId) {} +} + +class TestDownloadListenerHostApiImpl extends TestDownloadListenerHostApi { + @override + void create(int instanceId) {} + + @override + void dispose(int instanceId) {} +} + +class TestWebChromeClientHostApiImpl extends TestWebChromeClientHostApi { + @override + void create(int instanceId, int webViewClientInstanceId) {} + + @override + void dispose(int instanceId) {} +} diff --git a/packages/webview_flutter/webview_flutter_android/test/instance_manager_test.dart b/packages/webview_flutter/webview_flutter_android/test/instance_manager_test.dart new file mode 100644 index 000000000000..fd020fc362c8 --- /dev/null +++ b/packages/webview_flutter/webview_flutter_android/test/instance_manager_test.dart @@ -0,0 +1,35 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:flutter_test/flutter_test.dart'; +import 'package:webview_flutter_android/src/instance_manager.dart'; + +void main() { + group('$InstanceManager', () { + late InstanceManager testInstanceManager; + + setUp(() { + testInstanceManager = InstanceManager(); + }); + + test('tryAddInstance', () { + final Object object = Object(); + + expect(testInstanceManager.tryAddInstance(object), 0); + expect(testInstanceManager.getInstanceId(object), 0); + expect(testInstanceManager.getInstance(0), object); + expect(testInstanceManager.tryAddInstance(object), null); + }); + + test('removeInstance', () { + final Object object = Object(); + testInstanceManager.tryAddInstance(object); + + expect(testInstanceManager.removeInstance(object), 0); + expect(testInstanceManager.getInstanceId(object), null); + expect(testInstanceManager.getInstance(0), null); + expect(testInstanceManager.removeInstance(object), null); + }); + }); +}