Friend intent: Proper support for dataSet
- Introduce AccountTypeWithDataSet to encapsulate accountType + dataSet
and use it instead of the "account type + '/' + dataset" string,
for better type safety.
Bug 5162267
Change-Id: Id96aea69804bb1151b612838f3fdc24841e5f527
diff --git a/src/com/android/contacts/ContactLoader.java b/src/com/android/contacts/ContactLoader.java
index dbfe411..1107530 100644
--- a/src/com/android/contacts/ContactLoader.java
+++ b/src/com/android/contacts/ContactLoader.java
@@ -18,11 +18,13 @@
import com.android.contacts.model.AccountType;
import com.android.contacts.model.AccountTypeManager;
+import com.android.contacts.model.AccountTypeWithDataSet;
import com.android.contacts.util.DataStatus;
import com.android.contacts.util.StreamItemEntry;
import com.android.contacts.util.StreamItemPhotoEntry;
import com.google.android.collect.Lists;
import com.google.common.annotations.VisibleForTesting;
+import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import android.content.ContentResolver;
@@ -781,20 +783,21 @@
* TODO Exclude the ones with no raw contacts in the database.
*/
private void loadInvitableAccountTypes(Result contactData) {
- Map<String, AccountType> allInvitables =
+ Map<AccountTypeWithDataSet, AccountType> allInvitables =
AccountTypeManager.getInstance(getContext()).getInvitableAccountTypes();
if (allInvitables.isEmpty()) {
return;
}
- HashMap<String, AccountType> result = new HashMap<String, AccountType>(allInvitables);
+ HashMap<AccountTypeWithDataSet, AccountType> result = Maps.newHashMap(allInvitables);
// Remove the ones that already have a raw contact in the current contact
for (Entity entity : contactData.getEntities()) {
- final String type = entity.getEntityValues().getAsString(RawContacts.ACCOUNT_TYPE);
- if (!TextUtils.isEmpty(type)) {
- result.remove(type);
- }
+ final ContentValues values = entity.getEntityValues();
+ final AccountTypeWithDataSet type = AccountTypeWithDataSet.get(
+ values.getAsString(RawContacts.ACCOUNT_TYPE),
+ values.getAsString(RawContacts.DATA_SET));
+ result.remove(type);
}
// Set to mInvitableAccountTypes
diff --git a/src/com/android/contacts/model/AccountType.java b/src/com/android/contacts/model/AccountType.java
index 95216e6..8ee1aa1 100644
--- a/src/com/android/contacts/model/AccountType.java
+++ b/src/com/android/contacts/model/AccountType.java
@@ -51,8 +51,6 @@
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.
*/
@@ -150,21 +148,10 @@
}
/**
- * 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.
+ * Returns {@link AccountTypeWithDataSet} for this 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;
+ public AccountTypeWithDataSet getAccountTypeAndDataSet() {
+ return AccountTypeWithDataSet.get(accountType, dataSet);
}
/**
diff --git a/src/com/android/contacts/model/AccountTypeManager.java b/src/com/android/contacts/model/AccountTypeManager.java
index b517c2c..6d52e18 100644
--- a/src/com/android/contacts/model/AccountTypeManager.java
+++ b/src/com/android/contacts/model/AccountTypeManager.java
@@ -88,10 +88,10 @@
public abstract AccountType getAccountType(String accountType, String dataSet);
/**
- * @return Unmodifiable map from account type strings to {@link AccountType}s which support
- * the "invite" feature and have one or more account.
+ * @return Unmodifiable map from {@link AccountTypeWithDataSet}s to {@link AccountType}s
+ * which support the "invite" feature and have one or more account.
*/
- public abstract Map<String, AccountType> getInvitableAccountTypes();
+ public abstract Map<AccountTypeWithDataSet, AccountType> getInvitableAccountTypes();
/**
* Find the best {@link DataKind} matching the requested
@@ -114,9 +114,9 @@
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>());
+ private Map<AccountTypeWithDataSet, AccountType> mAccountTypesWithDataSets = Maps.newHashMap();
+ private Map<AccountTypeWithDataSet, AccountType> mInvitableAccountTypes =
+ Collections.unmodifiableMap(new HashMap<AccountTypeWithDataSet, AccountType>());
private static final int MESSAGE_LOAD_DATA = 0;
private static final int MESSAGE_PROCESS_BROADCAST_INTENT = 1;
@@ -266,7 +266,7 @@
long startTime = SystemClock.currentThreadTimeMillis();
// Account types, keyed off the account type and data set concatenation.
- Map<String, AccountType> accountTypesByTypeAndDataSet = Maps.newHashMap();
+ Map<AccountTypeWithDataSet, 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
@@ -404,7 +404,7 @@
// Bookkeeping method for tracking the known account types in the given maps.
private void addAccountType(AccountType accountType,
- Map<String, AccountType> accountTypesByTypeAndDataSet,
+ Map<AccountTypeWithDataSet, AccountType> accountTypesByTypeAndDataSet,
Map<String, List<AccountType>> accountTypesByType) {
accountTypesByTypeAndDataSet.put(accountType.getAccountTypeAndDataSet(), accountType);
List<AccountType> accountsForType = accountTypesByType.get(accountType.accountType);
@@ -450,7 +450,7 @@
// Try finding account type and kind matching request
final AccountType type = mAccountTypesWithDataSets.get(
- AccountType.getAccountTypeAndDataSet(accountType, dataSet));
+ AccountTypeWithDataSet.get(accountType, dataSet));
if (type != null) {
kind = type.getKindForMimetype(mimeType);
}
@@ -475,13 +475,13 @@
ensureAccountsLoaded();
synchronized (this) {
AccountType type = mAccountTypesWithDataSets.get(
- AccountType.getAccountTypeAndDataSet(accountType, dataSet));
+ AccountTypeWithDataSet.get(accountType, dataSet));
return type != null ? type : mFallbackAccountType;
}
}
@Override
- public Map<String, AccountType> getInvitableAccountTypes() {
+ public Map<AccountTypeWithDataSet, AccountType> getInvitableAccountTypes() {
return mInvitableAccountTypes;
}
@@ -490,14 +490,13 @@
* its {@link AccountType#getInviteContactActivityClassName()} is not empty.
*/
@VisibleForTesting
- static Map<String, AccountType> findInvitableAccountTypes(Context context,
+ static Map<AccountTypeWithDataSet, AccountType> findInvitableAccountTypes(Context context,
Collection<AccountWithDataSet> accounts,
- Map<String, AccountType> accountTypesByTypeAndDataSet) {
- HashMap<String, AccountType> result = Maps.newHashMap();
+ Map<AccountTypeWithDataSet, AccountType> accountTypesByTypeAndDataSet) {
+ HashMap<AccountTypeWithDataSet, AccountType> result = Maps.newHashMap();
for (AccountWithDataSet account : accounts) {
- String accountTypeWithDataSet = account.getAccountTypeWithDataSet();
- AccountType type = accountTypesByTypeAndDataSet.get(
- account.getAccountTypeWithDataSet());
+ AccountTypeWithDataSet accountTypeWithDataSet = account.getAccountTypeAndWithDataSet();
+ AccountType type = accountTypesByTypeAndDataSet.get(accountTypeWithDataSet);
if (type == null) continue; // just in case
if (result.containsKey(accountTypeWithDataSet)) continue;
diff --git a/src/com/android/contacts/model/AccountTypeWithDataSet.java b/src/com/android/contacts/model/AccountTypeWithDataSet.java
new file mode 100644
index 0000000..d5cdbdd
--- /dev/null
+++ b/src/com/android/contacts/model/AccountTypeWithDataSet.java
@@ -0,0 +1,63 @@
+/*
+ * 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.google.common.base.Objects;
+
+import android.text.TextUtils;
+
+
+/**
+ * Encapsulates an "account type" string and a "data set" string.
+ */
+public class AccountTypeWithDataSet {
+ /** account type will never be null. */
+ public final String accountType;
+
+ /** dataSet may be null, but never be "". */
+ public final String dataSet;
+
+ private AccountTypeWithDataSet(String accountType, String dataSet) {
+ if (accountType == null) throw new NullPointerException();
+
+ this.accountType = accountType;
+ this.dataSet = TextUtils.isEmpty(dataSet) ? null : dataSet;
+ }
+
+ public static AccountTypeWithDataSet get(String accountType, String dataSet) {
+ return new AccountTypeWithDataSet(accountType, dataSet);
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (!(o instanceof AccountTypeWithDataSet)) return false;
+
+ AccountTypeWithDataSet other = (AccountTypeWithDataSet) o;
+ return Objects.equal(accountType, other.accountType)
+ && Objects.equal(dataSet, other.dataSet);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(accountType) ^ (dataSet == null ? 0 : Objects.hashCode(dataSet));
+ }
+
+ @Override
+ public String toString() {
+ return "[" + accountType + "/" + dataSet + "]";
+ }
+}
diff --git a/src/com/android/contacts/model/AccountWithDataSet.java b/src/com/android/contacts/model/AccountWithDataSet.java
index 1d97614..f607737 100644
--- a/src/com/android/contacts/model/AccountWithDataSet.java
+++ b/src/com/android/contacts/model/AccountWithDataSet.java
@@ -27,19 +27,22 @@
public class AccountWithDataSet extends Account {
public final String dataSet;
+ private final AccountTypeWithDataSet mAccountTypeWithDataSet;
public AccountWithDataSet(String name, String type, String dataSet) {
super(name, type);
this.dataSet = dataSet;
+ mAccountTypeWithDataSet = AccountTypeWithDataSet.get(type, dataSet);
}
public AccountWithDataSet(Parcel in, String dataSet) {
super(in);
this.dataSet = dataSet;
+ mAccountTypeWithDataSet = AccountTypeWithDataSet.get(type, dataSet);
}
- public String getAccountTypeWithDataSet() {
- return dataSet == null ? type : AccountType.getAccountTypeAndDataSet(type, dataSet);
+ public AccountTypeWithDataSet getAccountTypeAndWithDataSet() {
+ return mAccountTypeWithDataSet;
}
@Override