stuff

Change-Id: Id02140cd488d8141257fa0341aa8e44b3d33953e
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 88b0bfb..bb8b18f 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;
@@ -161,11 +162,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");
         }
@@ -568,6 +572,7 @@
         // VFutures.sync(ensureCloudDatabaseExists); // must finish before syncgroup setup
         ensureUserSyncgroupExists();
         Sharing.initDiscovery(sDatabase); // 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);
+        }
+    }   
 }