ether sky_echo: get it working with echo service

Change-Id: I05f5d19ea0f4aec2d15539dafc3679629ba0c1f7
diff --git a/Makefile b/Makefile
index ce984f4..b842125 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 SHELL := /bin/bash -euo pipefail
 PWD := $(shell pwd)
 V23_GOPATH := $(shell echo `v23 run env | grep GOPATH | cut -d\= -f2`)
-DART_FILES := $(shell find dart/bin dart/lib dart/test -name "*.dart" -not -path "dart/lib/gen/*")
+DART_FILES := $(shell find dart/bin dart/lib dart/test sky_echo/lib -name "*.dart" -not -path "dart/lib/gen/*")
 GO_FILES := $(shell find go/src -name "*.go")
 V23_GO_FILES := $(shell find $(V23_ROOT) -name "*.go")
 
@@ -167,12 +167,17 @@
 	# TODO(nlacasse): Fix dart mojom binding generator so it does not produce
 	# files that violate dartanalyzer.  For now, we use "grep -v" to hide all
 	# warnings from *.mojom.dart files.
-	cd dart && dartanalyzer bin/*.dart lib/*.dart test/*.dart | grep -v '\.mojom\.dart'
+	cd dart && dartanalyzer bin/*.dart lib/*.dart test/*.dart | grep -v "\[hint\] Dead code.*\.mojom\.dart"
+	cd sky_echo && dartanalyzer lib/*.dart
 
 # Installs dart dependencies.
 dart/packages: dart/pubspec.yaml
 	cd dart && pub get
 
+# Installs dart dependencies.
+sky_echo/packages: sky_echo/pubspec.yaml
+	cd sky_echo && pub get
+
 .PHONY: run-syncbase-example
 run-syncbase-example: $(ETHER_BUILD_DIR)/syncbase_server.mojo dart/packages dart/lib/gen/dart-pkg/mojom/lib/mojo/syncbase.mojom.dart | env-check
 	$(MOJO_DIR)/src/mojo/devtools/common/mojo_run --config-file $(PWD)/mojoconfig $(MOJO_SHELL_FLAGS) $(MOJO_ANDROID_FLAGS) https://mojo.v.io/syncbase_example.dart
@@ -182,7 +187,7 @@
 	$(MOJO_DIR)/src/mojo/devtools/common/mojo_run --config-file $(PWD)/mojoconfig $(MOJO_SHELL_FLAGS) $(MOJO_ANDROID_FLAGS) https://mojo.v.io/echo_example.dart
 
 .PHONY: run-sky-echo
-run-sky-echo: $(ETHER_BUILD_DIR)/echo_server.mojo dart/packages dart/lib/gen/dart-pkg/mojom/lib/mojo/echo.mojom.dart | env-check
+run-sky-echo: $(ETHER_BUILD_DIR)/echo_server.mojo sky_echo/packages dart/lib/gen/dart-pkg/mojom/lib/mojo/echo.mojom.dart | env-check
 	$(MOJO_DIR)/src/mojo/devtools/common/mojo_run --config-file $(PWD)/sky_echo/mojoconfig $(MOJO_SHELL_FLAGS) $(MOJO_ANDROID_FLAGS) 'mojo:window_manager https://mojo.v.io/sky_echo/lib/main.dart'
 
 # TODO(nlacasse): The tests are currently flaky due to
diff --git a/dart/bin/echo_example.dart b/dart/bin/echo_example.dart
index 4d62e38..7bd205c 100755
--- a/dart/bin/echo_example.dart
+++ b/dart/bin/echo_example.dart
@@ -1,6 +1,6 @@
 #!mojo mojo:dart_content_handler
-import 'package:ether/initialized_application.dart' show InitializedApplication;
 import 'package:ether/echo_client.dart' show EchoClient;
+import 'package:ether/initialized_application.dart' show InitializedApplication;
 
 main(List args) async {
   InitializedApplication app = new InitializedApplication.fromHandle(args[0]);
@@ -8,7 +8,7 @@
 
   String url = 'https://mojo.v.io/echo_server.mojo';
 
-  EchoClient c = new EchoClient(app, url);
+  EchoClient c = new EchoClient(app.connectToService, url);
 
   String input = 'foobar';
   String output = await c.echo(input);
diff --git a/dart/lib/echo_client.dart b/dart/lib/echo_client.dart
index a32e9b4..a639253 100644
--- a/dart/lib/echo_client.dart
+++ b/dart/lib/echo_client.dart
@@ -2,29 +2,30 @@
 
 import 'dart:async';
 
-import 'package:mojo/application.dart' show Application;
+import 'package:mojo/bindings.dart' as bindings;
 
 import 'gen/dart-gen/mojom/lib/mojo/echo.mojom.dart' as mojom;
 
+typedef void ConnectToServiceFn(String url, bindings.ProxyBase proxy);
+
 class EchoClient {
-  final Application _app;
   final mojom.EchoProxy _proxy;
-  final String url;
+  final String _url;
 
   Future close({bool immediate: false}) {
     return _proxy.close(immediate: immediate);
   }
 
-  EchoClient(this._app, this.url) : _proxy = new mojom.EchoProxy.unbound() {
-    print('connecting to $url');
-    _app.connectToService(url, _proxy);
+  EchoClient(ConnectToServiceFn cts, this._url)
+      : _proxy = new mojom.EchoProxy.unbound() {
+    print('connecting to $_url');
+    cts(_url, _proxy);
     print('connected');
   }
 
   Future<String> echo(String s) async {
     print('calling echoString($s)');
     mojom.EchoEchoStringResponseParams v = await _proxy.ptr.echoString(s);
-
     String output = v.value;
     print('got echo result: $output');
     return output;
diff --git a/dart/test/echo_test.dart b/dart/test/echo_test.dart
index 00101eb..435fbbd 100644
--- a/dart/test/echo_test.dart
+++ b/dart/test/echo_test.dart
@@ -13,7 +13,7 @@
 
   String url = 'https://mojo.v.io/echo_server.mojo';
 
-  EchoClient c = new EchoClient(app, url);
+  EchoClient c = new EchoClient(app.connectToService, url);
 
   tearDown(() {
     app.resetConnections();
diff --git a/sky_echo/lib/main.dart b/sky_echo/lib/main.dart
index e461537..3c92aa9 100644
--- a/sky_echo/lib/main.dart
+++ b/sky_echo/lib/main.dart
@@ -1,97 +1,61 @@
-import 'package:sky/widgets.dart';
-
-class HelloWorldApp extends App {
-  Widget build() {
-    return new Center(child: new Text('Hello, world!'));
-  }
-}
-
-void main() {
-  runApp(new HelloWorldApp());
-}
-
-
-/*
-import 'package:sky/widgets.dart';
-
 import 'dart:async';
 
-import 'package:mojo/core.dart';
-import 'package:mojo/bindings.dart';
 import 'package:sky/mojo/embedder.dart' show embedder;
+import 'package:sky/widgets.dart';
 
-import 'package:ether/echo_client.dart' show EchoClient;
+import '../../dart/lib/echo_client.dart' show EchoClient;
+
+log(String msg) {
+  DateTime now = new DateTime.now();
+  print('${now.toString()} $msg');
+}
 
 class EchoApp extends App {
-  EchoApp() : super();
+  final EchoClient _c;
 
-  EchoClient c = new EchoClient(app, 'https://mojo.v.io/echo_server.mojo');
-  String sentMsg = '';
+  EchoApp()
+      : _c = new EchoClient(
+            embedder.connectToService, 'https://mojo.v.io/echo_server.mojo') {}
+
+  int seq = 0;
+  String sendMsg = '';
   String recvMsg = '';
-  bool connected = false;
 
-  void _connect() {
-    if (connected) return;
-    //embedder.connectToService('mojo:echo_server', echoProxy);
-    //embedder.connectToService('https://core.mojoapps.io/go_echo_server.mojo', echoProxy); // works with echo_server.mojo, but must use --enable-multiprocess for this one
-    embedder.connectToService('https://core.mojoapps.io/go_forward_echo_server.mojo', echoProxy);
+  Future doEcho() async {
+    log('EchoApp.doEcho');
+    setState(() {
+      sendMsg = seq.toString();
+      recvMsg = '';
+    });
+    seq++;
+    log('setState sendMsg done');
 
-    connected = true;
+    String recvMsgAsync = await _c.echo(sendMsg);
+
+    setState(() {
+      recvMsg = recvMsgAsync;
+    });
+    log('setState recvMsg done');
   }
 
-  Future doEcho({bool immediate: false}) async {
-    setState(() {
-      sendMsg = 'hello';
-    });
-    print('Sent message $sendMsg');
-
-    recvMsg = await c.echo(sendMsg);
-    _connect();
-    String msg = 'Hello ' + recvMsg;
-    setState(() {
-      sentMsg = msg;
-      print('Sending message $sentMsg');
-    });
-    try {
-      //final EchoEchoStringResponseParams result = await echoProxy.ptr.echoString(msg);
-      String endpoint = '/@5@wsh@172.17.166.74:33841@cbf4008c9abb8a430b1b455058e1e7ba@s@alexfandrianto@alexfandrianto0.mtv.corp.google.com-18361@@/mojo:go_echo_server/mojo::examples::Echo';
-      final ForwardEchoEchoForwardResponseParams result = await echoProxy.ptr.echoForward(msg, endpoint);
-
-      setState(() {
-        recvMsg = result.value;
-        print('Got message $recvMsg');
-      });
-    } catch(e) {
-      print('Error echoing: ' + e.toString());
-      return false;
-    }
-    return true;
-  }
-
+  // TODO(sadovsky): I don't think Sky calls App.close().
   Future close({bool immediate: false}) async {
-    await echoProxy.close(immediate: immediate);
-    return;
+    log('EchoApp.close');
+    return await _c.close(immediate: immediate);
   }
 
   Widget build() {
     return new Container(
-      decoration: const BoxDecoration(
-        backgroundColor: const Color(0xFF00ACC1)
-      ),
-      child: new Flex([
-        new RaisedButton(
-          child: new Text('Click here'),
-          onPressed: doEcho
-        ),
-        new Text('Sent message $sentMsg'),
-        new Text('Received message $recvMsg')
-      ],
-      direction: FlexDirection.vertical)
-    );
+        decoration:
+            const BoxDecoration(backgroundColor: const Color(0xFF00ACC1)),
+        child: new Flex([
+          new RaisedButton(child: new Text('doEcho'), onPressed: doEcho),
+          new Text('Sent message $sendMsg'),
+          new Text('Received message $recvMsg')
+        ], direction: FlexDirection.vertical));
   }
 }
 
 void main() {
   runApp(new EchoApp());
 }
-*/
diff --git a/sky_echo/mojoconfig b/sky_echo/mojoconfig
index 74d997d..36838cf 100644
--- a/sky_echo/mojoconfig
+++ b/sky_echo/mojoconfig
@@ -6,8 +6,10 @@
       'host': 'https://mojo.v.io/',
       'mappings': [
         ('packages/', [
+          # For echo_client.dart.
+          '@{ETHER_DIR}/dart/packages',
           # For sky/widgets.dart.
-          '@{ETHER_DIR}/sky_echo/packages'
+          '@{ETHER_DIR}/sky_echo/packages',
         ]),
         ('', [
           # For echo_server.mojo.
@@ -22,7 +24,7 @@
       'mappings': [
         ('', [
           # For sky_viewer.mojo.
-          '@{SKY_BUILD_DIR}'
+          '@{SKY_BUILD_DIR}',
         ]),
       ],
     }