ether: start of sky app that sends echo request

Change-Id: Ia9a5005128841cff80631f74c3381ceabd3a5760
diff --git a/.gitignore b/.gitignore
index 8210b0a..8165887 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,10 +2,10 @@
 /bin
 /creds
 /gen
-
-# Dart dependencies
-/dart/.packages
-/dart/.pub
 /dart/lib/gen
-/dart/pubspec.lock
-/dart/**/packages
+
+# Dart artifacts
+.packages
+.pub
+pubspec.lock
+packages
diff --git a/Makefile b/Makefile
index 16c271a..ce984f4 100644
--- a/Makefile
+++ b/Makefile
@@ -11,7 +11,7 @@
 SYNCBASED_ADDR := 127.0.0.1:4002
 V23_MOJO_FLAGS := --v=5 --root-dir=/tmp/syncbase_mojo --v23.tcp.address=$(SYNCBASED_ADDR) --v23.permissions.literal={\"Admin\":{\"In\":[\"...\"]},\"Write\":{\"In\":[\"...\"]},\"Read\":{\"In\":[\"...\"]},\"Resolve\":{\"In\":[\"...\"]},\"Debug\":{\"In\":[\"...\"]}}
 
-#MOUNTTABLE_ADDR := 127.0.0.1:4001
+# MOUNTTABLE_ADDR := 127.0.0.1:4001
 ifdef MOUNTTABLE_ADDR
 	V23_MOJO_FLAGS += --name=syncbase_mojo --v23.namespace.root=/$(MOUNTTABLE_ADDR)
 endif
@@ -33,7 +33,7 @@
 	MOJO_BUILD_DIR := $(MOJO_DIR)/src/out/android_Debug
 	MOJO_SHARED_LIB := $(PWD)/gen/lib/android/libsystem_thunk.a
 	MOJO_SHELL_PATH := $(MOJO_BUILD_DIR)/apks/MojoShell.apk
-
+	SKY_BUILD_DIR := $(SKY_DIR)/src/out/android_Debug
 	ETHER_BUILD_DIR := $(PWD)/gen/mojo/android
 
 	THIRD_PARTY_LIBS := $(V23_ROOT)/third_party/cout/android_arm
@@ -53,7 +53,7 @@
 	MOJO_BUILD_DIR := $(MOJO_DIR)/src/out/Debug
 	MOJO_SHARED_LIB := $(PWD)/gen/lib/linux_amd64/libsystem_thunk.a
 	MOJO_SHELL_PATH := $(MOJO_BUILD_DIR)/mojo_shell
-
+	SKY_BUILD_DIR := $(SKY_DIR)/src/out/Debug
 	ETHER_BUILD_DIR := $(PWD)/gen/mojo/linux_amd64
 
 	THIRD_PARTY_LIBS := $(V23_ROOT)/third_party/cout/linux_amd64
@@ -68,7 +68,9 @@
 # very large, and can interfere with C++ memory if they are in the same
 # process.
 MOJO_SHELL_FLAGS := -v --enable-multiprocess \
-	--config-file $(PWD)/mojoconfig \
+	--config-alias MOJO_BUILD_DIR=$(MOJO_BUILD_DIR) \
+	--config-alias SKY_DIR=$(SKY_DIR) \
+	--config-alias SKY_BUILD_DIR=$(SKY_BUILD_DIR) \
 	--config-alias ETHER_DIR=$(PWD) \
 	--config-alias ETHER_BUILD_DIR=$(ETHER_BUILD_DIR)
 
@@ -173,24 +175,31 @@
 
 .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 $(MOJO_SHELL_FLAGS) $(MOJO_ANDROID_FLAGS) https://mojo.v.io/syncbase_example.dart
+	$(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
 
 .PHONY: run-echo-example
 run-echo-example: $(ETHER_BUILD_DIR)/echo_server.mojo dart/packages dart/lib/gen/dart-pkg/mojom/lib/mojo/echo.mojom.dart | env-check
-	$(MOJO_DIR)/src/mojo/devtools/common/mojo_run $(MOJO_SHELL_FLAGS) $(MOJO_ANDROID_FLAGS) https://mojo.v.io/echo_example.dart
+	$(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
+	$(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
 # https://github.com/domokit/mojo/issues/387.  If you see errors about
 # "!consumer_in_two_phase_read()", ignore and re-run the tests.
 .PHONY: test
 test: dart/packages $(ETHER_BUILD_DIR)/echo_server.mojo $(ETHER_BUILD_DIR)/syncbase_server.mojo gen-mojom | env-check
-	$(MOJO_DIR)/src/mojo/devtools/common/mojo_test $(MOJO_SHELL_FLAGS) $(MOJO_ANDROID_FLAGS) --shell-path $(MOJO_SHELL_PATH) tests
+	$(MOJO_DIR)/src/mojo/devtools/common/mojo_test --config-file $(PWD)/mojoconfig $(MOJO_SHELL_FLAGS) $(MOJO_ANDROID_FLAGS) --shell-path $(MOJO_SHELL_PATH) tests
 
 .PHONY: env-check
 env-check:
 ifndef MOJO_DIR
 	$(error MOJO_DIR is not set)
 endif
+ifndef SKY_DIR
+	$(error SKY_DIR is not set)
+endif
 ifndef V23_ROOT
 	$(error V23_ROOT is not set)
 endif
@@ -217,4 +226,5 @@
 .PHONY: veryclean
 veryclean: clean
 	rm -rf gen
-	rm -rf dart/{lib/gen,packages,.packages,pubspec.lock}
+	rm -rf dart/lib/gen
+	rm -rf dart/{.packages,pubspec.lock,packages}
diff --git a/README.md b/README.md
index 53855f3..e21f655 100644
--- a/README.md
+++ b/README.md
@@ -63,6 +63,15 @@
        $ ./mojo/tools/mojob.py gn --android
        $ ./mojo/tools/mojob.py build --android # NOTE: This can take up to 10 minutes.
 
+## Sky setup
+
+You must have the Sky code in `$SKY_DIR`. Follow the instructions in the Sky
+[CONTRIBUTING.md][sky contrib] file for "Getting the code" and "Building the
+code".
+
+Also, you must patch your Mojo code (and rebuild Mojo):
+https://github.com/domokit/mojo/issues/370
+
 ## Install Dart SDK
 
 To run Dart apps, you must install the Dart SDK.
@@ -88,3 +97,4 @@
 [depot tools]: http://www.chromium.org/developers/how-tos/install-depot-tools
 [goma]: https://sites.google.com/a/google.com/goma/how-to-use-goma/how-to-use-goma-for-chrome-team
 [mojo readme]: https://github.com/domokit/mojo/blob/master/README.md
+[sky contrib]: https://github.com/domokit/sky_engine/blob/master/CONTRIBUTING.md
diff --git a/dart/bin/echo_example.dart b/dart/bin/echo_example.dart
index 921be15..4d62e38 100755
--- a/dart/bin/echo_example.dart
+++ b/dart/bin/echo_example.dart
@@ -1,5 +1,4 @@
 #!mojo mojo:dart_content_handler
-
 import 'package:ether/initialized_application.dart' show InitializedApplication;
 import 'package:ether/echo_client.dart' show EchoClient;
 
diff --git a/dart/bin/syncbase_example.dart b/dart/bin/syncbase_example.dart
index c5aef26..a2d7be3 100644
--- a/dart/bin/syncbase_example.dart
+++ b/dart/bin/syncbase_example.dart
@@ -1,5 +1,4 @@
 #!mojo mojo:dart_content_handler
-
 import 'package:ether/initialized_application.dart' show InitializedApplication;
 import 'package:ether/syncbase_client.dart' show SyncbaseClient;
 
diff --git a/dart/lib/echo_client.dart b/dart/lib/echo_client.dart
index 3954cea..a32e9b4 100644
--- a/dart/lib/echo_client.dart
+++ b/dart/lib/echo_client.dart
@@ -12,7 +12,7 @@
   final String url;
 
   Future close({bool immediate: false}) {
-    return _proxy.close();
+    return _proxy.close(immediate: immediate);
   }
 
   EchoClient(this._app, this.url) : _proxy = new mojom.EchoProxy.unbound() {
diff --git a/dart/pubspec.yaml b/dart/pubspec.yaml
index cbdd228..bfef881 100644
--- a/dart/pubspec.yaml
+++ b/dart/pubspec.yaml
@@ -1,7 +1,6 @@
 name: ether
 dependencies:
-    mojo: any
+  mojo: any
 dev_dependencies:
-    dart_style: any
-    test: any
-
+  dart_style: any
+  test: any
diff --git a/mojoconfig b/mojoconfig
index 4830855..8fb6c9c 100644
--- a/mojoconfig
+++ b/mojoconfig
@@ -1,48 +1,20 @@
-# NOTE(nlacasse): This file was taken from $MOJO_DIR/mojoconfig and modified to
-# serve "https://mojo.v.io" assets from ETHER_DIR and ETHER_BUILD_DIR.
-
-# This is a configuration file for devtools (`mojo_run`, `mojo_test) running
-# within a Mojo checkout.
-
-# The content has to parse to a Python dictionary literal. Strings of the form
-# '@{ABC}' are aliases that will be substituted for their values before
-# evaluation:
-#  '@{BUILD_DIR}': path to the mojo output directory
-#  '@{ETHER_DIR}': path to root of ether project
-#  '@{ETHER_BUILD_DIR}': path to directory of built ether mojo files
+# Derived from $MOJO_DIR/mojoconfig.
 
 {
-  # Each dev server will be configured as specified and mapped for the
-  # indicated host using --map-origin.
   'dev_servers': [
     {
-      'host': 'https://core.mojoapps.io/',
-      # First matching prefix will apply. Within the directiories specified for
-      # a prefix, first location that contains the requested path will apply.
+      'host': 'https://mojo.v.io/',
       'mappings': [
-        ('packages/', [
-          '@{BUILD_DIR}/gen/dart-pkg/packages',
-          '@{ETHER_DIR}/dart/lib/gen/dart-pkg/packages'
-        ]),
         ('', [
-          # We map two directiories, so that both exploded dart apps under
-          # checkout root and built apps in the build directory are available.
-          # For example, one could refer to the apps of either type using urls:
-          #  - https://core.mojoapps.io/spinning_cube.mojo
-          #  - https://core.mojoapps.io/examples/dart/device_info/main.dart
-          '@{BUILD_DIR}',
-          '.'
+          # For echo_server.mojo and syncbase_server.mojo.
+          '@{ETHER_BUILD_DIR}',
+          # For echo_example.dart and syncbase_example.dart.
+          '@{ETHER_DIR}/dart/bin'
         ]),
       ],
     },
     {
-      'host': 'https://mojo.v.io',
-      'mappings': [
-        ('', ['@{ETHER_BUILD_DIR}', '@{ETHER_DIR}/dart/bin']),
-      ],
-    },
-    {
-      'host': 'https://test.mojo.v.io',
+      'host': 'https://test.mojo.v.io/',
       'mappings': [
         ('', ['@{ETHER_DIR}/dart/test']),
       ],
diff --git a/sky_echo/lib/main.dart b/sky_echo/lib/main.dart
new file mode 100644
index 0000000..e461537
--- /dev/null
+++ b/sky_echo/lib/main.dart
@@ -0,0 +1,97 @@
+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:ether/echo_client.dart' show EchoClient;
+
+class EchoApp extends App {
+  EchoApp() : super();
+
+  EchoClient c = new EchoClient(app, 'https://mojo.v.io/echo_server.mojo');
+  String sentMsg = '';
+  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);
+
+    connected = true;
+  }
+
+  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;
+  }
+
+  Future close({bool immediate: false}) async {
+    await echoProxy.close(immediate: immediate);
+    return;
+  }
+
+  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)
+    );
+  }
+}
+
+void main() {
+  runApp(new EchoApp());
+}
+*/
diff --git a/sky_echo/mojoconfig b/sky_echo/mojoconfig
new file mode 100644
index 0000000..74d997d
--- /dev/null
+++ b/sky_echo/mojoconfig
@@ -0,0 +1,34 @@
+# Combination of ../mojoconfig and $MOJO_DIR/src/mojo/tools/configs/sky.
+
+{
+  'dev_servers': [
+    {
+      'host': 'https://mojo.v.io/',
+      'mappings': [
+        ('packages/', [
+          # For sky/widgets.dart.
+          '@{ETHER_DIR}/sky_echo/packages'
+        ]),
+        ('', [
+          # For echo_server.mojo.
+          '@{ETHER_BUILD_DIR}',
+          # For sky_echo/lib/main.dart.
+          '@{ETHER_DIR}',
+        ]),
+      ],
+    },
+    {
+      'host': 'https://sky/',
+      'mappings': [
+        ('', [
+          # For sky_viewer.mojo.
+          '@{SKY_BUILD_DIR}'
+        ]),
+      ],
+    }
+  ],
+
+  'content_handlers': {
+    'application/dart': 'https://sky/sky_viewer.mojo',
+  }
+}
diff --git a/sky_echo/pubspec.yaml b/sky_echo/pubspec.yaml
new file mode 100644
index 0000000..9d18ee0
--- /dev/null
+++ b/sky_echo/pubspec.yaml
@@ -0,0 +1,4 @@
+name: sky_echo
+dependencies:
+  sky: any
+  sky_tools: any