Merge pull request #5520 from k9mail/fix_crypto_status_icon
Fix crypto status icon
This commit is contained in:
commit
21b7d37dfc
4 changed files with 334 additions and 434 deletions
|
@ -109,12 +109,12 @@ public class CryptoInfoDialog extends DialogFragment {
|
|||
}
|
||||
|
||||
private void setMessageForDisplayStatus(MessageCryptoDisplayStatus displayStatus) {
|
||||
if (displayStatus.titleTextRes == null) {
|
||||
if (displayStatus.getTitleTextRes() == null) {
|
||||
throw new AssertionError("Crypto info dialog can only be displayed for items with text!");
|
||||
}
|
||||
|
||||
setMessageSingleLine(displayStatus.colorAttr, displayStatus.titleTextRes, displayStatus.descriptionTextRes,
|
||||
displayStatus.statusIconRes);
|
||||
setMessageSingleLine(displayStatus.getColorAttr(), displayStatus.getTitleTextRes(),
|
||||
displayStatus.getDescriptionTextRes(), displayStatus.getStatusIconRes());
|
||||
}
|
||||
|
||||
private void setMessageSingleLine(@AttrRes int colorAttr, @StringRes int titleTextRes,
|
||||
|
|
|
@ -1,415 +0,0 @@
|
|||
package com.fsck.k9.view;
|
||||
|
||||
|
||||
import androidx.annotation.AttrRes;
|
||||
import androidx.annotation.DrawableRes;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.StringRes;
|
||||
|
||||
import com.fsck.k9.ui.R;
|
||||
import com.fsck.k9.mailstore.CryptoResultAnnotation;
|
||||
import org.openintents.openpgp.OpenPgpDecryptionResult;
|
||||
import org.openintents.openpgp.OpenPgpSignatureResult;
|
||||
|
||||
|
||||
public enum MessageCryptoDisplayStatus {
|
||||
LOADING (
|
||||
false,
|
||||
R.attr.openpgp_grey,
|
||||
R.drawable.status_lock_disabled
|
||||
),
|
||||
|
||||
CANCELLED (
|
||||
R.attr.openpgp_black,
|
||||
R.drawable.status_lock_unknown,
|
||||
R.string.crypto_msg_title_encrypted_unknown,
|
||||
R.string.crypto_msg_cancelled
|
||||
),
|
||||
|
||||
DISABLED (
|
||||
false,
|
||||
R.attr.openpgp_grey,
|
||||
R.drawable.status_lock_disabled,
|
||||
R.string.crypto_msg_title_plaintext,
|
||||
null
|
||||
),
|
||||
UNENCRYPTED_SIGN_ERROR (
|
||||
R.attr.openpgp_grey,
|
||||
R.drawable.status_signature_unknown,
|
||||
R.string.crypto_msg_title_plaintext,
|
||||
R.string.crypto_msg_unencrypted_sign_error
|
||||
),
|
||||
INCOMPLETE_SIGNED (
|
||||
R.attr.openpgp_black,
|
||||
R.drawable.status_signature_unknown,
|
||||
R.string.crypto_msg_title_plaintext,
|
||||
R.string.crypto_msg_incomplete_signed
|
||||
),
|
||||
|
||||
UNENCRYPTED_SIGN_VERIFIED (
|
||||
R.attr.openpgp_blue,
|
||||
R.drawable.status_signature_dots_3,
|
||||
R.string.crypto_msg_title_unencrypted_signed_e2e,
|
||||
R.string.crypto_msg_unencrypted_sign_verified
|
||||
),
|
||||
UNENCRYPTED_SIGN_UNVERIFIED (
|
||||
R.attr.openpgp_blue,
|
||||
R.drawable.status_signature,
|
||||
R.string.crypto_msg_title_unencrypted_signed_e2e,
|
||||
null
|
||||
),
|
||||
|
||||
UNENCRYPTED_SIGN_UNKNOWN (
|
||||
R.attr.openpgp_orange,
|
||||
R.drawable.status_signature_unknown,
|
||||
R.string.crypto_msg_title_unencrypted_signed,
|
||||
R.string.crypto_msg_unencrypted_sign_unknown
|
||||
),
|
||||
UNENCRYPTED_SIGN_MISMATCH (
|
||||
R.attr.openpgp_grey,
|
||||
R.drawable.status_signature_unknown,
|
||||
R.string.crypto_msg_title_unencrypted_signed,
|
||||
R.string.crypto_msg_unencrypted_sign_mismatch
|
||||
),
|
||||
UNENCRYPTED_SIGN_EXPIRED (
|
||||
R.attr.openpgp_grey,
|
||||
R.drawable.status_signature_unknown,
|
||||
R.string.crypto_msg_title_unencrypted_signed,
|
||||
R.string.crypto_msg_unencrypted_sign_expired
|
||||
),
|
||||
UNENCRYPTED_SIGN_REVOKED (
|
||||
R.attr.openpgp_grey,
|
||||
R.drawable.status_signature_unknown,
|
||||
R.string.crypto_msg_title_unencrypted_signed,
|
||||
R.string.crypto_msg_unencrypted_sign_revoked
|
||||
),
|
||||
UNENCRYPTED_SIGN_INSECURE (
|
||||
R.attr.openpgp_grey,
|
||||
R.drawable.status_signature_unknown,
|
||||
R.string.crypto_msg_title_unencrypted_signed,
|
||||
R.string.crypto_msg_unencrypted_sign_insecure
|
||||
),
|
||||
|
||||
ENCRYPTED_SIGN_VERIFIED (
|
||||
R.attr.openpgp_green,
|
||||
R.drawable.status_lock_dots_3,
|
||||
R.string.crypto_msg_title_encrypted_signed_e2e,
|
||||
R.string.crypto_msg_encrypted_sign_verified
|
||||
),
|
||||
ENCRYPTED_SIGN_UNVERIFIED (
|
||||
R.attr.openpgp_green,
|
||||
R.drawable.status_lock,
|
||||
R.string.crypto_msg_title_encrypted_signed_e2e,
|
||||
null
|
||||
),
|
||||
|
||||
ENCRYPTED_SIGN_UNKNOWN (
|
||||
R.attr.openpgp_orange,
|
||||
R.drawable.status_lock_unknown,
|
||||
R.string.crypto_msg_title_encrypted_signed,
|
||||
R.string.crypto_msg_encrypted_sign_unknown
|
||||
),
|
||||
ENCRYPTED_SIGN_MISMATCH (
|
||||
R.attr.openpgp_grey,
|
||||
R.drawable.status_lock_error,
|
||||
R.string.crypto_msg_title_encrypted_signed,
|
||||
R.string.crypto_msg_encrypted_sign_mismatch
|
||||
),
|
||||
ENCRYPTED_SIGN_EXPIRED (
|
||||
R.attr.openpgp_grey,
|
||||
R.drawable.status_lock_error,
|
||||
R.string.crypto_msg_title_encrypted_signed,
|
||||
R.string.crypto_msg_encrypted_sign_expired
|
||||
),
|
||||
ENCRYPTED_SIGN_REVOKED (
|
||||
R.attr.openpgp_grey,
|
||||
R.drawable.status_lock_error,
|
||||
R.string.crypto_msg_title_encrypted_signed,
|
||||
R.string.crypto_msg_encrypted_sign_revoked
|
||||
),
|
||||
ENCRYPTED_SIGN_INSECURE (
|
||||
R.attr.openpgp_grey,
|
||||
R.drawable.status_lock_error,
|
||||
R.string.crypto_msg_title_encrypted_signed,
|
||||
R.string.crypto_msg_encrypted_sign_insecure
|
||||
),
|
||||
ENCRYPTED_SIGN_ERROR (
|
||||
R.attr.openpgp_grey,
|
||||
R.drawable.status_lock_error,
|
||||
R.string.crypto_msg_title_encrypted_signed,
|
||||
R.string.crypto_msg_encrypted_sign_error
|
||||
),
|
||||
ENCRYPTED_INSECURE (
|
||||
R.attr.openpgp_red,
|
||||
R.drawable.status_lock_error,
|
||||
R.string.crypto_msg_title_encrypted_signed,
|
||||
R.string.crypto_msg_encrypted_insecure
|
||||
),
|
||||
|
||||
ENCRYPTED_UNSIGNED (
|
||||
R.attr.openpgp_grey,
|
||||
R.drawable.status_lock_error,
|
||||
R.string.crypto_msg_title_encrypted_unsigned,
|
||||
R.string.crypto_msg_encrypted_unsigned
|
||||
),
|
||||
|
||||
ENCRYPTED_ERROR (
|
||||
R.attr.openpgp_red,
|
||||
R.drawable.status_lock_error,
|
||||
R.string.crypto_msg_title_encrypted_unknown,
|
||||
R.string.crypto_msg_encrypted_error
|
||||
),
|
||||
|
||||
INCOMPLETE_ENCRYPTED (
|
||||
R.attr.openpgp_black,
|
||||
R.drawable.status_lock_unknown,
|
||||
R.string.crypto_msg_title_encrypted_unknown,
|
||||
R.string.crypto_msg_encrypted_incomplete
|
||||
),
|
||||
|
||||
ENCRYPTED_NO_PROVIDER (
|
||||
R.attr.openpgp_red,
|
||||
R.drawable.status_lock_error,
|
||||
R.string.crypto_msg_title_encrypted_unknown,
|
||||
R.string.crypto_msg_encrypted_no_provider
|
||||
),
|
||||
|
||||
UNSUPPORTED_ENCRYPTED (
|
||||
R.attr.openpgp_red,
|
||||
R.drawable.status_lock_error,
|
||||
R.string.crypto_msg_title_encrypted_unknown,
|
||||
R.string.crypto_msg_unsupported_encrypted
|
||||
),
|
||||
UNSUPPORTED_SIGNED (
|
||||
R.attr.openpgp_grey,
|
||||
R.drawable.status_lock_disabled,
|
||||
R.string.crypto_msg_title_encrypted_unknown,
|
||||
R.string.crypto_msg_unsupported_signed
|
||||
),
|
||||
;
|
||||
|
||||
@AttrRes public final int colorAttr;
|
||||
@DrawableRes public final int statusIconRes;
|
||||
@StringRes public final Integer titleTextRes;
|
||||
@StringRes public final Integer descriptionTextRes;
|
||||
public boolean isEnabled;
|
||||
|
||||
MessageCryptoDisplayStatus(@AttrRes int colorAttr, @DrawableRes int statusIconRes, @StringRes int titleTextRes,
|
||||
Integer descriptionTextRes) {
|
||||
this.colorAttr = colorAttr;
|
||||
this.statusIconRes = statusIconRes;
|
||||
|
||||
this.titleTextRes = titleTextRes;
|
||||
this.descriptionTextRes = descriptionTextRes;
|
||||
}
|
||||
|
||||
MessageCryptoDisplayStatus(boolean isEnabled, @AttrRes int colorAttr, @DrawableRes int statusIconRes,
|
||||
@StringRes int titleTextRes, Integer descriptionTextRes) {
|
||||
this(colorAttr, statusIconRes, titleTextRes, descriptionTextRes);
|
||||
this.isEnabled = isEnabled;
|
||||
}
|
||||
|
||||
MessageCryptoDisplayStatus(boolean isEnabled, @AttrRes int colorAttr, @DrawableRes int statusIconRes) {
|
||||
this.colorAttr = colorAttr;
|
||||
this.statusIconRes = statusIconRes;
|
||||
|
||||
this.titleTextRes = null;
|
||||
this.descriptionTextRes = null;
|
||||
|
||||
this.isEnabled = isEnabled;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public static MessageCryptoDisplayStatus fromResultAnnotation(CryptoResultAnnotation cryptoResult) {
|
||||
if (cryptoResult == null) {
|
||||
return DISABLED;
|
||||
}
|
||||
|
||||
switch (cryptoResult.getErrorType()) {
|
||||
case OPENPGP_OK:
|
||||
return getDisplayStatusForPgpResult(cryptoResult);
|
||||
|
||||
case OPENPGP_ENCRYPTED_BUT_INCOMPLETE:
|
||||
return INCOMPLETE_ENCRYPTED;
|
||||
|
||||
case OPENPGP_SIGNED_BUT_INCOMPLETE:
|
||||
return INCOMPLETE_SIGNED;
|
||||
|
||||
case ENCRYPTED_BUT_UNSUPPORTED:
|
||||
return UNSUPPORTED_ENCRYPTED;
|
||||
|
||||
case SIGNED_BUT_UNSUPPORTED:
|
||||
return UNSUPPORTED_SIGNED;
|
||||
|
||||
case OPENPGP_UI_CANCELED:
|
||||
return CANCELLED;
|
||||
|
||||
case OPENPGP_SIGNED_API_ERROR:
|
||||
return UNENCRYPTED_SIGN_ERROR;
|
||||
|
||||
case OPENPGP_ENCRYPTED_API_ERROR:
|
||||
return ENCRYPTED_ERROR;
|
||||
|
||||
case OPENPGP_ENCRYPTED_NO_PROVIDER:
|
||||
return ENCRYPTED_NO_PROVIDER;
|
||||
}
|
||||
throw new IllegalStateException("Unhandled case!");
|
||||
}
|
||||
|
||||
@NonNull
|
||||
private static MessageCryptoDisplayStatus getDisplayStatusForPgpResult(CryptoResultAnnotation cryptoResult) {
|
||||
OpenPgpSignatureResult signatureResult = cryptoResult.getOpenPgpSignatureResult();
|
||||
OpenPgpDecryptionResult decryptionResult = cryptoResult.getOpenPgpDecryptionResult();
|
||||
if (decryptionResult == null || signatureResult == null) {
|
||||
throw new AssertionError("Both OpenPGP results must be non-null at this point!");
|
||||
}
|
||||
|
||||
if (signatureResult.getResult() == OpenPgpSignatureResult.RESULT_NO_SIGNATURE &&
|
||||
cryptoResult.hasEncapsulatedResult()) {
|
||||
CryptoResultAnnotation encapsulatedResult = cryptoResult.getEncapsulatedResult();
|
||||
if (encapsulatedResult.isOpenPgpResult()) {
|
||||
signatureResult = encapsulatedResult.getOpenPgpSignatureResult();
|
||||
if (signatureResult == null) {
|
||||
throw new AssertionError("OpenPGP must contain signature result at this point!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
switch (decryptionResult.getResult()) {
|
||||
case OpenPgpDecryptionResult.RESULT_NOT_ENCRYPTED:
|
||||
return getStatusForPgpUnencryptedResult(signatureResult);
|
||||
|
||||
case OpenPgpDecryptionResult.RESULT_ENCRYPTED:
|
||||
return getStatusForPgpEncryptedResult(signatureResult);
|
||||
|
||||
case OpenPgpDecryptionResult.RESULT_INSECURE:
|
||||
return ENCRYPTED_INSECURE;
|
||||
}
|
||||
|
||||
throw new AssertionError("all cases must be handled, this is a bug!");
|
||||
}
|
||||
|
||||
@NonNull
|
||||
private static MessageCryptoDisplayStatus getStatusForPgpEncryptedResult(OpenPgpSignatureResult signatureResult) {
|
||||
switch (signatureResult.getResult()) {
|
||||
case OpenPgpSignatureResult.RESULT_NO_SIGNATURE:
|
||||
return ENCRYPTED_UNSIGNED;
|
||||
|
||||
case OpenPgpSignatureResult.RESULT_VALID_KEY_CONFIRMED:
|
||||
case OpenPgpSignatureResult.RESULT_VALID_KEY_UNCONFIRMED:
|
||||
switch (signatureResult.getSenderStatusResult()) {
|
||||
case USER_ID_CONFIRMED:
|
||||
return ENCRYPTED_SIGN_VERIFIED;
|
||||
case USER_ID_UNCONFIRMED:
|
||||
return ENCRYPTED_SIGN_UNVERIFIED;
|
||||
case USER_ID_MISSING:
|
||||
return ENCRYPTED_SIGN_MISMATCH;
|
||||
case UNKNOWN:
|
||||
return ENCRYPTED_SIGN_UNVERIFIED;
|
||||
}
|
||||
throw new IllegalStateException("unhandled encrypted result case!");
|
||||
|
||||
case OpenPgpSignatureResult.RESULT_KEY_MISSING:
|
||||
return ENCRYPTED_SIGN_UNKNOWN;
|
||||
|
||||
case OpenPgpSignatureResult.RESULT_INVALID_SIGNATURE:
|
||||
return ENCRYPTED_SIGN_ERROR;
|
||||
|
||||
case OpenPgpSignatureResult.RESULT_INVALID_KEY_EXPIRED:
|
||||
return ENCRYPTED_SIGN_EXPIRED;
|
||||
|
||||
case OpenPgpSignatureResult.RESULT_INVALID_KEY_REVOKED:
|
||||
return ENCRYPTED_SIGN_REVOKED;
|
||||
|
||||
case OpenPgpSignatureResult.RESULT_INVALID_KEY_INSECURE:
|
||||
return ENCRYPTED_SIGN_INSECURE;
|
||||
|
||||
default:
|
||||
throw new IllegalStateException("unhandled encrypted result case!");
|
||||
}
|
||||
}
|
||||
|
||||
@NonNull
|
||||
private static MessageCryptoDisplayStatus getStatusForPgpUnencryptedResult(OpenPgpSignatureResult signatureResult) {
|
||||
switch (signatureResult.getResult()) {
|
||||
case OpenPgpSignatureResult.RESULT_NO_SIGNATURE:
|
||||
return DISABLED;
|
||||
|
||||
case OpenPgpSignatureResult.RESULT_VALID_KEY_CONFIRMED:
|
||||
case OpenPgpSignatureResult.RESULT_VALID_KEY_UNCONFIRMED:
|
||||
switch (signatureResult.getSenderStatusResult()) {
|
||||
case USER_ID_CONFIRMED:
|
||||
return UNENCRYPTED_SIGN_VERIFIED;
|
||||
case USER_ID_UNCONFIRMED:
|
||||
return UNENCRYPTED_SIGN_UNVERIFIED;
|
||||
case USER_ID_MISSING:
|
||||
return UNENCRYPTED_SIGN_MISMATCH;
|
||||
case UNKNOWN:
|
||||
return UNENCRYPTED_SIGN_UNVERIFIED;
|
||||
}
|
||||
throw new IllegalStateException("unhandled encrypted result case!");
|
||||
|
||||
case OpenPgpSignatureResult.RESULT_KEY_MISSING:
|
||||
return UNENCRYPTED_SIGN_UNKNOWN;
|
||||
|
||||
case OpenPgpSignatureResult.RESULT_INVALID_SIGNATURE:
|
||||
return UNENCRYPTED_SIGN_ERROR;
|
||||
|
||||
case OpenPgpSignatureResult.RESULT_INVALID_KEY_EXPIRED:
|
||||
return UNENCRYPTED_SIGN_EXPIRED;
|
||||
|
||||
case OpenPgpSignatureResult.RESULT_INVALID_KEY_REVOKED:
|
||||
return UNENCRYPTED_SIGN_REVOKED;
|
||||
|
||||
case OpenPgpSignatureResult.RESULT_INVALID_KEY_INSECURE:
|
||||
return UNENCRYPTED_SIGN_INSECURE;
|
||||
|
||||
default:
|
||||
throw new IllegalStateException("unhandled encrypted result case!");
|
||||
}
|
||||
}
|
||||
|
||||
public boolean hasAssociatedKey() {
|
||||
switch (this) {
|
||||
case ENCRYPTED_SIGN_VERIFIED:
|
||||
case ENCRYPTED_SIGN_UNVERIFIED:
|
||||
case ENCRYPTED_SIGN_MISMATCH:
|
||||
case ENCRYPTED_SIGN_EXPIRED:
|
||||
case ENCRYPTED_SIGN_REVOKED:
|
||||
case ENCRYPTED_SIGN_INSECURE:
|
||||
|
||||
case UNENCRYPTED_SIGN_VERIFIED:
|
||||
case UNENCRYPTED_SIGN_UNVERIFIED:
|
||||
case UNENCRYPTED_SIGN_MISMATCH:
|
||||
case UNENCRYPTED_SIGN_EXPIRED:
|
||||
case UNENCRYPTED_SIGN_REVOKED:
|
||||
case UNENCRYPTED_SIGN_INSECURE:
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isUnencryptedSigned() {
|
||||
switch (this) {
|
||||
case UNENCRYPTED_SIGN_ERROR:
|
||||
case UNENCRYPTED_SIGN_UNKNOWN:
|
||||
case UNENCRYPTED_SIGN_VERIFIED:
|
||||
case UNENCRYPTED_SIGN_UNVERIFIED:
|
||||
case UNENCRYPTED_SIGN_MISMATCH:
|
||||
case UNENCRYPTED_SIGN_EXPIRED:
|
||||
case UNENCRYPTED_SIGN_REVOKED:
|
||||
case UNENCRYPTED_SIGN_INSECURE:
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isUnknownKey() {
|
||||
switch (this) {
|
||||
case ENCRYPTED_SIGN_UNKNOWN:
|
||||
case UNENCRYPTED_SIGN_UNKNOWN:
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,325 @@
|
|||
package com.fsck.k9.view
|
||||
|
||||
import androidx.annotation.AttrRes
|
||||
import androidx.annotation.DrawableRes
|
||||
import androidx.annotation.StringRes
|
||||
import com.fsck.k9.mailstore.CryptoResultAnnotation
|
||||
import com.fsck.k9.mailstore.CryptoResultAnnotation.CryptoError
|
||||
import com.fsck.k9.ui.R
|
||||
import org.openintents.openpgp.OpenPgpDecryptionResult.RESULT_ENCRYPTED
|
||||
import org.openintents.openpgp.OpenPgpDecryptionResult.RESULT_INSECURE
|
||||
import org.openintents.openpgp.OpenPgpDecryptionResult.RESULT_NOT_ENCRYPTED
|
||||
import org.openintents.openpgp.OpenPgpSignatureResult
|
||||
import org.openintents.openpgp.OpenPgpSignatureResult.RESULT_INVALID_KEY_EXPIRED
|
||||
import org.openintents.openpgp.OpenPgpSignatureResult.RESULT_INVALID_KEY_INSECURE
|
||||
import org.openintents.openpgp.OpenPgpSignatureResult.RESULT_INVALID_KEY_REVOKED
|
||||
import org.openintents.openpgp.OpenPgpSignatureResult.RESULT_INVALID_SIGNATURE
|
||||
import org.openintents.openpgp.OpenPgpSignatureResult.RESULT_KEY_MISSING
|
||||
import org.openintents.openpgp.OpenPgpSignatureResult.RESULT_NO_SIGNATURE
|
||||
import org.openintents.openpgp.OpenPgpSignatureResult.RESULT_VALID_KEY_CONFIRMED
|
||||
import org.openintents.openpgp.OpenPgpSignatureResult.RESULT_VALID_KEY_UNCONFIRMED
|
||||
import org.openintents.openpgp.OpenPgpSignatureResult.SenderStatusResult.UNKNOWN
|
||||
import org.openintents.openpgp.OpenPgpSignatureResult.SenderStatusResult.USER_ID_CONFIRMED
|
||||
import org.openintents.openpgp.OpenPgpSignatureResult.SenderStatusResult.USER_ID_MISSING
|
||||
import org.openintents.openpgp.OpenPgpSignatureResult.SenderStatusResult.USER_ID_UNCONFIRMED
|
||||
|
||||
enum class MessageCryptoDisplayStatus(
|
||||
val isEnabled: Boolean = true,
|
||||
|
||||
@AttrRes
|
||||
val colorAttr: Int,
|
||||
|
||||
@DrawableRes
|
||||
val statusIconRes: Int,
|
||||
|
||||
@StringRes
|
||||
val titleTextRes: Int? = null,
|
||||
|
||||
@StringRes
|
||||
val descriptionTextRes: Int? = null
|
||||
) {
|
||||
LOADING(
|
||||
isEnabled = false,
|
||||
colorAttr = R.attr.openpgp_grey,
|
||||
statusIconRes = R.drawable.status_lock_disabled
|
||||
),
|
||||
CANCELLED(
|
||||
colorAttr = R.attr.openpgp_black,
|
||||
statusIconRes = R.drawable.status_lock_unknown,
|
||||
titleTextRes = R.string.crypto_msg_title_encrypted_unknown,
|
||||
descriptionTextRes = R.string.crypto_msg_cancelled
|
||||
),
|
||||
DISABLED(
|
||||
isEnabled = false,
|
||||
colorAttr = R.attr.openpgp_grey,
|
||||
statusIconRes = R.drawable.status_lock_disabled,
|
||||
titleTextRes = R.string.crypto_msg_title_plaintext
|
||||
),
|
||||
UNENCRYPTED_SIGN_ERROR(
|
||||
colorAttr = R.attr.openpgp_grey,
|
||||
statusIconRes = R.drawable.status_signature_unknown,
|
||||
titleTextRes = R.string.crypto_msg_title_plaintext,
|
||||
descriptionTextRes = R.string.crypto_msg_unencrypted_sign_error
|
||||
),
|
||||
INCOMPLETE_SIGNED(
|
||||
colorAttr = R.attr.openpgp_black,
|
||||
statusIconRes = R.drawable.status_signature_unknown,
|
||||
titleTextRes = R.string.crypto_msg_title_plaintext,
|
||||
descriptionTextRes = R.string.crypto_msg_incomplete_signed
|
||||
),
|
||||
UNENCRYPTED_SIGN_VERIFIED(
|
||||
colorAttr = R.attr.openpgp_blue,
|
||||
statusIconRes = R.drawable.status_signature_dots_3,
|
||||
titleTextRes = R.string.crypto_msg_title_unencrypted_signed_e2e,
|
||||
descriptionTextRes = R.string.crypto_msg_unencrypted_sign_verified
|
||||
),
|
||||
UNENCRYPTED_SIGN_UNVERIFIED(
|
||||
colorAttr = R.attr.openpgp_blue,
|
||||
statusIconRes = R.drawable.status_signature,
|
||||
titleTextRes = R.string.crypto_msg_title_unencrypted_signed_e2e
|
||||
),
|
||||
UNENCRYPTED_SIGN_UNKNOWN(
|
||||
colorAttr = R.attr.openpgp_orange,
|
||||
statusIconRes = R.drawable.status_signature_unknown,
|
||||
titleTextRes = R.string.crypto_msg_title_unencrypted_signed,
|
||||
descriptionTextRes = R.string.crypto_msg_unencrypted_sign_unknown
|
||||
),
|
||||
UNENCRYPTED_SIGN_MISMATCH(
|
||||
colorAttr = R.attr.openpgp_grey,
|
||||
statusIconRes = R.drawable.status_signature_unknown,
|
||||
titleTextRes = R.string.crypto_msg_title_unencrypted_signed,
|
||||
descriptionTextRes = R.string.crypto_msg_unencrypted_sign_mismatch
|
||||
),
|
||||
UNENCRYPTED_SIGN_EXPIRED(
|
||||
colorAttr = R.attr.openpgp_grey,
|
||||
statusIconRes = R.drawable.status_signature_unknown,
|
||||
titleTextRes = R.string.crypto_msg_title_unencrypted_signed,
|
||||
descriptionTextRes = R.string.crypto_msg_unencrypted_sign_expired
|
||||
),
|
||||
UNENCRYPTED_SIGN_REVOKED(
|
||||
colorAttr = R.attr.openpgp_grey,
|
||||
statusIconRes = R.drawable.status_signature_unknown,
|
||||
titleTextRes = R.string.crypto_msg_title_unencrypted_signed,
|
||||
descriptionTextRes = R.string.crypto_msg_unencrypted_sign_revoked
|
||||
),
|
||||
UNENCRYPTED_SIGN_INSECURE(
|
||||
colorAttr = R.attr.openpgp_grey,
|
||||
statusIconRes = R.drawable.status_signature_unknown,
|
||||
titleTextRes = R.string.crypto_msg_title_unencrypted_signed,
|
||||
descriptionTextRes = R.string.crypto_msg_unencrypted_sign_insecure
|
||||
),
|
||||
ENCRYPTED_SIGN_VERIFIED(
|
||||
colorAttr = R.attr.openpgp_green,
|
||||
statusIconRes = R.drawable.status_lock_dots_3,
|
||||
titleTextRes = R.string.crypto_msg_title_encrypted_signed_e2e,
|
||||
descriptionTextRes = R.string.crypto_msg_encrypted_sign_verified
|
||||
),
|
||||
ENCRYPTED_SIGN_UNVERIFIED(
|
||||
colorAttr = R.attr.openpgp_green,
|
||||
statusIconRes = R.drawable.status_lock,
|
||||
titleTextRes = R.string.crypto_msg_title_encrypted_signed_e2e
|
||||
),
|
||||
ENCRYPTED_SIGN_UNKNOWN(
|
||||
colorAttr = R.attr.openpgp_orange,
|
||||
statusIconRes = R.drawable.status_lock_unknown,
|
||||
titleTextRes = R.string.crypto_msg_title_encrypted_signed,
|
||||
descriptionTextRes = R.string.crypto_msg_encrypted_sign_unknown
|
||||
),
|
||||
ENCRYPTED_SIGN_MISMATCH(
|
||||
colorAttr = R.attr.openpgp_grey,
|
||||
statusIconRes = R.drawable.status_lock_error,
|
||||
titleTextRes = R.string.crypto_msg_title_encrypted_signed,
|
||||
descriptionTextRes = R.string.crypto_msg_encrypted_sign_mismatch
|
||||
),
|
||||
ENCRYPTED_SIGN_EXPIRED(
|
||||
colorAttr = R.attr.openpgp_grey,
|
||||
statusIconRes = R.drawable.status_lock_error,
|
||||
titleTextRes = R.string.crypto_msg_title_encrypted_signed,
|
||||
descriptionTextRes = R.string.crypto_msg_encrypted_sign_expired
|
||||
),
|
||||
ENCRYPTED_SIGN_REVOKED(
|
||||
colorAttr = R.attr.openpgp_grey,
|
||||
statusIconRes = R.drawable.status_lock_error,
|
||||
titleTextRes = R.string.crypto_msg_title_encrypted_signed,
|
||||
descriptionTextRes = R.string.crypto_msg_encrypted_sign_revoked
|
||||
),
|
||||
ENCRYPTED_SIGN_INSECURE(
|
||||
colorAttr = R.attr.openpgp_grey,
|
||||
statusIconRes = R.drawable.status_lock_error,
|
||||
titleTextRes = R.string.crypto_msg_title_encrypted_signed,
|
||||
descriptionTextRes = R.string.crypto_msg_encrypted_sign_insecure
|
||||
),
|
||||
ENCRYPTED_SIGN_ERROR(
|
||||
colorAttr = R.attr.openpgp_grey,
|
||||
statusIconRes = R.drawable.status_lock_error,
|
||||
titleTextRes = R.string.crypto_msg_title_encrypted_signed,
|
||||
descriptionTextRes = R.string.crypto_msg_encrypted_sign_error
|
||||
),
|
||||
ENCRYPTED_INSECURE(
|
||||
colorAttr = R.attr.openpgp_red,
|
||||
statusIconRes = R.drawable.status_lock_error,
|
||||
titleTextRes = R.string.crypto_msg_title_encrypted_signed,
|
||||
descriptionTextRes = R.string.crypto_msg_encrypted_insecure
|
||||
),
|
||||
ENCRYPTED_UNSIGNED(
|
||||
colorAttr = R.attr.openpgp_grey,
|
||||
statusIconRes = R.drawable.status_lock_error,
|
||||
titleTextRes = R.string.crypto_msg_title_encrypted_unsigned,
|
||||
descriptionTextRes = R.string.crypto_msg_encrypted_unsigned
|
||||
),
|
||||
ENCRYPTED_ERROR(
|
||||
colorAttr = R.attr.openpgp_red,
|
||||
statusIconRes = R.drawable.status_lock_error,
|
||||
titleTextRes = R.string.crypto_msg_title_encrypted_unknown,
|
||||
descriptionTextRes = R.string.crypto_msg_encrypted_error
|
||||
),
|
||||
INCOMPLETE_ENCRYPTED(
|
||||
colorAttr = R.attr.openpgp_black,
|
||||
statusIconRes = R.drawable.status_lock_unknown,
|
||||
titleTextRes = R.string.crypto_msg_title_encrypted_unknown,
|
||||
descriptionTextRes = R.string.crypto_msg_encrypted_incomplete
|
||||
),
|
||||
ENCRYPTED_NO_PROVIDER(
|
||||
colorAttr = R.attr.openpgp_red,
|
||||
statusIconRes = R.drawable.status_lock_error,
|
||||
titleTextRes = R.string.crypto_msg_title_encrypted_unknown,
|
||||
descriptionTextRes = R.string.crypto_msg_encrypted_no_provider
|
||||
),
|
||||
UNSUPPORTED_ENCRYPTED(
|
||||
colorAttr = R.attr.openpgp_red,
|
||||
statusIconRes = R.drawable.status_lock_error,
|
||||
titleTextRes = R.string.crypto_msg_title_encrypted_unknown,
|
||||
descriptionTextRes = R.string.crypto_msg_unsupported_encrypted
|
||||
),
|
||||
UNSUPPORTED_SIGNED(
|
||||
colorAttr = R.attr.openpgp_grey,
|
||||
statusIconRes = R.drawable.status_lock_disabled,
|
||||
titleTextRes = R.string.crypto_msg_title_encrypted_unknown,
|
||||
descriptionTextRes = R.string.crypto_msg_unsupported_signed
|
||||
);
|
||||
|
||||
fun hasAssociatedKey(): Boolean {
|
||||
return when (this) {
|
||||
ENCRYPTED_SIGN_VERIFIED,
|
||||
ENCRYPTED_SIGN_UNVERIFIED,
|
||||
ENCRYPTED_SIGN_MISMATCH,
|
||||
ENCRYPTED_SIGN_EXPIRED,
|
||||
ENCRYPTED_SIGN_REVOKED,
|
||||
ENCRYPTED_SIGN_INSECURE,
|
||||
UNENCRYPTED_SIGN_VERIFIED,
|
||||
UNENCRYPTED_SIGN_UNVERIFIED,
|
||||
UNENCRYPTED_SIGN_MISMATCH,
|
||||
UNENCRYPTED_SIGN_EXPIRED,
|
||||
UNENCRYPTED_SIGN_REVOKED,
|
||||
UNENCRYPTED_SIGN_INSECURE -> true
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
|
||||
val isUnencryptedSigned: Boolean
|
||||
get() = when (this) {
|
||||
UNENCRYPTED_SIGN_ERROR,
|
||||
UNENCRYPTED_SIGN_UNKNOWN,
|
||||
UNENCRYPTED_SIGN_VERIFIED,
|
||||
UNENCRYPTED_SIGN_UNVERIFIED,
|
||||
UNENCRYPTED_SIGN_MISMATCH,
|
||||
UNENCRYPTED_SIGN_EXPIRED,
|
||||
UNENCRYPTED_SIGN_REVOKED,
|
||||
UNENCRYPTED_SIGN_INSECURE -> true
|
||||
else -> false
|
||||
}
|
||||
|
||||
val isUnknownKey: Boolean
|
||||
get() = when (this) {
|
||||
ENCRYPTED_SIGN_UNKNOWN, UNENCRYPTED_SIGN_UNKNOWN -> true
|
||||
else -> false
|
||||
}
|
||||
|
||||
companion object {
|
||||
@JvmStatic
|
||||
fun fromResultAnnotation(cryptoResult: CryptoResultAnnotation?): MessageCryptoDisplayStatus {
|
||||
return when (cryptoResult?.errorType) {
|
||||
null -> DISABLED
|
||||
CryptoError.OPENPGP_OK -> getDisplayStatusForPgpResult(cryptoResult)
|
||||
CryptoError.OPENPGP_ENCRYPTED_BUT_INCOMPLETE -> INCOMPLETE_ENCRYPTED
|
||||
CryptoError.OPENPGP_SIGNED_BUT_INCOMPLETE -> INCOMPLETE_SIGNED
|
||||
CryptoError.ENCRYPTED_BUT_UNSUPPORTED -> UNSUPPORTED_ENCRYPTED
|
||||
CryptoError.SIGNED_BUT_UNSUPPORTED -> UNSUPPORTED_SIGNED
|
||||
CryptoError.OPENPGP_UI_CANCELED -> CANCELLED
|
||||
CryptoError.OPENPGP_SIGNED_API_ERROR -> UNENCRYPTED_SIGN_ERROR
|
||||
CryptoError.OPENPGP_ENCRYPTED_API_ERROR -> ENCRYPTED_ERROR
|
||||
CryptoError.OPENPGP_ENCRYPTED_NO_PROVIDER -> ENCRYPTED_NO_PROVIDER
|
||||
else -> error("Unhandled case!")
|
||||
}
|
||||
}
|
||||
|
||||
private fun getDisplayStatusForPgpResult(cryptoResult: CryptoResultAnnotation): MessageCryptoDisplayStatus {
|
||||
var signatureResult = cryptoResult.openPgpSignatureResult
|
||||
val decryptionResult = cryptoResult.openPgpDecryptionResult
|
||||
if (decryptionResult == null || signatureResult == null) {
|
||||
throw AssertionError("Both OpenPGP results must be non-null at this point!")
|
||||
}
|
||||
|
||||
if (signatureResult.result == RESULT_NO_SIGNATURE && cryptoResult.hasEncapsulatedResult()) {
|
||||
val encapsulatedResult = cryptoResult.encapsulatedResult
|
||||
if (encapsulatedResult.isOpenPgpResult) {
|
||||
signatureResult = encapsulatedResult.openPgpSignatureResult
|
||||
?: throw AssertionError("OpenPGP must contain signature result at this point!")
|
||||
}
|
||||
}
|
||||
|
||||
return when (decryptionResult.getResult()) {
|
||||
RESULT_NOT_ENCRYPTED -> getStatusForPgpUnencryptedResult(signatureResult)
|
||||
RESULT_ENCRYPTED -> getStatusForPgpEncryptedResult(signatureResult)
|
||||
RESULT_INSECURE -> ENCRYPTED_INSECURE
|
||||
else -> throw AssertionError("all cases must be handled, this is a bug!")
|
||||
}
|
||||
}
|
||||
|
||||
private fun getStatusForPgpEncryptedResult(
|
||||
signatureResult: OpenPgpSignatureResult
|
||||
): MessageCryptoDisplayStatus {
|
||||
return when (signatureResult.result) {
|
||||
RESULT_NO_SIGNATURE -> ENCRYPTED_UNSIGNED
|
||||
RESULT_VALID_KEY_CONFIRMED, RESULT_VALID_KEY_UNCONFIRMED -> {
|
||||
return when (signatureResult.senderStatusResult) {
|
||||
USER_ID_CONFIRMED -> ENCRYPTED_SIGN_VERIFIED
|
||||
USER_ID_UNCONFIRMED -> ENCRYPTED_SIGN_UNVERIFIED
|
||||
USER_ID_MISSING -> ENCRYPTED_SIGN_MISMATCH
|
||||
UNKNOWN -> ENCRYPTED_SIGN_UNVERIFIED
|
||||
else -> error("unhandled encrypted result case!")
|
||||
}
|
||||
}
|
||||
RESULT_KEY_MISSING -> ENCRYPTED_SIGN_UNKNOWN
|
||||
RESULT_INVALID_SIGNATURE -> ENCRYPTED_SIGN_ERROR
|
||||
RESULT_INVALID_KEY_EXPIRED -> ENCRYPTED_SIGN_EXPIRED
|
||||
RESULT_INVALID_KEY_REVOKED -> ENCRYPTED_SIGN_REVOKED
|
||||
RESULT_INVALID_KEY_INSECURE -> ENCRYPTED_SIGN_INSECURE
|
||||
else -> error("unhandled encrypted result case!")
|
||||
}
|
||||
}
|
||||
|
||||
private fun getStatusForPgpUnencryptedResult(
|
||||
signatureResult: OpenPgpSignatureResult
|
||||
): MessageCryptoDisplayStatus {
|
||||
return when (signatureResult.result) {
|
||||
RESULT_NO_SIGNATURE -> DISABLED
|
||||
RESULT_VALID_KEY_CONFIRMED, RESULT_VALID_KEY_UNCONFIRMED -> {
|
||||
return when (signatureResult.senderStatusResult) {
|
||||
USER_ID_CONFIRMED -> UNENCRYPTED_SIGN_VERIFIED
|
||||
USER_ID_UNCONFIRMED -> UNENCRYPTED_SIGN_UNVERIFIED
|
||||
USER_ID_MISSING -> UNENCRYPTED_SIGN_MISMATCH
|
||||
UNKNOWN -> UNENCRYPTED_SIGN_UNVERIFIED
|
||||
else -> error("unhandled encrypted result case!")
|
||||
}
|
||||
}
|
||||
RESULT_KEY_MISSING -> UNENCRYPTED_SIGN_UNKNOWN
|
||||
RESULT_INVALID_SIGNATURE -> UNENCRYPTED_SIGN_ERROR
|
||||
RESULT_INVALID_KEY_EXPIRED -> UNENCRYPTED_SIGN_EXPIRED
|
||||
RESULT_INVALID_KEY_REVOKED -> UNENCRYPTED_SIGN_REVOKED
|
||||
RESULT_INVALID_KEY_INSECURE -> UNENCRYPTED_SIGN_INSECURE
|
||||
else -> error("unhandled encrypted result case!")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -2,22 +2,11 @@ package com.fsck.k9.view;
|
|||
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Typeface;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.widget.PopupMenu;
|
||||
import androidx.appcompat.widget.PopupMenu.OnMenuItemClickListener;
|
||||
import android.text.SpannableString;
|
||||
import android.text.SpannableStringBuilder;
|
||||
import android.text.TextUtils;
|
||||
import android.text.format.DateUtils;
|
||||
import android.text.style.StyleSpan;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.Gravity;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.view.View.OnLongClickListener;
|
||||
|
@ -27,6 +16,9 @@ import android.widget.LinearLayout;
|
|||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.widget.PopupMenu;
|
||||
import androidx.appcompat.widget.PopupMenu.OnMenuItemClickListener;
|
||||
import com.fsck.k9.Account;
|
||||
import com.fsck.k9.DI;
|
||||
import com.fsck.k9.FontSizes;
|
||||
|
@ -38,9 +30,7 @@ import com.fsck.k9.helper.Contacts;
|
|||
import com.fsck.k9.helper.MessageHelper;
|
||||
import com.fsck.k9.mail.Address;
|
||||
import com.fsck.k9.mail.Flag;
|
||||
import com.fsck.k9.mail.Header;
|
||||
import com.fsck.k9.mail.Message;
|
||||
import com.fsck.k9.mail.internet.MimeUtility;
|
||||
import com.fsck.k9.ui.ContactBadge;
|
||||
import com.fsck.k9.ui.R;
|
||||
import com.fsck.k9.ui.messageview.OnCryptoClickListener;
|
||||
|
@ -328,10 +318,10 @@ public class MessageHeader extends LinearLayout implements OnClickListener, OnLo
|
|||
}
|
||||
|
||||
private void setCryptoDisplayStatus(MessageCryptoDisplayStatus displayStatus) {
|
||||
int color = ThemeUtils.getStyledColor(getContext(), displayStatus.colorAttr);
|
||||
mCryptoStatusIcon.setEnabled(displayStatus.isEnabled);
|
||||
int color = ThemeUtils.getStyledColor(getContext(), displayStatus.getColorAttr());
|
||||
mCryptoStatusIcon.setEnabled(displayStatus.isEnabled());
|
||||
mCryptoStatusIcon.setVisibility(View.VISIBLE);
|
||||
mCryptoStatusIcon.setImageResource(displayStatus.statusIconRes);
|
||||
mCryptoStatusIcon.setImageResource(displayStatus.getStatusIconRes());
|
||||
mCryptoStatusIcon.setColorFilter(color);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue