Adding text echo UI
Also fixing up discovery logic.
Change-Id: Ic30e3e0ab6d547850cd3b41504daef5edfa202fe
diff --git a/examples/distro/app/src/flutter/lib/main.dart b/examples/distro/app/src/flutter/lib/main.dart
index 6f366ca..6772b09 100644
--- a/examples/distro/app/src/flutter/lib/main.dart
+++ b/examples/distro/app/src/flutter/lib/main.dart
@@ -32,13 +32,18 @@
}
class _BakuDistroState extends State<BakuDistro> {
- Map<String, String> devices = {};
+ final Map<String, String> devices = {};
+ InputValue data = InputValue.empty;
_BakuDistroState() {
HostMessages.addMessageHandler('deviceOnline', _onDeviceOnline);
HostMessages.addMessageHandler('deviceOffline', _onDeviceOffline);
}
+ void castTo(final String name) {
+
+ }
+
@override
Widget build(final BuildContext context) {
final List<_Device> sortedDevices = devices.keys.map((name) =>
@@ -49,11 +54,28 @@
appBar: new AppBar(
title: new Text('Baku Distro Example')
),
- body: new MaterialList(
- type: MaterialListType.oneLine,
- children: sortedDevices.map((d) => new ListItem(
- title: new Text(d.description)
- ))
+ body: new Column(
+ children: <Widget>[
+ new Padding(
+ padding: new EdgeInsets.all(8.0),
+ child: data.text.isEmpty?
+ new Text('No content', style:
+ new TextStyle(color: Theme.of(context).disabledColor)) :
+ new Text(data.text)
+ ),
+ new Input(
+ value: data,
+ labelText: 'Text content',
+ onChanged: (value) => setState(() => data = value)
+ ),
+ new MaterialList(
+ type: MaterialListType.oneLine,
+ children: sortedDevices.map((d) => new ListItem(
+ title: new Text(d.description),
+ onTap: () => castTo(d.name)
+ ))
+ )
+ ]
)
);
}
diff --git a/examples/distro/app/src/main/java/io/baku/examples/distro/Connection.java b/examples/distro/app/src/main/java/io/baku/examples/distro/Connection.java
deleted file mode 100644
index 1cee39b..0000000
--- a/examples/distro/app/src/main/java/io/baku/examples/distro/Connection.java
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright 2016 The Vanadium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package io.baku.examples.distro;
-
-import com.google.common.util.concurrent.ListenableFuture;
-import com.google.common.util.concurrent.MoreExecutors;
-
-import io.v.v23.context.VContext;
-
-public class Connection {
- private final DistroClient client;
-
- public Connection(final String name) {
- client = DistroClientFactory.getDistroClient(name);
- }
-
- private ListenableFuture<String> opInProgress;
-
- public ListenableFuture<String> pollDescription(final VContext vContext) {
- if (opInProgress == null) {
- opInProgress = client.getDescription(vContext);
- opInProgress.addListener(() -> opInProgress = null, MoreExecutors.directExecutor());
- return opInProgress;
- } else {
- return null;
- }
- }
-}
\ No newline at end of file
diff --git a/examples/distro/app/src/main/java/io/baku/examples/distro/DistroActivity.java b/examples/distro/app/src/main/java/io/baku/examples/distro/DistroActivity.java
index c45b373..cace0c5 100644
--- a/examples/distro/app/src/main/java/io/baku/examples/distro/DistroActivity.java
+++ b/examples/distro/app/src/main/java/io/baku/examples/distro/DistroActivity.java
@@ -30,6 +30,9 @@
import java.io.File;
import java.util.HashMap;
import java.util.Map;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.ScheduledThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
import io.flutter.view.FlutterMain;
import io.flutter.view.FlutterView;
@@ -48,10 +51,12 @@
public class DistroActivity extends FragmentActivity implements GoogleApiClient.OnConnectionFailedListener {
private static final String TAG = DistroActivity.class.getSimpleName();
private static final Duration PING_TIMEOUT = Duration.standardSeconds(2);
- private static final long DISCO_DEBOUNCE = 250;
+ private static final long POLL_INTERVAL = 750;
private VAndroidContext context;
private FlutterView flutterView;
+ private final Map<String, ConnectionMonitor> clients = new HashMap<>();
+ private ScheduledExecutorService poller;
private Subscription subscription;
@Override
@@ -66,6 +71,8 @@
FlutterMain.APP_BUNDLE);
flutterView.runFromBundle(appBundle.getPath(), null);
+ poller = new ScheduledThreadPoolExecutor(1);
+
context = VAndroidContexts.withDefaults(this, savedInstanceState);
Futures.addCallback(BlessingsManager
@@ -108,6 +115,9 @@
subscription.unsubscribe();
}
+ poller.shutdown();
+ clients.clear();
+
if (flutterView != null) {
flutterView.destroy();
}
@@ -143,34 +153,57 @@
}
}
+ private boolean isActive() {
+ return subscription != null && !subscription.isUnsubscribed();
+ }
+
+ private class ConnectionMonitor implements FutureCallback<String> {
+ final String name;
+ final DistroClient client;
+
+ private ListenableFuture<String> poll;
+
+ public ConnectionMonitor(final String name) {
+ this.name = name;
+ client = DistroClientFactory.getDistroClient(name);
+
+ poll();
+ }
+
+ public void poll() {
+ poll = client.getDescription(context.getVContext().withTimeout(PING_TIMEOUT));
+ Futures.addCallback(poll, this);
+ }
+
+ @Override
+ public void onSuccess(final String description) {
+ if (isActive()) {
+ final JSONObject message = new JSONObject();
+ try {
+ message.put("name", name);
+ message.put("description", description);
+ } catch (final JSONException wtf) {
+ throw new RuntimeException(wtf);
+ }
+ flutterView.sendToFlutter("deviceOnline", message.toString());
+
+ poller.schedule(this::poll, POLL_INTERVAL, TimeUnit.MILLISECONDS);
+ }
+ }
+
+ @Override
+ public void onFailure(final Throwable t) {
+ if (isActive()) {
+ flutterView.sendToFlutter("deviceOffline", name);
+
+ clients.remove(name);
+ }
+ }
+ }
+
private Subscription startScanning() {
- final Map<String, Connection> clients = new HashMap<>();
-
return Disco.scanContinuously(context)
- .subscribe(name -> {
- final Connection conn = Maps.computeIfAbsent(clients, name, Connection::new);
- ListenableFuture<String> descFuture = conn
- .pollDescription(context.getVContext().withTimeout(PING_TIMEOUT));
- if (descFuture != null) {
- Futures.addCallback(descFuture, new FutureCallback<String>() {
- @Override
- public void onSuccess(final String description) {
- final JSONObject message = new JSONObject();
- try {
- message.put("name", name);
- message.put("description", description);
- } catch (final JSONException wtf) {
- throw new RuntimeException(wtf);
- }
- flutterView.sendToFlutter("deviceOnline", message.toString());
- }
-
- @Override
- public void onFailure(final Throwable t) {
- flutterView.sendToFlutter("deviceOffline", name);
- }
- });
- }
- }, t -> context.getErrorReporter().onError(R.string.err_scan, t));
+ .subscribe(name -> Maps.computeIfAbsent(clients, name, ConnectionMonitor::new),
+ t -> context.getErrorReporter().onError(R.string.err_scan, t));
}
}