Reduce/eliminate DB access in server settings

* Create shared async worker to check for duplicate accounts
* Use it in AccountSetupIncomingFragment
* Use it in AccountSetupExchangeFragment
* Debounce proceed/next button because work is now async
* Also, upgrade leftover old-style code in AccountSetupOutgoingFragment

Bug: 3134666
Change-Id: I5c24a6546d1ab66aedc5c4ac826ddf4f1ff53446
This commit is contained in:
Andy Stadler 2010-12-22 18:57:27 -08:00
parent 6ebaa90847
commit 8d22e85e45
4 changed files with 74 additions and 37 deletions

View File

@ -17,11 +17,15 @@
package com.android.email.activity.setup;
import com.android.email.R;
import com.android.email.Utility;
import com.android.email.provider.EmailContent;
import com.android.email.provider.EmailContent.Account;
import com.android.email.provider.EmailContent.HostAuth;
import android.app.Activity;
import android.app.Fragment;
import android.content.Context;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
@ -45,6 +49,8 @@ public abstract class AccountServerBaseFragment extends Fragment
protected boolean mSettingsMode;
// This is null in the setup wizard screens, and non-null in AccountSettings mode
public Button mProceedButton;
// This is used to debounce multiple clicks on the proceed button (which does async work)
public boolean mProceedButtonPressed;
/**
* Callback interface that owning activities must provide
@ -100,6 +106,8 @@ public abstract class AccountServerBaseFragment extends Fragment
if (getArguments() != null) {
mSettingsMode = getArguments().getBoolean(BUNDLE_KEY_SETTINGS);
}
mProceedButtonPressed = false;
}
/**
@ -139,6 +147,11 @@ public abstract class AccountServerBaseFragment extends Fragment
getActivity().onBackPressed();
break;
case R.id.done:
// Simple debounce - just ignore while checks are underway
if (mProceedButtonPressed) {
return;
}
mProceedButtonPressed = true;
onNext();
break;
}
@ -166,6 +179,56 @@ public abstract class AccountServerBaseFragment extends Fragment
mCallback.onEnableProceedButtons(enable);
}
/**
* Performs async operations as part of saving changes to the settings.
* Check for duplicate account
* Display dialog if necessary
* Else, proceed via mCallback.onProceedNext
*/
protected void startDuplicateTaskCheck(long accountId, String checkHost, String checkLogin,
int checkSettingsMode) {
new DuplicateCheckTask(accountId, checkHost, checkLogin, checkSettingsMode).execute();
}
private class DuplicateCheckTask extends AsyncTask<Void, Void, Account> {
private final long mAccountId;
private final String mCheckHost;
private final String mCheckLogin;
private final int mCheckSettingsMode;
public DuplicateCheckTask(long accountId, String checkHost, String checkLogin,
int checkSettingsMode) {
mAccountId = accountId;
mCheckHost = checkHost;
mCheckLogin = checkLogin;
mCheckSettingsMode = checkSettingsMode;
}
@Override
protected Account doInBackground(Void... params) {
EmailContent.Account account = Utility.findExistingAccount(mContext, mAccountId,
mCheckHost, mCheckLogin);
return account;
}
@Override
protected void onPostExecute(Account duplicateAccount) {
AccountServerBaseFragment fragment = AccountServerBaseFragment.this;
if (duplicateAccount != null) {
// Show duplicate account warning
DuplicateAccountDialogFragment dialogFragment =
DuplicateAccountDialogFragment.newInstance(duplicateAccount.mDisplayName);
dialogFragment.show(fragment.getFragmentManager(),
DuplicateAccountDialogFragment.TAG);
} else {
// Otherwise, proceed with the save/check
mCallback.onProceedNext(mCheckSettingsMode, fragment);
}
mProceedButtonPressed = false;
}
}
/**
* Implements AccountCheckSettingsFragment.Callbacks
*

View File

@ -418,16 +418,9 @@ public class AccountSetupExchangeFragment extends AccountServerBaseFragment
setupAccount.setStoreUri(mContext, uri.toString());
setupAccount.setSenderUri(mContext, uri.toString());
// Stop here if the login credentials duplicate an existing account
// (unless they duplicate the existing account, as they of course will)
Account account = Utility.findExistingAccount(mContext, setupAccount.mId,
uri.getHost(), mCacheLoginCredential);
if (account != null) {
DuplicateAccountDialogFragment dialogFragment =
DuplicateAccountDialogFragment.newInstance(account.mDisplayName);
dialogFragment.show(getActivity(), DuplicateAccountDialogFragment.TAG);
return;
}
// Check for a duplicate account (requires async DB work) and if OK, proceed with check
startDuplicateTaskCheck(setupAccount.mId, uri.getHost(), mCacheLoginCredential,
SetupData.CHECK_INCOMING);
} catch (URISyntaxException use) {
/*
* It's unrecoverable if we cannot create a URI from components that
@ -435,7 +428,5 @@ public class AccountSetupExchangeFragment extends AccountServerBaseFragment
*/
throw new Error(use);
}
mCallback.onProceedNext(SetupData.CHECK_INCOMING, this);
}
}

View File

@ -479,20 +479,17 @@ public class AccountSetupIncomingFragment extends AccountServerBaseFragment {
@Override
public void onNext() {
EmailContent.Account setupAccount = SetupData.getAccount();
setupAccount.setDeletePolicy(
(Integer)((SpinnerOption)mDeletePolicyView.getSelectedItem()).value);
try {
URI uri = getUri();
setupAccount.setStoreUri(mContext, uri.toString());
// Stop here if the login credentials duplicate an existing account
// (unless they duplicate the existing account, as they of course will)
EmailContent.Account account = Utility.findExistingAccount(mContext, setupAccount.mId,
uri.getHost(), mCacheLoginCredential);
if (account != null) {
DuplicateAccountDialogFragment dialogFragment =
DuplicateAccountDialogFragment.newInstance(account.mDisplayName);
dialogFragment.show(getActivity(), DuplicateAccountDialogFragment.TAG);
return;
}
// Check for a duplicate account (requires async DB work) and if OK, proceed with check
startDuplicateTaskCheck(setupAccount.mId, uri.getHost(), mCacheLoginCredential,
SetupData.CHECK_INCOMING);
} catch (URISyntaxException use) {
/*
* It's unrecoverable if we cannot create a URI from components that
@ -500,10 +497,5 @@ public class AccountSetupIncomingFragment extends AccountServerBaseFragment {
*/
throw new Error(use);
}
setupAccount.setDeletePolicy(
(Integer)((SpinnerOption)mDeletePolicyView.getSelectedItem()).value);
mCallback.onProceedNext(SetupData.CHECK_INCOMING, this);
}
}

View File

@ -415,15 +415,6 @@ public class AccountSetupOutgoingFragment extends AccountServerBaseFragment
throw new Error(use);
}
// STOPSHIP - use new checker fragment only during account settings (TODO: account setup)
Activity activity = getActivity();
if (activity instanceof PreferenceActivity) {
AccountCheckSettingsFragment checkerFragment =
AccountCheckSettingsFragment.newInstance(SetupData.CHECK_OUTGOING, this);
((PreferenceActivity)activity).startPreferenceFragment(checkerFragment, true);
} else {
// STOPSHIP remove this old code
mCallback.onProceedNext(SetupData.CHECK_OUTGOING, this);
}
mCallback.onProceedNext(SetupData.CHECK_OUTGOING, this);
}
}