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