get rid of consolidate operation

This commit is contained in:
Vincent Breitmoser
2017-09-22 04:26:12 +02:00
parent f413d77360
commit b814753b3b
13 changed files with 18 additions and 690 deletions

View File

@@ -772,9 +772,6 @@
android:name=".ui.LogDisplayActivity"
android:configChanges="orientation|screenSize|keyboardHidden|keyboard"
android:label="@string/title_log_display" />
<activity
android:name=".ui.ConsolidateDialogActivity"
android:theme="@style/Theme.Keychain.Transparent" />
<activity
android:name=".ui.PassphraseDialogActivity"
android:theme="@style/Theme.Keychain.Transparent" />

View File

@@ -17,11 +17,14 @@
package org.sufficientlysecure.keychain;
import java.security.Security;
import java.util.HashMap;
import android.accounts.Account;
import android.accounts.AccountManager;
import android.app.Application;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.PorterDuff;
import android.graphics.drawable.Drawable;
@@ -31,19 +34,15 @@ import android.support.annotation.Nullable;
import android.widget.Toast;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.sufficientlysecure.keychain.network.TlsCertificatePinning;
import org.sufficientlysecure.keychain.provider.KeychainDatabase;
import org.sufficientlysecure.keychain.provider.TemporaryFileProvider;
import org.sufficientlysecure.keychain.service.ContactSyncAdapterService;
import org.sufficientlysecure.keychain.service.KeyserverSyncAdapterService;
import org.sufficientlysecure.keychain.ui.ConsolidateDialogActivity;
import org.sufficientlysecure.keychain.ui.util.FormattingUtils;
import org.sufficientlysecure.keychain.util.Log;
import org.sufficientlysecure.keychain.util.PRNGFixes;
import org.sufficientlysecure.keychain.util.Preferences;
import org.sufficientlysecure.keychain.network.TlsCertificatePinning;
import java.security.Security;
import java.util.HashMap;
public class KeychainApplication extends Application {
@@ -119,11 +118,6 @@ public class KeychainApplication extends Application {
TlsCertificatePinning.addPinnedCertificate("api.keybase.io", getAssets(), "api.keybase.io.CA.cer");
TemporaryFileProvider.cleanUp(this);
if (!checkConsolidateRecovery()) {
// force DB upgrade, https://github.com/open-keychain/open-keychain/issues/1334
new KeychainDatabase(this).getReadableDatabase().close();
}
}
/**
@@ -164,21 +158,6 @@ public class KeychainApplication extends Application {
}
}
/**
* Restart consolidate process if it has been interrupted before
*/
public boolean checkConsolidateRecovery() {
if (Preferences.getPreferences(this).getCachedConsolidate()) {
Intent consolidateIntent = new Intent(this, ConsolidateDialogActivity.class);
consolidateIntent.putExtra(ConsolidateDialogActivity.EXTRA_CONSOLIDATE_RECOVERY, true);
consolidateIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(consolidateIntent);
return true;
} else {
return false;
}
}
static void brandGlowEffect(Context context, int brandColor) {
// no hack on Android 5
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {

View File

@@ -1,48 +0,0 @@
/*
* Copyright (C) 2015 Dominik Schürmann <dominik@dominikschuermann.de>
* Copyright (C) 2015 Vincent Breitmoser <v.breitmoser@mugenguild.com>
* Copyright (C) 2015 Adithya Abraham Philip <adithyaphilip@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.sufficientlysecure.keychain.operations;
import android.content.Context;
import android.support.annotation.NonNull;
import org.sufficientlysecure.keychain.operations.results.ConsolidateResult;
import org.sufficientlysecure.keychain.pgp.Progressable;
import org.sufficientlysecure.keychain.provider.KeyWritableRepository;
import org.sufficientlysecure.keychain.service.ConsolidateInputParcel;
import org.sufficientlysecure.keychain.service.input.CryptoInputParcel;
public class ConsolidateOperation extends BaseReadWriteOperation<ConsolidateInputParcel> {
public ConsolidateOperation(Context context, KeyWritableRepository databaseInteractor, Progressable
progressable) {
super(context, databaseInteractor, progressable);
}
@NonNull
@Override
public ConsolidateResult execute(ConsolidateInputParcel consolidateInputParcel,
CryptoInputParcel cryptoInputParcel) {
if (consolidateInputParcel.isStartFromRecovery()) {
return mKeyWritableRepository.consolidateDatabaseStep2(mProgressable);
} else {
return mKeyWritableRepository.consolidateDatabaseStep1(mProgressable);
}
}
}

View File

@@ -598,32 +598,6 @@ public abstract class OperationResult implements Parcelable {
MSG_MF_UNLOCK_ERROR (LogLevel.ERROR, R.string.msg_mf_unlock_error),
MSG_MF_UNLOCK (LogLevel.DEBUG, R.string.msg_mf_unlock),
// consolidate
MSG_CON_CRITICAL_IN (LogLevel.DEBUG, R.string.msg_con_critical_in),
MSG_CON_CRITICAL_OUT (LogLevel.DEBUG, R.string.msg_con_critical_out),
MSG_CON_DB_CLEAR (LogLevel.DEBUG, R.string.msg_con_db_clear),
MSG_CON_DELETE_PUBLIC (LogLevel.DEBUG, R.string.msg_con_delete_public),
MSG_CON_DELETE_SECRET (LogLevel.DEBUG, R.string.msg_con_delete_secret),
MSG_CON_ERROR_BAD_STATE (LogLevel.ERROR, R.string.msg_con_error_bad_state),
MSG_CON_ERROR_CONCURRENT(LogLevel.ERROR, R.string.msg_con_error_concurrent),
MSG_CON_ERROR_DB (LogLevel.ERROR, R.string.msg_con_error_db),
MSG_CON_ERROR_IO_PUBLIC (LogLevel.ERROR, R.string.msg_con_error_io_public),
MSG_CON_ERROR_IO_SECRET (LogLevel.ERROR, R.string.msg_con_error_io_secret),
MSG_CON_ERROR_PUBLIC (LogLevel.ERROR, R.string.msg_con_error_public),
MSG_CON_ERROR_SECRET (LogLevel.ERROR, R.string.msg_con_error_secret),
MSG_CON_RECOVER (LogLevel.DEBUG, R.string.msg_con_recover),
MSG_CON_RECURSIVE (LogLevel.OK, R.string.msg_con_recursive),
MSG_CON_REIMPORT_PUBLIC (LogLevel.DEBUG, R.plurals.msg_con_reimport_public),
MSG_CON_REIMPORT_PUBLIC_SKIP (LogLevel.DEBUG, R.string.msg_con_reimport_public_skip),
MSG_CON_REIMPORT_SECRET (LogLevel.DEBUG, R.plurals.msg_con_reimport_secret),
MSG_CON_REIMPORT_SECRET_SKIP (LogLevel.DEBUG, R.string.msg_con_reimport_secret_skip),
MSG_CON (LogLevel.START, R.string.msg_con),
MSG_CON_SAVE_PUBLIC (LogLevel.DEBUG, R.string.msg_con_save_public),
MSG_CON_SAVE_SECRET (LogLevel.DEBUG, R.string.msg_con_save_secret),
MSG_CON_SUCCESS (LogLevel.OK, R.string.msg_con_success),
MSG_CON_WARN_DELETE_PUBLIC (LogLevel.WARN, R.string.msg_con_warn_delete_public),
MSG_CON_WARN_DELETE_SECRET (LogLevel.WARN, R.string.msg_con_warn_delete_secret),
// edit key (higher level operation than modify)
MSG_ED (LogLevel.START, R.string.msg_ed),
MSG_ED_CACHING_NEW (LogLevel.DEBUG, R.string.msg_ed_caching_new),

View File

@@ -25,7 +25,6 @@ import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Iterator;
import java.util.List;
import android.content.ContentProviderOperation;
@@ -41,11 +40,6 @@ import android.support.v4.util.LongSparseArray;
import org.openintents.openpgp.util.OpenPgpUtils;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.keyimport.ParcelableKeyRing;
import org.sufficientlysecure.keychain.operations.ImportOperation;
import org.sufficientlysecure.keychain.operations.results.ConsolidateResult;
import org.sufficientlysecure.keychain.operations.results.ImportKeyResult;
import org.sufficientlysecure.keychain.operations.results.OperationResult.LogType;
import org.sufficientlysecure.keychain.operations.results.OperationResult.OperationLog;
import org.sufficientlysecure.keychain.operations.results.SaveKeyringResult;
@@ -73,11 +67,7 @@ import org.sufficientlysecure.keychain.provider.KeychainContract.UpdatedKeys;
import org.sufficientlysecure.keychain.provider.KeychainContract.UserPackets;
import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
import org.sufficientlysecure.keychain.util.IterableIterator;
import org.sufficientlysecure.keychain.util.IteratorWithSize;
import org.sufficientlysecure.keychain.util.Log;
import org.sufficientlysecure.keychain.util.ParcelableFileCache;
import org.sufficientlysecure.keychain.util.Preferences;
import org.sufficientlysecure.keychain.util.ProgressFixedScaler;
import org.sufficientlysecure.keychain.util.Utf8Util;
/**
@@ -1070,335 +1060,6 @@ public class KeyWritableRepository extends KeyRepository {
}
}
@NonNull
public ConsolidateResult consolidateDatabaseStep1(Progressable progress) {
OperationLog log = new OperationLog();
int indent = 0;
// 1a. fetch all secret keyrings into a cache file
log.add(LogType.MSG_CON, indent);
indent += 1;
if (mConsolidateCritical) {
log.add(LogType.MSG_CON_RECURSIVE, indent);
return new ConsolidateResult(ConsolidateResult.RESULT_OK, log);
}
progress.setProgress(R.string.progress_con_saving, 0, 100);
// The consolidate operation can never be cancelled!
progress.setPreventCancel();
try {
log.add(LogType.MSG_CON_SAVE_SECRET, indent);
indent += 1;
final Cursor cursor = mContentResolver.query(KeyRingData.buildSecretKeyRingUri(),
new String[]{KeyRingData.KEY_RING_DATA}, null, null, null);
if (cursor == null) {
log.add(LogType.MSG_CON_ERROR_DB, indent);
return new ConsolidateResult(ConsolidateResult.RESULT_ERROR, log);
}
// No keys existing might be a legitimate option, we write an empty file in that case
cursor.moveToFirst();
ParcelableFileCache<ParcelableKeyRing> cache =
new ParcelableFileCache<>(mContext, "consolidate_secret.pcl");
cache.writeCache(cursor.getCount(), new Iterator<ParcelableKeyRing>() {
ParcelableKeyRing ring;
@Override
public boolean hasNext() {
if (ring != null) {
return true;
}
if (cursor.isAfterLast()) {
return false;
}
ring = ParcelableKeyRing.createFromEncodedBytes(cursor.getBlob(0));
cursor.moveToNext();
return true;
}
@Override
public ParcelableKeyRing next() {
try {
return ring;
} finally {
ring = null;
}
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
});
cursor.close();
} catch (IOException e) {
Log.e(Constants.TAG, "error saving secret", e);
log.add(LogType.MSG_CON_ERROR_IO_SECRET, indent);
return new ConsolidateResult(ConsolidateResult.RESULT_ERROR, log);
} finally {
indent -= 1;
}
progress.setProgress(R.string.progress_con_saving, 3, 100);
// 1b. fetch all public keyrings into a cache file
try {
log.add(LogType.MSG_CON_SAVE_PUBLIC, indent);
indent += 1;
final Cursor cursor = mContentResolver.query(
KeyRingData.buildPublicKeyRingUri(),
new String[]{KeyRingData.MASTER_KEY_ID, KeyRingData.KEY_RING_DATA}, null, null, null);
if (cursor == null) {
log.add(LogType.MSG_CON_ERROR_DB, indent);
return new ConsolidateResult(ConsolidateResult.RESULT_ERROR, log);
}
// No keys existing might be a legitimate option, we write an empty file in that case
cursor.moveToFirst();
ParcelableFileCache<ParcelableKeyRing> cache =
new ParcelableFileCache<>(mContext, "consolidate_public.pcl");
cache.writeCache(cursor.getCount(), new Iterator<ParcelableKeyRing>() {
ParcelableKeyRing ring;
@Override
public boolean hasNext() {
if (ring != null) {
return true;
}
if (cursor.isAfterLast()) {
return false;
}
long masterKeyId = cursor.getLong(0);
byte[] keyBytes = cursor.getBlob(1);
if (keyBytes == null) {
try {
keyBytes = mLocalPublicKeyStorage.readPublicKey(masterKeyId);
} catch (IOException e) {
Log.e(Constants.TAG, "Failed reading key data!", e);
}
}
if (keyBytes == null) {
throw new IllegalStateException("Lost a key! This should never happen!");
}
ring = ParcelableKeyRing.createFromEncodedBytes(keyBytes);
cursor.moveToNext();
return true;
}
@Override
public ParcelableKeyRing next() {
try {
return ring;
} finally {
ring = null;
}
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
});
cursor.close();
} catch (IOException e) {
Log.e(Constants.TAG, "error saving public", e);
log.add(LogType.MSG_CON_ERROR_IO_PUBLIC, indent);
return new ConsolidateResult(ConsolidateResult.RESULT_ERROR, log);
} finally {
indent -= 1;
}
log.add(LogType.MSG_CON_CRITICAL_IN, indent);
Preferences.getPreferences(mContext).setCachedConsolidate(true);
return consolidateDatabaseStep2(log, indent, progress, false);
}
@NonNull
public ConsolidateResult consolidateDatabaseStep2(Progressable progress) {
return consolidateDatabaseStep2(new OperationLog(), 0, progress, true);
}
private static boolean mConsolidateCritical = false;
@NonNull
private ConsolidateResult consolidateDatabaseStep2(
OperationLog log, int indent, Progressable progress, boolean recovery) {
synchronized (KeyWritableRepository.class) {
if (mConsolidateCritical) {
log.add(LogType.MSG_CON_ERROR_CONCURRENT, indent);
return new ConsolidateResult(ConsolidateResult.RESULT_ERROR, log);
}
mConsolidateCritical = true;
}
try {
Preferences prefs = Preferences.getPreferences(mContext);
if (recovery) {
log.add(LogType.MSG_CON_RECOVER, indent);
indent += 1;
}
if (!prefs.getCachedConsolidate()) {
log.add(LogType.MSG_CON_ERROR_BAD_STATE, indent);
return new ConsolidateResult(ConsolidateResult.RESULT_ERROR, log);
}
// 2. wipe database (IT'S DANGEROUS)
// first, backup our list of updated key times
ArrayList<ContentValues> updatedKeysValues = new ArrayList<>();
final int INDEX_MASTER_KEY_ID = 0;
final int INDEX_LAST_UPDATED = 1;
final int INDEX_SEEN_ON_KEYSERVERS = 2;
Cursor lastUpdatedCursor = mContentResolver.query(
UpdatedKeys.CONTENT_URI,
new String[]{
UpdatedKeys.MASTER_KEY_ID,
UpdatedKeys.LAST_UPDATED,
UpdatedKeys.SEEN_ON_KEYSERVERS
},
null, null, null);
while (lastUpdatedCursor.moveToNext()) {
ContentValues values = new ContentValues();
values.put(UpdatedKeys.MASTER_KEY_ID,
lastUpdatedCursor.getLong(INDEX_MASTER_KEY_ID));
if (!lastUpdatedCursor.isNull(INDEX_LAST_UPDATED)) {
values.put(UpdatedKeys.LAST_UPDATED, lastUpdatedCursor.getLong(INDEX_LAST_UPDATED));
} else {
values.putNull(UpdatedKeys.LAST_UPDATED);
}
if (!lastUpdatedCursor.isNull(INDEX_SEEN_ON_KEYSERVERS)) {
values.put(UpdatedKeys.SEEN_ON_KEYSERVERS, lastUpdatedCursor.getInt(INDEX_SEEN_ON_KEYSERVERS));
} else {
values.putNull(UpdatedKeys.SEEN_ON_KEYSERVERS);
}
updatedKeysValues.add(values);
}
lastUpdatedCursor.close();
log.add(LogType.MSG_CON_DB_CLEAR, indent);
mContentResolver.delete(KeyRings.buildUnifiedKeyRingsUri(), null, null);
ParcelableFileCache<ParcelableKeyRing> cacheSecret, cachePublic;
// Set flag that we have a cached consolidation here
try {
cacheSecret = new ParcelableFileCache<>(mContext, "consolidate_secret.pcl");
IteratorWithSize<ParcelableKeyRing> itSecrets = cacheSecret.readCache(false);
int numSecrets = itSecrets.getSize();
log.add(LogType.MSG_CON_REIMPORT_SECRET, indent, numSecrets);
indent += 1;
// 3. Re-Import secret keyrings from cache
if (numSecrets > 0) {
ImportKeyResult result = new ImportOperation(mContext, this,
new ProgressFixedScaler(progress, 10, 25, 100, R.string.progress_con_reimport))
.serialKeyRingImport(itSecrets, numSecrets, null, null, false);
log.add(result, indent);
} else {
log.add(LogType.MSG_CON_REIMPORT_SECRET_SKIP, indent);
}
} catch (IOException e) {
Log.e(Constants.TAG, "error importing secret", e);
log.add(LogType.MSG_CON_ERROR_SECRET, indent);
return new ConsolidateResult(ConsolidateResult.RESULT_ERROR, log);
} finally {
indent -= 1;
}
try {
cachePublic = new ParcelableFileCache<>(mContext, "consolidate_public.pcl");
IteratorWithSize<ParcelableKeyRing> itPublics = cachePublic.readCache();
int numPublics = itPublics.getSize();
log.add(LogType.MSG_CON_REIMPORT_PUBLIC, indent, numPublics);
indent += 1;
// 4. Re-Import public keyrings from cache
if (numPublics > 0) {
ImportKeyResult result = new ImportOperation(mContext, this,
new ProgressFixedScaler(progress, 25, 99, 100, R.string.progress_con_reimport))
.serialKeyRingImport(itPublics, numPublics, null, null, false);
log.add(result, indent);
// re-insert our backed up list of updated key times
// TODO: can this cause issues in case a public key re-import failed?
mContentResolver.bulkInsert(UpdatedKeys.CONTENT_URI,
updatedKeysValues.toArray(new ContentValues[updatedKeysValues.size()]));
} else {
log.add(LogType.MSG_CON_REIMPORT_PUBLIC_SKIP, indent);
}
} catch (IOException e) {
Log.e(Constants.TAG, "error importing public", e);
log.add(LogType.MSG_CON_ERROR_PUBLIC, indent);
return new ConsolidateResult(ConsolidateResult.RESULT_ERROR, log);
} finally {
indent -= 1;
}
log.add(LogType.MSG_CON_CRITICAL_OUT, indent);
Preferences.getPreferences(mContext).setCachedConsolidate(false);
// 5. Delete caches
try {
log.add(LogType.MSG_CON_DELETE_SECRET, indent);
indent += 1;
cacheSecret.delete();
} catch (IOException e) {
// doesn't /really/ matter
Log.e(Constants.TAG, "IOException during delete of secret cache", e);
log.add(LogType.MSG_CON_WARN_DELETE_SECRET, indent);
} finally {
indent -= 1;
}
try {
log.add(LogType.MSG_CON_DELETE_PUBLIC, indent);
indent += 1;
cachePublic.delete();
} catch (IOException e) {
// doesn't /really/ matter
Log.e(Constants.TAG, "IOException during deletion of public cache", e);
log.add(LogType.MSG_CON_WARN_DELETE_PUBLIC, indent);
} finally {
indent -= 1;
}
progress.setProgress(100, 100);
log.add(LogType.MSG_CON_SUCCESS, indent);
return new ConsolidateResult(ConsolidateResult.RESULT_OK, log);
} finally {
mConsolidateCritical = false;
}
}
/**
* Build ContentProviderOperation to add PGPPublicKey to database corresponding to a keyRing
*/

View File

@@ -25,7 +25,6 @@ import java.io.FileOutputStream;
import java.io.IOException;
import android.content.Context;
import android.content.Intent;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
import android.database.sqlite.SQLiteOpenHelper;
@@ -42,7 +41,6 @@ import org.sufficientlysecure.keychain.provider.KeychainContract.KeysColumns;
import org.sufficientlysecure.keychain.provider.KeychainContract.OverriddenWarnings;
import org.sufficientlysecure.keychain.provider.KeychainContract.UpdatedKeysColumns;
import org.sufficientlysecure.keychain.provider.KeychainContract.UserPacketsColumns;
import org.sufficientlysecure.keychain.ui.ConsolidateDialogActivity;
import org.sufficientlysecure.keychain.util.Log;
/**
@@ -406,19 +404,7 @@ public class KeychainDatabase extends SQLiteOpenHelper {
+ "PRIMARY KEY(master_key_id, signer_key_id), "
+ "FOREIGN KEY(master_key_id) REFERENCES keyrings_public(master_key_id) ON DELETE CASCADE"
+ ")");
if (oldVersion == 18 || oldVersion == 19 || oldVersion == 20 || oldVersion == 21 || oldVersion == 22 ||
oldVersion == 23) {
return;
}
}
// TODO: don't depend on consolidate! make migrations inline!
// 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);
}
@Override

View File

@@ -1,35 +0,0 @@
/*
* Copyright (C) 2015 Dominik Schürmann <dominik@dominikschuermann.de>
* Copyright (C) 2015 Vincent Breitmoser <v.breitmoser@mugenguild.com>
* Copyright (C) 2015 Adithya Abraham Philip <adithyaphilip@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.sufficientlysecure.keychain.service;
import android.os.Parcelable;
import com.google.auto.value.AutoValue;
@AutoValue
public abstract class ConsolidateInputParcel implements Parcelable {
public abstract boolean isStartFromRecovery();
public static ConsolidateInputParcel createConsolidateInputParcel(boolean consolidateRecovery) {
return new AutoValue_ConsolidateInputParcel(consolidateRecovery);
}
}

View File

@@ -18,6 +18,9 @@
package org.sufficientlysecure.keychain.service;
import java.util.concurrent.atomic.AtomicBoolean;
import android.app.Service;
import android.content.Intent;
import android.os.Bundle;
@@ -28,24 +31,23 @@ import android.os.Parcelable;
import android.os.RemoteException;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.operations.BackupOperation;
import org.sufficientlysecure.keychain.operations.BaseOperation;
import org.sufficientlysecure.keychain.operations.BenchmarkOperation;
import org.sufficientlysecure.keychain.operations.CertifyOperation;
import org.sufficientlysecure.keychain.operations.ConsolidateOperation;
import org.sufficientlysecure.keychain.operations.ChangeUnlockOperation;
import org.sufficientlysecure.keychain.operations.DeleteOperation;
import org.sufficientlysecure.keychain.operations.EditKeyOperation;
import org.sufficientlysecure.keychain.operations.BackupOperation;
import org.sufficientlysecure.keychain.operations.ImportOperation;
import org.sufficientlysecure.keychain.operations.KeybaseVerificationOperation;
import org.sufficientlysecure.keychain.operations.InputDataOperation;
import org.sufficientlysecure.keychain.operations.ChangeUnlockOperation;
import org.sufficientlysecure.keychain.operations.KeybaseVerificationOperation;
import org.sufficientlysecure.keychain.operations.PromoteKeyOperation;
import org.sufficientlysecure.keychain.operations.RevokeOperation;
import org.sufficientlysecure.keychain.operations.SignEncryptOperation;
import org.sufficientlysecure.keychain.operations.UploadOperation;
import org.sufficientlysecure.keychain.operations.results.OperationResult;
import org.sufficientlysecure.keychain.pgp.PgpDecryptVerifyOperation;
import org.sufficientlysecure.keychain.pgp.PgpDecryptVerifyInputParcel;
import org.sufficientlysecure.keychain.pgp.PgpDecryptVerifyOperation;
import org.sufficientlysecure.keychain.pgp.Progressable;
import org.sufficientlysecure.keychain.pgp.SignEncryptParcel;
import org.sufficientlysecure.keychain.provider.KeyWritableRepository;
@@ -53,8 +55,6 @@ import org.sufficientlysecure.keychain.service.ServiceProgressHandler.MessageSta
import org.sufficientlysecure.keychain.service.input.CryptoInputParcel;
import org.sufficientlysecure.keychain.util.Log;
import java.util.concurrent.atomic.AtomicBoolean;
/**
* This Service contains all important long lasting operations for OpenKeychain. It receives Intents with
* data from the activities or other apps, executes them, and stops itself after doing them.
@@ -135,8 +135,6 @@ public class KeychainService extends Service implements Progressable {
op = new BackupOperation(outerThis, databaseInteractor, outerThis, mActionCanceled);
} else if (inputParcel instanceof UploadKeyringParcel) {
op = new UploadOperation(outerThis, databaseInteractor, outerThis, mActionCanceled);
} else if (inputParcel instanceof ConsolidateInputParcel) {
op = new ConsolidateOperation(outerThis, databaseInteractor, outerThis);
} else if (inputParcel instanceof KeybaseVerificationParcel) {
op = new KeybaseVerificationOperation(outerThis, databaseInteractor, outerThis);
} else if (inputParcel instanceof InputDataParcel) {

View File

@@ -1,94 +0,0 @@
/*
* Copyright (C) 2014 Dominik Schürmann <dominik@dominikschuermann.de>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.sufficientlysecure.keychain.ui;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.operations.results.ConsolidateResult;
import org.sufficientlysecure.keychain.service.ConsolidateInputParcel;
import org.sufficientlysecure.keychain.ui.base.CryptoOperationHelper;
/**
* We can not directly create a dialog on the application context.
* This activity encapsulates a DialogFragment to emulate a dialog.
*/
public class ConsolidateDialogActivity extends FragmentActivity
implements CryptoOperationHelper.Callback<ConsolidateInputParcel, ConsolidateResult> {
public static final String EXTRA_CONSOLIDATE_RECOVERY = "consolidate_recovery";
private CryptoOperationHelper<ConsolidateInputParcel, ConsolidateResult> mConsolidateOpHelper;
private boolean mRecovery;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// this activity itself has no content view (see manifest)
boolean recovery = getIntent().getBooleanExtra(EXTRA_CONSOLIDATE_RECOVERY, false);
consolidateRecovery(recovery);
}
private void consolidateRecovery(boolean recovery) {
mRecovery = recovery;
mConsolidateOpHelper = new CryptoOperationHelper<>(1, this, this, R.string.progress_importing);
mConsolidateOpHelper.cryptoOperation();
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (mConsolidateOpHelper != null) {
mConsolidateOpHelper.handleActivityResult(requestCode, resultCode, data);
}
}
@Override
public ConsolidateInputParcel createOperationInput() {
return ConsolidateInputParcel.createConsolidateInputParcel(mRecovery);
}
@Override
public void onCryptoOperationSuccess(ConsolidateResult result) {
// don't care about result (for now?)
ConsolidateDialogActivity.this.finish();
}
@Override
public void onCryptoOperationCancelled() {
}
@Override
public void onCryptoOperationError(ConsolidateResult result) {
// don't care about result (for now?)
ConsolidateDialogActivity.this.finish();
}
@Override
public boolean onCryptoSetProgress(String msg, int progress, int max) {
return false;
}
}

View File

@@ -19,6 +19,10 @@
package org.sufficientlysecure.keychain.ui;
import java.io.IOException;
import java.util.ArrayList;
import android.animation.ObjectAnimator;
import android.app.Activity;
import android.content.Intent;
@@ -47,34 +51,28 @@ import com.futuremind.recyclerviewfastscroll.FastScroller;
import com.getbase.floatingactionbutton.FloatingActionButton;
import com.getbase.floatingactionbutton.FloatingActionsMenu;
import com.tonicartos.superslim.LayoutManager;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.keyimport.HkpKeyserverAddress;
import org.sufficientlysecure.keychain.keyimport.ParcelableKeyRing;
import org.sufficientlysecure.keychain.operations.results.BenchmarkResult;
import org.sufficientlysecure.keychain.operations.results.ConsolidateResult;
import org.sufficientlysecure.keychain.operations.results.ImportKeyResult;
import org.sufficientlysecure.keychain.operations.results.OperationResult;
import org.sufficientlysecure.keychain.provider.KeyRepository;
import org.sufficientlysecure.keychain.provider.KeychainContract;
import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
import org.sufficientlysecure.keychain.provider.KeychainDatabase;
import org.sufficientlysecure.keychain.provider.KeyRepository;
import org.sufficientlysecure.keychain.service.BenchmarkInputParcel;
import org.sufficientlysecure.keychain.service.ConsolidateInputParcel;
import org.sufficientlysecure.keychain.service.ImportKeyringParcel;
import org.sufficientlysecure.keychain.ui.adapter.KeySectionedListAdapter;
import org.sufficientlysecure.keychain.ui.base.CryptoOperationHelper;
import org.sufficientlysecure.keychain.ui.base.RecyclerFragment;
import org.sufficientlysecure.keychain.ui.keyview.ViewKeyActivity;
import org.sufficientlysecure.keychain.ui.util.Notify;
import org.sufficientlysecure.keychain.ui.base.RecyclerFragment;
import org.sufficientlysecure.keychain.util.FabContainer;
import org.sufficientlysecure.keychain.util.Log;
import org.sufficientlysecure.keychain.util.Preferences;
import java.io.IOException;
import java.util.ArrayList;
public class KeyListFragment extends RecyclerFragment<KeySectionedListAdapter>
implements SearchView.OnQueryTextListener,
LoaderManager.LoaderCallbacks<Cursor>, FabContainer {
@@ -97,9 +95,6 @@ public class KeyListFragment extends RecyclerFragment<KeySectionedListAdapter>
private HkpKeyserverAddress mKeyserver;
private CryptoOperationHelper<ImportKeyringParcel, ImportKeyResult> mImportOpHelper;
// for ConsolidateOperation
private CryptoOperationHelper<ConsolidateInputParcel, ConsolidateResult> mConsolidateOpHelper;
// Callbacks related to listview and menu events
private final ActionMode.Callback mActionCallback
= new ActionMode.Callback() {
@@ -334,7 +329,6 @@ public class KeyListFragment extends RecyclerFragment<KeySectionedListAdapter>
inflater.inflate(R.menu.key_list, menu);
if (Constants.DEBUG) {
menu.findItem(R.id.menu_key_list_debug_cons).setVisible(true);
menu.findItem(R.id.menu_key_list_debug_bench).setVisible(true);
menu.findItem(R.id.menu_key_list_debug_read).setVisible(true);
menu.findItem(R.id.menu_key_list_debug_write).setVisible(true);
@@ -413,10 +407,6 @@ public class KeyListFragment extends RecyclerFragment<KeySectionedListAdapter>
getActivity().finish();
return true;
}
case R.id.menu_key_list_debug_cons: {
consolidate();
return true;
}
case R.id.menu_key_list_debug_bench: {
benchmark();
return true;
@@ -547,39 +537,6 @@ public class KeyListFragment extends RecyclerFragment<KeySectionedListAdapter>
mImportOpHelper.cryptoOperation();
}
private void consolidate() {
CryptoOperationHelper.Callback<ConsolidateInputParcel, ConsolidateResult> callback
= new CryptoOperationHelper.Callback<ConsolidateInputParcel, ConsolidateResult>() {
@Override
public ConsolidateInputParcel createOperationInput() {
return ConsolidateInputParcel.createConsolidateInputParcel(false); // we want to perform a full consolidate
}
@Override
public void onCryptoOperationSuccess(ConsolidateResult result) {
result.createNotify(getActivity()).show();
}
@Override
public void onCryptoOperationCancelled() {
}
@Override
public void onCryptoOperationError(ConsolidateResult result) {
result.createNotify(getActivity()).show();
}
@Override
public boolean onCryptoSetProgress(String msg, int progress, int max) {
return false;
}
};
mConsolidateOpHelper = new CryptoOperationHelper<>(2, this, callback, R.string.progress_importing);
mConsolidateOpHelper.cryptoOperation();
}
private void benchmark() {
CryptoOperationHelper.Callback<BenchmarkInputParcel, BenchmarkResult> callback
= new CryptoOperationHelper.Callback<BenchmarkInputParcel, BenchmarkResult>() {
@@ -619,10 +576,6 @@ public class KeyListFragment extends RecyclerFragment<KeySectionedListAdapter>
mImportOpHelper.handleActivityResult(requestCode, resultCode, data);
}
if (mConsolidateOpHelper != null) {
mConsolidateOpHelper.handleActivityResult(requestCode, resultCode, data);
}
switch (requestCode) {
case REQUEST_DELETE: {
if (mActionMode != null) {

View File

@@ -52,10 +52,6 @@ public class ParcelableFileCache<E extends Parcelable> {
mFilename = filename;
}
public static boolean cacheFileExists(Context context, String filename) {
return new File(context.getCacheDir(), filename).exists();
}
public void writeCache(int numEntries, Iterator<E> it) throws IOException {
DataOutputStream oos = getOutputStream();

View File

@@ -19,12 +19,6 @@
android:title="@string/menu_update_all_keys"
app:showAsAction="never" />
<item
android:id="@+id/menu_key_list_debug_cons"
android:title="Debug / Consolidate"
android:visible="false"
app:showAsAction="never" />
<item
android:id="@+id/menu_key_list_debug_bench"
android:title="Debug / Benchmark"

View File

@@ -1146,39 +1146,6 @@
<string name="msg_mf_unlock_error">"Error unlocking keyring!"</string>
<string name="msg_mf_unlock">"Unlocking keyring"</string>
<!-- Consolidate -->
<string name="msg_con">"Consolidating database"</string>
<string name="msg_con_error_bad_state">"Consolidation was started while no database was cached! This is probably a programming error, please file a bug report."</string>
<string name="msg_con_error_concurrent">"Consolidation aborted, already running on other thread!"</string>
<string name="msg_con_save_secret">"Saving secret keyrings"</string>
<string name="msg_con_save_public">"Saving public keyrings"</string>
<string name="msg_con_db_clear">"Clearing database"</string>
<string name="msg_con_success">"Successfully consolidated database"</string>
<string name="msg_con_critical_in">"Entering critical phase"</string>
<string name="msg_con_critical_out">"Leaving critical phase"</string>
<string name="msg_con_delete_public">"Deleting public keyring cache file"</string>
<string name="msg_con_delete_secret">"Deleting secret keyring cache file"</string>
<string name="msg_con_error_db">"Error opening database!"</string>
<string name="msg_con_error_io_public">"IO error writing public keys to cache!"</string>
<string name="msg_con_error_io_secret">"IO error writing secret keys to cache!"</string>
<string name="msg_con_error_public">"Error reimporting public keys!"</string>
<string name="msg_con_error_secret">"Error reimporting secret keys!"</string>
<string name="msg_con_recover">"Resuming consolidation process"</string>
<string name="msg_con_recursive">"Skipping recursive consolidation"</string>
<string name="msg_con_recover_unknown">"Resuming consolidation process from unknown state"</string>
<plurals name="msg_con_reimport_public">
<item quantity="one">"Reimporting one public key"</item>
<item quantity="other">"Reimporting %d public keys"</item>
</plurals>
<string name="msg_con_reimport_public_skip">"No public keys to reimport, skipping…"</string>
<plurals name="msg_con_reimport_secret">
<item quantity="one">"Reimporting one secret key"</item>
<item quantity="other">"Reimporting %d secret keys"</item>
</plurals>
<string name="msg_con_reimport_secret_skip">"No secret keys to reimport, skipping…"</string>
<string name="msg_con_warn_delete_public">"Exception deleting public cache file"</string>
<string name="msg_con_warn_delete_secret">"Exception deleting secret cache file"</string>
<!-- Edit Key (higher level than modify) -->
<string name="msg_ed">"Performing key operation"</string>
<string name="msg_ed_caching_new">"Caching new password"</string>