diff --git a/res/layout/account_setup_credentials_fragment.xml b/res/layout/account_setup_credentials_fragment.xml
index d3e2e7c7f..0003ff17c 100644
--- a/res/layout/account_setup_credentials_fragment.xml
+++ b/res/layout/account_setup_credentials_fragment.xml
@@ -20,6 +20,42 @@
android:layout_weight="1"
android:orientation="vertical">
+
+
+
+
+
+
+
+
+ android:imeOptions="actionDone"/>
#777777
#cccccc
+
+ #FFA500
+ #808080
+
\ No newline at end of file
diff --git a/res/values/strings.xml b/res/values/strings.xml
index a8ee98ceb..1f04c0807 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -194,6 +194,11 @@
Requesting authorization
Sign in
+
+
+ Email address or password are incorrect
+
+ Email address:
Email account
@@ -207,7 +212,8 @@
OR
Sign in with Google
-
+
+ Password
Password
diff --git a/src/com/android/email/activity/setup/AccountCredentials.java b/src/com/android/email/activity/setup/AccountCredentials.java
index 9b2b43cd3..41e4d5374 100644
--- a/src/com/android/email/activity/setup/AccountCredentials.java
+++ b/src/com/android/email/activity/setup/AccountCredentials.java
@@ -36,7 +36,7 @@ public class AccountCredentials extends Activity
final String protocol = getIntent().getStringExtra(EXTRA_PROTOCOL);
final AccountSetupCredentialsFragment f =
- AccountSetupCredentialsFragment.newInstance(emailAddress, protocol);
+ AccountSetupCredentialsFragment.newInstance(emailAddress, protocol, false);
getFragmentManager().beginTransaction()
.add(R.id.account_credentials_fragment_container, f, CREDENTIALS_FRAGMENT_TAG)
.commit();
diff --git a/src/com/android/email/activity/setup/AccountSetupCredentialsFragment.java b/src/com/android/email/activity/setup/AccountSetupCredentialsFragment.java
index 4b4e57292..3a54b45b1 100644
--- a/src/com/android/email/activity/setup/AccountSetupCredentialsFragment.java
+++ b/src/com/android/email/activity/setup/AccountSetupCredentialsFragment.java
@@ -24,10 +24,12 @@ import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.text.format.DateUtils;
+import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
+import android.view.inputmethod.EditorInfo;
import android.widget.EditText;
import android.widget.TextView;
@@ -54,6 +56,7 @@ public class AccountSetupCredentialsFragment extends AccountSetupFragment
private static final String EXTRA_EMAIL = "email";
private static final String EXTRA_PROTOCOL = "protocol";
+ private static final String EXTRA_PASSWORD_FAILED = "password_failed";
public static final String EXTRA_PASSWORD = "password";
public static final String EXTRA_OAUTH_PROVIDER = "provider";
@@ -66,6 +69,10 @@ public class AccountSetupCredentialsFragment extends AccountSetupFragment
private EditText mImapPasswordText;
private EditText mRegularPasswordText;
private TextWatcher mValidationTextWatcher;
+ private TextView mPasswordWarningLabel;
+ private TextView mEmailConfirmationLabel;
+ private TextView mEmailConfirmation;
+ private TextView.OnEditorActionListener mEditorActionListener;
private String mEmailAddress;
private boolean mOfferOAuth;
private boolean mOfferCerts;
@@ -87,11 +94,12 @@ public class AccountSetupCredentialsFragment extends AccountSetupFragment
* @return new fragment instance
*/
public static AccountSetupCredentialsFragment newInstance(final String email,
- final String protocol) {
+ final String protocol, final boolean passwordFailed) {
final AccountSetupCredentialsFragment f = new AccountSetupCredentialsFragment();
final Bundle b = new Bundle(2);
b.putString(EXTRA_EMAIL, email);
b.putString(EXTRA_PROTOCOL, protocol);
+ b.putBoolean(EXTRA_PASSWORD_FAILED, passwordFailed);
f.setArguments(b);
return f;
}
@@ -111,6 +119,29 @@ public class AccountSetupCredentialsFragment extends AccountSetupFragment
mDeviceIdSection = UiUtilities.getView(view, R.id.device_id_section);
mDeviceId = UiUtilities.getView(view, R.id.device_id);
mClientCertificateSelector.setHostCallback(this);
+ mPasswordWarningLabel = UiUtilities.getView(view, R.id.wrong_password_warning_label);
+ mEmailConfirmationLabel = UiUtilities.getView(view, R.id.email_confirmation_label);
+ mEmailConfirmation = UiUtilities.getView(view, R.id.email_confirmation);
+
+ mEditorActionListener = new TextView.OnEditorActionListener() {
+ @Override
+ public boolean onEditorAction(TextView view, int actionId, KeyEvent event) {
+ if (actionId == EditorInfo.IME_ACTION_DONE) {
+ final Callback callback = (Callback) getActivity();
+ if (callback != null) {
+ final Bundle results = new Bundle(1);
+ results.putString(EXTRA_PASSWORD, getPassword());
+ mResults = results;
+ callback.onCredentialsComplete(results);
+ }
+ return true;
+ } else {
+ return false;
+ }
+ }
+ };
+ mImapPasswordText.setOnEditorActionListener(mEditorActionListener);
+ mRegularPasswordText.setOnEditorActionListener(mEditorActionListener);
// After any text edits, call validateFields() which enables or disables the Next button
mValidationTextWatcher = new TextWatcher() {
@@ -166,6 +197,8 @@ public class AccountSetupCredentialsFragment extends AccountSetupFragment
}
mDeviceId.setText(deviceId);
}
+ final boolean passwordFailed = getArguments().getBoolean(EXTRA_PASSWORD_FAILED, false);
+ setPasswordFailed(passwordFailed);
validatePassword();
}
@@ -174,14 +207,29 @@ public class AccountSetupCredentialsFragment extends AccountSetupFragment
super.onDestroy();
if (mImapPasswordText != null) {
mImapPasswordText.removeTextChangedListener(mValidationTextWatcher);
+ mImapPasswordText.setOnEditorActionListener(null);
mImapPasswordText = null;
}
if (mRegularPasswordText != null) {
mRegularPasswordText.removeTextChangedListener(mValidationTextWatcher);
+ mRegularPasswordText.setOnEditorActionListener(null);
mRegularPasswordText = null;
}
}
+ public void setPasswordFailed(final boolean failed) {
+ if (failed) {
+ mPasswordWarningLabel.setVisibility(View.VISIBLE);
+ mEmailConfirmationLabel.setVisibility(View.VISIBLE);
+ mEmailConfirmation.setVisibility(View.VISIBLE);
+ mEmailConfirmation.setText(mEmailAddress);
+ } else {
+ mPasswordWarningLabel.setVisibility(View.GONE);
+ mEmailConfirmationLabel.setVisibility(View.GONE);
+ mEmailConfirmation.setVisibility(View.GONE);
+ }
+ }
+
public void validatePassword() {
final Callback callback = (Callback) getActivity();
if (callback != null) {
diff --git a/src/com/android/email/activity/setup/AccountSetupFinal.java b/src/com/android/email/activity/setup/AccountSetupFinal.java
index 20249aa43..dd215c8f8 100644
--- a/src/com/android/email/activity/setup/AccountSetupFinal.java
+++ b/src/com/android/email/activity/setup/AccountSetupFinal.java
@@ -23,6 +23,7 @@ import android.app.AlertDialog;
import android.app.Dialog;
import android.app.DialogFragment;
import android.app.Fragment;
+import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.app.LoaderManager;
import android.app.ProgressDialog;
@@ -108,8 +109,10 @@ public class AccountSetupFinal extends AccountSetupActivity
"AccountSetupFinal.authErr";
private static final String SAVESTATE_KEY_IS_PRE_CONFIGURED = "AccountSetupFinal.preconfig";
private static final String SAVESTATE_KEY_SKIP_AUTO_DISCOVER = "AccountSetupFinal.noAuto";
+ private static final String SAVESTATE_KEY_PASSWORD_FAILED = "AccountSetupFinal.passwordFailed";
private static final String CONTENT_FRAGMENT_TAG = "AccountSetupContentFragment";
+ private static final String CREDENTIALS_BACKSTACK_TAG = "AccountSetupCredentialsFragment";
// Collecting initial email and password
private static final int STATE_BASICS = 0;
@@ -154,6 +157,7 @@ public class AccountSetupFinal extends AccountSetupActivity
private boolean mPreConfiguredFailed = false;
private VendorPolicyLoader.Provider mProvider;
+ private boolean mPasswordFailed;
// UI elements
@VisibleForTesting
@@ -210,6 +214,7 @@ public class AccountSetupFinal extends AccountSetupActivity
mIsPreConfiguredProvider =
savedInstanceState.getBoolean(SAVESTATE_KEY_IS_PRE_CONFIGURED);
mSkipAutoDiscover = savedInstanceState.getBoolean(SAVESTATE_KEY_SKIP_AUTO_DISCOVER);
+ mPasswordFailed = savedInstanceState.getBoolean(SAVESTATE_KEY_PASSWORD_FAILED);
// I don't know why this view state doesn't get restored
updateHeadline();
} else {
@@ -249,6 +254,7 @@ public class AccountSetupFinal extends AccountSetupActivity
}
updateHeadline();
updateContentFragment(false /* addToBackstack */);
+ mPasswordFailed = false;
}
UiUtilities.getView(this, R.id.previous).setOnClickListener(this);
@@ -398,6 +404,7 @@ public class AccountSetupFinal extends AccountSetupActivity
outState.putBoolean(SAVESTATE_KEY_REPORT_AUTHENTICATOR_ERROR,
mReportAccountAuthenticatorError);
outState.putBoolean(SAVESTATE_KEY_IS_PRE_CONFIGURED, mIsPreConfiguredProvider);
+ outState.putBoolean(SAVESTATE_KEY_PASSWORD_FAILED, mPasswordFailed);
}
/**
@@ -439,13 +446,17 @@ public class AccountSetupFinal extends AccountSetupActivity
*/
private void updateContentFragment(boolean addToBackstack) {
final AccountSetupFragment f;
+ String backstackTag = null;
+
switch (mState) {
case STATE_BASICS:
f = AccountSetupBasicsFragment.newInstance();
break;
case STATE_CREDENTIALS:
f = AccountSetupCredentialsFragment.newInstance(mSetupData.getEmail(),
- mSetupData.getAccount().getOrCreateHostAuthRecv(this).mProtocol);
+ mSetupData.getAccount().getOrCreateHostAuthRecv(this).mProtocol,
+ mPasswordFailed);
+ backstackTag = CREDENTIALS_BACKSTACK_TAG;
break;
case STATE_TYPE:
f = AccountSetupTypeFragment.newInstance();
@@ -469,7 +480,7 @@ public class AccountSetupFinal extends AccountSetupActivity
final FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.replace(R.id.setup_fragment_container, f, CONTENT_FRAGMENT_TAG);
if (addToBackstack) {
- ft.addToBackStack(null);
+ ft.addToBackStack(backstackTag);
}
ft.commit();
}
@@ -488,6 +499,9 @@ public class AccountSetupFinal extends AccountSetupActivity
*/
private void resetStateFromCurrentFragment() {
AccountSetupFragment f = getContentFragment();
+ if (mState == STATE_CREDENTIALS) {
+ mPasswordFailed = false;
+ }
mState = f.getState();
updateHeadline();
}
@@ -505,6 +519,7 @@ public class AccountSetupFinal extends AccountSetupActivity
switch (mState) {
case STATE_BASICS:
onBasicsComplete();
+ // TODO: Move protocol choice before password entry
if (shouldDivertToManual()) {
// Alternate entry to the debug options screen (for devices without a physical
// keyboard):
@@ -544,9 +559,13 @@ public class AccountSetupFinal extends AccountSetupActivity
break;
case STATE_CHECKING_PRECONFIGURED:
if (mPreConfiguredFailed) {
- mState = STATE_MANUAL_INCOMING;
- updateHeadline();
- updateContentFragment(true /* addToBackstack */);
+ // Get rid of the previous instance of the AccountSetupCredentialsFragment.
+ FragmentManager fm = getFragmentManager();
+ fm.popBackStackImmediate(CREDENTIALS_BACKSTACK_TAG, 0);
+ final AccountSetupCredentialsFragment f = (AccountSetupCredentialsFragment)
+ getContentFragment();
+ f.setPasswordFailed(mPasswordFailed);
+ resetStateFromCurrentFragment();
} else {
mState = STATE_OPTIONS;
updateHeadline();
@@ -896,6 +915,7 @@ public class AccountSetupFinal extends AccountSetupActivity
@Override
public void onCheckSettingsError(int reason, String message) {
+ mPasswordFailed = true;
dismissCheckSettingsFragment();
final DialogFragment f =
CheckSettingsErrorDialogFragment.newInstance(reason, message);
@@ -916,7 +936,7 @@ public class AccountSetupFinal extends AccountSetupActivity
@Override
public void onCheckSettingsErrorDialogEditSettings() {
- // If we're checking pre-configured, set a flag that we failed and navigate fowards to
+ // If we're checking pre-configured, set a flag that we failed and navigate forwards to
// incoming settings
if (mState == STATE_CHECKING_PRECONFIGURED || mState == STATE_AUTO_DISCOVER) {
mPreConfiguredFailed = true;
@@ -928,6 +948,8 @@ public class AccountSetupFinal extends AccountSetupActivity
@Override
public void onCheckSettingsComplete() {
+ mPreConfiguredFailed = false;
+ mPasswordFailed = false;
dismissCheckSettingsFragment();
proceed();
}