LocalBluetoothProfileManager.java revision c090feb64f674d9840993736a24f9667f8b0e0d5
1/* 2 * Copyright (C) 2008 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 com.android.settings.bluetooth; 18 19import com.android.settings.R; 20 21import android.bluetooth.BluetoothA2dp; 22import android.bluetooth.BluetoothAdapter; 23import android.bluetooth.BluetoothDevice; 24import android.bluetooth.BluetoothHeadset; 25import android.bluetooth.BluetoothInputDevice; 26import android.bluetooth.BluetoothPan; 27import android.bluetooth.BluetoothProfile; 28import android.bluetooth.BluetoothUuid; 29import android.os.Handler; 30import android.os.ParcelUuid; 31import android.util.Log; 32 33import java.util.HashMap; 34import java.util.Iterator; 35import java.util.LinkedList; 36import java.util.List; 37import java.util.Map; 38 39/** 40 * LocalBluetoothProfileManager is an abstract class defining the basic 41 * functionality related to a profile. 42 */ 43public abstract class LocalBluetoothProfileManager { 44 private static final String TAG = "LocalBluetoothProfileManager"; 45 46 /* package */ static final ParcelUuid[] HEADSET_PROFILE_UUIDS = new ParcelUuid[] { 47 BluetoothUuid.HSP, 48 BluetoothUuid.Handsfree, 49 }; 50 51 /* package */ static final ParcelUuid[] A2DP_PROFILE_UUIDS = new ParcelUuid[] { 52 BluetoothUuid.AudioSink, 53 BluetoothUuid.AdvAudioDist, 54 }; 55 56 /* package */ static final ParcelUuid[] OPP_PROFILE_UUIDS = new ParcelUuid[] { 57 BluetoothUuid.ObexObjectPush 58 }; 59 60 /* package */ static final ParcelUuid[] HID_PROFILE_UUIDS = new ParcelUuid[] { 61 BluetoothUuid.Hid 62 }; 63 64 /* package */ static final ParcelUuid[] PANU_PROFILE_UUIDS = new ParcelUuid[] { 65 BluetoothUuid.PANU 66 }; 67 68 /* package */ static final ParcelUuid[] NAP_PROFILE_UUIDS = new ParcelUuid[] { 69 BluetoothUuid.NAP 70 }; 71 72 /** 73 * An interface for notifying BluetoothHeadset IPC clients when they have 74 * been connected to the BluetoothHeadset service. 75 */ 76 public interface ServiceListener { 77 /** 78 * Called to notify the client when this proxy object has been 79 * connected to the BluetoothHeadset service. Clients must wait for 80 * this callback before making IPC calls on the BluetoothHeadset 81 * service. 82 */ 83 public void onServiceConnected(); 84 85 /** 86 * Called to notify the client that this proxy object has been 87 * disconnected from the BluetoothHeadset service. Clients must not 88 * make IPC calls on the BluetoothHeadset service after this callback. 89 * This callback will currently only occur if the application hosting 90 * the BluetoothHeadset service, but may be called more often in future. 91 */ 92 public void onServiceDisconnected(); 93 } 94 95 // TODO: close profiles when we're shutting down 96 private static Map<Profile, LocalBluetoothProfileManager> sProfileMap = 97 new HashMap<Profile, LocalBluetoothProfileManager>(); 98 99 protected LocalBluetoothManager mLocalManager; 100 101 public static void init(LocalBluetoothManager localManager) { 102 synchronized (sProfileMap) { 103 if (sProfileMap.size() == 0) { 104 LocalBluetoothProfileManager profileManager; 105 106 profileManager = new A2dpProfileManager(localManager); 107 sProfileMap.put(Profile.A2DP, profileManager); 108 109 profileManager = new HeadsetProfileManager(localManager); 110 sProfileMap.put(Profile.HEADSET, profileManager); 111 112 profileManager = new OppProfileManager(localManager); 113 sProfileMap.put(Profile.OPP, profileManager); 114 115 profileManager = new HidProfileManager(localManager); 116 sProfileMap.put(Profile.HID, profileManager); 117 118 profileManager = new PanProfileManager(localManager); 119 sProfileMap.put(Profile.PAN, profileManager); 120 } 121 } 122 } 123 124 // TODO(): Combine the init and updateLocalProfiles codes. 125 // init can get called from various paths, it makes no sense to add and then delete. 126 public static void updateLocalProfiles(LocalBluetoothManager localManager, ParcelUuid[] uuids) { 127 if (!BluetoothUuid.containsAnyUuid(uuids, HEADSET_PROFILE_UUIDS)) { 128 sProfileMap.remove(Profile.HEADSET); 129 } 130 131 if (BluetoothUuid.containsAnyUuid(uuids, A2DP_PROFILE_UUIDS)) { 132 sProfileMap.remove(Profile.A2DP); 133 } 134 135 if (BluetoothUuid.containsAnyUuid(uuids, OPP_PROFILE_UUIDS)) { 136 sProfileMap.remove(Profile.OPP); 137 } 138 139 if (BluetoothUuid.containsAnyUuid(uuids, HID_PROFILE_UUIDS)) { 140 sProfileMap.remove(Profile.HID); 141 } 142 143 if (BluetoothUuid.containsAnyUuid(uuids, PANU_PROFILE_UUIDS)) { 144 sProfileMap.remove(Profile.PAN); 145 } 146 } 147 148 private static LinkedList<ServiceListener> mServiceListeners = 149 new LinkedList<ServiceListener>(); 150 151 public static void addServiceListener(ServiceListener l) { 152 mServiceListeners.add(l); 153 } 154 155 public static void removeServiceListener(ServiceListener l) { 156 mServiceListeners.remove(l); 157 } 158 159 public static boolean isManagerReady() { 160 // Getting just the headset profile is fine for now. Will need to deal with A2DP 161 // and others if they aren't always in a ready state. 162 LocalBluetoothProfileManager profileManager = sProfileMap.get(Profile.HEADSET); 163 if (profileManager == null) { 164 return sProfileMap.size() > 0; 165 } 166 return profileManager.isProfileReady(); 167 } 168 169 public static LocalBluetoothProfileManager getProfileManager(LocalBluetoothManager localManager, 170 Profile profile) { 171 // Note: This code assumes that "localManager" is same as the 172 // LocalBluetoothManager that was used to initialize the sProfileMap. 173 // If that every changes, we can't just keep one copy of sProfileMap. 174 synchronized (sProfileMap) { 175 LocalBluetoothProfileManager profileManager = sProfileMap.get(profile); 176 if (profileManager == null) { 177 Log.e(TAG, "profileManager can't be found for " + profile.toString()); 178 } 179 return profileManager; 180 } 181 } 182 183 /** 184 * Temporary method to fill profiles based on a device's class. 185 * 186 * NOTE: This list happens to define the connection order. We should put this logic in a more 187 * well known place when this method is no longer temporary. 188 * @param uuids of the remote device 189 * @param profiles The list of profiles to fill 190 */ 191 public static void updateProfiles(ParcelUuid[] uuids, List<Profile> profiles) { 192 profiles.clear(); 193 194 if (uuids == null) { 195 return; 196 } 197 198 if (BluetoothUuid.containsAnyUuid(uuids, HEADSET_PROFILE_UUIDS) && 199 sProfileMap.containsKey(Profile.HEADSET)) { 200 profiles.add(Profile.HEADSET); 201 } 202 203 if (BluetoothUuid.containsAnyUuid(uuids, A2DP_PROFILE_UUIDS) && 204 sProfileMap.containsKey(Profile.A2DP)) { 205 profiles.add(Profile.A2DP); 206 } 207 208 if (BluetoothUuid.containsAnyUuid(uuids, OPP_PROFILE_UUIDS) && 209 sProfileMap.containsKey(Profile.OPP)) { 210 profiles.add(Profile.OPP); 211 } 212 213 if (BluetoothUuid.containsAnyUuid(uuids, HID_PROFILE_UUIDS) && 214 sProfileMap.containsKey(Profile.HID)) { 215 profiles.add(Profile.HID); 216 } 217 218 if (BluetoothUuid.containsAnyUuid(uuids, PANU_PROFILE_UUIDS) && 219 sProfileMap.containsKey(Profile.PAN)) { 220 profiles.add(Profile.PAN); 221 } 222 } 223 224 protected LocalBluetoothProfileManager(LocalBluetoothManager localManager) { 225 mLocalManager = localManager; 226 } 227 228 public abstract List<BluetoothDevice> getConnectedDevices(); 229 230 public abstract boolean connect(BluetoothDevice device); 231 232 public abstract boolean disconnect(BluetoothDevice device); 233 234 public abstract int getConnectionStatus(BluetoothDevice device); 235 236 public abstract int getSummary(BluetoothDevice device); 237 238 public abstract int convertState(int a2dpState); 239 240 public abstract boolean isPreferred(BluetoothDevice device); 241 242 public abstract int getPreferred(BluetoothDevice device); 243 244 public abstract void setPreferred(BluetoothDevice device, boolean preferred); 245 246 public boolean isConnected(BluetoothDevice device) { 247 return SettingsBtStatus.isConnectionStatusConnected(getConnectionStatus(device)); 248 } 249 250 public abstract boolean isProfileReady(); 251 252 public int getDrawableResource() { 253 return R.drawable.ic_bt_headphones_a2dp; 254 } 255 256 public static enum Profile { 257 HEADSET(R.string.bluetooth_profile_headset), 258 A2DP(R.string.bluetooth_profile_a2dp), 259 OPP(R.string.bluetooth_profile_opp), 260 HID(R.string.bluetooth_profile_hid), 261 PAN(R.string.bluetooth_profile_pan); 262 263 public final int localizedString; 264 265 private Profile(int localizedString) { 266 this.localizedString = localizedString; 267 } 268 } 269 270 /** 271 * A2dpProfileManager is an abstraction for the {@link BluetoothA2dp} service. 272 */ 273 private static class A2dpProfileManager extends LocalBluetoothProfileManager 274 implements BluetoothProfile.ServiceListener { 275 private BluetoothA2dp mService; 276 277 // TODO(): The calls must wait for mService. Its not null just 278 // because it runs in the system server. 279 public A2dpProfileManager(LocalBluetoothManager localManager) { 280 super(localManager); 281 BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter(); 282 adapter.getProfileProxy(localManager.getContext(), this, BluetoothProfile.A2DP); 283 284 } 285 286 public void onServiceConnected(int profile, BluetoothProfile proxy) { 287 mService = (BluetoothA2dp) proxy; 288 } 289 290 public void onServiceDisconnected(int profile) { 291 mService = null; 292 } 293 294 @Override 295 public List<BluetoothDevice> getConnectedDevices() { 296 return mService.getDevicesMatchingConnectionStates( 297 new int[] {BluetoothProfile.STATE_CONNECTED, 298 BluetoothProfile.STATE_CONNECTING, 299 BluetoothProfile.STATE_DISCONNECTING}); 300 } 301 302 @Override 303 public boolean connect(BluetoothDevice device) { 304 List<BluetoothDevice> sinks = getConnectedDevices(); 305 if (sinks != null) { 306 for (BluetoothDevice sink : sinks) { 307 mService.disconnect(sink); 308 } 309 } 310 return mService.connect(device); 311 } 312 313 @Override 314 public boolean disconnect(BluetoothDevice device) { 315 // Downgrade priority as user is disconnecting the sink. 316 if (mService.getPriority(device) > BluetoothProfile.PRIORITY_ON) { 317 mService.setPriority(device, BluetoothProfile.PRIORITY_ON); 318 } 319 return mService.disconnect(device); 320 } 321 322 @Override 323 public int getConnectionStatus(BluetoothDevice device) { 324 return convertState(mService.getConnectionState(device)); 325 } 326 327 @Override 328 public int getSummary(BluetoothDevice device) { 329 int connectionStatus = getConnectionStatus(device); 330 331 if (SettingsBtStatus.isConnectionStatusConnected(connectionStatus)) { 332 return R.string.bluetooth_a2dp_profile_summary_connected; 333 } else { 334 return SettingsBtStatus.getConnectionStatusSummary(connectionStatus); 335 } 336 } 337 338 @Override 339 public boolean isPreferred(BluetoothDevice device) { 340 return mService.getPriority(device) > BluetoothProfile.PRIORITY_OFF; 341 } 342 343 @Override 344 public int getPreferred(BluetoothDevice device) { 345 return mService.getPriority(device); 346 } 347 348 @Override 349 public void setPreferred(BluetoothDevice device, boolean preferred) { 350 if (preferred) { 351 if (mService.getPriority(device) < BluetoothProfile.PRIORITY_ON) { 352 mService.setPriority(device, BluetoothProfile.PRIORITY_ON); 353 } 354 } else { 355 mService.setPriority(device, BluetoothProfile.PRIORITY_OFF); 356 } 357 } 358 359 @Override 360 public int convertState(int a2dpState) { 361 switch (a2dpState) { 362 case BluetoothProfile.STATE_CONNECTED: 363 return SettingsBtStatus.CONNECTION_STATUS_CONNECTED; 364 case BluetoothProfile.STATE_CONNECTING: 365 return SettingsBtStatus.CONNECTION_STATUS_CONNECTING; 366 case BluetoothProfile.STATE_DISCONNECTED: 367 return SettingsBtStatus.CONNECTION_STATUS_DISCONNECTED; 368 case BluetoothProfile.STATE_DISCONNECTING: 369 return SettingsBtStatus.CONNECTION_STATUS_DISCONNECTING; 370 case BluetoothA2dp.STATE_PLAYING: 371 return SettingsBtStatus.CONNECTION_STATUS_ACTIVE; 372 default: 373 return SettingsBtStatus.CONNECTION_STATUS_UNKNOWN; 374 } 375 } 376 377 @Override 378 public boolean isProfileReady() { 379 return true; 380 } 381 382 @Override 383 public int getDrawableResource() { 384 return R.drawable.ic_bt_headphones_a2dp; 385 } 386 } 387 388 /** 389 * HeadsetProfileManager is an abstraction for the {@link BluetoothHeadset} service. 390 */ 391 private static class HeadsetProfileManager extends LocalBluetoothProfileManager 392 implements BluetoothProfile.ServiceListener { 393 private BluetoothHeadset mService; 394 private Handler mUiHandler = new Handler(); 395 private boolean profileReady = false; 396 397 // TODO(): The calls must get queued if mService becomes null. 398 // It can happen when phone app crashes for some reason. 399 // All callers should have service listeners. Dock Service is the only 400 // one right now. 401 public HeadsetProfileManager(LocalBluetoothManager localManager) { 402 super(localManager); 403 BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter(); 404 adapter.getProfileProxy(localManager.getContext(), this, BluetoothProfile.HEADSET); 405 } 406 407 public void onServiceConnected(int profile, BluetoothProfile proxy) { 408 mService = (BluetoothHeadset) proxy; 409 profileReady = true; 410 // This could be called on a non-UI thread, funnel to UI thread. 411 mUiHandler.post(new Runnable() { 412 public void run() { 413 /* 414 * We just bound to the service, so refresh the UI of the 415 * headset device. 416 */ 417 List<BluetoothDevice> deviceList = mService.getConnectedDevices(); 418 if (deviceList.size() == 0) return; 419 420 mLocalManager.getCachedDeviceManager() 421 .onProfileStateChanged(deviceList.get(0), Profile.HEADSET, 422 BluetoothProfile.STATE_CONNECTED); 423 } 424 }); 425 426 if (mServiceListeners.size() > 0) { 427 Iterator<ServiceListener> it = mServiceListeners.iterator(); 428 while(it.hasNext()) { 429 it.next().onServiceConnected(); 430 } 431 } 432 } 433 434 public void onServiceDisconnected(int profile) { 435 mService = null; 436 profileReady = false; 437 if (mServiceListeners.size() > 0) { 438 Iterator<ServiceListener> it = mServiceListeners.iterator(); 439 while(it.hasNext()) { 440 it.next().onServiceDisconnected(); 441 } 442 } 443 } 444 445 @Override 446 public boolean isProfileReady() { 447 return profileReady; 448 } 449 450 @Override 451 public List<BluetoothDevice> getConnectedDevices() { 452 return mService.getConnectedDevices(); 453 } 454 455 @Override 456 public boolean connect(BluetoothDevice device) { 457 return mService.connect(device); 458 } 459 460 @Override 461 public boolean disconnect(BluetoothDevice device) { 462 List<BluetoothDevice> deviceList = getConnectedDevices(); 463 if (deviceList.size() != 0 && deviceList.get(0).equals(device)) { 464 // Downgrade priority as user is disconnecting the headset. 465 if (mService.getPriority(device) > BluetoothProfile.PRIORITY_ON) { 466 mService.setPriority(device, BluetoothProfile.PRIORITY_ON); 467 } 468 return mService.disconnect(device); 469 } else { 470 return false; 471 } 472 } 473 474 @Override 475 public int getConnectionStatus(BluetoothDevice device) { 476 List<BluetoothDevice> deviceList = getConnectedDevices(); 477 478 return deviceList.size() > 0 && deviceList.get(0).equals(device) 479 ? convertState(mService.getConnectionState(device)) 480 : SettingsBtStatus.CONNECTION_STATUS_DISCONNECTED; 481 } 482 483 @Override 484 public int getSummary(BluetoothDevice device) { 485 int connectionStatus = getConnectionStatus(device); 486 487 if (SettingsBtStatus.isConnectionStatusConnected(connectionStatus)) { 488 return R.string.bluetooth_headset_profile_summary_connected; 489 } else { 490 return SettingsBtStatus.getConnectionStatusSummary(connectionStatus); 491 } 492 } 493 494 @Override 495 public boolean isPreferred(BluetoothDevice device) { 496 return mService.getPriority(device) > BluetoothProfile.PRIORITY_OFF; 497 } 498 499 @Override 500 public int getPreferred(BluetoothDevice device) { 501 return mService.getPriority(device); 502 } 503 504 @Override 505 public void setPreferred(BluetoothDevice device, boolean preferred) { 506 if (preferred) { 507 if (mService.getPriority(device) < BluetoothProfile.PRIORITY_ON) { 508 mService.setPriority(device, BluetoothProfile.PRIORITY_ON); 509 } 510 } else { 511 mService.setPriority(device, BluetoothProfile.PRIORITY_OFF); 512 } 513 } 514 515 @Override 516 public int convertState(int headsetState) { 517 switch (headsetState) { 518 case BluetoothProfile.STATE_CONNECTED: 519 return SettingsBtStatus.CONNECTION_STATUS_CONNECTED; 520 case BluetoothProfile.STATE_CONNECTING: 521 return SettingsBtStatus.CONNECTION_STATUS_CONNECTING; 522 case BluetoothProfile.STATE_DISCONNECTED: 523 return SettingsBtStatus.CONNECTION_STATUS_DISCONNECTED; 524 default: 525 return SettingsBtStatus.CONNECTION_STATUS_UNKNOWN; 526 } 527 } 528 529 @Override 530 public int getDrawableResource() { 531 return R.drawable.ic_bt_headset_hfp; 532 } 533 } 534 535 /** 536 * OppProfileManager 537 */ 538 private static class OppProfileManager extends LocalBluetoothProfileManager { 539 540 public OppProfileManager(LocalBluetoothManager localManager) { 541 super(localManager); 542 } 543 544 @Override 545 public List<BluetoothDevice> getConnectedDevices() { 546 return null; 547 } 548 549 @Override 550 public boolean connect(BluetoothDevice device) { 551 return false; 552 } 553 554 @Override 555 public boolean disconnect(BluetoothDevice device) { 556 return false; 557 } 558 559 @Override 560 public int getConnectionStatus(BluetoothDevice device) { 561 return -1; 562 } 563 564 @Override 565 public int getSummary(BluetoothDevice device) { 566 int connectionStatus = getConnectionStatus(device); 567 568 if (SettingsBtStatus.isConnectionStatusConnected(connectionStatus)) { 569 return R.string.bluetooth_opp_profile_summary_connected; 570 } else { 571 return R.string.bluetooth_opp_profile_summary_not_connected; 572 } 573 } 574 575 @Override 576 public boolean isPreferred(BluetoothDevice device) { 577 return false; 578 } 579 580 @Override 581 public int getPreferred(BluetoothDevice device) { 582 return -1; 583 } 584 585 @Override 586 public void setPreferred(BluetoothDevice device, boolean preferred) { 587 } 588 589 @Override 590 public boolean isProfileReady() { 591 return true; 592 } 593 594 @Override 595 public int convertState(int oppState) { 596 switch (oppState) { 597 case 0: 598 return SettingsBtStatus.CONNECTION_STATUS_CONNECTED; 599 case 1: 600 return SettingsBtStatus.CONNECTION_STATUS_CONNECTING; 601 case 2: 602 return SettingsBtStatus.CONNECTION_STATUS_DISCONNECTED; 603 default: 604 return SettingsBtStatus.CONNECTION_STATUS_UNKNOWN; 605 } 606 } 607 608 @Override 609 public int getDrawableResource() { 610 // TODO: 611 return 0; 612 } 613 } 614 615 private static class HidProfileManager extends LocalBluetoothProfileManager { 616 private BluetoothInputDevice mService; 617 618 public HidProfileManager(LocalBluetoothManager localManager) { 619 super(localManager); 620 mService = new BluetoothInputDevice(localManager.getContext()); 621 } 622 623 @Override 624 public boolean connect(BluetoothDevice device) { 625 return mService.connectInputDevice(device); 626 } 627 628 @Override 629 public int convertState(int hidState) { 630 switch (hidState) { 631 case BluetoothInputDevice.STATE_CONNECTED: 632 return SettingsBtStatus.CONNECTION_STATUS_CONNECTED; 633 case BluetoothInputDevice.STATE_CONNECTING: 634 return SettingsBtStatus.CONNECTION_STATUS_CONNECTING; 635 case BluetoothInputDevice.STATE_DISCONNECTED: 636 return SettingsBtStatus.CONNECTION_STATUS_DISCONNECTED; 637 case BluetoothInputDevice.STATE_DISCONNECTING: 638 return SettingsBtStatus.CONNECTION_STATUS_DISCONNECTING; 639 default: 640 return SettingsBtStatus.CONNECTION_STATUS_UNKNOWN; 641 } 642 } 643 644 @Override 645 public boolean disconnect(BluetoothDevice device) { 646 return mService.disconnectInputDevice(device); 647 } 648 649 @Override 650 public List<BluetoothDevice> getConnectedDevices() { 651 return mService.getConnectedInputDevices(); 652 } 653 654 @Override 655 public int getConnectionStatus(BluetoothDevice device) { 656 return convertState(mService.getInputDeviceState(device)); 657 } 658 659 @Override 660 public int getPreferred(BluetoothDevice device) { 661 return mService.getInputDevicePriority(device); 662 } 663 664 @Override 665 public int getSummary(BluetoothDevice device) { 666 final int connectionStatus = getConnectionStatus(device); 667 668 if (SettingsBtStatus.isConnectionStatusConnected(connectionStatus)) { 669 return R.string.bluetooth_hid_profile_summary_connected; 670 } else { 671 return SettingsBtStatus.getConnectionStatusSummary(connectionStatus); 672 } 673 } 674 675 @Override 676 public boolean isPreferred(BluetoothDevice device) { 677 return mService.getInputDevicePriority(device) > BluetoothInputDevice.PRIORITY_OFF; 678 } 679 680 @Override 681 public boolean isProfileReady() { 682 return true; 683 } 684 685 @Override 686 public void setPreferred(BluetoothDevice device, boolean preferred) { 687 if (preferred) { 688 if (mService.getInputDevicePriority(device) < BluetoothInputDevice.PRIORITY_ON) { 689 mService.setInputDevicePriority(device, BluetoothInputDevice.PRIORITY_ON); 690 } 691 } else { 692 mService.setInputDevicePriority(device, BluetoothInputDevice.PRIORITY_OFF); 693 } 694 } 695 696 @Override 697 public int getDrawableResource() { 698 // TODO: 699 return 0; 700 } 701 } 702 703 private static class PanProfileManager extends LocalBluetoothProfileManager { 704 private BluetoothPan mService; 705 706 public PanProfileManager(LocalBluetoothManager localManager) { 707 super(localManager); 708 mService = new BluetoothPan(localManager.getContext()); 709 } 710 711 @Override 712 public boolean connect(BluetoothDevice device) { 713 return mService.connect(device); 714 } 715 716 @Override 717 public int convertState(int panState) { 718 switch (panState) { 719 case BluetoothPan.STATE_CONNECTED: 720 return SettingsBtStatus.CONNECTION_STATUS_CONNECTED; 721 case BluetoothPan.STATE_CONNECTING: 722 return SettingsBtStatus.CONNECTION_STATUS_CONNECTING; 723 case BluetoothPan.STATE_DISCONNECTED: 724 return SettingsBtStatus.CONNECTION_STATUS_DISCONNECTED; 725 case BluetoothPan.STATE_DISCONNECTING: 726 return SettingsBtStatus.CONNECTION_STATUS_DISCONNECTING; 727 default: 728 return SettingsBtStatus.CONNECTION_STATUS_UNKNOWN; 729 } 730 } 731 732 @Override 733 public boolean disconnect(BluetoothDevice device) { 734 return mService.disconnect(device); 735 } 736 737 @Override 738 public int getSummary(BluetoothDevice device) { 739 final int connectionStatus = getConnectionStatus(device); 740 741 if (SettingsBtStatus.isConnectionStatusConnected(connectionStatus)) { 742 return R.string.bluetooth_pan_profile_summary_connected; 743 } else { 744 return SettingsBtStatus.getConnectionStatusSummary(connectionStatus); 745 } 746 } 747 748 @Override 749 public boolean isProfileReady() { 750 return true; 751 } 752 753 @Override 754 public List<BluetoothDevice> getConnectedDevices() { 755 return mService.getConnectedDevices(); 756 } 757 758 @Override 759 public int getConnectionStatus(BluetoothDevice device) { 760 return convertState(mService.getPanDeviceState(device)); 761 } 762 763 @Override 764 public int getPreferred(BluetoothDevice device) { 765 return -1; 766 } 767 768 @Override 769 public boolean isPreferred(BluetoothDevice device) { 770 return false; 771 } 772 773 @Override 774 public void setPreferred(BluetoothDevice device, boolean preferred) { 775 return; 776 } 777 778 @Override 779 public int getDrawableResource() { 780 // TODO: 781 return 0; 782 } 783 } 784} 785