blob: 91cb3b6cfc1982257e03b9590e07067c03bd97d4 [file] [log] [blame]
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'dart:async';
import 'package:flutter/services.dart';
import '../platform_interface.dart';
/// A [WebViewPlatformController] that uses a method channel to control the webview.
class MethodChannelWebViewPlatform implements WebViewPlatformController {
MethodChannelWebViewPlatform(int id, this._platformCallbacksHandler)
: assert(_platformCallbacksHandler != null),
_channel = MethodChannel('plugins.flutter.io/webview_$id') {
_channel.setMethodCallHandler(_onMethodCall);
}
final WebViewPlatformCallbacksHandler _platformCallbacksHandler;
final MethodChannel _channel;
static const MethodChannel _cookieManagerChannel =
MethodChannel('plugins.flutter.io/cookie_manager');
Future<bool> _onMethodCall(MethodCall call) async {
switch (call.method) {
case 'javascriptChannelMessage':
final String channel = call.arguments['channel'];
final String message = call.arguments['message'];
_platformCallbacksHandler.onJavaScriptChannelMessage(channel, message);
return true;
case 'navigationRequest':
return _platformCallbacksHandler.onNavigationRequest(
url: call.arguments['url'],
isForMainFrame: call.arguments['isForMainFrame'],
);
case 'onPageFinished':
_platformCallbacksHandler.onPageFinished(call.arguments['url']);
return null;
}
throw MissingPluginException(
'${call.method} was invoked but has no handler');
}
@override
Future<void> loadUrl(
String url,
Map<String, String> headers,
) async {
assert(url != null);
// TODO(amirh): remove this on when the invokeMethod update makes it to stable Flutter.
// https://github.com/flutter/flutter/issues/26431
// ignore: strong_mode_implicit_dynamic_method
return _channel.invokeMethod('loadUrl', <String, dynamic>{
'url': url,
'headers': headers,
});
}
@override
Future<String> currentUrl() => _channel.invokeMethod('currentUrl');
@override
Future<bool> canGoBack() => _channel.invokeMethod("canGoBack");
@override
Future<bool> canGoForward() => _channel.invokeMethod("canGoForward");
@override
Future<void> goBack() => _channel.invokeMethod("goBack");
@override
Future<void> goForward() => _channel.invokeMethod("goForward");
@override
Future<void> reload() => _channel.invokeMethod("reload");
@override
Future<void> clearCache() => _channel.invokeMethod("clearCache");
@override
Future<void> updateSettings(WebSettings settings) {
// TODO(amirh): remove this on when the invokeMethod update makes it to stable Flutter.
// https://github.com/flutter/flutter/issues/26431
// ignore: strong_mode_implicit_dynamic_method
final Map<String, dynamic> updatesMap = _webSettingsToMap(settings);
if (updatesMap.isEmpty) {
return null;
}
return _channel.invokeMethod('updateSettings', updatesMap);
}
@override
Future<String> evaluateJavascript(String javascriptString) {
return _channel.invokeMethod('evaluateJavascript', javascriptString);
}
@override
Future<void> addJavascriptChannels(Set<String> javascriptChannelNames) {
return _channel.invokeMethod(
'addJavascriptChannels', javascriptChannelNames.toList());
}
@override
Future<void> removeJavascriptChannels(Set<String> javascriptChannelNames) {
return _channel.invokeMethod(
'removeJavascriptChannels', javascriptChannelNames.toList());
}
/// Method channel mplementation for [WebViewPlatform.clearCookies].
static Future<bool> clearCookies() {
return _cookieManagerChannel
// TODO(amirh): remove this when the invokeMethod update makes it to stable Flutter.
// https://github.com/flutter/flutter/issues/26431
// ignore: strong_mode_implicit_dynamic_method
.invokeMethod('clearCookies')
.then<bool>((dynamic result) => result);
}
static Map<String, dynamic> _webSettingsToMap(WebSettings settings) {
final Map<String, dynamic> map = <String, dynamic>{};
void _addIfNonNull(String key, dynamic value) {
if (value == null) {
return;
}
map[key] = value;
}
_addIfNonNull('jsMode', settings.javascriptMode?.index);
_addIfNonNull('hasNavigationDelegate', settings.hasNavigationDelegate);
_addIfNonNull('debuggingEnabled', settings.debuggingEnabled);
return map;
}
/// Converts a [CreationParams] object to a map as expected by `platform_views` channel.
///
/// This is used for the `creationParams` argument of the platform views created by
/// [AndroidWebViewBuilder] and [CupertinoWebViewBuilder].
static Map<String, dynamic> creationParamsToMap(
CreationParams creationParams) {
return <String, dynamic>{
'initialUrl': creationParams.initialUrl,
'settings': _webSettingsToMap(creationParams.webSettings),
'javascriptChannelNames': creationParams.javascriptChannelNames.toList(),
};
}
}