package com.u17od.upm;
import java.io.File;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.util.Date;
import javax.crypto.SecretKey;
import android.app.Activity;
import android.content.Intent;
import android.util.Log;
import com.u17od.upm.crypto.InvalidPasswordException;
import com.u17od.upm.database.PasswordDatabase;
import com.u17od.upm.database.ProblemReadingDatabaseFile;
public abstract class SyncDatabaseActivity extends Activity {
private static final int ENTER_PW_REQUEST_CODE = 222;
public static final int SYNC_DB_REQUEST_CODE = 226;
public static final int RESULT_REFRESH = 1;
public static interface SyncResult {
public static final int IN_SYNC = 0;
public static final int UPLOAD_LOCAL = 1;
public static final int KEEP_REMOTE = 2;
}
protected File downloadedDatabaseFile;
protected abstract void uploadDatabase();
protected abstract void downloadDatabase();
protected void decryptDatabase() {
SecretKey existingDBSecretKey = getPasswordDatabase().getEncryptionService().getSecretKey();
try {
PasswordDatabase passwordDatabase = null;
if (downloadedDatabaseFile != null) {
passwordDatabase = new PasswordDatabase(downloadedDatabaseFile, existingDBSecretKey);
}
syncDb(passwordDatabase);
} catch (IOException e) {
Log.e("SyncDatabaseActivity.onCreate()", "Problem reading database", e);
UIUtilities.showToast(SyncDatabaseActivity.this, R.string.problem_reading_upm_db, true);
finish();
} catch (GeneralSecurityException e) {
Log.e("SyncDatabaseActivity.onCreate()", "Problem decrypting database", e);
UIUtilities.showToast(SyncDatabaseActivity.this, R.string.problem_decrypying_db, true);
finish();
} catch (ProblemReadingDatabaseFile e) {
Log.e("SyncDatabaseActivity.onCreate()", "Not a password database", e);
UIUtilities.showToast(SyncDatabaseActivity.this, R.string.not_password_database);
finish();
} catch (InvalidPasswordException e) {
EnterMasterPassword.databaseFileToDecrypt = downloadedDatabaseFile;
Intent i = new Intent(SyncDatabaseActivity.this, EnterMasterPassword.class);
startActivityForResult(i, ENTER_PW_REQUEST_CODE);
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
switch(requestCode) {
case ENTER_PW_REQUEST_CODE:
if (resultCode == Activity.RESULT_CANCELED) {
UIUtilities.showToast(this, R.string.enter_password_cancalled);
finish();
} else {
syncDb(EnterMasterPassword.decryptedPasswordDatabase);
}
break;
}
}
/**
* Check if the downloaded DB is more recent than the current db.
* If it is the replace the current DB with the downloaded one and reload
* the accounts listview
*/
protected int syncDb(PasswordDatabase dbDownloadedOnSync) {
int syncResult = SyncResult.IN_SYNC;
UPMApplication app = (UPMApplication) getApplication();
if (dbDownloadedOnSync == null || dbDownloadedOnSync.getRevision() < app.getPasswordDatabase().getRevision()) {
uploadDatabase();
syncResult = SyncResult.UPLOAD_LOCAL;
} else if (dbDownloadedOnSync.getRevision() > app.getPasswordDatabase().getRevision()) {
app.copyFile(downloadedDatabaseFile, Utilities.getDatabaseFile(this), this);
app.setPasswordDatabase(dbDownloadedOnSync);
dbDownloadedOnSync.setDatabaseFile(Utilities.getDatabaseFile(this));
setResult(RESULT_REFRESH);
syncResult = SyncResult.KEEP_REMOTE;
UIUtilities.showToast(this, R.string.new_db_downloaded);
finish();
} else if (dbDownloadedOnSync.getRevision() == app.getPasswordDatabase().getRevision()) {
UIUtilities.showToast(this, R.string.db_uptodate);
finish();
}
app.setTimeOfLastSync(new Date());
if (downloadedDatabaseFile != null) {
downloadedDatabaseFile.delete();
}
return syncResult;
}
protected PasswordDatabase getPasswordDatabase() {
return ((UPMApplication) getApplication()).getPasswordDatabase();
}
}