Loading k9mail/src/main/java/com/fsck/k9/mailstore/CryptoResultAnnotation.java +5 −5 Original line number Diff line number Diff line Loading @@ -57,12 +57,12 @@ public final class CryptoResultAnnotation { public static CryptoResultAnnotation createOpenPgpResultAnnotation(OpenPgpDecryptionResult decryptionResult, OpenPgpSignatureResult signatureResult, PendingIntent pendingIntent, MimeBodyPart replacementPart) { return new CryptoResultAnnotation(CryptoError.NONE, replacementPart, return new CryptoResultAnnotation(CryptoError.OPENPGP_OK, replacementPart, decryptionResult, signatureResult, pendingIntent, null); } public static CryptoResultAnnotation createErrorAnnotation(CryptoError error, MimeBodyPart replacementData) { if (error == CryptoError.NONE) { if (error == CryptoError.OPENPGP_OK) { throw new AssertionError("CryptoError must be actual error state!"); } return new CryptoResultAnnotation(error, replacementData, null, null, null, null); Loading Loading @@ -134,11 +134,11 @@ public final class CryptoResultAnnotation { public enum CryptoError { NONE, OPENPGP_OK, OPENPGP_UI_CANCELED, OPENPGP_API_RETURNED_ERROR, SIGNED_BUT_INCOMPLETE, ENCRYPTED_BUT_INCOMPLETE, OPENPGP_SIGNED_BUT_INCOMPLETE, OPENPGP_ENCRYPTED_BUT_INCOMPLETE, SIGNED_BUT_UNSUPPORTED, ENCRYPTED_BUT_UNSUPPORTED, } Loading k9mail/src/main/java/com/fsck/k9/ui/crypto/MessageCryptoHelper.java +2 −2 Original line number Diff line number Diff line Loading @@ -123,7 +123,7 @@ public class MessageCryptoHelper { private void processFoundEncryptedParts(List<Part> foundParts) { for (Part part : foundParts) { if (!MessageHelper.isCompletePartAvailable(part)) { addErrorAnnotation(part, CryptoError.ENCRYPTED_BUT_INCOMPLETE, MessageHelper.createEmptyPart()); addErrorAnnotation(part, CryptoError.OPENPGP_ENCRYPTED_BUT_INCOMPLETE, MessageHelper.createEmptyPart()); continue; } if (MessageDecryptVerifier.isPgpMimeEncryptedOrSignedPart(part)) { Loading @@ -139,7 +139,7 @@ public class MessageCryptoHelper { for (Part part : foundParts) { if (!MessageHelper.isCompletePartAvailable(part)) { MimeBodyPart replacementPart = getMultipartSignedContentPartIfAvailable(part); addErrorAnnotation(part, CryptoError.SIGNED_BUT_INCOMPLETE, replacementPart); addErrorAnnotation(part, CryptoError.OPENPGP_SIGNED_BUT_INCOMPLETE, replacementPart); continue; } if (MessageDecryptVerifier.isPgpMimeEncryptedOrSignedPart(part)) { Loading k9mail/src/main/java/com/fsck/k9/ui/messageview/AttachmentView.java +0 −1 Original line number Diff line number Diff line Loading @@ -15,7 +15,6 @@ import com.bumptech.glide.Glide; import com.fsck.k9.K9; import com.fsck.k9.R; import com.fsck.k9.helper.SizeFormatter; import com.fsck.k9.mail.MessagingException; import com.fsck.k9.mailstore.AttachmentViewInfo; Loading k9mail/src/main/java/com/fsck/k9/ui/messageview/MessageCryptoPresenter.java +25 −1 Original line number Diff line number Diff line Loading @@ -3,10 +3,15 @@ package com.fsck.k9.ui.messageview; import android.app.Activity; import android.app.PendingIntent; import android.content.Context; import android.content.Intent; import android.content.IntentSender; import android.content.pm.PackageManager.NameNotFoundException; import android.graphics.drawable.Drawable; import android.support.annotation.Nullable; import android.util.Log; import com.fsck.k9.Account; import com.fsck.k9.K9; import com.fsck.k9.mailstore.MessageViewInfo; import com.fsck.k9.view.MessageCryptoDisplayStatus; Loading @@ -16,7 +21,8 @@ public class MessageCryptoPresenter implements OnCryptoClickListener { public static final int REQUEST_CODE_UNKNOWN_KEY = 123; MessageCryptoMvpView messageCryptoMvpView; private final MessageCryptoMvpView messageCryptoMvpView; private MessageViewInfo messageViewInfo; Loading Loading @@ -90,6 +96,24 @@ public class MessageCryptoPresenter implements OnCryptoClickListener { } } public void onClickRetryCryptoOperation() { messageCryptoMvpView.restartMessageCryptoProcessing(); } @Nullable // TODO this isn't really very presenter-like, but it works for now public static Drawable getOpenPgpApiProviderIcon(Context context, Account account) { try { String openPgpProvider = account.getOpenPgpProvider(); if (Account.NO_OPENPGP_PROVIDER.equals(openPgpProvider)) { return null; } return context.getPackageManager().getApplicationIcon(openPgpProvider); } catch (NameNotFoundException e) { return null; } } public interface MessageCryptoMvpView { void restartMessageCryptoProcessing(); Loading k9mail/src/main/java/com/fsck/k9/ui/messageview/MessageTopView.java +100 −10 Original line number Diff line number Diff line Loading @@ -8,12 +8,14 @@ import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.animation.ObjectAnimator; import android.content.Context; import android.graphics.drawable.Drawable; import android.util.AttributeSet; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.Button; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.ProgressBar; import android.widget.TextView; Loading @@ -28,7 +30,6 @@ import com.fsck.k9.mail.Flag; import com.fsck.k9.mail.Message; import com.fsck.k9.mail.MessagingException; import com.fsck.k9.mailstore.MessageViewInfo; import com.fsck.k9.view.MessageHeader; import com.fsck.k9.ui.messageview.MessageContainerView.OnRenderingFinishedListener; import com.fsck.k9.view.MessageCryptoDisplayStatus; import com.fsck.k9.view.MessageHeader; Loading @@ -36,12 +37,13 @@ import com.fsck.k9.view.ToolableViewAnimator; import org.openintents.openpgp.OpenPgpError; public class MessageTopView extends LinearLayout implements ShowPicturesController, OnRenderingFinishedListener { public class MessageTopView extends LinearLayout implements ShowPicturesController { public static final int PROGRESS_MAX = 1000; public static final int PROGRESS_MAX_WITH_MARGIN = 950; public static final int PROGRESS_STEP_DURATION = 180; private ToolableViewAnimator viewAnimator; private ProgressBar progressBar; private TextView progressText; Loading Loading @@ -107,25 +109,114 @@ public class MessageTopView extends LinearLayout implements ShowPicturesControll containerView.removeAllViews(); } public void setMessage(Account account, MessageViewInfo messageViewInfo) throws MessagingException { public void setMessage(Account account, MessageViewInfo messageViewInfo) throws MessagingException { resetView(); MessageCryptoDisplayStatus displayStatus = MessageCryptoDisplayStatus.fromResultAnnotation(messageViewInfo.cryptoResultAnnotation); mHeaderContainer.setCryptoStatus(displayStatus); switch (displayStatus) { case DISABLED: case INCOMPLETE_SIGNED: case UNSUPPORTED_SIGNED: default: { // in most cases, we simply display the message showMessageContentView(account, messageViewInfo); break; } case CANCELLED: { showMessageCryptoCancelledView(account); break; } case INCOMPLETE_ENCRYPTED: { showEncryptedButIncompleteView(account); break; } case ENCRYPTED_ERROR: case UNSUPPORTED_ENCRYPTED: { showMessageCryptoErrorView(account, messageViewInfo); break; } case LOADING: { throw new IllegalStateException("Displaying message while in loading state!"); } } } private void showEncryptedButIncompleteView(Account account) { View view = mInflater.inflate(R.layout.message_content_crypto_incomplete, containerView, false); ImageView cryptoProviderIcon = (ImageView) view.findViewById(R.id.crypto_error_icon); setCryptoProviderIcon(account, cryptoProviderIcon); containerView.addView(view); displayViewOnLoadFinished(false); } private void showMessageContentView(Account account, MessageViewInfo messageViewInfo) throws MessagingException { ShowPictures showPicturesSetting = account.getShowPictures(); boolean automaticallyLoadPictures = shouldAutomaticallyLoadPictures(showPicturesSetting, messageViewInfo.message); MessageContainerView view = (MessageContainerView) mInflater.inflate(R.layout.message_container, containerView, false); view.displayMessageViewContainer(messageViewInfo, this, automaticallyLoadPictures, this, attachmentCallback); containerView.addView(view); view.displayMessageViewContainer(messageViewInfo, new OnRenderingFinishedListener() { @Override public void onLoadFinished() { displayViewOnLoadFinished(true); } }, automaticallyLoadPictures, this, attachmentCallback); } private void showMessageCryptoErrorView(Account account, MessageViewInfo messageViewInfo) { View view = mInflater.inflate(R.layout.message_content_crypto_error, containerView, false); ImageView cryptoProviderIcon = (ImageView) view.findViewById(R.id.crypto_error_icon); setCryptoProviderIcon(account, cryptoProviderIcon); TextView cryptoErrorText = (TextView) view.findViewById(R.id.crypto_error_text); OpenPgpError openPgpError = messageViewInfo.cryptoResultAnnotation.getOpenPgpError(); if (openPgpError != null) { String errorText = openPgpError.getMessage(); cryptoErrorText.setText(errorText); } boolean displayPgpHeader = account.isOpenPgpProviderConfigured(); if (displayPgpHeader) { mHeaderContainer.setCryptoStatus(messageViewInfo.cryptoResultAnnotation); containerView.addView(view); displayViewOnLoadFinished(false); } private void showMessageCryptoCancelledView(Account account) { View view = mInflater.inflate(R.layout.message_content_crypto_cancelled, containerView, false); view.findViewById(R.id.crypto_cancelled_retry).setOnClickListener(new OnClickListener() { @Override public void onClick(View view) { messageCryptoPresenter.onClickRetryCryptoOperation(); } }); ImageView cryptoProviderIcon = (ImageView) view.findViewById(R.id.crypto_error_icon); setCryptoProviderIcon(account, cryptoProviderIcon); containerView.addView(view); displayViewOnLoadFinished(false); } private void setCryptoProviderIcon(Account account, ImageView cryptoProviderIcon) { Drawable openPgpApiProviderIcon = MessageCryptoPresenter.getOpenPgpApiProviderIcon(getContext(), account); if (openPgpApiProviderIcon != null) { cryptoProviderIcon.setImageDrawable(openPgpApiProviderIcon); } else { cryptoProviderIcon.setImageResource(R.drawable.status_lock_error); cryptoProviderIcon.setColorFilter(getResources().getColor(R.color.openpgp_red)); } } /** Loading @@ -141,8 +232,7 @@ public class MessageTopView extends LinearLayout implements ShowPicturesControll try { mHeaderContainer.populate(message, account); if (account.isOpenPgpProviderConfigured()) { // TODO show loading icon // mHeaderContainer.setCryptoStatus(MessageCryptoDisplayStatus.LOADING); mHeaderContainer.setCryptoStatus(MessageCryptoDisplayStatus.LOADING); } mHeaderContainer.setVisibility(View.VISIBLE); Loading Loading
k9mail/src/main/java/com/fsck/k9/mailstore/CryptoResultAnnotation.java +5 −5 Original line number Diff line number Diff line Loading @@ -57,12 +57,12 @@ public final class CryptoResultAnnotation { public static CryptoResultAnnotation createOpenPgpResultAnnotation(OpenPgpDecryptionResult decryptionResult, OpenPgpSignatureResult signatureResult, PendingIntent pendingIntent, MimeBodyPart replacementPart) { return new CryptoResultAnnotation(CryptoError.NONE, replacementPart, return new CryptoResultAnnotation(CryptoError.OPENPGP_OK, replacementPart, decryptionResult, signatureResult, pendingIntent, null); } public static CryptoResultAnnotation createErrorAnnotation(CryptoError error, MimeBodyPart replacementData) { if (error == CryptoError.NONE) { if (error == CryptoError.OPENPGP_OK) { throw new AssertionError("CryptoError must be actual error state!"); } return new CryptoResultAnnotation(error, replacementData, null, null, null, null); Loading Loading @@ -134,11 +134,11 @@ public final class CryptoResultAnnotation { public enum CryptoError { NONE, OPENPGP_OK, OPENPGP_UI_CANCELED, OPENPGP_API_RETURNED_ERROR, SIGNED_BUT_INCOMPLETE, ENCRYPTED_BUT_INCOMPLETE, OPENPGP_SIGNED_BUT_INCOMPLETE, OPENPGP_ENCRYPTED_BUT_INCOMPLETE, SIGNED_BUT_UNSUPPORTED, ENCRYPTED_BUT_UNSUPPORTED, } Loading
k9mail/src/main/java/com/fsck/k9/ui/crypto/MessageCryptoHelper.java +2 −2 Original line number Diff line number Diff line Loading @@ -123,7 +123,7 @@ public class MessageCryptoHelper { private void processFoundEncryptedParts(List<Part> foundParts) { for (Part part : foundParts) { if (!MessageHelper.isCompletePartAvailable(part)) { addErrorAnnotation(part, CryptoError.ENCRYPTED_BUT_INCOMPLETE, MessageHelper.createEmptyPart()); addErrorAnnotation(part, CryptoError.OPENPGP_ENCRYPTED_BUT_INCOMPLETE, MessageHelper.createEmptyPart()); continue; } if (MessageDecryptVerifier.isPgpMimeEncryptedOrSignedPart(part)) { Loading @@ -139,7 +139,7 @@ public class MessageCryptoHelper { for (Part part : foundParts) { if (!MessageHelper.isCompletePartAvailable(part)) { MimeBodyPart replacementPart = getMultipartSignedContentPartIfAvailable(part); addErrorAnnotation(part, CryptoError.SIGNED_BUT_INCOMPLETE, replacementPart); addErrorAnnotation(part, CryptoError.OPENPGP_SIGNED_BUT_INCOMPLETE, replacementPart); continue; } if (MessageDecryptVerifier.isPgpMimeEncryptedOrSignedPart(part)) { Loading
k9mail/src/main/java/com/fsck/k9/ui/messageview/AttachmentView.java +0 −1 Original line number Diff line number Diff line Loading @@ -15,7 +15,6 @@ import com.bumptech.glide.Glide; import com.fsck.k9.K9; import com.fsck.k9.R; import com.fsck.k9.helper.SizeFormatter; import com.fsck.k9.mail.MessagingException; import com.fsck.k9.mailstore.AttachmentViewInfo; Loading
k9mail/src/main/java/com/fsck/k9/ui/messageview/MessageCryptoPresenter.java +25 −1 Original line number Diff line number Diff line Loading @@ -3,10 +3,15 @@ package com.fsck.k9.ui.messageview; import android.app.Activity; import android.app.PendingIntent; import android.content.Context; import android.content.Intent; import android.content.IntentSender; import android.content.pm.PackageManager.NameNotFoundException; import android.graphics.drawable.Drawable; import android.support.annotation.Nullable; import android.util.Log; import com.fsck.k9.Account; import com.fsck.k9.K9; import com.fsck.k9.mailstore.MessageViewInfo; import com.fsck.k9.view.MessageCryptoDisplayStatus; Loading @@ -16,7 +21,8 @@ public class MessageCryptoPresenter implements OnCryptoClickListener { public static final int REQUEST_CODE_UNKNOWN_KEY = 123; MessageCryptoMvpView messageCryptoMvpView; private final MessageCryptoMvpView messageCryptoMvpView; private MessageViewInfo messageViewInfo; Loading Loading @@ -90,6 +96,24 @@ public class MessageCryptoPresenter implements OnCryptoClickListener { } } public void onClickRetryCryptoOperation() { messageCryptoMvpView.restartMessageCryptoProcessing(); } @Nullable // TODO this isn't really very presenter-like, but it works for now public static Drawable getOpenPgpApiProviderIcon(Context context, Account account) { try { String openPgpProvider = account.getOpenPgpProvider(); if (Account.NO_OPENPGP_PROVIDER.equals(openPgpProvider)) { return null; } return context.getPackageManager().getApplicationIcon(openPgpProvider); } catch (NameNotFoundException e) { return null; } } public interface MessageCryptoMvpView { void restartMessageCryptoProcessing(); Loading
k9mail/src/main/java/com/fsck/k9/ui/messageview/MessageTopView.java +100 −10 Original line number Diff line number Diff line Loading @@ -8,12 +8,14 @@ import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.animation.ObjectAnimator; import android.content.Context; import android.graphics.drawable.Drawable; import android.util.AttributeSet; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.Button; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.ProgressBar; import android.widget.TextView; Loading @@ -28,7 +30,6 @@ import com.fsck.k9.mail.Flag; import com.fsck.k9.mail.Message; import com.fsck.k9.mail.MessagingException; import com.fsck.k9.mailstore.MessageViewInfo; import com.fsck.k9.view.MessageHeader; import com.fsck.k9.ui.messageview.MessageContainerView.OnRenderingFinishedListener; import com.fsck.k9.view.MessageCryptoDisplayStatus; import com.fsck.k9.view.MessageHeader; Loading @@ -36,12 +37,13 @@ import com.fsck.k9.view.ToolableViewAnimator; import org.openintents.openpgp.OpenPgpError; public class MessageTopView extends LinearLayout implements ShowPicturesController, OnRenderingFinishedListener { public class MessageTopView extends LinearLayout implements ShowPicturesController { public static final int PROGRESS_MAX = 1000; public static final int PROGRESS_MAX_WITH_MARGIN = 950; public static final int PROGRESS_STEP_DURATION = 180; private ToolableViewAnimator viewAnimator; private ProgressBar progressBar; private TextView progressText; Loading Loading @@ -107,25 +109,114 @@ public class MessageTopView extends LinearLayout implements ShowPicturesControll containerView.removeAllViews(); } public void setMessage(Account account, MessageViewInfo messageViewInfo) throws MessagingException { public void setMessage(Account account, MessageViewInfo messageViewInfo) throws MessagingException { resetView(); MessageCryptoDisplayStatus displayStatus = MessageCryptoDisplayStatus.fromResultAnnotation(messageViewInfo.cryptoResultAnnotation); mHeaderContainer.setCryptoStatus(displayStatus); switch (displayStatus) { case DISABLED: case INCOMPLETE_SIGNED: case UNSUPPORTED_SIGNED: default: { // in most cases, we simply display the message showMessageContentView(account, messageViewInfo); break; } case CANCELLED: { showMessageCryptoCancelledView(account); break; } case INCOMPLETE_ENCRYPTED: { showEncryptedButIncompleteView(account); break; } case ENCRYPTED_ERROR: case UNSUPPORTED_ENCRYPTED: { showMessageCryptoErrorView(account, messageViewInfo); break; } case LOADING: { throw new IllegalStateException("Displaying message while in loading state!"); } } } private void showEncryptedButIncompleteView(Account account) { View view = mInflater.inflate(R.layout.message_content_crypto_incomplete, containerView, false); ImageView cryptoProviderIcon = (ImageView) view.findViewById(R.id.crypto_error_icon); setCryptoProviderIcon(account, cryptoProviderIcon); containerView.addView(view); displayViewOnLoadFinished(false); } private void showMessageContentView(Account account, MessageViewInfo messageViewInfo) throws MessagingException { ShowPictures showPicturesSetting = account.getShowPictures(); boolean automaticallyLoadPictures = shouldAutomaticallyLoadPictures(showPicturesSetting, messageViewInfo.message); MessageContainerView view = (MessageContainerView) mInflater.inflate(R.layout.message_container, containerView, false); view.displayMessageViewContainer(messageViewInfo, this, automaticallyLoadPictures, this, attachmentCallback); containerView.addView(view); view.displayMessageViewContainer(messageViewInfo, new OnRenderingFinishedListener() { @Override public void onLoadFinished() { displayViewOnLoadFinished(true); } }, automaticallyLoadPictures, this, attachmentCallback); } private void showMessageCryptoErrorView(Account account, MessageViewInfo messageViewInfo) { View view = mInflater.inflate(R.layout.message_content_crypto_error, containerView, false); ImageView cryptoProviderIcon = (ImageView) view.findViewById(R.id.crypto_error_icon); setCryptoProviderIcon(account, cryptoProviderIcon); TextView cryptoErrorText = (TextView) view.findViewById(R.id.crypto_error_text); OpenPgpError openPgpError = messageViewInfo.cryptoResultAnnotation.getOpenPgpError(); if (openPgpError != null) { String errorText = openPgpError.getMessage(); cryptoErrorText.setText(errorText); } boolean displayPgpHeader = account.isOpenPgpProviderConfigured(); if (displayPgpHeader) { mHeaderContainer.setCryptoStatus(messageViewInfo.cryptoResultAnnotation); containerView.addView(view); displayViewOnLoadFinished(false); } private void showMessageCryptoCancelledView(Account account) { View view = mInflater.inflate(R.layout.message_content_crypto_cancelled, containerView, false); view.findViewById(R.id.crypto_cancelled_retry).setOnClickListener(new OnClickListener() { @Override public void onClick(View view) { messageCryptoPresenter.onClickRetryCryptoOperation(); } }); ImageView cryptoProviderIcon = (ImageView) view.findViewById(R.id.crypto_error_icon); setCryptoProviderIcon(account, cryptoProviderIcon); containerView.addView(view); displayViewOnLoadFinished(false); } private void setCryptoProviderIcon(Account account, ImageView cryptoProviderIcon) { Drawable openPgpApiProviderIcon = MessageCryptoPresenter.getOpenPgpApiProviderIcon(getContext(), account); if (openPgpApiProviderIcon != null) { cryptoProviderIcon.setImageDrawable(openPgpApiProviderIcon); } else { cryptoProviderIcon.setImageResource(R.drawable.status_lock_error); cryptoProviderIcon.setColorFilter(getResources().getColor(R.color.openpgp_red)); } } /** Loading @@ -141,8 +232,7 @@ public class MessageTopView extends LinearLayout implements ShowPicturesControll try { mHeaderContainer.populate(message, account); if (account.isOpenPgpProviderConfigured()) { // TODO show loading icon // mHeaderContainer.setCryptoStatus(MessageCryptoDisplayStatus.LOADING); mHeaderContainer.setCryptoStatus(MessageCryptoDisplayStatus.LOADING); } mHeaderContainer.setVisibility(View.VISIBLE); Loading