mirror of
https://github.com/moparisthebest/open-keychain
synced 2024-12-24 07:58:50 -05:00
Merge branch 'master' into v/multi-decrypt
this also fixes weird-bug Conflicts: OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFilesFragment.java OpenKeychain/src/main/res/values/strings.xml
This commit is contained in:
commit
b779211f55
@ -1 +1 @@
|
||||
Please go to https://github.com/open-keychain/open-keychain/blob/development/OpenKeychain/src/main/res/raw/help_changelog.md
|
||||
Please go to https://github.com/open-keychain/open-keychain/blob/HEAD/OpenKeychain/src/main/res/raw/help_changelog.md
|
@ -719,7 +719,7 @@
|
||||
android:exported="false"
|
||||
android:process=":remote_api" />
|
||||
<service
|
||||
android:name=".service.KeychainIntentService"
|
||||
android:name=".service.KeychainService"
|
||||
android:exported="false" />
|
||||
<service
|
||||
android:name=".service.CloudImportService"
|
||||
|
@ -84,6 +84,10 @@ public final class Constants {
|
||||
public static final String SEARCH_KEYBASE = "search_keybase_pref";
|
||||
public static final String USE_DEFAULT_YUBIKEY_PIN = "useDefaultYubikeyPin";
|
||||
public static final String USE_NUMKEYPAD_FOR_YUBIKEY_PIN = "useNumKeypadForYubikeyPin";
|
||||
public static final String ENCRYPT_FILENAMES = "encryptFilenames";
|
||||
public static final String FILE_USE_COMPRESSION = "useFileCompression";
|
||||
public static final String TEXT_USE_COMPRESSION = "useTextCompression";
|
||||
public static final String USE_ARMOR = "useArmor";
|
||||
}
|
||||
|
||||
public static final class Defaults {
|
||||
|
@ -40,7 +40,7 @@ public abstract class BaseOperation implements PassphraseCacheInterface {
|
||||
* of common methods for progress, cancellation and passphrase cache handling.
|
||||
*
|
||||
* An "operation" in this sense is a high level operation which is called
|
||||
* by the KeychainIntentService or OpenPgpService services. Concrete
|
||||
* by the KeychainService or OpenPgpService services. Concrete
|
||||
* subclasses of this class should implement either a single or a group of
|
||||
* related operations. An operation must rely solely on its input
|
||||
* parameters for operation specifics. It should also write a log of its
|
||||
@ -49,7 +49,7 @@ public abstract class BaseOperation implements PassphraseCacheInterface {
|
||||
*
|
||||
* An operation must *not* throw exceptions of any kind, errors should be
|
||||
* handled as part of the OperationResult! Consequently, all handling of
|
||||
* errors in KeychainIntentService and OpenPgpService should consist of
|
||||
* errors in KeychainService and OpenPgpService should consist of
|
||||
* informational rather than operational means.
|
||||
*
|
||||
* Note that subclasses of this class should be either Android- or
|
||||
|
@ -38,7 +38,6 @@ import org.sufficientlysecure.keychain.operations.results.OperationResult.Operat
|
||||
import org.sufficientlysecure.keychain.operations.results.SaveKeyringResult;
|
||||
import org.sufficientlysecure.keychain.pgp.CanonicalizedKeyRing;
|
||||
import org.sufficientlysecure.keychain.pgp.CanonicalizedPublicKeyRing;
|
||||
import org.sufficientlysecure.keychain.pgp.PgpHelper;
|
||||
import org.sufficientlysecure.keychain.pgp.Progressable;
|
||||
import org.sufficientlysecure.keychain.pgp.UncachedKeyRing;
|
||||
import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException;
|
||||
@ -157,6 +156,15 @@ public class ImportExportOperation extends BaseOperation {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Since the introduction of multithreaded import, we expect calling functions to handle the key sync i,e
|
||||
* ContactSyncAdapterService.requestSync()
|
||||
*
|
||||
* @param entries keys to import
|
||||
* @param num number of keys to import
|
||||
* @param keyServerUri contains uri of keyserver to import from, if it is an import from cloud
|
||||
* @return
|
||||
*/
|
||||
public ImportKeyResult importKeyRings(Iterator<ParcelableKeyRing> entries, int num, String keyServerUri) {
|
||||
updateProgress(R.string.progress_importing, 0, 100);
|
||||
|
||||
@ -244,25 +252,25 @@ public class ImportExportOperation extends BaseOperation {
|
||||
try {
|
||||
log.add(LogType.MSG_IMPORT_FETCH_KEYBASE, 2, entry.mKeybaseName);
|
||||
byte[] data = keybaseServer.get(entry.mKeybaseName).getBytes();
|
||||
key = UncachedKeyRing.decodeFromData(data);
|
||||
UncachedKeyRing keybaseKey = UncachedKeyRing.decodeFromData(data);
|
||||
|
||||
// If there already is a key (of keybase origin), merge the two
|
||||
if (key != null) {
|
||||
// If there already is a key, merge the two
|
||||
if (key != null && keybaseKey != null) {
|
||||
log.add(LogType.MSG_IMPORT_MERGE, 3);
|
||||
UncachedKeyRing merged = UncachedKeyRing.decodeFromData(data);
|
||||
merged = key.merge(merged, log, 4);
|
||||
keybaseKey = key.merge(keybaseKey, log, 4);
|
||||
// If the merge didn't fail, use the new merged key
|
||||
if (merged != null) {
|
||||
key = merged;
|
||||
if (keybaseKey != null) {
|
||||
key = keybaseKey;
|
||||
} else {
|
||||
log.add(LogType.MSG_IMPORT_MERGE_ERROR, 4);
|
||||
}
|
||||
} else {
|
||||
log.add(LogType.MSG_IMPORT_FETCH_ERROR_DECODE, 3);
|
||||
key = UncachedKeyRing.decodeFromData(data);
|
||||
} else if (keybaseKey != null) {
|
||||
key = keybaseKey;
|
||||
}
|
||||
} catch (Keyserver.QueryFailedException e) {
|
||||
// download failed, too bad. just proceed
|
||||
Log.e(Constants.TAG, "query failed", e);
|
||||
log.add(LogType.MSG_IMPORT_FETCH_KEYSERVER_ERROR, 3);
|
||||
log.add(LogType.MSG_IMPORT_FETCH_KEYSERVER_ERROR, 3, e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -331,8 +339,8 @@ public class ImportExportOperation extends BaseOperation {
|
||||
|
||||
// Special: make sure new data is synced into contacts
|
||||
// disabling sync right now since it reduces speed while multi-threading
|
||||
// so, we expect calling functions to take care of it. KeychainIntentService handles this
|
||||
//ContactSyncAdapterService.requestSync();
|
||||
// so, we expect calling functions to take care of it. KeychainService handles this
|
||||
// ContactSyncAdapterService.requestSync();
|
||||
|
||||
// convert to long array
|
||||
long[] importedMasterKeyIdsArray = new long[importedMasterKeyIds.size()];
|
||||
@ -376,8 +384,6 @@ public class ImportExportOperation extends BaseOperation {
|
||||
log.add(LogType.MSG_IMPORT_ERROR, 1);
|
||||
}
|
||||
|
||||
ContactSyncAdapterService.requestSync();
|
||||
|
||||
return new ImportKeyResult(resultType, log, newKeys, updatedKeys, badKeys, secret,
|
||||
importedMasterKeyIdsArray);
|
||||
}
|
||||
|
@ -696,6 +696,7 @@ public abstract class OperationResult implements Parcelable {
|
||||
MSG_IMPORT_FETCH_KEYBASE (LogLevel.INFO, R.string.msg_import_fetch_keybase),
|
||||
MSG_IMPORT_KEYSERVER (LogLevel.DEBUG, R.string.msg_import_keyserver),
|
||||
MSG_IMPORT_MERGE (LogLevel.DEBUG, R.string.msg_import_merge),
|
||||
MSG_IMPORT_MERGE_ERROR (LogLevel.ERROR, R.string.msg_import_merge_error),
|
||||
MSG_IMPORT_FINGERPRINT_ERROR (LogLevel.ERROR, R.string.msg_import_fingerprint_error),
|
||||
MSG_IMPORT_FINGERPRINT_OK (LogLevel.DEBUG, R.string.msg_import_fingerprint_ok),
|
||||
MSG_IMPORT_ERROR (LogLevel.ERROR, R.string.msg_import_error),
|
||||
|
@ -1,384 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2012-2013 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.service;
|
||||
|
||||
import android.app.Service;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.os.IBinder;
|
||||
import android.os.Message;
|
||||
import android.os.Messenger;
|
||||
import android.os.RemoteException;
|
||||
|
||||
import org.sufficientlysecure.keychain.Constants;
|
||||
import org.sufficientlysecure.keychain.keyimport.ParcelableKeyRing;
|
||||
import org.sufficientlysecure.keychain.operations.ImportExportOperation;
|
||||
import org.sufficientlysecure.keychain.operations.results.ImportKeyResult;
|
||||
import org.sufficientlysecure.keychain.operations.results.OperationResult;
|
||||
import org.sufficientlysecure.keychain.pgp.Progressable;
|
||||
import org.sufficientlysecure.keychain.provider.ProviderHelper;
|
||||
import org.sufficientlysecure.keychain.util.Log;
|
||||
import org.sufficientlysecure.keychain.util.ParcelableFileCache;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.SynchronousQueue;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
/**
|
||||
* When this service is started it will initiate a multi-threaded key import and when done it will
|
||||
* shut itself down.
|
||||
*/
|
||||
public class CloudImportService extends Service implements Progressable {
|
||||
|
||||
// required as extras from intent
|
||||
public static final String EXTRA_MESSENGER = "messenger";
|
||||
public static final String EXTRA_DATA = "data";
|
||||
|
||||
// required by data bundle
|
||||
public static final String IMPORT_KEY_LIST = "import_key_list";
|
||||
public static final String IMPORT_KEY_SERVER = "import_key_server";
|
||||
|
||||
// indicates a request to cancel the import
|
||||
public static final String ACTION_CANCEL = Constants.INTENT_PREFIX + "CANCEL";
|
||||
|
||||
// tells the spawned threads whether the user has requested a cancel
|
||||
private static AtomicBoolean mActionCancelled = new AtomicBoolean(false);
|
||||
|
||||
@Override
|
||||
public IBinder onBind(Intent intent) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to accumulate the results of individual key imports
|
||||
*/
|
||||
private class KeyImportAccumulator {
|
||||
private OperationResult.OperationLog mImportLog = new OperationResult.OperationLog();
|
||||
private int mTotalKeys;
|
||||
private int mImportedKeys = 0;
|
||||
private Progressable mImportProgressable;
|
||||
ArrayList<Long> mImportedMasterKeyIds = new ArrayList<Long>();
|
||||
private int mBadKeys = 0;
|
||||
private int mNewKeys = 0;
|
||||
private int mUpdatedKeys = 0;
|
||||
private int mSecret = 0;
|
||||
private int mResultType = 0;
|
||||
|
||||
public KeyImportAccumulator(int totalKeys) {
|
||||
mTotalKeys = totalKeys;
|
||||
// ignore updates from ImportExportOperation for now
|
||||
mImportProgressable = new Progressable() {
|
||||
@Override
|
||||
public void setProgress(String message, int current, int total) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setProgress(int resourceId, int current, int total) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setProgress(int current, int total) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPreventCancel() {
|
||||
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public Progressable getImportProgressable() {
|
||||
return mImportProgressable;
|
||||
}
|
||||
|
||||
public int getTotalKeys() {
|
||||
return mTotalKeys;
|
||||
}
|
||||
|
||||
public int getImportedKeys() {
|
||||
return mImportedKeys;
|
||||
}
|
||||
|
||||
public synchronized void accumulateKeyImport(ImportKeyResult result) {
|
||||
mImportedKeys++;
|
||||
mImportLog.addAll(result.getLog().toList());//accumulates log
|
||||
mBadKeys += result.mBadKeys;
|
||||
mNewKeys += result.mNewKeys;
|
||||
mUpdatedKeys += result.mUpdatedKeys;
|
||||
mSecret += result.mSecret;
|
||||
|
||||
long[] masterKeyIds = result.getImportedMasterKeyIds();
|
||||
for (long masterKeyId : masterKeyIds) {
|
||||
mImportedMasterKeyIds.add(masterKeyId);
|
||||
}
|
||||
|
||||
// if any key import has been cancelled, set result type to cancelled
|
||||
// resultType is added to in getConsolidatedKayImport to account for remaining factors
|
||||
mResultType |= result.getResult() & ImportKeyResult.RESULT_CANCELLED;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns accumulated result of all imports so far
|
||||
*/
|
||||
public ImportKeyResult getConsolidatedImportKeyResult() {
|
||||
|
||||
// adding required information to mResultType
|
||||
// special case,no keys requested for import
|
||||
if (mBadKeys == 0 && mNewKeys == 0 && mUpdatedKeys == 0) {
|
||||
mResultType = ImportKeyResult.RESULT_FAIL_NOTHING;
|
||||
} else {
|
||||
if (mNewKeys > 0) {
|
||||
mResultType |= ImportKeyResult.RESULT_OK_NEWKEYS;
|
||||
}
|
||||
if (mUpdatedKeys > 0) {
|
||||
mResultType |= ImportKeyResult.RESULT_OK_UPDATED;
|
||||
}
|
||||
if (mBadKeys > 0) {
|
||||
mResultType |= ImportKeyResult.RESULT_WITH_ERRORS;
|
||||
if (mNewKeys == 0 && mUpdatedKeys == 0) {
|
||||
mResultType |= ImportKeyResult.RESULT_ERROR;
|
||||
}
|
||||
}
|
||||
if (mImportLog.containsWarnings()) {
|
||||
mResultType |= ImportKeyResult.RESULT_WARNINGS;
|
||||
}
|
||||
}
|
||||
|
||||
long masterKeyIds[] = new long[mImportedMasterKeyIds.size()];
|
||||
for (int i = 0; i < masterKeyIds.length; i++) {
|
||||
masterKeyIds[i] = mImportedMasterKeyIds.get(i);
|
||||
}
|
||||
|
||||
return new ImportKeyResult(mResultType, mImportLog, mNewKeys, mUpdatedKeys, mBadKeys,
|
||||
mSecret, masterKeyIds);
|
||||
}
|
||||
|
||||
public boolean isImportFinished() {
|
||||
return mTotalKeys == mImportedKeys;
|
||||
}
|
||||
}
|
||||
|
||||
private KeyImportAccumulator mKeyImportAccumulator;
|
||||
|
||||
Messenger mMessenger;
|
||||
|
||||
@Override
|
||||
public int onStartCommand(Intent intent, int flags, int startId) {
|
||||
|
||||
if (ACTION_CANCEL.equals(intent.getAction())) {
|
||||
mActionCancelled.set(true);
|
||||
return Service.START_NOT_STICKY;
|
||||
}
|
||||
|
||||
mActionCancelled.set(false);//we haven't been cancelled, yet
|
||||
|
||||
Bundle extras = intent.getExtras();
|
||||
|
||||
mMessenger = (Messenger) extras.get(EXTRA_MESSENGER);
|
||||
|
||||
Bundle data = extras.getBundle(EXTRA_DATA);
|
||||
|
||||
final String keyServer = data.getString(IMPORT_KEY_SERVER);
|
||||
// keyList being null (in case key list to be reaad from cache) is checked by importKeys
|
||||
final ArrayList<ParcelableKeyRing> keyList = data.getParcelableArrayList(IMPORT_KEY_LIST);
|
||||
|
||||
// Adding keys to the ThreadPoolExecutor takes time, we don't want to block the main thread
|
||||
Thread baseImportThread = new Thread(new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
importKeys(keyList, keyServer);
|
||||
}
|
||||
});
|
||||
baseImportThread.start();
|
||||
return Service.START_NOT_STICKY;
|
||||
}
|
||||
|
||||
public void importKeys(ArrayList<ParcelableKeyRing> keyList, final String keyServer) {
|
||||
ParcelableFileCache<ParcelableKeyRing> cache =
|
||||
new ParcelableFileCache<>(this, "key_import.pcl");
|
||||
int totKeys = 0;
|
||||
Iterator<ParcelableKeyRing> keyListIterator = null;
|
||||
// either keyList or cache must be null, no guarantees otherwise
|
||||
if (keyList == null) {//export from cache, copied from ImportExportOperation.importKeyRings
|
||||
|
||||
try {
|
||||
ParcelableFileCache.IteratorWithSize<ParcelableKeyRing> it = cache.readCache();
|
||||
keyListIterator = it;
|
||||
totKeys = it.getSize();
|
||||
} catch (IOException e) {
|
||||
|
||||
// Special treatment here, we need a lot
|
||||
OperationResult.OperationLog log = new OperationResult.OperationLog();
|
||||
log.add(OperationResult.LogType.MSG_IMPORT, 0, 0);
|
||||
log.add(OperationResult.LogType.MSG_IMPORT_ERROR_IO, 0, 0);
|
||||
|
||||
keyImportFailed(new ImportKeyResult(ImportKeyResult.RESULT_ERROR, log));
|
||||
}
|
||||
} else {
|
||||
keyListIterator = keyList.iterator();
|
||||
totKeys = keyList.size();
|
||||
}
|
||||
|
||||
|
||||
if (keyListIterator != null) {
|
||||
mKeyImportAccumulator = new KeyImportAccumulator(totKeys);
|
||||
setProgress(0, totKeys);
|
||||
|
||||
final int maxThreads = 200;
|
||||
ExecutorService importExecutor = new ThreadPoolExecutor(0, maxThreads,
|
||||
30L, TimeUnit.SECONDS,
|
||||
new SynchronousQueue<Runnable>());
|
||||
|
||||
while (keyListIterator.hasNext()) {
|
||||
|
||||
final ParcelableKeyRing pkRing = keyListIterator.next();
|
||||
|
||||
Runnable importOperationRunnable = new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
ImportKeyResult result = null;
|
||||
try {
|
||||
ImportExportOperation importExportOperation = new ImportExportOperation(
|
||||
CloudImportService.this,
|
||||
new ProviderHelper(CloudImportService.this),
|
||||
mKeyImportAccumulator.getImportProgressable(),
|
||||
mActionCancelled);
|
||||
|
||||
ArrayList<ParcelableKeyRing> list = new ArrayList<>();
|
||||
list.add(pkRing);
|
||||
result = importExportOperation.importKeyRings(list,
|
||||
keyServer);
|
||||
} finally {
|
||||
// in the off-chance that importKeyRings does something to crash the
|
||||
// thread before it can call singleKeyRingImportCompleted, our imported
|
||||
// key count will go wrong. This will cause the service to never die,
|
||||
// and the progress dialog to stay displayed. The finally block was
|
||||
// originally meant to ensure singleKeyRingImportCompleted was called,
|
||||
// and checks for null were to be introduced, but in such a scenario,
|
||||
// knowing an uncaught error exists in importKeyRings is more important.
|
||||
|
||||
// if a null gets passed, something wrong is happening. We want a crash.
|
||||
|
||||
singleKeyRingImportCompleted(result);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
importExecutor.execute(importOperationRunnable);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private synchronized void singleKeyRingImportCompleted(ImportKeyResult result) {
|
||||
// increase imported key count and accumulate log and bad, new etc. key counts from result
|
||||
mKeyImportAccumulator.accumulateKeyImport(result);
|
||||
|
||||
setProgress(mKeyImportAccumulator.getImportedKeys(), mKeyImportAccumulator.getTotalKeys());
|
||||
|
||||
if (mKeyImportAccumulator.isImportFinished()) {
|
||||
ContactSyncAdapterService.requestSync();
|
||||
|
||||
sendMessageToHandler(ServiceProgressHandler.MessageStatus.OKAY,
|
||||
mKeyImportAccumulator.getConsolidatedImportKeyResult());
|
||||
|
||||
stopSelf();//we're done here
|
||||
}
|
||||
}
|
||||
|
||||
private void keyImportFailed(ImportKeyResult result) {
|
||||
sendMessageToHandler(ServiceProgressHandler.MessageStatus.OKAY, result);
|
||||
}
|
||||
|
||||
private void sendMessageToHandler(ServiceProgressHandler.MessageStatus status, Integer arg2, Bundle data) {
|
||||
|
||||
Message msg = Message.obtain();
|
||||
assert msg != null;
|
||||
msg.arg1 = status.ordinal();
|
||||
if (arg2 != null) {
|
||||
msg.arg2 = arg2;
|
||||
}
|
||||
if (data != null) {
|
||||
msg.setData(data);
|
||||
}
|
||||
|
||||
try {
|
||||
mMessenger.send(msg);
|
||||
} catch (RemoteException e) {
|
||||
Log.w(Constants.TAG, "Exception sending message, Is handler present?", e);
|
||||
} catch (NullPointerException e) {
|
||||
Log.w(Constants.TAG, "Messenger is null!", e);
|
||||
}
|
||||
}
|
||||
|
||||
private void sendMessageToHandler(ServiceProgressHandler.MessageStatus status, OperationResult data) {
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putParcelable(OperationResult.EXTRA_RESULT, data);
|
||||
sendMessageToHandler(status, null, bundle);
|
||||
}
|
||||
|
||||
private void sendMessageToHandler(ServiceProgressHandler.MessageStatus status, Bundle data) {
|
||||
sendMessageToHandler(status, null, data);
|
||||
}
|
||||
|
||||
private void sendMessageToHandler(ServiceProgressHandler.MessageStatus status) {
|
||||
sendMessageToHandler(status, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set progress of ProgressDialog by sending message to handler on UI thread
|
||||
*/
|
||||
@Override
|
||||
public synchronized void setProgress(String message, int progress, int max) {
|
||||
Log.d(Constants.TAG, "Send message by setProgress with progress=" + progress + ", max="
|
||||
+ max);
|
||||
|
||||
Bundle data = new Bundle();
|
||||
if (message != null) {
|
||||
data.putString(ServiceProgressHandler.DATA_MESSAGE, message);
|
||||
}
|
||||
data.putInt(ServiceProgressHandler.DATA_PROGRESS, progress);
|
||||
data.putInt(ServiceProgressHandler.DATA_PROGRESS_MAX, max);
|
||||
|
||||
sendMessageToHandler(ServiceProgressHandler.MessageStatus.UPDATE_PROGRESS, null, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void setProgress(int resourceId, int progress, int max) {
|
||||
setProgress(getString(resourceId), progress, max);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void setProgress(int progress, int max) {
|
||||
setProgress(null, progress, max);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void setPreventCancel() {
|
||||
sendMessageToHandler(ServiceProgressHandler.MessageStatus.PREVENT_CANCEL);
|
||||
}
|
||||
}
|
@ -1,613 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2012-2014 Dominik Schürmann <dominik@dominikschuermann.de>
|
||||
* Copyright (C) 2014 Vincent Breitmoser <v.breitmoser@mugenguild.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.app.IntentService;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.os.Message;
|
||||
import android.os.Messenger;
|
||||
import android.os.RemoteException;
|
||||
|
||||
import com.textuality.keybase.lib.Proof;
|
||||
import com.textuality.keybase.lib.prover.Prover;
|
||||
|
||||
import org.json.JSONObject;
|
||||
import org.spongycastle.openpgp.PGPUtil;
|
||||
import org.sufficientlysecure.keychain.Constants;
|
||||
import org.sufficientlysecure.keychain.R;
|
||||
import org.sufficientlysecure.keychain.keyimport.HkpKeyserver;
|
||||
import org.sufficientlysecure.keychain.keyimport.Keyserver;
|
||||
import org.sufficientlysecure.keychain.keyimport.ParcelableKeyRing;
|
||||
import org.sufficientlysecure.keychain.operations.CertifyOperation;
|
||||
import org.sufficientlysecure.keychain.operations.DeleteOperation;
|
||||
import org.sufficientlysecure.keychain.operations.EditKeyOperation;
|
||||
import org.sufficientlysecure.keychain.operations.ImportExportOperation;
|
||||
import org.sufficientlysecure.keychain.operations.PromoteKeyOperation;
|
||||
import org.sufficientlysecure.keychain.operations.SignEncryptOperation;
|
||||
import org.sufficientlysecure.keychain.operations.results.CertifyResult;
|
||||
import org.sufficientlysecure.keychain.operations.results.ConsolidateResult;
|
||||
import org.sufficientlysecure.keychain.operations.results.DecryptVerifyResult;
|
||||
import org.sufficientlysecure.keychain.operations.results.DeleteResult;
|
||||
import org.sufficientlysecure.keychain.operations.results.ExportResult;
|
||||
import org.sufficientlysecure.keychain.operations.results.ImportKeyResult;
|
||||
import org.sufficientlysecure.keychain.operations.results.OperationResult;
|
||||
import org.sufficientlysecure.keychain.operations.results.OperationResult.OperationLog;
|
||||
import org.sufficientlysecure.keychain.operations.results.PromoteKeyResult;
|
||||
import org.sufficientlysecure.keychain.operations.results.SignEncryptResult;
|
||||
import org.sufficientlysecure.keychain.pgp.CanonicalizedPublicKeyRing;
|
||||
import org.sufficientlysecure.keychain.pgp.PgpDecryptVerify;
|
||||
import org.sufficientlysecure.keychain.pgp.PgpDecryptVerifyInputParcel;
|
||||
import org.sufficientlysecure.keychain.pgp.Progressable;
|
||||
import org.sufficientlysecure.keychain.pgp.SignEncryptParcel;
|
||||
import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException;
|
||||
import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralMsgIdException;
|
||||
import org.sufficientlysecure.keychain.provider.ProviderHelper;
|
||||
import org.sufficientlysecure.keychain.service.input.CryptoInputParcel;
|
||||
import org.sufficientlysecure.keychain.service.ServiceProgressHandler.MessageStatus;
|
||||
import org.sufficientlysecure.keychain.util.Log;
|
||||
import org.sufficientlysecure.keychain.util.ParcelableFileCache;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import de.measite.minidns.Client;
|
||||
import de.measite.minidns.DNSMessage;
|
||||
import de.measite.minidns.Question;
|
||||
import de.measite.minidns.Record;
|
||||
import de.measite.minidns.record.Data;
|
||||
import de.measite.minidns.record.TXT;
|
||||
|
||||
/**
|
||||
* This Service contains all important long lasting operations for OpenKeychain. It receives Intents with
|
||||
* data from the activities or other apps, queues these intents, executes them, and stops itself
|
||||
* after doing them.
|
||||
*/
|
||||
public class KeychainIntentService extends IntentService implements Progressable {
|
||||
|
||||
/* extras that can be given by intent */
|
||||
public static final String EXTRA_MESSENGER = "messenger";
|
||||
public static final String EXTRA_DATA = "data";
|
||||
|
||||
/* possible actions */
|
||||
public static final String ACTION_SIGN_ENCRYPT = Constants.INTENT_PREFIX + "SIGN_ENCRYPT";
|
||||
|
||||
public static final String ACTION_DECRYPT_VERIFY = Constants.INTENT_PREFIX + "DECRYPT_VERIFY";
|
||||
|
||||
public static final String ACTION_VERIFY_KEYBASE_PROOF = Constants.INTENT_PREFIX + "VERIFY_KEYBASE_PROOF";
|
||||
|
||||
public static final String ACTION_DECRYPT_METADATA = Constants.INTENT_PREFIX + "DECRYPT_METADATA";
|
||||
|
||||
public static final String ACTION_EDIT_KEYRING = Constants.INTENT_PREFIX + "EDIT_KEYRING";
|
||||
|
||||
public static final String ACTION_PROMOTE_KEYRING = Constants.INTENT_PREFIX + "PROMOTE_KEYRING";
|
||||
|
||||
public static final String ACTION_IMPORT_KEYRING = Constants.INTENT_PREFIX + "IMPORT_KEYRING";
|
||||
public static final String ACTION_EXPORT_KEYRING = Constants.INTENT_PREFIX + "EXPORT_KEYRING";
|
||||
|
||||
public static final String ACTION_UPLOAD_KEYRING = Constants.INTENT_PREFIX + "UPLOAD_KEYRING";
|
||||
|
||||
public static final String ACTION_CERTIFY_KEYRING = Constants.INTENT_PREFIX + "SIGN_KEYRING";
|
||||
|
||||
public static final String ACTION_DELETE = Constants.INTENT_PREFIX + "DELETE";
|
||||
|
||||
public static final String ACTION_CONSOLIDATE = Constants.INTENT_PREFIX + "CONSOLIDATE";
|
||||
|
||||
public static final String ACTION_CANCEL = Constants.INTENT_PREFIX + "CANCEL";
|
||||
|
||||
/* keys for data bundle */
|
||||
|
||||
// encrypt
|
||||
public static final String ENCRYPT_DECRYPT_INPUT_URI = "input_uri";
|
||||
public static final String ENCRYPT_DECRYPT_OUTPUT_URI = "output_uri";
|
||||
public static final String SIGN_ENCRYPT_PARCEL = "sign_encrypt_parcel";
|
||||
|
||||
// decrypt/verify
|
||||
public static final String DECRYPT_VERIFY_PARCEL = "decrypt_verify_parcel";
|
||||
|
||||
// keybase proof
|
||||
public static final String KEYBASE_REQUIRED_FINGERPRINT = "keybase_required_fingerprint";
|
||||
public static final String KEYBASE_PROOF = "keybase_proof";
|
||||
|
||||
// save keyring
|
||||
public static final String EDIT_KEYRING_PARCEL = "save_parcel";
|
||||
public static final String EDIT_KEYRING_PASSPHRASE = "passphrase";
|
||||
public static final String EXTRA_CRYPTO_INPUT = "crypto_input";
|
||||
|
||||
// delete keyring(s)
|
||||
public static final String DELETE_KEY_LIST = "delete_list";
|
||||
public static final String DELETE_IS_SECRET = "delete_is_secret";
|
||||
|
||||
// import key
|
||||
public static final String IMPORT_KEY_LIST = "import_key_list";
|
||||
public static final String IMPORT_KEY_SERVER = "import_key_server";
|
||||
|
||||
// export key
|
||||
public static final String EXPORT_FILENAME = "export_filename";
|
||||
public static final String EXPORT_URI = "export_uri";
|
||||
public static final String EXPORT_SECRET = "export_secret";
|
||||
public static final String EXPORT_ALL = "export_all";
|
||||
public static final String EXPORT_KEY_RING_MASTER_KEY_ID = "export_key_ring_id";
|
||||
|
||||
// upload key
|
||||
public static final String UPLOAD_KEY_SERVER = "upload_key_server";
|
||||
|
||||
// certify key
|
||||
public static final String CERTIFY_PARCEL = "certify_parcel";
|
||||
|
||||
// promote key
|
||||
public static final String PROMOTE_MASTER_KEY_ID = "promote_master_key_id";
|
||||
public static final String PROMOTE_CARD_AID = "promote_card_aid";
|
||||
public static final String PROMOTE_SUBKEY_IDS = "promote_fingerprints";
|
||||
|
||||
// consolidate
|
||||
public static final String CONSOLIDATE_RECOVERY = "consolidate_recovery";
|
||||
|
||||
Messenger mMessenger;
|
||||
|
||||
// this attribute can possibly merged with the one above? not sure...
|
||||
private AtomicBoolean mActionCanceled = new AtomicBoolean(false);
|
||||
|
||||
public KeychainIntentService() {
|
||||
super("KeychainIntentService");
|
||||
}
|
||||
|
||||
/**
|
||||
* The IntentService calls this method from the default worker thread with the intent that
|
||||
* started the service. When this method returns, IntentService stops the service, as
|
||||
* appropriate.
|
||||
*/
|
||||
@Override
|
||||
protected void onHandleIntent(Intent intent) {
|
||||
|
||||
// We have not been cancelled! (yet)
|
||||
mActionCanceled.set(false);
|
||||
|
||||
Bundle extras = intent.getExtras();
|
||||
if (extras == null) {
|
||||
Log.e(Constants.TAG, "Extras bundle is null!");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(extras.containsKey(EXTRA_MESSENGER) || extras.containsKey(EXTRA_DATA) || (intent
|
||||
.getAction() == null))) {
|
||||
Log.e(Constants.TAG,
|
||||
"Extra bundle must contain a messenger, a data bundle, and an action!");
|
||||
return;
|
||||
}
|
||||
|
||||
Uri dataUri = intent.getData();
|
||||
|
||||
mMessenger = (Messenger) extras.get(EXTRA_MESSENGER);
|
||||
Bundle data = extras.getBundle(EXTRA_DATA);
|
||||
if (data == null) {
|
||||
Log.e(Constants.TAG, "data extra is null!");
|
||||
return;
|
||||
}
|
||||
|
||||
Log.logDebugBundle(data, "EXTRA_DATA");
|
||||
|
||||
ProviderHelper providerHelper = new ProviderHelper(this);
|
||||
|
||||
String action = intent.getAction();
|
||||
|
||||
// executeServiceMethod action from extra bundle
|
||||
switch (action) {
|
||||
case ACTION_CERTIFY_KEYRING: {
|
||||
|
||||
// Input
|
||||
CertifyActionsParcel parcel = data.getParcelable(CERTIFY_PARCEL);
|
||||
CryptoInputParcel cryptoInput = data.getParcelable(EXTRA_CRYPTO_INPUT);
|
||||
String keyServerUri = data.getString(UPLOAD_KEY_SERVER);
|
||||
|
||||
// Operation
|
||||
CertifyOperation op = new CertifyOperation(this, providerHelper, this, mActionCanceled);
|
||||
CertifyResult result = op.certify(parcel, cryptoInput, keyServerUri);
|
||||
|
||||
// Result
|
||||
sendMessageToHandler(MessageStatus.OKAY, result);
|
||||
|
||||
break;
|
||||
}
|
||||
case ACTION_CONSOLIDATE: {
|
||||
|
||||
// Operation
|
||||
ConsolidateResult result;
|
||||
if (data.containsKey(CONSOLIDATE_RECOVERY) && data.getBoolean(CONSOLIDATE_RECOVERY)) {
|
||||
result = new ProviderHelper(this).consolidateDatabaseStep2(this);
|
||||
} else {
|
||||
result = new ProviderHelper(this).consolidateDatabaseStep1(this);
|
||||
}
|
||||
|
||||
// Result
|
||||
sendMessageToHandler(MessageStatus.OKAY, result);
|
||||
|
||||
break;
|
||||
}
|
||||
case ACTION_DECRYPT_METADATA: {
|
||||
|
||||
/* Input */
|
||||
CryptoInputParcel cryptoInput = data.getParcelable(EXTRA_CRYPTO_INPUT);
|
||||
PgpDecryptVerifyInputParcel input = data.getParcelable(DECRYPT_VERIFY_PARCEL);
|
||||
|
||||
// this action is here for compatibility only
|
||||
input.setDecryptMetadataOnly(true);
|
||||
|
||||
/* Operation */
|
||||
PgpDecryptVerify op = new PgpDecryptVerify(this, new ProviderHelper(this), this);
|
||||
DecryptVerifyResult decryptVerifyResult = op.execute(input, cryptoInput);
|
||||
|
||||
/* Result */
|
||||
sendMessageToHandler(MessageStatus.OKAY, decryptVerifyResult);
|
||||
|
||||
break;
|
||||
}
|
||||
case ACTION_VERIFY_KEYBASE_PROOF: {
|
||||
|
||||
try {
|
||||
Proof proof = new Proof(new JSONObject(data.getString(KEYBASE_PROOF)));
|
||||
setProgress(R.string.keybase_message_fetching_data, 0, 100);
|
||||
|
||||
Prover prover = Prover.findProverFor(proof);
|
||||
|
||||
if (prover == null) {
|
||||
sendProofError(getString(R.string.keybase_no_prover_found) + ": " + proof.getPrettyName());
|
||||
return;
|
||||
}
|
||||
|
||||
if (!prover.fetchProofData()) {
|
||||
sendProofError(prover.getLog(), getString(R.string.keybase_problem_fetching_evidence));
|
||||
return;
|
||||
}
|
||||
String requiredFingerprint = data.getString(KEYBASE_REQUIRED_FINGERPRINT);
|
||||
if (!prover.checkFingerprint(requiredFingerprint)) {
|
||||
sendProofError(getString(R.string.keybase_key_mismatch));
|
||||
return;
|
||||
}
|
||||
|
||||
String domain = prover.dnsTxtCheckRequired();
|
||||
if (domain != null) {
|
||||
DNSMessage dnsQuery = new Client().query(new Question(domain, Record.TYPE.TXT));
|
||||
if (dnsQuery == null) {
|
||||
sendProofError(prover.getLog(), getString(R.string.keybase_dns_query_failure));
|
||||
return;
|
||||
}
|
||||
Record[] records = dnsQuery.getAnswers();
|
||||
List<List<byte[]>> extents = new ArrayList<List<byte[]>>();
|
||||
for (Record r : records) {
|
||||
Data d = r.getPayload();
|
||||
if (d instanceof TXT) {
|
||||
extents.add(((TXT) d).getExtents());
|
||||
}
|
||||
}
|
||||
if (!prover.checkDnsTxt(extents)) {
|
||||
sendProofError(prover.getLog(), null);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
byte[] messageBytes = prover.getPgpMessage().getBytes();
|
||||
if (prover.rawMessageCheckRequired()) {
|
||||
InputStream messageByteStream = PGPUtil.getDecoderStream(new ByteArrayInputStream(messageBytes));
|
||||
if (!prover.checkRawMessageBytes(messageByteStream)) {
|
||||
sendProofError(prover.getLog(), null);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
PgpDecryptVerify op = new PgpDecryptVerify(this, new ProviderHelper(this), this);
|
||||
|
||||
PgpDecryptVerifyInputParcel input = new PgpDecryptVerifyInputParcel(messageBytes)
|
||||
.setSignedLiteralData(true)
|
||||
.setRequiredSignerFingerprint(requiredFingerprint);
|
||||
|
||||
DecryptVerifyResult decryptVerifyResult = op.execute(input, new CryptoInputParcel());
|
||||
|
||||
if (!decryptVerifyResult.success()) {
|
||||
OperationLog log = decryptVerifyResult.getLog();
|
||||
OperationResult.LogEntryParcel lastEntry = null;
|
||||
for (OperationResult.LogEntryParcel entry : log) {
|
||||
lastEntry = entry;
|
||||
}
|
||||
sendProofError(getString(lastEntry.mType.getMsgId()));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!prover.validate(new String(decryptVerifyResult.getOutputBytes()))) {
|
||||
sendProofError(getString(R.string.keybase_message_payload_mismatch));
|
||||
return;
|
||||
}
|
||||
|
||||
Bundle resultData = new Bundle();
|
||||
resultData.putString(ServiceProgressHandler.DATA_MESSAGE, "OK");
|
||||
|
||||
// these help the handler construct a useful human-readable message
|
||||
resultData.putString(ServiceProgressHandler.KEYBASE_PROOF_URL, prover.getProofUrl());
|
||||
resultData.putString(ServiceProgressHandler.KEYBASE_PRESENCE_URL, prover.getPresenceUrl());
|
||||
resultData.putString(ServiceProgressHandler.KEYBASE_PRESENCE_LABEL, prover.getPresenceLabel());
|
||||
sendMessageToHandler(MessageStatus.OKAY, resultData);
|
||||
} catch (Exception e) {
|
||||
sendErrorToHandler(e);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case ACTION_DECRYPT_VERIFY: {
|
||||
|
||||
/* Input */
|
||||
CryptoInputParcel cryptoInput = data.getParcelable(EXTRA_CRYPTO_INPUT);
|
||||
PgpDecryptVerifyInputParcel input = data.getParcelable(DECRYPT_VERIFY_PARCEL);
|
||||
|
||||
/* Operation */
|
||||
PgpDecryptVerify op = new PgpDecryptVerify(this, new ProviderHelper(this), this);
|
||||
DecryptVerifyResult decryptVerifyResult = op.execute(input, cryptoInput);
|
||||
|
||||
/* Output */
|
||||
sendMessageToHandler(MessageStatus.OKAY, decryptVerifyResult);
|
||||
|
||||
break;
|
||||
}
|
||||
case ACTION_DELETE: {
|
||||
|
||||
// Input
|
||||
long[] masterKeyIds = data.getLongArray(DELETE_KEY_LIST);
|
||||
boolean isSecret = data.getBoolean(DELETE_IS_SECRET);
|
||||
|
||||
// Operation
|
||||
DeleteOperation op = new DeleteOperation(this, new ProviderHelper(this), this);
|
||||
DeleteResult result = op.execute(masterKeyIds, isSecret);
|
||||
|
||||
// Result
|
||||
sendMessageToHandler(MessageStatus.OKAY, result);
|
||||
|
||||
break;
|
||||
}
|
||||
case ACTION_EDIT_KEYRING: {
|
||||
|
||||
// Input
|
||||
SaveKeyringParcel saveParcel = data.getParcelable(EDIT_KEYRING_PARCEL);
|
||||
CryptoInputParcel cryptoInput = data.getParcelable(EXTRA_CRYPTO_INPUT);
|
||||
|
||||
// Operation
|
||||
EditKeyOperation op = new EditKeyOperation(this, providerHelper, this, mActionCanceled);
|
||||
OperationResult result = op.execute(saveParcel, cryptoInput);
|
||||
|
||||
// Result
|
||||
sendMessageToHandler(MessageStatus.OKAY, result);
|
||||
|
||||
break;
|
||||
}
|
||||
case ACTION_PROMOTE_KEYRING: {
|
||||
|
||||
// Input
|
||||
long keyRingId = data.getLong(PROMOTE_MASTER_KEY_ID);
|
||||
byte[] cardAid = data.getByteArray(PROMOTE_CARD_AID);
|
||||
long[] subKeyIds = data.getLongArray(PROMOTE_SUBKEY_IDS);
|
||||
|
||||
// Operation
|
||||
PromoteKeyOperation op = new PromoteKeyOperation(
|
||||
this, providerHelper, this, mActionCanceled);
|
||||
PromoteKeyResult result = op.execute(keyRingId, cardAid, subKeyIds);
|
||||
|
||||
// Result
|
||||
sendMessageToHandler(MessageStatus.OKAY, result);
|
||||
|
||||
break;
|
||||
}
|
||||
case ACTION_EXPORT_KEYRING: {
|
||||
|
||||
// Input
|
||||
boolean exportSecret = data.getBoolean(EXPORT_SECRET, false);
|
||||
String outputFile = data.getString(EXPORT_FILENAME);
|
||||
Uri outputUri = data.getParcelable(EXPORT_URI);
|
||||
|
||||
boolean exportAll = data.getBoolean(EXPORT_ALL);
|
||||
long[] masterKeyIds = exportAll ? null : data.getLongArray(EXPORT_KEY_RING_MASTER_KEY_ID);
|
||||
|
||||
// Operation
|
||||
ImportExportOperation importExportOperation = new ImportExportOperation(this, new ProviderHelper(this), this);
|
||||
ExportResult result;
|
||||
if (outputFile != null) {
|
||||
result = importExportOperation.exportToFile(masterKeyIds, exportSecret, outputFile);
|
||||
} else {
|
||||
result = importExportOperation.exportToUri(masterKeyIds, exportSecret, outputUri);
|
||||
}
|
||||
|
||||
// Result
|
||||
sendMessageToHandler(MessageStatus.OKAY, result);
|
||||
|
||||
break;
|
||||
}
|
||||
case ACTION_IMPORT_KEYRING: {
|
||||
|
||||
// Input
|
||||
String keyServer = data.getString(IMPORT_KEY_SERVER);
|
||||
ArrayList<ParcelableKeyRing> list = data.getParcelableArrayList(IMPORT_KEY_LIST);
|
||||
ParcelableFileCache<ParcelableKeyRing> cache =
|
||||
new ParcelableFileCache<>(this, "key_import.pcl");
|
||||
|
||||
// Operation
|
||||
ImportExportOperation importExportOperation = new ImportExportOperation(
|
||||
this, providerHelper, this, mActionCanceled);
|
||||
// Either list or cache must be null, no guarantees otherwise.
|
||||
ImportKeyResult result = list != null
|
||||
? importExportOperation.importKeyRings(list, keyServer)
|
||||
: importExportOperation.importKeyRings(cache, keyServer);
|
||||
|
||||
// Result
|
||||
sendMessageToHandler(MessageStatus.OKAY, result);
|
||||
|
||||
break;
|
||||
|
||||
}
|
||||
case ACTION_SIGN_ENCRYPT: {
|
||||
|
||||
// Input
|
||||
SignEncryptParcel inputParcel = data.getParcelable(SIGN_ENCRYPT_PARCEL);
|
||||
CryptoInputParcel cryptoInput = data.getParcelable(EXTRA_CRYPTO_INPUT);
|
||||
|
||||
// Operation
|
||||
SignEncryptOperation op = new SignEncryptOperation(
|
||||
this, new ProviderHelper(this), this, mActionCanceled);
|
||||
SignEncryptResult result = op.execute(inputParcel, cryptoInput);
|
||||
|
||||
// Result
|
||||
sendMessageToHandler(MessageStatus.OKAY, result);
|
||||
|
||||
break;
|
||||
}
|
||||
case ACTION_UPLOAD_KEYRING: {
|
||||
try {
|
||||
|
||||
/* Input */
|
||||
String keyServer = data.getString(UPLOAD_KEY_SERVER);
|
||||
// and dataUri!
|
||||
|
||||
/* Operation */
|
||||
HkpKeyserver server = new HkpKeyserver(keyServer);
|
||||
|
||||
CanonicalizedPublicKeyRing keyring = providerHelper.getCanonicalizedPublicKeyRing(dataUri);
|
||||
ImportExportOperation importExportOperation = new ImportExportOperation(this, new ProviderHelper(this), this);
|
||||
|
||||
try {
|
||||
importExportOperation.uploadKeyRingToServer(server, keyring);
|
||||
} catch (Keyserver.AddKeyException e) {
|
||||
throw new PgpGeneralException("Unable to export key to selected server");
|
||||
}
|
||||
|
||||
sendMessageToHandler(MessageStatus.OKAY);
|
||||
} catch (Exception e) {
|
||||
sendErrorToHandler(e);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void sendProofError(List<String> log, String label) {
|
||||
String msg = null;
|
||||
label = (label == null) ? "" : label + ": ";
|
||||
for (String m : log) {
|
||||
Log.e(Constants.TAG, label + m);
|
||||
msg = m;
|
||||
}
|
||||
sendProofError(label + msg);
|
||||
}
|
||||
|
||||
private void sendProofError(String msg) {
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putString(ServiceProgressHandler.DATA_ERROR, msg);
|
||||
sendMessageToHandler(MessageStatus.OKAY, bundle);
|
||||
}
|
||||
|
||||
private void sendErrorToHandler(Exception e) {
|
||||
// TODO: Implement a better exception handling here
|
||||
// contextualize the exception, if necessary
|
||||
String message;
|
||||
if (e instanceof PgpGeneralMsgIdException) {
|
||||
e = ((PgpGeneralMsgIdException) e).getContextualized(this);
|
||||
message = e.getMessage();
|
||||
} else {
|
||||
message = e.getMessage();
|
||||
}
|
||||
Log.d(Constants.TAG, "KeychainIntentService Exception: ", e);
|
||||
|
||||
Bundle data = new Bundle();
|
||||
data.putString(ServiceProgressHandler.DATA_ERROR, message);
|
||||
sendMessageToHandler(MessageStatus.EXCEPTION, null, data);
|
||||
}
|
||||
|
||||
private void sendMessageToHandler(MessageStatus status, Integer arg2, Bundle data) {
|
||||
|
||||
Message msg = Message.obtain();
|
||||
assert msg != null;
|
||||
msg.arg1 = status.ordinal();
|
||||
if (arg2 != null) {
|
||||
msg.arg2 = arg2;
|
||||
}
|
||||
if (data != null) {
|
||||
msg.setData(data);
|
||||
}
|
||||
|
||||
try {
|
||||
mMessenger.send(msg);
|
||||
} catch (RemoteException e) {
|
||||
Log.w(Constants.TAG, "Exception sending message, Is handler present?", e);
|
||||
} catch (NullPointerException e) {
|
||||
Log.w(Constants.TAG, "Messenger is null!", e);
|
||||
}
|
||||
}
|
||||
|
||||
private void sendMessageToHandler(MessageStatus status, OperationResult data) {
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putParcelable(OperationResult.EXTRA_RESULT, data);
|
||||
sendMessageToHandler(status, null, bundle);
|
||||
}
|
||||
|
||||
private void sendMessageToHandler(MessageStatus status, Bundle data) {
|
||||
sendMessageToHandler(status, null, data);
|
||||
}
|
||||
|
||||
private void sendMessageToHandler(MessageStatus status) {
|
||||
sendMessageToHandler(status, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set progress of ProgressDialog by sending message to handler on UI thread
|
||||
*/
|
||||
public void setProgress(String message, int progress, int max) {
|
||||
Log.d(Constants.TAG, "Send message by setProgress with progress=" + progress + ", max="
|
||||
+ max);
|
||||
|
||||
Bundle data = new Bundle();
|
||||
if (message != null) {
|
||||
data.putString(ServiceProgressHandler.DATA_MESSAGE, message);
|
||||
}
|
||||
data.putInt(ServiceProgressHandler.DATA_PROGRESS, progress);
|
||||
data.putInt(ServiceProgressHandler.DATA_PROGRESS_MAX, max);
|
||||
|
||||
sendMessageToHandler(MessageStatus.UPDATE_PROGRESS, null, data);
|
||||
}
|
||||
|
||||
public void setProgress(int resourceId, int progress, int max) {
|
||||
setProgress(getString(resourceId), progress, max);
|
||||
}
|
||||
|
||||
public void setProgress(int progress, int max) {
|
||||
setProgress(null, progress, max);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPreventCancel() {
|
||||
sendMessageToHandler(MessageStatus.PREVENT_CANCEL);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int onStartCommand(Intent intent, int flags, int startId) {
|
||||
if (ACTION_CANCEL.equals(intent.getAction())) {
|
||||
mActionCanceled.set(true);
|
||||
return START_NOT_STICKY;
|
||||
}
|
||||
return super.onStartCommand(intent, flags, startId);
|
||||
}
|
||||
}
|
@ -0,0 +1,865 @@
|
||||
/*
|
||||
* Copyright (C) 2012-2014 Dominik Schürmann <dominik@dominikschuermann.de>
|
||||
* Copyright (C) 2014 Vincent Breitmoser <v.breitmoser@mugenguild.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.app.Service;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.os.IBinder;
|
||||
import android.os.Message;
|
||||
import android.os.Messenger;
|
||||
import android.os.RemoteException;
|
||||
|
||||
import com.textuality.keybase.lib.Proof;
|
||||
import com.textuality.keybase.lib.prover.Prover;
|
||||
|
||||
import org.json.JSONObject;
|
||||
import org.spongycastle.openpgp.PGPUtil;
|
||||
import org.sufficientlysecure.keychain.Constants;
|
||||
import org.sufficientlysecure.keychain.R;
|
||||
import org.sufficientlysecure.keychain.keyimport.HkpKeyserver;
|
||||
import org.sufficientlysecure.keychain.keyimport.Keyserver;
|
||||
import org.sufficientlysecure.keychain.keyimport.ParcelableKeyRing;
|
||||
import org.sufficientlysecure.keychain.operations.CertifyOperation;
|
||||
import org.sufficientlysecure.keychain.operations.DeleteOperation;
|
||||
import org.sufficientlysecure.keychain.operations.EditKeyOperation;
|
||||
import org.sufficientlysecure.keychain.operations.ImportExportOperation;
|
||||
import org.sufficientlysecure.keychain.operations.PromoteKeyOperation;
|
||||
import org.sufficientlysecure.keychain.operations.SignEncryptOperation;
|
||||
import org.sufficientlysecure.keychain.operations.results.CertifyResult;
|
||||
import org.sufficientlysecure.keychain.operations.results.ConsolidateResult;
|
||||
import org.sufficientlysecure.keychain.operations.results.DecryptVerifyResult;
|
||||
import org.sufficientlysecure.keychain.operations.results.DeleteResult;
|
||||
import org.sufficientlysecure.keychain.operations.results.ExportResult;
|
||||
import org.sufficientlysecure.keychain.operations.results.ImportKeyResult;
|
||||
import org.sufficientlysecure.keychain.operations.results.OperationResult;
|
||||
import org.sufficientlysecure.keychain.operations.results.OperationResult.OperationLog;
|
||||
import org.sufficientlysecure.keychain.operations.results.PromoteKeyResult;
|
||||
import org.sufficientlysecure.keychain.operations.results.SignEncryptResult;
|
||||
import org.sufficientlysecure.keychain.pgp.CanonicalizedPublicKeyRing;
|
||||
import org.sufficientlysecure.keychain.pgp.PgpDecryptVerify;
|
||||
import org.sufficientlysecure.keychain.pgp.PgpDecryptVerifyInputParcel;
|
||||
import org.sufficientlysecure.keychain.pgp.Progressable;
|
||||
import org.sufficientlysecure.keychain.pgp.SignEncryptParcel;
|
||||
import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException;
|
||||
import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralMsgIdException;
|
||||
import org.sufficientlysecure.keychain.provider.ProviderHelper;
|
||||
import org.sufficientlysecure.keychain.service.input.CryptoInputParcel;
|
||||
import org.sufficientlysecure.keychain.service.ServiceProgressHandler.MessageStatus;
|
||||
import org.sufficientlysecure.keychain.util.Log;
|
||||
import org.sufficientlysecure.keychain.util.ParcelableFileCache;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.SynchronousQueue;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import de.measite.minidns.Client;
|
||||
import de.measite.minidns.DNSMessage;
|
||||
import de.measite.minidns.Question;
|
||||
import de.measite.minidns.Record;
|
||||
import de.measite.minidns.record.Data;
|
||||
import de.measite.minidns.record.TXT;
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
public class KeychainService extends Service implements Progressable {
|
||||
|
||||
/* extras that can be given by intent */
|
||||
public static final String EXTRA_MESSENGER = "messenger";
|
||||
public static final String EXTRA_DATA = "data";
|
||||
|
||||
/* possible actions */
|
||||
public static final String ACTION_SIGN_ENCRYPT = Constants.INTENT_PREFIX + "SIGN_ENCRYPT";
|
||||
|
||||
public static final String ACTION_DECRYPT_VERIFY = Constants.INTENT_PREFIX + "DECRYPT_VERIFY";
|
||||
|
||||
public static final String ACTION_VERIFY_KEYBASE_PROOF = Constants.INTENT_PREFIX + "VERIFY_KEYBASE_PROOF";
|
||||
|
||||
public static final String ACTION_DECRYPT_METADATA = Constants.INTENT_PREFIX + "DECRYPT_METADATA";
|
||||
|
||||
public static final String ACTION_EDIT_KEYRING = Constants.INTENT_PREFIX + "EDIT_KEYRING";
|
||||
|
||||
public static final String ACTION_PROMOTE_KEYRING = Constants.INTENT_PREFIX + "PROMOTE_KEYRING";
|
||||
|
||||
public static final String ACTION_IMPORT_KEYRING = Constants.INTENT_PREFIX + "IMPORT_KEYRING";
|
||||
public static final String ACTION_EXPORT_KEYRING = Constants.INTENT_PREFIX + "EXPORT_KEYRING";
|
||||
|
||||
public static final String ACTION_UPLOAD_KEYRING = Constants.INTENT_PREFIX + "UPLOAD_KEYRING";
|
||||
|
||||
public static final String ACTION_CERTIFY_KEYRING = Constants.INTENT_PREFIX + "SIGN_KEYRING";
|
||||
|
||||
public static final String ACTION_DELETE = Constants.INTENT_PREFIX + "DELETE";
|
||||
|
||||
public static final String ACTION_CONSOLIDATE = Constants.INTENT_PREFIX + "CONSOLIDATE";
|
||||
|
||||
public static final String ACTION_CANCEL = Constants.INTENT_PREFIX + "CANCEL";
|
||||
|
||||
/* keys for data bundle */
|
||||
|
||||
// encrypt
|
||||
public static final String ENCRYPT_DECRYPT_INPUT_URI = "input_uri";
|
||||
public static final String ENCRYPT_DECRYPT_OUTPUT_URI = "output_uri";
|
||||
public static final String SIGN_ENCRYPT_PARCEL = "sign_encrypt_parcel";
|
||||
|
||||
// decrypt/verify
|
||||
public static final String DECRYPT_VERIFY_PARCEL = "decrypt_verify_parcel";
|
||||
|
||||
// keybase proof
|
||||
public static final String KEYBASE_REQUIRED_FINGERPRINT = "keybase_required_fingerprint";
|
||||
public static final String KEYBASE_PROOF = "keybase_proof";
|
||||
|
||||
// save keyring
|
||||
public static final String EDIT_KEYRING_PARCEL = "save_parcel";
|
||||
public static final String EDIT_KEYRING_PASSPHRASE = "passphrase";
|
||||
public static final String EXTRA_CRYPTO_INPUT = "crypto_input";
|
||||
|
||||
// delete keyring(s)
|
||||
public static final String DELETE_KEY_LIST = "delete_list";
|
||||
public static final String DELETE_IS_SECRET = "delete_is_secret";
|
||||
|
||||
// import key
|
||||
public static final String IMPORT_KEY_LIST = "import_key_list";
|
||||
public static final String IMPORT_KEY_SERVER = "import_key_server";
|
||||
|
||||
// export key
|
||||
public static final String EXPORT_FILENAME = "export_filename";
|
||||
public static final String EXPORT_URI = "export_uri";
|
||||
public static final String EXPORT_SECRET = "export_secret";
|
||||
public static final String EXPORT_ALL = "export_all";
|
||||
public static final String EXPORT_KEY_RING_MASTER_KEY_ID = "export_key_ring_id";
|
||||
|
||||
// upload key
|
||||
public static final String UPLOAD_KEY_SERVER = "upload_key_server";
|
||||
|
||||
// certify key
|
||||
public static final String CERTIFY_PARCEL = "certify_parcel";
|
||||
|
||||
// promote key
|
||||
public static final String PROMOTE_MASTER_KEY_ID = "promote_master_key_id";
|
||||
public static final String PROMOTE_CARD_AID = "promote_card_aid";
|
||||
public static final String PROMOTE_SUBKEY_IDS = "promote_fingerprints";
|
||||
|
||||
// consolidate
|
||||
public static final String CONSOLIDATE_RECOVERY = "consolidate_recovery";
|
||||
|
||||
Messenger mMessenger;
|
||||
|
||||
// this attribute can possibly merged with the one above? not sure...
|
||||
private AtomicBoolean mActionCanceled = new AtomicBoolean(false);
|
||||
|
||||
|
||||
private KeyImportAccumulator mKeyImportAccumulator;
|
||||
|
||||
private KeychainService mKeychainService;
|
||||
|
||||
@Override
|
||||
public IBinder onBind(Intent intent) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* This is run on the main thread, we need to spawn a runnable which runs on another thread for the actual operation
|
||||
*/
|
||||
@Override
|
||||
public int onStartCommand(final Intent intent, int flags, int startId) {
|
||||
mKeychainService = this;
|
||||
|
||||
if (ACTION_CANCEL.equals(intent.getAction())) {
|
||||
mActionCanceled.set(true);
|
||||
return START_NOT_STICKY;
|
||||
}
|
||||
|
||||
Runnable actionRunnable = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
// We have not been cancelled! (yet)
|
||||
mActionCanceled.set(false);
|
||||
|
||||
Bundle extras = intent.getExtras();
|
||||
if (extras == null) {
|
||||
Log.e(Constants.TAG, "Extras bundle is null!");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(extras.containsKey(EXTRA_MESSENGER) || extras.containsKey(EXTRA_DATA) || (intent
|
||||
.getAction() == null))) {
|
||||
Log.e(Constants.TAG,
|
||||
"Extra bundle must contain a messenger, a data bundle, and an action!");
|
||||
return;
|
||||
}
|
||||
|
||||
Uri dataUri = intent.getData();
|
||||
|
||||
mMessenger = (Messenger) extras.get(EXTRA_MESSENGER);
|
||||
Bundle data = extras.getBundle(EXTRA_DATA);
|
||||
if (data == null) {
|
||||
Log.e(Constants.TAG, "data extra is null!");
|
||||
return;
|
||||
}
|
||||
|
||||
Log.logDebugBundle(data, "EXTRA_DATA");
|
||||
|
||||
ProviderHelper providerHelper = new ProviderHelper(mKeychainService);
|
||||
|
||||
String action = intent.getAction();
|
||||
|
||||
// executeServiceMethod action from extra bundle
|
||||
switch (action) {
|
||||
case ACTION_CERTIFY_KEYRING: {
|
||||
|
||||
// Input
|
||||
CertifyActionsParcel parcel = data.getParcelable(CERTIFY_PARCEL);
|
||||
CryptoInputParcel cryptoInput = data.getParcelable(EXTRA_CRYPTO_INPUT);
|
||||
String keyServerUri = data.getString(UPLOAD_KEY_SERVER);
|
||||
|
||||
// Operation
|
||||
CertifyOperation op = new CertifyOperation(mKeychainService, providerHelper, mKeychainService,
|
||||
mActionCanceled);
|
||||
CertifyResult result = op.certify(parcel, cryptoInput, keyServerUri);
|
||||
|
||||
// Result
|
||||
sendMessageToHandler(MessageStatus.OKAY, result);
|
||||
|
||||
break;
|
||||
}
|
||||
case ACTION_CONSOLIDATE: {
|
||||
|
||||
// Operation
|
||||
ConsolidateResult result;
|
||||
if (data.containsKey(CONSOLIDATE_RECOVERY) && data.getBoolean(CONSOLIDATE_RECOVERY)) {
|
||||
result = providerHelper.consolidateDatabaseStep2(mKeychainService);
|
||||
} else {
|
||||
result = providerHelper.consolidateDatabaseStep1(mKeychainService);
|
||||
}
|
||||
|
||||
// Result
|
||||
sendMessageToHandler(MessageStatus.OKAY, result);
|
||||
|
||||
break;
|
||||
}
|
||||
case ACTION_DECRYPT_METADATA: {
|
||||
|
||||
// Input
|
||||
CryptoInputParcel cryptoInput = data.getParcelable(EXTRA_CRYPTO_INPUT);
|
||||
PgpDecryptVerifyInputParcel input = data.getParcelable(DECRYPT_VERIFY_PARCEL);
|
||||
|
||||
// this action is here for compatibility only
|
||||
input.setDecryptMetadataOnly(true);
|
||||
|
||||
// Operation
|
||||
PgpDecryptVerify op = new PgpDecryptVerify(mKeychainService, providerHelper, mKeychainService);
|
||||
DecryptVerifyResult decryptVerifyResult = op.execute(input, cryptoInput);
|
||||
|
||||
// Result
|
||||
sendMessageToHandler(MessageStatus.OKAY, decryptVerifyResult);
|
||||
|
||||
break;
|
||||
}
|
||||
case ACTION_VERIFY_KEYBASE_PROOF: {
|
||||
|
||||
try {
|
||||
Proof proof = new Proof(new JSONObject(data.getString(KEYBASE_PROOF)));
|
||||
setProgress(R.string.keybase_message_fetching_data, 0, 100);
|
||||
|
||||
Prover prover = Prover.findProverFor(proof);
|
||||
|
||||
if (prover == null) {
|
||||
sendProofError(getString(R.string.keybase_no_prover_found) + ": " + proof
|
||||
.getPrettyName());
|
||||
return;
|
||||
}
|
||||
|
||||
if (!prover.fetchProofData()) {
|
||||
sendProofError(prover.getLog(), getString(R.string.keybase_problem_fetching_evidence));
|
||||
return;
|
||||
}
|
||||
String requiredFingerprint = data.getString(KEYBASE_REQUIRED_FINGERPRINT);
|
||||
if (!prover.checkFingerprint(requiredFingerprint)) {
|
||||
sendProofError(getString(R.string.keybase_key_mismatch));
|
||||
return;
|
||||
}
|
||||
|
||||
String domain = prover.dnsTxtCheckRequired();
|
||||
if (domain != null) {
|
||||
DNSMessage dnsQuery = new Client().query(new Question(domain, Record.TYPE.TXT));
|
||||
if (dnsQuery == null) {
|
||||
sendProofError(prover.getLog(), getString(R.string.keybase_dns_query_failure));
|
||||
return;
|
||||
}
|
||||
Record[] records = dnsQuery.getAnswers();
|
||||
List<List<byte[]>> extents = new ArrayList<List<byte[]>>();
|
||||
for (Record r : records) {
|
||||
Data d = r.getPayload();
|
||||
if (d instanceof TXT) {
|
||||
extents.add(((TXT) d).getExtents());
|
||||
}
|
||||
}
|
||||
if (!prover.checkDnsTxt(extents)) {
|
||||
sendProofError(prover.getLog(), null);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
byte[] messageBytes = prover.getPgpMessage().getBytes();
|
||||
if (prover.rawMessageCheckRequired()) {
|
||||
InputStream messageByteStream = PGPUtil.getDecoderStream(new ByteArrayInputStream
|
||||
(messageBytes));
|
||||
if (!prover.checkRawMessageBytes(messageByteStream)) {
|
||||
sendProofError(prover.getLog(), null);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
PgpDecryptVerify op = new PgpDecryptVerify(mKeychainService, providerHelper,
|
||||
mKeychainService);
|
||||
|
||||
PgpDecryptVerifyInputParcel input = new PgpDecryptVerifyInputParcel(messageBytes)
|
||||
.setSignedLiteralData(true)
|
||||
.setRequiredSignerFingerprint(requiredFingerprint);
|
||||
|
||||
DecryptVerifyResult decryptVerifyResult = op.execute(input, new CryptoInputParcel());
|
||||
|
||||
if (!decryptVerifyResult.success()) {
|
||||
OperationLog log = decryptVerifyResult.getLog();
|
||||
OperationResult.LogEntryParcel lastEntry = null;
|
||||
for (OperationResult.LogEntryParcel entry : log) {
|
||||
lastEntry = entry;
|
||||
}
|
||||
sendProofError(getString(lastEntry.mType.getMsgId()));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!prover.validate(new String(decryptVerifyResult.getOutputBytes()))) {
|
||||
sendProofError(getString(R.string.keybase_message_payload_mismatch));
|
||||
return;
|
||||
}
|
||||
|
||||
Bundle resultData = new Bundle();
|
||||
resultData.putString(ServiceProgressHandler.DATA_MESSAGE, "OK");
|
||||
|
||||
// these help the handler construct a useful human-readable message
|
||||
resultData.putString(ServiceProgressHandler.KEYBASE_PROOF_URL, prover.getProofUrl());
|
||||
resultData.putString(ServiceProgressHandler.KEYBASE_PRESENCE_URL, prover.getPresenceUrl());
|
||||
resultData.putString(ServiceProgressHandler.KEYBASE_PRESENCE_LABEL, prover
|
||||
.getPresenceLabel());
|
||||
sendMessageToHandler(MessageStatus.OKAY, resultData);
|
||||
} catch (Exception e) {
|
||||
sendErrorToHandler(e);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case ACTION_DECRYPT_VERIFY: {
|
||||
|
||||
// Input
|
||||
CryptoInputParcel cryptoInput = data.getParcelable(EXTRA_CRYPTO_INPUT);
|
||||
PgpDecryptVerifyInputParcel input = data.getParcelable(DECRYPT_VERIFY_PARCEL);
|
||||
|
||||
// for compatibility
|
||||
// TODO merge with ACTION_DECRYPT_METADATA
|
||||
input.setDecryptMetadataOnly(false);
|
||||
|
||||
// Operation
|
||||
PgpDecryptVerify op = new PgpDecryptVerify(mKeychainService, providerHelper, mKeychainService);
|
||||
DecryptVerifyResult decryptVerifyResult = op.execute(input, cryptoInput);
|
||||
|
||||
// Output
|
||||
sendMessageToHandler(MessageStatus.OKAY, decryptVerifyResult);
|
||||
|
||||
break;
|
||||
}
|
||||
case ACTION_DELETE: {
|
||||
|
||||
// Input
|
||||
long[] masterKeyIds = data.getLongArray(DELETE_KEY_LIST);
|
||||
boolean isSecret = data.getBoolean(DELETE_IS_SECRET);
|
||||
|
||||
// Operation
|
||||
DeleteOperation op = new DeleteOperation(mKeychainService, providerHelper, mKeychainService);
|
||||
DeleteResult result = op.execute(masterKeyIds, isSecret);
|
||||
|
||||
// Result
|
||||
sendMessageToHandler(MessageStatus.OKAY, result);
|
||||
|
||||
break;
|
||||
}
|
||||
case ACTION_EDIT_KEYRING: {
|
||||
|
||||
// Input
|
||||
SaveKeyringParcel saveParcel = data.getParcelable(EDIT_KEYRING_PARCEL);
|
||||
CryptoInputParcel cryptoInput = data.getParcelable(EXTRA_CRYPTO_INPUT);
|
||||
|
||||
// Operation
|
||||
EditKeyOperation op = new EditKeyOperation(mKeychainService, providerHelper,
|
||||
mKeychainService, mActionCanceled);
|
||||
OperationResult result = op.execute(saveParcel, cryptoInput);
|
||||
|
||||
// Result
|
||||
sendMessageToHandler(MessageStatus.OKAY, result);
|
||||
|
||||
break;
|
||||
}
|
||||
case ACTION_PROMOTE_KEYRING: {
|
||||
|
||||
// Input
|
||||
long keyRingId = data.getLong(PROMOTE_MASTER_KEY_ID);
|
||||
byte[] cardAid = data.getByteArray(PROMOTE_CARD_AID);
|
||||
long[] subKeyIds = data.getLongArray(PROMOTE_SUBKEY_IDS);
|
||||
|
||||
// Operation
|
||||
PromoteKeyOperation op = new PromoteKeyOperation(
|
||||
mKeychainService, providerHelper, mKeychainService,
|
||||
mActionCanceled);
|
||||
PromoteKeyResult result = op.execute(keyRingId, cardAid, subKeyIds);
|
||||
|
||||
// Result
|
||||
sendMessageToHandler(MessageStatus.OKAY, result);
|
||||
|
||||
break;
|
||||
}
|
||||
case ACTION_EXPORT_KEYRING: {
|
||||
|
||||
// Input
|
||||
boolean exportSecret = data.getBoolean(EXPORT_SECRET, false);
|
||||
String outputFile = data.getString(EXPORT_FILENAME);
|
||||
Uri outputUri = data.getParcelable(EXPORT_URI);
|
||||
|
||||
boolean exportAll = data.getBoolean(EXPORT_ALL);
|
||||
long[] masterKeyIds = exportAll ? null : data.getLongArray(EXPORT_KEY_RING_MASTER_KEY_ID);
|
||||
|
||||
// Operation
|
||||
ImportExportOperation importExportOperation = new ImportExportOperation(
|
||||
mKeychainService, providerHelper, mKeychainService);
|
||||
ExportResult result;
|
||||
if (outputFile != null) {
|
||||
result = importExportOperation.exportToFile(masterKeyIds, exportSecret, outputFile);
|
||||
} else {
|
||||
result = importExportOperation.exportToUri(masterKeyIds, exportSecret, outputUri);
|
||||
}
|
||||
|
||||
// Result
|
||||
sendMessageToHandler(MessageStatus.OKAY, result);
|
||||
|
||||
break;
|
||||
}
|
||||
case ACTION_IMPORT_KEYRING: {
|
||||
|
||||
// Input
|
||||
String keyServer = data.getString(IMPORT_KEY_SERVER);
|
||||
ArrayList<ParcelableKeyRing> keyList = data.getParcelableArrayList(IMPORT_KEY_LIST);
|
||||
|
||||
// either keyList or cache must be null, no guarantees otherwise
|
||||
if (keyList == null) {// import from file, do serially
|
||||
serialKeyImport(null, keyServer, providerHelper);
|
||||
} else {
|
||||
// if there is more than one key with the same fingerprint, we do a serial import to prevent
|
||||
// https://github.com/open-keychain/open-keychain/issues/1221
|
||||
HashSet<String> keyFingerprintSet = new HashSet<>();
|
||||
for (int i = 0; i < keyList.size(); i++) {
|
||||
keyFingerprintSet.add(keyList.get(i).mExpectedFingerprint);
|
||||
}
|
||||
if (keyFingerprintSet.size() == keyList.size()) {
|
||||
// all keys have unique fingerprints
|
||||
multiThreadedKeyImport(keyList.iterator(), keyList.size(), keyServer);
|
||||
} else {
|
||||
serialKeyImport(keyList, keyServer, providerHelper);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case ACTION_SIGN_ENCRYPT: {
|
||||
|
||||
// Input
|
||||
SignEncryptParcel inputParcel = data.getParcelable(SIGN_ENCRYPT_PARCEL);
|
||||
CryptoInputParcel cryptoInput = data.getParcelable(EXTRA_CRYPTO_INPUT);
|
||||
|
||||
// Operation
|
||||
SignEncryptOperation op = new SignEncryptOperation(
|
||||
mKeychainService, providerHelper, mKeychainService, mActionCanceled);
|
||||
SignEncryptResult result = op.execute(inputParcel, cryptoInput);
|
||||
|
||||
// Result
|
||||
sendMessageToHandler(MessageStatus.OKAY, result);
|
||||
|
||||
break;
|
||||
}
|
||||
case ACTION_UPLOAD_KEYRING: {
|
||||
try {
|
||||
|
||||
// Input
|
||||
String keyServer = data.getString(UPLOAD_KEY_SERVER);
|
||||
// and dataUri!
|
||||
|
||||
// Operation
|
||||
HkpKeyserver server = new HkpKeyserver(keyServer);
|
||||
|
||||
CanonicalizedPublicKeyRing keyring = providerHelper.getCanonicalizedPublicKeyRing(dataUri);
|
||||
ImportExportOperation importExportOperation = new ImportExportOperation(mKeychainService,
|
||||
providerHelper, mKeychainService);
|
||||
|
||||
try {
|
||||
importExportOperation.uploadKeyRingToServer(server, keyring);
|
||||
} catch (Keyserver.AddKeyException e) {
|
||||
throw new PgpGeneralException("Unable to export key to selected server");
|
||||
}
|
||||
|
||||
sendMessageToHandler(MessageStatus.OKAY);
|
||||
} catch (Exception e) {
|
||||
sendErrorToHandler(e);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!intent.getAction().equals(ACTION_IMPORT_KEYRING)) {
|
||||
// import keyring handles stopping service on its own
|
||||
stopSelf();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Thread actionThread = new Thread(actionRunnable);
|
||||
actionThread.start();
|
||||
|
||||
return START_NOT_STICKY;
|
||||
}
|
||||
|
||||
private void sendProofError(List<String> log, String label) {
|
||||
String msg = null;
|
||||
label = (label == null) ? "" : label + ": ";
|
||||
for (String m : log) {
|
||||
Log.e(Constants.TAG, label + m);
|
||||
msg = m;
|
||||
}
|
||||
sendProofError(label + msg);
|
||||
}
|
||||
|
||||
private void sendProofError(String msg) {
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putString(ServiceProgressHandler.DATA_ERROR, msg);
|
||||
sendMessageToHandler(MessageStatus.OKAY, bundle);
|
||||
}
|
||||
|
||||
private void sendErrorToHandler(Exception e) {
|
||||
// TODO: Implement a better exception handling here
|
||||
// contextualize the exception, if necessary
|
||||
String message;
|
||||
if (e instanceof PgpGeneralMsgIdException) {
|
||||
e = ((PgpGeneralMsgIdException) e).getContextualized(mKeychainService);
|
||||
message = e.getMessage();
|
||||
} else {
|
||||
message = e.getMessage();
|
||||
}
|
||||
Log.d(Constants.TAG, "KeychainService Exception: ", e);
|
||||
|
||||
Bundle data = new Bundle();
|
||||
data.putString(ServiceProgressHandler.DATA_ERROR, message);
|
||||
sendMessageToHandler(MessageStatus.EXCEPTION, null, data);
|
||||
}
|
||||
|
||||
private void sendMessageToHandler(MessageStatus status, Integer arg2, Bundle data) {
|
||||
|
||||
Message msg = Message.obtain();
|
||||
assert msg != null;
|
||||
msg.arg1 = status.ordinal();
|
||||
if (arg2 != null) {
|
||||
msg.arg2 = arg2;
|
||||
}
|
||||
if (data != null) {
|
||||
msg.setData(data);
|
||||
}
|
||||
|
||||
try {
|
||||
mMessenger.send(msg);
|
||||
} catch (RemoteException e) {
|
||||
Log.w(Constants.TAG, "Exception sending message, Is handler present?", e);
|
||||
} catch (NullPointerException e) {
|
||||
Log.w(Constants.TAG, "Messenger is null!", e);
|
||||
}
|
||||
}
|
||||
|
||||
private void sendMessageToHandler(MessageStatus status, OperationResult data) {
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putParcelable(OperationResult.EXTRA_RESULT, data);
|
||||
sendMessageToHandler(status, null, bundle);
|
||||
}
|
||||
|
||||
private void sendMessageToHandler(MessageStatus status, Bundle data) {
|
||||
sendMessageToHandler(status, null, data);
|
||||
}
|
||||
|
||||
private void sendMessageToHandler(MessageStatus status) {
|
||||
sendMessageToHandler(status, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set progress of ProgressDialog by sending message to handler on UI thread
|
||||
*/
|
||||
@Override
|
||||
public void setProgress(String message, int progress, int max) {
|
||||
Log.d(Constants.TAG, "Send message by setProgress with progress=" + progress + ", max="
|
||||
+ max);
|
||||
|
||||
Bundle data = new Bundle();
|
||||
if (message != null) {
|
||||
data.putString(ServiceProgressHandler.DATA_MESSAGE, message);
|
||||
}
|
||||
data.putInt(ServiceProgressHandler.DATA_PROGRESS, progress);
|
||||
data.putInt(ServiceProgressHandler.DATA_PROGRESS_MAX, max);
|
||||
|
||||
sendMessageToHandler(MessageStatus.UPDATE_PROGRESS, null, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setProgress(int resourceId, int progress, int max) {
|
||||
setProgress(getString(resourceId), progress, max);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setProgress(int progress, int max) {
|
||||
setProgress(null, progress, max);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPreventCancel() {
|
||||
sendMessageToHandler(MessageStatus.PREVENT_CANCEL);
|
||||
}
|
||||
|
||||
public void serialKeyImport(ArrayList<ParcelableKeyRing> keyList, final String keyServer,
|
||||
ProviderHelper providerHelper) {
|
||||
Log.d(Constants.TAG, "serial key import starting");
|
||||
ParcelableFileCache<ParcelableKeyRing> cache =
|
||||
new ParcelableFileCache<>(mKeychainService, "key_import.pcl");
|
||||
|
||||
// Operation
|
||||
ImportExportOperation importExportOperation = new ImportExportOperation(
|
||||
mKeychainService, providerHelper, mKeychainService,
|
||||
mActionCanceled);
|
||||
// Either list or cache must be null, no guarantees otherwise.
|
||||
ImportKeyResult result = keyList != null
|
||||
? importExportOperation.importKeyRings(keyList, keyServer)
|
||||
: importExportOperation.importKeyRings(cache, keyServer);
|
||||
|
||||
ContactSyncAdapterService.requestSync();
|
||||
// Result
|
||||
sendMessageToHandler(MessageStatus.OKAY, result);
|
||||
|
||||
stopSelf();
|
||||
}
|
||||
|
||||
public void multiThreadedKeyImport(Iterator<ParcelableKeyRing> keyListIterator, int totKeys, final String
|
||||
keyServer) {
|
||||
Log.d(Constants.TAG, "Multi-threaded key import starting");
|
||||
if (keyListIterator != null) {
|
||||
mKeyImportAccumulator = new KeyImportAccumulator(totKeys, mKeychainService);
|
||||
setProgress(0, totKeys);
|
||||
|
||||
final int maxThreads = 200;
|
||||
ExecutorService importExecutor = new ThreadPoolExecutor(0, maxThreads,
|
||||
30L, TimeUnit.SECONDS,
|
||||
new SynchronousQueue<Runnable>());
|
||||
|
||||
while (keyListIterator.hasNext()) {
|
||||
|
||||
final ParcelableKeyRing pkRing = keyListIterator.next();
|
||||
|
||||
Runnable importOperationRunnable = new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
ImportKeyResult result = null;
|
||||
try {
|
||||
ImportExportOperation importExportOperation = new ImportExportOperation(
|
||||
mKeychainService,
|
||||
new ProviderHelper(mKeychainService),
|
||||
mKeyImportAccumulator.getImportProgressable(),
|
||||
mActionCanceled);
|
||||
|
||||
ArrayList<ParcelableKeyRing> list = new ArrayList<>();
|
||||
list.add(pkRing);
|
||||
|
||||
result = importExportOperation.importKeyRings(list,
|
||||
keyServer);
|
||||
} finally {
|
||||
// in the off-chance that importKeyRings does something to crash the
|
||||
// thread before it can call singleKeyRingImportCompleted, our imported
|
||||
// key count will go wrong. This will cause the service to never die,
|
||||
// and the progress dialog to stay displayed. The finally block was
|
||||
// originally meant to ensure singleKeyRingImportCompleted was called,
|
||||
// and checks for null were to be introduced, but in such a scenario,
|
||||
// knowing an uncaught error exists in importKeyRings is more important.
|
||||
|
||||
// if a null gets passed, something wrong is happening. We want a crash.
|
||||
|
||||
mKeyImportAccumulator.singleKeyRingImportCompleted(result);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
importExecutor.execute(importOperationRunnable);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to accumulate the results of individual key imports
|
||||
*/
|
||||
private class KeyImportAccumulator {
|
||||
private OperationResult.OperationLog mImportLog = new OperationResult.OperationLog();
|
||||
private int mTotalKeys;
|
||||
private int mImportedKeys = 0;
|
||||
private Progressable mInternalProgressable;
|
||||
ArrayList<Long> mImportedMasterKeyIds = new ArrayList<Long>();
|
||||
private int mBadKeys = 0;
|
||||
private int mNewKeys = 0;
|
||||
private int mUpdatedKeys = 0;
|
||||
private int mSecret = 0;
|
||||
private int mResultType = 0;
|
||||
|
||||
/**
|
||||
* meant to be used with a service due to stopSelf() in singleKeyRingImportCompleted. Remove this if
|
||||
* generalising.
|
||||
*
|
||||
* @param totalKeys total number of keys to be imported
|
||||
* @param externalProgressable the external progressable to be updated every time a key is imported
|
||||
*/
|
||||
public KeyImportAccumulator(int totalKeys, Progressable externalProgressable) {
|
||||
mTotalKeys = totalKeys;
|
||||
// ignore updates from ImportExportOperation for now
|
||||
mInternalProgressable = new Progressable() {
|
||||
@Override
|
||||
public void setProgress(String message, int current, int total) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setProgress(int resourceId, int current, int total) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setProgress(int current, int total) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPreventCancel() {
|
||||
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private synchronized void singleKeyRingImportCompleted(ImportKeyResult result) {
|
||||
// increase imported key count and accumulate log and bad, new etc. key counts from result
|
||||
mKeyImportAccumulator.accumulateKeyImport(result);
|
||||
|
||||
setProgress(mKeyImportAccumulator.getImportedKeys(), mKeyImportAccumulator.getTotalKeys());
|
||||
|
||||
if (mKeyImportAccumulator.isImportFinished()) {
|
||||
ContactSyncAdapterService.requestSync();
|
||||
|
||||
sendMessageToHandler(ServiceProgressHandler.MessageStatus.OKAY,
|
||||
mKeyImportAccumulator.getConsolidatedImportKeyResult());
|
||||
|
||||
stopSelf();//we're done here
|
||||
}
|
||||
}
|
||||
|
||||
public Progressable getImportProgressable() {
|
||||
return mInternalProgressable;
|
||||
}
|
||||
|
||||
public int getTotalKeys() {
|
||||
return mTotalKeys;
|
||||
}
|
||||
|
||||
public int getImportedKeys() {
|
||||
return mImportedKeys;
|
||||
}
|
||||
|
||||
public synchronized void accumulateKeyImport(ImportKeyResult result) {
|
||||
mImportedKeys++;
|
||||
mImportLog.addAll(result.getLog().toList());//accumulates log
|
||||
mBadKeys += result.mBadKeys;
|
||||
mNewKeys += result.mNewKeys;
|
||||
mUpdatedKeys += result.mUpdatedKeys;
|
||||
mSecret += result.mSecret;
|
||||
|
||||
long[] masterKeyIds = result.getImportedMasterKeyIds();
|
||||
for (long masterKeyId : masterKeyIds) {
|
||||
mImportedMasterKeyIds.add(masterKeyId);
|
||||
}
|
||||
|
||||
// if any key import has been cancelled, set result type to cancelled
|
||||
// resultType is added to in getConsolidatedKayImport to account for remaining factors
|
||||
mResultType |= result.getResult() & ImportKeyResult.RESULT_CANCELLED;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns accumulated result of all imports so far
|
||||
*/
|
||||
public ImportKeyResult getConsolidatedImportKeyResult() {
|
||||
|
||||
// adding required information to mResultType
|
||||
// special case,no keys requested for import
|
||||
if (mBadKeys == 0 && mNewKeys == 0 && mUpdatedKeys == 0) {
|
||||
mResultType = ImportKeyResult.RESULT_FAIL_NOTHING;
|
||||
} else {
|
||||
if (mNewKeys > 0) {
|
||||
mResultType |= ImportKeyResult.RESULT_OK_NEWKEYS;
|
||||
}
|
||||
if (mUpdatedKeys > 0) {
|
||||
mResultType |= ImportKeyResult.RESULT_OK_UPDATED;
|
||||
}
|
||||
if (mBadKeys > 0) {
|
||||
mResultType |= ImportKeyResult.RESULT_WITH_ERRORS;
|
||||
if (mNewKeys == 0 && mUpdatedKeys == 0) {
|
||||
mResultType |= ImportKeyResult.RESULT_ERROR;
|
||||
}
|
||||
}
|
||||
if (mImportLog.containsWarnings()) {
|
||||
mResultType |= ImportKeyResult.RESULT_WARNINGS;
|
||||
}
|
||||
}
|
||||
|
||||
long masterKeyIds[] = new long[mImportedMasterKeyIds.size()];
|
||||
for (int i = 0; i < masterKeyIds.length; i++) {
|
||||
masterKeyIds[i] = mImportedMasterKeyIds.get(i);
|
||||
}
|
||||
|
||||
return new ImportKeyResult(mResultType, mImportLog, mNewKeys, mUpdatedKeys, mBadKeys,
|
||||
mSecret, masterKeyIds);
|
||||
}
|
||||
|
||||
public boolean isImportFinished() {
|
||||
return mTotalKeys == mImportedKeys;
|
||||
}
|
||||
}
|
||||
}
|
@ -18,14 +18,16 @@
|
||||
package org.sufficientlysecure.keychain.service;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.FragmentManager;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.Message;
|
||||
import android.support.v4.app.FragmentActivity;
|
||||
import android.support.v4.app.FragmentManager;
|
||||
|
||||
import org.sufficientlysecure.keychain.Constants;
|
||||
import org.sufficientlysecure.keychain.R;
|
||||
import org.sufficientlysecure.keychain.operations.results.CertifyResult;
|
||||
import org.sufficientlysecure.keychain.ui.dialog.ProgressDialogFragment;
|
||||
import org.sufficientlysecure.keychain.ui.util.Notify;
|
||||
import org.sufficientlysecure.keychain.util.Log;
|
||||
@ -33,7 +35,7 @@ import org.sufficientlysecure.keychain.util.Log;
|
||||
public class ServiceProgressHandler extends Handler {
|
||||
|
||||
// possible messages sent from this service to handler on ui
|
||||
public static enum MessageStatus{
|
||||
public enum MessageStatus {
|
||||
UNKNOWN,
|
||||
OKAY,
|
||||
EXCEPTION,
|
||||
@ -42,9 +44,8 @@ public class ServiceProgressHandler extends Handler {
|
||||
|
||||
private static final MessageStatus[] values = values();
|
||||
|
||||
public static MessageStatus fromInt(int n)
|
||||
{
|
||||
if(n < 0 || n >= values.length) {
|
||||
public static MessageStatus fromInt(int n) {
|
||||
if (n < 0 || n >= values.length) {
|
||||
return UNKNOWN;
|
||||
} else {
|
||||
return values[n];
|
||||
@ -71,30 +72,24 @@ public class ServiceProgressHandler extends Handler {
|
||||
this.mActivity = activity;
|
||||
}
|
||||
|
||||
public ServiceProgressHandler(Activity activity,
|
||||
ProgressDialogFragment progressDialogFragment) {
|
||||
public ServiceProgressHandler(Activity activity, ProgressDialogFragment progressDialogFragment) {
|
||||
this.mActivity = activity;
|
||||
this.mProgressDialogFragment = progressDialogFragment;
|
||||
}
|
||||
|
||||
public ServiceProgressHandler(Activity activity,
|
||||
String progressDialogMessage,
|
||||
int progressDialogStyle,
|
||||
ProgressDialogFragment.ServiceType serviceType) {
|
||||
this(activity, progressDialogMessage, progressDialogStyle, false, serviceType);
|
||||
public ServiceProgressHandler(Activity activity, String progressDialogMessage, int progressDialogStyle) {
|
||||
this(activity, progressDialogMessage, progressDialogStyle, false);
|
||||
}
|
||||
|
||||
public ServiceProgressHandler(Activity activity,
|
||||
String progressDialogMessage,
|
||||
int progressDialogStyle,
|
||||
boolean cancelable,
|
||||
ProgressDialogFragment.ServiceType serviceType) {
|
||||
boolean cancelable) {
|
||||
this.mActivity = activity;
|
||||
this.mProgressDialogFragment = ProgressDialogFragment.newInstance(
|
||||
progressDialogMessage,
|
||||
progressDialogStyle,
|
||||
cancelable,
|
||||
serviceType);
|
||||
cancelable);
|
||||
}
|
||||
|
||||
public void showProgressDialog(FragmentActivity activity) {
|
||||
@ -104,7 +99,7 @@ public class ServiceProgressHandler extends Handler {
|
||||
|
||||
// TODO: This is a hack!, see
|
||||
// http://stackoverflow.com/questions/10114324/show-dialogfragment-from-onactivityresult
|
||||
final FragmentManager manager = activity.getFragmentManager();
|
||||
final FragmentManager manager = activity.getSupportFragmentManager();
|
||||
Handler handler = new Handler();
|
||||
handler.post(new Runnable() {
|
||||
public void run() {
|
||||
|
@ -52,12 +52,11 @@ import org.sufficientlysecure.keychain.provider.KeychainDatabase.Tables;
|
||||
import org.sufficientlysecure.keychain.provider.ProviderHelper;
|
||||
import org.sufficientlysecure.keychain.service.CertifyActionsParcel;
|
||||
import org.sufficientlysecure.keychain.service.CertifyActionsParcel.CertifyAction;
|
||||
import org.sufficientlysecure.keychain.service.KeychainIntentService;
|
||||
import org.sufficientlysecure.keychain.service.KeychainService;
|
||||
import org.sufficientlysecure.keychain.service.ServiceProgressHandler;
|
||||
import org.sufficientlysecure.keychain.service.input.CryptoInputParcel;
|
||||
import org.sufficientlysecure.keychain.ui.adapter.MultiUserIdsAdapter;
|
||||
import org.sufficientlysecure.keychain.ui.base.CachingCryptoOperationFragment;
|
||||
import org.sufficientlysecure.keychain.ui.dialog.ProgressDialogFragment;
|
||||
import org.sufficientlysecure.keychain.ui.util.Notify;
|
||||
import org.sufficientlysecure.keychain.ui.widget.CertifyKeySpinner;
|
||||
import org.sufficientlysecure.keychain.util.Log;
|
||||
@ -104,7 +103,7 @@ public class CertifyKeyFragment extends CachingCryptoOperationFragment<CertifyAc
|
||||
}
|
||||
|
||||
mPassthroughMessenger = getActivity().getIntent().getParcelableExtra(
|
||||
KeychainIntentService.EXTRA_MESSENGER);
|
||||
KeychainService.EXTRA_MESSENGER);
|
||||
mPassthroughMessenger = null; // TODO doesn't work with CryptoOperationFragment, disabled for now
|
||||
|
||||
ArrayList<Boolean> checkedStates;
|
||||
@ -330,31 +329,32 @@ public class CertifyKeyFragment extends CachingCryptoOperationFragment<CertifyAc
|
||||
cacheActionsParcel(actionsParcel);
|
||||
}
|
||||
|
||||
data.putParcelable(KeychainIntentService.EXTRA_CRYPTO_INPUT, cryptoInput);
|
||||
data.putParcelable(KeychainIntentService.CERTIFY_PARCEL, actionsParcel);
|
||||
data.putParcelable(KeychainService.EXTRA_CRYPTO_INPUT, cryptoInput);
|
||||
data.putParcelable(KeychainService.CERTIFY_PARCEL, actionsParcel);
|
||||
|
||||
if (mUploadKeyCheckbox.isChecked()) {
|
||||
String keyserver = Preferences.getPreferences(getActivity()).getPreferredKeyserver();
|
||||
data.putString(KeychainIntentService.UPLOAD_KEY_SERVER, keyserver);
|
||||
data.putString(KeychainService.UPLOAD_KEY_SERVER, keyserver);
|
||||
}
|
||||
}
|
||||
|
||||
// Send all information needed to service to sign key in other thread
|
||||
Intent intent = new Intent(getActivity(), KeychainIntentService.class);
|
||||
intent.setAction(KeychainIntentService.ACTION_CERTIFY_KEYRING);
|
||||
intent.putExtra(KeychainIntentService.EXTRA_DATA, data);
|
||||
Intent intent = new Intent(getActivity(), KeychainService.class);
|
||||
intent.setAction(KeychainService.ACTION_CERTIFY_KEYRING);
|
||||
intent.putExtra(KeychainService.EXTRA_DATA, data);
|
||||
|
||||
if (mPassthroughMessenger != null) {
|
||||
intent.putExtra(KeychainIntentService.EXTRA_MESSENGER, mPassthroughMessenger);
|
||||
intent.putExtra(KeychainService.EXTRA_MESSENGER, mPassthroughMessenger);
|
||||
} else {
|
||||
|
||||
// Message is received after signing is done in KeychainIntentService
|
||||
// Message is received after signing is done in KeychainService
|
||||
ServiceProgressHandler saveHandler = new ServiceProgressHandler(
|
||||
getActivity(),
|
||||
getString(R.string.progress_certifying),
|
||||
ProgressDialog.STYLE_SPINNER,
|
||||
true,
|
||||
ProgressDialogFragment.ServiceType.KEYCHAIN_INTENT) {
|
||||
true
|
||||
) {
|
||||
@Override
|
||||
public void handleMessage(Message message) {
|
||||
// handle messages by KeychainIntentCryptoServiceHandler first
|
||||
super.handleMessage(message);
|
||||
@ -379,7 +379,7 @@ public class CertifyKeyFragment extends CachingCryptoOperationFragment<CertifyAc
|
||||
|
||||
// Create a new Messenger for the communication back
|
||||
Messenger messenger = new Messenger(saveHandler);
|
||||
intent.putExtra(KeychainIntentService.EXTRA_MESSENGER, messenger);
|
||||
intent.putExtra(KeychainService.EXTRA_MESSENGER, messenger);
|
||||
|
||||
// show progress dialog
|
||||
saveHandler.showProgressDialog(getActivity());
|
||||
|
@ -25,9 +25,8 @@ import android.os.Messenger;
|
||||
import android.support.v4.app.FragmentActivity;
|
||||
|
||||
import org.sufficientlysecure.keychain.R;
|
||||
import org.sufficientlysecure.keychain.service.KeychainIntentService;
|
||||
import org.sufficientlysecure.keychain.service.KeychainService;
|
||||
import org.sufficientlysecure.keychain.service.ServiceProgressHandler;
|
||||
import org.sufficientlysecure.keychain.ui.dialog.ProgressDialogFragment;
|
||||
|
||||
/**
|
||||
* We can not directly create a dialog on the application context.
|
||||
@ -49,12 +48,13 @@ public class ConsolidateDialogActivity extends FragmentActivity {
|
||||
}
|
||||
|
||||
private void consolidateRecovery(boolean recovery) {
|
||||
// Message is received after importing is done in KeychainIntentService
|
||||
// Message is received after importing is done in KeychainService
|
||||
ServiceProgressHandler saveHandler = new ServiceProgressHandler(
|
||||
this,
|
||||
getString(R.string.progress_importing),
|
||||
ProgressDialog.STYLE_HORIZONTAL,
|
||||
ProgressDialogFragment.ServiceType.KEYCHAIN_INTENT) {
|
||||
ProgressDialog.STYLE_HORIZONTAL
|
||||
) {
|
||||
@Override
|
||||
public void handleMessage(Message message) {
|
||||
// handle messages by standard KeychainIntentServiceHandler first
|
||||
super.handleMessage(message);
|
||||
@ -68,7 +68,7 @@ public class ConsolidateDialogActivity extends FragmentActivity {
|
||||
return;
|
||||
}
|
||||
final ConsolidateResult result =
|
||||
returnData.getParcelable(KeychainIntentService.RESULT_CONSOLIDATE);
|
||||
returnData.getParcelable(KeychainService.RESULT_CONSOLIDATE);
|
||||
if (result == null) {
|
||||
return;
|
||||
}
|
||||
@ -81,17 +81,17 @@ public class ConsolidateDialogActivity extends FragmentActivity {
|
||||
};
|
||||
|
||||
// Send all information needed to service to import key in other thread
|
||||
Intent intent = new Intent(this, KeychainIntentService.class);
|
||||
intent.setAction(KeychainIntentService.ACTION_CONSOLIDATE);
|
||||
Intent intent = new Intent(this, KeychainService.class);
|
||||
intent.setAction(KeychainService.ACTION_CONSOLIDATE);
|
||||
|
||||
// fill values for this action
|
||||
Bundle data = new Bundle();
|
||||
data.putBoolean(KeychainIntentService.CONSOLIDATE_RECOVERY, recovery);
|
||||
intent.putExtra(KeychainIntentService.EXTRA_DATA, data);
|
||||
data.putBoolean(KeychainService.CONSOLIDATE_RECOVERY, recovery);
|
||||
intent.putExtra(KeychainService.EXTRA_DATA, data);
|
||||
|
||||
// Create a new Messenger for the communication back
|
||||
Messenger messenger = new Messenger(saveHandler);
|
||||
intent.putExtra(KeychainIntentService.EXTRA_MESSENGER, messenger);
|
||||
intent.putExtra(KeychainService.EXTRA_MESSENGER, messenger);
|
||||
|
||||
// show progress dialog
|
||||
saveHandler.showProgressDialog(this);
|
||||
|
@ -38,13 +38,12 @@ import org.sufficientlysecure.keychain.operations.results.EditKeyResult;
|
||||
import org.sufficientlysecure.keychain.operations.results.OperationResult;
|
||||
import org.sufficientlysecure.keychain.pgp.KeyRing;
|
||||
import org.sufficientlysecure.keychain.provider.KeychainContract;
|
||||
import org.sufficientlysecure.keychain.service.KeychainIntentService;
|
||||
import org.sufficientlysecure.keychain.service.KeychainService;
|
||||
import org.sufficientlysecure.keychain.service.ServiceProgressHandler;
|
||||
import org.sufficientlysecure.keychain.service.SaveKeyringParcel;
|
||||
import org.sufficientlysecure.keychain.service.SaveKeyringParcel.Algorithm;
|
||||
import org.sufficientlysecure.keychain.service.SaveKeyringParcel.ChangeUnlockParcel;
|
||||
import org.sufficientlysecure.keychain.ui.CreateKeyActivity.FragAction;
|
||||
import org.sufficientlysecure.keychain.ui.dialog.ProgressDialogFragment;
|
||||
import org.sufficientlysecure.keychain.util.Log;
|
||||
import org.sufficientlysecure.keychain.util.Preferences;
|
||||
|
||||
@ -195,14 +194,15 @@ public class CreateKeyFinalFragment extends Fragment {
|
||||
|
||||
|
||||
private void createKey() {
|
||||
Intent intent = new Intent(getActivity(), KeychainIntentService.class);
|
||||
intent.setAction(KeychainIntentService.ACTION_EDIT_KEYRING);
|
||||
Intent intent = new Intent(getActivity(), KeychainService.class);
|
||||
intent.setAction(KeychainService.ACTION_EDIT_KEYRING);
|
||||
|
||||
ServiceProgressHandler saveHandler = new ServiceProgressHandler(
|
||||
getActivity(),
|
||||
getString(R.string.progress_building_key),
|
||||
ProgressDialog.STYLE_HORIZONTAL,
|
||||
ProgressDialogFragment.ServiceType.KEYCHAIN_INTENT) {
|
||||
ProgressDialog.STYLE_HORIZONTAL
|
||||
) {
|
||||
@Override
|
||||
public void handleMessage(Message message) {
|
||||
// handle messages by standard KeychainIntentServiceHandler first
|
||||
super.handleMessage(message);
|
||||
@ -237,13 +237,13 @@ public class CreateKeyFinalFragment extends Fragment {
|
||||
Bundle data = new Bundle();
|
||||
|
||||
// get selected key entries
|
||||
data.putParcelable(KeychainIntentService.EDIT_KEYRING_PARCEL, mSaveKeyringParcel);
|
||||
data.putParcelable(KeychainService.EDIT_KEYRING_PARCEL, mSaveKeyringParcel);
|
||||
|
||||
intent.putExtra(KeychainIntentService.EXTRA_DATA, data);
|
||||
intent.putExtra(KeychainService.EXTRA_DATA, data);
|
||||
|
||||
// Create a new Messenger for the communication back
|
||||
Messenger messenger = new Messenger(saveHandler);
|
||||
intent.putExtra(KeychainIntentService.EXTRA_MESSENGER, messenger);
|
||||
intent.putExtra(KeychainService.EXTRA_MESSENGER, messenger);
|
||||
|
||||
saveHandler.showProgressDialog(getActivity());
|
||||
|
||||
@ -253,9 +253,9 @@ public class CreateKeyFinalFragment extends Fragment {
|
||||
// TODO move into EditKeyOperation
|
||||
private void uploadKey(final EditKeyResult saveKeyResult) {
|
||||
// Send all information needed to service to upload key in other thread
|
||||
final Intent intent = new Intent(getActivity(), KeychainIntentService.class);
|
||||
final Intent intent = new Intent(getActivity(), KeychainService.class);
|
||||
|
||||
intent.setAction(KeychainIntentService.ACTION_UPLOAD_KEYRING);
|
||||
intent.setAction(KeychainService.ACTION_UPLOAD_KEYRING);
|
||||
|
||||
// set data uri as path to keyring
|
||||
Uri blobUri = KeychainContract.KeyRings.buildUnifiedKeyRingUri(
|
||||
@ -267,15 +267,16 @@ public class CreateKeyFinalFragment extends Fragment {
|
||||
|
||||
// upload to favorite keyserver
|
||||
String keyserver = Preferences.getPreferences(getActivity()).getPreferredKeyserver();
|
||||
data.putString(KeychainIntentService.UPLOAD_KEY_SERVER, keyserver);
|
||||
data.putString(KeychainService.UPLOAD_KEY_SERVER, keyserver);
|
||||
|
||||
intent.putExtra(KeychainIntentService.EXTRA_DATA, data);
|
||||
intent.putExtra(KeychainService.EXTRA_DATA, data);
|
||||
|
||||
ServiceProgressHandler saveHandler = new ServiceProgressHandler(
|
||||
getActivity(),
|
||||
getString(R.string.progress_uploading),
|
||||
ProgressDialog.STYLE_HORIZONTAL,
|
||||
ProgressDialogFragment.ServiceType.KEYCHAIN_INTENT) {
|
||||
ProgressDialog.STYLE_HORIZONTAL
|
||||
) {
|
||||
@Override
|
||||
public void handleMessage(Message message) {
|
||||
// handle messages by standard KeychainIntentServiceHandler first
|
||||
super.handleMessage(message);
|
||||
@ -297,7 +298,7 @@ public class CreateKeyFinalFragment extends Fragment {
|
||||
|
||||
// Create a new Messenger for the communication back
|
||||
Messenger messenger = new Messenger(saveHandler);
|
||||
intent.putExtra(KeychainIntentService.EXTRA_MESSENGER, messenger);
|
||||
intent.putExtra(KeychainService.EXTRA_MESSENGER, messenger);
|
||||
|
||||
// show progress dialog
|
||||
saveHandler.showProgressDialog(getActivity());
|
||||
|
@ -40,11 +40,10 @@ import org.sufficientlysecure.keychain.keyimport.ParcelableKeyRing;
|
||||
import org.sufficientlysecure.keychain.operations.results.DecryptVerifyResult;
|
||||
import org.sufficientlysecure.keychain.operations.results.ImportKeyResult;
|
||||
import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
|
||||
import org.sufficientlysecure.keychain.service.KeychainIntentService;
|
||||
import org.sufficientlysecure.keychain.service.KeychainService;
|
||||
import org.sufficientlysecure.keychain.service.ServiceProgressHandler;
|
||||
import org.sufficientlysecure.keychain.ui.CreateKeyActivity.FragAction;
|
||||
import org.sufficientlysecure.keychain.ui.CreateKeyActivity.NfcListenerFragment;
|
||||
import org.sufficientlysecure.keychain.ui.dialog.ProgressDialogFragment;
|
||||
import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
|
||||
import org.sufficientlysecure.keychain.util.Preferences;
|
||||
|
||||
@ -176,13 +175,13 @@ public class CreateKeyYubiKeyImportFragment extends Fragment implements NfcListe
|
||||
|
||||
public void importKey() {
|
||||
|
||||
// Message is received after decrypting is done in KeychainIntentService
|
||||
// Message is received after decrypting is done in KeychainService
|
||||
ServiceProgressHandler saveHandler = new ServiceProgressHandler(
|
||||
getActivity(),
|
||||
getString(R.string.progress_importing),
|
||||
ProgressDialog.STYLE_HORIZONTAL,
|
||||
ProgressDialogFragment.ServiceType.KEYCHAIN_INTENT
|
||||
ProgressDialog.STYLE_HORIZONTAL
|
||||
) {
|
||||
@Override
|
||||
public void handleMessage(Message message) {
|
||||
// handle messages by standard KeychainIntentServiceHandler first
|
||||
super.handleMessage(message);
|
||||
@ -220,29 +219,29 @@ public class CreateKeyYubiKeyImportFragment extends Fragment implements NfcListe
|
||||
};
|
||||
|
||||
// Send all information needed to service to decrypt in other thread
|
||||
Intent intent = new Intent(getActivity(), KeychainIntentService.class);
|
||||
Intent intent = new Intent(getActivity(), KeychainService.class);
|
||||
|
||||
// fill values for this action
|
||||
Bundle data = new Bundle();
|
||||
|
||||
intent.setAction(KeychainIntentService.ACTION_IMPORT_KEYRING);
|
||||
intent.setAction(KeychainService.ACTION_IMPORT_KEYRING);
|
||||
|
||||
ArrayList<ParcelableKeyRing> keyList = new ArrayList<>();
|
||||
keyList.add(new ParcelableKeyRing(mNfcFingerprint, null, null));
|
||||
data.putParcelableArrayList(KeychainIntentService.IMPORT_KEY_LIST, keyList);
|
||||
data.putParcelableArrayList(KeychainService.IMPORT_KEY_LIST, keyList);
|
||||
|
||||
{
|
||||
Preferences prefs = Preferences.getPreferences(getActivity());
|
||||
Preferences.CloudSearchPrefs cloudPrefs =
|
||||
new Preferences.CloudSearchPrefs(true, true, prefs.getPreferredKeyserver());
|
||||
data.putString(KeychainIntentService.IMPORT_KEY_SERVER, cloudPrefs.keyserver);
|
||||
data.putString(KeychainService.IMPORT_KEY_SERVER, cloudPrefs.keyserver);
|
||||
}
|
||||
|
||||
intent.putExtra(KeychainIntentService.EXTRA_DATA, data);
|
||||
intent.putExtra(KeychainService.EXTRA_DATA, data);
|
||||
|
||||
// Create a new Messenger for the communication back
|
||||
Messenger messenger = new Messenger(saveHandler);
|
||||
intent.putExtra(KeychainIntentService.EXTRA_MESSENGER, messenger);
|
||||
intent.putExtra(KeychainService.EXTRA_MESSENGER, messenger);
|
||||
|
||||
saveHandler.showProgressDialog(getActivity());
|
||||
|
||||
|
@ -61,22 +61,25 @@ import org.sufficientlysecure.keychain.operations.results.DecryptVerifyResult;
|
||||
import org.sufficientlysecure.keychain.pgp.PgpDecryptVerifyInputParcel;
|
||||
import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
|
||||
import org.sufficientlysecure.keychain.provider.TemporaryStorageProvider;
|
||||
import org.sufficientlysecure.keychain.service.KeychainIntentService;
|
||||
import org.sufficientlysecure.keychain.service.KeychainService;
|
||||
import org.sufficientlysecure.keychain.service.ServiceProgressHandler;
|
||||
import org.sufficientlysecure.keychain.service.ServiceProgressHandler.MessageStatus;
|
||||
import org.sufficientlysecure.keychain.service.input.CryptoInputParcel;
|
||||
// this import NEEDS to be above the ViewModel one, or it won't compile! (as of 06/06/15)
|
||||
import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils.StatusHolder;
|
||||
import org.sufficientlysecure.keychain.ui.DecryptFilesListFragment.DecryptFilesAdapter.ViewModel;
|
||||
import org.sufficientlysecure.keychain.ui.adapter.SpacesItemDecoration;
|
||||
import org.sufficientlysecure.keychain.ui.base.CryptoOperationFragment;
|
||||
import org.sufficientlysecure.keychain.ui.util.FormattingUtils;
|
||||
import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
|
||||
import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils.StatusHolder;
|
||||
import org.sufficientlysecure.keychain.ui.util.Notify;
|
||||
import org.sufficientlysecure.keychain.ui.util.Notify.Style;
|
||||
import org.sufficientlysecure.keychain.util.FileHelper;
|
||||
import org.sufficientlysecure.keychain.util.Log;
|
||||
|
||||
public class DecryptFilesListFragment extends CryptoOperationFragment implements OnMenuItemClickListener {
|
||||
public class DecryptFilesListFragment
|
||||
extends CryptoOperationFragment
|
||||
implements OnMenuItemClickListener {
|
||||
public static final String ARG_URIS = "uris";
|
||||
|
||||
private static final int REQUEST_CODE_OUTPUT = 0x00007007;
|
||||
@ -264,12 +267,12 @@ public class DecryptFilesListFragment extends CryptoOperationFragment implements
|
||||
}
|
||||
|
||||
// Send all information needed to service to decrypt in other thread
|
||||
Intent intent = new Intent(getActivity(), KeychainIntentService.class);
|
||||
Intent intent = new Intent(getActivity(), KeychainService.class);
|
||||
|
||||
// fill values for this action
|
||||
Bundle data = new Bundle();
|
||||
// use current operation, either decrypt metadata or decrypt payload
|
||||
intent.setAction(KeychainIntentService.ACTION_DECRYPT_VERIFY);
|
||||
intent.setAction(KeychainService.ACTION_DECRYPT_VERIFY);
|
||||
|
||||
// data
|
||||
|
||||
@ -279,10 +282,10 @@ public class DecryptFilesListFragment extends CryptoOperationFragment implements
|
||||
PgpDecryptVerifyInputParcel input = new PgpDecryptVerifyInputParcel(mCurrentInputUri, currentOutputUri)
|
||||
.setAllowSymmetricDecryption(true);
|
||||
|
||||
data.putParcelable(KeychainIntentService.DECRYPT_VERIFY_PARCEL, input);
|
||||
data.putParcelable(KeychainIntentService.EXTRA_CRYPTO_INPUT, cryptoInput);
|
||||
data.putParcelable(KeychainService.DECRYPT_VERIFY_PARCEL, input);
|
||||
data.putParcelable(KeychainService.EXTRA_CRYPTO_INPUT, cryptoInput);
|
||||
|
||||
intent.putExtra(KeychainIntentService.EXTRA_DATA, data);
|
||||
intent.putExtra(KeychainService.EXTRA_DATA, data);
|
||||
|
||||
// Message is received after decrypting is done in KeychainIntentService
|
||||
Handler saveHandler = new Handler() {
|
||||
@ -344,7 +347,7 @@ public class DecryptFilesListFragment extends CryptoOperationFragment implements
|
||||
|
||||
// Create a new Messenger for the communication back
|
||||
Messenger messenger = new Messenger(saveHandler);
|
||||
intent.putExtra(KeychainIntentService.EXTRA_MESSENGER, messenger);
|
||||
intent.putExtra(KeychainService.EXTRA_MESSENGER, messenger);
|
||||
|
||||
// start service with intent
|
||||
getActivity().startService(intent);
|
||||
|
@ -47,7 +47,7 @@ import org.sufficientlysecure.keychain.pgp.exception.PgpKeyNotFoundException;
|
||||
import org.sufficientlysecure.keychain.provider.KeychainContract;
|
||||
import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
|
||||
import org.sufficientlysecure.keychain.provider.ProviderHelper;
|
||||
import org.sufficientlysecure.keychain.service.KeychainIntentService;
|
||||
import org.sufficientlysecure.keychain.service.KeychainService;
|
||||
import org.sufficientlysecure.keychain.service.ServiceProgressHandler;
|
||||
import org.sufficientlysecure.keychain.ui.base.CryptoOperationFragment;
|
||||
import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
|
||||
@ -130,8 +130,9 @@ public abstract class DecryptFragment extends CryptoOperationFragment implements
|
||||
|
||||
private void lookupUnknownKey(long unknownKeyId) {
|
||||
|
||||
// Message is received after importing is done in KeychainIntentService
|
||||
// Message is received after importing is done in KeychainService
|
||||
ServiceProgressHandler serviceHandler = new ServiceProgressHandler(getActivity()) {
|
||||
@Override
|
||||
public void handleMessage(Message message) {
|
||||
// handle messages by standard KeychainIntentServiceHandler first
|
||||
super.handleMessage(message);
|
||||
@ -162,7 +163,7 @@ public abstract class DecryptFragment extends CryptoOperationFragment implements
|
||||
Preferences prefs = Preferences.getPreferences(getActivity());
|
||||
Preferences.CloudSearchPrefs cloudPrefs =
|
||||
new Preferences.CloudSearchPrefs(true, true, prefs.getPreferredKeyserver());
|
||||
data.putString(KeychainIntentService.IMPORT_KEY_SERVER, cloudPrefs.keyserver);
|
||||
data.putString(KeychainService.IMPORT_KEY_SERVER, cloudPrefs.keyserver);
|
||||
}
|
||||
|
||||
{
|
||||
@ -171,17 +172,17 @@ public abstract class DecryptFragment extends CryptoOperationFragment implements
|
||||
ArrayList<ParcelableKeyRing> selectedEntries = new ArrayList<>();
|
||||
selectedEntries.add(keyEntry);
|
||||
|
||||
data.putParcelableArrayList(KeychainIntentService.IMPORT_KEY_LIST, selectedEntries);
|
||||
data.putParcelableArrayList(KeychainService.IMPORT_KEY_LIST, selectedEntries);
|
||||
}
|
||||
|
||||
// Send all information needed to service to query keys in other thread
|
||||
Intent intent = new Intent(getActivity(), KeychainIntentService.class);
|
||||
intent.setAction(KeychainIntentService.ACTION_IMPORT_KEYRING);
|
||||
intent.putExtra(KeychainIntentService.EXTRA_DATA, data);
|
||||
Intent intent = new Intent(getActivity(), KeychainService.class);
|
||||
intent.setAction(KeychainService.ACTION_IMPORT_KEYRING);
|
||||
intent.putExtra(KeychainService.EXTRA_DATA, data);
|
||||
|
||||
// Create a new Messenger for the communication back
|
||||
Messenger messenger = new Messenger(serviceHandler);
|
||||
intent.putExtra(KeychainIntentService.EXTRA_MESSENGER, messenger);
|
||||
intent.putExtra(KeychainService.EXTRA_MESSENGER, messenger);
|
||||
|
||||
getActivity().startService(intent);
|
||||
}
|
||||
|
@ -35,10 +35,9 @@ import org.sufficientlysecure.keychain.R;
|
||||
import org.sufficientlysecure.keychain.compatibility.ClipboardReflection;
|
||||
import org.sufficientlysecure.keychain.operations.results.DecryptVerifyResult;
|
||||
import org.sufficientlysecure.keychain.pgp.PgpDecryptVerifyInputParcel;
|
||||
import org.sufficientlysecure.keychain.service.KeychainIntentService;
|
||||
import org.sufficientlysecure.keychain.service.KeychainService;
|
||||
import org.sufficientlysecure.keychain.service.ServiceProgressHandler;
|
||||
import org.sufficientlysecure.keychain.service.input.CryptoInputParcel;
|
||||
import org.sufficientlysecure.keychain.ui.dialog.ProgressDialogFragment;
|
||||
import org.sufficientlysecure.keychain.ui.util.Notify;
|
||||
import org.sufficientlysecure.keychain.util.ShareHelper;
|
||||
|
||||
@ -161,25 +160,25 @@ public class DecryptTextFragment extends DecryptFragment {
|
||||
@Override
|
||||
protected void cryptoOperation(CryptoInputParcel cryptoInput) {
|
||||
// Send all information needed to service to decrypt in other thread
|
||||
Intent intent = new Intent(getActivity(), KeychainIntentService.class);
|
||||
Intent intent = new Intent(getActivity(), KeychainService.class);
|
||||
|
||||
// fill values for this action
|
||||
Bundle data = new Bundle();
|
||||
|
||||
intent.setAction(KeychainIntentService.ACTION_DECRYPT_VERIFY);
|
||||
intent.setAction(KeychainService.ACTION_DECRYPT_VERIFY);
|
||||
|
||||
PgpDecryptVerifyInputParcel input = new PgpDecryptVerifyInputParcel(mCiphertext.getBytes());
|
||||
data.putParcelable(KeychainIntentService.DECRYPT_VERIFY_PARCEL, input);
|
||||
data.putParcelable(KeychainIntentService.EXTRA_CRYPTO_INPUT, cryptoInput);
|
||||
data.putParcelable(KeychainService.DECRYPT_VERIFY_PARCEL, input);
|
||||
data.putParcelable(KeychainService.EXTRA_CRYPTO_INPUT, cryptoInput);
|
||||
|
||||
intent.putExtra(KeychainIntentService.EXTRA_DATA, data);
|
||||
intent.putExtra(KeychainService.EXTRA_DATA, data);
|
||||
|
||||
// Message is received after encrypting is done in KeychainIntentService
|
||||
// Message is received after encrypting is done in KeychainService
|
||||
ServiceProgressHandler saveHandler = new ServiceProgressHandler(
|
||||
getActivity(),
|
||||
getString(R.string.progress_decrypting),
|
||||
ProgressDialog.STYLE_HORIZONTAL,
|
||||
ProgressDialogFragment.ServiceType.KEYCHAIN_INTENT) {
|
||||
ProgressDialog.STYLE_HORIZONTAL
|
||||
) {
|
||||
public void handleMessage(Message message) {
|
||||
// handle messages by standard KeychainIntentServiceHandler first
|
||||
super.handleMessage(message);
|
||||
@ -223,7 +222,7 @@ public class DecryptTextFragment extends DecryptFragment {
|
||||
|
||||
// Create a new Messenger for the communication back
|
||||
Messenger messenger = new Messenger(saveHandler);
|
||||
intent.putExtra(KeychainIntentService.EXTRA_MESSENGER, messenger);
|
||||
intent.putExtra(KeychainService.EXTRA_MESSENGER, messenger);
|
||||
|
||||
// show progress dialog
|
||||
saveHandler.showProgressDialog(getActivity());
|
||||
|
@ -50,7 +50,7 @@ import org.sufficientlysecure.keychain.provider.KeychainContract;
|
||||
import org.sufficientlysecure.keychain.provider.KeychainContract.UserPackets;
|
||||
import org.sufficientlysecure.keychain.provider.ProviderHelper;
|
||||
import org.sufficientlysecure.keychain.provider.ProviderHelper.NotFoundException;
|
||||
import org.sufficientlysecure.keychain.service.KeychainIntentService;
|
||||
import org.sufficientlysecure.keychain.service.KeychainService;
|
||||
import org.sufficientlysecure.keychain.service.ServiceProgressHandler;
|
||||
import org.sufficientlysecure.keychain.service.SaveKeyringParcel;
|
||||
import org.sufficientlysecure.keychain.service.SaveKeyringParcel.ChangeUnlockParcel;
|
||||
@ -66,8 +66,6 @@ import org.sufficientlysecure.keychain.ui.util.Notify;
|
||||
import org.sufficientlysecure.keychain.util.Log;
|
||||
import org.sufficientlysecure.keychain.util.Passphrase;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
|
||||
public class EditKeyFragment extends CryptoOperationFragment implements
|
||||
LoaderManager.LoaderCallbacks<Cursor> {
|
||||
@ -603,8 +601,8 @@ public class EditKeyFragment extends CryptoOperationFragment implements
|
||||
getActivity(),
|
||||
getString(R.string.progress_saving),
|
||||
ProgressDialog.STYLE_HORIZONTAL,
|
||||
true,
|
||||
ProgressDialogFragment.ServiceType.KEYCHAIN_INTENT) {
|
||||
true
|
||||
) {
|
||||
public void handleMessage(Message message) {
|
||||
// handle messages by standard KeychainIntentServiceHandler first
|
||||
super.handleMessage(message);
|
||||
@ -643,18 +641,18 @@ public class EditKeyFragment extends CryptoOperationFragment implements
|
||||
};
|
||||
|
||||
// Send all information needed to service to import key in other thread
|
||||
Intent intent = new Intent(getActivity(), KeychainIntentService.class);
|
||||
intent.setAction(KeychainIntentService.ACTION_EDIT_KEYRING);
|
||||
Intent intent = new Intent(getActivity(), KeychainService.class);
|
||||
intent.setAction(KeychainService.ACTION_EDIT_KEYRING);
|
||||
|
||||
// fill values for this action
|
||||
Bundle data = new Bundle();
|
||||
data.putParcelable(KeychainIntentService.EXTRA_CRYPTO_INPUT, cryptoInput);
|
||||
data.putParcelable(KeychainIntentService.EDIT_KEYRING_PARCEL, mSaveKeyringParcel);
|
||||
intent.putExtra(KeychainIntentService.EXTRA_DATA, data);
|
||||
data.putParcelable(KeychainService.EXTRA_CRYPTO_INPUT, cryptoInput);
|
||||
data.putParcelable(KeychainService.EDIT_KEYRING_PARCEL, mSaveKeyringParcel);
|
||||
intent.putExtra(KeychainService.EXTRA_DATA, data);
|
||||
|
||||
// Create a new Messenger for the communication back
|
||||
Messenger messenger = new Messenger(saveHandler);
|
||||
intent.putExtra(KeychainIntentService.EXTRA_MESSENGER, messenger);
|
||||
intent.putExtra(KeychainService.EXTRA_MESSENGER, messenger);
|
||||
|
||||
// show progress dialog
|
||||
saveHandler.showProgressDialog(getActivity());
|
||||
|
@ -73,12 +73,10 @@ public class EncryptFilesActivity extends EncryptActivity {
|
||||
uris = intent.getParcelableArrayListExtra(Intent.EXTRA_STREAM);
|
||||
}
|
||||
|
||||
boolean useArmor = extras.getBoolean(EXTRA_ASCII_ARMOR, false);
|
||||
|
||||
if (savedInstanceState == null) {
|
||||
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
|
||||
|
||||
EncryptFilesFragment encryptFragment = EncryptFilesFragment.newInstance(uris, useArmor);
|
||||
EncryptFilesFragment encryptFragment = EncryptFilesFragment.newInstance(uris);
|
||||
transaction.replace(R.id.encrypt_file_container, encryptFragment);
|
||||
transaction.commit();
|
||||
}
|
||||
|
@ -49,18 +49,20 @@ import org.sufficientlysecure.keychain.pgp.KeyRing;
|
||||
import org.sufficientlysecure.keychain.pgp.PgpConstants;
|
||||
import org.sufficientlysecure.keychain.pgp.SignEncryptParcel;
|
||||
import org.sufficientlysecure.keychain.provider.TemporaryStorageProvider;
|
||||
import org.sufficientlysecure.keychain.service.KeychainIntentService;
|
||||
import org.sufficientlysecure.keychain.service.KeychainService;
|
||||
import org.sufficientlysecure.keychain.service.ServiceProgressHandler;
|
||||
import org.sufficientlysecure.keychain.service.input.CryptoInputParcel;
|
||||
import org.sufficientlysecure.keychain.ui.adapter.SpacesItemDecoration;
|
||||
import org.sufficientlysecure.keychain.ui.base.CachingCryptoOperationFragment;
|
||||
import org.sufficientlysecure.keychain.ui.dialog.DeleteFileDialogFragment;
|
||||
import org.sufficientlysecure.keychain.ui.dialog.ProgressDialogFragment;
|
||||
import org.sufficientlysecure.keychain.ui.util.FormattingUtils;
|
||||
import org.sufficientlysecure.keychain.ui.util.Notify;
|
||||
import org.sufficientlysecure.keychain.ui.util.Notify.ActionListener;
|
||||
import org.sufficientlysecure.keychain.ui.util.Notify.Style;
|
||||
import org.sufficientlysecure.keychain.util.FileHelper;
|
||||
import org.sufficientlysecure.keychain.util.Log;
|
||||
import org.sufficientlysecure.keychain.util.Passphrase;
|
||||
import org.sufficientlysecure.keychain.util.Preferences;
|
||||
import org.sufficientlysecure.keychain.util.ShareHelper;
|
||||
|
||||
import java.io.File;
|
||||
@ -99,11 +101,10 @@ public class EncryptFilesFragment extends CachingCryptoOperationFragment<SignEnc
|
||||
/**
|
||||
* Creates new instance of this fragment
|
||||
*/
|
||||
public static EncryptFilesFragment newInstance(ArrayList<Uri> uris, boolean useArmor) {
|
||||
public static EncryptFilesFragment newInstance(ArrayList<Uri> uris) {
|
||||
EncryptFilesFragment frag = new EncryptFilesFragment();
|
||||
|
||||
Bundle args = new Bundle();
|
||||
args.putBoolean(ARG_USE_ASCII_ARMOR, useArmor);
|
||||
args.putParcelableArrayList(ARG_URIS, uris);
|
||||
frag.setArguments(args);
|
||||
|
||||
@ -167,11 +168,28 @@ public class EncryptFilesFragment extends CachingCryptoOperationFragment<SignEnc
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
Preferences prefs = Preferences.getPreferences(getActivity());
|
||||
|
||||
Bundle args = savedInstanceState == null ? getArguments() : savedInstanceState;
|
||||
mDeleteAfterEncrypt = args.getBoolean(ARG_DELETE_AFTER_ENCRYPT, false);
|
||||
mUseArmor = args.getBoolean(ARG_USE_ASCII_ARMOR, false);
|
||||
mUseCompression = args.getBoolean(ARG_USE_COMPRESSION, true);
|
||||
mEncryptFilenames = args.getBoolean(ARG_ENCRYPT_FILENAMES, true);
|
||||
|
||||
if (args.containsKey(ARG_USE_ASCII_ARMOR)) {
|
||||
mUseArmor = args.getBoolean(ARG_USE_ASCII_ARMOR, false);
|
||||
} else {
|
||||
mUseArmor = prefs.getUseArmor();
|
||||
}
|
||||
|
||||
if (args.containsKey(ARG_USE_COMPRESSION)) {
|
||||
mUseCompression = args.getBoolean(ARG_USE_COMPRESSION, true);
|
||||
} else {
|
||||
mUseCompression = prefs.getFilesUseCompression();
|
||||
}
|
||||
|
||||
if (args.containsKey(ARG_ENCRYPT_FILENAMES)) {
|
||||
mEncryptFilenames = args.getBoolean(ARG_ENCRYPT_FILENAMES, true);
|
||||
} else {
|
||||
mEncryptFilenames = prefs.getEncryptFilenames();
|
||||
}
|
||||
|
||||
setHasOptionsMenu(true);
|
||||
}
|
||||
@ -262,9 +280,7 @@ public class EncryptFilesFragment extends CachingCryptoOperationFragment<SignEnc
|
||||
break;
|
||||
}
|
||||
case R.id.check_use_armor: {
|
||||
// we can NOT do this for every item, others might care!
|
||||
item.setChecked(!item.isChecked());
|
||||
mUseArmor = item.isChecked();
|
||||
toggleUseArmor(item, !item.isChecked());
|
||||
break;
|
||||
}
|
||||
case R.id.check_delete_after_encrypt: {
|
||||
@ -273,13 +289,11 @@ public class EncryptFilesFragment extends CachingCryptoOperationFragment<SignEnc
|
||||
break;
|
||||
}
|
||||
case R.id.check_enable_compression: {
|
||||
item.setChecked(!item.isChecked());
|
||||
mUseCompression = item.isChecked();
|
||||
toggleEnableCompression(item, !item.isChecked());
|
||||
break;
|
||||
}
|
||||
case R.id.check_encrypt_filenames: {
|
||||
item.setChecked(!item.isChecked());
|
||||
mEncryptFilenames = item.isChecked();
|
||||
toggleEncryptFilenamesCheck(item, !item.isChecked());
|
||||
break;
|
||||
}
|
||||
// case R.id.check_hidden_recipients: {
|
||||
@ -294,6 +308,72 @@ public class EncryptFilesFragment extends CachingCryptoOperationFragment<SignEnc
|
||||
return true;
|
||||
}
|
||||
|
||||
public void toggleUseArmor(MenuItem item, final boolean useArmor) {
|
||||
|
||||
mUseArmor = useArmor;
|
||||
item.setChecked(useArmor);
|
||||
|
||||
Notify.create(getActivity(), useArmor
|
||||
? R.string.snack_armor_on
|
||||
: R.string.snack_armor_off,
|
||||
Notify.LENGTH_LONG, Style.OK, new ActionListener() {
|
||||
@Override
|
||||
public void onAction() {
|
||||
Preferences.getPreferences(getActivity()).setUseArmor(useArmor);
|
||||
Notify.create(getActivity(), useArmor
|
||||
? R.string.snack_armor_on
|
||||
: R.string.snack_armor_off,
|
||||
Notify.LENGTH_SHORT, Style.OK, null, R.string.btn_saved)
|
||||
.show(EncryptFilesFragment.this, false);
|
||||
}
|
||||
}, R.string.btn_save_default).show(this);
|
||||
|
||||
}
|
||||
|
||||
public void toggleEnableCompression(MenuItem item, final boolean compress) {
|
||||
|
||||
mUseCompression = compress;
|
||||
item.setChecked(compress);
|
||||
|
||||
Notify.create(getActivity(), compress
|
||||
? R.string.snack_compression_on
|
||||
: R.string.snack_compression_off,
|
||||
Notify.LENGTH_LONG, Style.OK, new ActionListener() {
|
||||
@Override
|
||||
public void onAction() {
|
||||
Preferences.getPreferences(getActivity()).setFilesUseCompression(compress);
|
||||
Notify.create(getActivity(), compress
|
||||
? R.string.snack_compression_on
|
||||
: R.string.snack_compression_off,
|
||||
Notify.LENGTH_SHORT, Style.OK, null, R.string.btn_saved)
|
||||
.show(EncryptFilesFragment.this, false);
|
||||
}
|
||||
}, R.string.btn_save_default).show(this);
|
||||
|
||||
}
|
||||
|
||||
public void toggleEncryptFilenamesCheck(MenuItem item, final boolean encryptFilenames) {
|
||||
|
||||
mEncryptFilenames = encryptFilenames;
|
||||
item.setChecked(encryptFilenames);
|
||||
|
||||
Notify.create(getActivity(), encryptFilenames
|
||||
? R.string.snack_encrypt_filenames_on
|
||||
: R.string.snack_encrypt_filenames_off,
|
||||
Notify.LENGTH_LONG, Style.OK, new ActionListener() {
|
||||
@Override
|
||||
public void onAction() {
|
||||
Preferences.getPreferences(getActivity()).setEncryptFilenames(encryptFilenames);
|
||||
Notify.create(getActivity(), encryptFilenames
|
||||
? R.string.snack_encrypt_filenames_on
|
||||
: R.string.snack_encrypt_filenames_off,
|
||||
Notify.LENGTH_SHORT, Style.OK, null, R.string.btn_saved)
|
||||
.show(EncryptFilesFragment.this, false);
|
||||
}
|
||||
}, R.string.btn_save_default).show(this);
|
||||
|
||||
}
|
||||
|
||||
public void onEncryptSuccess(final SignEncryptResult result) {
|
||||
if (mDeleteAfterEncrypt) {
|
||||
DeleteFileDialogFragment deleteFileDialog =
|
||||
@ -505,21 +585,22 @@ public class EncryptFilesFragment extends CachingCryptoOperationFragment<SignEnc
|
||||
}
|
||||
|
||||
// Send all information needed to service to edit key in other thread
|
||||
Intent intent = new Intent(getActivity(), KeychainIntentService.class);
|
||||
intent.setAction(KeychainIntentService.ACTION_SIGN_ENCRYPT);
|
||||
Intent intent = new Intent(getActivity(), KeychainService.class);
|
||||
intent.setAction(KeychainService.ACTION_SIGN_ENCRYPT);
|
||||
|
||||
Bundle data = new Bundle();
|
||||
data.putParcelable(KeychainIntentService.SIGN_ENCRYPT_PARCEL, actionsParcel);
|
||||
data.putParcelable(KeychainIntentService.EXTRA_CRYPTO_INPUT, cryptoInput);
|
||||
intent.putExtra(KeychainIntentService.EXTRA_DATA, data);
|
||||
data.putParcelable(KeychainService.SIGN_ENCRYPT_PARCEL, actionsParcel);
|
||||
data.putParcelable(KeychainService.EXTRA_CRYPTO_INPUT, cryptoInput);
|
||||
intent.putExtra(KeychainService.EXTRA_DATA, data);
|
||||
|
||||
// Message is received after encrypting is done in KeychainIntentService
|
||||
// Message is received after encrypting is done in KeychainService
|
||||
ServiceProgressHandler serviceHandler = new ServiceProgressHandler(
|
||||
getActivity(),
|
||||
getString(R.string.progress_encrypting),
|
||||
ProgressDialog.STYLE_HORIZONTAL,
|
||||
true,
|
||||
ProgressDialogFragment.ServiceType.KEYCHAIN_INTENT) {
|
||||
true
|
||||
) {
|
||||
@Override
|
||||
public void handleMessage(Message message) {
|
||||
// handle messages by standard KeychainIntentServiceHandler first
|
||||
super.handleMessage(message);
|
||||
@ -542,7 +623,7 @@ public class EncryptFilesFragment extends CachingCryptoOperationFragment<SignEnc
|
||||
};
|
||||
// Create a new Messenger for the communication back
|
||||
Messenger messenger = new Messenger(serviceHandler);
|
||||
intent.putExtra(KeychainIntentService.EXTRA_MESSENGER, messenger);
|
||||
intent.putExtra(KeychainService.EXTRA_MESSENGER, messenger);
|
||||
|
||||
// show progress dialog
|
||||
serviceHandler.showProgressDialog(getActivity());
|
||||
|
@ -41,13 +41,15 @@ import org.sufficientlysecure.keychain.operations.results.SignEncryptResult;
|
||||
import org.sufficientlysecure.keychain.pgp.KeyRing;
|
||||
import org.sufficientlysecure.keychain.pgp.PgpConstants;
|
||||
import org.sufficientlysecure.keychain.pgp.SignEncryptParcel;
|
||||
import org.sufficientlysecure.keychain.service.KeychainIntentService;
|
||||
import org.sufficientlysecure.keychain.service.KeychainService;
|
||||
import org.sufficientlysecure.keychain.service.ServiceProgressHandler;
|
||||
import org.sufficientlysecure.keychain.service.input.CryptoInputParcel;
|
||||
import org.sufficientlysecure.keychain.ui.base.CachingCryptoOperationFragment;
|
||||
import org.sufficientlysecure.keychain.ui.dialog.ProgressDialogFragment;
|
||||
import org.sufficientlysecure.keychain.ui.util.Notify;
|
||||
import org.sufficientlysecure.keychain.ui.util.Notify.ActionListener;
|
||||
import org.sufficientlysecure.keychain.ui.util.Notify.Style;
|
||||
import org.sufficientlysecure.keychain.util.Passphrase;
|
||||
import org.sufficientlysecure.keychain.util.Preferences;
|
||||
import org.sufficientlysecure.keychain.util.ShareHelper;
|
||||
|
||||
import java.util.HashSet;
|
||||
@ -131,8 +133,16 @@ public class EncryptTextFragment extends CachingCryptoOperationFragment<SignEncr
|
||||
mMessage = getArguments().getString(ARG_TEXT);
|
||||
}
|
||||
|
||||
Preferences prefs = Preferences.getPreferences(getActivity());
|
||||
|
||||
Bundle args = savedInstanceState == null ? getArguments() : savedInstanceState;
|
||||
|
||||
mUseCompression = args.getBoolean(ARG_USE_COMPRESSION, true);
|
||||
if (args.containsKey(ARG_USE_COMPRESSION)) {
|
||||
mUseCompression = args.getBoolean(ARG_USE_COMPRESSION, true);
|
||||
} else {
|
||||
mUseCompression = prefs.getTextUseCompression();
|
||||
}
|
||||
|
||||
setHasOptionsMenu(true);
|
||||
}
|
||||
@ -147,12 +157,9 @@ public class EncryptTextFragment extends CachingCryptoOperationFragment<SignEncr
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
if (item.isCheckable()) {
|
||||
item.setChecked(!item.isChecked());
|
||||
}
|
||||
switch (item.getItemId()) {
|
||||
case R.id.check_enable_compression: {
|
||||
mUseCompression = item.isChecked();
|
||||
toggleEnableCompression(item, !item.isChecked());
|
||||
break;
|
||||
}
|
||||
// case R.id.check_hidden_recipients: {
|
||||
@ -175,6 +182,28 @@ public class EncryptTextFragment extends CachingCryptoOperationFragment<SignEncr
|
||||
return true;
|
||||
}
|
||||
|
||||
public void toggleEnableCompression(MenuItem item, final boolean compress) {
|
||||
|
||||
mUseCompression = compress;
|
||||
item.setChecked(compress);
|
||||
|
||||
Notify.create(getActivity(), compress
|
||||
? R.string.snack_compression_on
|
||||
: R.string.snack_compression_off,
|
||||
Notify.LENGTH_LONG, Style.OK, new ActionListener() {
|
||||
@Override
|
||||
public void onAction() {
|
||||
Preferences.getPreferences(getActivity()).setTextUseCompression(compress);
|
||||
Notify.create(getActivity(), compress
|
||||
? R.string.snack_compression_on
|
||||
: R.string.snack_compression_off,
|
||||
Notify.LENGTH_SHORT, Style.OK, null, R.string.btn_saved)
|
||||
.show(EncryptTextFragment.this, false);
|
||||
}
|
||||
}, R.string.btn_save_default).show(this);
|
||||
|
||||
}
|
||||
|
||||
protected void onEncryptSuccess(SignEncryptResult result) {
|
||||
if (mShareAfterEncrypt) {
|
||||
// Share encrypted message/file
|
||||
@ -323,20 +352,21 @@ public class EncryptTextFragment extends CachingCryptoOperationFragment<SignEncr
|
||||
}
|
||||
|
||||
// Send all information needed to service to edit key in other thread
|
||||
Intent intent = new Intent(getActivity(), KeychainIntentService.class);
|
||||
intent.setAction(KeychainIntentService.ACTION_SIGN_ENCRYPT);
|
||||
Intent intent = new Intent(getActivity(), KeychainService.class);
|
||||
intent.setAction(KeychainService.ACTION_SIGN_ENCRYPT);
|
||||
|
||||
Bundle data = new Bundle();
|
||||
data.putParcelable(KeychainIntentService.SIGN_ENCRYPT_PARCEL, actionsParcel);
|
||||
data.putParcelable(KeychainIntentService.EXTRA_CRYPTO_INPUT, cryptoInput);
|
||||
intent.putExtra(KeychainIntentService.EXTRA_DATA, data);
|
||||
data.putParcelable(KeychainService.SIGN_ENCRYPT_PARCEL, actionsParcel);
|
||||
data.putParcelable(KeychainService.EXTRA_CRYPTO_INPUT, cryptoInput);
|
||||
intent.putExtra(KeychainService.EXTRA_DATA, data);
|
||||
|
||||
// Message is received after encrypting is done in KeychainIntentService
|
||||
// Message is received after encrypting is done in KeychainService
|
||||
ServiceProgressHandler serviceHandler = new ServiceProgressHandler(
|
||||
getActivity(),
|
||||
getString(R.string.progress_encrypting),
|
||||
ProgressDialog.STYLE_HORIZONTAL,
|
||||
ProgressDialogFragment.ServiceType.KEYCHAIN_INTENT) {
|
||||
ProgressDialog.STYLE_HORIZONTAL
|
||||
) {
|
||||
@Override
|
||||
public void handleMessage(Message message) {
|
||||
// handle messages by standard KeychainIntentServiceHandler first
|
||||
super.handleMessage(message);
|
||||
@ -359,7 +389,7 @@ public class EncryptTextFragment extends CachingCryptoOperationFragment<SignEncr
|
||||
};
|
||||
// Create a new Messenger for the communication back
|
||||
Messenger messenger = new Messenger(serviceHandler);
|
||||
intent.putExtra(KeychainIntentService.EXTRA_MESSENGER, messenger);
|
||||
intent.putExtra(KeychainService.EXTRA_MESSENGER, messenger);
|
||||
|
||||
// show progress dialog
|
||||
serviceHandler.showProgressDialog(getActivity());
|
||||
|
@ -35,11 +35,9 @@ import org.sufficientlysecure.keychain.keyimport.ImportKeysListEntry;
|
||||
import org.sufficientlysecure.keychain.keyimport.ParcelableKeyRing;
|
||||
import org.sufficientlysecure.keychain.operations.results.ImportKeyResult;
|
||||
import org.sufficientlysecure.keychain.operations.results.OperationResult;
|
||||
import org.sufficientlysecure.keychain.service.KeychainIntentService;
|
||||
import org.sufficientlysecure.keychain.service.KeychainService;
|
||||
import org.sufficientlysecure.keychain.ui.base.BaseNfcActivity;
|
||||
import org.sufficientlysecure.keychain.service.CloudImportService;
|
||||
import org.sufficientlysecure.keychain.service.ServiceProgressHandler;
|
||||
import org.sufficientlysecure.keychain.ui.dialog.ProgressDialogFragment;
|
||||
import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
|
||||
import org.sufficientlysecure.keychain.ui.util.Notify;
|
||||
import org.sufficientlysecure.keychain.util.Log;
|
||||
@ -383,7 +381,6 @@ public class ImportKeysActivity extends BaseNfcActivity {
|
||||
* Import keys with mImportData
|
||||
*/
|
||||
public void importKeys() {
|
||||
ImportKeysListFragment.LoaderState ls = mListFragment.getLoaderState();
|
||||
|
||||
if (mListFragment.getSelectedEntries().size() == 0) {
|
||||
Notify.create(this, R.string.error_nothing_import_selected, Notify.Style.ERROR)
|
||||
@ -391,32 +388,33 @@ public class ImportKeysActivity extends BaseNfcActivity {
|
||||
return;
|
||||
}
|
||||
|
||||
ServiceProgressHandler serviceHandler = new ServiceProgressHandler(
|
||||
this,
|
||||
getString(R.string.progress_importing),
|
||||
ProgressDialog.STYLE_HORIZONTAL,
|
||||
true
|
||||
) {
|
||||
@Override
|
||||
public void handleMessage(Message message) {
|
||||
// handle messages by standard KeychainIntentServiceHandler first
|
||||
super.handleMessage(message);
|
||||
|
||||
ImportKeysActivity.this.handleMessage(message);
|
||||
}
|
||||
};
|
||||
|
||||
// Send all information needed to service to import key in other thread
|
||||
Intent intent = new Intent(this, KeychainService.class);
|
||||
|
||||
intent.setAction(KeychainService.ACTION_IMPORT_KEYRING);
|
||||
|
||||
// fill values for this action
|
||||
Bundle data = new Bundle();
|
||||
|
||||
ImportKeysListFragment.LoaderState ls = mListFragment.getLoaderState();
|
||||
if (ls instanceof ImportKeysListFragment.BytesLoaderState) {
|
||||
Log.d(Constants.TAG, "importKeys started");
|
||||
|
||||
ServiceProgressHandler serviceHandler = new ServiceProgressHandler(
|
||||
this,
|
||||
getString(R.string.progress_importing),
|
||||
ProgressDialog.STYLE_HORIZONTAL,
|
||||
true,
|
||||
ProgressDialogFragment.ServiceType.KEYCHAIN_INTENT) {
|
||||
public void handleMessage(Message message) {
|
||||
// handle messages by standard KeychainIntentServiceHandler first
|
||||
super.handleMessage(message);
|
||||
|
||||
ImportKeysActivity.this.handleMessage(message);
|
||||
}
|
||||
};
|
||||
|
||||
// TODO: Currently not using CloudImport here due to https://github.com/open-keychain/open-keychain/issues/1221
|
||||
// Send all information needed to service to import key in other thread
|
||||
Intent intent = new Intent(this, KeychainIntentService.class);
|
||||
|
||||
intent.setAction(KeychainIntentService.ACTION_IMPORT_KEYRING);
|
||||
|
||||
// fill values for this action
|
||||
Bundle data = new Bundle();
|
||||
|
||||
// get DATA from selected key entries
|
||||
IteratorWithSize<ParcelableKeyRing> selectedEntries = mListFragment.getSelectedData();
|
||||
|
||||
@ -430,11 +428,11 @@ public class ImportKeysActivity extends BaseNfcActivity {
|
||||
new ParcelableFileCache<>(this, "key_import.pcl");
|
||||
cache.writeCache(selectedEntries);
|
||||
|
||||
intent.putExtra(KeychainIntentService.EXTRA_DATA, data);
|
||||
intent.putExtra(KeychainService.EXTRA_DATA, data);
|
||||
|
||||
// Create a new Messenger for the communication back
|
||||
Messenger messenger = new Messenger(serviceHandler);
|
||||
intent.putExtra(KeychainIntentService.EXTRA_MESSENGER, messenger);
|
||||
intent.putExtra(KeychainService.EXTRA_MESSENGER, messenger);
|
||||
|
||||
// show progress dialog
|
||||
serviceHandler.showProgressDialog(this);
|
||||
@ -449,27 +447,7 @@ public class ImportKeysActivity extends BaseNfcActivity {
|
||||
} else if (ls instanceof ImportKeysListFragment.CloudLoaderState) {
|
||||
ImportKeysListFragment.CloudLoaderState sls = (ImportKeysListFragment.CloudLoaderState) ls;
|
||||
|
||||
ServiceProgressHandler serviceHandler = new ServiceProgressHandler(
|
||||
this,
|
||||
getString(R.string.progress_importing),
|
||||
ProgressDialog.STYLE_HORIZONTAL,
|
||||
true,
|
||||
ProgressDialogFragment.ServiceType.CLOUD_IMPORT) {
|
||||
public void handleMessage(Message message) {
|
||||
// handle messages by standard KeychainIntentServiceHandler first
|
||||
super.handleMessage(message);
|
||||
|
||||
ImportKeysActivity.this.handleMessage(message);
|
||||
}
|
||||
};
|
||||
|
||||
// Send all information needed to service to query keys in other thread
|
||||
Intent intent = new Intent(this, CloudImportService.class);
|
||||
|
||||
// fill values for this action
|
||||
Bundle data = new Bundle();
|
||||
|
||||
data.putString(CloudImportService.IMPORT_KEY_SERVER, sls.mCloudPrefs.keyserver);
|
||||
data.putString(KeychainService.IMPORT_KEY_SERVER, sls.mCloudPrefs.keyserver);
|
||||
|
||||
// get selected key entries
|
||||
ArrayList<ParcelableKeyRing> keys = new ArrayList<>();
|
||||
@ -482,13 +460,13 @@ public class ImportKeysActivity extends BaseNfcActivity {
|
||||
);
|
||||
}
|
||||
}
|
||||
data.putParcelableArrayList(CloudImportService.IMPORT_KEY_LIST, keys);
|
||||
data.putParcelableArrayList(KeychainService.IMPORT_KEY_LIST, keys);
|
||||
|
||||
intent.putExtra(CloudImportService.EXTRA_DATA, data);
|
||||
intent.putExtra(KeychainService.EXTRA_DATA, data);
|
||||
|
||||
// Create a new Messenger for the communication back
|
||||
Messenger messenger = new Messenger(serviceHandler);
|
||||
intent.putExtra(CloudImportService.EXTRA_MESSENGER, messenger);
|
||||
intent.putExtra(KeychainService.EXTRA_MESSENGER, messenger);
|
||||
|
||||
// show progress dialog
|
||||
serviceHandler.showProgressDialog(this);
|
||||
|
@ -43,9 +43,8 @@ import org.sufficientlysecure.keychain.operations.results.ImportKeyResult;
|
||||
import org.sufficientlysecure.keychain.operations.results.OperationResult;
|
||||
import org.sufficientlysecure.keychain.operations.results.OperationResult.LogType;
|
||||
import org.sufficientlysecure.keychain.operations.results.SingletonResult;
|
||||
import org.sufficientlysecure.keychain.service.KeychainIntentService;
|
||||
import org.sufficientlysecure.keychain.service.KeychainService;
|
||||
import org.sufficientlysecure.keychain.service.ServiceProgressHandler;
|
||||
import org.sufficientlysecure.keychain.ui.dialog.ProgressDialogFragment;
|
||||
import org.sufficientlysecure.keychain.util.IntentIntegratorSupportV4;
|
||||
import org.sufficientlysecure.keychain.util.Log;
|
||||
import org.sufficientlysecure.keychain.util.Preferences;
|
||||
@ -206,13 +205,14 @@ public class ImportKeysProxyActivity extends FragmentActivity {
|
||||
|
||||
private void startImportService(ArrayList<ParcelableKeyRing> keyRings) {
|
||||
|
||||
// Message is received after importing is done in KeychainIntentService
|
||||
// Message is received after importing is done in KeychainService
|
||||
ServiceProgressHandler serviceHandler = new ServiceProgressHandler(
|
||||
this,
|
||||
getString(R.string.progress_importing),
|
||||
ProgressDialog.STYLE_HORIZONTAL,
|
||||
true,
|
||||
ProgressDialogFragment.ServiceType.KEYCHAIN_INTENT) {
|
||||
true
|
||||
) {
|
||||
@Override
|
||||
public void handleMessage(Message message) {
|
||||
// handle messages by standard KeychainIntentServiceHandler first
|
||||
super.handleMessage(message);
|
||||
@ -258,19 +258,19 @@ public class ImportKeysProxyActivity extends FragmentActivity {
|
||||
Preferences prefs = Preferences.getPreferences(this);
|
||||
Preferences.CloudSearchPrefs cloudPrefs =
|
||||
new Preferences.CloudSearchPrefs(true, true, prefs.getPreferredKeyserver());
|
||||
data.putString(KeychainIntentService.IMPORT_KEY_SERVER, cloudPrefs.keyserver);
|
||||
data.putString(KeychainService.IMPORT_KEY_SERVER, cloudPrefs.keyserver);
|
||||
}
|
||||
|
||||
data.putParcelableArrayList(KeychainIntentService.IMPORT_KEY_LIST, keyRings);
|
||||
data.putParcelableArrayList(KeychainService.IMPORT_KEY_LIST, keyRings);
|
||||
|
||||
// Send all information needed to service to query keys in other thread
|
||||
Intent intent = new Intent(this, KeychainIntentService.class);
|
||||
intent.setAction(KeychainIntentService.ACTION_IMPORT_KEYRING);
|
||||
intent.putExtra(KeychainIntentService.EXTRA_DATA, data);
|
||||
Intent intent = new Intent(this, KeychainService.class);
|
||||
intent.setAction(KeychainService.ACTION_IMPORT_KEYRING);
|
||||
intent.putExtra(KeychainService.EXTRA_DATA, data);
|
||||
|
||||
// Create a new Messenger for the communication back
|
||||
Messenger messenger = new Messenger(serviceHandler);
|
||||
intent.putExtra(KeychainIntentService.EXTRA_MESSENGER, messenger);
|
||||
intent.putExtra(KeychainService.EXTRA_MESSENGER, messenger);
|
||||
|
||||
// show progress dialog
|
||||
serviceHandler.showProgressDialog(this);
|
||||
|
@ -64,12 +64,10 @@ import org.sufficientlysecure.keychain.provider.KeychainContract;
|
||||
import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
|
||||
import org.sufficientlysecure.keychain.provider.KeychainDatabase;
|
||||
import org.sufficientlysecure.keychain.provider.ProviderHelper;
|
||||
import org.sufficientlysecure.keychain.service.CloudImportService;
|
||||
import org.sufficientlysecure.keychain.service.KeychainIntentService;
|
||||
import org.sufficientlysecure.keychain.service.KeychainService;
|
||||
import org.sufficientlysecure.keychain.service.ServiceProgressHandler;
|
||||
import org.sufficientlysecure.keychain.service.PassphraseCacheService;
|
||||
import org.sufficientlysecure.keychain.ui.dialog.DeleteKeyDialogFragment;
|
||||
import org.sufficientlysecure.keychain.ui.dialog.ProgressDialogFragment;
|
||||
import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
|
||||
import org.sufficientlysecure.keychain.ui.adapter.KeyAdapter;
|
||||
import org.sufficientlysecure.keychain.ui.util.Notify;
|
||||
@ -578,8 +576,9 @@ public class KeyListFragment extends LoaderFragment
|
||||
getActivity(),
|
||||
getString(R.string.progress_updating),
|
||||
ProgressDialog.STYLE_HORIZONTAL,
|
||||
true,
|
||||
ProgressDialogFragment.ServiceType.CLOUD_IMPORT) {
|
||||
true
|
||||
) {
|
||||
@Override
|
||||
public void handleMessage(Message message) {
|
||||
// handle messages by standard KeychainIntentServiceHandler first
|
||||
super.handleMessage(message);
|
||||
@ -603,7 +602,8 @@ public class KeyListFragment extends LoaderFragment
|
||||
};
|
||||
|
||||
// Send all information needed to service to query keys in other thread
|
||||
Intent intent = new Intent(getActivity(), CloudImportService.class);
|
||||
Intent intent = new Intent(getActivity(), KeychainService.class);
|
||||
intent.setAction(KeychainService.ACTION_IMPORT_KEYRING);
|
||||
|
||||
// fill values for this action
|
||||
Bundle data = new Bundle();
|
||||
@ -613,16 +613,16 @@ public class KeyListFragment extends LoaderFragment
|
||||
Preferences prefs = Preferences.getPreferences(getActivity());
|
||||
Preferences.CloudSearchPrefs cloudPrefs =
|
||||
new Preferences.CloudSearchPrefs(true, true, prefs.getPreferredKeyserver());
|
||||
data.putString(CloudImportService.IMPORT_KEY_SERVER, cloudPrefs.keyserver);
|
||||
data.putString(KeychainService.IMPORT_KEY_SERVER, cloudPrefs.keyserver);
|
||||
}
|
||||
|
||||
data.putParcelableArrayList(CloudImportService.IMPORT_KEY_LIST, keyList);
|
||||
data.putParcelableArrayList(KeychainService.IMPORT_KEY_LIST, keyList);
|
||||
|
||||
intent.putExtra(CloudImportService.EXTRA_DATA, data);
|
||||
intent.putExtra(KeychainService.EXTRA_DATA, data);
|
||||
|
||||
// Create a new Messenger for the communication back
|
||||
Messenger messenger = new Messenger(serviceHandler);
|
||||
intent.putExtra(CloudImportService.EXTRA_MESSENGER, messenger);
|
||||
intent.putExtra(KeychainService.EXTRA_MESSENGER, messenger);
|
||||
|
||||
// show progress dialog
|
||||
serviceHandler.showProgressDialog(getActivity());
|
||||
@ -632,12 +632,13 @@ public class KeyListFragment extends LoaderFragment
|
||||
}
|
||||
|
||||
private void consolidate() {
|
||||
// Message is received after importing is done in KeychainIntentService
|
||||
// Message is received after importing is done in KeychainService
|
||||
ServiceProgressHandler saveHandler = new ServiceProgressHandler(
|
||||
getActivity(),
|
||||
getString(R.string.progress_importing),
|
||||
ProgressDialog.STYLE_HORIZONTAL,
|
||||
ProgressDialogFragment.ServiceType.KEYCHAIN_INTENT) {
|
||||
ProgressDialog.STYLE_HORIZONTAL
|
||||
) {
|
||||
@Override
|
||||
public void handleMessage(Message message) {
|
||||
// handle messages by standard KeychainIntentServiceHandler first
|
||||
super.handleMessage(message);
|
||||
@ -660,18 +661,18 @@ public class KeyListFragment extends LoaderFragment
|
||||
};
|
||||
|
||||
// Send all information needed to service to import key in other thread
|
||||
Intent intent = new Intent(getActivity(), KeychainIntentService.class);
|
||||
Intent intent = new Intent(getActivity(), KeychainService.class);
|
||||
|
||||
intent.setAction(KeychainIntentService.ACTION_CONSOLIDATE);
|
||||
intent.setAction(KeychainService.ACTION_CONSOLIDATE);
|
||||
|
||||
// fill values for this action
|
||||
Bundle data = new Bundle();
|
||||
|
||||
intent.putExtra(KeychainIntentService.EXTRA_DATA, data);
|
||||
intent.putExtra(KeychainService.EXTRA_DATA, data);
|
||||
|
||||
// Create a new Messenger for the communication back
|
||||
Messenger messenger = new Messenger(saveHandler);
|
||||
intent.putExtra(KeychainIntentService.EXTRA_MESSENGER, messenger);
|
||||
intent.putExtra(KeychainService.EXTRA_MESSENGER, messenger);
|
||||
|
||||
// show progress dialog
|
||||
saveHandler.showProgressDialog(getActivity());
|
||||
|
@ -38,10 +38,9 @@ import org.sufficientlysecure.keychain.operations.results.ImportKeyResult;
|
||||
import org.sufficientlysecure.keychain.operations.results.OperationResult;
|
||||
import org.sufficientlysecure.keychain.provider.KeychainContract;
|
||||
import org.sufficientlysecure.keychain.provider.ProviderHelper;
|
||||
import org.sufficientlysecure.keychain.service.KeychainIntentService;
|
||||
import org.sufficientlysecure.keychain.service.KeychainService;
|
||||
import org.sufficientlysecure.keychain.ui.base.BaseActivity;
|
||||
import org.sufficientlysecure.keychain.service.ServiceProgressHandler;
|
||||
import org.sufficientlysecure.keychain.ui.dialog.ProgressDialogFragment;
|
||||
import org.sufficientlysecure.keychain.ui.util.Notify;
|
||||
import org.sufficientlysecure.keychain.util.Log;
|
||||
import org.sufficientlysecure.keychain.util.ParcelableFileCache;
|
||||
@ -124,13 +123,14 @@ public class SafeSlingerActivity extends BaseActivity {
|
||||
|
||||
final FragmentActivity activity = SafeSlingerActivity.this;
|
||||
|
||||
// Message is received after importing is done in KeychainIntentService
|
||||
// Message is received after importing is done in KeychainService
|
||||
ServiceProgressHandler saveHandler = new ServiceProgressHandler(
|
||||
activity,
|
||||
getString(R.string.progress_importing),
|
||||
ProgressDialog.STYLE_HORIZONTAL,
|
||||
true,
|
||||
ProgressDialogFragment.ServiceType.KEYCHAIN_INTENT) {
|
||||
true
|
||||
) {
|
||||
@Override
|
||||
public void handleMessage(Message message) {
|
||||
// handle messages by standard KeychainIntentServiceHandler first
|
||||
super.handleMessage(message);
|
||||
@ -176,9 +176,9 @@ public class SafeSlingerActivity extends BaseActivity {
|
||||
Log.d(Constants.TAG, "importKeys started");
|
||||
|
||||
// Send all information needed to service to import key in other thread
|
||||
Intent intent = new Intent(activity, KeychainIntentService.class);
|
||||
Intent intent = new Intent(activity, KeychainService.class);
|
||||
|
||||
intent.setAction(KeychainIntentService.ACTION_IMPORT_KEYRING);
|
||||
intent.setAction(KeychainService.ACTION_IMPORT_KEYRING);
|
||||
|
||||
// instead of giving the entries by Intent extra, cache them into a
|
||||
// file to prevent Java Binder problems on heavy imports
|
||||
@ -195,11 +195,11 @@ public class SafeSlingerActivity extends BaseActivity {
|
||||
|
||||
// fill values for this action
|
||||
Bundle bundle = new Bundle();
|
||||
intent.putExtra(KeychainIntentService.EXTRA_DATA, bundle);
|
||||
intent.putExtra(KeychainService.EXTRA_DATA, bundle);
|
||||
|
||||
// Create a new Messenger for the communication back
|
||||
Messenger messenger = new Messenger(saveHandler);
|
||||
intent.putExtra(KeychainIntentService.EXTRA_MESSENGER, messenger);
|
||||
intent.putExtra(KeychainService.EXTRA_MESSENGER, messenger);
|
||||
|
||||
// show progress dialog
|
||||
saveHandler.showProgressDialog(activity);
|
||||
|
@ -35,10 +35,9 @@ import org.sufficientlysecure.keychain.Constants;
|
||||
import org.sufficientlysecure.keychain.R;
|
||||
import org.sufficientlysecure.keychain.provider.KeychainContract;
|
||||
import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
|
||||
import org.sufficientlysecure.keychain.service.KeychainIntentService;
|
||||
import org.sufficientlysecure.keychain.service.KeychainService;
|
||||
import org.sufficientlysecure.keychain.ui.base.BaseActivity;
|
||||
import org.sufficientlysecure.keychain.service.ServiceProgressHandler;
|
||||
import org.sufficientlysecure.keychain.ui.dialog.ProgressDialogFragment;
|
||||
import org.sufficientlysecure.keychain.util.Log;
|
||||
import org.sufficientlysecure.keychain.util.Preferences;
|
||||
|
||||
@ -92,9 +91,9 @@ public class UploadKeyActivity extends BaseActivity {
|
||||
|
||||
private void uploadKey() {
|
||||
// Send all information needed to service to upload key in other thread
|
||||
Intent intent = new Intent(this, KeychainIntentService.class);
|
||||
Intent intent = new Intent(this, KeychainService.class);
|
||||
|
||||
intent.setAction(KeychainIntentService.ACTION_UPLOAD_KEYRING);
|
||||
intent.setAction(KeychainService.ACTION_UPLOAD_KEYRING);
|
||||
|
||||
// set data uri as path to keyring
|
||||
Uri blobUri = KeyRings.buildUnifiedKeyRingUri(mDataUri);
|
||||
@ -104,16 +103,17 @@ public class UploadKeyActivity extends BaseActivity {
|
||||
Bundle data = new Bundle();
|
||||
|
||||
String server = (String) mKeyServerSpinner.getSelectedItem();
|
||||
data.putString(KeychainIntentService.UPLOAD_KEY_SERVER, server);
|
||||
data.putString(KeychainService.UPLOAD_KEY_SERVER, server);
|
||||
|
||||
intent.putExtra(KeychainIntentService.EXTRA_DATA, data);
|
||||
intent.putExtra(KeychainService.EXTRA_DATA, data);
|
||||
|
||||
// Message is received after uploading is done in KeychainIntentService
|
||||
// Message is received after uploading is done in KeychainService
|
||||
ServiceProgressHandler saveHandler = new ServiceProgressHandler(
|
||||
this,
|
||||
getString(R.string.progress_uploading),
|
||||
ProgressDialog.STYLE_HORIZONTAL,
|
||||
ProgressDialogFragment.ServiceType.KEYCHAIN_INTENT) {
|
||||
ProgressDialog.STYLE_HORIZONTAL
|
||||
) {
|
||||
@Override
|
||||
public void handleMessage(Message message) {
|
||||
// handle messages by standard KeychainIntentServiceHandler first
|
||||
super.handleMessage(message);
|
||||
@ -129,7 +129,7 @@ public class UploadKeyActivity extends BaseActivity {
|
||||
|
||||
// Create a new Messenger for the communication back
|
||||
Messenger messenger = new Messenger(saveHandler);
|
||||
intent.putExtra(KeychainIntentService.EXTRA_MESSENGER, messenger);
|
||||
intent.putExtra(KeychainService.EXTRA_MESSENGER, messenger);
|
||||
|
||||
// show progress dialog
|
||||
saveHandler.showProgressDialog(this);
|
||||
|
@ -65,7 +65,7 @@ import org.sufficientlysecure.keychain.provider.CachedPublicKeyRing;
|
||||
import org.sufficientlysecure.keychain.provider.KeychainContract;
|
||||
import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
|
||||
import org.sufficientlysecure.keychain.provider.ProviderHelper;
|
||||
import org.sufficientlysecure.keychain.service.KeychainIntentService;
|
||||
import org.sufficientlysecure.keychain.service.KeychainService;
|
||||
import org.sufficientlysecure.keychain.service.ServiceProgressHandler;
|
||||
import org.sufficientlysecure.keychain.service.ServiceProgressHandler.MessageStatus;
|
||||
import org.sufficientlysecure.keychain.service.PassphraseCacheService;
|
||||
@ -402,8 +402,9 @@ public class ViewKeyActivity extends BaseNfcActivity implements
|
||||
}
|
||||
|
||||
private void startCertifyIntent(Intent intent) {
|
||||
// Message is received after signing is done in KeychainIntentService
|
||||
// Message is received after signing is done in KeychainService
|
||||
ServiceProgressHandler saveHandler = new ServiceProgressHandler(this) {
|
||||
@Override
|
||||
public void handleMessage(Message message) {
|
||||
// handle messages by standard KeychainIntentServiceHandler first
|
||||
super.handleMessage(message);
|
||||
@ -418,7 +419,7 @@ public class ViewKeyActivity extends BaseNfcActivity implements
|
||||
};
|
||||
// Create a new Messenger for the communication back
|
||||
Messenger messenger = new Messenger(saveHandler);
|
||||
intent.putExtra(KeychainIntentService.EXTRA_MESSENGER, messenger);
|
||||
intent.putExtra(KeychainService.EXTRA_MESSENGER, messenger);
|
||||
|
||||
startActivityForResult(intent, 0);
|
||||
}
|
||||
@ -651,8 +652,9 @@ public class ViewKeyActivity extends BaseNfcActivity implements
|
||||
ArrayList<ParcelableKeyRing> entries = new ArrayList<>();
|
||||
entries.add(keyEntry);
|
||||
|
||||
// Message is received after importing is done in KeychainIntentService
|
||||
// Message is received after importing is done in KeychainService
|
||||
ServiceProgressHandler serviceHandler = new ServiceProgressHandler(this) {
|
||||
@Override
|
||||
public void handleMessage(Message message) {
|
||||
// handle messages by standard KeychainIntentServiceHandler first
|
||||
super.handleMessage(message);
|
||||
@ -682,19 +684,19 @@ public class ViewKeyActivity extends BaseNfcActivity implements
|
||||
Preferences prefs = Preferences.getPreferences(this);
|
||||
Preferences.CloudSearchPrefs cloudPrefs =
|
||||
new Preferences.CloudSearchPrefs(true, true, prefs.getPreferredKeyserver());
|
||||
data.putString(KeychainIntentService.IMPORT_KEY_SERVER, cloudPrefs.keyserver);
|
||||
data.putString(KeychainService.IMPORT_KEY_SERVER, cloudPrefs.keyserver);
|
||||
}
|
||||
|
||||
data.putParcelableArrayList(KeychainIntentService.IMPORT_KEY_LIST, entries);
|
||||
data.putParcelableArrayList(KeychainService.IMPORT_KEY_LIST, entries);
|
||||
|
||||
// Send all information needed to service to query keys in other thread
|
||||
Intent intent = new Intent(this, KeychainIntentService.class);
|
||||
intent.setAction(KeychainIntentService.ACTION_IMPORT_KEYRING);
|
||||
intent.putExtra(KeychainIntentService.EXTRA_DATA, data);
|
||||
Intent intent = new Intent(this, KeychainService.class);
|
||||
intent.setAction(KeychainService.ACTION_IMPORT_KEYRING);
|
||||
intent.putExtra(KeychainService.EXTRA_DATA, data);
|
||||
|
||||
// Create a new Messenger for the communication back
|
||||
Messenger messenger = new Messenger(serviceHandler);
|
||||
intent.putExtra(KeychainIntentService.EXTRA_MESSENGER, messenger);
|
||||
intent.putExtra(KeychainService.EXTRA_MESSENGER, messenger);
|
||||
|
||||
// show progress dialog
|
||||
serviceHandler.showProgressDialog(this);
|
||||
|
@ -140,12 +140,17 @@ public class ViewKeyAdvShareFragment extends LoaderFragment implements
|
||||
}
|
||||
});
|
||||
|
||||
mKeyNfcButton.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
mNfcHelper.invokeNfcBeam();
|
||||
}
|
||||
});
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
mKeyNfcButton.setVisibility(View.VISIBLE);
|
||||
mKeyNfcButton.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
mNfcHelper.invokeNfcBeam();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
mKeyNfcButton.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
mKeySafeSlingerButton.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
|
@ -49,9 +49,8 @@ import com.textuality.keybase.lib.User;
|
||||
import org.sufficientlysecure.keychain.Constants;
|
||||
import org.sufficientlysecure.keychain.R;
|
||||
import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
|
||||
import org.sufficientlysecure.keychain.service.KeychainIntentService;
|
||||
import org.sufficientlysecure.keychain.service.KeychainService;
|
||||
import org.sufficientlysecure.keychain.service.ServiceProgressHandler;
|
||||
import org.sufficientlysecure.keychain.ui.dialog.ProgressDialogFragment;
|
||||
import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
|
||||
import org.sufficientlysecure.keychain.util.Log;
|
||||
|
||||
@ -350,13 +349,13 @@ public class ViewKeyTrustFragment extends LoaderFragment implements
|
||||
}
|
||||
|
||||
private void verify(final Proof proof, final String fingerprint) {
|
||||
Intent intent = new Intent(getActivity(), KeychainIntentService.class);
|
||||
Intent intent = new Intent(getActivity(), KeychainService.class);
|
||||
Bundle data = new Bundle();
|
||||
intent.setAction(KeychainIntentService.ACTION_VERIFY_KEYBASE_PROOF);
|
||||
intent.setAction(KeychainService.ACTION_VERIFY_KEYBASE_PROOF);
|
||||
|
||||
data.putString(KeychainIntentService.KEYBASE_PROOF, proof.toString());
|
||||
data.putString(KeychainIntentService.KEYBASE_REQUIRED_FINGERPRINT, fingerprint);
|
||||
intent.putExtra(KeychainIntentService.EXTRA_DATA, data);
|
||||
data.putString(KeychainService.KEYBASE_PROOF, proof.toString());
|
||||
data.putString(KeychainService.KEYBASE_REQUIRED_FINGERPRINT, fingerprint);
|
||||
intent.putExtra(KeychainService.EXTRA_DATA, data);
|
||||
|
||||
mProofVerifyDetail.setVisibility(View.GONE);
|
||||
|
||||
@ -365,8 +364,9 @@ public class ViewKeyTrustFragment extends LoaderFragment implements
|
||||
ServiceProgressHandler handler = new ServiceProgressHandler(
|
||||
getActivity(),
|
||||
getString(R.string.progress_verifying_signature),
|
||||
ProgressDialog.STYLE_HORIZONTAL,
|
||||
ProgressDialogFragment.ServiceType.KEYCHAIN_INTENT) {
|
||||
ProgressDialog.STYLE_HORIZONTAL
|
||||
) {
|
||||
@Override
|
||||
public void handleMessage(Message message) {
|
||||
// handle messages by standard KeychainIntentServiceHandler first
|
||||
super.handleMessage(message);
|
||||
@ -451,7 +451,7 @@ public class ViewKeyTrustFragment extends LoaderFragment implements
|
||||
|
||||
// Create a new Messenger for the communication back
|
||||
Messenger messenger = new Messenger(handler);
|
||||
intent.putExtra(KeychainIntentService.EXTRA_MESSENGER, messenger);
|
||||
intent.putExtra(KeychainService.EXTRA_MESSENGER, messenger);
|
||||
|
||||
// show progress dialog
|
||||
handler.showProgressDialog(getActivity());
|
||||
|
@ -43,7 +43,7 @@ import org.sufficientlysecure.keychain.operations.results.DecryptVerifyResult;
|
||||
import org.sufficientlysecure.keychain.operations.results.PromoteKeyResult;
|
||||
import org.sufficientlysecure.keychain.pgp.CanonicalizedSecretKey.SecretKeyType;
|
||||
import org.sufficientlysecure.keychain.provider.KeychainContract.Keys;
|
||||
import org.sufficientlysecure.keychain.service.KeychainIntentService;
|
||||
import org.sufficientlysecure.keychain.service.KeychainService;
|
||||
import org.sufficientlysecure.keychain.service.ServiceProgressHandler;
|
||||
import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
|
||||
|
||||
@ -129,6 +129,7 @@ public class ViewKeyYubiKeyFragment extends Fragment
|
||||
public void promoteToSecretKey() {
|
||||
|
||||
ServiceProgressHandler saveHandler = new ServiceProgressHandler(getActivity()) {
|
||||
@Override
|
||||
public void handleMessage(Message message) {
|
||||
// handle messages by standard KeychainIntentServiceHandler first
|
||||
super.handleMessage(message);
|
||||
@ -147,25 +148,25 @@ public class ViewKeyYubiKeyFragment extends Fragment
|
||||
};
|
||||
|
||||
// Send all information needed to service to decrypt in other thread
|
||||
Intent intent = new Intent(getActivity(), KeychainIntentService.class);
|
||||
Intent intent = new Intent(getActivity(), KeychainService.class);
|
||||
|
||||
// fill values for this action
|
||||
|
||||
intent.setAction(KeychainIntentService.ACTION_PROMOTE_KEYRING);
|
||||
intent.setAction(KeychainService.ACTION_PROMOTE_KEYRING);
|
||||
|
||||
Bundle data = new Bundle();
|
||||
data.putLong(KeychainIntentService.PROMOTE_MASTER_KEY_ID, mMasterKeyId);
|
||||
data.putByteArray(KeychainIntentService.PROMOTE_CARD_AID, mCardAid);
|
||||
data.putLong(KeychainService.PROMOTE_MASTER_KEY_ID, mMasterKeyId);
|
||||
data.putByteArray(KeychainService.PROMOTE_CARD_AID, mCardAid);
|
||||
long[] subKeyIds = new long[mFingerprints.length];
|
||||
for (int i = 0; i < subKeyIds.length; i++) {
|
||||
subKeyIds[i] = KeyFormattingUtils.getKeyIdFromFingerprint(mFingerprints[i]);
|
||||
}
|
||||
data.putLongArray(KeychainIntentService.PROMOTE_SUBKEY_IDS, subKeyIds);
|
||||
intent.putExtra(KeychainIntentService.EXTRA_DATA, data);
|
||||
data.putLongArray(KeychainService.PROMOTE_SUBKEY_IDS, subKeyIds);
|
||||
intent.putExtra(KeychainService.EXTRA_DATA, data);
|
||||
|
||||
// Create a new Messenger for the communication back
|
||||
Messenger messenger = new Messenger(saveHandler);
|
||||
intent.putExtra(KeychainIntentService.EXTRA_MESSENGER, messenger);
|
||||
intent.putExtra(KeychainService.EXTRA_MESSENGER, messenger);
|
||||
|
||||
// start service with intent
|
||||
getActivity().startService(intent);
|
||||
|
@ -109,7 +109,7 @@ public class ImportKeysListCloudLoader
|
||||
ImportKeysListEntry uniqueEntry = searchResult.get(0);
|
||||
/*
|
||||
* set fingerprint explicitly after query
|
||||
* to enforce a check when the key is imported by KeychainIntentService
|
||||
* to enforce a check when the key is imported by KeychainService
|
||||
*/
|
||||
uniqueEntry.setFingerprintHex(fingerprint);
|
||||
uniqueEntry.setSelected(true);
|
||||
|
@ -36,7 +36,7 @@ import org.sufficientlysecure.keychain.R;
|
||||
import org.sufficientlysecure.keychain.pgp.KeyRing;
|
||||
import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
|
||||
import org.sufficientlysecure.keychain.provider.ProviderHelper;
|
||||
import org.sufficientlysecure.keychain.service.KeychainIntentService;
|
||||
import org.sufficientlysecure.keychain.service.KeychainService;
|
||||
import org.sufficientlysecure.keychain.service.ServiceProgressHandler;
|
||||
import org.sufficientlysecure.keychain.util.Log;
|
||||
|
||||
@ -130,17 +130,17 @@ public class DeleteKeyDialogFragment extends DialogFragment {
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
|
||||
// Send all information needed to service to import key in other thread
|
||||
Intent intent = new Intent(getActivity(), KeychainIntentService.class);
|
||||
Intent intent = new Intent(getActivity(), KeychainService.class);
|
||||
|
||||
intent.setAction(KeychainIntentService.ACTION_DELETE);
|
||||
intent.setAction(KeychainService.ACTION_DELETE);
|
||||
|
||||
// Message is received after importing is done in KeychainIntentService
|
||||
// Message is received after importing is done in KeychainService
|
||||
ServiceProgressHandler saveHandler = new ServiceProgressHandler(
|
||||
getActivity(),
|
||||
getString(R.string.progress_deleting),
|
||||
ProgressDialog.STYLE_HORIZONTAL,
|
||||
true,
|
||||
ProgressDialogFragment.ServiceType.KEYCHAIN_INTENT) {
|
||||
true
|
||||
) {
|
||||
@Override
|
||||
public void handleMessage(Message message) {
|
||||
super.handleMessage(message);
|
||||
@ -159,13 +159,13 @@ public class DeleteKeyDialogFragment extends DialogFragment {
|
||||
|
||||
// fill values for this action
|
||||
Bundle data = new Bundle();
|
||||
data.putLongArray(KeychainIntentService.DELETE_KEY_LIST, masterKeyIds);
|
||||
data.putBoolean(KeychainIntentService.DELETE_IS_SECRET, hasSecret);
|
||||
intent.putExtra(KeychainIntentService.EXTRA_DATA, data);
|
||||
data.putLongArray(KeychainService.DELETE_KEY_LIST, masterKeyIds);
|
||||
data.putBoolean(KeychainService.DELETE_IS_SECRET, hasSecret);
|
||||
intent.putExtra(KeychainService.EXTRA_DATA, data);
|
||||
|
||||
// Create a new Messenger for the communication back
|
||||
Messenger messenger = new Messenger(saveHandler);
|
||||
intent.putExtra(KeychainIntentService.EXTRA_MESSENGER, messenger);
|
||||
intent.putExtra(KeychainService.EXTRA_MESSENGER, messenger);
|
||||
|
||||
// show progress dialog
|
||||
saveHandler.showProgressDialog(getActivity());
|
||||
|
@ -19,7 +19,6 @@ package org.sufficientlysecure.keychain.ui.dialog;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.Dialog;
|
||||
import android.app.DialogFragment;
|
||||
import android.app.ProgressDialog;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.DialogInterface.OnKeyListener;
|
||||
@ -27,31 +26,25 @@ import android.content.Intent;
|
||||
import android.graphics.Color;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.v4.app.DialogFragment;
|
||||
import android.view.ContextThemeWrapper;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.widget.Button;
|
||||
|
||||
import org.sufficientlysecure.keychain.Constants;
|
||||
import org.sufficientlysecure.keychain.R;
|
||||
import org.sufficientlysecure.keychain.service.CloudImportService;
|
||||
import org.sufficientlysecure.keychain.service.KeychainIntentService;
|
||||
import org.sufficientlysecure.keychain.util.Log;
|
||||
import org.sufficientlysecure.keychain.service.KeychainService;
|
||||
|
||||
/**
|
||||
* meant to be used
|
||||
*/
|
||||
public class ProgressDialogFragment extends DialogFragment {
|
||||
private static final String ARG_MESSAGE = "message";
|
||||
private static final String ARG_STYLE = "style";
|
||||
private static final String ARG_CANCELABLE = "cancelable";
|
||||
private static final String ARG_SERVICE_TYPE = "service_class";
|
||||
|
||||
public enum ServiceType {
|
||||
KEYCHAIN_INTENT,
|
||||
CLOUD_IMPORT
|
||||
}
|
||||
|
||||
ServiceType mServiceType;
|
||||
|
||||
boolean mCanCancel = false, mPreventCancel = false, mIsCancelled = false;
|
||||
|
||||
/**
|
||||
@ -59,16 +52,14 @@ public class ProgressDialogFragment extends DialogFragment {
|
||||
* @param message the message to be displayed initially above the progress bar
|
||||
* @param style the progress bar style, as defined in ProgressDialog (horizontal or spinner)
|
||||
* @param cancelable should we let the user cancel this operation
|
||||
* @param serviceType which Service this progress dialog is meant for
|
||||
* @return
|
||||
*/
|
||||
public static ProgressDialogFragment newInstance(String message, int style, boolean cancelable,
|
||||
ServiceType serviceType) {
|
||||
public static ProgressDialogFragment newInstance(String message, int style, boolean cancelable) {
|
||||
ProgressDialogFragment frag = new ProgressDialogFragment();
|
||||
Bundle args = new Bundle();
|
||||
args.putString(ARG_MESSAGE, message);
|
||||
args.putInt(ARG_STYLE, style);
|
||||
args.putBoolean(ARG_CANCELABLE, cancelable);
|
||||
args.putSerializable(ARG_SERVICE_TYPE, serviceType);
|
||||
|
||||
frag.setArguments(args);
|
||||
|
||||
@ -121,7 +112,6 @@ public class ProgressDialogFragment extends DialogFragment {
|
||||
String message = getArguments().getString(ARG_MESSAGE);
|
||||
int style = getArguments().getInt(ARG_STYLE);
|
||||
mCanCancel = getArguments().getBoolean(ARG_CANCELABLE);
|
||||
mServiceType = (ServiceType) getArguments().getSerializable(ARG_SERVICE_TYPE);
|
||||
|
||||
dialog.setMessage(message);
|
||||
dialog.setProgressStyle(style);
|
||||
@ -189,23 +179,11 @@ public class ProgressDialogFragment extends DialogFragment {
|
||||
negative.setTextColor(Color.GRAY);
|
||||
|
||||
// send a cancel message. note that this message will be handled by
|
||||
// KeychainIntentService.onStartCommand, which runs in this thread,
|
||||
// KeychainService.onStartCommand, which runs in this thread,
|
||||
// not the service one, and will not queue up a command.
|
||||
Intent serviceIntent = null;
|
||||
Intent serviceIntent = new Intent(getActivity(), KeychainService.class);
|
||||
|
||||
switch (mServiceType) {
|
||||
case CLOUD_IMPORT:
|
||||
serviceIntent = new Intent(getActivity(), CloudImportService.class);
|
||||
break;
|
||||
case KEYCHAIN_INTENT:
|
||||
serviceIntent = new Intent(getActivity(), KeychainIntentService.class);
|
||||
break;
|
||||
default:
|
||||
//should never happen, unless we forget to include a ServiceType enum case
|
||||
Log.e(Constants.TAG, "Unrecognized ServiceType at ProgressDialogFragment");
|
||||
}
|
||||
|
||||
serviceIntent.setAction(KeychainIntentService.ACTION_CANCEL);
|
||||
serviceIntent.setAction(KeychainService.ACTION_CANCEL);
|
||||
getActivity().startService(serviceIntent);
|
||||
|
||||
// Set the progress bar accordingly
|
||||
|
@ -62,9 +62,10 @@ public class Notify {
|
||||
|
||||
public static final int LENGTH_INDEFINITE = 0;
|
||||
public static final int LENGTH_LONG = 3500;
|
||||
public static final int LENGTH_SHORT = 1500;
|
||||
|
||||
public static Showable create(final Activity activity, String text, int duration, Style style,
|
||||
final ActionListener actionListener, int actionResId) {
|
||||
final ActionListener actionListener, Integer actionResId) {
|
||||
final Snackbar snackbar = Snackbar.with(activity)
|
||||
.type(SnackbarType.MULTI_LINE)
|
||||
.text(text);
|
||||
@ -77,14 +78,16 @@ public class Notify {
|
||||
|
||||
style.applyToBar(snackbar);
|
||||
|
||||
if (actionResId != null) {
|
||||
snackbar.actionLabel(actionResId);
|
||||
}
|
||||
if (actionListener != null) {
|
||||
snackbar.actionLabel(actionResId)
|
||||
.actionListener(new ActionClickListener() {
|
||||
@Override
|
||||
public void onActionClicked(Snackbar snackbar) {
|
||||
actionListener.onAction();
|
||||
}
|
||||
});
|
||||
snackbar.actionListener(new ActionClickListener() {
|
||||
@Override
|
||||
public void onActionClicked(Snackbar snackbar) {
|
||||
actionListener.onAction();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (activity instanceof FabContainer) {
|
||||
@ -107,6 +110,13 @@ public class Notify {
|
||||
SnackbarManager.show(snackbar, activity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void show(Fragment fragment, boolean animate) {
|
||||
snackbar.animation(animate);
|
||||
snackbar.dismissOnActionClicked(animate);
|
||||
show(fragment);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void show(Fragment fragment) {
|
||||
if (fragment != null) {
|
||||
@ -134,7 +144,7 @@ public class Notify {
|
||||
}
|
||||
|
||||
public static Showable create(Activity activity, String text, int duration, Style style) {
|
||||
return create(activity, text, duration, style, null, -1);
|
||||
return create(activity, text, duration, style, null, null);
|
||||
}
|
||||
|
||||
public static Showable create(Activity activity, String text, Style style) {
|
||||
@ -159,24 +169,26 @@ public class Notify {
|
||||
/**
|
||||
* Shows the notification on the bottom of the Activity.
|
||||
*/
|
||||
public void show();
|
||||
void show();
|
||||
|
||||
void show(Fragment fragment, boolean animate);
|
||||
|
||||
/**
|
||||
* Shows the notification on the bottom of the Fragment.
|
||||
*/
|
||||
public void show(Fragment fragment);
|
||||
void show(Fragment fragment);
|
||||
|
||||
/**
|
||||
* Shows the notification on the given ViewGroup.
|
||||
* The viewGroup should be either a RelativeLayout or FrameLayout.
|
||||
*/
|
||||
public void show(ViewGroup viewGroup);
|
||||
void show(ViewGroup viewGroup);
|
||||
|
||||
}
|
||||
|
||||
public interface ActionListener {
|
||||
|
||||
public void onAction();
|
||||
void onAction();
|
||||
|
||||
}
|
||||
|
||||
|
@ -26,7 +26,7 @@ import org.sufficientlysecure.keychain.keyimport.HkpKeyserver;
|
||||
import org.sufficientlysecure.keychain.keyimport.ImportKeysListEntry;
|
||||
import org.sufficientlysecure.keychain.keyimport.Keyserver;
|
||||
import org.sufficientlysecure.keychain.keyimport.ParcelableKeyRing;
|
||||
import org.sufficientlysecure.keychain.service.KeychainIntentService;
|
||||
import org.sufficientlysecure.keychain.service.KeychainService;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
@ -79,12 +79,12 @@ public class EmailKeyHelper {
|
||||
}
|
||||
|
||||
private static void importKeys(Context context, Messenger messenger, ArrayList<ParcelableKeyRing> keys) {
|
||||
Intent importIntent = new Intent(context, KeychainIntentService.class);
|
||||
importIntent.setAction(KeychainIntentService.ACTION_IMPORT_KEYRING);
|
||||
Intent importIntent = new Intent(context, KeychainService.class);
|
||||
importIntent.setAction(KeychainService.ACTION_IMPORT_KEYRING);
|
||||
Bundle importData = new Bundle();
|
||||
importData.putParcelableArrayList(KeychainIntentService.IMPORT_KEY_LIST, keys);
|
||||
importIntent.putExtra(KeychainIntentService.EXTRA_DATA, importData);
|
||||
importIntent.putExtra(KeychainIntentService.EXTRA_MESSENGER, messenger);
|
||||
importData.putParcelableArrayList(KeychainService.IMPORT_KEY_LIST, keys);
|
||||
importIntent.putExtra(KeychainService.EXTRA_DATA, importData);
|
||||
importIntent.putExtra(KeychainService.EXTRA_MESSENGER, messenger);
|
||||
|
||||
context.startService(importIntent);
|
||||
}
|
||||
|
@ -27,9 +27,8 @@ import android.support.v4.app.FragmentActivity;
|
||||
import org.sufficientlysecure.keychain.Constants;
|
||||
import org.sufficientlysecure.keychain.R;
|
||||
import org.sufficientlysecure.keychain.operations.results.ExportResult;
|
||||
import org.sufficientlysecure.keychain.service.KeychainIntentService;
|
||||
import org.sufficientlysecure.keychain.service.KeychainService;
|
||||
import org.sufficientlysecure.keychain.service.ServiceProgressHandler;
|
||||
import org.sufficientlysecure.keychain.ui.dialog.ProgressDialogFragment;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
@ -79,29 +78,30 @@ public class ExportHelper {
|
||||
Log.d(Constants.TAG, "exportKeys started");
|
||||
|
||||
// Send all information needed to service to export key in other thread
|
||||
final Intent intent = new Intent(mActivity, KeychainIntentService.class);
|
||||
final Intent intent = new Intent(mActivity, KeychainService.class);
|
||||
|
||||
intent.setAction(KeychainIntentService.ACTION_EXPORT_KEYRING);
|
||||
intent.setAction(KeychainService.ACTION_EXPORT_KEYRING);
|
||||
|
||||
// fill values for this action
|
||||
Bundle data = new Bundle();
|
||||
|
||||
data.putString(KeychainIntentService.EXPORT_FILENAME, mExportFile.getAbsolutePath());
|
||||
data.putBoolean(KeychainIntentService.EXPORT_SECRET, exportSecret);
|
||||
data.putString(KeychainService.EXPORT_FILENAME, mExportFile.getAbsolutePath());
|
||||
data.putBoolean(KeychainService.EXPORT_SECRET, exportSecret);
|
||||
|
||||
if (masterKeyIds == null) {
|
||||
data.putBoolean(KeychainIntentService.EXPORT_ALL, true);
|
||||
data.putBoolean(KeychainService.EXPORT_ALL, true);
|
||||
} else {
|
||||
data.putLongArray(KeychainIntentService.EXPORT_KEY_RING_MASTER_KEY_ID, masterKeyIds);
|
||||
data.putLongArray(KeychainService.EXPORT_KEY_RING_MASTER_KEY_ID, masterKeyIds);
|
||||
}
|
||||
|
||||
intent.putExtra(KeychainIntentService.EXTRA_DATA, data);
|
||||
intent.putExtra(KeychainService.EXTRA_DATA, data);
|
||||
|
||||
// Message is received after exporting is done in KeychainIntentService
|
||||
// Message is received after exporting is done in KeychainService
|
||||
ServiceProgressHandler exportHandler = new ServiceProgressHandler(mActivity,
|
||||
mActivity.getString(R.string.progress_exporting),
|
||||
ProgressDialog.STYLE_HORIZONTAL,
|
||||
ProgressDialogFragment.ServiceType.KEYCHAIN_INTENT) {
|
||||
ProgressDialog.STYLE_HORIZONTAL
|
||||
) {
|
||||
@Override
|
||||
public void handleMessage(Message message) {
|
||||
// handle messages by standard KeychainIntentServiceHandler first
|
||||
super.handleMessage(message);
|
||||
@ -118,7 +118,7 @@ public class ExportHelper {
|
||||
|
||||
// Create a new Messenger for the communication back
|
||||
Messenger messenger = new Messenger(exportHandler);
|
||||
intent.putExtra(KeychainIntentService.EXTRA_MESSENGER, messenger);
|
||||
intent.putExtra(KeychainService.EXTRA_MESSENGER, messenger);
|
||||
|
||||
// show progress dialog
|
||||
exportHandler.showProgressDialog(mActivity);
|
||||
|
@ -51,15 +51,15 @@ public class KeyUpdateHelper {
|
||||
}
|
||||
|
||||
// Start the service and update the keys
|
||||
Intent importIntent = new Intent(mContext, KeychainIntentService.class);
|
||||
importIntent.setAction(KeychainIntentService.ACTION_DOWNLOAD_AND_IMPORT_KEYS);
|
||||
Intent importIntent = new Intent(mContext, KeychainService.class);
|
||||
importIntent.setAction(KeychainService.ACTION_DOWNLOAD_AND_IMPORT_KEYS);
|
||||
|
||||
Bundle importData = new Bundle();
|
||||
importData.putParcelableArrayList(KeychainIntentService.DOWNLOAD_KEY_LIST,
|
||||
importData.putParcelableArrayList(KeychainService.DOWNLOAD_KEY_LIST,
|
||||
new ArrayList<ImportKeysListEntry>(keys));
|
||||
importIntent.putExtra(KeychainIntentService.EXTRA_SERVICE_INTENT, importData);
|
||||
importIntent.putExtra(KeychainService.EXTRA_SERVICE_INTENT, importData);
|
||||
|
||||
importIntent.putExtra(KeychainIntentService.EXTRA_MESSENGER, new Messenger(mHandler));
|
||||
importIntent.putExtra(KeychainService.EXTRA_MESSENGER, new Messenger(mHandler));
|
||||
|
||||
mContext.startService(importIntent);
|
||||
}
|
||||
|
@ -182,6 +182,48 @@ public class Preferences {
|
||||
editor.commit();
|
||||
}
|
||||
|
||||
public void setFilesUseCompression(boolean compress) {
|
||||
SharedPreferences.Editor editor = mSharedPreferences.edit();
|
||||
editor.putBoolean(Pref.FILE_USE_COMPRESSION, compress);
|
||||
editor.commit();
|
||||
}
|
||||
|
||||
public boolean getFilesUseCompression() {
|
||||
return mSharedPreferences.getBoolean(Pref.FILE_USE_COMPRESSION, true);
|
||||
}
|
||||
|
||||
public void setTextUseCompression(boolean compress) {
|
||||
SharedPreferences.Editor editor = mSharedPreferences.edit();
|
||||
editor.putBoolean(Pref.TEXT_USE_COMPRESSION, compress);
|
||||
editor.commit();
|
||||
}
|
||||
|
||||
public boolean getTextUseCompression() {
|
||||
return mSharedPreferences.getBoolean(Pref.TEXT_USE_COMPRESSION, true);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void setUseArmor(boolean useArmor) {
|
||||
SharedPreferences.Editor editor = mSharedPreferences.edit();
|
||||
editor.putBoolean(Pref.USE_ARMOR, useArmor);
|
||||
editor.commit();
|
||||
}
|
||||
|
||||
public boolean getUseArmor() {
|
||||
return mSharedPreferences.getBoolean(Pref.USE_ARMOR, false);
|
||||
}
|
||||
|
||||
public void setEncryptFilenames(boolean encryptFilenames) {
|
||||
SharedPreferences.Editor editor = mSharedPreferences.edit();
|
||||
editor.putBoolean(Pref.ENCRYPT_FILENAMES, encryptFilenames);
|
||||
editor.commit();
|
||||
}
|
||||
|
||||
public boolean getEncryptFilenames() {
|
||||
return mSharedPreferences.getBoolean(Pref.ENCRYPT_FILENAMES, true);
|
||||
}
|
||||
|
||||
public CloudSearchPrefs getCloudSearchPrefs() {
|
||||
return new CloudSearchPrefs(mSharedPreferences.getBoolean(Pref.SEARCH_KEYSERVER, true),
|
||||
mSharedPreferences.getBoolean(Pref.SEARCH_KEYBASE, true),
|
||||
|
@ -88,6 +88,8 @@
|
||||
<string name="btn_add_email">"Add additional email address"</string>
|
||||
<string name="btn_unlock">"Unlock"</string>
|
||||
<string name="btn_add_keyserver">"Add"</string>
|
||||
<string name="btn_save_default">"Save as default"</string>
|
||||
<string name="btn_saved">"Saved!"</string>
|
||||
|
||||
<!-- menu -->
|
||||
<string name="menu_preferences">"Settings"</string>
|
||||
@ -1154,6 +1156,7 @@
|
||||
<string name="msg_import_fingerprint_error">"Fingerprint of fetched key didn't match expected!"</string>
|
||||
<string name="msg_import_fingerprint_ok">"Fingerprint check OK"</string>
|
||||
<string name="msg_import_merge">"Merging retrieved data"</string>
|
||||
<string name="msg_import_merge_error">"Error merging retrieved data!"</string>
|
||||
<string name="msg_import_error">"Import operation failed!"</string>
|
||||
<string name="msg_import_error_io">"Import operation failed due to i/o error!"</string>
|
||||
<string name="msg_import_partial">"Import operation successful, with errors!"</string>
|
||||
@ -1310,4 +1313,11 @@
|
||||
<string name="error_bluetooth_file">Error creating temporary file. Bluetooth sharing will fail.</string>
|
||||
<string name="btn_delete_original">Delete original file</string>
|
||||
|
||||
<string name="snack_encrypt_filenames_on">"Filenames <b>are</b> encrypted."</string>
|
||||
<string name="snack_encrypt_filenames_off">"Filenames <b>are not</b> encrypted."</string>
|
||||
<string name="snack_armor_on">"Output encoded as Text."</string>
|
||||
<string name="snack_armor_off">"Output encoded as Binary."</string>
|
||||
<string name="snack_compression_on">"Compression <b>enabled</b>."</string>
|
||||
<string name="snack_compression_off">"Compression <b>disabled</b>."</string>
|
||||
|
||||
</resources>
|
||||
|
@ -174,7 +174,7 @@ The full coding style can be found at http://source.android.com/source/code-styl
|
||||
|
||||
## Licenses
|
||||
OpenKechain is licensed under GPLv3+.
|
||||
The full license text can be found in the [LICENSE file](https://github.com/open-keychain/open-keychain/blob/master/LICENSE).
|
||||
The full license text can be found in the [LICENSE file](https://github.com/open-keychain/open-keychain/blob/HEAD/LICENSE).
|
||||
Some parts and some libraries are Apache License v2, MIT X11 License (see below).
|
||||
|
||||
> This program is free software: you can redistribute it and/or modify
|
||||
@ -193,7 +193,7 @@ Some parts and some libraries are Apache License v2, MIT X11 License (see below)
|
||||
|
||||
### Libraries
|
||||
|
||||
See https://github.com/open-keychain/open-keychain/blob/development/OpenKeychain/src/main/res/raw/help_about.md
|
||||
See [In-app about screen](https://github.com/open-keychain/open-keychain/blob/HEAD/OpenKeychain/src/main/res/raw/help_about.md)
|
||||
|
||||
### Images
|
||||
* icon.svg
|
||||
|
Loading…
Reference in New Issue
Block a user