1
0
mirror of https://github.com/moparisthebest/k-9 synced 2024-11-27 11:42:16 -05:00

Fix default port setting reversion

The problem:  begin modifying the server settings by changing the security
type (which will change the port to a default value), then change the port
to a custom value, then change screen orientation.  The default port value
is restored, wiping out the custom value.

When onRestoreInstanceState() is called, the custom port value is
restored.  But the spinner doesn't actually restore its state at that
time.  Instead, it waits until View.layout(), at which time it posts a
runnable to call onItemSelected() if the restored state doesn't match the
state initialized in onCreate().  When onItemSelected() is eventually run
sometime later, it wipes out the custom port value that was restored.

The solution is to keep track of the spinner state ourselves and only
revert the port to a default when we see the spinner state changed by the
user.

This problem goes back to 4.904 and before.
This commit is contained in:
Joe Steele 2014-07-28 12:56:01 -04:00
parent cf3561da5c
commit 5d5fab3081
2 changed files with 78 additions and 38 deletions

View File

@ -43,6 +43,7 @@ import java.util.Map;
public class AccountSetupIncoming extends K9Activity implements OnClickListener {
private static final String EXTRA_ACCOUNT = "account";
private static final String EXTRA_MAKE_DEFAULT = "makeDefault";
private static final String STATE_SECURITY_TYPE_POSITION = "stateSecurityTypePosition";
private static final String POP3_PORT = "110";
private static final String POP3_SSL_PORT = "995";
@ -255,7 +256,20 @@ public class AccountSetupIncoming extends K9Activity implements OnClickListener
mSecurityTypeView.setAdapter(securityTypesAdapter);
// Select currently configured security type
if (savedInstanceState == null) {
mCurrentSecurityTypeViewPosition = securityTypesAdapter.getPosition(settings.connectionSecurity);
} else {
/*
* Restore the spinner state now, before calling
* setOnItemSelectedListener(), thus avoiding a call to
* onItemSelected(). Then, when the system restores the state
* (again) in onRestoreInstanceState(), The system will see that
* the new state is the same as the current state (set here), so
* once again onItemSelected() will not be called.
*/
mCurrentSecurityTypeViewPosition = savedInstanceState.getInt(STATE_SECURITY_TYPE_POSITION);
}
mSecurityTypeView.setSelection(mCurrentSecurityTypeViewPosition, false);
updateAuthPlainTextFromSecurityType(settings.connectionSecurity);
@ -298,20 +312,25 @@ public class AccountSetupIncoming extends K9Activity implements OnClickListener
/*
* Updates the port when the user changes the security type. This allows
* us to show a reasonable default which the user can change.
*
* Note: It's important that we set this listener *after* an initial
* mSecurityTypeView option has been selected by the code in onCreate().
* Otherwise the listener might be called after onCreate() is finished
* which would wipe out the initial port value set in onCreate(),
* replacing it with the default port for the selected security type.
*/
mSecurityTypeView.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> 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();
validateFields();
}
}
@Override
public void onNothingSelected(AdapterView<?> parent) { /* unused */ }
@ -350,6 +369,7 @@ public class AccountSetupIncoming extends K9Activity implements OnClickListener
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putString(EXTRA_ACCOUNT, mAccount.getUuid());
outState.putInt(STATE_SECURITY_TYPE_POSITION, mCurrentSecurityTypeViewPosition);
}
@Override

View File

@ -35,6 +35,7 @@ public class AccountSetupOutgoing extends K9Activity implements OnClickListener,
private static final String EXTRA_ACCOUNT = "account";
private static final String EXTRA_MAKE_DEFAULT = "makeDefault";
private static final String STATE_SECURITY_TYPE_POSITION = "stateSecurityTypePosition";
private static final String SMTP_PORT = "587";
private static final String SMTP_SSL_PORT = "465";
@ -145,7 +146,20 @@ public class AccountSetupOutgoing extends K9Activity implements OnClickListener,
updateViewFromAuthType();
// Select currently configured security type
if (savedInstanceState == null) {
mCurrentSecurityTypeViewPosition = settings.connectionSecurity.ordinal();
} else {
/*
* Restore the spinner state now, before calling
* setOnItemSelectedListener(), thus avoiding a call to
* onItemSelected(). Then, when the system restores the state
* (again) in onRestoreInstanceState(), The system will see that
* the new state is the same as the current state (set here), so
* once again onItemSelected() will not be called.
*/
mCurrentSecurityTypeViewPosition = savedInstanceState.getInt(STATE_SECURITY_TYPE_POSITION);
}
mSecurityTypeView.setSelection(mCurrentSecurityTypeViewPosition, false);
if (settings.username != null && !settings.username.isEmpty()) {
@ -198,17 +212,21 @@ public class AccountSetupOutgoing extends K9Activity implements OnClickListener,
/*
* Updates the port when the user changes the security type. This allows
* us to show a reasonable default which the user can change.
*
* Note: It's important that we set this listener *after* an initial
* mSecurityTypeView option has been selected by the code in onCreate().
* Otherwise the listener might be called after onCreate() is finished
* which would wipe out the initial port value set in onCreate(),
* replacing it with the default port for the selected security type.
*/
mSecurityTypeView.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> 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();
boolean isInsecure = ConnectionSecurity.NONE.equals(mSecurityTypeView.getSelectedItem());
@ -236,6 +254,7 @@ public class AccountSetupOutgoing extends K9Activity implements OnClickListener,
validateFields();
}
}
@Override
public void onNothingSelected(AdapterView<?> parent) { /* unused */ }
@ -275,6 +294,7 @@ public class AccountSetupOutgoing extends K9Activity implements OnClickListener,
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putString(EXTRA_ACCOUNT, mAccount.getUuid());
outState.putInt(STATE_SECURITY_TYPE_POSITION, mCurrentSecurityTypeViewPosition);
}
@Override