Home | History | Annotate | Download | only in pbapclient
      1 /*
      2  * Copyright (C) 2016 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.bluetooth.pbapclient;
     18 
     19 import android.accounts.Account;
     20 import android.bluetooth.BluetoothDevice;
     21 import android.os.Handler;
     22 import android.os.Message;
     23 import android.util.Log;
     24 
     25 import java.lang.ref.WeakReference;
     26 
     27 /**
     28  * Internal API to control Phone Book Profile (PCE role only).
     29  * <p>
     30  * This class defines methods that shall be used by application for the
     31  * retrieval of phone book objects from remote device.
     32  * <p>
     33  * How to connect to remote device which is acting in PSE role:
     34  * <ul>
     35  * <li>Create a <code>BluetoothDevice</code> object which corresponds to remote
     36  * device in PSE role;
     37  * <li>Create an instance of <code>BluetoothPbapClient</code> class, passing
     38  * <code>BluetothDevice</code> object along with a <code>Handler</code> to it;
     39  * <li>Use {@link #setPhoneBookFolderRoot}, {@link #setPhoneBookFolderUp} and
     40  * {@link #setPhoneBookFolderDown} to navigate in virtual phone book folder
     41  * structure
     42  * <li>Use {@link #pullPhoneBookSize} or {@link #pullVcardListingSize} to
     43  * retrieve the size of selected phone book
     44  * <li>Use {@link #pullPhoneBook} to retrieve phone book entries
     45  * <li>Use {@link #pullVcardListing} to retrieve list of entries in the phone
     46  * book
     47  * <li>Use {@link #pullVcardEntry} to pull single entry from the phone book
     48  * </ul>
     49  * Upon completion of each call above PCE will notify application if operation
     50  * completed successfully (along with results) or failed.
     51  * <p>
     52  * Therefore, application should handle following events in its message queue
     53  * handler:
     54  * <ul>
     55  * <li><code>EVENT_PULL_PHONE_BOOK_SIZE_DONE</code>
     56  * <li><code>EVENT_PULL_VCARD_LISTING_SIZE_DONE</code>
     57  * <li><code>EVENT_PULL_PHONE_BOOK_DONE</code>
     58  * <li><code>EVENT_PULL_VCARD_LISTING_DONE</code>
     59  * <li><code>EVENT_PULL_VCARD_ENTRY_DONE</code>
     60  * <li><code>EVENT_SET_PHONE_BOOK_DONE</code>
     61  * </ul>
     62  * and
     63  * <ul>
     64  * <li><code>EVENT_PULL_PHONE_BOOK_SIZE_ERROR</code>
     65  * <li><code>EVENT_PULL_VCARD_LISTING_SIZE_ERROR</code>
     66  * <li><code>EVENT_PULL_PHONE_BOOK_ERROR</code>
     67  * <li><code>EVENT_PULL_VCARD_LISTING_ERROR</code>
     68  * <li><code>EVENT_PULL_VCARD_ENTRY_ERROR</code>
     69  * <li><code>EVENT_SET_PHONE_BOOK_ERROR</code>
     70  * </ul>
     71  * <code>connect</code> and <code>disconnect</code> methods are introduced for
     72  * testing purposes. An application does not need to use them as the session
     73  * connection and disconnection happens automatically internally.
     74  */
     75 public class BluetoothPbapClient {
     76     private static final boolean DBG = true;
     77 
     78     private static final String TAG = "BluetoothPbapClient";
     79 
     80     /**
     81      * Path to local incoming calls history object
     82      */
     83     public static final String ICH_PATH = "telecom/ich.vcf";
     84 
     85     /**
     86      * Path to local outgoing calls history object
     87      */
     88     public static final String OCH_PATH = "telecom/och.vcf";
     89 
     90     /**
     91      * Path to local missed calls history object
     92      */
     93     public static final String MCH_PATH = "telecom/mch.vcf";
     94 
     95     /**
     96      * Path to local combined calls history object
     97      */
     98     public static final String CCH_PATH = "telecom/cch.vcf";
     99 
    100     /**
    101      * Path to local main phone book object
    102      */
    103     public static final String PB_PATH = "telecom/pb.vcf";
    104 
    105     /**
    106      * Path to incoming calls history object stored on the phone's SIM card
    107      */
    108     public static final String SIM_ICH_PATH = "SIM1/telecom/ich.vcf";
    109 
    110     /**
    111      * Path to outgoing calls history object stored on the phone's SIM card
    112      */
    113     public static final String SIM_OCH_PATH = "SIM1/telecom/och.vcf";
    114 
    115     /**
    116      * Path to missed calls history object stored on the phone's SIM card
    117      */
    118     public static final String SIM_MCH_PATH = "SIM1/telecom/mch.vcf";
    119 
    120     /**
    121      * Path to combined calls history object stored on the phone's SIM card
    122      */
    123     public static final String SIM_CCH_PATH = "SIM1/telecom/cch.vcf";
    124 
    125     /**
    126      * Path to main phone book object stored on the phone's SIM card
    127      */
    128     public static final String SIM_PB_PATH = "SIM1/telecom/pb.vcf";
    129 
    130     /**
    131      * Indicates to server that default sorting order shall be used for vCard
    132      * listing.
    133      */
    134     public static final byte ORDER_BY_DEFAULT = -1;
    135 
    136     /**
    137      * Indicates to server that indexed sorting order shall be used for vCard
    138      * listing.
    139      */
    140     public static final byte ORDER_BY_INDEXED = 0;
    141 
    142     /**
    143      * Indicates to server that alphabetical sorting order shall be used for the
    144      * vCard listing.
    145      */
    146     public static final byte ORDER_BY_ALPHABETICAL = 1;
    147 
    148     /**
    149      * Indicates to server that phonetical (based on sound attribute) sorting
    150      * order shall be used for the vCard listing.
    151      */
    152     public static final byte ORDER_BY_PHONETIC = 2;
    153 
    154     /**
    155      * Indicates to server that Name attribute of vCard shall be used to carry
    156      * out the search operation on
    157      */
    158     public static final byte SEARCH_ATTR_NAME = 0;
    159 
    160     /**
    161      * Indicates to server that Number attribute of vCard shall be used to carry
    162      * out the search operation on
    163      */
    164     public static final byte SEARCH_ATTR_NUMBER = 1;
    165 
    166     /**
    167      * Indicates to server that Sound attribute of vCard shall be used to carry
    168      * out the search operation
    169      */
    170     public static final byte SEARCH_ATTR_SOUND = 2;
    171 
    172     /**
    173      * VCard format version 2.1
    174      */
    175     public static final byte VCARD_TYPE_21 = 0;
    176 
    177     /**
    178      * VCard format version 3.0
    179      */
    180     public static final byte VCARD_TYPE_30 = 1;
    181 
    182     /* 64-bit mask used to filter out VCard fields */
    183     // TODO: Think of extracting to separate class
    184     public static final long VCARD_ATTR_VERSION = 0x000000000000000001;
    185     public static final long VCARD_ATTR_FN = 0x000000000000000002;
    186     public static final long VCARD_ATTR_N = 0x000000000000000004;
    187     public static final long VCARD_ATTR_PHOTO = 0x000000000000000008;
    188     public static final long VCARD_ATTR_BDAY = 0x000000000000000010;
    189     public static final long VCARD_ATTR_ADDR = 0x000000000000000020;
    190     public static final long VCARD_ATTR_LABEL = 0x000000000000000040;
    191     public static final long VCARD_ATTR_TEL = 0x000000000000000080;
    192     public static final long VCARD_ATTR_EMAIL = 0x000000000000000100;
    193     public static final long VCARD_ATTR_MAILER = 0x000000000000000200;
    194     public static final long VCARD_ATTR_TZ = 0x000000000000000400;
    195     public static final long VCARD_ATTR_GEO = 0x000000000000000800;
    196     public static final long VCARD_ATTR_TITLE = 0x000000000000001000;
    197     public static final long VCARD_ATTR_ROLE = 0x000000000000002000;
    198     public static final long VCARD_ATTR_LOGO = 0x000000000000004000;
    199     public static final long VCARD_ATTR_AGENT = 0x000000000000008000;
    200     public static final long VCARD_ATTR_ORG = 0x000000000000010000;
    201     public static final long VCARD_ATTR_NOTE = 0x000000000000020000;
    202     public static final long VCARD_ATTR_REV = 0x000000000000040000;
    203     public static final long VCARD_ATTR_SOUND = 0x000000000000080000;
    204     public static final long VCARD_ATTR_URL = 0x000000000000100000;
    205     public static final long VCARD_ATTR_UID = 0x000000000000200000;
    206     public static final long VCARD_ATTR_KEY = 0x000000000000400000;
    207     public static final long VCARD_ATTR_NICKNAME = 0x000000000000800000;
    208     public static final long VCARD_ATTR_CATEGORIES = 0x000000000001000000;
    209     public static final long VCARD_ATTR_PROID = 0x000000000002000000;
    210     public static final long VCARD_ATTR_CLASS = 0x000000000004000000;
    211     public static final long VCARD_ATTR_SORT_STRING = 0x000000000008000000;
    212     public static final long VCARD_ATTR_X_IRMC_CALL_DATETIME =
    213             0x000000000010000000;
    214 
    215     /**
    216      * Maximal number of entries of the phone book that PCE can handle
    217      */
    218     public static final short MAX_LIST_COUNT = (short) 0xFFFF;
    219 
    220     /**
    221      * Event propagated upon completion of <code>setPhoneBookFolderRoot</code>,
    222      * <code>setPhoneBookFolderUp</code> or <code>setPhoneBookFolderDown</code>
    223      * request.
    224      * <p>
    225      * This event indicates that request completed successfully.
    226      * @see #setPhoneBookFolderRoot
    227      * @see #setPhoneBookFolderUp
    228      * @see #setPhoneBookFolderDown
    229      */
    230     public static final int EVENT_SET_PHONE_BOOK_DONE = 1;
    231 
    232     /**
    233      * Event propagated upon completion of <code>pullPhoneBook</code> request.
    234      * <p>
    235      * This event carry on results of the request.
    236      * <p>
    237      * The resulting message contains:
    238      * <table>
    239      * <tr>
    240      * <td><code>msg.arg1</code></td>
    241      * <td>newMissedCalls parameter (only in case of missed calls history object
    242      * request)</td>
    243      * </tr>
    244      * <tr>
    245      * <td><code>msg.obj</code></td>
    246      * <td>which is a list of <code>VCardEntry</code> objects</td>
    247      * </tr>
    248      * </table>
    249      * @see #pullPhoneBook
    250      */
    251     public static final int EVENT_PULL_PHONE_BOOK_DONE = 2;
    252 
    253     /**
    254      * Event propagated upon completion of <code>pullVcardListing</code>
    255      * request.
    256      * <p>
    257      * This event carry on results of the request.
    258      * <p>
    259      * The resulting message contains:
    260      * <table>
    261      * <tr>
    262      * <td><code>msg.arg1</code></td>
    263      * <td>newMissedCalls parameter (only in case of missed calls history object
    264      * request)</td>
    265      * </tr>
    266      * <tr>
    267      * <td><code>msg.obj</code></td>
    268      * <td>which is a list of <code>BluetoothPbapCard</code> objects</td>
    269      * </tr>
    270      * </table>
    271      * @see #pullVcardListing
    272      */
    273     public static final int EVENT_PULL_VCARD_LISTING_DONE = 3;
    274 
    275     /**
    276      * Event propagated upon completion of <code>pullVcardEntry</code> request.
    277      * <p>
    278      * This event carry on results of the request.
    279      * <p>
    280      * The resulting message contains:
    281      * <table>
    282      * <tr>
    283      * <td><code>msg.obj</code></td>
    284      * <td>vCard as and object of type <code>VCardEntry</code></td>
    285      * </tr>
    286      * </table>
    287      * @see #pullVcardEntry
    288      */
    289     public static final int EVENT_PULL_VCARD_ENTRY_DONE = 4;
    290 
    291     /**
    292      * Event propagated upon completion of <code>pullPhoneBookSize</code>
    293      * request.
    294      * <p>
    295      * This event carry on results of the request.
    296      * <p>
    297      * The resulting message contains:
    298      * <table>
    299      * <tr>
    300      * <td><code>msg.arg1</code></td>
    301      * <td>size of the phone book</td>
    302      * </tr>
    303      * </table>
    304      * @see #pullPhoneBookSize
    305      */
    306     public static final int EVENT_PULL_PHONE_BOOK_SIZE_DONE = 5;
    307 
    308     /**
    309      * Event propagated upon completion of <code>pullVcardListingSize</code>
    310      * request.
    311      * <p>
    312      * This event carry on results of the request.
    313      * <p>
    314      * The resulting message contains:
    315      * <table>
    316      * <tr>
    317      * <td><code>msg.arg1</code></td>
    318      * <td>size of the phone book listing</td>
    319      * </tr>
    320      * </table>
    321      * @see #pullVcardListingSize
    322      */
    323     public static final int EVENT_PULL_VCARD_LISTING_SIZE_DONE = 6;
    324 
    325     /**
    326      * Event propagated upon completion of <code>setPhoneBookFolderRoot</code>,
    327      * <code>setPhoneBookFolderUp</code> or <code>setPhoneBookFolderDown</code>
    328      * request. This event indicates an error during operation.
    329      */
    330     public static final int EVENT_SET_PHONE_BOOK_ERROR = 101;
    331 
    332     /**
    333      * Event propagated upon completion of <code>pullPhoneBook</code> request.
    334      * This event indicates an error during operation.
    335      */
    336     public static final int EVENT_PULL_PHONE_BOOK_ERROR = 102;
    337 
    338     /**
    339      * Event propagated upon completion of <code>pullVcardListing</code>
    340      * request. This event indicates an error during operation.
    341      */
    342     public static final int EVENT_PULL_VCARD_LISTING_ERROR = 103;
    343 
    344     /**
    345      * Event propagated upon completion of <code>pullVcardEntry</code> request.
    346      * This event indicates an error during operation.
    347      */
    348     public static final int EVENT_PULL_VCARD_ENTRY_ERROR = 104;
    349 
    350     /**
    351      * Event propagated upon completion of <code>pullPhoneBookSize</code>
    352      * request. This event indicates an error during operation.
    353      */
    354     public static final int EVENT_PULL_PHONE_BOOK_SIZE_ERROR = 105;
    355 
    356     /**
    357      * Event propagated upon completion of <code>pullVcardListingSize</code>
    358      * request. This event indicates an error during operation.
    359      */
    360     public static final int EVENT_PULL_VCARD_LISTING_SIZE_ERROR = 106;
    361 
    362     /**
    363      * Event propagated when PCE has been connected to PSE
    364      */
    365     public static final int EVENT_SESSION_CONNECTED = 201;
    366 
    367     /**
    368      * Event propagated when PCE has been disconnected from PSE
    369      */
    370     public static final int EVENT_SESSION_DISCONNECTED = 202;
    371     public static final int EVENT_SESSION_AUTH_REQUESTED = 203;
    372     public static final int EVENT_SESSION_AUTH_TIMEOUT = 204;
    373 
    374     public enum ConnectionState {
    375         DISCONNECTED, CONNECTING, CONNECTED, DISCONNECTING;
    376     }
    377 
    378     private final Account mAccount;
    379     private final Handler mClientHandler;
    380     private final BluetoothPbapSession mSession;
    381     private ConnectionState mConnectionState = ConnectionState.DISCONNECTED;
    382 
    383     private SessionHandler mSessionHandler;
    384 
    385     private static class SessionHandler extends Handler {
    386 
    387         private final WeakReference<BluetoothPbapClient> mClient;
    388 
    389         SessionHandler(BluetoothPbapClient client) {
    390             mClient = new WeakReference<BluetoothPbapClient>(client);
    391         }
    392 
    393         @Override
    394         public void handleMessage(Message msg) {
    395             Log.d(TAG, "handleMessage: what=" + msg.what);
    396 
    397             BluetoothPbapClient client = mClient.get();
    398             if (client == null) {
    399                 return;
    400             }
    401 
    402             switch (msg.what) {
    403                 case BluetoothPbapSession.REQUEST_FAILED:
    404                 {
    405                     BluetoothPbapRequest req = (BluetoothPbapRequest) msg.obj;
    406 
    407                     if (req instanceof BluetoothPbapRequestPullPhoneBookSize) {
    408                         client.sendToClient(EVENT_PULL_PHONE_BOOK_SIZE_ERROR);
    409                     } else if (req instanceof BluetoothPbapRequestPullVcardListingSize) {
    410                         client.sendToClient(EVENT_PULL_VCARD_LISTING_SIZE_ERROR);
    411                     } else if (req instanceof BluetoothPbapRequestPullPhoneBook) {
    412                         client.sendToClient(EVENT_PULL_PHONE_BOOK_ERROR);
    413                     } else if (req instanceof BluetoothPbapRequestPullVcardListing) {
    414                         client.sendToClient(EVENT_PULL_VCARD_LISTING_ERROR);
    415                     } else if (req instanceof BluetoothPbapRequestPullVcardEntry) {
    416                         client.sendToClient(EVENT_PULL_VCARD_ENTRY_ERROR);
    417                     } else if (req instanceof BluetoothPbapRequestSetPath) {
    418                         client.sendToClient(EVENT_SET_PHONE_BOOK_ERROR);
    419                     }
    420 
    421                     break;
    422                 }
    423 
    424                 case BluetoothPbapSession.REQUEST_COMPLETED:
    425                 {
    426                     BluetoothPbapRequest req = (BluetoothPbapRequest) msg.obj;
    427 
    428                     if (req instanceof BluetoothPbapRequestPullPhoneBookSize) {
    429                         int size = ((BluetoothPbapRequestPullPhoneBookSize) req).getSize();
    430                         client.sendToClient(EVENT_PULL_PHONE_BOOK_SIZE_DONE, size);
    431 
    432                     } else if (req instanceof BluetoothPbapRequestPullVcardListingSize) {
    433                         int size = ((BluetoothPbapRequestPullVcardListingSize) req).getSize();
    434                         client.sendToClient(EVENT_PULL_VCARD_LISTING_SIZE_DONE, size);
    435 
    436                     } else if (req instanceof BluetoothPbapRequestPullPhoneBook) {
    437                         BluetoothPbapRequestPullPhoneBook r = (BluetoothPbapRequestPullPhoneBook) req;
    438                         client.sendToClient(EVENT_PULL_PHONE_BOOK_DONE, r.getNewMissedCalls(),
    439                                 r.getList());
    440 
    441                     } else if (req instanceof BluetoothPbapRequestPullVcardListing) {
    442                         BluetoothPbapRequestPullVcardListing r = (BluetoothPbapRequestPullVcardListing) req;
    443                         client.sendToClient(EVENT_PULL_VCARD_LISTING_DONE, r.getNewMissedCalls(),
    444                                 r.getList());
    445 
    446                     } else if (req instanceof BluetoothPbapRequestPullVcardEntry) {
    447                         BluetoothPbapRequestPullVcardEntry r = (BluetoothPbapRequestPullVcardEntry) req;
    448                         client.sendToClient(EVENT_PULL_VCARD_ENTRY_DONE, r.getVcard());
    449 
    450                     } else if (req instanceof BluetoothPbapRequestSetPath) {
    451                         client.sendToClient(EVENT_SET_PHONE_BOOK_DONE);
    452                     }
    453 
    454                     break;
    455                 }
    456 
    457                 case BluetoothPbapSession.AUTH_REQUESTED:
    458                     client.sendToClient(EVENT_SESSION_AUTH_REQUESTED);
    459                     break;
    460 
    461                 case BluetoothPbapSession.AUTH_TIMEOUT:
    462                     client.sendToClient(EVENT_SESSION_AUTH_TIMEOUT);
    463                     break;
    464 
    465                 /*
    466                  * app does not need to know when session is connected since
    467                  * OBEX session is managed inside BluetoothPbapSession
    468                  * automatically - we add this only so app can visualize PBAP
    469                  * connection status in case it wants to
    470                  */
    471 
    472                 case BluetoothPbapSession.SESSION_CONNECTING:
    473                     client.mConnectionState = ConnectionState.CONNECTING;
    474                     break;
    475 
    476                 case BluetoothPbapSession.SESSION_CONNECTED:
    477                     client.mConnectionState = ConnectionState.CONNECTED;
    478                     client.sendToClient(EVENT_SESSION_CONNECTED);
    479                     break;
    480 
    481                 case BluetoothPbapSession.SESSION_DISCONNECTED:
    482                     client.mConnectionState = ConnectionState.DISCONNECTED;
    483                     client.sendToClient(EVENT_SESSION_DISCONNECTED);
    484                     break;
    485             }
    486         }
    487     };
    488 
    489     private void sendToClient(int eventId) {
    490         sendToClient(eventId, 0, null);
    491     }
    492 
    493     private void sendToClient(int eventId, int param) {
    494         sendToClient(eventId, param, null);
    495     }
    496 
    497     private void sendToClient(int eventId, Object param) {
    498         sendToClient(eventId, 0, param);
    499     }
    500 
    501     private void sendToClient(int eventId, int param1, Object param2) {
    502         mClientHandler.obtainMessage(eventId, param1, 0, param2).sendToTarget();
    503     }
    504 
    505     /**
    506      * Constructs PCE object
    507      *
    508      * @param device BluetoothDevice that corresponds to remote acting in PSE
    509      *            role
    510      * @param account the account to which contacts will be added {@see #pullPhoneBook}.
    511      * @param handler the handle that will be used by PCE to notify events and
    512      *            results to application
    513      * @throws NullPointerException
    514      */
    515     public BluetoothPbapClient(BluetoothDevice device, Account account, Handler handler) {
    516         if (DBG) {
    517             Log.d(TAG, " device " + device + " account " + account);
    518         }
    519         if (device == null) {
    520             throw new NullPointerException("BluetoothDevice is null");
    521         }
    522 
    523         mAccount = account;
    524 
    525         mClientHandler = handler;
    526 
    527         mSessionHandler = new SessionHandler(this);
    528 
    529         mSession = new BluetoothPbapSession(device, mSessionHandler);
    530     }
    531 
    532     /**
    533      * Starts a pbap session. <pb> This method set up rfcomm session, obex
    534      * session and waits for requests to be transfered to PSE.
    535      */
    536     public void connect() {
    537         mSession.start();
    538     }
    539 
    540     @Override
    541     public void finalize() {
    542         if (mSession != null) {
    543             mSession.stop();
    544         }
    545     }
    546 
    547     /**
    548      * Stops all the active transactions and disconnects from the server.
    549      */
    550     public void disconnect() {
    551         mSession.stop();
    552     }
    553 
    554     /**
    555      * Aborts current request, if any
    556      */
    557     public void abort() {
    558         mSession.abort();
    559     }
    560 
    561     public ConnectionState getState() {
    562         return mConnectionState;
    563     }
    564 
    565     /**
    566      * Sets current folder to root
    567      *
    568      * @return <code>true</code> if request has been sent successfully;
    569      *         <code>false</code> otherwise; upon completion PCE sends
    570      *         {@link #EVENT_SET_PHONE_BOOK_DONE} or
    571      *         {@link #EVENT_SET_PHONE_BOOK_ERROR} in case of failure
    572      */
    573     public boolean setPhoneBookFolderRoot() {
    574         BluetoothPbapRequest req = new BluetoothPbapRequestSetPath(false);
    575         return mSession.makeRequest(req);
    576     }
    577 
    578     /**
    579      * Sets current folder to parent
    580      *
    581      * @return <code>true</code> if request has been sent successfully;
    582      *         <code>false</code> otherwise; upon completion PCE sends
    583      *         {@link #EVENT_SET_PHONE_BOOK_DONE} or
    584      *         {@link #EVENT_SET_PHONE_BOOK_ERROR} in case of failure
    585      */
    586     public boolean setPhoneBookFolderUp() {
    587         BluetoothPbapRequest req = new BluetoothPbapRequestSetPath(true);
    588         return mSession.makeRequest(req);
    589     }
    590 
    591     /**
    592      * Sets current folder to selected sub-folder
    593      *
    594      * @param folder the name of the sub-folder
    595      * @return @return <code>true</code> if request has been sent successfully;
    596      *         <code>false</code> otherwise; upon completion PCE sends
    597      *         {@link #EVENT_SET_PHONE_BOOK_DONE} or
    598      *         {@link #EVENT_SET_PHONE_BOOK_ERROR} in case of failure
    599      */
    600     public boolean setPhoneBookFolderDown(String folder) {
    601         BluetoothPbapRequest req = new BluetoothPbapRequestSetPath(folder);
    602         return mSession.makeRequest(req);
    603     }
    604 
    605     /**
    606      * Requests for the number of entries in the phone book.
    607      *
    608      * @param pbName absolute path to the phone book
    609      * @return <code>true</code> if request has been sent successfully;
    610      *         <code>false</code> otherwise; upon completion PCE sends
    611      *         {@link #EVENT_PULL_PHONE_BOOK_SIZE_DONE} or
    612      *         {@link #EVENT_PULL_PHONE_BOOK_SIZE_ERROR} in case of failure
    613      */
    614     public boolean pullPhoneBookSize(String pbName) {
    615         BluetoothPbapRequestPullPhoneBookSize req = new BluetoothPbapRequestPullPhoneBookSize(
    616                 pbName);
    617 
    618         return mSession.makeRequest(req);
    619     }
    620 
    621     /**
    622      * Requests for the number of entries in the phone book listing.
    623      *
    624      * @param folder the name of the folder to be retrieved
    625      * @return <code>true</code> if request has been sent successfully;
    626      *         <code>false</code> otherwise; upon completion PCE sends
    627      *         {@link #EVENT_PULL_VCARD_LISTING_SIZE_DONE} or
    628      *         {@link #EVENT_PULL_VCARD_LISTING_SIZE_ERROR} in case of failure
    629      */
    630     public boolean pullVcardListingSize(String folder) {
    631         BluetoothPbapRequestPullVcardListingSize req = new BluetoothPbapRequestPullVcardListingSize(
    632                 folder);
    633 
    634         return mSession.makeRequest(req);
    635     }
    636 
    637     /**
    638      * Pulls complete phone book. This method pulls phone book which entries are
    639      * of <code>VCARD_TYPE_21</code> type and each single vCard contains minimal
    640      * required set of fields and the number of entries in response is not
    641      * limited.
    642      *
    643      * @param pbName absolute path to the phone book
    644      * @return <code>true</code> if request has been sent successfully;
    645      *         <code>false</code> otherwise; upon completion PCE sends
    646      *         {@link #EVENT_PULL_PHONE_BOOK_DONE} or
    647      *         {@link #EVENT_PULL_PHONE_BOOK_ERROR} in case of failure
    648      */
    649     public boolean pullPhoneBook(String pbName) {
    650         return pullPhoneBook(pbName, 0, VCARD_TYPE_21, 0, 0);
    651     }
    652 
    653     /**
    654      * Pulls complete phone book. This method pulls all entries from the phone
    655      * book.
    656      *
    657      * @param pbName absolute path to the phone book
    658      * @param filter bit mask which indicates which fields of the vCard shall be
    659      *            included in each entry of the resulting list
    660      * @param format vCard format of entries in the resulting list
    661      * @return <code>true</code> if request has been sent successfully;
    662      *         <code>false</code> otherwise; upon completion PCE sends
    663      *         {@link #EVENT_PULL_PHONE_BOOK_DONE} or
    664      *         {@link #EVENT_PULL_PHONE_BOOK_ERROR} in case of failure
    665      */
    666     public boolean pullPhoneBook(String pbName, long filter, byte format) {
    667         return pullPhoneBook(pbName, filter, format, 0, 0);
    668     }
    669 
    670     /**
    671      * Pulls complete phone book. This method pulls entries from the phone book
    672      * limited to the number of <code>maxListCount</code> starting from the
    673      * position of <code>listStartOffset</code>.
    674      * <p>
    675      * The resulting list contains vCard objects in version
    676      * <code>VCARD_TYPE_21</code> which in turns contain minimal required set of
    677      * vCard fields.
    678      *
    679      * @param pbName absolute path to the phone book
    680      * @param maxListCount limits number of entries in the response
    681      * @param listStartOffset offset to the first entry of the list that would
    682      *            be returned
    683      * @return <code>true</code> if request has been sent successfully;
    684      *         <code>false</code> otherwise; upon completion PCE sends
    685      *         {@link #EVENT_PULL_PHONE_BOOK_DONE} or
    686      *         {@link #EVENT_PULL_PHONE_BOOK_ERROR} in case of failure
    687      */
    688     public boolean pullPhoneBook(String pbName, int maxListCount, int listStartOffset) {
    689         return pullPhoneBook(pbName, 0, VCARD_TYPE_21, maxListCount, listStartOffset);
    690     }
    691 
    692     /**
    693      * Pulls complete phone book.
    694      *
    695      * @param pbName absolute path to the phone book
    696      * @param filter bit mask which indicates which fields of the vCard hall be
    697      *            included in each entry of the resulting list
    698      * @param format vCard format of entries in the resulting list
    699      * @param maxListCount limits number of entries in the response
    700      * @param listStartOffset offset to the first entry of the list that would
    701      *            be returned
    702      * @return <code>true</code> if request has been sent successfully;
    703      *         <code>false</code> otherwise; upon completion PCE sends
    704      *         {@link #EVENT_PULL_PHONE_BOOK_DONE} or
    705      *         {@link #EVENT_PULL_PHONE_BOOK_ERROR} in case of failure
    706      */
    707     public boolean pullPhoneBook(String pbName, long filter, byte format, int maxListCount,
    708             int listStartOffset) {
    709         BluetoothPbapRequest req = new BluetoothPbapRequestPullPhoneBook(
    710                 pbName, mAccount, filter, format, maxListCount, listStartOffset);
    711         return mSession.makeRequest(req);
    712     }
    713 
    714     /**
    715      * Pulls list of entries in the phone book.
    716      * <p>
    717      * This method pulls the list of entries in the <code>folder</code>.
    718      *
    719      * @param folder the name of the folder to be retrieved
    720      * @return <code>true</code> if request has been sent successfully;
    721      *         <code>false</code> otherwise; upon completion PCE sends
    722      *         {@link #EVENT_PULL_VCARD_LISTING_DONE} or
    723      *         {@link #EVENT_PULL_VCARD_LISTING_ERROR} in case of failure
    724      */
    725     public boolean pullVcardListing(String folder) {
    726         return pullVcardListing(folder, ORDER_BY_DEFAULT, SEARCH_ATTR_NAME, null, 0, 0);
    727     }
    728 
    729     /**
    730      * Pulls list of entries in the <code>folder</code>.
    731      *
    732      * @param folder the name of the folder to be retrieved
    733      * @param order the sorting order of the resulting list of entries
    734      * @return <code>true</code> if request has been sent successfully;
    735      *         <code>false</code> otherwise; upon completion PCE sends
    736      *         {@link #EVENT_PULL_VCARD_LISTING_DONE} or
    737      *         {@link #EVENT_PULL_VCARD_LISTING_ERROR} in case of failure
    738      */
    739     public boolean pullVcardListing(String folder, byte order) {
    740         return pullVcardListing(folder, order, SEARCH_ATTR_NAME, null, 0, 0);
    741     }
    742 
    743     /**
    744      * Pulls list of entries in the <code>folder</code>. Only entries where
    745      * <code>searchAttr</code> attribute of vCard matches <code>searchVal</code>
    746      * will be listed.
    747      *
    748      * @param folder the name of the folder to be retrieved
    749      * @param searchAttr vCard attribute which shall be used to carry out search
    750      *            operation on
    751      * @param searchVal text string used by matching routine to match the value
    752      *            of the attribute indicated by SearchAttr
    753      * @return <code>true</code> if request has been sent successfully;
    754      *         <code>false</code> otherwise; upon completion PCE sends
    755      *         {@link #EVENT_PULL_VCARD_LISTING_DONE} or
    756      *         {@link #EVENT_PULL_VCARD_LISTING_ERROR} in case of failure
    757      */
    758     public boolean pullVcardListing(String folder, byte searchAttr, String searchVal) {
    759         return pullVcardListing(folder, ORDER_BY_DEFAULT, searchAttr, searchVal, 0, 0);
    760     }
    761 
    762     /**
    763      * Pulls list of entries in the <code>folder</code>.
    764      *
    765      * @param folder the name of the folder to be retrieved
    766      * @param order the sorting order of the resulting list of entries
    767      * @param maxListCount limits number of entries in the response
    768      * @param listStartOffset offset to the first entry of the list that would
    769      *            be returned
    770      * @return <code>true</code> if request has been sent successfully;
    771      *         <code>false</code> otherwise; upon completion PCE sends
    772      *         {@link #EVENT_PULL_VCARD_LISTING_DONE} or
    773      *         {@link #EVENT_PULL_VCARD_LISTING_ERROR} in case of failure
    774      */
    775     public boolean pullVcardListing(String folder, byte order, int maxListCount,
    776             int listStartOffset) {
    777         return pullVcardListing(folder, order, SEARCH_ATTR_NAME, null, maxListCount,
    778                 listStartOffset);
    779     }
    780 
    781     /**
    782      * Pulls list of entries in the <code>folder</code>.
    783      *
    784      * @param folder the name of the folder to be retrieved
    785      * @param maxListCount limits number of entries in the response
    786      * @param listStartOffset offset to the first entry of the list that would
    787      *            be returned
    788      * @return <code>true</code> if request has been sent successfully;
    789      *         <code>false</code> otherwise; upon completion PCE sends
    790      *         {@link #EVENT_PULL_VCARD_LISTING_DONE} or
    791      *         {@link #EVENT_PULL_VCARD_LISTING_ERROR} in case of failure
    792      */
    793     public boolean pullVcardListing(String folder, int maxListCount, int listStartOffset) {
    794         return pullVcardListing(folder, ORDER_BY_DEFAULT, SEARCH_ATTR_NAME, null, maxListCount,
    795                 listStartOffset);
    796     }
    797 
    798     /**
    799      * Pulls list of entries in the <code>folder</code>.
    800      *
    801      * @param folder the name of the folder to be retrieved
    802      * @param order the sorting order of the resulting list of entries
    803      * @param searchAttr vCard attribute which shall be used to carry out search
    804      *            operation on
    805      * @param searchVal text string used by matching routine to match the value
    806      *            of the attribute indicated by SearchAttr
    807      * @param maxListCount limits number of entries in the response
    808      * @param listStartOffset offset to the first entry of the list that would
    809      *            be returned
    810      * @return <code>true</code> if request has been sent successfully;
    811      *         <code>false</code> otherwise; upon completion PCE sends
    812      *         {@link #EVENT_PULL_VCARD_LISTING_DONE} or
    813      *         {@link #EVENT_PULL_VCARD_LISTING_ERROR} in case of failure
    814      */
    815     public boolean pullVcardListing(String folder, byte order, byte searchAttr,
    816             String searchVal, int maxListCount, int listStartOffset) {
    817         BluetoothPbapRequest req = new BluetoothPbapRequestPullVcardListing(folder, order,
    818                 searchAttr, searchVal, maxListCount, listStartOffset);
    819         return mSession.makeRequest(req);
    820     }
    821 
    822     /**
    823      * Pulls single vCard object
    824      *
    825      * @param handle handle to the vCard which shall be pulled
    826      * @return <code>true</code> if request has been sent successfully;
    827      *         <code>false</code> otherwise; upon completion PCE sends
    828      *         {@link #EVENT_PULL_VCARD_DONE} or
    829      * @link #EVENT_PULL_VCARD_ERROR} in case of failure
    830      */
    831     public boolean pullVcardEntry(String handle) {
    832         return pullVcardEntry(handle, (byte) 0, VCARD_TYPE_21);
    833     }
    834 
    835     /**
    836      * Pulls single vCard object
    837      *
    838      * @param handle handle to the vCard which shall be pulled
    839      * @param filter bit mask of the vCard fields that shall be included in the
    840      *            resulting vCard
    841      * @param format resulting vCard version
    842      * @return <code>true</code> if request has been sent successfully;
    843      *         <code>false</code> otherwise; upon completion PCE sends
    844      *         {@link #EVENT_PULL_VCARD_DONE}
    845      * @link #EVENT_PULL_VCARD_ERROR} in case of failure
    846      */
    847     public boolean pullVcardEntry(String handle, long filter, byte format) {
    848         BluetoothPbapRequest req =
    849                 new BluetoothPbapRequestPullVcardEntry(handle, mAccount, filter, format);
    850         return mSession.makeRequest(req);
    851     }
    852 
    853     public boolean setAuthResponse(String key) {
    854         Log.d(TAG, " setAuthResponse key=" + key);
    855         return mSession.setAuthResponse(key);
    856     }
    857 }
    858