BluetoothPbapVcardManager.java revision c592e5a6de0011cd60f23ac18a7bd56d8eeb5dd1
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 362f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yueimport android.content.ContentResolver; 372f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yueimport android.content.Context; 38c592e5a6de0011cd60f23ac18a7bd56d8eeb5dd1Hemant Guptaimport android.database.CursorWindowAllocationException; 39198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawaimport android.database.Cursor; 40198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawaimport android.net.Uri; 41198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawaimport android.provider.CallLog; 42198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawaimport android.provider.CallLog.Calls; 432f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yueimport android.provider.ContactsContract.CommonDataKinds; 442f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yueimport android.provider.ContactsContract.Contacts; 452f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yueimport android.provider.ContactsContract.Data; 462f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yueimport android.provider.ContactsContract.CommonDataKinds.Phone; 470dcd2262d853c2011e11617a8efba6758370c41fLiejun Taoimport android.provider.ContactsContract.PhoneLookup; 48d956b40b2f59599447ae0fa0762e055c0c0ce1a3Daisuke Miyakawaimport android.telephony.PhoneNumberUtils; 49198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawaimport android.text.TextUtils; 50198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawaimport android.util.Log; 51198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa 52198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawaimport com.android.bluetooth.R; 5312cb33f6d9fd269944a5618661e3880beea58b6eDaisuke Miyakawaimport com.android.vcard.VCardComposer; 5412cb33f6d9fd269944a5618661e3880beea58b6eDaisuke Miyakawaimport com.android.vcard.VCardConfig; 55d956b40b2f59599447ae0fa0762e055c0c0ce1a3Daisuke Miyakawaimport com.android.vcard.VCardPhoneNumberTranslationCallback; 562f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue 572f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yueimport java.io.IOException; 582f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yueimport java.io.OutputStream; 592c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fanimport java.util.ArrayList; 602c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 610b1b0069658326e8c12dc0f887e4319c5227feb5Lixin Yueimport javax.obex.ServerOperation; 62198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawaimport javax.obex.Operation; 63198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawaimport javax.obex.ResponseCodes; 64198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa 65c7a57f31515107366589bd6875c3cc4af1fc806efredcimport com.android.bluetooth.Utils; 66c7a57f31515107366589bd6875c3cc4af1fc806efredc 672c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fanpublic class BluetoothPbapVcardManager { 682f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue private static final String TAG = "BluetoothPbapVcardManager"; 692c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 704446eaa935994bc91d6d308303e8d27526b4590dLixin Yue private static final boolean V = BluetoothPbapService.VERBOSE; 714446eaa935994bc91d6d308303e8d27526b4590dLixin Yue 722c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan private ContentResolver mResolver; 732c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 742c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan private Context mContext; 752c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 762f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue static final String[] PHONES_PROJECTION = new String[] { 772f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue Data._ID, // 0 782f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue CommonDataKinds.Phone.TYPE, // 1 792f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue CommonDataKinds.Phone.LABEL, // 2 802f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue CommonDataKinds.Phone.NUMBER, // 3 812f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue Contacts.DISPLAY_NAME, // 4 822c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan }; 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 882b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh static final String[] CONTACTS_PROJECTION = new String[] { 892b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh Contacts._ID, // 0 902b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh Contacts.DISPLAY_NAME, // 1 912b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh }; 922b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh 932b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh static final int CONTACTS_ID_COLUMN_INDEX = 0; 942b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh 952b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh static final int CONTACTS_NAME_COLUMN_INDEX = 1; 962b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh 972b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh // call histories use dynamic handles, and handles should order by date; the 982b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh // most recently one should be the first handle. In table "calls", _id and 992b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh // date are consistent in ordering, to implement simply, we sort by _id 1002b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh // here. 1012b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh static final String CALLLOG_SORT_ORDER = Calls._ID + " DESC"; 1022b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh 103cd5ed0c7d04119e508fbddfd9656ef8559e3e524Lixin Yue private static final String CLAUSE_ONLY_VISIBLE = Contacts.IN_VISIBLE_GROUP + "=1"; 104cd5ed0c7d04119e508fbddfd9656ef8559e3e524Lixin Yue 1052c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan public BluetoothPbapVcardManager(final Context context) { 1062c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan mContext = context; 1072c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan mResolver = mContext.getContentResolver(); 1082c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 1092c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 110c7a57f31515107366589bd6875c3cc4af1fc806efredc /** 111c7a57f31515107366589bd6875c3cc4af1fc806efredc * Create an owner vcard from the configured profile 112c7a57f31515107366589bd6875c3cc4af1fc806efredc * @param vcardType21 113c7a57f31515107366589bd6875c3cc4af1fc806efredc * @return 114c7a57f31515107366589bd6875c3cc4af1fc806efredc */ 115c7a57f31515107366589bd6875c3cc4af1fc806efredc private final String getOwnerPhoneNumberVcardFromProfile(final boolean vcardType21, final byte[] filter) { 116c7a57f31515107366589bd6875c3cc4af1fc806efredc // Currently only support Generic Vcard 2.1 and 3.0 117c7a57f31515107366589bd6875c3cc4af1fc806efredc int vcardType; 118c7a57f31515107366589bd6875c3cc4af1fc806efredc if (vcardType21) { 119c7a57f31515107366589bd6875c3cc4af1fc806efredc vcardType = VCardConfig.VCARD_TYPE_V21_GENERIC; 120c7a57f31515107366589bd6875c3cc4af1fc806efredc } else { 121c7a57f31515107366589bd6875c3cc4af1fc806efredc vcardType = VCardConfig.VCARD_TYPE_V30_GENERIC; 122c7a57f31515107366589bd6875c3cc4af1fc806efredc } 1234a53a55dc10d3a26c94e5844f7d4a2565a67142cfredc 1244a53a55dc10d3a26c94e5844f7d4a2565a67142cfredc if (!BluetoothPbapConfig.includePhotosInVcard()) { 1254a53a55dc10d3a26c94e5844f7d4a2565a67142cfredc vcardType |= VCardConfig.FLAG_REFRAIN_IMAGE_EXPORT; 1264a53a55dc10d3a26c94e5844f7d4a2565a67142cfredc } 1274a53a55dc10d3a26c94e5844f7d4a2565a67142cfredc 128c7a57f31515107366589bd6875c3cc4af1fc806efredc return BluetoothPbapUtils.createProfileVCard(mContext, vcardType,filter); 129c7a57f31515107366589bd6875c3cc4af1fc806efredc } 130c7a57f31515107366589bd6875c3cc4af1fc806efredc 131c7a57f31515107366589bd6875c3cc4af1fc806efredc public final String getOwnerPhoneNumberVcard(final boolean vcardType21, final byte[] filter) { 132c7a57f31515107366589bd6875c3cc4af1fc806efredc //Owner vCard enhancement: Use "ME" profile if configured 133c7a57f31515107366589bd6875c3cc4af1fc806efredc if (BluetoothPbapConfig.useProfileForOwnerVcard()) { 134c7a57f31515107366589bd6875c3cc4af1fc806efredc String vcard = getOwnerPhoneNumberVcardFromProfile(vcardType21, filter); 135c7a57f31515107366589bd6875c3cc4af1fc806efredc if (vcard != null && vcard.length() != 0) { 136c7a57f31515107366589bd6875c3cc4af1fc806efredc return vcard; 137c7a57f31515107366589bd6875c3cc4af1fc806efredc } 138c7a57f31515107366589bd6875c3cc4af1fc806efredc } 139c7a57f31515107366589bd6875c3cc4af1fc806efredc //End enhancement 140c7a57f31515107366589bd6875c3cc4af1fc806efredc 1413c4d2c77c2fffe675fbe89ba58856686b6873d2fDaisuke Miyakawa BluetoothPbapCallLogComposer composer = new BluetoothPbapCallLogComposer(mContext); 1422f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue String name = BluetoothPbapService.getLocalPhoneName(); 1432f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue String number = BluetoothPbapService.getLocalPhoneNum(); 1442f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue String vcard = composer.composeVCardForPhoneOwnNumber(Phone.TYPE_MOBILE, name, number, 1452f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue vcardType21); 1462f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue return vcard; 1472c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 1482c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 1492f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue public final int getPhonebookSize(final int type) { 1502f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue int size; 1512f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue switch (type) { 1522f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue case BluetoothPbapObexServer.ContentType.PHONEBOOK: 1532f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue size = getContactsSize(); 1542f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue break; 1552f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue default: 1562f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue size = getCallHistorySize(type); 1572f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue break; 1582c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 159c7a57f31515107366589bd6875c3cc4af1fc806efredc if (V) Log.v(TAG, "getPhonebookSize size = " + size + " type = " + type); 1602f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue return size; 1612c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 1622c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 1632f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue public final int getContactsSize() { 1642b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh final Uri myUri = Contacts.CONTENT_URI; 1652f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue int size = 0; 1662f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue Cursor contactCursor = null; 1672f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue try { 168cd5ed0c7d04119e508fbddfd9656ef8559e3e524Lixin Yue contactCursor = mResolver.query(myUri, null, CLAUSE_ONLY_VISIBLE, null, null); 1692f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue if (contactCursor != null) { 1702f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue size = contactCursor.getCount() + 1; // always has the 0.vcf 1712f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue } 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(); 177c592e5a6de0011cd60f23ac18a7bd56d8eeb5dd1Hemant Gupta contactCursor = null; 1782f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue } 1792c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 1802f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue return size; 1812c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 1822c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 1832f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue public final int getCallHistorySize(final int type) { 1842b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh final Uri myUri = CallLog.Calls.CONTENT_URI; 1852f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue String selection = BluetoothPbapObexServer.createSelectionPara(type); 1862f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue int size = 0; 1872f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue Cursor callCursor = null; 1882f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue try { 1892f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue callCursor = mResolver.query(myUri, null, selection, null, 1902f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue CallLog.Calls.DEFAULT_SORT_ORDER); 1912f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue if (callCursor != null) { 1922f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue size = callCursor.getCount(); 1934446eaa935994bc91d6d308303e8d27526b4590dLixin Yue } 194c592e5a6de0011cd60f23ac18a7bd56d8eeb5dd1Hemant Gupta } catch (CursorWindowAllocationException e) { 195c592e5a6de0011cd60f23ac18a7bd56d8eeb5dd1Hemant Gupta Log.e(TAG, "CursorWindowAllocationException while getting CallHistory size"); 1962f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue } finally { 1972f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue if (callCursor != null) { 1982f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue callCursor.close(); 199c592e5a6de0011cd60f23ac18a7bd56d8eeb5dd1Hemant Gupta callCursor = null; 2004446eaa935994bc91d6d308303e8d27526b4590dLixin Yue } 2012f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue } 2022f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue return size; 2032f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue } 2044446eaa935994bc91d6d308303e8d27526b4590dLixin Yue 2052f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue public final ArrayList<String> loadCallHistoryList(final int type) { 2062b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh final Uri myUri = CallLog.Calls.CONTENT_URI; 2072f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue String selection = BluetoothPbapObexServer.createSelectionPara(type); 2082f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue String[] projection = new String[] { 2099674eb043aeb1474aa23ddd0739e3b8f05432630Jay Shrauner Calls.NUMBER, Calls.CACHED_NAME, Calls.NUMBER_PRESENTATION 2102f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue }; 2112f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue final int CALLS_NUMBER_COLUMN_INDEX = 0; 2122f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue final int CALLS_NAME_COLUMN_INDEX = 1; 2139674eb043aeb1474aa23ddd0739e3b8f05432630Jay Shrauner final int CALLS_NUMBER_PRESENTATION_COLUMN_INDEX = 2; 2142f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue 2152f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue Cursor callCursor = null; 2162f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue ArrayList<String> list = new ArrayList<String>(); 2172f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue try { 2182f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue callCursor = mResolver.query(myUri, projection, selection, null, 2192b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh CALLLOG_SORT_ORDER); 2202f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue if (callCursor != null) { 2212f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue for (callCursor.moveToFirst(); !callCursor.isAfterLast(); 2222f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue callCursor.moveToNext()) { 2232f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue String name = callCursor.getString(CALLS_NAME_COLUMN_INDEX); 2242f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue if (TextUtils.isEmpty(name)) { 22577ba5f6684f4dd7e4b7fc37982271da5654aec07Staffan Lindvall // name not found, use number instead 2269674eb043aeb1474aa23ddd0739e3b8f05432630Jay Shrauner final int numberPresentation = callCursor.getInt( 2279674eb043aeb1474aa23ddd0739e3b8f05432630Jay Shrauner CALLS_NUMBER_PRESENTATION_COLUMN_INDEX); 2289674eb043aeb1474aa23ddd0739e3b8f05432630Jay Shrauner if (numberPresentation != Calls.PRESENTATION_ALLOWED) { 22977ba5f6684f4dd7e4b7fc37982271da5654aec07Staffan Lindvall name = mContext.getString(R.string.unknownNumber); 2309674eb043aeb1474aa23ddd0739e3b8f05432630Jay Shrauner } else { 2319674eb043aeb1474aa23ddd0739e3b8f05432630Jay Shrauner name = callCursor.getString(CALLS_NUMBER_COLUMN_INDEX); 23277ba5f6684f4dd7e4b7fc37982271da5654aec07Staffan Lindvall } 2332f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue } 2342f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue list.add(name); 2352f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue } 2362f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue } 237c592e5a6de0011cd60f23ac18a7bd56d8eeb5dd1Hemant Gupta } catch (CursorWindowAllocationException e) { 238c592e5a6de0011cd60f23ac18a7bd56d8eeb5dd1Hemant Gupta Log.e(TAG, "CursorWindowAllocationException while loading CallHistory"); 2392f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue } finally { 2402f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue if (callCursor != null) { 2412f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue callCursor.close(); 242c592e5a6de0011cd60f23ac18a7bd56d8eeb5dd1Hemant Gupta callCursor = null; 2432c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 2442c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 2452f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue return list; 2462c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 2472c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 2482b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh public final ArrayList<String> getPhonebookNameList(final int orderByWhat) { 2492f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue ArrayList<String> nameList = new ArrayList<String>(); 250c7a57f31515107366589bd6875c3cc4af1fc806efredc //Owner vCard enhancement. Use "ME" profile if configured 251c7a57f31515107366589bd6875c3cc4af1fc806efredc String ownerName = null; 252c7a57f31515107366589bd6875c3cc4af1fc806efredc if (BluetoothPbapConfig.useProfileForOwnerVcard()) { 253c7a57f31515107366589bd6875c3cc4af1fc806efredc ownerName = BluetoothPbapUtils.getProfileName(mContext); 254c7a57f31515107366589bd6875c3cc4af1fc806efredc } 255c7a57f31515107366589bd6875c3cc4af1fc806efredc if (ownerName == null || ownerName.length()==0) { 256c7a57f31515107366589bd6875c3cc4af1fc806efredc ownerName = BluetoothPbapService.getLocalPhoneName(); 257c7a57f31515107366589bd6875c3cc4af1fc806efredc } 258c7a57f31515107366589bd6875c3cc4af1fc806efredc nameList.add(ownerName); 259c7a57f31515107366589bd6875c3cc4af1fc806efredc //End enhancement 2604446eaa935994bc91d6d308303e8d27526b4590dLixin Yue 2612b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh final Uri myUri = Contacts.CONTENT_URI; 2622b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh Cursor contactCursor = null; 2632f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue try { 2642b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh if (orderByWhat == BluetoothPbapObexServer.ORDER_BY_INDEXED) { 2650dcd2262d853c2011e11617a8efba6758370c41fLiejun Tao if (V) Log.v(TAG, "getPhonebookNameList, order by index"); 266cd5ed0c7d04119e508fbddfd9656ef8559e3e524Lixin Yue contactCursor = mResolver.query(myUri, CONTACTS_PROJECTION, CLAUSE_ONLY_VISIBLE, 267cd5ed0c7d04119e508fbddfd9656ef8559e3e524Lixin Yue null, Contacts._ID); 2682b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh } else if (orderByWhat == BluetoothPbapObexServer.ORDER_BY_ALPHABETICAL) { 2690dcd2262d853c2011e11617a8efba6758370c41fLiejun Tao if (V) Log.v(TAG, "getPhonebookNameList, order by alpha"); 270cd5ed0c7d04119e508fbddfd9656ef8559e3e524Lixin Yue contactCursor = mResolver.query(myUri, CONTACTS_PROJECTION, CLAUSE_ONLY_VISIBLE, 271cd5ed0c7d04119e508fbddfd9656ef8559e3e524Lixin Yue null, Contacts.DISPLAY_NAME); 2722b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh } 2732b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh if (contactCursor != null) { 2742b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh for (contactCursor.moveToFirst(); !contactCursor.isAfterLast(); contactCursor 2752f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue .moveToNext()) { 2762b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh String name = contactCursor.getString(CONTACTS_NAME_COLUMN_INDEX); 277130969d18eadbd94361fe95bf16b8131cdea6168Hemant Gupta long id = contactCursor.getLong(CONTACTS_ID_COLUMN_INDEX); 2782f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue if (TextUtils.isEmpty(name)) { 2792f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue name = mContext.getString(android.R.string.unknownName); 2802f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue } 281130969d18eadbd94361fe95bf16b8131cdea6168Hemant Gupta nameList.add(name + "," + id); 2822f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue } 2832f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue } 284c592e5a6de0011cd60f23ac18a7bd56d8eeb5dd1Hemant Gupta } catch (CursorWindowAllocationException e) { 285c592e5a6de0011cd60f23ac18a7bd56d8eeb5dd1Hemant Gupta Log.e(TAG, "CursorWindowAllocationException while getting Phonebook name list"); 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>(); 2970dcd2262d853c2011e11617a8efba6758370c41fLiejun Tao 2980dcd2262d853c2011e11617a8efba6758370c41fLiejun Tao Cursor contactCursor = null; 2994bba23a751f042596561eab0e677135d5267bcdfStaffan Lindvall Uri uri = null; 3004bba23a751f042596561eab0e677135d5267bcdfStaffan Lindvall 3014bba23a751f042596561eab0e677135d5267bcdfStaffan Lindvall if (phoneNumber != null && phoneNumber.length() == 0) { 3024bba23a751f042596561eab0e677135d5267bcdfStaffan Lindvall uri = Contacts.CONTENT_URI; 3034bba23a751f042596561eab0e677135d5267bcdfStaffan Lindvall } else { 3044bba23a751f042596561eab0e677135d5267bcdfStaffan Lindvall uri = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, 3050dcd2262d853c2011e11617a8efba6758370c41fLiejun Tao Uri.encode(phoneNumber)); 3064bba23a751f042596561eab0e677135d5267bcdfStaffan Lindvall } 3074446eaa935994bc91d6d308303e8d27526b4590dLixin Yue 3082f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue try { 3090dcd2262d853c2011e11617a8efba6758370c41fLiejun Tao contactCursor = mResolver.query(uri, CONTACTS_PROJECTION, CLAUSE_ONLY_VISIBLE, 3100dcd2262d853c2011e11617a8efba6758370c41fLiejun Tao null, Contacts._ID); 3110dcd2262d853c2011e11617a8efba6758370c41fLiejun Tao 3120dcd2262d853c2011e11617a8efba6758370c41fLiejun Tao if (contactCursor != null) { 3130dcd2262d853c2011e11617a8efba6758370c41fLiejun Tao for (contactCursor.moveToFirst(); !contactCursor.isAfterLast(); contactCursor 3142f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue .moveToNext()) { 3150dcd2262d853c2011e11617a8efba6758370c41fLiejun Tao String name = contactCursor.getString(CONTACTS_NAME_COLUMN_INDEX); 3160dcd2262d853c2011e11617a8efba6758370c41fLiejun Tao long id = contactCursor.getLong(CONTACTS_ID_COLUMN_INDEX); 3170dcd2262d853c2011e11617a8efba6758370c41fLiejun Tao if (TextUtils.isEmpty(name)) { 3180dcd2262d853c2011e11617a8efba6758370c41fLiejun Tao name = mContext.getString(android.R.string.unknownName); 3192f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue } 3200dcd2262d853c2011e11617a8efba6758370c41fLiejun Tao if (V) Log.v(TAG, "got name " + name + " by number " + phoneNumber + " @" + id); 321130969d18eadbd94361fe95bf16b8131cdea6168Hemant Gupta nameList.add(name + "," + id); 3222f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue } 3232f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue } 324c592e5a6de0011cd60f23ac18a7bd56d8eeb5dd1Hemant Gupta } catch (CursorWindowAllocationException e) { 325c592e5a6de0011cd60f23ac18a7bd56d8eeb5dd1Hemant Gupta Log.e(TAG, "CursorWindowAllocationException while getting contact names"); 3262f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue } finally { 3270dcd2262d853c2011e11617a8efba6758370c41fLiejun Tao if (contactCursor != null) { 3280dcd2262d853c2011e11617a8efba6758370c41fLiejun Tao contactCursor.close(); 329c592e5a6de0011cd60f23ac18a7bd56d8eeb5dd1Hemant Gupta contactCursor = null; 3302f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue } 3312c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 3320dcd2262d853c2011e11617a8efba6758370c41fLiejun Tao return nameList; 3332c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 3342c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 3350b1b0069658326e8c12dc0f887e4319c5227feb5Lixin Yue public final int composeAndSendCallLogVcards(final int type, Operation op, 3362f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue final int startPoint, final int endPoint, final boolean vcardType21) { 33759256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh if (startPoint < 1 || startPoint > endPoint) { 33859256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh Log.e(TAG, "internal error: startPoint or endPoint is not correct."); 33959256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh return ResponseCodes.OBEX_HTTP_INTERNAL_ERROR; 34059256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh } 3412f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue String typeSelection = BluetoothPbapObexServer.createSelectionPara(type); 34259256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh 3432b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh final Uri myUri = CallLog.Calls.CONTENT_URI; 34459256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh final String[] CALLLOG_PROJECTION = new String[] { 34559256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh CallLog.Calls._ID, // 0 34659256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh }; 34759256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh final int ID_COLUMN_INDEX = 0; 34859256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh 34959256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh Cursor callsCursor = null; 35059256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh long startPointId = 0; 35159256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh long endPointId = 0; 35259256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh try { 35359256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh // Need test to see if order by _ID is ok here, or by date? 35459256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh callsCursor = mResolver.query(myUri, CALLLOG_PROJECTION, typeSelection, null, 3552b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh CALLLOG_SORT_ORDER); 35659256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh if (callsCursor != null) { 35759256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh callsCursor.moveToPosition(startPoint - 1); 35859256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh startPointId = callsCursor.getLong(ID_COLUMN_INDEX); 35959256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh if (V) Log.v(TAG, "Call Log query startPointId = " + startPointId); 36059256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh if (startPoint == endPoint) { 36159256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh endPointId = startPointId; 36259256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh } else { 36359256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh callsCursor.moveToPosition(endPoint - 1); 36459256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh endPointId = callsCursor.getLong(ID_COLUMN_INDEX); 36559256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh } 36659256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh if (V) Log.v(TAG, "Call log query endPointId = " + endPointId); 36759256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh } 368c592e5a6de0011cd60f23ac18a7bd56d8eeb5dd1Hemant Gupta } catch (CursorWindowAllocationException e) { 369c592e5a6de0011cd60f23ac18a7bd56d8eeb5dd1Hemant Gupta Log.e(TAG, "CursorWindowAllocationException while composing calllog vcards"); 37059256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh } finally { 37159256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh if (callsCursor != null) { 37259256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh callsCursor.close(); 373c592e5a6de0011cd60f23ac18a7bd56d8eeb5dd1Hemant Gupta callsCursor = null; 37459256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh } 37559256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh } 37659256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh 3772f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue String recordSelection; 3782f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue if (startPoint == endPoint) { 37959256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh recordSelection = Calls._ID + "=" + startPointId; 3802f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue } else { 3812b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh // The query to call table is by "_id DESC" order, so change 3822b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh // correspondingly. 3832b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh recordSelection = Calls._ID + ">=" + endPointId + " AND " + Calls._ID + "<=" 3842b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh + startPointId; 3854446eaa935994bc91d6d308303e8d27526b4590dLixin Yue } 3864446eaa935994bc91d6d308303e8d27526b4590dLixin Yue 3872f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue String selection; 3882f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue if (typeSelection == null) { 3892f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue selection = recordSelection; 3902f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue } else { 3912f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue selection = "(" + typeSelection + ") AND (" + recordSelection + ")"; 3924446eaa935994bc91d6d308303e8d27526b4590dLixin Yue } 3934446eaa935994bc91d6d308303e8d27526b4590dLixin Yue 39459256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh if (V) Log.v(TAG, "Call log query selection is: " + selection); 3954446eaa935994bc91d6d308303e8d27526b4590dLixin Yue 3962f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue return composeAndSendVCards(op, selection, vcardType21, null, false); 3974446eaa935994bc91d6d308303e8d27526b4590dLixin Yue } 3984446eaa935994bc91d6d308303e8d27526b4590dLixin Yue 3990b1b0069658326e8c12dc0f887e4319c5227feb5Lixin Yue public final int composeAndSendPhonebookVcards(Operation op, final int startPoint, 4002f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue final int endPoint, final boolean vcardType21, String ownerVCard) { 40159256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh if (startPoint < 1 || startPoint > endPoint) { 40259256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh Log.e(TAG, "internal error: startPoint or endPoint is not correct."); 40359256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh return ResponseCodes.OBEX_HTTP_INTERNAL_ERROR; 40459256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh } 4052b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh final Uri myUri = Contacts.CONTENT_URI; 40659256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh 40759256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh Cursor contactCursor = null; 40859256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh long startPointId = 0; 40959256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh long endPointId = 0; 41059256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh try { 411cd5ed0c7d04119e508fbddfd9656ef8559e3e524Lixin Yue contactCursor = mResolver.query(myUri, CONTACTS_PROJECTION, CLAUSE_ONLY_VISIBLE, null, 4122b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh Contacts._ID); 41359256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh if (contactCursor != null) { 41459256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh contactCursor.moveToPosition(startPoint - 1); 4152b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh startPointId = contactCursor.getLong(CONTACTS_ID_COLUMN_INDEX); 41659256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh if (V) Log.v(TAG, "Query startPointId = " + startPointId); 41759256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh if (startPoint == endPoint) { 41859256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh endPointId = startPointId; 41959256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh } else { 42059256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh contactCursor.moveToPosition(endPoint - 1); 4212b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh endPointId = contactCursor.getLong(CONTACTS_ID_COLUMN_INDEX); 42259256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh } 42359256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh if (V) Log.v(TAG, "Query endPointId = " + endPointId); 42459256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh } 425c592e5a6de0011cd60f23ac18a7bd56d8eeb5dd1Hemant Gupta } catch (CursorWindowAllocationException e) { 426c592e5a6de0011cd60f23ac18a7bd56d8eeb5dd1Hemant Gupta Log.e(TAG, "CursorWindowAllocationException while composing phonebook vcards"); 42759256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh } finally { 42859256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh if (contactCursor != null) { 42959256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh contactCursor.close(); 430c592e5a6de0011cd60f23ac18a7bd56d8eeb5dd1Hemant Gupta contactCursor = null; 43159256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh } 43259256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh } 43359256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh 4342b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh final String selection; 4352f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue if (startPoint == endPoint) { 436cd5ed0c7d04119e508fbddfd9656ef8559e3e524Lixin Yue selection = Contacts._ID + "=" + startPointId + " AND " + CLAUSE_ONLY_VISIBLE; 4372f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue } else { 4382b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh selection = Contacts._ID + ">=" + startPointId + " AND " + Contacts._ID + "<=" 439cd5ed0c7d04119e508fbddfd9656ef8559e3e524Lixin Yue + endPointId + " AND " + CLAUSE_ONLY_VISIBLE; 4404446eaa935994bc91d6d308303e8d27526b4590dLixin Yue } 4414446eaa935994bc91d6d308303e8d27526b4590dLixin Yue 4422f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue if (V) Log.v(TAG, "Query selection is: " + selection); 4434446eaa935994bc91d6d308303e8d27526b4590dLixin Yue 4442f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue return composeAndSendVCards(op, selection, vcardType21, ownerVCard, true); 4454446eaa935994bc91d6d308303e8d27526b4590dLixin Yue } 4464446eaa935994bc91d6d308303e8d27526b4590dLixin Yue 4470b1b0069658326e8c12dc0f887e4319c5227feb5Lixin Yue public final int composeAndSendPhonebookOneVcard(Operation op, final int offset, 4482b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh final boolean vcardType21, String ownerVCard, int orderByWhat) { 4492b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh if (offset < 1) { 4502b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh Log.e(TAG, "Internal error: offset is not correct."); 4512b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh return ResponseCodes.OBEX_HTTP_INTERNAL_ERROR; 4522b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh } 4532b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh final Uri myUri = Contacts.CONTENT_URI; 4542b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh Cursor contactCursor = null; 4552b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh String selection = null; 4562b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh long contactId = 0; 4572b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh if (orderByWhat == BluetoothPbapObexServer.ORDER_BY_INDEXED) { 4582b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh try { 459cd5ed0c7d04119e508fbddfd9656ef8559e3e524Lixin Yue contactCursor = mResolver.query(myUri, CONTACTS_PROJECTION, CLAUSE_ONLY_VISIBLE, 460cd5ed0c7d04119e508fbddfd9656ef8559e3e524Lixin Yue null, Contacts._ID); 4612b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh if (contactCursor != null) { 4622b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh contactCursor.moveToPosition(offset - 1); 4632b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh contactId = contactCursor.getLong(CONTACTS_ID_COLUMN_INDEX); 4642b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh if (V) Log.v(TAG, "Query startPointId = " + contactId); 4652b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh } 466c592e5a6de0011cd60f23ac18a7bd56d8eeb5dd1Hemant Gupta } catch (CursorWindowAllocationException e) { 467c592e5a6de0011cd60f23ac18a7bd56d8eeb5dd1Hemant Gupta Log.e(TAG, "CursorWindowAllocationException while composing phonebook one vcard order by index"); 4682b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh } finally { 4692b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh if (contactCursor != null) { 4702b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh contactCursor.close(); 471c592e5a6de0011cd60f23ac18a7bd56d8eeb5dd1Hemant Gupta contactCursor = null; 4722b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh } 4732b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh } 4742b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh } else if (orderByWhat == BluetoothPbapObexServer.ORDER_BY_ALPHABETICAL) { 4752b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh try { 476cd5ed0c7d04119e508fbddfd9656ef8559e3e524Lixin Yue contactCursor = mResolver.query(myUri, CONTACTS_PROJECTION, CLAUSE_ONLY_VISIBLE, 477cd5ed0c7d04119e508fbddfd9656ef8559e3e524Lixin Yue null, Contacts.DISPLAY_NAME); 4782b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh if (contactCursor != null) { 4792b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh contactCursor.moveToPosition(offset - 1); 4802b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh contactId = contactCursor.getLong(CONTACTS_ID_COLUMN_INDEX); 4812b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh if (V) Log.v(TAG, "Query startPointId = " + contactId); 4822b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh } 483c592e5a6de0011cd60f23ac18a7bd56d8eeb5dd1Hemant Gupta } catch (CursorWindowAllocationException e) { 484c592e5a6de0011cd60f23ac18a7bd56d8eeb5dd1Hemant Gupta Log.e(TAG, "CursorWindowAllocationException while composing phonebook one vcard order by alphabetical"); 4852b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh } finally { 4862b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh if (contactCursor != null) { 4872b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh contactCursor.close(); 488c592e5a6de0011cd60f23ac18a7bd56d8eeb5dd1Hemant Gupta contactCursor = null; 4892b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh } 4902b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh } 4912b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh } else { 4922b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh Log.e(TAG, "Parameter orderByWhat is not supported!"); 4932b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh return ResponseCodes.OBEX_HTTP_INTERNAL_ERROR; 4942b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh } 4952b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh selection = Contacts._ID + "=" + contactId; 4962b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh 4972b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh if (V) Log.v(TAG, "Query selection is: " + selection); 4982b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh 4992b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh return composeAndSendVCards(op, selection, vcardType21, ownerVCard, true); 5002b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh } 5012b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh 5020b1b0069658326e8c12dc0f887e4319c5227feb5Lixin Yue public final int composeAndSendVCards(Operation op, final String selection, 5032f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue final boolean vcardType21, String ownerVCard, boolean isContacts) { 5042f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue long timestamp = 0; 5052f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue if (V) timestamp = System.currentTimeMillis(); 5064446eaa935994bc91d6d308303e8d27526b4590dLixin Yue 507198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa if (isContacts) { 508198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa VCardComposer composer = null; 5093c4d2c77c2fffe675fbe89ba58856686b6873d2fDaisuke Miyakawa HandlerForStringBuffer buffer = null; 510198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa try { 511198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa // Currently only support Generic Vcard 2.1 and 3.0 512198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa int vcardType; 513198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa if (vcardType21) { 514e05d3a710c592db386b55a265a1e657b0467e49fDaisuke Miyakawa vcardType = VCardConfig.VCARD_TYPE_V21_GENERIC; 515198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa } else { 516e05d3a710c592db386b55a265a1e657b0467e49fDaisuke Miyakawa vcardType = VCardConfig.VCARD_TYPE_V30_GENERIC; 517198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa } 5184a53a55dc10d3a26c94e5844f7d4a2565a67142cfredc 5194a53a55dc10d3a26c94e5844f7d4a2565a67142cfredc if (!BluetoothPbapConfig.includePhotosInVcard()) { 5204a53a55dc10d3a26c94e5844f7d4a2565a67142cfredc vcardType |= VCardConfig.FLAG_REFRAIN_IMAGE_EXPORT; 5214a53a55dc10d3a26c94e5844f7d4a2565a67142cfredc } 5224446eaa935994bc91d6d308303e8d27526b4590dLixin Yue 523c7a57f31515107366589bd6875c3cc4af1fc806efredc //Enhancement: customize Vcard based on preferences/settings and input from caller 524c7a57f31515107366589bd6875c3cc4af1fc806efredc composer = BluetoothPbapUtils.createFilteredVCardComposer(mContext, vcardType,null); 525c7a57f31515107366589bd6875c3cc4af1fc806efredc //End enhancement 526c7a57f31515107366589bd6875c3cc4af1fc806efredc 527d956b40b2f59599447ae0fa0762e055c0c0ce1a3Daisuke Miyakawa // BT does want PAUSE/WAIT conversion while it doesn't want the other formatting 528d956b40b2f59599447ae0fa0762e055c0c0ce1a3Daisuke Miyakawa // done by vCard library by default. 529d956b40b2f59599447ae0fa0762e055c0c0ce1a3Daisuke Miyakawa composer.setPhoneNumberTranslationCallback( 530d956b40b2f59599447ae0fa0762e055c0c0ce1a3Daisuke Miyakawa new VCardPhoneNumberTranslationCallback() { 531d956b40b2f59599447ae0fa0762e055c0c0ce1a3Daisuke Miyakawa public String onValueReceived( 532d956b40b2f59599447ae0fa0762e055c0c0ce1a3Daisuke Miyakawa String rawValue, int type, String label, boolean isPrimary) { 533d956b40b2f59599447ae0fa0762e055c0c0ce1a3Daisuke Miyakawa // 'p' and 'w' are the standard characters for pause and wait 534d956b40b2f59599447ae0fa0762e055c0c0ce1a3Daisuke Miyakawa // (see RFC 3601) 535d956b40b2f59599447ae0fa0762e055c0c0ce1a3Daisuke Miyakawa // so use those when exporting phone numbers via vCard. 536d956b40b2f59599447ae0fa0762e055c0c0ce1a3Daisuke Miyakawa String numberWithControlSequence = rawValue 537d956b40b2f59599447ae0fa0762e055c0c0ce1a3Daisuke Miyakawa .replace(PhoneNumberUtils.PAUSE, 'p') 538d956b40b2f59599447ae0fa0762e055c0c0ce1a3Daisuke Miyakawa .replace(PhoneNumberUtils.WAIT, 'w'); 539d956b40b2f59599447ae0fa0762e055c0c0ce1a3Daisuke Miyakawa return numberWithControlSequence; 540d956b40b2f59599447ae0fa0762e055c0c0ce1a3Daisuke Miyakawa } 541d956b40b2f59599447ae0fa0762e055c0c0ce1a3Daisuke Miyakawa }); 5423c4d2c77c2fffe675fbe89ba58856686b6873d2fDaisuke Miyakawa buffer = new HandlerForStringBuffer(op, ownerVCard); 5433c4d2c77c2fffe675fbe89ba58856686b6873d2fDaisuke Miyakawa if (!composer.init(Contacts.CONTENT_URI, selection, null, Contacts._ID) || 5443c4d2c77c2fffe675fbe89ba58856686b6873d2fDaisuke Miyakawa !buffer.onInit(mContext)) { 5452f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue return ResponseCodes.OBEX_HTTP_INTERNAL_ERROR; 5464446eaa935994bc91d6d308303e8d27526b4590dLixin Yue } 547198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa 548198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa while (!composer.isAfterLast()) { 5490b1b0069658326e8c12dc0f887e4319c5227feb5Lixin Yue if (BluetoothPbapObexServer.sIsAborted) { 5500b1b0069658326e8c12dc0f887e4319c5227feb5Lixin Yue ((ServerOperation)op).isAborted = true; 5510b1b0069658326e8c12dc0f887e4319c5227feb5Lixin Yue BluetoothPbapObexServer.sIsAborted = false; 5520b1b0069658326e8c12dc0f887e4319c5227feb5Lixin Yue break; 5530b1b0069658326e8c12dc0f887e4319c5227feb5Lixin Yue } 5543c4d2c77c2fffe675fbe89ba58856686b6873d2fDaisuke Miyakawa String vcard = composer.createOneEntry(); 5553c4d2c77c2fffe675fbe89ba58856686b6873d2fDaisuke Miyakawa if (vcard == null) { 556198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa Log.e(TAG, "Failed to read a contact. Error reason: " 557198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa + composer.getErrorReason()); 558198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa return ResponseCodes.OBEX_HTTP_INTERNAL_ERROR; 559198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa } 560c7a57f31515107366589bd6875c3cc4af1fc806efredc if (V) { 561c7a57f31515107366589bd6875c3cc4af1fc806efredc Log.v(TAG, "Vcard Entry:"); 562c7a57f31515107366589bd6875c3cc4af1fc806efredc Log.v(TAG,vcard); 563c7a57f31515107366589bd6875c3cc4af1fc806efredc } 564c7a57f31515107366589bd6875c3cc4af1fc806efredc 5653c4d2c77c2fffe675fbe89ba58856686b6873d2fDaisuke Miyakawa if (!buffer.onEntryCreated(vcard)) { 5663c4d2c77c2fffe675fbe89ba58856686b6873d2fDaisuke Miyakawa // onEntryCreate() already emits error. 5673c4d2c77c2fffe675fbe89ba58856686b6873d2fDaisuke Miyakawa return ResponseCodes.OBEX_HTTP_INTERNAL_ERROR; 5683c4d2c77c2fffe675fbe89ba58856686b6873d2fDaisuke Miyakawa } 569198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa } 570198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa } finally { 571198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa if (composer != null) { 572198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa composer.terminate(); 573198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa } 5743c4d2c77c2fffe675fbe89ba58856686b6873d2fDaisuke Miyakawa if (buffer != null) { 5753c4d2c77c2fffe675fbe89ba58856686b6873d2fDaisuke Miyakawa buffer.onTerminate(); 5763c4d2c77c2fffe675fbe89ba58856686b6873d2fDaisuke Miyakawa } 5774446eaa935994bc91d6d308303e8d27526b4590dLixin Yue } 578198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa } else { // CallLog 579198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa BluetoothPbapCallLogComposer composer = null; 5803c4d2c77c2fffe675fbe89ba58856686b6873d2fDaisuke Miyakawa HandlerForStringBuffer buffer = null; 581198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa try { 5823c4d2c77c2fffe675fbe89ba58856686b6873d2fDaisuke Miyakawa 5833c4d2c77c2fffe675fbe89ba58856686b6873d2fDaisuke Miyakawa composer = new BluetoothPbapCallLogComposer(mContext); 5843c4d2c77c2fffe675fbe89ba58856686b6873d2fDaisuke Miyakawa buffer = new HandlerForStringBuffer(op, ownerVCard); 5854492b2c66cf3b26fd988f3b7f1f5df6cc9ed49f2Jaikumar Ganesh if (!composer.init(CallLog.Calls.CONTENT_URI, selection, null, 5863c4d2c77c2fffe675fbe89ba58856686b6873d2fDaisuke Miyakawa CALLLOG_SORT_ORDER) || 5873c4d2c77c2fffe675fbe89ba58856686b6873d2fDaisuke Miyakawa !buffer.onInit(mContext)) { 588198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa return ResponseCodes.OBEX_HTTP_INTERNAL_ERROR; 589198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa } 590198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa 591198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa while (!composer.isAfterLast()) { 5920b1b0069658326e8c12dc0f887e4319c5227feb5Lixin Yue if (BluetoothPbapObexServer.sIsAborted) { 5930b1b0069658326e8c12dc0f887e4319c5227feb5Lixin Yue ((ServerOperation)op).isAborted = true; 5940b1b0069658326e8c12dc0f887e4319c5227feb5Lixin Yue BluetoothPbapObexServer.sIsAborted = false; 5950b1b0069658326e8c12dc0f887e4319c5227feb5Lixin Yue break; 5960b1b0069658326e8c12dc0f887e4319c5227feb5Lixin Yue } 59773adcc0f5b6051ef514a3f16a2e28eabee2b367eConley Owens String vcard = composer.createOneEntry(vcardType21); 5983c4d2c77c2fffe675fbe89ba58856686b6873d2fDaisuke Miyakawa if (vcard == null) { 599198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa Log.e(TAG, "Failed to read a contact. Error reason: " 600198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa + composer.getErrorReason()); 601198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa return ResponseCodes.OBEX_HTTP_INTERNAL_ERROR; 602198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa } 603c7a57f31515107366589bd6875c3cc4af1fc806efredc if (V) { 604c7a57f31515107366589bd6875c3cc4af1fc806efredc Log.v(TAG, "Vcard Entry:"); 605c7a57f31515107366589bd6875c3cc4af1fc806efredc Log.v(TAG,vcard); 606c7a57f31515107366589bd6875c3cc4af1fc806efredc } 607c7a57f31515107366589bd6875c3cc4af1fc806efredc 6083c4d2c77c2fffe675fbe89ba58856686b6873d2fDaisuke Miyakawa buffer.onEntryCreated(vcard); 609198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa } 610198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa } finally { 611198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa if (composer != null) { 612198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa composer.terminate(); 613198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa } 6143c4d2c77c2fffe675fbe89ba58856686b6873d2fDaisuke Miyakawa if (buffer != null) { 6153c4d2c77c2fffe675fbe89ba58856686b6873d2fDaisuke Miyakawa buffer.onTerminate(); 6163c4d2c77c2fffe675fbe89ba58856686b6873d2fDaisuke Miyakawa } 6174446eaa935994bc91d6d308303e8d27526b4590dLixin Yue } 6184446eaa935994bc91d6d308303e8d27526b4590dLixin Yue } 6194446eaa935994bc91d6d308303e8d27526b4590dLixin Yue 6202f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue if (V) Log.v(TAG, "Total vcard composing and sending out takes " 6212f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue + (System.currentTimeMillis() - timestamp) + " ms"); 6222f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue 6232f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue return ResponseCodes.OBEX_HTTP_OK; 6244446eaa935994bc91d6d308303e8d27526b4590dLixin Yue } 6254446eaa935994bc91d6d308303e8d27526b4590dLixin Yue 6262f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue /** 627ce8d51a3a43d113a4a6bad30d595c2a81d0f623cYoshiharu Kurita * Handler to emit vCards to PCE. 6282f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue */ 6293c4d2c77c2fffe675fbe89ba58856686b6873d2fDaisuke Miyakawa public class HandlerForStringBuffer { 6302f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue private Operation operation; 6314446eaa935994bc91d6d308303e8d27526b4590dLixin Yue 6322f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue private OutputStream outputStream; 6332f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue 6342f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue private String phoneOwnVCard = null; 6352f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue 6362f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue public HandlerForStringBuffer(Operation op, String ownerVCard) { 6372f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue operation = op; 6382f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue if (ownerVCard != null) { 6392f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue phoneOwnVCard = ownerVCard; 6402f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue if (V) Log.v(TAG, "phone own number vcard:"); 6412f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue if (V) Log.v(TAG, phoneOwnVCard); 6422c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 6432c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 6442c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 645ce8d51a3a43d113a4a6bad30d595c2a81d0f623cYoshiharu Kurita private boolean write(String vCard) { 646ce8d51a3a43d113a4a6bad30d595c2a81d0f623cYoshiharu Kurita try { 647ce8d51a3a43d113a4a6bad30d595c2a81d0f623cYoshiharu Kurita if (vCard != null) { 648ce8d51a3a43d113a4a6bad30d595c2a81d0f623cYoshiharu Kurita outputStream.write(vCard.getBytes()); 649ce8d51a3a43d113a4a6bad30d595c2a81d0f623cYoshiharu Kurita return true; 650ce8d51a3a43d113a4a6bad30d595c2a81d0f623cYoshiharu Kurita } 651ce8d51a3a43d113a4a6bad30d595c2a81d0f623cYoshiharu Kurita } catch (IOException e) { 652ce8d51a3a43d113a4a6bad30d595c2a81d0f623cYoshiharu Kurita Log.e(TAG, "write outputstrem failed" + e.toString()); 653ce8d51a3a43d113a4a6bad30d595c2a81d0f623cYoshiharu Kurita } 654ce8d51a3a43d113a4a6bad30d595c2a81d0f623cYoshiharu Kurita return false; 655ce8d51a3a43d113a4a6bad30d595c2a81d0f623cYoshiharu Kurita } 656ce8d51a3a43d113a4a6bad30d595c2a81d0f623cYoshiharu Kurita 6572f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue public boolean onInit(Context context) { 6582f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue try { 6592f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue outputStream = operation.openOutputStream(); 6602f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue if (phoneOwnVCard != null) { 661ce8d51a3a43d113a4a6bad30d595c2a81d0f623cYoshiharu Kurita return write(phoneOwnVCard); 6622c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 663ce8d51a3a43d113a4a6bad30d595c2a81d0f623cYoshiharu Kurita return true; 6642f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue } catch (IOException e) { 6652f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue Log.e(TAG, "open outputstrem failed" + e.toString()); 6662c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 667ce8d51a3a43d113a4a6bad30d595c2a81d0f623cYoshiharu Kurita return false; 6682c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 6692c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 6702f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue public boolean onEntryCreated(String vcard) { 671ce8d51a3a43d113a4a6bad30d595c2a81d0f623cYoshiharu Kurita return write(vcard); 6722c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 6732c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan 6742f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue public void onTerminate() { 6752f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue if (!BluetoothPbapObexServer.closeStream(outputStream, operation)) { 6762f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue if (V) Log.v(TAG, "CloseStream failed!"); 6772c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } else { 6782f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue if (V) Log.v(TAG, "CloseStream ok!"); 6792c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 6802c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 6812c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan } 6822c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan} 683