From 1d6643fa6ba430f47da732bf4512287e4caf4628 Mon Sep 17 00:00:00 2001 From: Kent Date: Fri, 20 Mar 2015 06:40:52 +0800 Subject: Fixed #1152: - Checking if input.getSignatureSubKeyId() is not null before proceeding. --- .../keychain/pgp/PgpSignEncryptOperation.java | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) (limited to 'OpenKeychain/src/main/java') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncryptOperation.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncryptOperation.java index bd3c31d3a..16a09e77b 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncryptOperation.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/PgpSignEncryptOperation.java @@ -62,19 +62,19 @@ import java.util.Arrays; import java.util.Date; import java.util.concurrent.atomic.AtomicBoolean; -/** This class supports a single, low-level, sign/encrypt operation. - * +/** + * This class supports a single, low-level, sign/encrypt operation. + *

* The operation of this class takes an Input- and OutputStream plus a * PgpSignEncryptInput, and signs and/or encrypts the stream as * parametrized in the PgpSignEncryptInput object. It returns its status * and a possible detached signature as a SignEncryptResult. - * + *

* For a high-level operation based on URIs, see SignEncryptOperation. * * @see org.sufficientlysecure.keychain.pgp.PgpSignEncryptInput * @see org.sufficientlysecure.keychain.operations.results.PgpSignEncryptResult * @see org.sufficientlysecure.keychain.operations.SignEncryptOperation - * */ public class PgpSignEncryptOperation extends BaseOperation { @@ -100,7 +100,7 @@ public class PgpSignEncryptOperation extends BaseOperation { * Signs and/or encrypts data based on parameters of class */ public PgpSignEncryptResult execute(PgpSignEncryptInput input, - InputData inputData, OutputStream outputStream) { + InputData inputData, OutputStream outputStream) { int indent = 0; OperationLog log = new OperationLog(); @@ -487,6 +487,12 @@ public class PgpSignEncryptOperation extends BaseOperation { log.add(LogType.MSG_PSE_PENDING_NFC, indent); PgpSignEncryptResult result = new PgpSignEncryptResult(PgpSignEncryptResult.RESULT_PENDING_NFC, log); + + // SignatureSubKeyId can be null. + if (input.getSignatureSubKeyId() == null) { + return new PgpSignEncryptResult(PgpSignEncryptResult.RESULT_ERROR, log); + } + // Note that the checked key here is the master key, not the signing key // (although these are always the same on Yubikeys) result.setNfcData(input.getSignatureSubKeyId(), e.hashToSign, e.hashAlgo, e.creationTimestamp, input.getSignaturePassphrase()); -- cgit v1.2.3 From b3a599f214489ba9edce5b8c3f56b3f671499e86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Mon, 23 Mar 2015 01:11:11 +0100 Subject: Use markdown for in-app help --- .../keychain/ui/HelpAboutFragment.java | 13 +++- .../keychain/ui/HelpActivity.java | 19 +++-- .../keychain/ui/HelpHtmlFragment.java | 76 ------------------- .../keychain/ui/HelpMarkdownFragment.java | 86 ++++++++++++++++++++++ 4 files changed, 109 insertions(+), 85 deletions(-) delete mode 100644 OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/HelpHtmlFragment.java create mode 100644 OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/HelpMarkdownFragment.java (limited to 'OpenKeychain/src/main/java') 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/HelpHtmlFragment.java deleted file mode 100644 index a3f0ef614..000000000 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/HelpHtmlFragment.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (C) 2012-2014 Dominik Schürmann - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package org.sufficientlysecure.keychain.ui; - -import android.app.Activity; -import android.os.Bundle; -import android.support.v4.app.Fragment; -import android.util.TypedValue; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.ScrollView; - -import org.sufficientlysecure.htmltextview.HtmlTextView; - -public class HelpHtmlFragment extends Fragment { - private Activity mActivity; - - private int mHtmlFile; - - public static final String ARG_HTML_FILE = "htmlFile"; - - /** - * Create a new instance of HelpHtmlFragment, providing "htmlFile" as an argument. - */ - static HelpHtmlFragment newInstance(int htmlFile) { - HelpHtmlFragment f = new HelpHtmlFragment(); - - // Supply html raw file input as an argument. - Bundle args = new Bundle(); - args.putInt(ARG_HTML_FILE, htmlFile); - f.setArguments(args); - - return f; - } - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - mActivity = getActivity(); - - mHtmlFile = getArguments().getInt(ARG_HTML_FILE); - - ScrollView scroller = new ScrollView(mActivity); - HtmlTextView text = new HtmlTextView(mActivity); - - // padding - int padding = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 16, mActivity - .getResources().getDisplayMetrics()); - text.setPadding(padding, padding, padding, 0); - - scroller.addView(text); - - // load html from raw resource (Parsing handled by HtmlTextView library) - text.setHtmlFromRawResource(getActivity(), mHtmlFile, true); - - // no flickering when clicking textview for Android < 4 - text.setTextColor(getResources().getColor(android.R.color.black)); - - return scroller; - } -} diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/HelpMarkdownFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/HelpMarkdownFragment.java new file mode 100644 index 000000000..69ddf2e99 --- /dev/null +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/HelpMarkdownFragment.java @@ -0,0 +1,86 @@ +/* + * Copyright (C) 2012-2014 Dominik Schürmann + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package org.sufficientlysecure.keychain.ui; + +import android.app.Activity; +import android.os.Bundle; +import android.support.v4.app.Fragment; +import android.util.TypedValue; +import android.view.LayoutInflater; +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; + +import java.io.IOException; + +public class HelpMarkdownFragment extends Fragment { + private Activity mActivity; + + private int mHtmlFile; + + public static final String ARG_MARKDOWN_FILE = "htmlFile"; + + /** + * Create a new instance of HelpHtmlFragment, providing "htmlFile" as an argument. + */ + static HelpMarkdownFragment newInstance(int htmlFile) { + HelpMarkdownFragment f = new HelpMarkdownFragment(); + + // Supply html raw file input as an argument. + Bundle args = new Bundle(); + args.putInt(ARG_MARKDOWN_FILE, htmlFile); + f.setArguments(args); + + return f; + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + mActivity = getActivity(); + + mHtmlFile = getArguments().getInt(ARG_MARKDOWN_FILE); + + ScrollView scroller = new ScrollView(mActivity); + HtmlTextView text = new HtmlTextView(mActivity); + + // padding + int padding = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 16, mActivity + .getResources().getDisplayMetrics()); + text.setPadding(padding, padding, padding, 0); + + scroller.addView(text); + + // 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)); + + return scroller; + } +} -- cgit v1.2.3 From 19775c399b106149e8906a7482a4b5a4af2ac8fa Mon Sep 17 00:00:00 2001 From: Adithya Abraham Philip Date: Thu, 19 Mar 2015 20:31:34 +0530 Subject: introduced multi-threading refactored oldKeys to updatedKeys added update all keys, ThreadPoolExecutor used modified CachedThreadPoolExecutor --- .../keychain/operations/ImportExportOperation.java | 20 +- .../keychain/service/KeychainIntentService.java | 235 ++++++++++++++++++--- .../keychain/ui/KeyListFragment.java | 88 ++++++++ .../keychain/util/ParcelableFileCache.java | 12 ++ 4 files changed, 320 insertions(+), 35 deletions(-) (limited to 'OpenKeychain/src/main/java') 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 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/service/KeychainIntentService.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java index d5f13f7ce..0cac8fb32 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java @@ -21,11 +21,11 @@ package org.sufficientlysecure.keychain.service; import android.app.IntentService; import android.content.Intent; import android.net.Uri; + import android.os.Bundle; import android.os.Message; import android.os.Messenger; import android.os.RemoteException; - import com.textuality.keybase.lib.Proof; import com.textuality.keybase.lib.prover.Prover; @@ -74,7 +74,9 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.ArrayList; +import java.util.Iterator; import java.util.List; +import java.util.concurrent.*; import java.util.concurrent.atomic.AtomicBoolean; import de.measite.minidns.Client; @@ -136,7 +138,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]; @@ -201,7 +203,127 @@ public class KeychainIntentService extends IntentService implements Progressable Messenger mMessenger; // this attribute can possibly merged with the one above? not sure... - private AtomicBoolean mActionCanceled = new AtomicBoolean(false); + private static AtomicBoolean sActionCanceled = new AtomicBoolean(false); + + /** + * accumulates the results from a multi-threaded key import from a keyserver and + * consolidates them into a single ImportKeyResult, besides keeping count of keys imported and + * total keys to be imported. Also provides the Progressable used by these threads, which + * currently ignores updates + */ + private class KeyImportAccumulator { + private OperationLog mImportLog = new OperationLog(); + private int mTotalKeys; + private int mImportedKeys = 0; + private Progressable mImportProgressable; + ArrayList mImportedMasterKeyIds = new ArrayList(); + 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; public KeychainIntentService() { super("KeychainIntentService"); @@ -216,7 +338,7 @@ public class KeychainIntentService extends IntentService implements Progressable protected void onHandleIntent(Intent intent) { // We have not been cancelled! (yet) - mActionCanceled.set(false); + sActionCanceled.set(false); Bundle extras = intent.getExtras(); if (extras == null) { @@ -242,7 +364,7 @@ public class KeychainIntentService extends IntentService implements Progressable Log.logDebugBundle(data, "EXTRA_DATA"); - ProviderHelper providerHelper = new ProviderHelper(this); + final ProviderHelper providerHelper = new ProviderHelper(this); String action = intent.getAction(); @@ -255,7 +377,7 @@ public class KeychainIntentService extends IntentService implements Progressable String keyServerUri = data.getString(UPLOAD_KEY_SERVER); // Operation - CertifyOperation op = new CertifyOperation(this, providerHelper, this, mActionCanceled); + CertifyOperation op = new CertifyOperation(this, providerHelper, this, sActionCanceled); CertifyResult result = op.certify(parcel, keyServerUri); // Result @@ -473,7 +595,7 @@ public class KeychainIntentService extends IntentService implements Progressable Passphrase passphrase = data.getParcelable(EDIT_KEYRING_PASSPHRASE); // Operation - EditKeyOperation op = new EditKeyOperation(this, providerHelper, this, mActionCanceled); + EditKeyOperation op = new EditKeyOperation(this, providerHelper, this, sActionCanceled); EditKeyResult result = op.execute(saveParcel, passphrase); // Result @@ -487,7 +609,7 @@ public class KeychainIntentService extends IntentService implements Progressable long keyRingId = data.getInt(EXPORT_KEY_RING_MASTER_KEY_ID); // Operation - PromoteKeyOperation op = new PromoteKeyOperation(this, providerHelper, this, mActionCanceled); + PromoteKeyOperation op = new PromoteKeyOperation(this, providerHelper, this, sActionCanceled); PromoteKeyResult result = op.execute(keyRingId); // Result @@ -520,26 +642,68 @@ public class KeychainIntentService extends IntentService implements Progressable break; } case ACTION_IMPORT_KEYRING: { - // Input - String keyServer = data.getString(IMPORT_KEY_SERVER); + final String keyServer = data.getString(IMPORT_KEY_SERVER); ArrayList list = data.getParcelableArrayList(IMPORT_KEY_LIST); ParcelableFileCache cache = new ParcelableFileCache<>(this, "key_import.pcl"); + int totKeys = 0; + Iterator keyListIterator = null; + //either list or cache must be null, no guarantees otherwise + if (list == null) {//export from cache, copied from ImportExportOperation.importKeyRings - // Operation - ImportExportOperation importExportOperation = new ImportExportOperation( - this, providerHelper, this, mActionCanceled); - // Either list or cache must be null, no guarantees otherwise. - ImportKeyResult result = list != null - ? importExportOperation.importKeyRings(list, keyServer) - : importExportOperation.importKeyRings(cache, keyServer); + try { + ParcelableFileCache.IteratorWithSize it = cache.readCache(); + keyListIterator = it; + totKeys = it.getSize(); + } catch (IOException e) { - // Result - sendMessageToHandler(MessageStatus.OKAY, result); + // Special treatment here, we need a lot + OperationLog log = new OperationLog(); + log.add(OperationResult.LogType.MSG_IMPORT, 0, 0); + log.add(OperationResult.LogType.MSG_IMPORT_ERROR_IO, 0, 0); - break; + keyImportFailed(new ImportKeyResult(ImportKeyResult.RESULT_ERROR, log)); + } + } else { + keyListIterator = list.iterator(); + totKeys = list.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()); + + while (keyListIterator.hasNext()) { + final ParcelableKeyRing pkRing = keyListIterator.next(); + Runnable importOperationRunnable = new Runnable() { + @Override + public void run() { + // Operation + ImportExportOperation importExportOperation = new ImportExportOperation( + KeychainIntentService.this, + new ProviderHelper(KeychainIntentService.this), + mKeyImportAccumulator.getImportProgressable(), + sActionCanceled); + + ArrayList list = new ArrayList<>(); + list.add(pkRing); + ImportKeyResult result = importExportOperation.importKeyRings(list, + keyServer); + singleKeyRingImportCompleted(result); + } + }; + importExecutor.execute(importOperationRunnable); + } + } + break; } case ACTION_SIGN_ENCRYPT: { @@ -548,7 +712,7 @@ public class KeychainIntentService extends IntentService implements Progressable // Operation SignEncryptOperation op = new SignEncryptOperation( - this, new ProviderHelper(this), this, mActionCanceled); + this, new ProviderHelper(this), this, sActionCanceled); SignEncryptResult result = op.execute(inputParcel); // Result @@ -584,6 +748,23 @@ public class KeychainIntentService extends IntentService implements Progressable } } + private synchronized void singleKeyRingImportCompleted(ImportKeyResult result) { + mKeyImportAccumulator.accumulateKeyImport(result); + + setProgress(mKeyImportAccumulator.getImportedKeys(), mKeyImportAccumulator.getTotalKeys()); + + if (mKeyImportAccumulator.isImportFinished()) { + ContactSyncAdapterService.requestSync(); + + sendMessageToHandler(MessageStatus.OKAY, + mKeyImportAccumulator.getConsolidatedImportKeyResult()); + } + } + + private void keyImportFailed(ImportKeyResult result) { + sendMessageToHandler(MessageStatus.OKAY, result); + } + private void sendProofError(List log, String label) { String msg = null; label = (label == null) ? "" : label + ": "; @@ -655,7 +836,7 @@ public class KeychainIntentService extends IntentService implements Progressable /** * Set progress of ProgressDialog by sending message to handler on UI thread */ - public void setProgress(String message, int progress, int max) { + public synchronized void setProgress(String message, int progress, int max) { Log.d(Constants.TAG, "Send message by setProgress with progress=" + progress + ", max=" + max); @@ -669,16 +850,16 @@ public class KeychainIntentService extends IntentService implements Progressable sendMessageToHandler(MessageStatus.UPDATE_PROGRESS, null, data); } - public void setProgress(int resourceId, int progress, int max) { + public synchronized void setProgress(int resourceId, int progress, int max) { setProgress(getString(resourceId), progress, max); } - public void setProgress(int progress, int max) { + public synchronized void setProgress(int progress, int max) { setProgress(null, progress, max); } @Override - public void setPreventCancel() { + public synchronized void setPreventCancel() { sendMessageToHandler(MessageStatus.PREVENT_CANCEL); } @@ -743,8 +924,10 @@ public class KeychainIntentService extends IntentService implements Progressable @Override public int onStartCommand(Intent intent, int flags, int startId) { + // onStartCommand will be run on the thread which starts the service + // cancel operation is introduced here as it must not be queued up if (ACTION_CANCEL.equals(intent.getAction())) { - mActionCanceled.set(true); + sActionCanceled.set(true); return START_NOT_STICKY; } return super.onStartCommand(intent, flags, startId); 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 5f1189deb..513da7785 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java @@ -20,6 +20,7 @@ package org.sufficientlysecure.keychain.ui; import android.animation.ObjectAnimator; import android.annotation.TargetApi; +import android.app.Activity; import android.app.ProgressDialog; import android.content.Context; import android.content.Intent; @@ -58,13 +59,17 @@ import com.getbase.floatingactionbutton.FloatingActionsMenu; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; +import org.sufficientlysecure.keychain.keyimport.ImportKeysListEntry; +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.KeychainIntentService; import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler; import org.sufficientlysecure.keychain.ui.dialog.DeleteKeyDialogFragment; @@ -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; @@ -477,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; @@ -561,6 +571,84 @@ public class KeyListFragment extends LoaderFragment startActivityForResult(intent, 0); } + private void updateAllKeys() { + Context context = this.getActivity(); + + ProviderHelper providerHelper = new ProviderHelper(context); + + Cursor cursor = providerHelper.getContentResolver().query( + KeyRings.buildUnifiedKeyRingsUri(), new String[]{ + KeyRings.FINGERPRINT + }, null, null, null + ); + + ArrayList 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); + } + + KeychainIntentServiceHandler serviceHandler = new KeychainIntentServiceHandler( + getActivity(), + getString(R.string.progress_importing), + ProgressDialog.STYLE_HORIZONTAL, + true) { + 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(KeyListFragment.this.getActivity()).show(); + } + } + }; + + // Send all information needed to service to query keys in other thread + Intent intent = new Intent(getActivity(), KeychainIntentService.class); + + intent.setAction(KeychainIntentService.ACTION_IMPORT_KEYRING); + + // 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(KeychainIntentService.IMPORT_KEY_SERVER, cloudPrefs.keyserver); + } + + data.putParcelableArrayList(KeychainIntentService.IMPORT_KEY_LIST, keyList); + + intent.putExtra(KeychainIntentService.EXTRA_DATA, data); + + // Create a new Messenger for the communication back + Messenger messenger = new Messenger(serviceHandler); + intent.putExtra(KeychainIntentService.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( 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 { } + /** + * 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 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 readCache(final boolean deleteAfterRead) throws IOException { File cacheDir = mContext.getCacheDir(); -- cgit v1.2.3 From 9f5581463f1b2d07217f59fa32346c786069dbf5 Mon Sep 17 00:00:00 2001 From: Adithya Abraham Philip Date: Sun, 22 Mar 2015 03:31:13 +0530 Subject: shifted multi-threading to own service added multi-threaded cloud import, restored KeychainIntentService eliminated code duplication in multi-threaded import --- .../keychain/service/CloudImportService.java | 387 +++++++++++++++++++++ .../keychain/service/KeychainIntentService.java | 253 ++------------ .../service/KeychainIntentServiceHandler.java | 166 --------- .../keychain/service/ServiceProgressHandler.java | 172 +++++++++ .../keychain/ui/CertifyKeyFragment.java | 11 +- .../keychain/ui/ConsolidateDialogActivity.java | 8 +- .../keychain/ui/CreateKeyFinalFragment.java | 17 +- .../keychain/ui/DecryptFilesFragment.java | 17 +- .../keychain/ui/DecryptTextFragment.java | 10 +- .../keychain/ui/EditKeyFragment.java | 14 +- .../keychain/ui/EncryptActivity.java | 10 +- .../keychain/ui/ImportKeysActivity.java | 32 +- .../keychain/ui/ImportKeysProxyActivity.java | 8 +- .../keychain/ui/KeyListFragment.java | 34 +- .../keychain/ui/SafeSlingerActivity.java | 8 +- .../keychain/ui/UploadKeyActivity.java | 10 +- .../keychain/ui/ViewKeyActivity.java | 8 +- .../keychain/ui/ViewKeyTrustFragment.java | 21 +- .../ui/dialog/DeleteKeyDialogFragment.java | 11 +- .../keychain/ui/dialog/ProgressDialogFragment.java | 44 ++- .../keychain/util/ExportHelper.java | 13 +- 21 files changed, 764 insertions(+), 490 deletions(-) create mode 100644 OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/CloudImportService.java delete mode 100644 OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentServiceHandler.java create mode 100644 OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/ServiceProgressHandler.java (limited to 'OpenKeychain/src/main/java') 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 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package org.sufficientlysecure.keychain.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 mImportedMasterKeyIds = new ArrayList(); + 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 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 keyList, final String keyServer) { + ParcelableFileCache cache = + new ParcelableFileCache<>(this, "key_import.pcl"); + int totKeys = 0; + Iterator 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 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()); + + 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 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 0cac8fb32..5ecfb29f5 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java @@ -21,11 +21,11 @@ package org.sufficientlysecure.keychain.service; import android.app.IntentService; import android.content.Intent; import android.net.Uri; - import android.os.Bundle; import android.os.Message; import android.os.Messenger; import android.os.RemoteException; + import com.textuality.keybase.lib.Proof; import com.textuality.keybase.lib.prover.Prover; @@ -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; @@ -74,9 +74,7 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.ArrayList; -import java.util.Iterator; import java.util.List; -import java.util.concurrent.*; import java.util.concurrent.atomic.AtomicBoolean; import de.measite.minidns.Client; @@ -203,127 +201,7 @@ public class KeychainIntentService extends IntentService implements Progressable Messenger mMessenger; // this attribute can possibly merged with the one above? not sure... - private static AtomicBoolean sActionCanceled = new AtomicBoolean(false); - - /** - * accumulates the results from a multi-threaded key import from a keyserver and - * consolidates them into a single ImportKeyResult, besides keeping count of keys imported and - * total keys to be imported. Also provides the Progressable used by these threads, which - * currently ignores updates - */ - private class KeyImportAccumulator { - private OperationLog mImportLog = new OperationLog(); - private int mTotalKeys; - private int mImportedKeys = 0; - private Progressable mImportProgressable; - ArrayList mImportedMasterKeyIds = new ArrayList(); - 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; + private AtomicBoolean mActionCanceled = new AtomicBoolean(false); public KeychainIntentService() { super("KeychainIntentService"); @@ -338,7 +216,7 @@ public class KeychainIntentService extends IntentService implements Progressable protected void onHandleIntent(Intent intent) { // We have not been cancelled! (yet) - sActionCanceled.set(false); + mActionCanceled.set(false); Bundle extras = intent.getExtras(); if (extras == null) { @@ -364,7 +242,7 @@ public class KeychainIntentService extends IntentService implements Progressable Log.logDebugBundle(data, "EXTRA_DATA"); - final ProviderHelper providerHelper = new ProviderHelper(this); + ProviderHelper providerHelper = new ProviderHelper(this); String action = intent.getAction(); @@ -377,7 +255,7 @@ public class KeychainIntentService extends IntentService implements Progressable String keyServerUri = data.getString(UPLOAD_KEY_SERVER); // Operation - CertifyOperation op = new CertifyOperation(this, providerHelper, this, sActionCanceled); + CertifyOperation op = new CertifyOperation(this, providerHelper, this, mActionCanceled); CertifyResult result = op.certify(parcel, keyServerUri); // Result @@ -517,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); @@ -595,7 +473,7 @@ public class KeychainIntentService extends IntentService implements Progressable Passphrase passphrase = data.getParcelable(EDIT_KEYRING_PASSPHRASE); // Operation - EditKeyOperation op = new EditKeyOperation(this, providerHelper, this, sActionCanceled); + EditKeyOperation op = new EditKeyOperation(this, providerHelper, this, mActionCanceled); EditKeyResult result = op.execute(saveParcel, passphrase); // Result @@ -609,7 +487,7 @@ public class KeychainIntentService extends IntentService implements Progressable long keyRingId = data.getInt(EXPORT_KEY_RING_MASTER_KEY_ID); // Operation - PromoteKeyOperation op = new PromoteKeyOperation(this, providerHelper, this, sActionCanceled); + PromoteKeyOperation op = new PromoteKeyOperation(this, providerHelper, this, mActionCanceled); PromoteKeyResult result = op.execute(keyRingId); // Result @@ -642,68 +520,26 @@ public class KeychainIntentService extends IntentService implements Progressable break; } case ACTION_IMPORT_KEYRING: { + // Input - final String keyServer = data.getString(IMPORT_KEY_SERVER); + String keyServer = data.getString(IMPORT_KEY_SERVER); ArrayList list = data.getParcelableArrayList(IMPORT_KEY_LIST); ParcelableFileCache cache = new ParcelableFileCache<>(this, "key_import.pcl"); - int totKeys = 0; - Iterator keyListIterator = null; - //either list or cache must be null, no guarantees otherwise - if (list == null) {//export from cache, copied from ImportExportOperation.importKeyRings - - try { - ParcelableFileCache.IteratorWithSize it = cache.readCache(); - keyListIterator = it; - totKeys = it.getSize(); - } catch (IOException e) { - - // Special treatment here, we need a lot - OperationLog log = new 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 = list.iterator(); - totKeys = list.size(); - } + // Operation + ImportExportOperation importExportOperation = new ImportExportOperation( + this, providerHelper, this, mActionCanceled); + // Either list or cache must be null, no guarantees otherwise. + ImportKeyResult result = list != null + ? importExportOperation.importKeyRings(list, keyServer) + : importExportOperation.importKeyRings(cache, keyServer); - 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()); - - while (keyListIterator.hasNext()) { - final ParcelableKeyRing pkRing = keyListIterator.next(); - Runnable importOperationRunnable = new Runnable() { - @Override - public void run() { - // Operation - ImportExportOperation importExportOperation = new ImportExportOperation( - KeychainIntentService.this, - new ProviderHelper(KeychainIntentService.this), - mKeyImportAccumulator.getImportProgressable(), - sActionCanceled); - - ArrayList list = new ArrayList<>(); - list.add(pkRing); - ImportKeyResult result = importExportOperation.importKeyRings(list, - keyServer); - singleKeyRingImportCompleted(result); - } - }; - importExecutor.execute(importOperationRunnable); - } - } + // Result + sendMessageToHandler(MessageStatus.OKAY, result); break; + } case ACTION_SIGN_ENCRYPT: { @@ -712,7 +548,7 @@ public class KeychainIntentService extends IntentService implements Progressable // Operation SignEncryptOperation op = new SignEncryptOperation( - this, new ProviderHelper(this), this, sActionCanceled); + this, new ProviderHelper(this), this, mActionCanceled); SignEncryptResult result = op.execute(inputParcel); // Result @@ -748,23 +584,6 @@ public class KeychainIntentService extends IntentService implements Progressable } } - private synchronized void singleKeyRingImportCompleted(ImportKeyResult result) { - mKeyImportAccumulator.accumulateKeyImport(result); - - setProgress(mKeyImportAccumulator.getImportedKeys(), mKeyImportAccumulator.getTotalKeys()); - - if (mKeyImportAccumulator.isImportFinished()) { - ContactSyncAdapterService.requestSync(); - - sendMessageToHandler(MessageStatus.OKAY, - mKeyImportAccumulator.getConsolidatedImportKeyResult()); - } - } - - private void keyImportFailed(ImportKeyResult result) { - sendMessageToHandler(MessageStatus.OKAY, result); - } - private void sendProofError(List log, String label) { String msg = null; label = (label == null) ? "" : label + ": "; @@ -777,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); } @@ -794,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); } @@ -836,30 +655,30 @@ public class KeychainIntentService extends IntentService implements Progressable /** * Set progress of ProgressDialog by sending message to handler on UI thread */ - public synchronized void setProgress(String message, int progress, int max) { + public void setProgress(String message, int progress, int max) { Log.d(Constants.TAG, "Send message by setProgress with progress=" + progress + ", max=" + max); Bundle data = new Bundle(); if (message != null) { - data.putString(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); } - public synchronized void setProgress(int resourceId, int progress, int max) { + public void setProgress(int resourceId, int progress, int max) { setProgress(getString(resourceId), progress, max); } - public synchronized void setProgress(int progress, int max) { + public void setProgress(int progress, int max) { setProgress(null, progress, max); } @Override - public synchronized void setPreventCancel() { + public void setPreventCancel() { sendMessageToHandler(MessageStatus.PREVENT_CANCEL); } @@ -924,10 +743,8 @@ public class KeychainIntentService extends IntentService implements Progressable @Override public int onStartCommand(Intent intent, int flags, int startId) { - // onStartCommand will be run on the thread which starts the service - // cancel operation is introduced here as it must not be queued up if (ACTION_CANCEL.equals(intent.getAction())) { - sActionCanceled.set(true); + mActionCanceled.set(true); return START_NOT_STICKY; } return super.onStartCommand(intent, flags, startId); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentServiceHandler.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentServiceHandler.java deleted file mode 100644 index 91a079a5d..000000000 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentServiceHandler.java +++ /dev/null @@ -1,166 +0,0 @@ -/* - * Copyright (C) 2012-2013 Dominik Schürmann - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package org.sufficientlysecure.keychain.service; - -import android.app.Activity; -import android.os.Bundle; -import android.os.Handler; -import android.os.Message; -import android.support.v4.app.FragmentActivity; -import android.support.v4.app.FragmentManager; - -import org.sufficientlysecure.keychain.Constants; -import org.sufficientlysecure.keychain.R; -import org.sufficientlysecure.keychain.ui.dialog.ProgressDialogFragment; -import org.sufficientlysecure.keychain.ui.util.Notify; -import org.sufficientlysecure.keychain.util.Log; - -public class KeychainIntentServiceHandler extends Handler { - - // possible messages sent from this service to handler on ui - public static enum MessageStatus{ - UNKNOWN, - OKAY, - EXCEPTION, - UPDATE_PROGRESS, - PREVENT_CANCEL; - - private static final MessageStatus[] values = values(); - - public static MessageStatus fromInt(int n) - { - if(n < 0 || n >= values.length) { - return UNKNOWN; - } else { - return values[n]; - } - } - } - - // possible data keys for messages - public static final String DATA_ERROR = "error"; - public static final String DATA_PROGRESS = "progress"; - public static final String DATA_PROGRESS_MAX = "max"; - public static final String DATA_MESSAGE = "message"; - public static final String DATA_MESSAGE_ID = "message_id"; - - // keybase proof specific - public static final String KEYBASE_PROOF_URL = "keybase_proof_url"; - public static final String KEYBASE_PRESENCE_URL = "keybase_presence_url"; - public static final String KEYBASE_PRESENCE_LABEL = "keybase_presence_label"; - - Activity mActivity; - ProgressDialogFragment mProgressDialogFragment; - - public KeychainIntentServiceHandler(Activity activity) { - this.mActivity = activity; - } - - public KeychainIntentServiceHandler(Activity activity, - ProgressDialogFragment progressDialogFragment) { - this.mActivity = activity; - this.mProgressDialogFragment = progressDialogFragment; - } - - public KeychainIntentServiceHandler(Activity activity, String progressDialogMessage, - int progressDialogStyle) { - this(activity, progressDialogMessage, progressDialogStyle, false); - } - - public KeychainIntentServiceHandler(Activity activity, String progressDialogMessage, - int progressDialogStyle, boolean cancelable) { - this.mActivity = activity; - this.mProgressDialogFragment = ProgressDialogFragment.newInstance( - progressDialogMessage, - progressDialogStyle, - cancelable); - } - - public void showProgressDialog(FragmentActivity activity) { - if (mProgressDialogFragment == null) { - return; - } - - // TODO: This is a hack!, see - // http://stackoverflow.com/questions/10114324/show-dialogfragment-from-onactivityresult - final FragmentManager manager = activity.getSupportFragmentManager(); - Handler handler = new Handler(); - handler.post(new Runnable() { - public void run() { - mProgressDialogFragment.show(manager, "progressDialog"); - } - }); - } - - @Override - public void handleMessage(Message message) { - Bundle data = message.getData(); - - if (mProgressDialogFragment == null) { - // Log.e(Constants.TAG, - // "Progress has not been updated because mProgressDialogFragment was null!"); - return; - } - - MessageStatus status = MessageStatus.fromInt(message.arg1); - switch (status) { - case OKAY: - mProgressDialogFragment.dismissAllowingStateLoss(); - - break; - - case EXCEPTION: - mProgressDialogFragment.dismissAllowingStateLoss(); - - // show error from service - if (data.containsKey(DATA_ERROR)) { - Notify.create(mActivity, - mActivity.getString(R.string.error_message, data.getString(DATA_ERROR)), - Notify.Style.ERROR).show(); - } - - break; - - case UPDATE_PROGRESS: - if (data.containsKey(DATA_PROGRESS) && data.containsKey(DATA_PROGRESS_MAX)) { - - // update progress from service - if (data.containsKey(DATA_MESSAGE)) { - mProgressDialogFragment.setProgress(data.getString(DATA_MESSAGE), - data.getInt(DATA_PROGRESS), data.getInt(DATA_PROGRESS_MAX)); - } else if (data.containsKey(DATA_MESSAGE_ID)) { - mProgressDialogFragment.setProgress(data.getInt(DATA_MESSAGE_ID), - data.getInt(DATA_PROGRESS), data.getInt(DATA_PROGRESS_MAX)); - } else { - mProgressDialogFragment.setProgress(data.getInt(DATA_PROGRESS), - data.getInt(DATA_PROGRESS_MAX)); - } - } - - break; - - case PREVENT_CANCEL: - mProgressDialogFragment.setPreventCancel(true); - break; - - default: - Log.e(Constants.TAG, "unknown handler message!"); - break; - } - } -} diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/ServiceProgressHandler.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/ServiceProgressHandler.java new file mode 100644 index 000000000..4bd3481e6 --- /dev/null +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/ServiceProgressHandler.java @@ -0,0 +1,172 @@ +/* + * Copyright (C) 2012-2013 Dominik Schürmann + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package org.sufficientlysecure.keychain.service; + +import android.app.Activity; +import android.os.Bundle; +import android.os.Handler; +import android.os.Message; +import android.support.v4.app.FragmentActivity; +import android.support.v4.app.FragmentManager; + +import org.sufficientlysecure.keychain.Constants; +import org.sufficientlysecure.keychain.R; +import org.sufficientlysecure.keychain.ui.dialog.ProgressDialogFragment; +import org.sufficientlysecure.keychain.ui.util.Notify; +import org.sufficientlysecure.keychain.util.Log; + +public class ServiceProgressHandler extends Handler { + + // possible messages sent from this service to handler on ui + public static enum MessageStatus{ + UNKNOWN, + OKAY, + EXCEPTION, + UPDATE_PROGRESS, + PREVENT_CANCEL; + + private static final MessageStatus[] values = values(); + + public static MessageStatus fromInt(int n) + { + if(n < 0 || n >= values.length) { + return UNKNOWN; + } else { + return values[n]; + } + } + } + + // possible data keys for messages + public static final String DATA_ERROR = "error"; + public static final String DATA_PROGRESS = "progress"; + public static final String DATA_PROGRESS_MAX = "max"; + public static final String DATA_MESSAGE = "message"; + public static final String DATA_MESSAGE_ID = "message_id"; + + // keybase proof specific + public static final String KEYBASE_PROOF_URL = "keybase_proof_url"; + public static final String KEYBASE_PRESENCE_URL = "keybase_presence_url"; + public static final String KEYBASE_PRESENCE_LABEL = "keybase_presence_label"; + + Activity mActivity; + ProgressDialogFragment mProgressDialogFragment; + + public ServiceProgressHandler(Activity activity) { + this.mActivity = activity; + } + + public ServiceProgressHandler(Activity activity, + ProgressDialogFragment progressDialogFragment) { + this.mActivity = activity; + this.mProgressDialogFragment = progressDialogFragment; + } + + public ServiceProgressHandler(Activity activity, + String progressDialogMessage, + int progressDialogStyle, + ProgressDialogFragment.ServiceType serviceType) { + this(activity, progressDialogMessage, progressDialogStyle, false, serviceType); + } + + public ServiceProgressHandler(Activity activity, + String progressDialogMessage, + int progressDialogStyle, + boolean cancelable, + ProgressDialogFragment.ServiceType serviceType) { + this.mActivity = activity; + this.mProgressDialogFragment = ProgressDialogFragment.newInstance( + progressDialogMessage, + progressDialogStyle, + cancelable, + serviceType); + } + + public void showProgressDialog(FragmentActivity activity) { + if (mProgressDialogFragment == null) { + return; + } + + // TODO: This is a hack!, see + // http://stackoverflow.com/questions/10114324/show-dialogfragment-from-onactivityresult + final FragmentManager manager = activity.getSupportFragmentManager(); + Handler handler = new Handler(); + handler.post(new Runnable() { + public void run() { + mProgressDialogFragment.show(manager, "progressDialog"); + } + }); + } + + @Override + public void handleMessage(Message message) { + Bundle data = message.getData(); + + if (mProgressDialogFragment == null) { + // Log.e(Constants.TAG, + // "Progress has not been updated because mProgressDialogFragment was null!"); + return; + } + + MessageStatus status = MessageStatus.fromInt(message.arg1); + switch (status) { + case OKAY: + mProgressDialogFragment.dismissAllowingStateLoss(); + + break; + + case EXCEPTION: + mProgressDialogFragment.dismissAllowingStateLoss(); + + // show error from service + if (data.containsKey(DATA_ERROR)) { + Notify.create(mActivity, + mActivity.getString(R.string.error_message, data.getString(DATA_ERROR)), + Notify.Style.ERROR).show(); + } + + break; + + case UPDATE_PROGRESS: + if (data.containsKey(DATA_PROGRESS) && data.containsKey(DATA_PROGRESS_MAX)) { + + // update progress from service + if (data.containsKey(DATA_MESSAGE)) { + mProgressDialogFragment.setProgress(data.getString(DATA_MESSAGE), + data.getInt(DATA_PROGRESS), data.getInt(DATA_PROGRESS_MAX)); + } else if (data.containsKey(DATA_MESSAGE_ID)) { + mProgressDialogFragment.setProgress(data.getInt(DATA_MESSAGE_ID), + data.getInt(DATA_PROGRESS), data.getInt(DATA_PROGRESS_MAX)); + } else { + mProgressDialogFragment.setProgress(data.getInt(DATA_PROGRESS), + data.getInt(DATA_PROGRESS_MAX)); + } + } + + break; + + case PREVENT_CANCEL: + mProgressDialogFragment.setPreventCancel(true); + break; + + default: + Log.e(Constants.TAG, "unknown handler message!"); + 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 b3738851c..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; @@ -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 cbe3eecd4..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); 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 a92fb596c..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; @@ -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/DecryptTextFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptTextFragment.java index 80a07214b..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; @@ -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 61a02720e..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; @@ -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/ImportKeysActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java index 9143609ad..dc4a2eb10 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java @@ -35,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; @@ -294,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); @@ -342,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(); @@ -362,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); @@ -382,14 +382,12 @@ public class ImportKeysActivity extends BaseActivity { 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 keys = new ArrayList<>(); @@ -402,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); 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 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 513da7785..861ae12d9 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java @@ -20,7 +20,6 @@ package org.sufficientlysecure.keychain.ui; import android.animation.ObjectAnimator; import android.annotation.TargetApi; -import android.app.Activity; import android.app.ProgressDialog; import android.content.Context; import android.content.Intent; @@ -59,7 +58,6 @@ import com.getbase.floatingactionbutton.FloatingActionsMenu; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; -import org.sufficientlysecure.keychain.keyimport.ImportKeysListEntry; import org.sufficientlysecure.keychain.keyimport.ParcelableKeyRing; import org.sufficientlysecure.keychain.operations.results.ConsolidateResult; import org.sufficientlysecure.keychain.operations.results.DeleteResult; @@ -70,9 +68,11 @@ 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; @@ -572,7 +572,7 @@ public class KeyListFragment extends LoaderFragment } private void updateAllKeys() { - Context context = this.getActivity(); + Context context = getActivity(); ProviderHelper providerHelper = new ProviderHelper(context); @@ -591,11 +591,12 @@ public class KeyListFragment extends LoaderFragment keyList.add(keyEntry); } - KeychainIntentServiceHandler serviceHandler = new KeychainIntentServiceHandler( + ServiceProgressHandler serviceHandler = new ServiceProgressHandler( getActivity(), - getString(R.string.progress_importing), + getString(R.string.progress_updating), ProgressDialog.STYLE_HORIZONTAL, - true) { + true, + ProgressDialogFragment.ServiceType.CLOUD_IMPORT) { public void handleMessage(Message message) { // handle messages by standard KeychainIntentServiceHandler first super.handleMessage(message); @@ -613,15 +614,13 @@ public class KeyListFragment extends LoaderFragment return; } - result.createNotify(KeyListFragment.this.getActivity()).show(); + result.createNotify(getActivity()).show(); } } }; // Send all information needed to service to query keys in other thread - Intent intent = new Intent(getActivity(), KeychainIntentService.class); - - intent.setAction(KeychainIntentService.ACTION_IMPORT_KEYRING); + Intent intent = new Intent(getActivity(), CloudImportService.class); // fill values for this action Bundle data = new Bundle(); @@ -631,16 +630,16 @@ public class KeyListFragment extends LoaderFragment Preferences prefs = Preferences.getPreferences(getActivity()); Preferences.CloudSearchPrefs cloudPrefs = new Preferences.CloudSearchPrefs(true, true, prefs.getPreferredKeyserver()); - data.putString(KeychainIntentService.IMPORT_KEY_SERVER, cloudPrefs.keyserver); + data.putString(CloudImportService.IMPORT_KEY_SERVER, cloudPrefs.keyserver); } - data.putParcelableArrayList(KeychainIntentService.IMPORT_KEY_LIST, keyList); + data.putParcelableArrayList(CloudImportService.IMPORT_KEY_LIST, keyList); - intent.putExtra(KeychainIntentService.EXTRA_DATA, data); + intent.putExtra(CloudImportService.EXTRA_DATA, data); // Create a new Messenger for the communication back Messenger messenger = new Messenger(serviceHandler); - intent.putExtra(KeychainIntentService.EXTRA_MESSENGER, messenger); + intent.putExtra(CloudImportService.EXTRA_MESSENGER, messenger); // show progress dialog serviceHandler.showProgressDialog(getActivity()); @@ -651,10 +650,11 @@ public class KeyListFragment extends LoaderFragment 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); 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 863aef65f..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); 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 484956e6a..0c2d8693f 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java @@ -63,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; @@ -387,7 +387,7 @@ public class ViewKeyActivity extends BaseActivity implements 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); @@ -562,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); 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/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/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); -- cgit v1.2.3 From 5bdac11ef84d9ce5990536110280d7857165cf10 Mon Sep 17 00:00:00 2001 From: JesperBK Date: Mon, 23 Mar 2015 11:17:01 +0100 Subject: Fixed issue where setting a passphrase to null later causes a NullPointerException. --- .../java/org/sufficientlysecure/keychain/ui/EncryptTextActivity.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'OpenKeychain/src/main/java') 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 c800153ae..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; } -- cgit v1.2.3 From aa3565b857d088be3d12c1fb9acf052cc6cb7720 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Mon, 23 Mar 2015 15:38:02 +0100 Subject: Fix passphrase cache not clearing all passphrases --- .../sufficientlysecure/keychain/service/PassphraseCacheService.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'OpenKeychain/src/main/java') 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); } -- cgit v1.2.3 From e2f27d0f47b5a459183f6641fdc26ced6917d93c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Mon, 23 Mar 2015 15:54:48 +0100 Subject: Pull from transifex --- .../org/sufficientlysecure/keychain/ui/HelpAboutFragment.java | 2 +- .../java/org/sufficientlysecure/keychain/ui/HelpActivity.java | 8 ++++---- .../sufficientlysecure/keychain/ui/HelpMarkdownFragment.java | 10 +++++----- 3 files changed, 10 insertions(+), 10 deletions(-) (limited to 'OpenKeychain/src/main/java') 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 912caf32f..ac4b94d64 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/HelpAboutFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/HelpAboutFragment.java @@ -47,7 +47,7 @@ public class HelpAboutFragment extends Fragment { HtmlTextView aboutTextView = (HtmlTextView) view.findViewById(R.id.help_about_text); - // load mardown from raw resource + // load markdown from raw resource try { String html = new Markdown4jProcessor().process( getActivity().getResources().openRawResource(R.raw.help_about)); 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 24136a4b8..6c3336547 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/HelpActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/HelpActivity.java @@ -64,22 +64,22 @@ public class HelpActivity extends BaseActivity { } Bundle startBundle = new Bundle(); - startBundle.putInt(HelpMarkdownFragment.ARG_MARKDOWN_FILE, R.raw.help_start); + startBundle.putInt(HelpMarkdownFragment.ARG_MARKDOWN_RES, R.raw.help_start); mTabsAdapter.addTab(HelpMarkdownFragment.class, startBundle, getString(R.string.help_tab_start)); Bundle certificationBundle = new Bundle(); - certificationBundle.putInt(HelpMarkdownFragment.ARG_MARKDOWN_FILE, R.raw.help_certification); + certificationBundle.putInt(HelpMarkdownFragment.ARG_MARKDOWN_RES, 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); + faqBundle.putInt(HelpMarkdownFragment.ARG_MARKDOWN_RES, R.raw.help_faq); mTabsAdapter.addTab(HelpMarkdownFragment.class, faqBundle, getString(R.string.help_tab_faq)); Bundle changelogBundle = new Bundle(); - changelogBundle.putInt(HelpMarkdownFragment.ARG_MARKDOWN_FILE, R.raw.help_changelog); + changelogBundle.putInt(HelpMarkdownFragment.ARG_MARKDOWN_RES, R.raw.help_changelog); mTabsAdapter.addTab(HelpMarkdownFragment.class, changelogBundle, getString(R.string.help_tab_changelog)); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/HelpMarkdownFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/HelpMarkdownFragment.java index 69ddf2e99..97d39feb1 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/HelpMarkdownFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/HelpMarkdownFragment.java @@ -38,17 +38,17 @@ public class HelpMarkdownFragment extends Fragment { private int mHtmlFile; - public static final String ARG_MARKDOWN_FILE = "htmlFile"; + public static final String ARG_MARKDOWN_RES = "htmlFile"; /** * Create a new instance of HelpHtmlFragment, providing "htmlFile" as an argument. */ - static HelpMarkdownFragment newInstance(int htmlFile) { + static HelpMarkdownFragment newInstance(int markdownRes) { HelpMarkdownFragment f = new HelpMarkdownFragment(); // Supply html raw file input as an argument. Bundle args = new Bundle(); - args.putInt(ARG_MARKDOWN_FILE, htmlFile); + args.putInt(ARG_MARKDOWN_RES, markdownRes); f.setArguments(args); return f; @@ -58,7 +58,7 @@ public class HelpMarkdownFragment extends Fragment { public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { mActivity = getActivity(); - mHtmlFile = getArguments().getInt(ARG_MARKDOWN_FILE); + mHtmlFile = getArguments().getInt(ARG_MARKDOWN_RES); ScrollView scroller = new ScrollView(mActivity); HtmlTextView text = new HtmlTextView(mActivity); @@ -70,7 +70,7 @@ public class HelpMarkdownFragment extends Fragment { scroller.addView(text); - // load mardown from raw resource + // load markdown from raw resource try { String html = new Markdown4jProcessor().process(getActivity().getResources().openRawResource(mHtmlFile)); text.setHtmlFromString(html, true); -- cgit v1.2.3