1758f56580b973894213569b61b1ae23b293071c2Walter Jang/* 2758f56580b973894213569b61b1ae23b293071c2Walter Jang * Copyright (C) 2016 The Android Open Source Project 3758f56580b973894213569b61b1ae23b293071c2Walter Jang * 4758f56580b973894213569b61b1ae23b293071c2Walter Jang * Licensed under the Apache License, Version 2.0 (the "License"); 5758f56580b973894213569b61b1ae23b293071c2Walter Jang * you may not use this file except in compliance with the License. 6758f56580b973894213569b61b1ae23b293071c2Walter Jang * You may obtain a copy of the License at 7758f56580b973894213569b61b1ae23b293071c2Walter Jang * 8758f56580b973894213569b61b1ae23b293071c2Walter Jang * http://www.apache.org/licenses/LICENSE-2.0 9758f56580b973894213569b61b1ae23b293071c2Walter Jang * 10758f56580b973894213569b61b1ae23b293071c2Walter Jang * Unless required by applicable law or agreed to in writing, software 11758f56580b973894213569b61b1ae23b293071c2Walter Jang * distributed under the License is distributed on an "AS IS" BASIS, 12758f56580b973894213569b61b1ae23b293071c2Walter Jang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13758f56580b973894213569b61b1ae23b293071c2Walter Jang * See the License for the specific language governing permissions and 14758f56580b973894213569b61b1ae23b293071c2Walter Jang * limitations under the License. 15758f56580b973894213569b61b1ae23b293071c2Walter Jang */ 16758f56580b973894213569b61b1ae23b293071c2Walter Jang 17758f56580b973894213569b61b1ae23b293071c2Walter Jangpackage com.android.contacts.group; 18758f56580b973894213569b61b1ae23b293071c2Walter Jang 199970f301c1944c3d8155e1718ac34abbe8f69199Sean Midfordimport android.app.Fragment; 209970f301c1944c3d8155e1718ac34abbe8f69199Sean Midfordimport android.content.ContentResolver; 21758f56580b973894213569b61b1ae23b293071c2Walter Jangimport android.content.Context; 22758f56580b973894213569b61b1ae23b293071c2Walter Jangimport android.content.Intent; 23758f56580b973894213569b61b1ae23b293071c2Walter Jangimport android.database.Cursor; 24758f56580b973894213569b61b1ae23b293071c2Walter Jangimport android.net.Uri; 2538860a58d52eacbeb922412bbfc31905cdd8bdc1Wenyi Wangimport android.os.Bundle; 26ff6f1bb6782fe92b8745ef4acb6c622fef3d0cbcSean Midfordimport android.provider.ContactsContract; 2738860a58d52eacbeb922412bbfc31905cdd8bdc1Wenyi Wangimport android.provider.ContactsContract.Contacts; 28758f56580b973894213569b61b1ae23b293071c2Walter Jangimport android.provider.ContactsContract.Groups; 293fafbb29c949ba998af2104451859ed81b06f663Wenyi Wangimport android.text.TextUtils; 30758f56580b973894213569b61b1ae23b293071c2Walter Jang 310a49afa2ad697307cc04ef4cb86570574fa720f2Gary Maiimport com.android.contacts.ContactsUtils; 32758f56580b973894213569b61b1ae23b293071c2Walter Jangimport com.android.contacts.GroupListLoader; 336927bf35fa2d1b4261e25c46bcd4951cd7b3208aWenyi Wangimport com.android.contacts.activities.ContactSelectionActivity; 3469c182afb0e6d82a341a28b4317aa703af768906Gary Maiimport com.android.contacts.list.ContactsSectionIndexer; 35d8effeb5adf3fc9d81e552c41450400eb86076c7yaoluimport com.android.contacts.list.UiIntentActions; 360a49afa2ad697307cc04ef4cb86570574fa720f2Gary Maiimport com.android.contacts.model.account.GoogleAccountType; 37758f56580b973894213569b61b1ae23b293071c2Walter Jang 3838860a58d52eacbeb922412bbfc31905cdd8bdc1Wenyi Wangimport java.util.ArrayList; 393fafbb29c949ba998af2104451859ed81b06f663Wenyi Wangimport java.util.Arrays; 403fafbb29c949ba998af2104451859ed81b06f663Wenyi Wangimport java.util.HashSet; 4138860a58d52eacbeb922412bbfc31905cdd8bdc1Wenyi Wangimport java.util.List; 423fafbb29c949ba998af2104451859ed81b06f663Wenyi Wangimport java.util.Set; 433fafbb29c949ba998af2104451859ed81b06f663Wenyi Wang 44758f56580b973894213569b61b1ae23b293071c2Walter Jang/** 45758f56580b973894213569b61b1ae23b293071c2Walter Jang * Group utility methods. 46758f56580b973894213569b61b1ae23b293071c2Walter Jang */ 47758f56580b973894213569b61b1ae23b293071c2Walter Jangpublic final class GroupUtil { 48758f56580b973894213569b61b1ae23b293071c2Walter Jang 495c1bff2efa542ea112c3f2a1d1ed1e271c7691a7Gary Mai public final static String ALL_GROUPS_SELECTION = 505c1bff2efa542ea112c3f2a1d1ed1e271c7691a7Gary Mai Groups.ACCOUNT_TYPE + " NOT NULL AND " + Groups.ACCOUNT_NAME + " NOT NULL AND " 515c1bff2efa542ea112c3f2a1d1ed1e271c7691a7Gary Mai + Groups.DELETED + "=0"; 525c1bff2efa542ea112c3f2a1d1ed1e271c7691a7Gary Mai 535c1bff2efa542ea112c3f2a1d1ed1e271c7691a7Gary Mai public final static String DEFAULT_SELECTION = ALL_GROUPS_SELECTION + " AND " 545c1bff2efa542ea112c3f2a1d1ed1e271c7691a7Gary Mai + Groups.AUTO_ADD + "=0 AND " + Groups.FAVORITES + "=0"; 555c1bff2efa542ea112c3f2a1d1ed1e271c7691a7Gary Mai 566927bf35fa2d1b4261e25c46bcd4951cd7b3208aWenyi Wang public static final String ACTION_ADD_TO_GROUP = "addToGroup"; 57cc8f272af38bd46710b8186424caf515215f2582Wenyi Wang public static final String ACTION_CREATE_GROUP = "createGroup"; 58cc8f272af38bd46710b8186424caf515215f2582Wenyi Wang public static final String ACTION_DELETE_GROUP = "deleteGroup"; 596927bf35fa2d1b4261e25c46bcd4951cd7b3208aWenyi Wang public static final String ACTION_REMOVE_FROM_GROUP = "removeFromGroup"; 60cc8f272af38bd46710b8186424caf515215f2582Wenyi Wang public static final String ACTION_SWITCH_GROUP = "switchGroup"; 61cc8f272af38bd46710b8186424caf515215f2582Wenyi Wang public static final String ACTION_UPDATE_GROUP = "updateGroup"; 626927bf35fa2d1b4261e25c46bcd4951cd7b3208aWenyi Wang 639970f301c1944c3d8155e1718ac34abbe8f69199Sean Midford public static final int RESULT_SEND_TO_SELECTION = 100; 649970f301c1944c3d8155e1718ac34abbe8f69199Sean Midford 653fafbb29c949ba998af2104451859ed81b06f663Wenyi Wang // System IDs of FFC groups in Google accounts 663fafbb29c949ba998af2104451859ed81b06f663Wenyi Wang private static final Set<String> FFC_GROUPS = 673fafbb29c949ba998af2104451859ed81b06f663Wenyi Wang new HashSet(Arrays.asList("Friends", "Family", "Coworkers")); 683fafbb29c949ba998af2104451859ed81b06f663Wenyi Wang 69758f56580b973894213569b61b1ae23b293071c2Walter Jang private GroupUtil() { 70758f56580b973894213569b61b1ae23b293071c2Walter Jang } 71758f56580b973894213569b61b1ae23b293071c2Walter Jang 72758f56580b973894213569b61b1ae23b293071c2Walter Jang /** Returns a {@link GroupListItem} read from the given cursor and position. */ 73b8b86d1a272b313fd2b3ff9e324ce014f24aa44dWenyi Wang public static GroupListItem getGroupListItem(Cursor cursor, int position) { 74758f56580b973894213569b61b1ae23b293071c2Walter Jang if (cursor == null || cursor.isClosed() || !cursor.moveToPosition(position)) { 75758f56580b973894213569b61b1ae23b293071c2Walter Jang return null; 76758f56580b973894213569b61b1ae23b293071c2Walter Jang } 77758f56580b973894213569b61b1ae23b293071c2Walter Jang String accountName = cursor.getString(GroupListLoader.ACCOUNT_NAME); 78758f56580b973894213569b61b1ae23b293071c2Walter Jang String accountType = cursor.getString(GroupListLoader.ACCOUNT_TYPE); 79758f56580b973894213569b61b1ae23b293071c2Walter Jang String dataSet = cursor.getString(GroupListLoader.DATA_SET); 80758f56580b973894213569b61b1ae23b293071c2Walter Jang long groupId = cursor.getLong(GroupListLoader.GROUP_ID); 81758f56580b973894213569b61b1ae23b293071c2Walter Jang String title = cursor.getString(GroupListLoader.TITLE); 82758f56580b973894213569b61b1ae23b293071c2Walter Jang int memberCount = cursor.getInt(GroupListLoader.MEMBER_COUNT); 833fafbb29c949ba998af2104451859ed81b06f663Wenyi Wang boolean isReadOnly = cursor.getInt(GroupListLoader.IS_READ_ONLY) == 1; 843fafbb29c949ba998af2104451859ed81b06f663Wenyi Wang String systemId = cursor.getString(GroupListLoader.SYSTEM_ID); 85758f56580b973894213569b61b1ae23b293071c2Walter Jang 86758f56580b973894213569b61b1ae23b293071c2Walter Jang // Figure out if this is the first group for this account name / account type pair by 87758f56580b973894213569b61b1ae23b293071c2Walter Jang // checking the previous entry. This is to determine whether or not we need to display an 88758f56580b973894213569b61b1ae23b293071c2Walter Jang // account header in this item. 89758f56580b973894213569b61b1ae23b293071c2Walter Jang int previousIndex = position - 1; 90758f56580b973894213569b61b1ae23b293071c2Walter Jang boolean isFirstGroupInAccount = true; 91758f56580b973894213569b61b1ae23b293071c2Walter Jang if (previousIndex >= 0 && cursor.moveToPosition(previousIndex)) { 92758f56580b973894213569b61b1ae23b293071c2Walter Jang String previousGroupAccountName = cursor.getString(GroupListLoader.ACCOUNT_NAME); 93758f56580b973894213569b61b1ae23b293071c2Walter Jang String previousGroupAccountType = cursor.getString(GroupListLoader.ACCOUNT_TYPE); 94758f56580b973894213569b61b1ae23b293071c2Walter Jang String previousGroupDataSet = cursor.getString(GroupListLoader.DATA_SET); 95758f56580b973894213569b61b1ae23b293071c2Walter Jang 96dd2d8e27d8548893122c469bd1b68d5117fc5318Walter Jang if (TextUtils.equals(accountName, previousGroupAccountName) 97dd2d8e27d8548893122c469bd1b68d5117fc5318Walter Jang && TextUtils.equals(accountType, previousGroupAccountType) 98dd2d8e27d8548893122c469bd1b68d5117fc5318Walter Jang && TextUtils.equals(dataSet, previousGroupDataSet)) { 99758f56580b973894213569b61b1ae23b293071c2Walter Jang isFirstGroupInAccount = false; 100758f56580b973894213569b61b1ae23b293071c2Walter Jang } 101758f56580b973894213569b61b1ae23b293071c2Walter Jang } 102758f56580b973894213569b61b1ae23b293071c2Walter Jang 103758f56580b973894213569b61b1ae23b293071c2Walter Jang return new GroupListItem(accountName, accountType, dataSet, groupId, title, 1043fafbb29c949ba998af2104451859ed81b06f663Wenyi Wang isFirstGroupInAccount, memberCount, isReadOnly, systemId); 105758f56580b973894213569b61b1ae23b293071c2Walter Jang } 106758f56580b973894213569b61b1ae23b293071c2Walter Jang 1079970f301c1944c3d8155e1718ac34abbe8f69199Sean Midford public static List<String> getSendToDataForIds(Context context, long[] ids, String scheme) { 1089970f301c1944c3d8155e1718ac34abbe8f69199Sean Midford final List<String> items = new ArrayList<>(); 1099970f301c1944c3d8155e1718ac34abbe8f69199Sean Midford final String sIds = GroupUtil.convertArrayToString(ids); 1109970f301c1944c3d8155e1718ac34abbe8f69199Sean Midford final String select = (ContactsUtils.SCHEME_MAILTO.equals(scheme) 1119970f301c1944c3d8155e1718ac34abbe8f69199Sean Midford ? GroupMembersFragment.Query.EMAIL_SELECTION 1129970f301c1944c3d8155e1718ac34abbe8f69199Sean Midford + " AND " + ContactsContract.CommonDataKinds.Email._ID + " IN (" + sIds + ")" 1139970f301c1944c3d8155e1718ac34abbe8f69199Sean Midford : GroupMembersFragment.Query.PHONE_SELECTION 1149970f301c1944c3d8155e1718ac34abbe8f69199Sean Midford + " AND " + ContactsContract.CommonDataKinds.Phone._ID + " IN (" + sIds + ")"); 1159970f301c1944c3d8155e1718ac34abbe8f69199Sean Midford final ContentResolver contentResolver = context.getContentResolver(); 1169970f301c1944c3d8155e1718ac34abbe8f69199Sean Midford final Cursor cursor = contentResolver.query(ContactsContract.Data.CONTENT_URI, 1179970f301c1944c3d8155e1718ac34abbe8f69199Sean Midford ContactsUtils.SCHEME_MAILTO.equals(scheme) 1189970f301c1944c3d8155e1718ac34abbe8f69199Sean Midford ? GroupMembersFragment.Query.EMAIL_PROJECTION 1199970f301c1944c3d8155e1718ac34abbe8f69199Sean Midford : GroupMembersFragment.Query.PHONE_PROJECTION, 1209970f301c1944c3d8155e1718ac34abbe8f69199Sean Midford select, null, null); 1219970f301c1944c3d8155e1718ac34abbe8f69199Sean Midford 1229970f301c1944c3d8155e1718ac34abbe8f69199Sean Midford if (cursor == null) { 1239970f301c1944c3d8155e1718ac34abbe8f69199Sean Midford return items; 1249970f301c1944c3d8155e1718ac34abbe8f69199Sean Midford } 1259970f301c1944c3d8155e1718ac34abbe8f69199Sean Midford 1269970f301c1944c3d8155e1718ac34abbe8f69199Sean Midford try { 1279970f301c1944c3d8155e1718ac34abbe8f69199Sean Midford cursor.moveToPosition(-1); 1289970f301c1944c3d8155e1718ac34abbe8f69199Sean Midford while (cursor.moveToNext()) { 1299970f301c1944c3d8155e1718ac34abbe8f69199Sean Midford final String data = cursor.getString(GroupMembersFragment.Query.DATA1); 1309970f301c1944c3d8155e1718ac34abbe8f69199Sean Midford 1319970f301c1944c3d8155e1718ac34abbe8f69199Sean Midford if (!TextUtils.isEmpty(data)) { 1329970f301c1944c3d8155e1718ac34abbe8f69199Sean Midford items.add(data); 1339970f301c1944c3d8155e1718ac34abbe8f69199Sean Midford } 1349970f301c1944c3d8155e1718ac34abbe8f69199Sean Midford } 1359970f301c1944c3d8155e1718ac34abbe8f69199Sean Midford } finally { 1369970f301c1944c3d8155e1718ac34abbe8f69199Sean Midford cursor.close(); 1379970f301c1944c3d8155e1718ac34abbe8f69199Sean Midford } 1389970f301c1944c3d8155e1718ac34abbe8f69199Sean Midford 1399970f301c1944c3d8155e1718ac34abbe8f69199Sean Midford return items; 1409970f301c1944c3d8155e1718ac34abbe8f69199Sean Midford } 1419970f301c1944c3d8155e1718ac34abbe8f69199Sean Midford 142ff6f1bb6782fe92b8745ef4acb6c622fef3d0cbcSean Midford /** Returns an Intent to send emails/phones to some activity/app */ 1439970f301c1944c3d8155e1718ac34abbe8f69199Sean Midford public static void startSendToSelectionActivity( 1449970f301c1944c3d8155e1718ac34abbe8f69199Sean Midford Fragment fragment, String itemsList, String sendScheme, String title) { 145ff6f1bb6782fe92b8745ef4acb6c622fef3d0cbcSean Midford final Intent intent = new Intent(Intent.ACTION_SENDTO, 146ff6f1bb6782fe92b8745ef4acb6c622fef3d0cbcSean Midford Uri.fromParts(sendScheme, itemsList, null)); 1479970f301c1944c3d8155e1718ac34abbe8f69199Sean Midford fragment.startActivityForResult( 1489970f301c1944c3d8155e1718ac34abbe8f69199Sean Midford Intent.createChooser(intent, title), RESULT_SEND_TO_SELECTION); 149ff6f1bb6782fe92b8745ef4acb6c622fef3d0cbcSean Midford } 150ff6f1bb6782fe92b8745ef4acb6c622fef3d0cbcSean Midford 151ff6f1bb6782fe92b8745ef4acb6c622fef3d0cbcSean Midford /** Returns an Intent to pick emails/phones to send to selection (or group) */ 1524b2ccd27dbb05d7cc1d340ce18182ccb2b9a3326Sean Midford public static Intent createSendToSelectionPickerIntent(Context context, long[] ids, 1534b2ccd27dbb05d7cc1d340ce18182ccb2b9a3326Sean Midford long[] defaultSelection, String sendScheme, String title) { 154ff6f1bb6782fe92b8745ef4acb6c622fef3d0cbcSean Midford final Intent intent = new Intent(context, ContactSelectionActivity.class); 155ff6f1bb6782fe92b8745ef4acb6c622fef3d0cbcSean Midford intent.setAction(UiIntentActions.ACTION_SELECT_ITEMS); 156ff6f1bb6782fe92b8745ef4acb6c622fef3d0cbcSean Midford intent.setType(ContactsUtils.SCHEME_MAILTO.equals(sendScheme) 157ff6f1bb6782fe92b8745ef4acb6c622fef3d0cbcSean Midford ? ContactsContract.CommonDataKinds.Email.CONTENT_TYPE 158ff6f1bb6782fe92b8745ef4acb6c622fef3d0cbcSean Midford : ContactsContract.CommonDataKinds.Phone.CONTENT_TYPE); 1594b2ccd27dbb05d7cc1d340ce18182ccb2b9a3326Sean Midford intent.putExtra(UiIntentActions.SELECTION_ITEM_LIST, ids); 1604b2ccd27dbb05d7cc1d340ce18182ccb2b9a3326Sean Midford intent.putExtra(UiIntentActions.SELECTION_DEFAULT_SELECTION, defaultSelection); 161b460f44f6517f269bac35f339f57e603669f45d7Sean Midford intent.putExtra(UiIntentActions.SELECTION_SEND_SCHEME, sendScheme); 162b460f44f6517f269bac35f339f57e603669f45d7Sean Midford intent.putExtra(UiIntentActions.SELECTION_SEND_TITLE, title); 163b460f44f6517f269bac35f339f57e603669f45d7Sean Midford 164ff6f1bb6782fe92b8745ef4acb6c622fef3d0cbcSean Midford return intent; 165ff6f1bb6782fe92b8745ef4acb6c622fef3d0cbcSean Midford } 166ff6f1bb6782fe92b8745ef4acb6c622fef3d0cbcSean Midford 167d8effeb5adf3fc9d81e552c41450400eb86076c7yaolu /** Returns an Intent to pick contacts to add to a group. */ 16841c6886cabf68370f160ccd68d173bd6a59a1a07John Shao public static Intent createPickMemberIntent(Context context, 169428824eaca7ed60c14add0a1d45edfe4535059bbWalter Jang GroupMetaData groupMetaData, ArrayList<String> memberContactIds) { 1706927bf35fa2d1b4261e25c46bcd4951cd7b3208aWenyi Wang final Intent intent = new Intent(context, ContactSelectionActivity.class); 17141c6886cabf68370f160ccd68d173bd6a59a1a07John Shao intent.setAction(Intent.ACTION_PICK); 1721110d678aee0b1967898e83334a63df49a7e30f6Walter Jang intent.setType(Groups.CONTENT_TYPE); 173428824eaca7ed60c14add0a1d45edfe4535059bbWalter Jang intent.putExtra(UiIntentActions.GROUP_ACCOUNT_NAME, groupMetaData.accountName); 174428824eaca7ed60c14add0a1d45edfe4535059bbWalter Jang intent.putExtra(UiIntentActions.GROUP_ACCOUNT_TYPE, groupMetaData.accountType); 175428824eaca7ed60c14add0a1d45edfe4535059bbWalter Jang intent.putExtra(UiIntentActions.GROUP_ACCOUNT_DATA_SET, groupMetaData.dataSet); 176d8effeb5adf3fc9d81e552c41450400eb86076c7yaolu intent.putExtra(UiIntentActions.GROUP_CONTACT_IDS, memberContactIds); 177d8effeb5adf3fc9d81e552c41450400eb86076c7yaolu return intent; 178d8effeb5adf3fc9d81e552c41450400eb86076c7yaolu } 179d8effeb5adf3fc9d81e552c41450400eb86076c7yaolu 180ff6f1bb6782fe92b8745ef4acb6c622fef3d0cbcSean Midford public static String convertArrayToString(long[] list) { 181ff6f1bb6782fe92b8745ef4acb6c622fef3d0cbcSean Midford if (list == null || list.length == 0) return ""; 182ff6f1bb6782fe92b8745ef4acb6c622fef3d0cbcSean Midford return Arrays.toString(list).replace("[", "").replace("]", ""); 183ff6f1bb6782fe92b8745ef4acb6c622fef3d0cbcSean Midford } 184ff6f1bb6782fe92b8745ef4acb6c622fef3d0cbcSean Midford 185ff6f1bb6782fe92b8745ef4acb6c622fef3d0cbcSean Midford public static long[] convertLongSetToLongArray(Set<Long> set) { 186ff6f1bb6782fe92b8745ef4acb6c622fef3d0cbcSean Midford final Long[] contactIds = set.toArray(new Long[set.size()]); 187ff6f1bb6782fe92b8745ef4acb6c622fef3d0cbcSean Midford final long[] result = new long[contactIds.length]; 188ff6f1bb6782fe92b8745ef4acb6c622fef3d0cbcSean Midford for (int i = 0; i < contactIds.length; i++) { 189ff6f1bb6782fe92b8745ef4acb6c622fef3d0cbcSean Midford result[i] = contactIds[i]; 190ff6f1bb6782fe92b8745ef4acb6c622fef3d0cbcSean Midford } 191ff6f1bb6782fe92b8745ef4acb6c622fef3d0cbcSean Midford return result; 192ff6f1bb6782fe92b8745ef4acb6c622fef3d0cbcSean Midford } 193ff6f1bb6782fe92b8745ef4acb6c622fef3d0cbcSean Midford 194ff6f1bb6782fe92b8745ef4acb6c622fef3d0cbcSean Midford public static long[] convertStringSetToLongArray(Set<String> set) { 195ff6f1bb6782fe92b8745ef4acb6c622fef3d0cbcSean Midford final String[] contactIds = set.toArray(new String[set.size()]); 196ff6f1bb6782fe92b8745ef4acb6c622fef3d0cbcSean Midford final long[] result = new long[contactIds.length]; 197ff6f1bb6782fe92b8745ef4acb6c622fef3d0cbcSean Midford for (int i = 0; i < contactIds.length; i++) { 198ff6f1bb6782fe92b8745ef4acb6c622fef3d0cbcSean Midford try { 199ff6f1bb6782fe92b8745ef4acb6c622fef3d0cbcSean Midford result[i] = Long.parseLong(contactIds[i]); 200ff6f1bb6782fe92b8745ef4acb6c622fef3d0cbcSean Midford } catch (NumberFormatException e) { 201ff6f1bb6782fe92b8745ef4acb6c622fef3d0cbcSean Midford result[i] = -1; 202ff6f1bb6782fe92b8745ef4acb6c622fef3d0cbcSean Midford } 203ff6f1bb6782fe92b8745ef4acb6c622fef3d0cbcSean Midford } 204ff6f1bb6782fe92b8745ef4acb6c622fef3d0cbcSean Midford return result; 205ff6f1bb6782fe92b8745ef4acb6c622fef3d0cbcSean Midford } 206ff6f1bb6782fe92b8745ef4acb6c622fef3d0cbcSean Midford 2070680a31c87d083eca56ef6093de54bbb3b5c2d27Walter Jang /** 208f9dd12948a7844ddcf5edb8778d7edbf50dd0e82John Shao * Returns true if it's an empty and read-only group and the system ID of 2093fafbb29c949ba998af2104451859ed81b06f663Wenyi Wang * the group is one of "Friends", "Family" and "Coworkers". 2103fafbb29c949ba998af2104451859ed81b06f663Wenyi Wang */ 2113fafbb29c949ba998af2104451859ed81b06f663Wenyi Wang public static boolean isEmptyFFCGroup(GroupListItem groupListItem) { 212f9dd12948a7844ddcf5edb8778d7edbf50dd0e82John Shao return groupListItem.isReadOnly() 2133fafbb29c949ba998af2104451859ed81b06f663Wenyi Wang && isSystemIdFFC(groupListItem.getSystemId()) 2143fafbb29c949ba998af2104451859ed81b06f663Wenyi Wang && (groupListItem.getMemberCount() <= 0); 2153fafbb29c949ba998af2104451859ed81b06f663Wenyi Wang } 2163fafbb29c949ba998af2104451859ed81b06f663Wenyi Wang 2173fafbb29c949ba998af2104451859ed81b06f663Wenyi Wang private static boolean isSystemIdFFC(String systemId) { 2183fafbb29c949ba998af2104451859ed81b06f663Wenyi Wang return !TextUtils.isEmpty(systemId) && FFC_GROUPS.contains(systemId); 2193fafbb29c949ba998af2104451859ed81b06f663Wenyi Wang } 2209afaddec062bc1c9f3d7bb30992d70198fbe0840Wenyi Wang 2219afaddec062bc1c9f3d7bb30992d70198fbe0840Wenyi Wang /** 2227967545e62b473503473b2c9e127cef405f67201Wenyi Wang * Returns true the URI is a group URI. 2237967545e62b473503473b2c9e127cef405f67201Wenyi Wang */ 2247967545e62b473503473b2c9e127cef405f67201Wenyi Wang public static boolean isGroupUri(Uri uri) { 2257967545e62b473503473b2c9e127cef405f67201Wenyi Wang return uri != null && uri.toString().startsWith(Groups.CONTENT_URI.toString()); 2267967545e62b473503473b2c9e127cef405f67201Wenyi Wang } 2277967545e62b473503473b2c9e127cef405f67201Wenyi Wang 2287967545e62b473503473b2c9e127cef405f67201Wenyi Wang /** 2299afaddec062bc1c9f3d7bb30992d70198fbe0840Wenyi Wang * Sort groups alphabetically and in a localized way. 2309afaddec062bc1c9f3d7bb30992d70198fbe0840Wenyi Wang */ 2319afaddec062bc1c9f3d7bb30992d70198fbe0840Wenyi Wang public static String getGroupsSortOrder() { 2329afaddec062bc1c9f3d7bb30992d70198fbe0840Wenyi Wang return Groups.TITLE + " COLLATE LOCALIZED ASC"; 2339afaddec062bc1c9f3d7bb30992d70198fbe0840Wenyi Wang } 23438860a58d52eacbeb922412bbfc31905cdd8bdc1Wenyi Wang 23538860a58d52eacbeb922412bbfc31905cdd8bdc1Wenyi Wang /** 23638860a58d52eacbeb922412bbfc31905cdd8bdc1Wenyi Wang * The sum of the last element in counts[] and the last element in positions[] is the total 23738860a58d52eacbeb922412bbfc31905cdd8bdc1Wenyi Wang * number of remaining elements in cursor. If count is more than what's in the indexer now, 23838860a58d52eacbeb922412bbfc31905cdd8bdc1Wenyi Wang * then we don't need to trim. 23938860a58d52eacbeb922412bbfc31905cdd8bdc1Wenyi Wang */ 24038860a58d52eacbeb922412bbfc31905cdd8bdc1Wenyi Wang public static boolean needTrimming(int count, int[] counts, int[] positions) { 24138860a58d52eacbeb922412bbfc31905cdd8bdc1Wenyi Wang // The sum of the last element in counts[] and the last element in positions[] is 24238860a58d52eacbeb922412bbfc31905cdd8bdc1Wenyi Wang // the total number of remaining elements in cursor. If mCount is more than 24338860a58d52eacbeb922412bbfc31905cdd8bdc1Wenyi Wang // what's in the indexer now, then we don't need to trim. 24438860a58d52eacbeb922412bbfc31905cdd8bdc1Wenyi Wang return positions.length > 0 && counts.length > 0 24538860a58d52eacbeb922412bbfc31905cdd8bdc1Wenyi Wang && count <= (counts[counts.length - 1] + positions[positions.length - 1]); 24638860a58d52eacbeb922412bbfc31905cdd8bdc1Wenyi Wang } 24738860a58d52eacbeb922412bbfc31905cdd8bdc1Wenyi Wang 24838860a58d52eacbeb922412bbfc31905cdd8bdc1Wenyi Wang /** 24938860a58d52eacbeb922412bbfc31905cdd8bdc1Wenyi Wang * Update Bundle extras so as to update indexer. 25038860a58d52eacbeb922412bbfc31905cdd8bdc1Wenyi Wang */ 25138860a58d52eacbeb922412bbfc31905cdd8bdc1Wenyi Wang public static void updateBundle(Bundle bundle, ContactsSectionIndexer indexer, 25238860a58d52eacbeb922412bbfc31905cdd8bdc1Wenyi Wang List<Integer> subscripts, String[] sections, int[] counts) { 25338860a58d52eacbeb922412bbfc31905cdd8bdc1Wenyi Wang for (int i : subscripts) { 25438860a58d52eacbeb922412bbfc31905cdd8bdc1Wenyi Wang final int filteredContact = indexer.getSectionForPosition(i); 25538860a58d52eacbeb922412bbfc31905cdd8bdc1Wenyi Wang if (filteredContact < counts.length && filteredContact >= 0) { 25638860a58d52eacbeb922412bbfc31905cdd8bdc1Wenyi Wang counts[filteredContact]--; 25738860a58d52eacbeb922412bbfc31905cdd8bdc1Wenyi Wang if (counts[filteredContact] == 0) { 25838860a58d52eacbeb922412bbfc31905cdd8bdc1Wenyi Wang sections[filteredContact] = ""; 25938860a58d52eacbeb922412bbfc31905cdd8bdc1Wenyi Wang } 26038860a58d52eacbeb922412bbfc31905cdd8bdc1Wenyi Wang } 26138860a58d52eacbeb922412bbfc31905cdd8bdc1Wenyi Wang } 26238860a58d52eacbeb922412bbfc31905cdd8bdc1Wenyi Wang final String[] newSections = clearEmptyString(sections); 26338860a58d52eacbeb922412bbfc31905cdd8bdc1Wenyi Wang bundle.putStringArray(Contacts.EXTRA_ADDRESS_BOOK_INDEX_TITLES, newSections); 26438860a58d52eacbeb922412bbfc31905cdd8bdc1Wenyi Wang final int[] newCounts = clearZeros(counts); 26538860a58d52eacbeb922412bbfc31905cdd8bdc1Wenyi Wang bundle.putIntArray(Contacts.EXTRA_ADDRESS_BOOK_INDEX_COUNTS, newCounts); 26638860a58d52eacbeb922412bbfc31905cdd8bdc1Wenyi Wang } 26738860a58d52eacbeb922412bbfc31905cdd8bdc1Wenyi Wang 26838860a58d52eacbeb922412bbfc31905cdd8bdc1Wenyi Wang private static String[] clearEmptyString(String[] strings) { 26938860a58d52eacbeb922412bbfc31905cdd8bdc1Wenyi Wang final List<String> list = new ArrayList<>(); 27038860a58d52eacbeb922412bbfc31905cdd8bdc1Wenyi Wang for (String s : strings) { 27138860a58d52eacbeb922412bbfc31905cdd8bdc1Wenyi Wang if (!TextUtils.isEmpty(s)) { 27238860a58d52eacbeb922412bbfc31905cdd8bdc1Wenyi Wang list.add(s); 27338860a58d52eacbeb922412bbfc31905cdd8bdc1Wenyi Wang } 27438860a58d52eacbeb922412bbfc31905cdd8bdc1Wenyi Wang } 27538860a58d52eacbeb922412bbfc31905cdd8bdc1Wenyi Wang return list.toArray(new String[list.size()]); 27638860a58d52eacbeb922412bbfc31905cdd8bdc1Wenyi Wang } 27738860a58d52eacbeb922412bbfc31905cdd8bdc1Wenyi Wang 27838860a58d52eacbeb922412bbfc31905cdd8bdc1Wenyi Wang private static int[] clearZeros(int[] numbers) { 27938860a58d52eacbeb922412bbfc31905cdd8bdc1Wenyi Wang final List<Integer> list = new ArrayList<>(); 28038860a58d52eacbeb922412bbfc31905cdd8bdc1Wenyi Wang for (int n : numbers) { 28138860a58d52eacbeb922412bbfc31905cdd8bdc1Wenyi Wang if (n > 0) { 28238860a58d52eacbeb922412bbfc31905cdd8bdc1Wenyi Wang list.add(n); 28338860a58d52eacbeb922412bbfc31905cdd8bdc1Wenyi Wang } 28438860a58d52eacbeb922412bbfc31905cdd8bdc1Wenyi Wang } 28538860a58d52eacbeb922412bbfc31905cdd8bdc1Wenyi Wang final int[] array = new int[list.size()]; 28638860a58d52eacbeb922412bbfc31905cdd8bdc1Wenyi Wang for(int i = 0; i < list.size(); i++) { 28738860a58d52eacbeb922412bbfc31905cdd8bdc1Wenyi Wang array[i] = list.get(i); 28838860a58d52eacbeb922412bbfc31905cdd8bdc1Wenyi Wang } 28938860a58d52eacbeb922412bbfc31905cdd8bdc1Wenyi Wang return array; 29038860a58d52eacbeb922412bbfc31905cdd8bdc1Wenyi Wang } 2912d97b5f89ae1ae1b5e782e40b82ba60f0588f964Marcus Hagerott 2922d97b5f89ae1ae1b5e782e40b82ba60f0588f964Marcus Hagerott /** 2932d97b5f89ae1ae1b5e782e40b82ba60f0588f964Marcus Hagerott * Stores column ordering for the projection of a query of ContactsContract.Groups 2942d97b5f89ae1ae1b5e782e40b82ba60f0588f964Marcus Hagerott */ 2952d97b5f89ae1ae1b5e782e40b82ba60f0588f964Marcus Hagerott public static final class GroupsProjection { 2962d97b5f89ae1ae1b5e782e40b82ba60f0588f964Marcus Hagerott public final int groupId; 2972d97b5f89ae1ae1b5e782e40b82ba60f0588f964Marcus Hagerott public final int title; 2982d97b5f89ae1ae1b5e782e40b82ba60f0588f964Marcus Hagerott public final int summaryCount; 2992d97b5f89ae1ae1b5e782e40b82ba60f0588f964Marcus Hagerott public final int systemId; 3002d97b5f89ae1ae1b5e782e40b82ba60f0588f964Marcus Hagerott public final int accountName; 3012d97b5f89ae1ae1b5e782e40b82ba60f0588f964Marcus Hagerott public final int accountType; 3022d97b5f89ae1ae1b5e782e40b82ba60f0588f964Marcus Hagerott public final int dataSet; 3032d97b5f89ae1ae1b5e782e40b82ba60f0588f964Marcus Hagerott public final int autoAdd; 3042d97b5f89ae1ae1b5e782e40b82ba60f0588f964Marcus Hagerott public final int favorites; 3052d97b5f89ae1ae1b5e782e40b82ba60f0588f964Marcus Hagerott public final int isReadOnly; 3062d97b5f89ae1ae1b5e782e40b82ba60f0588f964Marcus Hagerott public final int deleted; 3072d97b5f89ae1ae1b5e782e40b82ba60f0588f964Marcus Hagerott 3082d97b5f89ae1ae1b5e782e40b82ba60f0588f964Marcus Hagerott public GroupsProjection(Cursor cursor) { 3092d97b5f89ae1ae1b5e782e40b82ba60f0588f964Marcus Hagerott groupId = cursor.getColumnIndex(Groups._ID); 3102d97b5f89ae1ae1b5e782e40b82ba60f0588f964Marcus Hagerott title = cursor.getColumnIndex(Groups.TITLE); 3112d97b5f89ae1ae1b5e782e40b82ba60f0588f964Marcus Hagerott summaryCount = cursor.getColumnIndex(Groups.SUMMARY_COUNT); 3122d97b5f89ae1ae1b5e782e40b82ba60f0588f964Marcus Hagerott systemId = cursor.getColumnIndex(Groups.SYSTEM_ID); 3132d97b5f89ae1ae1b5e782e40b82ba60f0588f964Marcus Hagerott accountName = cursor.getColumnIndex(Groups.ACCOUNT_NAME); 3142d97b5f89ae1ae1b5e782e40b82ba60f0588f964Marcus Hagerott accountType = cursor.getColumnIndex(Groups.ACCOUNT_TYPE); 3152d97b5f89ae1ae1b5e782e40b82ba60f0588f964Marcus Hagerott dataSet = cursor.getColumnIndex(Groups.DATA_SET); 3162d97b5f89ae1ae1b5e782e40b82ba60f0588f964Marcus Hagerott autoAdd = cursor.getColumnIndex(Groups.AUTO_ADD); 3172d97b5f89ae1ae1b5e782e40b82ba60f0588f964Marcus Hagerott favorites = cursor.getColumnIndex(Groups.FAVORITES); 3182d97b5f89ae1ae1b5e782e40b82ba60f0588f964Marcus Hagerott isReadOnly = cursor.getColumnIndex(Groups.GROUP_IS_READ_ONLY); 3192d97b5f89ae1ae1b5e782e40b82ba60f0588f964Marcus Hagerott deleted = cursor.getColumnIndex(Groups.DELETED); 3202d97b5f89ae1ae1b5e782e40b82ba60f0588f964Marcus Hagerott } 3212d97b5f89ae1ae1b5e782e40b82ba60f0588f964Marcus Hagerott 3222d97b5f89ae1ae1b5e782e40b82ba60f0588f964Marcus Hagerott public GroupsProjection(String[] projection) { 3232d97b5f89ae1ae1b5e782e40b82ba60f0588f964Marcus Hagerott List<String> list = Arrays.asList(projection); 3242d97b5f89ae1ae1b5e782e40b82ba60f0588f964Marcus Hagerott groupId = list.indexOf(Groups._ID); 3252d97b5f89ae1ae1b5e782e40b82ba60f0588f964Marcus Hagerott title = list.indexOf(Groups.TITLE); 3262d97b5f89ae1ae1b5e782e40b82ba60f0588f964Marcus Hagerott summaryCount = list.indexOf(Groups.SUMMARY_COUNT); 3272d97b5f89ae1ae1b5e782e40b82ba60f0588f964Marcus Hagerott systemId = list.indexOf(Groups.SYSTEM_ID); 3282d97b5f89ae1ae1b5e782e40b82ba60f0588f964Marcus Hagerott accountName = list.indexOf(Groups.ACCOUNT_NAME); 3292d97b5f89ae1ae1b5e782e40b82ba60f0588f964Marcus Hagerott accountType = list.indexOf(Groups.ACCOUNT_TYPE); 3302d97b5f89ae1ae1b5e782e40b82ba60f0588f964Marcus Hagerott dataSet = list.indexOf(Groups.DATA_SET); 3312d97b5f89ae1ae1b5e782e40b82ba60f0588f964Marcus Hagerott autoAdd = list.indexOf(Groups.AUTO_ADD); 3322d97b5f89ae1ae1b5e782e40b82ba60f0588f964Marcus Hagerott favorites = list.indexOf(Groups.FAVORITES); 3332d97b5f89ae1ae1b5e782e40b82ba60f0588f964Marcus Hagerott isReadOnly = list.indexOf(Groups.GROUP_IS_READ_ONLY); 3342d97b5f89ae1ae1b5e782e40b82ba60f0588f964Marcus Hagerott deleted = list.indexOf(Groups.DELETED); 3352d97b5f89ae1ae1b5e782e40b82ba60f0588f964Marcus Hagerott } 3362d97b5f89ae1ae1b5e782e40b82ba60f0588f964Marcus Hagerott 3372d97b5f89ae1ae1b5e782e40b82ba60f0588f964Marcus Hagerott public String getTitle(Cursor cursor) { 3382d97b5f89ae1ae1b5e782e40b82ba60f0588f964Marcus Hagerott return cursor.getString(title); 3392d97b5f89ae1ae1b5e782e40b82ba60f0588f964Marcus Hagerott } 3402d97b5f89ae1ae1b5e782e40b82ba60f0588f964Marcus Hagerott 3412d97b5f89ae1ae1b5e782e40b82ba60f0588f964Marcus Hagerott public long getId(Cursor cursor) { 3422d97b5f89ae1ae1b5e782e40b82ba60f0588f964Marcus Hagerott return cursor.getLong(groupId); 3432d97b5f89ae1ae1b5e782e40b82ba60f0588f964Marcus Hagerott } 3442d97b5f89ae1ae1b5e782e40b82ba60f0588f964Marcus Hagerott 3452d97b5f89ae1ae1b5e782e40b82ba60f0588f964Marcus Hagerott public String getSystemId(Cursor cursor) { 3462d97b5f89ae1ae1b5e782e40b82ba60f0588f964Marcus Hagerott return cursor.getString(systemId); 3472d97b5f89ae1ae1b5e782e40b82ba60f0588f964Marcus Hagerott } 3482d97b5f89ae1ae1b5e782e40b82ba60f0588f964Marcus Hagerott 3492d97b5f89ae1ae1b5e782e40b82ba60f0588f964Marcus Hagerott public int getSummaryCount(Cursor cursor) { 3502d97b5f89ae1ae1b5e782e40b82ba60f0588f964Marcus Hagerott return cursor.getInt(summaryCount); 3512d97b5f89ae1ae1b5e782e40b82ba60f0588f964Marcus Hagerott } 3522d97b5f89ae1ae1b5e782e40b82ba60f0588f964Marcus Hagerott 3532d97b5f89ae1ae1b5e782e40b82ba60f0588f964Marcus Hagerott public boolean isEmptyFFCGroup(Cursor cursor) { 3542d97b5f89ae1ae1b5e782e40b82ba60f0588f964Marcus Hagerott if (accountType == -1 || isReadOnly == -1 || 3552d97b5f89ae1ae1b5e782e40b82ba60f0588f964Marcus Hagerott systemId == -1 || summaryCount == -1) { 3562d97b5f89ae1ae1b5e782e40b82ba60f0588f964Marcus Hagerott throw new IllegalArgumentException("Projection is missing required columns"); 3572d97b5f89ae1ae1b5e782e40b82ba60f0588f964Marcus Hagerott } 3582d97b5f89ae1ae1b5e782e40b82ba60f0588f964Marcus Hagerott return GoogleAccountType.ACCOUNT_TYPE.equals(cursor.getString(accountType)) 3592d97b5f89ae1ae1b5e782e40b82ba60f0588f964Marcus Hagerott && cursor.getInt(isReadOnly) != 0 3602d97b5f89ae1ae1b5e782e40b82ba60f0588f964Marcus Hagerott && isSystemIdFFC(cursor.getString(systemId)) 3612d97b5f89ae1ae1b5e782e40b82ba60f0588f964Marcus Hagerott && cursor.getInt(summaryCount) <= 0; 3622d97b5f89ae1ae1b5e782e40b82ba60f0588f964Marcus Hagerott } 3632d97b5f89ae1ae1b5e782e40b82ba60f0588f964Marcus Hagerott } 3646bb8718b04da174f3642fbdcefea0fee6086db3dWalter Jang} 365