Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6ad227f9 authored by Makoto Onuki's avatar Makoto Onuki
Browse files

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
parent 2c41f5bb
Loading
Loading
Loading
Loading
+9 −6
Original line number Diff line number Diff line
@@ -18,11 +18,13 @@ package com.android.contacts;

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,21 +783,22 @@ public class ContactLoader extends Loader<ContactLoader.Result> {
         * 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)) {
                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
            contactData.mInvitableAccountTypes.addAll(result.values());
+3 −16
Original line number Diff line number Diff line
@@ -51,8 +51,6 @@ import java.util.List;
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 @@ public abstract class AccountType {
    }

    /**
     * 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.
     * Returns {@link AccountTypeWithDataSet} for this 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);
    }

    /**
+16 −17
Original line number Diff line number Diff line
@@ -88,10 +88,10 @@ public abstract class AccountTypeManager {
    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 @@ class AccountTypeManagerImpl extends AccountTypeManager

    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 @@ class AccountTypeManagerImpl extends AccountTypeManager
        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 @@ class AccountTypeManagerImpl extends AccountTypeManager

    // 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 @@ class AccountTypeManagerImpl extends AccountTypeManager

        // 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 @@ class AccountTypeManagerImpl extends AccountTypeManager
        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 @@ class AccountTypeManagerImpl extends AccountTypeManager
     * 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;

+63 −0
Original line number Diff line number Diff line
/*
 * 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 + "]";
    }
}
+5 −2
Original line number Diff line number Diff line
@@ -27,19 +27,22 @@ import android.os.Parcel;
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
Loading