diff --git a/OpenKeychain/src/main/AndroidManifest.xml b/OpenKeychain/src/main/AndroidManifest.xml
index 9b52bb788..d0f50d5cc 100644
--- a/OpenKeychain/src/main/AndroidManifest.xml
+++ b/OpenKeychain/src/main/AndroidManifest.xml
@@ -696,6 +696,10 @@
android:name=".service.PassphraseCacheService"
android:exported="false"
android:process=":passphrase_cache" />
+
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/CryptoInputParcelCacheService.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/CryptoInputParcelCacheService.java
new file mode 100644
index 000000000..e3e39417a
--- /dev/null
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/CryptoInputParcelCacheService.java
@@ -0,0 +1,246 @@
+/*
+ * Copyright (C) 2015 Dominik Schürmann
+ *
+ * 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 .
+ */
+
+package org.sufficientlysecure.keychain.remote;
+
+import android.app.Service;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Binder;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.IBinder;
+import android.os.Message;
+import android.os.Messenger;
+import android.os.RemoteException;
+
+import org.openintents.openpgp.util.OpenPgpApi;
+import org.sufficientlysecure.keychain.Constants;
+import org.sufficientlysecure.keychain.service.input.CryptoInputParcel;
+import org.sufficientlysecure.keychain.util.Log;
+
+import java.util.UUID;
+import java.util.concurrent.ConcurrentHashMap;
+
+
+public class CryptoInputParcelCacheService extends Service {
+
+ public static final String ACTION_ADD = Constants.INTENT_PREFIX + "ADD";
+ public static final String ACTION_GET = Constants.INTENT_PREFIX + "GET";
+
+ public static final String EXTRA_CRYPTO_INPUT_PARCEL = "crypto_input_parcel";
+ public static final String EXTRA_UUID1 = "uuid1";
+ public static final String EXTRA_UUID2 = "uuid2";
+ public static final String EXTRA_MESSENGER = "messenger";
+
+ private static final int MSG_GET_OKAY = 1;
+ private static final int MSG_GET_NOT_FOUND = 2;
+
+ Context mContext;
+
+ private static final UUID NULL_UUID = new UUID(0, 0);
+
+ private ConcurrentHashMap mCache = new ConcurrentHashMap<>();
+
+ public static class InputParcelNotFound extends Exception {
+ public InputParcelNotFound() {
+ }
+
+ public InputParcelNotFound(String name) {
+ super(name);
+ }
+ }
+
+ public static void addCryptoInputParcel(Context context, Intent data, CryptoInputParcel inputParcel) {
+ UUID mTicket = addCryptoInputParcel(context, inputParcel);
+ // And write out the UUID most and least significant bits.
+ data.putExtra(OpenPgpApi.EXTRA_CALL_UUID1, mTicket.getMostSignificantBits());
+ data.putExtra(OpenPgpApi.EXTRA_CALL_UUID2, mTicket.getLeastSignificantBits());
+ }
+
+ public static CryptoInputParcel getCryptoInputParcel(Context context, Intent data) {
+ if (!data.getExtras().containsKey(OpenPgpApi.EXTRA_CALL_UUID1)
+ || !data.getExtras().containsKey(OpenPgpApi.EXTRA_CALL_UUID2)) {
+ return null;
+ }
+ long mostSig = data.getLongExtra(OpenPgpApi.EXTRA_CALL_UUID1, 0);
+ long leastSig = data.getLongExtra(OpenPgpApi.EXTRA_CALL_UUID2, 0);
+ UUID uuid = new UUID(mostSig, leastSig);
+ try {
+ return getCryptoInputParcel(context, uuid);
+ } catch (InputParcelNotFound inputParcelNotFound) {
+ return null;
+ }
+ }
+
+ private static UUID addCryptoInputParcel(Context context, CryptoInputParcel inputParcel) {
+ UUID uuid = UUID.randomUUID();
+
+ Intent intent = new Intent(context, CryptoInputParcelCacheService.class);
+ intent.setAction(ACTION_ADD);
+ intent.putExtra(EXTRA_CRYPTO_INPUT_PARCEL, inputParcel);
+ intent.putExtra(EXTRA_UUID1, uuid.getMostSignificantBits());
+ intent.putExtra(EXTRA_UUID2, uuid.getLeastSignificantBits());
+ context.startService(intent);
+ return uuid;
+ }
+
+ private static CryptoInputParcel getCryptoInputParcel(Context context, UUID uuid) throws InputParcelNotFound {
+ Intent intent = new Intent(context, CryptoInputParcelCacheService.class);
+ intent.setAction(ACTION_GET);
+
+ final Object mutex = new Object();
+ final Message returnMessage = Message.obtain();
+
+ HandlerThread handlerThread = new HandlerThread("getParcelableThread");
+ handlerThread.start();
+ Handler returnHandler = new Handler(handlerThread.getLooper()) {
+ @Override
+ public void handleMessage(Message message) {
+ // copy over result to handle after mutex.wait
+ returnMessage.what = message.what;
+ returnMessage.copyFrom(message);
+ synchronized (mutex) {
+ mutex.notify();
+ }
+ // quit handlerThread
+ getLooper().quit();
+ }
+ };
+
+ // Create a new Messenger for the communication back
+ Messenger messenger = new Messenger(returnHandler);
+ intent.putExtra(EXTRA_UUID1, uuid.getMostSignificantBits());
+ intent.putExtra(EXTRA_UUID2, uuid.getLeastSignificantBits());
+ intent.putExtra(EXTRA_MESSENGER, messenger);
+ // send intent to this service
+ context.startService(intent);
+
+ // Wait on mutex until parcelable is returned to handlerThread. Note that this local
+ // variable is used in the handler closure above, so it does make sense here!
+ // noinspection SynchronizationOnLocalVariableOrMethodParameter
+ synchronized (mutex) {
+ try {
+ mutex.wait(3000);
+ } catch (InterruptedException e) {
+ // don't care
+ }
+ }
+
+ switch (returnMessage.what) {
+ case MSG_GET_OKAY:
+ Bundle returnData = returnMessage.getData();
+ returnData.setClassLoader(context.getClassLoader());
+ return returnData.getParcelable(EXTRA_CRYPTO_INPUT_PARCEL);
+ case MSG_GET_NOT_FOUND:
+ throw new InputParcelNotFound();
+ default:
+ Log.e(Constants.TAG, "timeout!");
+ throw new InputParcelNotFound("should not happen!");
+ }
+ }
+
+ /**
+ * Executed when service is started by intent
+ */
+ @Override
+ public int onStartCommand(Intent intent, int flags, int startId) {
+
+ if (intent == null || intent.getAction() == null) {
+ return START_NOT_STICKY;
+ }
+
+ String action = intent.getAction();
+ switch (action) {
+ case ACTION_ADD: {
+ long uuid1 = intent.getLongExtra(EXTRA_UUID1, 0);
+ long uuid2 = intent.getLongExtra(EXTRA_UUID2, 0);
+ UUID uuid = new UUID(uuid1, uuid2);
+ CryptoInputParcel inputParcel = intent.getParcelableExtra(EXTRA_CRYPTO_INPUT_PARCEL);
+ mCache.put(uuid, inputParcel);
+
+ break;
+ }
+ case ACTION_GET: {
+ long uuid1 = intent.getLongExtra(EXTRA_UUID1, 0);
+ long uuid2 = intent.getLongExtra(EXTRA_UUID2, 0);
+ UUID uuid = new UUID(uuid1, uuid2);
+ Messenger messenger = intent.getParcelableExtra(EXTRA_MESSENGER);
+
+ Message msg = Message.obtain();
+ // UUID.equals isn't well documented; we use compareTo instead.
+ if (NULL_UUID.compareTo(uuid) == 0) {
+ msg.what = MSG_GET_NOT_FOUND;
+ } else {
+ CryptoInputParcel inputParcel = mCache.get(uuid);
+ mCache.remove(uuid);
+ msg.what = MSG_GET_OKAY;
+ Bundle bundle = new Bundle();
+ bundle.putParcelable(EXTRA_CRYPTO_INPUT_PARCEL, inputParcel);
+ msg.setData(bundle);
+ }
+
+ try {
+ messenger.send(msg);
+ } catch (RemoteException e) {
+ Log.e(Constants.TAG, "CryptoInputParcelCacheService: Sending message failed", e);
+ }
+ break;
+ }
+ default: {
+ Log.e(Constants.TAG, "CryptoInputParcelCacheService: Intent or Intent Action not supported!");
+ break;
+ }
+ }
+
+ if (mCache.size() <= 0) {
+ // stop whole service if cache is empty
+ Log.d(Constants.TAG, "CryptoInputParcelCacheService: No passphrases remaining in memory, stopping service!");
+ stopSelf();
+ }
+
+ return START_NOT_STICKY;
+ }
+
+ @Override
+ public void onCreate() {
+ super.onCreate();
+ mContext = this;
+ Log.d(Constants.TAG, "CryptoInputParcelCacheService, onCreate()");
+ }
+
+ @Override
+ public void onDestroy() {
+ super.onDestroy();
+ Log.d(Constants.TAG, "CryptoInputParcelCacheService, onDestroy()");
+ }
+
+ @Override
+ public IBinder onBind(Intent intent) {
+ return mBinder;
+ }
+
+ public class CryptoInputParcelCacheServiceBinder extends Binder {
+ public CryptoInputParcelCacheService getService() {
+ return CryptoInputParcelCacheService.this;
+ }
+ }
+
+ private final IBinder mBinder = new CryptoInputParcelCacheServiceBinder();
+
+}
\ No newline at end of file
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java
index 39f7f815c..71843cd7f 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java
@@ -36,7 +36,6 @@ import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.operations.results.DecryptVerifyResult;
import org.sufficientlysecure.keychain.operations.results.OperationResult.LogEntryParcel;
import org.sufficientlysecure.keychain.operations.results.PgpSignEncryptResult;
-import org.sufficientlysecure.keychain.operations.results.SignEncryptResult;
import org.sufficientlysecure.keychain.pgp.PgpConstants;
import org.sufficientlysecure.keychain.pgp.PgpDecryptVerify;
import org.sufficientlysecure.keychain.pgp.PgpSignEncryptInputParcel;
@@ -57,7 +56,6 @@ import org.sufficientlysecure.keychain.ui.PassphraseDialogActivity;
import org.sufficientlysecure.keychain.ui.ViewKeyActivity;
import org.sufficientlysecure.keychain.util.InputData;
import org.sufficientlysecure.keychain.util.Log;
-import org.sufficientlysecure.keychain.util.ParcelableCache;
import org.sufficientlysecure.keychain.util.Passphrase;
import java.io.IOException;
@@ -68,25 +66,6 @@ import java.util.Set;
public class OpenPgpService extends RemoteService {
- /**
- * Instead of parceling the CryptoInputParcel, they are cached on our side to prevent
- * leakage of passphrases, symmetric keys, an yubikey related pass-through values
- */
- private static ParcelableCache inputParcelCache;
- static {
- inputParcelCache = new ParcelableCache<>();
- }
-
- public static void cacheCryptoInputParcel(Intent data, CryptoInputParcel inputParcel) {
- inputParcelCache.cacheAndWriteToIntent(inputParcel, data,
- OpenPgpApi.EXTRA_CALL_UUID1, OpenPgpApi.EXTRA_CALL_UUID2);
- }
-
- public static CryptoInputParcel getCryptoInputParcel(Intent data) {
- return inputParcelCache.readFromIntentAndGetFromCache(data,
- OpenPgpApi.EXTRA_CALL_UUID1, OpenPgpApi.EXTRA_CALL_UUID2);
- }
-
static final String[] EMAIL_SEARCH_PROJECTION = new String[]{
KeyRings._ID,
KeyRings.MASTER_KEY_ID,
@@ -283,7 +262,7 @@ public class OpenPgpService extends RemoteService {
long inputLength = is.available();
InputData inputData = new InputData(is, inputLength);
- CryptoInputParcel inputParcel = getCryptoInputParcel(data);
+ CryptoInputParcel inputParcel = CryptoInputParcelCacheService.getCryptoInputParcel(this, data);
if (inputParcel == null) {
inputParcel = new CryptoInputParcel();
}
@@ -424,7 +403,7 @@ public class OpenPgpService extends RemoteService {
.setAdditionalEncryptId(signKeyId); // add sign key for encryption
}
- CryptoInputParcel inputParcel = getCryptoInputParcel(data);
+ CryptoInputParcel inputParcel = CryptoInputParcelCacheService.getCryptoInputParcel(this, data);
if (inputParcel == null) {
inputParcel = new CryptoInputParcel();
}
@@ -513,7 +492,7 @@ public class OpenPgpService extends RemoteService {
this, new ProviderHelper(getContext()), null, inputData, os
);
- CryptoInputParcel inputParcel = getCryptoInputParcel(data);
+ CryptoInputParcel inputParcel = CryptoInputParcelCacheService.getCryptoInputParcel(this, data);
if (inputParcel == null) {
inputParcel = new CryptoInputParcel();
}
@@ -768,9 +747,7 @@ public class OpenPgpService extends RemoteService {
return null;
}
- // TODO: multi-threading
private final IOpenPgpService.Stub mBinder = new IOpenPgpService.Stub() {
-
@Override
public Intent execute(Intent data, ParcelFileDescriptor input, ParcelFileDescriptor output) {
try {
@@ -780,30 +757,42 @@ public class OpenPgpService extends RemoteService {
}
String action = data.getAction();
- if (OpenPgpApi.ACTION_CLEARTEXT_SIGN.equals(action)) {
- return signImpl(data, input, output, true);
- } else if (OpenPgpApi.ACTION_SIGN.equals(action)) {
- // DEPRECATED: same as ACTION_CLEARTEXT_SIGN
- Log.w(Constants.TAG, "You are using a deprecated API call, please use ACTION_CLEARTEXT_SIGN instead of ACTION_SIGN!");
- return signImpl(data, input, output, true);
- } else if (OpenPgpApi.ACTION_DETACHED_SIGN.equals(action)) {
- return signImpl(data, input, output, false);
- } else if (OpenPgpApi.ACTION_ENCRYPT.equals(action)) {
- return encryptAndSignImpl(data, input, output, false);
- } else if (OpenPgpApi.ACTION_SIGN_AND_ENCRYPT.equals(action)) {
- return encryptAndSignImpl(data, input, output, true);
- } else if (OpenPgpApi.ACTION_DECRYPT_VERIFY.equals(action)) {
- return decryptAndVerifyImpl(data, input, output, false);
- } else if (OpenPgpApi.ACTION_DECRYPT_METADATA.equals(action)) {
- return decryptAndVerifyImpl(data, input, output, true);
- } else if (OpenPgpApi.ACTION_GET_SIGN_KEY_ID.equals(action)) {
- return getSignKeyIdImpl(data);
- } else if (OpenPgpApi.ACTION_GET_KEY_IDS.equals(action)) {
- return getKeyIdsImpl(data);
- } else if (OpenPgpApi.ACTION_GET_KEY.equals(action)) {
- return getKeyImpl(data);
- } else {
- return null;
+ switch (action) {
+ case OpenPgpApi.ACTION_CLEARTEXT_SIGN: {
+ return signImpl(data, input, output, true);
+ }
+ case OpenPgpApi.ACTION_SIGN: {
+ // DEPRECATED: same as ACTION_CLEARTEXT_SIGN
+ Log.w(Constants.TAG, "You are using a deprecated API call, please use ACTION_CLEARTEXT_SIGN instead of ACTION_SIGN!");
+ return signImpl(data, input, output, true);
+ }
+ case OpenPgpApi.ACTION_DETACHED_SIGN: {
+ return signImpl(data, input, output, false);
+ }
+ case OpenPgpApi.ACTION_ENCRYPT: {
+ return encryptAndSignImpl(data, input, output, false);
+ }
+ case OpenPgpApi.ACTION_SIGN_AND_ENCRYPT: {
+ return encryptAndSignImpl(data, input, output, true);
+ }
+ case OpenPgpApi.ACTION_DECRYPT_VERIFY: {
+ return decryptAndVerifyImpl(data, input, output, false);
+ }
+ case OpenPgpApi.ACTION_DECRYPT_METADATA: {
+ return decryptAndVerifyImpl(data, input, output, true);
+ }
+ case OpenPgpApi.ACTION_GET_SIGN_KEY_ID: {
+ return getSignKeyIdImpl(data);
+ }
+ case OpenPgpApi.ACTION_GET_KEY_IDS: {
+ return getKeyIdsImpl(data);
+ }
+ case OpenPgpApi.ACTION_GET_KEY: {
+ return getKeyImpl(data);
+ }
+ default: {
+ return null;
+ }
}
} finally {
// always close input and output file descriptors even in error cases
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/PassphraseCacheService.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/PassphraseCacheService.java
index 2e09db900..778d0d525 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/PassphraseCacheService.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/PassphraseCacheService.java
@@ -337,11 +337,17 @@ public class PassphraseCacheService extends Service {
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d(Constants.TAG, "PassphraseCacheService.onStartCommand()");
+ if (intent == null || intent.getAction() == null) {
+ updateService();
+ return START_STICKY;
+ }
+
// register broadcastreceiver
registerReceiver();
- if (intent != null && intent.getAction() != null) {
- if (ACTION_PASSPHRASE_CACHE_ADD.equals(intent.getAction())) {
+ String action = intent.getAction();
+ switch (action) {
+ case ACTION_PASSPHRASE_CACHE_ADD: {
long ttl = intent.getLongExtra(EXTRA_TTL, DEFAULT_TTL);
long masterKeyId = intent.getLongExtra(EXTRA_KEY_ID, -1);
long subKeyId = intent.getLongExtra(EXTRA_SUBKEY_ID, -1);
@@ -365,9 +371,9 @@ public class PassphraseCacheService extends Service {
AlarmManager am = (AlarmManager) this.getSystemService(Context.ALARM_SERVICE);
am.set(AlarmManager.RTC_WAKEUP, triggerTime, buildIntent(this, referenceKeyId));
}
-
- updateService();
- } else if (ACTION_PASSPHRASE_CACHE_GET.equals(intent.getAction())) {
+ break;
+ }
+ case ACTION_PASSPHRASE_CACHE_GET: {
long masterKeyId = intent.getLongExtra(EXTRA_KEY_ID, Constants.key.symmetric);
long subKeyId = intent.getLongExtra(EXTRA_SUBKEY_ID, Constants.key.symmetric);
Messenger messenger = intent.getParcelableExtra(EXTRA_MESSENGER);
@@ -395,7 +401,9 @@ public class PassphraseCacheService extends Service {
} catch (RemoteException e) {
Log.e(Constants.TAG, "PassphraseCacheService: Sending message failed", e);
}
- } else if (ACTION_PASSPHRASE_CACHE_CLEAR.equals(intent.getAction())) {
+ break;
+ }
+ case ACTION_PASSPHRASE_CACHE_CLEAR: {
AlarmManager am = (AlarmManager) this.getSystemService(Context.ALARM_SERVICE);
if (intent.hasExtra(EXTRA_SUBKEY_ID) && intent.hasExtra(EXTRA_KEY_ID)) {
@@ -419,13 +427,16 @@ public class PassphraseCacheService extends Service {
mPassphraseCache.clear();
}
-
- updateService();
- } else {
+ break;
+ }
+ default: {
Log.e(Constants.TAG, "PassphraseCacheService: Intent or Intent Action not supported!");
+ break;
}
}
+ updateService();
+
return START_STICKY;
}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/NfcOperationActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/NfcOperationActivity.java
index 02fc81825..a0b38c2b2 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/NfcOperationActivity.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/NfcOperationActivity.java
@@ -10,13 +10,11 @@ import android.annotation.TargetApi;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
-import android.os.Parcelable;
import android.view.WindowManager;
-import org.openintents.openpgp.util.OpenPgpApi;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R;
-import org.sufficientlysecure.keychain.remote.OpenPgpService;
+import org.sufficientlysecure.keychain.remote.CryptoInputParcelCacheService;
import org.sufficientlysecure.keychain.service.PassphraseCacheService;
import org.sufficientlysecure.keychain.service.input.CryptoInputParcel;
import org.sufficientlysecure.keychain.service.input.RequiredInputParcel;
@@ -93,7 +91,7 @@ public class NfcOperationActivity extends BaseNfcActivity {
}
if (mServiceIntent != null) {
- OpenPgpService.cacheCryptoInputParcel(mServiceIntent, inputParcel);
+ CryptoInputParcelCacheService.addCryptoInputParcel(this, mServiceIntent, inputParcel);
setResult(RESULT_OK, mServiceIntent);
} else {
Intent result = new Intent();
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/PassphraseDialogActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/PassphraseDialogActivity.java
index bf6129407..84612002f 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/PassphraseDialogActivity.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/PassphraseDialogActivity.java
@@ -41,7 +41,6 @@ import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
-import org.openintents.openpgp.util.OpenPgpApi;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.compatibility.DialogFragmentWorkaround;
@@ -53,11 +52,10 @@ import org.sufficientlysecure.keychain.pgp.exception.PgpKeyNotFoundException;
import org.sufficientlysecure.keychain.provider.CachedPublicKeyRing;
import org.sufficientlysecure.keychain.provider.KeychainContract;
import org.sufficientlysecure.keychain.provider.ProviderHelper;
-import org.sufficientlysecure.keychain.remote.OpenPgpService;
+import org.sufficientlysecure.keychain.remote.CryptoInputParcelCacheService;
import org.sufficientlysecure.keychain.service.PassphraseCacheService;
import org.sufficientlysecure.keychain.service.input.CryptoInputParcel;
import org.sufficientlysecure.keychain.service.input.RequiredInputParcel;
-import org.sufficientlysecure.keychain.service.input.RequiredInputParcel.RequiredInputType;
import org.sufficientlysecure.keychain.ui.dialog.CustomAlertDialogBuilder;
import org.sufficientlysecure.keychain.util.Log;
import org.sufficientlysecure.keychain.util.Passphrase;
@@ -428,7 +426,7 @@ public class PassphraseDialogActivity extends FragmentActivity {
CryptoInputParcel inputParcel = new CryptoInputParcel(null, passphrase);
if (mServiceIntent != null) {
- OpenPgpService.cacheCryptoInputParcel(mServiceIntent, inputParcel);
+ CryptoInputParcelCacheService.addCryptoInputParcel(getActivity(), mServiceIntent, inputParcel);
getActivity().setResult(RESULT_OK, mServiceIntent);
} else {
// also return passphrase back to activity
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/ParcelableCache.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/ParcelableCache.java
index 54c984190..75bdee00a 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/ParcelableCache.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/ParcelableCache.java
@@ -17,8 +17,6 @@
package org.sufficientlysecure.keychain.util;
-import android.content.Intent;
-import android.os.Bundle;
import android.os.Parcel;
import java.util.UUID;
@@ -30,7 +28,7 @@ import java.util.concurrent.ConcurrentHashMap;
* To overcome this issue this class allows to cache Parcelables, mapped by unique UUIDs,
* which are written to the parcel instead of the whole Parcelable.
*/
-public class ParcelableCache {
+public class ParcelableCache {
private static final UUID NULL_UUID = new UUID(0, 0);
@@ -39,7 +37,7 @@ public class ParcelableCache {
* This is used such that when we become parceled, we are
* well below the 1 MB boundary that is specified.
*/
- private ConcurrentHashMap dehydratedLogs = new ConcurrentHashMap<>();
+ private ConcurrentHashMap objectCache = new ConcurrentHashMap<>();
/**
* Dehydrate a Parcelable (such that it is available after deparcelization)
@@ -52,9 +50,9 @@ public class ParcelableCache {
if (parcelable == null) {
return NULL_UUID;
} else {
- UUID ticket = UUID.randomUUID();
- dehydratedLogs.put(ticket, parcelable);
- return ticket;
+ UUID uuid = UUID.randomUUID();
+ objectCache.put(uuid, parcelable);
+ return uuid;
}
}
@@ -63,53 +61,34 @@ public class ParcelableCache {
* invalidating its place in the dehydration pool.
* This is used such that when parcelized, the Parcelable is no larger than 1 MB.
*
- * @param ticket A UUID ticket that identifies the log in question.
+ * @param uuid A UUID ticket that identifies the log in question.
* @return An OperationLog.
*/
- private E rehydrateParcelable(UUID ticket) {
+ private E rehydrateParcelable(UUID uuid) {
// UUID.equals isn't well documented; we use compareTo instead.
- if (NULL_UUID.compareTo(ticket) == 0) {
+ if (NULL_UUID.compareTo(uuid) == 0) {
return null;
} else {
- E parcelable = dehydratedLogs.get(ticket);
- dehydratedLogs.remove(ticket);
+ E parcelable = objectCache.get(uuid);
+ objectCache.remove(uuid);
return parcelable;
}
}
- public E readFromIntentAndGetFromCache(Intent data, String key1, String key2) {
- if (!data.getExtras().containsKey(key1) || !data.getExtras().containsKey(key2)) {
- return null;
- }
- long mostSig = data.getLongExtra(key1, 0);
- long leastSig = data.getLongExtra(key2, 0);
- UUID mTicket = new UUID(mostSig, leastSig);
- // fetch the dehydrated log out of storage (this removes it from the dehydration pool)
- return rehydrateParcelable(mTicket);
- }
-
public E readFromParcelAndGetFromCache(Parcel source) {
long mostSig = source.readLong();
long leastSig = source.readLong();
UUID mTicket = new UUID(mostSig, leastSig);
- // fetch the dehydrated log out of storage (this removes it from the dehydration pool)
+ // fetch the dehydrated parcelable out of storage (this removes it from the dehydration pool)
return rehydrateParcelable(mTicket);
}
public void cacheAndWriteToParcel(E parcelable, Parcel dest) {
- // Get a ticket for our log.
+ // Get a ticket for our parcelable.
UUID mTicket = dehydrateParcelable(parcelable);
// And write out the UUID most and least significant bits.
dest.writeLong(mTicket.getMostSignificantBits());
dest.writeLong(mTicket.getLeastSignificantBits());
}
- public void cacheAndWriteToIntent(E parcelable, Intent data, String key1, String key2) {
- // Get a ticket for our log.
- UUID mTicket = dehydrateParcelable(parcelable);
- // And write out the UUID most and least significant bits.
- data.putExtra(key1, mTicket.getMostSignificantBits());
- data.putExtra(key2, mTicket.getLeastSignificantBits());
- }
-
}