blob: ac033a3c86a57141f7f968da0c1abef8d7bd72ee [file] [log] [blame]
// 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.v.todos.sharing;
import android.support.annotation.NonNull;
import android.util.Log;
import com.google.common.base.Function;
import com.google.common.collect.Iterables;
import com.google.common.util.concurrent.FutureCallback;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import javax.annotation.Nullable;
import io.v.android.v23.V;
import io.v.todos.R;
import io.v.todos.persistence.syncbase.SyncbasePersistence;
import io.v.v23.InputChannelCallback;
import io.v.v23.InputChannels;
import io.v.v23.context.VContext;
import io.v.v23.discovery.Advertisement;
import io.v.v23.discovery.Discovery;
import io.v.v23.discovery.Update;
import io.v.v23.security.BlessingPattern;
import io.v.v23.services.syncbase.Id;
import io.v.v23.syncbase.ChangeType;
import io.v.v23.syncbase.Database;
import io.v.v23.syncbase.Invite;
import io.v.v23.syncbase.Syncbase;
import io.v.v23.syncbase.WatchChange;
import io.v.v23.verror.VException;
public final class Sharing {
private Sharing() {
}
private static final String TAG = "SHARING";
private static final Object sDiscoveryMutex = new Object();
private static Discovery sDiscovery;
private static VContext sScanContext;
public static Discovery getDiscovery() {
return sDiscovery;
}
public static void initDiscovery(Database db) throws VException {
synchronized (sDiscoveryMutex) {
if (sDiscovery == null) {
sDiscovery = V.newDiscovery(SyncbasePersistence.getAppVContext());
// Rely on the neighborhood fragment to initialize presence advertisement.
NeighborhoodFragment.initSharePresence();
sScanContext = initScanForInvites(db);
}
}
}
// TODO(alexfandrianto): Nobody calls this, so we never stop sharing.
public static void stopDiscovery() {
synchronized (sDiscoveryMutex) {
sScanContext.cancel();
}
}
private static String getRootInterface() {
return SyncbasePersistence.getAppContext().getPackageName();
}
// TODO(alexfandrianto): Make this "presence" and "invitation" once everyone migrates over.
public static String getPresenceInterface() {
return getRootInterface() + ".presence2";
}
/**
* Starts a scanner seeking advertisements that invite this user to a todo list. When an invite
* is found, the app will automatically accept it.
*/
public static VContext initScanForInvites(Database db)
throws VException {
VContext vContext = SyncbasePersistence.getAppVContext().withCancel();
try {
db.listenForInvites(vContext, new Database.InviteHandler() {
@Override
public void handleInvite(Invite invite) {
String prefix = SyncbasePersistence.LIST_COLLECTION_SYNCGROUP_PREFIX +
SyncbasePersistence.LISTS_PREFIX;
String name = invite.getSyncgroupId().getName();
if (!name.startsWith(prefix)) {
// Not actually a Todo List.
return;
}
Log.d(TAG, "Accepting todo list invite: " + invite.getSyncgroupId().toString());
String blessing = invite.getSyncgroupId().getBlessing();
Id listId = new Id(blessing, name.substring(
SyncbasePersistence.LIST_COLLECTION_SYNCGROUP_PREFIX.length()));
SyncbasePersistence.acceptSharedTodoList(listId);
}
});
} catch (VException e) {
handleScanListsError(e);
}
return vContext;
}
private static void handleScanListsError(Throwable t) {
SyncbasePersistence.getAppErrorReporter().onError(R.string.err_scan_lists, t);
}
}