blob: c8ec3614636e060840d44ec627a3734e83ed2d78 [file] [log] [blame]
Brian Attwelld28851f2014-06-10 13:25:07 -07001package com.android.contacts.quickcontact;
2
3
Gary Maie4874662016-09-26 11:42:54 -07004import android.content.Context;
5import android.content.Intent;
6import android.provider.ContactsContract.CommonDataKinds.GroupMembership;
Brian Attwelld28851f2014-06-10 13:25:07 -07007
8import com.android.contacts.ContactSaveService;
Gary Mai0a49afa2016-12-05 15:53:58 -08009import com.android.contacts.group.GroupMetaData;
Gary Mai69c182a2016-12-05 13:07:03 -080010import com.android.contacts.model.AccountTypeManager;
11import com.android.contacts.model.Contact;
12import com.android.contacts.model.RawContact;
13import com.android.contacts.model.RawContactDelta;
14import com.android.contacts.model.RawContactDeltaList;
15import com.android.contacts.model.RawContactModifier;
16import com.android.contacts.model.ValuesDelta;
17import com.android.contacts.model.account.AccountType;
18import com.android.contacts.model.dataitem.DataItem;
19import com.android.contacts.model.dataitem.DataKind;
20import com.android.contacts.model.dataitem.GroupMembershipDataItem;
Brian Attwelld28851f2014-06-10 13:25:07 -070021
Gary Maie4874662016-09-26 11:42:54 -070022import com.google.common.collect.Iterables;
Brian Attwelld28851f2014-06-10 13:25:07 -070023
24import java.util.List;
25
26/**
27 * Utility class to support adding invisible contacts. Ie, contacts that don't belong to the
28 * default group.
29 */
30public class InvisibleContactUtil {
31
32 public static boolean isInvisibleAndAddable(Contact contactData, Context context) {
33 // Only local contacts
34 if (contactData == null || contactData.isDirectoryEntry()) return false;
35
36 // User profile cannot be added to contacts
37 if (contactData.isUserProfile()) return false;
38
39 // Only if exactly one raw contact
40 if (contactData.getRawContacts().size() != 1) return false;
41
42 // test if the default group is assigned
43 final List<GroupMetaData> groups = contactData.getGroupMetaData();
44
45 // For accounts without group support, groups is null
46 if (groups == null) return false;
47
48 // remember the default group id. no default group? bail out early
49 final long defaultGroupId = getDefaultGroupId(groups);
50 if (defaultGroupId == -1) return false;
51
52 final RawContact rawContact = (RawContact) contactData.getRawContacts().get(0);
53 final AccountType type = rawContact.getAccountType(context);
54 // Offline or non-writeable account? Nothing to fix
55 if (type == null || !type.areContactsWritable()) return false;
56
57 // Check whether the contact is in the default group
58 boolean isInDefaultGroup = false;
59 for (DataItem dataItem : Iterables.filter(
60 rawContact.getDataItems(), GroupMembershipDataItem.class)) {
61 GroupMembershipDataItem groupMembership = (GroupMembershipDataItem) dataItem;
62 final Long groupId = groupMembership.getGroupRowId();
63 if (groupId != null && groupId == defaultGroupId) {
64 isInDefaultGroup = true;
65 break;
66 }
67 }
68
69 return !isInDefaultGroup;
70 }
71
72 public static void addToDefaultGroup(Contact contactData, Context context) {
Gary Maie4874662016-09-26 11:42:54 -070073 final RawContactDeltaList contactDeltaList = contactData.createRawContactDeltaList();
74 if (markAddToDefaultGroup(contactData, contactDeltaList, context)) {
75 // Fire off the intent. we don't need a callback, as the database listener
76 // should update the ui
77 final Intent intent = ContactSaveService.createSaveContactIntent(
78 context,
79 contactDeltaList, "", 0, false, QuickContactActivity.class,
80 Intent.ACTION_VIEW, null, /* joinContactIdExtraKey =*/ null,
81 /* joinContactId =*/ null);
82 ContactSaveService.startService(context, intent);
83 }
84 }
85
86 public static boolean markAddToDefaultGroup(Contact contactData,
87 RawContactDeltaList rawContactDeltaList, Context context) {
Brian Attwelld28851f2014-06-10 13:25:07 -070088 final long defaultGroupId = getDefaultGroupId(contactData.getGroupMetaData());
89 // there should always be a default group (otherwise the button would be invisible),
90 // but let's be safe here
Gary Maie4874662016-09-26 11:42:54 -070091 if (defaultGroupId == -1) return false;
Brian Attwelld28851f2014-06-10 13:25:07 -070092
93 // add the group membership to the current state
Gary Maie4874662016-09-26 11:42:54 -070094 final RawContactDelta rawContactEntityDelta = rawContactDeltaList.get(0);
Brian Attwelld28851f2014-06-10 13:25:07 -070095
96 final AccountTypeManager accountTypes = AccountTypeManager.getInstance(
97 context);
98 final AccountType type = rawContactEntityDelta.getAccountType(accountTypes);
99 final DataKind groupMembershipKind = type.getKindForMimetype(
100 GroupMembership.CONTENT_ITEM_TYPE);
101 final ValuesDelta entry = RawContactModifier.insertChild(rawContactEntityDelta,
102 groupMembershipKind);
Gary Maie4874662016-09-26 11:42:54 -0700103 if (entry == null) return false;
Brian Attwelld28851f2014-06-10 13:25:07 -0700104 entry.setGroupRowId(defaultGroupId);
Gary Maie4874662016-09-26 11:42:54 -0700105 return true;
Brian Attwelld28851f2014-06-10 13:25:07 -0700106 }
107
108 /** return default group id or -1 if no group or several groups are marked as default */
109 private static long getDefaultGroupId(List<GroupMetaData> groups) {
110 long defaultGroupId = -1;
111 for (GroupMetaData group : groups) {
Walter Jang428824e2016-09-09 13:18:35 -0700112 if (group.defaultGroup) {
Brian Attwelld28851f2014-06-10 13:25:07 -0700113 // two default groups? return neither
114 if (defaultGroupId != -1) return -1;
Walter Jang428824e2016-09-09 13:18:35 -0700115 defaultGroupId = group.groupId;
Brian Attwelld28851f2014-06-10 13:25:07 -0700116 }
117 }
118 return defaultGroupId;
119 }
120}