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