Make the presence scan always run in the background.
Change-Id: I941987bc0f5f8ffde0dc51e779fe870c10d7504c
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 2b6110d..75b7d36 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;
@@ -566,6 +567,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);
+ }
+ }
}