[scenic] child_view -> V2 ViewProvider

ChildViewConnection now uses eventpairs and the V2 ViewProvider
interface.

TEST: Ran SysUI, set_root_view perspective, set_root_view simple_flutter

SCN-898 #comment
SCN-1031 #comment

Change-Id: I615925bdda89d95869c7812c728a56117008d204
diff --git a/public/dart/fuchsia_scenic_flutter/BUILD.gn b/public/dart/fuchsia_scenic_flutter/BUILD.gn
index bb8d8e0..2a78a90 100644
--- a/public/dart/fuchsia_scenic_flutter/BUILD.gn
+++ b/public/dart/fuchsia_scenic_flutter/BUILD.gn
@@ -14,8 +14,8 @@
 
   sources = [
     "child_view.dart",
-    "src/child_view_connection.dart",
     "src/child_view.dart",
+    "src/child_view_connection.dart",
     "src/internal/_child_scene_layer.dart",
     "src/internal/_mozart.dart",
     "src/internal/_view_container_listener_impl.dart",
@@ -24,15 +24,17 @@
 
   deps = [
     "//garnet/public/fidl/fuchsia.math",
+    "//garnet/public/fidl/fuchsia.sys",
+    "//garnet/public/fidl/fuchsia.ui.app",
     "//garnet/public/fidl/fuchsia.ui.viewsv1",
     "//garnet/public/fidl/fuchsia.ui.viewsv1token",
-    "//garnet/public/fidl/fuchsia.sys",
     "//third_party/dart-pkg/git/flutter/packages/flutter",
     "//third_party/dart-pkg/pub/meta",
     "//topaz/public/dart/fidl",
     "//topaz/public/dart/fuchsia_logger",
   ]
 }
+
 # Runs these tests using:
 #   fx run-host-tests fuchsia_scenic_flutter_unittests
 dart_test("fuchsia_scenic_flutter_unittests") {
@@ -44,4 +46,4 @@
     ":fuchsia_scenic_flutter",
     "//third_party/dart-pkg/pub/test",
   ]
-}
\ No newline at end of file
+}
diff --git a/public/dart/fuchsia_scenic_flutter/lib/src/child_view_connection.dart b/public/dart/fuchsia_scenic_flutter/lib/src/child_view_connection.dart
index 7b79273..379db7d 100644
--- a/public/dart/fuchsia_scenic_flutter/lib/src/child_view_connection.dart
+++ b/public/dart/fuchsia_scenic_flutter/lib/src/child_view_connection.dart
@@ -75,13 +75,15 @@
   //     {InterfaceRequest<ServiceProvider> childServices,
   //     ChildViewConnectionCallback onAvailable,
   //     ChildViewConnectionCallback onUnavailable}) {
-  //   final ViewProviderProxy viewProvider = ViewProviderProxy();
-  //   services.connectToService(viewProvider.ctrl);
-  //   try {
-  //     final InterfacePair<ViewOwner> viewOwner = InterfacePair<ViewOwner>();
-  //     viewProvider.createView(viewOwner.passRequest(), childServices);
-  //     return ChildViewConnection(viewOwner.passHandle(),
-  //         onAvailable: onAvailable, onUnavailable: onUnavailable);
+  // final app.ViewProviderProxy viewProvider = new app.ViewProviderProxy();
+  // services.connectToService(viewProvider.ctrl);
+  // try {
+  //   EventPairPair viewTokens = new EventPairPair();
+  //   assert(viewTokens.status == ZX.OK);
+
+  //   viewProvider.createView(viewTokens.second, childServices, null);
+  //   return new ChildViewConnection.fromViewHolderToken(viewTokens.first,
+  //       onAvailable: onAvailable, onUnavailable: onUnavailable);
   //   } finally {
   //     viewProvider.ctrl.close();
   //   }
@@ -89,7 +91,7 @@
 
   final ChildViewConnectionCallback _onAvailableCallback;
   final ChildViewConnectionCallback _onUnavailableCallback;
-  InterfaceHandle<ViewOwner> _viewOwner;
+  EventPair _viewHolderToken;
 
   int _viewKey;
   ViewProperties _currentViewProperties;
@@ -100,13 +102,24 @@
   SceneHost _sceneHost;
   int _attachments = 0;
 
-  /// inits [ChildViewConnection] object
-  ChildViewConnection(this._viewOwner,
+  /// Deprecated.
+  ChildViewConnection(InterfaceHandle<ViewOwner> viewOwner,
+      {ChildViewConnectionCallback onAvailable,
+      ChildViewConnectionCallback onUnavailable})
+      : this.fromViewHolderToken(
+            new EventPair(viewOwner?.passChannel()?.passHandle()),
+            onAvailable: onAvailable,
+            onUnavailable: onUnavailable);
+
+  /// Constructs |ChildViewConnection| from a token.
+  ChildViewConnection.fromViewHolderToken(EventPair viewHolderToken,
       {ChildViewConnectionCallback onAvailable,
       ChildViewConnectionCallback onUnavailable})
       : _onAvailableCallback = onAvailable ?? _emptyConnectionCallback,
         _onUnavailableCallback = onUnavailable ?? _emptyConnectionCallback,
-        assert(_viewOwner != null);
+        _viewHolderToken = viewHolderToken {
+    assert(_viewHolderToken != null);
+  }
 
   bool get _attached => _attachments > 0;
 
@@ -159,7 +172,7 @@
       return;
     }
     assert(_attached);
-    assert(_viewOwner != null);
+    assert(_viewHolderToken != null);
     assert(_viewKey == null);
     assert(_viewInfo == null);
     assert(_sceneHost == null);
@@ -170,8 +183,8 @@
     // Analyzer doesn't know Handle must be dart:zircon's Handle
     _sceneHost = new SceneHost(sceneTokens.first.passHandle());
     _viewKey = _nextViewKey++;
-    _viewContainer.addChild(_viewKey, _viewOwner, sceneTokens.second);
-    _viewOwner = null;
+    _viewContainer.addChild2(_viewKey, _viewHolderToken, sceneTokens.second);
+    _viewHolderToken = null;
     assert(!ViewContainerListenerImpl().containsConnectionForKey(_viewKey));
     ViewContainerListenerImpl().addConnectionForKey(_viewKey, this);
   }
@@ -227,16 +240,15 @@
       return;
     }
     assert(!_attached);
-    assert(_viewOwner == null);
+    assert(_viewHolderToken == null);
     assert(_viewKey != null);
     assert(_sceneHost != null);
     assert(ViewContainerListenerImpl().getConnectionForKey(_viewKey) == this);
-    final ChannelPair pair = ChannelPair();
-    assert(pair.status == ZX.OK);
+    final EventPairPair viewTokens = new EventPairPair();
+    assert(viewTokens.status == ZX.OK);
     ViewContainerListenerImpl().removeConnectionForKey(_viewKey);
-    _viewOwner = InterfaceHandle<ViewOwner>(pair.first);
-    _viewContainer.removeChild(
-        _viewKey, InterfaceRequest<ViewOwner>(pair.second));
+    _viewHolderToken = viewTokens.first;
+    _viewContainer.removeChild2(_viewKey, viewTokens.second);
     _viewKey = null;
     _viewInfo = null;
     _currentViewProperties = null;
diff --git a/public/lib/ui/flutter/BUILD.gn b/public/lib/ui/flutter/BUILD.gn
index 8eff7c5..34f3e6f 100644
--- a/public/lib/ui/flutter/BUILD.gn
+++ b/public/lib/ui/flutter/BUILD.gn
@@ -18,6 +18,7 @@
 
   deps = [
     "//garnet/public/fidl/fuchsia.math",
+    "//garnet/public/fidl/fuchsia.ui.app",
     "//garnet/public/fidl/fuchsia.ui.viewsv1",
     "//third_party/dart-pkg/git/flutter/packages/flutter",
     "//third_party/dart-pkg/pub/meta",
diff --git a/public/lib/ui/flutter/child_view.dart b/public/lib/ui/flutter/child_view.dart
index 0db9144..2ad7f41 100644
--- a/public/lib/ui/flutter/child_view.dart
+++ b/public/lib/ui/flutter/child_view.dart
@@ -9,6 +9,7 @@
 import 'package:lib.app.dart/app.dart';
 import 'package:fidl_fuchsia_sys/fidl.dart';
 import 'package:fidl_fuchsia_math/fidl.dart' as fidl;
+import 'package:fidl_fuchsia_ui_app/fidl.dart' as app;
 import 'package:fidl_fuchsia_ui_viewsv1/fidl.dart';
 import 'package:fidl_fuchsia_ui_viewsv1token/fidl.dart';
 import 'package:flutter/rendering.dart';
@@ -20,7 +21,6 @@
 import 'mozart.dart';
 
 export 'package:fidl_fuchsia_ui_viewsv1token/fidl.dart' show ViewOwner;
-export 'child_view2.dart';
 
 ViewContainerProxy _initViewContainer() {
   // Analyzer doesn't know Handle must be dart:zircon's Handle
@@ -81,12 +81,22 @@
 ///
 /// Used with the [ChildView] widget to display a child view.
 class ChildViewConnection {
-  ChildViewConnection(this._viewOwner,
+  ChildViewConnection(InterfaceHandle<ViewOwner> viewOwner,
+      {ChildViewConnectionCallback onAvailable,
+      ChildViewConnectionCallback onUnavailable})
+      : this.fromViewHolderToken(
+            new EventPair(viewOwner?.passChannel()?.passHandle()),
+            onAvailable: onAvailable,
+            onUnavailable: onUnavailable);
+
+  ChildViewConnection.fromViewHolderToken(EventPair viewHolderToken,
       {ChildViewConnectionCallback onAvailable,
       ChildViewConnectionCallback onUnavailable})
       : _onAvailableCallback = onAvailable ?? _emptyConnectionCallback,
         _onUnavailableCallback = onUnavailable ?? _emptyConnectionCallback,
-        assert(_viewOwner != null);
+        _viewHolderToken = viewHolderToken {
+    assert(_viewHolderToken != null);
+  }
 
   factory ChildViewConnection.launch(String url, Launcher launcher,
       {InterfaceRequest<ComponentController> controller,
@@ -111,12 +121,14 @@
       {InterfaceRequest<ServiceProvider> childServices,
       ChildViewConnectionCallback onAvailable,
       ChildViewConnectionCallback onUnavailable}) {
-    final ViewProviderProxy viewProvider = new ViewProviderProxy();
+    final app.ViewProviderProxy viewProvider = new app.ViewProviderProxy();
     services.connectToService(viewProvider.ctrl);
     try {
-      final InterfacePair<ViewOwner> viewOwner = new InterfacePair<ViewOwner>();
-      viewProvider.createView(viewOwner.passRequest(), childServices);
-      return new ChildViewConnection(viewOwner.passHandle(),
+      EventPairPair viewTokens = new EventPairPair();
+      assert(viewTokens.status == ZX.OK);
+
+      viewProvider.createView(viewTokens.second, childServices, null);
+      return new ChildViewConnection.fromViewHolderToken(viewTokens.first,
           onAvailable: onAvailable, onUnavailable: onUnavailable);
     } finally {
       viewProvider.ctrl.close();
@@ -125,7 +137,7 @@
 
   final ChildViewConnectionCallback _onAvailableCallback;
   final ChildViewConnectionCallback _onUnavailableCallback;
-  InterfaceHandle<ViewOwner> _viewOwner;
+  EventPair _viewHolderToken;
 
   static int _nextViewKey = 1;
   int _viewKey;
@@ -155,7 +167,7 @@
       return;
     }
     assert(_attached);
-    assert(_viewOwner != null);
+    assert(_viewHolderToken != null);
     assert(_viewKey == null);
     assert(_viewInfo == null);
     assert(_sceneHost == null);
@@ -166,8 +178,8 @@
     // Analyzer doesn't know Handle must be dart:zircon's Handle
     _sceneHost = new ui.SceneHost(sceneTokens.first.passHandle());
     _viewKey = _nextViewKey++;
-    _viewContainer.addChild(_viewKey, _viewOwner, sceneTokens.second);
-    _viewOwner = null;
+    _viewContainer.addChild2(_viewKey, _viewHolderToken, sceneTokens.second);
+    _viewHolderToken = null;
     assert(!_ViewContainerListenerImpl.instance._connections
         .containsKey(_viewKey));
     _ViewContainerListenerImpl.instance._connections[_viewKey] = this;
@@ -178,16 +190,15 @@
       return;
     }
     assert(!_attached);
-    assert(_viewOwner == null);
+    assert(_viewHolderToken == null);
     assert(_viewKey != null);
     assert(_sceneHost != null);
     assert(_ViewContainerListenerImpl.instance._connections[_viewKey] == this);
-    final ChannelPair pair = new ChannelPair();
-    assert(pair.status == ZX.OK);
+    final EventPairPair viewTokens = new EventPairPair();
+    assert(viewTokens.status == ZX.OK);
     _ViewContainerListenerImpl.instance._connections.remove(_viewKey);
-    _viewOwner = new InterfaceHandle<ViewOwner>(pair.first);
-    _viewContainer.removeChild(
-        _viewKey, new InterfaceRequest<ViewOwner>(pair.second));
+    _viewHolderToken = viewTokens.first;
+    _viewContainer.removeChild2(_viewKey, viewTokens.second);
     _viewKey = null;
     _viewInfo = null;
     _currentViewProperties = null;
diff --git a/public/lib/ui/flutter/child_view2.dart b/public/lib/ui/flutter/child_view2.dart
deleted file mode 100644
index 36a83b7..0000000
--- a/public/lib/ui/flutter/child_view2.dart
+++ /dev/null
@@ -1,562 +0,0 @@
-// Copyright 2016 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:async';
-import 'dart:collection';
-import 'dart:ui' as ui;
-
-import 'package:lib.app.dart/app.dart';
-import 'package:fidl_fuchsia_sys/fidl.dart';
-import 'package:fidl_fuchsia_math/fidl.dart' as fidl;
-import 'package:fidl_fuchsia_ui_viewsv1/fidl.dart';
-import 'package:fidl_fuchsia_ui_viewsv1token/fidl.dart';
-import 'package:flutter/rendering.dart';
-import 'package:flutter/widgets.dart';
-import 'package:fidl/fidl.dart';
-import 'package:meta/meta.dart';
-import 'package:zircon/zircon.dart';
-
-import 'mozart.dart';
-
-export 'package:fidl_fuchsia_ui_viewsv1token/fidl.dart' show ViewOwner;
-
-ViewContainerProxy _initViewContainer() {
-  // Analyzer doesn't know Handle must be dart:zircon's Handle
-  final Handle handle = ScenicStartupInfo.takeViewContainer();
-  if (handle == null) {
-    return null;
-  }
-  final ViewContainerProxy proxy = new ViewContainerProxy()
-    ..ctrl.bind(new InterfaceHandle<ViewContainer>(new Channel(handle)))
-    ..setListener(_ViewContainerListenerImpl2.instance.createInterfaceHandle());
-
-  assert(() {
-    proxy.ctrl.error.then((ProxyError error) {
-      print('ViewContainerProxy: error: $error');
-    });
-    return true;
-  }());
-
-  return proxy;
-}
-
-final ViewContainerProxy _viewContainer = _initViewContainer();
-
-class _ViewContainerListenerImpl2 extends ViewContainerListener {
-  final ViewContainerListenerBinding _binding =
-      new ViewContainerListenerBinding();
-
-  InterfaceHandle<ViewContainerListener> createInterfaceHandle() {
-    return _binding.wrap(this);
-  }
-
-  static final _ViewContainerListenerImpl2 instance =
-      new _ViewContainerListenerImpl2();
-
-  @override
-  void onChildAttached(int childKey, ViewInfo childViewInfo, void callback()) {
-    ChildViewConnection2 connection = _connections[childKey];
-    connection?._onAttachedToContainer(childViewInfo);
-    callback();
-  }
-
-  @override
-  void onChildUnavailable(int childKey, void callback()) {
-    ChildViewConnection2 connection = _connections[childKey];
-    connection?._onUnavailable();
-    callback();
-  }
-
-  final Map<int, ChildViewConnection2> _connections =
-      new HashMap<int, ChildViewConnection2>();
-}
-
-typedef ChildViewConnection2Callback = void Function(
-    ChildViewConnection2 connection);
-void _emptyConnectionCallback(ChildViewConnection2 c) {}
-
-/// A connection with a child view.
-///
-/// Used with the [ChildView2] widget to display a child view.
-class ChildViewConnection2 {
-  ChildViewConnection2(this._viewOwner,
-      {ChildViewConnection2Callback onAvailable,
-      ChildViewConnection2Callback onUnavailable})
-      : _onAvailableCallback = onAvailable ?? _emptyConnectionCallback,
-        _onUnavailableCallback = onUnavailable ?? _emptyConnectionCallback,
-        assert(_viewOwner != null);
-
-  factory ChildViewConnection2.launch(String url, Launcher launcher,
-      {InterfaceRequest<ComponentController> controller,
-      InterfaceRequest<ServiceProvider> childServices,
-      ChildViewConnection2Callback onAvailable,
-      ChildViewConnection2Callback onUnavailable}) {
-    final Services services = new Services();
-    final LaunchInfo launchInfo =
-        new LaunchInfo(url: url, directoryRequest: services.request());
-    try {
-      launcher.createComponent(launchInfo, controller);
-      return new ChildViewConnection2.connect(services,
-          childServices: childServices,
-          onAvailable: onAvailable,
-          onUnavailable: onUnavailable);
-    } finally {
-      services.close();
-    }
-  }
-
-  factory ChildViewConnection2.connect(Services services,
-      {InterfaceRequest<ServiceProvider> childServices,
-      ChildViewConnection2Callback onAvailable,
-      ChildViewConnection2Callback onUnavailable}) {
-    final ViewProviderProxy viewProvider = new ViewProviderProxy();
-    services.connectToService(viewProvider.ctrl);
-    try {
-      final InterfacePair<ViewOwner> viewOwner = new InterfacePair<ViewOwner>();
-      viewProvider.createView(viewOwner.passRequest(), childServices);
-      return new ChildViewConnection2(viewOwner.passHandle(),
-          onAvailable: onAvailable, onUnavailable: onUnavailable);
-    } finally {
-      viewProvider.ctrl.close();
-    }
-  }
-
-  final ChildViewConnection2Callback _onAvailableCallback;
-  final ChildViewConnection2Callback _onUnavailableCallback;
-  InterfaceHandle<ViewOwner> _viewOwner;
-
-  static int _nextViewKey = 1;
-  int _viewKey;
-
-  ViewProperties _currentViewProperties;
-
-  VoidCallback _onViewInfoAvailable;
-  ViewInfo _viewInfo;
-  ui.SceneHost _sceneHost;
-
-  void _onAttachedToContainer(ViewInfo viewInfo) {
-    assert(_viewInfo == null);
-    _viewInfo = viewInfo;
-    if (_onViewInfoAvailable != null) {
-      _onViewInfoAvailable();
-    }
-    _onAvailableCallback(this);
-  }
-
-  void _onUnavailable() {
-    _viewInfo = null;
-    _onUnavailableCallback(this);
-  }
-
-  void _addChildToViewHost() {
-    if (_viewContainer == null) {
-      return;
-    }
-    assert(_attached);
-    assert(_viewOwner != null);
-    assert(_viewKey == null);
-    assert(_viewInfo == null);
-    assert(_sceneHost == null);
-
-    final EventPairPair pair = new EventPairPair();
-    assert(pair.status == ZX.OK);
-
-    // Analyzer doesn't know Handle must be dart:zircon's Handle
-    _sceneHost = new ui.SceneHost(pair.first.passHandle());
-    _viewKey = _nextViewKey++;
-    _viewContainer.addChild(_viewKey, _viewOwner, pair.second);
-    _viewOwner = null;
-    assert(!_ViewContainerListenerImpl2.instance._connections
-        .containsKey(_viewKey));
-    _ViewContainerListenerImpl2.instance._connections[_viewKey] = this;
-  }
-
-  void _removeChildFromViewHost() {
-    if (_viewContainer == null) {
-      return;
-    }
-    assert(!_attached);
-    assert(_viewOwner == null);
-    assert(_viewKey != null);
-    assert(_sceneHost != null);
-    assert(_ViewContainerListenerImpl2.instance._connections[_viewKey] == this);
-    final ChannelPair pair = new ChannelPair();
-    assert(pair.status == ZX.OK);
-    _ViewContainerListenerImpl2.instance._connections.remove(_viewKey);
-    _viewOwner = new InterfaceHandle<ViewOwner>(pair.first);
-    _viewContainer.removeChild(
-        _viewKey, new InterfaceRequest<ViewOwner>(pair.second));
-    _viewKey = null;
-    _viewInfo = null;
-    _currentViewProperties = null;
-    _sceneHost.dispose();
-    _sceneHost = null;
-  }
-
-  /// Only call when the connection is available.
-  void requestFocus() {
-    if (_viewKey != null) {
-      _viewContainer.requestFocus(_viewKey);
-    }
-  }
-
-  // The number of render objects attached to this view. In between frames, we
-  // might have more than one connected if we get added to a new render object
-  // before we get removed from the old render object. By the time we get around
-  // to computing our layout, we must be back to just having one render object.
-  int _attachments = 0;
-  bool get _attached => _attachments > 0;
-
-  void _attach() {
-    assert(_attachments >= 0);
-    ++_attachments;
-    if (_viewKey == null) {
-      _addChildToViewHost();
-    }
-  }
-
-  void _detach() {
-    assert(_attached);
-    --_attachments;
-    scheduleMicrotask(_removeChildFromViewHostIfNeeded);
-  }
-
-  void _removeChildFromViewHostIfNeeded() {
-    assert(_attachments >= 0);
-    if (_attachments == 0 && _viewKey != null) {
-      _removeChildFromViewHost();
-    }
-  }
-
-  ViewProperties _createViewProperties(
-      double width,
-      double height,
-      double insetTop,
-      double insetRight,
-      double insetBottom,
-      double insetLeft,
-      bool focusable) {
-    if (_currentViewProperties != null &&
-        _currentViewProperties.viewLayout.size.width == width &&
-        _currentViewProperties.viewLayout.size.height == height &&
-        _currentViewProperties.viewLayout.inset.top == insetTop &&
-        _currentViewProperties.viewLayout.inset.right == insetRight &&
-        _currentViewProperties.viewLayout.inset.bottom == insetBottom &&
-        _currentViewProperties.viewLayout.inset.left == insetLeft &&
-        (_currentViewProperties.customFocusBehavior == null ||
-                _currentViewProperties.customFocusBehavior.allowFocus) ==
-            focusable) {
-      return null;
-    }
-
-    fidl.SizeF size = new fidl.SizeF(width: width, height: height);
-    fidl.InsetF inset = new fidl.InsetF(
-        top: insetTop, right: insetRight, bottom: insetBottom, left: insetLeft);
-    ViewLayout viewLayout = new ViewLayout(size: size, inset: inset);
-    final customFocusBehavior = new CustomFocusBehavior(allowFocus: focusable);
-    return _currentViewProperties = new ViewProperties(
-      viewLayout: viewLayout,
-      customFocusBehavior: customFocusBehavior,
-    );
-  }
-
-  void _setChildProperties(
-    double width,
-    double height,
-    double insetTop,
-    double insetRight,
-    double insetBottom,
-    double insetLeft,
-    bool focusable,
-  ) {
-    assert(_attached);
-    assert(_attachments == 1);
-    assert(_viewKey != null);
-    if (_viewContainer == null) {
-      return;
-    }
-    ViewProperties viewProperties = _createViewProperties(
-        width, height, insetTop, insetRight, insetBottom, insetLeft, focusable);
-    if (viewProperties == null) {
-      return;
-    }
-    _viewContainer.setChildProperties(_viewKey, viewProperties);
-  }
-}
-
-class _RenderChildView2 extends RenderBox {
-  /// Creates a child view render object.
-  _RenderChildView2({
-    ChildViewConnection2 connection,
-    bool hitTestable = true,
-    bool focusable = true,
-  })  : _connection = connection,
-        _hitTestable = hitTestable,
-        _focusable = focusable,
-        assert(hitTestable != null);
-
-  /// The child to display.
-  ChildViewConnection2 get connection => _connection;
-  ChildViewConnection2 _connection;
-  set connection(ChildViewConnection2 value) {
-    if (value == _connection) {
-      return;
-    }
-    if (attached && _connection != null) {
-      _connection._detach();
-      assert(_connection._onViewInfoAvailable != null);
-      _connection._onViewInfoAvailable = null;
-    }
-    _connection = value;
-    if (attached && _connection != null) {
-      _connection._attach();
-      assert(_connection._onViewInfoAvailable == null);
-      _connection._onViewInfoAvailable = markNeedsPaint;
-    }
-    if (_connection == null) {
-      markNeedsPaint();
-    } else {
-      markNeedsLayout();
-    }
-  }
-
-  /// Whether this child should be included during hit testing.
-  bool get hitTestable => _hitTestable;
-  bool _hitTestable;
-  set hitTestable(bool value) {
-    assert(value != null);
-    if (value == _hitTestable) {
-      return;
-    }
-    _hitTestable = value;
-    if (_connection != null) {
-      markNeedsPaint();
-    }
-  }
-
-  /// Whether this child should be able to recieve focus events
-  bool get focusable => _focusable;
-  bool _focusable;
-  set focusable(bool value) {
-    assert(value != null);
-    if (value == _focusable) {
-      return;
-    }
-    _focusable = value;
-    if (_connection != null) {
-      markNeedsPaint();
-    }
-  }
-
-  @override
-  void attach(PipelineOwner owner) {
-    super.attach(owner);
-    if (_connection != null) {
-      _connection._attach();
-      assert(_connection._onViewInfoAvailable == null);
-      _connection._onViewInfoAvailable = markNeedsPaint;
-    }
-  }
-
-  @override
-  void detach() {
-    if (_connection != null) {
-      _connection._detach();
-      assert(_connection._onViewInfoAvailable != null);
-      _connection._onViewInfoAvailable = null;
-    }
-    super.detach();
-  }
-
-  @override
-  bool get alwaysNeedsCompositing => true;
-
-  TextPainter _debugErrorMessage;
-
-  double _width;
-  double _height;
-
-  @override
-  void performLayout() {
-    size = constraints.biggest;
-
-    // Ignore if we have no child view connection.
-    if (_connection == null) {
-      return;
-    }
-
-    if (_width != null && _height != null) {
-      double deltaWidth = (_width - size.width).abs();
-      double deltaHeight = (_height - size.height).abs();
-
-      // Ignore insignificant changes in size that are likely rounding errors.
-      if (deltaWidth < 0.0001 && deltaHeight < 0.0001) {
-        return;
-      }
-    }
-
-    _width = size.width;
-    _height = size.height;
-    _connection._setChildProperties(
-        _width, _height, 0.0, 0.0, 0.0, 0.0, _focusable);
-    assert(() {
-      if (_viewContainer == null) {
-        _debugErrorMessage ??= new TextPainter(
-            text: const TextSpan(
-                text:
-                    'Child views are supported only when running in Scenic.'));
-        _debugErrorMessage.layout(minWidth: size.width, maxWidth: size.width);
-      }
-      return true;
-    }());
-  }
-
-  @override
-  bool hitTestSelf(Offset position) => true;
-
-  @override
-  void paint(PaintingContext context, Offset offset) {
-    assert(needsCompositing);
-    if (_connection?._viewInfo != null) {
-      context.addLayer(new ChildSceneLayer(
-        offset: offset,
-        width: _width,
-        height: _height,
-        sceneHost: _connection._sceneHost,
-        hitTestable: hitTestable,
-      ));
-    }
-    assert(() {
-      if (_viewContainer == null) {
-        context.canvas.drawRect(
-            offset & size, new Paint()..color = const Color(0xFF0000FF));
-        _debugErrorMessage.paint(context.canvas, offset);
-      }
-      return true;
-    }());
-  }
-
-  @override
-  void debugFillProperties(DiagnosticPropertiesBuilder description) {
-    super.debugFillProperties(description);
-    description.add(
-      new DiagnosticsProperty<ChildViewConnection2>(
-        'connection',
-        connection,
-      ),
-    );
-  }
-}
-
-/// A layer that represents content from another process.
-class ChildSceneLayer extends Layer {
-  /// Creates a layer that displays content rendered by another process.
-  ///
-  /// All of the arguments must not be null.
-  ChildSceneLayer({
-    this.offset = Offset.zero,
-    this.width = 0.0,
-    this.height = 0.0,
-    this.sceneHost,
-    this.hitTestable = true,
-  });
-
-  /// Offset from parent in the parent's coordinate system.
-  Offset offset;
-
-  /// The horizontal extent of the child, in logical pixels.
-  double width;
-
-  /// The vertical extent of the child, in logical pixels.
-  double height;
-
-  /// The host site for content rendered by the child.
-  ui.SceneHost sceneHost;
-
-  /// Whether this child should be included during hit testing.
-  ///
-  /// Defaults to true.
-  bool hitTestable;
-
-  @override
-  ui.EngineLayer addToScene(ui.SceneBuilder builder,
-      [Offset layerOffset = Offset.zero]) {
-    builder.addChildScene(
-      offset: offset + layerOffset,
-      width: width,
-      height: height,
-      sceneHost: sceneHost,
-      hitTestable: hitTestable,
-    );
-    return null;
-  }
-
-  @override
-  void debugFillProperties(DiagnosticPropertiesBuilder description) {
-    super.debugFillProperties(description);
-    description
-      ..add(new DiagnosticsProperty<Offset>('offset', offset))
-      ..add(new DoubleProperty('width', width))
-      ..add(new DoubleProperty('height', height))
-      ..add(new DiagnosticsProperty<ui.SceneHost>('sceneHost', sceneHost))
-      ..add(new DiagnosticsProperty<bool>('hitTestable', hitTestable));
-  }
-
-  @override
-  S find<S>(Offset regionOffset) => null;
-}
-
-/// A widget that is replaced by content from another process.
-///
-/// Requires a [MediaQuery] ancestor to provide appropriate media information to
-/// the child.
-@immutable
-class ChildView2 extends LeafRenderObjectWidget {
-  /// Creates a widget that is replaced by content from another process.
-  ChildView2({this.connection, this.hitTestable = true, this.focusable = true})
-      : super(key: new GlobalObjectKey(connection));
-
-  /// A connection to the child whose content will replace this widget.
-  final ChildViewConnection2 connection;
-
-  /// Whether this child should be included during hit testing.
-  ///
-  /// Defaults to true.
-  final bool hitTestable;
-
-  /// Whether this child and its children should be allowed to receive focus.
-  ///
-  /// Defaults to true.
-  final bool focusable;
-
-  @override
-  _RenderChildView2 createRenderObject(BuildContext context) {
-    return new _RenderChildView2(
-      connection: connection,
-      hitTestable: hitTestable,
-      focusable: focusable,
-    );
-  }
-
-  @override
-  void updateRenderObject(
-      BuildContext context, _RenderChildView2 renderObject) {
-    renderObject
-      ..connection = connection
-      ..hitTestable = hitTestable
-      ..focusable = focusable;
-  }
-}
-
-class View2 {
-  /// Provide services to Scenic throught |provider|.
-  ///
-  /// |services| should contain the list of service names offered by the
-  /// |provider|.
-  static void offerServiceProvider(
-      InterfaceHandle<ServiceProvider> provider, List<String> services) {
-    // Analyzer doesn't know Handle must be dart:zircon's Handle
-    Scenic.offerServiceProvider(provider.passChannel().handle, services);
-  }
-}
diff --git a/public/lib/ui/flutter/child_view2_async.dart b/public/lib/ui/flutter/child_view2_async.dart
deleted file mode 100644
index a85c7f4..0000000
--- a/public/lib/ui/flutter/child_view2_async.dart
+++ /dev/null
@@ -1,560 +0,0 @@
-// Copyright 2016 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:async';
-import 'dart:collection';
-import 'dart:ui' as ui;
-
-import 'package:lib.app.dart/app_async.dart';
-import 'package:fidl_fuchsia_sys/fidl_async.dart';
-import 'package:fidl_fuchsia_math/fidl_async.dart' as fidl;
-import 'package:fidl_fuchsia_ui_viewsv1/fidl_async.dart';
-import 'package:fidl_fuchsia_ui_viewsv1token/fidl_async.dart';
-import 'package:flutter/rendering.dart';
-import 'package:flutter/widgets.dart';
-import 'package:fidl/fidl.dart';
-import 'package:meta/meta.dart';
-import 'package:zircon/zircon.dart';
-
-import 'mozart.dart';
-
-export 'package:fidl_fuchsia_ui_viewsv1token/fidl_async.dart' show ViewOwner;
-
-ViewContainerProxy _initViewContainer() {
-  // Analyzer doesn't know Handle must be dart:zircon's Handle
-  final Handle handle = ScenicStartupInfo.takeViewContainer();
-  if (handle == null) {
-    return null;
-  }
-  final ViewContainerProxy proxy = new ViewContainerProxy()
-    ..ctrl.bind(new InterfaceHandle<ViewContainer>(new Channel(handle)))
-    ..setListener(_ViewContainerListenerImpl2.instance.createInterfaceHandle());
-
-  assert(() {
-    proxy.ctrl.whenClosed.then((_) async {
-      print('ViewContainerProxy: closed');
-    });
-    return true;
-  }());
-
-  return proxy;
-}
-
-final ViewContainerProxy _viewContainer = _initViewContainer();
-
-class _ViewContainerListenerImpl2 extends ViewContainerListener {
-  final ViewContainerListenerBinding _binding =
-      new ViewContainerListenerBinding();
-
-  InterfaceHandle<ViewContainerListener> createInterfaceHandle() {
-    return _binding.wrap(this);
-  }
-
-  static final _ViewContainerListenerImpl2 instance =
-      new _ViewContainerListenerImpl2();
-
-  @override
-  Future<Null> onChildAttached(int childKey, ViewInfo childViewInfo) async {
-    ChildViewConnection2 connection = _connections[childKey];
-    connection?._onAttachedToContainer(childViewInfo);
-  }
-
-  @override
-  Future<Null> onChildUnavailable(int childKey) async {
-    ChildViewConnection2 connection = _connections[childKey];
-    connection?._onUnavailable();
-  }
-
-  final Map<int, ChildViewConnection2> _connections =
-      new HashMap<int, ChildViewConnection2>();
-}
-
-typedef ChildViewConnection2Callback = void Function(
-    ChildViewConnection2 connection);
-void _emptyConnectionCallback(ChildViewConnection2 c) {}
-
-/// A connection with a child view.
-///
-/// Used with the [ChildView2] widget to display a child view.
-class ChildViewConnection2 {
-  ChildViewConnection2(this._viewOwner,
-      {ChildViewConnection2Callback onAvailable,
-      ChildViewConnection2Callback onUnavailable})
-      : _onAvailableCallback = onAvailable ?? _emptyConnectionCallback,
-        _onUnavailableCallback = onUnavailable ?? _emptyConnectionCallback,
-        assert(_viewOwner != null);
-
-  factory ChildViewConnection2.launch(String url, Launcher launcher,
-      {InterfaceRequest<ComponentController> controller,
-      InterfaceRequest<ServiceProvider> childServices,
-      ChildViewConnection2Callback onAvailable,
-      ChildViewConnection2Callback onUnavailable}) {
-    final Services services = new Services();
-    final LaunchInfo launchInfo =
-        new LaunchInfo(url: url, directoryRequest: services.request());
-    try {
-      launcher.createComponent(launchInfo, controller);
-      return new ChildViewConnection2.connect(services,
-          childServices: childServices,
-          onAvailable: onAvailable,
-          onUnavailable: onUnavailable);
-    } finally {
-      services.close();
-    }
-  }
-
-  factory ChildViewConnection2.connect(Services services,
-      {InterfaceRequest<ServiceProvider> childServices,
-      ChildViewConnection2Callback onAvailable,
-      ChildViewConnection2Callback onUnavailable}) {
-    final ViewProviderProxy viewProvider = new ViewProviderProxy();
-    services.connectToService(viewProvider.ctrl);
-    try {
-      final InterfacePair<ViewOwner> viewOwner = new InterfacePair<ViewOwner>();
-      viewProvider.createView(viewOwner.passRequest(), childServices);
-      return new ChildViewConnection2(viewOwner.passHandle(),
-          onAvailable: onAvailable, onUnavailable: onUnavailable);
-    } finally {
-      viewProvider.ctrl.close();
-    }
-  }
-
-  final ChildViewConnection2Callback _onAvailableCallback;
-  final ChildViewConnection2Callback _onUnavailableCallback;
-  InterfaceHandle<ViewOwner> _viewOwner;
-
-  static int _nextViewKey = 1;
-  int _viewKey;
-
-  ViewProperties _currentViewProperties;
-
-  VoidCallback _onViewInfoAvailable;
-  ViewInfo _viewInfo;
-  ui.SceneHost _sceneHost;
-
-  void _onAttachedToContainer(ViewInfo viewInfo) {
-    assert(_viewInfo == null);
-    _viewInfo = viewInfo;
-    if (_onViewInfoAvailable != null) {
-      _onViewInfoAvailable();
-    }
-    _onAvailableCallback(this);
-  }
-
-  void _onUnavailable() {
-    _viewInfo = null;
-    _onUnavailableCallback(this);
-  }
-
-  void _addChildToViewHost() {
-    if (_viewContainer == null) {
-      return;
-    }
-    assert(_attached);
-    assert(_viewOwner != null);
-    assert(_viewKey == null);
-    assert(_viewInfo == null);
-    assert(_sceneHost == null);
-
-    final EventPairPair pair = new EventPairPair();
-    assert(pair.status == ZX.OK);
-
-    // Analyzer doesn't know Handle must be dart:zircon's Handle
-    _sceneHost = new ui.SceneHost(pair.first.passHandle());
-    _viewKey = _nextViewKey++;
-    _viewContainer.addChild(_viewKey, _viewOwner, pair.second);
-    _viewOwner = null;
-    assert(!_ViewContainerListenerImpl2.instance._connections
-        .containsKey(_viewKey));
-    _ViewContainerListenerImpl2.instance._connections[_viewKey] = this;
-  }
-
-  void _removeChildFromViewHost() {
-    if (_viewContainer == null) {
-      return;
-    }
-    assert(!_attached);
-    assert(_viewOwner == null);
-    assert(_viewKey != null);
-    assert(_sceneHost != null);
-    assert(_ViewContainerListenerImpl2.instance._connections[_viewKey] == this);
-    final ChannelPair pair = new ChannelPair();
-    assert(pair.status == ZX.OK);
-    _ViewContainerListenerImpl2.instance._connections.remove(_viewKey);
-    _viewOwner = new InterfaceHandle<ViewOwner>(pair.first);
-    _viewContainer.removeChild(
-        _viewKey, new InterfaceRequest<ViewOwner>(pair.second));
-    _viewKey = null;
-    _viewInfo = null;
-    _currentViewProperties = null;
-    _sceneHost.dispose();
-    _sceneHost = null;
-  }
-
-  /// Only call when the connection is available.
-  void requestFocus() {
-    if (_viewKey != null) {
-      _viewContainer.requestFocus(_viewKey);
-    }
-  }
-
-  // The number of render objects attached to this view. In between frames, we
-  // might have more than one connected if we get added to a new render object
-  // before we get removed from the old render object. By the time we get around
-  // to computing our layout, we must be back to just having one render object.
-  int _attachments = 0;
-  bool get _attached => _attachments > 0;
-
-  void _attach() {
-    assert(_attachments >= 0);
-    ++_attachments;
-    if (_viewKey == null) {
-      _addChildToViewHost();
-    }
-  }
-
-  void _detach() {
-    assert(_attached);
-    --_attachments;
-    scheduleMicrotask(_removeChildFromViewHostIfNeeded);
-  }
-
-  void _removeChildFromViewHostIfNeeded() {
-    assert(_attachments >= 0);
-    if (_attachments == 0 && _viewKey != null) {
-      _removeChildFromViewHost();
-    }
-  }
-
-  ViewProperties _createViewProperties(
-      double width,
-      double height,
-      double insetTop,
-      double insetRight,
-      double insetBottom,
-      double insetLeft,
-      bool focusable) {
-    if (_currentViewProperties != null &&
-        _currentViewProperties.viewLayout.size.width == width &&
-        _currentViewProperties.viewLayout.size.height == height &&
-        _currentViewProperties.viewLayout.inset.top == insetTop &&
-        _currentViewProperties.viewLayout.inset.right == insetRight &&
-        _currentViewProperties.viewLayout.inset.bottom == insetBottom &&
-        _currentViewProperties.viewLayout.inset.left == insetLeft &&
-        (_currentViewProperties.customFocusBehavior == null ||
-                _currentViewProperties.customFocusBehavior.allowFocus) ==
-            focusable) {
-      return null;
-    }
-
-    fidl.SizeF size = new fidl.SizeF(width: width, height: height);
-    fidl.InsetF inset = new fidl.InsetF(
-        top: insetTop, right: insetRight, bottom: insetBottom, left: insetLeft);
-    ViewLayout viewLayout = new ViewLayout(size: size, inset: inset);
-    final customFocusBehavior = new CustomFocusBehavior(allowFocus: focusable);
-    return _currentViewProperties = new ViewProperties(
-      viewLayout: viewLayout,
-      customFocusBehavior: customFocusBehavior,
-    );
-  }
-
-  void _setChildProperties(
-    double width,
-    double height,
-    double insetTop,
-    double insetRight,
-    double insetBottom,
-    double insetLeft,
-    bool focusable,
-  ) {
-    assert(_attached);
-    assert(_attachments == 1);
-    assert(_viewKey != null);
-    if (_viewContainer == null) {
-      return;
-    }
-    ViewProperties viewProperties = _createViewProperties(
-        width, height, insetTop, insetRight, insetBottom, insetLeft, focusable);
-    if (viewProperties == null) {
-      return;
-    }
-    _viewContainer.setChildProperties(_viewKey, viewProperties);
-  }
-}
-
-class _RenderChildView2 extends RenderBox {
-  /// Creates a child view render object.
-  _RenderChildView2({
-    ChildViewConnection2 connection,
-    bool hitTestable = true,
-    bool focusable = true,
-  })  : _connection = connection,
-        _hitTestable = hitTestable,
-        _focusable = focusable,
-        assert(hitTestable != null);
-
-  /// The child to display.
-  ChildViewConnection2 get connection => _connection;
-  ChildViewConnection2 _connection;
-  set connection(ChildViewConnection2 value) {
-    if (value == _connection) {
-      return;
-    }
-    if (attached && _connection != null) {
-      _connection._detach();
-      assert(_connection._onViewInfoAvailable != null);
-      _connection._onViewInfoAvailable = null;
-    }
-    _connection = value;
-    if (attached && _connection != null) {
-      _connection._attach();
-      assert(_connection._onViewInfoAvailable == null);
-      _connection._onViewInfoAvailable = markNeedsPaint;
-    }
-    if (_connection == null) {
-      markNeedsPaint();
-    } else {
-      markNeedsLayout();
-    }
-  }
-
-  /// Whether this child should be included during hit testing.
-  bool get hitTestable => _hitTestable;
-  bool _hitTestable;
-  set hitTestable(bool value) {
-    assert(value != null);
-    if (value == _hitTestable) {
-      return;
-    }
-    _hitTestable = value;
-    if (_connection != null) {
-      markNeedsPaint();
-    }
-  }
-
-  /// Whether this child should be able to recieve focus events
-  bool get focusable => _focusable;
-  bool _focusable;
-  set focusable(bool value) {
-    assert(value != null);
-    if (value == _focusable) {
-      return;
-    }
-    _focusable = value;
-    if (_connection != null) {
-      markNeedsPaint();
-    }
-  }
-
-  @override
-  void attach(PipelineOwner owner) {
-    super.attach(owner);
-    if (_connection != null) {
-      _connection._attach();
-      assert(_connection._onViewInfoAvailable == null);
-      _connection._onViewInfoAvailable = markNeedsPaint;
-    }
-  }
-
-  @override
-  void detach() {
-    if (_connection != null) {
-      _connection._detach();
-      assert(_connection._onViewInfoAvailable != null);
-      _connection._onViewInfoAvailable = null;
-    }
-    super.detach();
-  }
-
-  @override
-  bool get alwaysNeedsCompositing => true;
-
-  TextPainter _debugErrorMessage;
-
-  double _width;
-  double _height;
-
-  @override
-  void performLayout() {
-    size = constraints.biggest;
-
-    // Ignore if we have no child view connection.
-    if (_connection == null) {
-      return;
-    }
-
-    if (_width != null && _height != null) {
-      double deltaWidth = (_width - size.width).abs();
-      double deltaHeight = (_height - size.height).abs();
-
-      // Ignore insignificant changes in size that are likely rounding errors.
-      if (deltaWidth < 0.0001 && deltaHeight < 0.0001) {
-        return;
-      }
-    }
-
-    _width = size.width;
-    _height = size.height;
-    _connection._setChildProperties(
-        _width, _height, 0.0, 0.0, 0.0, 0.0, _focusable);
-    assert(() {
-      if (_viewContainer == null) {
-        _debugErrorMessage ??= new TextPainter(
-            text: const TextSpan(
-                text:
-                    'Child views are supported only when running in Scenic.'));
-        _debugErrorMessage.layout(minWidth: size.width, maxWidth: size.width);
-      }
-      return true;
-    }());
-  }
-
-  @override
-  bool hitTestSelf(Offset position) => true;
-
-  @override
-  void paint(PaintingContext context, Offset offset) {
-    assert(needsCompositing);
-    if (_connection?._viewInfo != null) {
-      context.addLayer(new ChildSceneLayer(
-        offset: offset,
-        width: _width,
-        height: _height,
-        sceneHost: _connection._sceneHost,
-        hitTestable: hitTestable,
-      ));
-    }
-    assert(() {
-      if (_viewContainer == null) {
-        context.canvas.drawRect(
-            offset & size, new Paint()..color = const Color(0xFF0000FF));
-        _debugErrorMessage.paint(context.canvas, offset);
-      }
-      return true;
-    }());
-  }
-
-  @override
-  void debugFillProperties(DiagnosticPropertiesBuilder description) {
-    super.debugFillProperties(description);
-    description.add(
-      new DiagnosticsProperty<ChildViewConnection2>(
-        'connection',
-        connection,
-      ),
-    );
-  }
-}
-
-/// A layer that represents content from another process.
-class ChildSceneLayer extends Layer {
-  /// Creates a layer that displays content rendered by another process.
-  ///
-  /// All of the arguments must not be null.
-  ChildSceneLayer({
-    this.offset = Offset.zero,
-    this.width = 0.0,
-    this.height = 0.0,
-    this.sceneHost,
-    this.hitTestable = true,
-  });
-
-  /// Offset from parent in the parent's coordinate system.
-  Offset offset;
-
-  /// The horizontal extent of the child, in logical pixels.
-  double width;
-
-  /// The vertical extent of the child, in logical pixels.
-  double height;
-
-  /// The host site for content rendered by the child.
-  ui.SceneHost sceneHost;
-
-  /// Whether this child should be included during hit testing.
-  ///
-  /// Defaults to true.
-  bool hitTestable;
-
-  @override
-  ui.EngineLayer addToScene(ui.SceneBuilder builder,
-      [Offset layerOffset = Offset.zero]) {
-    builder.addChildScene(
-      offset: offset + layerOffset,
-      width: width,
-      height: height,
-      sceneHost: sceneHost,
-      hitTestable: hitTestable,
-    );
-    return null;
-  }
-
-  @override
-  void debugFillProperties(DiagnosticPropertiesBuilder description) {
-    super.debugFillProperties(description);
-    description
-      ..add(new DiagnosticsProperty<Offset>('offset', offset))
-      ..add(new DoubleProperty('width', width))
-      ..add(new DoubleProperty('height', height))
-      ..add(new DiagnosticsProperty<ui.SceneHost>('sceneHost', sceneHost))
-      ..add(new DiagnosticsProperty<bool>('hitTestable', hitTestable));
-  }
-
-  @override
-  S find<S>(Offset regionOffset) => null;
-}
-
-/// A widget that is replaced by content from another process.
-///
-/// Requires a [MediaQuery] ancestor to provide appropriate media information to
-/// the child.
-@immutable
-class ChildView2 extends LeafRenderObjectWidget {
-  /// Creates a widget that is replaced by content from another process.
-  ChildView2({this.connection, this.hitTestable = true, this.focusable = true})
-      : super(key: new GlobalObjectKey(connection));
-
-  /// A connection to the child whose content will replace this widget.
-  final ChildViewConnection2 connection;
-
-  /// Whether this child should be included during hit testing.
-  ///
-  /// Defaults to true.
-  final bool hitTestable;
-
-  /// Whether this child and its children should be allowed to receive focus.
-  ///
-  /// Defaults to true.
-  final bool focusable;
-
-  @override
-  _RenderChildView2 createRenderObject(BuildContext context) {
-    return new _RenderChildView2(
-      connection: connection,
-      hitTestable: hitTestable,
-      focusable: focusable,
-    );
-  }
-
-  @override
-  void updateRenderObject(
-      BuildContext context, _RenderChildView2 renderObject) {
-    renderObject
-      ..connection = connection
-      ..hitTestable = hitTestable
-      ..focusable = focusable;
-  }
-}
-
-class View2 {
-  /// Provide services to Scenic throught |provider|.
-  ///
-  /// |services| should contain the list of service names offered by the
-  /// |provider|.
-  static void offerServiceProvider(
-      InterfaceHandle<ServiceProvider> provider, List<String> services) {
-    // Analyzer doesn't know Handle must be dart:zircon's Handle
-    Scenic.offerServiceProvider(provider.passChannel().handle, services);
-  }
-}
diff --git a/public/lib/ui/flutter/child_view_async.dart b/public/lib/ui/flutter/child_view_async.dart
index 7060c41..8593201 100644
--- a/public/lib/ui/flutter/child_view_async.dart
+++ b/public/lib/ui/flutter/child_view_async.dart
@@ -9,6 +9,7 @@
 import 'package:lib.app.dart/app_async.dart';
 import 'package:fidl_fuchsia_sys/fidl_async.dart';
 import 'package:fidl_fuchsia_math/fidl_async.dart' as fidl;
+import 'package:fidl_fuchsia_ui_app/fidl_async.dart' as app;
 import 'package:fidl_fuchsia_ui_viewsv1/fidl_async.dart';
 import 'package:fidl_fuchsia_ui_viewsv1token/fidl_async.dart';
 import 'package:flutter/rendering.dart';
@@ -20,7 +21,6 @@
 import 'mozart.dart';
 
 export 'package:fidl_fuchsia_ui_viewsv1token/fidl_async.dart' show ViewOwner;
-export 'child_view2_async.dart';
 
 ViewContainerProxy _initViewContainer() {
   // Analyzer doesn't know Handle must be dart:zircon's Handle
@@ -79,12 +79,22 @@
 ///
 /// Used with the [ChildView] widget to display a child view.
 class ChildViewConnection {
-  ChildViewConnection(this._viewOwner,
+  ChildViewConnection(InterfaceHandle<ViewOwner> viewOwner,
+      {ChildViewConnectionCallback onAvailable,
+      ChildViewConnectionCallback onUnavailable})
+      : this.fromViewHolderToken(
+            new EventPair(viewOwner?.passChannel()?.passHandle()),
+            onAvailable: onAvailable,
+            onUnavailable: onUnavailable);
+
+  ChildViewConnection.fromViewHolderToken(EventPair viewHolderToken,
       {ChildViewConnectionCallback onAvailable,
       ChildViewConnectionCallback onUnavailable})
       : _onAvailableCallback = onAvailable ?? _emptyConnectionCallback,
         _onUnavailableCallback = onUnavailable ?? _emptyConnectionCallback,
-        assert(_viewOwner != null);
+        _viewHolderToken = viewHolderToken {
+    assert(_viewHolderToken != null);
+  }
 
   factory ChildViewConnection.launch(String url, Launcher launcher,
       {InterfaceRequest<ComponentController> controller,
@@ -109,12 +119,14 @@
       {InterfaceRequest<ServiceProvider> childServices,
       ChildViewConnectionCallback onAvailable,
       ChildViewConnectionCallback onUnavailable}) {
-    final ViewProviderProxy viewProvider = new ViewProviderProxy();
+    final app.ViewProviderProxy viewProvider = new app.ViewProviderProxy();
     services.connectToService(viewProvider.ctrl);
     try {
-      final InterfacePair<ViewOwner> viewOwner = new InterfacePair<ViewOwner>();
-      viewProvider.createView(viewOwner.passRequest(), childServices);
-      return new ChildViewConnection(viewOwner.passHandle(),
+      EventPairPair viewTokens = new EventPairPair();
+      assert(viewTokens.status == ZX.OK);
+
+      viewProvider.createView(viewTokens.second, childServices, null);
+      return new ChildViewConnection.fromViewHolderToken(viewTokens.first,
           onAvailable: onAvailable, onUnavailable: onUnavailable);
     } finally {
       viewProvider.ctrl.close();
@@ -123,7 +135,7 @@
 
   final ChildViewConnectionCallback _onAvailableCallback;
   final ChildViewConnectionCallback _onUnavailableCallback;
-  InterfaceHandle<ViewOwner> _viewOwner;
+  EventPair _viewHolderToken;
 
   static int _nextViewKey = 1;
   int _viewKey;
@@ -153,7 +165,7 @@
       return;
     }
     assert(_attached);
-    assert(_viewOwner != null);
+    assert(_viewHolderToken != null);
     assert(_viewKey == null);
     assert(_viewInfo == null);
     assert(_sceneHost == null);
@@ -164,8 +176,8 @@
     // Analyzer doesn't know Handle must be dart:zircon's Handle
     _sceneHost = new ui.SceneHost(sceneTokens.first.passHandle());
     _viewKey = _nextViewKey++;
-    _viewContainer.addChild(_viewKey, _viewOwner, sceneTokens.second);
-    _viewOwner = null;
+    _viewContainer.addChild2(_viewKey, _viewHolderToken, sceneTokens.second);
+    _viewHolderToken = null;
     assert(!_ViewContainerListenerImpl.instance._connections
         .containsKey(_viewKey));
     _ViewContainerListenerImpl.instance._connections[_viewKey] = this;
@@ -176,16 +188,15 @@
       return;
     }
     assert(!_attached);
-    assert(_viewOwner == null);
+    assert(_viewHolderToken == null);
     assert(_viewKey != null);
     assert(_sceneHost != null);
     assert(_ViewContainerListenerImpl.instance._connections[_viewKey] == this);
-    final ChannelPair pair = new ChannelPair();
-    assert(pair.status == ZX.OK);
+    final EventPairPair viewTokens = new EventPairPair();
+    assert(viewTokens.status == ZX.OK);
     _ViewContainerListenerImpl.instance._connections.remove(_viewKey);
-    _viewOwner = new InterfaceHandle<ViewOwner>(pair.first);
-    _viewContainer.removeChild(
-        _viewKey, new InterfaceRequest<ViewOwner>(pair.second));
+    _viewHolderToken = viewTokens.first;
+    _viewContainer.removeChild2(_viewKey, viewTokens.second);
     _viewKey = null;
     _viewInfo = null;
     _currentViewProperties = null;