Consolidate on database upgrade

This commit is contained in:
Dominik Schürmann 2014-09-09 09:26:03 +02:00
parent c344158c37
commit 7c67f7a715
7 changed files with 52 additions and 27 deletions

View File

@ -104,8 +104,8 @@ public class KeychainApplication extends Application {
*/ */
public void checkConsolidateRecovery() { public void checkConsolidateRecovery() {
if (Preferences.getPreferences(this).getCachedConsolidate()) { if (Preferences.getPreferences(this).getCachedConsolidate()) {
// do something which calls ProviderHelper.consolidateDatabaseStep2 with a progressable
Intent consolidateIntent = new Intent(this, ConsolidateDialogActivity.class); Intent consolidateIntent = new Intent(this, ConsolidateDialogActivity.class);
consolidateIntent.putExtra(ConsolidateDialogActivity.EXTRA_CONSOLIDATE_RECOVERY, true);
consolidateIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); consolidateIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(consolidateIntent); startActivity(consolidateIntent);
} }

View File

@ -19,6 +19,7 @@
package org.sufficientlysecure.keychain.provider; package org.sufficientlysecure.keychain.provider;
import android.content.Context; import android.content.Context;
import android.content.Intent;
import android.database.Cursor; import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper; import android.database.sqlite.SQLiteOpenHelper;
@ -33,6 +34,7 @@ import org.sufficientlysecure.keychain.provider.KeychainContract.CertsColumns;
import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRingsColumns; import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRingsColumns;
import org.sufficientlysecure.keychain.provider.KeychainContract.KeysColumns; import org.sufficientlysecure.keychain.provider.KeychainContract.KeysColumns;
import org.sufficientlysecure.keychain.provider.KeychainContract.UserIdsColumns; import org.sufficientlysecure.keychain.provider.KeychainContract.UserIdsColumns;
import org.sufficientlysecure.keychain.ui.ConsolidateDialogActivity;
import org.sufficientlysecure.keychain.util.Log; import org.sufficientlysecure.keychain.util.Log;
import java.io.File; import java.io.File;
@ -52,8 +54,9 @@ import java.io.IOException;
*/ */
public class KeychainDatabase extends SQLiteOpenHelper { public class KeychainDatabase extends SQLiteOpenHelper {
private static final String DATABASE_NAME = "openkeychain.db"; private static final String DATABASE_NAME = "openkeychain.db";
private static final int DATABASE_VERSION = 3; private static final int DATABASE_VERSION = 4;
static Boolean apgHack = false; static Boolean apgHack = false;
private Context mContext;
public interface Tables { public interface Tables {
String KEY_RINGS_PUBLIC = "keyrings_public"; String KEY_RINGS_PUBLIC = "keyrings_public";
@ -164,6 +167,7 @@ public class KeychainDatabase extends SQLiteOpenHelper {
KeychainDatabase(Context context) { KeychainDatabase(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION); super(context, DATABASE_NAME, null, DATABASE_VERSION);
mContext = context;
// make sure this is only done once, on the first instance! // make sure this is only done once, on the first instance!
boolean iAmIt = false; boolean iAmIt = false;
@ -203,21 +207,35 @@ public class KeychainDatabase extends SQLiteOpenHelper {
@Override @Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// add has_secret for all who are upgrading from a beta version Log.d(Constants.TAG, "Upgrading db from " + oldVersion + " to " + newVersion);
switch (oldVersion) { switch (oldVersion) {
case 1: case 1:
// add has_secret for all who are upgrading from a beta version
try { try {
db.execSQL("ALTER TABLE keys ADD COLUMN has_secret BOOLEAN"); db.execSQL("ALTER TABLE keys ADD COLUMN has_secret BOOLEAN");
} catch(Exception e){ } catch(Exception e){
// never mind, the column probably already existed // never mind, the column probably already existed
} }
// fall through
case 2: case 2:
// ECC support
try { try {
db.execSQL("ALTER TABLE keys ADD COLUMN " + KeysColumns.KEY_CURVE_OID + " TEXT"); db.execSQL("ALTER TABLE keys ADD COLUMN " + KeysColumns.KEY_CURVE_OID + " TEXT");
} catch(Exception e){ } catch(Exception e){
// never mind, the column probably already existed // never mind, the column probably already existed
} }
// fall through
case 3:
// better s2k detection, we need consolidate
// fall through
} }
// always do consolidate after upgrade
Intent consolidateIntent = new Intent(mContext.getApplicationContext(), ConsolidateDialogActivity.class);
consolidateIntent.putExtra(ConsolidateDialogActivity.EXTRA_CONSOLIDATE_RECOVERY, false);
consolidateIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
mContext.getApplicationContext().startActivity(consolidateIntent);
} }
/** This method tries to import data from a provided database. /** This method tries to import data from a provided database.

View File

@ -59,7 +59,7 @@ import org.sufficientlysecure.keychain.service.OperationResultParcel.LogType;
import org.sufficientlysecure.keychain.service.OperationResultParcel.OperationLog; import org.sufficientlysecure.keychain.service.OperationResultParcel.OperationLog;
import org.sufficientlysecure.keychain.service.OperationResults.ConsolidateResult; import org.sufficientlysecure.keychain.service.OperationResults.ConsolidateResult;
import org.sufficientlysecure.keychain.service.OperationResults.SaveKeyringResult; import org.sufficientlysecure.keychain.service.OperationResults.SaveKeyringResult;
import org.sufficientlysecure.keychain.util.FileImportCache; import org.sufficientlysecure.keychain.util.ParcelableFileCache;
import org.sufficientlysecure.keychain.util.IterableIterator; import org.sufficientlysecure.keychain.util.IterableIterator;
import org.sufficientlysecure.keychain.util.Log; import org.sufficientlysecure.keychain.util.Log;
import org.sufficientlysecure.keychain.util.ProgressFixedScaler; import org.sufficientlysecure.keychain.util.ProgressFixedScaler;
@ -889,8 +889,8 @@ public class ProviderHelper {
Preferences.getPreferences(mContext).setCachedConsolidateNumSecrets(cursor.getCount()); Preferences.getPreferences(mContext).setCachedConsolidateNumSecrets(cursor.getCount());
FileImportCache<ParcelableKeyRing> cache = ParcelableFileCache<ParcelableKeyRing> cache =
new FileImportCache<ParcelableKeyRing>(mContext, "consolidate_secret.pcl"); new ParcelableFileCache<ParcelableKeyRing>(mContext, "consolidate_secret.pcl");
cache.writeCache(new Iterator<ParcelableKeyRing>() { cache.writeCache(new Iterator<ParcelableKeyRing>() {
ParcelableKeyRing ring; ParcelableKeyRing ring;
@ -951,8 +951,8 @@ public class ProviderHelper {
Preferences.getPreferences(mContext).setCachedConsolidateNumPublics(cursor.getCount()); Preferences.getPreferences(mContext).setCachedConsolidateNumPublics(cursor.getCount());
FileImportCache<ParcelableKeyRing> cache = ParcelableFileCache<ParcelableKeyRing> cache =
new FileImportCache<ParcelableKeyRing>(mContext, "consolidate_public.pcl"); new ParcelableFileCache<ParcelableKeyRing>(mContext, "consolidate_public.pcl");
cache.writeCache(new Iterator<ParcelableKeyRing>() { cache.writeCache(new Iterator<ParcelableKeyRing>() {
ParcelableKeyRing ring; ParcelableKeyRing ring;
@ -1041,10 +1041,10 @@ public class ProviderHelper {
log(LogLevel.DEBUG, LogType.MSG_CON_DB_CLEAR); log(LogLevel.DEBUG, LogType.MSG_CON_DB_CLEAR);
mContentResolver.delete(KeyRings.buildUnifiedKeyRingsUri(), null, null); mContentResolver.delete(KeyRings.buildUnifiedKeyRingsUri(), null, null);
FileImportCache<ParcelableKeyRing> cacheSecret = ParcelableFileCache<ParcelableKeyRing> cacheSecret =
new FileImportCache<ParcelableKeyRing>(mContext, "consolidate_secret.pcl"); new ParcelableFileCache<ParcelableKeyRing>(mContext, "consolidate_secret.pcl");
FileImportCache<ParcelableKeyRing> cachePublic = ParcelableFileCache<ParcelableKeyRing> cachePublic =
new FileImportCache<ParcelableKeyRing>(mContext, "consolidate_public.pcl"); new ParcelableFileCache<ParcelableKeyRing>(mContext, "consolidate_public.pcl");
// 3. Re-Import secret keyrings from cache // 3. Re-Import secret keyrings from cache
if (numSecrets > 0) try { if (numSecrets > 0) try {

View File

@ -61,7 +61,7 @@ import org.sufficientlysecure.keychain.service.OperationResults.ConsolidateResul
import org.sufficientlysecure.keychain.service.OperationResults.EditKeyResult; import org.sufficientlysecure.keychain.service.OperationResults.EditKeyResult;
import org.sufficientlysecure.keychain.service.OperationResults.ImportKeyResult; import org.sufficientlysecure.keychain.service.OperationResults.ImportKeyResult;
import org.sufficientlysecure.keychain.service.OperationResults.SaveKeyringResult; import org.sufficientlysecure.keychain.service.OperationResults.SaveKeyringResult;
import org.sufficientlysecure.keychain.util.FileImportCache; import org.sufficientlysecure.keychain.util.ParcelableFileCache;
import org.sufficientlysecure.keychain.util.InputData; import org.sufficientlysecure.keychain.util.InputData;
import org.sufficientlysecure.keychain.util.Log; import org.sufficientlysecure.keychain.util.Log;
import org.sufficientlysecure.keychain.util.ProgressScaler; import org.sufficientlysecure.keychain.util.ProgressScaler;
@ -512,8 +512,8 @@ public class KeychainIntentService extends IntentService implements Progressable
entries = data.getParcelableArrayList(IMPORT_KEY_LIST); entries = data.getParcelableArrayList(IMPORT_KEY_LIST);
} else { } else {
// get entries from cached file // get entries from cached file
FileImportCache<ParcelableKeyRing> cache = ParcelableFileCache<ParcelableKeyRing> cache =
new FileImportCache<ParcelableKeyRing>(this, "key_import.pcl"); new ParcelableFileCache<ParcelableKeyRing>(this, "key_import.pcl");
entries = cache.readCacheIntoList(); entries = cache.readCacheIntoList();
} }

View File

@ -34,17 +34,20 @@ import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler;
*/ */
public class ConsolidateDialogActivity extends FragmentActivity { public class ConsolidateDialogActivity extends FragmentActivity {
public static final String EXTRA_CONSOLIDATE_RECOVERY = "consolidate_recovery";
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
// this activity itself has no content view (see manifest) // this activity itself has no content view (see manifest)
consolidateRecovery(); boolean recovery = getIntent().getBooleanExtra(EXTRA_CONSOLIDATE_RECOVERY, false);
consolidateRecovery(recovery);
} }
private void consolidateRecovery() { private void consolidateRecovery(boolean recovery) {
// Message is received after importing is done in KeychainIntentService // Message is received after importing is done in KeychainIntentService
KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler( KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler(
this, this,
@ -81,7 +84,7 @@ public class ConsolidateDialogActivity extends FragmentActivity {
// fill values for this action // fill values for this action
Bundle data = new Bundle(); Bundle data = new Bundle();
data.putBoolean(KeychainIntentService.CONSOLIDATE_RECOVERY, true); data.putBoolean(KeychainIntentService.CONSOLIDATE_RECOVERY, recovery);
intent.putExtra(KeychainIntentService.EXTRA_DATA, data); intent.putExtra(KeychainIntentService.EXTRA_DATA, data);
// Create a new Messenger for the communication back // Create a new Messenger for the communication back
@ -93,7 +96,6 @@ public class ConsolidateDialogActivity extends FragmentActivity {
// start service with intent // start service with intent
startService(intent); startService(intent);
} }
} }

View File

@ -19,8 +19,6 @@ package org.sufficientlysecure.keychain.ui;
import android.annotation.TargetApi; import android.annotation.TargetApi;
import android.app.ProgressDialog; import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.content.DialogInterface.OnCancelListener;
import android.content.Intent; import android.content.Intent;
import android.net.Uri; import android.net.Uri;
import android.nfc.NdefMessage; import android.nfc.NdefMessage;
@ -52,7 +50,7 @@ import org.sufficientlysecure.keychain.service.OperationResultParcel;
import org.sufficientlysecure.keychain.service.OperationResults.ImportKeyResult; import org.sufficientlysecure.keychain.service.OperationResults.ImportKeyResult;
import org.sufficientlysecure.keychain.ui.adapter.PagerTabStripAdapter; import org.sufficientlysecure.keychain.ui.adapter.PagerTabStripAdapter;
import org.sufficientlysecure.keychain.ui.widget.SlidingTabLayout; import org.sufficientlysecure.keychain.ui.widget.SlidingTabLayout;
import org.sufficientlysecure.keychain.util.FileImportCache; import org.sufficientlysecure.keychain.util.ParcelableFileCache;
import org.sufficientlysecure.keychain.util.Log; import org.sufficientlysecure.keychain.util.Log;
import org.sufficientlysecure.keychain.util.Notify; import org.sufficientlysecure.keychain.util.Notify;
@ -505,8 +503,8 @@ public class ImportKeysActivity extends ActionBarActivity {
// to prevent Java Binder problems on heavy imports // to prevent Java Binder problems on heavy imports
// read FileImportCache for more info. // read FileImportCache for more info.
try { try {
FileImportCache<ParcelableKeyRing> cache = ParcelableFileCache<ParcelableKeyRing> cache =
new FileImportCache<ParcelableKeyRing>(this, "key_import.pcl"); new ParcelableFileCache<ParcelableKeyRing>(this, "key_import.pcl");
cache.writeCache(selectedEntries); cache.writeCache(selectedEntries);
intent.putExtra(KeychainIntentService.EXTRA_DATA, data); intent.putExtra(KeychainIntentService.EXTRA_DATA, data);

View File

@ -29,6 +29,7 @@ import java.io.DataOutputStream;
import java.io.EOFException; import java.io.EOFException;
import java.io.File; import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream; import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
@ -42,13 +43,13 @@ import java.util.List;
* To overcome this problem, we cache large Parcelables into a file in our private cache directory * To overcome this problem, we cache large Parcelables into a file in our private cache directory
* instead of sending them through IPC. * instead of sending them through IPC.
*/ */
public class FileImportCache<E extends Parcelable> { public class ParcelableFileCache<E extends Parcelable> {
private Context mContext; private Context mContext;
private final String mFilename; private final String mFilename;
public FileImportCache(Context context, String filename) { public ParcelableFileCache(Context context, String filename) {
mContext = context; mContext = context;
mFilename = filename; mFilename = filename;
} }
@ -104,7 +105,13 @@ public class FileImportCache<E extends Parcelable> {
} }
final File tempFile = new File(cacheDir, mFilename); final File tempFile = new File(cacheDir, mFilename);
final DataInputStream ois = new DataInputStream(new FileInputStream(tempFile)); final DataInputStream ois;
try {
ois = new DataInputStream(new FileInputStream(tempFile));
} catch (FileNotFoundException e) {
Log.e(Constants.TAG, "parcel import file not existing", e);
throw new IOException(e);
}
return new Iterator<E>() { return new Iterator<E>() {