Remove UI thread access in AccountSetupBasics
* Move getOwnerName to a FutureTask * Use AsyncTask for call to Utility.findExistingAccount() Change-Id: I85e35a12cc28b1dda8a0ccd930869316032a3b12
This commit is contained in:
parent
e6027c46f7
commit
8b5cd2beff
@ -55,6 +55,9 @@ import android.widget.Toast;
|
|||||||
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.net.URISyntaxException;
|
import java.net.URISyntaxException;
|
||||||
|
import java.util.concurrent.Callable;
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
|
import java.util.concurrent.FutureTask;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prompts the user for the email address and password. Also prompts for "Use this account as
|
* Prompts the user for the email address and password. Also prompts for "Use this account as
|
||||||
@ -113,6 +116,7 @@ public class AccountSetupBasics extends AccountSetupActivity
|
|||||||
private Provider mProvider;
|
private Provider mProvider;
|
||||||
private Button mManualButton;
|
private Button mManualButton;
|
||||||
private Button mNextButton;
|
private Button mNextButton;
|
||||||
|
private boolean mNextButtonInhibit;
|
||||||
|
|
||||||
// Used when this Activity is called as part of account authentification flow,
|
// Used when this Activity is called as part of account authentification flow,
|
||||||
// which requires to do extra work before and after the account creation.
|
// which requires to do extra work before and after the account creation.
|
||||||
@ -120,6 +124,9 @@ public class AccountSetupBasics extends AccountSetupActivity
|
|||||||
private AccountAuthenticatorResponse mAccountAuthenticatorResponse = null;
|
private AccountAuthenticatorResponse mAccountAuthenticatorResponse = null;
|
||||||
private Bundle mResultBundle = null;
|
private Bundle mResultBundle = null;
|
||||||
|
|
||||||
|
// FutureTask to look up the owner
|
||||||
|
FutureTask<String> mOwnerLookupTask;
|
||||||
|
|
||||||
public static void actionNewAccount(Activity fromActivity) {
|
public static void actionNewAccount(Activity fromActivity) {
|
||||||
SetupData.init(SetupData.FLOW_MODE_NORMAL);
|
SetupData.init(SetupData.FLOW_MODE_NORMAL);
|
||||||
fromActivity.startActivity(new Intent(fromActivity, AccountSetupBasics.class));
|
fromActivity.startActivity(new Intent(fromActivity, AccountSetupBasics.class));
|
||||||
@ -230,6 +237,8 @@ public class AccountSetupBasics extends AccountSetupActivity
|
|||||||
mNextButton.setOnClickListener(this);
|
mNextButton.setOnClickListener(this);
|
||||||
// Force disabled until validator notifies otherwise
|
// Force disabled until validator notifies otherwise
|
||||||
onEnableProceedButtons(false);
|
onEnableProceedButtons(false);
|
||||||
|
// Lightweight debounce while Async tasks underway
|
||||||
|
mNextButtonInhibit = false;
|
||||||
|
|
||||||
mAccountAuthenticatorResponse =
|
mAccountAuthenticatorResponse =
|
||||||
getIntent().getParcelableExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE);
|
getIntent().getParcelableExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE);
|
||||||
@ -278,6 +287,11 @@ public class AccountSetupBasics extends AccountSetupActivity
|
|||||||
if (savedInstanceState != null && savedInstanceState.containsKey(STATE_KEY_PROVIDER)) {
|
if (savedInstanceState != null && savedInstanceState.containsKey(STATE_KEY_PROVIDER)) {
|
||||||
mProvider = (Provider) savedInstanceState.getSerializable(STATE_KEY_PROVIDER);
|
mProvider = (Provider) savedInstanceState.getSerializable(STATE_KEY_PROVIDER);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Launch a worker to look up the owner name. It should be ready well in advance of
|
||||||
|
// the time the user clicks next or manual.
|
||||||
|
mOwnerLookupTask = new FutureTask<String>(mOwnerLookupCallable);
|
||||||
|
Utility.runAsync(mOwnerLookupTask);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -310,6 +324,10 @@ public class AccountSetupBasics extends AccountSetupActivity
|
|||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
switch (v.getId()) {
|
switch (v.getId()) {
|
||||||
case R.id.next:
|
case R.id.next:
|
||||||
|
// Simple debounce - just ignore while async checks are underway
|
||||||
|
if (mNextButtonInhibit) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
onNext();
|
onNext();
|
||||||
break;
|
break;
|
||||||
case R.id.manual_setup:
|
case R.id.manual_setup:
|
||||||
@ -345,21 +363,36 @@ public class AccountSetupBasics extends AccountSetupActivity
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TODO this should also be in AsyncTask
|
* Return an existing username if found, or null. This is the result of the Callable (below).
|
||||||
* TODO figure out another way to get the owner name
|
|
||||||
*/
|
*/
|
||||||
private String getOwnerName() {
|
private String getOwnerName() {
|
||||||
String name = null;
|
String result = null;
|
||||||
long defaultId = Account.getDefaultAccountId(this);
|
try {
|
||||||
if (defaultId != -1) {
|
result = mOwnerLookupTask.get();
|
||||||
Account account = Account.restoreAccountWithId(this, defaultId);
|
} catch (InterruptedException e) {
|
||||||
if (account != null) {
|
} catch (ExecutionException e) {
|
||||||
name = account.getSenderName();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return name;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callable that returns the username (based on other accounts) or null.
|
||||||
|
*/
|
||||||
|
private Callable<String> mOwnerLookupCallable = new Callable<String>() {
|
||||||
|
public String call() {
|
||||||
|
Context context = AccountSetupBasics.this;
|
||||||
|
String name = null;
|
||||||
|
long defaultId = Account.getDefaultAccountId(context);
|
||||||
|
if (defaultId != -1) {
|
||||||
|
Account account = Account.restoreAccountWithId(context, defaultId);
|
||||||
|
if (account != null) {
|
||||||
|
name = account.getSenderName();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Finish the auto setup process, in some cases after showing a warning dialog.
|
* Finish the auto setup process, in some cases after showing a warning dialog.
|
||||||
*/
|
*/
|
||||||
@ -371,8 +404,8 @@ public class AccountSetupBasics extends AccountSetupActivity
|
|||||||
String domain = emailParts[1];
|
String domain = emailParts[1];
|
||||||
URI incomingUri = null;
|
URI incomingUri = null;
|
||||||
URI outgoingUri = null;
|
URI outgoingUri = null;
|
||||||
|
String incomingUsername = mProvider.incomingUsernameTemplate;
|
||||||
try {
|
try {
|
||||||
String incomingUsername = mProvider.incomingUsernameTemplate;
|
|
||||||
incomingUsername = incomingUsername.replaceAll("\\$email", email);
|
incomingUsername = incomingUsername.replaceAll("\\$email", email);
|
||||||
incomingUsername = incomingUsername.replaceAll("\\$user", user);
|
incomingUsername = incomingUsername.replaceAll("\\$user", user);
|
||||||
incomingUsername = incomingUsername.replaceAll("\\$domain", domain);
|
incomingUsername = incomingUsername.replaceAll("\\$domain", domain);
|
||||||
@ -392,17 +425,6 @@ public class AccountSetupBasics extends AccountSetupActivity
|
|||||||
+ password, outgoingUriTemplate.getHost(), outgoingUriTemplate.getPort(),
|
+ password, outgoingUriTemplate.getHost(), outgoingUriTemplate.getPort(),
|
||||||
outgoingUriTemplate.getPath(), null, null);
|
outgoingUriTemplate.getPath(), null, null);
|
||||||
|
|
||||||
// Stop here if the login credentials duplicate an existing account
|
|
||||||
// TODO this shouldn't be in UI thread
|
|
||||||
Account account = Utility.findExistingAccount(this, -1,
|
|
||||||
incomingUri.getHost(), incomingUsername);
|
|
||||||
if (account != null) {
|
|
||||||
DuplicateAccountDialogFragment dialogFragment =
|
|
||||||
DuplicateAccountDialogFragment.newInstance(account.mDisplayName);
|
|
||||||
dialogFragment.show(getFragmentManager(), DuplicateAccountDialogFragment.TAG);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (URISyntaxException use) {
|
} catch (URISyntaxException use) {
|
||||||
/*
|
/*
|
||||||
* If there is some problem with the URI we give up and go on to
|
* If there is some problem with the URI we give up and go on to
|
||||||
@ -414,21 +436,61 @@ public class AccountSetupBasics extends AccountSetupActivity
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Populate the setup data, assuming that the duplicate account check will succeed
|
||||||
populateSetupData(getOwnerName(), email, mDefaultView.isChecked(),
|
populateSetupData(getOwnerName(), email, mDefaultView.isChecked(),
|
||||||
incomingUri.toString(), outgoingUri.toString());
|
incomingUri.toString(), outgoingUri.toString());
|
||||||
|
|
||||||
/**
|
// Stop here if the login credentials duplicate an existing account
|
||||||
* Start the account checker fragment
|
// Launch an Async task to do the work
|
||||||
* TODO how to link directly from activity<-->fragment
|
new DuplicateCheckTask(this, incomingUri.getHost(), incomingUsername).execute();
|
||||||
*/
|
|
||||||
AccountCheckSettingsFragment checkerFragment = AccountCheckSettingsFragment.newInstance(
|
|
||||||
SetupData.CHECK_INCOMING | SetupData.CHECK_OUTGOING, null);
|
|
||||||
FragmentTransaction transaction = getFragmentManager().openTransaction();
|
|
||||||
transaction.add(checkerFragment, AccountCheckSettingsFragment.TAG);
|
|
||||||
transaction.addToBackStack("back");
|
|
||||||
transaction.commit();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Async task that continues the work of finishAutoSetup(). Checks for a duplicate
|
||||||
|
* account and then either alerts the user, or continues.
|
||||||
|
*/
|
||||||
|
private class DuplicateCheckTask extends AsyncTask<Void, Void, Account> {
|
||||||
|
private final Context mContext;
|
||||||
|
private final String mCheckHost;
|
||||||
|
private final String mCheckLogin;
|
||||||
|
|
||||||
|
public DuplicateCheckTask(Context context, String checkHost, String checkLogin) {
|
||||||
|
mContext = context;
|
||||||
|
mCheckHost = checkHost;
|
||||||
|
mCheckLogin = checkLogin;
|
||||||
|
// Prevent additional clicks on the next button during Async lookup
|
||||||
|
mNextButtonInhibit = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Account doInBackground(Void... params) {
|
||||||
|
EmailContent.Account account = Utility.findExistingAccount(mContext, -1,
|
||||||
|
mCheckHost, mCheckLogin);
|
||||||
|
return account;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onPostExecute(Account duplicateAccount) {
|
||||||
|
mNextButtonInhibit = false;
|
||||||
|
// Show duplicate account warning, or proceed
|
||||||
|
if (duplicateAccount != null) {
|
||||||
|
DuplicateAccountDialogFragment dialogFragment =
|
||||||
|
DuplicateAccountDialogFragment.newInstance(duplicateAccount.mDisplayName);
|
||||||
|
dialogFragment.show(getFragmentManager(), DuplicateAccountDialogFragment.TAG);
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
AccountCheckSettingsFragment checkerFragment =
|
||||||
|
AccountCheckSettingsFragment.newInstance(
|
||||||
|
SetupData.CHECK_INCOMING | SetupData.CHECK_OUTGOING, null);
|
||||||
|
FragmentTransaction transaction = getFragmentManager().openTransaction();
|
||||||
|
transaction.add(checkerFragment, AccountCheckSettingsFragment.TAG);
|
||||||
|
transaction.addToBackStack("back");
|
||||||
|
transaction.commit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* When "next" button is clicked
|
* When "next" button is clicked
|
||||||
*/
|
*/
|
||||||
|
Loading…
Reference in New Issue
Block a user