Merge changes If1b344d5,Idaffc3f0,I5a33ad27 into ub-contactsdialer-i-dev
* changes:
Remove getGroupWritableAccounts method
Replace getAccounts method with blockForWritableAccounts
Add setter for accounts in AccountsListAdapter
diff --git a/src/com/android/contacts/ContactsDrawerActivity.java b/src/com/android/contacts/ContactsDrawerActivity.java
index f0bc37e..ad4c2ac 100644
--- a/src/com/android/contacts/ContactsDrawerActivity.java
+++ b/src/com/android/contacts/ContactsDrawerActivity.java
@@ -67,16 +67,17 @@
import com.android.contacts.model.AccountTypeManager;
import com.android.contacts.model.account.AccountDisplayInfo;
import com.android.contacts.model.account.AccountDisplayInfoFactory;
+import com.android.contacts.model.account.AccountInfo;
import com.android.contacts.model.account.AccountWithDataSet;
import com.android.contacts.preference.ContactsPreferenceActivity;
import com.android.contacts.util.AccountFilterUtil;
-import com.android.contacts.util.AccountsListAdapter.AccountListFilter;
import com.android.contacts.util.ImplicitIntentsUtil;
import com.android.contacts.util.MaterialColorMapUtils;
import com.android.contacts.util.SharedPreferenceUtil;
import com.android.contacts.util.ViewUtil;
import com.android.contactsbind.HelpUtils;
import com.android.contactsbind.ObjectFactory;
+import com.google.common.util.concurrent.Futures;
import java.util.HashMap;
import java.util.Iterator;
@@ -402,7 +403,8 @@
}
@Override
- public void onGroupsLoaded(List<GroupListItem> groupListItems) {
+ public void onGroupsLoaded(List<GroupListItem> groupListItems,
+ boolean areGroupWritableAccountsAvailable) {
final Menu menu = mNavigationView.getMenu();
final MenuItem groupsMenuItem = menu.findItem(R.id.nav_groups);
final SubMenu subMenu = groupsMenuItem.getSubMenu();
@@ -443,7 +445,7 @@
}
// Don't show "Create new..." menu if there's no group-writable accounts available.
- if (!ContactsUtils.areGroupWritableAccountsAvailable(this)) {
+ if (!areGroupWritableAccountsAvailable) {
return;
}
@@ -679,8 +681,10 @@
}
private void selectAccountForNewGroup() {
- final List<AccountWithDataSet> accounts = AccountTypeManager.getInstance(this)
- .getGroupWritableAccounts();
+ // This should never block because the GroupsFragment loads the accounts and the
+ // "Create Label" item only exists when that loading finishes
+ final List<AccountInfo> accounts = Futures.getUnchecked(AccountTypeManager.getInstance(this)
+ .filterAccountsAsync(AccountTypeManager.AccountFilter.GROUPS_WRITABLE));
if (accounts.isEmpty()) {
// We shouldn't present the add group button if there are no writable accounts
// but check it since it's possible we are started with an Intent.
@@ -689,11 +693,11 @@
}
// If there is a single writable account, use it w/o showing a dialog.
if (accounts.size() == 1) {
- onAccountChosen(accounts.get(0), /* extraArgs */ null);
+ onAccountChosen(accounts.get(0).getAccount(), /* extraArgs */ null);
return;
}
SelectAccountDialogFragment.show(getFragmentManager(), R.string.dialog_new_group_account,
- AccountListFilter.ACCOUNTS_GROUP_WRITABLE, /* extraArgs */ null,
+ AccountTypeManager.AccountFilter.GROUPS_WRITABLE, /* extraArgs */ null,
TAG_SELECT_ACCOUNT_DIALOG);
}
diff --git a/src/com/android/contacts/ContactsUtils.java b/src/com/android/contacts/ContactsUtils.java
index 448e696..69890b4 100644
--- a/src/com/android/contacts/ContactsUtils.java
+++ b/src/com/android/contacts/ContactsUtils.java
@@ -29,13 +29,10 @@
import com.android.contacts.compat.ContactsCompat;
import com.android.contacts.compat.DirectoryCompat;
-import com.android.contacts.model.AccountTypeManager;
-import com.android.contacts.model.account.AccountWithDataSet;
import com.android.contacts.model.dataitem.ImDataItem;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
-import java.util.List;
public class ContactsUtils {
private static final String TAG = "ContactsUtils";
@@ -138,12 +135,6 @@
return TextUtils.equals(a.getAction(), b.getAction());
}
- public static boolean areGroupWritableAccountsAvailable(Context context) {
- final List<AccountWithDataSet> accounts =
- AccountTypeManager.getInstance(context).getGroupWritableAccounts();
- return !accounts.isEmpty();
- }
-
/**
* Returns the size (width and height) of thumbnail pictures as configured in the provider. This
* can safely be called from the UI thread, as the provider can serve this without performing
diff --git a/src/com/android/contacts/activities/ContactEditorAccountsChangedActivity.java b/src/com/android/contacts/activities/ContactEditorAccountsChangedActivity.java
index 2c3c2c8..2717cab 100644
--- a/src/com/android/contacts/activities/ContactEditorAccountsChangedActivity.java
+++ b/src/com/android/contacts/activities/ContactEditorAccountsChangedActivity.java
@@ -37,7 +37,6 @@
import com.android.contacts.model.account.AccountWithDataSet;
import com.android.contacts.model.account.AccountsLoader;
import com.android.contacts.util.AccountsListAdapter;
-import com.android.contacts.util.AccountsListAdapter.AccountListFilter;
import com.android.contacts.util.ImplicitIntentsUtil;
import java.util.List;
@@ -142,8 +141,7 @@
button.setOnClickListener(mAddAccountClickListener);
final ListView accountListView = (ListView) view.findViewById(R.id.account_list);
- mAccountListAdapter = new AccountsListAdapter(this,
- AccountListFilter.ACCOUNTS_CONTACT_WRITABLE);
+ mAccountListAdapter = new AccountsListAdapter(this, accounts);
accountListView.setAdapter(mAccountListAdapter);
accountListView.setOnItemClickListener(mAccountListItemClickListener);
} else if (numAccounts == 1 && !accounts.get(0).getAccount().isNullAccount()) {
diff --git a/src/com/android/contacts/editor/SelectAccountDialogFragment.java b/src/com/android/contacts/editor/SelectAccountDialogFragment.java
index fe3d9d6..88e92b7 100644
--- a/src/com/android/contacts/editor/SelectAccountDialogFragment.java
+++ b/src/com/android/contacts/editor/SelectAccountDialogFragment.java
@@ -27,43 +27,51 @@
import android.widget.TextView;
import com.android.contacts.R;
+import com.android.contacts.model.AccountTypeManager;
+import com.android.contacts.model.account.AccountInfo;
import com.android.contacts.model.account.AccountWithDataSet;
+import com.android.contacts.model.account.AccountsLoader;
import com.android.contacts.util.AccountsListAdapter;
-import com.android.contacts.util.AccountsListAdapter.AccountListFilter;
+import com.google.common.base.Preconditions;
+
+import java.util.List;
/**
* Shows a dialog asking the user which account to chose.
*
* The result is passed to {@code targetFragment} passed to {@link #show}.
*/
-public final class SelectAccountDialogFragment extends DialogFragment {
+public final class SelectAccountDialogFragment extends DialogFragment
+ implements AccountsLoader.AccountsListener {
public static final String TAG = "SelectAccountDialogFragment";
private static final String KEY_TITLE_RES_ID = "title_res_id";
private static final String KEY_LIST_FILTER = "list_filter";
private static final String KEY_EXTRA_ARGS = "extra_args";
+ private AccountsListAdapter mAccountsAdapter;
+ private AccountTypeManager.AccountFilter mFilter;
+
/**
* Show the dialog.
*
* @param fragmentManager {@link FragmentManager}.
* @param titleResourceId resource ID to use as the title.
- * @param accountListFilter account filter.
* @param extraArgs Extra arguments, which will later be passed to
* {@link Listener#onAccountChosen}. {@code null} will be converted to
* {@link Bundle#EMPTY}.
*/
public static void show(FragmentManager fragmentManager, int titleResourceId,
- AccountListFilter accountListFilter, Bundle extraArgs) {
- show(fragmentManager, titleResourceId, accountListFilter, extraArgs, /* tag */ null);
+ AccountTypeManager.AccountFilter filter, Bundle extraArgs) {
+ show(fragmentManager, titleResourceId, filter, extraArgs, /* tag */ null);
}
public static void show(FragmentManager fragmentManager, int titleResourceId,
- AccountListFilter accountListFilter, Bundle extraArgs, String tag) {
+ AccountTypeManager.AccountFilter filter, Bundle extraArgs, String tag) {
final Bundle args = new Bundle();
args.putInt(KEY_TITLE_RES_ID, titleResourceId);
- args.putSerializable(KEY_LIST_FILTER, accountListFilter);
args.putBundle(KEY_EXTRA_ARGS, (extraArgs == null) ? Bundle.EMPTY : extraArgs);
+ args.putSerializable(KEY_LIST_FILTER, filter);
final SelectAccountDialogFragment instance = new SelectAccountDialogFragment();
instance.setArguments(args);
@@ -71,14 +79,22 @@
}
@Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ final Bundle args = getArguments();
+ mFilter = (AccountTypeManager.AccountFilter) args.getSerializable(KEY_LIST_FILTER);
+ if (mFilter == null) {
+ mFilter = AccountTypeManager.AccountFilter.ALL;
+ }
+ }
+
+ @Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
final Bundle args = getArguments();
- final AccountListFilter filter = (AccountListFilter) args.getSerializable(KEY_LIST_FILTER);
- final AccountsListAdapter accountAdapter = new AccountsListAdapter(builder.getContext(),
- filter);
- accountAdapter.setCustomLayout(R.layout.account_selector_list_item_condensed);
+ mAccountsAdapter = new AccountsListAdapter(builder.getContext());
+ mAccountsAdapter.setCustomLayout(R.layout.account_selector_list_item_condensed);
final DialogInterface.OnClickListener clickListener =
new DialogInterface.OnClickListener() {
@@ -86,19 +102,25 @@
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
- onAccountSelected(accountAdapter.getItem(which));
+ onAccountSelected(mAccountsAdapter.getItem(which));
}
};
final TextView title = (TextView) View.inflate(getActivity(), R.layout.dialog_title, null);
title.setText(args.getInt(KEY_TITLE_RES_ID));
builder.setCustomTitle(title);
- builder.setSingleChoiceItems(accountAdapter, 0, clickListener);
+ builder.setSingleChoiceItems(mAccountsAdapter, 0, clickListener);
final AlertDialog result = builder.create();
return result;
}
@Override
+ public void onActivityCreated(Bundle savedInstanceState) {
+ super.onActivityCreated(savedInstanceState);
+ AccountsLoader.loadAccounts(this, 0, mFilter);
+ }
+
+ @Override
public void onCancel(DialogInterface dialog) {
super.onCancel(dialog);
final Listener listener = getListener();
@@ -126,6 +148,13 @@
return listener;
}
+ @Override
+ public void onAccountsLoaded(List<AccountInfo> accounts) {
+ Preconditions.checkNotNull(mAccountsAdapter,
+ "Accounts adapter should have been initialized");
+ mAccountsAdapter.setAccounts(accounts, null);
+ }
+
public interface Listener {
void onAccountChosen(AccountWithDataSet account, Bundle extraArgs);
void onAccountSelectorCancelled();
diff --git a/src/com/android/contacts/group/GroupsFragment.java b/src/com/android/contacts/group/GroupsFragment.java
index 522d3ba..e2a1de4 100644
--- a/src/com/android/contacts/group/GroupsFragment.java
+++ b/src/com/android/contacts/group/GroupsFragment.java
@@ -24,6 +24,9 @@
import android.os.Bundle;
import com.android.contacts.GroupListLoader;
+import com.android.contacts.model.AccountTypeManager;
+import com.android.contacts.model.account.AccountInfo;
+import com.android.contacts.model.account.AccountsLoader;
import java.util.ArrayList;
import java.util.List;
@@ -31,9 +34,10 @@
/**
* Loads groups and group metadata for all accounts.
*/
-public final class GroupsFragment extends Fragment {
+public final class GroupsFragment extends Fragment implements AccountsLoader.AccountsListener {
private static final int LOADER_GROUPS = 1;
+ private static final int LOADER_ACCOUNTS = 2;
/**
* Callbacks for hosts of the {@link GroupsFragment}.
@@ -43,7 +47,8 @@
/**
* Invoked after groups and group metadata have been loaded.
*/
- void onGroupsLoaded(List<GroupListItem> groupListItems);
+ void onGroupsLoaded(List<GroupListItem> groupListItems,
+ boolean areGroupWritableAccountsAvailable);
}
private final LoaderManager.LoaderCallbacks<Cursor> mGroupListLoaderListener =
@@ -65,9 +70,8 @@
mGroupListItems.add(GroupUtil.getGroupListItem(data, i));
}
}
- if (mListener != null) {
- mListener.onGroupsLoaded(mGroupListItems);
- }
+ mGroupsLoaded = true;
+ notifyIfReady();
}
public void onLoaderReset(Loader<Cursor> loader) {
@@ -75,15 +79,33 @@
};
private List<GroupListItem> mGroupListItems = new ArrayList<>();
+ private boolean mHasGroupWritableAccounts = false;
+ private boolean mGroupsLoaded = false;
+ private boolean mAccountsLoaded = false;
private GroupsListener mListener;
@Override
- public void onStart() {
+ public void onActivityCreated(Bundle savedInstanceState) {
+ super.onActivityCreated(savedInstanceState);
+ AccountsLoader.loadAccounts(this, LOADER_ACCOUNTS,
+ AccountTypeManager.AccountFilter.GROUPS_WRITABLE);
getLoaderManager().initLoader(LOADER_GROUPS, null, mGroupListLoaderListener);
- super.onStart();
}
public void setListener(GroupsListener listener) {
mListener = listener;
}
+
+ @Override
+ public void onAccountsLoaded(List<AccountInfo> accounts) {
+ mHasGroupWritableAccounts = !accounts.isEmpty();
+ mAccountsLoaded = true;
+ notifyIfReady();
+ }
+
+ private void notifyIfReady() {
+ if (mAccountsLoaded && mGroupsLoaded && mListener != null) {
+ mListener.onGroupsLoaded(mGroupListItems, mHasGroupWritableAccounts);
+ }
+ }
}
diff --git a/src/com/android/contacts/interactions/ImportDialogFragment.java b/src/com/android/contacts/interactions/ImportDialogFragment.java
index 5bf4fe4..367ae2f 100644
--- a/src/com/android/contacts/interactions/ImportDialogFragment.java
+++ b/src/com/android/contacts/interactions/ImportDialogFragment.java
@@ -44,12 +44,9 @@
import com.android.contacts.model.SimCard;
import com.android.contacts.model.SimContact;
import com.android.contacts.model.account.AccountInfo;
-import com.android.contacts.model.account.AccountType;
import com.android.contacts.model.account.AccountWithDataSet;
import com.android.contacts.util.AccountSelectionUtil;
-import com.android.contacts.util.AccountsListAdapter.AccountListFilter;
import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
import java.util.List;
import java.util.concurrent.Future;
@@ -274,7 +271,7 @@
args.putInt(KEY_SUBSCRIPTION_ID, subscriptionId);
SelectAccountDialogFragment.show(
getFragmentManager(), R.string.dialog_new_contact_account,
- AccountListFilter.ACCOUNTS_CONTACT_WRITABLE, args);
+ AccountTypeManager.AccountFilter.CONTACTS_WRITABLE, args);
} else {
AccountSelectionUtil.doImport(getActivity(), resId,
(size == 1 ? accountList.get(0) : null),
diff --git a/src/com/android/contacts/model/AccountTypeManager.java b/src/com/android/contacts/model/AccountTypeManager.java
index cbdccd5..f8e20e8 100644
--- a/src/com/android/contacts/model/AccountTypeManager.java
+++ b/src/com/android/contacts/model/AccountTypeManager.java
@@ -54,9 +54,7 @@
import com.google.common.base.Function;
import com.google.common.base.Objects;
import com.google.common.base.Predicate;
-import com.google.common.base.Predicates;
import com.google.common.collect.Collections2;
-import com.google.common.collect.Lists;
import com.google.common.util.concurrent.FutureCallback;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
@@ -83,6 +81,27 @@
public static final String BROADCAST_ACCOUNTS_CHANGED = AccountTypeManager.class.getName() +
".AccountsChanged";
+ public enum AccountFilter implements Predicate<AccountInfo> {
+ ALL {
+ @Override
+ public boolean apply(@Nullable AccountInfo input) {
+ return input != null;
+ }
+ },
+ CONTACTS_WRITABLE {
+ @Override
+ public boolean apply(@Nullable AccountInfo input) {
+ return input != null && input.getType().areContactsWritable();
+ }
+ },
+ GROUPS_WRITABLE {
+ @Override
+ public boolean apply(@Nullable AccountInfo input) {
+ return input != null && input.getType().isGroupMembershipEditable();
+ }
+ };
+ }
+
/**
* Requests the singleton instance of {@link AccountTypeManager} with data bound from
* the available authenticators. This method can safely be called from the UI thread.
@@ -118,11 +137,6 @@
private static final AccountTypeManager EMPTY = new AccountTypeManager() {
@Override
- public List<AccountWithDataSet> getAccounts(boolean contactWritableOnly) {
- return Collections.emptyList();
- }
-
- @Override
public ListenableFuture<List<AccountInfo>> getAccountsAsync() {
return Futures.immediateFuture(Collections.<AccountInfo>emptyList());
}
@@ -139,11 +153,6 @@
}
@Override
- public List<AccountWithDataSet> getGroupWritableAccounts() {
- return Collections.emptyList();
- }
-
- @Override
public Account getDefaultGoogleAccount() {
return null;
}
@@ -157,9 +166,29 @@
/**
* Returns the list of all accounts (if contactWritableOnly is false) or just the list of
* contact writable accounts (if contactWritableOnly is true).
+ *
+ * <p>TODO(mhagerott) delete this method. It's left in place to prevent build breakages when
+ * this change is automerged. Usages of this method in downstream branches should be
+ * replaced with an asynchronous account loading pattern</p>
*/
- // TODO: Consider splitting this into getContactWritableAccounts() and getAllAccounts()
- public abstract List<AccountWithDataSet> getAccounts(boolean contactWritableOnly);
+ public List<AccountWithDataSet> getAccounts(boolean contactWritableOnly) {
+ return contactWritableOnly
+ ? blockForWritableAccounts()
+ : AccountInfo.extractAccounts(Futures.getUnchecked(getAccountsAsync()));
+ }
+
+ /**
+ * Returns all contact writable accounts
+ *
+ * <p>In general this method should be avoided. It exists to support some legacy usages of
+ * accounts in infrequently used features where refactoring to asynchronous loading is
+ * not justified. The chance that this will actually block is pretty low if the app has been
+ * launched previously</p>
+ */
+ public List<AccountWithDataSet> blockForWritableAccounts() {
+ return AccountInfo.extractAccounts(
+ Futures.getUnchecked(filterAccountsAsync(AccountFilter.CONTACTS_WRITABLE)));
+ }
/**
* Loads accounts in background and returns future that will complete with list of all accounts
@@ -175,11 +204,6 @@
public abstract AccountInfo getAccountInfoForAccount(AccountWithDataSet account);
/**
- * Returns the list of accounts that are group writable.
- */
- public abstract List<AccountWithDataSet> getGroupWritableAccounts();
-
- /**
* Returns the default google account.
*/
public abstract Account getDefaultGoogleAccount();
@@ -298,43 +322,12 @@
return canGetAccounts && canReadContacts;
}
- public static Predicate<AccountInfo> nonNullAccountFilter() {
- return new Predicate<AccountInfo>() {
- @Override
- public boolean apply(AccountInfo info) {
- AccountWithDataSet account = info != null ? info.getAccount() : null;
- return account != null && !account.isNullAccount();
- }
- };
-
- }
-
public static Predicate<AccountInfo> writableFilter() {
- return new Predicate<AccountInfo>() {
- @Override
- public boolean apply(AccountInfo account) {
- return account.getType().areContactsWritable();
- }
- };
+ return AccountFilter.CONTACTS_WRITABLE;
}
public static Predicate<AccountInfo> groupWritableFilter() {
- return new Predicate<AccountInfo>() {
- @Override
- public boolean apply(@Nullable AccountInfo account) {
- return account.getType().isGroupMembershipEditable();
- }
- };
- }
-
- public static Predicate<AccountInfo> onlyNonEmptyExtensionFilter(Context context) {
- final Context appContext = context.getApplicationContext();
- return new Predicate<AccountInfo>() {
- @Override
- public boolean apply(@Nullable AccountInfo input) {
- return !input.getType().isExtension() || input.getAccount().hasData(appContext);
- }
- };
+ return AccountFilter.GROUPS_WRITABLE;
}
}
@@ -530,19 +523,6 @@
mMainThreadExecutor);
}
- /**
- * Return list of all known or contact writable {@link AccountWithDataSet}'s.
- * {@param contactWritableOnly} whether to restrict to contact writable accounts only
- */
- @Override
- public List<AccountWithDataSet> getAccounts(boolean contactWritableOnly) {
- final Predicate<AccountInfo> filter = contactWritableOnly ?
- writableFilter() : Predicates.<AccountInfo>alwaysTrue();
- // TODO: Shouldn't have a synchronous version for getting all accounts
- return Lists.transform(Futures.getUnchecked(filterAccountsAsync(filter)),
- AccountInfo.ACCOUNT_EXTRACTOR);
- }
-
@Override
public ListenableFuture<List<AccountInfo>> getAccountsAsync() {
return getAllAccountsAsyncInternal();
@@ -621,14 +601,6 @@
}
/**
- * Return the list of all known, group writable {@link AccountWithDataSet}'s.
- */
- public List<AccountWithDataSet> getGroupWritableAccounts() {
- return Lists.transform(Futures.getUnchecked(
- filterAccountsAsync(groupWritableFilter())), AccountInfo.ACCOUNT_EXTRACTOR);
- }
-
- /**
* Returns the default google account specified in preferences, the first google account
* if it is not specified in preferences or is no longer on the device, and null otherwise.
*/
diff --git a/src/com/android/contacts/model/account/AccountsLoader.java b/src/com/android/contacts/model/account/AccountsLoader.java
index 260c44b..e3b4336 100644
--- a/src/com/android/contacts/model/account/AccountsLoader.java
+++ b/src/com/android/contacts/model/account/AccountsLoader.java
@@ -71,6 +71,8 @@
* <p>This is a convenience method to reduce the
* boilerplate needed when implementing {@link android.app.LoaderManager.LoaderCallbacks}
* in the simple case that the fragment wants to just load the accounts directly</p>
+ * <p>Note that changing the filter between invocations in the same component will not work
+ * properly because the loader is cached.</p>
*/
public static <FragmentType extends Fragment & AccountsListener> void loadAccounts(
final FragmentType fragment, int loaderId, final Predicate<AccountInfo> filter) {
@@ -78,6 +80,9 @@
fragment.getActivity(), fragment.getLoaderManager(), loaderId, filter, fragment);
}
+ /**
+ * Same as {@link #loadAccounts(Fragment, int, Predicate)} for an Activity
+ */
public static <ActivityType extends Activity & AccountsListener> void loadAccounts(
final ActivityType activity, int id, final Predicate<AccountInfo> filter) {
loadAccounts(activity, activity.getLoaderManager(), id, filter, activity);
diff --git a/src/com/android/contacts/preference/DefaultAccountPreference.java b/src/com/android/contacts/preference/DefaultAccountPreference.java
index 72ba74d..efff5a0 100644
--- a/src/com/android/contacts/preference/DefaultAccountPreference.java
+++ b/src/com/android/contacts/preference/DefaultAccountPreference.java
@@ -24,14 +24,17 @@
import android.view.View;
import com.android.contacts.model.AccountTypeManager;
-import com.android.contacts.model.account.AccountDisplayInfoFactory;
+import com.android.contacts.model.account.AccountInfo;
import com.android.contacts.model.account.AccountWithDataSet;
import com.android.contacts.util.AccountsListAdapter;
+import java.util.List;
+
public class DefaultAccountPreference extends DialogPreference {
private ContactsPreferences mPreferences;
private AccountsListAdapter mListAdapter;
private AccountTypeManager mAccountTypeManager;
+ private List<AccountInfo> mAccounts;
private int mChosenIndex = -1;
public DefaultAccountPreference(Context context) {
@@ -44,6 +47,13 @@
prepare();
}
+ public void setAccounts(List<AccountInfo> accounts) {
+ mAccounts = accounts;
+ if (mListAdapter != null) {
+ mListAdapter.setAccounts(accounts, null);
+ }
+ }
+
@Override
protected View onCreateDialogView() {
prepare();
@@ -52,8 +62,10 @@
private void prepare() {
mPreferences = new ContactsPreferences(getContext());
- mListAdapter = new AccountsListAdapter(getContext(),
- AccountsListAdapter.AccountListFilter.ACCOUNTS_CONTACT_WRITABLE);
+ mListAdapter = new AccountsListAdapter(getContext());
+ if (mAccounts != null) {
+ mListAdapter.setAccounts(mAccounts, null);
+ }
mAccountTypeManager = AccountTypeManager.getInstance(getContext());
}
diff --git a/src/com/android/contacts/preference/DisplayOptionsPreferenceFragment.java b/src/com/android/contacts/preference/DisplayOptionsPreferenceFragment.java
index a9ec250..e9c3a01 100644
--- a/src/com/android/contacts/preference/DisplayOptionsPreferenceFragment.java
+++ b/src/com/android/contacts/preference/DisplayOptionsPreferenceFragment.java
@@ -297,6 +297,10 @@
if (accounts.isEmpty()) {
getPreferenceScreen().removePreference(findPreference(KEY_DEFAULT_ACCOUNT));
getPreferenceScreen().removePreference(findPreference(KEY_CUSTOM_CONTACTS_FILTER));
+ } else {
+ final DefaultAccountPreference preference =
+ (DefaultAccountPreference) findPreference(KEY_DEFAULT_ACCOUNT);
+ preference.setAccounts(accounts);
}
}
diff --git a/src/com/android/contacts/util/AccountSelectionUtil.java b/src/com/android/contacts/util/AccountSelectionUtil.java
index a29af9a..bfe8a08 100644
--- a/src/com/android/contacts/util/AccountSelectionUtil.java
+++ b/src/com/android/contacts/util/AccountSelectionUtil.java
@@ -84,15 +84,6 @@
}
}
- public static Dialog getSelectAccountDialog(Activity activity, int resId) {
- return getSelectAccountDialog(activity, resId, null, null);
- }
-
- public static Dialog getSelectAccountDialog(Activity activity, int resId,
- DialogInterface.OnClickListener onClickListener) {
- return getSelectAccountDialog(activity, resId, onClickListener, null);
- }
-
/**
* When OnClickListener or OnCancelListener is null, uses a default listener.
* The default OnCancelListener just closes itself with {@link Dialog#dismiss()}.
@@ -101,7 +92,8 @@
DialogInterface.OnClickListener onClickListener,
DialogInterface.OnCancelListener onCancelListener) {
final AccountTypeManager accountTypes = AccountTypeManager.getInstance(activity);
- final List<AccountWithDataSet> writableAccountList = accountTypes.getAccounts(true);
+ final List<AccountWithDataSet> writableAccountList =
+ accountTypes.blockForWritableAccounts();
Log.i(LOG_TAG, "The number of available accounts: " + writableAccountList.size());
diff --git a/src/com/android/contacts/util/AccountsListAdapter.java b/src/com/android/contacts/util/AccountsListAdapter.java
index 005bb8d..2bcc68b 100644
--- a/src/com/android/contacts/util/AccountsListAdapter.java
+++ b/src/com/android/contacts/util/AccountsListAdapter.java
@@ -30,6 +30,7 @@
import com.android.contacts.model.account.AccountWithDataSet;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.List;
/**
@@ -37,50 +38,11 @@
*/
public final class AccountsListAdapter extends BaseAdapter {
private final LayoutInflater mInflater;
- private final List<AccountInfo> mAccounts;
- private final Context mContext;
+ private List<AccountInfo> mAccounts;
private int mCustomLayout = -1;
- public enum AccountListFilter {
- ALL_ACCOUNTS {
- @Override
- public List<AccountWithDataSet> getSourceAccounts(Context context) {
- return AccountTypeManager.getInstance(context).getAccounts(false);
- }
- },
- ACCOUNTS_CONTACT_WRITABLE {
- @Override
- public List<AccountWithDataSet> getSourceAccounts(Context context) {
- return AccountTypeManager.getInstance(context).getAccounts(true);
- }
- },
- ACCOUNTS_GROUP_WRITABLE {
- @Override
- public List<AccountWithDataSet> getSourceAccounts(Context context) {
- return AccountTypeManager.getInstance(context).getGroupWritableAccounts();
- }
- };
-
- private List<AccountInfo> getAccounts(Context context) {
- final AccountTypeManager accountTypeManager = AccountTypeManager.getInstance(context);
- final List<AccountInfo> result = new ArrayList<>();
- final List<AccountWithDataSet> sourceAccounts = getSourceAccounts(context);
- for (AccountWithDataSet account : sourceAccounts) {
- result.add(accountTypeManager.getAccountInfoForAccount(account));
- }
- return result;
- }
-
- public abstract List<AccountWithDataSet> getSourceAccounts(Context context);
- }
-
- public AccountsListAdapter(Context context, AccountListFilter filter) {
- this(context, filter.getAccounts(context), null);
- }
-
- public AccountsListAdapter(Context context, AccountListFilter filter,
- AccountWithDataSet currentAccount) {
- this(context, filter.getAccounts(context), currentAccount);
+ public AccountsListAdapter(Context context) {
+ this(context, Collections.<AccountInfo>emptyList(), null);
}
public AccountsListAdapter(Context context, List<AccountInfo> accounts) {
@@ -93,19 +55,28 @@
*/
public AccountsListAdapter(Context context, List<AccountInfo> accounts,
AccountWithDataSet currentAccount) {
- mContext = context;
-
- final AccountInfo currentInfo = AccountInfo.getAccount(accounts, currentAccount);
- if (currentInfo != null
- && !accounts.isEmpty()
- && !accounts.get(0).sameAccount(currentAccount)
- && accounts.remove(currentInfo)) {
- accounts.add(0, currentInfo);
- }
-
mInflater = LayoutInflater.from(context);
- mAccounts = accounts;
+ mAccounts = new ArrayList<>(accounts.size());
+ setAccounts(accounts, currentAccount);
+ }
+
+ public void setAccounts(List<AccountInfo> accounts, AccountWithDataSet currentAccount) {
+ // If it's not empty use the previous "current" account (the first one in the list)
+ final AccountInfo currentInfo = mAccounts.isEmpty()
+ ? AccountInfo.getAccount(accounts, currentAccount)
+ : AccountInfo.getAccount(accounts, mAccounts.get(0).getAccount());
+
+ mAccounts.clear();
+ mAccounts.addAll(accounts);
+
+ if (currentInfo != null
+ && !mAccounts.isEmpty()
+ && !mAccounts.get(0).sameAccount(currentAccount)
+ && mAccounts.remove(currentInfo)) {
+ mAccounts.add(0, currentInfo);
+ }
+ notifyDataSetChanged();
}
public void setCustomLayout(int customLayout) {
diff --git a/src/com/android/contacts/vcard/ImportVCardActivity.java b/src/com/android/contacts/vcard/ImportVCardActivity.java
index 6d486e3..2c69cdf 100644
--- a/src/com/android/contacts/vcard/ImportVCardActivity.java
+++ b/src/com/android/contacts/vcard/ImportVCardActivity.java
@@ -597,7 +597,7 @@
mAccount = new AccountWithDataSet(accountName, accountType, dataSet);
} else {
final AccountTypeManager accountTypes = AccountTypeManager.getInstance(this);
- final List<AccountWithDataSet> accountList = accountTypes.getAccounts(true);
+ final List<AccountWithDataSet> accountList = accountTypes.blockForWritableAccounts();
if (accountList.size() == 0) {
mAccount = null;
} else if (accountList.size() == 1) {
diff --git a/src/com/android/contacts/vcard/NfcImportVCardActivity.java b/src/com/android/contacts/vcard/NfcImportVCardActivity.java
index 4793d47..4eb9b57 100644
--- a/src/com/android/contacts/vcard/NfcImportVCardActivity.java
+++ b/src/com/android/contacts/vcard/NfcImportVCardActivity.java
@@ -194,7 +194,7 @@
mRecord = msg.getRecords()[0];
final AccountTypeManager accountTypes = AccountTypeManager.getInstance(this);
- final List<AccountWithDataSet> accountList = accountTypes.getAccounts(true);
+ final List<AccountWithDataSet> accountList = accountTypes.blockForWritableAccounts();
if (accountList.size() == 0) {
mAccount = null;
} else if (accountList.size() == 1) {
diff --git a/src/com/android/contacts/vcard/SelectAccountActivity.java b/src/com/android/contacts/vcard/SelectAccountActivity.java
index 8809fac..ac5b3eb 100644
--- a/src/com/android/contacts/vcard/SelectAccountActivity.java
+++ b/src/com/android/contacts/vcard/SelectAccountActivity.java
@@ -58,7 +58,7 @@
// - no account -> use phone-local storage without asking the user
final int resId = R.string.import_from_vcf_file;
final AccountTypeManager accountTypes = AccountTypeManager.getInstance(this);
- final List<AccountWithDataSet> accountList = accountTypes.getAccounts(true);
+ final List<AccountWithDataSet> accountList = accountTypes.blockForWritableAccounts();
if (accountList.size() == 0) {
Log.w(LOG_TAG, "Account does not exist");
finish();
diff --git a/tests/src/com/android/contacts/test/mocks/MockAccountTypeManager.java b/tests/src/com/android/contacts/test/mocks/MockAccountTypeManager.java
index 956f775..d5c1ccb 100644
--- a/tests/src/com/android/contacts/test/mocks/MockAccountTypeManager.java
+++ b/tests/src/com/android/contacts/test/mocks/MockAccountTypeManager.java
@@ -25,9 +25,6 @@
import com.android.contacts.model.account.BaseAccountType;
import com.google.common.base.Objects;
import com.google.common.base.Predicate;
-import com.google.common.collect.Collections2;
-import com.google.common.collect.Lists;
-import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import java.util.Arrays;
@@ -66,7 +63,7 @@
}
@Override
- public List<AccountWithDataSet> getAccounts(boolean writableOnly) {
+ public List<AccountWithDataSet> blockForWritableAccounts() {
return Arrays.asList(mAccounts);
}
@@ -86,11 +83,6 @@
}
@Override
- public List<AccountWithDataSet> getGroupWritableAccounts() {
- return Arrays.asList(mAccounts);
- }
-
- @Override
public Account getDefaultGoogleAccount() {
return null;
}