Create setup flow for use by Accounts manager.

* Create a new entry point for the exchange setup flow and switch
    EASAuthenticatorService to call it
* Pass "eas flow mode" down through the setup screens
* Slightly modify their behavior as we go (e.g. we skip the
    (account type" screen since we know it's EAS.)
* Add a checkbox to "sync contacts from this account" and pass that
    value into ExchangeStore when we set up the account.
* Change the flow exit to pop back to the account manager instead of
    taking the user to the new inbox.

This CL satisfies cases 1 & 2 of bug # 1974752.
This commit is contained in:
Andrew Stadler 2009-08-20 15:51:36 -07:00
parent a8aedb2f37
commit bcff14acf2
10 changed files with 104 additions and 22 deletions

View File

@ -52,6 +52,12 @@
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:text="@string/account_setup_options_notify_label" />
<CheckBox
android:id="@+id/account_sync_contacts"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:text="@string/account_setup_options_sync_contacts_label"
android:visibility="gone" />
<View
android:layout_width="fill_parent"
android:layout_height="0px"

View File

@ -375,6 +375,9 @@
<string name="account_setup_options_default_label">Send email from this account by default.</string>
<!-- In Account setup options & Account Settings screens, check box for new-mail notification -->
<string name="account_setup_options_notify_label">Notify me when email arrives.</string>
<!-- In Account setup options & Account Settings screens, optional check box to also sync
contacts -->
<string name="account_setup_options_sync_contacts_label">Sync contacts from this account.</string>
<!-- Dialog title when "setup" could not finish -->
<string name="account_setup_failed_dlg_title">Setup could not finish</string>
<!-- In Account setup options screen, label for email check frequency selector -->

View File

@ -41,29 +41,40 @@ public class AccountSetupAccountType extends Activity implements OnClickListener
private static final String EXTRA_ACCOUNT = "account";
private static final String EXTRA_MAKE_DEFAULT = "makeDefault";
private static final String EXTRA_EAS_FLOW = "easFlow";
private Account mAccount;
private boolean mMakeDefault;
public static void actionSelectAccountType(Activity fromActivity, Account account,
boolean makeDefault) {
boolean makeDefault, boolean easFlowMode) {
Intent i = new Intent(fromActivity, AccountSetupAccountType.class);
i.putExtra(EXTRA_ACCOUNT, account);
i.putExtra(EXTRA_MAKE_DEFAULT, makeDefault);
i.putExtra(EXTRA_EAS_FLOW, easFlowMode);
fromActivity.startActivity(i);
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mAccount = (Account) getIntent().getParcelableExtra(EXTRA_ACCOUNT);
mMakeDefault = getIntent().getBooleanExtra(EXTRA_MAKE_DEFAULT, false);
boolean easFlowMode = getIntent().getBooleanExtra(EXTRA_EAS_FLOW, false);
// If we're in account setup flow mode, for EAS, skip this screen and "click" EAS
if (easFlowMode) {
onExchange(true);
return;
}
// Otherwise proceed into this screen
setContentView(R.layout.account_setup_account_type);
((Button)findViewById(R.id.pop)).setOnClickListener(this);
((Button)findViewById(R.id.imap)).setOnClickListener(this);
((Button)findViewById(R.id.exchange)).setOnClickListener(this);
mAccount = (Account) getIntent().getParcelableExtra(EXTRA_ACCOUNT);
mMakeDefault = getIntent().getBooleanExtra(EXTRA_MAKE_DEFAULT, false);
if (isExchangeAvailable()) {
findViewById(R.id.exchange).setVisibility(View.VISIBLE);
}
@ -112,7 +123,7 @@ public class AccountSetupAccountType extends Activity implements OnClickListener
* email address. Also set the mail delete policy here, because there is no UI (for exchange),
* and switch the default sync interval to "push".
*/
private void onExchange() {
private void onExchange(boolean easFlowMode) {
try {
URI uri = new URI(mAccount.getStoreUri(this));
uri = new URI("eas+ssl+", uri.getUserInfo(), uri.getHost(), uri.getPort(),
@ -129,7 +140,7 @@ public class AccountSetupAccountType extends Activity implements OnClickListener
mAccount.setDeletePolicy(Account.DELETE_POLICY_ON_DELETE);
mAccount.setSyncInterval(Account.CHECK_INTERVAL_PUSH);
mAccount.setSyncLookback(1);
AccountSetupExchange.actionIncomingSettings(this, mAccount, mMakeDefault);
AccountSetupExchange.actionIncomingSettings(this, mAccount, mMakeDefault, easFlowMode);
finish();
}
@ -195,7 +206,7 @@ public class AccountSetupAccountType extends Activity implements OnClickListener
onImap();
break;
case R.id.exchange:
onExchange();
onExchange(false);
break;
}
}

View File

@ -28,6 +28,7 @@ import com.android.email.provider.EmailContent.Account;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.res.XmlResourceParser;
@ -61,7 +62,10 @@ import java.net.URISyntaxException;
public class AccountSetupBasics extends Activity
implements OnClickListener, TextWatcher {
private final static boolean ENTER_DEBUG_SCREEN = true;
private final static String EXTRA_ACCOUNT = "com.android.email.AccountSetupBasics.account";
private final static String EXTRA_EAS_FLOW = "com.android.email.extra.eas_flow";
private final static int DIALOG_NOTE = 1;
private final static String STATE_KEY_PROVIDER =
"com.android.email.AccountSetupBasics.provider";
@ -77,6 +81,7 @@ public class AccountSetupBasics extends Activity
private Button mManualSetupButton;
private EmailContent.Account mAccount;
private Provider mProvider;
private boolean mEasFlowMode;
private EmailAddressValidator mEmailValidator = new EmailAddressValidator();
@ -85,6 +90,16 @@ public class AccountSetupBasics extends Activity
fromActivity.startActivity(i);
}
/**
* This creates an intent that can be used to start a self-contained account creation flow
* for exchange accounts.
*/
public static Intent actionSetupExchangeIntent(Context context) {
Intent i = new Intent(context, AccountSetupBasics.class);
i.putExtra(EXTRA_EAS_FLOW, true);
return i;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@ -119,6 +134,12 @@ public class AccountSetupBasics extends Activity
}
}
mEasFlowMode = getIntent().getBooleanExtra(EXTRA_EAS_FLOW, false);
if (mEasFlowMode) {
mManualSetupButton.setVisibility(View.GONE);
// TODO: probably need different text here
}
if (savedInstanceState != null && savedInstanceState.containsKey(EXTRA_ACCOUNT)) {
mAccount = (EmailContent.Account)savedInstanceState.getParcelable(EXTRA_ACCOUNT);
}
@ -297,6 +318,13 @@ public class AccountSetupBasics extends Activity
}
}
/**
* This is used in automatic setup mode to jump directly down to the names screen.
*
* NOTE: With this organization, it is *not* possible to auto-create an exchange account,
* because certain necessary actions happen during AccountSetupOptions (which we are
* skipping here).
*/
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK) {
@ -308,7 +336,7 @@ public class AccountSetupBasics extends Activity
// From now on we'll only pass the accountId around.
mAccount.save(this);
Email.setServicesEnabled(this);
AccountSetupNames.actionSetNames(this, mAccount.mId);
AccountSetupNames.actionSetNames(this, mAccount.mId, false);
finish();
}
}
@ -352,7 +380,8 @@ public class AccountSetupBasics extends Activity
*/
mAccount.setSyncInterval(DEFAULT_ACCOUNT_CHECK_INTERVAL);
AccountSetupAccountType.actionSelectAccountType(this, mAccount, mDefaultView.isChecked());
AccountSetupAccountType.actionSelectAccountType(this, mAccount, mDefaultView.isChecked(),
mEasFlowMode);
finish();
}

View File

@ -48,6 +48,7 @@ import java.net.URISyntaxException;
public class AccountSetupExchange extends Activity implements OnClickListener {
private static final String EXTRA_ACCOUNT = "account";
private static final String EXTRA_MAKE_DEFAULT = "makeDefault";
private static final String EXTRA_EAS_FLOW = "easFlow";
private EditText mUsernameView;
private EditText mPasswordView;
@ -60,10 +61,11 @@ public class AccountSetupExchange extends Activity implements OnClickListener {
private boolean mMakeDefault;
public static void actionIncomingSettings(Activity fromActivity, EmailContent.Account account,
boolean makeDefault) {
boolean makeDefault, boolean easFlowMode) {
Intent i = new Intent(fromActivity, AccountSetupExchange.class);
i.putExtra(EXTRA_ACCOUNT, account);
i.putExtra(EXTRA_MAKE_DEFAULT, makeDefault);
i.putExtra(EXTRA_EAS_FLOW, easFlowMode);
fromActivity.startActivity(i);
}
@ -217,7 +219,8 @@ public class AccountSetupExchange extends Activity implements OnClickListener {
finish();
} else {
// Go directly to end - there is no 2nd screen for incoming settings
AccountSetupOptions.actionOptions(this, mAccount, mMakeDefault);
boolean easFlowMode = getIntent().getBooleanExtra(EXTRA_EAS_FLOW, false);
AccountSetupOptions.actionOptions(this, mAccount, mMakeDefault, easFlowMode);
finish();
}
}

View File

@ -37,15 +37,17 @@ import android.widget.EditText;
public class AccountSetupNames extends Activity implements OnClickListener {
private static final String EXTRA_ACCOUNT_ID = "accountId";
private static final String EXTRA_EAS_FLOW = "easFlow";
private EditText mDescription;
private EditText mName;
private EmailContent.Account mAccount;
private Button mDoneButton;
public static void actionSetNames(Activity fromActivity, long accountId) {
public static void actionSetNames(Activity fromActivity, long accountId, boolean easFlowMode) {
Intent i = new Intent(fromActivity, AccountSetupNames.class);
i.putExtra(EXTRA_ACCOUNT_ID, accountId);
i.putExtra(EXTRA_EAS_FLOW, easFlowMode);
fromActivity.startActivity(i);
}
@ -99,6 +101,10 @@ public class AccountSetupNames extends Activity implements OnClickListener {
}
/**
* After having a chance to input the display names, we normally jump directly to the
* inbox for the new account. However if we're in EAS flow mode (externally-launched
* account creation) we simply "pop" here which should return us to the Accounts activities.
*
* TODO: Validator should also trim the description string before checking it.
*/
private void onNext() {
@ -111,7 +117,13 @@ public class AccountSetupNames extends Activity implements OnClickListener {
cv.put(AccountColumns.DISPLAY_NAME, mAccount.getDisplayName());
cv.put(AccountColumns.SENDER_NAME, name);
mAccount.update(this, cv);
MessageList.actionHandleAccount(this, mAccount.mId, EmailContent.Mailbox.TYPE_INBOX);
// Exit or dispatch per flow mode
if (getIntent().getBooleanExtra(EXTRA_EAS_FLOW, false)) {
// do nothing - just pop off the activity stack
} else {
MessageList.actionHandleAccount(this, mAccount.mId, EmailContent.Mailbox.TYPE_INBOX);
}
finish();
}

View File

@ -35,18 +35,22 @@ public class AccountSetupOptions extends Activity implements OnClickListener {
private static final String EXTRA_ACCOUNT = "account";
private static final String EXTRA_MAKE_DEFAULT = "makeDefault";
private static final String EXTRA_EAS_FLOW = "easFlow";
private Spinner mCheckFrequencyView;
private Spinner mSyncWindowView;
private CheckBox mDefaultView;
private CheckBox mNotifyView;
private CheckBox mSyncContactsView;
private EmailContent.Account mAccount;
private boolean mEasFlowMode;
public static void actionOptions(Activity fromActivity, EmailContent.Account account,
boolean makeDefault) {
boolean makeDefault, boolean easFlowMode) {
Intent i = new Intent(fromActivity, AccountSetupOptions.class);
i.putExtra(EXTRA_ACCOUNT, account);
i.putExtra(EXTRA_MAKE_DEFAULT, makeDefault);
i.putExtra(EXTRA_EAS_FLOW, easFlowMode);
fromActivity.startActivity(i);
}
@ -59,6 +63,7 @@ public class AccountSetupOptions extends Activity implements OnClickListener {
mSyncWindowView = (Spinner) findViewById(R.id.account_sync_window);
mDefaultView = (CheckBox)findViewById(R.id.account_default);
mNotifyView = (CheckBox)findViewById(R.id.account_notify);
mSyncContactsView = (CheckBox) findViewById(R.id.account_sync_contacts);
findViewById(R.id.next).setOnClickListener(this);
@ -105,6 +110,14 @@ public class AccountSetupOptions extends Activity implements OnClickListener {
(mAccount.getFlags() & EmailContent.Account.FLAGS_NOTIFY_NEW_MAIL) != 0);
SpinnerOption.setSpinnerOptionValue(mCheckFrequencyView, mAccount
.getSyncInterval());
// Setup any additional items to support EAS & EAS flow mode
mEasFlowMode = getIntent().getBooleanExtra(EXTRA_EAS_FLOW, false);
if ("eas".equals(info.mScheme)) {
// "also sync contacts" == "true"
mSyncContactsView.setVisibility(View.VISIBLE);
mSyncContactsView.setChecked(true);
}
}
private void onDone() {
@ -121,14 +134,17 @@ public class AccountSetupOptions extends Activity implements OnClickListener {
mAccount.setSyncLookback(window);
}
mAccount.setDefaultAccount(mDefaultView.isChecked());
// EAS needs a hook to store account information for use by AccountManager
if (!mAccount.isSaved() && mAccount.mHostAuthRecv != null
// Call EAS to store account information for use by AccountManager
if (!mAccount.isSaved()
&& mAccount.mHostAuthRecv != null
&& mAccount.mHostAuthRecv.mProtocol.equals("eas")) {
ExchangeStore.addSystemAccount(this, mAccount);
boolean alsoSyncContacts = mEasFlowMode && mSyncContactsView.isChecked();
ExchangeStore.addSystemAccount(this, mAccount, alsoSyncContacts);
}
AccountSettingsUtils.commitSettings(this, mAccount);
Email.setServicesEnabled(this);
AccountSetupNames.actionSetNames(this, mAccount.mId);
AccountSetupNames.actionSetNames(this, mAccount.mId, mEasFlowMode);
finish();
}

View File

@ -257,7 +257,7 @@ public class AccountSetupOutgoing extends Activity implements OnClickListener,
}
finish();
} else {
AccountSetupOptions.actionOptions(this, mAccount, mMakeDefault);
AccountSetupOptions.actionOptions(this, mAccount, mMakeDefault, false);
finish();
}
}

View File

@ -114,11 +114,13 @@ public class ExchangeStore extends Store {
mTransport.checkSettings(mUri);
}
static public void addSystemAccount(Context context, Account acct) {
// This code was taken from sample code in AccountsTester
static public void addSystemAccount(Context context, Account acct, boolean syncContacts) {
// Create a description of the new account
Bundle options = new Bundle();
options.putString(EasAuthenticatorService.OPTIONS_USERNAME, acct.mEmailAddress);
options.putString(EasAuthenticatorService.OPTIONS_PASSWORD, acct.mHostAuthRecv.mPassword);
options.putBoolean(EasAuthenticatorService.OPTIONS_CONTACTS_SYNC_ENABLED, syncContacts);
AccountManagerCallback<Bundle> callback = new AccountManagerCallback<Bundle>() {
public void run(AccountManagerFuture<Bundle> future) {
try {

View File

@ -89,7 +89,7 @@ public class EasAuthenticatorService extends Service {
} else {
Bundle b = new Bundle();
Intent intent =
new Intent(EasAuthenticatorService.this, AccountSetupBasics.class);
AccountSetupBasics.actionSetupExchangeIntent(EasAuthenticatorService.this);
// Add extras that indicate this is an Exchange account creation
// So we'll skip the "account type" activity, and we'll use the response when
// we're done