diff --git a/app/k9mail/src/main/AndroidManifest.xml b/app/k9mail/src/main/AndroidManifest.xml index 14b327a487..994b8a0b67 100644 --- a/app/k9mail/src/main/AndroidManifest.xml +++ b/app/k9mail/src/main/AndroidManifest.xml @@ -72,11 +72,6 @@ android:configChanges="locale" android:label="@string/account_settings_composition_title"/> - - parent, View view, int position, - long id) { - - /* - * We keep our own record of the spinner state so we - * know for sure that onItemSelected() was called - * because of user input, not because of spinner - * state initialization. This assures that the port - * will not be replaced with a default value except - * on user input. - */ - if (mCurrentSecurityTypeViewPosition != position) { - updatePortFromSecurityType(); - updateViewFromSecurity(); - boolean isInsecure = (ConnectionSecurity.NONE == getSelectedSecurity()); - boolean isAuthExternal = (AuthType.EXTERNAL == getSelectedAuthType()); - boolean loginNotRequired = !mRequireLoginView.isChecked(); - - /* - * If the user selects ConnectionSecurity.NONE, a - * warning would normally pop up if the authentication - * is AuthType.EXTERNAL (i.e., using client - * certificates). But such a warning is irrelevant if - * login is not required. So to avoid such a warning - * (generated in validateFields()) under those - * conditions, we change the (irrelevant) authentication - * method to PLAIN. - */ - if (isInsecure && isAuthExternal && loginNotRequired) { - OnItemSelectedListener onItemSelectedListener = mAuthTypeView.getOnItemSelectedListener(); - mAuthTypeView.setOnItemSelectedListener(null); - mCurrentAuthTypeViewPosition = mAuthTypeAdapter.getAuthPosition(AuthType.PLAIN); - mAuthTypeView.setSelection(mCurrentAuthTypeViewPosition, false); - mAuthTypeView.setOnItemSelectedListener(onItemSelectedListener); - updateViewFromAuthType(); - } - - validateFields(); - } - } - - @Override - public void onNothingSelected(AdapterView parent) { /* unused */ } - }); - - mAuthTypeView.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { - @Override - public void onItemSelected(AdapterView parent, View view, int position, - long id) { - if (mCurrentAuthTypeViewPosition == position) { - return; - } - - updateViewFromAuthType(); - updateViewFromSecurity(); - validateFields(); - AuthType selection = getSelectedAuthType(); - - // Have the user select the client certificate if not already selected - if ((AuthType.EXTERNAL == selection) && (mClientCertificateSpinner.getAlias() == null)) { - // This may again invoke validateFields() - mClientCertificateSpinner.chooseCertificate(); - } else { - mPasswordView.requestFocus(); - } - } - - @Override - public void onNothingSelected(AdapterView parent) { /* unused */ } - }); - - mRequireLoginView.setOnCheckedChangeListener(this); - mClientCertificateSpinner.setOnClientCertificateChangedListener(clientCertificateChangedListener); - mUsernameView.addTextChangedListener(validationTextWatcher); - mPasswordView.addTextChangedListener(validationTextWatcher); - mServerView.addTextChangedListener(validationTextWatcher); - mPortView.addTextChangedListener(validationTextWatcher); - - TextInputLayoutHelper.configureAuthenticatedPasswordToggle( - mPasswordLayoutView, - this, - getString(R.string.account_setup_basics_show_password_biometrics_title), - getString(R.string.account_setup_basics_show_password_biometrics_subtitle), - getString(R.string.account_setup_basics_show_password_need_lock) - ); - } - - @Override - public void onSaveInstanceState(@NonNull Bundle outState) { - super.onSaveInstanceState(outState); - outState.putString(EXTRA_ACCOUNT, mAccount.getUuid()); - outState.putInt(STATE_SECURITY_TYPE_POSITION, mCurrentSecurityTypeViewPosition); - outState.putInt(STATE_AUTH_TYPE_POSITION, mCurrentAuthTypeViewPosition); - } - - @Override - protected void onRestoreInstanceState(Bundle savedInstanceState) { - super.onRestoreInstanceState(savedInstanceState); - - if (mRequireLoginView.isChecked()) { - mRequireLoginSettingsView.setVisibility(View.VISIBLE); - } else { - mRequireLoginSettingsView.setVisibility(View.GONE); - } - } - - @Override - protected void onPostCreate(Bundle savedInstanceState) { - super.onPostCreate(savedInstanceState); - - /* - * We didn't want the listeners active while the state was being restored - * because they could overwrite the restored port with a default port when - * the security type was restored. - */ - initializeViewListeners(); - validateFields(); - } - - @Override - public boolean onOptionsItemSelected(@NonNull MenuItem item) { - if (item.getItemId() == android.R.id.home) { - onBackPressed(); - return true; - } - - return super.onOptionsItemSelected(item); - } - - /** - * Shows/hides password field - */ - private void updateViewFromAuthType() { - switch (getSelectedAuthType()) { - case EXTERNAL: - case XOAUTH2: - mPasswordLayoutView.setVisibility(View.GONE); - break; - default: - mPasswordLayoutView.setVisibility(View.VISIBLE); - break; - } - } - - /** - * Shows/hides client certificate spinner - */ - private void updateViewFromSecurity() { - ConnectionSecurity security = getSelectedSecurity(); - boolean isUsingTLS = ((ConnectionSecurity.SSL_TLS_REQUIRED == security) || (ConnectionSecurity.STARTTLS_REQUIRED == security)); - boolean isUsingOAuth = getSelectedAuthType() == AuthType.XOAUTH2; - - if (isUsingTLS && !isUsingOAuth) { - mAllowClientCertificateView.setVisibility(View.VISIBLE); - } else { - mAllowClientCertificateView.setVisibility(View.GONE); - } - } - - - /** - * This is invoked only when the user makes changes to a widget, not when - * widgets are changed programmatically. (The logic is simpler when you know - * that this is the last thing called after an input change.) - */ - private void validateFields() { - AuthType authType = getSelectedAuthType(); - boolean isAuthTypeExternal = (AuthType.EXTERNAL == authType); - - ConnectionSecurity connectionSecurity = getSelectedSecurity(); - boolean hasConnectionSecurity = (connectionSecurity != ConnectionSecurity.NONE); - - if (isAuthTypeExternal && !hasConnectionSecurity) { - - // Notify user of an invalid combination of AuthType.EXTERNAL & ConnectionSecurity.NONE - String toastText = getString(R.string.account_setup_outgoing_invalid_setting_combo_notice, - getString(R.string.account_setup_incoming_auth_type_label), - AuthType.EXTERNAL.toString(), - getString(R.string.account_setup_incoming_security_label), - ConnectionSecurity.NONE.toString()); - Toast.makeText(this, toastText, Toast.LENGTH_LONG).show(); - - // Reset the views back to their previous settings without recursing through here again - OnItemSelectedListener onItemSelectedListener = mAuthTypeView.getOnItemSelectedListener(); - mAuthTypeView.setOnItemSelectedListener(null); - mAuthTypeView.setSelection(mCurrentAuthTypeViewPosition, false); - mAuthTypeView.setOnItemSelectedListener(onItemSelectedListener); - updateViewFromAuthType(); - updateViewFromSecurity(); - - onItemSelectedListener = mSecurityTypeView.getOnItemSelectedListener(); - mSecurityTypeView.setOnItemSelectedListener(null); - mSecurityTypeView.setSelection(mCurrentSecurityTypeViewPosition, false); - mSecurityTypeView.setOnItemSelectedListener(onItemSelectedListener); - updateAuthPlainTextFromSecurityType(getSelectedSecurity()); - - mPortView.removeTextChangedListener(validationTextWatcher); - mPortView.setText(mCurrentPortViewSetting); - mPortView.addTextChangedListener(validationTextWatcher); - - authType = getSelectedAuthType(); - isAuthTypeExternal = (AuthType.EXTERNAL == authType); - - connectionSecurity = getSelectedSecurity(); - hasConnectionSecurity = (connectionSecurity != ConnectionSecurity.NONE); - } else { - mCurrentAuthTypeViewPosition = mAuthTypeView.getSelectedItemPosition(); - mCurrentSecurityTypeViewPosition = mSecurityTypeView.getSelectedItemPosition(); - mCurrentPortViewSetting = mPortView.getText().toString(); - } - - boolean hasValidCertificateAlias = mClientCertificateSpinner.getAlias() != null; - boolean hasValidUserName = Utility.requiredFieldValid(mUsernameView); - - boolean hasValidPasswordSettings = hasValidUserName - && !isAuthTypeExternal - && Utility.requiredFieldValid(mPasswordView); - - boolean hasValidExternalAuthSettings = hasValidUserName - && isAuthTypeExternal - && hasConnectionSecurity - && hasValidCertificateAlias; - - boolean hasValidOAuthSettings = hasValidUserName - && hasConnectionSecurity - && authType == AuthType.XOAUTH2; - - mNextButton - .setEnabled(Utility.domainFieldValid(mServerView) - && Utility.requiredFieldValid(mPortView) - && (!mRequireLoginView.isChecked() - || hasValidPasswordSettings || hasValidExternalAuthSettings || hasValidOAuthSettings)); - Utility.setCompoundDrawablesAlpha(mNextButton, mNextButton.isEnabled() ? 255 : 128); - } - - private void updatePortFromSecurityType() { - ConnectionSecurity securityType = getSelectedSecurity(); - updateAuthPlainTextFromSecurityType(securityType); - - // Remove listener so as not to trigger validateFields() which is called - // elsewhere as a result of user interaction. - mPortView.removeTextChangedListener(validationTextWatcher); - mPortView.setText(String.valueOf(accountCreatorHelper.getDefaultPort(securityType, Protocols.SMTP))); - mPortView.addTextChangedListener(validationTextWatcher); - } - - private void updateAuthPlainTextFromSecurityType(ConnectionSecurity securityType) { - mAuthTypeAdapter.useInsecureText(securityType == ConnectionSecurity.NONE); - } - - @Override - public void onActivityResult(int requestCode, int resultCode, Intent data) { - if (requestCode != AccountSetupCheckSettings.ACTIVITY_REQUEST_CODE) { - super.onActivityResult(requestCode, resultCode, data); - return; - } - - if (resultCode == RESULT_OK) { - Preferences.getPreferences().saveAccount(mAccount); - finish(); - } - } - - protected void onNext() { - ConnectionSecurity securityType = getSelectedSecurity(); - String username = ""; - String password = null; - String clientCertificateAlias = null; - AuthType authType = AuthType.AUTOMATIC; - if ((ConnectionSecurity.STARTTLS_REQUIRED == securityType) || - (ConnectionSecurity.SSL_TLS_REQUIRED == securityType)) { - clientCertificateAlias = mClientCertificateSpinner.getAlias(); - } - if (mRequireLoginView.isChecked()) { - username = mUsernameView.getText().toString().trim(); - authType = getSelectedAuthType(); - - if (AuthType.EXTERNAL != authType) { - password = mPasswordView.getText().toString(); - } - } - - String newHost = mServerView.getText().toString(); - int newPort = Integer.parseInt(mPortView.getText().toString()); - ServerSettings server = new ServerSettings(Protocols.SMTP, newHost, newPort, securityType, authType, username, - password, clientCertificateAlias); - DI.get(LocalKeyStoreManager.class).deleteCertificate(mAccount, newHost, newPort, MailServerDirection.OUTGOING); - mAccount.setOutgoingServerSettings(server); - AccountSetupCheckSettings.actionCheckSettings(this, mAccount, CheckDirection.OUTGOING); - } - - public void onClick(View v) { - if (v.getId() == R.id.next) { - onNext(); - } - } - - public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { - mRequireLoginSettingsView.setVisibility(isChecked ? View.VISIBLE : View.GONE); - validateFields(); - } - - private void failure(Exception use) { - Timber.e(use, "Failure"); - String toastText = getString(R.string.account_setup_bad_uri, use.getMessage()); - - Toast toast = Toast.makeText(getApplication(), toastText, Toast.LENGTH_LONG); - toast.show(); - } - - /* - * Calls validateFields() which enables or disables the Next button - * based on the fields' validity. - */ - TextWatcher validationTextWatcher = new TextWatcher() { - public void afterTextChanged(Editable s) { - validateFields(); - } - - public void beforeTextChanged(CharSequence s, int start, int count, int after) { - } - - public void onTextChanged(CharSequence s, int start, int before, int count) { - } - }; - - OnClientCertificateChangedListener clientCertificateChangedListener = alias -> validateFields(); - - private AuthType getSelectedAuthType() { - AuthTypeHolder holder = (AuthTypeHolder) mAuthTypeView.getSelectedItem(); - return holder.authType; - } - - private ConnectionSecurity getSelectedSecurity() { - ConnectionSecurityHolder holder = (ConnectionSecurityHolder) mSecurityTypeView.getSelectedItem(); - return holder.connectionSecurity; - } -} diff --git a/app/ui/legacy/src/main/res/layout/account_setup_outgoing.xml b/app/ui/legacy/src/main/res/layout/account_setup_outgoing.xml deleted file mode 100644 index cd920297f4..0000000000 --- a/app/ui/legacy/src/main/res/layout/account_setup_outgoing.xml +++ /dev/null @@ -1,161 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/app/ui/legacy/src/main/res/values/dimensions.xml b/app/ui/legacy/src/main/res/values/dimensions.xml index 976cd47bbd..5a33b87e4b 100644 --- a/app/ui/legacy/src/main/res/values/dimensions.xml +++ b/app/ui/legacy/src/main/res/values/dimensions.xml @@ -6,7 +6,6 @@ 8dp 4dp - 12dp 16dp 72dp diff --git a/app/ui/legacy/src/main/res/values/strings.xml b/app/ui/legacy/src/main/res/values/strings.xml index e9669d7183..3dcbea5fd1 100644 --- a/app/ui/legacy/src/main/res/values/strings.xml +++ b/app/ui/legacy/src/main/res/values/strings.xml @@ -370,9 +370,6 @@ Client certificate OAuth 2.0 - Client certificate - Security - Authentication None SSL/TLS STARTTLS @@ -396,19 +393,6 @@ Show only subscribed folders Auto-expand folder - Outgoing server settings - SMTP server - Port - Security - Require sign-in. - Username - Password - Authentication - \"%1$s = %2$s\" is not valid with \"%3$s = %4$s\" - - Invalid setup: %s - - Folder poll frequency Never Every 15 minutes