aboutsummaryrefslogtreecommitdiffstats
path: root/OpenKeychain/src/main/java/org/sufficientlysecure
diff options
context:
space:
mode:
Diffstat (limited to 'OpenKeychain/src/main/java/org/sufficientlysecure')
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/ImportExportOperation.java20
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/CertifyResult.java2
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/DeleteResult.java2
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/ImportKeyResult.java2
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/OperationResult.java26
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java28
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/RemoteServiceActivity.java2
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/CloudImportService.java387
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java22
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/PassphraseCacheService.java4
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/ServiceProgressHandler.java (renamed from OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentServiceHandler.java)30
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyFragment.java19
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ConsolidateDialogActivity.java8
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyFinalFragment.java21
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFilesFragment.java19
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptTextActivity.java4
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptTextFragment.java12
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyFragment.java18
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivity.java10
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptFilesActivity.java12
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptFilesFragment.java8
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptTextActivity.java21
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/HelpAboutFragment.java13
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/HelpActivity.java19
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/HelpMarkdownFragment.java (renamed from OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/HelpHtmlFragment.java)26
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java45
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysProxyActivity.java8
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java125
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/QrCodeViewActivity.java4
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/SafeSlingerActivity.java10
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/UploadKeyActivity.java10
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java187
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvShareFragment.java31
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyTrustFragment.java21
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteKeyDialogFragment.java11
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/FileDialogFragment.java2
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/ProgressDialogFragment.java44
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/util/Notify.java231
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/ExportHelper.java13
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/NfcHelper.java218
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/ParcelableFileCache.java12
41 files changed, 1204 insertions, 503 deletions
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/ImportExportOperation.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/ImportExportOperation.java
index 20dba95e9..f2516f1bd 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/ImportExportOperation.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/ImportExportOperation.java
@@ -168,7 +168,7 @@ public class ImportExportOperation extends BaseOperation {
return new ImportKeyResult(ImportKeyResult.RESULT_FAIL_NOTHING, log);
}
- int newKeys = 0, oldKeys = 0, badKeys = 0, secret = 0;
+ int newKeys = 0, updatedKeys = 0, badKeys = 0, secret = 0;
ArrayList<Long> importedMasterKeyIds = new ArrayList<>();
boolean cancelled = false;
@@ -302,7 +302,7 @@ public class ImportExportOperation extends BaseOperation {
if (!result.success()) {
badKeys += 1;
} else if (result.updated()) {
- oldKeys += 1;
+ updatedKeys += 1;
importedMasterKeyIds.add(key.getMasterKeyId());
} else {
newKeys += 1;
@@ -333,7 +333,9 @@ public class ImportExportOperation extends BaseOperation {
}
// Special: make sure new data is synced into contacts
- ContactSyncAdapterService.requestSync();
+ // 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();
// convert to long array
long[] importedMasterKeyIdsArray = new long[importedMasterKeyIds.size()];
@@ -348,18 +350,18 @@ public class ImportExportOperation extends BaseOperation {
}
// special return case: no new keys at all
- if (badKeys == 0 && newKeys == 0 && oldKeys == 0) {
+ if (badKeys == 0 && newKeys == 0 && updatedKeys == 0) {
resultType = ImportKeyResult.RESULT_FAIL_NOTHING;
} else {
if (newKeys > 0) {
resultType |= ImportKeyResult.RESULT_OK_NEWKEYS;
}
- if (oldKeys > 0) {
+ if (updatedKeys > 0) {
resultType |= ImportKeyResult.RESULT_OK_UPDATED;
}
if (badKeys > 0) {
resultType |= ImportKeyResult.RESULT_WITH_ERRORS;
- if (newKeys == 0 && oldKeys == 0) {
+ if (newKeys == 0 && updatedKeys == 0) {
resultType |= ImportKeyResult.RESULT_ERROR;
}
}
@@ -369,15 +371,15 @@ public class ImportExportOperation extends BaseOperation {
}
// Final log entry, it's easier to do this individually
- if ( (newKeys > 0 || oldKeys > 0) && badKeys > 0) {
+ if ( (newKeys > 0 || updatedKeys > 0) && badKeys > 0) {
log.add(LogType.MSG_IMPORT_PARTIAL, 1);
- } else if (newKeys > 0 || oldKeys > 0) {
+ } else if (newKeys > 0 || updatedKeys > 0) {
log.add(LogType.MSG_IMPORT_SUCCESS, 1);
} else {
log.add(LogType.MSG_IMPORT_ERROR, 1);
}
- return new ImportKeyResult(resultType, log, newKeys, oldKeys, badKeys, secret,
+ return new ImportKeyResult(resultType, log, newKeys, updatedKeys, badKeys, secret,
importedMasterKeyIdsArray);
}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/CertifyResult.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/CertifyResult.java
index 94684851a..f56fe4bb9 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/CertifyResult.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/CertifyResult.java
@@ -120,7 +120,7 @@ public class CertifyResult extends OperationResult {
mCertifyError, mCertifyError);
}
- return Notify.createNotify(activity, str, duration, style, new ActionListener() {
+ return Notify.create(activity, str, duration, style, new ActionListener() {
@Override
public void onAction() {
Intent intent = new Intent(
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/DeleteResult.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/DeleteResult.java
index 62197541a..50f49add2 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/DeleteResult.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/DeleteResult.java
@@ -116,7 +116,7 @@ public class DeleteResult extends OperationResult {
}
}
- return Notify.createNotify(activity, str, duration, style, new ActionListener() {
+ return Notify.create(activity, str, duration, style, new ActionListener() {
@Override
public void onAction() {
Intent intent = new Intent(
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/ImportKeyResult.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/ImportKeyResult.java
index 2d533ed16..af9f67114 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/ImportKeyResult.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/ImportKeyResult.java
@@ -179,7 +179,7 @@ public class ImportKeyResult extends OperationResult {
}
}
- return Notify.createNotify(activity, str, duration, style, new ActionListener() {
+ return Notify.create(activity, str, duration, style, new ActionListener() {
@Override
public void onAction() {
Intent intent = new Intent(
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/OperationResult.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/OperationResult.java
index 068e314d5..f2a27b0fc 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/OperationResult.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/OperationResult.java
@@ -273,19 +273,19 @@ public abstract class OperationResult implements Parcelable {
}
if (getLog() == null || getLog().isEmpty()) {
- return Notify.createNotify(activity, msgId, Notify.LENGTH_LONG, style);
- }
-
- return Notify.createNotify(activity, msgId, Notify.LENGTH_LONG, style,
- new ActionListener() {
- @Override
- public void onAction() {
- Intent intent = new Intent(
- activity, LogDisplayActivity.class);
- intent.putExtra(LogDisplayFragment.EXTRA_RESULT, OperationResult.this);
- activity.startActivity(intent);
- }
- }, R.string.view_log);
+ return Notify.create(activity, msgId, Notify.LENGTH_LONG, style);
+ }
+
+ return Notify.create(activity, msgId, Notify.LENGTH_LONG, style,
+ new ActionListener() {
+ @Override
+ public void onAction() {
+ Intent intent = new Intent(
+ activity, LogDisplayActivity.class);
+ intent.putExtra(LogDisplayFragment.EXTRA_RESULT, OperationResult.this);
+ activity.startActivity(intent);
+ }
+ }, R.string.view_log);
}
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 98a9ff44f..bd2866985 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/OpenPgpService.java
@@ -240,6 +240,11 @@ public class OpenPgpService extends RemoteService {
try {
boolean asciiArmor = cleartextSign || data.getBooleanExtra(OpenPgpApi.EXTRA_REQUEST_ASCII_ARMOR, true);
+ Passphrase passphrase = null;
+ if (data.getCharArrayExtra(OpenPgpApi.EXTRA_PASSPHRASE) != null) {
+ passphrase = new Passphrase(data.getCharArrayExtra(OpenPgpApi.EXTRA_PASSPHRASE));
+ }
+
byte[] nfcSignedHash = data.getByteArrayExtra(OpenPgpApi.EXTRA_NFC_SIGNED_HASH);
if (nfcSignedHash != null) {
Log.d(Constants.TAG, "nfcSignedHash:" + Hex.toHexString(nfcSignedHash));
@@ -278,6 +283,7 @@ public class OpenPgpService extends RemoteService {
// sign-only
PgpSignEncryptInput pseInput = new PgpSignEncryptInput()
+ .setSignaturePassphrase(passphrase)
.setEnableAsciiArmorOutput(asciiArmor)
.setCleartextSignature(cleartextSign)
.setDetachedSignature(!cleartextSign)
@@ -366,6 +372,11 @@ public class OpenPgpService extends RemoteService {
compressionId = CompressionAlgorithmTags.UNCOMPRESSED;
}
+ Passphrase passphrase = null;
+ if (data.getCharArrayExtra(OpenPgpApi.EXTRA_PASSPHRASE) != null) {
+ passphrase = new Passphrase(data.getCharArrayExtra(OpenPgpApi.EXTRA_PASSPHRASE));
+ }
+
// first try to get key ids from non-ambiguous key id extra
long[] keyIds = data.getLongArrayExtra(OpenPgpApi.EXTRA_KEY_IDS);
if (keyIds == null) {
@@ -391,7 +402,8 @@ public class OpenPgpService extends RemoteService {
InputData inputData = new InputData(is, inputLength, originalFilename);
PgpSignEncryptInput pseInput = new PgpSignEncryptInput();
- pseInput.setEnableAsciiArmorOutput(asciiArmor)
+ pseInput.setSignaturePassphrase(passphrase)
+ .setEnableAsciiArmorOutput(asciiArmor)
.setVersionHeader(null)
.setCompressionId(compressionId)
.setSymmetricEncryptionAlgorithm(PgpConstants.OpenKeychainSymmetricKeyAlgorithmTags.USE_PREFERRED)
@@ -499,6 +511,11 @@ public class OpenPgpService extends RemoteService {
os = new ParcelFileDescriptor.AutoCloseOutputStream(output);
}
+ Passphrase passphrase = null;
+ if (data.getCharArrayExtra(OpenPgpApi.EXTRA_PASSPHRASE) != null) {
+ passphrase = new Passphrase(data.getCharArrayExtra(OpenPgpApi.EXTRA_PASSPHRASE));
+ }
+
String currentPkg = getCurrentCallingPackage();
Set<Long> allowedKeyIds;
if (data.getIntExtra(OpenPgpApi.EXTRA_API_VERSION, -1) < 7) {
@@ -509,7 +526,6 @@ public class OpenPgpService extends RemoteService {
KeychainContract.ApiAllowedKeys.buildBaseUri(currentPkg));
}
- Passphrase passphrase = data.getParcelableExtra(OpenPgpApi.EXTRA_PASSPHRASE);
long inputLength = is.available();
InputData inputData = new InputData(is, inputLength);
@@ -555,15 +571,16 @@ public class OpenPgpService extends RemoteService {
}
} else if (pgpResult.success()) {
Intent result = new Intent();
- int resultType = OpenPgpApi.RESULT_TYPE_UNENCRYPTED_UNSIGNED;
OpenPgpSignatureResult signatureResult = pgpResult.getSignatureResult();
+ // TODO: currently RESULT_TYPE_UNENCRYPTED_UNSIGNED is never returned
+ // instead an error is returned when no pgp data has been found
+ int resultType = OpenPgpApi.RESULT_TYPE_UNENCRYPTED_UNSIGNED;
if (signatureResult != null) {
resultType |= OpenPgpApi.RESULT_TYPE_SIGNED;
if (!signatureResult.isSignatureOnly()) {
resultType |= OpenPgpApi.RESULT_TYPE_ENCRYPTED;
}
- result.putExtra(OpenPgpApi.RESULT_TYPE, resultType);
result.putExtra(OpenPgpApi.RESULT_SIGNATURE, signatureResult);
@@ -583,7 +600,10 @@ public class OpenPgpService extends RemoteService {
// If signature key is known, return PendingIntent to show key
result.putExtra(OpenPgpApi.RESULT_INTENT, getShowKeyPendingIntent(signatureResult.getKeyId()));
}
+ } else {
+ resultType |= OpenPgpApi.RESULT_TYPE_ENCRYPTED;
}
+ result.putExtra(OpenPgpApi.RESULT_TYPE, resultType);
if (data.getIntExtra(OpenPgpApi.EXTRA_API_VERSION, -1) >= 4) {
OpenPgpMetadata metadata = pgpResult.getDecryptMetadata();
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/RemoteServiceActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/RemoteServiceActivity.java
index 2c5c78161..e8c3e4511 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/RemoteServiceActivity.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/RemoteServiceActivity.java
@@ -186,7 +186,7 @@ public class RemoteServiceActivity extends BaseActivity {
// user needs to select a key if it has explicitly requested (None is only allowed for new accounts)
if (mUpdateExistingAccount && mAccSettingsFragment.getAccSettings().getKeyId() == Constants.key.none) {
- Notify.showNotify(RemoteServiceActivity.this, getString(R.string.api_register_error_select_key), Notify.Style.ERROR);
+ Notify.create(RemoteServiceActivity.this, getString(R.string.api_register_error_select_key), Notify.Style.ERROR).show();
} else {
if (mUpdateExistingAccount) {
Uri baseUri = KeychainContract.ApiAccounts.buildBaseUri(packageName);
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/CloudImportService.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/CloudImportService.java
new file mode 100644
index 000000000..180109297
--- /dev/null
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/CloudImportService.java
@@ -0,0 +1,387 @@
+/*
+ * 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 (int i = 0; i < masterKeyIds.length; i++) {
+ mImportedMasterKeyIds.add(masterKeyIds[i]);
+ }
+
+ // 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
+ *
+ * @return
+ */
+ 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);
+ }
+}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java
index d5f13f7ce..5ecfb29f5 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java
@@ -60,7 +60,7 @@ 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.KeychainIntentServiceHandler.MessageStatus;
+import org.sufficientlysecure.keychain.service.ServiceProgressHandler.MessageStatus;
import org.sufficientlysecure.keychain.util.FileHelper;
import org.sufficientlysecure.keychain.util.InputData;
import org.sufficientlysecure.keychain.util.Log;
@@ -136,7 +136,7 @@ public class KeychainIntentService extends IntentService implements Progressable
private static final IOType[] values = values();
public static IOType fromInt(int n) {
- if(n < 0 || n >= values.length) {
+ if (n < 0 || n >= values.length) {
return UNKNOWN;
} else {
return values[n];
@@ -395,12 +395,12 @@ public class KeychainIntentService extends IntentService implements Progressable
}
Bundle resultData = new Bundle();
- resultData.putString(KeychainIntentServiceHandler.DATA_MESSAGE, "OK");
+ resultData.putString(ServiceProgressHandler.DATA_MESSAGE, "OK");
// these help the handler construct a useful human-readable message
- resultData.putString(KeychainIntentServiceHandler.KEYBASE_PROOF_URL, prover.getProofUrl());
- resultData.putString(KeychainIntentServiceHandler.KEYBASE_PRESENCE_URL, prover.getPresenceUrl());
- resultData.putString(KeychainIntentServiceHandler.KEYBASE_PRESENCE_LABEL, prover.getPresenceLabel());
+ 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);
@@ -596,7 +596,7 @@ public class KeychainIntentService extends IntentService implements Progressable
private void sendProofError(String msg) {
Bundle bundle = new Bundle();
- bundle.putString(KeychainIntentServiceHandler.DATA_ERROR, msg);
+ bundle.putString(ServiceProgressHandler.DATA_ERROR, msg);
sendMessageToHandler(MessageStatus.OKAY, bundle);
}
@@ -613,7 +613,7 @@ public class KeychainIntentService extends IntentService implements Progressable
Log.d(Constants.TAG, "KeychainIntentService Exception: ", e);
Bundle data = new Bundle();
- data.putString(KeychainIntentServiceHandler.DATA_ERROR, message);
+ data.putString(ServiceProgressHandler.DATA_ERROR, message);
sendMessageToHandler(MessageStatus.EXCEPTION, null, data);
}
@@ -661,10 +661,10 @@ public class KeychainIntentService extends IntentService implements Progressable
Bundle data = new Bundle();
if (message != null) {
- data.putString(KeychainIntentServiceHandler.DATA_MESSAGE, message);
+ data.putString(ServiceProgressHandler.DATA_MESSAGE, message);
}
- data.putInt(KeychainIntentServiceHandler.DATA_PROGRESS, progress);
- data.putInt(KeychainIntentServiceHandler.DATA_PROGRESS_MAX, max);
+ data.putInt(ServiceProgressHandler.DATA_PROGRESS, progress);
+ data.putInt(ServiceProgressHandler.DATA_PROGRESS_MAX, max);
sendMessageToHandler(MessageStatus.UPDATE_PROGRESS, null, data);
}
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 ee481ad31..93a2bee23 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/PassphraseCacheService.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/PassphraseCacheService.java
@@ -93,7 +93,6 @@ public class PassphraseCacheService extends Service {
public static final String EXTRA_MESSENGER = "messenger";
public static final String EXTRA_USER_ID = "user_id";
- private static final int REQUEST_ID = 0;
private static final long DEFAULT_TTL = 15;
private static final int NOTIFICATION_ID = 1;
@@ -314,7 +313,8 @@ public class PassphraseCacheService extends Service {
private static PendingIntent buildIntent(Context context, long keyId) {
Intent intent = new Intent(BROADCAST_ACTION_PASSPHRASE_CACHE_SERVICE);
intent.putExtra(EXTRA_KEY_ID, keyId);
- return PendingIntent.getBroadcast(context, REQUEST_ID, intent,
+ // request code should be unique for each PendingIntent, thus keyId is used
+ return PendingIntent.getBroadcast(context, (int) keyId, intent,
PendingIntent.FLAG_CANCEL_CURRENT);
}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentServiceHandler.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/ServiceProgressHandler.java
index bd047518d..4bd3481e6 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentServiceHandler.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/ServiceProgressHandler.java
@@ -30,7 +30,7 @@ import org.sufficientlysecure.keychain.ui.dialog.ProgressDialogFragment;
import org.sufficientlysecure.keychain.ui.util.Notify;
import org.sufficientlysecure.keychain.util.Log;
-public class KeychainIntentServiceHandler extends Handler {
+public class ServiceProgressHandler extends Handler {
// possible messages sent from this service to handler on ui
public static enum MessageStatus{
@@ -67,28 +67,34 @@ public class KeychainIntentServiceHandler extends Handler {
Activity mActivity;
ProgressDialogFragment mProgressDialogFragment;
- public KeychainIntentServiceHandler(Activity activity) {
+ public ServiceProgressHandler(Activity activity) {
this.mActivity = activity;
}
- public KeychainIntentServiceHandler(Activity activity,
- ProgressDialogFragment progressDialogFragment) {
+ public ServiceProgressHandler(Activity activity,
+ ProgressDialogFragment progressDialogFragment) {
this.mActivity = activity;
this.mProgressDialogFragment = progressDialogFragment;
}
- public KeychainIntentServiceHandler(Activity activity, String progressDialogMessage,
- int progressDialogStyle) {
- this(activity, progressDialogMessage, progressDialogStyle, false);
+ public ServiceProgressHandler(Activity activity,
+ String progressDialogMessage,
+ int progressDialogStyle,
+ ProgressDialogFragment.ServiceType serviceType) {
+ this(activity, progressDialogMessage, progressDialogStyle, false, serviceType);
}
- public KeychainIntentServiceHandler(Activity activity, String progressDialogMessage,
- int progressDialogStyle, boolean cancelable) {
+ public ServiceProgressHandler(Activity activity,
+ String progressDialogMessage,
+ int progressDialogStyle,
+ boolean cancelable,
+ ProgressDialogFragment.ServiceType serviceType) {
this.mActivity = activity;
this.mProgressDialogFragment = ProgressDialogFragment.newInstance(
progressDialogMessage,
progressDialogStyle,
- cancelable);
+ cancelable,
+ serviceType);
}
public void showProgressDialog(FragmentActivity activity) {
@@ -129,9 +135,9 @@ public class KeychainIntentServiceHandler extends Handler {
// show error from service
if (data.containsKey(DATA_ERROR)) {
- Notify.showNotify(mActivity,
+ Notify.create(mActivity,
mActivity.getString(R.string.error_message, data.getString(DATA_ERROR)),
- Notify.Style.ERROR);
+ Notify.Style.ERROR).show();
}
break;
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyFragment.java
index a0f89b06a..9b6e8d8f9 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyFragment.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyFragment.java
@@ -55,9 +55,10 @@ 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.KeychainIntentServiceHandler;
+import org.sufficientlysecure.keychain.service.ServiceProgressHandler;
import org.sufficientlysecure.keychain.service.PassphraseCacheService;
import org.sufficientlysecure.keychain.ui.adapter.MultiUserIdsAdapter;
+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.ui.widget.KeySpinner;
@@ -169,8 +170,8 @@ public class CertifyKeyFragment extends LoaderFragment
@Override
public void onClick(View v) {
if (mSignMasterKeyId == Constants.key.none) {
- Notify.showNotify(getActivity(), getString(R.string.select_key_to_certify),
- Notify.Style.ERROR);
+ Notify.create(getActivity(), getString(R.string.select_key_to_certify),
+ Notify.Style.ERROR).show();
} else {
initiateCertifying();
}
@@ -360,8 +361,8 @@ public class CertifyKeyFragment extends LoaderFragment
// Bail out if there is not at least one user id selected
ArrayList<CertifyAction> certifyActions = mUserIdsAdapter.getSelectedCertifyActions();
if (certifyActions.isEmpty()) {
- Notify.showNotify(getActivity(), "No identities selected!",
- Notify.Style.ERROR);
+ Notify.create(getActivity(), "No identities selected!",
+ Notify.Style.ERROR).show();
return;
}
@@ -388,8 +389,12 @@ public class CertifyKeyFragment extends LoaderFragment
} else {
// Message is received after signing is done in KeychainIntentService
- KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler(getActivity(),
- getString(R.string.progress_certifying), ProgressDialog.STYLE_SPINNER, true) {
+ ServiceProgressHandler saveHandler = new ServiceProgressHandler(
+ getActivity(),
+ getString(R.string.progress_certifying),
+ ProgressDialog.STYLE_SPINNER,
+ true,
+ ProgressDialogFragment.ServiceType.KEYCHAIN_INTENT) {
public void handleMessage(Message message) {
// handle messages by standard KeychainIntentServiceHandler first
super.handleMessage(message);
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ConsolidateDialogActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ConsolidateDialogActivity.java
index c55aad1f9..11ba3e287 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ConsolidateDialogActivity.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ConsolidateDialogActivity.java
@@ -26,7 +26,8 @@ import android.support.v4.app.FragmentActivity;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.service.KeychainIntentService;
-import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler;
+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,10 +50,11 @@ public class ConsolidateDialogActivity extends FragmentActivity {
private void consolidateRecovery(boolean recovery) {
// Message is received after importing is done in KeychainIntentService
- KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler(
+ ServiceProgressHandler saveHandler = new ServiceProgressHandler(
this,
getString(R.string.progress_importing),
- ProgressDialog.STYLE_HORIZONTAL) {
+ ProgressDialog.STYLE_HORIZONTAL,
+ ProgressDialogFragment.ServiceType.KEYCHAIN_INTENT) {
public void handleMessage(Message message) {
// handle messages by standard KeychainIntentServiceHandler first
super.handleMessage(message);
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyFinalFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyFinalFragment.java
index 75f49a426..b0a13c897 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyFinalFragment.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyFinalFragment.java
@@ -39,16 +39,15 @@ 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.KeychainIntentServiceHandler;
+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.Passphrase;
import org.sufficientlysecure.keychain.util.Preferences;
-import java.util.ArrayList;
import java.util.Iterator;
public class CreateKeyFinalFragment extends Fragment {
@@ -195,10 +194,11 @@ public class CreateKeyFinalFragment extends Fragment {
Intent intent = new Intent(getActivity(), KeychainIntentService.class);
intent.setAction(KeychainIntentService.ACTION_EDIT_KEYRING);
- KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler(
+ ServiceProgressHandler saveHandler = new ServiceProgressHandler(
getActivity(),
getString(R.string.progress_building_key),
- ProgressDialog.STYLE_HORIZONTAL) {
+ ProgressDialog.STYLE_HORIZONTAL,
+ ProgressDialogFragment.ServiceType.KEYCHAIN_INTENT) {
public void handleMessage(Message message) {
// handle messages by standard KeychainIntentServiceHandler first
super.handleMessage(message);
@@ -267,8 +267,11 @@ public class CreateKeyFinalFragment extends Fragment {
intent.putExtra(KeychainIntentService.EXTRA_DATA, data);
- KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler(getActivity(),
- getString(R.string.progress_uploading), ProgressDialog.STYLE_HORIZONTAL) {
+ ServiceProgressHandler saveHandler = new ServiceProgressHandler(
+ getActivity(),
+ getString(R.string.progress_uploading),
+ ProgressDialog.STYLE_HORIZONTAL,
+ ProgressDialogFragment.ServiceType.KEYCHAIN_INTENT) {
public void handleMessage(Message message) {
// handle messages by standard KeychainIntentServiceHandler first
super.handleMessage(message);
@@ -277,8 +280,8 @@ public class CreateKeyFinalFragment extends Fragment {
// TODO: upload operation needs a result!
// TODO: then combine these results
//if (result.getResult() == OperationResultParcel.RESULT_OK) {
- //Notify.showNotify(getActivity(), R.string.key_send_success,
- //Notify.Style.INFO);
+ //Notify.create(getActivity(), R.string.key_send_success,
+ //Notify.Style.OK).show();
Intent data = new Intent();
data.putExtra(OperationResult.EXTRA_RESULT, saveKeyResult);
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFilesFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFilesFragment.java
index 71832daa5..c75e28145 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFilesFragment.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFilesFragment.java
@@ -38,8 +38,9 @@ import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.operations.results.DecryptVerifyResult;
import org.sufficientlysecure.keychain.service.KeychainIntentService;
import org.sufficientlysecure.keychain.service.KeychainIntentService.IOType;
-import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler;
+import org.sufficientlysecure.keychain.service.ServiceProgressHandler;
import org.sufficientlysecure.keychain.ui.dialog.DeleteFileDialogFragment;
+import org.sufficientlysecure.keychain.ui.dialog.ProgressDialogFragment;
import org.sufficientlysecure.keychain.ui.util.Notify;
import org.sufficientlysecure.keychain.util.FileHelper;
import org.sufficientlysecure.keychain.util.Log;
@@ -139,7 +140,7 @@ public class DecryptFilesFragment extends DecryptFragment {
private void decryptAction() {
if (mInputUri == null) {
- Notify.showNotify(getActivity(), R.string.no_file_selected, Notify.Style.ERROR);
+ Notify.create(getActivity(), R.string.no_file_selected, Notify.Style.ERROR).show();
return;
}
@@ -197,8 +198,11 @@ public class DecryptFilesFragment extends DecryptFragment {
intent.putExtra(KeychainIntentService.EXTRA_DATA, data);
// Message is received after decrypting is done in KeychainIntentService
- KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler(getActivity(),
- getString(R.string.progress_decrypting), ProgressDialog.STYLE_HORIZONTAL) {
+ ServiceProgressHandler saveHandler = new ServiceProgressHandler(
+ getActivity(),
+ getString(R.string.progress_decrypting),
+ ProgressDialog.STYLE_HORIZONTAL,
+ ProgressDialogFragment.ServiceType.KEYCHAIN_INTENT) {
public void handleMessage(Message message) {
// handle messages by standard KeychainIntentServiceHandler first
super.handleMessage(message);
@@ -271,8 +275,11 @@ public class DecryptFilesFragment extends DecryptFragment {
intent.putExtra(KeychainIntentService.EXTRA_DATA, data);
// Message is received after decrypting is done in KeychainIntentService
- KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler(getActivity(),
- getString(R.string.progress_decrypting), ProgressDialog.STYLE_HORIZONTAL) {
+ ServiceProgressHandler saveHandler = new ServiceProgressHandler(
+ getActivity(),
+ getString(R.string.progress_decrypting),
+ ProgressDialog.STYLE_HORIZONTAL,
+ ProgressDialogFragment.ServiceType.KEYCHAIN_INTENT) {
public void handleMessage(Message message) {
// handle messages by standard KeychainIntentServiceHandler first
super.handleMessage(message);
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptTextActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptTextActivity.java
index 1e9e7bcb1..bc2ec014a 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptTextActivity.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptTextActivity.java
@@ -161,7 +161,7 @@ public class DecryptTextActivity extends BaseActivity {
if (sharedText != null) {
loadFragment(savedInstanceState, sharedText);
} else {
- Notify.showNotify(this, R.string.error_invalid_data, Notify.Style.ERROR);
+ Notify.create(this, R.string.error_invalid_data, Notify.Style.ERROR).show();
}
} else {
Log.e(Constants.TAG, "ACTION_SEND received non-plaintext, this should not happen in this activity!");
@@ -175,7 +175,7 @@ public class DecryptTextActivity extends BaseActivity {
if (extraText != null) {
loadFragment(savedInstanceState, extraText);
} else {
- Notify.showNotify(this, R.string.error_invalid_data, Notify.Style.ERROR);
+ Notify.create(this, R.string.error_invalid_data, Notify.Style.ERROR).show();
}
} else if (ACTION_DECRYPT_FROM_CLIPBOARD.equals(action)) {
Log.d(Constants.TAG, "ACTION_DECRYPT_FROM_CLIPBOARD");
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptTextFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptTextFragment.java
index 30cf739fc..f6e21937d 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptTextFragment.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptTextFragment.java
@@ -37,7 +37,8 @@ import org.sufficientlysecure.keychain.compatibility.ClipboardReflection;
import org.sufficientlysecure.keychain.operations.results.DecryptVerifyResult;
import org.sufficientlysecure.keychain.service.KeychainIntentService;
import org.sufficientlysecure.keychain.service.KeychainIntentService.IOType;
-import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler;
+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.ShareHelper;
@@ -132,7 +133,7 @@ public class DecryptTextFragment extends DecryptFragment {
private void copyToClipboard(String text) {
ClipboardReflection.copyToClipboard(getActivity(), text);
- Notify.showNotify(getActivity(), R.string.text_copied_to_clipboard, Notify.Style.INFO);
+ Notify.create(getActivity(), R.string.text_copied_to_clipboard, Notify.Style.OK).show();
}
@Override
@@ -167,8 +168,11 @@ public class DecryptTextFragment extends DecryptFragment {
intent.putExtra(KeychainIntentService.EXTRA_DATA, data);
// Message is received after encrypting is done in KeychainIntentService
- KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler(getActivity(),
- getString(R.string.progress_decrypting), ProgressDialog.STYLE_HORIZONTAL) {
+ ServiceProgressHandler saveHandler = new ServiceProgressHandler(
+ getActivity(),
+ getString(R.string.progress_decrypting),
+ ProgressDialog.STYLE_HORIZONTAL,
+ ProgressDialogFragment.ServiceType.KEYCHAIN_INTENT) {
public void handleMessage(Message message) {
// handle messages by standard KeychainIntentServiceHandler first
super.handleMessage(message);
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyFragment.java
index d2c1ab74c..417b50b50 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyFragment.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyFragment.java
@@ -50,7 +50,7 @@ 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.KeychainIntentServiceHandler;
+import org.sufficientlysecure.keychain.service.ServiceProgressHandler;
import org.sufficientlysecure.keychain.service.PassphraseCacheService;
import org.sufficientlysecure.keychain.service.SaveKeyringParcel;
import org.sufficientlysecure.keychain.service.SaveKeyringParcel.ChangeUnlockParcel;
@@ -59,12 +59,7 @@ import org.sufficientlysecure.keychain.ui.adapter.SubkeysAdapter;
import org.sufficientlysecure.keychain.ui.adapter.SubkeysAddedAdapter;
import org.sufficientlysecure.keychain.ui.adapter.UserIdsAdapter;
import org.sufficientlysecure.keychain.ui.adapter.UserIdsAddedAdapter;
-import org.sufficientlysecure.keychain.ui.dialog.AddSubkeyDialogFragment;
-import org.sufficientlysecure.keychain.ui.dialog.AddUserIdDialogFragment;
-import org.sufficientlysecure.keychain.ui.dialog.EditSubkeyDialogFragment;
-import org.sufficientlysecure.keychain.ui.dialog.EditSubkeyExpiryDialogFragment;
-import org.sufficientlysecure.keychain.ui.dialog.EditUserIdDialogFragment;
-import org.sufficientlysecure.keychain.ui.dialog.SetPassphraseDialogFragment;
+import org.sufficientlysecure.keychain.ui.dialog.*;
import org.sufficientlysecure.keychain.ui.util.Notify;
import org.sufficientlysecure.keychain.util.Log;
import org.sufficientlysecure.keychain.util.Passphrase;
@@ -577,11 +572,11 @@ public class EditKeyFragment extends LoaderFragment implements
private void returnKeyringParcel() {
if (mSaveKeyringParcel.mAddUserIds.size() == 0) {
- Notify.showNotify(getActivity(), R.string.edit_key_error_add_identity, Notify.Style.ERROR);
+ Notify.create(getActivity(), R.string.edit_key_error_add_identity, Notify.Style.ERROR).show();
return;
}
if (mSaveKeyringParcel.mAddSubKeys.size() == 0) {
- Notify.showNotify(getActivity(), R.string.edit_key_error_add_subkey, Notify.Style.ERROR);
+ Notify.create(getActivity(), R.string.edit_key_error_add_subkey, Notify.Style.ERROR).show();
return;
}
@@ -597,11 +592,12 @@ public class EditKeyFragment extends LoaderFragment implements
private void saveInDatabase(Passphrase passphrase) {
Log.d(Constants.TAG, "mSaveKeyringParcel:\n" + mSaveKeyringParcel.toString());
- KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler(
+ ServiceProgressHandler saveHandler = new ServiceProgressHandler(
getActivity(),
getString(R.string.progress_saving),
ProgressDialog.STYLE_HORIZONTAL,
- true) {
+ true,
+ ProgressDialogFragment.ServiceType.KEYCHAIN_INTENT) {
public void handleMessage(Message message) {
// handle messages by standard KeychainIntentServiceHandler first
super.handleMessage(message);
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivity.java
index 5438f667c..cd1028de4 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivity.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivity.java
@@ -31,7 +31,8 @@ import org.sufficientlysecure.keychain.operations.results.PgpSignEncryptResult;
import org.sufficientlysecure.keychain.operations.results.SignEncryptResult;
import org.sufficientlysecure.keychain.pgp.SignEncryptParcel;
import org.sufficientlysecure.keychain.service.KeychainIntentService;
-import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler;
+import org.sufficientlysecure.keychain.service.ServiceProgressHandler;
+import org.sufficientlysecure.keychain.ui.dialog.ProgressDialogFragment;
import org.sufficientlysecure.keychain.util.Passphrase;
import java.util.Date;
@@ -123,8 +124,11 @@ public abstract class EncryptActivity extends BaseActivity {
intent.putExtra(KeychainIntentService.EXTRA_DATA, data);
// Message is received after encrypting is done in KeychainIntentService
- KeychainIntentServiceHandler serviceHandler = new KeychainIntentServiceHandler(this,
- getString(R.string.progress_encrypting), ProgressDialog.STYLE_HORIZONTAL) {
+ ServiceProgressHandler serviceHandler = new ServiceProgressHandler(
+ this,
+ getString(R.string.progress_encrypting),
+ ProgressDialog.STYLE_HORIZONTAL,
+ ProgressDialogFragment.ServiceType.KEYCHAIN_INTENT) {
public void handleMessage(Message message) {
// handle messages by standard KeychainIntentServiceHandler first
super.handleMessage(message);
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptFilesActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptFilesActivity.java
index 0dd672c90..fe9b05226 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptFilesActivity.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptFilesActivity.java
@@ -303,7 +303,8 @@ public class EncryptFilesActivity extends EncryptActivity implements EncryptActi
// file checks
if (mInputUris.isEmpty()) {
- Notify.showNotify(this, R.string.no_file_selected, Notify.Style.ERROR);
+ Notify.create(this, R.string.no_file_selected, Notify.Style.ERROR)
+ .show(getSupportFragmentManager().findFragmentById(R.id.encrypt_file_fragment));
return false;
} else if (mInputUris.size() > 1 && !mShareAfterEncrypt) {
// This should be impossible...
@@ -317,11 +318,13 @@ public class EncryptFilesActivity extends EncryptActivity implements EncryptActi
// symmetric encryption checks
if (mPassphrase == null) {
- Notify.showNotify(this, R.string.passphrases_do_not_match, Notify.Style.ERROR);
+ Notify.create(this, R.string.passphrases_do_not_match, Notify.Style.ERROR)
+ .show(getSupportFragmentManager().findFragmentById(R.id.encrypt_file_fragment));
return false;
}
if (mPassphrase.isEmpty()) {
- Notify.showNotify(this, R.string.passphrase_must_not_be_empty, Notify.Style.ERROR);
+ Notify.create(this, R.string.passphrase_must_not_be_empty, Notify.Style.ERROR)
+ .show(getSupportFragmentManager().findFragmentById(R.id.encrypt_file_fragment));
return false;
}
@@ -333,7 +336,8 @@ public class EncryptFilesActivity extends EncryptActivity implements EncryptActi
// Files must be encrypted, only text can be signed-only right now
if (!gotEncryptionKeys) {
- Notify.showNotify(this, R.string.select_encryption_key, Notify.Style.ERROR);
+ Notify.create(this, R.string.select_encryption_key, Notify.Style.ERROR)
+ .show(getSupportFragmentManager().findFragmentById(R.id.encrypt_file_fragment));
return false;
}
}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptFilesFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptFilesFragment.java
index 9c9b44511..4ba76d8ea 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptFilesFragment.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptFilesFragment.java
@@ -115,9 +115,9 @@ public class EncryptFilesFragment extends Fragment implements EncryptActivityInt
}
if (mEncryptInterface.getInputUris().contains(inputUri)) {
- Notify.showNotify(getActivity(),
+ Notify.create(getActivity(),
getActivity().getString(R.string.error_file_added_already, FileHelper.getFilename(getActivity(), inputUri)),
- Notify.Style.ERROR);
+ Notify.Style.ERROR).show(this);
return;
}
@@ -153,7 +153,7 @@ public class EncryptFilesFragment extends Fragment implements EncryptActivityInt
private void encryptClicked(boolean share) {
if (mEncryptInterface.getInputUris().isEmpty()) {
- Notify.showNotify(getActivity(), R.string.error_no_file_selected, Notify.Style.ERROR);
+ Notify.create(getActivity(), R.string.error_no_file_selected, Notify.Style.ERROR).show(this);
return;
}
if (share) {
@@ -169,7 +169,7 @@ public class EncryptFilesFragment extends Fragment implements EncryptActivityInt
mEncryptInterface.startEncrypt(true);
} else {
if (mEncryptInterface.getInputUris().size() > 1) {
- Notify.showNotify(getActivity(), R.string.error_multi_not_supported, Notify.Style.ERROR);
+ Notify.create(getActivity(), R.string.error_multi_not_supported, Notify.Style.ERROR).show(this);
return;
}
showOutputFileDialog();
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptTextActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptTextActivity.java
index 847f745d7..dd09e62c3 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptTextActivity.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptTextActivity.java
@@ -136,7 +136,9 @@ public class EncryptTextActivity extends EncryptActivity implements EncryptActiv
@Override
public void setPassphrase(Passphrase passphrase) {
- mPassphrase.removeFromMemory();
+ if (mPassphrase != null) {
+ mPassphrase.removeFromMemory();
+ }
mPassphrase = passphrase;
}
@@ -198,8 +200,9 @@ public class EncryptTextActivity extends EncryptActivity implements EncryptActiv
// Copy to clipboard
copyToClipboard(result.getResultBytes());
result.createNotify(EncryptTextActivity.this).show();
- // Notify.showNotify(EncryptTextActivity.this,
- // R.string.encrypt_sign_clipboard_successful, Notify.Style.INFO);
+ // Notify.create(EncryptTextActivity.this,
+ // R.string.encrypt_sign_clipboard_successful, Notify.Style.OK)
+ // .show(getSupportFragmentManager().findFragmentById(R.id.encrypt_text_fragment));
}
}
@@ -281,7 +284,8 @@ public class EncryptTextActivity extends EncryptActivity implements EncryptActiv
protected boolean inputIsValid() {
if (mMessage == null) {
- Notify.showNotify(this, R.string.error_message, Notify.Style.ERROR);
+ Notify.create(this, R.string.error_message, Notify.Style.ERROR)
+ .show(getSupportFragmentManager().findFragmentById(R.id.encrypt_text_fragment));
return false;
}
@@ -289,11 +293,13 @@ public class EncryptTextActivity extends EncryptActivity implements EncryptActiv
// symmetric encryption checks
if (mPassphrase == null) {
- Notify.showNotify(this, R.string.passphrases_do_not_match, Notify.Style.ERROR);
+ Notify.create(this, R.string.passphrases_do_not_match, Notify.Style.ERROR)
+ .show(getSupportFragmentManager().findFragmentById(R.id.encrypt_text_fragment));
return false;
}
if (mPassphrase.isEmpty()) {
- Notify.showNotify(this, R.string.passphrase_must_not_be_empty, Notify.Style.ERROR);
+ Notify.create(this, R.string.passphrase_must_not_be_empty, Notify.Style.ERROR)
+ .show(getSupportFragmentManager().findFragmentById(R.id.encrypt_text_fragment));
return false;
}
@@ -304,7 +310,8 @@ public class EncryptTextActivity extends EncryptActivity implements EncryptActiv
&& mEncryptionKeyIds.length > 0);
if (!gotEncryptionKeys && mSigningKeyId == 0) {
- Notify.showNotify(this, R.string.select_encryption_or_signature_key, Notify.Style.ERROR);
+ Notify.create(this, R.string.select_encryption_or_signature_key, Notify.Style.ERROR)
+ .show(getSupportFragmentManager().findFragmentById(R.id.encrypt_text_fragment));
return false;
}
}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/HelpAboutFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/HelpAboutFragment.java
index 5909970af..912caf32f 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/HelpAboutFragment.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/HelpAboutFragment.java
@@ -27,11 +27,14 @@ import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
+import org.markdown4j.Markdown4jProcessor;
import org.sufficientlysecure.htmltextview.HtmlTextView;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.util.Log;
+import java.io.IOException;
+
public class HelpAboutFragment extends Fragment {
@@ -44,8 +47,14 @@ public class HelpAboutFragment extends Fragment {
HtmlTextView aboutTextView = (HtmlTextView) view.findViewById(R.id.help_about_text);
- // load html from raw resource (Parsing handled by HtmlTextView library)
- aboutTextView.setHtmlFromRawResource(getActivity(), R.raw.help_about, true);
+ // load mardown from raw resource
+ try {
+ String html = new Markdown4jProcessor().process(
+ getActivity().getResources().openRawResource(R.raw.help_about));
+ aboutTextView.setHtmlFromString(html, true);
+ } catch (IOException e) {
+ Log.e(Constants.TAG, "IOException", e);
+ }
// no flickering when clicking textview for Android < 4
aboutTextView.setTextColor(getResources().getColor(android.R.color.black));
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/HelpActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/HelpActivity.java
index cd6cdf4d6..24136a4b8 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/HelpActivity.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/HelpActivity.java
@@ -64,18 +64,23 @@ public class HelpActivity extends BaseActivity {
}
Bundle startBundle = new Bundle();
- startBundle.putInt(HelpHtmlFragment.ARG_HTML_FILE, R.raw.help_start);
- mTabsAdapter.addTab(HelpHtmlFragment.class, startBundle,
+ startBundle.putInt(HelpMarkdownFragment.ARG_MARKDOWN_FILE, R.raw.help_start);
+ mTabsAdapter.addTab(HelpMarkdownFragment.class, startBundle,
getString(R.string.help_tab_start));
- Bundle wotBundle = new Bundle();
- wotBundle.putInt(HelpHtmlFragment.ARG_HTML_FILE, R.raw.help_certification);
- mTabsAdapter.addTab(HelpHtmlFragment.class, wotBundle,
+ Bundle certificationBundle = new Bundle();
+ certificationBundle.putInt(HelpMarkdownFragment.ARG_MARKDOWN_FILE, R.raw.help_certification);
+ mTabsAdapter.addTab(HelpMarkdownFragment.class, certificationBundle,
getString(R.string.help_tab_wot));
+ Bundle faqBundle = new Bundle();
+ faqBundle.putInt(HelpMarkdownFragment.ARG_MARKDOWN_FILE, R.raw.help_faq);
+ mTabsAdapter.addTab(HelpMarkdownFragment.class, faqBundle,
+ getString(R.string.help_tab_faq));
+
Bundle changelogBundle = new Bundle();
- changelogBundle.putInt(HelpHtmlFragment.ARG_HTML_FILE, R.raw.help_changelog);
- mTabsAdapter.addTab(HelpHtmlFragment.class, changelogBundle,
+ changelogBundle.putInt(HelpMarkdownFragment.ARG_MARKDOWN_FILE, R.raw.help_changelog);
+ mTabsAdapter.addTab(HelpMarkdownFragment.class, changelogBundle,
getString(R.string.help_tab_changelog));
mTabsAdapter.addTab(HelpAboutFragment.class, null,
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/HelpHtmlFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/HelpMarkdownFragment.java
index a3f0ef614..69ddf2e99 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/HelpHtmlFragment.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/HelpMarkdownFragment.java
@@ -26,24 +26,29 @@ import android.view.View;
import android.view.ViewGroup;
import android.widget.ScrollView;
+import org.markdown4j.Markdown4jProcessor;
import org.sufficientlysecure.htmltextview.HtmlTextView;
+import org.sufficientlysecure.keychain.Constants;
+import org.sufficientlysecure.keychain.util.Log;
-public class HelpHtmlFragment extends Fragment {
+import java.io.IOException;
+
+public class HelpMarkdownFragment extends Fragment {
private Activity mActivity;
private int mHtmlFile;
- public static final String ARG_HTML_FILE = "htmlFile";
+ public static final String ARG_MARKDOWN_FILE = "htmlFile";
/**
* Create a new instance of HelpHtmlFragment, providing "htmlFile" as an argument.
*/
- static HelpHtmlFragment newInstance(int htmlFile) {
- HelpHtmlFragment f = new HelpHtmlFragment();
+ static HelpMarkdownFragment newInstance(int htmlFile) {
+ HelpMarkdownFragment f = new HelpMarkdownFragment();
// Supply html raw file input as an argument.
Bundle args = new Bundle();
- args.putInt(ARG_HTML_FILE, htmlFile);
+ args.putInt(ARG_MARKDOWN_FILE, htmlFile);
f.setArguments(args);
return f;
@@ -53,7 +58,7 @@ public class HelpHtmlFragment extends Fragment {
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
mActivity = getActivity();
- mHtmlFile = getArguments().getInt(ARG_HTML_FILE);
+ mHtmlFile = getArguments().getInt(ARG_MARKDOWN_FILE);
ScrollView scroller = new ScrollView(mActivity);
HtmlTextView text = new HtmlTextView(mActivity);
@@ -65,8 +70,13 @@ public class HelpHtmlFragment extends Fragment {
scroller.addView(text);
- // load html from raw resource (Parsing handled by HtmlTextView library)
- text.setHtmlFromRawResource(getActivity(), mHtmlFile, true);
+ // load mardown from raw resource
+ try {
+ String html = new Markdown4jProcessor().process(getActivity().getResources().openRawResource(mHtmlFile));
+ text.setHtmlFromString(html, true);
+ } catch (IOException e) {
+ Log.e(Constants.TAG, "IOException", e);
+ }
// no flickering when clicking textview for Android < 4
text.setTextColor(getResources().getColor(android.R.color.black));
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java
index d51e2c7fc..dc4a2eb10 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java
@@ -26,6 +26,7 @@ import android.os.Messenger;
import android.support.v4.app.Fragment;
import android.view.View;
import android.view.View.OnClickListener;
+import android.view.ViewGroup;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R;
@@ -34,8 +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.KeychainIntentServiceHandler;
+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;
@@ -277,7 +279,8 @@ public class ImportKeysActivity extends BaseActivity {
private boolean isFingerprintValid(String fingerprint) {
if (fingerprint == null || fingerprint.length() < 40) {
- Notify.showNotify(this, R.string.import_qr_code_too_short_fingerprint, Notify.Style.ERROR);
+ Notify.create(this, R.string.import_qr_code_too_short_fingerprint, Notify.Style.ERROR)
+ .show((ViewGroup) findViewById(R.id.import_snackbar));
return false;
} else {
return true;
@@ -292,12 +295,13 @@ public class ImportKeysActivity extends BaseActivity {
* Import keys with mImportData
*/
public void importKeys() {
- // Message is received after importing is done in KeychainIntentService
- KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler(
+ // Message is received after importing is done in CloudImportService
+ ServiceProgressHandler saveHandler = new ServiceProgressHandler(
this,
getString(R.string.progress_importing),
ProgressDialog.STYLE_HORIZONTAL,
- true) {
+ true,
+ ProgressDialogFragment.ServiceType.CLOUD_IMPORT) {
public void handleMessage(Message message) {
// handle messages by standard KeychainIntentServiceHandler first
super.handleMessage(message);
@@ -329,7 +333,8 @@ public class ImportKeysActivity extends BaseActivity {
return;
}
- result.createNotify(ImportKeysActivity.this).show();
+ result.createNotify(ImportKeysActivity.this)
+ .show((ViewGroup) findViewById(R.id.import_snackbar));
}
}
};
@@ -339,9 +344,7 @@ public class ImportKeysActivity extends BaseActivity {
Log.d(Constants.TAG, "importKeys started");
// 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);
+ Intent intent = new Intent(this, CloudImportService.class);
// fill values for this action
Bundle data = new Bundle();
@@ -359,11 +362,11 @@ public class ImportKeysActivity extends BaseActivity {
new ParcelableFileCache<>(this, "key_import.pcl");
cache.writeCache(selectedEntries);
- intent.putExtra(KeychainIntentService.EXTRA_DATA, data);
+ intent.putExtra(CloudImportService.EXTRA_DATA, data);
// Create a new Messenger for the communication back
Messenger messenger = new Messenger(saveHandler);
- intent.putExtra(KeychainIntentService.EXTRA_MESSENGER, messenger);
+ intent.putExtra(CloudImportService.EXTRA_MESSENGER, messenger);
// show progress dialog
saveHandler.showProgressDialog(this);
@@ -372,20 +375,19 @@ public class ImportKeysActivity extends BaseActivity {
startService(intent);
} catch (IOException e) {
Log.e(Constants.TAG, "Problem writing cache file", e);
- Notify.showNotify(this, "Problem writing cache file!", Notify.Style.ERROR);
+ Notify.create(this, "Problem writing cache file!", Notify.Style.ERROR)
+ .show((ViewGroup) findViewById(R.id.import_snackbar));
}
} else if (ls instanceof ImportKeysListFragment.CloudLoaderState) {
ImportKeysListFragment.CloudLoaderState sls = (ImportKeysListFragment.CloudLoaderState) ls;
// 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 intent = new Intent(this, CloudImportService.class);
// fill values for this action
Bundle data = new Bundle();
- data.putString(KeychainIntentService.IMPORT_KEY_SERVER, sls.mCloudPrefs.keyserver);
+ data.putString(CloudImportService.IMPORT_KEY_SERVER, sls.mCloudPrefs.keyserver);
// get selected key entries
ArrayList<ParcelableKeyRing> keys = new ArrayList<>();
@@ -398,13 +400,13 @@ public class ImportKeysActivity extends BaseActivity {
);
}
}
- data.putParcelableArrayList(KeychainIntentService.IMPORT_KEY_LIST, keys);
+ data.putParcelableArrayList(CloudImportService.IMPORT_KEY_LIST, keys);
- intent.putExtra(KeychainIntentService.EXTRA_DATA, data);
+ intent.putExtra(CloudImportService.EXTRA_DATA, data);
// Create a new Messenger for the communication back
Messenger messenger = new Messenger(saveHandler);
- intent.putExtra(KeychainIntentService.EXTRA_MESSENGER, messenger);
+ intent.putExtra(CloudImportService.EXTRA_MESSENGER, messenger);
// show progress dialog
saveHandler.showProgressDialog(this);
@@ -412,7 +414,8 @@ public class ImportKeysActivity extends BaseActivity {
// start service with intent
startService(intent);
} else {
- Notify.showNotify(this, R.string.error_nothing_import, Notify.Style.ERROR);
+ Notify.create(this, R.string.error_nothing_import, Notify.Style.ERROR)
+ .show((ViewGroup) findViewById(R.id.import_snackbar));
}
}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysProxyActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysProxyActivity.java
index 1c1e5fe99..21747f77b 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysProxyActivity.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysProxyActivity.java
@@ -42,7 +42,8 @@ import org.sufficientlysecure.keychain.operations.results.ImportKeyResult;
import org.sufficientlysecure.keychain.operations.results.OperationResult;
import org.sufficientlysecure.keychain.operations.results.SingletonResult;
import org.sufficientlysecure.keychain.service.KeychainIntentService;
-import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler;
+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;
@@ -213,11 +214,12 @@ public class ImportKeysProxyActivity extends FragmentActivity {
private void startImportService (ArrayList<ParcelableKeyRing> keyRings) {
// Message is received after importing is done in KeychainIntentService
- KeychainIntentServiceHandler serviceHandler = new KeychainIntentServiceHandler(
+ ServiceProgressHandler serviceHandler = new ServiceProgressHandler(
this,
getString(R.string.progress_importing),
ProgressDialog.STYLE_HORIZONTAL,
- true) {
+ true,
+ ProgressDialogFragment.ServiceType.KEYCHAIN_INTENT) {
public void handleMessage(Message message) {
// handle messages by standard KeychainIntentServiceHandler first
super.handleMessage(message);
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java
index f8939f3d1..861ae12d9 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java
@@ -58,16 +58,21 @@ import com.getbase.floatingactionbutton.FloatingActionsMenu;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R;
+import org.sufficientlysecure.keychain.keyimport.ParcelableKeyRing;
import org.sufficientlysecure.keychain.operations.results.ConsolidateResult;
import org.sufficientlysecure.keychain.operations.results.DeleteResult;
+import org.sufficientlysecure.keychain.operations.results.ImportKeyResult;
import org.sufficientlysecure.keychain.operations.results.OperationResult;
import org.sufficientlysecure.keychain.pgp.KeyRing;
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.KeychainIntentServiceHandler;
+import org.sufficientlysecure.keychain.service.ServiceProgressHandler;
import org.sufficientlysecure.keychain.ui.dialog.DeleteKeyDialogFragment;
+import org.sufficientlysecure.keychain.ui.dialog.ProgressDialogFragment;
import org.sufficientlysecure.keychain.ui.util.Highlighter;
import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils.State;
@@ -78,6 +83,7 @@ import org.sufficientlysecure.keychain.util.Log;
import org.sufficientlysecure.keychain.util.Preferences;
import java.io.IOException;
+import java.util.ArrayList;
import java.util.HashMap;
import se.emilsjolander.stickylistheaders.StickyListHeadersAdapter;
@@ -169,6 +175,22 @@ public class KeyListFragment extends LoaderFragment
mStickyList.setDrawingListUnderStickyHeader(false);
mStickyList.setFastScrollEnabled(true);
+ // Adds an empty footer view so that the Floating Action Button won't block content
+ // in last few rows.
+ View footer = new View(getActivity());
+
+ int spacing = (int) android.util.TypedValue.applyDimension(
+ android.util.TypedValue.COMPLEX_UNIT_DIP, 72, getResources().getDisplayMetrics()
+ );
+
+ android.widget.AbsListView.LayoutParams params = new android.widget.AbsListView.LayoutParams(
+ android.widget.AbsListView.LayoutParams.MATCH_PARENT,
+ spacing
+ );
+
+ footer.setLayoutParams(params);
+ mStickyList.addFooterView(footer, null, false);
+
/*
* Multi-selection
*/
@@ -369,13 +391,13 @@ public class KeyListFragment extends LoaderFragment
/**
* Show dialog to delete key
*
- * @param hasSecret must contain whether the list of masterKeyIds contains a secret key or not
+ * @param hasSecret must contain whether the list of masterKeyIds contains a secret key or not
*/
public void showDeleteKeyDialog(final ActionMode mode, long[] masterKeyIds, boolean hasSecret) {
// Can only work on singular secret keys
if (hasSecret && masterKeyIds.length > 1) {
- Notify.showNotify(getActivity(), R.string.secret_cannot_multiple,
- Notify.Style.ERROR);
+ Notify.create(getActivity(), R.string.secret_cannot_multiple,
+ Notify.Style.ERROR).show();
return;
}
@@ -461,6 +483,10 @@ public class KeyListFragment extends LoaderFragment
mExportHelper.showExportKeysDialog(null, Constants.Path.APP_DIR_FILE, true);
return true;
+ case R.id.menu_key_list_update_all_keys:
+ updateAllKeys();
+ return true;
+
case R.id.menu_key_list_debug_cons:
consolidate();
return true;
@@ -468,21 +494,21 @@ public class KeyListFragment extends LoaderFragment
case R.id.menu_key_list_debug_read:
try {
KeychainDatabase.debugBackup(getActivity(), true);
- Notify.showNotify(getActivity(), "Restored debug_backup.db", Notify.Style.INFO);
+ Notify.create(getActivity(), "Restored debug_backup.db", Notify.Style.OK).show();
getActivity().getContentResolver().notifyChange(KeychainContract.KeyRings.CONTENT_URI, null);
} catch (IOException e) {
Log.e(Constants.TAG, "IO Error", e);
- Notify.showNotify(getActivity(), "IO Error " + e.getMessage(), Notify.Style.ERROR);
+ Notify.create(getActivity(), "IO Error " + e.getMessage(), Notify.Style.ERROR).show();
}
return true;
case R.id.menu_key_list_debug_write:
try {
KeychainDatabase.debugBackup(getActivity(), false);
- Notify.showNotify(getActivity(), "Backup to debug_backup.db completed", Notify.Style.INFO);
+ Notify.create(getActivity(), "Backup to debug_backup.db completed", Notify.Style.OK).show();
} catch (IOException e) {
Log.e(Constants.TAG, "IO Error", e);
- Notify.showNotify(getActivity(), "IO Error: " + e.getMessage(), Notify.Style.ERROR);
+ Notify.create(getActivity(), "IO Error: " + e.getMessage(), Notify.Style.ERROR).show();
}
return true;
@@ -545,12 +571,90 @@ public class KeyListFragment extends LoaderFragment
startActivityForResult(intent, 0);
}
+ private void updateAllKeys() {
+ Context context = getActivity();
+
+ ProviderHelper providerHelper = new ProviderHelper(context);
+
+ Cursor cursor = providerHelper.getContentResolver().query(
+ KeyRings.buildUnifiedKeyRingsUri(), new String[]{
+ KeyRings.FINGERPRINT
+ }, null, null, null
+ );
+
+ ArrayList<ParcelableKeyRing> keyList = new ArrayList<>();
+
+ while (cursor.moveToNext()) {
+ byte[] blob = cursor.getBlob(0);//fingerprint column is 0
+ String fingerprint = KeyFormattingUtils.convertFingerprintToHex(blob);
+ ParcelableKeyRing keyEntry = new ParcelableKeyRing(fingerprint, null, null);
+ keyList.add(keyEntry);
+ }
+
+ ServiceProgressHandler serviceHandler = new ServiceProgressHandler(
+ getActivity(),
+ getString(R.string.progress_updating),
+ ProgressDialog.STYLE_HORIZONTAL,
+ true,
+ ProgressDialogFragment.ServiceType.CLOUD_IMPORT) {
+ public void handleMessage(Message message) {
+ // handle messages by standard KeychainIntentServiceHandler first
+ super.handleMessage(message);
+
+ if (message.arg1 == MessageStatus.OKAY.ordinal()) {
+ // get returned data bundle
+ Bundle returnData = message.getData();
+ if (returnData == null) {
+ return;
+ }
+ final ImportKeyResult result =
+ returnData.getParcelable(OperationResult.EXTRA_RESULT);
+ if (result == null) {
+ Log.e(Constants.TAG, "result == null");
+ return;
+ }
+
+ result.createNotify(getActivity()).show();
+ }
+ }
+ };
+
+ // Send all information needed to service to query keys in other thread
+ Intent intent = new Intent(getActivity(), CloudImportService.class);
+
+ // fill values for this action
+ Bundle data = new Bundle();
+
+ // search config
+ {
+ Preferences prefs = Preferences.getPreferences(getActivity());
+ Preferences.CloudSearchPrefs cloudPrefs =
+ new Preferences.CloudSearchPrefs(true, true, prefs.getPreferredKeyserver());
+ data.putString(CloudImportService.IMPORT_KEY_SERVER, cloudPrefs.keyserver);
+ }
+
+ data.putParcelableArrayList(CloudImportService.IMPORT_KEY_LIST, keyList);
+
+ intent.putExtra(CloudImportService.EXTRA_DATA, data);
+
+ // Create a new Messenger for the communication back
+ Messenger messenger = new Messenger(serviceHandler);
+ intent.putExtra(CloudImportService.EXTRA_MESSENGER, messenger);
+
+ // show progress dialog
+ serviceHandler.showProgressDialog(getActivity());
+
+ // start service with intent
+ getActivity().startService(intent);
+ }
+
private void consolidate() {
// Message is received after importing is done in KeychainIntentService
- KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler(
+ ServiceProgressHandler saveHandler = new ServiceProgressHandler(
getActivity(),
getString(R.string.progress_importing),
- ProgressDialog.STYLE_HORIZONTAL) {
+ ProgressDialog.STYLE_HORIZONTAL,
+ ProgressDialogFragment.ServiceType.KEYCHAIN_INTENT) {
public void handleMessage(Message message) {
// handle messages by standard KeychainIntentServiceHandler first
super.handleMessage(message);
@@ -909,5 +1013,4 @@ public class KeyListFragment extends LoaderFragment
}
-
}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/QrCodeViewActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/QrCodeViewActivity.java
index d3c1d971a..43af07bbe 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/QrCodeViewActivity.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/QrCodeViewActivity.java
@@ -80,7 +80,7 @@ public class QrCodeViewActivity extends BaseActivity {
KeychainContract.KeyRings.FINGERPRINT, ProviderHelper.FIELD_TYPE_BLOB);
if (blob == null) {
Log.e(Constants.TAG, "key not found!");
- Notify.showNotify(this, R.string.error_key_not_found, Style.ERROR);
+ Notify.create(this, R.string.error_key_not_found, Style.ERROR).show();
ActivityCompat.finishAfterTransition(QrCodeViewActivity.this);
}
@@ -102,7 +102,7 @@ public class QrCodeViewActivity extends BaseActivity {
});
} catch (ProviderHelper.NotFoundException e) {
Log.e(Constants.TAG, "key not found!", e);
- Notify.showNotify(this, R.string.error_key_not_found, Style.ERROR);
+ Notify.create(this, R.string.error_key_not_found, Style.ERROR).show();
ActivityCompat.finishAfterTransition(QrCodeViewActivity.this);
}
}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/SafeSlingerActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/SafeSlingerActivity.java
index d0cea5f05..c58a945d3 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/SafeSlingerActivity.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/SafeSlingerActivity.java
@@ -39,7 +39,8 @@ 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.KeychainIntentServiceHandler;
+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;
@@ -123,11 +124,12 @@ public class SafeSlingerActivity extends BaseActivity {
final FragmentActivity activity = SafeSlingerActivity.this;
// Message is received after importing is done in KeychainIntentService
- KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler(
+ ServiceProgressHandler saveHandler = new ServiceProgressHandler(
activity,
getString(R.string.progress_importing),
ProgressDialog.STYLE_HORIZONTAL,
- true) {
+ true,
+ ProgressDialogFragment.ServiceType.KEYCHAIN_INTENT) {
public void handleMessage(Message message) {
// handle messages by standard KeychainIntentServiceHandler first
super.handleMessage(message);
@@ -205,7 +207,7 @@ public class SafeSlingerActivity extends BaseActivity {
activity.startService(intent);
} catch (IOException e) {
Log.e(Constants.TAG, "Problem writing cache file", e);
- Notify.showNotify(activity, "Problem writing cache file!", Notify.Style.ERROR);
+ Notify.create(activity, "Problem writing cache file!", Notify.Style.ERROR).show();
}
} else {
// give everything else down to KeyListActivity!
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/UploadKeyActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/UploadKeyActivity.java
index 4fb2074a5..c518cbcdb 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/UploadKeyActivity.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/UploadKeyActivity.java
@@ -36,7 +36,8 @@ 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.KeychainIntentServiceHandler;
+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;
@@ -107,8 +108,11 @@ public class UploadKeyActivity extends BaseActivity {
intent.putExtra(KeychainIntentService.EXTRA_DATA, data);
// Message is received after uploading is done in KeychainIntentService
- KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler(this,
- getString(R.string.progress_uploading), ProgressDialog.STYLE_HORIZONTAL) {
+ ServiceProgressHandler saveHandler = new ServiceProgressHandler(
+ this,
+ getString(R.string.progress_uploading),
+ ProgressDialog.STYLE_HORIZONTAL,
+ ProgressDialogFragment.ServiceType.KEYCHAIN_INTENT) {
public void handleMessage(Message message) {
// handle messages by standard KeychainIntentServiceHandler first
super.handleMessage(message);
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java
index 5834fa502..0c2d8693f 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java
@@ -21,18 +21,12 @@ package org.sufficientlysecure.keychain.ui;
import android.animation.ArgbEvaluator;
import android.animation.ObjectAnimator;
import android.annotation.SuppressLint;
-import android.annotation.TargetApi;
import android.app.Activity;
import android.app.ActivityOptions;
import android.content.Intent;
-import android.content.pm.PackageManager;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.net.Uri;
-import android.nfc.NdefMessage;
-import android.nfc.NdefRecord;
-import android.nfc.NfcAdapter;
-import android.nfc.NfcEvent;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
@@ -40,7 +34,6 @@ import android.os.Handler;
import android.os.Message;
import android.os.Messenger;
import android.provider.ContactsContract;
-import android.provider.Settings;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.LoaderManager;
import android.support.v4.content.CursorLoader;
@@ -58,9 +51,7 @@ import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;
-
import com.getbase.floatingactionbutton.FloatingActionButton;
-
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.keyimport.ParcelableKeyRing;
@@ -72,8 +63,8 @@ import org.sufficientlysecure.keychain.pgp.exception.PgpKeyNotFoundException;
import org.sufficientlysecure.keychain.provider.KeychainContract;
import org.sufficientlysecure.keychain.provider.ProviderHelper;
import org.sufficientlysecure.keychain.service.KeychainIntentService;
-import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler;
-import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler.MessageStatus;
+import org.sufficientlysecure.keychain.service.ServiceProgressHandler;
+import org.sufficientlysecure.keychain.service.ServiceProgressHandler.MessageStatus;
import org.sufficientlysecure.keychain.service.PassphraseCacheService;
import org.sufficientlysecure.keychain.ui.dialog.DeleteKeyDialogFragment;
import org.sufficientlysecure.keychain.ui.util.FormattingUtils;
@@ -84,6 +75,7 @@ import org.sufficientlysecure.keychain.ui.util.QrCodeUtils;
import org.sufficientlysecure.keychain.util.ContactHelper;
import org.sufficientlysecure.keychain.util.ExportHelper;
import org.sufficientlysecure.keychain.util.Log;
+import org.sufficientlysecure.keychain.util.NfcHelper;
import org.sufficientlysecure.keychain.util.Preferences;
import java.util.ArrayList;
@@ -93,8 +85,8 @@ public class ViewKeyActivity extends BaseActivity implements
LoaderManager.LoaderCallbacks<Cursor> {
static final int REQUEST_QR_FINGERPRINT = 1;
- static final int REQUEST_DELETE= 2;
- static final int REQUEST_EXPORT= 3;
+ static final int REQUEST_DELETE = 2;
+ static final int REQUEST_EXPORT = 3;
ExportHelper mExportHelper;
ProviderHelper mProviderHelper;
@@ -115,11 +107,7 @@ public class ViewKeyActivity extends BaseActivity implements
private CardView mQrCodeLayout;
// NFC
- private NfcAdapter mNfcAdapter;
- private NfcAdapter.CreateNdefMessageCallback mNdefCallback;
- private NfcAdapter.OnNdefPushCompleteCallback mNdefCompleteCallback;
- private byte[] mNfcKeyringBytes;
- private static final int NFC_SENT = 1;
+ private NfcHelper mNfcHelper;
private static final int LOADER_ID_UNIFIED = 0;
@@ -256,7 +244,7 @@ public class ViewKeyActivity extends BaseActivity implements
mActionNfc.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
- invokeNfcBeam();
+ mNfcHelper.invokeNfcBeam();
}
});
@@ -264,7 +252,8 @@ public class ViewKeyActivity extends BaseActivity implements
// or start new ones.
getSupportLoaderManager().initLoader(LOADER_ID_UNIFIED, null, this);
- initNfc(mDataUri);
+ mNfcHelper = new NfcHelper(this, mProviderHelper);
+ mNfcHelper.initNfc(mDataUri);
startFragment(savedInstanceState, mDataUri);
}
@@ -349,7 +338,7 @@ public class ViewKeyActivity extends BaseActivity implements
try {
updateFromKeyserver(mDataUri, mProviderHelper);
} catch (ProviderHelper.NotFoundException e) {
- Notify.showNotify(this, R.string.error_key_not_found, Notify.Style.ERROR);
+ Notify.create(this, R.string.error_key_not_found, Notify.Style.ERROR).show();
}
return true;
}
@@ -375,41 +364,6 @@ public class ViewKeyActivity extends BaseActivity implements
return true;
}
- @TargetApi(Build.VERSION_CODES.LOLLIPOP)
- private void invokeNfcBeam() {
- // Check if device supports NFC
- if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_NFC)) {
- Notify.createNotify(this, R.string.no_nfc_support, Notify.LENGTH_LONG, Notify.Style.ERROR).show();
- return;
- }
- // Check for available NFC Adapter
- mNfcAdapter = NfcAdapter.getDefaultAdapter(this);
- if (mNfcAdapter == null || !mNfcAdapter.isEnabled()) {
- Notify.createNotify(this, R.string.error_nfc_needed, Notify.LENGTH_LONG, Notify.Style.ERROR, new Notify.ActionListener() {
- @Override
- public void onAction() {
- Intent intentSettings = new Intent(Settings.ACTION_NFC_SETTINGS);
- startActivity(intentSettings);
- }
- }, R.string.menu_nfc_preferences).show();
-
- return;
- }
-
- if (!mNfcAdapter.isNdefPushEnabled()) {
- Notify.createNotify(this, R.string.error_beam_needed, Notify.LENGTH_LONG, Notify.Style.ERROR, new Notify.ActionListener() {
- @Override
- public void onAction() {
- Intent intentSettings = new Intent(Settings.ACTION_NFCSHARING_SETTINGS);
- startActivity(intentSettings);
- }
- }, R.string.menu_beam_preferences).show();
-
- return;
- }
-
- mNfcAdapter.invokeBeam(this);
- }
private void scanQrCode() {
Intent scanQrCode = new Intent(this, ImportKeysProxyActivity.class);
@@ -426,14 +380,14 @@ public class ViewKeyActivity extends BaseActivity implements
private void certifyImmediate() {
Intent intent = new Intent(this, CertifyKeyActivity.class);
- intent.putExtra(CertifyKeyActivity.EXTRA_KEY_IDS, new long[]{mMasterKeyId});
+ intent.putExtra(CertifyKeyActivity.EXTRA_KEY_IDS, new long[] {mMasterKeyId});
startCertifyIntent(intent);
}
private void startCertifyIntent(Intent intent) {
// Message is received after signing is done in KeychainIntentService
- KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler(this) {
+ ServiceProgressHandler saveHandler = new ServiceProgressHandler(this) {
public void handleMessage(Message message) {
// handle messages by standard KeychainIntentServiceHandler first
super.handleMessage(message);
@@ -487,15 +441,15 @@ public class ViewKeyActivity extends BaseActivity implements
HashMap<String, Object> data = providerHelper.getGenericData(
baseUri,
- new String[]{KeychainContract.Keys.MASTER_KEY_ID, KeychainContract.KeyRings.HAS_SECRET},
- new int[]{ProviderHelper.FIELD_TYPE_INTEGER, ProviderHelper.FIELD_TYPE_INTEGER});
+ new String[] {KeychainContract.Keys.MASTER_KEY_ID, KeychainContract.KeyRings.HAS_SECRET},
+ new int[] {ProviderHelper.FIELD_TYPE_INTEGER, ProviderHelper.FIELD_TYPE_INTEGER});
exportHelper.showExportKeysDialog(
- new long[]{(Long) data.get(KeychainContract.KeyRings.MASTER_KEY_ID)},
+ new long[] {(Long) data.get(KeychainContract.KeyRings.MASTER_KEY_ID)},
Constants.Path.APP_DIR_FILE, ((Long) data.get(KeychainContract.KeyRings.HAS_SECRET) != 0)
);
} catch (ProviderHelper.NotFoundException e) {
- Notify.showNotify(this, R.string.error_key_not_found, Notify.Style.ERROR);
+ Notify.create(this, R.string.error_key_not_found, Notify.Style.ERROR).show();
Log.e(Constants.TAG, "Key not found", e);
}
}
@@ -515,7 +469,7 @@ public class ViewKeyActivity extends BaseActivity implements
// Create a new Messenger for the communication back
Messenger messenger = new Messenger(returnHandler);
DeleteKeyDialogFragment deleteKeyDialog = DeleteKeyDialogFragment.newInstance(messenger,
- new long[]{ mMasterKeyId });
+ new long[] {mMasterKeyId});
deleteKeyDialog.show(getSupportFragmentManager(), "deleteKeyDialog");
}
@@ -532,25 +486,25 @@ public class ViewKeyActivity extends BaseActivity implements
String fp = data.getStringExtra(ImportKeysProxyActivity.EXTRA_FINGERPRINT);
if (fp == null) {
- Notify.createNotify(this, "Error scanning fingerprint!",
+ Notify.create(this, "Error scanning fingerprint!",
Notify.LENGTH_LONG, Notify.Style.ERROR).show();
return;
}
if (mFingerprint.equalsIgnoreCase(fp)) {
certifyImmediate();
} else {
- Notify.createNotify(this, "Fingerprints did not match!",
+ Notify.create(this, "Fingerprints did not match!",
Notify.LENGTH_LONG, Notify.Style.ERROR).show();
}
return;
}
- if (requestCode == REQUEST_DELETE && resultCode == Activity.RESULT_OK){
+ if (requestCode == REQUEST_DELETE && resultCode == Activity.RESULT_OK) {
deleteKey();
}
- if (requestCode == REQUEST_EXPORT && resultCode == Activity.RESULT_OK){
+ if (requestCode == REQUEST_EXPORT && resultCode == Activity.RESULT_OK) {
exportToFile(mDataUri, mExportHelper, mProviderHelper);
}
@@ -565,14 +519,14 @@ public class ViewKeyActivity extends BaseActivity implements
private void encrypt(Uri dataUri, boolean text) {
// If there is no encryption key, don't bother.
if (!mHasEncrypt) {
- Notify.showNotify(this, R.string.error_no_encrypt_subkey, Notify.Style.ERROR);
+ Notify.create(this, R.string.error_no_encrypt_subkey, Notify.Style.ERROR).show();
return;
}
try {
long keyId = new ProviderHelper(this)
.getCachedPublicKeyRing(dataUri)
.extractOrGetMasterKeyId();
- long[] encryptionKeyIds = new long[]{keyId};
+ long[] encryptionKeyIds = new long[] {keyId};
Intent intent;
if (text) {
intent = new Intent(this, EncryptTextActivity.class);
@@ -608,7 +562,7 @@ public class ViewKeyActivity extends BaseActivity implements
entries.add(keyEntry);
// Message is received after importing is done in KeychainIntentService
- KeychainIntentServiceHandler serviceHandler = new KeychainIntentServiceHandler(this) {
+ ServiceProgressHandler serviceHandler = new ServiceProgressHandler(this) {
public void handleMessage(Message message) {
// handle messages by standard KeychainIntentServiceHandler first
super.handleMessage(message);
@@ -710,98 +664,9 @@ public class ViewKeyActivity extends BaseActivity implements
loadTask.execute();
}
- /**
- * NFC: Initialize NFC sharing if OS and device supports it
- */
- @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
- private void initNfc(final Uri dataUri) {
- // check if NFC Beam is supported (>= Android 4.1)
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
-
- // Implementation for the CreateNdefMessageCallback interface
- mNdefCallback = new NfcAdapter.CreateNdefMessageCallback() {
- @Override
- public NdefMessage createNdefMessage(NfcEvent event) {
- /*
- * When a device receives a push with an AAR in it, the application specified in the AAR is
- * guaranteed to run. The AAR overrides the tag dispatch system. You can add it back in to
- * guarantee that this activity starts when receiving a beamed message. For now, this code
- * uses the tag dispatch system.
- */
- return new NdefMessage(NdefRecord.createMime(Constants.NFC_MIME,
- mNfcKeyringBytes), NdefRecord.createApplicationRecord(Constants.PACKAGE_NAME));
- }
- };
-
- // Implementation for the OnNdefPushCompleteCallback interface
- mNdefCompleteCallback = new NfcAdapter.OnNdefPushCompleteCallback() {
- @Override
- public void onNdefPushComplete(NfcEvent event) {
- // A handler is needed to send messages to the activity when this
- // callback occurs, because it happens from a binder thread
- mNfcHandler.obtainMessage(NFC_SENT).sendToTarget();
- }
- };
-
- // Check for available NFC Adapter
- mNfcAdapter = NfcAdapter.getDefaultAdapter(this);
- if (mNfcAdapter != null) {
- /*
- * Retrieve mNfcKeyringBytes here asynchronously (to not block the UI)
- * and init nfc adapter afterwards.
- * mNfcKeyringBytes can not be retrieved in createNdefMessage, because this process
- * has no permissions to query the Uri.
- */
- AsyncTask<Void, Void, Void> initTask =
- new AsyncTask<Void, Void, Void>() {
- protected Void doInBackground(Void... unused) {
- try {
- Uri blobUri =
- KeychainContract.KeyRingData.buildPublicKeyRingUri(dataUri);
- mNfcKeyringBytes = (byte[]) mProviderHelper.getGenericData(
- blobUri,
- KeychainContract.KeyRingData.KEY_RING_DATA,
- ProviderHelper.FIELD_TYPE_BLOB);
- } catch (ProviderHelper.NotFoundException e) {
- Log.e(Constants.TAG, "key not found!", e);
- }
-
- // no AsyncTask return (Void)
- return null;
- }
-
- protected void onPostExecute(Void unused) {
- // Register callback to set NDEF message
- mNfcAdapter.setNdefPushMessageCallback(mNdefCallback,
- ViewKeyActivity.this);
- // Register callback to listen for message-sent success
- mNfcAdapter.setOnNdefPushCompleteCallback(mNdefCompleteCallback,
- ViewKeyActivity.this);
- }
- };
-
- initTask.execute();
- }
- }
- }
-
- /**
- * NFC: This handler receives a message from onNdefPushComplete
- */
- private final Handler mNfcHandler = new Handler() {
- @Override
- public void handleMessage(Message msg) {
- switch (msg.what) {
- case NFC_SENT:
- Notify.showNotify(
- ViewKeyActivity.this, R.string.nfc_successful, Notify.Style.INFO);
- break;
- }
- }
- };
// These are the rows that we will retrieve.
- static final String[] PROJECTION = new String[]{
+ static final String[] PROJECTION = new String[] {
KeychainContract.KeyRings._ID,
KeychainContract.KeyRings.MASTER_KEY_ID,
KeychainContract.KeyRings.USER_ID,
@@ -1018,4 +883,4 @@ public class ViewKeyActivity extends BaseActivity implements
public void onLoaderReset(Loader<Cursor> loader) {
}
-}
+} \ No newline at end of file
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvShareFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvShareFragment.java
index 95a6faea9..6bd3a9303 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvShareFragment.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvShareFragment.java
@@ -52,6 +52,7 @@ import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
import org.sufficientlysecure.keychain.ui.util.Notify;
import org.sufficientlysecure.keychain.ui.util.QrCodeUtils;
import org.sufficientlysecure.keychain.util.Log;
+import org.sufficientlysecure.keychain.util.NfcHelper;
import java.io.IOException;
@@ -68,10 +69,12 @@ public class ViewKeyAdvShareFragment extends LoaderFragment implements
private View mFingerprintClipboardButton;
private View mKeyShareButton;
private View mKeyClipboardButton;
+ private View mKeyNfcButton;
private ImageButton mKeySafeSlingerButton;
private View mKeyUploadButton;
ProviderHelper mProviderHelper;
+ NfcHelper mNfcHelper;
private static final int LOADER_ID_UNIFIED = 0;
@@ -83,6 +86,7 @@ public class ViewKeyAdvShareFragment extends LoaderFragment implements
View view = inflater.inflate(R.layout.view_key_adv_share_fragment, getContainer());
mProviderHelper = new ProviderHelper(ViewKeyAdvShareFragment.this.getActivity());
+ mNfcHelper = new NfcHelper(getActivity(), mProviderHelper);
mFingerprint = (TextView) view.findViewById(R.id.view_key_fingerprint);
mQrCode = (ImageView) view.findViewById(R.id.view_key_qr_code);
@@ -90,6 +94,7 @@ public class ViewKeyAdvShareFragment extends LoaderFragment implements
mFingerprintShareButton = view.findViewById(R.id.view_key_action_fingerprint_share);
mFingerprintClipboardButton = view.findViewById(R.id.view_key_action_fingerprint_clipboard);
mKeyShareButton = view.findViewById(R.id.view_key_action_key_share);
+ mKeyNfcButton = view.findViewById(R.id.view_key_action_key_nfc);
mKeyClipboardButton = view.findViewById(R.id.view_key_action_key_clipboard);
mKeySafeSlingerButton = (ImageButton) view.findViewById(R.id.view_key_action_key_safeslinger);
mKeyUploadButton = view.findViewById(R.id.view_key_action_upload);
@@ -128,6 +133,14 @@ public class ViewKeyAdvShareFragment extends LoaderFragment implements
share(mDataUri, mProviderHelper, false, true);
}
});
+
+ mKeyNfcButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ mNfcHelper.invokeNfcBeam();
+ }
+ });
+
mKeySafeSlingerButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
@@ -186,13 +199,13 @@ public class ViewKeyAdvShareFragment extends LoaderFragment implements
} else {
message = getResources().getString(R.string.key_copied_to_clipboard);
}
- Notify.showNotify(getActivity(), message, Notify.Style.OK);
+ Notify.create(getActivity(), message, Notify.Style.OK).show();
} else {
// Android will fail with android.os.TransactionTooLargeException if key is too big
// see http://www.lonestarprod.com/?p=34
if (content.length() >= 86389) {
- Notify.showNotify(getActivity(), R.string.key_too_big_for_sharing,
- Notify.Style.ERROR);
+ Notify.create(getActivity(), R.string.key_too_big_for_sharing,
+ Notify.Style.ERROR).show();
return;
}
@@ -210,10 +223,10 @@ public class ViewKeyAdvShareFragment extends LoaderFragment implements
}
} catch (PgpGeneralException | IOException e) {
Log.e(Constants.TAG, "error processing key!", e);
- Notify.showNotify(getActivity(), R.string.error_key_processing, Notify.Style.ERROR);
+ Notify.create(getActivity(), R.string.error_key_processing, Notify.Style.ERROR).show();
} catch (ProviderHelper.NotFoundException e) {
Log.e(Constants.TAG, "key not found!", e);
- Notify.showNotify(getActivity(), R.string.error_key_not_found, Notify.Style.ERROR);
+ Notify.create(getActivity(), R.string.error_key_not_found, Notify.Style.ERROR).show();
}
}
@@ -255,9 +268,12 @@ public class ViewKeyAdvShareFragment extends LoaderFragment implements
// Prepare the loaders. Either re-connect with an existing ones,
// or start new ones.
getLoaderManager().initLoader(LOADER_ID_UNIFIED, null, this);
+
+ // Prepare the NfcHelper
+ mNfcHelper.initNfc(mDataUri);
}
- static final String[] UNIFIED_PROJECTION = new String[]{
+ static final String[] UNIFIED_PROJECTION = new String[] {
KeyRings._ID, KeyRings.MASTER_KEY_ID, KeyRings.HAS_ANY_SECRET,
KeyRings.USER_ID, KeyRings.FINGERPRINT,
KeyRings.ALGORITHM, KeyRings.KEY_SIZE, KeyRings.CREATION, KeyRings.IS_EXPIRED,
@@ -362,4 +378,5 @@ public class ViewKeyAdvShareFragment extends LoaderFragment implements
startActivityForResult(uploadIntent, 0);
}
-}
+
+} \ No newline at end of file
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyTrustFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyTrustFragment.java
index e20796f8f..d5870d8c5 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyTrustFragment.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyTrustFragment.java
@@ -50,12 +50,12 @@ 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.KeychainIntentServiceHandler;
+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;
import java.util.ArrayList;
-import java.util.Date;
import java.util.Hashtable;
import java.util.List;
@@ -362,23 +362,26 @@ public class ViewKeyTrustFragment extends LoaderFragment implements
// Create a new Messenger for the communication back after proof work is done
//
- KeychainIntentServiceHandler handler = new KeychainIntentServiceHandler(getActivity(),
- getString(R.string.progress_verifying_signature), ProgressDialog.STYLE_HORIZONTAL) {
+ ServiceProgressHandler handler = new ServiceProgressHandler(
+ getActivity(),
+ getString(R.string.progress_verifying_signature),
+ ProgressDialog.STYLE_HORIZONTAL,
+ ProgressDialogFragment.ServiceType.KEYCHAIN_INTENT) {
public void handleMessage(Message message) {
// handle messages by standard KeychainIntentServiceHandler first
super.handleMessage(message);
if (message.arg1 == MessageStatus.OKAY.ordinal()) {
Bundle returnData = message.getData();
- String msg = returnData.getString(KeychainIntentServiceHandler.DATA_MESSAGE);
+ String msg = returnData.getString(ServiceProgressHandler.DATA_MESSAGE);
SpannableStringBuilder ssb = new SpannableStringBuilder();
if ((msg != null) && msg.equals("OK")) {
//yay
- String proofUrl = returnData.getString(KeychainIntentServiceHandler.KEYBASE_PROOF_URL);
- String presenceUrl = returnData.getString(KeychainIntentServiceHandler.KEYBASE_PRESENCE_URL);
- String presenceLabel = returnData.getString(KeychainIntentServiceHandler.KEYBASE_PRESENCE_LABEL);
+ String proofUrl = returnData.getString(ServiceProgressHandler.KEYBASE_PROOF_URL);
+ String presenceUrl = returnData.getString(ServiceProgressHandler.KEYBASE_PRESENCE_URL);
+ String presenceLabel = returnData.getString(ServiceProgressHandler.KEYBASE_PRESENCE_LABEL);
String proofLabel;
switch (proof.getType()) {
@@ -429,7 +432,7 @@ public class ViewKeyTrustFragment extends LoaderFragment implements
ssb.append(" ").append(getString(R.string.keybase_contained_signature));
} else {
// verification failed!
- msg = returnData.getString(KeychainIntentServiceHandler.DATA_ERROR);
+ msg = returnData.getString(ServiceProgressHandler.DATA_ERROR);
ssb.append(getString(R.string.keybase_proof_failure));
if (msg == null) {
msg = getString(R.string.keybase_unknown_proof_failure);
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteKeyDialogFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteKeyDialogFragment.java
index f512ecca2..581a96e52 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteKeyDialogFragment.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteKeyDialogFragment.java
@@ -37,7 +37,7 @@ 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.KeychainIntentServiceHandler;
+import org.sufficientlysecure.keychain.service.ServiceProgressHandler;
import org.sufficientlysecure.keychain.util.Log;
import java.util.HashMap;
@@ -135,9 +135,12 @@ public class DeleteKeyDialogFragment extends DialogFragment {
intent.setAction(KeychainIntentService.ACTION_DELETE);
// Message is received after importing is done in KeychainIntentService
- KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler(
- getActivity(), getString(R.string.progress_deleting),
- ProgressDialog.STYLE_HORIZONTAL, true) {
+ ServiceProgressHandler saveHandler = new ServiceProgressHandler(
+ getActivity(),
+ getString(R.string.progress_deleting),
+ ProgressDialog.STYLE_HORIZONTAL,
+ true,
+ ProgressDialogFragment.ServiceType.KEYCHAIN_INTENT) {
@Override
public void handleMessage(Message message) {
super.handleMessage(message);
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/FileDialogFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/FileDialogFragment.java
index 7ac85781f..63b6d26ac 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/FileDialogFragment.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/FileDialogFragment.java
@@ -190,7 +190,7 @@ public class FileDialogFragment extends DialogFragment {
mFile = file;
mFilename.setText(mFile.getName());
} else {
- Notify.showNotify(getActivity(), R.string.no_file_selected, Notify.Style.ERROR);
+ Notify.create(getActivity(), R.string.no_file_selected, Notify.Style.ERROR).show();
}
}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/ProgressDialogFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/ProgressDialogFragment.java
index df7943f55..b58f584c8 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/ProgressDialogFragment.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/ProgressDialogFragment.java
@@ -32,23 +32,43 @@ 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;
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 static enum ServiceType {
+ KEYCHAIN_INTENT,
+ CLOUD_IMPORT
+ }
+
+ ServiceType mServiceType;
boolean mCanCancel = false, mPreventCancel = false, mIsCancelled = false;
- /** Creates new instance of this fragment */
- public static ProgressDialogFragment newInstance(String message, int style, boolean cancelable) {
+ /**
+ * creates a new instance of this fragment
+ * @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) {
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);
@@ -106,6 +126,7 @@ 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);
@@ -175,9 +196,22 @@ public class ProgressDialogFragment extends DialogFragment {
// send a cancel message. note that this message will be handled by
// KeychainIntentService.onStartCommand, which runs in this thread,
// not the service one, and will not queue up a command.
- Intent intent = new Intent(getActivity(), KeychainIntentService.class);
- intent.setAction(KeychainIntentService.ACTION_CANCEL);
- getActivity().startService(intent);
+ Intent serviceIntent = null;
+
+ 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);
+ getActivity().startService(serviceIntent);
}
});
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/util/Notify.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/util/Notify.java
index 9736b5765..7e07ed818 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/util/Notify.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/util/Notify.java
@@ -18,10 +18,7 @@
package org.sufficientlysecure.keychain.ui.util;
import android.app.Activity;
-import android.content.res.Resources;
import android.support.v4.app.Fragment;
-import android.support.v4.app.FragmentActivity;
-import android.support.v4.app.FragmentManager;
import android.view.View;
import android.view.ViewGroup;
@@ -40,135 +37,58 @@ import org.sufficientlysecure.keychain.util.FabContainer;
*/
public class Notify {
- public static enum Style {OK, WARN, INFO, ERROR}
+ public static enum Style {
+ OK, WARN, ERROR;
+
+ public void applyToBar(Snackbar bar) {
+
+ switch (this) {
+ case OK:
+ // bar.actionColorResource(R.color.android_green_light);
+ bar.lineColorResource(R.color.android_green_light);
+ break;
+ case WARN:
+ // bar.textColorResource(R.color.android_orange_light);
+ bar.lineColorResource(R.color.android_orange_light);
+ break;
+ case ERROR:
+ // bar.textColorResource(R.color.android_red_light);
+ bar.lineColorResource(R.color.android_red_light);
+ break;
+ }
+
+ }
+ }
public static final int LENGTH_INDEFINITE = 0;
public static final int LENGTH_LONG = 3500;
- /**
- * Shows a simple in-layout notification with the CharSequence given as parameter
- * @param text Text to show
- * @param style Notification styling
- */
- public static void showNotify(final Activity activity, CharSequence text, Style style) {
-
- Snackbar bar = getSnackbar(activity)
+ public static Showable create(final Activity activity, String text, int duration, Style style,
+ final ActionListener actionListener, int actionResId) {
+ final Snackbar snackbar = Snackbar.with(activity)
+ .type(SnackbarType.MULTI_LINE)
.text(text);
- switch (style) {
- case OK:
- break;
- case WARN:
- bar.textColor(activity.getResources().getColor(R.color.android_orange_light));
- break;
- case ERROR:
- bar.textColor(activity.getResources().getColor(R.color.android_red_light));
- break;
- }
-
- showSnackbar(activity, bar);
-
- }
-
- public static Showable createNotify (final Activity activity, int resId, int duration, Style style) {
- final Snackbar bar = getSnackbar(activity)
- .text(resId);
-
if (duration == LENGTH_INDEFINITE) {
- bar.duration(SnackbarDuration.LENGTH_INDEFINITE);
+ snackbar.duration(SnackbarDuration.LENGTH_INDEFINITE);
} else {
- bar.duration(duration);
+ snackbar.duration(duration);
}
- switch (style) {
- case OK:
- bar.actionColor(activity.getResources().getColor(R.color.android_green_light));
- break;
- case WARN:
- bar.textColor(activity.getResources().getColor(R.color.android_orange_light));
- break;
- case ERROR:
- bar.textColor(activity.getResources().getColor(R.color.android_red_light));
- break;
- }
+ style.applyToBar(snackbar);
- return new Showable () {
- @Override
- public void show() {
- showSnackbar(activity, bar);
- }
- };
- }
-
- public static Showable createNotify(Activity activity, int resId, int duration, Style style,
- final ActionListener listener, int resIdAction) {
- return createNotify(activity, activity.getString(resId), duration, style, listener, resIdAction);
- }
-
- public static Showable createNotify(Activity activity, String msg, int duration, Style style) {
- return createNotify(activity, msg, duration, style, null, 0);
- }
-
- public static Showable createNotify(final Activity activity, String msg, int duration, Style style,
- final ActionListener listener, int resIdAction) {
-
- final Snackbar bar = getSnackbar(activity)
- .text(msg);
-
- if (listener != null) {
- bar.actionLabel(resIdAction);
- bar.actionListener(new ActionClickListener() {
- @Override
- public void onActionClicked(Snackbar snackbar) {
- listener.onAction();
- }
- });
- }
-
- if (duration == LENGTH_INDEFINITE) {
- bar.duration(SnackbarDuration.LENGTH_INDEFINITE);
- } else {
- bar.duration(duration);
- }
-
- switch (style) {
- case OK:
- bar.actionColor(activity.getResources().getColor(R.color.android_green_light));
- break;
- case WARN:
- bar.textColor(activity.getResources().getColor(R.color.android_orange_light));
- break;
- case ERROR:
- bar.textColor(activity.getResources().getColor(R.color.android_red_light));
- break;
+ if (actionListener != null) {
+ snackbar.actionLabel(actionResId)
+ .actionListener(new ActionClickListener() {
+ @Override
+ public void onActionClicked(Snackbar snackbar) {
+ actionListener.onAction();
+ }
+ });
}
- return new Showable () {
- @Override
- public void show() {
- showSnackbar(activity, bar);
- }
- };
-
- }
-
- /**
- * Shows a simple in-layout notification with the resource text from given id
- * @param resId ResourceId of notification text
- * @param style Notification styling
- * @throws Resources.NotFoundException
- */
- public static void showNotify(Activity activity, int resId, Style style) throws Resources.NotFoundException {
- showNotify(activity, activity.getResources().getText(resId), style);
- }
-
- private static Snackbar getSnackbar(final Activity activity) {
- Snackbar bar = Snackbar.with(activity)
- .type(SnackbarType.MULTI_LINE)
- .duration(SnackbarDuration.LENGTH_LONG);
-
if (activity instanceof FabContainer) {
- bar.eventListener(new EventListenerAdapter() {
+ snackbar.eventListener(new EventListenerAdapter() {
@Override
public void onShow(Snackbar snackbar) {
((FabContainer) activity).fabMoveUp(snackbar.getHeight());
@@ -180,37 +100,84 @@ public class Notify {
}
});
}
- return bar;
- }
- private static void showSnackbar(Activity activity, Snackbar snackbar) {
- if (activity instanceof FragmentActivity) {
- FragmentManager fragmentManager = ((FragmentActivity) activity).getSupportFragmentManager();
+ return new Showable() {
+ @Override
+ public void show() {
+ SnackbarManager.show(snackbar, activity);
+ }
- int count = fragmentManager.getBackStackEntryCount();
- Fragment fragment = fragmentManager.getFragments().get(count > 0 ? count - 1 : 0);
+ @Override
+ public void show(Fragment fragment) {
+ if (fragment != null) {
+ View view = fragment.getView();
+
+ if (view != null && view instanceof ViewGroup) {
+ SnackbarManager.show(snackbar, (ViewGroup) view);
+ return;
+ }
+ }
- if (fragment != null) {
- View view = fragment.getView();
+ show();
+ }
- if (view != null) {
- SnackbarManager.show(snackbar, (ViewGroup) view);
+ @Override
+ public void show(ViewGroup viewGroup) {
+ if (viewGroup != null) {
+ SnackbarManager.show(snackbar, viewGroup);
return;
}
+
+ show();
}
- }
+ };
+ }
+
+ public static Showable create(Activity activity, String text, int duration, Style style) {
+ return create(activity, text, duration, style, null, -1);
+ }
+
+ public static Showable create(Activity activity, String text, Style style) {
+ return create(activity, text, LENGTH_LONG, style);
+ }
- SnackbarManager.show(snackbar);
+ public static Showable create(Activity activity, int textResId, int duration, Style style,
+ ActionListener actionListener, int actionResId) {
+ return create(activity, activity.getString(textResId), duration, style, actionListener, actionResId);
+ }
+
+ public static Showable create(Activity activity, int textResId, int duration, Style style) {
+ return create(activity, activity.getString(textResId), duration, style);
+ }
+
+ public static Showable create(Activity activity, int textResId, Style style) {
+ return create(activity, activity.getString(textResId), style);
}
public interface Showable {
+
+ /**
+ * Shows the notification on the bottom of the Activity.
+ */
public void show();
+ /**
+ * Shows the notification on the bottom of the Fragment.
+ */
+ public 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);
+
}
public interface ActionListener {
+
public void onAction();
}
-} \ No newline at end of file
+}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/ExportHelper.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/ExportHelper.java
index 7b164f2b2..7efb7c5af 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/ExportHelper.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/ExportHelper.java
@@ -19,9 +19,7 @@ package org.sufficientlysecure.keychain.util;
import android.app.ProgressDialog;
import android.content.Intent;
-import android.net.Uri;
import android.os.Bundle;
-import android.os.Handler;
import android.os.Message;
import android.os.Messenger;
import android.support.v4.app.FragmentActivity;
@@ -29,11 +27,9 @@ 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.pgp.exception.PgpKeyNotFoundException;
-import org.sufficientlysecure.keychain.provider.ProviderHelper;
import org.sufficientlysecure.keychain.service.KeychainIntentService;
-import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler;
-import org.sufficientlysecure.keychain.ui.dialog.DeleteKeyDialogFragment;
+import org.sufficientlysecure.keychain.service.ServiceProgressHandler;
+import org.sufficientlysecure.keychain.ui.dialog.ProgressDialogFragment;
import java.io.File;
@@ -102,9 +98,10 @@ public class ExportHelper {
intent.putExtra(KeychainIntentService.EXTRA_DATA, data);
// Message is received after exporting is done in KeychainIntentService
- KeychainIntentServiceHandler exportHandler = new KeychainIntentServiceHandler(mActivity,
+ ServiceProgressHandler exportHandler = new ServiceProgressHandler(mActivity,
mActivity.getString(R.string.progress_exporting),
- ProgressDialog.STYLE_HORIZONTAL) {
+ ProgressDialog.STYLE_HORIZONTAL,
+ ProgressDialogFragment.ServiceType.KEYCHAIN_INTENT) {
public void handleMessage(Message message) {
// handle messages by standard KeychainIntentServiceHandler first
super.handleMessage(message);
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/NfcHelper.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/NfcHelper.java
new file mode 100644
index 000000000..e4e4e4d05
--- /dev/null
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/NfcHelper.java
@@ -0,0 +1,218 @@
+/*
+ * Copyright (C) 2013-2014 Dominik Schürmann <dominik@dominikschuermann.de>
+ * Copyright (C) 2015 Kent Nguyen <kentnguyen@moneylover.me>
+ *
+ * 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.util;
+
+import android.annotation.TargetApi;
+import android.app.Activity;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.net.Uri;
+import android.nfc.NdefMessage;
+import android.nfc.NdefRecord;
+import android.nfc.NfcAdapter;
+import android.nfc.NfcEvent;
+import android.os.AsyncTask;
+import android.os.Build;
+import android.os.Handler;
+import android.os.Message;
+import android.provider.Settings;
+
+import org.sufficientlysecure.keychain.Constants;
+import org.sufficientlysecure.keychain.R;
+import org.sufficientlysecure.keychain.provider.KeychainContract;
+import org.sufficientlysecure.keychain.provider.ProviderHelper;
+import org.sufficientlysecure.keychain.ui.util.Notify;
+
+import java.lang.ref.WeakReference;
+
+/**
+ * This class contains NFC functionality that can be shared across Fragments or Activities.
+ */
+
+public class NfcHelper {
+
+ private Activity mActivity;
+ private ProviderHelper mProviderHelper;
+
+ /**
+ * NFC: This handler receives a message from onNdefPushComplete
+ */
+ private static NfcHandler mNfcHandler;
+
+ private NfcAdapter mNfcAdapter;
+ private NfcAdapter.CreateNdefMessageCallback mNdefCallback;
+ private NfcAdapter.OnNdefPushCompleteCallback mNdefCompleteCallback;
+ private byte[] mNfcKeyringBytes;
+ private static final int NFC_SENT = 1;
+
+ /**
+ * Initializes the NfcHelper.
+ */
+ public NfcHelper(final Activity activity, final ProviderHelper providerHelper) {
+ mActivity = activity;
+ mProviderHelper = providerHelper;
+
+ mNfcHandler = new NfcHandler(mActivity);
+ }
+
+ /**
+ * Return true if the NFC Adapter of this Helper has any features enabled.
+ *
+ * @return true if this NFC Adapter has any features enabled
+ */
+ public boolean isEnabled() {
+ return mNfcAdapter.isEnabled();
+ }
+
+ /**
+ * NFC: Initialize NFC sharing if OS and device supports it
+ */
+ @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
+ public void initNfc(final Uri dataUri) {
+ // check if NFC Beam is supported (>= Android 4.1)
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
+
+ // Implementation for the CreateNdefMessageCallback interface
+ mNdefCallback = new NfcAdapter.CreateNdefMessageCallback() {
+ @Override
+ public NdefMessage createNdefMessage(NfcEvent event) {
+ /*
+ * When a device receives a push with an AAR in it, the application specified in the AAR is
+ * guaranteed to run. The AAR overrides the tag dispatch system. You can add it back in to
+ * guarantee that this activity starts when receiving a beamed message. For now, this code
+ * uses the tag dispatch system.
+ */
+ return new NdefMessage(NdefRecord.createMime(Constants.NFC_MIME,
+ mNfcKeyringBytes), NdefRecord.createApplicationRecord(Constants.PACKAGE_NAME));
+ }
+ };
+
+ // Implementation for the OnNdefPushCompleteCallback interface
+ mNdefCompleteCallback = new NfcAdapter.OnNdefPushCompleteCallback() {
+ @Override
+ public void onNdefPushComplete(NfcEvent event) {
+ // A handler is needed to send messages to the activity when this
+ // callback occurs, because it happens from a binder thread
+ mNfcHandler.obtainMessage(NFC_SENT).sendToTarget();
+ }
+ };
+
+ // Check for available NFC Adapter
+ mNfcAdapter = NfcAdapter.getDefaultAdapter(mActivity);
+ if (mNfcAdapter != null) {
+ /*
+ * Retrieve mNfcKeyringBytes here asynchronously (to not block the UI)
+ * and init nfc adapter afterwards.
+ * mNfcKeyringBytes can not be retrieved in createNdefMessage, because this process
+ * has no permissions to query the Uri.
+ */
+ AsyncTask<Void, Void, Void> initTask =
+ new AsyncTask<Void, Void, Void>() {
+ protected Void doInBackground(Void... unused) {
+ try {
+ Uri blobUri =
+ KeychainContract.KeyRingData.buildPublicKeyRingUri(dataUri);
+ mNfcKeyringBytes = (byte[]) mProviderHelper.getGenericData(
+ blobUri,
+ KeychainContract.KeyRingData.KEY_RING_DATA,
+ ProviderHelper.FIELD_TYPE_BLOB);
+ } catch (ProviderHelper.NotFoundException e) {
+ Log.e(Constants.TAG, "key not found!", e);
+ }
+
+ // no AsyncTask return (Void)
+ return null;
+ }
+
+ protected void onPostExecute(Void unused) {
+ // Register callback to set NDEF message
+ mNfcAdapter.setNdefPushMessageCallback(mNdefCallback,
+ mActivity);
+ // Register callback to listen for message-sent success
+ mNfcAdapter.setOnNdefPushCompleteCallback(mNdefCompleteCallback,
+ mActivity);
+ }
+ };
+
+ initTask.execute();
+ }
+ }
+ }
+
+ @TargetApi(Build.VERSION_CODES.LOLLIPOP)
+ public void invokeNfcBeam() {
+ // Check if device supports NFC
+ if (!mActivity.getPackageManager().hasSystemFeature(PackageManager.FEATURE_NFC)) {
+ Notify.create(mActivity, R.string.no_nfc_support, Notify.LENGTH_LONG, Notify.Style.ERROR).show();
+ return;
+ }
+ // Check for available NFC Adapter
+ mNfcAdapter = NfcAdapter.getDefaultAdapter(mActivity);
+ if (mNfcAdapter == null || !mNfcAdapter.isEnabled()) {
+ Notify.create(mActivity, R.string.error_nfc_needed, Notify.LENGTH_LONG, Notify.Style.ERROR, new Notify.ActionListener() {
+ @Override
+ public void onAction() {
+ Intent intentSettings = new Intent(Settings.ACTION_NFC_SETTINGS);
+ mActivity.startActivity(intentSettings);
+ }
+ }, R.string.menu_nfc_preferences).show();
+
+ return;
+ }
+
+ if (!mNfcAdapter.isNdefPushEnabled()) {
+ Notify.create(mActivity, R.string.error_beam_needed, Notify.LENGTH_LONG, Notify.Style.ERROR, new Notify.ActionListener() {
+ @Override
+ public void onAction() {
+ Intent intentSettings = new Intent(Settings.ACTION_NFCSHARING_SETTINGS);
+ mActivity.startActivity(intentSettings);
+ }
+ }, R.string.menu_beam_preferences).show();
+
+ return;
+ }
+
+ mNfcAdapter.invokeBeam(mActivity);
+ }
+
+ /**
+ * A static subclass of {@link Handler} with a {@link WeakReference} to an {@link Activity} to avoid memory leaks.
+ */
+ private static class NfcHandler extends Handler {
+ private final WeakReference<Activity> mActivityReference;
+
+ public NfcHandler(Activity activity) {
+ mActivityReference = new WeakReference<>(activity);
+ }
+
+ @Override
+ public void handleMessage(Message msg) {
+ Activity activity = mActivityReference.get();
+
+ if (activity != null) {
+ switch (msg.what) {
+ case NFC_SENT:
+ Notify.create(activity, R.string.nfc_successful, Notify.Style.OK).show();
+ break;
+ }
+ }
+ }
+ }
+
+} \ No newline at end of file
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/ParcelableFileCache.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/ParcelableFileCache.java
index 6f9cb277e..5a314ad0b 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/ParcelableFileCache.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/util/ParcelableFileCache.java
@@ -83,10 +83,22 @@ public class ParcelableFileCache<E extends Parcelable> {
}
+ /**
+ * Reads from cache file and deletes it afterward. Convenience function for readCache(boolean).
+ * @return an IteratorWithSize object containing entries read from the cache file
+ * @throws IOException
+ */
public IteratorWithSize<E> readCache() throws IOException {
return readCache(true);
}
+ /**
+ * Reads entries from a cache file and returns an IteratorWithSize object containing the entries
+ * @param deleteAfterRead if true, the cache file will be deleted after being read
+ * @return an IteratorWithSize object containing entries read from the cache file
+ * @throws IOException if cache directory/parcel import file does not exist, or a read error
+ * occurs
+ */
public IteratorWithSize<E> readCache(final boolean deleteAfterRead) throws IOException {
File cacheDir = mContext.getCacheDir();