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