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

Unverified Commit a14d0b0b authored by cketti's avatar cketti Committed by GitHub
Browse files

Merge pull request #3276 from k9mail/account-e2e-setting

Revamp e2e settings
parents 3f07313b 7f5d852b
Loading
Loading
Loading
Loading
+46 −8
Original line number Diff line number Diff line
@@ -17,6 +17,8 @@ import java.util.concurrent.ConcurrentHashMap;

import android.content.Context;
import android.net.Uri;
import android.support.annotation.Nullable;
import android.text.TextUtils;

import com.fsck.k9.activity.setup.AccountSetupCheckSettings.CheckDirection;
import com.fsck.k9.helper.Utility;
@@ -201,8 +203,10 @@ public class Account implements BaseAccount, StoreConfig {
    private boolean replyAfterQuote;
    private boolean stripSignature;
    private boolean syncRemoteDeletions;
    private long pgpCryptoKey;
    private String openPgpProvider;
    private long openPgpKey;
    private boolean autocryptPreferEncryptMutual;
    private boolean openPgpHideSignOnly;
    private boolean markMessageAsReadOnView;
    private boolean alwaysShowCcBcc;
    private boolean allowRemoteSearch;
@@ -296,7 +300,7 @@ public class Account implements BaseAccount, StoreConfig {
        replyAfterQuote = DEFAULT_REPLY_AFTER_QUOTE;
        stripSignature = DEFAULT_STRIP_SIGNATURE;
        syncRemoteDeletions = true;
        pgpCryptoKey = NO_OPENPGP_KEY;
        openPgpKey = NO_OPENPGP_KEY;
        allowRemoteSearch = false;
        remoteSearchFullText = false;
        remoteSearchNumResults = DEFAULT_REMOTE_SEARCH_NUM_RESULTS;
@@ -428,7 +432,10 @@ public class Account implements BaseAccount, StoreConfig {
        isSignatureBeforeQuotedText = storage.getBoolean(accountUuid + ".signatureBeforeQuotedText", false);
        identities = loadIdentities(storage);

        pgpCryptoKey = storage.getLong(accountUuid + ".cryptoKey", NO_OPENPGP_KEY);
        openPgpProvider = storage.getString(accountUuid + ".openPgpProvider", "");
        openPgpKey = storage.getLong(accountUuid + ".cryptoKey", NO_OPENPGP_KEY);
        openPgpHideSignOnly = storage.getBoolean(accountUuid + ".openPgpHideSignOnly", true);
        autocryptPreferEncryptMutual = storage.getBoolean(accountUuid + ".autocryptMutualMode", false);
        allowRemoteSearch = storage.getBoolean(accountUuid + ".allowRemoteSearch", false);
        remoteSearchFullText = storage.getBoolean(accountUuid + ".remoteSearchFullText", false);
        remoteSearchNumResults = storage.getInt(accountUuid + ".remoteSearchNumResults", DEFAULT_REMOTE_SEARCH_NUM_RESULTS);
@@ -694,7 +701,10 @@ public class Account implements BaseAccount, StoreConfig {
        editor.putBoolean(accountUuid + ".defaultQuotedTextShown", defaultQuotedTextShown);
        editor.putBoolean(accountUuid + ".replyAfterQuote", replyAfterQuote);
        editor.putBoolean(accountUuid + ".stripSignature", stripSignature);
        editor.putLong(accountUuid + ".cryptoKey", pgpCryptoKey);
        editor.putLong(accountUuid + ".cryptoKey", openPgpKey);
        editor.putBoolean(accountUuid + ".openPgpHideSignOnly", openPgpHideSignOnly);
        editor.putString(accountUuid + ".openPgpProvider", openPgpProvider);
        editor.putBoolean(accountUuid + ".autocryptMutualMode", autocryptPreferEncryptMutual);
        editor.putBoolean(accountUuid + ".allowRemoteSearch", allowRemoteSearch);
        editor.putBoolean(accountUuid + ".remoteSearchFullText", remoteSearchFullText);
        editor.putInt(accountUuid + ".remoteSearchNumResults", remoteSearchNumResults);
@@ -1501,12 +1511,32 @@ public class Account implements BaseAccount, StoreConfig {
        this.stripSignature = stripSignature;
    }

    public long getCryptoKey() {
        return pgpCryptoKey;
    public boolean isOpenPgpProviderConfigured() {
        return !TextUtils.isEmpty(openPgpProvider);
    }

    public void setCryptoKey(long keyId) {
        pgpCryptoKey = keyId;
    @Nullable
    public String getOpenPgpProvider() {
        if (TextUtils.isEmpty(openPgpProvider)) {
            return null;
        }
        return openPgpProvider;
    }

    public void setOpenPgpProvider(String openPgpProvider) {
        this.openPgpProvider = openPgpProvider;
    }

    public long getOpenPgpKey() {
        return openPgpKey;
    }

    public void setOpenPgpKey(long keyId) {
        openPgpKey = keyId;
    }

    public boolean hasOpenPgpKey() {
        return openPgpKey != NO_OPENPGP_KEY;
    }

    public boolean getAutocryptPreferEncryptMutual() {
@@ -1517,6 +1547,14 @@ public class Account implements BaseAccount, StoreConfig {
        this.autocryptPreferEncryptMutual = autocryptPreferEncryptMutual;
    }

    public boolean getOpenPgpHideSignOnly() {
        return openPgpHideSignOnly;
    }

    public void setOpenPgpHideSignOnly(boolean openPgpHideSignOnly) {
        this.openPgpHideSignOnly = openPgpHideSignOnly;
    }

    public boolean allowRemoteSearch() {
        return allowRemoteSearch;
    }
+25 −31
Original line number Diff line number Diff line
@@ -50,6 +50,9 @@ import timber.log.Timber.DebugTree;


public class K9 extends Application {

    public static final int VERSION_MIGRATE_OPENPGP_TO_ACCOUNTS = 63;

    /**
     * Components that are interested in knowing when the K9 instance is
     * available and ready (Android invokes Application.onCreate() after other
@@ -239,9 +242,6 @@ public class K9 extends Application {
    private static boolean hideTimeZone = false;
    private static boolean hideHostnameWhenConnecting = false;

    private static String openPgpProvider = "";
    private static boolean openPgpSupportSignOnly = false;

    private static SortType sortType;
    private static Map<SortType, Boolean> sortAscending = new HashMap<SortType, Boolean>();

@@ -311,8 +311,6 @@ public class K9 extends Application {

    public static final int BOOT_RECEIVER_WAKE_LOCK_TIMEOUT = 60000;

    public static final String NO_OPENPGP_PROVIDER = "";

    public static class Intents {

        public static class EmailReceived {
@@ -479,9 +477,6 @@ public class K9 extends Application {
        editor.putBoolean("hideTimeZone", hideTimeZone);
        editor.putBoolean("hideHostnameWhenConnecting", hideHostnameWhenConnecting);

        editor.putString("openPgpProvider", openPgpProvider);
        editor.putBoolean("openPgpSupportSignOnly", openPgpSupportSignOnly);

        editor.putString("language", language);
        editor.putInt("theme", theme.ordinal());
        editor.putInt("messageViewTheme", messageViewTheme.ordinal());
@@ -669,6 +664,28 @@ public class K9 extends Application {
        if (cachedVersion >= LocalStore.DB_VERSION) {
            K9.setDatabasesUpToDate(false);
        }
        if (cachedVersion < VERSION_MIGRATE_OPENPGP_TO_ACCOUNTS) {
            migrateOpenPgpGlobalToAccountSettings();
        }
    }

    private void migrateOpenPgpGlobalToAccountSettings() {
        Preferences preferences = Preferences.getPreferences(this);
        Storage storage = preferences.getStorage();

        String openPgpProvider = storage.getString("openPgpProvider", null);
        boolean openPgpSupportSignOnly = storage.getBoolean("openPgpSupportSignOnly", false);

        for (Account account : preferences.getAccounts()) {
            account.setOpenPgpProvider(openPgpProvider);
            account.setOpenPgpHideSignOnly(!openPgpSupportSignOnly);
            account.save(preferences);
        }

        storage.edit()
                .remove("openPgpProvider")
                .remove("openPgpSupportSignOnly")
                .commit();
    }

    /**
@@ -716,9 +733,6 @@ public class K9 extends Application {
        hideTimeZone = storage.getBoolean("hideTimeZone", false);
        hideHostnameWhenConnecting = storage.getBoolean("hideHostnameWhenConnecting", false);

        openPgpProvider = storage.getString("openPgpProvider", NO_OPENPGP_PROVIDER);
        openPgpSupportSignOnly = storage.getBoolean("openPgpSupportSignOnly", false);

        confirmDelete = storage.getBoolean("confirmDelete", false);
        confirmDiscardMessage = storage.getBoolean("confirmDiscardMessage", true);
        confirmDeleteStarred = storage.getBoolean("confirmDeleteStarred", false);
@@ -1245,26 +1259,6 @@ public class K9 extends Application {
        hideHostnameWhenConnecting = state;
    }

    public static boolean isOpenPgpProviderConfigured() {
        return !NO_OPENPGP_PROVIDER.equals(openPgpProvider);
    }

    public static String getOpenPgpProvider() {
        return openPgpProvider;
    }

    public static void setOpenPgpProvider(String openPgpProvider) {
        K9.openPgpProvider = openPgpProvider;
    }

    public static boolean getOpenPgpSupportSignOnly() {
        return openPgpSupportSignOnly;
    }

    public static void setOpenPgpSupportSignOnly(boolean supportSignOnly) {
        openPgpSupportSignOnly = supportSignOnly;
    }

    public static String getAttachmentDefaultPath() {
        return attachmentDefaultPath;
    }
+14 −16
Original line number Diff line number Diff line
@@ -14,13 +14,9 @@ import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.annotation.UiThread;

import com.fsck.k9.autocrypt.AutocryptOperations;
import com.fsck.k9.ui.crypto.OpenPgpApiFactory;
import timber.log.Timber;

import com.fsck.k9.Account;
import com.fsck.k9.K9;
import com.fsck.k9.Preferences;
import com.fsck.k9.autocrypt.AutocryptOperations;
import com.fsck.k9.controller.MessagingController;
import com.fsck.k9.controller.MessagingListener;
import com.fsck.k9.controller.SimpleMessagingListener;
@@ -31,9 +27,11 @@ import com.fsck.k9.mailstore.MessageViewInfo;
import com.fsck.k9.ui.crypto.MessageCryptoAnnotations;
import com.fsck.k9.ui.crypto.MessageCryptoCallback;
import com.fsck.k9.ui.crypto.MessageCryptoHelper;
import com.fsck.k9.ui.crypto.OpenPgpApiFactory;
import com.fsck.k9.ui.message.LocalMessageExtractorLoader;
import com.fsck.k9.ui.message.LocalMessageLoader;
import org.openintents.openpgp.OpenPgpDecryptionResult;
import timber.log.Timber;


/** This class is responsible for loading a message start to finish, and
@@ -81,7 +79,6 @@ public class MessageLoaderHelper {
    private LoaderManager loaderManager;
    @Nullable // make this explicitly nullable, make sure to cancel/ignore any operation if this is null
    private MessageLoaderCallbacks callback;
    private final boolean processSignedOnly;


    // transient state
@@ -102,8 +99,6 @@ public class MessageLoaderHelper {
        this.loaderManager = loaderManager;
        this.fragmentManager = fragmentManager;
        this.callback = callback;

        processSignedOnly = K9.getOpenPgpSupportSignOnly();
    }


@@ -144,8 +139,10 @@ public class MessageLoaderHelper {
    public void asyncRestartMessageCryptoProcessing() {
        cancelAndClearCryptoOperation();
        cancelAndClearDecodeLoader();
        if (K9.isOpenPgpProviderConfigured()) {
            startOrResumeCryptoOperation();

        if (account.isOpenPgpProviderConfigured()) {
            String openPgpProvider = account.getOpenPgpProvider();
            startOrResumeCryptoOperation(openPgpProvider);
        } else {
            startOrResumeDecodeMessage();
        }
@@ -231,8 +228,9 @@ public class MessageLoaderHelper {
            return;
        }

        if (K9.isOpenPgpProviderConfigured()) {
            startOrResumeCryptoOperation();
        if (account.isOpenPgpProviderConfigured()) {
            String openPgpProvider = account.getOpenPgpProvider();
            startOrResumeCryptoOperation(openPgpProvider);
            return;
        }

@@ -287,18 +285,18 @@ public class MessageLoaderHelper {

    // process with crypto helper

    private void startOrResumeCryptoOperation() {
    private void startOrResumeCryptoOperation(String openPgpProvider) {
        RetainFragment<MessageCryptoHelper> retainCryptoHelperFragment = getMessageCryptoHelperRetainFragment(true);
        if (retainCryptoHelperFragment.hasData()) {
            messageCryptoHelper = retainCryptoHelperFragment.getData();
        }
        if (messageCryptoHelper == null || messageCryptoHelper.isConfiguredForOutdatedCryptoProvider()) {
        if (messageCryptoHelper == null || !messageCryptoHelper.isConfiguredForOpenPgpProvider(openPgpProvider)) {
            messageCryptoHelper = new MessageCryptoHelper(
                    context, new OpenPgpApiFactory(), AutocryptOperations.getInstance());
                    context, new OpenPgpApiFactory(), AutocryptOperations.getInstance(), openPgpProvider);
            retainCryptoHelperFragment.setData(messageCryptoHelper);
        }
        messageCryptoHelper.asyncStartOrResumeProcessingMessage(
                localMessage, messageCryptoCallback, cachedDecryptionResult, processSignedOnly);
                localMessage, messageCryptoCallback, cachedDecryptionResult, !account.getOpenPgpHideSignOnly());
    }

    private void cancelAndClearCryptoOperation() {
+5 −6
Original line number Diff line number Diff line
@@ -277,7 +277,7 @@ public class RecipientPresenter implements PermissionPingCallback {
            menu.findItem(R.id.openpgp_encrypt_enable).setVisible(!isEncrypting);
            menu.findItem(R.id.openpgp_encrypt_disable).setVisible(isEncrypting);

            boolean showSignOnly = K9.getOpenPgpSupportSignOnly();
            boolean showSignOnly = !account.getOpenPgpHideSignOnly();
            boolean isSignOnly = currentCryptoStatus.isSignOnly();
            menu.findItem(R.id.openpgp_sign_only).setVisible(showSignOnly && !isSignOnly);
            menu.findItem(R.id.openpgp_sign_only_disable).setVisible(showSignOnly && isSignOnly);
@@ -311,7 +311,7 @@ public class RecipientPresenter implements PermissionPingCallback {
        }

        // This does not strictly depend on the account, but this is as good a point to set this as any
        setupCryptoProvider();
        setupCryptoProvider(account.getOpenPgpProvider());
    }

    @SuppressWarnings("UnusedParameters")
@@ -391,7 +391,7 @@ public class RecipientPresenter implements PermissionPingCallback {
            pendingUserInteractionIntent = null;
        }

        Long accountCryptoKey = account.getCryptoKey();
        Long accountCryptoKey = account.getOpenPgpKey();
        if (accountCryptoKey == Account.NO_OPENPGP_KEY) {
            accountCryptoKey = null;
        }
@@ -708,8 +708,7 @@ public class RecipientPresenter implements PermissionPingCallback {
        }
    }

    private void setupCryptoProvider() {
        String openPgpProvider = K9.getOpenPgpProvider();
    private void setupCryptoProvider(String openPgpProvider) {
        if (TextUtils.isEmpty(openPgpProvider)) {
            openPgpProvider = null;
        }
@@ -818,7 +817,7 @@ public class RecipientPresenter implements PermissionPingCallback {
        if (error.getErrorId() == OpenPgpError.INCOMPATIBLE_API_VERSIONS) {
            // nothing we can do here, this is irrecoverable!
            openPgpProvider = null;
            K9.setOpenPgpProvider(null);
            account.setOpenPgpProvider(null);
            recipientMvpView.showErrorOpenPgpIncompatible();
            setCryptoProviderState(CryptoProviderState.UNCONFIGURED);
        } else {
+112 −34
Original line number Diff line number Diff line
@@ -22,6 +22,9 @@ import android.preference.Preference.OnPreferenceChangeListener;
import android.preference.Preference.OnPreferenceClickListener;
import android.preference.PreferenceScreen;
import android.preference.RingtonePreference;
import android.preference.SwitchPreference;
import android.text.TextUtils;
import android.widget.ListAdapter;
import android.widget.Toast;

import com.fsck.k9.Account;
@@ -48,11 +51,13 @@ import com.fsck.k9.service.MailService;
import com.fsck.k9.ui.dialog.AutocryptPreferEncryptDialog;
import com.fsck.k9.ui.dialog.AutocryptPreferEncryptDialog.OnPreferEncryptChangedListener;
import org.openintents.openpgp.util.OpenPgpKeyPreference;
import org.openintents.openpgp.util.OpenPgpProviderUtil;
import timber.log.Timber;


public class AccountSettings extends K9PreferenceActivity {
    private static final String EXTRA_ACCOUNT = "account";
    private static final String EXTRA_SHOW_OPENPGP = "show_openpgp";

    private static final int DIALOG_COLOR_PICKER_ACCOUNT = 1;
    private static final int DIALOG_COLOR_PICKER_LED = 2;
@@ -110,8 +115,10 @@ public class AccountSettings extends K9PreferenceActivity {
    private static final String PREFERENCE_REPLY_AFTER_QUOTE = "reply_after_quote";
    private static final String PREFERENCE_STRIP_SIGNATURE = "strip_signature";
    private static final String PREFERENCE_SYNC_REMOTE_DELETIONS = "account_sync_remote_deletetions";
    private static final String PREFERENCE_CRYPTO = "crypto";
    private static final String PREFERENCE_CRYPTO_KEY = "crypto_key";
    private static final String PREFERENCE_CRYPTO = "openpgp";
    private static final String PREFERENCE_CRYPTO_PROVIDER = "openpgp_provider";
    private static final String PREFERENCE_CRYPTO_KEY = "openpgp_key";
    private static final String PREFERENCE_CRYPTO_HIDE_SIGN_ONLY = "openpgp_hide_sign_only";
    private static final String PREFERENCE_AUTOCRYPT_PREFER_ENCRYPT = "autocrypt_prefer_encrypt";
    private static final String PREFERENCE_CLOUD_SEARCH_ENABLED = "remote_search_enabled";
    private static final String PREFERENCE_REMOTE_SEARCH_NUM_RESULTS = "account_remote_search_num_results";
@@ -177,9 +184,9 @@ public class AccountSettings extends K9PreferenceActivity {
    private CheckBoxPreference pushPollOnConnect;
    private ListPreference idleRefreshPeriod;
    private ListPreference mMaxPushFolders;
    private boolean hasPgpCrypto = false;
    private OpenPgpKeyPreference pgpCryptoKey;
    private Preference autocryptPreferEncryptMutual;
    private SwitchPreference pgpHideSignOnly;

    private PreferenceScreen searchScreen;
    private CheckBoxPreference cloudSearchEnabled;
@@ -198,6 +205,7 @@ public class AccountSettings extends K9PreferenceActivity {
    private ListPreference spamFolder;
    private ListPreference trashFolder;
    private CheckBoxPreference alwaysShowCcBcc;
    private SwitchPreference pgpEnable;


    public static void actionSettings(Context context, Account account) {
@@ -206,12 +214,20 @@ public class AccountSettings extends K9PreferenceActivity {
        context.startActivity(i);
    }

    public static void actionSettingsOpenPgp(Context context, Account account) {
        Intent i = new Intent(context, AccountSettings.class);
        i.putExtra(EXTRA_ACCOUNT, account.getUuid());
        i.putExtra(EXTRA_SHOW_OPENPGP, true);
        context.startActivity(i);
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        String accountUuid = getIntent().getStringExtra(EXTRA_ACCOUNT);
        account = Preferences.getPreferences(this).getAccount(accountUuid);
        boolean startInOpenPgp = getIntent().getBooleanExtra(EXTRA_SHOW_OPENPGP, false);

        try {
            RemoteStore store = account.getRemoteStore();
@@ -694,48 +710,100 @@ public class AccountSettings extends K9PreferenceActivity {
            }
        });

        hasPgpCrypto = K9.isOpenPgpProviderConfigured();
        PreferenceScreen cryptoMenu = (PreferenceScreen) findPreference(PREFERENCE_CRYPTO);
        if (hasPgpCrypto) {
            pgpCryptoKey = (OpenPgpKeyPreference) findPreference(PREFERENCE_CRYPTO_KEY);

            pgpCryptoKey.setValue(account.getCryptoKey());
            pgpCryptoKey.setOpenPgpProvider(K9.getOpenPgpProvider());
            // TODO: other identities?
            pgpCryptoKey.setDefaultUserId(OpenPgpApiHelper.buildUserId(account.getIdentity(0)));
            pgpCryptoKey.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
                public boolean onPreferenceChange(Preference preference, Object newValue) {
                    long value = (Long) newValue;
                    pgpCryptoKey.setValue(value);
                    return false;
        if (savedInstanceState == null && startInOpenPgp) {
            PreferenceScreen preference = (PreferenceScreen) findPreference(PREFERENCE_CRYPTO);
            goToPreferenceScreen(preference);
        }
    }
            });

            cryptoMenu.setOnPreferenceClickListener(null);
    @Override
    protected void onResume() {
        super.onResume();

        // we might return here from the play store, so it's important we refresh on resume
        setupCryptoSettings();
    }

    private void setupCryptoSettings() {
        pgpEnable = (SwitchPreference) findPreference(PREFERENCE_CRYPTO_PROVIDER);
        pgpCryptoKey = (OpenPgpKeyPreference) findPreference(PREFERENCE_CRYPTO_KEY);
        autocryptPreferEncryptMutual = findPreference(PREFERENCE_AUTOCRYPT_PREFER_ENCRYPT);
            autocryptPreferEncryptMutual.setOnPreferenceClickListener(new OnPreferenceClickListener() {
        pgpHideSignOnly = (SwitchPreference) findPreference(PREFERENCE_CRYPTO_HIDE_SIGN_ONLY);

        String pgpProvider = account.getOpenPgpProvider();
        String pgpProviderName = null;
        boolean isPgpConfigured = account.isOpenPgpProviderConfigured();
        boolean isKeyConfigured = account.hasOpenPgpKey();

        if (isPgpConfigured) {
            pgpProviderName = OpenPgpProviderUtil.getOpenPgpProviderName(getPackageManager(), pgpProvider);

            if (pgpProviderName == null) {
                Toast.makeText(this, R.string.account_settings_openpgp_missing, Toast.LENGTH_LONG).show();
                account.setOpenPgpProvider(null);
                pgpProvider = null;
                isPgpConfigured = false;
            }
        }

        if (!isPgpConfigured) {
            pgpEnable.setChecked(false);
            pgpEnable.setSummary(R.string.account_settings_crypto_summary_off);
            pgpEnable.setOnPreferenceClickListener(new OnPreferenceClickListener() {
                @Override
                public boolean onPreferenceClick(Preference preference) {
                    showDialog(DIALOG_AUTOCRYPT_PREFER_ENCRYPT);
                    pgpEnable.setOnPreferenceClickListener(null);
                    List<String> openPgpProviderPackages =
                            OpenPgpProviderUtil.getOpenPgpProviderPackages(getApplicationContext());
                    if (openPgpProviderPackages.size() == 1) {
                        account.setOpenPgpProvider(openPgpProviderPackages.get(0));
                        setupCryptoSettings();
                    } else {
                        OpenPgpAppSelectDialog.startOpenPgpChooserActivity(AccountSettings.this, account);
                    }
                    return false;
                }
            });
        } else {
            cryptoMenu.setSummary(R.string.account_settings_no_openpgp_provider_configured);
            cryptoMenu.setOnPreferenceClickListener(new OnPreferenceClickListener() {
            pgpEnable.setChecked(true);
            pgpEnable.setSummary(getString(R.string.account_settings_crypto_summary_on, pgpProviderName));
            pgpEnable.setOnPreferenceClickListener(new OnPreferenceClickListener() {
                @Override
                public boolean onPreferenceClick(Preference preference) {
                    Dialog dialog = ((PreferenceScreen) preference).getDialog();
                    if (dialog != null) {
                        dialog.dismiss();
                    }
                    Toast.makeText(AccountSettings.this,
                            R.string.no_crypto_provider_see_global, Toast.LENGTH_SHORT).show();
                    pgpEnable.setOnPreferenceClickListener(null);
                    account.setOpenPgpProvider(null);
                    setupCryptoSettings();
                    return true;
                }
            });

            pgpCryptoKey.setOpenPgpProvider(pgpProvider);
        }

        pgpCryptoKey.setEnabled(isPgpConfigured);
        pgpCryptoKey.setValue(account.getOpenPgpKey());
        pgpCryptoKey.setDefaultUserId(OpenPgpApiHelper.buildUserId(account.getIdentity(0)));
        pgpCryptoKey.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
            public boolean onPreferenceChange(Preference preference, Object newValue) {
                long value = (Long) newValue;
                account.setOpenPgpKey(value);
                setupCryptoSettings();
                return false;
            }
        });

        autocryptPreferEncryptMutual.setEnabled(isPgpConfigured && isKeyConfigured);
        autocryptPreferEncryptMutual.setOnPreferenceClickListener(new OnPreferenceClickListener() {
            @Override
            public boolean onPreferenceClick(Preference preference) {
                showDialog(DIALOG_AUTOCRYPT_PREFER_ENCRYPT);
                return false;
            }
        });

        pgpHideSignOnly.setEnabled(isPgpConfigured && isKeyConfigured);
        pgpHideSignOnly = (SwitchPreference) findPreference(PREFERENCE_CRYPTO_HIDE_SIGN_ONLY);
        pgpHideSignOnly.setChecked(account.getOpenPgpHideSignOnly());
    }

    private void removeListEntry(ListPreference listPreference, String remove) {
@@ -796,11 +864,10 @@ public class AccountSettings extends K9PreferenceActivity {
        account.setReplyAfterQuote(replyAfterQuote.isChecked());
        account.setStripSignature(stripSignature.isChecked());
        account.setLocalStorageProviderId(localStorageProvider.getValue());
        if (hasPgpCrypto) {
            account.setCryptoKey(pgpCryptoKey.getValue());
        } else {
            account.setCryptoKey(Account.NO_OPENPGP_KEY);
        if (pgpCryptoKey != null) {
            account.setOpenPgpKey(pgpCryptoKey.getValue());
        }
        account.setOpenPgpHideSignOnly(pgpHideSignOnly.isChecked());

        account.setAutoExpandFolder(autoExpandFolder.getValue());

@@ -990,6 +1057,17 @@ public class AccountSettings extends K9PreferenceActivity {
        }
    }

    private void goToPreferenceScreen(PreferenceScreen preference) {
        PreferenceScreen preferenceScreen = getPreferenceScreen();
        ListAdapter listAdapter = preferenceScreen.getRootAdapter();
        for (int itemNumber = 0; itemNumber < listAdapter.getCount(); itemNumber++) {
            if (listAdapter.getItem(itemNumber).equals(preference)) {
                preferenceScreen.onItemClick(null, null, itemNumber, 0);
                break;
            }
        }
    }

    private class PopulateFolderPrefsTask extends AsyncTask<Void, Void, Void> {
        List <? extends Folder > folders = new LinkedList<>();
        String[] allFolderValues;
Loading