introduce error dialog when moving from crypto enabled to keys unavailable state

This commit is contained in:
Vincent Breitmoser 2017-06-24 17:53:37 +02:00
parent f4d8425007
commit 58c1ee6ef5
7 changed files with 147 additions and 27 deletions

View file

@ -57,6 +57,7 @@ import com.fsck.k9.activity.compose.ComposeCryptoStatus;
import com.fsck.k9.activity.compose.ComposeCryptoStatus.SendErrorState;
import com.fsck.k9.activity.compose.IdentityAdapter;
import com.fsck.k9.activity.compose.IdentityAdapter.IdentityContainer;
import com.fsck.k9.activity.compose.PgpEnabledErrorDialog.OnOpenPgpDisableListener;
import com.fsck.k9.activity.compose.PgpInlineDialog.OnOpenPgpInlineChangeListener;
import com.fsck.k9.activity.compose.PgpSignOnlyDialog.OnOpenPgpSignOnlyChangeListener;
import com.fsck.k9.activity.compose.RecipientMvpView;
@ -104,7 +105,8 @@ import timber.log.Timber;
public class MessageCompose extends K9Activity implements OnClickListener,
CancelListener, AttachmentDownloadCancelListener, OnFocusChangeListener,
OnOpenPgpInlineChangeListener, OnOpenPgpSignOnlyChangeListener, MessageBuilder.Callback,
AttachmentPresenter.AttachmentsChangedListener, RecipientPresenter.RecipientsChangedListener {
AttachmentPresenter.AttachmentsChangedListener, RecipientPresenter.RecipientsChangedListener,
OnOpenPgpDisableListener {
private static final int DIALOG_SAVE_OR_DISCARD_DRAFT_MESSAGE = 1;
private static final int DIALOG_CONFIRM_DISCARD_ON_BACK = 2;
@ -900,6 +902,12 @@ public class MessageCompose extends K9Activity implements OnClickListener,
public void onOpenPgpSignOnlyChange(boolean enabled) {
recipientPresenter.onCryptoPgpSignOnlyDisabled();
}
@Override
public void onOpenPgpClickDisable() {
recipientPresenter.onCryptoPgpClickDisable();
}
@Override
public void onAttachmentAdded() {
changesMadeSinceLastSave = true;

View file

@ -63,16 +63,18 @@ public class ComposeCryptoStatus {
} else {
return CryptoStatusDisplayType.CHOICE_ENABLED_UNTRUSTED;
}
}
throw new IllegalStateException("crypto enabled while unavailable!");
case CHOICE_DISABLED:
if (!recipientAutocryptStatus.isMutual()) {
throw new IllegalStateException("crypto disabled while not mutual!");
}
if (recipientAutocryptStatus.isConfirmed()) {
return CryptoStatusDisplayType.CHOICE_DISABLED_TRUSTED;
} else {
return CryptoStatusDisplayType.CHOICE_DISABLED_UNTRUSTED;
return CryptoStatusDisplayType.CHOICE_ENABLED_ERROR;
}
case CHOICE_DISABLED:
if (recipientAutocryptStatus.canEncrypt()) {
if (recipientAutocryptStatus.isConfirmed()) {
return CryptoStatusDisplayType.CHOICE_DISABLED_TRUSTED;
} else {
return CryptoStatusDisplayType.CHOICE_DISABLED_UNTRUSTED;
}
} else {
return CryptoStatusDisplayType.CHOICE_DISABLED_UNAVAILABLE;
}
case NO_CHOICE:
if (recipientAutocryptStatus == RecipientAutocryptStatus.NO_RECIPIENTS) {
@ -139,7 +141,7 @@ public class ComposeCryptoStatus {
return cryptoProviderState == CryptoProviderState.OK;
}
public boolean canEncrypt() {
boolean canEncrypt() {
return recipientAutocryptStatus != null && recipientAutocryptStatus.canEncrypt();
}
@ -151,10 +153,14 @@ public class ComposeCryptoStatus {
return recipientAddresses.length > 0;
}
public boolean canEncryptAndIsMutual() {
boolean canEncryptAndIsMutual() {
return canEncrypt() && recipientAutocryptStatus.isMutual();
}
boolean isEncryptionEnabledError() {
return isEncryptionEnabled() && !canEncrypt();
}
public static class ComposeCryptoStatusBuilder {
private CryptoProviderState cryptoProviderState;
@ -237,7 +243,8 @@ public class ComposeCryptoStatus {
}
public enum SendErrorState {
PROVIDER_ERROR
PROVIDER_ERROR,
ENABLED_ERROR
}
public SendErrorState getSendErrorStateOrNull() {
@ -246,6 +253,10 @@ public class ComposeCryptoStatus {
return SendErrorState.PROVIDER_ERROR;
}
if (isEncryptionEnabledError()) {
return SendErrorState.ENABLED_ERROR;
}
return null;
}

View file

@ -0,0 +1,65 @@
package com.fsck.k9.activity.compose;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.os.Bundle;
import android.support.annotation.IdRes;
import android.view.LayoutInflater;
import android.view.View;
import com.fsck.k9.R;
import com.fsck.k9.view.HighlightDialogFragment;
public class PgpEnabledErrorDialog extends HighlightDialogFragment {
public static PgpEnabledErrorDialog newInstance(@IdRes int showcaseView) {
PgpEnabledErrorDialog dialog = new PgpEnabledErrorDialog();
Bundle args = new Bundle();
args.putInt(ARG_HIGHLIGHT_VIEW, showcaseView);
dialog.setArguments(args);
return dialog;
}
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
Activity activity = getActivity();
@SuppressLint("InflateParams")
View view = LayoutInflater.from(activity).inflate(R.layout.openpgp_enabled_error_dialog, null);
AlertDialog.Builder builder = new AlertDialog.Builder(activity);
builder.setView(view);
builder.setNegativeButton("Back", new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
builder.setPositiveButton("Disable Encryption", new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Activity activity = getActivity();
if (activity == null) {
return;
}
((OnOpenPgpDisableListener) activity).onOpenPgpClickDisable();
dialog.dismiss();
}
});
return builder.create();
}
public interface OnOpenPgpDisableListener {
void onOpenPgpClickDisable();
}
}

View file

@ -347,10 +347,6 @@ public class RecipientMvpView implements OnFocusChangeListener, OnClickListener
Toast.makeText(activity, R.string.compose_error_no_signing_key, Toast.LENGTH_LONG).show();
}
public void showErrorPrivateButMissingKeys() {
Toast.makeText(activity, R.string.compose_error_private_missing_keys, Toast.LENGTH_LONG).show();
}
public void showErrorInlineAttach() {
Toast.makeText(activity, R.string.error_crypto_inline_attach, Toast.LENGTH_LONG).show();
}
@ -416,6 +412,11 @@ public class RecipientMvpView implements OnFocusChangeListener, OnClickListener
dialog.show(activity.getFragmentManager(), "openpgp_signonly");
}
public void showOpenPgpEnabledErrorDialog() {
PgpEnabledErrorDialog dialog = PgpEnabledErrorDialog.newInstance(R.id.crypto_status);
dialog.show(activity.getFragmentManager(), "openpgp_error");
}
public void showOpenPgpEncryptExplanationDialog() {
PgpEncryptDescriptionDialog dialog = PgpEncryptDescriptionDialog.newInstance(R.id.crypto_status);
dialog.show(activity.getFragmentManager(), "openpgp_description");
@ -443,8 +444,10 @@ public class RecipientMvpView implements OnFocusChangeListener, OnClickListener
NO_CHOICE_MUTUAL_TRUSTED(R.id.crypto_status_trusted),
CHOICE_ENABLED_UNTRUSTED(R.id.crypto_status_enabled),
CHOICE_ENABLED_TRUSTED(R.id.crypto_status_trusted),
CHOICE_ENABLED_ERROR(R.id.crypto_status_error),
CHOICE_DISABLED_UNTRUSTED(R.id.crypto_status_disabled),
CHOICE_DISABLED_TRUSTED(R.id.crypto_status_disabled),
CHOICE_DISABLED_UNAVAILABLE(VIEW_INDEX_HIDDEN),
ERROR(R.id.crypto_status_error);

View file

@ -410,12 +410,6 @@ public class RecipientPresenter implements PermissionPingCallback {
@Override
protected void onPostExecute(RecipientAutocryptStatus recipientAutocryptStatus) {
if (recipientAutocryptStatus != null) {
if (!recipientAutocryptStatus.canEncrypt() && composeCryptoStatus.isEncryptionEnabled()) {
currentCryptoMode = CryptoMode.NO_CHOICE;
asyncUpdateCryptoStatus();
return;
}
cachedCryptoStatus = composeCryptoStatus.withRecipientAutocryptStatus(recipientAutocryptStatus);
} else {
cachedCryptoStatus = composeCryptoStatus;
@ -613,12 +607,13 @@ public class RecipientPresenter implements PermissionPingCallback {
Timber.e("click on crypto status while unconfigured - this should not really happen?!");
return;
case OK:
if (cachedCryptoStatus == null) {
ComposeCryptoStatus currentCryptoStatus = getCurrentCachedCryptoStatus();
if (currentCryptoStatus == null) {
Timber.e("click on crypto status while crypto status not available - should not really happen?!");
return;
}
if (currentCryptoStatus.isEncryptionEnabled() && !currentCryptoStatus.canEncrypt()) {
if (currentCryptoStatus.isEncryptionEnabledError()) {
recipientMvpView.showOpenPgpEnabledErrorDialog();
return;
}
@ -626,11 +621,14 @@ public class RecipientPresenter implements PermissionPingCallback {
if (currentCryptoMode == CryptoMode.SIGN_ONLY) {
recipientMvpView.showErrorIsSignOnly();
} else if (currentCryptoMode == CryptoMode.NO_CHOICE) {
if (cachedCryptoStatus.canEncryptAndIsMutual()) {
if (currentCryptoStatus.canEncryptAndIsMutual()) {
onCryptoModeChanged(CryptoMode.CHOICE_DISABLED);
} else {
onCryptoModeChanged(CryptoMode.CHOICE_ENABLED);
}
} else if (currentCryptoMode == CryptoMode.CHOICE_DISABLED &&
!currentCryptoStatus.canEncryptAndIsMutual()) {
onCryptoModeChanged(CryptoMode.CHOICE_ENABLED);
} else {
onCryptoModeChanged(CryptoMode.NO_CHOICE);
}
@ -664,6 +662,9 @@ public class RecipientPresenter implements PermissionPingCallback {
public void showPgpSendError(SendErrorState sendErrorState) {
switch (sendErrorState) {
case ENABLED_ERROR:
recipientMvpView.showOpenPgpEnabledErrorDialog();
break;
case PROVIDER_ERROR:
recipientMvpView.showErrorOpenPgpConnection();
break;
@ -853,6 +854,10 @@ public class RecipientPresenter implements PermissionPingCallback {
}
}
public void onCryptoPgpClickDisable() {
onCryptoModeChanged(CryptoMode.NO_CHOICE);
}
public void onCryptoPgpSignOnlyDisabled() {
onCryptoPgpInlineChanged(false);
onCryptoModeChanged(CryptoMode.NO_CHOICE);

View file

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingLeft="24dp"
android:paddingRight="24dp"
android:paddingTop="24dp"
android:paddingBottom="24dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="20dp"
android:textAppearance="?android:textAppearanceLarge"
android:text="@string/openpgp_enabled_error_title"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:textAppearanceSmall"
android:text="@string/openpgp_enabled_error_msg"
style="?android:textAppearanceMedium"
/>
</LinearLayout>

View file

@ -1143,7 +1143,6 @@ Please submit bug reports, contribute new features and ask questions at
<string name="address_type_mobile">Mobile</string>
<string name="compose_error_no_draft_folder">No Drafts folder configured for this account!</string>
<string name="compose_error_no_signing_key">No key configured for signing! Please check your settings.</string>
<string name="compose_error_private_missing_keys">Private mode is enabled, but some recipients do not have keys!</string>
<string name="crypto_mode_disabled">Don\'t encrypt</string>
<string name="crypto_mode_opportunistic">Encrypt if possible</string>
<string name="crypto_mode_private">Encrypt</string>
@ -1243,6 +1242,8 @@ Please submit bug reports, contribute new features and ask questions at
<string name="messageview_crypto_warning_details">Show Details</string>
<string name="error_recipient_crypto_retrieve">Error retrieving recipient status from OpenPGP provider!</string>
<string name="openpgp_enabled_error_title">Encryption not possible</string>
<string name="openpgp_enabled_error_msg">Some of the selected recipients don\'t support this feature!</string>
<string name="enable_encryption">Enable Encryption</string>
<string name="disable_encryption">Disable Encryption</string>
<string name="openpgp_description_text1">Encrypting messages ensures they can be read by the recipient, and nobody else.</string>