1b9cd7fee03a41e56a0cea9aa2e1af3b28c5be590Jaikumar Ganesh/* 2b9cd7fee03a41e56a0cea9aa2e1af3b28c5be590Jaikumar Ganesh * Copyright (c) 2008-2009, Motorola, Inc. 3c7a57f31515107366589bd6875c3cc4af1fc806efredc * Copyright (C) 2009-2012, Broadcom Corporation 4b9cd7fee03a41e56a0cea9aa2e1af3b28c5be590Jaikumar Ganesh * 5b9cd7fee03a41e56a0cea9aa2e1af3b28c5be590Jaikumar Ganesh * All rights reserved. 6b9cd7fee03a41e56a0cea9aa2e1af3b28c5be590Jaikumar Ganesh * 7b9cd7fee03a41e56a0cea9aa2e1af3b28c5be590Jaikumar Ganesh * Redistribution and use in source and binary forms, with or without 8b9cd7fee03a41e56a0cea9aa2e1af3b28c5be590Jaikumar Ganesh * modification, are permitted provided that the following conditions are met: 9b9cd7fee03a41e56a0cea9aa2e1af3b28c5be590Jaikumar Ganesh * 10b9cd7fee03a41e56a0cea9aa2e1af3b28c5be590Jaikumar Ganesh * - Redistributions of source code must retain the above copyright notice, 11b9cd7fee03a41e56a0cea9aa2e1af3b28c5be590Jaikumar Ganesh * this list of conditions and the following disclaimer. 12b9cd7fee03a41e56a0cea9aa2e1af3b28c5be590Jaikumar Ganesh * 13b9cd7fee03a41e56a0cea9aa2e1af3b28c5be590Jaikumar Ganesh * - Redistributions in binary form must reproduce the above copyright notice, 14b9cd7fee03a41e56a0cea9aa2e1af3b28c5be590Jaikumar Ganesh * this list of conditions and the following disclaimer in the documentation 15b9cd7fee03a41e56a0cea9aa2e1af3b28c5be590Jaikumar Ganesh * and/or other materials provided with the distribution. 16b9cd7fee03a41e56a0cea9aa2e1af3b28c5be590Jaikumar Ganesh * 17b9cd7fee03a41e56a0cea9aa2e1af3b28c5be590Jaikumar Ganesh * - Neither the name of the Motorola, Inc. nor the names of its contributors 18b9cd7fee03a41e56a0cea9aa2e1af3b28c5be590Jaikumar Ganesh * may be used to endorse or promote products derived from this software 19b9cd7fee03a41e56a0cea9aa2e1af3b28c5be590Jaikumar Ganesh * without specific prior written permission. 20b9cd7fee03a41e56a0cea9aa2e1af3b28c5be590Jaikumar Ganesh * 21b9cd7fee03a41e56a0cea9aa2e1af3b28c5be590Jaikumar Ganesh * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 22b9cd7fee03a41e56a0cea9aa2e1af3b28c5be590Jaikumar Ganesh * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23b9cd7fee03a41e56a0cea9aa2e1af3b28c5be590Jaikumar Ganesh * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24b9cd7fee03a41e56a0cea9aa2e1af3b28c5be590Jaikumar Ganesh * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 25b9cd7fee03a41e56a0cea9aa2e1af3b28c5be590Jaikumar Ganesh * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 26b9cd7fee03a41e56a0cea9aa2e1af3b28c5be590Jaikumar Ganesh * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 27b9cd7fee03a41e56a0cea9aa2e1af3b28c5be590Jaikumar Ganesh * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 28b9cd7fee03a41e56a0cea9aa2e1af3b28c5be590Jaikumar Ganesh * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 29b9cd7fee03a41e56a0cea9aa2e1af3b28c5be590Jaikumar Ganesh * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 30b9cd7fee03a41e56a0cea9aa2e1af3b28c5be590Jaikumar Ganesh * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 31b9cd7fee03a41e56a0cea9aa2e1af3b28c5be590Jaikumar Ganesh * POSSIBILITY OF SUCH DAMAGE. 32b9cd7fee03a41e56a0cea9aa2e1af3b28c5be590Jaikumar Ganesh */ 332c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 342c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fanpackage com.android.bluetooth.pbap; 352c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 369d68ffa1079ca2e85a8ccf62bf8dca2f43f1ade3Tony Makimport com.android.bluetooth.R; 379d68ffa1079ca2e85a8ccf62bf8dca2f43f1ade3Tony Makimport com.android.bluetooth.util.DevicePolicyUtils; 389d68ffa1079ca2e85a8ccf62bf8dca2f43f1ade3Tony Makimport com.android.vcard.VCardComposer; 399d68ffa1079ca2e85a8ccf62bf8dca2f43f1ade3Tony Makimport com.android.vcard.VCardConfig; 409d68ffa1079ca2e85a8ccf62bf8dca2f43f1ade3Tony Makimport com.android.vcard.VCardPhoneNumberTranslationCallback; 419d68ffa1079ca2e85a8ccf62bf8dca2f43f1ade3Tony Mak 422f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yueimport android.content.ContentResolver; 432f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yueimport android.content.Context; 44198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawaimport android.database.Cursor; 459d68ffa1079ca2e85a8ccf62bf8dca2f43f1ade3Tony Makimport android.database.CursorWindowAllocationException; 465006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Waiimport android.database.MatrixCursor; 47198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawaimport android.net.Uri; 48198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawaimport android.provider.CallLog; 49198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawaimport android.provider.CallLog.Calls; 502f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yueimport android.provider.ContactsContract.CommonDataKinds; 519d68ffa1079ca2e85a8ccf62bf8dca2f43f1ade3Tony Makimport android.provider.ContactsContract.CommonDataKinds.Phone; 522f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yueimport android.provider.ContactsContract.Contacts; 532f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yueimport android.provider.ContactsContract.Data; 540dcd2262d853c2011e11617a8efba6758370c41fLiejun Taoimport android.provider.ContactsContract.PhoneLookup; 555006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Waiimport android.provider.ContactsContract.RawContactsEntity; 56d956b40b2f59599447ae0fa0762e055c0c0ce1a3Daisuke Miyakawaimport android.telephony.PhoneNumberUtils; 57198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawaimport android.text.TextUtils; 58198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawaimport android.util.Log; 595a37bc407ab1b8844c3541ff4e6653635b108bedHemant Guptaimport java.nio.ByteBuffer; 605a37bc407ab1b8844c3541ff4e6653635b108bedHemant Guptaimport java.util.Collections; 615a37bc407ab1b8844c3541ff4e6653635b108bedHemant Guptaimport java.util.Comparator; 625a37bc407ab1b8844c3541ff4e6653635b108bedHemant Guptaimport com.android.bluetooth.R; 635a37bc407ab1b8844c3541ff4e6653635b108bedHemant Guptaimport com.android.vcard.VCardComposer; 645a37bc407ab1b8844c3541ff4e6653635b108bedHemant Guptaimport com.android.vcard.VCardConfig; 655a37bc407ab1b8844c3541ff4e6653635b108bedHemant Guptaimport com.android.vcard.VCardPhoneNumberTranslationCallback; 66198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa 672f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yueimport java.io.IOException; 682f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yueimport java.io.OutputStream; 692c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fanimport java.util.ArrayList; 702c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 71198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawaimport javax.obex.Operation; 72198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawaimport javax.obex.ResponseCodes; 739d68ffa1079ca2e85a8ccf62bf8dca2f43f1ade3Tony Makimport javax.obex.ServerOperation; 74c7a57f31515107366589bd6875c3cc4af1fc806efredc 752c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fanpublic class BluetoothPbapVcardManager { 762f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue private static final String TAG = "BluetoothPbapVcardManager"; 772c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 784446eaa935994bc91d6d308303e8d27526b4590dLixin Yue private static final boolean V = BluetoothPbapService.VERBOSE; 794446eaa935994bc91d6d308303e8d27526b4590dLixin Yue 802c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan private ContentResolver mResolver; 812c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 822c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan private Context mContext; 832c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 84e10881ae39eb4affb7a78827f2060964e8534515Daisuke Miyakawa private static final int PHONE_NUMBER_COLUMN_INDEX = 3; 852c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 862f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue static final String SORT_ORDER_PHONE_NUMBER = CommonDataKinds.Phone.NUMBER + " ASC"; 874446eaa935994bc91d6d308303e8d27526b4590dLixin Yue 885006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai static final String[] PHONES_CONTACTS_PROJECTION = new String[] { 895006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai Phone.CONTACT_ID, // 0 905006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai Phone.DISPLAY_NAME, // 1 915006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai }; 925006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai 935006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai static final String[] PHONE_LOOKUP_PROJECTION = new String[] { 945006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai PhoneLookup._ID, PhoneLookup.DISPLAY_NAME 952b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh }; 962b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh 972b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh static final int CONTACTS_ID_COLUMN_INDEX = 0; 982b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh 992b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh static final int CONTACTS_NAME_COLUMN_INDEX = 1; 1002b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh 1015a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta static long LAST_FETCHED_TIME_STAMP; 1025a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta 1032b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh // call histories use dynamic handles, and handles should order by date; the 1042b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh // most recently one should be the first handle. In table "calls", _id and 1052b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh // date are consistent in ordering, to implement simply, we sort by _id 1062b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh // here. 1072b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh static final String CALLLOG_SORT_ORDER = Calls._ID + " DESC"; 1082b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh 1095a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta private static final int NEED_SEND_BODY = -1; 1105a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta 1112c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan public BluetoothPbapVcardManager(final Context context) { 1122c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan mContext = context; 1132c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan mResolver = mContext.getContentResolver(); 1145a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta LAST_FETCHED_TIME_STAMP = System.currentTimeMillis(); 1152c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 1162c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 117c7a57f31515107366589bd6875c3cc4af1fc806efredc /** 118c7a57f31515107366589bd6875c3cc4af1fc806efredc * Create an owner vcard from the configured profile 119c7a57f31515107366589bd6875c3cc4af1fc806efredc * @param vcardType21 120c7a57f31515107366589bd6875c3cc4af1fc806efredc * @return 121c7a57f31515107366589bd6875c3cc4af1fc806efredc */ 1225a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta private final String getOwnerPhoneNumberVcardFromProfile( 1235a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta final boolean vcardType21, final byte[] filter) { 124c7a57f31515107366589bd6875c3cc4af1fc806efredc // Currently only support Generic Vcard 2.1 and 3.0 125c7a57f31515107366589bd6875c3cc4af1fc806efredc int vcardType; 126c7a57f31515107366589bd6875c3cc4af1fc806efredc if (vcardType21) { 127c7a57f31515107366589bd6875c3cc4af1fc806efredc vcardType = VCardConfig.VCARD_TYPE_V21_GENERIC; 128c7a57f31515107366589bd6875c3cc4af1fc806efredc } else { 129c7a57f31515107366589bd6875c3cc4af1fc806efredc vcardType = VCardConfig.VCARD_TYPE_V30_GENERIC; 130c7a57f31515107366589bd6875c3cc4af1fc806efredc } 1314a53a55dc10d3a26c94e5844f7d4a2565a67142cfredc 1324a53a55dc10d3a26c94e5844f7d4a2565a67142cfredc if (!BluetoothPbapConfig.includePhotosInVcard()) { 1334a53a55dc10d3a26c94e5844f7d4a2565a67142cfredc vcardType |= VCardConfig.FLAG_REFRAIN_IMAGE_EXPORT; 1344a53a55dc10d3a26c94e5844f7d4a2565a67142cfredc } 1354a53a55dc10d3a26c94e5844f7d4a2565a67142cfredc 136c7a57f31515107366589bd6875c3cc4af1fc806efredc return BluetoothPbapUtils.createProfileVCard(mContext, vcardType,filter); 137c7a57f31515107366589bd6875c3cc4af1fc806efredc } 138c7a57f31515107366589bd6875c3cc4af1fc806efredc 139c7a57f31515107366589bd6875c3cc4af1fc806efredc public final String getOwnerPhoneNumberVcard(final boolean vcardType21, final byte[] filter) { 140c7a57f31515107366589bd6875c3cc4af1fc806efredc //Owner vCard enhancement: Use "ME" profile if configured 141c7a57f31515107366589bd6875c3cc4af1fc806efredc if (BluetoothPbapConfig.useProfileForOwnerVcard()) { 142c7a57f31515107366589bd6875c3cc4af1fc806efredc String vcard = getOwnerPhoneNumberVcardFromProfile(vcardType21, filter); 143c7a57f31515107366589bd6875c3cc4af1fc806efredc if (vcard != null && vcard.length() != 0) { 144c7a57f31515107366589bd6875c3cc4af1fc806efredc return vcard; 145c7a57f31515107366589bd6875c3cc4af1fc806efredc } 146c7a57f31515107366589bd6875c3cc4af1fc806efredc } 147c7a57f31515107366589bd6875c3cc4af1fc806efredc //End enhancement 148c7a57f31515107366589bd6875c3cc4af1fc806efredc 1493c4d2c77c2fffe675fbe89ba58856686b6873d2fDaisuke Miyakawa BluetoothPbapCallLogComposer composer = new BluetoothPbapCallLogComposer(mContext); 1502f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue String name = BluetoothPbapService.getLocalPhoneName(); 1512f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue String number = BluetoothPbapService.getLocalPhoneNum(); 1522f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue String vcard = composer.composeVCardForPhoneOwnNumber(Phone.TYPE_MOBILE, name, number, 1532f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue vcardType21); 1542f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue return vcard; 1552c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 1562c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 1572f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue public final int getPhonebookSize(final int type) { 1582f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue int size; 1592f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue switch (type) { 1602f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue case BluetoothPbapObexServer.ContentType.PHONEBOOK: 1612f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue size = getContactsSize(); 1622f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue break; 1632f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue default: 1642f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue size = getCallHistorySize(type); 1652f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue break; 1662c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 167c7a57f31515107366589bd6875c3cc4af1fc806efredc if (V) Log.v(TAG, "getPhonebookSize size = " + size + " type = " + type); 1682f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue return size; 1692c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 1702c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 1712f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue public final int getContactsSize() { 1723178b08c6823899dbb58513673bf2a80f637be7cRicky Wai final Uri myUri = DevicePolicyUtils.getEnterprisePhoneUri(mContext); 1732f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue Cursor contactCursor = null; 1742f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue try { 1754ca05d6f02264b0eb2983e43d34ca4051434a4d4Ajay Panicker contactCursor = mResolver.query( 1764ca05d6f02264b0eb2983e43d34ca4051434a4d4Ajay Panicker myUri, new String[] {Phone.CONTACT_ID}, null, null, Phone.CONTACT_ID); 1775006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai if (contactCursor == null) { 1785006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai return 0; 1792f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue } 180c438463431b171a67b22b50886ef8dd737c44004Andre Eisenbach return getDistinctContactIdSize(contactCursor) + 1; // always has the 0.vcf 181c592e5a6de0011cd60f23ac18a7bd56d8eeb5dd1Hemant Gupta } catch (CursorWindowAllocationException e) { 182c592e5a6de0011cd60f23ac18a7bd56d8eeb5dd1Hemant Gupta Log.e(TAG, "CursorWindowAllocationException while getting Contacts size"); 1832f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue } finally { 1842f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue if (contactCursor != null) { 1852f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue contactCursor.close(); 1862f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue } 1872c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 1885006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai return 0; 1892c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 1902c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 1912f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue public final int getCallHistorySize(final int type) { 1922b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh final Uri myUri = CallLog.Calls.CONTENT_URI; 1932f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue String selection = BluetoothPbapObexServer.createSelectionPara(type); 1942f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue int size = 0; 1952f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue Cursor callCursor = null; 1962f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue try { 1972f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue callCursor = mResolver.query(myUri, null, selection, null, 1982f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue CallLog.Calls.DEFAULT_SORT_ORDER); 1992f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue if (callCursor != null) { 2002f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue size = callCursor.getCount(); 2014446eaa935994bc91d6d308303e8d27526b4590dLixin Yue } 202c592e5a6de0011cd60f23ac18a7bd56d8eeb5dd1Hemant Gupta } catch (CursorWindowAllocationException e) { 203c592e5a6de0011cd60f23ac18a7bd56d8eeb5dd1Hemant Gupta Log.e(TAG, "CursorWindowAllocationException while getting CallHistory size"); 2042f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue } finally { 2052f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue if (callCursor != null) { 2062f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue callCursor.close(); 207c592e5a6de0011cd60f23ac18a7bd56d8eeb5dd1Hemant Gupta callCursor = null; 2084446eaa935994bc91d6d308303e8d27526b4590dLixin Yue } 2092f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue } 2102f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue return size; 2112f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue } 2124446eaa935994bc91d6d308303e8d27526b4590dLixin Yue 2132f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue public final ArrayList<String> loadCallHistoryList(final int type) { 2142b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh final Uri myUri = CallLog.Calls.CONTENT_URI; 2152f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue String selection = BluetoothPbapObexServer.createSelectionPara(type); 2162f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue String[] projection = new String[] { 2179674eb043aeb1474aa23ddd0739e3b8f05432630Jay Shrauner Calls.NUMBER, Calls.CACHED_NAME, Calls.NUMBER_PRESENTATION 2182f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue }; 2192f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue final int CALLS_NUMBER_COLUMN_INDEX = 0; 2202f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue final int CALLS_NAME_COLUMN_INDEX = 1; 2219674eb043aeb1474aa23ddd0739e3b8f05432630Jay Shrauner final int CALLS_NUMBER_PRESENTATION_COLUMN_INDEX = 2; 2222f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue 2232f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue Cursor callCursor = null; 2242f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue ArrayList<String> list = new ArrayList<String>(); 2252f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue try { 2262f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue callCursor = mResolver.query(myUri, projection, selection, null, 2272b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh CALLLOG_SORT_ORDER); 2282f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue if (callCursor != null) { 2292f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue for (callCursor.moveToFirst(); !callCursor.isAfterLast(); 2302f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue callCursor.moveToNext()) { 2312f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue String name = callCursor.getString(CALLS_NAME_COLUMN_INDEX); 2322f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue if (TextUtils.isEmpty(name)) { 23377ba5f6684f4dd7e4b7fc37982271da5654aec07Staffan Lindvall // name not found, use number instead 2349674eb043aeb1474aa23ddd0739e3b8f05432630Jay Shrauner final int numberPresentation = callCursor.getInt( 2359674eb043aeb1474aa23ddd0739e3b8f05432630Jay Shrauner CALLS_NUMBER_PRESENTATION_COLUMN_INDEX); 2369674eb043aeb1474aa23ddd0739e3b8f05432630Jay Shrauner if (numberPresentation != Calls.PRESENTATION_ALLOWED) { 23777ba5f6684f4dd7e4b7fc37982271da5654aec07Staffan Lindvall name = mContext.getString(R.string.unknownNumber); 2389674eb043aeb1474aa23ddd0739e3b8f05432630Jay Shrauner } else { 2399674eb043aeb1474aa23ddd0739e3b8f05432630Jay Shrauner name = callCursor.getString(CALLS_NUMBER_COLUMN_INDEX); 24077ba5f6684f4dd7e4b7fc37982271da5654aec07Staffan Lindvall } 2412f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue } 2422f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue list.add(name); 2432f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue } 2442f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue } 245c592e5a6de0011cd60f23ac18a7bd56d8eeb5dd1Hemant Gupta } catch (CursorWindowAllocationException e) { 246c592e5a6de0011cd60f23ac18a7bd56d8eeb5dd1Hemant Gupta Log.e(TAG, "CursorWindowAllocationException while loading CallHistory"); 2472f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue } finally { 2482f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue if (callCursor != null) { 2492f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue callCursor.close(); 250c592e5a6de0011cd60f23ac18a7bd56d8eeb5dd1Hemant Gupta callCursor = null; 2512c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 2522c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 2532f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue return list; 2542c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 2552c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 2562b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh public final ArrayList<String> getPhonebookNameList(final int orderByWhat) { 2572f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue ArrayList<String> nameList = new ArrayList<String>(); 258c7a57f31515107366589bd6875c3cc4af1fc806efredc //Owner vCard enhancement. Use "ME" profile if configured 259c7a57f31515107366589bd6875c3cc4af1fc806efredc String ownerName = null; 260c7a57f31515107366589bd6875c3cc4af1fc806efredc if (BluetoothPbapConfig.useProfileForOwnerVcard()) { 261c7a57f31515107366589bd6875c3cc4af1fc806efredc ownerName = BluetoothPbapUtils.getProfileName(mContext); 262c7a57f31515107366589bd6875c3cc4af1fc806efredc } 263c7a57f31515107366589bd6875c3cc4af1fc806efredc if (ownerName == null || ownerName.length()==0) { 264c7a57f31515107366589bd6875c3cc4af1fc806efredc ownerName = BluetoothPbapService.getLocalPhoneName(); 265c7a57f31515107366589bd6875c3cc4af1fc806efredc } 266c7a57f31515107366589bd6875c3cc4af1fc806efredc nameList.add(ownerName); 267c7a57f31515107366589bd6875c3cc4af1fc806efredc //End enhancement 2684446eaa935994bc91d6d308303e8d27526b4590dLixin Yue 2693178b08c6823899dbb58513673bf2a80f637be7cRicky Wai final Uri myUri = DevicePolicyUtils.getEnterprisePhoneUri(mContext); 2702b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh Cursor contactCursor = null; 2713c8b50f8dc1c4ce11168fb42a884f604d1810c46Hemant Gupta // By default order is indexed 2723c8b50f8dc1c4ce11168fb42a884f604d1810c46Hemant Gupta String orderBy = Phone.CONTACT_ID; 2732f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue try { 2743c8b50f8dc1c4ce11168fb42a884f604d1810c46Hemant Gupta if (orderByWhat == BluetoothPbapObexServer.ORDER_BY_ALPHABETICAL) { 2753c8b50f8dc1c4ce11168fb42a884f604d1810c46Hemant Gupta orderBy = Phone.DISPLAY_NAME; 2763c8b50f8dc1c4ce11168fb42a884f604d1810c46Hemant Gupta } 2774ca05d6f02264b0eb2983e43d34ca4051434a4d4Ajay Panicker contactCursor = mResolver.query(myUri, PHONES_CONTACTS_PROJECTION, null, null, orderBy); 2782b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh if (contactCursor != null) { 2795006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai appendDistinctNameIdList(nameList, 280c438463431b171a67b22b50886ef8dd737c44004Andre Eisenbach mContext.getString(android.R.string.unknownName), 281c438463431b171a67b22b50886ef8dd737c44004Andre Eisenbach contactCursor); 2822f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue } 2833c8b50f8dc1c4ce11168fb42a884f604d1810c46Hemant Gupta } catch (CursorWindowAllocationException e) { 2843c8b50f8dc1c4ce11168fb42a884f604d1810c46Hemant Gupta Log.e(TAG, "CursorWindowAllocationException while getting phonebook name list"); 285bf37a0295d110b77b635ca2986172bbdd59331bbAndre Eisenbach } catch (Exception e) { 2863c8b50f8dc1c4ce11168fb42a884f604d1810c46Hemant Gupta Log.e(TAG, "Exception while getting phonebook name list", e); 2872f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue } finally { 2882b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh if (contactCursor != null) { 2892b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh contactCursor.close(); 290c592e5a6de0011cd60f23ac18a7bd56d8eeb5dd1Hemant Gupta contactCursor = null; 2912f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue } 2922f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue } 2932f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue return nameList; 2944446eaa935994bc91d6d308303e8d27526b4590dLixin Yue } 2954446eaa935994bc91d6d308303e8d27526b4590dLixin Yue 2965a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta final ArrayList<String> getSelectedPhonebookNameList(final int orderByWhat, 2975a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta final boolean vcardType21, int needSendBody, int pbSize, byte[] selector, 2985a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta String vcardselectorop) { 2995a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta ArrayList<String> nameList = new ArrayList<String>(); 3005a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta PropertySelector vcardselector = new PropertySelector(selector); 3015a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta VCardComposer composer = null; 3025a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta int vcardType; 3035a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta 3045a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta if (vcardType21) { 3055a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta vcardType = VCardConfig.VCARD_TYPE_V21_GENERIC; 3065a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta } else { 3075a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta vcardType = VCardConfig.VCARD_TYPE_V30_GENERIC; 3085a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta } 3095a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta 3105a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta composer = BluetoothPbapUtils.createFilteredVCardComposer(mContext, vcardType, null); 3115a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta composer.setPhoneNumberTranslationCallback(new VCardPhoneNumberTranslationCallback() { 3125a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta 3135a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta public String onValueReceived( 3145a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta String rawValue, int type, String label, boolean isPrimary) { 3155a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta String numberWithControlSequence = rawValue.replace(PhoneNumberUtils.PAUSE, 'p') 3165a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta .replace(PhoneNumberUtils.WAIT, 'w'); 3175a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta return numberWithControlSequence; 3185a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta } 3195a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta }); 3205a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta 3215a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta // Owner vCard enhancement. Use "ME" profile if configured 3225a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta String ownerName = null; 3235a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta if (BluetoothPbapConfig.useProfileForOwnerVcard()) { 3245a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta ownerName = BluetoothPbapUtils.getProfileName(mContext); 3255a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta } 3265a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta if (ownerName == null || ownerName.length() == 0) { 3275a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta ownerName = BluetoothPbapService.getLocalPhoneName(); 3285a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta } 3295a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta nameList.add(ownerName); 3305a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta // End enhancement 3315a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta 3325a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta final Uri myUri = DevicePolicyUtils.getEnterprisePhoneUri(mContext); 3335a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta Cursor contactCursor = null; 3345a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta try { 3355a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta contactCursor = mResolver.query( 3365a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta myUri, PHONES_CONTACTS_PROJECTION, null, null, Phone.CONTACT_ID); 3375a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta 3385a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta if (contactCursor != null) { 3395a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta if (!composer.initWithCallback( 3405a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta contactCursor, new EnterpriseRawContactEntitlesInfoCallback())) { 3415a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta return nameList; 3425a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta } 3435a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta 3445a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta while (!composer.isAfterLast()) { 3455a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta String vcard = composer.createOneEntry(); 3465a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta if (vcard == null) { 3475a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta Log.e(TAG, "Failed to read a contact. Error reason: " 3485a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta + composer.getErrorReason()); 3495a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta return nameList; 3505a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta } 3515a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta if (V) Log.v(TAG, "Checking selected bits in the vcard composer" + vcard); 3525a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta 3535a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta if (!vcardselector.CheckVcardSelector(vcard, vcardselectorop)) { 3545a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta Log.e(TAG, "vcard selector check fail"); 3555a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta vcard = null; 3565a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta pbSize--; 3575a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta continue; 3585a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta } else { 3595a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta String name = vcardselector.getName(vcard); 3605a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta if (TextUtils.isEmpty(name)) { 3615a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta name = mContext.getString(android.R.string.unknownName); 3625a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta } 3635a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta nameList.add(name); 3645a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta } 3655a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta } 3665a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta if (orderByWhat == BluetoothPbapObexServer.ORDER_BY_INDEXED) { 3675a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta if (V) Log.v(TAG, "getPhonebookNameList, order by index"); 3685a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta // Do not need to do anything, as we sort it by index already 3695a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta } else if (orderByWhat == BluetoothPbapObexServer.ORDER_BY_ALPHABETICAL) { 3705a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta if (V) Log.v(TAG, "getPhonebookNameList, order by alpha"); 3715a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta Collections.sort(nameList); 3725a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta } 3735a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta } 3745a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta } catch (CursorWindowAllocationException e) { 3755a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta Log.e(TAG, "CursorWindowAllocationException while getting Phonebook name list"); 3765a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta } finally { 3775a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta if (contactCursor != null) { 3785a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta contactCursor.close(); 3795a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta contactCursor = null; 3805a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta } 3815a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta } 3825a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta return nameList; 3835a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta } 3845a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta 3850dcd2262d853c2011e11617a8efba6758370c41fLiejun Tao public final ArrayList<String> getContactNamesByNumber(final String phoneNumber) { 3860dcd2262d853c2011e11617a8efba6758370c41fLiejun Tao ArrayList<String> nameList = new ArrayList<String>(); 3871321cd814a7406260ba6282d9c71e1a2d8925262Hemant Gupta ArrayList<String> tempNameList = new ArrayList<String>(); 3880dcd2262d853c2011e11617a8efba6758370c41fLiejun Tao 3890dcd2262d853c2011e11617a8efba6758370c41fLiejun Tao Cursor contactCursor = null; 390c438463431b171a67b22b50886ef8dd737c44004Andre Eisenbach Uri uri = null; 391c438463431b171a67b22b50886ef8dd737c44004Andre Eisenbach String[] projection = null; 392c438463431b171a67b22b50886ef8dd737c44004Andre Eisenbach 3935006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai if (TextUtils.isEmpty(phoneNumber)) { 3943178b08c6823899dbb58513673bf2a80f637be7cRicky Wai uri = DevicePolicyUtils.getEnterprisePhoneUri(mContext); 395c438463431b171a67b22b50886ef8dd737c44004Andre Eisenbach projection = PHONES_CONTACTS_PROJECTION; 3964bba23a751f042596561eab0e677135d5267bcdfStaffan Lindvall } else { 397c438463431b171a67b22b50886ef8dd737c44004Andre Eisenbach uri = Uri.withAppendedPath(getPhoneLookupFilterUri(), 398c438463431b171a67b22b50886ef8dd737c44004Andre Eisenbach Uri.encode(phoneNumber)); 399c438463431b171a67b22b50886ef8dd737c44004Andre Eisenbach projection = PHONE_LOOKUP_PROJECTION; 4004bba23a751f042596561eab0e677135d5267bcdfStaffan Lindvall } 4014446eaa935994bc91d6d308303e8d27526b4590dLixin Yue 4022f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue try { 4034ca05d6f02264b0eb2983e43d34ca4051434a4d4Ajay Panicker contactCursor = mResolver.query(uri, projection, null, null, Phone.CONTACT_ID); 4040dcd2262d853c2011e11617a8efba6758370c41fLiejun Tao 4050dcd2262d853c2011e11617a8efba6758370c41fLiejun Tao if (contactCursor != null) { 4065006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai appendDistinctNameIdList(nameList, 4075006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai mContext.getString(android.R.string.unknownName), 408c438463431b171a67b22b50886ef8dd737c44004Andre Eisenbach contactCursor); 4095006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai if (V) { 4105006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai for (String nameIdStr : nameList) { 4115006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai Log.v(TAG, "got name " + nameIdStr + " by number " + phoneNumber); 4122f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue } 4132f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue } 4142f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue } 415c592e5a6de0011cd60f23ac18a7bd56d8eeb5dd1Hemant Gupta } catch (CursorWindowAllocationException e) { 416c592e5a6de0011cd60f23ac18a7bd56d8eeb5dd1Hemant Gupta Log.e(TAG, "CursorWindowAllocationException while getting contact names"); 4172f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue } finally { 4180dcd2262d853c2011e11617a8efba6758370c41fLiejun Tao if (contactCursor != null) { 4190dcd2262d853c2011e11617a8efba6758370c41fLiejun Tao contactCursor.close(); 420c592e5a6de0011cd60f23ac18a7bd56d8eeb5dd1Hemant Gupta contactCursor = null; 4212f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue } 4222c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 4231321cd814a7406260ba6282d9c71e1a2d8925262Hemant Gupta int tempListSize = tempNameList.size(); 4241321cd814a7406260ba6282d9c71e1a2d8925262Hemant Gupta for (int index = 0; index < tempListSize; index++) { 4251321cd814a7406260ba6282d9c71e1a2d8925262Hemant Gupta String object = tempNameList.get(index); 4261321cd814a7406260ba6282d9c71e1a2d8925262Hemant Gupta if (!nameList.contains(object)) 4271321cd814a7406260ba6282d9c71e1a2d8925262Hemant Gupta nameList.add(object); 4281321cd814a7406260ba6282d9c71e1a2d8925262Hemant Gupta } 4291321cd814a7406260ba6282d9c71e1a2d8925262Hemant Gupta 4300dcd2262d853c2011e11617a8efba6758370c41fLiejun Tao return nameList; 4312c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 4322c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 4335a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta byte[] getCallHistoryPrimaryFolderVersion(final int type) { 4345a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta final Uri myUri = CallLog.Calls.CONTENT_URI; 4355a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta String selection = BluetoothPbapObexServer.createSelectionPara(type); 4365a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta selection = selection + " AND date >= " + LAST_FETCHED_TIME_STAMP; 4375a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta 4385a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta Log.d(TAG, "LAST_FETCHED_TIME_STAMP is " + LAST_FETCHED_TIME_STAMP); 4395a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta Cursor callCursor = null; 4405a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta long count = 0; 4415a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta long primaryVcMsb = 0; 4425a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta ArrayList<String> list = new ArrayList<String>(); 4435a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta try { 4445a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta callCursor = mResolver.query(myUri, null, selection, null, null); 4455a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta while (callCursor != null && callCursor.moveToNext()) { 4465a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta count = count + 1; 4475a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta } 4485a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta } catch (Exception e) { 4495a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta Log.e(TAG, "exception while fetching callHistory pvc"); 4505a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta } finally { 4515a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta if (callCursor != null) { 4525a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta callCursor.close(); 4535a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta callCursor = null; 4545a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta } 4555a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta } 4565a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta 4575a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta LAST_FETCHED_TIME_STAMP = System.currentTimeMillis(); 4585a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta Log.d(TAG, "getCallHistoryPrimaryFolderVersion count is " + count + " type is " + type); 4595a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta ByteBuffer pvc = ByteBuffer.allocate(16); 4605a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta pvc.putLong(primaryVcMsb); 461cf92c2759b709461acf7c36c08f4eef9c8004c85Hemant Gupta Log.d(TAG, "primaryVersionCounter is " + BluetoothPbapUtils.primaryVersionCounter); 4625a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta pvc.putLong(count); 4635a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta return pvc.array(); 4645a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta } 4655a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta 4665a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta final int composeAndSendSelectedCallLogVcards(final int type, Operation op, 4675a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta final int startPoint, final int endPoint, final boolean vcardType21, int needSendBody, 4685a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta int pbSize, boolean ignorefilter, byte[] filter, byte[] vcardselector, 4695a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta String vcardselectorop, boolean vcardselect) { 47059256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh if (startPoint < 1 || startPoint > endPoint) { 47159256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh Log.e(TAG, "internal error: startPoint or endPoint is not correct."); 47259256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh return ResponseCodes.OBEX_HTTP_INTERNAL_ERROR; 47359256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh } 4742f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue String typeSelection = BluetoothPbapObexServer.createSelectionPara(type); 47559256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh 4762b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh final Uri myUri = CallLog.Calls.CONTENT_URI; 47759256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh final String[] CALLLOG_PROJECTION = new String[] { 47859256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh CallLog.Calls._ID, // 0 47959256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh }; 48059256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh final int ID_COLUMN_INDEX = 0; 48159256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh 48259256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh Cursor callsCursor = null; 48359256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh long startPointId = 0; 48459256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh long endPointId = 0; 48559256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh try { 48659256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh // Need test to see if order by _ID is ok here, or by date? 48759256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh callsCursor = mResolver.query(myUri, CALLLOG_PROJECTION, typeSelection, null, 4882b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh CALLLOG_SORT_ORDER); 48959256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh if (callsCursor != null) { 49059256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh callsCursor.moveToPosition(startPoint - 1); 49159256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh startPointId = callsCursor.getLong(ID_COLUMN_INDEX); 49259256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh if (V) Log.v(TAG, "Call Log query startPointId = " + startPointId); 49359256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh if (startPoint == endPoint) { 49459256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh endPointId = startPointId; 49559256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh } else { 49659256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh callsCursor.moveToPosition(endPoint - 1); 49759256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh endPointId = callsCursor.getLong(ID_COLUMN_INDEX); 49859256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh } 49959256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh if (V) Log.v(TAG, "Call log query endPointId = " + endPointId); 50059256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh } 501c592e5a6de0011cd60f23ac18a7bd56d8eeb5dd1Hemant Gupta } catch (CursorWindowAllocationException e) { 502c592e5a6de0011cd60f23ac18a7bd56d8eeb5dd1Hemant Gupta Log.e(TAG, "CursorWindowAllocationException while composing calllog vcards"); 50359256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh } finally { 50459256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh if (callsCursor != null) { 50559256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh callsCursor.close(); 506c592e5a6de0011cd60f23ac18a7bd56d8eeb5dd1Hemant Gupta callsCursor = null; 50759256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh } 50859256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh } 50959256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh 5102f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue String recordSelection; 5112f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue if (startPoint == endPoint) { 51259256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh recordSelection = Calls._ID + "=" + startPointId; 5132f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue } else { 5142b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh // The query to call table is by "_id DESC" order, so change 5152b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh // correspondingly. 5162b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh recordSelection = Calls._ID + ">=" + endPointId + " AND " + Calls._ID + "<=" 5172b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh + startPointId; 5184446eaa935994bc91d6d308303e8d27526b4590dLixin Yue } 5194446eaa935994bc91d6d308303e8d27526b4590dLixin Yue 5202f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue String selection; 5212f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue if (typeSelection == null) { 5222f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue selection = recordSelection; 5232f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue } else { 5242f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue selection = "(" + typeSelection + ") AND (" + recordSelection + ")"; 5254446eaa935994bc91d6d308303e8d27526b4590dLixin Yue } 5264446eaa935994bc91d6d308303e8d27526b4590dLixin Yue 52759256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh if (V) Log.v(TAG, "Call log query selection is: " + selection); 5284446eaa935994bc91d6d308303e8d27526b4590dLixin Yue 5295a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta return composeCallLogsAndSendSelectedVCards(op, selection, vcardType21, needSendBody, 5305a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta pbSize, null, ignorefilter, filter, vcardselector, vcardselectorop, vcardselect); 5314446eaa935994bc91d6d308303e8d27526b4590dLixin Yue } 5324446eaa935994bc91d6d308303e8d27526b4590dLixin Yue 5335a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta final int composeAndSendPhonebookVcards(Operation op, final int startPoint, final int endPoint, 5345a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta final boolean vcardType21, String ownerVCard, int needSendBody, int pbSize, 5355a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta boolean ignorefilter, byte[] filter, byte[] vcardselector, String vcardselectorop, 5365a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta boolean vcardselect) { 53759256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh if (startPoint < 1 || startPoint > endPoint) { 53859256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh Log.e(TAG, "internal error: startPoint or endPoint is not correct."); 53959256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh return ResponseCodes.OBEX_HTTP_INTERNAL_ERROR; 54059256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh } 54159256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh 5423178b08c6823899dbb58513673bf2a80f637be7cRicky Wai final Uri myUri = DevicePolicyUtils.getEnterprisePhoneUri(mContext); 54359256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh Cursor contactCursor = null; 5440ff315d60bb44c5cc4223abff48e086defaec8adTony Mak Cursor contactIdCursor = new MatrixCursor(new String[] { 5450ff315d60bb44c5cc4223abff48e086defaec8adTony Mak Phone.CONTACT_ID 5460ff315d60bb44c5cc4223abff48e086defaec8adTony Mak }); 54759256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh try { 5484ca05d6f02264b0eb2983e43d34ca4051434a4d4Ajay Panicker contactCursor = mResolver.query( 5494ca05d6f02264b0eb2983e43d34ca4051434a4d4Ajay Panicker myUri, PHONES_CONTACTS_PROJECTION, null, null, Phone.CONTACT_ID); 55059256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh if (contactCursor != null) { 5510ff315d60bb44c5cc4223abff48e086defaec8adTony Mak contactIdCursor = ContactCursorFilter.filterByRange(contactCursor, startPoint, 5520ff315d60bb44c5cc4223abff48e086defaec8adTony Mak endPoint); 55359256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh } 554c592e5a6de0011cd60f23ac18a7bd56d8eeb5dd1Hemant Gupta } catch (CursorWindowAllocationException e) { 555c592e5a6de0011cd60f23ac18a7bd56d8eeb5dd1Hemant Gupta Log.e(TAG, "CursorWindowAllocationException while composing phonebook vcards"); 55659256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh } finally { 55759256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh if (contactCursor != null) { 55859256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh contactCursor.close(); 55959256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh } 56059256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh } 5615a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta 5625a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta if (vcardselect) 5635a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta return composeContactsAndSendSelectedVCards(op, contactIdCursor, vcardType21, 5645a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta ownerVCard, needSendBody, pbSize, ignorefilter, filter, vcardselector, 5655a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta vcardselectorop); 5665a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta else 5675a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta return composeContactsAndSendVCards( 5685a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta op, contactIdCursor, vcardType21, ownerVCard, ignorefilter, filter); 5694446eaa935994bc91d6d308303e8d27526b4590dLixin Yue } 5704446eaa935994bc91d6d308303e8d27526b4590dLixin Yue 5715a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta final int composeAndSendPhonebookOneVcard(Operation op, final int offset, 5725a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta final boolean vcardType21, String ownerVCard, int orderByWhat, boolean ignorefilter, 5735a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta byte[] filter) { 5742b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh if (offset < 1) { 5752b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh Log.e(TAG, "Internal error: offset is not correct."); 5762b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh return ResponseCodes.OBEX_HTTP_INTERNAL_ERROR; 5772b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh } 5783178b08c6823899dbb58513673bf2a80f637be7cRicky Wai final Uri myUri = DevicePolicyUtils.getEnterprisePhoneUri(mContext); 5790ff315d60bb44c5cc4223abff48e086defaec8adTony Mak 5802b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh Cursor contactCursor = null; 5810ff315d60bb44c5cc4223abff48e086defaec8adTony Mak Cursor contactIdCursor = new MatrixCursor(new String[] { 5820ff315d60bb44c5cc4223abff48e086defaec8adTony Mak Phone.CONTACT_ID 5830ff315d60bb44c5cc4223abff48e086defaec8adTony Mak }); 5843c8b50f8dc1c4ce11168fb42a884f604d1810c46Hemant Gupta // By default order is indexed 5853c8b50f8dc1c4ce11168fb42a884f604d1810c46Hemant Gupta String orderBy = Phone.CONTACT_ID; 5865006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai try { 5873c8b50f8dc1c4ce11168fb42a884f604d1810c46Hemant Gupta if (orderByWhat == BluetoothPbapObexServer.ORDER_BY_ALPHABETICAL) { 5883c8b50f8dc1c4ce11168fb42a884f604d1810c46Hemant Gupta orderBy = Phone.DISPLAY_NAME; 5893c8b50f8dc1c4ce11168fb42a884f604d1810c46Hemant Gupta } 5904ca05d6f02264b0eb2983e43d34ca4051434a4d4Ajay Panicker contactCursor = mResolver.query(myUri, PHONES_CONTACTS_PROJECTION, null, null, orderBy); 5915006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai } catch (CursorWindowAllocationException e) { 5925006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai Log.e(TAG, 5933c8b50f8dc1c4ce11168fb42a884f604d1810c46Hemant Gupta "CursorWindowAllocationException while composing phonebook one vcard"); 5945006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai } finally { 5955006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai if (contactCursor != null) { 5963c8b50f8dc1c4ce11168fb42a884f604d1810c46Hemant Gupta contactIdCursor = ContactCursorFilter.filterByOffset(contactCursor, offset); 5975006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai contactCursor.close(); 5983c8b50f8dc1c4ce11168fb42a884f604d1810c46Hemant Gupta contactCursor = null; 5992b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh } 6005006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai } 6015a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta return composeContactsAndSendVCards( 6025a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta op, contactIdCursor, vcardType21, ownerVCard, ignorefilter, filter); 6030ff315d60bb44c5cc4223abff48e086defaec8adTony Mak } 6040ff315d60bb44c5cc4223abff48e086defaec8adTony Mak 6050ff315d60bb44c5cc4223abff48e086defaec8adTony Mak /** 6060ff315d60bb44c5cc4223abff48e086defaec8adTony Mak * Filter contact cursor by certain condition. 6070ff315d60bb44c5cc4223abff48e086defaec8adTony Mak */ 6085a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta private static final class ContactCursorFilter { 6090ff315d60bb44c5cc4223abff48e086defaec8adTony Mak /** 6100ff315d60bb44c5cc4223abff48e086defaec8adTony Mak * 6110ff315d60bb44c5cc4223abff48e086defaec8adTony Mak * @param contactCursor 6120ff315d60bb44c5cc4223abff48e086defaec8adTony Mak * @param offset 6130ff315d60bb44c5cc4223abff48e086defaec8adTony Mak * @return a cursor containing contact id of {@code offset} contact. 6140ff315d60bb44c5cc4223abff48e086defaec8adTony Mak */ 6150ff315d60bb44c5cc4223abff48e086defaec8adTony Mak public static Cursor filterByOffset(Cursor contactCursor, int offset) { 6160ff315d60bb44c5cc4223abff48e086defaec8adTony Mak return filterByRange(contactCursor, offset, offset); 6170ff315d60bb44c5cc4223abff48e086defaec8adTony Mak } 6180ff315d60bb44c5cc4223abff48e086defaec8adTony Mak 6190ff315d60bb44c5cc4223abff48e086defaec8adTony Mak /** 6200ff315d60bb44c5cc4223abff48e086defaec8adTony Mak * 6210ff315d60bb44c5cc4223abff48e086defaec8adTony Mak * @param contactCursor 6220ff315d60bb44c5cc4223abff48e086defaec8adTony Mak * @param startPoint 6230ff315d60bb44c5cc4223abff48e086defaec8adTony Mak * @param endPoint 6240ff315d60bb44c5cc4223abff48e086defaec8adTony Mak * @return a cursor containing contact ids of {@code startPoint}th to {@code endPoint}th 6250ff315d60bb44c5cc4223abff48e086defaec8adTony Mak * contact. 6260ff315d60bb44c5cc4223abff48e086defaec8adTony Mak */ 6270ff315d60bb44c5cc4223abff48e086defaec8adTony Mak public static Cursor filterByRange(Cursor contactCursor, int startPoint, int endPoint) { 6280ff315d60bb44c5cc4223abff48e086defaec8adTony Mak final int contactIdColumn = contactCursor.getColumnIndex(Data.CONTACT_ID); 6290ff315d60bb44c5cc4223abff48e086defaec8adTony Mak long previousContactId = -1; 6300ff315d60bb44c5cc4223abff48e086defaec8adTony Mak // As startPoint, endOffset index starts from 1 to n, we set 6310ff315d60bb44c5cc4223abff48e086defaec8adTony Mak // currentPoint base as 1 not 0 6320ff315d60bb44c5cc4223abff48e086defaec8adTony Mak int currentOffset = 1; 6330ff315d60bb44c5cc4223abff48e086defaec8adTony Mak final MatrixCursor contactIdsCursor = new MatrixCursor(new String[]{ 6340ff315d60bb44c5cc4223abff48e086defaec8adTony Mak Phone.CONTACT_ID 6350ff315d60bb44c5cc4223abff48e086defaec8adTony Mak }); 6360ff315d60bb44c5cc4223abff48e086defaec8adTony Mak while (contactCursor.moveToNext() && currentOffset <= endPoint) { 6370ff315d60bb44c5cc4223abff48e086defaec8adTony Mak long currentContactId = contactCursor.getLong(contactIdColumn); 6380ff315d60bb44c5cc4223abff48e086defaec8adTony Mak if (previousContactId != currentContactId) { 6390ff315d60bb44c5cc4223abff48e086defaec8adTony Mak previousContactId = currentContactId; 6400ff315d60bb44c5cc4223abff48e086defaec8adTony Mak if (currentOffset >= startPoint) { 6410ff315d60bb44c5cc4223abff48e086defaec8adTony Mak contactIdsCursor.addRow(new Long[]{currentContactId}); 6420ff315d60bb44c5cc4223abff48e086defaec8adTony Mak if (V) Log.v(TAG, "contactIdsCursor.addRow: " + currentContactId); 6430ff315d60bb44c5cc4223abff48e086defaec8adTony Mak } 6440ff315d60bb44c5cc4223abff48e086defaec8adTony Mak currentOffset++; 6452b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh } 6462b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh } 6470ff315d60bb44c5cc4223abff48e086defaec8adTony Mak return contactIdsCursor; 6482b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh } 6492b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh } 6502b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh 6515006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai /** 6525006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai * Handler enterprise contact id in VCardComposer 6535006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai */ 6545006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai private static class EnterpriseRawContactEntitlesInfoCallback implements 6555006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai VCardComposer.RawContactEntitlesInfoCallback { 6565006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai @Override 6575006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai public VCardComposer.RawContactEntitlesInfo getRawContactEntitlesInfo(long contactId) { 6585006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai if (Contacts.isEnterpriseContactId(contactId)) { 6595006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai return new VCardComposer.RawContactEntitlesInfo(RawContactsEntity.CORP_CONTENT_URI, 6605006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai contactId - Contacts.ENTERPRISE_CONTACT_ID_BASE); 6615006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai } else { 6625006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai return new VCardComposer.RawContactEntitlesInfo(RawContactsEntity.CONTENT_URI, contactId); 6635006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai } 6645006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai } 6655006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai } 6665006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai 6675a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta private final int composeContactsAndSendVCards(Operation op, final Cursor contactIdCursor, 6685006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai final boolean vcardType21, String ownerVCard, boolean ignorefilter, byte[] filter) { 6692f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue long timestamp = 0; 6702f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue if (V) timestamp = System.currentTimeMillis(); 6714446eaa935994bc91d6d308303e8d27526b4590dLixin Yue 6725006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai VCardComposer composer = null; 6735006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai VCardFilter vcardfilter = new VCardFilter(ignorefilter ? null : filter); 6745f659853fff6a50fd12e1f7956997cbef244f798Andre Eisenbach 6755006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai HandlerForStringBuffer buffer = null; 6765006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai try { 6775006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai // Currently only support Generic Vcard 2.1 and 3.0 6785006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai int vcardType; 6795006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai if (vcardType21) { 6805006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai vcardType = VCardConfig.VCARD_TYPE_V21_GENERIC; 6815006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai } else { 6825006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai vcardType = VCardConfig.VCARD_TYPE_V30_GENERIC; 6835006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai } 6845006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai if (!vcardfilter.isPhotoEnabled()) { 6855006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai vcardType |= VCardConfig.FLAG_REFRAIN_IMAGE_EXPORT; 6865006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai } 6875006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai 6885006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai // Enhancement: customize Vcard based on preferences/settings and 6895006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai // input from caller 6905006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai composer = BluetoothPbapUtils.createFilteredVCardComposer(mContext, vcardType, null); 6915006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai // End enhancement 6925006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai 6935006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai // BT does want PAUSE/WAIT conversion while it doesn't want the 6945006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai // other formatting 6955006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai // done by vCard library by default. 6965006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai composer.setPhoneNumberTranslationCallback(new VCardPhoneNumberTranslationCallback() { 6975006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai public String onValueReceived(String rawValue, int type, String label, 6985006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai boolean isPrimary) { 6995006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai // 'p' and 'w' are the standard characters for pause and 7005006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai // wait 7015006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai // (see RFC 3601) 7025006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai // so use those when exporting phone numbers via vCard. 7035006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai String numberWithControlSequence = rawValue 7045006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai .replace(PhoneNumberUtils.PAUSE, 'p').replace(PhoneNumberUtils.WAIT, 7055006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai 'w'); 7065006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai return numberWithControlSequence; 7074a53a55dc10d3a26c94e5844f7d4a2565a67142cfredc } 7085006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai }); 7095006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai buffer = new HandlerForStringBuffer(op, ownerVCard); 7105006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai Log.v(TAG, "contactIdCursor size: " + contactIdCursor.getCount()); 7115006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai if (!composer.initWithCallback(contactIdCursor, 7125006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai new EnterpriseRawContactEntitlesInfoCallback()) 7135006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai || !buffer.onInit(mContext)) { 7145006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai return ResponseCodes.OBEX_HTTP_INTERNAL_ERROR; 7155006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai } 7164446eaa935994bc91d6d308303e8d27526b4590dLixin Yue 7175006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai while (!composer.isAfterLast()) { 7185006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai if (BluetoothPbapObexServer.sIsAborted) { 7195006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai ((ServerOperation) op).isAborted = true; 7205006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai BluetoothPbapObexServer.sIsAborted = false; 7215006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai break; 7225006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai } 7235006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai String vcard = composer.createOneEntry(); 7245006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai if (vcard == null) { 7255006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai Log.e(TAG, 7265006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai "Failed to read a contact. Error reason: " + composer.getErrorReason()); 7272f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue return ResponseCodes.OBEX_HTTP_INTERNAL_ERROR; 7284446eaa935994bc91d6d308303e8d27526b4590dLixin Yue } 7295006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai if (V) Log.v(TAG, "vCard from composer: " + vcard); 730198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa 7315006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai vcard = vcardfilter.apply(vcard, vcardType21); 7325006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai vcard = StripTelephoneNumber(vcard); 7335f659853fff6a50fd12e1f7956997cbef244f798Andre Eisenbach 7345006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai if (V) Log.v(TAG, "vCard after cleanup: " + vcard); 735c7a57f31515107366589bd6875c3cc4af1fc806efredc 7365006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai if (!buffer.onEntryCreated(vcard)) { 7375006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai // onEntryCreate() already emits error. 7385006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai return ResponseCodes.OBEX_HTTP_INTERNAL_ERROR; 7393c4d2c77c2fffe675fbe89ba58856686b6873d2fDaisuke Miyakawa } 7404446eaa935994bc91d6d308303e8d27526b4590dLixin Yue } 7415006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai } finally { 7425006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai if (composer != null) { 7435006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai composer.terminate(); 7445006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai } 7455006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai if (buffer != null) { 7465006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai buffer.onTerminate(); 7475006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai } 7485006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai } 7493c4d2c77c2fffe675fbe89ba58856686b6873d2fDaisuke Miyakawa 7505006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai if (V) Log.v(TAG, "Total vcard composing and sending out takes " 7515006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai + (System.currentTimeMillis() - timestamp) + " ms"); 752198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa 7535006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai return ResponseCodes.OBEX_HTTP_OK; 7545006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai } 7555006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai 7565a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta private final int composeContactsAndSendSelectedVCards(Operation op, 7575a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta final Cursor contactIdCursor, final boolean vcardType21, String ownerVCard, 7585a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta int needSendBody, int pbSize, boolean ignorefilter, byte[] filter, byte[] selector, 7595a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta String vcardselectorop) { 7605006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai long timestamp = 0; 7615006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai if (V) timestamp = System.currentTimeMillis(); 7625006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai 7635a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta VCardComposer composer = null; 7645a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta VCardFilter vcardfilter = new VCardFilter(ignorefilter ? null : filter); 7655a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta PropertySelector vcardselector = new PropertySelector(selector); 7665a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta 7675006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai HandlerForStringBuffer buffer = null; 7685a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta 7695006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai try { 7705a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta // Currently only support Generic Vcard 2.1 and 3.0 7715a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta int vcardType; 7725a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta if (vcardType21) { 7735a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta vcardType = VCardConfig.VCARD_TYPE_V21_GENERIC; 7745a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta } else { 7755a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta vcardType = VCardConfig.VCARD_TYPE_V30_GENERIC; 7765a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta } 7775a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta if (!vcardfilter.isPhotoEnabled()) { 7785a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta vcardType |= VCardConfig.FLAG_REFRAIN_IMAGE_EXPORT; 7795a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta } 7805006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai 7815a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta // Enhancement: customize Vcard based on preferences/settings and 7825a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta // input from caller 7835a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta composer = BluetoothPbapUtils.createFilteredVCardComposer(mContext, vcardType, null); 7845a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta // End enhancement 7855a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta 7865a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta /* BT does want PAUSE/WAIT conversion while it doesn't want the 7875a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta * other formatting done by vCard library by default. */ 7885a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta composer.setPhoneNumberTranslationCallback(new VCardPhoneNumberTranslationCallback() { 7895a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta public String onValueReceived( 7905a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta String rawValue, int type, String label, boolean isPrimary) { 7915a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta /* 'p' and 'w' are the standard characters for pause and wait 7925a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta * (see RFC 3601) so use those when exporting phone numbers via vCard.*/ 7935a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta String numberWithControlSequence = rawValue.replace(PhoneNumberUtils.PAUSE, 'p') 7945a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta .replace(PhoneNumberUtils.WAIT, 'w'); 7955a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta return numberWithControlSequence; 7965a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta } 7975a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta }); 7985006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai buffer = new HandlerForStringBuffer(op, ownerVCard); 7995a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta Log.v(TAG, "contactIdCursor size: " + contactIdCursor.getCount()); 8005a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta if (!composer.initWithCallback( 8015a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta contactIdCursor, new EnterpriseRawContactEntitlesInfoCallback()) 8025006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai || !buffer.onInit(mContext)) { 8035006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai return ResponseCodes.OBEX_HTTP_INTERNAL_ERROR; 8045006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai } 805c7a57f31515107366589bd6875c3cc4af1fc806efredc 8065006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai while (!composer.isAfterLast()) { 8075006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai if (BluetoothPbapObexServer.sIsAborted) { 8085006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai ((ServerOperation) op).isAborted = true; 8095006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai BluetoothPbapObexServer.sIsAborted = false; 8105006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai break; 811198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa } 8125a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta String vcard = composer.createOneEntry(); 8135006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai if (vcard == null) { 8145006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai Log.e(TAG, 8155006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai "Failed to read a contact. Error reason: " + composer.getErrorReason()); 8165006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai return ResponseCodes.OBEX_HTTP_INTERNAL_ERROR; 817198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa } 8185a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta if (V) Log.v(TAG, "Checking selected bits in the vcard composer" + vcard); 8195a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta 8205a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta if (!vcardselector.CheckVcardSelector(vcard, vcardselectorop)) { 8215a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta Log.e(TAG, "vcard selector check fail"); 8225a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta vcard = null; 8235a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta pbSize--; 8245a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta continue; 8253c4d2c77c2fffe675fbe89ba58856686b6873d2fDaisuke Miyakawa } 8265006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai 8275a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta Log.e(TAG, "vcard selector check pass"); 8285a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta 8295a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta if (needSendBody == NEED_SEND_BODY) { 8305a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta vcard = vcardfilter.apply(vcard, vcardType21); 8315a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta vcard = StripTelephoneNumber(vcard); 8325a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta 8335a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta if (V) Log.v(TAG, "vCard after cleanup: " + vcard); 8345a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta 8355a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta if (!buffer.onEntryCreated(vcard)) { 8365a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta // onEntryCreate() already emits error. 8375a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta return ResponseCodes.OBEX_HTTP_INTERNAL_ERROR; 8385a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta } 8395a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta } 8405a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta } 8415a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta 8425a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta if (needSendBody != NEED_SEND_BODY) return pbSize; 8435a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta } finally { 8445a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta if (composer != null) { 8455a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta composer.terminate(); 8465a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta } 8475a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta if (buffer != null) { 8485a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta buffer.onTerminate(); 8495a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta } 8505a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta } 8515a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta 8525a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta if (V) 8535a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta Log.v(TAG, "Total vcard composing and sending out takes " 8545a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta + (System.currentTimeMillis() - timestamp) + " ms"); 8555a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta 8565a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta return ResponseCodes.OBEX_HTTP_OK; 8575a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta } 8585a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta 8595a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta private final int composeCallLogsAndSendSelectedVCards(Operation op, final String selection, 8605a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta final boolean vcardType21, int needSendBody, int pbSize, String ownerVCard, 8615a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta boolean ignorefilter, byte[] filter, byte[] selector, String vcardselectorop, 8625a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta boolean vCardSelct) { 8635a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta long timestamp = 0; 8645a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta if (V) timestamp = System.currentTimeMillis(); 8655a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta 8665a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta BluetoothPbapCallLogComposer composer = null; 8675a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta HandlerForStringBuffer buffer = null; 8685a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta 8695a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta try { 8705a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta VCardFilter vcardfilter = new VCardFilter(ignorefilter ? null : filter); 8715a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta PropertySelector vcardselector = new PropertySelector(selector); 8725a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta composer = new BluetoothPbapCallLogComposer(mContext); 8735a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta buffer = new HandlerForStringBuffer(op, ownerVCard); 8745a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta if (!composer.init(CallLog.Calls.CONTENT_URI, selection, null, CALLLOG_SORT_ORDER) 8755a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta || !buffer.onInit(mContext)) { 8765a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta return ResponseCodes.OBEX_HTTP_INTERNAL_ERROR; 8775a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta } 8785a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta 8795a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta while (!composer.isAfterLast()) { 8805a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta if (BluetoothPbapObexServer.sIsAborted) { 8815a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta ((ServerOperation) op).isAborted = true; 8825a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta BluetoothPbapObexServer.sIsAborted = false; 8835a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta break; 8845a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta } 8855a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta String vcard = composer.createOneEntry(vcardType21); 8865a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta if (vCardSelct) { 8875a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta if (!vcardselector.CheckVcardSelector(vcard, vcardselectorop)) { 8885a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta Log.e(TAG, "Checking vcard selector for call log"); 8895a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta vcard = null; 8905a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta pbSize--; 8915a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta continue; 8925a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta } 8935a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta if (needSendBody == NEED_SEND_BODY) { 8945a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta if (vcard != null) { 8955a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta vcard = vcardfilter.apply(vcard, vcardType21); 8965a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta } 8975a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta if (vcard == null) { 8985a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta Log.e(TAG, "Failed to read a contact. Error reason: " 8995a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta + composer.getErrorReason()); 9005a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta return ResponseCodes.OBEX_HTTP_INTERNAL_ERROR; 9015a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta } 9025a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta if (V) { 9035a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta Log.v(TAG, "Vcard Entry:"); 9045a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta Log.v(TAG, vcard); 9055a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta } 9065a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta buffer.onEntryCreated(vcard); 9075a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta } 9085a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta } else { 9095a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta if (vcard == null) { 9105a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta Log.e(TAG, "Failed to read a contact. Error reason: " 9115a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta + composer.getErrorReason()); 9125a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta return ResponseCodes.OBEX_HTTP_INTERNAL_ERROR; 9135a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta } 9145a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta if (V) { 9155a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta Log.v(TAG, "Vcard Entry:"); 9165a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta Log.v(TAG, vcard); 9175a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta } 9185a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta buffer.onEntryCreated(vcard); 9195a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta } 9205006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai } 9215a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta if (needSendBody != NEED_SEND_BODY && vCardSelct) return pbSize; 9225006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai } finally { 9235006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai if (composer != null) { 9245006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai composer.terminate(); 9255006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai } 9265006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai if (buffer != null) { 9275006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai buffer.onTerminate(); 9284446eaa935994bc91d6d308303e8d27526b4590dLixin Yue } 9294446eaa935994bc91d6d308303e8d27526b4590dLixin Yue } 9304446eaa935994bc91d6d308303e8d27526b4590dLixin Yue 9312f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue if (V) Log.v(TAG, "Total vcard composing and sending out takes " 9325006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai + (System.currentTimeMillis() - timestamp) + " ms"); 9332f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue return ResponseCodes.OBEX_HTTP_OK; 9344446eaa935994bc91d6d308303e8d27526b4590dLixin Yue } 9354446eaa935994bc91d6d308303e8d27526b4590dLixin Yue 93629ab94a024ffce08229f1c2c6776d1e72d2a3f75Hemant Gupta public String StripTelephoneNumber (String vCard){ 93729ab94a024ffce08229f1c2c6776d1e72d2a3f75Hemant Gupta String attr [] = vCard.split(System.getProperty("line.separator")); 93829ab94a024ffce08229f1c2c6776d1e72d2a3f75Hemant Gupta String Vcard = ""; 93929ab94a024ffce08229f1c2c6776d1e72d2a3f75Hemant Gupta for (int i=0; i < attr.length; i++) { 94029ab94a024ffce08229f1c2c6776d1e72d2a3f75Hemant Gupta if(attr[i].startsWith("TEL")) { 94129ab94a024ffce08229f1c2c6776d1e72d2a3f75Hemant Gupta attr[i] = attr[i].replace("(", ""); 94229ab94a024ffce08229f1c2c6776d1e72d2a3f75Hemant Gupta attr[i] = attr[i].replace(")", ""); 94329ab94a024ffce08229f1c2c6776d1e72d2a3f75Hemant Gupta attr[i] = attr[i].replace("-", ""); 94429ab94a024ffce08229f1c2c6776d1e72d2a3f75Hemant Gupta attr[i] = attr[i].replace(" ", ""); 94529ab94a024ffce08229f1c2c6776d1e72d2a3f75Hemant Gupta } 94629ab94a024ffce08229f1c2c6776d1e72d2a3f75Hemant Gupta } 94729ab94a024ffce08229f1c2c6776d1e72d2a3f75Hemant Gupta 94829ab94a024ffce08229f1c2c6776d1e72d2a3f75Hemant Gupta for (int i=0; i < attr.length; i++) { 94929ab94a024ffce08229f1c2c6776d1e72d2a3f75Hemant Gupta if(!attr[i].equals("")){ 95029ab94a024ffce08229f1c2c6776d1e72d2a3f75Hemant Gupta Vcard = Vcard.concat(attr[i] + "\n"); 95129ab94a024ffce08229f1c2c6776d1e72d2a3f75Hemant Gupta } 95229ab94a024ffce08229f1c2c6776d1e72d2a3f75Hemant Gupta } 95302fc1acb99dbf3ae0a710ee7e4b6de8dd779e84eRakesh Iyer if (V) Log.v(TAG, "Vcard with stripped telephone no.: " + Vcard); 95429ab94a024ffce08229f1c2c6776d1e72d2a3f75Hemant Gupta return Vcard; 95529ab94a024ffce08229f1c2c6776d1e72d2a3f75Hemant Gupta } 95629ab94a024ffce08229f1c2c6776d1e72d2a3f75Hemant Gupta 9572f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue /** 958ce8d51a3a43d113a4a6bad30d595c2a81d0f623cYoshiharu Kurita * Handler to emit vCards to PCE. 9592f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue */ 9603c4d2c77c2fffe675fbe89ba58856686b6873d2fDaisuke Miyakawa public class HandlerForStringBuffer { 9612f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue private Operation operation; 9624446eaa935994bc91d6d308303e8d27526b4590dLixin Yue 9632f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue private OutputStream outputStream; 9642f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue 9652f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue private String phoneOwnVCard = null; 9662f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue 9672f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue public HandlerForStringBuffer(Operation op, String ownerVCard) { 9682f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue operation = op; 9692f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue if (ownerVCard != null) { 9702f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue phoneOwnVCard = ownerVCard; 9712f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue if (V) Log.v(TAG, "phone own number vcard:"); 9722f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue if (V) Log.v(TAG, phoneOwnVCard); 9732c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 9742c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 9752c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 976ce8d51a3a43d113a4a6bad30d595c2a81d0f623cYoshiharu Kurita private boolean write(String vCard) { 977ce8d51a3a43d113a4a6bad30d595c2a81d0f623cYoshiharu Kurita try { 978ce8d51a3a43d113a4a6bad30d595c2a81d0f623cYoshiharu Kurita if (vCard != null) { 979ce8d51a3a43d113a4a6bad30d595c2a81d0f623cYoshiharu Kurita outputStream.write(vCard.getBytes()); 980ce8d51a3a43d113a4a6bad30d595c2a81d0f623cYoshiharu Kurita return true; 981ce8d51a3a43d113a4a6bad30d595c2a81d0f623cYoshiharu Kurita } 982ce8d51a3a43d113a4a6bad30d595c2a81d0f623cYoshiharu Kurita } catch (IOException e) { 983ce8d51a3a43d113a4a6bad30d595c2a81d0f623cYoshiharu Kurita Log.e(TAG, "write outputstrem failed" + e.toString()); 984ce8d51a3a43d113a4a6bad30d595c2a81d0f623cYoshiharu Kurita } 985ce8d51a3a43d113a4a6bad30d595c2a81d0f623cYoshiharu Kurita return false; 986ce8d51a3a43d113a4a6bad30d595c2a81d0f623cYoshiharu Kurita } 987ce8d51a3a43d113a4a6bad30d595c2a81d0f623cYoshiharu Kurita 9882f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue public boolean onInit(Context context) { 9892f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue try { 9902f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue outputStream = operation.openOutputStream(); 9912f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue if (phoneOwnVCard != null) { 992ce8d51a3a43d113a4a6bad30d595c2a81d0f623cYoshiharu Kurita return write(phoneOwnVCard); 9932c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 994ce8d51a3a43d113a4a6bad30d595c2a81d0f623cYoshiharu Kurita return true; 9952f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue } catch (IOException e) { 9962f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue Log.e(TAG, "open outputstrem failed" + e.toString()); 9972c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 998ce8d51a3a43d113a4a6bad30d595c2a81d0f623cYoshiharu Kurita return false; 9992c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 10002c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 10012f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue public boolean onEntryCreated(String vcard) { 1002ce8d51a3a43d113a4a6bad30d595c2a81d0f623cYoshiharu Kurita return write(vcard); 10032c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 10042c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 10052f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue public void onTerminate() { 10062f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue if (!BluetoothPbapObexServer.closeStream(outputStream, operation)) { 10072f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue if (V) Log.v(TAG, "CloseStream failed!"); 10082c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } else { 10092f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue if (V) Log.v(TAG, "CloseStream ok!"); 10102c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 10112c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 10122c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 10136db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta 10145f659853fff6a50fd12e1f7956997cbef244f798Andre Eisenbach public static class VCardFilter { 10155f659853fff6a50fd12e1f7956997cbef244f798Andre Eisenbach private static enum FilterBit { 10165211519fa7617f3e34b214264f59157db9f495aaSmriti Gupta // bit property onlyCheckV21 excludeForV21 10175211519fa7617f3e34b214264f59157db9f495aaSmriti Gupta FN ( 1, "FN", true, false), 10185211519fa7617f3e34b214264f59157db9f495aaSmriti Gupta PHOTO( 3, "PHOTO", false, false), 10195211519fa7617f3e34b214264f59157db9f495aaSmriti Gupta BDAY( 4, "BDAY", false, false), 10205211519fa7617f3e34b214264f59157db9f495aaSmriti Gupta ADR( 5, "ADR", false, false), 10215211519fa7617f3e34b214264f59157db9f495aaSmriti Gupta EMAIL( 8, "EMAIL", false, false), 10225211519fa7617f3e34b214264f59157db9f495aaSmriti Gupta TITLE( 12, "TITLE", false, false), 10235211519fa7617f3e34b214264f59157db9f495aaSmriti Gupta ORG( 16, "ORG", false, false), 10245211519fa7617f3e34b214264f59157db9f495aaSmriti Gupta NOTE( 17, "NOTE", false, false), 10255211519fa7617f3e34b214264f59157db9f495aaSmriti Gupta URL( 20, "URL", false, false), 10265211519fa7617f3e34b214264f59157db9f495aaSmriti Gupta NICKNAME( 23, "NICKNAME", false, true), 10275211519fa7617f3e34b214264f59157db9f495aaSmriti Gupta DATETIME( 28, "X-IRMC-CALL-DATETIME", false, false); 10285f659853fff6a50fd12e1f7956997cbef244f798Andre Eisenbach 10295f659853fff6a50fd12e1f7956997cbef244f798Andre Eisenbach public final int pos; 10305f659853fff6a50fd12e1f7956997cbef244f798Andre Eisenbach public final String prop; 10315f659853fff6a50fd12e1f7956997cbef244f798Andre Eisenbach public final boolean onlyCheckV21; 10325f659853fff6a50fd12e1f7956997cbef244f798Andre Eisenbach public final boolean excludeForV21; 10335f659853fff6a50fd12e1f7956997cbef244f798Andre Eisenbach 10345f659853fff6a50fd12e1f7956997cbef244f798Andre Eisenbach FilterBit(int pos, String prop, boolean onlyCheckV21, boolean excludeForV21) { 10355f659853fff6a50fd12e1f7956997cbef244f798Andre Eisenbach this.pos = pos; 10365f659853fff6a50fd12e1f7956997cbef244f798Andre Eisenbach this.prop = prop; 10375f659853fff6a50fd12e1f7956997cbef244f798Andre Eisenbach this.onlyCheckV21 = onlyCheckV21; 10385f659853fff6a50fd12e1f7956997cbef244f798Andre Eisenbach this.excludeForV21 = excludeForV21; 10395f659853fff6a50fd12e1f7956997cbef244f798Andre Eisenbach } 10405f659853fff6a50fd12e1f7956997cbef244f798Andre Eisenbach } 10415f659853fff6a50fd12e1f7956997cbef244f798Andre Eisenbach 10425f659853fff6a50fd12e1f7956997cbef244f798Andre Eisenbach private static final String SEPARATOR = System.getProperty("line.separator"); 10435f659853fff6a50fd12e1f7956997cbef244f798Andre Eisenbach private final byte[] filter; 10445f659853fff6a50fd12e1f7956997cbef244f798Andre Eisenbach 1045976a53f0f946e589aa2b5204ce3262abcf2afc55Hemant Gupta //This function returns true if the attributes needs to be included in the filtered vcard. 1046976a53f0f946e589aa2b5204ce3262abcf2afc55Hemant Gupta private boolean isFilteredIn(FilterBit bit, boolean vCardType21) { 10475f659853fff6a50fd12e1f7956997cbef244f798Andre Eisenbach final int offset = (bit.pos / 8) + 1; 10485f659853fff6a50fd12e1f7956997cbef244f798Andre Eisenbach final int bit_pos = bit.pos % 8; 1049976a53f0f946e589aa2b5204ce3262abcf2afc55Hemant Gupta if (!vCardType21 && bit.onlyCheckV21) return true; 1050976a53f0f946e589aa2b5204ce3262abcf2afc55Hemant Gupta if (vCardType21 && bit.excludeForV21) return false; 1051976a53f0f946e589aa2b5204ce3262abcf2afc55Hemant Gupta if (filter == null || offset >= filter.length) return true; 10525f659853fff6a50fd12e1f7956997cbef244f798Andre Eisenbach return ((filter[filter.length - offset] >> bit_pos) & 0x01) != 0; 10535f659853fff6a50fd12e1f7956997cbef244f798Andre Eisenbach } 10545f659853fff6a50fd12e1f7956997cbef244f798Andre Eisenbach 10555f659853fff6a50fd12e1f7956997cbef244f798Andre Eisenbach VCardFilter(byte[] filter) { 10565f659853fff6a50fd12e1f7956997cbef244f798Andre Eisenbach this.filter = filter; 10575f659853fff6a50fd12e1f7956997cbef244f798Andre Eisenbach } 10585f659853fff6a50fd12e1f7956997cbef244f798Andre Eisenbach 10595f659853fff6a50fd12e1f7956997cbef244f798Andre Eisenbach public boolean isPhotoEnabled() { 1060976a53f0f946e589aa2b5204ce3262abcf2afc55Hemant Gupta return isFilteredIn(FilterBit.PHOTO, false); 10615f659853fff6a50fd12e1f7956997cbef244f798Andre Eisenbach } 10625f659853fff6a50fd12e1f7956997cbef244f798Andre Eisenbach 10635f659853fff6a50fd12e1f7956997cbef244f798Andre Eisenbach public String apply(String vCard, boolean vCardType21){ 10645f659853fff6a50fd12e1f7956997cbef244f798Andre Eisenbach if (filter == null) return vCard; 10655f659853fff6a50fd12e1f7956997cbef244f798Andre Eisenbach String lines[] = vCard.split(SEPARATOR); 10665f659853fff6a50fd12e1f7956997cbef244f798Andre Eisenbach StringBuilder filteredVCard = new StringBuilder(); 1067976a53f0f946e589aa2b5204ce3262abcf2afc55Hemant Gupta boolean filteredIn = false; 10685f659853fff6a50fd12e1f7956997cbef244f798Andre Eisenbach 10695f659853fff6a50fd12e1f7956997cbef244f798Andre Eisenbach for (String line : lines) { 10705f659853fff6a50fd12e1f7956997cbef244f798Andre Eisenbach // Check whether the current property is changing (ignoring multi-line properties) 10715f659853fff6a50fd12e1f7956997cbef244f798Andre Eisenbach // and determine if the current property is filtered in. 10725f659853fff6a50fd12e1f7956997cbef244f798Andre Eisenbach if (!Character.isWhitespace(line.charAt(0)) && !line.startsWith("=")) { 10735f659853fff6a50fd12e1f7956997cbef244f798Andre Eisenbach String currentProp = line.split("[;:]")[0]; 1074976a53f0f946e589aa2b5204ce3262abcf2afc55Hemant Gupta filteredIn = true; 10755f659853fff6a50fd12e1f7956997cbef244f798Andre Eisenbach 10765f659853fff6a50fd12e1f7956997cbef244f798Andre Eisenbach for (FilterBit bit : FilterBit.values()) { 10775f659853fff6a50fd12e1f7956997cbef244f798Andre Eisenbach if (bit.prop.equals(currentProp)) { 1078976a53f0f946e589aa2b5204ce3262abcf2afc55Hemant Gupta filteredIn = isFilteredIn(bit, vCardType21); 10795f659853fff6a50fd12e1f7956997cbef244f798Andre Eisenbach break; 10806db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta } 10816db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta } 10826db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta 10835f659853fff6a50fd12e1f7956997cbef244f798Andre Eisenbach // Since PBAP does not have filter bits for IM and SIP, 10845f659853fff6a50fd12e1f7956997cbef244f798Andre Eisenbach // exclude them by default. Easiest way is to exclude all 10855211519fa7617f3e34b214264f59157db9f495aaSmriti Gupta // X- fields, except date time.... 10865211519fa7617f3e34b214264f59157db9f495aaSmriti Gupta if (currentProp.startsWith("X-")) { 10875211519fa7617f3e34b214264f59157db9f495aaSmriti Gupta filteredIn = false; 10885211519fa7617f3e34b214264f59157db9f495aaSmriti Gupta if (currentProp.equals("X-IRMC-CALL-DATETIME")) { 10895211519fa7617f3e34b214264f59157db9f495aaSmriti Gupta filteredIn = true; 10905211519fa7617f3e34b214264f59157db9f495aaSmriti Gupta } 10915211519fa7617f3e34b214264f59157db9f495aaSmriti Gupta } 10926db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta } 10936db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta 10945f659853fff6a50fd12e1f7956997cbef244f798Andre Eisenbach // Build filtered vCard 10955211519fa7617f3e34b214264f59157db9f495aaSmriti Gupta if (filteredIn) { 10965211519fa7617f3e34b214264f59157db9f495aaSmriti Gupta filteredVCard.append(line + SEPARATOR); 10975211519fa7617f3e34b214264f59157db9f495aaSmriti Gupta } 10986db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta } 10996db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta 11005f659853fff6a50fd12e1f7956997cbef244f798Andre Eisenbach return filteredVCard.toString(); 11016db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta } 11026db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta } 11035006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai 11045a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta private static class PropertySelector { 11055a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta private static enum PropertyMask { 11065a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta // bit property 11075a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta VERSION(0, "VERSION"), 11085a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta FN(1, "FN"), 11095a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta NAME(2, "N"), 11105a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta PHOTO(3, "PHOTO"), 11115a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta BDAY(4, "BDAY"), 11125a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta ADR(5, "ADR"), 11135a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta LABEL(6, "LABEL"), 11145a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta TEL(7, "TEL"), 11155a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta EMAIL(8, "EMAIL"), 11165a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta TITLE(12, "TITLE"), 11175a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta ORG(16, "ORG"), 11185a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta NOTE(17, "NOTE"), 11195a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta URL(20, "URL"), 11205a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta NICKNAME(23, "NICKNAME"), 11215a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta DATETIME(28, "DATETIME"); 11225a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta 11235a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta public final int pos; 11245a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta public final String prop; 11255a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta 11265a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta PropertyMask(int pos, String prop) { 11275a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta this.pos = pos; 11285a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta this.prop = prop; 11295a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta } 11305a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta } 11315a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta 11325a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta private static final String SEPARATOR = System.getProperty("line.separator"); 11335a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta private final byte[] selector; 11345a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta 11355a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta PropertySelector(byte[] selector) { 11365a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta this.selector = selector; 11375a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta } 11385a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta 11395a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta private boolean checkbit(int attr_bit, byte[] selector) { 11405a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta int selectorlen = selector.length; 11415a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta if (((selector[selectorlen - 1 - ((int) attr_bit / 8)] >> (attr_bit % 8)) & 0x01) 11425a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta == 0) { 11435a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta return false; 11445a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta } 11455a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta return true; 11465a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta } 11475a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta 11485a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta private boolean checkprop(String vcard, String prop) { 11495a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta String lines[] = vcard.split(SEPARATOR); 11505a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta boolean isPresent = false; 11515a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta for (String line : lines) { 11525a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta if (!Character.isWhitespace(line.charAt(0)) && !line.startsWith("=")) { 11535a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta String currentProp = line.split("[;:]")[0]; 11545a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta if (prop.equals(currentProp)) { 11555a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta Log.d(TAG, "bit.prop.equals current prop :" + prop); 11565a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta isPresent = true; 11575a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta return isPresent; 11585a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta } 11595a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta } 11605a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta } 11615a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta 11625a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta return isPresent; 11635a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta } 11645a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta 11655a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta private boolean CheckVcardSelector(String vcard, String vcardselectorop) { 11665a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta boolean selectedIn = true; 11675a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta 11685a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta for (PropertyMask bit : PropertyMask.values()) { 11695a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta if (checkbit(bit.pos, selector)) { 11705a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta Log.d(TAG, "checking for prop :" + bit.prop); 11715a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta if (vcardselectorop.equals("0")) { 11725a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta if (checkprop(vcard, bit.prop)) { 11735a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta Log.d(TAG, "bit.prop.equals current prop :" + bit.prop); 11745a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta selectedIn = true; 11755a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta break; 11765a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta } else { 11775a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta selectedIn = false; 11785a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta } 11795a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta } else if (vcardselectorop.equals("1")) { 11805a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta if (!checkprop(vcard, bit.prop)) { 11815a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta Log.d(TAG, "bit.prop.notequals current prop" + bit.prop); 11825a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta selectedIn = false; 11835a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta return selectedIn; 11845a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta } else { 11855a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta selectedIn = true; 11865a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta } 11875a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta } 11885a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta } 11895a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta } 11905a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta return selectedIn; 11915a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta } 11925a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta 11935a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta private String getName(String vcard) { 11945a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta String lines[] = vcard.split(SEPARATOR); 11955a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta String name = ""; 11965a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta for (String line : lines) { 11975a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta if (!Character.isWhitespace(line.charAt(0)) && !line.startsWith("=")) { 11985a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta if (line.startsWith("N:")) 11995a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta name = line.substring(line.lastIndexOf(':'), line.length()); 12005a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta } 12015a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta } 12025a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta Log.d(TAG, "returning name: " + name); 12035a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta return name; 12045a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta } 12055a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta } 12065a37bc407ab1b8844c3541ff4e6653635b108bedHemant Gupta 12075006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai private static final Uri getPhoneLookupFilterUri() { 12085006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai return PhoneLookup.ENTERPRISE_CONTENT_FILTER_URI; 12095006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai } 1210c438463431b171a67b22b50886ef8dd737c44004Andre Eisenbach 12115006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai /** 12125006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai * Get size of the cursor without duplicated contact id. This assumes the 12136a50944dff2081fc161974cfae7d85d834b123cfSmriti Gupta * given cursor is sorted by CONTACT_ID. 12145006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai */ 1215c438463431b171a67b22b50886ef8dd737c44004Andre Eisenbach private static final int getDistinctContactIdSize(Cursor cursor) { 1216c438463431b171a67b22b50886ef8dd737c44004Andre Eisenbach final int contactIdColumn = cursor.getColumnIndex(Data.CONTACT_ID); 1217c438463431b171a67b22b50886ef8dd737c44004Andre Eisenbach final int idColumn = cursor.getColumnIndex(Data._ID); 12185006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai long previousContactId = -1; 12195006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai int count = 0; 12205006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai cursor.moveToPosition(-1); 12215006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai while (cursor.moveToNext()) { 1222c438463431b171a67b22b50886ef8dd737c44004Andre Eisenbach final long contactId = cursor.getLong(contactIdColumn != -1 ? contactIdColumn : idColumn); 12235006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai if (previousContactId != contactId) { 12245006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai count++; 12255006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai previousContactId = contactId; 12265006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai } 12275006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai } 12285006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai if (V) { 12295006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai Log.i(TAG, "getDistinctContactIdSize result: " + count); 12305006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai } 12315006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai return count; 12325006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai } 12335006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai 12345006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai /** 1235c438463431b171a67b22b50886ef8dd737c44004Andre Eisenbach * Append "display_name,contact_id" string array from cursor to ArrayList. 1236c438463431b171a67b22b50886ef8dd737c44004Andre Eisenbach * This assumes the given cursor is sorted by CONTACT_ID. 12375006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai */ 12385006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai private static void appendDistinctNameIdList(ArrayList<String> resultList, 1239c438463431b171a67b22b50886ef8dd737c44004Andre Eisenbach String defaultName, Cursor cursor) { 1240c438463431b171a67b22b50886ef8dd737c44004Andre Eisenbach final int contactIdColumn = cursor.getColumnIndex(Data.CONTACT_ID); 1241c438463431b171a67b22b50886ef8dd737c44004Andre Eisenbach final int idColumn = cursor.getColumnIndex(Data._ID); 1242c438463431b171a67b22b50886ef8dd737c44004Andre Eisenbach final int nameColumn = cursor.getColumnIndex(Data.DISPLAY_NAME); 12435006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai cursor.moveToPosition(-1); 12445006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai while (cursor.moveToNext()) { 1245c438463431b171a67b22b50886ef8dd737c44004Andre Eisenbach final long contactId = cursor.getLong(contactIdColumn != -1 ? contactIdColumn : idColumn); 1246c438463431b171a67b22b50886ef8dd737c44004Andre Eisenbach String displayName = nameColumn != -1 ? cursor.getString(nameColumn) : defaultName; 12475006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai if (TextUtils.isEmpty(displayName)) { 12485006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai displayName = defaultName; 12495006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai } 12505006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai 12516a50944dff2081fc161974cfae7d85d834b123cfSmriti Gupta String newString = displayName + "," + contactId; 12526a50944dff2081fc161974cfae7d85d834b123cfSmriti Gupta if (!resultList.contains(newString)) { 12536a50944dff2081fc161974cfae7d85d834b123cfSmriti Gupta resultList.add(newString); 12545006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai } 12555006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai } 12565006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai if (V) { 12575006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai for (String nameId : resultList) { 12585006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai Log.i(TAG, "appendDistinctNameIdList result: " + nameId); 12595006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai } 12605006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai } 12615006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai } 12622c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan} 1263