BluetoothPbapVcardManager.java revision 6db8e703719f301f75acdf4acacc3296cc1b5016
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>();
2971321cd814a7406260ba6282d9c71e1a2d8925262Hemant Gupta        ArrayList<String> tempNameList = new ArrayList<String>();
2980dcd2262d853c2011e11617a8efba6758370c41fLiejun Tao
2990dcd2262d853c2011e11617a8efba6758370c41fLiejun Tao        Cursor contactCursor = null;
3004bba23a751f042596561eab0e677135d5267bcdfStaffan Lindvall        Uri uri = null;
3014bba23a751f042596561eab0e677135d5267bcdfStaffan Lindvall
3024bba23a751f042596561eab0e677135d5267bcdfStaffan Lindvall        if (phoneNumber != null && phoneNumber.length() == 0) {
3034bba23a751f042596561eab0e677135d5267bcdfStaffan Lindvall            uri = Contacts.CONTENT_URI;
3044bba23a751f042596561eab0e677135d5267bcdfStaffan Lindvall        } else {
3054bba23a751f042596561eab0e677135d5267bcdfStaffan Lindvall            uri = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI,
3060dcd2262d853c2011e11617a8efba6758370c41fLiejun Tao                Uri.encode(phoneNumber));
3074bba23a751f042596561eab0e677135d5267bcdfStaffan Lindvall        }
3084446eaa935994bc91d6d308303e8d27526b4590dLixin Yue
3092f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue        try {
3100dcd2262d853c2011e11617a8efba6758370c41fLiejun Tao            contactCursor = mResolver.query(uri, CONTACTS_PROJECTION, CLAUSE_ONLY_VISIBLE,
3110dcd2262d853c2011e11617a8efba6758370c41fLiejun Tao                        null, Contacts._ID);
3120dcd2262d853c2011e11617a8efba6758370c41fLiejun Tao
3130dcd2262d853c2011e11617a8efba6758370c41fLiejun Tao            if (contactCursor != null) {
3140dcd2262d853c2011e11617a8efba6758370c41fLiejun Tao                for (contactCursor.moveToFirst(); !contactCursor.isAfterLast(); contactCursor
3152f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue                        .moveToNext()) {
3160dcd2262d853c2011e11617a8efba6758370c41fLiejun Tao                    String name = contactCursor.getString(CONTACTS_NAME_COLUMN_INDEX);
3170dcd2262d853c2011e11617a8efba6758370c41fLiejun Tao                    long id = contactCursor.getLong(CONTACTS_ID_COLUMN_INDEX);
3180dcd2262d853c2011e11617a8efba6758370c41fLiejun Tao                    if (TextUtils.isEmpty(name)) {
3190dcd2262d853c2011e11617a8efba6758370c41fLiejun Tao                        name = mContext.getString(android.R.string.unknownName);
3202f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue                    }
3210dcd2262d853c2011e11617a8efba6758370c41fLiejun Tao                    if (V) Log.v(TAG, "got name " + name + " by number " + phoneNumber + " @" + id);
3221321cd814a7406260ba6282d9c71e1a2d8925262Hemant Gupta                    tempNameList.add(name + "," + id);
3232f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue                }
3242f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue            }
325c592e5a6de0011cd60f23ac18a7bd56d8eeb5dd1Hemant Gupta        } catch (CursorWindowAllocationException e) {
326c592e5a6de0011cd60f23ac18a7bd56d8eeb5dd1Hemant Gupta            Log.e(TAG, "CursorWindowAllocationException while getting contact names");
3272f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue        } finally {
3280dcd2262d853c2011e11617a8efba6758370c41fLiejun Tao            if (contactCursor != null) {
3290dcd2262d853c2011e11617a8efba6758370c41fLiejun Tao                contactCursor.close();
330c592e5a6de0011cd60f23ac18a7bd56d8eeb5dd1Hemant Gupta                contactCursor = null;
3312f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue            }
3322c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        }
3331321cd814a7406260ba6282d9c71e1a2d8925262Hemant Gupta        int tempListSize = tempNameList.size();
3341321cd814a7406260ba6282d9c71e1a2d8925262Hemant Gupta        for (int index = 0; index < tempListSize; index++) {
3351321cd814a7406260ba6282d9c71e1a2d8925262Hemant Gupta            String object = tempNameList.get(index);
3361321cd814a7406260ba6282d9c71e1a2d8925262Hemant Gupta            if (!nameList.contains(object))
3371321cd814a7406260ba6282d9c71e1a2d8925262Hemant Gupta                nameList.add(object);
3381321cd814a7406260ba6282d9c71e1a2d8925262Hemant Gupta        }
3391321cd814a7406260ba6282d9c71e1a2d8925262Hemant Gupta
3400dcd2262d853c2011e11617a8efba6758370c41fLiejun Tao        return nameList;
3412c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    }
3422c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan
3430b1b0069658326e8c12dc0f887e4319c5227feb5Lixin Yue    public final int composeAndSendCallLogVcards(final int type, Operation op,
3446db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta            final int startPoint, final int endPoint, final boolean vcardType21,
3456db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta            boolean ignorefilter, byte[] filter) {
34659256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh        if (startPoint < 1 || startPoint > endPoint) {
34759256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh            Log.e(TAG, "internal error: startPoint or endPoint is not correct.");
34859256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh            return ResponseCodes.OBEX_HTTP_INTERNAL_ERROR;
34959256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh        }
3502f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue        String typeSelection = BluetoothPbapObexServer.createSelectionPara(type);
35159256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh
3522b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh        final Uri myUri = CallLog.Calls.CONTENT_URI;
35359256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh        final String[] CALLLOG_PROJECTION = new String[] {
35459256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh            CallLog.Calls._ID, // 0
35559256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh        };
35659256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh        final int ID_COLUMN_INDEX = 0;
35759256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh
35859256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh        Cursor callsCursor = null;
35959256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh        long startPointId = 0;
36059256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh        long endPointId = 0;
36159256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh        try {
36259256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh            // Need test to see if order by _ID is ok here, or by date?
36359256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh            callsCursor = mResolver.query(myUri, CALLLOG_PROJECTION, typeSelection, null,
3642b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh                    CALLLOG_SORT_ORDER);
36559256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh            if (callsCursor != null) {
36659256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh                callsCursor.moveToPosition(startPoint - 1);
36759256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh                startPointId = callsCursor.getLong(ID_COLUMN_INDEX);
36859256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh                if (V) Log.v(TAG, "Call Log query startPointId = " + startPointId);
36959256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh                if (startPoint == endPoint) {
37059256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh                    endPointId = startPointId;
37159256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh                } else {
37259256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh                    callsCursor.moveToPosition(endPoint - 1);
37359256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh                    endPointId = callsCursor.getLong(ID_COLUMN_INDEX);
37459256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh                }
37559256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh                if (V) Log.v(TAG, "Call log query endPointId = " + endPointId);
37659256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh            }
377c592e5a6de0011cd60f23ac18a7bd56d8eeb5dd1Hemant Gupta        } catch (CursorWindowAllocationException e) {
378c592e5a6de0011cd60f23ac18a7bd56d8eeb5dd1Hemant Gupta            Log.e(TAG, "CursorWindowAllocationException while composing calllog vcards");
37959256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh        } finally {
38059256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh            if (callsCursor != null) {
38159256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh                callsCursor.close();
382c592e5a6de0011cd60f23ac18a7bd56d8eeb5dd1Hemant Gupta                callsCursor = null;
38359256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh            }
38459256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh        }
38559256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh
3862f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue        String recordSelection;
3872f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue        if (startPoint == endPoint) {
38859256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh            recordSelection = Calls._ID + "=" + startPointId;
3892f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue        } else {
3902b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh            // The query to call table is by "_id DESC" order, so change
3912b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh            // correspondingly.
3922b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh            recordSelection = Calls._ID + ">=" + endPointId + " AND " + Calls._ID + "<="
3932b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh                    + startPointId;
3944446eaa935994bc91d6d308303e8d27526b4590dLixin Yue        }
3954446eaa935994bc91d6d308303e8d27526b4590dLixin Yue
3962f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue        String selection;
3972f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue        if (typeSelection == null) {
3982f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue            selection = recordSelection;
3992f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue        } else {
4002f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue            selection = "(" + typeSelection + ") AND (" + recordSelection + ")";
4014446eaa935994bc91d6d308303e8d27526b4590dLixin Yue        }
4024446eaa935994bc91d6d308303e8d27526b4590dLixin Yue
40359256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh        if (V) Log.v(TAG, "Call log query selection is: " + selection);
4044446eaa935994bc91d6d308303e8d27526b4590dLixin Yue
4056db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta        return composeAndSendVCards(op, selection, vcardType21, null, false, ignorefilter, filter);
4064446eaa935994bc91d6d308303e8d27526b4590dLixin Yue    }
4074446eaa935994bc91d6d308303e8d27526b4590dLixin Yue
4080b1b0069658326e8c12dc0f887e4319c5227feb5Lixin Yue    public final int composeAndSendPhonebookVcards(Operation op, final int startPoint,
4096db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta            final int endPoint, final boolean vcardType21, String ownerVCard,
4106db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta            boolean ignorefilter, byte[] filter) {
41159256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh        if (startPoint < 1 || startPoint > endPoint) {
41259256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh            Log.e(TAG, "internal error: startPoint or endPoint is not correct.");
41359256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh            return ResponseCodes.OBEX_HTTP_INTERNAL_ERROR;
41459256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh        }
4152b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh        final Uri myUri = Contacts.CONTENT_URI;
41659256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh
41759256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh        Cursor contactCursor = null;
41859256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh        long startPointId = 0;
41959256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh        long endPointId = 0;
42059256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh        try {
421cd5ed0c7d04119e508fbddfd9656ef8559e3e524Lixin Yue            contactCursor = mResolver.query(myUri, CONTACTS_PROJECTION, CLAUSE_ONLY_VISIBLE, null,
4222b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh                    Contacts._ID);
42359256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh            if (contactCursor != null) {
42459256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh                contactCursor.moveToPosition(startPoint - 1);
4252b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh                startPointId = contactCursor.getLong(CONTACTS_ID_COLUMN_INDEX);
42659256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh                if (V) Log.v(TAG, "Query startPointId = " + startPointId);
42759256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh                if (startPoint == endPoint) {
42859256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh                    endPointId = startPointId;
42959256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh                } else {
43059256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh                    contactCursor.moveToPosition(endPoint - 1);
4312b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh                    endPointId = contactCursor.getLong(CONTACTS_ID_COLUMN_INDEX);
43259256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh                }
43359256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh                if (V) Log.v(TAG, "Query endPointId = " + endPointId);
43459256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh            }
435c592e5a6de0011cd60f23ac18a7bd56d8eeb5dd1Hemant Gupta        } catch (CursorWindowAllocationException e) {
436c592e5a6de0011cd60f23ac18a7bd56d8eeb5dd1Hemant Gupta            Log.e(TAG, "CursorWindowAllocationException while composing phonebook vcards");
43759256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh        } finally {
43859256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh            if (contactCursor != null) {
43959256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh                contactCursor.close();
440c592e5a6de0011cd60f23ac18a7bd56d8eeb5dd1Hemant Gupta                contactCursor = null;
44159256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh            }
44259256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh        }
44359256dee3f9787fd660c346d61e0271ecd4bfe9aJaikumar Ganesh
4442b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh        final String selection;
4452f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue        if (startPoint == endPoint) {
446cd5ed0c7d04119e508fbddfd9656ef8559e3e524Lixin Yue            selection = Contacts._ID + "=" + startPointId + " AND " + CLAUSE_ONLY_VISIBLE;
4472f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue        } else {
4482b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh            selection = Contacts._ID + ">=" + startPointId + " AND " + Contacts._ID + "<="
449cd5ed0c7d04119e508fbddfd9656ef8559e3e524Lixin Yue                    + endPointId + " AND " + CLAUSE_ONLY_VISIBLE;
4504446eaa935994bc91d6d308303e8d27526b4590dLixin Yue        }
4514446eaa935994bc91d6d308303e8d27526b4590dLixin Yue
4522f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue        if (V) Log.v(TAG, "Query selection is: " + selection);
4534446eaa935994bc91d6d308303e8d27526b4590dLixin Yue
4546db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta        return composeAndSendVCards(op, selection, vcardType21, ownerVCard, true,
4556db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta            ignorefilter, filter);
4564446eaa935994bc91d6d308303e8d27526b4590dLixin Yue    }
4574446eaa935994bc91d6d308303e8d27526b4590dLixin Yue
4580b1b0069658326e8c12dc0f887e4319c5227feb5Lixin Yue    public final int composeAndSendPhonebookOneVcard(Operation op, final int offset,
4596db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta            final boolean vcardType21, String ownerVCard, int orderByWhat,
4606db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta            boolean ignorefilter, byte[] filter) {
4612b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh        if (offset < 1) {
4622b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh            Log.e(TAG, "Internal error: offset is not correct.");
4632b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh            return ResponseCodes.OBEX_HTTP_INTERNAL_ERROR;
4642b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh        }
4652b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh        final Uri myUri = Contacts.CONTENT_URI;
4662b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh        Cursor contactCursor = null;
4672b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh        String selection = null;
4682b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh        long contactId = 0;
4692b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh        if (orderByWhat == BluetoothPbapObexServer.ORDER_BY_INDEXED) {
4702b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh            try {
471cd5ed0c7d04119e508fbddfd9656ef8559e3e524Lixin Yue                contactCursor = mResolver.query(myUri, CONTACTS_PROJECTION, CLAUSE_ONLY_VISIBLE,
472cd5ed0c7d04119e508fbddfd9656ef8559e3e524Lixin Yue                        null, Contacts._ID);
4732b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh                if (contactCursor != null) {
4742b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh                    contactCursor.moveToPosition(offset - 1);
4752b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh                    contactId = contactCursor.getLong(CONTACTS_ID_COLUMN_INDEX);
4762b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh                    if (V) Log.v(TAG, "Query startPointId = " + contactId);
4772b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh                }
478c592e5a6de0011cd60f23ac18a7bd56d8eeb5dd1Hemant Gupta            } catch (CursorWindowAllocationException e) {
479c592e5a6de0011cd60f23ac18a7bd56d8eeb5dd1Hemant Gupta                Log.e(TAG, "CursorWindowAllocationException while composing phonebook one vcard order by index");
4802b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh            } finally {
4812b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh                if (contactCursor != null) {
4822b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh                    contactCursor.close();
483c592e5a6de0011cd60f23ac18a7bd56d8eeb5dd1Hemant Gupta                    contactCursor = null;
4842b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh                }
4852b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh            }
4862b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh        } else if (orderByWhat == BluetoothPbapObexServer.ORDER_BY_ALPHABETICAL) {
4872b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh            try {
488cd5ed0c7d04119e508fbddfd9656ef8559e3e524Lixin Yue                contactCursor = mResolver.query(myUri, CONTACTS_PROJECTION, CLAUSE_ONLY_VISIBLE,
489cd5ed0c7d04119e508fbddfd9656ef8559e3e524Lixin Yue                        null, Contacts.DISPLAY_NAME);
4902b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh                if (contactCursor != null) {
4912b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh                    contactCursor.moveToPosition(offset - 1);
4922b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh                    contactId = contactCursor.getLong(CONTACTS_ID_COLUMN_INDEX);
4932b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh                    if (V) Log.v(TAG, "Query startPointId = " + contactId);
4942b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh                }
495c592e5a6de0011cd60f23ac18a7bd56d8eeb5dd1Hemant Gupta            } catch (CursorWindowAllocationException e) {
496c592e5a6de0011cd60f23ac18a7bd56d8eeb5dd1Hemant Gupta                Log.e(TAG, "CursorWindowAllocationException while composing phonebook one vcard order by alphabetical");
4972b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh            } finally {
4982b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh                if (contactCursor != null) {
4992b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh                    contactCursor.close();
500c592e5a6de0011cd60f23ac18a7bd56d8eeb5dd1Hemant Gupta                    contactCursor = null;
5012b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh                }
5022b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh            }
5032b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh        } else {
5042b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh            Log.e(TAG, "Parameter orderByWhat is not supported!");
5052b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh            return ResponseCodes.OBEX_HTTP_INTERNAL_ERROR;
5062b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh        }
5072b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh        selection = Contacts._ID + "=" + contactId;
5082b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh
5092b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh        if (V) Log.v(TAG, "Query selection is: " + selection);
5102b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh
5116db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta        return composeAndSendVCards(op, selection, vcardType21, ownerVCard, true,
5126db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta            ignorefilter, filter);
5132b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh    }
5142b36e1731eb5ed784abc1a374eb69d8523123df1Jaikumar Ganesh
5150b1b0069658326e8c12dc0f887e4319c5227feb5Lixin Yue    public final int composeAndSendVCards(Operation op, final String selection,
5166db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta            final boolean vcardType21, String ownerVCard, boolean isContacts,
5176db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta            boolean ignorefilter, byte[] filter) {
5182f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue        long timestamp = 0;
5192f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue        if (V) timestamp = System.currentTimeMillis();
5204446eaa935994bc91d6d308303e8d27526b4590dLixin Yue
521198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa        if (isContacts) {
522198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa            VCardComposer composer = null;
5236db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta            FilterVcard vcardfilter= new FilterVcard();
5246db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta            if (!ignorefilter) {
5256db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                vcardfilter.setFilter(filter);
5266db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta            }
5273c4d2c77c2fffe675fbe89ba58856686b6873d2fDaisuke Miyakawa            HandlerForStringBuffer buffer = null;
528198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa            try {
529198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa                // Currently only support Generic Vcard 2.1 and 3.0
530198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa                int vcardType;
531198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa                if (vcardType21) {
532e05d3a710c592db386b55a265a1e657b0467e49fDaisuke Miyakawa                    vcardType = VCardConfig.VCARD_TYPE_V21_GENERIC;
533198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa                } else {
534e05d3a710c592db386b55a265a1e657b0467e49fDaisuke Miyakawa                    vcardType = VCardConfig.VCARD_TYPE_V30_GENERIC;
535198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa                }
5366db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                if (!vcardfilter.isPhotoEnabled()) {
5374a53a55dc10d3a26c94e5844f7d4a2565a67142cfredc                    vcardType |= VCardConfig.FLAG_REFRAIN_IMAGE_EXPORT;
5384a53a55dc10d3a26c94e5844f7d4a2565a67142cfredc                }
5394446eaa935994bc91d6d308303e8d27526b4590dLixin Yue
540c7a57f31515107366589bd6875c3cc4af1fc806efredc                //Enhancement: customize Vcard based on preferences/settings and input from caller
541c7a57f31515107366589bd6875c3cc4af1fc806efredc                composer = BluetoothPbapUtils.createFilteredVCardComposer(mContext, vcardType,null);
542c7a57f31515107366589bd6875c3cc4af1fc806efredc                //End enhancement
543c7a57f31515107366589bd6875c3cc4af1fc806efredc
544d956b40b2f59599447ae0fa0762e055c0c0ce1a3Daisuke Miyakawa                // BT does want PAUSE/WAIT conversion while it doesn't want the other formatting
545d956b40b2f59599447ae0fa0762e055c0c0ce1a3Daisuke Miyakawa                // done by vCard library by default.
546d956b40b2f59599447ae0fa0762e055c0c0ce1a3Daisuke Miyakawa                composer.setPhoneNumberTranslationCallback(
547d956b40b2f59599447ae0fa0762e055c0c0ce1a3Daisuke Miyakawa                        new VCardPhoneNumberTranslationCallback() {
548d956b40b2f59599447ae0fa0762e055c0c0ce1a3Daisuke Miyakawa                            public String onValueReceived(
549d956b40b2f59599447ae0fa0762e055c0c0ce1a3Daisuke Miyakawa                                    String rawValue, int type, String label, boolean isPrimary) {
550d956b40b2f59599447ae0fa0762e055c0c0ce1a3Daisuke Miyakawa                                // 'p' and 'w' are the standard characters for pause and wait
551d956b40b2f59599447ae0fa0762e055c0c0ce1a3Daisuke Miyakawa                                // (see RFC 3601)
552d956b40b2f59599447ae0fa0762e055c0c0ce1a3Daisuke Miyakawa                                // so use those when exporting phone numbers via vCard.
553d956b40b2f59599447ae0fa0762e055c0c0ce1a3Daisuke Miyakawa                                String numberWithControlSequence = rawValue
554d956b40b2f59599447ae0fa0762e055c0c0ce1a3Daisuke Miyakawa                                        .replace(PhoneNumberUtils.PAUSE, 'p')
555d956b40b2f59599447ae0fa0762e055c0c0ce1a3Daisuke Miyakawa                                        .replace(PhoneNumberUtils.WAIT, 'w');
556d956b40b2f59599447ae0fa0762e055c0c0ce1a3Daisuke Miyakawa                                return numberWithControlSequence;
557d956b40b2f59599447ae0fa0762e055c0c0ce1a3Daisuke Miyakawa                            }
558d956b40b2f59599447ae0fa0762e055c0c0ce1a3Daisuke Miyakawa                        });
5593c4d2c77c2fffe675fbe89ba58856686b6873d2fDaisuke Miyakawa                buffer = new HandlerForStringBuffer(op, ownerVCard);
5603c4d2c77c2fffe675fbe89ba58856686b6873d2fDaisuke Miyakawa                if (!composer.init(Contacts.CONTENT_URI, selection, null, Contacts._ID) ||
5613c4d2c77c2fffe675fbe89ba58856686b6873d2fDaisuke Miyakawa                        !buffer.onInit(mContext)) {
5622f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue                    return ResponseCodes.OBEX_HTTP_INTERNAL_ERROR;
5634446eaa935994bc91d6d308303e8d27526b4590dLixin Yue                }
564198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa
565198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa                while (!composer.isAfterLast()) {
5660b1b0069658326e8c12dc0f887e4319c5227feb5Lixin Yue                    if (BluetoothPbapObexServer.sIsAborted) {
5670b1b0069658326e8c12dc0f887e4319c5227feb5Lixin Yue                        ((ServerOperation)op).isAborted = true;
5680b1b0069658326e8c12dc0f887e4319c5227feb5Lixin Yue                        BluetoothPbapObexServer.sIsAborted = false;
5690b1b0069658326e8c12dc0f887e4319c5227feb5Lixin Yue                        break;
5700b1b0069658326e8c12dc0f887e4319c5227feb5Lixin Yue                    }
5713c4d2c77c2fffe675fbe89ba58856686b6873d2fDaisuke Miyakawa                    String vcard = composer.createOneEntry();
5723c4d2c77c2fffe675fbe89ba58856686b6873d2fDaisuke Miyakawa                    if (vcard == null) {
573198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa                        Log.e(TAG, "Failed to read a contact. Error reason: "
574198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa                                + composer.getErrorReason());
575198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa                        return ResponseCodes.OBEX_HTTP_INTERNAL_ERROR;
576198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa                    }
5776db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                    Log.v (TAG , "vCard from composer: " + vcard);
5786db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                    if (!ignorefilter) {
5796db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                        vcard = vcardfilter.applyFilter(vcard, vcardType21);
5806db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                        Log.v (TAG , "vCard on applying filter: " + vcard);
5816db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                    }
58229ab94a024ffce08229f1c2c6776d1e72d2a3f75Hemant Gupta                    vcard = StripTelephoneNumber(vcard);
583c7a57f31515107366589bd6875c3cc4af1fc806efredc                    if (V) {
584c7a57f31515107366589bd6875c3cc4af1fc806efredc                        Log.v(TAG, "Vcard Entry:");
585c7a57f31515107366589bd6875c3cc4af1fc806efredc                        Log.v(TAG,vcard);
586c7a57f31515107366589bd6875c3cc4af1fc806efredc                    }
587c7a57f31515107366589bd6875c3cc4af1fc806efredc
5883c4d2c77c2fffe675fbe89ba58856686b6873d2fDaisuke Miyakawa                    if (!buffer.onEntryCreated(vcard)) {
5893c4d2c77c2fffe675fbe89ba58856686b6873d2fDaisuke Miyakawa                        // onEntryCreate() already emits error.
5903c4d2c77c2fffe675fbe89ba58856686b6873d2fDaisuke Miyakawa                        return ResponseCodes.OBEX_HTTP_INTERNAL_ERROR;
5913c4d2c77c2fffe675fbe89ba58856686b6873d2fDaisuke Miyakawa                    }
592198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa                }
593198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa            } finally {
594198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa                if (composer != null) {
595198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa                    composer.terminate();
596198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa                }
5973c4d2c77c2fffe675fbe89ba58856686b6873d2fDaisuke Miyakawa                if (buffer != null) {
5983c4d2c77c2fffe675fbe89ba58856686b6873d2fDaisuke Miyakawa                    buffer.onTerminate();
5993c4d2c77c2fffe675fbe89ba58856686b6873d2fDaisuke Miyakawa                }
6004446eaa935994bc91d6d308303e8d27526b4590dLixin Yue            }
601198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa        } else { // CallLog
602198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa            BluetoothPbapCallLogComposer composer = null;
6033c4d2c77c2fffe675fbe89ba58856686b6873d2fDaisuke Miyakawa            HandlerForStringBuffer buffer = null;
604198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa            try {
6053c4d2c77c2fffe675fbe89ba58856686b6873d2fDaisuke Miyakawa
6063c4d2c77c2fffe675fbe89ba58856686b6873d2fDaisuke Miyakawa                composer = new BluetoothPbapCallLogComposer(mContext);
6073c4d2c77c2fffe675fbe89ba58856686b6873d2fDaisuke Miyakawa                buffer = new HandlerForStringBuffer(op, ownerVCard);
6084492b2c66cf3b26fd988f3b7f1f5df6cc9ed49f2Jaikumar Ganesh                if (!composer.init(CallLog.Calls.CONTENT_URI, selection, null,
6093c4d2c77c2fffe675fbe89ba58856686b6873d2fDaisuke Miyakawa                                   CALLLOG_SORT_ORDER) ||
6103c4d2c77c2fffe675fbe89ba58856686b6873d2fDaisuke Miyakawa                                   !buffer.onInit(mContext)) {
611198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa                    return ResponseCodes.OBEX_HTTP_INTERNAL_ERROR;
612198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa                }
613198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa
614198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa                while (!composer.isAfterLast()) {
6150b1b0069658326e8c12dc0f887e4319c5227feb5Lixin Yue                    if (BluetoothPbapObexServer.sIsAborted) {
6160b1b0069658326e8c12dc0f887e4319c5227feb5Lixin Yue                        ((ServerOperation)op).isAborted = true;
6170b1b0069658326e8c12dc0f887e4319c5227feb5Lixin Yue                        BluetoothPbapObexServer.sIsAborted = false;
6180b1b0069658326e8c12dc0f887e4319c5227feb5Lixin Yue                        break;
6190b1b0069658326e8c12dc0f887e4319c5227feb5Lixin Yue                    }
62073adcc0f5b6051ef514a3f16a2e28eabee2b367eConley Owens                    String vcard = composer.createOneEntry(vcardType21);
6213c4d2c77c2fffe675fbe89ba58856686b6873d2fDaisuke Miyakawa                    if (vcard == null) {
622198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa                        Log.e(TAG, "Failed to read a contact. Error reason: "
623198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa                                + composer.getErrorReason());
624198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa                        return ResponseCodes.OBEX_HTTP_INTERNAL_ERROR;
625198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa                    }
626c7a57f31515107366589bd6875c3cc4af1fc806efredc                    if (V) {
627c7a57f31515107366589bd6875c3cc4af1fc806efredc                        Log.v(TAG, "Vcard Entry:");
628c7a57f31515107366589bd6875c3cc4af1fc806efredc                        Log.v(TAG,vcard);
629c7a57f31515107366589bd6875c3cc4af1fc806efredc                    }
630c7a57f31515107366589bd6875c3cc4af1fc806efredc
6313c4d2c77c2fffe675fbe89ba58856686b6873d2fDaisuke Miyakawa                    buffer.onEntryCreated(vcard);
632198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa                }
633198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa            } finally {
634198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa                if (composer != null) {
635198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa                    composer.terminate();
636198e5d109571b27b7c45c30ed3ea42febcb99201Daisuke Miyakawa                }
6373c4d2c77c2fffe675fbe89ba58856686b6873d2fDaisuke Miyakawa                if (buffer != null) {
6383c4d2c77c2fffe675fbe89ba58856686b6873d2fDaisuke Miyakawa                    buffer.onTerminate();
6393c4d2c77c2fffe675fbe89ba58856686b6873d2fDaisuke Miyakawa                }
6404446eaa935994bc91d6d308303e8d27526b4590dLixin Yue            }
6414446eaa935994bc91d6d308303e8d27526b4590dLixin Yue        }
6424446eaa935994bc91d6d308303e8d27526b4590dLixin Yue
6432f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue        if (V) Log.v(TAG, "Total vcard composing and sending out takes "
6442f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue                    + (System.currentTimeMillis() - timestamp) + " ms");
6452f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue
6462f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue        return ResponseCodes.OBEX_HTTP_OK;
6474446eaa935994bc91d6d308303e8d27526b4590dLixin Yue    }
6484446eaa935994bc91d6d308303e8d27526b4590dLixin Yue
64929ab94a024ffce08229f1c2c6776d1e72d2a3f75Hemant Gupta    public String StripTelephoneNumber (String vCard){
65029ab94a024ffce08229f1c2c6776d1e72d2a3f75Hemant Gupta        String attr [] = vCard.split(System.getProperty("line.separator"));
65129ab94a024ffce08229f1c2c6776d1e72d2a3f75Hemant Gupta        String Vcard = "";
65229ab94a024ffce08229f1c2c6776d1e72d2a3f75Hemant Gupta            for (int i=0; i < attr.length; i++) {
65329ab94a024ffce08229f1c2c6776d1e72d2a3f75Hemant Gupta                if(attr[i].startsWith("TEL")) {
65429ab94a024ffce08229f1c2c6776d1e72d2a3f75Hemant Gupta                    attr[i] = attr[i].replace("(", "");
65529ab94a024ffce08229f1c2c6776d1e72d2a3f75Hemant Gupta                    attr[i] = attr[i].replace(")", "");
65629ab94a024ffce08229f1c2c6776d1e72d2a3f75Hemant Gupta                    attr[i] = attr[i].replace("-", "");
65729ab94a024ffce08229f1c2c6776d1e72d2a3f75Hemant Gupta                    attr[i] = attr[i].replace(" ", "");
65829ab94a024ffce08229f1c2c6776d1e72d2a3f75Hemant Gupta                }
65929ab94a024ffce08229f1c2c6776d1e72d2a3f75Hemant Gupta            }
66029ab94a024ffce08229f1c2c6776d1e72d2a3f75Hemant Gupta
66129ab94a024ffce08229f1c2c6776d1e72d2a3f75Hemant Gupta            for (int i=0; i < attr.length; i++) {
66229ab94a024ffce08229f1c2c6776d1e72d2a3f75Hemant Gupta                if(!attr[i].equals("")){
66329ab94a024ffce08229f1c2c6776d1e72d2a3f75Hemant Gupta                    Vcard = Vcard.concat(attr[i] + "\n");
66429ab94a024ffce08229f1c2c6776d1e72d2a3f75Hemant Gupta                }
66529ab94a024ffce08229f1c2c6776d1e72d2a3f75Hemant Gupta            }
66629ab94a024ffce08229f1c2c6776d1e72d2a3f75Hemant Gupta        Log.v(TAG, "Vcard with stripped telephone no.: " + Vcard);
66729ab94a024ffce08229f1c2c6776d1e72d2a3f75Hemant Gupta        return Vcard;
66829ab94a024ffce08229f1c2c6776d1e72d2a3f75Hemant Gupta    }
66929ab94a024ffce08229f1c2c6776d1e72d2a3f75Hemant Gupta
6702f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue    /**
671ce8d51a3a43d113a4a6bad30d595c2a81d0f623cYoshiharu Kurita     * Handler to emit vCards to PCE.
6722f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue     */
6733c4d2c77c2fffe675fbe89ba58856686b6873d2fDaisuke Miyakawa    public class HandlerForStringBuffer {
6742f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue        private Operation operation;
6754446eaa935994bc91d6d308303e8d27526b4590dLixin Yue
6762f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue        private OutputStream outputStream;
6772f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue
6782f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue        private String phoneOwnVCard = null;
6792f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue
6802f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue        public HandlerForStringBuffer(Operation op, String ownerVCard) {
6812f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue            operation = op;
6822f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue            if (ownerVCard != null) {
6832f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue                phoneOwnVCard = ownerVCard;
6842f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue                if (V) Log.v(TAG, "phone own number vcard:");
6852f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue                if (V) Log.v(TAG, phoneOwnVCard);
6862c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan            }
6872c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        }
6882c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan
689ce8d51a3a43d113a4a6bad30d595c2a81d0f623cYoshiharu Kurita        private boolean write(String vCard) {
690ce8d51a3a43d113a4a6bad30d595c2a81d0f623cYoshiharu Kurita            try {
691ce8d51a3a43d113a4a6bad30d595c2a81d0f623cYoshiharu Kurita                if (vCard != null) {
692ce8d51a3a43d113a4a6bad30d595c2a81d0f623cYoshiharu Kurita                    outputStream.write(vCard.getBytes());
693ce8d51a3a43d113a4a6bad30d595c2a81d0f623cYoshiharu Kurita                    return true;
694ce8d51a3a43d113a4a6bad30d595c2a81d0f623cYoshiharu Kurita                }
695ce8d51a3a43d113a4a6bad30d595c2a81d0f623cYoshiharu Kurita            } catch (IOException e) {
696ce8d51a3a43d113a4a6bad30d595c2a81d0f623cYoshiharu Kurita                Log.e(TAG, "write outputstrem failed" + e.toString());
697ce8d51a3a43d113a4a6bad30d595c2a81d0f623cYoshiharu Kurita            }
698ce8d51a3a43d113a4a6bad30d595c2a81d0f623cYoshiharu Kurita            return false;
699ce8d51a3a43d113a4a6bad30d595c2a81d0f623cYoshiharu Kurita        }
700ce8d51a3a43d113a4a6bad30d595c2a81d0f623cYoshiharu Kurita
7012f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue        public boolean onInit(Context context) {
7022f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue            try {
7032f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue                outputStream = operation.openOutputStream();
7042f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue                if (phoneOwnVCard != null) {
705ce8d51a3a43d113a4a6bad30d595c2a81d0f623cYoshiharu Kurita                    return write(phoneOwnVCard);
7062c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan                }
707ce8d51a3a43d113a4a6bad30d595c2a81d0f623cYoshiharu Kurita                return true;
7082f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue            } catch (IOException e) {
7092f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue                Log.e(TAG, "open outputstrem failed" + e.toString());
7102c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan            }
711ce8d51a3a43d113a4a6bad30d595c2a81d0f623cYoshiharu Kurita            return false;
7122c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        }
7132c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan
7142f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue        public boolean onEntryCreated(String vcard) {
715ce8d51a3a43d113a4a6bad30d595c2a81d0f623cYoshiharu Kurita            return write(vcard);
7162c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        }
7172c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan
7182f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue        public void onTerminate() {
7192f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue            if (!BluetoothPbapObexServer.closeStream(outputStream, operation)) {
7202f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue                if (V) Log.v(TAG, "CloseStream failed!");
7212c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan            } else {
7222f8fe66f45bac2bc61395bd4f8de553f4c2b7c30Lixin Yue                if (V) Log.v(TAG, "CloseStream ok!");
7232c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan            }
7242c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan        }
7252c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan    }
7266db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta
7276db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta    public class FilterVcard{
7286db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta
7296db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta        public FilterVcard(){
7306db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta        };
7316db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta
7326db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta        private final int FN_BIT = 1;
7336db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta
7346db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta        private boolean fn = true;
7356db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta
7366db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta        private final int PHOTO_BIT = 3;
7376db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta
7386db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta        private boolean photo = true;
7396db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta
7406db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta        //BDAY falls under events
7416db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta        private final int BDAY_BIT = 4;
7426db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta
7436db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta        private boolean bday = true;
7446db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta
7456db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta        private final int ADR_BIT = 5;
7466db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta
7476db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta        private boolean adr = true;
7486db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta
7496db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta        private final int EMAIL_BIT = 8;
7506db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta
7516db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta        private boolean email = true;
7526db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta
7536db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta        private final int TITLE_BIT = 12;
7546db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta
7556db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta        private boolean title = true;
7566db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta
7576db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta        private final int ORG_BIT = 16;
7586db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta
7596db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta        private boolean org = true;
7606db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta
7616db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta        private final int NOTES_BIT = 17;
7626db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta
7636db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta        private boolean notes = true;
7646db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta
7656db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta        private final int URL_BIT = 20;
7666db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta
7676db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta        private boolean url = true;
7686db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta
7696db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta        private final int NICKNAME_BIT = 23;
7706db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta
7716db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta        private boolean nickname = true;
7726db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta
7736db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta        public void setFilter(byte[] filter){
7746db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta
7756db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta           fn = checkbit(FN_BIT, filter);
7766db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta           photo = checkbit(PHOTO_BIT, filter);
7776db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta           bday = checkbit(BDAY_BIT, filter);
7786db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta           adr = checkbit(ADR_BIT, filter);
7796db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta           email = checkbit(EMAIL_BIT, filter);
7806db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta           title = checkbit(TITLE_BIT, filter);
7816db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta           org = checkbit(ORG_BIT, filter);
7826db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta           notes = checkbit(NOTES_BIT, filter);
7836db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta           url = checkbit(URL_BIT, filter);
7846db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta           nickname = checkbit(NICKNAME_BIT, filter);
7856db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta        }
7866db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta
7876db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta        private boolean checkbit (int attr_bit, byte[] filter){
7886db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta            int filterlen = filter.length;
7896db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta            if( ((filter[filterlen -1 -((int)attr_bit/8)] >> (attr_bit%8)) & 0x01) == 0) {
7906db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                return false;
7916db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta            }
7926db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta            return true;
7936db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta        }
7946db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta
7956db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta        public boolean isPhotoEnabled(){
7966db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta            return photo;
7976db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta        }
7986db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta
7996db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta        private boolean checkValidFilter (String attr) {
8006db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta            if((attr.startsWith("N:")) || (attr.startsWith("TEL"))
8016db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                || (attr.startsWith("VERSION")) || (attr.startsWith("URL"))
8026db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                || (attr.startsWith("FN")) || (attr.startsWith("BDAY"))
8036db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                || (attr.startsWith("ADR")) || (attr.startsWith("EMAIL"))
8046db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                || (attr.startsWith("TITLE")) || (attr.startsWith("ORG"))
8056db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                || (attr.startsWith("NOTE")) || (attr.startsWith("NICKNAME"))) {
8066db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                return true;
8076db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta            }
8086db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta            return false;
8096db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta        }
8106db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta
8116db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta        public String applyFilter ( String vCard, boolean vCardType21){
8126db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta            String attr [] = vCard.split(System.getProperty("line.separator"));
8136db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta            String filteredVcard = "";
8146db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta
8156db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta            //FN is not the mandatory field in 2.1 vCard
8166db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta            if(((!fn) && (vCardType21)) && (vCard.contains("FN"))) {
8176db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                for (int i=0; i < attr.length; i++) {
8186db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                    if(attr[i].startsWith("FN")){
8196db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                        attr[i] = "";
8206db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                        /** Remove multiline Content, if any */
8216db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                        /** End traversal before END:VCARD */
8226db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                        for (int j = i+1; j < attr.length - 1; j++) {
8236db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                            if (checkValidFilter(attr[j])) {
8246db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                                break;
8256db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                            } else {
8266db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                                /** Continuation of above attribute, remove */
8276db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                                attr[j] = "";
8286db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                            }
8296db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                        }
8306db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                    }
8316db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                }
8326db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta            }
8336db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta
8346db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta          //NOTE: No need to check photo, we already refrained it if it is not set in the filter
8356db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta            if((!bday) && (vCard.contains("BDAY"))) {
8366db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                for (int i=0; i < attr.length; i++) {
8376db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                    if(attr[i].startsWith("BDAY")){
8386db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                        attr[i] = "";
8396db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                        /** Remove multiline Content, if any */
8406db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                        /** End traversal before END:VCARD */
8416db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                        for (int j = i+1; j < attr.length - 1; j++) {
8426db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                            if (checkValidFilter(attr[j])) {
8436db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                                break;
8446db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                            } else {
8456db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                                /** Continuation of above attribute, remove */
8466db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                                attr[j] = "";
8476db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                            }
8486db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                        }
8496db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                    }
8506db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                }
8516db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta            }
8526db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta
8536db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta            if((!adr) && (vCard.contains("ADR"))) {
8546db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                for (int i=0; i < attr.length; i++) {
8556db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                    if(attr[i].startsWith("ADR")){
8566db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                        attr[i] = "";
8576db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                        /** Remove multiline Content, if any */
8586db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                        /** End traversal before END:VCARD */
8596db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                        for (int j = i+1; j < attr.length - 1; j++) {
8606db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                            if (checkValidFilter(attr[j])) {
8616db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                                break;
8626db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                            } else {
8636db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                                /** Continuation of above attribute, remove */
8646db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                                attr[j] = "";
8656db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                            }
8666db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                        }
8676db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                    }
8686db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                }
8696db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta            }
8706db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta
8716db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta            if((!email) && (vCard.contains("EMAIL"))) {
8726db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                for (int i=0; i < attr.length; i++) {
8736db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                    if(attr[i].startsWith("EMAIL")){
8746db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                        attr[i] = "";
8756db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                        /** Remove multiline Content, if any */
8766db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                        /** End traversal before END:VCARD */
8776db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                        for (int j = i+1; j < attr.length - 1; j++) {
8786db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                            if (checkValidFilter(attr[j])) {
8796db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                                break;
8806db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                            } else {
8816db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                                /** Continuation of above attribute, remove */
8826db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                                attr[j] = "";
8836db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                            }
8846db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                        }
8856db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                    }
8866db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                }
8876db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta            }
8886db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta
8896db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta            if((!title) && (vCard.contains("TITLE"))) {
8906db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                for (int i=0; i < attr.length; i++) {
8916db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                    if(attr[i].startsWith("TITLE")){
8926db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                        attr[i] = "";
8936db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                        /** Remove multiline Content, if any */
8946db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                        /** End traversal before END:VCARD */
8956db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                        for (int j = i+1; j < attr.length - 1; j++) {
8966db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                            if (checkValidFilter(attr[j])) {
8976db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                                break;
8986db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                            } else {
8996db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                                /** Continuation of above attribute, remove */
9006db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                                attr[j] = "";
9016db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                            }
9026db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                        }
9036db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                    }
9046db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                }
9056db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta            }
9066db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta
9076db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta            if((!org) && (vCard.contains("ORG"))) {
9086db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                for (int i=0; i < attr.length; i++) {
9096db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                    if(attr[i].startsWith("ORG")){
9106db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                        attr[i] = "";
9116db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                        /** Remove multiline Content, if any */
9126db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                        /** End traversal before END:VCARD */
9136db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                        for (int j = i+1; j < attr.length - 1; j++) {
9146db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                            if (checkValidFilter(attr[j])) {
9156db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                                break;
9166db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                            } else {
9176db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                                /** Continuation of above attribute, remove */
9186db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                                attr[j] = "";
9196db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                            }
9206db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                        }
9216db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                    }
9226db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                }
9236db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta            }
9246db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta
9256db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta            if((!notes) && (vCard.contains("NOTE"))) {
9266db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                for (int i=0; i < attr.length; i++) {
9276db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                    if(attr[i].startsWith("NOTE")){
9286db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                        attr[i] = "";
9296db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                        /** Remove multiline Content, if any */
9306db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                        /** End traversal before END:VCARD */
9316db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                        for (int j = i+1; j < attr.length - 1; j++) {
9326db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                            if (checkValidFilter(attr[j])) {
9336db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                                break;
9346db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                            } else {
9356db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                                /** Continuation of above attribute, remove */
9366db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                                attr[j] = "";
9376db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                            }
9386db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                        }
9396db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                    }
9406db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                }
9416db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta            }
9426db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta            /*Nickname is not supported in 2.1 version.
9436db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta             *Android still ads it for 2.1 with nickname mentioned in lower case, and therefore
9446db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta             *we need to check for both cases.
9456db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta             */
9466db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta            if(((!nickname) || (vCardType21)) && (vCard.contains("NICKNAME"))) {
9476db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                for (int i=0; i < attr.length; i++) {
9486db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                    if(attr[i].startsWith("NICKNAME")){
9496db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                        attr[i] = "";
9506db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                        /** Remove multiline Content, if any */
9516db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                        /** End traversal before END:VCARD */
9526db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                        for (int j = i+1; j < attr.length - 1; j++) {
9536db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                            if (checkValidFilter(attr[j])) {
9546db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                                break;
9556db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                            } else {
9566db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                                /** Continuation of above attribute, remove */
9576db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                                attr[j] = "";
9586db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                            }
9596db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                        }
9606db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                    }
9616db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                }
9626db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta            }
9636db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta
9646db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta            if((!url) && (vCard.contains("URL"))) {
9656db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                for (int i=0; i < attr.length; i++) {
9666db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                    if(attr[i].startsWith("URL")){
9676db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                        attr[i] = "";
9686db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                        /** Remove multiline Content, if any */
9696db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                        /** End traversal before END:VCARD */
9706db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                        for (int j = i+1; j < attr.length - 1; j++) {
9716db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                            if (checkValidFilter(attr[j])) {
9726db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                                break;
9736db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                            } else {
9746db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                                /** Continuation of above attribute, remove */
9756db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                                attr[j] = "";
9766db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                            }
9776db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                        }
9786db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                    }
9796db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                }
9806db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta            }
9816db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta            /*Since PBAP does not have filter bit for IM and SIP,
9826db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta             *removing them by default.
9836db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta            */
9846db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta            if(vCard.toUpperCase().contains("IM")) {
9856db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                for (int i=0; i < attr.length; i++) {
9866db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                    if(attr[i].toUpperCase().contains("IM")){
9876db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                        vCard = vCard.replace(attr[i] + "\n", "");
9886db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                    }
9896db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                }
9906db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta            }
9916db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta
9926db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta            if(vCard.toUpperCase().contains("SIP")) {
9936db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                for (int i=0; i < attr.length; i++) {
9946db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                    if(attr[i].toUpperCase().contains("SIP")){
9956db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                        vCard = vCard.replace(attr[i] + "\n", "");
9966db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                    }
9976db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                }
9986db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta            }
9996db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta
10006db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta            Log.v(TAG, "Tokens after applying filter: ");
10016db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta
10026db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta            for (int i=0; i < attr.length; i++) {
10036db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                if(!attr[i].equals("")){
10046db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                    filteredVcard = filteredVcard.concat(attr[i] + "\n");
10056db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta                }
10066db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta            }
10076db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta
10086db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta            return filteredVcard;
10096db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta        }
10106db8e703719f301f75acdf4acacc3296cc1b5016Hemant Gupta    }
10112c282d5898ac0916470ebfa9ff26ba784cf4bb24Jackson Fan}
1012