LocalBluetoothProfileManager.java revision 8c04b90cc95b16f8d7e99a61d8e2c940ed83b0c4
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 // TODO: int instead of enum 257 public static enum Profile { 258 HEADSET(R.string.bluetooth_profile_headset), 259 A2DP(R.string.bluetooth_profile_a2dp), 260 OPP(R.string.bluetooth_profile_opp), 261 HID(R.string.bluetooth_profile_hid), 262 PAN(R.string.bluetooth_profile_pan); 263 264 public final int localizedString; 265 266 private Profile(int localizedString) { 267 this.localizedString = localizedString; 268 } 269 } 270 271 /** 272 * A2dpProfileManager is an abstraction for the {@link BluetoothA2dp} service. 273 */ 274 private static class A2dpProfileManager extends LocalBluetoothProfileManager 275 implements BluetoothProfile.ServiceListener { 276 private BluetoothA2dp mService; 277 278 // TODO(): The calls must wait for mService. Its not null just 279 // because it runs in the system server. 280 public A2dpProfileManager(LocalBluetoothManager localManager) { 281 super(localManager); 282 BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter(); 283 adapter.getProfileProxy(localManager.getContext(), this, BluetoothProfile.A2DP); 284 285 } 286 287 public void onServiceConnected(int profile, BluetoothProfile proxy) { 288 mService = (BluetoothA2dp) proxy; 289 } 290 291 public void onServiceDisconnected(int profile) { 292 mService = null; 293 } 294 295 @Override 296 public List<BluetoothDevice> getConnectedDevices() { 297 return mService.getDevicesMatchingConnectionStates( 298 new int[] {BluetoothProfile.STATE_CONNECTED, 299 BluetoothProfile.STATE_CONNECTING, 300 BluetoothProfile.STATE_DISCONNECTING}); 301 } 302 303 @Override 304 public boolean connect(BluetoothDevice device) { 305 List<BluetoothDevice> sinks = getConnectedDevices(); 306 if (sinks != null) { 307 for (BluetoothDevice sink : sinks) { 308 mService.disconnect(sink); 309 } 310 } 311 return mService.connect(device); 312 } 313 314 @Override 315 public boolean disconnect(BluetoothDevice device) { 316 // Downgrade priority as user is disconnecting the sink. 317 if (mService.getPriority(device) > BluetoothProfile.PRIORITY_ON) { 318 mService.setPriority(device, BluetoothProfile.PRIORITY_ON); 319 } 320 return mService.disconnect(device); 321 } 322 323 @Override 324 public int getConnectionStatus(BluetoothDevice device) { 325 return convertState(mService.getConnectionState(device)); 326 } 327 328 @Override 329 public int getSummary(BluetoothDevice device) { 330 int connectionStatus = getConnectionStatus(device); 331 332 if (SettingsBtStatus.isConnectionStatusConnected(connectionStatus)) { 333 return R.string.bluetooth_a2dp_profile_summary_connected; 334 } else { 335 return SettingsBtStatus.getConnectionStatusSummary(connectionStatus); 336 } 337 } 338 339 @Override 340 public boolean isPreferred(BluetoothDevice device) { 341 return mService.getPriority(device) > BluetoothProfile.PRIORITY_OFF; 342 } 343 344 @Override 345 public int getPreferred(BluetoothDevice device) { 346 return mService.getPriority(device); 347 } 348 349 @Override 350 public void setPreferred(BluetoothDevice device, boolean preferred) { 351 if (preferred) { 352 if (mService.getPriority(device) < BluetoothProfile.PRIORITY_ON) { 353 mService.setPriority(device, BluetoothProfile.PRIORITY_ON); 354 } 355 } else { 356 mService.setPriority(device, BluetoothProfile.PRIORITY_OFF); 357 } 358 } 359 360 @Override 361 public int convertState(int a2dpState) { 362 switch (a2dpState) { 363 case BluetoothProfile.STATE_CONNECTED: 364 return SettingsBtStatus.CONNECTION_STATUS_CONNECTED; 365 case BluetoothProfile.STATE_CONNECTING: 366 return SettingsBtStatus.CONNECTION_STATUS_CONNECTING; 367 case BluetoothProfile.STATE_DISCONNECTED: 368 return SettingsBtStatus.CONNECTION_STATUS_DISCONNECTED; 369 case BluetoothProfile.STATE_DISCONNECTING: 370 return SettingsBtStatus.CONNECTION_STATUS_DISCONNECTING; 371 case BluetoothA2dp.STATE_PLAYING: 372 return SettingsBtStatus.CONNECTION_STATUS_ACTIVE; 373 default: 374 return SettingsBtStatus.CONNECTION_STATUS_UNKNOWN; 375 } 376 } 377 378 @Override 379 public boolean isProfileReady() { 380 return true; 381 } 382 383 @Override 384 public int getDrawableResource() { 385 return R.drawable.ic_bt_headphones_a2dp; 386 } 387 } 388 389 /** 390 * HeadsetProfileManager is an abstraction for the {@link BluetoothHeadset} service. 391 */ 392 private static class HeadsetProfileManager extends LocalBluetoothProfileManager 393 implements BluetoothProfile.ServiceListener { 394 private BluetoothHeadset mService; 395 private Handler mUiHandler = new Handler(); 396 private boolean profileReady = false; 397 398 // TODO(): The calls must get queued if mService becomes null. 399 // It can happen when phone app crashes for some reason. 400 // All callers should have service listeners. Dock Service is the only 401 // one right now. 402 public HeadsetProfileManager(LocalBluetoothManager localManager) { 403 super(localManager); 404 BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter(); 405 adapter.getProfileProxy(localManager.getContext(), this, BluetoothProfile.HEADSET); 406 } 407 408 public void onServiceConnected(int profile, BluetoothProfile proxy) { 409 mService = (BluetoothHeadset) proxy; 410 profileReady = true; 411 // This could be called on a non-UI thread, funnel to UI thread. 412 mUiHandler.post(new Runnable() { 413 public void run() { 414 /* 415 * We just bound to the service, so refresh the UI of the 416 * headset device. 417 */ 418 List<BluetoothDevice> deviceList = mService.getConnectedDevices(); 419 if (deviceList.size() == 0) return; 420 421 mLocalManager.getCachedDeviceManager() 422 .onProfileStateChanged(deviceList.get(0), Profile.HEADSET, 423 BluetoothProfile.STATE_CONNECTED); 424 } 425 }); 426 427 if (mServiceListeners.size() > 0) { 428 Iterator<ServiceListener> it = mServiceListeners.iterator(); 429 while(it.hasNext()) { 430 it.next().onServiceConnected(); 431 } 432 } 433 } 434 435 public void onServiceDisconnected(int profile) { 436 mService = null; 437 profileReady = false; 438 if (mServiceListeners.size() > 0) { 439 Iterator<ServiceListener> it = mServiceListeners.iterator(); 440 while(it.hasNext()) { 441 it.next().onServiceDisconnected(); 442 } 443 } 444 } 445 446 @Override 447 public boolean isProfileReady() { 448 return profileReady; 449 } 450 451 @Override 452 public List<BluetoothDevice> getConnectedDevices() { 453 return mService.getConnectedDevices(); 454 } 455 456 @Override 457 public boolean connect(BluetoothDevice device) { 458 return mService.connect(device); 459 } 460 461 @Override 462 public boolean disconnect(BluetoothDevice device) { 463 List<BluetoothDevice> deviceList = getConnectedDevices(); 464 if (deviceList.size() != 0 && deviceList.get(0).equals(device)) { 465 // Downgrade priority as user is disconnecting the headset. 466 if (mService.getPriority(device) > BluetoothProfile.PRIORITY_ON) { 467 mService.setPriority(device, BluetoothProfile.PRIORITY_ON); 468 } 469 return mService.disconnect(device); 470 } else { 471 return false; 472 } 473 } 474 475 @Override 476 public int getConnectionStatus(BluetoothDevice device) { 477 List<BluetoothDevice> deviceList = getConnectedDevices(); 478 479 return deviceList.size() > 0 && deviceList.get(0).equals(device) 480 ? convertState(mService.getConnectionState(device)) 481 : SettingsBtStatus.CONNECTION_STATUS_DISCONNECTED; 482 } 483 484 @Override 485 public int getSummary(BluetoothDevice device) { 486 int connectionStatus = getConnectionStatus(device); 487 488 if (SettingsBtStatus.isConnectionStatusConnected(connectionStatus)) { 489 return R.string.bluetooth_headset_profile_summary_connected; 490 } else { 491 return SettingsBtStatus.getConnectionStatusSummary(connectionStatus); 492 } 493 } 494 495 @Override 496 public boolean isPreferred(BluetoothDevice device) { 497 return mService.getPriority(device) > BluetoothProfile.PRIORITY_OFF; 498 } 499 500 @Override 501 public int getPreferred(BluetoothDevice device) { 502 return mService.getPriority(device); 503 } 504 505 @Override 506 public void setPreferred(BluetoothDevice device, boolean preferred) { 507 if (preferred) { 508 if (mService.getPriority(device) < BluetoothProfile.PRIORITY_ON) { 509 mService.setPriority(device, BluetoothProfile.PRIORITY_ON); 510 } 511 } else { 512 mService.setPriority(device, BluetoothProfile.PRIORITY_OFF); 513 } 514 } 515 516 @Override 517 public int convertState(int headsetState) { 518 switch (headsetState) { 519 case BluetoothProfile.STATE_CONNECTED: 520 return SettingsBtStatus.CONNECTION_STATUS_CONNECTED; 521 case BluetoothProfile.STATE_CONNECTING: 522 return SettingsBtStatus.CONNECTION_STATUS_CONNECTING; 523 case BluetoothProfile.STATE_DISCONNECTED: 524 return SettingsBtStatus.CONNECTION_STATUS_DISCONNECTED; 525 default: 526 return SettingsBtStatus.CONNECTION_STATUS_UNKNOWN; 527 } 528 } 529 530 @Override 531 public int getDrawableResource() { 532 return R.drawable.ic_bt_headset_hfp; 533 } 534 } 535 536 /** 537 * OppProfileManager 538 */ 539 private static class OppProfileManager extends LocalBluetoothProfileManager { 540 541 public OppProfileManager(LocalBluetoothManager localManager) { 542 super(localManager); 543 } 544 545 @Override 546 public List<BluetoothDevice> getConnectedDevices() { 547 return null; 548 } 549 550 @Override 551 public boolean connect(BluetoothDevice device) { 552 return false; 553 } 554 555 @Override 556 public boolean disconnect(BluetoothDevice device) { 557 return false; 558 } 559 560 @Override 561 public int getConnectionStatus(BluetoothDevice device) { 562 return -1; 563 } 564 565 @Override 566 public int getSummary(BluetoothDevice device) { 567 int connectionStatus = getConnectionStatus(device); 568 569 if (SettingsBtStatus.isConnectionStatusConnected(connectionStatus)) { 570 return R.string.bluetooth_opp_profile_summary_connected; 571 } else { 572 return R.string.bluetooth_opp_profile_summary_not_connected; 573 } 574 } 575 576 @Override 577 public boolean isPreferred(BluetoothDevice device) { 578 return false; 579 } 580 581 @Override 582 public int getPreferred(BluetoothDevice device) { 583 return -1; 584 } 585 586 @Override 587 public void setPreferred(BluetoothDevice device, boolean preferred) { 588 } 589 590 @Override 591 public boolean isProfileReady() { 592 return true; 593 } 594 595 @Override 596 public int convertState(int oppState) { 597 switch (oppState) { 598 case 0: 599 return SettingsBtStatus.CONNECTION_STATUS_CONNECTED; 600 case 1: 601 return SettingsBtStatus.CONNECTION_STATUS_CONNECTING; 602 case 2: 603 return SettingsBtStatus.CONNECTION_STATUS_DISCONNECTED; 604 default: 605 return SettingsBtStatus.CONNECTION_STATUS_UNKNOWN; 606 } 607 } 608 609 @Override 610 public int getDrawableResource() { 611 // TODO: 612 return 0; 613 } 614 } 615 616 private static class HidProfileManager extends LocalBluetoothProfileManager { 617 private BluetoothInputDevice mService; 618 619 public HidProfileManager(LocalBluetoothManager localManager) { 620 super(localManager); 621 mService = new BluetoothInputDevice(localManager.getContext()); 622 } 623 624 @Override 625 public boolean connect(BluetoothDevice device) { 626 return mService.connectInputDevice(device); 627 } 628 629 @Override 630 public int convertState(int hidState) { 631 switch (hidState) { 632 case BluetoothInputDevice.STATE_CONNECTED: 633 return SettingsBtStatus.CONNECTION_STATUS_CONNECTED; 634 case BluetoothInputDevice.STATE_CONNECTING: 635 return SettingsBtStatus.CONNECTION_STATUS_CONNECTING; 636 case BluetoothInputDevice.STATE_DISCONNECTED: 637 return SettingsBtStatus.CONNECTION_STATUS_DISCONNECTED; 638 case BluetoothInputDevice.STATE_DISCONNECTING: 639 return SettingsBtStatus.CONNECTION_STATUS_DISCONNECTING; 640 default: 641 return SettingsBtStatus.CONNECTION_STATUS_UNKNOWN; 642 } 643 } 644 645 @Override 646 public boolean disconnect(BluetoothDevice device) { 647 return mService.disconnectInputDevice(device); 648 } 649 650 @Override 651 public List<BluetoothDevice> getConnectedDevices() { 652 return mService.getConnectedInputDevices(); 653 } 654 655 @Override 656 public int getConnectionStatus(BluetoothDevice device) { 657 return convertState(mService.getInputDeviceState(device)); 658 } 659 660 @Override 661 public int getPreferred(BluetoothDevice device) { 662 return mService.getInputDevicePriority(device); 663 } 664 665 @Override 666 public int getSummary(BluetoothDevice device) { 667 final int connectionStatus = getConnectionStatus(device); 668 669 if (SettingsBtStatus.isConnectionStatusConnected(connectionStatus)) { 670 return R.string.bluetooth_hid_profile_summary_connected; 671 } else { 672 return SettingsBtStatus.getConnectionStatusSummary(connectionStatus); 673 } 674 } 675 676 @Override 677 public boolean isPreferred(BluetoothDevice device) { 678 return mService.getInputDevicePriority(device) > BluetoothInputDevice.PRIORITY_OFF; 679 } 680 681 @Override 682 public boolean isProfileReady() { 683 return true; 684 } 685 686 @Override 687 public void setPreferred(BluetoothDevice device, boolean preferred) { 688 if (preferred) { 689 if (mService.getInputDevicePriority(device) < BluetoothInputDevice.PRIORITY_ON) { 690 mService.setInputDevicePriority(device, BluetoothInputDevice.PRIORITY_ON); 691 } 692 } else { 693 mService.setInputDevicePriority(device, BluetoothInputDevice.PRIORITY_OFF); 694 } 695 } 696 697 @Override 698 public int getDrawableResource() { 699 // TODO: 700 return 0; 701 } 702 } 703 704 private static class PanProfileManager extends LocalBluetoothProfileManager { 705 private BluetoothPan mService; 706 707 public PanProfileManager(LocalBluetoothManager localManager) { 708 super(localManager); 709 mService = new BluetoothPan(localManager.getContext()); 710 } 711 712 @Override 713 public boolean connect(BluetoothDevice device) { 714 return mService.connect(device); 715 } 716 717 @Override 718 public int convertState(int panState) { 719 switch (panState) { 720 case BluetoothPan.STATE_CONNECTED: 721 return SettingsBtStatus.CONNECTION_STATUS_CONNECTED; 722 case BluetoothPan.STATE_CONNECTING: 723 return SettingsBtStatus.CONNECTION_STATUS_CONNECTING; 724 case BluetoothPan.STATE_DISCONNECTED: 725 return SettingsBtStatus.CONNECTION_STATUS_DISCONNECTED; 726 case BluetoothPan.STATE_DISCONNECTING: 727 return SettingsBtStatus.CONNECTION_STATUS_DISCONNECTING; 728 default: 729 return SettingsBtStatus.CONNECTION_STATUS_UNKNOWN; 730 } 731 } 732 733 @Override 734 public boolean disconnect(BluetoothDevice device) { 735 return mService.disconnect(device); 736 } 737 738 @Override 739 public int getSummary(BluetoothDevice device) { 740 final int connectionStatus = getConnectionStatus(device); 741 742 if (SettingsBtStatus.isConnectionStatusConnected(connectionStatus)) { 743 return R.string.bluetooth_pan_profile_summary_connected; 744 } else { 745 return SettingsBtStatus.getConnectionStatusSummary(connectionStatus); 746 } 747 } 748 749 @Override 750 public boolean isProfileReady() { 751 return true; 752 } 753 754 @Override 755 public List<BluetoothDevice> getConnectedDevices() { 756 return mService.getConnectedDevices(); 757 } 758 759 @Override 760 public int getConnectionStatus(BluetoothDevice device) { 761 return convertState(mService.getPanDeviceState(device)); 762 } 763 764 @Override 765 public int getPreferred(BluetoothDevice device) { 766 return -1; 767 } 768 769 @Override 770 public boolean isPreferred(BluetoothDevice device) { 771 return false; 772 } 773 774 @Override 775 public void setPreferred(BluetoothDevice device, boolean preferred) { 776 return; 777 } 778 779 @Override 780 public int getDrawableResource() { 781 // TODO: 782 return 0; 783 } 784 } 785} 786