[webview] Add dart webview on top of chromium
Change-Id: I8d7ab0fcca8c0995599bbe3467debdf847303408
diff --git a/public/lib/webview/BUILD.gn b/public/lib/webview/BUILD.gn
new file mode 100644
index 0000000..a1331ae
--- /dev/null
+++ b/public/lib/webview/BUILD.gn
@@ -0,0 +1,23 @@
+# Copyright 2018 The Fuchsia 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("//build/dart/dart_library.gni")
+
+dart_library("webview") {
+ package_name = "webview"
+
+ sources = [
+ "webview.dart",
+ ]
+
+ deps = [
+ "//sdk/fidl/fuchsia.sys",
+ "//sdk/fidl/fuchsia.ui.views",
+ "//topaz/public/dart/fuchsia_logger",
+ "//topaz/public/dart/fuchsia_scenic_flutter",
+ "//topaz/runtime/chromium:chromium.web",
+ "//zircon/public/fidl/fuchsia-io",
+ "//zircon/public/fidl/fuchsia-mem",
+ ]
+}
diff --git a/public/lib/webview/OWNERS b/public/lib/webview/OWNERS
new file mode 100644
index 0000000..dbb45dc
--- /dev/null
+++ b/public/lib/webview/OWNERS
@@ -0,0 +1,2 @@
+miguelfrde@google.com
+*
diff --git a/public/lib/webview/analysis_options.yaml b/public/lib/webview/analysis_options.yaml
new file mode 100644
index 0000000..f0cea8a
--- /dev/null
+++ b/public/lib/webview/analysis_options.yaml
@@ -0,0 +1,5 @@
+# Copyright 2018 The Fuchsia Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+include: ../../../tools/analysis_options.yaml
diff --git a/public/lib/webview/lib/src/webview.dart b/public/lib/webview/lib/src/webview.dart
new file mode 100644
index 0000000..462afaa
--- /dev/null
+++ b/public/lib/webview/lib/src/webview.dart
@@ -0,0 +1,99 @@
+// Copyright 2018 The Fuchsia 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:convert' show utf8;
+import 'dart:io';
+
+import 'package:fidl/fidl.dart';
+import 'package:fidl_chromium_web/fidl_async.dart' as web;
+import 'package:fidl_fuchsia_mem/fidl_async.dart' as fuchsia_mem;
+import 'package:fidl_fuchsia_io/fidl_async.dart' as fidl_io;
+import 'package:fidl_fuchsia_sys/fidl_async.dart' as sys;
+import 'package:fidl_fuchsia_ui_views/fidl_async.dart' as views;
+import 'package:fuchsia_logger/logger.dart';
+import 'package:fuchsia_scenic_flutter/child_view_connection.dart'
+ show ChildViewConnection;
+import 'package:zircon/zircon.dart';
+
+class ChromiumWebView {
+ final sys.ServiceProvider serviceProvider;
+ final web.ContextProviderProxy _contextProvider = web.ContextProviderProxy();
+ final web.ContextProxy _context = web.ContextProxy();
+ final web.FrameProxy _frame = web.FrameProxy();
+ final web.NavigationControllerProxy _navigationController =
+ web.NavigationControllerProxy();
+
+ final web.NavigationEventObserverBinding _navigationEventObserverBinding =
+ web.NavigationEventObserverBinding();
+
+ ChildViewConnection _childViewConnection;
+
+ ChromiumWebView(
+ this.serviceProvider, {
+ web.LogLevel javascriptLogLevel = web.LogLevel.none,
+ }) {
+ final contextProviderProxyRequest = _contextProvider.ctrl.request();
+ serviceProvider.connectToService(_contextProvider.ctrl.$serviceName,
+ contextProviderProxyRequest.passChannel());
+ if (!Directory('/svc').existsSync()) {
+ log.shout('no /svc directory');
+ return;
+ }
+ final channel = Channel.fromFile('/svc');
+ final web.CreateContextParams params = web.CreateContextParams(
+ serviceDirectory: InterfaceHandle<fidl_io.Directory>(channel));
+ _contextProvider.create(params, _context.ctrl.request());
+ _context.createFrame(_frame.ctrl.request());
+
+ // Create a token pair for the newly-created View.
+ final tokenPair = EventPairPair();
+ assert(tokenPair.status == ZX.OK);
+ final viewHolderToken = views.ViewHolderToken(value: tokenPair.first);
+ final viewToken = views.ViewToken(value: tokenPair.second);
+
+ _frame.createView2(viewToken.value, null, null);
+ _childViewConnection = ChildViewConnection(viewHolderToken);
+ _frame
+ ..getNavigationController(_navigationController.ctrl.request())
+ ..setJavaScriptLogLevel(javascriptLogLevel);
+ }
+
+ ChildViewConnection get childViewConnection => _childViewConnection;
+
+ web.NavigationControllerProxy get controller => _navigationController;
+
+ void setNavigationEventObserver(web.NavigationEventObserver observer) {
+ _frame.setNavigationEventObserver(
+ _navigationEventObserverBinding.wrap(observer));
+ }
+
+ Future<bool> injectJavascript(
+ String script,
+ List<String> origins, {
+ web.ExecuteMode executeMode = web.ExecuteMode.onPageLoad,
+ }) {
+ final vmo = SizedVmo.fromUint8List(utf8.encode(script));
+ final buffer = fuchsia_mem.Buffer(vmo: vmo, size: vmo.size);
+ return _frame.executeJavaScript(origins, buffer, executeMode);
+ }
+
+ Future<bool> postMessage(String message, String targetOrigin,
+ {InterfaceRequest<web.MessagePort> outgoingMessagePortRequest}) {
+ final vmo = SizedVmo.fromUint8List(utf8.encode(message));
+ var msg = web.WebMessage(
+ data: fuchsia_mem.Buffer(vmo: vmo, size: vmo.size),
+ outgoingTransfer: outgoingMessagePortRequest != null
+ ? web.OutgoingTransferable.withMessagePort(outgoingMessagePortRequest)
+ : null,
+ );
+ return _frame.postMessage(msg, targetOrigin);
+ }
+
+ void dispose() {
+ _navigationController.ctrl.close();
+ _frame.ctrl.close();
+ _context.ctrl.close();
+ _contextProvider.ctrl.close();
+ }
+}
diff --git a/public/lib/webview/lib/webview.dart b/public/lib/webview/lib/webview.dart
new file mode 100644
index 0000000..5853a51
--- /dev/null
+++ b/public/lib/webview/lib/webview.dart
@@ -0,0 +1,5 @@
+// Copyright 2018 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+export 'src/webview.dart';
diff --git a/public/lib/webview/pubspec.yaml b/public/lib/webview/pubspec.yaml
new file mode 100644
index 0000000..8db0f51
--- /dev/null
+++ b/public/lib/webview/pubspec.yaml
@@ -0,0 +1,5 @@
+# Copyright 2018 The Fuchsia Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+name: webview