App changes for account types with data sets.
This is primarily a replacement of the Android Account object in most
parts of the app with a new AccountWithDataSet object that extends
Account (by adding an additional attribute, the data set).
This also includes a major refactoring of the AccountTypeManager,
both to allow it to handle data sets and to allow for
non-sync-adapter packages to be referenced by the sync adapters for
an account and registered as sources of contact data. Attributes of
the sync adapter that would typically come from the authenticator
can be parsed out of the Contacts XML for these packages.
Bug 5077096
Change-Id: I88f311c64eae78c88e9999bff6f7de8538e62157
diff --git a/src/com/android/contacts/ContactLoader.java b/src/com/android/contacts/ContactLoader.java
index f2a9d13..9daa1e0 100644
--- a/src/com/android/contacts/ContactLoader.java
+++ b/src/com/android/contacts/ContactLoader.java
@@ -114,7 +114,7 @@
private final ArrayList<Entity> mEntities;
private ArrayList<StreamItemEntry> mStreamItems;
private final HashMap<Long, DataStatus> mStatuses;
- private final ArrayList<String> mInvitableAccountTypes;
+ private final ArrayList<AccountType> mInvitableAccountTypes;
private String mDirectoryDisplayName;
private String mDirectoryType;
@@ -292,7 +292,7 @@
return mPresence;
}
- public ArrayList<String> getInvitableAccontTypes() {
+ public ArrayList<AccountType> getInvitableAccountTypes() {
return mInvitableAccountTypes;
}
@@ -420,6 +420,8 @@
RawContacts.ACCOUNT_NAME,
RawContacts.ACCOUNT_TYPE,
+ RawContacts.DATA_SET,
+ RawContacts.ACCOUNT_TYPE_AND_DATA_SET,
RawContacts.DIRTY,
RawContacts.VERSION,
RawContacts.SOURCE_ID,
@@ -489,55 +491,57 @@
public final static int ACCOUNT_NAME = 15;
public final static int ACCOUNT_TYPE = 16;
- public final static int DIRTY = 17;
- public final static int VERSION = 18;
- public final static int SOURCE_ID = 19;
- public final static int SYNC1 = 20;
- public final static int SYNC2 = 21;
- public final static int SYNC3 = 22;
- public final static int SYNC4 = 23;
- public final static int DELETED = 24;
- public final static int NAME_VERIFIED = 25;
+ public final static int DATA_SET = 17;
+ public final static int ACCOUNT_TYPE_AND_DATA_SET = 18;
+ public final static int DIRTY = 19;
+ public final static int VERSION = 20;
+ public final static int SOURCE_ID = 21;
+ public final static int SYNC1 = 22;
+ public final static int SYNC2 = 23;
+ public final static int SYNC3 = 24;
+ public final static int SYNC4 = 25;
+ public final static int DELETED = 26;
+ public final static int NAME_VERIFIED = 27;
- public final static int DATA_ID = 26;
- public final static int DATA1 = 27;
- public final static int DATA2 = 28;
- public final static int DATA3 = 29;
- public final static int DATA4 = 30;
- public final static int DATA5 = 31;
- public final static int DATA6 = 32;
- public final static int DATA7 = 33;
- public final static int DATA8 = 34;
- public final static int DATA9 = 35;
- public final static int DATA10 = 36;
- public final static int DATA11 = 37;
- public final static int DATA12 = 38;
- public final static int DATA13 = 39;
- public final static int DATA14 = 40;
- public final static int DATA15 = 41;
- public final static int DATA_SYNC1 = 42;
- public final static int DATA_SYNC2 = 43;
- public final static int DATA_SYNC3 = 44;
- public final static int DATA_SYNC4 = 45;
- public final static int DATA_VERSION = 46;
- public final static int IS_PRIMARY = 47;
- public final static int IS_SUPERPRIMARY = 48;
- public final static int MIMETYPE = 49;
- public final static int RES_PACKAGE = 50;
+ public final static int DATA_ID = 28;
+ public final static int DATA1 = 29;
+ public final static int DATA2 = 30;
+ public final static int DATA3 = 31;
+ public final static int DATA4 = 32;
+ public final static int DATA5 = 33;
+ public final static int DATA6 = 34;
+ public final static int DATA7 = 35;
+ public final static int DATA8 = 36;
+ public final static int DATA9 = 37;
+ public final static int DATA10 = 38;
+ public final static int DATA11 = 39;
+ public final static int DATA12 = 40;
+ public final static int DATA13 = 41;
+ public final static int DATA14 = 42;
+ public final static int DATA15 = 43;
+ public final static int DATA_SYNC1 = 44;
+ public final static int DATA_SYNC2 = 45;
+ public final static int DATA_SYNC3 = 46;
+ public final static int DATA_SYNC4 = 47;
+ public final static int DATA_VERSION = 48;
+ public final static int IS_PRIMARY = 49;
+ public final static int IS_SUPERPRIMARY = 50;
+ public final static int MIMETYPE = 51;
+ public final static int RES_PACKAGE = 52;
- public final static int GROUP_SOURCE_ID = 51;
+ public final static int GROUP_SOURCE_ID = 53;
- public final static int PRESENCE = 52;
- public final static int CHAT_CAPABILITY = 53;
- public final static int STATUS = 54;
- public final static int STATUS_RES_PACKAGE = 55;
- public final static int STATUS_ICON = 56;
- public final static int STATUS_LABEL = 57;
- public final static int STATUS_TIMESTAMP = 58;
+ public final static int PRESENCE = 54;
+ public final static int CHAT_CAPABILITY = 55;
+ public final static int STATUS = 56;
+ public final static int STATUS_RES_PACKAGE = 57;
+ public final static int STATUS_ICON = 58;
+ public final static int STATUS_LABEL = 59;
+ public final static int STATUS_TIMESTAMP = 60;
- public final static int PHOTO_URI = 59;
- public final static int SEND_TO_VOICEMAIL = 60;
- public final static int CUSTOM_RINGTONE = 61;
+ public final static int PHOTO_URI = 61;
+ public final static int SEND_TO_VOICEMAIL = 62;
+ public final static int CUSTOM_RINGTONE = 63;
}
/**
@@ -565,6 +569,8 @@
final static String[] COLUMNS = new String[] {
Groups.ACCOUNT_NAME,
Groups.ACCOUNT_TYPE,
+ Groups.DATA_SET,
+ Groups.ACCOUNT_TYPE_AND_DATA_SET,
Groups._ID,
Groups.TITLE,
Groups.AUTO_ADD,
@@ -573,10 +579,12 @@
public final static int ACCOUNT_NAME = 0;
public final static int ACCOUNT_TYPE = 1;
- public final static int ID = 2;
- public final static int TITLE = 3;
- public final static int AUTO_ADD = 4;
- public final static int FAVORITES = 5;
+ public final static int DATA_SET = 2;
+ public final static int ACCOUNT_TYPE_AND_DATA_SET = 3;
+ public final static int ID = 4;
+ public final static int TITLE = 5;
+ public final static int AUTO_ADD = 6;
+ public final static int FAVORITES = 7;
}
private final class LoadContactTask extends AsyncTask<Void, Void, Result> {
@@ -773,7 +781,7 @@
}
// Set to mInvitableAccountTypes
- contactData.mInvitableAccountTypes.addAll(result.keySet());
+ contactData.mInvitableAccountTypes.addAll(result.values());
}
/**
@@ -825,6 +833,8 @@
cursorColumnToContentValues(cursor, cv, ContactQuery.ACCOUNT_NAME);
cursorColumnToContentValues(cursor, cv, ContactQuery.ACCOUNT_TYPE);
+ cursorColumnToContentValues(cursor, cv, ContactQuery.DATA_SET);
+ cursorColumnToContentValues(cursor, cv, ContactQuery.ACCOUNT_TYPE_AND_DATA_SET);
cursorColumnToContentValues(cursor, cv, ContactQuery.DIRTY);
cursorColumnToContentValues(cursor, cv, ContactQuery.VERSION);
cursorColumnToContentValues(cursor, cv, ContactQuery.SOURCE_ID);
@@ -946,14 +956,23 @@
ContentValues values = entity.getEntityValues();
String accountName = values.getAsString(RawContacts.ACCOUNT_NAME);
String accountType = values.getAsString(RawContacts.ACCOUNT_TYPE);
+ String dataSet = values.getAsString(RawContacts.DATA_SET);
if (accountName != null && accountType != null) {
if (selection.length() != 0) {
selection.append(" OR ");
}
selection.append(
- "(" + Groups.ACCOUNT_NAME + "=? AND " + Groups.ACCOUNT_TYPE + "=?)");
+ "(" + Groups.ACCOUNT_NAME + "=? AND " + Groups.ACCOUNT_TYPE + "=?");
selectionArgs.add(accountName);
selectionArgs.add(accountType);
+
+ if (dataSet != null) {
+ selection.append(" AND " + Groups.DATA_SET + "=?");
+ selectionArgs.add(dataSet);
+ } else {
+ selection.append(" AND " + Groups.DATA_SET + " IS NULL");
+ }
+ selection.append(")");
}
}
Cursor cursor = getContext().getContentResolver().query(Groups.CONTENT_URI,
@@ -963,6 +982,7 @@
while (cursor.moveToNext()) {
final String accountName = cursor.getString(GroupQuery.ACCOUNT_NAME);
final String accountType = cursor.getString(GroupQuery.ACCOUNT_TYPE);
+ final String dataSet = cursor.getString(GroupQuery.DATA_SET);
final long groupId = cursor.getLong(GroupQuery.ID);
final String title = cursor.getString(GroupQuery.TITLE);
final boolean defaultGroup = cursor.isNull(GroupQuery.AUTO_ADD)
@@ -973,7 +993,8 @@
: cursor.getInt(GroupQuery.FAVORITES) != 0;
result.addGroupMetaData(new GroupMetaData(
- accountName, accountType, groupId, title, defaultGroup, favorites));
+ accountName, accountType, dataSet, groupId, title, defaultGroup,
+ favorites));
}
} finally {
cursor.close();
diff --git a/src/com/android/contacts/ContactSaveService.java b/src/com/android/contacts/ContactSaveService.java
index e2ab6b0..221796a 100644
--- a/src/com/android/contacts/ContactSaveService.java
+++ b/src/com/android/contacts/ContactSaveService.java
@@ -17,12 +17,12 @@
package com.android.contacts;
import com.android.contacts.model.AccountTypeManager;
+import com.android.contacts.model.AccountWithDataSet;
import com.android.contacts.model.EntityDeltaList;
import com.android.contacts.model.EntityModifier;
import com.google.android.collect.Lists;
import com.google.android.collect.Sets;
-import android.accounts.Account;
import android.app.Activity;
import android.app.IntentService;
import android.content.ContentProviderOperation;
@@ -68,6 +68,7 @@
public static final String EXTRA_ACCOUNT_NAME = "accountName";
public static final String EXTRA_ACCOUNT_TYPE = "accountType";
+ public static final String EXTRA_DATA_SET = "dataSet";
public static final String EXTRA_CONTENT_VALUES = "contentValues";
public static final String EXTRA_CALLBACK_INTENT = "callbackIntent";
@@ -203,14 +204,15 @@
* using data presented as a set of ContentValues.
*/
public static Intent createNewRawContactIntent(Context context,
- ArrayList<ContentValues> values, Account account, Class<?> callbackActivity,
- String callbackAction) {
+ ArrayList<ContentValues> values, AccountWithDataSet account,
+ Class<?> callbackActivity, String callbackAction) {
Intent serviceIntent = new Intent(
context, ContactSaveService.class);
serviceIntent.setAction(ContactSaveService.ACTION_NEW_RAW_CONTACT);
if (account != null) {
serviceIntent.putExtra(ContactSaveService.EXTRA_ACCOUNT_NAME, account.name);
serviceIntent.putExtra(ContactSaveService.EXTRA_ACCOUNT_TYPE, account.type);
+ serviceIntent.putExtra(ContactSaveService.EXTRA_DATA_SET, account.dataSet);
}
serviceIntent.putParcelableArrayListExtra(
ContactSaveService.EXTRA_CONTENT_VALUES, values);
@@ -227,6 +229,7 @@
private void createRawContact(Intent intent) {
String accountName = intent.getStringExtra(EXTRA_ACCOUNT_NAME);
String accountType = intent.getStringExtra(EXTRA_ACCOUNT_TYPE);
+ String dataSet = intent.getStringExtra(EXTRA_DATA_SET);
List<ContentValues> valueList = intent.getParcelableArrayListExtra(EXTRA_CONTENT_VALUES);
Intent callbackIntent = intent.getParcelableExtra(EXTRA_CALLBACK_INTENT);
@@ -234,6 +237,7 @@
operations.add(ContentProviderOperation.newInsert(RawContacts.CONTENT_URI)
.withValue(RawContacts.ACCOUNT_NAME, accountName)
.withValue(RawContacts.ACCOUNT_TYPE, accountType)
+ .withValue(RawContacts.DATA_SET, dataSet)
.build());
int size = valueList.size();
@@ -392,14 +396,14 @@
* @param callbackActivity is the activity to send the callback intent to
* @param callbackAction is the intent action for the callback intent
*/
-
- public static Intent createNewGroupIntent(Context context, Account account,
+ public static Intent createNewGroupIntent(Context context, AccountWithDataSet account,
String label, long[] rawContactsToAdd, Class<?> callbackActivity,
String callbackAction) {
Intent serviceIntent = new Intent(context, ContactSaveService.class);
serviceIntent.setAction(ContactSaveService.ACTION_CREATE_GROUP);
serviceIntent.putExtra(ContactSaveService.EXTRA_ACCOUNT_TYPE, account.type);
serviceIntent.putExtra(ContactSaveService.EXTRA_ACCOUNT_NAME, account.name);
+ serviceIntent.putExtra(ContactSaveService.EXTRA_DATA_SET, account.dataSet);
serviceIntent.putExtra(ContactSaveService.EXTRA_GROUP_LABEL, label);
serviceIntent.putExtra(ContactSaveService.EXTRA_RAW_CONTACTS_TO_ADD, rawContactsToAdd);
@@ -413,14 +417,16 @@
}
private void createGroup(Intent intent) {
- final String accountType = intent.getStringExtra(EXTRA_ACCOUNT_TYPE);
- final String accountName = intent.getStringExtra(EXTRA_ACCOUNT_NAME);
- final String label = intent.getStringExtra(EXTRA_GROUP_LABEL);
+ String accountType = intent.getStringExtra(EXTRA_ACCOUNT_TYPE);
+ String accountName = intent.getStringExtra(EXTRA_ACCOUNT_NAME);
+ String dataSet = intent.getStringExtra(EXTRA_DATA_SET);
+ String label = intent.getStringExtra(EXTRA_GROUP_LABEL);
final long[] rawContactsToAdd = intent.getLongArrayExtra(EXTRA_RAW_CONTACTS_TO_ADD);
ContentValues values = new ContentValues();
values.put(Groups.ACCOUNT_TYPE, accountType);
values.put(Groups.ACCOUNT_NAME, accountName);
+ values.put(Groups.DATA_SET, dataSet);
values.put(Groups.TITLE, label);
final ContentResolver resolver = getContentResolver();
diff --git a/src/com/android/contacts/GroupListLoader.java b/src/com/android/contacts/GroupListLoader.java
index f5716e3..39c428f 100644
--- a/src/com/android/contacts/GroupListLoader.java
+++ b/src/com/android/contacts/GroupListLoader.java
@@ -31,6 +31,7 @@
private final static String[] COLUMNS = new String[] {
Groups.ACCOUNT_NAME,
Groups.ACCOUNT_TYPE,
+ Groups.DATA_SET,
Groups._ID,
Groups.TITLE,
Groups.ACTION,
@@ -41,12 +42,13 @@
public final static int ACCOUNT_NAME = 0;
public final static int ACCOUNT_TYPE = 1;
- public final static int GROUP_ID = 2;
- public final static int TITLE = 3;
- public final static int ACTION = 4;
- public final static int ACTION_URI = 5;
- public final static int MEMBER_COUNT = 6;
- public final static int GROUP_COUNT_PER_ACCOUNT = 7;
+ public final static int DATA_SET = 2;
+ public final static int GROUP_ID = 3;
+ public final static int TITLE = 4;
+ public final static int ACTION = 5;
+ public final static int ACTION_URI = 6;
+ public final static int MEMBER_COUNT = 7;
+ public final static int GROUP_COUNT_PER_ACCOUNT = 8;
private static final Uri GROUP_LIST_URI = Groups.CONTENT_SUMMARY_URI.buildUpon()
.appendQueryParameter(Groups.PARAM_RETURN_GROUP_COUNT_PER_ACCOUNT, "true").build();
@@ -55,7 +57,7 @@
super(context, GROUP_LIST_URI, COLUMNS, Groups.ACCOUNT_TYPE + " NOT NULL AND "
+ Groups.ACCOUNT_NAME + " NOT NULL AND " + Groups.AUTO_ADD + "=0 AND " +
Groups.FAVORITES + "=0 AND " + Groups.DELETED + "=0", null,
- Groups.ACCOUNT_TYPE + ", " + Groups.ACCOUNT_NAME + ", " +
+ Groups.ACCOUNT_TYPE + ", " + Groups.ACCOUNT_NAME + ", " + Groups.DATA_SET + ", " +
Groups.TITLE + " COLLATE LOCALIZED ASC");
}
}
diff --git a/src/com/android/contacts/GroupMetaData.java b/src/com/android/contacts/GroupMetaData.java
index 39e955d..462ac4a 100644
--- a/src/com/android/contacts/GroupMetaData.java
+++ b/src/com/android/contacts/GroupMetaData.java
@@ -22,15 +22,17 @@
public final class GroupMetaData {
private String mAccountName;
private String mAccountType;
+ private String mDataSet;
private long mGroupId;
private String mTitle;
private boolean mDefaultGroup;
private boolean mFavorites;
- public GroupMetaData(String accountName, String accountType, long groupId, String title,
- boolean defaultGroup, boolean favorites) {
+ public GroupMetaData(String accountName, String accountType, String dataSet, long groupId,
+ String title, boolean defaultGroup, boolean favorites) {
this.mAccountName = accountName;
this.mAccountType = accountType;
+ this.mDataSet = dataSet;
this.mGroupId = groupId;
this.mTitle = title;
this.mDefaultGroup = defaultGroup;
@@ -45,6 +47,10 @@
return mAccountType;
}
+ public String getDataSet() {
+ return mDataSet;
+ }
+
public long getGroupId() {
return mGroupId;
}
diff --git a/src/com/android/contacts/GroupMetaDataLoader.java b/src/com/android/contacts/GroupMetaDataLoader.java
index f11217c..2f3468b 100644
--- a/src/com/android/contacts/GroupMetaDataLoader.java
+++ b/src/com/android/contacts/GroupMetaDataLoader.java
@@ -29,6 +29,7 @@
private final static String[] COLUMNS = new String[] {
Groups.ACCOUNT_NAME,
Groups.ACCOUNT_TYPE,
+ Groups.DATA_SET,
Groups._ID,
Groups.TITLE,
Groups.AUTO_ADD,
@@ -41,14 +42,15 @@
public final static int ACCOUNT_NAME = 0;
public final static int ACCOUNT_TYPE = 1;
- public final static int GROUP_ID = 2;
- public final static int TITLE = 3;
- public final static int AUTO_ADD = 4;
- public final static int FAVORITES = 5;
- public final static int IS_READ_ONLY = 6;
- public final static int DELETED = 7;
- public final static int ACTION = 8;
- public final static int ACTION_URI = 9;
+ public final static int DATA_SET = 2;
+ public final static int GROUP_ID = 3;
+ public final static int TITLE = 4;
+ public final static int AUTO_ADD = 5;
+ public final static int FAVORITES = 6;
+ public final static int IS_READ_ONLY = 7;
+ public final static int DELETED = 8;
+ public final static int ACTION = 9;
+ public final static int ACTION_URI = 10;
public GroupMetaDataLoader(Context context, Uri groupUri) {
super(context, ensureIsGroupUri(groupUri), COLUMNS, Groups.ACCOUNT_TYPE + " NOT NULL AND "
diff --git a/src/com/android/contacts/SplitAggregateView.java b/src/com/android/contacts/SplitAggregateView.java
index d99ba85..091cd56 100644
--- a/src/com/android/contacts/SplitAggregateView.java
+++ b/src/com/android/contacts/SplitAggregateView.java
@@ -57,18 +57,20 @@
private interface SplitQuery {
String[] COLUMNS = new String[] {
- Data.MIMETYPE, RawContacts.ACCOUNT_TYPE, Data.RAW_CONTACT_ID, Data.IS_PRIMARY,
- StructuredName.DISPLAY_NAME, Nickname.NAME, Email.DATA, Phone.NUMBER
+ Data.MIMETYPE, RawContacts.ACCOUNT_TYPE, RawContacts.DATA_SET, Data.RAW_CONTACT_ID,
+ Data.IS_PRIMARY, StructuredName.DISPLAY_NAME, Nickname.NAME, Email.DATA,
+ Phone.NUMBER
};
int MIMETYPE = 0;
int ACCOUNT_TYPE = 1;
- int RAW_CONTACT_ID = 2;
- int IS_PRIMARY = 3;
- int DISPLAY_NAME = 4;
- int NICKNAME = 5;
- int EMAIL = 6;
- int PHONE = 7;
+ int DATA_SET = 2;
+ int RAW_CONTACT_ID = 3;
+ int IS_PRIMARY = 4;
+ int DISPLAY_NAME = 5;
+ int NICKNAME = 6;
+ int EMAIL = 7;
+ int PHONE = 8;
}
private final Uri mAggregateUri;
@@ -116,6 +118,7 @@
private static class RawContactInfo implements Comparable<RawContactInfo> {
final long rawContactId;
String accountType;
+ String dataSet;
String name;
String phone;
String email;
@@ -165,6 +168,7 @@
info = new RawContactInfo(rawContactId);
rawContactInfos.put(rawContactId, info);
info.accountType = cursor.getString(SplitQuery.ACCOUNT_TYPE);
+ info.dataSet = cursor.getString(SplitQuery.DATA_SET);
}
String mimetype = cursor.getString(SplitQuery.MIMETYPE);
@@ -247,7 +251,7 @@
cache.additionalData.setText(info.getAdditionalData());
Drawable icon = null;
- AccountType accountType = mAccountTypes.getAccountType(info.accountType);
+ AccountType accountType = mAccountTypes.getAccountType(info.accountType, info.dataSet);
if (accountType != null) {
icon = accountType.getDisplayIcon(getContext());
}
diff --git a/src/com/android/contacts/activities/AttachPhotoActivity.java b/src/com/android/contacts/activities/AttachPhotoActivity.java
index 1eabaf7..a697c29 100644
--- a/src/com/android/contacts/activities/AttachPhotoActivity.java
+++ b/src/com/android/contacts/activities/AttachPhotoActivity.java
@@ -217,7 +217,8 @@
if (assertAccount) {
// Make sure no pictures exist for Google, Exchange and unsynced phone accounts.
operations.add(ContentProviderOperation.newAssertQuery(rawContactDataUri)
- .withSelection(Photo.MIMETYPE + "=? AND ("
+ .withSelection(Photo.MIMETYPE + "=? AND "
+ + RawContacts.DATA_SET + " IS NULL AND ("
+ RawContacts.ACCOUNT_TYPE + " IN (?,?) OR "
+ RawContacts.ACCOUNT_TYPE + " IS NULL)",
new String[] {Photo.CONTENT_ITEM_TYPE, GoogleAccountType.ACCOUNT_TYPE,
diff --git a/src/com/android/contacts/activities/ContactDetailActivity.java b/src/com/android/contacts/activities/ContactDetailActivity.java
index c4330f9..6046f5e 100644
--- a/src/com/android/contacts/activities/ContactDetailActivity.java
+++ b/src/com/android/contacts/activities/ContactDetailActivity.java
@@ -19,7 +19,6 @@
import com.android.contacts.ContactLoader;
import com.android.contacts.ContactSaveService;
import com.android.contacts.ContactsActivity;
-import com.android.contacts.ContactsSearchManager;
import com.android.contacts.R;
import com.android.contacts.detail.ContactDetailDisplayUtils;
import com.android.contacts.detail.ContactDetailFragment;
@@ -29,9 +28,9 @@
import com.android.contacts.detail.ContactLoaderFragment;
import com.android.contacts.detail.ContactLoaderFragment.ContactLoaderFragmentListener;
import com.android.contacts.interactions.ContactDeletionInteraction;
+import com.android.contacts.model.AccountWithDataSet;
import com.android.contacts.util.PhoneCapabilityTester;
-import android.accounts.Account;
import android.app.ActionBar;
import android.app.Fragment;
import android.app.FragmentManager;
@@ -384,7 +383,7 @@
@Override
public void onCreateRawContactRequested(
- ArrayList<ContentValues> values, Account account) {
+ ArrayList<ContentValues> values, AccountWithDataSet account) {
Toast.makeText(ContactDetailActivity.this, R.string.toast_making_personal_copy,
Toast.LENGTH_LONG).show();
Intent serviceIntent = ContactSaveService.createNewRawContactIntent(
diff --git a/src/com/android/contacts/activities/ContactEditorActivity.java b/src/com/android/contacts/activities/ContactEditorActivity.java
index a5b3aab..54ea05f 100644
--- a/src/com/android/contacts/activities/ContactEditorActivity.java
+++ b/src/com/android/contacts/activities/ContactEditorActivity.java
@@ -17,18 +17,15 @@
package com.android.contacts.activities;
import com.android.contacts.ContactsActivity;
-import com.android.contacts.ContactsSearchManager;
import com.android.contacts.R;
import com.android.contacts.editor.ContactEditorFragment;
import com.android.contacts.editor.ContactEditorFragment.SaveMode;
-import com.android.contacts.interactions.ContactDeletionInteraction;
import com.android.contacts.model.AccountType;
import com.android.contacts.model.AccountTypeManager;
+import com.android.contacts.model.AccountWithDataSet;
import com.android.contacts.util.DialogManager;
-import android.accounts.Account;
import android.app.ActionBar;
-import android.app.Activity;
import android.app.Dialog;
import android.content.ContentValues;
import android.content.Context;
@@ -40,10 +37,8 @@
import android.provider.ContactsContract.RawContacts;
import android.util.Log;
import android.view.LayoutInflater;
-import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
-import android.widget.Button;
import java.util.ArrayList;
@@ -198,10 +193,12 @@
}
@Override
- public void onCustomCreateContactActivityRequested(Account account, Bundle intentExtras) {
+ public void onCustomCreateContactActivityRequested(AccountWithDataSet account,
+ Bundle intentExtras) {
final AccountTypeManager accountTypes =
AccountTypeManager.getInstance(ContactEditorActivity.this);
- final AccountType accountType = accountTypes.getAccountType(account.type);
+ final AccountType accountType = accountTypes.getAccountType(
+ account.type, account.dataSet);
Intent intent = new Intent();
intent.setClassName(accountType.resPackageName,
@@ -213,6 +210,7 @@
}
intent.putExtra(RawContacts.ACCOUNT_NAME, account.name);
intent.putExtra(RawContacts.ACCOUNT_TYPE, account.type);
+ intent.putExtra(RawContacts.DATA_SET, account.dataSet);
intent.setFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
| Intent.FLAG_ACTIVITY_FORWARD_RESULT);
startActivity(intent);
@@ -220,11 +218,12 @@
}
@Override
- public void onCustomEditContactActivityRequested(Account account, Uri rawContactUri,
- Bundle intentExtras, boolean redirect) {
+ public void onCustomEditContactActivityRequested(AccountWithDataSet account,
+ Uri rawContactUri, Bundle intentExtras, boolean redirect) {
final AccountTypeManager accountTypes =
AccountTypeManager.getInstance(ContactEditorActivity.this);
- final AccountType accountType = accountTypes.getAccountType(account.type);
+ final AccountType accountType = accountTypes.getAccountType(
+ account.type, account.dataSet);
Intent intent = new Intent();
intent.setClassName(accountType.resPackageName,
diff --git a/src/com/android/contacts/activities/GroupDetailActivity.java b/src/com/android/contacts/activities/GroupDetailActivity.java
index b56f182..b66d8b8 100644
--- a/src/com/android/contacts/activities/GroupDetailActivity.java
+++ b/src/com/android/contacts/activities/GroupDetailActivity.java
@@ -39,6 +39,7 @@
private boolean mShowGroupSourceInActionBar;
private String mAccountTypeString;
+ private String mDataSet;
private String mGroupSourceAction;
private String mGroupSourceUri;
@@ -84,9 +85,10 @@
}
@Override
- public void onGroupSourceUpdated(
- String accountTypeString, String groupSourceAction, String groupSourceActionUri) {
+ public void onGroupSourceUpdated(String accountTypeString, String dataSet,
+ String groupSourceAction, String groupSourceActionUri) {
mAccountTypeString = accountTypeString;
+ mDataSet = dataSet;
mGroupSourceAction = groupSourceAction;
mGroupSourceUri = groupSourceActionUri;
invalidateOptionsMenu();
@@ -133,7 +135,7 @@
}
View groupSourceView = GroupDetailDisplayUtils.getNewGroupSourceView(this);
GroupDetailDisplayUtils.bindGroupSourceView(this, groupSourceView,
- mAccountTypeString);
+ mAccountTypeString, mDataSet);
groupSourceView.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
diff --git a/src/com/android/contacts/activities/PeopleActivity.java b/src/com/android/contacts/activities/PeopleActivity.java
index 6a0d7ad..6dc727e 100644
--- a/src/com/android/contacts/activities/PeopleActivity.java
+++ b/src/com/android/contacts/activities/PeopleActivity.java
@@ -51,6 +51,7 @@
import com.android.contacts.list.ProviderStatusLoader.ProviderStatusListener;
import com.android.contacts.list.ContactTileListFragment;
import com.android.contacts.model.AccountTypeManager;
+import com.android.contacts.model.AccountWithDataSet;
import com.android.contacts.preference.ContactsPreferenceActivity;
import com.android.contacts.preference.DisplayOptionsPreferenceFragment;
import com.android.contacts.util.AccountSelectionUtil;
@@ -58,7 +59,6 @@
import com.android.contacts.util.DialogManager;
import com.android.contacts.util.PhoneCapabilityTester;
-import android.accounts.Account;
import android.app.Activity;
import android.app.Fragment;
import android.app.FragmentManager;
@@ -92,6 +92,7 @@
import android.widget.Toast;
import java.util.ArrayList;
+import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
/**
@@ -202,8 +203,8 @@
}
private boolean areAccountsAvailable() {
- final ArrayList<Account> accounts =
- AccountTypeManager.getInstance(this).getAccounts(true /* writeable */);
+ final List<AccountWithDataSet> accounts =
+ AccountTypeManager.getInstance(this).getAccounts(true /* writeable */);
return !accounts.isEmpty();
}
@@ -1091,7 +1092,8 @@
}
@Override
- public void onCreateRawContactRequested(ArrayList<ContentValues> values, Account account) {
+ public void onCreateRawContactRequested(ArrayList<ContentValues> values,
+ AccountWithDataSet account) {
Toast.makeText(PeopleActivity.this, R.string.toast_making_personal_copy,
Toast.LENGTH_LONG).show();
Intent serviceIntent = ContactSaveService.createNewRawContactIntent(
@@ -1169,8 +1171,8 @@
}
@Override
- public void onGroupSourceUpdated(
- String accountTypeString, String groupSourceAction, String groupSourceUri) {
+ public void onGroupSourceUpdated(String accountTypeString, String dataSet,
+ String groupSourceAction, String groupSourceUri) {
// Nothing needs to be done here because the group source will be displayed in the
// detail fragment
}
@@ -1393,7 +1395,7 @@
}
private void createNewGroupWithAccountDisambiguation() {
- final ArrayList<Account> accounts =
+ final List<AccountWithDataSet> accounts =
AccountTypeManager.getInstance(this).getAccounts(true);
if (accounts.size() <= 1 || mAddGroupImageView == null) {
// No account to choose or no control to anchor the popup-menu to
@@ -1415,9 +1417,11 @@
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
popup.dismiss();
+ AccountWithDataSet account = adapter.getItem(position);
final Intent intent = new Intent(PeopleActivity.this, GroupEditorActivity.class);
intent.setAction(Intent.ACTION_INSERT);
- intent.putExtra(Intents.Insert.ACCOUNT, adapter.getItem(position));
+ intent.putExtra(Intents.Insert.ACCOUNT, account);
+ intent.putExtra(Intents.Insert.DATA_SET, account.dataSet);
startActivityForResult(intent, SUBACTIVITY_NEW_GROUP);
}
});
diff --git a/src/com/android/contacts/detail/ContactDetailFragment.java b/src/com/android/contacts/detail/ContactDetailFragment.java
index 41324f8..946fbe8 100644
--- a/src/com/android/contacts/detail/ContactDetailFragment.java
+++ b/src/com/android/contacts/detail/ContactDetailFragment.java
@@ -31,6 +31,7 @@
import com.android.contacts.model.AccountType;
import com.android.contacts.model.AccountType.EditType;
import com.android.contacts.model.AccountTypeManager;
+import com.android.contacts.model.AccountWithDataSet;
import com.android.contacts.model.DataKind;
import com.android.contacts.model.EntityDelta;
import com.android.contacts.model.EntityDelta.ValuesDelta;
@@ -43,7 +44,6 @@
import com.android.contacts.widget.TransitionAnimationView;
import com.android.internal.telephony.ITelephony;
-import android.accounts.Account;
import android.app.Activity;
import android.app.Fragment;
import android.app.SearchManager;
@@ -491,12 +491,13 @@
for (Entity entity: mContactData.getEntities()) {
final ContentValues entValues = entity.getEntityValues();
final String accountType = entValues.getAsString(RawContacts.ACCOUNT_TYPE);
+ final String dataSet = entValues.getAsString(RawContacts.DATA_SET);
final long rawContactId = entValues.getAsLong(RawContacts._ID);
if (!mRawContactIds.contains(rawContactId)) {
mRawContactIds.add(rawContactId);
}
- AccountType type = accountTypes.getAccountType(accountType);
+ AccountType type = accountTypes.getAccountType(accountType, dataSet);
if (type == null || !type.readOnly) {
mWritableRawContactIds.add(rawContactId);
}
@@ -518,7 +519,7 @@
}
final DataKind kind = accountTypes.getKindOrFallback(
- accountType, mimeType);
+ accountType, dataSet, mimeType);
if (kind == null) continue;
final DetailViewEntry entry = DetailViewEntry.fromValues(mContext, mimeType, kind,
@@ -574,7 +575,7 @@
final DataStatus status = mContactData.getStatuses().get(entry.id);
if (status != null) {
final String imMime = Im.CONTENT_ITEM_TYPE;
- final DataKind imKind = accountTypes.getKindOrFallback(accountType,
+ final DataKind imKind = accountTypes.getKindOrFallback(accountType, dataSet,
imMime);
final DetailViewEntry imEntry = DetailViewEntry.fromValues(mContext, imMime,
imKind, dataId, entryValues, mContactData.isDirectoryEntry(),
@@ -764,7 +765,7 @@
String attribution = ContactDetailDisplayUtils.getAttribution(mContext, mContactData);
boolean hasAttribution = !TextUtils.isEmpty(attribution);
int networksCount = mOtherEntriesMap.keySet().size();
- int invitableCount = mContactData.getInvitableAccontTypes().size();
+ int invitableCount = mContactData.getInvitableAccountTypes().size();
if (!hasAttribution && networksCount == 0 && invitableCount == 0) {
return;
}
@@ -1638,11 +1639,11 @@
}
@Override
- public void onAccountChosen(int requestCode, Account account) {
+ public void onAccountChosen(int requestCode, AccountWithDataSet account) {
createCopy(account);
}
- private void createCopy(Account account) {
+ private void createCopy(AccountWithDataSet account) {
if (mListener != null) {
mListener.onCreateRawContactRequested(mContactData.getContentValues(), account);
}
@@ -1825,11 +1826,12 @@
if (defaultGroupId == -1) return false;
final Entity rawContactEntity = mContactData.getEntities().get(0);
- final String accountType =
- rawContactEntity.getEntityValues().getAsString(RawContacts.ACCOUNT_TYPE);
+ ContentValues rawValues = rawContactEntity.getEntityValues();
+ final String accountType = rawValues.getAsString(RawContacts.ACCOUNT_TYPE);
+ final String dataSet = rawValues.getAsString(RawContacts.DATA_SET);
final AccountTypeManager accountTypes =
AccountTypeManager.getInstance(mContext);
- final AccountType type = accountTypes.getAccountType(accountType);
+ final AccountType type = accountTypes.getAccountType(accountType, dataSet);
// Offline or non-writeable account? Nothing to fix
if (type == null || type.readOnly) return false;
@@ -1871,7 +1873,8 @@
final AccountTypeManager accountTypes = AccountTypeManager.getInstance(mContext);
final ValuesDelta values = rawContactEntityDelta.getValues();
final String accountType = values.getAsString(RawContacts.ACCOUNT_TYPE);
- final AccountType type = accountTypes.getAccountType(accountType);
+ final String dataSet = values.getAsString(RawContacts.DATA_SET);
+ final AccountType type = accountTypes.getAccountType(accountType, dataSet);
final DataKind groupMembershipKind = type.getKindForMimetype(
GroupMembership.CONTENT_ITEM_TYPE);
final ValuesDelta entry = EntityModifier.insertChild(rawContactEntityDelta,
@@ -1915,12 +1918,12 @@
int exportSupport = mContactData.getDirectoryExportSupport();
switch (exportSupport) {
case Directory.EXPORT_SUPPORT_SAME_ACCOUNT_ONLY: {
- createCopy(new Account(mContactData.getDirectoryAccountName(),
- mContactData.getDirectoryAccountType()));
+ createCopy(new AccountWithDataSet(mContactData.getDirectoryAccountName(),
+ mContactData.getDirectoryAccountType(), null));
break;
}
case Directory.EXPORT_SUPPORT_ANY_ACCOUNT: {
- final ArrayList<Account> accounts =
+ final List<AccountWithDataSet> accounts =
AccountTypeManager.getInstance(mContext).getAccounts(true);
if (accounts.isEmpty()) {
createCopy(null);
@@ -1998,9 +2001,10 @@
* User requested creation of a new contact with the specified values.
*
* @param values ContentValues containing data rows for the new contact.
- * @param account Account where the new contact should be created
+ * @param account Account where the new contact should be created.
*/
- public void onCreateRawContactRequested(ArrayList<ContentValues> values, Account account);
+ public void onCreateRawContactRequested(ArrayList<ContentValues> values,
+ AccountWithDataSet account);
}
/**
@@ -2016,12 +2020,12 @@
mContext = context;
mInflater = LayoutInflater.from(context);
mContactData = contactData;
- final List<String> types = contactData.getInvitableAccontTypes();
+ final List<AccountType> types = contactData.getInvitableAccountTypes();
mAccountTypes = new ArrayList<AccountType>(types.size());
AccountTypeManager manager = AccountTypeManager.getInstance(context);
for (int i = 0; i < types.size(); i++) {
- mAccountTypes.add(manager.getAccountType(types.get(i)));
+ mAccountTypes.add(types.get(i));
}
Collections.sort(mAccountTypes, new AccountType.DisplayLabelComparator(mContext));
diff --git a/src/com/android/contacts/editor/AggregationSuggestionEngine.java b/src/com/android/contacts/editor/AggregationSuggestionEngine.java
index bb17bbb..0861d92 100644
--- a/src/com/android/contacts/editor/AggregationSuggestionEngine.java
+++ b/src/com/android/contacts/editor/AggregationSuggestionEngine.java
@@ -58,10 +58,12 @@
public long rawContactId;
public String accountType;
public String accountName;
+ public String dataSet;
@Override
public String toString() {
- return "ID: " + rawContactId + " account: " + accountType + "/" + accountName;
+ return "ID: " + rawContactId + " account: " + accountType + "/" + accountName
+ + " dataSet: " + dataSet;
}
}
@@ -277,6 +279,7 @@
Photo.PHOTO,
RawContacts.ACCOUNT_TYPE,
RawContacts.ACCOUNT_NAME,
+ RawContacts.DATA_SET
};
public static final int ID = 0;
@@ -291,6 +294,7 @@
public static final int PHOTO = 9;
public static final int ACCOUNT_TYPE = 10;
public static final int ACCOUNT_NAME = 11;
+ public static final int DATA_SET = 12;
}
private void loadAggregationSuggestions(Uri uri) {
@@ -390,6 +394,7 @@
rawContact.rawContactId = rawContactId;
rawContact.accountName = mDataCursor.getString(DataQuery.ACCOUNT_NAME);
rawContact.accountType = mDataCursor.getString(DataQuery.ACCOUNT_TYPE);
+ rawContact.dataSet = mDataCursor.getString(DataQuery.DATA_SET);
suggestion.rawContacts.add(rawContact);
}
diff --git a/src/com/android/contacts/editor/AggregationSuggestionView.java b/src/com/android/contacts/editor/AggregationSuggestionView.java
index af8e7f8..07e67e8 100644
--- a/src/com/android/contacts/editor/AggregationSuggestionView.java
+++ b/src/com/android/contacts/editor/AggregationSuggestionView.java
@@ -118,10 +118,11 @@
AccountTypeManager accountTypes = AccountTypeManager.getInstance(getContext());
for (RawContact rawContact : mRawContacts) {
String accountType = rawContact.accountType;
+ String dataSet = rawContact.dataSet;
if (accountType == null) {
return true;
}
- AccountType type = accountTypes.getAccountType(accountType);
+ AccountType type = accountTypes.getAccountType(accountType, dataSet);
if (!type.readOnly) {
return true;
}
diff --git a/src/com/android/contacts/editor/ContactEditorFragment.java b/src/com/android/contacts/editor/ContactEditorFragment.java
index 5d9494c..e0f99ce 100644
--- a/src/com/android/contacts/editor/ContactEditorFragment.java
+++ b/src/com/android/contacts/editor/ContactEditorFragment.java
@@ -26,6 +26,7 @@
import com.android.contacts.editor.Editor.EditorListener;
import com.android.contacts.model.AccountType;
import com.android.contacts.model.AccountTypeManager;
+import com.android.contacts.model.AccountWithDataSet;
import com.android.contacts.model.EntityDelta;
import com.android.contacts.model.EntityDelta.ValuesDelta;
import com.android.contacts.model.EntityDeltaList;
@@ -316,11 +317,13 @@
if (mListener != null) mListener.setTitleTo(R.string.editContact_title_insert);
final Account account = mIntentExtras == null ? null :
- (Account) mIntentExtras.getParcelable(Intents.Insert.ACCOUNT);
+ (Account) mIntentExtras.getParcelable(Intents.Insert.ACCOUNT);
+ final String dataSet = mIntentExtras == null ? null :
+ mIntentExtras.getString(Intents.Insert.DATA_SET);
if (account != null) {
// Account specified in Intent
- createContact(account);
+ createContact(new AccountWithDataSet(account.name, account.type, dataSet));
} else {
// No Account specified. Let the user choose
// Load Accounts async so that we can present them
@@ -396,12 +399,15 @@
Entity entity = entities.get(0);
ContentValues entityValues = entity.getEntityValues();
String type = entityValues.getAsString(RawContacts.ACCOUNT_TYPE);
- AccountType accountType = AccountTypeManager.getInstance(mContext).getAccountType(type);
+ String dataSet = entityValues.getAsString(RawContacts.DATA_SET);
+ AccountType accountType = AccountTypeManager.getInstance(mContext).getAccountType(
+ type, dataSet);
if (accountType.getEditContactActivityClassName() != null) {
if (mListener != null) {
String name = entityValues.getAsString(RawContacts.ACCOUNT_NAME);
long rawContactId = entityValues.getAsLong(RawContacts.Entity._ID);
- mListener.onCustomEditContactActivityRequested(new Account(name, type),
+ mListener.onCustomEditContactActivityRequested(
+ new AccountWithDataSet(name, type, dataSet),
ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId),
mIntentExtras, true);
}
@@ -413,7 +419,7 @@
}
@Override
- public void onExternalEditorRequest(Account account, Uri uri) {
+ public void onExternalEditorRequest(AccountWithDataSet account, Uri uri) {
mListener.onCustomEditContactActivityRequested(account, uri, null, false);
}
@@ -440,7 +446,8 @@
final AccountTypeManager accountTypes = AccountTypeManager.getInstance(mContext);
for (EntityDelta state : mState) {
final String accountType = state.getValues().getAsString(RawContacts.ACCOUNT_TYPE);
- final AccountType type = accountTypes.getAccountType(accountType);
+ final String dataSet = state.getValues().getAsString(RawContacts.DATA_SET);
+ final AccountType type = accountTypes.getAccountType(accountType, dataSet);
if (!type.readOnly) {
// Apply extras to the first writable raw contact only
EntityModifier.parseExtras(mContext, type, state, extras);
@@ -454,7 +461,7 @@
* selected. If there's no available account, device-local contact should be created.
*/
private void createContact() {
- final ArrayList<Account> accounts =
+ final List<AccountWithDataSet> accounts =
AccountTypeManager.getInstance(mContext).getAccounts(true);
// No Accounts available. Create a phone-local contact.
if (accounts.isEmpty()) {
@@ -473,10 +480,11 @@
*
* @param account may be null to signal a device-local contact should be created.
*/
- private void createContact(Account account) {
+ private void createContact(AccountWithDataSet account) {
final AccountTypeManager accountTypes = AccountTypeManager.getInstance(mContext);
final AccountType accountType =
- accountTypes.getAccountType(account != null ? account.type : null);
+ accountTypes.getAccountType(account != null ? account.type : null,
+ account != null ? account.dataSet : null);
if (accountType.getCreateContactActivityClassName() != null) {
if (mListener != null) {
@@ -491,15 +499,17 @@
* Removes a current editor ({@link #mState}) and rebinds new editor for a new account.
* Some of old data are reused with new restriction enforced by the new account.
*
- * @param oldState Old data being editted.
+ * @param oldState Old data being edited.
* @param oldAccount Old account associated with oldState.
* @param newAccount New account to be used.
*/
private void rebindEditorsForNewContact(
- EntityDelta oldState, Account oldAccount, Account newAccount) {
+ EntityDelta oldState, AccountWithDataSet oldAccount, AccountWithDataSet newAccount) {
AccountTypeManager accountTypes = AccountTypeManager.getInstance(mContext);
- AccountType oldAccountType = accountTypes.getAccountType(oldAccount.type);
- AccountType newAccountType = accountTypes.getAccountType(newAccount.type);
+ AccountType oldAccountType = accountTypes.getAccountType(
+ oldAccount.type, oldAccount.dataSet);
+ AccountType newAccountType = accountTypes.getAccountType(
+ newAccount.type, newAccount.dataSet);
if (newAccountType.getCreateContactActivityClassName() != null) {
Log.w(TAG, "external activity called in rebind situation");
@@ -512,21 +522,24 @@
}
}
- private void bindEditorsForNewContact(Account account, final AccountType accountType) {
+ private void bindEditorsForNewContact(AccountWithDataSet account,
+ final AccountType accountType) {
bindEditorsForNewContact(account, accountType, null, null);
}
- private void bindEditorsForNewContact(Account newAccount, final AccountType newAccountType,
- EntityDelta oldState, AccountType oldAccountType) {
+ private void bindEditorsForNewContact(AccountWithDataSet newAccount,
+ final AccountType newAccountType, EntityDelta oldState, AccountType oldAccountType) {
mStatus = Status.EDITING;
final ContentValues values = new ContentValues();
if (newAccount != null) {
values.put(RawContacts.ACCOUNT_NAME, newAccount.name);
values.put(RawContacts.ACCOUNT_TYPE, newAccount.type);
+ values.put(RawContacts.DATA_SET, newAccount.dataSet);
} else {
values.putNull(RawContacts.ACCOUNT_NAME);
values.putNull(RawContacts.ACCOUNT_TYPE);
+ values.putNull(RawContacts.DATA_SET);
}
EntityDelta insert = new EntityDelta(ValuesDelta.fromAfter(values));
@@ -577,7 +590,8 @@
if (!values.isVisible()) continue;
final String accountType = values.getAsString(RawContacts.ACCOUNT_TYPE);
- final AccountType type = accountTypes.getAccountType(accountType);
+ final String dataSet = values.getAsString(RawContacts.DATA_SET);
+ final AccountType type = accountTypes.getAccountType(accountType, dataSet);
final long rawContactId = values.getAsLong(RawContacts._ID);
final BaseRawContactEditorView editor;
@@ -596,7 +610,7 @@
editor = rawContactEditor;
}
if (Intent.ACTION_INSERT.equals(mAction) && numRawContacts == 1) {
- final ArrayList<Account> accounts =
+ final List<AccountWithDataSet> accounts =
AccountTypeManager.getInstance(mContext).getAccounts(true);
if (accounts.size() > 1) {
addAccountSwitcher(mState.get(0), editor);
@@ -676,9 +690,10 @@
private void addAccountSwitcher(
final EntityDelta currentState, BaseRawContactEditorView editor) {
ValuesDelta values = currentState.getValues();
- final Account currentAccount = new Account(
+ final AccountWithDataSet currentAccount = new AccountWithDataSet(
values.getAsString(RawContacts.ACCOUNT_NAME),
- values.getAsString(RawContacts.ACCOUNT_TYPE));
+ values.getAsString(RawContacts.ACCOUNT_TYPE),
+ values.getAsString(RawContacts.DATA_SET));
final View accountView = editor.findViewById(R.id.account);
final View anchorView = editor.findViewById(R.id.anchor_for_account_switcher);
accountView.setOnClickListener(new View.OnClickListener() {
@@ -697,7 +712,7 @@
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
popup.dismiss();
- Account newAccount = adapter.getItem(position);
+ AccountWithDataSet newAccount = adapter.getItem(position);
if (!newAccount.equals(currentAccount)) {
rebindEditorsForNewContact(currentState, currentAccount, newAccount);
}
@@ -1059,7 +1074,8 @@
for (int i = 0; i < size; i++) {
ValuesDelta values = mState.get(i).getValues();
final String accountType = values.getAsString(RawContacts.ACCOUNT_TYPE);
- final AccountType type = accountTypes.getAccountType(accountType);
+ final String dataSet = values.getAsString(RawContacts.DATA_SET);
+ final AccountType type = accountTypes.getAccountType(accountType, dataSet);
if (!type.readOnly) {
return true;
}
@@ -1107,7 +1123,8 @@
* Contact is being created for an external account that provides its own
* new contact activity.
*/
- void onCustomCreateContactActivityRequested(Account account, Bundle intentExtras);
+ void onCustomCreateContactActivityRequested(AccountWithDataSet account,
+ Bundle intentExtras);
/**
* The edited raw contact belongs to an external account that provides
@@ -1116,7 +1133,7 @@
* @param redirect indicates that the current editor should be closed
* before the custom editor is shown.
*/
- void onCustomEditContactActivityRequested(Account account, Uri rawContactUri,
+ void onCustomEditContactActivityRequested(AccountWithDataSet account, Uri rawContactUri,
Bundle intentExtras, boolean redirect);
}
@@ -1132,10 +1149,12 @@
}
final AccountTypeManager accountTypes = AccountTypeManager.getInstance(mContext);
- String accountType2 = one.getValues().getAsString(RawContacts.ACCOUNT_TYPE);
- final AccountType type1 = accountTypes.getAccountType(accountType2);
- accountType2 = two.getValues().getAsString(RawContacts.ACCOUNT_TYPE);
- final AccountType type2 = accountTypes.getAccountType(accountType2);
+ String accountType1 = one.getValues().getAsString(RawContacts.ACCOUNT_TYPE);
+ String dataSet1 = one.getValues().getAsString(RawContacts.DATA_SET);
+ final AccountType type1 = accountTypes.getAccountType(accountType1, dataSet1);
+ String accountType2 = two.getValues().getAsString(RawContacts.ACCOUNT_TYPE);
+ String dataSet2 = two.getValues().getAsString(RawContacts.DATA_SET);
+ final AccountType type2 = accountTypes.getAccountType(accountType2, dataSet2);
// Check read-only
if (type1.readOnly && !type2.readOnly) {
@@ -1164,6 +1183,16 @@
value = type1.accountType.compareTo(type2.accountType);
if (value != 0) {
return value;
+ } else {
+ // Fall back to data set.
+ if (type1.dataSet != null) {
+ value = type1.dataSet.compareTo(type2.dataSet);
+ if (value != 0) {
+ return value;
+ }
+ } else if (type2.dataSet != null) {
+ return 1;
+ }
}
}
diff --git a/src/com/android/contacts/editor/ExternalRawContactEditorView.java b/src/com/android/contacts/editor/ExternalRawContactEditorView.java
index e1a669b..734f013 100644
--- a/src/com/android/contacts/editor/ExternalRawContactEditorView.java
+++ b/src/com/android/contacts/editor/ExternalRawContactEditorView.java
@@ -18,14 +18,13 @@
import com.android.contacts.ContactsUtils;
import com.android.contacts.R;
-import com.android.contacts.editor.ExternalRawContactEditorView.Listener;
import com.android.contacts.model.AccountType;
+import com.android.contacts.model.AccountWithDataSet;
import com.android.contacts.model.DataKind;
import com.android.contacts.model.EntityDelta;
import com.android.contacts.model.EntityDelta.ValuesDelta;
import com.android.contacts.model.EntityModifier;
-import android.accounts.Account;
import android.content.ContentUris;
import android.content.Context;
import android.net.Uri;
@@ -66,12 +65,13 @@
private String mAccountName;
private String mAccountType;
+ private String mDataSet;
private long mRawContactId = -1;
private Listener mListener;
public interface Listener {
- void onExternalEditorRequest(Account account, Uri uri);
+ void onExternalEditorRequest(AccountWithDataSet account, Uri uri);
}
public ExternalRawContactEditorView(Context context) {
@@ -127,6 +127,7 @@
ValuesDelta values = state.getValues();
mAccountName = values.getAsString(RawContacts.ACCOUNT_NAME);
mAccountType = values.getAsString(RawContacts.ACCOUNT_TYPE);
+ mDataSet = values.getAsString(RawContacts.DATA_SET);
CharSequence accountType = type.getDisplayLabel(mContext);
if (TextUtils.isEmpty(accountType)) {
accountType = mContext.getString(R.string.account_phone);
@@ -136,6 +137,9 @@
mContext.getString(R.string.from_account_format, mAccountName));
}
mAccountTypeTextView.setText(mContext.getString(R.string.account_type_format, accountType));
+
+ // TODO: Expose data set in the UI somehow?
+
mAccountIcon.setImageDrawable(type.getDisplayIcon(mContext));
mRawContactId = values.getAsLong(RawContacts._ID);
@@ -221,7 +225,8 @@
public void onClick(View v) {
if (v.getId() == R.id.button_edit_externally) {
if (mListener != null) {
- mListener.onExternalEditorRequest(new Account(mAccountName, mAccountType),
+ mListener.onExternalEditorRequest(
+ new AccountWithDataSet(mAccountName, mAccountType, mDataSet),
ContentUris.withAppendedId(RawContacts.CONTENT_URI, mRawContactId));
}
}
diff --git a/src/com/android/contacts/editor/GroupMembershipView.java b/src/com/android/contacts/editor/GroupMembershipView.java
index a581b11..9693915 100644
--- a/src/com/android/contacts/editor/GroupMembershipView.java
+++ b/src/com/android/contacts/editor/GroupMembershipView.java
@@ -23,6 +23,7 @@
import com.android.contacts.model.EntityDelta;
import com.android.contacts.model.EntityDelta.ValuesDelta;
import com.android.contacts.model.EntityModifier;
+import com.android.internal.util.Objects;
import android.app.Activity;
import android.content.Context;
@@ -84,6 +85,7 @@
private Cursor mGroupMetaData;
private String mAccountName;
private String mAccountType;
+ private String mDataSet;
private TextView mGroupList;
private ArrayAdapter<GroupSelectionItem> mAdapter;
private long mDefaultGroupId;
@@ -125,6 +127,7 @@
ValuesDelta values = state.getValues();
mAccountType = values.getAsString(RawContacts.ACCOUNT_TYPE);
mAccountName = values.getAsString(RawContacts.ACCOUNT_NAME);
+ mDataSet = values.getAsString(RawContacts.DATA_SET);
mDefaultGroupVisibilityKnown = false;
updateView();
}
@@ -145,7 +148,9 @@
while (mGroupMetaData.moveToNext()) {
String accountName = mGroupMetaData.getString(GroupMetaDataLoader.ACCOUNT_NAME);
String accountType = mGroupMetaData.getString(GroupMetaDataLoader.ACCOUNT_TYPE);
- if (accountName.equals(mAccountName) && accountType.equals(mAccountType)) {
+ String dataSet = mGroupMetaData.getString(GroupMetaDataLoader.DATA_SET);
+ if (accountName.equals(mAccountName) && accountType.equals(mAccountType)
+ && Objects.equal(dataSet, mDataSet)) {
long groupId = mGroupMetaData.getLong(GroupMetaDataLoader.GROUP_ID);
if (!mGroupMetaData.isNull(GroupMetaDataLoader.FAVORITES)
&& mGroupMetaData.getInt(GroupMetaDataLoader.FAVORITES) != 0) {
@@ -209,7 +214,9 @@
while (mGroupMetaData.moveToNext()) {
String accountName = mGroupMetaData.getString(GroupMetaDataLoader.ACCOUNT_NAME);
String accountType = mGroupMetaData.getString(GroupMetaDataLoader.ACCOUNT_TYPE);
- if (accountName.equals(mAccountName) && accountType.equals(mAccountType)) {
+ String dataSet = mGroupMetaData.getString(GroupMetaDataLoader.DATA_SET);
+ if (accountName.equals(mAccountName) && accountType.equals(mAccountType)
+ && Objects.equal(dataSet, mDataSet)) {
long groupId = mGroupMetaData.getLong(GroupMetaDataLoader.GROUP_ID);
if (groupId != mFavoritesGroupId
&& (groupId != mDefaultGroupId || mDefaultGroupVisible)) {
@@ -328,6 +335,7 @@
}
GroupCreationDialogFragment.show(
- ((Activity) getContext()).getFragmentManager(), mAccountType, mAccountName);
+ ((Activity) getContext()).getFragmentManager(), mAccountType, mAccountName,
+ mDataSet);
}
}
diff --git a/src/com/android/contacts/editor/RawContactEditorView.java b/src/com/android/contacts/editor/RawContactEditorView.java
index 499b86f..41f2ebd 100644
--- a/src/com/android/contacts/editor/RawContactEditorView.java
+++ b/src/com/android/contacts/editor/RawContactEditorView.java
@@ -24,6 +24,7 @@
import com.android.contacts.model.EntityDelta;
import com.android.contacts.model.EntityDelta.ValuesDelta;
import com.android.contacts.model.EntityModifier;
+import com.android.internal.util.Objects;
import android.content.Context;
import android.content.Entity;
@@ -350,11 +351,14 @@
private long getDefaultGroupId() {
String accountType = mState.getValues().getAsString(RawContacts.ACCOUNT_TYPE);
String accountName = mState.getValues().getAsString(RawContacts.ACCOUNT_NAME);
+ String accountDataSet = mState.getValues().getAsString(RawContacts.DATA_SET);
mGroupMetaData.moveToPosition(-1);
while (mGroupMetaData.moveToNext()) {
String name = mGroupMetaData.getString(GroupMetaDataLoader.ACCOUNT_NAME);
String type = mGroupMetaData.getString(GroupMetaDataLoader.ACCOUNT_TYPE);
- if (name.equals(accountName) && type.equals(accountType)) {
+ String dataSet = mGroupMetaData.getString(GroupMetaDataLoader.DATA_SET);
+ if (name.equals(accountName) && type.equals(accountType)
+ && Objects.equal(dataSet, accountDataSet)) {
long groupId = mGroupMetaData.getLong(GroupMetaDataLoader.GROUP_ID);
if (!mGroupMetaData.isNull(GroupMetaDataLoader.AUTO_ADD)
&& mGroupMetaData.getInt(GroupMetaDataLoader.AUTO_ADD) != 0) {
diff --git a/src/com/android/contacts/editor/SelectAccountDialogFragment.java b/src/com/android/contacts/editor/SelectAccountDialogFragment.java
index 0a33f25..9dbe20a 100644
--- a/src/com/android/contacts/editor/SelectAccountDialogFragment.java
+++ b/src/com/android/contacts/editor/SelectAccountDialogFragment.java
@@ -17,9 +17,9 @@
package com.android.contacts.editor;
import com.android.contacts.R;
+import com.android.contacts.model.AccountWithDataSet;
import com.android.contacts.util.AccountsListAdapter;
-import android.accounts.Account;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.DialogFragment;
@@ -80,10 +80,10 @@
}
/**
- * Calls {@link Listener#onAccountChosen(int, Account)} if the target fragment is castable
- * to {@link Listener}. Subclasses can also overide to directly perform an operation
+ * Calls {@link Listener#onAccountChosen(int, AccountWithDataSet)} if the target fragment is
+ * castable to {@link Listener}. Subclasses can also overide to directly perform an operation.
*/
- protected void onAccountSelected(Account account) {
+ protected void onAccountSelected(AccountWithDataSet account) {
final Fragment targetFragment = getTargetFragment();
if (targetFragment != null && targetFragment instanceof Listener) {
final Listener target = (Listener) targetFragment;
@@ -92,7 +92,7 @@
}
public interface Listener {
- void onAccountChosen(int requestCode, Account account);
+ void onAccountChosen(int requestCode, AccountWithDataSet account);
void onAccountSelectorCancelled();
}
}
diff --git a/src/com/android/contacts/group/GroupBrowseListAdapter.java b/src/com/android/contacts/group/GroupBrowseListAdapter.java
index be99738..753261a 100644
--- a/src/com/android/contacts/group/GroupBrowseListAdapter.java
+++ b/src/com/android/contacts/group/GroupBrowseListAdapter.java
@@ -20,6 +20,8 @@
import com.android.contacts.R;
import com.android.contacts.model.AccountType;
import com.android.contacts.model.AccountTypeManager;
+import com.android.contacts.model.AccountWithDataSet;
+import com.android.internal.util.Objects;
import android.content.ContentUris;
import android.content.Context;
@@ -104,6 +106,7 @@
}
String accountName = mCursor.getString(GroupListLoader.ACCOUNT_NAME);
String accountType = mCursor.getString(GroupListLoader.ACCOUNT_TYPE);
+ String dataSet = mCursor.getString(GroupListLoader.DATA_SET);
long groupId = mCursor.getLong(GroupListLoader.GROUP_ID);
String title = mCursor.getString(GroupListLoader.TITLE);
int memberCount = mCursor.getInt(GroupListLoader.MEMBER_COUNT);
@@ -117,14 +120,17 @@
if (previousIndex >= 0 && mCursor.moveToPosition(previousIndex)) {
String previousGroupAccountName = mCursor.getString(GroupListLoader.ACCOUNT_NAME);
String previousGroupAccountType = mCursor.getString(GroupListLoader.ACCOUNT_TYPE);
+ String previousGroupDataSet = mCursor.getString(GroupListLoader.DATA_SET);
+
if (accountName.equals(previousGroupAccountName) &&
- accountType.equals(previousGroupAccountType)) {
+ accountType.equals(previousGroupAccountType) &&
+ Objects.equal(dataSet, previousGroupDataSet)) {
isFirstGroupInAccount = false;
}
}
- return new GroupListItem(accountName, accountType, groupId, title, isFirstGroupInAccount,
- memberCount, groupCountForThisAccount);
+ return new GroupListItem(accountName, accountType, dataSet, groupId, title,
+ isFirstGroupInAccount, memberCount, groupCountForThisAccount);
}
@Override
@@ -167,7 +173,8 @@
}
private void bindHeaderView(GroupListItem entry, GroupListItemViewCache viewCache) {
- AccountType accountType = mAccountTypeManager.getAccountType(entry.getAccountType());
+ AccountType accountType = mAccountTypeManager.getAccountType(
+ entry.getAccountType(), entry.getDataSet());
viewCache.accountType.setText(accountType.getDisplayLabel(mContext).toString());
viewCache.accountName.setText(entry.getAccountName());
diff --git a/src/com/android/contacts/group/GroupDetailDisplayUtils.java b/src/com/android/contacts/group/GroupDetailDisplayUtils.java
index 56413b5..bb4cd5c 100644
--- a/src/com/android/contacts/group/GroupDetailDisplayUtils.java
+++ b/src/com/android/contacts/group/GroupDetailDisplayUtils.java
@@ -37,14 +37,15 @@
return inflater.inflate(R.layout.group_source_button, null);
}
- public static void bindGroupSourceView(Context context, View view, String accountTypeString) {
+ public static void bindGroupSourceView(Context context, View view, String accountTypeString,
+ String dataSet) {
ImageView accountIcon = (ImageView) view.findViewById(android.R.id.icon);
if (accountIcon == null) {
throw new IllegalStateException("Group source view must contain view with id"
+ "android.R.id.icon");
}
AccountTypeManager accountTypeManager = AccountTypeManager.getInstance(context);
- AccountType accountType = accountTypeManager.getAccountType(accountTypeString);
+ AccountType accountType = accountTypeManager.getAccountType(accountTypeString, dataSet);
accountIcon.setImageDrawable(accountType.getDisplayIcon(context));
}
}
\ No newline at end of file
diff --git a/src/com/android/contacts/group/GroupDetailFragment.java b/src/com/android/contacts/group/GroupDetailFragment.java
index 576f6c1..019dc11 100644
--- a/src/com/android/contacts/group/GroupDetailFragment.java
+++ b/src/com/android/contacts/group/GroupDetailFragment.java
@@ -70,8 +70,8 @@
/**
* The group source (intent action and action URI) has been determined.
*/
- public void onGroupSourceUpdated(String accountTypeString, String groupSourceAction,
- String groupSourceUri);
+ public void onGroupSourceUpdated(String accountTypeString, String dataSet,
+ String groupSourceAction, String groupSourceUri);
/**
* User decided to go to Edit-Mode
@@ -108,6 +108,7 @@
private long mGroupId;
private String mGroupName;
private String mAccountTypeString;
+ private String mDataSet;
private boolean mIsReadOnly;
private boolean mShowGroupActionInActionBar;
@@ -271,6 +272,7 @@
cursor.moveToPosition(-1);
if (cursor.moveToNext()) {
mAccountTypeString = cursor.getString(GroupMetaDataLoader.ACCOUNT_TYPE);
+ mDataSet = cursor.getString(GroupMetaDataLoader.DATA_SET);
mGroupId = cursor.getLong(GroupMetaDataLoader.GROUP_ID);
mGroupName = cursor.getString(GroupMetaDataLoader.TITLE);
mIsReadOnly = cursor.getInt(GroupMetaDataLoader.IS_READ_ONLY) == 1;
@@ -279,9 +281,10 @@
getActivity().invalidateOptionsMenu ();
final String accountTypeString = cursor.getString(GroupMetaDataLoader.ACCOUNT_TYPE);
+ final String dataSet = cursor.getString(GroupMetaDataLoader.DATA_SET);
final String groupSourceAction = cursor.getString(GroupMetaDataLoader.ACTION);
final String groupSourceUri = cursor.getString(GroupMetaDataLoader.ACTION_URI);
- updateGroupSouce(accountTypeString, groupSourceAction, groupSourceUri);
+ updateGroupSource(accountTypeString, dataSet, groupSourceAction, groupSourceUri);
}
}
@@ -304,7 +307,8 @@
} else {
String groupSizeTemplateString = getResources().getQuantityString(
R.plurals.num_contacts_in_group, size);
- AccountType accountType = mAccountTypeManager.getAccountType(mAccountTypeString);
+ AccountType accountType = mAccountTypeManager.getAccountType(mAccountTypeString,
+ mDataSet);
groupSizeString = String.format(groupSizeTemplateString, size,
accountType.getDisplayLabel(mContext));
}
@@ -323,14 +327,15 @@
* a button in a static header on the page, or as a header that scrolls with the
* {@link ListView}.
*/
- private void updateGroupSouce(final String accountTypeString, final String groupSourceAction,
- final String groupSourceUri) {
+ private void updateGroupSource(final String accountTypeString, final String dataSet,
+ final String groupSourceAction, final String groupSourceUri) {
// If the group action should be shown in the action bar, then pass the data to the
// listener who will take care of setting up the view and click listener. There is nothing
// else to be done by this {@link Fragment}.
if (mShowGroupActionInActionBar) {
- mListener.onGroupSourceUpdated(accountTypeString, groupSourceAction, groupSourceUri);
+ mListener.onGroupSourceUpdated(accountTypeString, dataSet, groupSourceAction,
+ groupSourceUri);
return;
}
@@ -354,7 +359,7 @@
// Rebind the data since this action can change if the loader returns updated data
mGroupSourceView.setVisibility(View.VISIBLE);
GroupDetailDisplayUtils.bindGroupSourceView(mContext, mGroupSourceView,
- accountTypeString);
+ accountTypeString, dataSet);
mGroupSourceView.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
diff --git a/src/com/android/contacts/group/GroupEditorFragment.java b/src/com/android/contacts/group/GroupEditorFragment.java
index bc9e5ba..9a09c77 100644
--- a/src/com/android/contacts/group/GroupEditorFragment.java
+++ b/src/com/android/contacts/group/GroupEditorFragment.java
@@ -27,6 +27,7 @@
import com.android.contacts.group.SuggestedMemberListAdapter.SuggestedMember;
import com.android.contacts.model.AccountType;
import com.android.contacts.model.AccountTypeManager;
+import com.android.contacts.model.AccountWithDataSet;
import com.android.internal.util.Objects;
import android.accounts.Account;
@@ -172,6 +173,7 @@
private boolean mGroupNameIsReadOnly;
private String mAccountName;
private String mAccountType;
+ private String mDataSet;
private String mOriginalGroupName = "";
private MemberListAdapter mMemberListAdapter;
@@ -221,11 +223,14 @@
final Account account = mIntentExtras == null ? null :
(Account) mIntentExtras.getParcelable(Intents.Insert.ACCOUNT);
+ final String dataSet = mIntentExtras == null ? null :
+ mIntentExtras.getString(Intents.Insert.DATA_SET);
if (account != null) {
- // Account specified in Intent
+ // Account specified in Intent - no data set can be specified in this manner.
mAccountName = account.name;
mAccountType = account.type;
+ mDataSet = dataSet;
setupEditorForAccount();
} else {
// No Account specified. Let the user choose from a disambiguation dialog.
@@ -245,7 +250,7 @@
}
private void selectAccountAndCreateGroup() {
- final ArrayList<Account> accounts =
+ final List<AccountWithDataSet> accounts =
AccountTypeManager.getInstance(mContext).getAccounts(true /* writeable */);
// No Accounts available
if (accounts.isEmpty()) {
@@ -257,6 +262,7 @@
if (accounts.size() == 1) {
mAccountName = accounts.get(0).name;
mAccountType = accounts.get(0).type;
+ mDataSet = accounts.get(0).dataSet;
setupEditorForAccount();
return; // Don't show a dialog.
}
@@ -268,9 +274,10 @@
}
@Override
- public void onAccountChosen(int requestCode, Account account) {
+ public void onAccountChosen(int requestCode, AccountWithDataSet account) {
mAccountName = account.name;
mAccountType = account.type;
+ mDataSet = account.dataSet;
setupEditorForAccount();
}
@@ -287,7 +294,7 @@
*/
private void setupEditorForAccount() {
final AccountTypeManager accountTypeManager = AccountTypeManager.getInstance(mContext);
- final AccountType accountType = accountTypeManager.getAccountType(mAccountType);
+ final AccountType accountType = accountTypeManager.getAccountType(mAccountType, mDataSet);
final boolean editable = accountType.isGroupMembershipEditable();
mMemberListAdapter.setIsGroupMembershipEditable(editable);
@@ -478,16 +485,17 @@
return false;
}
Intent saveIntent = null;
- if (mAction == Intent.ACTION_INSERT) {
+ if (Intent.ACTION_INSERT.equals(mAction)) {
// Create array of raw contact IDs for contacts to add to the group
long[] membersToAddArray = convertToArray(mListMembersToAdd);
// Create the save intent to create the group and add members at the same time
saveIntent = ContactSaveService.createNewGroupIntent(activity,
- new Account(mAccountName, mAccountType), mGroupNameView.getText().toString(),
+ new AccountWithDataSet(mAccountName, mAccountType, mDataSet),
+ mGroupNameView.getText().toString(),
membersToAddArray, activity.getClass(),
GroupEditorActivity.ACTION_SAVE_COMPLETED);
- } else if (mAction == Intent.ACTION_EDIT) {
+ } else if (Intent.ACTION_EDIT.equals(mAction)) {
// Create array of raw contact IDs for contacts to add to the group
long[] membersToAddArray = convertToArray(mListMembersToAdd);
diff --git a/src/com/android/contacts/group/GroupListItem.java b/src/com/android/contacts/group/GroupListItem.java
index 349b86e..c707ea7 100644
--- a/src/com/android/contacts/group/GroupListItem.java
+++ b/src/com/android/contacts/group/GroupListItem.java
@@ -22,6 +22,7 @@
public final class GroupListItem {
private final String mAccountName;
private final String mAccountType;
+ private final String mDataSet;
private final long mGroupId;
private final String mTitle;
private final boolean mIsFirstGroupInAccount;
@@ -30,10 +31,12 @@
/** Number of groups in the account that this group belongs to */
private final int mGroupCountForThisAccount;
- public GroupListItem(String accountName, String accountType, long groupId, String title,
- boolean isFirstGroupInAccount, int memberCount, int groupCountForThisAccount) {
+ public GroupListItem(String accountName, String accountType, String dataSet, long groupId,
+ String title, boolean isFirstGroupInAccount, int memberCount,
+ int groupCountForThisAccount) {
mAccountName = accountName;
mAccountType = accountType;
+ mDataSet = dataSet;
mGroupId = groupId;
mTitle = title;
mIsFirstGroupInAccount = isFirstGroupInAccount;
@@ -49,6 +52,10 @@
return mAccountType;
}
+ public String getDataSet() {
+ return mDataSet;
+ }
+
public long getGroupId() {
return mGroupId;
}
diff --git a/src/com/android/contacts/group/SuggestedMemberListAdapter.java b/src/com/android/contacts/group/SuggestedMemberListAdapter.java
index 5abb5fb..4f4413c 100644
--- a/src/com/android/contacts/group/SuggestedMemberListAdapter.java
+++ b/src/com/android/contacts/group/SuggestedMemberListAdapter.java
@@ -78,6 +78,7 @@
private String mAccountType = "";
private String mAccountName = "";
+ private String mDataSet = "";
// TODO: Make this a Map for better performance when we check if a new contact is in the list
// or not
@@ -98,6 +99,10 @@
mAccountName = accountName;
}
+ public void setDataSet(String dataSet) {
+ mDataSet = dataSet;
+ }
+
public void setContentResolver(ContentResolver resolver) {
mContentResolver = resolver;
}
@@ -171,12 +176,25 @@
// First query for all the raw contacts that match the given search query
// and have the same account name and type as specified in this adapter
String searchQuery = prefix.toString() + "%";
+ String accountClause = RawContacts.ACCOUNT_NAME + "=? AND " +
+ RawContacts.ACCOUNT_TYPE + "=?";
+ String[] args;
+ if (mDataSet == null) {
+ accountClause += " AND " + RawContacts.DATA_SET + " IS NULL";
+ args = new String[] {mAccountName, mAccountType, searchQuery, searchQuery};
+ } else {
+ accountClause += " AND " + RawContacts.DATA_SET + "=?";
+ args = new String[] {
+ mAccountName, mAccountType, mDataSet, searchQuery, searchQuery
+ };
+ }
+
Cursor cursor = mContentResolver.query(
RawContacts.CONTENT_URI, PROJECTION_FILTERED_MEMBERS,
- RawContacts.ACCOUNT_NAME + "=? AND " + RawContacts.ACCOUNT_TYPE + "=? AND (" +
+ accountClause + " AND (" +
RawContacts.DISPLAY_NAME_PRIMARY + " LIKE ? OR " +
RawContacts.DISPLAY_NAME_ALTERNATIVE + " LIKE ? )",
- new String[] {mAccountName, mAccountType, searchQuery, searchQuery}, null);
+ args, null);
if (cursor == null) {
return results;
diff --git a/src/com/android/contacts/interactions/ContactDeletionInteraction.java b/src/com/android/contacts/interactions/ContactDeletionInteraction.java
index dfcd7b6..93bd10e 100644
--- a/src/com/android/contacts/interactions/ContactDeletionInteraction.java
+++ b/src/com/android/contacts/interactions/ContactDeletionInteraction.java
@@ -59,14 +59,16 @@
private static final String[] ENTITY_PROJECTION = new String[] {
Entity.RAW_CONTACT_ID, //0
Entity.ACCOUNT_TYPE, //1
- Entity.CONTACT_ID, // 2
- Entity.LOOKUP_KEY, // 3
+ Entity.DATA_SET, // 2
+ Entity.CONTACT_ID, // 3
+ Entity.LOOKUP_KEY, // 4
};
private static final int COLUMN_INDEX_RAW_CONTACT_ID = 0;
private static final int COLUMN_INDEX_ACCOUNT_TYPE = 1;
- private static final int COLUMN_INDEX_CONTACT_ID = 2;
- private static final int COLUMN_INDEX_LOOKUP_KEY = 3;
+ private static final int COLUMN_INDEX_DATA_SET = 2;
+ private static final int COLUMN_INDEX_CONTACT_ID = 3;
+ private static final int COLUMN_INDEX_LOOKUP_KEY = 4;
private boolean mActive;
private Uri mContactUri;
@@ -233,9 +235,10 @@
while (cursor.moveToNext()) {
final long rawContactId = cursor.getLong(COLUMN_INDEX_RAW_CONTACT_ID);
final String accountType = cursor.getString(COLUMN_INDEX_ACCOUNT_TYPE);
+ final String dataSet = cursor.getString(COLUMN_INDEX_DATA_SET);
contactId = cursor.getLong(COLUMN_INDEX_CONTACT_ID);
lookupKey = cursor.getString(COLUMN_INDEX_LOOKUP_KEY);
- AccountType type = accountTypes.getAccountType(accountType);
+ AccountType type = accountTypes.getAccountType(accountType, dataSet);
boolean readonly = type != null && type.readOnly;
if (readonly) {
readOnlyRawContacts.add(rawContactId);
diff --git a/src/com/android/contacts/interactions/GroupCreationDialogFragment.java b/src/com/android/contacts/interactions/GroupCreationDialogFragment.java
index 87d83b4..224b4a0 100644
--- a/src/com/android/contacts/interactions/GroupCreationDialogFragment.java
+++ b/src/com/android/contacts/interactions/GroupCreationDialogFragment.java
@@ -17,8 +17,8 @@
import com.android.contacts.ContactSaveService;
import com.android.contacts.R;
+import com.android.contacts.model.AccountWithDataSet;
-import android.accounts.Account;
import android.app.Activity;
import android.app.FragmentManager;
import android.content.Intent;
@@ -31,13 +31,16 @@
public class GroupCreationDialogFragment extends GroupNameDialogFragment {
private static final String ARG_ACCOUNT_TYPE = "accountType";
private static final String ARG_ACCOUNT_NAME = "accountName";
+ private static final String ARG_DATA_SET = "dataSet";
public static void show(
- FragmentManager fragmentManager, String accountType, String accountName) {
+ FragmentManager fragmentManager, String accountType, String accountName,
+ String dataSet) {
GroupCreationDialogFragment dialog = new GroupCreationDialogFragment();
Bundle args = new Bundle();
args.putString(ARG_ACCOUNT_TYPE, accountType);
args.putString(ARG_ACCOUNT_NAME, accountName);
+ args.putString(ARG_DATA_SET, dataSet);
dialog.setArguments(args);
dialog.show(fragmentManager, "createGroup");
}
@@ -56,10 +59,11 @@
Bundle arguments = getArguments();
String accountType = arguments.getString(ARG_ACCOUNT_TYPE);
String accountName = arguments.getString(ARG_ACCOUNT_NAME);
+ String dataSet = arguments.getString(ARG_DATA_SET);
Activity activity = getActivity();
activity.startService(ContactSaveService.createNewGroupIntent(activity,
- new Account(accountName, accountType), groupLabel,
+ new AccountWithDataSet(accountName, accountType, dataSet), groupLabel,
null /* no new members to add */,
activity.getClass(), Intent.ACTION_EDIT));
}
diff --git a/src/com/android/contacts/interactions/ImportExportDialogFragment.java b/src/com/android/contacts/interactions/ImportExportDialogFragment.java
index 4e22fa2..a6a37ef 100644
--- a/src/com/android/contacts/interactions/ImportExportDialogFragment.java
+++ b/src/com/android/contacts/interactions/ImportExportDialogFragment.java
@@ -19,10 +19,10 @@
import com.android.contacts.R;
import com.android.contacts.editor.SelectAccountDialogFragment;
import com.android.contacts.model.AccountTypeManager;
+import com.android.contacts.model.AccountWithDataSet;
import com.android.contacts.util.AccountSelectionUtil;
import com.android.contacts.vcard.ExportVCardActivity;
-import android.accounts.Account;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.DialogFragment;
@@ -169,7 +169,7 @@
// - just one account -> use the account without asking the user
// - no account -> use phone-local storage without asking the user
final AccountTypeManager accountTypes = AccountTypeManager.getInstance(getActivity());
- final List<Account> accountList = accountTypes.getAccounts(true);
+ final List<AccountWithDataSet> accountList = accountTypes.getAccounts(true);
final int size = accountList.size();
if (size > 1) {
// Send over to the account selector
@@ -196,7 +196,7 @@
}
@Override
- protected void onAccountSelected(Account account) {
+ protected void onAccountSelected(AccountWithDataSet account) {
final int resourceId = getArguments().getInt(BUNDLE_RES_ID);
AccountSelectionUtil.doImport(getActivity(), resourceId, account);
}
diff --git a/src/com/android/contacts/interactions/PhoneNumberInteraction.java b/src/com/android/contacts/interactions/PhoneNumberInteraction.java
index 9762e3d..9442f5e 100644
--- a/src/com/android/contacts/interactions/PhoneNumberInteraction.java
+++ b/src/com/android/contacts/interactions/PhoneNumberInteraction.java
@@ -85,6 +85,7 @@
long id;
String phoneNumber;
String accountType;
+ String dataSet;
long type;
String label;
@@ -92,6 +93,7 @@
dest.writeLong(id);
dest.writeString(phoneNumber);
dest.writeString(accountType);
+ dest.writeString(dataSet);
dest.writeLong(type);
dest.writeString(label);
}
@@ -148,7 +150,8 @@
final View view = super.getView(position, convertView, parent);
final PhoneItem item = getItem(position);
- final AccountType accountType = mAccountTypeManager.getAccountType(item.accountType);
+ final AccountType accountType = mAccountTypeManager.getAccountType(
+ item.accountType, item.dataSet);
final TextView typeView = (TextView) view.findViewById(android.R.id.text1);
final DataKind kind = accountType.getKindForMimetype(Phone.CONTENT_ITEM_TYPE);
if (kind != null) {
@@ -237,6 +240,7 @@
Phone.NUMBER,
Phone.IS_SUPER_PRIMARY,
RawContacts.ACCOUNT_TYPE,
+ RawContacts.DATA_SET,
Phone.TYPE,
Phone.LABEL
};
@@ -335,6 +339,7 @@
item.phoneNumber = cursor.getString(cursor.getColumnIndex(Phone.NUMBER));
item.accountType =
cursor.getString(cursor.getColumnIndex(RawContacts.ACCOUNT_TYPE));
+ item.dataSet = cursor.getString(cursor.getColumnIndex(RawContacts.DATA_SET));
item.type = cursor.getInt(cursor.getColumnIndex(Phone.TYPE));
item.label = cursor.getString(cursor.getColumnIndex(Phone.LABEL));
diff --git a/src/com/android/contacts/list/AccountFilterActivity.java b/src/com/android/contacts/list/AccountFilterActivity.java
index 24eab23..f99b14e 100644
--- a/src/com/android/contacts/list/AccountFilterActivity.java
+++ b/src/com/android/contacts/list/AccountFilterActivity.java
@@ -22,8 +22,8 @@
import com.android.contacts.activities.PeopleActivity;
import com.android.contacts.model.AccountType;
import com.android.contacts.model.AccountTypeManager;
+import com.android.contacts.model.AccountWithDataSet;
-import android.accounts.Account;
import android.app.ActionBar;
import android.app.Activity;
import android.content.Context;
@@ -81,12 +81,12 @@
private void loadAccountFilters() {
ArrayList<ContactListFilter> accountFilters = new ArrayList<ContactListFilter>();
final AccountTypeManager accountTypes = AccountTypeManager.getInstance(this);
- ArrayList<Account> accounts = accountTypes.getAccounts(false);
- for (Account account : accounts) {
- AccountType accountType = accountTypes.getAccountType(account.type);
+ List<AccountWithDataSet> accounts = accountTypes.getAccounts(false);
+ for (AccountWithDataSet account : accounts) {
+ AccountType accountType = accountTypes.getAccountType(account.type, account.dataSet);
Drawable icon = accountType != null ? accountType.getDisplayIcon(this) : null;
accountFilters.add(ContactListFilter.createAccountFilter(account.type, account.name,
- icon, account.name));
+ account.dataSet, icon, account.name));
}
int count = accountFilters.size();
diff --git a/src/com/android/contacts/list/ContactListFilter.java b/src/com/android/contacts/list/ContactListFilter.java
index 0651986..cfcde2a 100644
--- a/src/com/android/contacts/list/ContactListFilter.java
+++ b/src/com/android/contacts/list/ContactListFilter.java
@@ -40,6 +40,7 @@
private static final String KEY_FILTER_TYPE = "filter.type";
private static final String KEY_ACCOUNT_NAME = "filter.accountName";
private static final String KEY_ACCOUNT_TYPE = "filter.accountType";
+ private static final String KEY_DATA_SET = "filter.dataSet";
private static final String KEY_GROUP_ID = "filter.groupId";
private static final String KEY_GROUP_SOURCE_ID = "filter.groupSourceId";
private static final String KEY_GROUP_READ_ONLY = "filter.groupReadOnly";
@@ -48,6 +49,7 @@
public final int filterType;
public final String accountType;
public final String accountName;
+ public final String dataSet;
public final Drawable icon;
public long groupId;
public String groupSourceId;
@@ -55,11 +57,13 @@
public final String title;
private String mId;
- public ContactListFilter(int filterType, String accountType, String accountName, Drawable icon,
- long groupId, String groupSourceId, boolean groupReadOnly, String title) {
+ public ContactListFilter(int filterType, String accountType, String accountName, String dataSet,
+ Drawable icon, long groupId, String groupSourceId, boolean groupReadOnly,
+ String title) {
this.filterType = filterType;
this.accountType = accountType;
this.accountName = accountName;
+ this.dataSet = dataSet;
this.icon = icon;
this.groupId = groupId;
this.groupSourceId = groupSourceId;
@@ -68,24 +72,25 @@
}
public static ContactListFilter createFilterWithType(int filterType) {
- return new ContactListFilter(filterType, null, null, null, 0, null, false, null);
+ return new ContactListFilter(filterType, null, null, null, null, 0, null, false, null);
}
public static ContactListFilter createGroupFilter(long groupId) {
- return new ContactListFilter(ContactListFilter.FILTER_TYPE_GROUP, null, null, null, groupId,
- null, false, null);
+ return new ContactListFilter(ContactListFilter.FILTER_TYPE_GROUP, null, null, null, null,
+ groupId, null, false, null);
}
public static ContactListFilter createGroupFilter(String accountType, String accountName,
- long groupId, String groupSourceId, boolean groupReadOnly, String title) {
+ String dataSet, long groupId, String groupSourceId, boolean groupReadOnly,
+ String title) {
return new ContactListFilter(ContactListFilter.FILTER_TYPE_GROUP, accountType, accountName,
- null, groupId, groupSourceId, groupReadOnly, title);
+ dataSet, null, groupId, groupSourceId, groupReadOnly, title);
}
public static ContactListFilter createAccountFilter(String accountType, String accountName,
- Drawable icon, String title) {
+ String dataSet, Drawable icon, String title) {
return new ContactListFilter(ContactListFilter.FILTER_TYPE_ACCOUNT, accountType,
- accountName, icon, 0, null, false, title);
+ accountName, dataSet, icon, 0, null, false, title);
}
/**
@@ -111,10 +116,11 @@
case FILTER_TYPE_SINGLE_CONTACT:
return "single";
case FILTER_TYPE_ACCOUNT:
- return "account: " + accountType + " " + accountName;
+ return "account: " + accountType + (dataSet != null ? "/" + dataSet : "")
+ + " " + accountName;
case FILTER_TYPE_GROUP:
- return "group: " + accountType + " " + accountName + " " + title + "(" + groupId
- + ")";
+ return "group: " + accountType + (dataSet != null ? "/" + dataSet : "")
+ + " " + accountName + " " + title + "(" + groupId + ")";
}
return super.toString();
}
@@ -147,6 +153,9 @@
code = code * 31 + accountType.hashCode();
code = code * 31 + accountName.hashCode();
}
+ if (dataSet != null) {
+ code = code * 31 + dataSet.hashCode();
+ }
if (groupSourceId != null) {
code = code * 31 + groupSourceId.hashCode();
} else if (groupId != 0) {
@@ -168,7 +177,8 @@
ContactListFilter otherFilter = (ContactListFilter) other;
if (filterType != otherFilter.filterType
|| !TextUtils.equals(accountName, otherFilter.accountName)
- || !TextUtils.equals(accountType, otherFilter.accountType)) {
+ || !TextUtils.equals(accountType, otherFilter.accountType)
+ || !TextUtils.equals(dataSet, otherFilter.dataSet)) {
return false;
}
@@ -184,6 +194,7 @@
.putInt(KEY_FILTER_TYPE, filter == null ? FILTER_TYPE_DEFAULT : filter.filterType)
.putString(KEY_ACCOUNT_NAME, filter == null ? null : filter.accountName)
.putString(KEY_ACCOUNT_TYPE, filter == null ? null : filter.accountType)
+ .putString(KEY_DATA_SET, filter == null ? null : filter.dataSet)
.putLong(KEY_GROUP_ID, filter == null ? -1 : filter.groupId)
.putString(KEY_GROUP_SOURCE_ID, filter == null ? null : filter.groupSourceId)
.putBoolean(KEY_GROUP_READ_ONLY, filter == null ? false : filter.groupReadOnly)
@@ -199,11 +210,12 @@
String accountName = prefs.getString(KEY_ACCOUNT_NAME, null);
String accountType = prefs.getString(KEY_ACCOUNT_TYPE, null);
+ String dataSet = prefs.getString(KEY_DATA_SET, null);
long groupId = prefs.getLong(KEY_GROUP_ID, -1);
String groupSourceId = prefs.getString(KEY_GROUP_SOURCE_ID, null);
boolean groupReadOnly = prefs.getBoolean(KEY_GROUP_READ_ONLY, false);
String title = prefs.getString(KEY_GROUP_TITLE, "group");
- return new ContactListFilter(filterType, accountType, accountName, null, groupId,
+ return new ContactListFilter(filterType, accountType, accountName, dataSet, null, groupId,
groupSourceId, groupReadOnly, title);
}
@@ -213,6 +225,7 @@
dest.writeInt(filterType);
dest.writeString(accountName);
dest.writeString(accountType);
+ dest.writeString(dataSet);
dest.writeLong(groupId);
dest.writeString(groupSourceId);
dest.writeInt(groupReadOnly ? 1 : 0);
@@ -225,11 +238,12 @@
int filterType = source.readInt();
String accountName = source.readString();
String accountType = source.readString();
+ String dataSet = source.readString();
long groupId = source.readLong();
String groupSourceId = source.readString();
boolean groupReadOnly = source.readInt() != 0;
- return new ContactListFilter(filterType, accountType, accountName, null, groupId,
- groupSourceId, groupReadOnly, null);
+ return new ContactListFilter(filterType, accountType, accountName, dataSet, null,
+ groupId, groupSourceId, groupReadOnly, null);
}
@Override
@@ -253,6 +267,9 @@
if (accountType != null) {
sb.append('-').append(accountType);
}
+ if (dataSet != null) {
+ sb.append('/').append(dataSet);
+ }
if (accountName != null) {
sb.append('-').append(accountName.replace('-', '_'));
}
diff --git a/src/com/android/contacts/list/CustomContactListFilterActivity.java b/src/com/android/contacts/list/CustomContactListFilterActivity.java
index 0f6aaad..ae21824 100644
--- a/src/com/android/contacts/list/CustomContactListFilterActivity.java
+++ b/src/com/android/contacts/list/CustomContactListFilterActivity.java
@@ -21,6 +21,7 @@
import com.android.contacts.R;
import com.android.contacts.model.AccountType;
import com.android.contacts.model.AccountTypeManager;
+import com.android.contacts.model.AccountWithDataSet;
import com.android.contacts.model.EntityDelta.ValuesDelta;
import com.android.contacts.model.GoogleAccountType;
import com.android.contacts.util.EmptyService;
@@ -28,7 +29,6 @@
import com.android.contacts.util.WeakAsyncTask;
import com.google.android.collect.Lists;
-import android.accounts.Account;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.LoaderManager.LoaderCallbacks;
@@ -124,13 +124,14 @@
final ContentResolver resolver = context.getContentResolver();
final AccountSet accounts = new AccountSet();
- for (Account account : accountTypes.getAccounts(false)) {
+ for (AccountWithDataSet account : accountTypes.getAccounts(false)) {
AccountDisplay accountDisplay =
- new AccountDisplay(resolver, account.name, account.type);
+ new AccountDisplay(resolver, account.name, account.type, account.dataSet);
final Uri groupsUri = Groups.CONTENT_URI.buildUpon()
.appendQueryParameter(Groups.ACCOUNT_NAME, account.name)
- .appendQueryParameter(Groups.ACCOUNT_TYPE, account.type).build();
+ .appendQueryParameter(Groups.ACCOUNT_TYPE, account.type)
+ .appendQueryParameter(Groups.DATA_SET, account.dataSet).build();
EntityIterator iterator = ContactsContract.Groups.newEntityIterator(resolver.query(
groupsUri, null, null, null, null));
try {
@@ -417,12 +418,13 @@
}
/**
- * {@link GroupDelta} details for a single {@link Account}, usually shown as
+ * {@link GroupDelta} details for a single {@link AccountWithDataSet}, usually shown as
* children under a single expandable group.
*/
protected static class AccountDisplay {
- public String mName;
- public String mType;
+ public final String mName;
+ public final String mType;
+ public final String mDataSet;
public GroupDelta mUngrouped;
public ArrayList<GroupDelta> mSyncedGroups = Lists.newArrayList();
@@ -430,11 +432,13 @@
/**
* Build an {@link AccountDisplay} covering all {@link Groups} under the
- * given {@link Account}.
+ * given {@link AccountWithDataSet}.
*/
- public AccountDisplay(ContentResolver resolver, String accountName, String accountType) {
+ public AccountDisplay(ContentResolver resolver, String accountName, String accountType,
+ String dataSet) {
mName = accountName;
mType = accountType;
+ mDataSet = dataSet;
}
/**
@@ -489,7 +493,7 @@
/**
* Build set of {@link ContentProviderOperation} to persist any user
- * changes to {@link GroupDelta} rows under this {@link Account}.
+ * changes to {@link GroupDelta} rows under this {@link AccountWithDataSet}.
*/
public void buildDiff(ArrayList<ContentProviderOperation> diff) {
for (GroupDelta group : mSyncedGroups) {
@@ -505,7 +509,7 @@
/**
* {@link ExpandableListAdapter} that shows {@link GroupDelta} settings,
- * grouped by {@link Account} type. Shows footer row when any groups are
+ * grouped by {@link AccountWithDataSet} type. Shows footer row when any groups are
* unsynced, as determined through {@link AccountDisplay#mUnsyncedGroups}.
*/
protected static class DisplayAdapter extends BaseExpandableListAdapter {
@@ -548,7 +552,8 @@
final AccountDisplay account = (AccountDisplay)this.getGroup(groupPosition);
- final AccountType accountType = mAccountTypes.getAccountType(account.mType);
+ final AccountType accountType = mAccountTypes.getAccountType(
+ account.mType, account.mDataSet);
text1.setText(account.mName);
text1.setVisibility(account.mName == null ? View.GONE : View.VISIBLE);
@@ -693,7 +698,7 @@
protected int getSyncMode(AccountDisplay account) {
// TODO: read sync mode through <sync-adapter> definition
- if (GoogleAccountType.ACCOUNT_TYPE.equals(account.mType)) {
+ if (GoogleAccountType.ACCOUNT_TYPE.equals(account.mType) && account.mDataSet == null) {
return SYNC_MODE_EVERYTHING;
} else {
return SYNC_MODE_UNSUPPORTED;
diff --git a/src/com/android/contacts/list/DefaultContactListAdapter.java b/src/com/android/contacts/list/DefaultContactListAdapter.java
index 8b93888..8e96690 100644
--- a/src/com/android/contacts/list/DefaultContactListAdapter.java
+++ b/src/com/android/contacts/list/DefaultContactListAdapter.java
@@ -196,9 +196,15 @@
+ "SELECT DISTINCT " + RawContacts.CONTACT_ID
+ " FROM raw_contacts"
+ " WHERE " + RawContacts.ACCOUNT_TYPE + "=?"
- + " AND " + RawContacts.ACCOUNT_NAME + "=?)");
+ + " AND " + RawContacts.ACCOUNT_NAME + "=?");
selectionArgs.add(filter.accountType);
selectionArgs.add(filter.accountName);
+ if (filter.dataSet != null) {
+ selection.append(" AND " + RawContacts.DATA_SET + "=?)");
+ selectionArgs.add(filter.dataSet);
+ } else {
+ selection.append(" AND " + RawContacts.DATA_SET + " IS NULL)");
+ }
break;
}
case ContactListFilter.FILTER_TYPE_GROUP: {
diff --git a/src/com/android/contacts/model/AccountType.java b/src/com/android/contacts/model/AccountType.java
index 608fca3..59b9f45 100644
--- a/src/com/android/contacts/model/AccountType.java
+++ b/src/com/android/contacts/model/AccountType.java
@@ -38,6 +38,7 @@
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
+import java.util.List;
/**
* Internal structure that represents constraints and styles for a specific data
@@ -49,12 +50,19 @@
public abstract class AccountType {
private static final String TAG = "AccountType";
+ private static final String ACCOUNT_TYPE_DATA_SET_DELIMITER = "/";
+
/**
* The {@link RawContacts#ACCOUNT_TYPE} these constraints apply to.
*/
public String accountType = null;
/**
+ * The {@link RawContacts#DATA_SET} these constraints apply to.
+ */
+ public String dataSet = null;
+
+ /**
* Package that resources should be loaded from, either defined through an
* {@link Account} or for matching against {@link Data#RES_PACKAGE}.
*/
@@ -116,6 +124,34 @@
}
/**
+ * Returns the account type with the data set (if any) appended after a delimiter.
+ * If the data set is null, this will simply return the account type.
+ */
+ public String getAccountTypeAndDataSet() {
+ return getAccountTypeAndDataSet(accountType, dataSet);
+ }
+
+ /**
+ * Utility method to concatenate the given account type with a data set with a delimiter.
+ * If the data set is null, this will simply return the account type.
+ */
+ public static String getAccountTypeAndDataSet(String accountType, String dataSet) {
+ return dataSet == null
+ ? accountType
+ : accountType + ACCOUNT_TYPE_DATA_SET_DELIMITER + dataSet;
+ }
+
+ /**
+ * Returns a list of additional package names that should be inspected as additional
+ * external account types. This allows for a primary account type to indicate other packages
+ * that may not be sync adapters but which still provide contact data, perhaps under a
+ * separate data set within the account.
+ */
+ public List<String> getExtensionPackageNames() {
+ return new ArrayList<String>();
+ }
+
+ /**
* Returns an optional custom label for the "invite contact" action, which will be shown on
* the contact card. (If not defined, returns null.)
*/
@@ -186,7 +222,7 @@
/**
* Find the {@link DataKind} for a specific MIME-type, if it's handled by
* this data source. If you may need a fallback {@link DataKind}, use
- * {@link AccountTypeManager#getKindOrFallback(String, String)}.
+ * {@link AccountTypeManager#getKindOrFallback(String, String, String)}.
*/
public DataKind getKindForMimetype(String mimeType) {
return this.mMimeKinds.get(mimeType);
diff --git a/src/com/android/contacts/model/AccountTypeManager.java b/src/com/android/contacts/model/AccountTypeManager.java
index ea2568f..7232a26 100644
--- a/src/com/android/contacts/model/AccountTypeManager.java
+++ b/src/com/android/contacts/model/AccountTypeManager.java
@@ -16,8 +16,10 @@
package com.android.contacts.model;
+import com.android.internal.util.Objects;
import com.google.android.collect.Lists;
import com.google.android.collect.Maps;
+import com.google.android.collect.Sets;
import com.google.common.annotations.VisibleForTesting;
import com.google.i18n.phonenumbers.PhoneNumberUtil;
@@ -43,13 +45,14 @@
import android.text.TextUtils;
import android.util.Log;
-import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
+import java.util.List;
import java.util.Locale;
import java.util.Map;
+import java.util.Set;
import java.util.concurrent.CountDownLatch;
/**
@@ -79,9 +82,9 @@
return new AccountTypeManagerImpl(context);
}
- public abstract ArrayList<Account> getAccounts(boolean writableOnly);
+ public abstract List<AccountWithDataSet> getAccounts(boolean writableOnly);
- public abstract AccountType getAccountType(String accountType);
+ public abstract AccountType getAccountType(String accountType, String dataSet);
/**
* @return Unmodifiable map from account type strings to {@link AccountType}s which support
@@ -91,11 +94,11 @@
/**
* Find the best {@link DataKind} matching the requested
- * {@link AccountType#accountType} and {@link DataKind#mimeType}. If no
- * direct match found, we try searching {@link FallbackAccountType}.
+ * {@link AccountType#accountType}, {@link AccountType#dataSet}, and {@link DataKind#mimeType}.
+ * If no direct match found, we try searching {@link FallbackAccountType}.
*/
- public DataKind getKindOrFallback(String accountType, String mimeType) {
- final AccountType type = getAccountType(accountType);
+ public DataKind getKindOrFallback(String accountType, String dataSet, String mimeType) {
+ final AccountType type = getAccountType(accountType, dataSet);
return type == null ? null : type.getKindForMimetype(mimeType);
}
}
@@ -108,9 +111,9 @@
private AccountType mFallbackAccountType;
- private ArrayList<Account> mAccounts = Lists.newArrayList();
- private ArrayList<Account> mWritableAccounts = Lists.newArrayList();
- private HashMap<String, AccountType> mAccountTypes = Maps.newHashMap();
+ private List<AccountWithDataSet> mAccounts = Lists.newArrayList();
+ private List<AccountWithDataSet> mWritableAccounts = Lists.newArrayList();
+ private Map<String, AccountType> mAccountTypesWithDataSets = Maps.newHashMap();
private Map<String, AccountType> mInvitableAccountTypes = Collections.unmodifiableMap(
new HashMap<String, AccountType>());
@@ -134,14 +137,41 @@
private volatile CountDownLatch mInitializationLatch = new CountDownLatch(1);
private static final Comparator<Account> ACCOUNT_COMPARATOR = new Comparator<Account>() {
-
@Override
- public int compare(Account account1, Account account2) {
- int diff = account1.name.compareTo(account2.name);
- if (diff != 0) {
- return diff;
+ public int compare(Account a, Account b) {
+ String aDataSet = null;
+ String bDataSet = null;
+ if (a instanceof AccountWithDataSet) {
+ aDataSet = ((AccountWithDataSet) a).dataSet;
}
- return account1.type.compareTo(account2.type);
+ if (b instanceof AccountWithDataSet) {
+ bDataSet = ((AccountWithDataSet) b).dataSet;
+ }
+
+ if (Objects.equal(a.name, b.name) && Objects.equal(a.type, b.type)
+ && Objects.equal(aDataSet, bDataSet)) {
+ return 0;
+ } else if (b.name == null || b.type == null) {
+ return -1;
+ } else if (a.name == null || a.type == null) {
+ return 1;
+ } else {
+ int diff = a.name.compareTo(b.name);
+ if (diff != 0) {
+ return diff;
+ }
+ diff = a.type.compareTo(b.type);
+ if (diff != 0) {
+ return diff;
+ }
+
+ // Accounts without data sets get sorted before those that have them.
+ if (aDataSet != null) {
+ return bDataSet == null ? 1 : aDataSet.compareTo(bDataSet);
+ } else {
+ return -1;
+ }
+ }
}
};
@@ -228,15 +258,23 @@
}
/**
- * Loads account list and corresponding account types. Always called on a
- * background thread.
+ * Loads account list and corresponding account types (potentially with data sets). Always
+ * called on a background thread.
*/
protected void loadAccountsInBackground() {
long startTime = SystemClock.currentThreadTimeMillis();
- HashMap<String, AccountType> accountTypes = Maps.newHashMap();
- ArrayList<Account> allAccounts = Lists.newArrayList();
- ArrayList<Account> writableAccounts = Lists.newArrayList();
+ // Account types, keyed off the account type and data set concatenation.
+ Map<String, AccountType> accountTypesByTypeAndDataSet = Maps.newHashMap();
+
+ // The same AccountTypes, but keyed off {@link RawContacts#ACCOUNT_TYPE}. Since there can
+ // be multiple account types (with different data sets) for the same type of account, each
+ // type string may have multiple AccountType entries.
+ Map<String, List<AccountType>> accountTypesByType = Maps.newHashMap();
+
+ List<AccountWithDataSet> allAccounts = Lists.newArrayList();
+ List<AccountWithDataSet> writableAccounts = Lists.newArrayList();
+ Set<String> extensionPackages = Sets.newHashSet();
final AccountManager am = mAccountManager;
final IContentService cs = ContentResolver.getContentService();
@@ -245,6 +283,7 @@
final SyncAdapterType[] syncs = cs.getSyncAdapterTypes();
final AuthenticatorDescription[] auths = am.getAuthenticatorTypes();
+ // First process sync adapters to find any that provide contact data.
for (SyncAdapterType sync : syncs) {
if (!ContactsContract.AUTHORITY.equals(sync.authority)) {
// Skip sync adapters that don't provide contact data.
@@ -277,31 +316,52 @@
accountType.titleRes = auth.labelId;
accountType.iconRes = auth.iconId;
- accountTypes.put(accountType.accountType, accountType);
+ addAccountType(accountType, accountTypesByTypeAndDataSet, accountTypesByType);
+
+ // Check to see if the account type knows of any other non-sync-adapter packages
+ // that may provide other data sets of contact data.
+ extensionPackages.addAll(accountType.getExtensionPackageNames());
+ }
+
+ // If any extension packages were specified, process them as well.
+ if (!extensionPackages.isEmpty()) {
+ Log.d(TAG, "Registering " + extensionPackages.size() + " extension packages");
+ for (String extensionPackage : extensionPackages) {
+ ExternalAccountType accountType =
+ new ExternalAccountType(mContext, extensionPackage);
+ Log.d(TAG, "Registering extension package account type="
+ + accountType.accountType + ", dataSet=" + accountType.dataSet
+ + ", packageName=" + extensionPackage);
+
+ addAccountType(accountType, accountTypesByTypeAndDataSet, accountTypesByType);
+ }
}
} catch (RemoteException e) {
Log.w(TAG, "Problem loading accounts: " + e.toString());
}
+ // Map in accounts to associate the account names with each account type entry.
Account[] accounts = mAccountManager.getAccounts();
for (Account account : accounts) {
boolean syncable = false;
try {
- int isSyncable = cs.getIsSyncable(account, ContactsContract.AUTHORITY);
- if (isSyncable > 0) {
- syncable = true;
- }
+ syncable = cs.getIsSyncable(account, ContactsContract.AUTHORITY) > 0;
} catch (RemoteException e) {
Log.e(TAG, "Cannot obtain sync flag for account: " + account, e);
}
if (syncable) {
- // Ensure we have details loaded for each account
- final AccountType accountType = accountTypes.get(account.type);
- if (accountType != null) {
- allAccounts.add(account);
- if (!accountType.readOnly) {
- writableAccounts.add(account);
+ List<AccountType> accountTypes = accountTypesByType.get(account.type);
+ if (accountTypes != null) {
+ // Add an account-with-data-set entry for each account type that is
+ // authenticated by this account.
+ for (AccountType accountType : accountTypes) {
+ AccountWithDataSet accountWithDataSet = new AccountWithDataSet(
+ account.name, account.type, accountType.dataSet);
+ allAccounts.add(accountWithDataSet);
+ if (!accountType.readOnly) {
+ writableAccounts.add(accountWithDataSet);
+ }
}
}
}
@@ -317,13 +377,14 @@
long endTime = SystemClock.currentThreadTimeMillis();
synchronized (this) {
- mAccountTypes = accountTypes;
+ mAccountTypesWithDataSets = accountTypesByTypeAndDataSet;
mAccounts = allAccounts;
mWritableAccounts = writableAccounts;
- mInvitableAccountTypes = findInvitableAccountTypes(mContext, allAccounts, accountTypes);
+ mInvitableAccountTypes = findInvitableAccountTypes(
+ mContext, allAccounts, accountTypesByTypeAndDataSet);
}
- Log.i(TAG, "Loaded meta-data for " + mAccountTypes.size() + " account types, "
+ Log.i(TAG, "Loaded meta-data for " + mAccountTypesWithDataSets.size() + " account types, "
+ mAccounts.size() + " accounts in " + (endTime - startTime) + "ms");
if (mInitializationLatch != null) {
@@ -332,6 +393,19 @@
}
}
+ // Bookkeeping method for tracking the known account types in the given maps.
+ private void addAccountType(AccountType accountType,
+ Map<String, AccountType> accountTypesByTypeAndDataSet,
+ Map<String, List<AccountType>> accountTypesByType) {
+ accountTypesByTypeAndDataSet.put(accountType.getAccountTypeAndDataSet(), accountType);
+ List<AccountType> accountsForType = accountTypesByType.get(accountType.accountType);
+ if (accountsForType == null) {
+ accountsForType = Lists.newArrayList();
+ }
+ accountsForType.add(accountType);
+ accountTypesByType.put(accountType.accountType, accountsForType);
+ }
+
/**
* Find a specific {@link AuthenticatorDescription} in the provided list
* that matches the given account type.
@@ -347,26 +421,27 @@
}
/**
- * Return list of all known, writable {@link Account}'s.
+ * Return list of all known, writable {@link AccountWithDataSet}'s.
*/
@Override
- public ArrayList<Account> getAccounts(boolean writableOnly) {
+ public List<AccountWithDataSet> getAccounts(boolean writableOnly) {
ensureAccountsLoaded();
return writableOnly ? mWritableAccounts : mAccounts;
}
/**
* Find the best {@link DataKind} matching the requested
- * {@link AccountType#accountType} and {@link DataKind#mimeType}. If no
- * direct match found, we try searching {@link FallbackAccountType}.
+ * {@link AccountType#accountType}, {@link AccountType#dataSet}, and {@link DataKind#mimeType}.
+ * If no direct match found, we try searching {@link FallbackAccountType}.
*/
@Override
- public DataKind getKindOrFallback(String accountType, String mimeType) {
+ public DataKind getKindOrFallback(String accountType, String dataSet, String mimeType) {
ensureAccountsLoaded();
DataKind kind = null;
// Try finding account type and kind matching request
- final AccountType type = mAccountTypes.get(accountType);
+ final AccountType type = mAccountTypesWithDataSets.get(
+ AccountType.getAccountTypeAndDataSet(accountType, dataSet));
if (type != null) {
kind = type.getKindForMimetype(mimeType);
}
@@ -384,13 +459,14 @@
}
/**
- * Return {@link AccountType} for the given account type.
+ * Return {@link AccountType} for the given account type and data set.
*/
@Override
- public AccountType getAccountType(String accountType) {
+ public AccountType getAccountType(String accountType, String dataSet) {
ensureAccountsLoaded();
synchronized (this) {
- AccountType type = mAccountTypes.get(accountType);
+ AccountType type = mAccountTypesWithDataSets.get(
+ AccountType.getAccountTypeAndDataSet(accountType, dataSet));
return type != null ? type : mFallbackAccountType;
}
}
@@ -406,20 +482,23 @@
*/
@VisibleForTesting
static Map<String, AccountType> findInvitableAccountTypes(Context context,
- Collection<Account> accounts, Map<String, AccountType> accountTypes) {
+ Collection<AccountWithDataSet> accounts,
+ Map<String, AccountType> accountTypesByTypeAndDataSet) {
HashMap<String, AccountType> result = Maps.newHashMap();
- for (Account account : accounts) {
- AccountType type = accountTypes.get(account.type);
+ for (AccountWithDataSet account : accounts) {
+ String accountTypeWithDataSet = account.getAccountTypeWithDataSet();
+ AccountType type = accountTypesByTypeAndDataSet.get(
+ account.getAccountTypeWithDataSet());
if (type == null) continue; // just in case
- if (result.containsKey(type.accountType)) continue;
+ if (result.containsKey(accountTypeWithDataSet)) continue;
if (Log.isLoggable(TAG, Log.DEBUG)) {
- Log.d(TAG, "Type " + type.accountType
+ Log.d(TAG, "Type " + accountTypeWithDataSet
+ " inviteClass=" + type.getInviteContactActivityClassName()
+ " inviteAction=" + type.getInviteContactActionLabel(context));
}
if (!TextUtils.isEmpty(type.getInviteContactActivityClassName())) {
- result.put(type.accountType, type);
+ result.put(accountTypeWithDataSet, type);
}
}
return Collections.unmodifiableMap(result);
diff --git a/src/com/android/contacts/model/AccountWithDataSet.java b/src/com/android/contacts/model/AccountWithDataSet.java
new file mode 100644
index 0000000..1d97614
--- /dev/null
+++ b/src/com/android/contacts/model/AccountWithDataSet.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.contacts.model;
+
+import com.android.internal.util.Objects;
+
+import android.accounts.Account;
+import android.os.Parcel;
+
+/**
+ * Wrapper for an account that includes a data set (which may be null).
+ */
+public class AccountWithDataSet extends Account {
+
+ public final String dataSet;
+
+ public AccountWithDataSet(String name, String type, String dataSet) {
+ super(name, type);
+ this.dataSet = dataSet;
+ }
+
+ public AccountWithDataSet(Parcel in, String dataSet) {
+ super(in);
+ this.dataSet = dataSet;
+ }
+
+ public String getAccountTypeWithDataSet() {
+ return dataSet == null ? type : AccountType.getAccountTypeAndDataSet(type, dataSet);
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ return (o instanceof AccountWithDataSet) && super.equals(o)
+ && Objects.equal(((AccountWithDataSet) o).dataSet, dataSet);
+ }
+
+ @Override
+ public int hashCode() {
+ return 31 * super.hashCode()
+ + (dataSet == null ? 0 : dataSet.hashCode());
+ }
+
+ @Override
+ public String toString() {
+ return "AccountWithDataSet {name=" + name + ", type=" + type + ", dataSet=" + dataSet + "}";
+ }
+}
diff --git a/src/com/android/contacts/model/BaseAccountType.java b/src/com/android/contacts/model/BaseAccountType.java
index c627c80..aca2d3c 100644
--- a/src/com/android/contacts/model/BaseAccountType.java
+++ b/src/com/android/contacts/model/BaseAccountType.java
@@ -64,6 +64,7 @@
public BaseAccountType() {
this.accountType = null;
+ this.dataSet = null;
this.titleRes = R.string.account_phone;
this.iconRes = R.mipmap.ic_launcher_contacts;
}
diff --git a/src/com/android/contacts/model/EntityModifier.java b/src/com/android/contacts/model/EntityModifier.java
index fb05162..fdac645 100644
--- a/src/com/android/contacts/model/EntityModifier.java
+++ b/src/com/android/contacts/model/EntityModifier.java
@@ -378,8 +378,10 @@
*/
public static void trimEmpty(EntityDeltaList set, AccountTypeManager accountTypes) {
for (EntityDelta state : set) {
- final String accountType = state.getValues().getAsString(RawContacts.ACCOUNT_TYPE);
- final AccountType type = accountTypes.getAccountType(accountType);
+ ValuesDelta values = state.getValues();
+ final String accountType = values.getAsString(RawContacts.ACCOUNT_TYPE);
+ final String dataSet = values.getAsString(RawContacts.DATA_SET);
+ final AccountType type = accountTypes.getAccountType(accountType, dataSet);
trimEmpty(state, type);
}
}
@@ -390,8 +392,10 @@
}
for (EntityDelta state : set) {
- final String accountType = state.getValues().getAsString(RawContacts.ACCOUNT_TYPE);
- final AccountType type = accountTypes.getAccountType(accountType);
+ ValuesDelta values = state.getValues();
+ final String accountType = values.getAsString(RawContacts.ACCOUNT_TYPE);
+ final String dataSet = values.getAsString(RawContacts.DATA_SET);
+ final AccountType type = accountTypes.getAccountType(accountType, dataSet);
if (hasChanges(state, type)) {
return true;
}
@@ -678,8 +682,8 @@
DataKind kind = accountType.getKindForMimetype(mimeType);
if (kind == null) {
- Log.e(TAG, "Mimetype not supported for account type " + accountType.accountType
- + ". Ignoring: " + values);
+ Log.e(TAG, "Mimetype not supported for account type "
+ + accountType.getAccountTypeAndDataSet() + ". Ignoring: " + values);
continue;
}
diff --git a/src/com/android/contacts/model/ExternalAccountType.java b/src/com/android/contacts/model/ExternalAccountType.java
index 4e6add0..caf311b 100644
--- a/src/com/android/contacts/model/ExternalAccountType.java
+++ b/src/com/android/contacts/model/ExternalAccountType.java
@@ -36,6 +36,7 @@
import android.util.Xml;
import java.io.IOException;
+import java.util.ArrayList;
import java.util.List;
/**
@@ -55,12 +56,24 @@
private static final String ATTR_CREATE_CONTACT_ACTIVITY = "createContactActivity";
private static final String ATTR_INVITE_CONTACT_ACTIVITY = "inviteContactActivity";
private static final String ATTR_INVITE_CONTACT_ACTION_LABEL = "inviteContactActionLabel";
+ private static final String ATTR_DATA_SET = "dataSet";
+ private static final String ATTR_EXTENSION_PACKAGE_NAMES = "extensionPackageNames";
+
+ // The following attributes should only be set in non-sync-adapter account types. They allow
+ // for the account type and resource IDs to be specified without an associated authenticator.
+ private static final String ATTR_ACCOUNT_TYPE = "accountType";
+ private static final String ATTR_READ_ONLY = "readOnly";
+ private static final String ATTR_ACCOUNT_LABEL = "accountTypeLabel";
+ private static final String ATTR_ACCOUNT_ICON = "accountTypeIcon";
private String mEditContactActivityClassName;
private String mCreateContactActivityClassName;
private String mInviteContactActivity;
private String mInviteActionLabelAttribute;
+ private List<String> mExtensionPackageNames;
private int mInviteActionLabelResId;
+ private String mAccountTypeLabelAttribute;
+ private String mAccountTypeIconAttribute;
public ExternalAccountType(Context context, String resPackageName) {
this.resPackageName = resPackageName;
@@ -81,8 +94,13 @@
}
}
+ mExtensionPackageNames = new ArrayList<String>();
mInviteActionLabelResId = resolveExternalResId(context, mInviteActionLabelAttribute,
summaryResPackageName, ATTR_INVITE_CONTACT_ACTION_LABEL);
+ titleRes = resolveExternalResId(context, mAccountTypeLabelAttribute,
+ this.resPackageName, ATTR_ACCOUNT_LABEL);
+ iconRes = resolveExternalResId(context, mAccountTypeIconAttribute,
+ this.resPackageName, ATTR_ACCOUNT_ICON);
// Bring in name and photo from fallback source, which are non-optional
addDataKindStructuredName(context);
@@ -116,6 +134,11 @@
return mInviteActionLabelResId;
}
+ @Override
+ public List<String> getExtensionPackageNames() {
+ return mExtensionPackageNames;
+ }
+
/**
* Inflate this {@link AccountType} from the given parser. This may only
* load details matching the publicly-defined schema.
@@ -156,6 +179,18 @@
mInviteContactActivity = value;
} else if (ATTR_INVITE_CONTACT_ACTION_LABEL.equals(attr)) {
mInviteActionLabelAttribute = value;
+ } else if (ATTR_DATA_SET.equals(attr)) {
+ dataSet = value;
+ } else if (ATTR_EXTENSION_PACKAGE_NAMES.equals(attr)) {
+ mExtensionPackageNames.add(value);
+ } else if (ATTR_ACCOUNT_TYPE.equals(attr)) {
+ accountType = value;
+ } else if (ATTR_READ_ONLY.equals(attr)) {
+ readOnly = !"0".equals(value) && !"false".equals(value);
+ } else if (ATTR_ACCOUNT_LABEL.equals(attr)) {
+ mAccountTypeLabelAttribute = value;
+ } else if (ATTR_ACCOUNT_ICON.equals(attr)) {
+ mAccountTypeIconAttribute = value;
} else {
Log.e(TAG, "Unsupported attribute " + attr);
}
diff --git a/src/com/android/contacts/model/FallbackAccountType.java b/src/com/android/contacts/model/FallbackAccountType.java
index 13540be..8bb3992 100644
--- a/src/com/android/contacts/model/FallbackAccountType.java
+++ b/src/com/android/contacts/model/FallbackAccountType.java
@@ -24,6 +24,7 @@
public FallbackAccountType(Context context) {
this.accountType = null;
+ this.dataSet = null;
this.titleRes = R.string.account_phone;
this.iconRes = R.mipmap.ic_launcher_contacts;
diff --git a/src/com/android/contacts/model/GoogleAccountType.java b/src/com/android/contacts/model/GoogleAccountType.java
index fd0eea4..c3dbd79 100644
--- a/src/com/android/contacts/model/GoogleAccountType.java
+++ b/src/com/android/contacts/model/GoogleAccountType.java
@@ -28,6 +28,8 @@
import android.provider.ContactsContract.CommonDataKinds.Relation;
import android.view.inputmethod.EditorInfo;
+import java.util.List;
+
public class GoogleAccountType extends BaseAccountType {
public static final String ACCOUNT_TYPE = "com.google";
protected static final int FLAGS_RELATION = EditorInfo.TYPE_CLASS_TEXT
@@ -57,6 +59,12 @@
}
@Override
+ public List<String> getExtensionPackageNames() {
+ // TODO: Return the Google+ package name once it has the XML for an ExternalAccountType.
+ return super.getExtensionPackageNames();
+ }
+
+ @Override
protected DataKind addDataKindPhone(Context context) {
final DataKind kind = super.addDataKindPhone(context);
diff --git a/src/com/android/contacts/quickcontact/QuickContactActivity.java b/src/com/android/contacts/quickcontact/QuickContactActivity.java
index 933b966..47e7173 100644
--- a/src/com/android/contacts/quickcontact/QuickContactActivity.java
+++ b/src/com/android/contacts/quickcontact/QuickContactActivity.java
@@ -383,6 +383,7 @@
final long dataId = cursor.getLong(DataQuery._ID);
final String accountType = cursor.getString(DataQuery.ACCOUNT_TYPE);
+ final String dataSet = cursor.getString(DataQuery.DATA_SET);
final boolean isPrimary = cursor.getInt(DataQuery.IS_PRIMARY) != 0;
final boolean isSuperPrimary = cursor.getInt(DataQuery.IS_SUPER_PRIMARY) != 0;
@@ -424,7 +425,7 @@
continue;
}
- final DataKind kind = accountTypes.getKindOrFallback(accountType, mimeType);
+ final DataKind kind = accountTypes.getKindOrFallback(accountType, dataSet, mimeType);
if (kind != null) {
// Build an action for this data entry, find a mapping to a UI
@@ -445,7 +446,7 @@
// Handle Email rows with presence data as Im entry
final boolean hasPresence = !cursor.isNull(DataQuery.PRESENCE);
if (hasPresence && Email.CONTENT_ITEM_TYPE.equals(mimeType)) {
- final DataKind imKind = accountTypes.getKindOrFallback(accountType,
+ final DataKind imKind = accountTypes.getKindOrFallback(accountType, dataSet,
Im.CONTENT_ITEM_TYPE);
if (imKind != null) {
final DataAction action = new DataAction(context, Im.CONTENT_ITEM_TYPE, imKind,
@@ -458,7 +459,7 @@
if (hasPresence && isIm) {
int chatCapability = cursor.getInt(DataQuery.CHAT_CAPABILITY);
if ((chatCapability & Im.CAPABILITY_HAS_CAMERA) != 0) {
- final DataKind imKind = accountTypes.getKindOrFallback(accountType,
+ final DataKind imKind = accountTypes.getKindOrFallback(accountType, dataSet,
Im.CONTENT_ITEM_TYPE);
if (imKind != null) {
final DataAction chatAction = new DataAction(context,
@@ -674,6 +675,7 @@
Data._ID,
RawContacts.ACCOUNT_TYPE,
+ RawContacts.DATA_SET,
Contacts.STARRED,
Contacts.DISPLAY_NAME,
Contacts.CONTACT_PRESENCE,
@@ -701,22 +703,23 @@
final int _ID = 0;
final int ACCOUNT_TYPE = 1;
- final int STARRED = 2;
- final int DISPLAY_NAME = 3;
- final int CONTACT_PRESENCE = 4;
- final int CONTACT_CHAT_CAPABILITY = 5;
+ final int DATA_SET = 2;
+ final int STARRED = 3;
+ final int DISPLAY_NAME = 4;
+ final int CONTACT_PRESENCE = 5;
+ final int CONTACT_CHAT_CAPABILITY = 6;
- final int STATUS = 6;
- final int STATUS_RES_PACKAGE = 7;
- final int STATUS_ICON = 8;
- final int STATUS_LABEL = 9;
- final int STATUS_TIMESTAMP = 10;
- final int PRESENCE = 11;
- final int CHAT_CAPABILITY = 12;
+ final int STATUS = 7;
+ final int STATUS_RES_PACKAGE = 8;
+ final int STATUS_ICON = 9;
+ final int STATUS_LABEL = 10;
+ final int STATUS_TIMESTAMP = 11;
+ final int PRESENCE = 12;
+ final int CHAT_CAPABILITY = 13;
- final int RES_PACKAGE = 13;
- final int MIMETYPE = 14;
- final int IS_PRIMARY = 15;
- final int IS_SUPER_PRIMARY = 16;
+ final int RES_PACKAGE = 14;
+ final int MIMETYPE = 15;
+ final int IS_PRIMARY = 16;
+ final int IS_SUPER_PRIMARY = 17;
}
}
diff --git a/src/com/android/contacts/util/AccountSelectionUtil.java b/src/com/android/contacts/util/AccountSelectionUtil.java
index 46d20b8..7317d21 100644
--- a/src/com/android/contacts/util/AccountSelectionUtil.java
+++ b/src/com/android/contacts/util/AccountSelectionUtil.java
@@ -16,7 +16,11 @@
package com.android.contacts.util;
-import android.accounts.Account;
+import com.android.contacts.R;
+import com.android.contacts.model.AccountType;
+import com.android.contacts.model.AccountTypeManager;
+import com.android.contacts.model.AccountWithDataSet;
+
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.Context;
@@ -31,10 +35,6 @@
import android.widget.ArrayAdapter;
import android.widget.TextView;
-import com.android.contacts.R;
-import com.android.contacts.model.AccountType;
-import com.android.contacts.model.AccountTypeManager;
-
import java.util.List;
/**
@@ -54,9 +54,10 @@
final private Context mContext;
final private int mResId;
- final protected List<Account> mAccountList;
+ final protected List<AccountWithDataSet> mAccountList;
- public AccountSelectedListener(Context context, List<Account> accountList, int resId) {
+ public AccountSelectedListener(Context context, List<AccountWithDataSet> accountList,
+ int resId) {
if (accountList == null || accountList.size() == 0) {
Log.e(LOG_TAG, "The size of Account list is 0.");
}
@@ -88,7 +89,7 @@
DialogInterface.OnClickListener onClickListener,
DialogInterface.OnCancelListener onCancelListener) {
final AccountTypeManager accountTypes = AccountTypeManager.getInstance(context);
- final List<Account> writableAccountList = accountTypes.getAccounts(true);
+ final List<AccountWithDataSet> writableAccountList = accountTypes.getAccounts(true);
Log.i(LOG_TAG, "The number of available accounts: " + writableAccountList.size());
@@ -99,8 +100,8 @@
context, android.R.style.Theme_Light);
final LayoutInflater dialogInflater = (LayoutInflater)dialogContext
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
- final ArrayAdapter<Account> accountAdapter =
- new ArrayAdapter<Account>(context, android.R.layout.simple_list_item_2,
+ final ArrayAdapter<AccountWithDataSet> accountAdapter =
+ new ArrayAdapter<AccountWithDataSet>(context, android.R.layout.simple_list_item_2,
writableAccountList) {
@Override
@@ -117,8 +118,9 @@
final TextView text2 =
(TextView)convertView.findViewById(android.R.id.text2);
- final Account account = this.getItem(position);
- final AccountType accountType = accountTypes.getAccountType(account.type);
+ final AccountWithDataSet account = this.getItem(position);
+ final AccountType accountType = accountTypes.getAccountType(
+ account.type, account.dataSet);
final Context context = getContext();
text1.setText(account.name);
@@ -147,7 +149,7 @@
.create();
}
- public static void doImport(Context context, int resId, Account account) {
+ public static void doImport(Context context, int resId, AccountWithDataSet account) {
switch (resId) {
case R.string.import_from_sim: {
doImportFromSim(context, account);
@@ -160,23 +162,25 @@
}
}
- public static void doImportFromSim(Context context, Account account) {
+ public static void doImportFromSim(Context context, AccountWithDataSet account) {
Intent importIntent = new Intent(Intent.ACTION_VIEW);
importIntent.setType("vnd.android.cursor.item/sim-contact");
if (account != null) {
importIntent.putExtra("account_name", account.name);
importIntent.putExtra("account_type", account.type);
+ importIntent.putExtra("data_set", account.dataSet);
}
importIntent.setClassName("com.android.phone", "com.android.phone.SimContacts");
context.startActivity(importIntent);
}
- public static void doImportFromSdCard(Context context, Account account) {
+ public static void doImportFromSdCard(Context context, AccountWithDataSet account) {
Intent importIntent = new Intent(context,
com.android.contacts.vcard.ImportVCardActivity.class);
if (account != null) {
importIntent.putExtra("account_name", account.name);
importIntent.putExtra("account_type", account.type);
+ importIntent.putExtra("data_set", account.dataSet);
}
if (mVCardShare) {
diff --git a/src/com/android/contacts/util/AccountsListAdapter.java b/src/com/android/contacts/util/AccountsListAdapter.java
index 5448d1d..d065255 100644
--- a/src/com/android/contacts/util/AccountsListAdapter.java
+++ b/src/com/android/contacts/util/AccountsListAdapter.java
@@ -19,8 +19,8 @@
import com.android.contacts.R;
import com.android.contacts.model.AccountType;
import com.android.contacts.model.AccountTypeManager;
+import com.android.contacts.model.AccountWithDataSet;
-import android.accounts.Account;
import android.content.Context;
import android.text.TextUtils.TruncateAt;
import android.view.LayoutInflater;
@@ -38,7 +38,7 @@
*/
public final class AccountsListAdapter extends BaseAdapter {
private final LayoutInflater mInflater;
- private final List<Account> mAccounts;
+ private final List<AccountWithDataSet> mAccounts;
private final AccountTypeManager mAccountTypes;
private final Context mContext;
@@ -51,11 +51,11 @@
* first in the list. Can be null.
*/
public AccountsListAdapter(Context context, boolean writableOnly,
- Account currentAccount) {
+ AccountWithDataSet currentAccount) {
mContext = context;
mAccountTypes = AccountTypeManager.getInstance(context);
// We don't want possible side-effect toward AccountTypeManager
- mAccounts = new ArrayList<Account>(mAccountTypes.getAccounts(writableOnly));
+ mAccounts = new ArrayList<AccountWithDataSet>(mAccountTypes.getAccounts(writableOnly));
if (currentAccount != null
&& !mAccounts.isEmpty()
&& !mAccounts.get(0).equals(currentAccount)
@@ -74,8 +74,8 @@
final TextView text2 = (TextView)resultView.findViewById(android.R.id.text2);
final ImageView icon = (ImageView)resultView.findViewById(android.R.id.icon);
- final Account account = mAccounts.get(position);
- final AccountType accountType = mAccountTypes.getAccountType(account.type);
+ final AccountWithDataSet account = mAccounts.get(position);
+ final AccountType accountType = mAccountTypes.getAccountType(account.type, account.dataSet);
text1.setText(account.name);
@@ -94,7 +94,7 @@
}
@Override
- public Account getItem(int position) {
+ public AccountWithDataSet getItem(int position) {
return mAccounts.get(position);
}
diff --git a/src/com/android/contacts/vcard/ImportVCardActivity.java b/src/com/android/contacts/vcard/ImportVCardActivity.java
index 0b84440..28b8540 100644
--- a/src/com/android/contacts/vcard/ImportVCardActivity.java
+++ b/src/com/android/contacts/vcard/ImportVCardActivity.java
@@ -19,6 +19,7 @@
import com.android.contacts.ContactsActivity;
import com.android.contacts.R;
import com.android.contacts.model.AccountTypeManager;
+import com.android.contacts.model.AccountWithDataSet;
import com.android.contacts.util.AccountSelectionUtil;
import com.android.vcard.VCardEntryCounter;
import com.android.vcard.VCardParser;
@@ -29,7 +30,6 @@
import com.android.vcard.exception.VCardNestedException;
import com.android.vcard.exception.VCardVersionException;
-import android.accounts.Account;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
@@ -118,7 +118,7 @@
private AccountSelectionUtil.AccountSelectedListener mAccountSelectionListener;
- private Account mAccount;
+ private AccountWithDataSet mAccount;
private ProgressDialog mProgressDialogForScanVCard;
private ProgressDialog mProgressDialogForCachingVCard;
@@ -839,19 +839,21 @@
String accountName = null;
String accountType = null;
+ String dataSet = null;
final Intent intent = getIntent();
if (intent != null) {
accountName = intent.getStringExtra(SelectAccountActivity.ACCOUNT_NAME);
accountType = intent.getStringExtra(SelectAccountActivity.ACCOUNT_TYPE);
+ dataSet = intent.getStringExtra(SelectAccountActivity.DATA_SET);
} else {
Log.e(LOG_TAG, "intent does not exist");
}
if (!TextUtils.isEmpty(accountName) && !TextUtils.isEmpty(accountType)) {
- mAccount = new Account(accountName, accountType);
+ mAccount = new AccountWithDataSet(accountName, accountType, dataSet);
} else {
final AccountTypeManager accountTypes = AccountTypeManager.getInstance(this);
- final List<Account> accountList = accountTypes.getAccounts(true);
+ final List<AccountWithDataSet> accountList = accountTypes.getAccounts(true);
if (accountList.size() == 0) {
mAccount = null;
} else if (accountList.size() == 1) {
@@ -870,9 +872,10 @@
public void onActivityResult(int requestCode, int resultCode, Intent intent) {
if (requestCode == SELECT_ACCOUNT) {
if (resultCode == RESULT_OK) {
- mAccount = new Account(
+ mAccount = new AccountWithDataSet(
intent.getStringExtra(SelectAccountActivity.ACCOUNT_NAME),
- intent.getStringExtra(SelectAccountActivity.ACCOUNT_TYPE));
+ intent.getStringExtra(SelectAccountActivity.ACCOUNT_TYPE),
+ intent.getStringExtra(SelectAccountActivity.DATA_SET));
startImport();
} else {
if (resultCode != RESULT_CANCELED) {
diff --git a/src/com/android/contacts/vcard/SelectAccountActivity.java b/src/com/android/contacts/vcard/SelectAccountActivity.java
index 5f8aa28..f27331e 100644
--- a/src/com/android/contacts/vcard/SelectAccountActivity.java
+++ b/src/com/android/contacts/vcard/SelectAccountActivity.java
@@ -18,9 +18,9 @@
import com.android.contacts.ContactsActivity;
import com.android.contacts.R;
import com.android.contacts.model.AccountTypeManager;
+import com.android.contacts.model.AccountWithDataSet;
import com.android.contacts.util.AccountSelectionUtil;
-import android.accounts.Account;
import android.app.Dialog;
import android.content.DialogInterface;
import android.content.Intent;
@@ -34,6 +34,7 @@
public static final String ACCOUNT_NAME = "account_name";
public static final String ACCOUNT_TYPE = "account_type";
+ public static final String DATA_SET = "data_set";
private class CancelListener
implements DialogInterface.OnClickListener, DialogInterface.OnCancelListener {
@@ -57,16 +58,17 @@
// - no account -> use phone-local storage without asking the user
final int resId = R.string.import_from_sdcard;
final AccountTypeManager accountTypes = AccountTypeManager.getInstance(this);
- final List<Account> accountList = accountTypes.getAccounts(true);
+ final List<AccountWithDataSet> accountList = accountTypes.getAccounts(true);
if (accountList.size() == 0) {
Log.w(LOG_TAG, "Account does not exist");
finish();
return;
} else if (accountList.size() == 1) {
- final Account account = accountList.get(0);
+ final AccountWithDataSet account = accountList.get(0);
final Intent intent = new Intent();
intent.putExtra(ACCOUNT_NAME, account.name);
intent.putExtra(ACCOUNT_TYPE, account.type);
+ intent.putExtra(DATA_SET, account.dataSet);
setResult(RESULT_OK, intent);
finish();
return;
@@ -81,10 +83,11 @@
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
- final Account account = mAccountList.get(which);
+ final AccountWithDataSet account = mAccountList.get(which);
final Intent intent = new Intent();
intent.putExtra(ACCOUNT_NAME, account.name);
intent.putExtra(ACCOUNT_TYPE, account.type);
+ intent.putExtra(DATA_SET, account.dataSet);
setResult(RESULT_OK, intent);
finish();
}