k-9/k9mail/src/main/java/com/fsck/k9/ui/messageview/OpenPgpHeaderView.java

364 lines
12 KiB
Java

package com.fsck.k9.ui.messageview;
import android.app.PendingIntent;
import android.content.Context;
import android.graphics.PorterDuff;
import android.graphics.drawable.Drawable;
import android.support.annotation.ColorRes;
import android.support.annotation.DrawableRes;
import android.support.annotation.StringRes;
import android.util.AttributeSet;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.fsck.k9.R;
import com.fsck.k9.mailstore.OpenPgpResultAnnotation;
import org.openintents.openpgp.OpenPgpError;
import org.openintents.openpgp.OpenPgpSignatureResult;
import org.openintents.openpgp.util.OpenPgpUtils;
public class OpenPgpHeaderView extends LinearLayout {
private Context context;
private OpenPgpHeaderViewCallback callback;
private OpenPgpResultAnnotation cryptoAnnotation;
private ImageView resultEncryptionIcon;
private TextView resultEncryptionText;
private ImageView resultSignatureIcon;
private TextView resultSignatureText;
private LinearLayout resultSignatureLayout;
private TextView resultSignatureName;
private TextView resultSignatureEmail;
private Button resultSignatureButton;
public OpenPgpHeaderView(Context context, AttributeSet attrs) {
super(context, attrs);
this.context = context;
}
@Override
public void onFinishInflate() {
resultEncryptionIcon = (ImageView) findViewById(R.id.result_encryption_icon);
resultEncryptionText = (TextView) findViewById(R.id.result_encryption_text);
resultSignatureIcon = (ImageView) findViewById(R.id.result_signature_icon);
resultSignatureText = (TextView) findViewById(R.id.result_signature_text);
resultSignatureLayout = (LinearLayout) findViewById(R.id.result_signature_layout);
resultSignatureName = (TextView) findViewById(R.id.result_signature_name);
resultSignatureEmail = (TextView) findViewById(R.id.result_signature_email);
resultSignatureButton = (Button) findViewById(R.id.result_signature_button);
}
public void setCallback(OpenPgpHeaderViewCallback callback) {
this.callback = callback;
}
public void setOpenPgpData(OpenPgpResultAnnotation cryptoAnnotation) {
this.cryptoAnnotation = cryptoAnnotation;
initializeEncryptionHeader();
initializeSignatureHeader();
}
private void initializeEncryptionHeader() {
if (noCryptoAnnotationFound()) {
displayNotEncrypted();
return;
}
switch (cryptoAnnotation.getErrorType()) {
case NONE: {
if (cryptoAnnotation.wasEncrypted()) {
displayEncrypted();
} else {
displayNotEncrypted();
}
break;
}
case CRYPTO_API_RETURNED_ERROR: {
displayEncryptionError();
break;
}
case ENCRYPTED_BUT_INCOMPLETE: {
displayIncompleteEncryptedPart();
break;
}
case SIGNED_BUT_INCOMPLETE: {
displayNotEncrypted();
break;
}
}
}
private boolean noCryptoAnnotationFound() {
return cryptoAnnotation == null;
}
private void displayEncrypted() {
setEncryptionImageAndTextColor(CryptoState.ENCRYPTED);
resultEncryptionText.setText(R.string.openpgp_result_encrypted);
}
private void displayNotEncrypted() {
setEncryptionImageAndTextColor(CryptoState.NOT_ENCRYPTED);
resultEncryptionText.setText(R.string.openpgp_result_not_encrypted);
}
private void displayEncryptionError() {
setEncryptionImageAndTextColor(CryptoState.INVALID);
OpenPgpError error = cryptoAnnotation.getError();
String text;
if (error == null) {
text = context.getString(R.string.openpgp_unknown_error);
} else {
text = context.getString(R.string.openpgp_error, error.getMessage());
}
resultEncryptionText.setText(text);
}
private void displayIncompleteEncryptedPart() {
setEncryptionImageAndTextColor(CryptoState.UNAVAILABLE);
resultEncryptionText.setText(R.string.crypto_incomplete_message);
}
private void initializeSignatureHeader() {
initializeSignatureButton();
if (noCryptoAnnotationFound()) {
displayNotSigned();
return;
}
switch (cryptoAnnotation.getErrorType()) {
case CRYPTO_API_RETURNED_ERROR:
case NONE: {
displayVerificationResult();
break;
}
case ENCRYPTED_BUT_INCOMPLETE:
case SIGNED_BUT_INCOMPLETE: {
displayIncompleteSignedPart();
break;
}
}
}
private void displayIncompleteSignedPart() {
setSignatureImageAndTextColor(CryptoState.UNAVAILABLE);
resultSignatureText.setText(R.string.crypto_incomplete_message);
hideSignatureLayout();
}
private void displayVerificationResult() {
OpenPgpSignatureResult signatureResult = cryptoAnnotation.getSignatureResult();
if (signatureResult == null) {
displayNotSigned();
return;
}
switch (signatureResult.getStatus()) {
case OpenPgpSignatureResult.SIGNATURE_ERROR: {
displaySignatureError();
break;
}
case OpenPgpSignatureResult.SIGNATURE_SUCCESS_CERTIFIED: {
displaySignatureSuccessCertified();
break;
}
case OpenPgpSignatureResult.SIGNATURE_KEY_MISSING: {
displaySignatureKeyMissing();
break;
}
case OpenPgpSignatureResult.SIGNATURE_SUCCESS_UNCERTIFIED: {
displaySignatureSuccessUncertified();
break;
}
case OpenPgpSignatureResult.SIGNATURE_KEY_EXPIRED: {
displaySignatureKeyExpired();
break;
}
case OpenPgpSignatureResult.SIGNATURE_KEY_REVOKED: {
displaySignatureKeyRevoked();
break;
}
}
}
private void initializeSignatureButton() {
if (noCryptoAnnotationFound()) {
hideSignatureButton();
} else if (isSignatureButtonUsed()) {
setSignatureButtonClickListener();
} else {
hideSignatureButton();
}
}
private boolean isSignatureButtonUsed() {
return cryptoAnnotation.getPendingIntent() != null;
}
private void setSignatureButtonClickListener() {
final PendingIntent pendingIntent = cryptoAnnotation.getPendingIntent();
resultSignatureButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
callback.onPgpSignatureButtonClick(pendingIntent);
}
});
}
private void hideSignatureButton() {
resultSignatureButton.setVisibility(View.GONE);
resultSignatureButton.setOnClickListener(null);
}
private void showSignatureButtonWithTextIfNecessary(@StringRes int stringId) {
if (isSignatureButtonUsed()) {
resultSignatureButton.setVisibility(View.VISIBLE);
resultSignatureButton.setText(stringId);
}
}
private void displayNotSigned() {
setSignatureImageAndTextColor(CryptoState.NOT_SIGNED);
resultSignatureText.setText(R.string.openpgp_result_no_signature);
hideSignatureLayout();
}
private void displaySignatureError() {
setSignatureImageAndTextColor(CryptoState.INVALID);
resultSignatureText.setText(R.string.openpgp_result_invalid_signature);
hideSignatureLayout();
}
private void displaySignatureSuccessCertified() {
setSignatureImageAndTextColor(CryptoState.VERIFIED);
resultSignatureText.setText(R.string.openpgp_result_signature_certified);
displayUserIdAndSignatureButton();
}
private void displaySignatureKeyMissing() {
setSignatureImageAndTextColor(CryptoState.UNKNOWN_KEY);
resultSignatureText.setText(R.string.openpgp_result_signature_missing_key);
setUserId(cryptoAnnotation.getSignatureResult());
showSignatureButtonWithTextIfNecessary(R.string.openpgp_result_action_lookup);
showSignatureLayout();
}
private void displaySignatureSuccessUncertified() {
setSignatureImageAndTextColor(CryptoState.UNVERIFIED);
resultSignatureText.setText(R.string.openpgp_result_signature_uncertified);
displayUserIdAndSignatureButton();
}
private void displaySignatureKeyExpired() {
setSignatureImageAndTextColor(CryptoState.EXPIRED);
resultSignatureText.setText(R.string.openpgp_result_signature_expired_key);
displayUserIdAndSignatureButton();
}
private void displaySignatureKeyRevoked() {
setSignatureImageAndTextColor(CryptoState.REVOKED);
resultSignatureText.setText(R.string.openpgp_result_signature_revoked_key);
displayUserIdAndSignatureButton();
}
private void displayUserIdAndSignatureButton() {
setUserId(cryptoAnnotation.getSignatureResult());
showSignatureButtonWithTextIfNecessary(R.string.openpgp_result_action_show);
showSignatureLayout();
}
private void setUserId(OpenPgpSignatureResult signatureResult) {
final OpenPgpUtils.UserId userInfo = OpenPgpUtils.splitUserId(signatureResult.getPrimaryUserId());
if (userInfo.name != null) {
resultSignatureName.setText(userInfo.name);
} else {
resultSignatureName.setText(R.string.openpgp_result_no_name);
}
if (userInfo.email != null) {
resultSignatureEmail.setText(userInfo.email);
} else {
resultSignatureEmail.setText(R.string.openpgp_result_no_email);
}
}
private void hideSignatureLayout() {
resultSignatureLayout.setVisibility(View.GONE);
}
private void showSignatureLayout() {
resultSignatureLayout.setVisibility(View.VISIBLE);
}
private void setEncryptionImageAndTextColor(CryptoState state) {
setStatusImageAndTextColor(resultEncryptionIcon, resultEncryptionText, state);
}
private void setSignatureImageAndTextColor(CryptoState state) {
setStatusImageAndTextColor(resultSignatureIcon, resultSignatureText, state);
}
private void setStatusImageAndTextColor(ImageView statusIcon, TextView statusText, CryptoState state) {
Drawable statusImageDrawable = context.getResources().getDrawable(state.getDrawableId());
statusIcon.setImageDrawable(statusImageDrawable);
int color = context.getResources().getColor(state.getColorId());
statusIcon.setColorFilter(color, PorterDuff.Mode.SRC_IN);
if (statusText != null) {
statusText.setTextColor(color);
}
}
private enum CryptoState {
VERIFIED(R.drawable.status_signature_verified_cutout, R.color.openpgp_green),
ENCRYPTED(R.drawable.status_lock_closed, R.color.openpgp_green),
UNAVAILABLE(R.drawable.status_signature_unverified_cutout, R.color.openpgp_orange),
UNVERIFIED(R.drawable.status_signature_unverified_cutout, R.color.openpgp_orange),
UNKNOWN_KEY(R.drawable.status_signature_unknown_cutout, R.color.openpgp_orange),
REVOKED(R.drawable.status_signature_revoked_cutout, R.color.openpgp_red),
EXPIRED(R.drawable.status_signature_expired_cutout, R.color.openpgp_red),
NOT_ENCRYPTED(R.drawable.status_lock_open, R.color.openpgp_red),
NOT_SIGNED(R.drawable.status_signature_unknown_cutout, R.color.openpgp_red),
INVALID(R.drawable.status_signature_invalid_cutout, R.color.openpgp_red);
private final int drawableId;
private final int colorId;
CryptoState(@DrawableRes int drawableId, @ColorRes int colorId) {
this.drawableId = drawableId;
this.colorId = colorId;
}
@DrawableRes
public int getDrawableId() {
return drawableId;
}
@ColorRes
public int getColorId() {
return colorId;
}
}
}