TBR: croupier: Using the new discovery API.

Change-Id: I02fff28220b62a6ea9d786b61abb35783e51b1c5
diff --git a/go/src/hearts/sync/client.go b/go/src/hearts/sync/client.go
index 195578a..dab0278 100644
--- a/go/src/hearts/sync/client.go
+++ b/go/src/hearts/sync/client.go
@@ -66,13 +66,13 @@
 		}
 	case discovery.UpdateLost:
 		lost := uType.Value
-		name, ok := instances[string(lost.InstanceId)]
+		name, ok := instances[string(lost.Service.InstanceId)]
 		if !ok {
 			name = "unknown"
 		}
-		delete(instances, string(lost.InstanceId))
-		u.DiscGroups[lost.InstanceId] = nil
-		fmt.Printf("Lost %q: Instance=%x\n", name, lost.InstanceId)
+		delete(instances, string(lost.Service.InstanceId))
+		u.DiscGroups[lost.Service.InstanceId] = nil
+		fmt.Printf("Lost %q: Instance=%x\n", name, lost.Service.InstanceId)
 	}
 }
 
diff --git a/lib/src/syncbase/croupier_client.dart b/lib/src/syncbase/croupier_client.dart
index 3746850..7f4558f 100644
--- a/lib/src/syncbase/croupier_client.dart
+++ b/lib/src/syncbase/croupier_client.dart
@@ -9,7 +9,6 @@
 import 'package:flutter/services.dart' show shell;
 import 'package:syncbase/src/naming/util.dart' as naming;
 import 'package:syncbase/syncbase_client.dart' as sc;
-import 'package:v23discovery/discovery.dart' as discovery;
 
 import '../../settings/client.dart' as settings_client;
 import 'discovery_client.dart' show DiscoveryClient;
@@ -45,16 +44,6 @@
             new sc.SyncbaseClient(shell.connectToService, syncbaseServerUrl),
         _discoveryClient = new DiscoveryClient() {
     print('Fetching syncbase_server.mojo from $syncbaseServerUrl');
-
-    // TODO(alexfandrianto): Remove this test advertisement once we are more
-    // comfortable with Discovery.
-    String interfaceName = "HelloWorld!";
-    _discoveryClient.scan(discoveryTestKey,
-        'v.InterfaceName="${interfaceName}"', new MyScanHandler());
-    _discoveryClient.advertise(
-        discoveryTestKey,
-        DiscoveryClient.serviceMaker(
-            interfaceName: interfaceName, addrs: ["dummy address"]));
   }
 
   DiscoveryClient get discoveryClient => _discoveryClient;
@@ -242,14 +231,3 @@
     return watchStream.listen((sc.WatchChange wc) => _handleChange(wc));
   }
 }
-
-// Example implementation of a ScanHandler.
-class MyScanHandler extends discovery.ScanHandler {
-  void found(discovery.Service s) {
-    util.log("MYSCANHANDLER Found ${s.instanceId} ${s.instanceName}");
-  }
-
-  void lost(String instanceId) {
-    util.log("MYSCANHANDLER Lost ${instanceId}");
-  }
-}
diff --git a/lib/src/syncbase/discovery_client.dart b/lib/src/syncbase/discovery_client.dart
index 51dcb9f..470dd0c 100644
--- a/lib/src/syncbase/discovery_client.dart
+++ b/lib/src/syncbase/discovery_client.dart
@@ -7,27 +7,15 @@
 import 'package:v23discovery/discovery.dart' as discovery;
 import 'package:flutter/services.dart' show shell;
 
-class ProxyHandlePair<T> {
-  final T proxy;
-  int handle;
-
-  ProxyHandlePair(this.proxy, this.handle);
-}
-
 /// Make this into the Dart Discovery client
 /// https://github.com/vanadium/issues/issues/835
 class DiscoveryClient {
-  final Map<String,
-          Future<ProxyHandlePair<discovery.AdvertiserProxy>>> _advertisers =
-      new Map<String, Future<ProxyHandlePair<discovery.AdvertiserProxy>>>();
-  final Map<String, Future<ProxyHandlePair<discovery.ScannerProxy>>> _scanners =
-      new Map<String, Future<ProxyHandlePair<discovery.ScannerProxy>>>();
-  final Map<String, Future> _stoppingAdvertisers = new Map<String, Future>();
-  final Map<String, Future> _stoppingScanners = new Map<String, Future>();
+  final Map<String, discovery.Advertiser> _advertisers = new Map();
+  final Map<String, discovery.Scanner> _scanners = new Map();
 
-  static final String discoveryUrl = 'https://mojo2.v.io/discovery.mojo';
-
-  DiscoveryClient() {}
+  static final String _discoveryUrl = 'https://mojo2.v.io/discovery.mojo';
+  final discovery.Client _discoveryClient =
+      new discovery.Client(shell.connectToService, _discoveryUrl);
 
   static discovery.Service serviceMaker(
       {String instanceId,
@@ -48,133 +36,53 @@
 
   // Scans for this query and handles found/lost objects with the handler.
   // Keeps track of this scanner via the key.
-  Future scan(String key, String query, discovery.ScanHandler handler) async {
+  Future scan(
+      String key, String query, Function onFound, Function onLost) async {
     // Return the existing scan if one is already going.
     if (_scanners.containsKey(key)) {
       return _scanners[key];
     }
 
-    Future _scanHelper() async {
-      discovery.ScannerProxy s = new discovery.ScannerProxy.unbound();
+    discovery.Scanner scanner = await _discoveryClient.scan(query);
+    _scanners[key] = scanner;
 
-      print('Starting up discovery scanner ${key}. Looking for ${query}');
+    scanner.onFound.listen(onFound);
+    scanner.onLost.listen(onLost);
 
-      shell.connectToService(discoveryUrl, s);
-
-      // Use a ScanHandlerStub (Mojo-encodable interface) to wrap the scan handler.
-      discovery.ScanHandlerStub shs = new discovery.ScanHandlerStub.unbound();
-      shs.impl = handler;
-
-      print('Scanning begins!');
-      return s.ptr
-          .scan(query, shs)
-          .then((discovery.ScannerScanResponseParams response) {
-        print(
-            "${key} scanning started. The cancel handle is ${response.handle}.");
-
-        return new ProxyHandlePair<discovery.ScannerProxy>(s, response.handle);
-      });
-    }
-
-    // Otherwise, set _scanners[key] and do the preparation inside the future
-    // so that stopScan can stop it if the two are called back to back.
-    _scanners[key] = _scanHelper();
-
+    print('Scanning begins!');
     return _scanners[key];
   }
 
-  // This sends a stop signal to the scanner. Handles repeated stop calls on
-  // the same key by returning the same Future.
-  Future stopScan(String key) {
+  // This sends a stop signal to the scanner.
+  Future stopScan(String key) async {
     if (!_scanners.containsKey(key)) {
-      return new Future.value();
+      return;
     }
-    if (_stoppingScanners.containsKey(key)) {
-      return _stoppingScanners[key];
-    }
-
-    _stoppingScanners[key] = _stopScanHelper(key);
-
-    return _stoppingScanners[key].then((_) {
-      // Success! Let's clean up both _scanners and _stoppingScanners.
-      _scanners.remove(key);
-      _stoppingScanners.remove(key);
-    }).catchError((e) {
-      // Failure. We can only clean up _stoppingScanners.
-      _stoppingScanners.remove(key);
-      throw e;
-    });
-  }
-
-  Future _stopScanHelper(String key) async {
-    ProxyHandlePair<discovery.ScannerProxy> sp = await _scanners[key];
-    await sp.proxy.ptr.stop(sp.handle);
-    await sp.proxy.close();
-    print("Scan was stopped for ${key}!");
+    await _scanners[key].stop();
+    _scanners.remove(key);
   }
 
   // Advertises the given service information. Keeps track of the advertiser
   // handle via the key.
-  Future advertise(String key, discovery.Service serviceInfo,
+  Future advertise(String key, discovery.Service service,
       {List<String> visibility}) async {
     // Return the existing advertisement if one is already going.
     if (_advertisers.containsKey(key)) {
       return _advertisers[key];
     }
 
-    Future _advertiseHelper() async {
-      discovery.AdvertiserProxy a = new discovery.AdvertiserProxy.unbound();
-
-      print(
-          'Starting up discovery advertiser ${key}. Broadcasting for ${serviceInfo.instanceName}');
-
-      shell.connectToService(discoveryUrl, a);
-
-      return a.ptr
-          .advertise(serviceInfo, visibility ?? <String>[])
-          .then((discovery.AdvertiserAdvertiseResponseParams response) {
-        print(
-            "${key} advertising started. The cancel handle is ${response.handle}.");
-
-        return new ProxyHandlePair<discovery.AdvertiserProxy>(
-            a, response.handle);
-      });
-    }
-
-    // Otherwise, set _advertisers[key] and do the preparation inside the future
-    // so that stopAdvertise can stop it if the two are called back to back.
-    _advertisers[key] = _advertiseHelper();
+    _advertisers[key] =
+        await _discoveryClient.advertise(service, visibility: visibility);
 
     return _advertisers[key];
   }
 
-  // This sends a stop signal to the advertiser. Handles repeated stop calls on
-  // the same key by returning the same Future.
-  Future stopAdvertise(String key) {
+  // This sends a stop signal to the advertiser.
+  Future stopAdvertise(String key) async {
     if (!_advertisers.containsKey(key)) {
-      return new Future.value();
+      return;
     }
-    if (_stoppingAdvertisers.containsKey(key)) {
-      return _stoppingAdvertisers[key];
-    }
-
-    _stoppingAdvertisers[key] = _stopAdvertiseHelper(key);
-
-    return _stoppingAdvertisers[key].then((_) {
-      // Success! Let's clean up both _advertisers and _stoppingAdvertisers.
-      _advertisers.remove(key);
-      _stoppingAdvertisers.remove(key);
-    }).catchError((e) {
-      // Failure. We can only clean up _stoppingAdvertisers.
-      _stoppingAdvertisers.remove(key);
-      throw e;
-    });
-  }
-
-  Future _stopAdvertiseHelper(String key) async {
-    ProxyHandlePair<discovery.AdvertiserProxy> ap = await _advertisers[key];
-    await ap.proxy.ptr.stop(ap.handle);
-    await ap.proxy.close();
-    print("Advertise was stopped for ${key}!");
+    await _advertisers[key].stop();
+    _advertisers.remove(key);
   }
 }
diff --git a/lib/src/syncbase/settings_manager.dart b/lib/src/syncbase/settings_manager.dart
index b6e2acf..a2170d1 100644
--- a/lib/src/syncbase/settings_manager.dart
+++ b/lib/src/syncbase/settings_manager.dart
@@ -269,8 +269,11 @@
   Future scanSettings() async {
     SettingsScanHandler ssh =
         new SettingsScanHandler(_cc, this.updateGamesCallback);
-    return _cc.discoveryClient.scan(_discoveryGameAdKey,
-        'v.InterfaceName="${util.discoveryInterfaceName}"', ssh);
+    return _cc.discoveryClient.scan(
+        _discoveryGameAdKey,
+        'v.InterfaceName="${util.discoveryInterfaceName}"',
+        ssh.found,
+        ssh.lost);
   }
 
   Future stopScanSettings() {
@@ -314,10 +317,10 @@
   }
 }
 
-// Implementation of the ScanHandler for Settings information.
-// Upon finding a settings advertiser, you want to join the syncgroup that
+// Manages found and lost settings advertisements.
+// Upon finding a settings advertisement, you want to join the syncgroup that
 // they're advertising.
-class SettingsScanHandler extends discovery.ScanHandler {
+class SettingsScanHandler {
   CroupierClient _cc;
   Map<String, String> settingsAddrs;
   Map<String, String> gameAddrs;
diff --git a/pubspec.lock b/pubspec.lock
index e1c978b..265a6fd 100644
--- a/pubspec.lock
+++ b/pubspec.lock
@@ -264,7 +264,7 @@
   v23discovery:
     description: v23discovery
     source: hosted
-    version: "0.0.9"
+    version: "0.0.10"
   vector_math:
     description: vector_math
     source: hosted
diff --git a/pubspec.yaml b/pubspec.yaml
index e1bdb0e..ea5be4e 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,6 +1,6 @@
 name: croupier
 dependencies:
-  v23discovery: ">=0.0.0 <0.1.0"
+  v23discovery: ">=0.0.10 <0.1.0"
   syncbase: ">=0.0.0 <0.1.0"
   flutter:
     path: ../../../flutter/packages/flutter