introduce error dialog when moving from crypto enabled to keys unavailable state
This commit is contained in:
parent
f4d8425007
commit
58c1ee6ef5
7 changed files with 147 additions and 27 deletions
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
27
k9mail/src/main/res/layout/openpgp_enabled_error_dialog.xml
Normal file
27
k9mail/src/main/res/layout/openpgp_enabled_error_dialog.xml
Normal 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>
|
|
@ -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>
|
||||
|
|
Loading…
Reference in a new issue