blob: 8ad5fce88492088c15d3254e61ba0c55e49417b0 [file] [log] [blame]
// Copyright 2015 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.syncslides.db;
import android.content.Context;
import android.os.Handler;
import android.os.Looper;
import android.provider.Settings;
import android.util.Log;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import java.io.File;
import java.util.Arrays;
import io.v.android.v23.V;
import io.v.impl.google.services.syncbase.SyncbaseServer;
import io.v.syncslides.InitException;
import io.v.syncslides.V23;
import io.v.syncslides.model.Deck;
import io.v.syncslides.model.DynamicList;
import io.v.v23.context.VContext;
import io.v.v23.rpc.Server;
import io.v.v23.security.BlessingPattern;
import io.v.v23.security.Blessings;
import io.v.v23.security.access.AccessList;
import io.v.v23.security.access.Constants;
import io.v.v23.security.access.Permissions;
import io.v.v23.syncbase.Syncbase;
import io.v.v23.syncbase.SyncbaseApp;
import io.v.v23.syncbase.SyncbaseService;
import io.v.v23.syncbase.nosql.Database;
import io.v.v23.syncbase.nosql.Table;
import io.v.v23.verror.VException;
public class SyncbaseDB implements DB {
private static final String TAG = "SyncbaseDB";
private static final String SYNCBASE_APP = "syncslides";
private static final String SYNCBASE_DB = "syncslides";
private static final String DECKS_TABLE = "Decks";
private static final String NOTES_TABLE = "Notes";
static final String PRESENTATIONS_TABLE = "Presentations";
static final String CURRENT_SLIDE = "CurrentSlide";
static final String QUESTIONS = "questions";
private static final String SYNCGROUP_PRESENTATION_DESCRIPTION = "Live Presentation";
private boolean mInitialized = false;
private Handler mHandler;
private Permissions mPermissions;
private Context mContext;
private VContext mVContext;
private Server mSyncbaseServer;
private Database mDB;
// Singleton.
SyncbaseDB() {
}
@Override
public void init(Context context) throws InitException {
if (mInitialized) {
return;
}
mContext = context;
mHandler = new Handler(Looper.getMainLooper());
// If blessings aren't in place, the fragment that called this
// initialization may continue to load and use DB, but nothing will
// work so DB methods should return noop values. It's assumed that
// the calling fragment will send the user to the AccountManager,
// accept blessings on return, then re-call this init.
if (!V23.Singleton.get().isBlessed()) {
Log.d(TAG, "no blessings.");
return;
}
mVContext = V23.Singleton.get().getVContext();
setupSyncbase();
}
// TODO(kash): Run this in an AsyncTask so it doesn't block the UI.
private void setupSyncbase() throws InitException {
Blessings blessings = V23.Singleton.get().getBlessings();
AccessList everyoneAcl = new AccessList(
ImmutableList.of(new BlessingPattern("...")), ImmutableList.<String>of());
AccessList justMeAcl = new AccessList(
ImmutableList.of(new BlessingPattern(blessings.toString())),
ImmutableList.<String>of());
mPermissions = new Permissions(ImmutableMap.of(
Constants.RESOLVE.getValue(), everyoneAcl,
Constants.READ.getValue(), justMeAcl,
Constants.WRITE.getValue(), justMeAcl,
Constants.ADMIN.getValue(), justMeAcl));
// Prepare the syncbase storage directory.
File storageDir = new File(mContext.getFilesDir(), "syncbase");
storageDir.mkdirs();
try {
String id = Settings.Secure.getString(
mContext.getContentResolver(), Settings.Secure.ANDROID_ID);
mVContext = SyncbaseServer.withNewServer(mVContext, new SyncbaseServer.Params()
.withPermissions(mPermissions)
// TODO(kash): Mount it!
//.withName(V23Manager.syncName(id))
.withStorageRootDir(storageDir.getAbsolutePath()));
} catch (SyncbaseServer.StartException e) {
throw new InitException("Couldn't start syncbase server", e);
}
try {
mSyncbaseServer = V.getServer(mVContext);
Log.i(TAG, "Endpoints: " + Arrays.toString(mSyncbaseServer.getStatus().getEndpoints()));
String serverName = "/" + mSyncbaseServer.getStatus().getEndpoints()[0];
// Now that we've started Syncbase, set up our connections to it.
SyncbaseService service = Syncbase.newService(serverName);
SyncbaseApp app = service.getApp(SYNCBASE_APP);
if (!app.exists(mVContext)) {
app.create(mVContext, mPermissions);
}
mDB = app.getNoSqlDatabase(SYNCBASE_DB, null);
if (!mDB.exists(mVContext)) {
mDB.create(mVContext, mPermissions);
}
Table decks = mDB.getTable(DECKS_TABLE);
if (!decks.exists(mVContext)) {
decks.create(mVContext, mPermissions);
}
Table notes = mDB.getTable(NOTES_TABLE);
if (!notes.exists(mVContext)) {
notes.create(mVContext, mPermissions);
}
Table presentations = mDB.getTable(PRESENTATIONS_TABLE);
if (!presentations.exists(mVContext)) {
presentations.create(mVContext, mPermissions);
}
//importDecks();
} catch (VException e) {
throw new InitException("Couldn't setup syncbase service", e);
}
mInitialized = true;
}
}