1d28851f436c39a83f02d3b405fd91f0fb4833b2aBrian Attwellpackage com.android.contacts.quickcontact;
2d28851f436c39a83f02d3b405fd91f0fb4833b2aBrian Attwell
3d28851f436c39a83f02d3b405fd91f0fb4833b2aBrian Attwell
4d28851f436c39a83f02d3b405fd91f0fb4833b2aBrian Attwellimport com.google.common.collect.Iterables;
5d28851f436c39a83f02d3b405fd91f0fb4833b2aBrian Attwell
6d28851f436c39a83f02d3b405fd91f0fb4833b2aBrian Attwellimport com.android.contacts.ContactSaveService;
7d28851f436c39a83f02d3b405fd91f0fb4833b2aBrian Attwellimport com.android.contacts.common.GroupMetaData;
8d28851f436c39a83f02d3b405fd91f0fb4833b2aBrian Attwellimport com.android.contacts.common.model.AccountTypeManager;
9d28851f436c39a83f02d3b405fd91f0fb4833b2aBrian Attwellimport com.android.contacts.common.model.Contact;
10d28851f436c39a83f02d3b405fd91f0fb4833b2aBrian Attwellimport com.android.contacts.common.model.RawContact;
11d28851f436c39a83f02d3b405fd91f0fb4833b2aBrian Attwellimport com.android.contacts.common.model.RawContactDelta;
12d28851f436c39a83f02d3b405fd91f0fb4833b2aBrian Attwellimport com.android.contacts.common.model.RawContactDeltaList;
13d28851f436c39a83f02d3b405fd91f0fb4833b2aBrian Attwellimport com.android.contacts.common.model.RawContactModifier;
14d28851f436c39a83f02d3b405fd91f0fb4833b2aBrian Attwellimport com.android.contacts.common.model.ValuesDelta;
15d28851f436c39a83f02d3b405fd91f0fb4833b2aBrian Attwellimport com.android.contacts.common.model.account.AccountType;
16d28851f436c39a83f02d3b405fd91f0fb4833b2aBrian Attwellimport com.android.contacts.common.model.dataitem.DataItem;
17d28851f436c39a83f02d3b405fd91f0fb4833b2aBrian Attwellimport com.android.contacts.common.model.dataitem.DataKind;
18d28851f436c39a83f02d3b405fd91f0fb4833b2aBrian Attwellimport com.android.contacts.common.model.dataitem.GroupMembershipDataItem;
19d28851f436c39a83f02d3b405fd91f0fb4833b2aBrian Attwell
20d28851f436c39a83f02d3b405fd91f0fb4833b2aBrian Attwellimport android.content.Context;
21d28851f436c39a83f02d3b405fd91f0fb4833b2aBrian Attwellimport android.content.Intent;
22d28851f436c39a83f02d3b405fd91f0fb4833b2aBrian Attwellimport android.provider.ContactsContract.CommonDataKinds.GroupMembership;
23d28851f436c39a83f02d3b405fd91f0fb4833b2aBrian Attwell
24d28851f436c39a83f02d3b405fd91f0fb4833b2aBrian Attwellimport java.util.List;
25d28851f436c39a83f02d3b405fd91f0fb4833b2aBrian Attwell
26d28851f436c39a83f02d3b405fd91f0fb4833b2aBrian Attwell/**
27d28851f436c39a83f02d3b405fd91f0fb4833b2aBrian Attwell * Utility class to support adding invisible contacts. Ie, contacts that don't belong to the
28d28851f436c39a83f02d3b405fd91f0fb4833b2aBrian Attwell * default group.
29d28851f436c39a83f02d3b405fd91f0fb4833b2aBrian Attwell */
30d28851f436c39a83f02d3b405fd91f0fb4833b2aBrian Attwellpublic class InvisibleContactUtil {
31d28851f436c39a83f02d3b405fd91f0fb4833b2aBrian Attwell
32d28851f436c39a83f02d3b405fd91f0fb4833b2aBrian Attwell    public static boolean isInvisibleAndAddable(Contact contactData, Context context) {
33d28851f436c39a83f02d3b405fd91f0fb4833b2aBrian Attwell        // Only local contacts
34d28851f436c39a83f02d3b405fd91f0fb4833b2aBrian Attwell        if (contactData == null || contactData.isDirectoryEntry()) return false;
35d28851f436c39a83f02d3b405fd91f0fb4833b2aBrian Attwell
36d28851f436c39a83f02d3b405fd91f0fb4833b2aBrian Attwell        // User profile cannot be added to contacts
37d28851f436c39a83f02d3b405fd91f0fb4833b2aBrian Attwell        if (contactData.isUserProfile()) return false;
38d28851f436c39a83f02d3b405fd91f0fb4833b2aBrian Attwell
39d28851f436c39a83f02d3b405fd91f0fb4833b2aBrian Attwell        // Only if exactly one raw contact
40d28851f436c39a83f02d3b405fd91f0fb4833b2aBrian Attwell        if (contactData.getRawContacts().size() != 1) return false;
41d28851f436c39a83f02d3b405fd91f0fb4833b2aBrian Attwell
42d28851f436c39a83f02d3b405fd91f0fb4833b2aBrian Attwell        // test if the default group is assigned
43d28851f436c39a83f02d3b405fd91f0fb4833b2aBrian Attwell        final List<GroupMetaData> groups = contactData.getGroupMetaData();
44d28851f436c39a83f02d3b405fd91f0fb4833b2aBrian Attwell
45d28851f436c39a83f02d3b405fd91f0fb4833b2aBrian Attwell        // For accounts without group support, groups is null
46d28851f436c39a83f02d3b405fd91f0fb4833b2aBrian Attwell        if (groups == null) return false;
47d28851f436c39a83f02d3b405fd91f0fb4833b2aBrian Attwell
48d28851f436c39a83f02d3b405fd91f0fb4833b2aBrian Attwell        // remember the default group id. no default group? bail out early
49d28851f436c39a83f02d3b405fd91f0fb4833b2aBrian Attwell        final long defaultGroupId = getDefaultGroupId(groups);
50d28851f436c39a83f02d3b405fd91f0fb4833b2aBrian Attwell        if (defaultGroupId == -1) return false;
51d28851f436c39a83f02d3b405fd91f0fb4833b2aBrian Attwell
52d28851f436c39a83f02d3b405fd91f0fb4833b2aBrian Attwell        final RawContact rawContact = (RawContact) contactData.getRawContacts().get(0);
53d28851f436c39a83f02d3b405fd91f0fb4833b2aBrian Attwell        final AccountType type = rawContact.getAccountType(context);
54d28851f436c39a83f02d3b405fd91f0fb4833b2aBrian Attwell        // Offline or non-writeable account? Nothing to fix
55d28851f436c39a83f02d3b405fd91f0fb4833b2aBrian Attwell        if (type == null || !type.areContactsWritable()) return false;
56d28851f436c39a83f02d3b405fd91f0fb4833b2aBrian Attwell
57d28851f436c39a83f02d3b405fd91f0fb4833b2aBrian Attwell        // Check whether the contact is in the default group
58d28851f436c39a83f02d3b405fd91f0fb4833b2aBrian Attwell        boolean isInDefaultGroup = false;
59d28851f436c39a83f02d3b405fd91f0fb4833b2aBrian Attwell        for (DataItem dataItem : Iterables.filter(
60d28851f436c39a83f02d3b405fd91f0fb4833b2aBrian Attwell                rawContact.getDataItems(), GroupMembershipDataItem.class)) {
61d28851f436c39a83f02d3b405fd91f0fb4833b2aBrian Attwell            GroupMembershipDataItem groupMembership = (GroupMembershipDataItem) dataItem;
62d28851f436c39a83f02d3b405fd91f0fb4833b2aBrian Attwell            final Long groupId = groupMembership.getGroupRowId();
63d28851f436c39a83f02d3b405fd91f0fb4833b2aBrian Attwell            if (groupId != null && groupId == defaultGroupId) {
64d28851f436c39a83f02d3b405fd91f0fb4833b2aBrian Attwell                isInDefaultGroup = true;
65d28851f436c39a83f02d3b405fd91f0fb4833b2aBrian Attwell                break;
66d28851f436c39a83f02d3b405fd91f0fb4833b2aBrian Attwell            }
67d28851f436c39a83f02d3b405fd91f0fb4833b2aBrian Attwell        }
68d28851f436c39a83f02d3b405fd91f0fb4833b2aBrian Attwell
69d28851f436c39a83f02d3b405fd91f0fb4833b2aBrian Attwell        return !isInDefaultGroup;
70d28851f436c39a83f02d3b405fd91f0fb4833b2aBrian Attwell    }
71d28851f436c39a83f02d3b405fd91f0fb4833b2aBrian Attwell
72d28851f436c39a83f02d3b405fd91f0fb4833b2aBrian Attwell    public static void addToDefaultGroup(Contact contactData, Context context) {
73d28851f436c39a83f02d3b405fd91f0fb4833b2aBrian Attwell        final long defaultGroupId = getDefaultGroupId(contactData.getGroupMetaData());
74d28851f436c39a83f02d3b405fd91f0fb4833b2aBrian Attwell        // there should always be a default group (otherwise the button would be invisible),
75d28851f436c39a83f02d3b405fd91f0fb4833b2aBrian Attwell        // but let's be safe here
76d28851f436c39a83f02d3b405fd91f0fb4833b2aBrian Attwell        if (defaultGroupId == -1) return;
77d28851f436c39a83f02d3b405fd91f0fb4833b2aBrian Attwell
78d28851f436c39a83f02d3b405fd91f0fb4833b2aBrian Attwell        // add the group membership to the current state
79d28851f436c39a83f02d3b405fd91f0fb4833b2aBrian Attwell        final RawContactDeltaList contactDeltaList = contactData.createRawContactDeltaList();
80d28851f436c39a83f02d3b405fd91f0fb4833b2aBrian Attwell        final RawContactDelta rawContactEntityDelta = contactDeltaList.get(0);
81d28851f436c39a83f02d3b405fd91f0fb4833b2aBrian Attwell
82d28851f436c39a83f02d3b405fd91f0fb4833b2aBrian Attwell        final AccountTypeManager accountTypes = AccountTypeManager.getInstance(
83d28851f436c39a83f02d3b405fd91f0fb4833b2aBrian Attwell                context);
84d28851f436c39a83f02d3b405fd91f0fb4833b2aBrian Attwell        final AccountType type = rawContactEntityDelta.getAccountType(accountTypes);
85d28851f436c39a83f02d3b405fd91f0fb4833b2aBrian Attwell        final DataKind groupMembershipKind = type.getKindForMimetype(
86d28851f436c39a83f02d3b405fd91f0fb4833b2aBrian Attwell                GroupMembership.CONTENT_ITEM_TYPE);
87d28851f436c39a83f02d3b405fd91f0fb4833b2aBrian Attwell        final ValuesDelta entry = RawContactModifier.insertChild(rawContactEntityDelta,
88d28851f436c39a83f02d3b405fd91f0fb4833b2aBrian Attwell                groupMembershipKind);
89d28851f436c39a83f02d3b405fd91f0fb4833b2aBrian Attwell        if (entry == null) return;
90d28851f436c39a83f02d3b405fd91f0fb4833b2aBrian Attwell        entry.setGroupRowId(defaultGroupId);
91d28851f436c39a83f02d3b405fd91f0fb4833b2aBrian Attwell
92d28851f436c39a83f02d3b405fd91f0fb4833b2aBrian Attwell        // and fire off the intent. we don't need a callback, as the database listener
93d28851f436c39a83f02d3b405fd91f0fb4833b2aBrian Attwell        // should update the ui
94d28851f436c39a83f02d3b405fd91f0fb4833b2aBrian Attwell        final Intent intent = ContactSaveService.createSaveContactIntent(
95d28851f436c39a83f02d3b405fd91f0fb4833b2aBrian Attwell                context,
96d28851f436c39a83f02d3b405fd91f0fb4833b2aBrian Attwell                contactDeltaList, "", 0, false, QuickContactActivity.class,
973e76408e47ca135c092b5eee73ae49d8697b0a10Walter Jang                Intent.ACTION_VIEW, null, /* backPressed =*/ false);
98d28851f436c39a83f02d3b405fd91f0fb4833b2aBrian Attwell        context.startService(intent);
99d28851f436c39a83f02d3b405fd91f0fb4833b2aBrian Attwell    }
100d28851f436c39a83f02d3b405fd91f0fb4833b2aBrian Attwell
101d28851f436c39a83f02d3b405fd91f0fb4833b2aBrian Attwell    /** return default group id or -1 if no group or several groups are marked as default */
102d28851f436c39a83f02d3b405fd91f0fb4833b2aBrian Attwell    private static long getDefaultGroupId(List<GroupMetaData> groups) {
103d28851f436c39a83f02d3b405fd91f0fb4833b2aBrian Attwell        long defaultGroupId = -1;
104d28851f436c39a83f02d3b405fd91f0fb4833b2aBrian Attwell        for (GroupMetaData group : groups) {
105d28851f436c39a83f02d3b405fd91f0fb4833b2aBrian Attwell            if (group.isDefaultGroup()) {
106d28851f436c39a83f02d3b405fd91f0fb4833b2aBrian Attwell                // two default groups? return neither
107d28851f436c39a83f02d3b405fd91f0fb4833b2aBrian Attwell                if (defaultGroupId != -1) return -1;
108d28851f436c39a83f02d3b405fd91f0fb4833b2aBrian Attwell                defaultGroupId = group.getGroupId();
109d28851f436c39a83f02d3b405fd91f0fb4833b2aBrian Attwell            }
110d28851f436c39a83f02d3b405fd91f0fb4833b2aBrian Attwell        }
111d28851f436c39a83f02d3b405fd91f0fb4833b2aBrian Attwell        return defaultGroupId;
112d28851f436c39a83f02d3b405fd91f0fb4833b2aBrian Attwell    }
113d28851f436c39a83f02d3b405fd91f0fb4833b2aBrian Attwell}
114