Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 58daf685 authored by Vincent Breitmoser's avatar Vincent Breitmoser Committed by Vincent Breitmoser
Browse files

messageview: handle crypto error states

parent c12ce959
Loading
Loading
Loading
Loading
+5 −5
Original line number Diff line number Diff line
@@ -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);
@@ -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,
    }
+2 −2
Original line number Diff line number Diff line
@@ -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)) {
@@ -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)) {
+0 −1
Original line number Diff line number Diff line
@@ -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;


+25 −1
Original line number Diff line number Diff line
@@ -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;
@@ -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;

@@ -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();

+100 −10
Original line number Diff line number Diff line
@@ -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;
@@ -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;
@@ -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;
@@ -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));
        }
    }

    /**
@@ -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