Loading k9mail/src/main/java/com/fsck/k9/ui/crypto/MessageCryptoCallback.java +1 −1 Original line number Diff line number Diff line Loading @@ -9,5 +9,5 @@ public interface MessageCryptoCallback { void onCryptoHelperProgress(int current, int max); void onCryptoOperationsFinished(MessageCryptoAnnotations annotations); void startPendingIntentForCryptoHelper(IntentSender si, int requestCode, Intent fillIntent, int flagsMask, int flagValues, int extraFlags) throws IntentSender.SendIntentException; int flagsMask, int flagValues, int extraFlags); } k9mail/src/main/java/com/fsck/k9/ui/crypto/MessageCryptoHelper.java +73 −25 Original line number Diff line number Diff line Loading @@ -13,7 +13,6 @@ import android.app.Activity; import android.app.PendingIntent; import android.content.Context; import android.content.Intent; import android.content.IntentSender.SendIntentException; import android.support.annotation.Nullable; import android.support.annotation.WorkerThread; import android.util.Log; Loading Loading @@ -58,8 +57,9 @@ public class MessageCryptoHelper { private final Context context; private final MessageCryptoCallback callback; private final Account account; private final String openPgpProviderPackage; @Nullable private MessageCryptoCallback callback; private Deque<CryptoPart> partsToDecryptOrVerify = new ArrayDeque<>(); private OpenPgpApi openPgpApi; Loading @@ -71,21 +71,23 @@ public class MessageCryptoHelper { private LocalMessage currentMessage; private boolean secondPassStarted; private CancelableBackgroundOperation cancelableBackgroundOperation; private PendingIntent queuedPendingIntent; private MessageCryptoAnnotations queuedMessageAnnotations; private boolean isCancelled; public MessageCryptoHelper(Activity activity, Account account, MessageCryptoCallback callback) { this.context = activity.getApplicationContext(); public MessageCryptoHelper(Context context, String openPgpProviderPackage, @Nullable MessageCryptoCallback callback) { this.context = context.getApplicationContext(); this.callback = callback; this.account = account; } this.openPgpProviderPackage = openPgpProviderPackage; public void decryptOrVerifyMessagePartsIfNecessary(LocalMessage message) { if (!account.isOpenPgpProviderConfigured()) { returnResultToFragment(); return; if (openPgpProviderPackage == null || Account.NO_OPENPGP_PROVIDER.equals(openPgpProviderPackage)) { throw new IllegalStateException("MessageCryptoHelper must only be called with a openpgp provider!"); } } public void decryptOrVerifyMessagePartsIfNecessary(LocalMessage message) { this.messageAnnotations = new MessageCryptoAnnotations(); this.currentMessage = message; Loading Loading @@ -180,8 +182,7 @@ public class MessageCryptoHelper { } private void connectToCryptoProviderService() { String openPgpProvider = account.getOpenPgpProvider(); new OpenPgpServiceConnection(context, openPgpProvider, new OpenPgpServiceConnection(context, openPgpProviderPackage, new OnBound() { @Override public void onBound(IOpenPgpService2 service) { Loading Loading @@ -244,7 +245,7 @@ public class MessageCryptoHelper { @Override public void onProgress(int current, int max) { Log.d(K9.LOG_TAG, "received progress status: " + current + " / " + max); callback.onCryptoHelperProgress(current, max); callbackProgress(current, max); } @Override Loading Loading @@ -295,7 +296,7 @@ public class MessageCryptoHelper { @Override public void onProgress(int current, int max) { Log.d(K9.LOG_TAG, "received progress status: " + current + " / " + max); callback.onCryptoHelperProgress(current, max); callbackProgress(current, max); } }); } Loading @@ -316,7 +317,7 @@ public class MessageCryptoHelper { @Override public void onProgress(int current, int max) { Log.d(K9.LOG_TAG, "received progress status: " + current + " / " + max); callback.onCryptoHelperProgress(current, max); callbackProgress(current, max); } }); } Loading Loading @@ -447,12 +448,7 @@ public class MessageCryptoHelper { throw new AssertionError("Expecting PendingIntent on USER_INTERACTION_REQUIRED!"); } try { callback.startPendingIntentForCryptoHelper( pendingIntent.getIntentSender(), REQUEST_CODE_USER_INTERACTION, null, 0, 0, 0); } catch (SendIntentException e) { Log.e(K9.LOG_TAG, "Internal error on starting pendingintent!", e); } callbackPendingIntent(pendingIntent); } private void handleCryptoOperationError() { Loading Loading @@ -535,15 +531,67 @@ public class MessageCryptoHelper { private void runSecondPassOrReturnResultToFragment() { if (secondPassStarted) { callback.onCryptoOperationsFinished(messageAnnotations); callbackReturnResult(); return; } secondPassStarted = true; runSecondPass(); } private void returnResultToFragment() { callback.onCryptoOperationsFinished(messageAnnotations); private final Object callbackLock = new Object(); public void detachCallback() { synchronized (callbackLock) { callback = null; } } public void reattachCallback(MessageCryptoCallback callback) { synchronized (callbackLock) { this.callback = callback; deliverResult(); } } private void callbackPendingIntent(PendingIntent pendingIntent) { synchronized (callbackLock) { queuedPendingIntent = pendingIntent; deliverResult(); } } private void callbackReturnResult() { synchronized (callbackLock) { queuedMessageAnnotations = messageAnnotations; deliverResult(); } } private void callbackProgress(int current, int max) { synchronized (callbackLock) { if (callback != null) { callback.onCryptoHelperProgress(current, max); } } } // This method must only be called inside a synchronized(callbackLock) block! private void deliverResult() { if (isCancelled) { return; } if (callback == null) { Log.d(K9.LOG_TAG, "Keeping crypto helper result in queue for later delivery"); return; } if (queuedMessageAnnotations != null) { callback.onCryptoOperationsFinished(queuedMessageAnnotations); } else if (queuedPendingIntent != null) { callback.startPendingIntentForCryptoHelper( queuedPendingIntent.getIntentSender(), REQUEST_CODE_USER_INTERACTION, null, 0, 0, 0); queuedPendingIntent = null; } } private static class CryptoPart { Loading k9mail/src/main/java/com/fsck/k9/ui/messageview/MessageViewFragment.java +19 −12 Original line number Diff line number Diff line Loading @@ -200,10 +200,7 @@ public class MessageViewFragment extends Fragment implements ConfirmationDialogF Log.d(K9.LOG_TAG, "MessageView displaying message " + mMessageReference); } Activity activity = getActivity(); Context appContext = activity.getApplicationContext(); mAccount = Preferences.getPreferences(appContext).getAccount(mMessageReference.getAccountUuid()); messageCryptoHelper = new MessageCryptoHelper(activity, mAccount, this); mAccount = Preferences.getPreferences(getApplicationContext()).getAccount(mMessageReference.getAccountUuid()); startLoadingMessageFromDatabase(); Loading Loading @@ -245,14 +242,20 @@ public class MessageViewFragment extends Fragment implements ConfirmationDialogF @UiThread private void onLoadMessageFromDatabaseFinished(LocalMessage message) { displayMessageHeader(message); mMessageView.setToLoadingState(); if (message.isBodyMissing()) { startDownloadingMessageBody(); } else { return; } if (mAccount.isOpenPgpProviderConfigured()) { messageCryptoHelper = new MessageCryptoHelper(getActivity(), mAccount.getOpenPgpProvider(), this); messageCryptoHelper.decryptOrVerifyMessagePartsIfNecessary(message); return; } startExtractingTextAndAttachments(); } private void onLoadMessageFromDatabaseFailed() { Loading Loading @@ -292,11 +295,11 @@ public class MessageViewFragment extends Fragment implements ConfirmationDialogF @Override public void onCryptoOperationsFinished(MessageCryptoAnnotations annotations) { startExtractingTextAndAttachments(annotations); this.messageAnnotations = annotations; startExtractingTextAndAttachments(); } private void startExtractingTextAndAttachments(MessageCryptoAnnotations annotations) { this.messageAnnotations = annotations; private void startExtractingTextAndAttachments() { getLoaderManager().restartLoader(DECODE_MESSAGE_LOADER_ID, null, decodeMessageLoaderCallback); } Loading Loading @@ -753,10 +756,14 @@ public class MessageViewFragment extends Fragment implements ConfirmationDialogF @Override public void startPendingIntentForCryptoHelper(IntentSender si, int requestCode, Intent fillIntent, int flagsMask, int flagValues, int extraFlags) throws SendIntentException { int flagsMask, int flagValues, int extraFlags) { requestCode |= REQUEST_MASK_CRYPTO_HELPER; try { getActivity().startIntentSenderForResult( si, requestCode, fillIntent, flagsMask, flagValues, extraFlags); } catch (SendIntentException e) { Log.e(K9.LOG_TAG, "Irrecoverable error calling PendingIntent!", e); } } public interface MessageViewFragmentListener { Loading Loading
k9mail/src/main/java/com/fsck/k9/ui/crypto/MessageCryptoCallback.java +1 −1 Original line number Diff line number Diff line Loading @@ -9,5 +9,5 @@ public interface MessageCryptoCallback { void onCryptoHelperProgress(int current, int max); void onCryptoOperationsFinished(MessageCryptoAnnotations annotations); void startPendingIntentForCryptoHelper(IntentSender si, int requestCode, Intent fillIntent, int flagsMask, int flagValues, int extraFlags) throws IntentSender.SendIntentException; int flagsMask, int flagValues, int extraFlags); }
k9mail/src/main/java/com/fsck/k9/ui/crypto/MessageCryptoHelper.java +73 −25 Original line number Diff line number Diff line Loading @@ -13,7 +13,6 @@ import android.app.Activity; import android.app.PendingIntent; import android.content.Context; import android.content.Intent; import android.content.IntentSender.SendIntentException; import android.support.annotation.Nullable; import android.support.annotation.WorkerThread; import android.util.Log; Loading Loading @@ -58,8 +57,9 @@ public class MessageCryptoHelper { private final Context context; private final MessageCryptoCallback callback; private final Account account; private final String openPgpProviderPackage; @Nullable private MessageCryptoCallback callback; private Deque<CryptoPart> partsToDecryptOrVerify = new ArrayDeque<>(); private OpenPgpApi openPgpApi; Loading @@ -71,21 +71,23 @@ public class MessageCryptoHelper { private LocalMessage currentMessage; private boolean secondPassStarted; private CancelableBackgroundOperation cancelableBackgroundOperation; private PendingIntent queuedPendingIntent; private MessageCryptoAnnotations queuedMessageAnnotations; private boolean isCancelled; public MessageCryptoHelper(Activity activity, Account account, MessageCryptoCallback callback) { this.context = activity.getApplicationContext(); public MessageCryptoHelper(Context context, String openPgpProviderPackage, @Nullable MessageCryptoCallback callback) { this.context = context.getApplicationContext(); this.callback = callback; this.account = account; } this.openPgpProviderPackage = openPgpProviderPackage; public void decryptOrVerifyMessagePartsIfNecessary(LocalMessage message) { if (!account.isOpenPgpProviderConfigured()) { returnResultToFragment(); return; if (openPgpProviderPackage == null || Account.NO_OPENPGP_PROVIDER.equals(openPgpProviderPackage)) { throw new IllegalStateException("MessageCryptoHelper must only be called with a openpgp provider!"); } } public void decryptOrVerifyMessagePartsIfNecessary(LocalMessage message) { this.messageAnnotations = new MessageCryptoAnnotations(); this.currentMessage = message; Loading Loading @@ -180,8 +182,7 @@ public class MessageCryptoHelper { } private void connectToCryptoProviderService() { String openPgpProvider = account.getOpenPgpProvider(); new OpenPgpServiceConnection(context, openPgpProvider, new OpenPgpServiceConnection(context, openPgpProviderPackage, new OnBound() { @Override public void onBound(IOpenPgpService2 service) { Loading Loading @@ -244,7 +245,7 @@ public class MessageCryptoHelper { @Override public void onProgress(int current, int max) { Log.d(K9.LOG_TAG, "received progress status: " + current + " / " + max); callback.onCryptoHelperProgress(current, max); callbackProgress(current, max); } @Override Loading Loading @@ -295,7 +296,7 @@ public class MessageCryptoHelper { @Override public void onProgress(int current, int max) { Log.d(K9.LOG_TAG, "received progress status: " + current + " / " + max); callback.onCryptoHelperProgress(current, max); callbackProgress(current, max); } }); } Loading @@ -316,7 +317,7 @@ public class MessageCryptoHelper { @Override public void onProgress(int current, int max) { Log.d(K9.LOG_TAG, "received progress status: " + current + " / " + max); callback.onCryptoHelperProgress(current, max); callbackProgress(current, max); } }); } Loading Loading @@ -447,12 +448,7 @@ public class MessageCryptoHelper { throw new AssertionError("Expecting PendingIntent on USER_INTERACTION_REQUIRED!"); } try { callback.startPendingIntentForCryptoHelper( pendingIntent.getIntentSender(), REQUEST_CODE_USER_INTERACTION, null, 0, 0, 0); } catch (SendIntentException e) { Log.e(K9.LOG_TAG, "Internal error on starting pendingintent!", e); } callbackPendingIntent(pendingIntent); } private void handleCryptoOperationError() { Loading Loading @@ -535,15 +531,67 @@ public class MessageCryptoHelper { private void runSecondPassOrReturnResultToFragment() { if (secondPassStarted) { callback.onCryptoOperationsFinished(messageAnnotations); callbackReturnResult(); return; } secondPassStarted = true; runSecondPass(); } private void returnResultToFragment() { callback.onCryptoOperationsFinished(messageAnnotations); private final Object callbackLock = new Object(); public void detachCallback() { synchronized (callbackLock) { callback = null; } } public void reattachCallback(MessageCryptoCallback callback) { synchronized (callbackLock) { this.callback = callback; deliverResult(); } } private void callbackPendingIntent(PendingIntent pendingIntent) { synchronized (callbackLock) { queuedPendingIntent = pendingIntent; deliverResult(); } } private void callbackReturnResult() { synchronized (callbackLock) { queuedMessageAnnotations = messageAnnotations; deliverResult(); } } private void callbackProgress(int current, int max) { synchronized (callbackLock) { if (callback != null) { callback.onCryptoHelperProgress(current, max); } } } // This method must only be called inside a synchronized(callbackLock) block! private void deliverResult() { if (isCancelled) { return; } if (callback == null) { Log.d(K9.LOG_TAG, "Keeping crypto helper result in queue for later delivery"); return; } if (queuedMessageAnnotations != null) { callback.onCryptoOperationsFinished(queuedMessageAnnotations); } else if (queuedPendingIntent != null) { callback.startPendingIntentForCryptoHelper( queuedPendingIntent.getIntentSender(), REQUEST_CODE_USER_INTERACTION, null, 0, 0, 0); queuedPendingIntent = null; } } private static class CryptoPart { Loading
k9mail/src/main/java/com/fsck/k9/ui/messageview/MessageViewFragment.java +19 −12 Original line number Diff line number Diff line Loading @@ -200,10 +200,7 @@ public class MessageViewFragment extends Fragment implements ConfirmationDialogF Log.d(K9.LOG_TAG, "MessageView displaying message " + mMessageReference); } Activity activity = getActivity(); Context appContext = activity.getApplicationContext(); mAccount = Preferences.getPreferences(appContext).getAccount(mMessageReference.getAccountUuid()); messageCryptoHelper = new MessageCryptoHelper(activity, mAccount, this); mAccount = Preferences.getPreferences(getApplicationContext()).getAccount(mMessageReference.getAccountUuid()); startLoadingMessageFromDatabase(); Loading Loading @@ -245,14 +242,20 @@ public class MessageViewFragment extends Fragment implements ConfirmationDialogF @UiThread private void onLoadMessageFromDatabaseFinished(LocalMessage message) { displayMessageHeader(message); mMessageView.setToLoadingState(); if (message.isBodyMissing()) { startDownloadingMessageBody(); } else { return; } if (mAccount.isOpenPgpProviderConfigured()) { messageCryptoHelper = new MessageCryptoHelper(getActivity(), mAccount.getOpenPgpProvider(), this); messageCryptoHelper.decryptOrVerifyMessagePartsIfNecessary(message); return; } startExtractingTextAndAttachments(); } private void onLoadMessageFromDatabaseFailed() { Loading Loading @@ -292,11 +295,11 @@ public class MessageViewFragment extends Fragment implements ConfirmationDialogF @Override public void onCryptoOperationsFinished(MessageCryptoAnnotations annotations) { startExtractingTextAndAttachments(annotations); this.messageAnnotations = annotations; startExtractingTextAndAttachments(); } private void startExtractingTextAndAttachments(MessageCryptoAnnotations annotations) { this.messageAnnotations = annotations; private void startExtractingTextAndAttachments() { getLoaderManager().restartLoader(DECODE_MESSAGE_LOADER_ID, null, decodeMessageLoaderCallback); } Loading Loading @@ -753,10 +756,14 @@ public class MessageViewFragment extends Fragment implements ConfirmationDialogF @Override public void startPendingIntentForCryptoHelper(IntentSender si, int requestCode, Intent fillIntent, int flagsMask, int flagValues, int extraFlags) throws SendIntentException { int flagsMask, int flagValues, int extraFlags) { requestCode |= REQUEST_MASK_CRYPTO_HELPER; try { getActivity().startIntentSenderForResult( si, requestCode, fillIntent, flagsMask, flagValues, extraFlags); } catch (SendIntentException e) { Log.e(K9.LOG_TAG, "Irrecoverable error calling PendingIntent!", e); } } public interface MessageViewFragmentListener { Loading