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