Merge branch 'master' into todoshacks
diff --git a/app/src/syncbase/java/io/v/todos/persistence/syncbase/SyncbasePersistence.java b/app/src/syncbase/java/io/v/todos/persistence/syncbase/SyncbasePersistence.java
index 8622abc..d7b3c31 100644
--- a/app/src/syncbase/java/io/v/todos/persistence/syncbase/SyncbasePersistence.java
+++ b/app/src/syncbase/java/io/v/todos/persistence/syncbase/SyncbasePersistence.java
@@ -54,6 +54,7 @@
import io.v.todos.R;
import io.v.todos.persistence.Persistence;
import io.v.todos.sharing.NeighborhoodFragment;
+import io.v.todos.sharing.ShareListDialogFragment;
import io.v.todos.sharing.Sharing;
import io.v.v23.InputChannel;
import io.v.v23.InputChannelCallback;
@@ -159,11 +160,14 @@
throws SyncbaseServer.StartException {
try {
ListenSpec ls = V.getListenSpec(vContext);
+ /*
ListenSpec.Address[] addresses = ls.getAddresses();
addresses = Arrays.copyOf(addresses, addresses.length + 1);
addresses[addresses.length - 1] = new ListenSpec.Address("bt", "/0");
ListenSpec newLs = new ListenSpec(addresses, PROXY, ls.getChooser());
vContext = V.withListenSpec(vContext, newLs);
+ */
+ vContext = V.withListenSpec(vContext, ls.withProxy(PROXY));
} catch (VException e) {
Log.w(TAG, "Unable to set up Vanadium proxy for Syncbase");
}
@@ -566,6 +570,7 @@
// VFutures.sync(ensureCloudDatabaseExists); // must finish before syncgroup setup
ensureUserSyncgroupExists();
Sharing.initDiscovery(); // requires that db and collection exist
+ ShareListDialogFragment.initScan();
sInitialized = true;
}
diff --git a/app/src/syncbase/java/io/v/todos/sharing/ShareListDialogFragment.java b/app/src/syncbase/java/io/v/todos/sharing/ShareListDialogFragment.java
index 14b93cd..7cb7eae 100644
--- a/app/src/syncbase/java/io/v/todos/sharing/ShareListDialogFragment.java
+++ b/app/src/syncbase/java/io/v/todos/sharing/ShareListDialogFragment.java
@@ -60,15 +60,13 @@
private ContactAdapter mAdapter;
- private VContext mScanContext;
-
private ShareListMenuFragment getParent() {
return ((ShareListMenuFragment) getParentFragment());
}
@Override
public void onDestroyView() {
- mScanContext.cancel();
+ rmAdapter(mAdapter);
super.onDestroyView();
}
@@ -99,41 +97,7 @@
mAdapter.setContactTouchListener(this);
mContacts = (RecyclerView) view.findViewById(R.id.recycler);
mContacts.setAdapter(mAdapter);
-
- mScanContext = SyncbasePersistence.getAppVContext().withCancel();
- try {
- ListenableFuture<Void> scan = InputChannels.withCallback(
- Sharing.getDiscovery().scan(mScanContext,
- "v.InterfaceName = \"" + Sharing.getPresenceInterface() + "\""),
- new InputChannelCallback<Update>() {
- @Override
- public ListenableFuture<Void> onNext(Update result) {
- final String email = Iterables.getOnlyElement(result.getAddresses());
- if (email == null ||
- email.equals(SyncbasePersistence.getPersonalEmail())) {
- return null;
- }
- if (result.isLost()) {
- mAdapter.onNearbyDeviceLost(email);
- } else {
- mAdapter.onNearbyDeviceDiscovered(email);
- }
- return null;
- }
- });
- Futures.addCallback(scan, new FutureCallback<Void>() {
- @Override
- public void onSuccess(@Nullable Void result) {
- }
-
- @Override
- public void onFailure(Throwable t) {
- handleScanningError(t);
- }
- });
- } catch (VException e) {
- handleScanningError(e);
- }
+ addAdapter(mAdapter);
final EditText editText = (EditText) view.findViewById(R.id.custom_email);
editText.setOnEditorActionListener(new TextView.OnEditorActionListener() {
@@ -166,7 +130,7 @@
.create();
}
- private void handleScanningError(Throwable t) {
+ private static void handleScanningError(Throwable t) {
//TODO(rosswang): indicate error in the view
SyncbasePersistence.getAppErrorReporter().onError(R.string.err_scan_nearby, t);
}
@@ -184,4 +148,66 @@
public void onContactTouch(RecyclerView.ViewHolder viewHolder) {
mAdapter.toggleContact(viewHolder.getAdapterPosition());
}
+
+ private static Set<String> mEmails = new HashSet<String>();
+ private static Set<ContactAdapter> mAdapters = new HashSet<ContactAdapter>();
+
+ public static synchronized void addEmail(String email) {
+ mEmails.add(email);
+ for(ContactAdapter adapter : mAdapters) {
+ adapter.onNearbyDeviceDiscovered(email);
+ }
+ }
+ public static synchronized void rmEmail(String email) {
+ mEmails.remove(email);
+ for(ContactAdapter adapter : mAdapters) {
+ adapter.onNearbyDeviceLost(email);
+ }
+ }
+ public static synchronized void addAdapter(ContactAdapter adapter) {
+ mAdapters.add(adapter);
+ for(String email : mEmails) {
+ adapter.onNearbyDeviceDiscovered(email);
+ }
+ }
+ public static synchronized void rmAdapter(ContactAdapter adapter) {
+ mAdapters.remove(adapter);
+ }
+
+ public static void initScan() {
+ VContext mScanContext = SyncbasePersistence.getAppVContext();
+ try {
+ ListenableFuture<Void> scan = InputChannels.withCallback(
+ Sharing.getDiscovery().scan(mScanContext,
+ "v.InterfaceName = \"" + Sharing.getPresenceInterface() + "\""),
+ new InputChannelCallback<Update>() {
+ @Override
+ public ListenableFuture<Void> onNext(Update result) {
+ final String email = Iterables.getOnlyElement(result.getAddresses());
+ if (email == null ||
+ email.equals(SyncbasePersistence.getPersonalEmail())) {
+ return null;
+ }
+ if (result.isLost()) {
+ rmEmail(email);
+ } else {
+ addEmail(email);
+ }
+ return null;
+ }
+ });
+ Futures.addCallback(scan, new FutureCallback<Void>() {
+ @Override
+ public void onSuccess(@Nullable Void result) {
+ }
+
+ @Override
+ public void onFailure(Throwable t) {
+ handleScanningError(t);
+ }
+ });
+ } catch (VException e) {
+ handleScanningError(e);
+ }
+ }
}