BluetoothPbapVcardManager.java revision 6a50944dff2081fc161974cfae7d85d834b123cf
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; 59198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa 602f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yueimport java.io.IOException; 612f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yueimport java.io.OutputStream; 622c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fanimport java.util.ArrayList; 635006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Waiimport java.util.Collections; 642c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 65198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawaimport javax.obex.Operation; 66198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawaimport javax.obex.ResponseCodes; 679d68ffa1079ca2e85a8ccf62bf8dca2f43f1ade3Tony Makimport javax.obex.ServerOperation; 68c7a57f31515107366589bd6875c3cc4af1fc806efredc 692c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fanpublic class BluetoothPbapVcardManager { 702f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue private static final String TAG = "BluetoothPbapVcardManager"; 712c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 724446eaa935994bc91d6d308303e8d27526b4590dLixin Yue private static final boolean V = BluetoothPbapService.VERBOSE; 734446eaa935994bc91d6d308303e8d27526b4590dLixin Yue 742c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan private ContentResolver mResolver; 752c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 762c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan private Context mContext; 772c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 78e10881ae39eb4affb7a78827f2060964e8534515Daisuke Miyakawa private static final int PHONE_NUMBER_COLUMN_INDEX = 3; 792c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 802f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue static final String SORT_ORDER_PHONE_NUMBER = CommonDataKinds.Phone.NUMBER + " ASC"; 814446eaa935994bc91d6d308303e8d27526b4590dLixin Yue 825006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai static final String[] PHONES_CONTACTS_PROJECTION = new String[] { 835006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai Phone.CONTACT_ID, // 0 845006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai Phone.DISPLAY_NAME, // 1 855006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai }; 865006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai 875006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai static final String[] PHONE_LOOKUP_PROJECTION = new String[] { 885006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai PhoneLookup._ID, PhoneLookup.DISPLAY_NAME 892b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh }; 902b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh 912b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh static final int CONTACTS_ID_COLUMN_INDEX = 0; 922b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh 932b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh static final int CONTACTS_NAME_COLUMN_INDEX = 1; 942b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh 952b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh // call histories use dynamic handles, and handles should order by date; the 962b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh // most recently one should be the first handle. In table "calls", _id and 972b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh // date are consistent in ordering, to implement simply, we sort by _id 982b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh // here. 992b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh static final String CALLLOG_SORT_ORDER = Calls._ID + " DESC"; 1002b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh 101cd5ed0c7d04119e508fbddfd9656ef8559e3e524Lixin Yue private static final String CLAUSE_ONLY_VISIBLE = Contacts.IN_VISIBLE_GROUP + "=1"; 102cd5ed0c7d04119e508fbddfd9656ef8559e3e524Lixin Yue 1032c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan public BluetoothPbapVcardManager(final Context context) { 1042c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan mContext = context; 1052c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan mResolver = mContext.getContentResolver(); 1062c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 1072c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 108c7a57f31515107366589bd6875c3cc4af1fc806efredc /** 109c7a57f31515107366589bd6875c3cc4af1fc806efredc * Create an owner vcard from the configured profile 110c7a57f31515107366589bd6875c3cc4af1fc806efredc * @param vcardType21 111c7a57f31515107366589bd6875c3cc4af1fc806efredc * @return 112c7a57f31515107366589bd6875c3cc4af1fc806efredc */ 113c7a57f31515107366589bd6875c3cc4af1fc806efredc private final String getOwnerPhoneNumberVcardFromProfile(final boolean vcardType21, final byte[] filter) { 114c7a57f31515107366589bd6875c3cc4af1fc806efredc // Currently only support Generic Vcard 2.1 and 3.0 115c7a57f31515107366589bd6875c3cc4af1fc806efredc int vcardType; 116c7a57f31515107366589bd6875c3cc4af1fc806efredc if (vcardType21) { 117c7a57f31515107366589bd6875c3cc4af1fc806efredc vcardType = VCardConfig.VCARD_TYPE_V21_GENERIC; 118c7a57f31515107366589bd6875c3cc4af1fc806efredc } else { 119c7a57f31515107366589bd6875c3cc4af1fc806efredc vcardType = VCardConfig.VCARD_TYPE_V30_GENERIC; 120c7a57f31515107366589bd6875c3cc4af1fc806efredc } 1214a53a55dc10d3a26c94e5844f7d4a2565a67142cfredc 1224a53a55dc10d3a26c94e5844f7d4a2565a67142cfredc if (!BluetoothPbapConfig.includePhotosInVcard()) { 1234a53a55dc10d3a26c94e5844f7d4a2565a67142cfredc vcardType |= VCardConfig.FLAG_REFRAIN_IMAGE_EXPORT; 1244a53a55dc10d3a26c94e5844f7d4a2565a67142cfredc } 1254a53a55dc10d3a26c94e5844f7d4a2565a67142cfredc 126c7a57f31515107366589bd6875c3cc4af1fc806efredc return BluetoothPbapUtils.createProfileVCard(mContext, vcardType,filter); 127c7a57f31515107366589bd6875c3cc4af1fc806efredc } 128c7a57f31515107366589bd6875c3cc4af1fc806efredc 129c7a57f31515107366589bd6875c3cc4af1fc806efredc public final String getOwnerPhoneNumberVcard(final boolean vcardType21, final byte[] filter) { 130c7a57f31515107366589bd6875c3cc4af1fc806efredc //Owner vCard enhancement: Use "ME" profile if configured 131c7a57f31515107366589bd6875c3cc4af1fc806efredc if (BluetoothPbapConfig.useProfileForOwnerVcard()) { 132c7a57f31515107366589bd6875c3cc4af1fc806efredc String vcard = getOwnerPhoneNumberVcardFromProfile(vcardType21, filter); 133c7a57f31515107366589bd6875c3cc4af1fc806efredc if (vcard != null && vcard.length() != 0) { 134c7a57f31515107366589bd6875c3cc4af1fc806efredc return vcard; 135c7a57f31515107366589bd6875c3cc4af1fc806efredc } 136c7a57f31515107366589bd6875c3cc4af1fc806efredc } 137c7a57f31515107366589bd6875c3cc4af1fc806efredc //End enhancement 138c7a57f31515107366589bd6875c3cc4af1fc806efredc 1393c4d2c77c2fffe675fbe89ba58856686b6873d2fDaisuke Miyakawa BluetoothPbapCallLogComposer composer = new BluetoothPbapCallLogComposer(mContext); 1402f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue String name = BluetoothPbapService.getLocalPhoneName(); 1412f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue String number = BluetoothPbapService.getLocalPhoneNum(); 1422f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue String vcard = composer.composeVCardForPhoneOwnNumber(Phone.TYPE_MOBILE, name, number, 1432f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue vcardType21); 1442f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue return vcard; 1452c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 1462c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 1472f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue public final int getPhonebookSize(final int type) { 1482f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue int size; 1492f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue switch (type) { 1502f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue case BluetoothPbapObexServer.ContentType.PHONEBOOK: 1512f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue size = getContactsSize(); 1522f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue break; 1532f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue default: 1542f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue size = getCallHistorySize(type); 1552f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue break; 1562c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 157c7a57f31515107366589bd6875c3cc4af1fc806efredc if (V) Log.v(TAG, "getPhonebookSize size = " + size + " type = " + type); 1582f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue return size; 1592c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 1602c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 1612f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue public final int getContactsSize() { 1623178b08c6823899dbb58513673bf2a80f637be7cRicky Wai final Uri myUri = DevicePolicyUtils.getEnterprisePhoneUri(mContext); 1632f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue Cursor contactCursor = null; 1642f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue try { 1655006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai contactCursor = mResolver.query(myUri, new String[] {Phone.CONTACT_ID}, 1665006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai CLAUSE_ONLY_VISIBLE, null, Phone.CONTACT_ID); 1675006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai if (contactCursor == null) { 1685006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai return 0; 1692f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue } 1709d68ffa1079ca2e85a8ccf62bf8dca2f43f1ade3Tony Mak return getDistinctContactIdSize(contactCursor, Phone.CONTACT_ID) 1719d68ffa1079ca2e85a8ccf62bf8dca2f43f1ade3Tony Mak + 1; // always has the 0.vcf 172c592e5a6de0011cd60f23ac18a7bd56d8eeb5dd1Hemant Gupta } catch (CursorWindowAllocationException e) { 173c592e5a6de0011cd60f23ac18a7bd56d8eeb5dd1Hemant Gupta Log.e(TAG, "CursorWindowAllocationException while getting Contacts size"); 1742f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue } finally { 1752f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue if (contactCursor != null) { 1762f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue contactCursor.close(); 1772f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue } 1782c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 1795006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai return 0; 1802c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 1812c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 1822f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue public final int getCallHistorySize(final int type) { 1832b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh final Uri myUri = CallLog.Calls.CONTENT_URI; 1842f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue String selection = BluetoothPbapObexServer.createSelectionPara(type); 1852f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue int size = 0; 1862f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue Cursor callCursor = null; 1872f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue try { 1882f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue callCursor = mResolver.query(myUri, null, selection, null, 1892f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue CallLog.Calls.DEFAULT_SORT_ORDER); 1902f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue if (callCursor != null) { 1912f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue size = callCursor.getCount(); 1924446eaa935994bc91d6d308303e8d27526b4590dLixin Yue } 193c592e5a6de0011cd60f23ac18a7bd56d8eeb5dd1Hemant Gupta } catch (CursorWindowAllocationException e) { 194c592e5a6de0011cd60f23ac18a7bd56d8eeb5dd1Hemant Gupta Log.e(TAG, "CursorWindowAllocationException while getting CallHistory size"); 1952f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue } finally { 1962f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue if (callCursor != null) { 1972f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue callCursor.close(); 198c592e5a6de0011cd60f23ac18a7bd56d8eeb5dd1Hemant Gupta callCursor = null; 1994446eaa935994bc91d6d308303e8d27526b4590dLixin Yue } 2002f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue } 2012f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue return size; 2022f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue } 2034446eaa935994bc91d6d308303e8d27526b4590dLixin Yue 2042f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue public final ArrayList<String> loadCallHistoryList(final int type) { 2052b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh final Uri myUri = CallLog.Calls.CONTENT_URI; 2062f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue String selection = BluetoothPbapObexServer.createSelectionPara(type); 2072f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue String[] projection = new String[] { 2089674eb043aeb1474aa23ddd0739e3b8f05432630Jay Shrauner Calls.NUMBER, Calls.CACHED_NAME, Calls.NUMBER_PRESENTATION 2092f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue }; 2102f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue final int CALLS_NUMBER_COLUMN_INDEX = 0; 2112f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue final int CALLS_NAME_COLUMN_INDEX = 1; 2129674eb043aeb1474aa23ddd0739e3b8f05432630Jay Shrauner final int CALLS_NUMBER_PRESENTATION_COLUMN_INDEX = 2; 2132f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue 2142f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue Cursor callCursor = null; 2152f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue ArrayList<String> list = new ArrayList<String>(); 2162f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue try { 2172f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue callCursor = mResolver.query(myUri, projection, selection, null, 2182b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh CALLLOG_SORT_ORDER); 2192f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue if (callCursor != null) { 2202f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue for (callCursor.moveToFirst(); !callCursor.isAfterLast(); 2212f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue callCursor.moveToNext()) { 2222f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue String name = callCursor.getString(CALLS_NAME_COLUMN_INDEX); 2232f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue if (TextUtils.isEmpty(name)) { 22477ba5f6684f4dd7e4b7fc37982271da5654aec07Staffan Lindvall // name not found, use number instead 2259674eb043aeb1474aa23ddd0739e3b8f05432630Jay Shrauner final int numberPresentation = callCursor.getInt( 2269674eb043aeb1474aa23ddd0739e3b8f05432630Jay Shrauner CALLS_NUMBER_PRESENTATION_COLUMN_INDEX); 2279674eb043aeb1474aa23ddd0739e3b8f05432630Jay Shrauner if (numberPresentation != Calls.PRESENTATION_ALLOWED) { 22877ba5f6684f4dd7e4b7fc37982271da5654aec07Staffan Lindvall name = mContext.getString(R.string.unknownNumber); 2299674eb043aeb1474aa23ddd0739e3b8f05432630Jay Shrauner } else { 2309674eb043aeb1474aa23ddd0739e3b8f05432630Jay Shrauner name = callCursor.getString(CALLS_NUMBER_COLUMN_INDEX); 23177ba5f6684f4dd7e4b7fc37982271da5654aec07Staffan Lindvall } 2322f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue } 2332f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue list.add(name); 2342f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue } 2352f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue } 236c592e5a6de0011cd60f23ac18a7bd56d8eeb5dd1Hemant Gupta } catch (CursorWindowAllocationException e) { 237c592e5a6de0011cd60f23ac18a7bd56d8eeb5dd1Hemant Gupta Log.e(TAG, "CursorWindowAllocationException while loading CallHistory"); 2382f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue } finally { 2392f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue if (callCursor != null) { 2402f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue callCursor.close(); 241c592e5a6de0011cd60f23ac18a7bd56d8eeb5dd1Hemant Gupta callCursor = null; 2422c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 2432c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 2442f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue return list; 2452c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 2462c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 2472b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh public final ArrayList<String> getPhonebookNameList(final int orderByWhat) { 2482f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue ArrayList<String> nameList = new ArrayList<String>(); 249c7a57f31515107366589bd6875c3cc4af1fc806efredc //Owner vCard enhancement. Use "ME" profile if configured 250c7a57f31515107366589bd6875c3cc4af1fc806efredc String ownerName = null; 251c7a57f31515107366589bd6875c3cc4af1fc806efredc if (BluetoothPbapConfig.useProfileForOwnerVcard()) { 252c7a57f31515107366589bd6875c3cc4af1fc806efredc ownerName = BluetoothPbapUtils.getProfileName(mContext); 253c7a57f31515107366589bd6875c3cc4af1fc806efredc } 254c7a57f31515107366589bd6875c3cc4af1fc806efredc if (ownerName == null || ownerName.length()==0) { 255c7a57f31515107366589bd6875c3cc4af1fc806efredc ownerName = BluetoothPbapService.getLocalPhoneName(); 256c7a57f31515107366589bd6875c3cc4af1fc806efredc } 257c7a57f31515107366589bd6875c3cc4af1fc806efredc nameList.add(ownerName); 258c7a57f31515107366589bd6875c3cc4af1fc806efredc //End enhancement 2594446eaa935994bc91d6d308303e8d27526b4590dLixin Yue 2603178b08c6823899dbb58513673bf2a80f637be7cRicky Wai final Uri myUri = DevicePolicyUtils.getEnterprisePhoneUri(mContext); 2612b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh Cursor contactCursor = null; 2623c8b50f8dc1c4ce11168fb42a884f604d1810c46Hemant Gupta // By default order is indexed 2633c8b50f8dc1c4ce11168fb42a884f604d1810c46Hemant Gupta String orderBy = Phone.CONTACT_ID; 2642f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue try { 2653c8b50f8dc1c4ce11168fb42a884f604d1810c46Hemant Gupta if (orderByWhat == BluetoothPbapObexServer.ORDER_BY_ALPHABETICAL) { 2663c8b50f8dc1c4ce11168fb42a884f604d1810c46Hemant Gupta orderBy = Phone.DISPLAY_NAME; 2673c8b50f8dc1c4ce11168fb42a884f604d1810c46Hemant Gupta } 2683c8b50f8dc1c4ce11168fb42a884f604d1810c46Hemant Gupta contactCursor = mResolver.query(myUri, PHONES_CONTACTS_PROJECTION, 2693c8b50f8dc1c4ce11168fb42a884f604d1810c46Hemant Gupta CLAUSE_ONLY_VISIBLE, null, orderBy); 2702b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh if (contactCursor != null) { 2715006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai appendDistinctNameIdList(nameList, 2729d68ffa1079ca2e85a8ccf62bf8dca2f43f1ade3Tony Mak mContext.getString(android.R.string.unknownName), contactCursor, 2739d68ffa1079ca2e85a8ccf62bf8dca2f43f1ade3Tony Mak Phone.CONTACT_ID, Phone.DISPLAY_NAME); 2745006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai if (orderByWhat == BluetoothPbapObexServer.ORDER_BY_INDEXED) { 2755006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai if (V) Log.v(TAG, "getPhonebookNameList, order by index"); 2765006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai // Do not need to do anything, as we sort it by index already 2775006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai } else if (orderByWhat == BluetoothPbapObexServer.ORDER_BY_ALPHABETICAL) { 2785006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai if (V) Log.v(TAG, "getPhonebookNameList, order by alpha"); 2795006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai Collections.sort(nameList); 2802f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue } 2812f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue } 2823c8b50f8dc1c4ce11168fb42a884f604d1810c46Hemant Gupta } catch (CursorWindowAllocationException e) { 2833c8b50f8dc1c4ce11168fb42a884f604d1810c46Hemant Gupta Log.e(TAG, "CursorWindowAllocationException while getting phonebook name list"); 284bf37a0295d110b77b635ca2986172bbdd59331bbAndre Eisenbach } catch (Exception e) { 2853c8b50f8dc1c4ce11168fb42a884f604d1810c46Hemant Gupta Log.e(TAG, "Exception while getting phonebook name list", e); 2862f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue } finally { 2872b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh if (contactCursor != null) { 2882b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh contactCursor.close(); 289c592e5a6de0011cd60f23ac18a7bd56d8eeb5dd1Hemant Gupta contactCursor = null; 2902f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue } 2912f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue } 2922f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue return nameList; 2934446eaa935994bc91d6d308303e8d27526b4590dLixin Yue } 2944446eaa935994bc91d6d308303e8d27526b4590dLixin Yue 2950dcd2262d853c2011e11617a8efba6758370c41fLiejun Tao public final ArrayList<String> getContactNamesByNumber(final String phoneNumber) { 2960dcd2262d853c2011e11617a8efba6758370c41fLiejun Tao ArrayList<String> nameList = new ArrayList<String>(); 2971321cd814a7406260ba6282d9c71e1a2d8925262Hemant Gupta ArrayList<String> tempNameList = new ArrayList<String>(); 2980dcd2262d853c2011e11617a8efba6758370c41fLiejun Tao 2990dcd2262d853c2011e11617a8efba6758370c41fLiejun Tao Cursor contactCursor = null; 3009d68ffa1079ca2e85a8ccf62bf8dca2f43f1ade3Tony Mak Uri uri; 3019d68ffa1079ca2e85a8ccf62bf8dca2f43f1ade3Tony Mak final String[] projection; 3029d68ffa1079ca2e85a8ccf62bf8dca2f43f1ade3Tony Mak final String contactIdColumn, displayNameColumn; 3035006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai if (TextUtils.isEmpty(phoneNumber)) { 3043178b08c6823899dbb58513673bf2a80f637be7cRicky Wai uri = DevicePolicyUtils.getEnterprisePhoneUri(mContext); 3059d68ffa1079ca2e85a8ccf62bf8dca2f43f1ade3Tony Mak contactIdColumn = Phone.CONTACT_ID; 3069d68ffa1079ca2e85a8ccf62bf8dca2f43f1ade3Tony Mak displayNameColumn = Phone.DISPLAY_NAME; 3074bba23a751f042596561eab0e677135d5267bcdfStaffan Lindvall } else { 3089d68ffa1079ca2e85a8ccf62bf8dca2f43f1ade3Tony Mak uri = Uri.withAppendedPath(getPhoneLookupFilterUri(), Uri.encode(phoneNumber)); 3099d68ffa1079ca2e85a8ccf62bf8dca2f43f1ade3Tony Mak contactIdColumn = PhoneLookup._ID; 3109d68ffa1079ca2e85a8ccf62bf8dca2f43f1ade3Tony Mak displayNameColumn = PhoneLookup.DISPLAY_NAME; 3114bba23a751f042596561eab0e677135d5267bcdfStaffan Lindvall } 3129d68ffa1079ca2e85a8ccf62bf8dca2f43f1ade3Tony Mak projection = new String[]{contactIdColumn, displayNameColumn}; 3134446eaa935994bc91d6d308303e8d27526b4590dLixin Yue 3142f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue try { 3159d68ffa1079ca2e85a8ccf62bf8dca2f43f1ade3Tony Mak contactCursor = mResolver 3169d68ffa1079ca2e85a8ccf62bf8dca2f43f1ade3Tony Mak .query(uri, projection, CLAUSE_ONLY_VISIBLE, null, contactIdColumn); 3170dcd2262d853c2011e11617a8efba6758370c41fLiejun Tao 3180dcd2262d853c2011e11617a8efba6758370c41fLiejun Tao if (contactCursor != null) { 3195006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai appendDistinctNameIdList(nameList, 3205006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai mContext.getString(android.R.string.unknownName), 3219d68ffa1079ca2e85a8ccf62bf8dca2f43f1ade3Tony Mak contactCursor, contactIdColumn, displayNameColumn); 3225006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai if (V) { 3235006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai for (String nameIdStr : nameList) { 3245006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai Log.v(TAG, "got name " + nameIdStr + " by number " + phoneNumber); 3252f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue } 3262f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue } 3272f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue } 328c592e5a6de0011cd60f23ac18a7bd56d8eeb5dd1Hemant Gupta } catch (CursorWindowAllocationException e) { 329c592e5a6de0011cd60f23ac18a7bd56d8eeb5dd1Hemant Gupta Log.e(TAG, "CursorWindowAllocationException while getting contact names"); 3302f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue } finally { 3310dcd2262d853c2011e11617a8efba6758370c41fLiejun Tao if (contactCursor != null) { 3320dcd2262d853c2011e11617a8efba6758370c41fLiejun Tao contactCursor.close(); 333c592e5a6de0011cd60f23ac18a7bd56d8eeb5dd1Hemant Gupta contactCursor = null; 3342f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue } 3352c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 3361321cd814a7406260ba6282d9c71e1a2d8925262Hemant Gupta int tempListSize = tempNameList.size(); 3371321cd814a7406260ba6282d9c71e1a2d8925262Hemant Gupta for (int index = 0; index < tempListSize; index++) { 3381321cd814a7406260ba6282d9c71e1a2d8925262Hemant Gupta String object = tempNameList.get(index); 3391321cd814a7406260ba6282d9c71e1a2d8925262Hemant Gupta if (!nameList.contains(object)) 3401321cd814a7406260ba6282d9c71e1a2d8925262Hemant Gupta nameList.add(object); 3411321cd814a7406260ba6282d9c71e1a2d8925262Hemant Gupta } 3421321cd814a7406260ba6282d9c71e1a2d8925262Hemant Gupta 3430dcd2262d853c2011e11617a8efba6758370c41fLiejun Tao return nameList; 3442c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 3452c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 3460b1b0069658326e8c12dc0f887e4319c5227feb5Lixin Yue public final int composeAndSendCallLogVcards(final int type, Operation op, 3476db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta final int startPoint, final int endPoint, final boolean vcardType21, 3486db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta boolean ignorefilter, byte[] filter) { 34959256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh if (startPoint < 1 || startPoint > endPoint) { 35059256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh Log.e(TAG, "internal error: startPoint or endPoint is not correct."); 35159256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh return ResponseCodes.OBEX_HTTP_INTERNAL_ERROR; 35259256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh } 3532f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue String typeSelection = BluetoothPbapObexServer.createSelectionPara(type); 35459256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh 3552b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh final Uri myUri = CallLog.Calls.CONTENT_URI; 35659256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh final String[] CALLLOG_PROJECTION = new String[] { 35759256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh CallLog.Calls._ID, // 0 35859256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh }; 35959256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh final int ID_COLUMN_INDEX = 0; 36059256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh 36159256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh Cursor callsCursor = null; 36259256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh long startPointId = 0; 36359256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh long endPointId = 0; 36459256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh try { 36559256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh // Need test to see if order by _ID is ok here, or by date? 36659256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh callsCursor = mResolver.query(myUri, CALLLOG_PROJECTION, typeSelection, null, 3672b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh CALLLOG_SORT_ORDER); 36859256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh if (callsCursor != null) { 36959256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh callsCursor.moveToPosition(startPoint - 1); 37059256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh startPointId = callsCursor.getLong(ID_COLUMN_INDEX); 37159256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh if (V) Log.v(TAG, "Call Log query startPointId = " + startPointId); 37259256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh if (startPoint == endPoint) { 37359256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh endPointId = startPointId; 37459256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh } else { 37559256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh callsCursor.moveToPosition(endPoint - 1); 37659256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh endPointId = callsCursor.getLong(ID_COLUMN_INDEX); 37759256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh } 37859256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh if (V) Log.v(TAG, "Call log query endPointId = " + endPointId); 37959256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh } 380c592e5a6de0011cd60f23ac18a7bd56d8eeb5dd1Hemant Gupta } catch (CursorWindowAllocationException e) { 381c592e5a6de0011cd60f23ac18a7bd56d8eeb5dd1Hemant Gupta Log.e(TAG, "CursorWindowAllocationException while composing calllog vcards"); 38259256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh } finally { 38359256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh if (callsCursor != null) { 38459256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh callsCursor.close(); 385c592e5a6de0011cd60f23ac18a7bd56d8eeb5dd1Hemant Gupta callsCursor = null; 38659256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh } 38759256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh } 38859256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh 3892f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue String recordSelection; 3902f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue if (startPoint == endPoint) { 39159256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh recordSelection = Calls._ID + "=" + startPointId; 3922f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue } else { 3932b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh // The query to call table is by "_id DESC" order, so change 3942b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh // correspondingly. 3952b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh recordSelection = Calls._ID + ">=" + endPointId + " AND " + Calls._ID + "<=" 3962b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh + startPointId; 3974446eaa935994bc91d6d308303e8d27526b4590dLixin Yue } 3984446eaa935994bc91d6d308303e8d27526b4590dLixin Yue 3992f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue String selection; 4002f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue if (typeSelection == null) { 4012f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue selection = recordSelection; 4022f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue } else { 4032f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue selection = "(" + typeSelection + ") AND (" + recordSelection + ")"; 4044446eaa935994bc91d6d308303e8d27526b4590dLixin Yue } 4054446eaa935994bc91d6d308303e8d27526b4590dLixin Yue 40659256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh if (V) Log.v(TAG, "Call log query selection is: " + selection); 4074446eaa935994bc91d6d308303e8d27526b4590dLixin Yue 4085006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai return composeCallLogsAndSendVCards(op, selection, vcardType21, null, ignorefilter, filter); 4094446eaa935994bc91d6d308303e8d27526b4590dLixin Yue } 4104446eaa935994bc91d6d308303e8d27526b4590dLixin Yue 4110b1b0069658326e8c12dc0f887e4319c5227feb5Lixin Yue public final int composeAndSendPhonebookVcards(Operation op, final int startPoint, 4126db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta final int endPoint, final boolean vcardType21, String ownerVCard, 4136db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta boolean ignorefilter, byte[] filter) { 41459256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh if (startPoint < 1 || startPoint > endPoint) { 41559256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh Log.e(TAG, "internal error: startPoint or endPoint is not correct."); 41659256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh return ResponseCodes.OBEX_HTTP_INTERNAL_ERROR; 41759256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh } 41859256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh 4193178b08c6823899dbb58513673bf2a80f637be7cRicky Wai final Uri myUri = DevicePolicyUtils.getEnterprisePhoneUri(mContext); 42059256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh Cursor contactCursor = null; 4210ff315d60bb44c5cc4223abff48e086defaec8adTony Mak Cursor contactIdCursor = new MatrixCursor(new String[] { 4220ff315d60bb44c5cc4223abff48e086defaec8adTony Mak Phone.CONTACT_ID 4230ff315d60bb44c5cc4223abff48e086defaec8adTony Mak }); 42459256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh try { 4255006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai contactCursor = mResolver.query(myUri, PHONES_CONTACTS_PROJECTION, CLAUSE_ONLY_VISIBLE, 4265006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai null, Phone.CONTACT_ID); 42759256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh if (contactCursor != null) { 4280ff315d60bb44c5cc4223abff48e086defaec8adTony Mak contactIdCursor = ContactCursorFilter.filterByRange(contactCursor, startPoint, 4290ff315d60bb44c5cc4223abff48e086defaec8adTony Mak endPoint); 43059256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh } 431c592e5a6de0011cd60f23ac18a7bd56d8eeb5dd1Hemant Gupta } catch (CursorWindowAllocationException e) { 432c592e5a6de0011cd60f23ac18a7bd56d8eeb5dd1Hemant Gupta Log.e(TAG, "CursorWindowAllocationException while composing phonebook vcards"); 43359256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh } finally { 43459256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh if (contactCursor != null) { 43559256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh contactCursor.close(); 43659256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh } 43759256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh } 4380ff315d60bb44c5cc4223abff48e086defaec8adTony Mak return composeContactsAndSendVCards(op, contactIdCursor, vcardType21, ownerVCard, 4390ff315d60bb44c5cc4223abff48e086defaec8adTony Mak ignorefilter, filter); 4404446eaa935994bc91d6d308303e8d27526b4590dLixin Yue } 4414446eaa935994bc91d6d308303e8d27526b4590dLixin Yue 4420b1b0069658326e8c12dc0f887e4319c5227feb5Lixin Yue public final int composeAndSendPhonebookOneVcard(Operation op, final int offset, 4436db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta final boolean vcardType21, String ownerVCard, int orderByWhat, 4446db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta boolean ignorefilter, byte[] filter) { 4452b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh if (offset < 1) { 4462b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh Log.e(TAG, "Internal error: offset is not correct."); 4472b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh return ResponseCodes.OBEX_HTTP_INTERNAL_ERROR; 4482b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh } 4493178b08c6823899dbb58513673bf2a80f637be7cRicky Wai final Uri myUri = DevicePolicyUtils.getEnterprisePhoneUri(mContext); 4500ff315d60bb44c5cc4223abff48e086defaec8adTony Mak 4512b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh Cursor contactCursor = null; 4520ff315d60bb44c5cc4223abff48e086defaec8adTony Mak Cursor contactIdCursor = new MatrixCursor(new String[] { 4530ff315d60bb44c5cc4223abff48e086defaec8adTony Mak Phone.CONTACT_ID 4540ff315d60bb44c5cc4223abff48e086defaec8adTony Mak }); 4553c8b50f8dc1c4ce11168fb42a884f604d1810c46Hemant Gupta // By default order is indexed 4563c8b50f8dc1c4ce11168fb42a884f604d1810c46Hemant Gupta String orderBy = Phone.CONTACT_ID; 4575006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai try { 4583c8b50f8dc1c4ce11168fb42a884f604d1810c46Hemant Gupta if (orderByWhat == BluetoothPbapObexServer.ORDER_BY_ALPHABETICAL) { 4593c8b50f8dc1c4ce11168fb42a884f604d1810c46Hemant Gupta orderBy = Phone.DISPLAY_NAME; 4603c8b50f8dc1c4ce11168fb42a884f604d1810c46Hemant Gupta } 4615006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai contactCursor = mResolver.query(myUri, PHONES_CONTACTS_PROJECTION, 4623c8b50f8dc1c4ce11168fb42a884f604d1810c46Hemant Gupta CLAUSE_ONLY_VISIBLE, null, orderBy); 4635006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai } catch (CursorWindowAllocationException e) { 4645006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai Log.e(TAG, 4653c8b50f8dc1c4ce11168fb42a884f604d1810c46Hemant Gupta "CursorWindowAllocationException while composing phonebook one vcard"); 4665006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai } finally { 4675006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai if (contactCursor != null) { 4683c8b50f8dc1c4ce11168fb42a884f604d1810c46Hemant Gupta contactIdCursor = ContactCursorFilter.filterByOffset(contactCursor, offset); 4695006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai contactCursor.close(); 4703c8b50f8dc1c4ce11168fb42a884f604d1810c46Hemant Gupta contactCursor = null; 4712b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh } 4725006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai } 4730ff315d60bb44c5cc4223abff48e086defaec8adTony Mak return composeContactsAndSendVCards(op, contactIdCursor, vcardType21, ownerVCard, 4740ff315d60bb44c5cc4223abff48e086defaec8adTony Mak ignorefilter, filter); 4750ff315d60bb44c5cc4223abff48e086defaec8adTony Mak } 4760ff315d60bb44c5cc4223abff48e086defaec8adTony Mak 4770ff315d60bb44c5cc4223abff48e086defaec8adTony Mak /** 4780ff315d60bb44c5cc4223abff48e086defaec8adTony Mak * Filter contact cursor by certain condition. 4790ff315d60bb44c5cc4223abff48e086defaec8adTony Mak */ 4800ff315d60bb44c5cc4223abff48e086defaec8adTony Mak public static final class ContactCursorFilter { 4810ff315d60bb44c5cc4223abff48e086defaec8adTony Mak /** 4820ff315d60bb44c5cc4223abff48e086defaec8adTony Mak * 4830ff315d60bb44c5cc4223abff48e086defaec8adTony Mak * @param contactCursor 4840ff315d60bb44c5cc4223abff48e086defaec8adTony Mak * @param offset 4850ff315d60bb44c5cc4223abff48e086defaec8adTony Mak * @return a cursor containing contact id of {@code offset} contact. 4860ff315d60bb44c5cc4223abff48e086defaec8adTony Mak */ 4870ff315d60bb44c5cc4223abff48e086defaec8adTony Mak public static Cursor filterByOffset(Cursor contactCursor, int offset) { 4880ff315d60bb44c5cc4223abff48e086defaec8adTony Mak return filterByRange(contactCursor, offset, offset); 4890ff315d60bb44c5cc4223abff48e086defaec8adTony Mak } 4900ff315d60bb44c5cc4223abff48e086defaec8adTony Mak 4910ff315d60bb44c5cc4223abff48e086defaec8adTony Mak /** 4920ff315d60bb44c5cc4223abff48e086defaec8adTony Mak * 4930ff315d60bb44c5cc4223abff48e086defaec8adTony Mak * @param contactCursor 4940ff315d60bb44c5cc4223abff48e086defaec8adTony Mak * @param startPoint 4950ff315d60bb44c5cc4223abff48e086defaec8adTony Mak * @param endPoint 4960ff315d60bb44c5cc4223abff48e086defaec8adTony Mak * @return a cursor containing contact ids of {@code startPoint}th to {@code endPoint}th 4970ff315d60bb44c5cc4223abff48e086defaec8adTony Mak * contact. 4980ff315d60bb44c5cc4223abff48e086defaec8adTony Mak */ 4990ff315d60bb44c5cc4223abff48e086defaec8adTony Mak public static Cursor filterByRange(Cursor contactCursor, int startPoint, int endPoint) { 5000ff315d60bb44c5cc4223abff48e086defaec8adTony Mak final int contactIdColumn = contactCursor.getColumnIndex(Data.CONTACT_ID); 5010ff315d60bb44c5cc4223abff48e086defaec8adTony Mak long previousContactId = -1; 5020ff315d60bb44c5cc4223abff48e086defaec8adTony Mak // As startPoint, endOffset index starts from 1 to n, we set 5030ff315d60bb44c5cc4223abff48e086defaec8adTony Mak // currentPoint base as 1 not 0 5040ff315d60bb44c5cc4223abff48e086defaec8adTony Mak int currentOffset = 1; 5050ff315d60bb44c5cc4223abff48e086defaec8adTony Mak final MatrixCursor contactIdsCursor = new MatrixCursor(new String[]{ 5060ff315d60bb44c5cc4223abff48e086defaec8adTony Mak Phone.CONTACT_ID 5070ff315d60bb44c5cc4223abff48e086defaec8adTony Mak }); 5080ff315d60bb44c5cc4223abff48e086defaec8adTony Mak while (contactCursor.moveToNext() && currentOffset <= endPoint) { 5090ff315d60bb44c5cc4223abff48e086defaec8adTony Mak long currentContactId = contactCursor.getLong(contactIdColumn); 5100ff315d60bb44c5cc4223abff48e086defaec8adTony Mak if (previousContactId != currentContactId) { 5110ff315d60bb44c5cc4223abff48e086defaec8adTony Mak previousContactId = currentContactId; 5120ff315d60bb44c5cc4223abff48e086defaec8adTony Mak if (currentOffset >= startPoint) { 5130ff315d60bb44c5cc4223abff48e086defaec8adTony Mak contactIdsCursor.addRow(new Long[]{currentContactId}); 5140ff315d60bb44c5cc4223abff48e086defaec8adTony Mak if (V) Log.v(TAG, "contactIdsCursor.addRow: " + currentContactId); 5150ff315d60bb44c5cc4223abff48e086defaec8adTony Mak } 5160ff315d60bb44c5cc4223abff48e086defaec8adTony Mak currentOffset++; 5172b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh } 5182b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh } 5190ff315d60bb44c5cc4223abff48e086defaec8adTony Mak return contactIdsCursor; 5202b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh } 5212b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh } 5222b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh 5235006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai /** 5245006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai * Handler enterprise contact id in VCardComposer 5255006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai */ 5265006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai private static class EnterpriseRawContactEntitlesInfoCallback implements 5275006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai VCardComposer.RawContactEntitlesInfoCallback { 5285006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai @Override 5295006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai public VCardComposer.RawContactEntitlesInfo getRawContactEntitlesInfo(long contactId) { 5305006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai if (Contacts.isEnterpriseContactId(contactId)) { 5315006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai return new VCardComposer.RawContactEntitlesInfo(RawContactsEntity.CORP_CONTENT_URI, 5325006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai contactId - Contacts.ENTERPRISE_CONTACT_ID_BASE); 5335006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai } else { 5345006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai return new VCardComposer.RawContactEntitlesInfo(RawContactsEntity.CONTENT_URI, contactId); 5355006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai } 5365006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai } 5375006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai } 5385006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai 5395006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai public final int composeContactsAndSendVCards(Operation op, final Cursor contactIdCursor, 5405006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai final boolean vcardType21, String ownerVCard, boolean ignorefilter, byte[] filter) { 5412f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue long timestamp = 0; 5422f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue if (V) timestamp = System.currentTimeMillis(); 5434446eaa935994bc91d6d308303e8d27526b4590dLixin Yue 5445006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai VCardComposer composer = null; 5455006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai VCardFilter vcardfilter = new VCardFilter(ignorefilter ? null : filter); 5465f659853fff6a50fd12e1f7956997cbef244f798Andre Eisenbach 5475006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai HandlerForStringBuffer buffer = null; 5485006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai try { 5495006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai // Currently only support Generic Vcard 2.1 and 3.0 5505006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai int vcardType; 5515006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai if (vcardType21) { 5525006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai vcardType = VCardConfig.VCARD_TYPE_V21_GENERIC; 5535006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai } else { 5545006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai vcardType = VCardConfig.VCARD_TYPE_V30_GENERIC; 5555006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai } 5565006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai if (!vcardfilter.isPhotoEnabled()) { 5575006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai vcardType |= VCardConfig.FLAG_REFRAIN_IMAGE_EXPORT; 5585006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai } 5595006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai 5605006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai // Enhancement: customize Vcard based on preferences/settings and 5615006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai // input from caller 5625006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai composer = BluetoothPbapUtils.createFilteredVCardComposer(mContext, vcardType, null); 5635006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai // End enhancement 5645006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai 5655006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai // BT does want PAUSE/WAIT conversion while it doesn't want the 5665006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai // other formatting 5675006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai // done by vCard library by default. 5685006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai composer.setPhoneNumberTranslationCallback(new VCardPhoneNumberTranslationCallback() { 5695006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai public String onValueReceived(String rawValue, int type, String label, 5705006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai boolean isPrimary) { 5715006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai // 'p' and 'w' are the standard characters for pause and 5725006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai // wait 5735006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai // (see RFC 3601) 5745006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai // so use those when exporting phone numbers via vCard. 5755006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai String numberWithControlSequence = rawValue 5765006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai .replace(PhoneNumberUtils.PAUSE, 'p').replace(PhoneNumberUtils.WAIT, 5775006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai 'w'); 5785006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai return numberWithControlSequence; 5794a53a55dc10d3a26c94e5844f7d4a2565a67142cfredc } 5805006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai }); 5815006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai buffer = new HandlerForStringBuffer(op, ownerVCard); 5825006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai Log.v(TAG, "contactIdCursor size: " + contactIdCursor.getCount()); 5835006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai if (!composer.initWithCallback(contactIdCursor, 5845006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai new EnterpriseRawContactEntitlesInfoCallback()) 5855006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai || !buffer.onInit(mContext)) { 5865006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai return ResponseCodes.OBEX_HTTP_INTERNAL_ERROR; 5875006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai } 5884446eaa935994bc91d6d308303e8d27526b4590dLixin Yue 5895006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai while (!composer.isAfterLast()) { 5905006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai if (BluetoothPbapObexServer.sIsAborted) { 5915006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai ((ServerOperation) op).isAborted = true; 5925006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai BluetoothPbapObexServer.sIsAborted = false; 5935006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai break; 5945006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai } 5955006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai String vcard = composer.createOneEntry(); 5965006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai if (vcard == null) { 5975006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai Log.e(TAG, 5985006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai "Failed to read a contact. Error reason: " + composer.getErrorReason()); 5992f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue return ResponseCodes.OBEX_HTTP_INTERNAL_ERROR; 6004446eaa935994bc91d6d308303e8d27526b4590dLixin Yue } 6015006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai if (V) Log.v(TAG, "vCard from composer: " + vcard); 602198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa 6035006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai vcard = vcardfilter.apply(vcard, vcardType21); 6045006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai vcard = StripTelephoneNumber(vcard); 6055f659853fff6a50fd12e1f7956997cbef244f798Andre Eisenbach 6065006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai if (V) Log.v(TAG, "vCard after cleanup: " + vcard); 607c7a57f31515107366589bd6875c3cc4af1fc806efredc 6085006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai if (!buffer.onEntryCreated(vcard)) { 6095006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai // onEntryCreate() already emits error. 6105006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai return ResponseCodes.OBEX_HTTP_INTERNAL_ERROR; 6113c4d2c77c2fffe675fbe89ba58856686b6873d2fDaisuke Miyakawa } 6124446eaa935994bc91d6d308303e8d27526b4590dLixin Yue } 6135006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai } finally { 6145006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai if (composer != null) { 6155006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai composer.terminate(); 6165006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai } 6175006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai if (buffer != null) { 6185006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai buffer.onTerminate(); 6195006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai } 6205006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai } 6213c4d2c77c2fffe675fbe89ba58856686b6873d2fDaisuke Miyakawa 6225006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai if (V) Log.v(TAG, "Total vcard composing and sending out takes " 6235006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai + (System.currentTimeMillis() - timestamp) + " ms"); 624198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa 6255006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai return ResponseCodes.OBEX_HTTP_OK; 6265006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai } 6275006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai 6285006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai public final int composeCallLogsAndSendVCards(Operation op, final String selection, 6295006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai final boolean vcardType21, String ownerVCard, boolean ignorefilter, 6305006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai byte[] filter) { 6315006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai long timestamp = 0; 6325006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai if (V) timestamp = System.currentTimeMillis(); 6335006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai 6345006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai BluetoothPbapCallLogComposer composer = null; 6355006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai HandlerForStringBuffer buffer = null; 6365006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai try { 6375006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai 6385006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai composer = new BluetoothPbapCallLogComposer(mContext); 6395006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai buffer = new HandlerForStringBuffer(op, ownerVCard); 6405006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai if (!composer.init(CallLog.Calls.CONTENT_URI, selection, null, CALLLOG_SORT_ORDER) 6415006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai || !buffer.onInit(mContext)) { 6425006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai return ResponseCodes.OBEX_HTTP_INTERNAL_ERROR; 6435006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai } 644c7a57f31515107366589bd6875c3cc4af1fc806efredc 6455006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai while (!composer.isAfterLast()) { 6465006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai if (BluetoothPbapObexServer.sIsAborted) { 6475006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai ((ServerOperation) op).isAborted = true; 6485006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai BluetoothPbapObexServer.sIsAborted = false; 6495006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai break; 650198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa } 6515006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai String vcard = composer.createOneEntry(vcardType21); 6525006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai if (vcard == null) { 6535006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai Log.e(TAG, 6545006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai "Failed to read a contact. Error reason: " + composer.getErrorReason()); 6555006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai return ResponseCodes.OBEX_HTTP_INTERNAL_ERROR; 656198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa } 6575006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai if (V) { 6585006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai Log.v(TAG, "Vcard Entry:"); 6595006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai Log.v(TAG, vcard); 6603c4d2c77c2fffe675fbe89ba58856686b6873d2fDaisuke Miyakawa } 6615006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai 6625006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai buffer.onEntryCreated(vcard); 6635006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai } 6645006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai } finally { 6655006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai if (composer != null) { 6665006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai composer.terminate(); 6675006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai } 6685006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai if (buffer != null) { 6695006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai buffer.onTerminate(); 6704446eaa935994bc91d6d308303e8d27526b4590dLixin Yue } 6714446eaa935994bc91d6d308303e8d27526b4590dLixin Yue } 6724446eaa935994bc91d6d308303e8d27526b4590dLixin Yue 6732f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue if (V) Log.v(TAG, "Total vcard composing and sending out takes " 6745006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai + (System.currentTimeMillis() - timestamp) + " ms"); 6752f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue return ResponseCodes.OBEX_HTTP_OK; 6764446eaa935994bc91d6d308303e8d27526b4590dLixin Yue } 6774446eaa935994bc91d6d308303e8d27526b4590dLixin Yue 67829ab94a024ffce08229f1c2c6776d1e72d2a3f75Hemant Gupta public String StripTelephoneNumber (String vCard){ 67929ab94a024ffce08229f1c2c6776d1e72d2a3f75Hemant Gupta String attr [] = vCard.split(System.getProperty("line.separator")); 68029ab94a024ffce08229f1c2c6776d1e72d2a3f75Hemant Gupta String Vcard = ""; 68129ab94a024ffce08229f1c2c6776d1e72d2a3f75Hemant Gupta for (int i=0; i < attr.length; i++) { 68229ab94a024ffce08229f1c2c6776d1e72d2a3f75Hemant Gupta if(attr[i].startsWith("TEL")) { 68329ab94a024ffce08229f1c2c6776d1e72d2a3f75Hemant Gupta attr[i] = attr[i].replace("(", ""); 68429ab94a024ffce08229f1c2c6776d1e72d2a3f75Hemant Gupta attr[i] = attr[i].replace(")", ""); 68529ab94a024ffce08229f1c2c6776d1e72d2a3f75Hemant Gupta attr[i] = attr[i].replace("-", ""); 68629ab94a024ffce08229f1c2c6776d1e72d2a3f75Hemant Gupta attr[i] = attr[i].replace(" ", ""); 68729ab94a024ffce08229f1c2c6776d1e72d2a3f75Hemant Gupta } 68829ab94a024ffce08229f1c2c6776d1e72d2a3f75Hemant Gupta } 68929ab94a024ffce08229f1c2c6776d1e72d2a3f75Hemant Gupta 69029ab94a024ffce08229f1c2c6776d1e72d2a3f75Hemant Gupta for (int i=0; i < attr.length; i++) { 69129ab94a024ffce08229f1c2c6776d1e72d2a3f75Hemant Gupta if(!attr[i].equals("")){ 69229ab94a024ffce08229f1c2c6776d1e72d2a3f75Hemant Gupta Vcard = Vcard.concat(attr[i] + "\n"); 69329ab94a024ffce08229f1c2c6776d1e72d2a3f75Hemant Gupta } 69429ab94a024ffce08229f1c2c6776d1e72d2a3f75Hemant Gupta } 69502fc1acb99dbf3ae0a710ee7e4b6de8dd779e84eRakesh Iyer if (V) Log.v(TAG, "Vcard with stripped telephone no.: " + Vcard); 69629ab94a024ffce08229f1c2c6776d1e72d2a3f75Hemant Gupta return Vcard; 69729ab94a024ffce08229f1c2c6776d1e72d2a3f75Hemant Gupta } 69829ab94a024ffce08229f1c2c6776d1e72d2a3f75Hemant Gupta 6992f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue /** 700ce8d51a3a43d113a4a6bad30d595c2a81d0f623cYoshiharu Kurita * Handler to emit vCards to PCE. 7012f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue */ 7023c4d2c77c2fffe675fbe89ba58856686b6873d2fDaisuke Miyakawa public class HandlerForStringBuffer { 7032f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue private Operation operation; 7044446eaa935994bc91d6d308303e8d27526b4590dLixin Yue 7052f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue private OutputStream outputStream; 7062f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue 7072f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue private String phoneOwnVCard = null; 7082f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue 7092f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue public HandlerForStringBuffer(Operation op, String ownerVCard) { 7102f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue operation = op; 7112f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue if (ownerVCard != null) { 7122f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue phoneOwnVCard = ownerVCard; 7132f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue if (V) Log.v(TAG, "phone own number vcard:"); 7142f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue if (V) Log.v(TAG, phoneOwnVCard); 7152c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 7162c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 7172c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 718ce8d51a3a43d113a4a6bad30d595c2a81d0f623cYoshiharu Kurita private boolean write(String vCard) { 719ce8d51a3a43d113a4a6bad30d595c2a81d0f623cYoshiharu Kurita try { 720ce8d51a3a43d113a4a6bad30d595c2a81d0f623cYoshiharu Kurita if (vCard != null) { 721ce8d51a3a43d113a4a6bad30d595c2a81d0f623cYoshiharu Kurita outputStream.write(vCard.getBytes()); 722ce8d51a3a43d113a4a6bad30d595c2a81d0f623cYoshiharu Kurita return true; 723ce8d51a3a43d113a4a6bad30d595c2a81d0f623cYoshiharu Kurita } 724ce8d51a3a43d113a4a6bad30d595c2a81d0f623cYoshiharu Kurita } catch (IOException e) { 725ce8d51a3a43d113a4a6bad30d595c2a81d0f623cYoshiharu Kurita Log.e(TAG, "write outputstrem failed" + e.toString()); 726ce8d51a3a43d113a4a6bad30d595c2a81d0f623cYoshiharu Kurita } 727ce8d51a3a43d113a4a6bad30d595c2a81d0f623cYoshiharu Kurita return false; 728ce8d51a3a43d113a4a6bad30d595c2a81d0f623cYoshiharu Kurita } 729ce8d51a3a43d113a4a6bad30d595c2a81d0f623cYoshiharu Kurita 7302f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue public boolean onInit(Context context) { 7312f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue try { 7322f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue outputStream = operation.openOutputStream(); 7332f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue if (phoneOwnVCard != null) { 734ce8d51a3a43d113a4a6bad30d595c2a81d0f623cYoshiharu Kurita return write(phoneOwnVCard); 7352c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 736ce8d51a3a43d113a4a6bad30d595c2a81d0f623cYoshiharu Kurita return true; 7372f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue } catch (IOException e) { 7382f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue Log.e(TAG, "open outputstrem failed" + e.toString()); 7392c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 740ce8d51a3a43d113a4a6bad30d595c2a81d0f623cYoshiharu Kurita return false; 7412c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 7422c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 7432f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue public boolean onEntryCreated(String vcard) { 744ce8d51a3a43d113a4a6bad30d595c2a81d0f623cYoshiharu Kurita return write(vcard); 7452c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 7462c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 7472f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue public void onTerminate() { 7482f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue if (!BluetoothPbapObexServer.closeStream(outputStream, operation)) { 7492f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue if (V) Log.v(TAG, "CloseStream failed!"); 7502c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } else { 7512f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue if (V) Log.v(TAG, "CloseStream ok!"); 7522c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 7532c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 7542c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 7556db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta 7565f659853fff6a50fd12e1f7956997cbef244f798Andre Eisenbach public static class VCardFilter { 7575f659853fff6a50fd12e1f7956997cbef244f798Andre Eisenbach private static enum FilterBit { 7585f659853fff6a50fd12e1f7956997cbef244f798Andre Eisenbach // bit property onlyCheckV21 excludeForV21 7595f659853fff6a50fd12e1f7956997cbef244f798Andre Eisenbach FN ( 1, "FN", true, false), 7605f659853fff6a50fd12e1f7956997cbef244f798Andre Eisenbach PHOTO( 3, "PHOTO", false, false), 7615f659853fff6a50fd12e1f7956997cbef244f798Andre Eisenbach BDAY( 4, "BDAY", false, false), 7625f659853fff6a50fd12e1f7956997cbef244f798Andre Eisenbach ADR( 5, "ADR", false, false), 7635f659853fff6a50fd12e1f7956997cbef244f798Andre Eisenbach EMAIL( 8, "EMAIL", false, false), 7645f659853fff6a50fd12e1f7956997cbef244f798Andre Eisenbach TITLE( 12, "TITLE", false, false), 7655f659853fff6a50fd12e1f7956997cbef244f798Andre Eisenbach ORG( 16, "ORG", false, false), 766976a53f0f946e589aa2b5204ce3262abcf2afc55Hemant Gupta NOTE( 17, "NOTE", false, false), 7675f659853fff6a50fd12e1f7956997cbef244f798Andre Eisenbach URL( 20, "URL", false, false), 768976a53f0f946e589aa2b5204ce3262abcf2afc55Hemant Gupta NICKNAME( 23, "NICKNAME", false, true), 769976a53f0f946e589aa2b5204ce3262abcf2afc55Hemant Gupta DATETIME( 28, "DATETIME", false, true); 7705f659853fff6a50fd12e1f7956997cbef244f798Andre Eisenbach 7715f659853fff6a50fd12e1f7956997cbef244f798Andre Eisenbach public final int pos; 7725f659853fff6a50fd12e1f7956997cbef244f798Andre Eisenbach public final String prop; 7735f659853fff6a50fd12e1f7956997cbef244f798Andre Eisenbach public final boolean onlyCheckV21; 7745f659853fff6a50fd12e1f7956997cbef244f798Andre Eisenbach public final boolean excludeForV21; 7755f659853fff6a50fd12e1f7956997cbef244f798Andre Eisenbach 7765f659853fff6a50fd12e1f7956997cbef244f798Andre Eisenbach FilterBit(int pos, String prop, boolean onlyCheckV21, boolean excludeForV21) { 7775f659853fff6a50fd12e1f7956997cbef244f798Andre Eisenbach this.pos = pos; 7785f659853fff6a50fd12e1f7956997cbef244f798Andre Eisenbach this.prop = prop; 7795f659853fff6a50fd12e1f7956997cbef244f798Andre Eisenbach this.onlyCheckV21 = onlyCheckV21; 7805f659853fff6a50fd12e1f7956997cbef244f798Andre Eisenbach this.excludeForV21 = excludeForV21; 7815f659853fff6a50fd12e1f7956997cbef244f798Andre Eisenbach } 7825f659853fff6a50fd12e1f7956997cbef244f798Andre Eisenbach } 7835f659853fff6a50fd12e1f7956997cbef244f798Andre Eisenbach 7845f659853fff6a50fd12e1f7956997cbef244f798Andre Eisenbach private static final String SEPARATOR = System.getProperty("line.separator"); 7855f659853fff6a50fd12e1f7956997cbef244f798Andre Eisenbach private final byte[] filter; 7865f659853fff6a50fd12e1f7956997cbef244f798Andre Eisenbach 787976a53f0f946e589aa2b5204ce3262abcf2afc55Hemant Gupta //This function returns true if the attributes needs to be included in the filtered vcard. 788976a53f0f946e589aa2b5204ce3262abcf2afc55Hemant Gupta private boolean isFilteredIn(FilterBit bit, boolean vCardType21) { 7895f659853fff6a50fd12e1f7956997cbef244f798Andre Eisenbach final int offset = (bit.pos / 8) + 1; 7905f659853fff6a50fd12e1f7956997cbef244f798Andre Eisenbach final int bit_pos = bit.pos % 8; 791976a53f0f946e589aa2b5204ce3262abcf2afc55Hemant Gupta if (!vCardType21 && bit.onlyCheckV21) return true; 792976a53f0f946e589aa2b5204ce3262abcf2afc55Hemant Gupta if (vCardType21 && bit.excludeForV21) return false; 793976a53f0f946e589aa2b5204ce3262abcf2afc55Hemant Gupta if (filter == null || offset >= filter.length) return true; 7945f659853fff6a50fd12e1f7956997cbef244f798Andre Eisenbach return ((filter[filter.length - offset] >> bit_pos) & 0x01) != 0; 7955f659853fff6a50fd12e1f7956997cbef244f798Andre Eisenbach } 7965f659853fff6a50fd12e1f7956997cbef244f798Andre Eisenbach 7975f659853fff6a50fd12e1f7956997cbef244f798Andre Eisenbach VCardFilter(byte[] filter) { 7985f659853fff6a50fd12e1f7956997cbef244f798Andre Eisenbach this.filter = filter; 7995f659853fff6a50fd12e1f7956997cbef244f798Andre Eisenbach } 8005f659853fff6a50fd12e1f7956997cbef244f798Andre Eisenbach 8015f659853fff6a50fd12e1f7956997cbef244f798Andre Eisenbach public boolean isPhotoEnabled() { 802976a53f0f946e589aa2b5204ce3262abcf2afc55Hemant Gupta return isFilteredIn(FilterBit.PHOTO, false); 8035f659853fff6a50fd12e1f7956997cbef244f798Andre Eisenbach } 8045f659853fff6a50fd12e1f7956997cbef244f798Andre Eisenbach 8055f659853fff6a50fd12e1f7956997cbef244f798Andre Eisenbach public String apply(String vCard, boolean vCardType21){ 8065f659853fff6a50fd12e1f7956997cbef244f798Andre Eisenbach if (filter == null) return vCard; 8075f659853fff6a50fd12e1f7956997cbef244f798Andre Eisenbach String lines[] = vCard.split(SEPARATOR); 8085f659853fff6a50fd12e1f7956997cbef244f798Andre Eisenbach StringBuilder filteredVCard = new StringBuilder(); 809976a53f0f946e589aa2b5204ce3262abcf2afc55Hemant Gupta boolean filteredIn = false; 8105f659853fff6a50fd12e1f7956997cbef244f798Andre Eisenbach 8115f659853fff6a50fd12e1f7956997cbef244f798Andre Eisenbach for (String line : lines) { 8125f659853fff6a50fd12e1f7956997cbef244f798Andre Eisenbach // Check whether the current property is changing (ignoring multi-line properties) 8135f659853fff6a50fd12e1f7956997cbef244f798Andre Eisenbach // and determine if the current property is filtered in. 8145f659853fff6a50fd12e1f7956997cbef244f798Andre Eisenbach if (!Character.isWhitespace(line.charAt(0)) && !line.startsWith("=")) { 8155f659853fff6a50fd12e1f7956997cbef244f798Andre Eisenbach String currentProp = line.split("[;:]")[0]; 816976a53f0f946e589aa2b5204ce3262abcf2afc55Hemant Gupta filteredIn = true; 8175f659853fff6a50fd12e1f7956997cbef244f798Andre Eisenbach 8185f659853fff6a50fd12e1f7956997cbef244f798Andre Eisenbach for (FilterBit bit : FilterBit.values()) { 8195f659853fff6a50fd12e1f7956997cbef244f798Andre Eisenbach if (bit.prop.equals(currentProp)) { 820976a53f0f946e589aa2b5204ce3262abcf2afc55Hemant Gupta filteredIn = isFilteredIn(bit, vCardType21); 8215f659853fff6a50fd12e1f7956997cbef244f798Andre Eisenbach break; 8226db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta } 8236db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta } 8246db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta 8255f659853fff6a50fd12e1f7956997cbef244f798Andre Eisenbach // Since PBAP does not have filter bits for IM and SIP, 8265f659853fff6a50fd12e1f7956997cbef244f798Andre Eisenbach // exclude them by default. Easiest way is to exclude all 8275f659853fff6a50fd12e1f7956997cbef244f798Andre Eisenbach // X- fields.... 828976a53f0f946e589aa2b5204ce3262abcf2afc55Hemant Gupta if (currentProp.startsWith("X-")) filteredIn = false; 8296db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta } 8306db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta 8315f659853fff6a50fd12e1f7956997cbef244f798Andre Eisenbach // Build filtered vCard 832976a53f0f946e589aa2b5204ce3262abcf2afc55Hemant Gupta if (filteredIn) filteredVCard.append(line + SEPARATOR); 8336db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta } 8346db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta 8355f659853fff6a50fd12e1f7956997cbef244f798Andre Eisenbach return filteredVCard.toString(); 8366db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta } 8376db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta } 8385006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai 8395006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai private static final Uri getPhoneLookupFilterUri() { 8405006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai return PhoneLookup.ENTERPRISE_CONTENT_FILTER_URI; 8415006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai } 8425006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai /** 8435006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai * Get size of the cursor without duplicated contact id. This assumes the 8446a50944dff2081fc161974cfae7d85d834b123cfSmriti Gupta * given cursor is sorted by CONTACT_ID. 8455006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai */ 8469d68ffa1079ca2e85a8ccf62bf8dca2f43f1ade3Tony Mak /** 8479d68ffa1079ca2e85a8ccf62bf8dca2f43f1ade3Tony Mak * Count number of rows having distinct contact id. It assumes 8489d68ffa1079ca2e85a8ccf62bf8dca2f43f1ade3Tony Mak * @param cursor cursor to be counted. 8499d68ffa1079ca2e85a8ccf62bf8dca2f43f1ade3Tony Mak * @param contactIdColumn column name of contact id 8509d68ffa1079ca2e85a8ccf62bf8dca2f43f1ade3Tony Mak * @return number of rows that have distinct contact id. 8519d68ffa1079ca2e85a8ccf62bf8dca2f43f1ade3Tony Mak */ 8529d68ffa1079ca2e85a8ccf62bf8dca2f43f1ade3Tony Mak private static final int getDistinctContactIdSize(Cursor cursor, String contactIdColumn) { 8539d68ffa1079ca2e85a8ccf62bf8dca2f43f1ade3Tony Mak final int contactIdColumnIndex = cursor.getColumnIndexOrThrow(contactIdColumn); 8545006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai long previousContactId = -1; 8555006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai int count = 0; 8565006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai cursor.moveToPosition(-1); 8575006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai while (cursor.moveToNext()) { 8589d68ffa1079ca2e85a8ccf62bf8dca2f43f1ade3Tony Mak final long contactId = cursor.getLong(contactIdColumnIndex); 8595006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai if (previousContactId != contactId) { 8605006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai count++; 8615006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai previousContactId = contactId; 8625006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai } 8635006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai } 8645006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai if (V) { 8655006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai Log.i(TAG, "getDistinctContactIdSize result: " + count); 8665006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai } 8675006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai return count; 8685006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai } 8695006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai 8705006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai /** 8719d68ffa1079ca2e85a8ccf62bf8dca2f43f1ade3Tony Mak * Construct "display_name,contact_id" strings and insert into a arraylist. 8729d68ffa1079ca2e85a8ccf62bf8dca2f43f1ade3Tony Mak * 8739d68ffa1079ca2e85a8ccf62bf8dca2f43f1ade3Tony Mak * @param resultList list to be inserted. 8749d68ffa1079ca2e85a8ccf62bf8dca2f43f1ade3Tony Mak * @param defaultName default name if the name of contact is empty. 8759d68ffa1079ca2e85a8ccf62bf8dca2f43f1ade3Tony Mak * @param cursor a cursor containing contact id and display name. 8769d68ffa1079ca2e85a8ccf62bf8dca2f43f1ade3Tony Mak * @param contactIdColumnName name of column that stores contact id. 8779d68ffa1079ca2e85a8ccf62bf8dca2f43f1ade3Tony Mak * @param displayNameColumnName name of column that stores display name. 8785006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai */ 8795006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai private static void appendDistinctNameIdList(ArrayList<String> resultList, 8809d68ffa1079ca2e85a8ccf62bf8dca2f43f1ade3Tony Mak String defaultName, Cursor cursor, String contactIdColumnName, 8819d68ffa1079ca2e85a8ccf62bf8dca2f43f1ade3Tony Mak String displayNameColumnName) { 8829d68ffa1079ca2e85a8ccf62bf8dca2f43f1ade3Tony Mak final int contactIdColumnIndex = cursor.getColumnIndexOrThrow(contactIdColumnName); 8839d68ffa1079ca2e85a8ccf62bf8dca2f43f1ade3Tony Mak final int displayNameColumnIndex = cursor.getColumnIndexOrThrow(displayNameColumnName); 8849d68ffa1079ca2e85a8ccf62bf8dca2f43f1ade3Tony Mak 8855006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai long previousContactId = -1; 8865006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai cursor.moveToPosition(-1); 8875006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai while (cursor.moveToNext()) { 8889d68ffa1079ca2e85a8ccf62bf8dca2f43f1ade3Tony Mak final long contactId = cursor.getLong(contactIdColumnIndex); 8899d68ffa1079ca2e85a8ccf62bf8dca2f43f1ade3Tony Mak String displayName = cursor.getString(displayNameColumnIndex); 8905006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai if (TextUtils.isEmpty(displayName)) { 8915006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai displayName = defaultName; 8925006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai } 8935006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai 8946a50944dff2081fc161974cfae7d85d834b123cfSmriti Gupta String newString = displayName + "," + contactId; 8956a50944dff2081fc161974cfae7d85d834b123cfSmriti Gupta if (!resultList.contains(newString)) { 8966a50944dff2081fc161974cfae7d85d834b123cfSmriti Gupta resultList.add(newString); 8975006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai } 8985006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai } 8995006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai if (V) { 9005006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai for (String nameId : resultList) { 9015006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai Log.i(TAG, "appendDistinctNameIdList result: " + nameId); 9025006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai } 9035006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai } 9045006c8597521a7652eafa89a6fb5483b5cb567b6Ricky Wai } 9052c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan} 906