Loading src/com/android/contacts/activities/PeopleActivity.java +2 −1 Original line number Original line Diff line number Diff line Loading @@ -1490,7 +1490,8 @@ public class PeopleActivity extends ContactsDrawerActivity implements if (getSupportActionBar() != null) { if (getSupportActionBar() != null) { String actionBarTitle; String actionBarTitle; if (filter.filterType == ContactListFilter.FILTER_TYPE_DEVICE_CONTACTS) { if (filter.filterType == ContactListFilter.FILTER_TYPE_DEVICE_CONTACTS && filter.accountName == null) { actionBarTitle = getString(R.string.account_phone); actionBarTitle = getString(R.string.account_phone); } else if (!TextUtils.isEmpty(filter.accountName)) { } else if (!TextUtils.isEmpty(filter.accountName)) { actionBarTitle = getActionBarTitleForAccount(filter); actionBarTitle = getActionBarTitleForAccount(filter); Loading src/com/android/contacts/common/list/ContactListFilter.java +7 −3 Original line number Original line Diff line number Diff line Loading @@ -93,6 +93,12 @@ public final class ContactListFilter implements Comparable<ContactListFilter>, P /* accountType= */ null, /* accountName= */ null, /* dataSet= */ null, icon); /* accountType= */ null, /* accountName= */ null, /* dataSet= */ null, icon); } } public static ContactListFilter createDeviceContactsFilter(Drawable icon, AccountWithDataSet account) { return new ContactListFilter(ContactListFilter.FILTER_TYPE_DEVICE_CONTACTS, account.type, account.name, account.dataSet, icon); } /** /** * Whether the given {@link ContactListFilter} has a filter type that should be displayed as * Whether the given {@link ContactListFilter} has a filter type that should be displayed as * the default contacts list view. * the default contacts list view. Loading Loading @@ -333,10 +339,8 @@ public final class ContactListFilter implements Comparable<ContactListFilter>, P } } public AccountWithDataSet toAccountWithDataSet() { public AccountWithDataSet toAccountWithDataSet() { if (filterType == FILTER_TYPE_ACCOUNT) { if (filterType == FILTER_TYPE_ACCOUNT || filterType == FILTER_TYPE_DEVICE_CONTACTS) { return new AccountWithDataSet(accountName, accountType, dataSet); return new AccountWithDataSet(accountName, accountType, dataSet); } else if (filterType == FILTER_TYPE_DEVICE_CONTACTS) { return AccountWithDataSet.getLocalAccount(); } else { } else { throw new IllegalStateException("Cannot create Account from filter type " + throw new IllegalStateException("Cannot create Account from filter type " + filterTypeToString(filterType)); filterTypeToString(filterType)); Loading src/com/android/contacts/common/model/DeviceLocalAccountLocator.java +64 −29 Original line number Original line Diff line number Diff line Loading @@ -18,10 +18,10 @@ package com.android.contacts.common.model; import android.accounts.AccountManager; import android.accounts.AccountManager; import android.content.ContentResolver; import android.content.ContentResolver; import android.database.Cursor; import android.database.Cursor; import android.net.Uri; import android.provider.ContactsContract; import android.provider.ContactsContract; import android.support.annotation.VisibleForTesting; import android.support.annotation.VisibleForTesting; import com.android.contacts.common.model.account.AccountType; import com.android.contacts.common.model.account.AccountWithDataSet; import com.android.contacts.common.model.account.AccountWithDataSet; import com.android.contacts.common.util.DeviceLocalAccountTypeFactory; import com.android.contacts.common.util.DeviceLocalAccountTypeFactory; Loading @@ -39,6 +39,9 @@ import java.util.Set; */ */ public class DeviceLocalAccountLocator { public class DeviceLocalAccountLocator { // Note this class is assuming ACCOUNT_NAME and ACCOUNT_TYPE have same values in // RawContacts, Groups, and Settings. This assumption simplifies the code somewhat and it // is true right now and unlikely to ever change. @VisibleForTesting @VisibleForTesting static String[] PROJECTION = new String[] { static String[] PROJECTION = new String[] { ContactsContract.RawContacts.ACCOUNT_NAME, ContactsContract.RawContacts.ACCOUNT_TYPE, ContactsContract.RawContacts.ACCOUNT_NAME, ContactsContract.RawContacts.ACCOUNT_TYPE, Loading @@ -49,30 +52,59 @@ public class DeviceLocalAccountLocator { private static final int COL_TYPE = 1; private static final int COL_TYPE = 1; private static final int COL_DATA_SET = 2; private static final int COL_DATA_SET = 2; private final ContentResolver mResolver; private final ContentResolver mResolver; private final DeviceLocalAccountTypeFactory mAccountTypeFactory; private final DeviceLocalAccountTypeFactory mAccountTypeFactory; private final Set<String> mKnownAccountTypes; private final String mSelection; private final String[] mSelectionArgs; public DeviceLocalAccountLocator(ContentResolver contentResolver, public DeviceLocalAccountLocator(ContentResolver contentResolver, DeviceLocalAccountTypeFactory factory, DeviceLocalAccountTypeFactory factory, List<AccountWithDataSet> knownAccounts) { List<AccountWithDataSet> knownAccounts) { mResolver = contentResolver; mResolver = contentResolver; mAccountTypeFactory = factory; mAccountTypeFactory = factory; mKnownAccountTypes = new HashSet<>(); final Set<String> knownAccountTypes = new HashSet<>(); for (AccountWithDataSet account : knownAccounts) { for (AccountWithDataSet account : knownAccounts) { mKnownAccountTypes.add(account.type); knownAccountTypes.add(account.type); } } mSelection = getSelection(knownAccountTypes); mSelectionArgs = getSelectionArgs(knownAccountTypes); } } public List<AccountWithDataSet> getDeviceLocalAccounts() { public List<AccountWithDataSet> getDeviceLocalAccounts() { final String[] selectionArgs = getSelectionArgs(); final Cursor cursor = mResolver.query(ContactsContract.RawContacts.CONTENT_URI, PROJECTION, getSelection(), selectionArgs, null); final Set<AccountWithDataSet> localAccounts = new HashSet<>(); final Set<AccountWithDataSet> localAccounts = new HashSet<>(); // Many device accounts have default groups associated with them. addAccountsFromQuery(ContactsContract.Groups.CONTENT_URI, localAccounts); addAccountsFromQuery(ContactsContract.Settings.CONTENT_URI, localAccounts); if (localAccounts.isEmpty()) { // It's probably safe to assume that if one of the earlier queries found a "device" // account then this query isn't going to find any different device accounts. // We skip this query because it probably is kind of expensive (relative to the other // queries). addAccountsFromQuery(ContactsContract.RawContacts.CONTENT_URI, localAccounts); } return new ArrayList<>(localAccounts); } private void addAccountsFromQuery(Uri uri, Set<AccountWithDataSet> accounts) { final Cursor cursor = mResolver.query(uri, PROJECTION, mSelection, mSelectionArgs, null); if (cursor == null) return; try { try { addAccountsFromCursor(cursor, accounts); } finally { cursor.close(); } } private void addAccountsFromCursor(Cursor cursor, Set<AccountWithDataSet> accounts) { while (cursor.moveToNext()) { while (cursor.moveToNext()) { final String name = cursor.getString(COL_NAME); final String name = cursor.getString(COL_NAME); final String type = cursor.getString(COL_TYPE); final String type = cursor.getString(COL_TYPE); Loading @@ -80,36 +112,39 @@ public class DeviceLocalAccountLocator { if (DeviceLocalAccountTypeFactory.Util.isLocalAccountType( if (DeviceLocalAccountTypeFactory.Util.isLocalAccountType( mAccountTypeFactory, type)) { mAccountTypeFactory, type)) { localAccounts.add(new AccountWithDataSet(name, type, dataSet)); accounts.add(new AccountWithDataSet(name, type, dataSet)); } } } } } finally { cursor.close(); } } return new ArrayList<>(localAccounts); @VisibleForTesting public String getSelection() { return mSelection; } } @VisibleForTesting @VisibleForTesting public String getSelection() { public String[] getSelectionArgs() { final StringBuilder sb = new StringBuilder(); return mSelectionArgs; sb.append(ContactsContract.RawContacts.DELETED).append(" =0 AND (") } private static String getSelection(Set<String> knownAccountTypes) { final StringBuilder sb = new StringBuilder() .append(ContactsContract.RawContacts.ACCOUNT_TYPE).append(" IS NULL"); .append(ContactsContract.RawContacts.ACCOUNT_TYPE).append(" IS NULL"); if (mKnownAccountTypes.isEmpty()) { if (knownAccountTypes.isEmpty()) { return sb.append(')').toString(); return sb.toString(); } } sb.append(" OR ").append(ContactsContract.RawContacts.ACCOUNT_TYPE).append(" NOT IN ("); sb.append(" OR ").append(ContactsContract.RawContacts.ACCOUNT_TYPE).append(" NOT IN ("); for (String ignored : mKnownAccountTypes) { for (String ignored : knownAccountTypes) { sb.append("?,"); sb.append("?,"); } } // Remove trailing ',' // Remove trailing ',' sb.deleteCharAt(sb.length() - 1).append(')').append(')'); sb.deleteCharAt(sb.length() - 1).append(')'); return sb.toString(); return sb.toString(); } } @VisibleForTesting private static String[] getSelectionArgs(Set<String> knownAccountTypes) { public String[] getSelectionArgs() { if (knownAccountTypes.isEmpty()) return null; return mKnownAccountTypes.toArray(new String[mKnownAccountTypes.size()]); return knownAccountTypes.toArray(new String[knownAccountTypes.size()]); } } } } src/com/android/contacts/common/model/account/AccountWithDataSet.java +1 −0 Original line number Original line Diff line number Diff line Loading @@ -139,6 +139,7 @@ public class AccountWithDataSet implements Parcelable { args = new String[] {type, name, dataSet}; args = new String[] {type, name, dataSet}; } } } } selection += " AND " + RawContacts.DELETED + "=0"; final Cursor c = context.getContentResolver().query(RAW_CONTACTS_URI_LIMIT_1, final Cursor c = context.getContentResolver().query(RAW_CONTACTS_URI_LIMIT_1, ID_PROJECTION, selection, args, null); ID_PROJECTION, selection, args, null); Loading src/com/android/contacts/common/util/AccountFilterUtil.java +15 −6 Original line number Original line Diff line number Diff line Loading @@ -22,7 +22,9 @@ import android.content.AsyncTaskLoader; import android.content.Context; import android.content.Context; import android.content.Intent; import android.content.Intent; import android.content.SharedPreferences; import android.content.SharedPreferences; import android.database.Cursor; import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable; import android.provider.ContactsContract; import android.text.TextUtils; import android.text.TextUtils; import android.util.Log; import android.util.Log; Loading @@ -31,8 +33,10 @@ import com.android.contacts.common.list.AccountFilterActivity; import com.android.contacts.common.list.ContactListFilter; import com.android.contacts.common.list.ContactListFilter; import com.android.contacts.common.list.ContactListFilterController; import com.android.contacts.common.list.ContactListFilterController; import com.android.contacts.common.model.AccountTypeManager; import com.android.contacts.common.model.AccountTypeManager; import com.android.contacts.common.model.RawContact; import com.android.contacts.common.model.account.AccountType; import com.android.contacts.common.model.account.AccountType; import com.android.contacts.common.model.account.AccountWithDataSet; import com.android.contacts.common.model.account.AccountWithDataSet; import com.android.contactsbind.ObjectFactory; import com.google.common.collect.Lists; import com.google.common.collect.Lists; import java.util.ArrayList; import java.util.ArrayList; Loading Loading @@ -90,15 +94,17 @@ public class AccountFilterUtil { */ */ public static class FilterLoader extends AsyncTaskLoader<List<ContactListFilter>> { public static class FilterLoader extends AsyncTaskLoader<List<ContactListFilter>> { private Context mContext; private Context mContext; private DeviceLocalAccountTypeFactory mDeviceLocalFactory; public FilterLoader(Context context) { public FilterLoader(Context context) { super(context); super(context); mContext = context; mContext = context; mDeviceLocalFactory = ObjectFactory.getDeviceLocalAccountTypeFactory(context); } } @Override @Override public List<ContactListFilter> loadInBackground() { public List<ContactListFilter> loadInBackground() { return loadAccountFilters(mContext); return loadAccountFilters(mContext, mDeviceLocalFactory); } } @Override @Override Loading @@ -117,7 +123,8 @@ public class AccountFilterUtil { } } } } private static List<ContactListFilter> loadAccountFilters(Context context) { private static List<ContactListFilter> loadAccountFilters(Context context, DeviceLocalAccountTypeFactory deviceAccountTypeFactory) { final ArrayList<ContactListFilter> accountFilters = Lists.newArrayList(); final ArrayList<ContactListFilter> accountFilters = Lists.newArrayList(); final AccountTypeManager accountTypeManager = AccountTypeManager.getInstance(context); final AccountTypeManager accountTypeManager = AccountTypeManager.getInstance(context); accountTypeManager.sortAccounts(/* defaultAccount */ getDefaultAccount(context)); accountTypeManager.sortAccounts(/* defaultAccount */ getDefaultAccount(context)); Loading @@ -127,13 +134,15 @@ public class AccountFilterUtil { for (AccountWithDataSet account : accounts) { for (AccountWithDataSet account : accounts) { final AccountType accountType = final AccountType accountType = accountTypeManager.getAccountType(account.type, account.dataSet); accountTypeManager.getAccountType(account.type, account.dataSet); if (accountType.isExtension() && !account.hasData(context)) { if ((accountType.isExtension() || DeviceLocalAccountTypeFactory.Util.isLocalAccountType( // Hide extensions with no raw_contacts. deviceAccountTypeFactory, account.type)) && !account.hasData(context)) { // Hide extensions and device accounts with no raw_contacts. continue; continue; } } final Drawable icon = accountType != null ? accountType.getDisplayIcon(context) : null; final Drawable icon = accountType != null ? accountType.getDisplayIcon(context) : null; if (account.isLocalAccount()) { if (DeviceLocalAccountTypeFactory.Util.isLocalAccountType( accountFilters.add(ContactListFilter.createDeviceContactsFilter(icon)); deviceAccountTypeFactory, account.type)) { accountFilters.add(ContactListFilter.createDeviceContactsFilter(icon, account)); } else { } else { accountFilters.add(ContactListFilter.createAccountFilter( accountFilters.add(ContactListFilter.createAccountFilter( account.type, account.name, account.dataSet, icon)); account.type, account.name, account.dataSet, icon)); Loading Loading
src/com/android/contacts/activities/PeopleActivity.java +2 −1 Original line number Original line Diff line number Diff line Loading @@ -1490,7 +1490,8 @@ public class PeopleActivity extends ContactsDrawerActivity implements if (getSupportActionBar() != null) { if (getSupportActionBar() != null) { String actionBarTitle; String actionBarTitle; if (filter.filterType == ContactListFilter.FILTER_TYPE_DEVICE_CONTACTS) { if (filter.filterType == ContactListFilter.FILTER_TYPE_DEVICE_CONTACTS && filter.accountName == null) { actionBarTitle = getString(R.string.account_phone); actionBarTitle = getString(R.string.account_phone); } else if (!TextUtils.isEmpty(filter.accountName)) { } else if (!TextUtils.isEmpty(filter.accountName)) { actionBarTitle = getActionBarTitleForAccount(filter); actionBarTitle = getActionBarTitleForAccount(filter); Loading
src/com/android/contacts/common/list/ContactListFilter.java +7 −3 Original line number Original line Diff line number Diff line Loading @@ -93,6 +93,12 @@ public final class ContactListFilter implements Comparable<ContactListFilter>, P /* accountType= */ null, /* accountName= */ null, /* dataSet= */ null, icon); /* accountType= */ null, /* accountName= */ null, /* dataSet= */ null, icon); } } public static ContactListFilter createDeviceContactsFilter(Drawable icon, AccountWithDataSet account) { return new ContactListFilter(ContactListFilter.FILTER_TYPE_DEVICE_CONTACTS, account.type, account.name, account.dataSet, icon); } /** /** * Whether the given {@link ContactListFilter} has a filter type that should be displayed as * Whether the given {@link ContactListFilter} has a filter type that should be displayed as * the default contacts list view. * the default contacts list view. Loading Loading @@ -333,10 +339,8 @@ public final class ContactListFilter implements Comparable<ContactListFilter>, P } } public AccountWithDataSet toAccountWithDataSet() { public AccountWithDataSet toAccountWithDataSet() { if (filterType == FILTER_TYPE_ACCOUNT) { if (filterType == FILTER_TYPE_ACCOUNT || filterType == FILTER_TYPE_DEVICE_CONTACTS) { return new AccountWithDataSet(accountName, accountType, dataSet); return new AccountWithDataSet(accountName, accountType, dataSet); } else if (filterType == FILTER_TYPE_DEVICE_CONTACTS) { return AccountWithDataSet.getLocalAccount(); } else { } else { throw new IllegalStateException("Cannot create Account from filter type " + throw new IllegalStateException("Cannot create Account from filter type " + filterTypeToString(filterType)); filterTypeToString(filterType)); Loading
src/com/android/contacts/common/model/DeviceLocalAccountLocator.java +64 −29 Original line number Original line Diff line number Diff line Loading @@ -18,10 +18,10 @@ package com.android.contacts.common.model; import android.accounts.AccountManager; import android.accounts.AccountManager; import android.content.ContentResolver; import android.content.ContentResolver; import android.database.Cursor; import android.database.Cursor; import android.net.Uri; import android.provider.ContactsContract; import android.provider.ContactsContract; import android.support.annotation.VisibleForTesting; import android.support.annotation.VisibleForTesting; import com.android.contacts.common.model.account.AccountType; import com.android.contacts.common.model.account.AccountWithDataSet; import com.android.contacts.common.model.account.AccountWithDataSet; import com.android.contacts.common.util.DeviceLocalAccountTypeFactory; import com.android.contacts.common.util.DeviceLocalAccountTypeFactory; Loading @@ -39,6 +39,9 @@ import java.util.Set; */ */ public class DeviceLocalAccountLocator { public class DeviceLocalAccountLocator { // Note this class is assuming ACCOUNT_NAME and ACCOUNT_TYPE have same values in // RawContacts, Groups, and Settings. This assumption simplifies the code somewhat and it // is true right now and unlikely to ever change. @VisibleForTesting @VisibleForTesting static String[] PROJECTION = new String[] { static String[] PROJECTION = new String[] { ContactsContract.RawContacts.ACCOUNT_NAME, ContactsContract.RawContacts.ACCOUNT_TYPE, ContactsContract.RawContacts.ACCOUNT_NAME, ContactsContract.RawContacts.ACCOUNT_TYPE, Loading @@ -49,30 +52,59 @@ public class DeviceLocalAccountLocator { private static final int COL_TYPE = 1; private static final int COL_TYPE = 1; private static final int COL_DATA_SET = 2; private static final int COL_DATA_SET = 2; private final ContentResolver mResolver; private final ContentResolver mResolver; private final DeviceLocalAccountTypeFactory mAccountTypeFactory; private final DeviceLocalAccountTypeFactory mAccountTypeFactory; private final Set<String> mKnownAccountTypes; private final String mSelection; private final String[] mSelectionArgs; public DeviceLocalAccountLocator(ContentResolver contentResolver, public DeviceLocalAccountLocator(ContentResolver contentResolver, DeviceLocalAccountTypeFactory factory, DeviceLocalAccountTypeFactory factory, List<AccountWithDataSet> knownAccounts) { List<AccountWithDataSet> knownAccounts) { mResolver = contentResolver; mResolver = contentResolver; mAccountTypeFactory = factory; mAccountTypeFactory = factory; mKnownAccountTypes = new HashSet<>(); final Set<String> knownAccountTypes = new HashSet<>(); for (AccountWithDataSet account : knownAccounts) { for (AccountWithDataSet account : knownAccounts) { mKnownAccountTypes.add(account.type); knownAccountTypes.add(account.type); } } mSelection = getSelection(knownAccountTypes); mSelectionArgs = getSelectionArgs(knownAccountTypes); } } public List<AccountWithDataSet> getDeviceLocalAccounts() { public List<AccountWithDataSet> getDeviceLocalAccounts() { final String[] selectionArgs = getSelectionArgs(); final Cursor cursor = mResolver.query(ContactsContract.RawContacts.CONTENT_URI, PROJECTION, getSelection(), selectionArgs, null); final Set<AccountWithDataSet> localAccounts = new HashSet<>(); final Set<AccountWithDataSet> localAccounts = new HashSet<>(); // Many device accounts have default groups associated with them. addAccountsFromQuery(ContactsContract.Groups.CONTENT_URI, localAccounts); addAccountsFromQuery(ContactsContract.Settings.CONTENT_URI, localAccounts); if (localAccounts.isEmpty()) { // It's probably safe to assume that if one of the earlier queries found a "device" // account then this query isn't going to find any different device accounts. // We skip this query because it probably is kind of expensive (relative to the other // queries). addAccountsFromQuery(ContactsContract.RawContacts.CONTENT_URI, localAccounts); } return new ArrayList<>(localAccounts); } private void addAccountsFromQuery(Uri uri, Set<AccountWithDataSet> accounts) { final Cursor cursor = mResolver.query(uri, PROJECTION, mSelection, mSelectionArgs, null); if (cursor == null) return; try { try { addAccountsFromCursor(cursor, accounts); } finally { cursor.close(); } } private void addAccountsFromCursor(Cursor cursor, Set<AccountWithDataSet> accounts) { while (cursor.moveToNext()) { while (cursor.moveToNext()) { final String name = cursor.getString(COL_NAME); final String name = cursor.getString(COL_NAME); final String type = cursor.getString(COL_TYPE); final String type = cursor.getString(COL_TYPE); Loading @@ -80,36 +112,39 @@ public class DeviceLocalAccountLocator { if (DeviceLocalAccountTypeFactory.Util.isLocalAccountType( if (DeviceLocalAccountTypeFactory.Util.isLocalAccountType( mAccountTypeFactory, type)) { mAccountTypeFactory, type)) { localAccounts.add(new AccountWithDataSet(name, type, dataSet)); accounts.add(new AccountWithDataSet(name, type, dataSet)); } } } } } finally { cursor.close(); } } return new ArrayList<>(localAccounts); @VisibleForTesting public String getSelection() { return mSelection; } } @VisibleForTesting @VisibleForTesting public String getSelection() { public String[] getSelectionArgs() { final StringBuilder sb = new StringBuilder(); return mSelectionArgs; sb.append(ContactsContract.RawContacts.DELETED).append(" =0 AND (") } private static String getSelection(Set<String> knownAccountTypes) { final StringBuilder sb = new StringBuilder() .append(ContactsContract.RawContacts.ACCOUNT_TYPE).append(" IS NULL"); .append(ContactsContract.RawContacts.ACCOUNT_TYPE).append(" IS NULL"); if (mKnownAccountTypes.isEmpty()) { if (knownAccountTypes.isEmpty()) { return sb.append(')').toString(); return sb.toString(); } } sb.append(" OR ").append(ContactsContract.RawContacts.ACCOUNT_TYPE).append(" NOT IN ("); sb.append(" OR ").append(ContactsContract.RawContacts.ACCOUNT_TYPE).append(" NOT IN ("); for (String ignored : mKnownAccountTypes) { for (String ignored : knownAccountTypes) { sb.append("?,"); sb.append("?,"); } } // Remove trailing ',' // Remove trailing ',' sb.deleteCharAt(sb.length() - 1).append(')').append(')'); sb.deleteCharAt(sb.length() - 1).append(')'); return sb.toString(); return sb.toString(); } } @VisibleForTesting private static String[] getSelectionArgs(Set<String> knownAccountTypes) { public String[] getSelectionArgs() { if (knownAccountTypes.isEmpty()) return null; return mKnownAccountTypes.toArray(new String[mKnownAccountTypes.size()]); return knownAccountTypes.toArray(new String[knownAccountTypes.size()]); } } } }
src/com/android/contacts/common/model/account/AccountWithDataSet.java +1 −0 Original line number Original line Diff line number Diff line Loading @@ -139,6 +139,7 @@ public class AccountWithDataSet implements Parcelable { args = new String[] {type, name, dataSet}; args = new String[] {type, name, dataSet}; } } } } selection += " AND " + RawContacts.DELETED + "=0"; final Cursor c = context.getContentResolver().query(RAW_CONTACTS_URI_LIMIT_1, final Cursor c = context.getContentResolver().query(RAW_CONTACTS_URI_LIMIT_1, ID_PROJECTION, selection, args, null); ID_PROJECTION, selection, args, null); Loading
src/com/android/contacts/common/util/AccountFilterUtil.java +15 −6 Original line number Original line Diff line number Diff line Loading @@ -22,7 +22,9 @@ import android.content.AsyncTaskLoader; import android.content.Context; import android.content.Context; import android.content.Intent; import android.content.Intent; import android.content.SharedPreferences; import android.content.SharedPreferences; import android.database.Cursor; import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable; import android.provider.ContactsContract; import android.text.TextUtils; import android.text.TextUtils; import android.util.Log; import android.util.Log; Loading @@ -31,8 +33,10 @@ import com.android.contacts.common.list.AccountFilterActivity; import com.android.contacts.common.list.ContactListFilter; import com.android.contacts.common.list.ContactListFilter; import com.android.contacts.common.list.ContactListFilterController; import com.android.contacts.common.list.ContactListFilterController; import com.android.contacts.common.model.AccountTypeManager; import com.android.contacts.common.model.AccountTypeManager; import com.android.contacts.common.model.RawContact; import com.android.contacts.common.model.account.AccountType; import com.android.contacts.common.model.account.AccountType; import com.android.contacts.common.model.account.AccountWithDataSet; import com.android.contacts.common.model.account.AccountWithDataSet; import com.android.contactsbind.ObjectFactory; import com.google.common.collect.Lists; import com.google.common.collect.Lists; import java.util.ArrayList; import java.util.ArrayList; Loading Loading @@ -90,15 +94,17 @@ public class AccountFilterUtil { */ */ public static class FilterLoader extends AsyncTaskLoader<List<ContactListFilter>> { public static class FilterLoader extends AsyncTaskLoader<List<ContactListFilter>> { private Context mContext; private Context mContext; private DeviceLocalAccountTypeFactory mDeviceLocalFactory; public FilterLoader(Context context) { public FilterLoader(Context context) { super(context); super(context); mContext = context; mContext = context; mDeviceLocalFactory = ObjectFactory.getDeviceLocalAccountTypeFactory(context); } } @Override @Override public List<ContactListFilter> loadInBackground() { public List<ContactListFilter> loadInBackground() { return loadAccountFilters(mContext); return loadAccountFilters(mContext, mDeviceLocalFactory); } } @Override @Override Loading @@ -117,7 +123,8 @@ public class AccountFilterUtil { } } } } private static List<ContactListFilter> loadAccountFilters(Context context) { private static List<ContactListFilter> loadAccountFilters(Context context, DeviceLocalAccountTypeFactory deviceAccountTypeFactory) { final ArrayList<ContactListFilter> accountFilters = Lists.newArrayList(); final ArrayList<ContactListFilter> accountFilters = Lists.newArrayList(); final AccountTypeManager accountTypeManager = AccountTypeManager.getInstance(context); final AccountTypeManager accountTypeManager = AccountTypeManager.getInstance(context); accountTypeManager.sortAccounts(/* defaultAccount */ getDefaultAccount(context)); accountTypeManager.sortAccounts(/* defaultAccount */ getDefaultAccount(context)); Loading @@ -127,13 +134,15 @@ public class AccountFilterUtil { for (AccountWithDataSet account : accounts) { for (AccountWithDataSet account : accounts) { final AccountType accountType = final AccountType accountType = accountTypeManager.getAccountType(account.type, account.dataSet); accountTypeManager.getAccountType(account.type, account.dataSet); if (accountType.isExtension() && !account.hasData(context)) { if ((accountType.isExtension() || DeviceLocalAccountTypeFactory.Util.isLocalAccountType( // Hide extensions with no raw_contacts. deviceAccountTypeFactory, account.type)) && !account.hasData(context)) { // Hide extensions and device accounts with no raw_contacts. continue; continue; } } final Drawable icon = accountType != null ? accountType.getDisplayIcon(context) : null; final Drawable icon = accountType != null ? accountType.getDisplayIcon(context) : null; if (account.isLocalAccount()) { if (DeviceLocalAccountTypeFactory.Util.isLocalAccountType( accountFilters.add(ContactListFilter.createDeviceContactsFilter(icon)); deviceAccountTypeFactory, account.type)) { accountFilters.add(ContactListFilter.createDeviceContactsFilter(icon, account)); } else { } else { accountFilters.add(ContactListFilter.createAccountFilter( accountFilters.add(ContactListFilter.createAccountFilter( account.type, account.name, account.dataSet, icon)); account.type, account.name, account.dataSet, icon)); Loading