[xi] migrate away from deprecated code

* do not use sync fidl bindings.
* use the dart sdk.

Change-Id: I5a67b6caa99f85d7998465037cc168c20b8993bb
diff --git a/bin/xi/xi_embeddable/BUILD.gn b/bin/xi/xi_embeddable/BUILD.gn
index 8167dc8..544fb37 100644
--- a/bin/xi/xi_embeddable/BUILD.gn
+++ b/bin/xi/xi_embeddable/BUILD.gn
@@ -20,7 +20,7 @@
     "//topaz/lib/xi/fuchsia_client:xi_fuchsia_client",
     "//topaz/lib/xi/widgets:xi_widgets",
     "//topaz/public/dart/fidl",
-    "//topaz/public/lib/app/dart",
-    "//topaz/public/lib/app_driver/dart",
+    "//topaz/public/dart/fuchsia_logger",
+    "//topaz/public/dart/fuchsia_modular",
   ]
 }
diff --git a/bin/xi/xi_embeddable/lib/main.dart b/bin/xi/xi_embeddable/lib/main.dart
index 5b11c99..a72b338 100644
--- a/bin/xi/xi_embeddable/lib/main.dart
+++ b/bin/xi/xi_embeddable/lib/main.dart
@@ -6,10 +6,10 @@
 import 'dart:convert';
 
 import 'package:flutter/material.dart';
-import 'package:fidl_fuchsia_mem/fidl.dart' as fuchsia_mem;
 import 'package:fidl_fuchsia_xi_session/fidl_async.dart';
-import 'package:lib.app_driver.dart/module_driver.dart';
-import 'package:lib.app.dart/logging.dart';
+import 'package:fuchsia_logger/logger.dart';
+import 'package:fuchsia_modular/module.dart';
+import 'package:fuchsia_modular/service_connection.dart';
 import 'package:xi_widgets/widgets.dart';
 import 'package:xi_fuchsia_client/client.dart';
 import 'package:zircon/zircon.dart';
@@ -26,36 +26,24 @@
   setupLogger(name: 'xi_embeddable');
   log.info('Module main called');
 
-  // TODO: Refactor this class to use the new SDK instead of deprecated API
-  // ignore: deprecated_member_use
-  final _driver = new ModuleDriver();
-  XiSessionManager _sessionManager;
+  final handler = StreamingIntentHandler();
+  Module().registerIntentHandler(handler);
+
+  final sessionManager = XiSessionManagerProxy();
+  connectToAgentService(kSessionManagerURL, sessionManager);
 
   SocketPair pair = SocketPair();
   final client = EmbeddedClient(pair.first)..init();
 
-// To do anything, we need our initial link and a connection to the agent.
-  Future
-      .wait([_getLink(_driver), _getSessionManager(_driver)])
-      .then((result) {
-        String sessionId = result[0];
-        _sessionManager = result[1];
-
-        log.info('got link $sessionId, agent $_sessionManager');
-        // We pass the sessionId and one side of the socket to the agent.
-        // We will then be able to communicate back and forth via `client`.
-        return _sessionManager.connectSession(sessionId, pair.second);
-      })
-      .catchError(
-          (err, trace) => log.severe('failed to get link or agent', err, trace))
-      .then((_) => log.info('session agent resolved'));
-
-  _driver
-      .start()
-      .then((_) => trace('driver started'))
-      .catchError((err, trace) => log.warning('driver error', err, trace));
-
-  log.info('Starting embeddable_xi');
+  handler.stream.first.then(_getSessionId).then((sessionId) {
+    log.info('got [$sessionId]');
+    // We pass the sessionId and one side of the socket to the agent.
+    // We will then be able to communicate back and forth via `client`.
+    return sessionManager.connectSession(sessionId, pair.second);
+  }).then((_) {
+    sessionManager.ctrl.close();
+  }).catchError(
+      (err, trace) => log.severe('failed to get link or agent', err, trace));
 
   runApp(new EmbeddedEditor(
     client: client,
@@ -63,25 +51,11 @@
   ));
 }
 
-// TODO: Refactor this class to use the new SDK instead of deprecated API
-// ignore: deprecated_member_use
-Future<String> _getLink(ModuleDriver _driver) async {
-  var link = await _driver.getLink('session-id');
-  fuchsia_mem.Buffer buffer = await link.get();
-  var dataVmo = new SizedVmo(buffer.vmo.handle, buffer.size);
-  var data = dataVmo.read(buffer.size);
-  dataVmo.close();
-  return jsonDecode(utf8.decode(data.bytesAsUint8List()));
-}
-
-// TODO: Refactor this class to use the new SDK instead of deprecated API
-// ignore: deprecated_member_use
-Future<XiSessionManager> _getSessionManager(ModuleDriver _driver) async {
-  XiSessionManagerProxy sessionManagerProxy = new XiSessionManagerProxy();
-  return _driver
-      .connectToAgentServiceWithAsyncProxy(
-          kSessionManagerURL, sessionManagerProxy)
-      .then((_) => sessionManagerProxy)
-      .catchError((err, stackTrace) => log.severe(
-          'error connecting to xi_session_manager', err, stackTrace));
+Future<String> _getSessionId(Intent intent) async {
+  //Note: this is currently broken and needs to be updated once the
+  //module is launched via an intent
+  final entity =
+      intent.getEntity(name: 'session-id', type: 'com.fuchsia.xi.session-id');
+  final data = await entity.getData();
+  return utf8.decode(data);
 }
diff --git a/bin/xi/xi_embeddable/meta/xi_embeddable.cmx b/bin/xi/xi_embeddable/meta/xi_embeddable.cmx
index 748be61..fb338f9 100644
--- a/bin/xi/xi_embeddable/meta/xi_embeddable.cmx
+++ b/bin/xi/xi_embeddable/meta/xi_embeddable.cmx
@@ -18,5 +18,22 @@
             "fuchsia.ui.viewsv1.ViewManager",
             "fuchsia.wlan.service.Wlan"
         ]
+    },
+    "facets": {
+        "fuchsia.module": {
+            "@version": 2,
+            "suggestion_headline": "embed a xi editor",
+            "intent_filters": [
+                {
+                "action": "com.fuchsia.xi.embed",
+                "parameters": [
+                    {
+                    "name": "session-id",
+                    "type": "com.fuchsia.xi.session-id"
+                    }
+                ]
+                }
+            ]
+        }
     }
 }
\ No newline at end of file
diff --git a/bin/xi/xi_mod/BUILD.gn b/bin/xi/xi_mod/BUILD.gn
index 3d16192..77fcce7 100644
--- a/bin/xi/xi_mod/BUILD.gn
+++ b/bin/xi/xi_mod/BUILD.gn
@@ -22,7 +22,7 @@
     "//topaz/lib/xi/fuchsia_client:xi_fuchsia_client",
     "//topaz/lib/xi/widgets:xi_widgets",
     "//topaz/public/dart/fidl",
-    "//topaz/public/dart/fuchsia",
-    "//topaz/public/lib/app/dart",
+    "//topaz/public/dart/fuchsia_logger",
+    "//topaz/public/dart/fuchsia_modular",
   ]
 }
diff --git a/bin/xi/xi_mod/lib/main.dart b/bin/xi/xi_mod/lib/main.dart
index e62b15f..67162ba 100644
--- a/bin/xi/xi_mod/lib/main.dart
+++ b/bin/xi/xi_mod/lib/main.dart
@@ -3,12 +3,8 @@
 // found in the LICENSE file.
 
 import 'package:flutter/material.dart';
-import 'package:fuchsia/fuchsia.dart';
-import 'package:fidl/fidl.dart';
-import 'package:fidl_fuchsia_ledger/fidl.dart';
-import 'package:fidl_fuchsia_modular/fidl.dart';
-import 'package:lib.app.dart/app.dart';
-import 'package:lib.app.dart/logging.dart';
+import 'package:fuchsia_modular/module.dart';
+import 'package:fuchsia_logger/logger.dart';
 import 'package:xi_widgets/widgets.dart';
 import 'package:xi_fuchsia_client/client.dart';
 import 'package:xi_client/client.dart';
@@ -18,55 +14,15 @@
 /// If `true`, draws the editor with a watermarked background.
 const bool kDrawDebugBackground = false;
 
-/// An implementation of the [Lifecycle] interface, which controls the lifetime
-/// of the module. Also manages the ModuleContext connection.
-class ModuleImpl implements Lifecycle {
-  /// Constructor.
-  ModuleImpl(this._ledgerRequest) {
-    log.info('ModuleImpl::init call');
-    connectToService(kContext.environmentServices, _moduleContext.ctrl);
-    _moduleContext.getComponentContext(_componentContext.ctrl.request());
-    _componentContext.getLedger(_ledgerRequest);
-  }
-
-  final LifecycleBinding _lifecycleBinding = new LifecycleBinding();
-  final ModuleContextProxy _moduleContext = new ModuleContextProxy();
-  final ComponentContextProxy _componentContext = new ComponentContextProxy();
-  final InterfaceRequest<Ledger> _ledgerRequest;
-
-  /// Bind an [InterfaceRequest] for a [Lifecycle] interface to this object.
-  void bindLifecycle(InterfaceRequest<Lifecycle> request) {
-    _lifecycleBinding.bind(this, request);
-  }
-
-  @override
-  void terminate() {
-    log.info('ModuleImpl::stop call');
-
-    // Cleaning up.
-    _moduleContext.ctrl.close();
-    _componentContext.ctrl.close();
-    _lifecycleBinding.close();
-    exit(0);
-  }
-}
-
 /// Main entry point to the example parent module.
 void main() {
   setupLogger(name: '[xi_mod]');
   log.info('Module main called');
 
-  InterfacePair<Ledger> pair = new InterfacePair<Ledger>();
-  final ModuleImpl module = new ModuleImpl(pair.passRequest());
+  //TODO: migrate to using intents
+  Module().registerIntentHandler(NoopIntentHandler());
 
-  kContext.outgoingServices.addServiceForName(
-    module.bindLifecycle,
-    Lifecycle.$serviceName,
-  );
-
-  log.info('Starting Flutter app...');
-
-  XiFuchsiaClient xi = new XiFuchsiaClient(pair.passHandle());
+  XiFuchsiaClient xi = new XiFuchsiaClient(null);
   XiCoreProxy coreProxy = new CoreProxy(xi);
 
   runApp(new EditorTabs(
diff --git a/bin/xi/xi_session_agent/BUILD.gn b/bin/xi/xi_session_agent/BUILD.gn
index af7ba35..c75d40a 100644
--- a/bin/xi/xi_session_agent/BUILD.gn
+++ b/bin/xi/xi_session_agent/BUILD.gn
@@ -27,7 +27,7 @@
     "//sdk/fidl/fuchsia.auth",
     "//topaz/lib/xi/fuchsia_client:xi_fuchsia_client",
     "//topaz/public/dart/fidl",
-    "//topaz/public/lib/agent/dart",
-    "//topaz/public/lib/app/dart",
+    "//topaz/public/dart/fuchsia_logger",
+    "//topaz/public/dart/fuchsia_modular",
   ]
 }
diff --git a/bin/xi/xi_session_agent/lib/main.dart b/bin/xi/xi_session_agent/lib/main.dart
index 11416b7..b8652c8 100644
--- a/bin/xi/xi_session_agent/lib/main.dart
+++ b/bin/xi/xi_session_agent/lib/main.dart
@@ -6,15 +6,9 @@
 import 'dart:convert';
 import 'dart:typed_data';
 
-import 'package:fidl/fidl.dart';
-import 'package:fidl_fuchsia_auth/fidl.dart';
-import 'package:fidl_fuchsia_xi_session/fidl.dart' as fidl_xi_session;
-
-import 'package:lib.app.dart/app.dart';
-import 'package:lib.agent.dart/agent.dart';
-import 'package:lib.app.dart/logging.dart';
-
-import 'package:meta/meta.dart';
+import 'package:fidl_fuchsia_xi_session/fidl_async.dart' as fidl_xi_session;
+import 'package:fuchsia_modular/agent.dart';
+import 'package:fuchsia_logger/logger.dart';
 import 'package:zircon/zircon.dart';
 
 import 'package:xi_fuchsia_client/client.dart';
@@ -28,45 +22,6 @@
   PendingNotification(this.method, this.params);
 }
 
-
-/// TODO: Refactor this class to use the new SDK instead of deprecated API
-/// ignore: deprecated_member_use
-class XiSessionAgent extends AgentImpl {
-  final _xiSessionManager = XiSessionManagerImpl();
-
-  final List<fidl_xi_session.XiSessionManagerBinding> _bindings =
-      <fidl_xi_session.XiSessionManagerBinding>[];
-
-  XiSessionAgent({@required StartupContext startupContext})
-      : super(startupContext: startupContext);
-
-  @override
-  Future<Null> onReady(
-    StartupContext startupContext,
-    AgentContext agentContext,
-    ComponentContext componentContext,
-    TokenManager tokenManager,
-    ServiceProviderImpl outgoingServices,
-  ) async {
-    outgoingServices.addServiceForName(
-      (InterfaceRequest<fidl_xi_session.XiSessionManager> request) {
-        log.info('got request $request');
-        _bindings.add(
-          fidl_xi_session.XiSessionManagerBinding()
-            ..bind(_xiSessionManager, request),
-        );
-      },
-      fidl_xi_session.XiSessionManager.$serviceName,
-    );
-  }
-
-  @override
-  void advertise() {
-    super.advertise();
-    log.info('advertising xi_session_agent');
-  }
-}
-
 class XiSessionManagerImpl extends fidl_xi_session.XiSessionManager
     implements XiRpcHandler {
   int _sessionId = 0;
@@ -89,32 +44,34 @@
   }
 
   @override
-  void newSession(void Function(String sessionId) callback) {
+  Future<String> newSession() async {
     int id = _sessionId++;
     String idString = 'session-$id';
+    //ignore: unawaited_futures
     xiCore.sendRpc('new_view', {}).then((viewId) {
       _availableSessions[idString] = viewId;
       log.info('associated session $idString with view $viewId');
     });
-    callback(idString);
+    return idString;
   }
 
   @override
-  void closeSession(String sessionId) {
+  Future<void> closeSession(String sessionId) async {
     final viewId = _activeSessions.remove(sessionId);
     if (viewId == null) {
       log.warning('attempted to close unknown session $sessionId');
     }
     _activeConnections.remove(viewId);
-    xiCore.sendRpc('close_view', {'view_id': viewId});
+    await xiCore.sendRpc('close_view', {'view_id': viewId});
   }
 
   @override
-  void connectSession(String sessionId, Socket socket) {
+  Future<void> connectSession(String sessionId, Socket socket) async {
     final viewId = _availableSessions.remove(sessionId);
     if (viewId == null) {
       log.warning('attempted to connect to unknown session $sessionId');
     }
+    //ignore: unawaited_futures
     final forwarder = ViewForwarder(socket, viewId, xiCore)..init();
     _activeConnections[viewId] = forwarder;
     _activeSessions[sessionId] = viewId;
@@ -128,27 +85,20 @@
   }
 
   @override
-  void getContents(String sessionId, void Function(Vmo buffer) callback) {
+  Future<Vmo> getContents(String sessionId) async {
     final viewId = _activeSessions[sessionId];
     if (viewId == null) {
       log.warning('getContents called for unknown session $sessionId');
-      callback(SizedVmo.fromUint8List(utf8.encode('unknown session id?? o_O')));
-      return;
+      return SizedVmo.fromUint8List(utf8.encode('unknown session id?? o_O'));
     }
-
-    xiCore.sendRpc('debug_get_contents', {'view_id': viewId}).then((result) {
-      String contents = result;
-      final vmo = SizedVmo.fromUint8List(utf8.encode(contents));
-      callback(vmo);
-    }).catchError((err) {
-      log.warning('get_contents failed for view $viewId', err);
-      callback(SizedVmo.fromUint8List(utf8.encode('getContents err $err')));
-    });
+    final contents =
+        await xiCore.sendRpc('debug_get_contents', {'view_id': viewId});
+    return SizedVmo.fromUint8List(utf8.encode(contents));
   }
 
   // handle a notification from xi-core, forwarding it to some session
   @override
-  void handleNotification(String method, dynamic params) {
+  Future<void> handleNotification(String method, dynamic params) async {
     String viewId = params.remove('view_id');
     if (viewId == null) {
       // we ignore things that aren't for a view
@@ -177,10 +127,7 @@
 void main(List<String> args) {
   setupLogger(name: '[xi_session_agent]');
   log.info('agent started');
-
-  new XiSessionAgent(
-    startupContext: StartupContext.fromStartupInfo(),
-  ).advertise();
+  Agent().exposeService(XiSessionManagerImpl());
 }
 
 class ViewForwarder extends XiClient implements XiRpcHandler {
diff --git a/bin/xi/xi_session_demo/BUILD.gn b/bin/xi/xi_session_demo/BUILD.gn
index 99fd2c3..8cef512 100644
--- a/bin/xi/xi_session_demo/BUILD.gn
+++ b/bin/xi/xi_session_demo/BUILD.gn
@@ -22,8 +22,8 @@
     "//third_party/dart-pkg/git/flutter/packages/flutter",
     "//topaz/bin/xi/xi_session_agent:xi_session_services",
     "//topaz/public/dart/fuchsia_scenic_flutter",
-    "//topaz/public/lib/app/dart",
-    "//topaz/public/lib/app_driver/dart",
+    "//topaz/public/dart/fuchsia_logger",
+    "//topaz/public/dart/fuchsia_modular",
     "//topaz/public/lib/widgets/dart",
   ]
 }
diff --git a/bin/xi/xi_session_demo/lib/main.dart b/bin/xi/xi_session_demo/lib/main.dart
index 2a1bb59..4368c74 100644
--- a/bin/xi/xi_session_demo/lib/main.dart
+++ b/bin/xi/xi_session_demo/lib/main.dart
@@ -3,7 +3,8 @@
 // found in the LICENSE file.
 
 import 'package:flutter/material.dart';
-import 'package:lib.app.dart/logging.dart';
+import 'package:fuchsia_logger/logger.dart';
+import 'package:fuchsia_modular/module.dart';
 import 'package:lib.widgets.dart/model.dart';
 
 import 'src/demo_model.dart';
@@ -16,6 +17,9 @@
 void main() {
   setupLogger(name: 'session_demo');
 
+  // explicitly disable intents
+  Module().registerIntentHandler(NoopIntentHandler());
+
   DemoModel model = DemoModel();
 
   runApp(new ScopedModel<DemoModel>(
diff --git a/bin/xi/xi_session_demo/lib/src/demo_model.dart b/bin/xi/xi_session_demo/lib/src/demo_model.dart
index 24eb9a0..d66cf80 100644
--- a/bin/xi/xi_session_demo/lib/src/demo_model.dart
+++ b/bin/xi/xi_session_demo/lib/src/demo_model.dart
@@ -3,26 +3,21 @@
 // found in the LICENSE file.
 
 import 'dart:async';
+import 'dart:convert' show utf8;
 
-import 'package:fidl/fidl.dart';
-import 'package:fidl_fuchsia_modular/fidl.dart';
-import 'package:fidl_fuchsia_ui_views/fidl_async.dart';
-import 'package:fidl_fuchsia_ui_viewsv1token/fidl.dart';
+import 'package:fidl_fuchsia_modular/fidl_async.dart' as modular;
 import 'package:fidl_fuchsia_xi_session/fidl_async.dart';
 import 'package:fuchsia_scenic_flutter/child_view_connection.dart'
     show ChildViewConnection;
-import 'package:lib.app_driver.dart/module_driver.dart';
-import 'package:lib.app.dart/logging.dart';
+import 'package:fuchsia_logger/logger.dart';
+import 'package:fuchsia_modular/module.dart';
+import 'package:fuchsia_modular/service_connection.dart';
 import 'package:lib.widgets.dart/model.dart';
-import 'package:zircon/zircon.dart';
 
 const String kSessionManagerURL =
     'fuchsia-pkg://fuchsia.com/xi_session_agent#meta/xi_session_agent.cmx';
 
 class DemoModel extends Model {
-  /// TODO: Refactor this class to use the new SDK instead of deprecated API
-  /// ignore: deprecated_member_use
-  final ModuleDriver driver = ModuleDriver();
   final List<String> messages = [
     'Hello!',
     'This is pretending to be a messaging app.',
@@ -30,28 +25,14 @@
     'Then press "send" to add a new message.',
   ];
 
-  XiSessionManager _sessionManager;
-  Future<XiSessionManager> _pendingManager;
+  final _sessionManagerProxy = XiSessionManagerProxy();
+  XiSessionManager get sessionManager => _sessionManagerProxy;
 
   DemoModel() {
-    driver.start().then((driver) => trace('ModuleDriver started')).catchError(
-        (error, trace) => log.severe('ModuleDriver errored:', error, trace));
-
-    XiSessionManagerProxy sessionManagerProxy = new XiSessionManagerProxy();
-    _pendingManager = driver
-        .connectToAgentServiceWithAsyncProxy(
-            kSessionManagerURL, sessionManagerProxy)
-        .then((_) => _sessionManager = sessionManagerProxy)
-        .catchError((err, stackTrace) => log.severe(
-            'error connecting to xi_session_manager', err, stackTrace));
+    connectToAgentService(kSessionManagerURL, _sessionManagerProxy);
   }
 
-  Future<XiSessionManager> get sessionManager => (_sessionManager == null)
-      ? _pendingManager
-      : Future.value(_sessionManager);
-
-  InterfacePair<ViewOwner> viewOwner;
-  ModuleControllerClient editorController;
+  modular.ModuleController editorController;
   ChildViewConnection _editorConn;
   ChildViewConnection get editorConn => _editorConn;
 
@@ -71,7 +52,7 @@
   /// in a new modal view.
   void composeButtonAction() async {
     _activeSession = await requestSessionId();
-    connectXiModule(_activeSession);
+    await connectXiModule(_activeSession);
     log.info('connecting session $_activeSession');
     showingModal = true;
     notifyListeners();
@@ -81,39 +62,37 @@
   /// as a new message to the messages list, and dismisses the modal.
   void sendButtonAction() async {
     log.info('requesting contents for $_activeSession');
-    final newMessage = await sessionManager
-        .then((manager) => manager.getContents(_activeSession))
-        .then((vmo) => vmo.read(vmo.getSize().size).bytesAsUTF8String());
+
+    final vmo = await sessionManager.getContents(_activeSession);
+    final newMessage = vmo.read(vmo.getSize().size).bytesAsUTF8String();
+
     messages.add(newMessage);
-    //TODO: close the active session
-    await editorController.stop();
+    if (editorController != null) {
+      await editorController.stop();
+    }
     _editorConn = null;
     showingModal = false;
     notifyListeners();
   }
 
   /// Requests a new session id from the xi session agent service.
-  Future<String> requestSessionId() async {
-    var manager = await sessionManager;
-    String result = await manager.newSession();
-    return result;
-  }
+  Future<String> requestSessionId() => sessionManager.newSession();
 
-  void connectXiModule(String sessionId) async {
-    viewOwner = InterfacePair();
-    editorController = new ModuleControllerClient();
-    IntentBuilder intentBuilder = new IntentBuilder.handler(
-        'fuchsia-pkg://fuchsia.com/xi_embeddable#meta/xi_embeddable.cmx')
-      ..addParameter('session-id', sessionId);
-    driver.moduleContext.proxy.embedModule(
-        'xi_embeddable',
-        intentBuilder.intent,
-        editorController.proxy.ctrl.request(),
-        viewOwner.passRequest(), (StartModuleStatus status) {
-      editorConn = ChildViewConnection(ViewHolderToken(
-        value: EventPair(viewOwner.passHandle().passChannel().passHandle()),
-      ));
-      log.info('Start embeddable intent status = $status');
-    });
+  Future<void> connectXiModule(String sessionId) async {
+    final entity = await Module()
+        .createEntity(type: 'string', initialData: utf8.encode(sessionId));
+
+    final intent = Intent(
+        action: '',
+        handler:
+            'fuchsia-pkg://fuchsia.com/xi_embeddable#meta/xi_embeddable.cmx')
+      ..addParameterFromEntityReference(
+          'session-id', await entity.getEntityReference());
+
+    final embeddedModule =
+        await Module().embedModule(name: 'xi_embeddable', intent: intent);
+
+    _editorConn = ChildViewConnection(embeddedModule.viewHolderToken);
+    editorController = embeddedModule.moduleController;
   }
 }
diff --git a/bin/xi/xi_session_demo/meta/xi_session_demo.cmx b/bin/xi/xi_session_demo/meta/xi_session_demo.cmx
index 392e370..9e03dfd 100644
--- a/bin/xi/xi_session_demo/meta/xi_session_demo.cmx
+++ b/bin/xi/xi_session_demo/meta/xi_session_demo.cmx
@@ -9,6 +9,7 @@
             "fuchsia.logger.LogSink",
             "fuchsia.modular.Clipboard",
             "fuchsia.modular.ContextWriter",
+            "fuchsia.modular.ComponentContext",
             "fuchsia.modular.ModuleContext",
             "fuchsia.netstack.Netstack",
             "fuchsia.sys.Environment",
diff --git a/lib/xi/client/BUILD.gn b/lib/xi/client/BUILD.gn
index 5024fa4..e242734 100644
--- a/lib/xi/client/BUILD.gn
+++ b/lib/xi/client/BUILD.gn
@@ -20,6 +20,6 @@
 
   deps = [
     "//third_party/dart-pkg/git/flutter/packages/flutter",
-    "//topaz/public/lib/app/dart",
+    "//topaz/public/dart/fuchsia_logger",
   ]
 }
diff --git a/lib/xi/client/lib/src/client.dart b/lib/xi/client/lib/src/client.dart
index 3c24ce2..c67597e 100644
--- a/lib/xi/client/lib/src/client.dart
+++ b/lib/xi/client/lib/src/client.dart
@@ -4,7 +4,8 @@
 
 import 'dart:async';
 import 'dart:convert';
-import 'package:lib.app.dart/logging.dart';
+
+import 'package:fuchsia_logger/logger.dart';
 
 /// ignore_for_file: avoid_annotating_with_dynamic
 
diff --git a/lib/xi/client/lib/src/handler_adapter.dart b/lib/xi/client/lib/src/handler_adapter.dart
index 587b169..739e8e0 100644
--- a/lib/xi/client/lib/src/handler_adapter.dart
+++ b/lib/xi/client/lib/src/handler_adapter.dart
@@ -2,7 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-import 'package:lib.app.dart/logging.dart';
+import 'package:fuchsia_logger/logger.dart';
+
 import 'client.dart';
 import 'handler_interface.dart';
 
diff --git a/lib/xi/client/lib/src/view_impl.dart b/lib/xi/client/lib/src/view_impl.dart
index 35d0269..3ed97ad 100644
--- a/lib/xi/client/lib/src/view_impl.dart
+++ b/lib/xi/client/lib/src/view_impl.dart
@@ -3,6 +3,7 @@
 // found in the LICENSE file.
 
 import 'dart:async';
+
 import 'client.dart';
 import 'view_interface.dart';
 
diff --git a/lib/xi/fuchsia_client/BUILD.gn b/lib/xi/fuchsia_client/BUILD.gn
index d9ff21a..9aabad4 100644
--- a/lib/xi/fuchsia_client/BUILD.gn
+++ b/lib/xi/fuchsia_client/BUILD.gn
@@ -18,7 +18,7 @@
     "//sdk/fidl/fuchsia.modular",
     "//topaz/public/dart/fidl",
     "//topaz/public/dart/fuchsia",
-    "//topaz/public/lib/app/dart",
+    "//topaz/public/dart/fuchsia_services",
   ]
 }
 
diff --git a/lib/xi/fuchsia_client/lib/client.dart b/lib/xi/fuchsia_client/lib/client.dart
index ea438c6..04336c7 100644
--- a/lib/xi/fuchsia_client/lib/client.dart
+++ b/lib/xi/fuchsia_client/lib/client.dart
@@ -6,17 +6,15 @@
 import 'dart:convert';
 import 'dart:typed_data';
 
-import 'package:lib.app.dart/app.dart';
-import 'package:fidl_fuchsia_ledger/fidl.dart';
-import 'package:fidl_fuchsia_sys/fidl.dart';
+import 'package:fidl_fuchsia_ledger/fidl_async.dart';
+import 'package:fidl_fuchsia_io/fidl_async.dart' as io;
+import 'package:fidl_fuchsia_sys/fidl_async.dart';
 import 'package:fidl/fidl.dart';
-import 'package:fidl_fuchsia_xi/fidl.dart' as service;
+import 'package:fidl_fuchsia_xi/fidl_async.dart' as service;
+import 'package:fuchsia_services/services.dart';
 import 'package:xi_client/client.dart';
 import 'package:zircon/zircon.dart';
 
-/// [StartupContext] exported here so it can be used in `main.dart`.
-final StartupContext kContext = new StartupContext.fromStartupInfo();
-
 /// A partial implementation of XiClient to handle socket reading and writing.
 /// This should not be used on its own, but subclassed by some another type
 /// that will handle setting up the socket.
@@ -71,7 +69,7 @@
   XiFuchsiaClient(InterfaceHandle<Ledger> _ledgerHandle) {
     // Note: _ledgerHandle is currently unused, but we're hoping to bring it back.
   }
-  final Services _services = new Services();
+  final _dirProxy = io.DirectoryProxy();
   final service.JsonProxy _jsonProxy = new service.JsonProxy();
 
   @override
@@ -80,18 +78,19 @@
       return;
     }
 
-    final LaunchInfo launchInfo =
-        new LaunchInfo(url: 'fuchsia-pkg://fuchsia.com/xi_core#meta/xi_core.cmx', directoryRequest: _services.request());
-    kContext.launcher.createComponent(launchInfo, null);
-    // TODO(jasoncampbell): File a bug for how to get rid of the Dart warning
-    // "Unsafe implicit cast from InterfaceHandle<dynamic>"?
-    // ignore: STRONG_MODE_DOWN_CAST_COMPOSITE
-    InterfaceHandle<service.Json> handle = _services.connectToServiceByName(
-      service.Json.$serviceName,
-    );
-    _jsonProxy.ctrl.bind(handle);
+    final LaunchInfo launchInfo = new LaunchInfo(
+        url: 'fuchsia-pkg://fuchsia.com/xi_core#meta/xi_core.cmx',
+        directoryRequest: _dirProxy.ctrl.request().passChannel());
+
+    //TODO: should explicitly control the lifecycle of the component instead of passing null
+    await StartupContext.fromStartupInfo()
+        .launcher
+        .createComponent(launchInfo, null);
+
+    Incoming(_dirProxy).connectToService(_jsonProxy);
+
     final SocketPair pair = new SocketPair();
-    _jsonProxy.connectSocket(pair.first);
+    await _jsonProxy.connectSocket(pair.first);
     _reader
       ..bind(pair.second)
       ..onReadable = handleRead;
diff --git a/lib/xi/widgets/BUILD.gn b/lib/xi/widgets/BUILD.gn
index b86e0a8..f6e4579 100644
--- a/lib/xi/widgets/BUILD.gn
+++ b/lib/xi/widgets/BUILD.gn
@@ -23,6 +23,6 @@
     "//third_party/dart-pkg/git/flutter/packages/flutter",
     "//topaz/lib/xi/client:xi_client",
     "//topaz/lib/xi/fuchsia_client:xi_fuchsia_client",
-    "//topaz/public/lib/app/dart",
+    "//topaz/public/dart/fuchsia_logger",
   ]
 }
diff --git a/lib/xi/widgets/lib/src/document.dart b/lib/xi/widgets/lib/src/document.dart
index fbaa32b..2de0f51 100644
--- a/lib/xi/widgets/lib/src/document.dart
+++ b/lib/xi/widgets/lib/src/document.dart
@@ -3,8 +3,10 @@
 // found in the LICENSE file.
 
 import 'dart:async';
+
 import 'package:flutter/material.dart';
 import 'package:xi_client/client.dart';
+
 import 'editor.dart';
 import 'line_cache.dart';
 
diff --git a/lib/xi/widgets/lib/src/editor.dart b/lib/xi/widgets/lib/src/editor.dart
index ecfecb2..78c0696 100644
--- a/lib/xi/widgets/lib/src/editor.dart
+++ b/lib/xi/widgets/lib/src/editor.dart
@@ -9,7 +9,7 @@
 
 import 'package:flutter/material.dart';
 import 'package:flutter/services.dart';
-import 'package:lib.app.dart/logging.dart';
+import 'package:fuchsia_logger/logger.dart';
 import 'package:xi_client/client.dart';
 
 import 'document.dart';
diff --git a/lib/xi/widgets/lib/src/editor_host.dart b/lib/xi/widgets/lib/src/editor_host.dart
index a8ff9fc..bae868c 100644
--- a/lib/xi/widgets/lib/src/editor_host.dart
+++ b/lib/xi/widgets/lib/src/editor_host.dart
@@ -3,8 +3,8 @@
 // found in the LICENSE file.
 
 import 'package:flutter/material.dart';
+import 'package:fuchsia_logger/logger.dart';
 import 'package:meta/meta.dart';
-import 'package:lib.app.dart/logging.dart';
 import 'package:xi_client/client.dart';
 
 import 'document.dart';
diff --git a/lib/xi/widgets/lib/src/editor_tabs.dart b/lib/xi/widgets/lib/src/editor_tabs.dart
index 78e0bba..318907b 100644
--- a/lib/xi/widgets/lib/src/editor_tabs.dart
+++ b/lib/xi/widgets/lib/src/editor_tabs.dart
@@ -3,9 +3,11 @@
 // found in the LICENSE file.
 
 import 'dart:math' as math;
+
 import 'package:flutter/material.dart';
-import 'package:lib.app.dart/logging.dart';
+import 'package:fuchsia_logger/logger.dart';
 import 'package:xi_client/client.dart';
+
 import 'document.dart';
 import 'editor.dart';
 import 'editor_host.dart';
diff --git a/lib/xi/widgets/lib/src/embedded_editor.dart b/lib/xi/widgets/lib/src/embedded_editor.dart
index e19ea4a..a8f2916 100644
--- a/lib/xi/widgets/lib/src/embedded_editor.dart
+++ b/lib/xi/widgets/lib/src/embedded_editor.dart
@@ -3,8 +3,8 @@
 // found in the LICENSE file.
 
 import 'package:flutter/material.dart';
+import 'package:fuchsia_logger/logger.dart';
 import 'package:meta/meta.dart';
-import 'package:lib.app.dart/logging.dart';
 import 'package:xi_client/client.dart';
 import 'package:xi_fuchsia_client/client.dart';