get rid of consolidate operation
This commit is contained in:
@@ -772,9 +772,6 @@
|
|||||||
android:name=".ui.LogDisplayActivity"
|
android:name=".ui.LogDisplayActivity"
|
||||||
android:configChanges="orientation|screenSize|keyboardHidden|keyboard"
|
android:configChanges="orientation|screenSize|keyboardHidden|keyboard"
|
||||||
android:label="@string/title_log_display" />
|
android:label="@string/title_log_display" />
|
||||||
<activity
|
|
||||||
android:name=".ui.ConsolidateDialogActivity"
|
|
||||||
android:theme="@style/Theme.Keychain.Transparent" />
|
|
||||||
<activity
|
<activity
|
||||||
android:name=".ui.PassphraseDialogActivity"
|
android:name=".ui.PassphraseDialogActivity"
|
||||||
android:theme="@style/Theme.Keychain.Transparent" />
|
android:theme="@style/Theme.Keychain.Transparent" />
|
||||||
|
|||||||
@@ -17,11 +17,14 @@
|
|||||||
|
|
||||||
package org.sufficientlysecure.keychain;
|
package org.sufficientlysecure.keychain;
|
||||||
|
|
||||||
|
|
||||||
|
import java.security.Security;
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
import android.accounts.Account;
|
import android.accounts.Account;
|
||||||
import android.accounts.AccountManager;
|
import android.accounts.AccountManager;
|
||||||
import android.app.Application;
|
import android.app.Application;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
|
||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
import android.graphics.PorterDuff;
|
import android.graphics.PorterDuff;
|
||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
@@ -31,19 +34,15 @@ import android.support.annotation.Nullable;
|
|||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
import org.bouncycastle.jce.provider.BouncyCastleProvider;
|
import org.bouncycastle.jce.provider.BouncyCastleProvider;
|
||||||
|
import org.sufficientlysecure.keychain.network.TlsCertificatePinning;
|
||||||
import org.sufficientlysecure.keychain.provider.KeychainDatabase;
|
import org.sufficientlysecure.keychain.provider.KeychainDatabase;
|
||||||
import org.sufficientlysecure.keychain.provider.TemporaryFileProvider;
|
import org.sufficientlysecure.keychain.provider.TemporaryFileProvider;
|
||||||
import org.sufficientlysecure.keychain.service.ContactSyncAdapterService;
|
import org.sufficientlysecure.keychain.service.ContactSyncAdapterService;
|
||||||
import org.sufficientlysecure.keychain.service.KeyserverSyncAdapterService;
|
import org.sufficientlysecure.keychain.service.KeyserverSyncAdapterService;
|
||||||
import org.sufficientlysecure.keychain.ui.ConsolidateDialogActivity;
|
|
||||||
import org.sufficientlysecure.keychain.ui.util.FormattingUtils;
|
import org.sufficientlysecure.keychain.ui.util.FormattingUtils;
|
||||||
import org.sufficientlysecure.keychain.util.Log;
|
import org.sufficientlysecure.keychain.util.Log;
|
||||||
import org.sufficientlysecure.keychain.util.PRNGFixes;
|
import org.sufficientlysecure.keychain.util.PRNGFixes;
|
||||||
import org.sufficientlysecure.keychain.util.Preferences;
|
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 {
|
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");
|
TlsCertificatePinning.addPinnedCertificate("api.keybase.io", getAssets(), "api.keybase.io.CA.cer");
|
||||||
|
|
||||||
TemporaryFileProvider.cleanUp(this);
|
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) {
|
static void brandGlowEffect(Context context, int brandColor) {
|
||||||
// no hack on Android 5
|
// no hack on Android 5
|
||||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
|
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
|
||||||
|
|||||||
@@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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_ERROR (LogLevel.ERROR, R.string.msg_mf_unlock_error),
|
||||||
MSG_MF_UNLOCK (LogLevel.DEBUG, R.string.msg_mf_unlock),
|
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)
|
// edit key (higher level operation than modify)
|
||||||
MSG_ED (LogLevel.START, R.string.msg_ed),
|
MSG_ED (LogLevel.START, R.string.msg_ed),
|
||||||
MSG_ED_CACHING_NEW (LogLevel.DEBUG, R.string.msg_ed_caching_new),
|
MSG_ED_CACHING_NEW (LogLevel.DEBUG, R.string.msg_ed_caching_new),
|
||||||
|
|||||||
@@ -25,7 +25,6 @@ import java.util.Arrays;
|
|||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.GregorianCalendar;
|
import java.util.GregorianCalendar;
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import android.content.ContentProviderOperation;
|
import android.content.ContentProviderOperation;
|
||||||
@@ -41,11 +40,6 @@ import android.support.v4.util.LongSparseArray;
|
|||||||
|
|
||||||
import org.openintents.openpgp.util.OpenPgpUtils;
|
import org.openintents.openpgp.util.OpenPgpUtils;
|
||||||
import org.sufficientlysecure.keychain.Constants;
|
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.LogType;
|
||||||
import org.sufficientlysecure.keychain.operations.results.OperationResult.OperationLog;
|
import org.sufficientlysecure.keychain.operations.results.OperationResult.OperationLog;
|
||||||
import org.sufficientlysecure.keychain.operations.results.SaveKeyringResult;
|
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.provider.KeychainContract.UserPackets;
|
||||||
import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
|
import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
|
||||||
import org.sufficientlysecure.keychain.util.IterableIterator;
|
import org.sufficientlysecure.keychain.util.IterableIterator;
|
||||||
import org.sufficientlysecure.keychain.util.IteratorWithSize;
|
|
||||||
import org.sufficientlysecure.keychain.util.Log;
|
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;
|
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
|
* Build ContentProviderOperation to add PGPPublicKey to database corresponding to a keyRing
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -25,7 +25,6 @@ import java.io.FileOutputStream;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
|
||||||
import android.database.sqlite.SQLiteDatabase;
|
import android.database.sqlite.SQLiteDatabase;
|
||||||
import android.database.sqlite.SQLiteException;
|
import android.database.sqlite.SQLiteException;
|
||||||
import android.database.sqlite.SQLiteOpenHelper;
|
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.OverriddenWarnings;
|
||||||
import org.sufficientlysecure.keychain.provider.KeychainContract.UpdatedKeysColumns;
|
import org.sufficientlysecure.keychain.provider.KeychainContract.UpdatedKeysColumns;
|
||||||
import org.sufficientlysecure.keychain.provider.KeychainContract.UserPacketsColumns;
|
import org.sufficientlysecure.keychain.provider.KeychainContract.UserPacketsColumns;
|
||||||
import org.sufficientlysecure.keychain.ui.ConsolidateDialogActivity;
|
|
||||||
import org.sufficientlysecure.keychain.util.Log;
|
import org.sufficientlysecure.keychain.util.Log;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -406,19 +404,7 @@ public class KeychainDatabase extends SQLiteOpenHelper {
|
|||||||
+ "PRIMARY KEY(master_key_id, signer_key_id), "
|
+ "PRIMARY KEY(master_key_id, signer_key_id), "
|
||||||
+ "FOREIGN KEY(master_key_id) REFERENCES keyrings_public(master_key_id) ON DELETE CASCADE"
|
+ "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
|
@Override
|
||||||
|
|||||||
@@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -18,6 +18,9 @@
|
|||||||
|
|
||||||
package org.sufficientlysecure.keychain.service;
|
package org.sufficientlysecure.keychain.service;
|
||||||
|
|
||||||
|
|
||||||
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
import android.app.Service;
|
import android.app.Service;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
@@ -28,24 +31,23 @@ import android.os.Parcelable;
|
|||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
|
|
||||||
import org.sufficientlysecure.keychain.Constants;
|
import org.sufficientlysecure.keychain.Constants;
|
||||||
|
import org.sufficientlysecure.keychain.operations.BackupOperation;
|
||||||
import org.sufficientlysecure.keychain.operations.BaseOperation;
|
import org.sufficientlysecure.keychain.operations.BaseOperation;
|
||||||
import org.sufficientlysecure.keychain.operations.BenchmarkOperation;
|
import org.sufficientlysecure.keychain.operations.BenchmarkOperation;
|
||||||
import org.sufficientlysecure.keychain.operations.CertifyOperation;
|
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.DeleteOperation;
|
||||||
import org.sufficientlysecure.keychain.operations.EditKeyOperation;
|
import org.sufficientlysecure.keychain.operations.EditKeyOperation;
|
||||||
import org.sufficientlysecure.keychain.operations.BackupOperation;
|
|
||||||
import org.sufficientlysecure.keychain.operations.ImportOperation;
|
import org.sufficientlysecure.keychain.operations.ImportOperation;
|
||||||
import org.sufficientlysecure.keychain.operations.KeybaseVerificationOperation;
|
|
||||||
import org.sufficientlysecure.keychain.operations.InputDataOperation;
|
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.PromoteKeyOperation;
|
||||||
import org.sufficientlysecure.keychain.operations.RevokeOperation;
|
import org.sufficientlysecure.keychain.operations.RevokeOperation;
|
||||||
import org.sufficientlysecure.keychain.operations.SignEncryptOperation;
|
import org.sufficientlysecure.keychain.operations.SignEncryptOperation;
|
||||||
import org.sufficientlysecure.keychain.operations.UploadOperation;
|
import org.sufficientlysecure.keychain.operations.UploadOperation;
|
||||||
import org.sufficientlysecure.keychain.operations.results.OperationResult;
|
import org.sufficientlysecure.keychain.operations.results.OperationResult;
|
||||||
import org.sufficientlysecure.keychain.pgp.PgpDecryptVerifyOperation;
|
|
||||||
import org.sufficientlysecure.keychain.pgp.PgpDecryptVerifyInputParcel;
|
import org.sufficientlysecure.keychain.pgp.PgpDecryptVerifyInputParcel;
|
||||||
|
import org.sufficientlysecure.keychain.pgp.PgpDecryptVerifyOperation;
|
||||||
import org.sufficientlysecure.keychain.pgp.Progressable;
|
import org.sufficientlysecure.keychain.pgp.Progressable;
|
||||||
import org.sufficientlysecure.keychain.pgp.SignEncryptParcel;
|
import org.sufficientlysecure.keychain.pgp.SignEncryptParcel;
|
||||||
import org.sufficientlysecure.keychain.provider.KeyWritableRepository;
|
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.service.input.CryptoInputParcel;
|
||||||
import org.sufficientlysecure.keychain.util.Log;
|
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
|
* 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.
|
* 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);
|
op = new BackupOperation(outerThis, databaseInteractor, outerThis, mActionCanceled);
|
||||||
} else if (inputParcel instanceof UploadKeyringParcel) {
|
} else if (inputParcel instanceof UploadKeyringParcel) {
|
||||||
op = new UploadOperation(outerThis, databaseInteractor, outerThis, mActionCanceled);
|
op = new UploadOperation(outerThis, databaseInteractor, outerThis, mActionCanceled);
|
||||||
} else if (inputParcel instanceof ConsolidateInputParcel) {
|
|
||||||
op = new ConsolidateOperation(outerThis, databaseInteractor, outerThis);
|
|
||||||
} else if (inputParcel instanceof KeybaseVerificationParcel) {
|
} else if (inputParcel instanceof KeybaseVerificationParcel) {
|
||||||
op = new KeybaseVerificationOperation(outerThis, databaseInteractor, outerThis);
|
op = new KeybaseVerificationOperation(outerThis, databaseInteractor, outerThis);
|
||||||
} else if (inputParcel instanceof InputDataParcel) {
|
} else if (inputParcel instanceof InputDataParcel) {
|
||||||
|
|||||||
@@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -19,6 +19,10 @@
|
|||||||
|
|
||||||
package org.sufficientlysecure.keychain.ui;
|
package org.sufficientlysecure.keychain.ui;
|
||||||
|
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
import android.animation.ObjectAnimator;
|
import android.animation.ObjectAnimator;
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
@@ -47,34 +51,28 @@ import com.futuremind.recyclerviewfastscroll.FastScroller;
|
|||||||
import com.getbase.floatingactionbutton.FloatingActionButton;
|
import com.getbase.floatingactionbutton.FloatingActionButton;
|
||||||
import com.getbase.floatingactionbutton.FloatingActionsMenu;
|
import com.getbase.floatingactionbutton.FloatingActionsMenu;
|
||||||
import com.tonicartos.superslim.LayoutManager;
|
import com.tonicartos.superslim.LayoutManager;
|
||||||
|
|
||||||
import org.sufficientlysecure.keychain.Constants;
|
import org.sufficientlysecure.keychain.Constants;
|
||||||
import org.sufficientlysecure.keychain.R;
|
import org.sufficientlysecure.keychain.R;
|
||||||
import org.sufficientlysecure.keychain.keyimport.HkpKeyserverAddress;
|
import org.sufficientlysecure.keychain.keyimport.HkpKeyserverAddress;
|
||||||
import org.sufficientlysecure.keychain.keyimport.ParcelableKeyRing;
|
import org.sufficientlysecure.keychain.keyimport.ParcelableKeyRing;
|
||||||
import org.sufficientlysecure.keychain.operations.results.BenchmarkResult;
|
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.ImportKeyResult;
|
||||||
import org.sufficientlysecure.keychain.operations.results.OperationResult;
|
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;
|
||||||
import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
|
import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
|
||||||
import org.sufficientlysecure.keychain.provider.KeychainDatabase;
|
import org.sufficientlysecure.keychain.provider.KeychainDatabase;
|
||||||
import org.sufficientlysecure.keychain.provider.KeyRepository;
|
|
||||||
import org.sufficientlysecure.keychain.service.BenchmarkInputParcel;
|
import org.sufficientlysecure.keychain.service.BenchmarkInputParcel;
|
||||||
import org.sufficientlysecure.keychain.service.ConsolidateInputParcel;
|
|
||||||
import org.sufficientlysecure.keychain.service.ImportKeyringParcel;
|
import org.sufficientlysecure.keychain.service.ImportKeyringParcel;
|
||||||
import org.sufficientlysecure.keychain.ui.adapter.KeySectionedListAdapter;
|
import org.sufficientlysecure.keychain.ui.adapter.KeySectionedListAdapter;
|
||||||
import org.sufficientlysecure.keychain.ui.base.CryptoOperationHelper;
|
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.keyview.ViewKeyActivity;
|
||||||
import org.sufficientlysecure.keychain.ui.util.Notify;
|
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.FabContainer;
|
||||||
import org.sufficientlysecure.keychain.util.Log;
|
import org.sufficientlysecure.keychain.util.Log;
|
||||||
import org.sufficientlysecure.keychain.util.Preferences;
|
import org.sufficientlysecure.keychain.util.Preferences;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
|
|
||||||
public class KeyListFragment extends RecyclerFragment<KeySectionedListAdapter>
|
public class KeyListFragment extends RecyclerFragment<KeySectionedListAdapter>
|
||||||
implements SearchView.OnQueryTextListener,
|
implements SearchView.OnQueryTextListener,
|
||||||
LoaderManager.LoaderCallbacks<Cursor>, FabContainer {
|
LoaderManager.LoaderCallbacks<Cursor>, FabContainer {
|
||||||
@@ -97,9 +95,6 @@ public class KeyListFragment extends RecyclerFragment<KeySectionedListAdapter>
|
|||||||
private HkpKeyserverAddress mKeyserver;
|
private HkpKeyserverAddress mKeyserver;
|
||||||
private CryptoOperationHelper<ImportKeyringParcel, ImportKeyResult> mImportOpHelper;
|
private CryptoOperationHelper<ImportKeyringParcel, ImportKeyResult> mImportOpHelper;
|
||||||
|
|
||||||
// for ConsolidateOperation
|
|
||||||
private CryptoOperationHelper<ConsolidateInputParcel, ConsolidateResult> mConsolidateOpHelper;
|
|
||||||
|
|
||||||
// Callbacks related to listview and menu events
|
// Callbacks related to listview and menu events
|
||||||
private final ActionMode.Callback mActionCallback
|
private final ActionMode.Callback mActionCallback
|
||||||
= new ActionMode.Callback() {
|
= new ActionMode.Callback() {
|
||||||
@@ -334,7 +329,6 @@ public class KeyListFragment extends RecyclerFragment<KeySectionedListAdapter>
|
|||||||
inflater.inflate(R.menu.key_list, menu);
|
inflater.inflate(R.menu.key_list, menu);
|
||||||
|
|
||||||
if (Constants.DEBUG) {
|
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_bench).setVisible(true);
|
||||||
menu.findItem(R.id.menu_key_list_debug_read).setVisible(true);
|
menu.findItem(R.id.menu_key_list_debug_read).setVisible(true);
|
||||||
menu.findItem(R.id.menu_key_list_debug_write).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();
|
getActivity().finish();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
case R.id.menu_key_list_debug_cons: {
|
|
||||||
consolidate();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
case R.id.menu_key_list_debug_bench: {
|
case R.id.menu_key_list_debug_bench: {
|
||||||
benchmark();
|
benchmark();
|
||||||
return true;
|
return true;
|
||||||
@@ -547,39 +537,6 @@ public class KeyListFragment extends RecyclerFragment<KeySectionedListAdapter>
|
|||||||
mImportOpHelper.cryptoOperation();
|
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() {
|
private void benchmark() {
|
||||||
CryptoOperationHelper.Callback<BenchmarkInputParcel, BenchmarkResult> callback
|
CryptoOperationHelper.Callback<BenchmarkInputParcel, BenchmarkResult> callback
|
||||||
= new CryptoOperationHelper.Callback<BenchmarkInputParcel, BenchmarkResult>() {
|
= new CryptoOperationHelper.Callback<BenchmarkInputParcel, BenchmarkResult>() {
|
||||||
@@ -619,10 +576,6 @@ public class KeyListFragment extends RecyclerFragment<KeySectionedListAdapter>
|
|||||||
mImportOpHelper.handleActivityResult(requestCode, resultCode, data);
|
mImportOpHelper.handleActivityResult(requestCode, resultCode, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mConsolidateOpHelper != null) {
|
|
||||||
mConsolidateOpHelper.handleActivityResult(requestCode, resultCode, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (requestCode) {
|
switch (requestCode) {
|
||||||
case REQUEST_DELETE: {
|
case REQUEST_DELETE: {
|
||||||
if (mActionMode != null) {
|
if (mActionMode != null) {
|
||||||
|
|||||||
@@ -52,10 +52,6 @@ public class ParcelableFileCache<E extends Parcelable> {
|
|||||||
mFilename = filename;
|
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 {
|
public void writeCache(int numEntries, Iterator<E> it) throws IOException {
|
||||||
DataOutputStream oos = getOutputStream();
|
DataOutputStream oos = getOutputStream();
|
||||||
|
|
||||||
|
|||||||
@@ -19,12 +19,6 @@
|
|||||||
android:title="@string/menu_update_all_keys"
|
android:title="@string/menu_update_all_keys"
|
||||||
app:showAsAction="never" />
|
app:showAsAction="never" />
|
||||||
|
|
||||||
<item
|
|
||||||
android:id="@+id/menu_key_list_debug_cons"
|
|
||||||
android:title="Debug / Consolidate"
|
|
||||||
android:visible="false"
|
|
||||||
app:showAsAction="never" />
|
|
||||||
|
|
||||||
<item
|
<item
|
||||||
android:id="@+id/menu_key_list_debug_bench"
|
android:id="@+id/menu_key_list_debug_bench"
|
||||||
android:title="Debug / Benchmark"
|
android:title="Debug / Benchmark"
|
||||||
|
|||||||
@@ -1146,39 +1146,6 @@
|
|||||||
<string name="msg_mf_unlock_error">"Error unlocking keyring!"</string>
|
<string name="msg_mf_unlock_error">"Error unlocking keyring!"</string>
|
||||||
<string name="msg_mf_unlock">"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) -->
|
<!-- Edit Key (higher level than modify) -->
|
||||||
<string name="msg_ed">"Performing key operation"</string>
|
<string name="msg_ed">"Performing key operation"</string>
|
||||||
<string name="msg_ed_caching_new">"Caching new password"</string>
|
<string name="msg_ed_caching_new">"Caching new password"</string>
|
||||||
|
|||||||
Reference in New Issue
Block a user