AdapterService.java revision 411ad52f79b7390a5831e30d3e3742c129c6bb6a
1/* 2 * Copyright (C) 2012 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/** 18 * @hide 19 */ 20 21package com.android.bluetooth.btservice; 22 23import android.app.AlarmManager; 24import android.app.Application; 25import android.app.PendingIntent; 26import android.app.Service; 27import android.bluetooth.BluetoothAdapter; 28import android.bluetooth.BluetoothDevice; 29import android.bluetooth.BluetoothProfile; 30import android.bluetooth.BluetoothUuid; 31import android.bluetooth.IBluetooth; 32import android.bluetooth.IBluetoothCallback; 33import android.bluetooth.IBluetoothManager; 34import android.bluetooth.IBluetoothManagerCallback; 35import android.content.BroadcastReceiver; 36import android.content.ContentResolver; 37import android.content.Context; 38import android.content.Intent; 39import android.content.IntentFilter; 40import android.os.Binder; 41import android.os.Bundle; 42import android.os.Handler; 43import android.os.IBinder; 44import android.os.Message; 45import android.os.ParcelFileDescriptor; 46import android.os.ParcelUuid; 47import android.os.PowerManager; 48import android.os.Process; 49import android.os.RemoteCallbackList; 50import android.os.RemoteException; 51import android.os.SystemClock; 52import android.provider.Settings; 53import android.util.Log; 54import android.util.Pair; 55import com.android.bluetooth.a2dp.A2dpService; 56import com.android.bluetooth.hid.HidService; 57import com.android.bluetooth.hfp.HeadsetService; 58import com.android.bluetooth.hdp.HealthService; 59import com.android.bluetooth.pan.PanService; 60import com.android.bluetooth.R; 61import com.android.bluetooth.Utils; 62import com.android.bluetooth.btservice.RemoteDevices.DeviceProperties; 63import java.io.FileDescriptor; 64import java.io.IOException; 65import java.util.ArrayList; 66import java.util.HashMap; 67import java.util.Set; 68import java.util.Map; 69import java.util.Iterator; 70import java.util.Map.Entry; 71import java.util.List; 72import android.content.pm.PackageManager; 73import android.os.ServiceManager; 74 75public class AdapterService extends Service { 76 private static final String TAG = "BluetoothAdapterService"; 77 private static final boolean DBG = false; 78 private static final boolean TRACE_REF = true; 79 private static final int MIN_ADVT_INSTANCES_FOR_MA = 5; 80 private static final int MIN_OFFLOADED_FILTERS = 10; 81 private static final int MIN_OFFLOADED_SCAN_STORAGE_BYTES = 2048; 82 //For Debugging only 83 private static int sRefCount=0; 84 85 public static final String ACTION_LOAD_ADAPTER_PROPERTIES = 86 "com.android.bluetooth.btservice.action.LOAD_ADAPTER_PROPERTIES"; 87 public static final String ACTION_SERVICE_STATE_CHANGED = 88 "com.android.bluetooth.btservice.action.STATE_CHANGED"; 89 public static final String EXTRA_ACTION="action"; 90 public static final int PROFILE_CONN_CONNECTED = 1; 91 public static final int PROFILE_CONN_REJECTED = 2; 92 93 private static final String ACTION_ALARM_WAKEUP = 94 "com.android.bluetooth.btservice.action.ALARM_WAKEUP"; 95 96 static final String BLUETOOTH_ADMIN_PERM = 97 android.Manifest.permission.BLUETOOTH_ADMIN; 98 static final String BLUETOOTH_PERM = android.Manifest.permission.BLUETOOTH; 99 static final String RECEIVE_MAP_PERM = android.Manifest.permission.RECEIVE_BLUETOOTH_MAP; 100 101 private static final int ADAPTER_SERVICE_TYPE=Service.START_STICKY; 102 103 static { 104 classInitNative(); 105 } 106 107 private static AdapterService sAdapterService; 108 public static synchronized AdapterService getAdapterService(){ 109 if (sAdapterService != null && !sAdapterService.mCleaningUp) { 110 Log.d(TAG, "getAdapterService() - returning " + sAdapterService); 111 return sAdapterService; 112 } 113 if (DBG) { 114 if (sAdapterService == null) { 115 Log.d(TAG, "getAdapterService() - Service not available"); 116 } else if (sAdapterService.mCleaningUp) { 117 Log.d(TAG,"getAdapterService() - Service is cleaning up"); 118 } 119 } 120 return null; 121 } 122 123 private static synchronized void setAdapterService(AdapterService instance) { 124 if (instance != null && !instance.mCleaningUp) { 125 if (DBG) Log.d(TAG, "setAdapterService() - set to: " + sAdapterService); 126 sAdapterService = instance; 127 } else { 128 if (DBG) { 129 if (sAdapterService == null) { 130 Log.d(TAG, "setAdapterService() - Service not available"); 131 } else if (sAdapterService.mCleaningUp) { 132 Log.d(TAG,"setAdapterService() - Service is cleaning up"); 133 } 134 } 135 } 136 } 137 138 private static synchronized void clearAdapterService() { 139 sAdapterService = null; 140 } 141 142 private AdapterProperties mAdapterProperties; 143 private AdapterState mAdapterStateMachine; 144 private BondStateMachine mBondStateMachine; 145 private JniCallbacks mJniCallbacks; 146 private RemoteDevices mRemoteDevices; 147 private boolean mProfilesStarted; 148 private boolean mNativeAvailable; 149 private boolean mCleaningUp; 150 private HashMap<String,Integer> mProfileServicesState = new HashMap<String,Integer>(); 151 private RemoteCallbackList<IBluetoothCallback> mCallbacks;//Only BluetoothManagerService should be registered 152 private int mCurrentRequestId; 153 private boolean mQuietmode = false; 154 155 private AlarmManager mAlarmManager; 156 private PendingIntent mPendingAlarm; 157 private PowerManager mPowerManager; 158 private PowerManager.WakeLock mWakeLock; 159 private String mWakeLockName; 160 161 public AdapterService() { 162 super(); 163 if (TRACE_REF) { 164 synchronized (AdapterService.class) { 165 sRefCount++; 166 debugLog("AdapterService() - REFCOUNT: CREATED. INSTANCE_COUNT" + sRefCount); 167 } 168 } 169 } 170 171 public void onProfileConnectionStateChanged(BluetoothDevice device, int profileId, int newState, int prevState) { 172 Message m = mHandler.obtainMessage(MESSAGE_PROFILE_CONNECTION_STATE_CHANGED); 173 m.obj = device; 174 m.arg1 = profileId; 175 m.arg2 = newState; 176 Bundle b = new Bundle(1); 177 b.putInt("prevState", prevState); 178 m.setData(b); 179 mHandler.sendMessage(m); 180 } 181 182 public void initProfilePriorities(BluetoothDevice device, ParcelUuid[] mUuids) { 183 if(mUuids == null) return; 184 Message m = mHandler.obtainMessage(MESSAGE_PROFILE_INIT_PRIORITIES); 185 m.obj = device; 186 m.arg1 = mUuids.length; 187 Bundle b = new Bundle(1); 188 for(int i=0; i<mUuids.length; i++) { 189 b.putParcelable("uuids" + i, mUuids[i]); 190 } 191 m.setData(b); 192 mHandler.sendMessage(m); 193 } 194 195 private void processInitProfilePriorities (BluetoothDevice device, ParcelUuid[] uuids){ 196 HidService hidService = HidService.getHidService(); 197 A2dpService a2dpService = A2dpService.getA2dpService(); 198 HeadsetService headsetService = HeadsetService.getHeadsetService(); 199 200 // Set profile priorities only for the profiles discovered on the remote device. 201 // This avoids needless auto-connect attempts to profiles non-existent on the remote device 202 if ((hidService != null) && 203 (BluetoothUuid.isUuidPresent(uuids, BluetoothUuid.Hid)) && 204 (hidService.getPriority(device) == BluetoothProfile.PRIORITY_UNDEFINED)){ 205 hidService.setPriority(device,BluetoothProfile.PRIORITY_ON); 206 } 207 208 if ((a2dpService != null) && 209 (BluetoothUuid.isUuidPresent(uuids, BluetoothUuid.AudioSink) || 210 (BluetoothUuid.isUuidPresent(uuids, BluetoothUuid.AdvAudioDist)) && 211 (a2dpService.getPriority(device) == BluetoothProfile.PRIORITY_UNDEFINED))){ 212 a2dpService.setPriority(device,BluetoothProfile.PRIORITY_ON); 213 } 214 215 if ((headsetService != null) && 216 ((BluetoothUuid.isUuidPresent(uuids, BluetoothUuid.HSP) || 217 BluetoothUuid.isUuidPresent(uuids, BluetoothUuid.Handsfree)) && 218 (headsetService.getPriority(device) == BluetoothProfile.PRIORITY_UNDEFINED))){ 219 headsetService.setPriority(device,BluetoothProfile.PRIORITY_ON); 220 } 221 } 222 223 private void processProfileStateChanged(BluetoothDevice device, int profileId, int newState, int prevState) { 224 if (((profileId == BluetoothProfile.A2DP) ||(profileId == BluetoothProfile.HEADSET)) && 225 (newState == BluetoothProfile.STATE_CONNECTED)){ 226 debugLog( "Profile connected. Schedule missing profile connection if any"); 227 connectOtherProfile(device, PROFILE_CONN_CONNECTED); 228 setProfileAutoConnectionPriority(device, profileId); 229 } 230 IBluetooth.Stub binder = mBinder; 231 if (binder != null) { 232 try { 233 binder.sendConnectionStateChange(device, profileId, newState,prevState); 234 } catch (RemoteException re) { 235 errorLog("" + re); 236 } 237 } 238 } 239 240 public void onProfileServiceStateChanged(String serviceName, int state) { 241 Message m = mHandler.obtainMessage(MESSAGE_PROFILE_SERVICE_STATE_CHANGED); 242 m.obj=serviceName; 243 m.arg1 = state; 244 mHandler.sendMessage(m); 245 } 246 247 private void processProfileServiceStateChanged(String serviceName, int state) { 248 boolean doUpdate=false; 249 boolean isTurningOn; 250 boolean isTurningOff; 251 252 synchronized (mProfileServicesState) { 253 Integer prevState = mProfileServicesState.get(serviceName); 254 if (prevState != null && prevState != state) { 255 mProfileServicesState.put(serviceName,state); 256 doUpdate=true; 257 } 258 } 259 debugLog("onProfileServiceStateChange() serviceName=" + serviceName 260 + ", state=" + state +", doUpdate=" + doUpdate); 261 262 if (!doUpdate) { 263 return; 264 } 265 266 synchronized (mAdapterStateMachine) { 267 isTurningOff = mAdapterStateMachine.isTurningOff(); 268 isTurningOn = mAdapterStateMachine.isTurningOn(); 269 } 270 271 if (isTurningOff) { 272 //Process stop or disable pending 273 //Check if all services are stopped if so, do cleanup 274 synchronized (mProfileServicesState) { 275 Iterator<Map.Entry<String,Integer>> i = mProfileServicesState.entrySet().iterator(); 276 while (i.hasNext()) { 277 Map.Entry<String,Integer> entry = i.next(); 278 if (BluetoothAdapter.STATE_OFF != entry.getValue()) { 279 debugLog("onProfileServiceStateChange() - Profile still running: " 280 + entry.getKey()); 281 return; 282 } 283 } 284 } 285 debugLog("onProfileServiceStateChange() - All profile services stopped..."); 286 //Send message to state machine 287 mProfilesStarted=false; 288 mAdapterStateMachine.sendMessage(mAdapterStateMachine.obtainMessage(AdapterState.STOPPED)); 289 } else if (isTurningOn) { 290 //Process start pending 291 //Check if all services are started if so, update state 292 synchronized (mProfileServicesState) { 293 Iterator<Map.Entry<String,Integer>> i = mProfileServicesState.entrySet().iterator(); 294 while (i.hasNext()) { 295 Map.Entry<String,Integer> entry = i.next(); 296 if (BluetoothAdapter.STATE_ON != entry.getValue()) { 297 debugLog("onProfileServiceStateChange() - Profile still not running:" 298 + entry.getKey()); 299 return; 300 } 301 } 302 } 303 debugLog("onProfileServiceStateChange() - All profile services started."); 304 mProfilesStarted=true; 305 //Send message to state machine 306 mAdapterStateMachine.sendMessage(mAdapterStateMachine.obtainMessage(AdapterState.STARTED)); 307 } 308 } 309 310 @Override 311 public void onCreate() { 312 super.onCreate(); 313 debugLog("onCreate()"); 314 mBinder = new AdapterServiceBinder(this); 315 mAdapterProperties = new AdapterProperties(this); 316 mAdapterStateMachine = AdapterState.make(this, mAdapterProperties); 317 mJniCallbacks = new JniCallbacks(mAdapterStateMachine, mAdapterProperties); 318 initNative(); 319 mNativeAvailable=true; 320 mCallbacks = new RemoteCallbackList<IBluetoothCallback>(); 321 //Load the name and address 322 getAdapterPropertyNative(AbstractionLayer.BT_PROPERTY_BDADDR); 323 getAdapterPropertyNative(AbstractionLayer.BT_PROPERTY_BDNAME); 324 mAlarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE); 325 mPowerManager = (PowerManager) getSystemService(Context.POWER_SERVICE); 326 327 registerReceiver(mAlarmBroadcastReceiver, new IntentFilter(ACTION_ALARM_WAKEUP)); 328 } 329 330 @Override 331 public IBinder onBind(Intent intent) { 332 debugLog("onBind()"); 333 return mBinder; 334 } 335 public boolean onUnbind(Intent intent) { 336 debugLog("onUnbind() - calling cleanup"); 337 cleanup(); 338 return super.onUnbind(intent); 339 } 340 341 public void onDestroy() { 342 debugLog("onDestroy()"); 343 } 344 345 void processStart() { 346 debugLog("processStart()"); 347 Class[] supportedProfileServices = Config.getSupportedProfiles(); 348 //Initialize data objects 349 for (int i=0; i < supportedProfileServices.length;i++) { 350 mProfileServicesState.put(supportedProfileServices[i].getName(),BluetoothAdapter.STATE_OFF); 351 } 352 mRemoteDevices = new RemoteDevices(this); 353 mAdapterProperties.init(mRemoteDevices); 354 355 debugLog("processStart() - Make Bond State Machine"); 356 mBondStateMachine = BondStateMachine.make(this, mAdapterProperties, mRemoteDevices); 357 358 mJniCallbacks.init(mBondStateMachine,mRemoteDevices); 359 360 //FIXME: Set static instance here??? 361 setAdapterService(this); 362 363 //Start profile services 364 if (!mProfilesStarted && supportedProfileServices.length >0) { 365 //Startup all profile services 366 setProfileServiceState(supportedProfileServices,BluetoothAdapter.STATE_ON); 367 }else { 368 debugLog("processStart() - Profile Services alreay started"); 369 mAdapterStateMachine.sendMessage(mAdapterStateMachine.obtainMessage(AdapterState.STARTED)); 370 } 371 } 372 373 void startBluetoothDisable() { 374 mAdapterStateMachine.sendMessage(mAdapterStateMachine.obtainMessage(AdapterState.BEGIN_DISABLE)); 375 } 376 377 boolean stopProfileServices() { 378 Class[] supportedProfileServices = Config.getSupportedProfiles(); 379 if (mProfilesStarted && supportedProfileServices.length>0) { 380 setProfileServiceState(supportedProfileServices,BluetoothAdapter.STATE_OFF); 381 return true; 382 } 383 debugLog("stopProfileServices() - No profiles services to stop or already stopped."); 384 return false; 385 } 386 387 void updateAdapterState(int prevState, int newState){ 388 if (mCallbacks !=null) { 389 int n=mCallbacks.beginBroadcast(); 390 debugLog("updateAdapterState() - Broadcasting state to " + n + " receivers."); 391 for (int i=0; i <n;i++) { 392 try { 393 mCallbacks.getBroadcastItem(i).onBluetoothStateChange(prevState,newState); 394 } catch (RemoteException e) { 395 debugLog("updateAdapterState() - Callback #" + i + " failed (" + e + ")"); 396 } 397 } 398 mCallbacks.finishBroadcast(); 399 } 400 } 401 402 void cleanup () { 403 debugLog("cleanup()"); 404 if (mCleaningUp) { 405 errorLog("cleanup() - Service already starting to cleanup, ignoring request..."); 406 return; 407 } 408 409 mCleaningUp = true; 410 411 unregisterReceiver(mAlarmBroadcastReceiver); 412 413 if (mPendingAlarm != null) { 414 mAlarmManager.cancel(mPendingAlarm); 415 mPendingAlarm = null; 416 } 417 418 // This wake lock release may also be called concurrently by 419 // {@link #releaseWakeLock(String lockName)}, so a synchronization is needed here. 420 synchronized (this) { 421 if (mWakeLock != null) { 422 mWakeLock.release(); 423 mWakeLock = null; 424 } 425 } 426 427 if (mAdapterStateMachine != null) { 428 mAdapterStateMachine.doQuit(); 429 mAdapterStateMachine.cleanup(); 430 } 431 432 if (mBondStateMachine != null) { 433 mBondStateMachine.doQuit(); 434 mBondStateMachine.cleanup(); 435 } 436 437 if (mRemoteDevices != null) { 438 mRemoteDevices.cleanup(); 439 } 440 441 if (mNativeAvailable) { 442 debugLog("cleanup() - Cleaning up adapter native"); 443 cleanupNative(); 444 mNativeAvailable=false; 445 } 446 447 if (mAdapterProperties != null) { 448 mAdapterProperties.cleanup(); 449 } 450 451 if (mJniCallbacks != null) { 452 mJniCallbacks.cleanup(); 453 } 454 455 if (mProfileServicesState != null) { 456 mProfileServicesState.clear(); 457 } 458 459 clearAdapterService(); 460 461 if (mBinder != null) { 462 mBinder.cleanup(); 463 mBinder = null; //Do not remove. Otherwise Binder leak! 464 } 465 466 if (mCallbacks !=null) { 467 mCallbacks.kill(); 468 } 469 470 debugLog("cleanup() - Bluetooth process exited normally."); 471 System.exit(0); 472 } 473 474 private static final int MESSAGE_PROFILE_SERVICE_STATE_CHANGED =1; 475 private static final int MESSAGE_PROFILE_CONNECTION_STATE_CHANGED=20; 476 private static final int MESSAGE_CONNECT_OTHER_PROFILES = 30; 477 private static final int MESSAGE_PROFILE_INIT_PRIORITIES=40; 478 private static final int CONNECT_OTHER_PROFILES_TIMEOUT= 6000; 479 480 private final Handler mHandler = new Handler() { 481 @Override 482 public void handleMessage(Message msg) { 483 debugLog("handleMessage() - Message: " + msg.what); 484 485 switch (msg.what) { 486 case MESSAGE_PROFILE_SERVICE_STATE_CHANGED: { 487 debugLog("handleMessage() - MESSAGE_PROFILE_SERVICE_STATE_CHANGED"); 488 processProfileServiceStateChanged((String) msg.obj, msg.arg1); 489 } 490 break; 491 case MESSAGE_PROFILE_CONNECTION_STATE_CHANGED: { 492 debugLog( "handleMessage() - MESSAGE_PROFILE_CONNECTION_STATE_CHANGED"); 493 processProfileStateChanged((BluetoothDevice) msg.obj, msg.arg1,msg.arg2, msg.getData().getInt("prevState",BluetoothAdapter.ERROR)); 494 } 495 break; 496 case MESSAGE_PROFILE_INIT_PRIORITIES: { 497 debugLog( "handleMessage() - MESSAGE_PROFILE_INIT_PRIORITIES"); 498 ParcelUuid[] mUuids = new ParcelUuid[msg.arg1]; 499 for(int i=0; i<mUuids.length; i++) { 500 mUuids[i] = msg.getData().getParcelable("uuids" + i); 501 } 502 processInitProfilePriorities((BluetoothDevice) msg.obj, 503 mUuids); 504 } 505 break; 506 case MESSAGE_CONNECT_OTHER_PROFILES: { 507 debugLog( "handleMessage() - MESSAGE_CONNECT_OTHER_PROFILES"); 508 processConnectOtherProfiles((BluetoothDevice) msg.obj,msg.arg1); 509 } 510 break; 511 } 512 } 513 }; 514 515 @SuppressWarnings("rawtypes") 516 private void setProfileServiceState(Class[] services, int state) { 517 if (state != BluetoothAdapter.STATE_ON && state != BluetoothAdapter.STATE_OFF) { 518 debugLog("setProfileServiceState() - Invalid state, leaving..."); 519 return; 520 } 521 522 int expectedCurrentState= BluetoothAdapter.STATE_OFF; 523 int pendingState = BluetoothAdapter.STATE_TURNING_ON; 524 if (state == BluetoothAdapter.STATE_OFF) { 525 expectedCurrentState= BluetoothAdapter.STATE_ON; 526 pendingState = BluetoothAdapter.STATE_TURNING_OFF; 527 } 528 529 for (int i=0; i <services.length;i++) { 530 String serviceName = services[i].getName(); 531 Integer serviceState = mProfileServicesState.get(serviceName); 532 if(serviceState != null && serviceState != expectedCurrentState) { 533 debugLog("setProfileServiceState() - Unable to " 534 + (state == BluetoothAdapter.STATE_OFF ? "start" : "stop" ) 535 + " service " + serviceName 536 + ". Invalid state: " + serviceState); 537 continue; 538 } 539 540 debugLog("setProfileServiceState() - " 541 + (state == BluetoothAdapter.STATE_OFF ? "Stopping" : "Starting") 542 + " service " + serviceName); 543 544 mProfileServicesState.put(serviceName,pendingState); 545 Intent intent = new Intent(this,services[i]); 546 intent.putExtra(EXTRA_ACTION,ACTION_SERVICE_STATE_CHANGED); 547 intent.putExtra(BluetoothAdapter.EXTRA_STATE,state); 548 startService(intent); 549 } 550 } 551 552 private boolean isAvailable() { 553 return !mCleaningUp; 554 } 555 556 /** 557 * Handlers for incoming service calls 558 */ 559 private AdapterServiceBinder mBinder; 560 561 /** 562 * The Binder implementation must be declared to be a static class, with 563 * the AdapterService instance passed in the constructor. Furthermore, 564 * when the AdapterService shuts down, the reference to the AdapterService 565 * must be explicitly removed. 566 * 567 * Otherwise, a memory leak can occur from repeated starting/stopping the 568 * service...Please refer to android.os.Binder for further details on 569 * why an inner instance class should be avoided. 570 * 571 */ 572 private static class AdapterServiceBinder extends IBluetooth.Stub { 573 private AdapterService mService; 574 575 public AdapterServiceBinder(AdapterService svc) { 576 mService = svc; 577 } 578 public boolean cleanup() { 579 mService = null; 580 return true; 581 } 582 583 public AdapterService getService() { 584 if (mService != null && mService.isAvailable()) { 585 return mService; 586 } 587 return null; 588 } 589 public boolean isEnabled() { 590 // don't check caller, may be called from system UI 591 AdapterService service = getService(); 592 if (service == null) return false; 593 return service.isEnabled(); 594 } 595 596 public int getState() { 597 // don't check caller, may be called from system UI 598 AdapterService service = getService(); 599 if (service == null) return BluetoothAdapter.STATE_OFF; 600 return service.getState(); 601 } 602 603 public boolean enable() { 604 if ((Binder.getCallingUid() != Process.SYSTEM_UID) && 605 (!Utils.checkCaller())) { 606 Log.w(TAG, "enable() - Not allowed for non-active user and non system user"); 607 return false; 608 } 609 610 AdapterService service = getService(); 611 if (service == null) return false; 612 return service.enable(); 613 } 614 615 public boolean enableNoAutoConnect() { 616 if ((Binder.getCallingUid() != Process.SYSTEM_UID) && 617 (!Utils.checkCaller())) { 618 Log.w(TAG, "enableNoAuto() - Not allowed for non-active user and non system user"); 619 return false; 620 } 621 622 AdapterService service = getService(); 623 if (service == null) return false; 624 return service.enableNoAutoConnect(); 625 } 626 627 public boolean disable() { 628 if ((Binder.getCallingUid() != Process.SYSTEM_UID) && 629 (!Utils.checkCaller())) { 630 Log.w(TAG, "disable() - Not allowed for non-active user and non system user"); 631 return false; 632 } 633 634 AdapterService service = getService(); 635 if (service == null) return false; 636 return service.disable(); 637 } 638 639 public String getAddress() { 640 if ((Binder.getCallingUid() != Process.SYSTEM_UID) && 641 (!Utils.checkCaller())) { 642 Log.w(TAG, "getAddress() - Not allowed for non-active user and non system user"); 643 return null; 644 } 645 646 AdapterService service = getService(); 647 if (service == null) return null; 648 return service.getAddress(); 649 } 650 651 public ParcelUuid[] getUuids() { 652 if (!Utils.checkCaller()) { 653 Log.w(TAG, "getUuids() - Not allowed for non-active user"); 654 return new ParcelUuid[0]; 655 } 656 657 AdapterService service = getService(); 658 if (service == null) return new ParcelUuid[0]; 659 return service.getUuids(); 660 } 661 662 public String getName() { 663 if ((Binder.getCallingUid() != Process.SYSTEM_UID) && 664 (!Utils.checkCaller())) { 665 Log.w(TAG, "getName() - Not allowed for non-active user and non system user"); 666 return null; 667 } 668 669 AdapterService service = getService(); 670 if (service == null) return null; 671 return service.getName(); 672 } 673 674 public boolean setName(String name) { 675 if (!Utils.checkCaller()) { 676 Log.w(TAG, "setName() - Not allowed for non-active user"); 677 return false; 678 } 679 680 AdapterService service = getService(); 681 if (service == null) return false; 682 return service.setName(name); 683 } 684 685 public int getScanMode() { 686 if (!Utils.checkCaller()) { 687 Log.w(TAG, "getScanMode() - Not allowed for non-active user"); 688 return BluetoothAdapter.SCAN_MODE_NONE; 689 } 690 691 AdapterService service = getService(); 692 if (service == null) return BluetoothAdapter.SCAN_MODE_NONE; 693 return service.getScanMode(); 694 } 695 696 public boolean setScanMode(int mode, int duration) { 697 if (!Utils.checkCaller()) { 698 Log.w(TAG, "setScanMode() - Not allowed for non-active user"); 699 return false; 700 } 701 702 AdapterService service = getService(); 703 if (service == null) return false; 704 return service.setScanMode(mode,duration); 705 } 706 707 public int getDiscoverableTimeout() { 708 if (!Utils.checkCaller()) { 709 Log.w(TAG, "getDiscoverableTimeout() - Not allowed for non-active user"); 710 return 0; 711 } 712 713 AdapterService service = getService(); 714 if (service == null) return 0; 715 return service.getDiscoverableTimeout(); 716 } 717 718 public boolean setDiscoverableTimeout(int timeout) { 719 if (!Utils.checkCaller()) { 720 Log.w(TAG, "setDiscoverableTimeout() - Not allowed for non-active user"); 721 return false; 722 } 723 724 AdapterService service = getService(); 725 if (service == null) return false; 726 return service.setDiscoverableTimeout(timeout); 727 } 728 729 public boolean startDiscovery() { 730 if (!Utils.checkCaller()) { 731 Log.w(TAG, "startDiscovery() - Not allowed for non-active user"); 732 return false; 733 } 734 735 AdapterService service = getService(); 736 if (service == null) return false; 737 return service.startDiscovery(); 738 } 739 740 public boolean cancelDiscovery() { 741 if (!Utils.checkCaller()) { 742 Log.w(TAG, "cancelDiscovery() - Not allowed for non-active user"); 743 return false; 744 } 745 746 AdapterService service = getService(); 747 if (service == null) return false; 748 return service.cancelDiscovery(); 749 } 750 public boolean isDiscovering() { 751 if (!Utils.checkCaller()) { 752 Log.w(TAG, "isDiscovering() - Not allowed for non-active user"); 753 return false; 754 } 755 756 AdapterService service = getService(); 757 if (service == null) return false; 758 return service.isDiscovering(); 759 } 760 761 public BluetoothDevice[] getBondedDevices() { 762 // don't check caller, may be called from system UI 763 AdapterService service = getService(); 764 if (service == null) return new BluetoothDevice[0]; 765 return service.getBondedDevices(); 766 } 767 768 public int getAdapterConnectionState() { 769 // don't check caller, may be called from system UI 770 AdapterService service = getService(); 771 if (service == null) return BluetoothAdapter.STATE_DISCONNECTED; 772 return service.getAdapterConnectionState(); 773 } 774 775 public int getProfileConnectionState(int profile) { 776 if (!Utils.checkCaller()) { 777 Log.w(TAG, "getProfileConnectionState- Not allowed for non-active user"); 778 return BluetoothProfile.STATE_DISCONNECTED; 779 } 780 781 AdapterService service = getService(); 782 if (service == null) return BluetoothProfile.STATE_DISCONNECTED; 783 return service.getProfileConnectionState(profile); 784 } 785 786 public boolean createBond(BluetoothDevice device) { 787 if (!Utils.checkCaller()) { 788 Log.w(TAG, "createBond() - Not allowed for non-active user"); 789 return false; 790 } 791 792 AdapterService service = getService(); 793 if (service == null) return false; 794 return service.createBond(device); 795 } 796 797 public boolean cancelBondProcess(BluetoothDevice device) { 798 if (!Utils.checkCaller()) { 799 Log.w(TAG, "cancelBondProcess() - Not allowed for non-active user"); 800 return false; 801 } 802 803 AdapterService service = getService(); 804 if (service == null) return false; 805 return service.cancelBondProcess(device); 806 } 807 808 public boolean removeBond(BluetoothDevice device) { 809 if (!Utils.checkCaller()) { 810 Log.w(TAG, "removeBond() - Not allowed for non-active user"); 811 return false; 812 } 813 814 AdapterService service = getService(); 815 if (service == null) return false; 816 return service.removeBond(device); 817 } 818 819 public int getBondState(BluetoothDevice device) { 820 // don't check caller, may be called from system UI 821 AdapterService service = getService(); 822 if (service == null) return BluetoothDevice.BOND_NONE; 823 return service.getBondState(device); 824 } 825 826 public boolean isConnected(BluetoothDevice device) { 827 AdapterService service = getService(); 828 if (service == null) { 829 return false; 830 } 831 return service.isConnected(device); 832 } 833 834 public String getRemoteName(BluetoothDevice device) { 835 if (!Utils.checkCaller()) { 836 Log.w(TAG, "getRemoteName() - Not allowed for non-active user"); 837 return null; 838 } 839 840 AdapterService service = getService(); 841 if (service == null) return null; 842 return service.getRemoteName(device); 843 } 844 845 public int getRemoteType(BluetoothDevice device) { 846 if (!Utils.checkCaller()) { 847 Log.w(TAG, "getRemoteType() - Not allowed for non-active user"); 848 return BluetoothDevice.DEVICE_TYPE_UNKNOWN; 849 } 850 851 AdapterService service = getService(); 852 if (service == null) return BluetoothDevice.DEVICE_TYPE_UNKNOWN; 853 return service.getRemoteType(device); 854 } 855 856 public String getRemoteAlias(BluetoothDevice device) { 857 if (!Utils.checkCaller()) { 858 Log.w(TAG, "getRemoteAlias() - Not allowed for non-active user"); 859 return null; 860 } 861 862 AdapterService service = getService(); 863 if (service == null) return null; 864 return service.getRemoteAlias(device); 865 } 866 867 public boolean setRemoteAlias(BluetoothDevice device, String name) { 868 if (!Utils.checkCaller()) { 869 Log.w(TAG, "setRemoteAlias() - Not allowed for non-active user"); 870 return false; 871 } 872 873 AdapterService service = getService(); 874 if (service == null) return false; 875 return service.setRemoteAlias(device, name); 876 } 877 878 public int getRemoteClass(BluetoothDevice device) { 879 if (!Utils.checkCaller()) { 880 Log.w(TAG, "getRemoteClass() - Not allowed for non-active user"); 881 return 0; 882 } 883 884 AdapterService service = getService(); 885 if (service == null) return 0; 886 return service.getRemoteClass(device); 887 } 888 889 public ParcelUuid[] getRemoteUuids(BluetoothDevice device) { 890 if (!Utils.checkCaller()) { 891 Log.w(TAG, "getRemoteUuids() - Not allowed for non-active user"); 892 return new ParcelUuid[0]; 893 } 894 895 AdapterService service = getService(); 896 if (service == null) return new ParcelUuid[0]; 897 return service.getRemoteUuids(device); 898 } 899 900 public boolean fetchRemoteUuids(BluetoothDevice device) { 901 if (!Utils.checkCaller()) { 902 Log.w(TAG, "fetchRemoteUuids() - Not allowed for non-active user"); 903 return false; 904 } 905 906 AdapterService service = getService(); 907 if (service == null) return false; 908 return service.fetchRemoteUuids(device); 909 } 910 911 public boolean fetchRemoteMasInstances(BluetoothDevice device) { 912 if (!Utils.checkCaller()) { 913 Log.w(TAG,"fetchMasInstances(): not allowed for non-active user"); 914 return false; 915 } 916 917 AdapterService service = getService(); 918 if (service == null) return false; 919 return service.fetchRemoteMasInstances(device); 920 } 921 922 public boolean setPin(BluetoothDevice device, boolean accept, int len, byte[] pinCode) { 923 if (!Utils.checkCaller()) { 924 Log.w(TAG, "setPin() - Not allowed for non-active user"); 925 return false; 926 } 927 928 AdapterService service = getService(); 929 if (service == null) return false; 930 return service.setPin(device, accept, len, pinCode); 931 } 932 933 public boolean setPasskey(BluetoothDevice device, boolean accept, int len, byte[] passkey) { 934 if (!Utils.checkCaller()) { 935 Log.w(TAG, "setPasskey() - Not allowed for non-active user"); 936 return false; 937 } 938 939 AdapterService service = getService(); 940 if (service == null) return false; 941 return service.setPasskey(device, accept, len, passkey); 942 } 943 944 public boolean setPairingConfirmation(BluetoothDevice device, boolean accept) { 945 if (!Utils.checkCaller()) { 946 Log.w(TAG, "setPairingConfirmation() - Not allowed for non-active user"); 947 return false; 948 } 949 950 AdapterService service = getService(); 951 if (service == null) return false; 952 return service.setPairingConfirmation(device, accept); 953 } 954 955 public void sendConnectionStateChange(BluetoothDevice 956 device, int profile, int state, int prevState) { 957 AdapterService service = getService(); 958 if (service == null) return; 959 service.sendConnectionStateChange(device, profile, state, prevState); 960 } 961 962 public ParcelFileDescriptor connectSocket(BluetoothDevice device, int type, 963 ParcelUuid uuid, int port, int flag) { 964 if (!Utils.checkCaller()) { 965 Log.w(TAG, "connectSocket() - Not allowed for non-active user"); 966 return null; 967 } 968 969 AdapterService service = getService(); 970 if (service == null) return null; 971 return service.connectSocket(device, type, uuid, port, flag); 972 } 973 974 public ParcelFileDescriptor createSocketChannel(int type, String serviceName, 975 ParcelUuid uuid, int port, int flag) { 976 if (!Utils.checkCaller()) { 977 Log.w(TAG, "createSocketChannel() - Not allowed for non-active user"); 978 return null; 979 } 980 981 AdapterService service = getService(); 982 if (service == null) return null; 983 return service.createSocketChannel(type, serviceName, uuid, port, flag); 984 } 985 986 public boolean configHciSnoopLog(boolean enable) { 987 if ((Binder.getCallingUid() != Process.SYSTEM_UID) && 988 (!Utils.checkCaller())) { 989 Log.w(TAG, "configHciSnoopLog() - Not allowed for non-active user"); 990 return false; 991 } 992 993 AdapterService service = getService(); 994 if (service == null) return false; 995 return service.configHciSnoopLog(enable); 996 } 997 998 public void registerCallback(IBluetoothCallback cb) { 999 AdapterService service = getService(); 1000 if (service == null) return ; 1001 service.registerCallback(cb); 1002 } 1003 1004 public void unregisterCallback(IBluetoothCallback cb) { 1005 AdapterService service = getService(); 1006 if (service == null) return ; 1007 service.unregisterCallback(cb); 1008 } 1009 1010 public boolean isMultiAdvertisementSupported() { 1011 AdapterService service = getService(); 1012 if (service == null) return false; 1013 int val = service.getNumOfAdvertisementInstancesSupported(); 1014 return (val >= MIN_ADVT_INSTANCES_FOR_MA); 1015 } 1016 1017 public boolean isOffloadedFilteringSupported() { 1018 AdapterService service = getService(); 1019 if (service == null) return false; 1020 int val = service.getNumOfOffloadedScanFilterSupported(); 1021 return (val >= MIN_OFFLOADED_FILTERS); 1022 } 1023 1024 public boolean isOffloadedScanBatchingSupported() { 1025 AdapterService service = getService(); 1026 if (service == null) return false; 1027 int val = service.getOffloadedScanResultStorage(); 1028 return (val >= MIN_OFFLOADED_SCAN_STORAGE_BYTES); 1029 } 1030 }; 1031 1032 1033 //----API Methods-------- 1034 boolean isEnabled() { 1035 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1036 1037 return mAdapterProperties.getState() == BluetoothAdapter.STATE_ON; 1038 } 1039 1040 int getState() { 1041 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1042 1043 if (mAdapterProperties == null){ 1044 return BluetoothAdapter.STATE_OFF; 1045 } 1046 else { 1047 debugLog("getState() - mAdapterProperties: " + mAdapterProperties); 1048 return mAdapterProperties.getState(); 1049 } 1050 } 1051 1052 boolean enable() { 1053 return enable (false); 1054 } 1055 1056 public boolean enableNoAutoConnect() { 1057 return enable (true); 1058 } 1059 1060 public synchronized boolean enable(boolean quietMode) { 1061 enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, 1062 "Need BLUETOOTH ADMIN permission"); 1063 debugLog("enable() - Enable called with quiet mode status = " + mQuietmode); 1064 mQuietmode = quietMode; 1065 Message m = 1066 mAdapterStateMachine.obtainMessage(AdapterState.USER_TURN_ON); 1067 mAdapterStateMachine.sendMessage(m); 1068 return true; 1069 } 1070 1071 boolean disable() { 1072 enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, 1073 "Need BLUETOOTH ADMIN permission"); 1074 1075 debugLog("disable() called..."); 1076 Message m = 1077 mAdapterStateMachine.obtainMessage(AdapterState.USER_TURN_OFF); 1078 mAdapterStateMachine.sendMessage(m); 1079 return true; 1080 } 1081 1082 String getAddress() { 1083 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1084 1085 String addrString = null; 1086 byte[] address = mAdapterProperties.getAddress(); 1087 return Utils.getAddressStringFromByte(address); 1088 } 1089 1090 ParcelUuid[] getUuids() { 1091 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1092 1093 return mAdapterProperties.getUuids(); 1094 } 1095 1096 String getName() { 1097 enforceCallingOrSelfPermission(BLUETOOTH_PERM, 1098 "Need BLUETOOTH permission"); 1099 1100 try { 1101 return mAdapterProperties.getName(); 1102 } catch (Throwable t) { 1103 debugLog("getName() - Unexpected exception (" + t + ")"); 1104 } 1105 return null; 1106 } 1107 1108 boolean setName(String name) { 1109 enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, 1110 "Need BLUETOOTH ADMIN permission"); 1111 1112 return mAdapterProperties.setName(name); 1113 } 1114 1115 int getScanMode() { 1116 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1117 1118 return mAdapterProperties.getScanMode(); 1119 } 1120 1121 boolean setScanMode(int mode, int duration) { 1122 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1123 1124 setDiscoverableTimeout(duration); 1125 1126 int newMode = convertScanModeToHal(mode); 1127 return mAdapterProperties.setScanMode(newMode); 1128 } 1129 1130 int getDiscoverableTimeout() { 1131 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1132 1133 return mAdapterProperties.getDiscoverableTimeout(); 1134 } 1135 1136 boolean setDiscoverableTimeout(int timeout) { 1137 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1138 1139 return mAdapterProperties.setDiscoverableTimeout(timeout); 1140 } 1141 1142 boolean startDiscovery() { 1143 enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, 1144 "Need BLUETOOTH ADMIN permission"); 1145 1146 return startDiscoveryNative(); 1147 } 1148 1149 boolean cancelDiscovery() { 1150 enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, 1151 "Need BLUETOOTH ADMIN permission"); 1152 1153 return cancelDiscoveryNative(); 1154 } 1155 1156 boolean isDiscovering() { 1157 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1158 1159 return mAdapterProperties.isDiscovering(); 1160 } 1161 1162 BluetoothDevice[] getBondedDevices() { 1163 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1164 return mAdapterProperties.getBondedDevices(); 1165 } 1166 1167 int getAdapterConnectionState() { 1168 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1169 return mAdapterProperties.getConnectionState(); 1170 } 1171 1172 int getProfileConnectionState(int profile) { 1173 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1174 1175 return mAdapterProperties.getProfileConnectionState(profile); 1176 } 1177 1178 boolean createBond(BluetoothDevice device) { 1179 enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, 1180 "Need BLUETOOTH ADMIN permission"); 1181 DeviceProperties deviceProp = mRemoteDevices.getDeviceProperties(device); 1182 if (deviceProp != null && deviceProp.getBondState() != BluetoothDevice.BOND_NONE) { 1183 return false; 1184 } 1185 1186 // Pairing is unreliable while scanning, so cancel discovery 1187 // Note, remove this when native stack improves 1188 cancelDiscoveryNative(); 1189 1190 Message msg = mBondStateMachine.obtainMessage(BondStateMachine.CREATE_BOND); 1191 msg.obj = device; 1192 mBondStateMachine.sendMessage(msg); 1193 return true; 1194 } 1195 1196 public boolean isQuietModeEnabled() { 1197 debugLog("isQuetModeEnabled() - Enabled = " + mQuietmode); 1198 return mQuietmode; 1199 } 1200 1201 public void autoConnect(){ 1202 if (getState() != BluetoothAdapter.STATE_ON){ 1203 errorLog("autoConnect() - BT is not ON. Exiting autoConnect"); 1204 return; 1205 } 1206 if (isQuietModeEnabled() == false) { 1207 debugLog( "autoConnect() - Initiate auto connection on BT on..."); 1208 autoConnectHeadset(); 1209 autoConnectA2dp(); 1210 } 1211 else { 1212 debugLog( "autoConnect() - BT is in quiet mode. Not initiating auto connections"); 1213 } 1214 } 1215 1216 private void autoConnectHeadset(){ 1217 HeadsetService hsService = HeadsetService.getHeadsetService(); 1218 1219 BluetoothDevice bondedDevices[] = getBondedDevices(); 1220 if ((bondedDevices == null) ||(hsService == null)) { 1221 return; 1222 } 1223 for (BluetoothDevice device : bondedDevices) { 1224 if (hsService.getPriority(device) == BluetoothProfile.PRIORITY_AUTO_CONNECT ){ 1225 debugLog("autoConnectHeadset() - Connecting HFP with " + device.toString()); 1226 hsService.connect(device); 1227 } 1228 } 1229 } 1230 1231 private void autoConnectA2dp(){ 1232 A2dpService a2dpSservice = A2dpService.getA2dpService(); 1233 BluetoothDevice bondedDevices[] = getBondedDevices(); 1234 if ((bondedDevices == null) ||(a2dpSservice == null)) { 1235 return; 1236 } 1237 for (BluetoothDevice device : bondedDevices) { 1238 if (a2dpSservice.getPriority(device) == BluetoothProfile.PRIORITY_AUTO_CONNECT ){ 1239 debugLog("autoConnectA2dp() - Connecting A2DP with " + device.toString()); 1240 a2dpSservice.connect(device); 1241 } 1242 } 1243 } 1244 1245 public void connectOtherProfile(BluetoothDevice device, int firstProfileStatus){ 1246 if ((mHandler.hasMessages(MESSAGE_CONNECT_OTHER_PROFILES) == false) && 1247 (isQuietModeEnabled()== false)){ 1248 Message m = mHandler.obtainMessage(MESSAGE_CONNECT_OTHER_PROFILES); 1249 m.obj = device; 1250 m.arg1 = (int)firstProfileStatus; 1251 mHandler.sendMessageDelayed(m,CONNECT_OTHER_PROFILES_TIMEOUT); 1252 } 1253 } 1254 1255 private void processConnectOtherProfiles (BluetoothDevice device, int firstProfileStatus){ 1256 if (getState()!= BluetoothAdapter.STATE_ON){ 1257 return; 1258 } 1259 HeadsetService hsService = HeadsetService.getHeadsetService(); 1260 A2dpService a2dpService = A2dpService.getA2dpService(); 1261 1262 // if any of the profile service is null, second profile connection not required 1263 if ((hsService == null) ||(a2dpService == null )){ 1264 return; 1265 } 1266 List<BluetoothDevice> a2dpConnDevList= a2dpService.getConnectedDevices(); 1267 List<BluetoothDevice> hfConnDevList= hsService.getConnectedDevices(); 1268 // Check if the device is in disconnected state and if so return 1269 // We ned to connect other profile only if one of the profile is still in connected state 1270 // This is required to avoide a race condition in which profiles would 1271 // automaticlly connect if the disconnection is initiated within 6 seconds of connection 1272 //First profile connection being rejected is an exception 1273 if((hfConnDevList.isEmpty() && a2dpConnDevList.isEmpty())&& 1274 (PROFILE_CONN_CONNECTED == firstProfileStatus)){ 1275 return; 1276 } 1277 if((hfConnDevList.isEmpty()) && 1278 (hsService.getPriority(device) >= BluetoothProfile.PRIORITY_ON)){ 1279 hsService.connect(device); 1280 } 1281 else if((a2dpConnDevList.isEmpty()) && 1282 (a2dpService.getPriority(device) >= BluetoothProfile.PRIORITY_ON)){ 1283 a2dpService.connect(device); 1284 } 1285 } 1286 1287 private void adjustOtherHeadsetPriorities(HeadsetService hsService, 1288 List<BluetoothDevice> connectedDeviceList) { 1289 for (BluetoothDevice device : getBondedDevices()) { 1290 if (hsService.getPriority(device) >= BluetoothProfile.PRIORITY_AUTO_CONNECT && 1291 !connectedDeviceList.contains(device)) { 1292 hsService.setPriority(device, BluetoothProfile.PRIORITY_ON); 1293 } 1294 } 1295 } 1296 1297 private void adjustOtherSinkPriorities(A2dpService a2dpService, 1298 BluetoothDevice connectedDevice) { 1299 for (BluetoothDevice device : getBondedDevices()) { 1300 if (a2dpService.getPriority(device) >= BluetoothProfile.PRIORITY_AUTO_CONNECT && 1301 !device.equals(connectedDevice)) { 1302 a2dpService.setPriority(device, BluetoothProfile.PRIORITY_ON); 1303 } 1304 } 1305 } 1306 1307 void setProfileAutoConnectionPriority (BluetoothDevice device, int profileId){ 1308 if (profileId == BluetoothProfile.HEADSET) { 1309 HeadsetService hsService = HeadsetService.getHeadsetService(); 1310 List<BluetoothDevice> deviceList = hsService.getConnectedDevices(); 1311 if ((hsService != null) && 1312 (BluetoothProfile.PRIORITY_AUTO_CONNECT != hsService.getPriority(device))){ 1313 adjustOtherHeadsetPriorities(hsService, deviceList); 1314 hsService.setPriority(device,BluetoothProfile.PRIORITY_AUTO_CONNECT); 1315 } 1316 } 1317 else if (profileId == BluetoothProfile.A2DP) { 1318 A2dpService a2dpService = A2dpService.getA2dpService(); 1319 if ((a2dpService != null) && 1320 (BluetoothProfile.PRIORITY_AUTO_CONNECT != a2dpService.getPriority(device))){ 1321 adjustOtherSinkPriorities(a2dpService, device); 1322 a2dpService.setPriority(device,BluetoothProfile.PRIORITY_AUTO_CONNECT); 1323 } 1324 } 1325 } 1326 1327 boolean cancelBondProcess(BluetoothDevice device) { 1328 enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, "Need BLUETOOTH ADMIN permission"); 1329 byte[] addr = Utils.getBytesFromAddress(device.getAddress()); 1330 return cancelBondNative(addr); 1331 } 1332 1333 boolean removeBond(BluetoothDevice device) { 1334 enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, "Need BLUETOOTH ADMIN permission"); 1335 DeviceProperties deviceProp = mRemoteDevices.getDeviceProperties(device); 1336 if (deviceProp == null || deviceProp.getBondState() != BluetoothDevice.BOND_BONDED) { 1337 return false; 1338 } 1339 Message msg = mBondStateMachine.obtainMessage(BondStateMachine.REMOVE_BOND); 1340 msg.obj = device; 1341 mBondStateMachine.sendMessage(msg); 1342 return true; 1343 } 1344 1345 int getBondState(BluetoothDevice device) { 1346 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1347 DeviceProperties deviceProp = mRemoteDevices.getDeviceProperties(device); 1348 if (deviceProp == null) { 1349 return BluetoothDevice.BOND_NONE; 1350 } 1351 return deviceProp.getBondState(); 1352 } 1353 1354 boolean isConnected(BluetoothDevice device) { 1355 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1356 byte[] addr = Utils.getBytesFromAddress(device.getAddress()); 1357 return isConnectedNative(addr); 1358 } 1359 1360 String getRemoteName(BluetoothDevice device) { 1361 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1362 DeviceProperties deviceProp = mRemoteDevices.getDeviceProperties(device); 1363 if (deviceProp == null) return null; 1364 return deviceProp.getName(); 1365 } 1366 1367 int getRemoteType(BluetoothDevice device) { 1368 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1369 DeviceProperties deviceProp = mRemoteDevices.getDeviceProperties(device); 1370 if (deviceProp == null) return BluetoothDevice.DEVICE_TYPE_UNKNOWN; 1371 return deviceProp.getDeviceType(); 1372 } 1373 1374 String getRemoteAlias(BluetoothDevice device) { 1375 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1376 DeviceProperties deviceProp = mRemoteDevices.getDeviceProperties(device); 1377 if (deviceProp == null) return null; 1378 return deviceProp.getAlias(); 1379 } 1380 1381 boolean setRemoteAlias(BluetoothDevice device, String name) { 1382 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1383 DeviceProperties deviceProp = mRemoteDevices.getDeviceProperties(device); 1384 if (deviceProp == null) return false; 1385 deviceProp.setAlias(name); 1386 return true; 1387 } 1388 1389 int getRemoteClass(BluetoothDevice device) { 1390 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1391 DeviceProperties deviceProp = mRemoteDevices.getDeviceProperties(device); 1392 if (deviceProp == null) return 0; 1393 1394 return deviceProp.getBluetoothClass(); 1395 } 1396 1397 ParcelUuid[] getRemoteUuids(BluetoothDevice device) { 1398 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1399 DeviceProperties deviceProp = mRemoteDevices.getDeviceProperties(device); 1400 if (deviceProp == null) return null; 1401 return deviceProp.getUuids(); 1402 } 1403 1404 boolean fetchRemoteUuids(BluetoothDevice device) { 1405 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1406 mRemoteDevices.fetchUuids(device); 1407 return true; 1408 } 1409 1410 boolean fetchRemoteMasInstances(BluetoothDevice device) { 1411 enforceCallingOrSelfPermission(RECEIVE_MAP_PERM, "Need RECEIVE BLUETOOTH MAP permission"); 1412 mRemoteDevices.fetchMasInstances(device); 1413 return true; 1414 } 1415 1416 boolean setPin(BluetoothDevice device, boolean accept, int len, byte[] pinCode) { 1417 enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, 1418 "Need BLUETOOTH ADMIN permission"); 1419 DeviceProperties deviceProp = mRemoteDevices.getDeviceProperties(device); 1420 if (deviceProp == null || deviceProp.getBondState() != BluetoothDevice.BOND_BONDING) { 1421 return false; 1422 } 1423 1424 byte[] addr = Utils.getBytesFromAddress(device.getAddress()); 1425 return pinReplyNative(addr, accept, len, pinCode); 1426 } 1427 1428 boolean setPasskey(BluetoothDevice device, boolean accept, int len, byte[] passkey) { 1429 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1430 DeviceProperties deviceProp = mRemoteDevices.getDeviceProperties(device); 1431 if (deviceProp == null || deviceProp.getBondState() != BluetoothDevice.BOND_BONDING) { 1432 return false; 1433 } 1434 1435 byte[] addr = Utils.getBytesFromAddress(device.getAddress()); 1436 return sspReplyNative(addr, AbstractionLayer.BT_SSP_VARIANT_PASSKEY_ENTRY, accept, 1437 Utils.byteArrayToInt(passkey)); 1438 } 1439 1440 boolean setPairingConfirmation(BluetoothDevice device, boolean accept) { 1441 enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, 1442 "Need BLUETOOTH ADMIN permission"); 1443 DeviceProperties deviceProp = mRemoteDevices.getDeviceProperties(device); 1444 if (deviceProp == null || deviceProp.getBondState() != BluetoothDevice.BOND_BONDING) { 1445 return false; 1446 } 1447 1448 byte[] addr = Utils.getBytesFromAddress(device.getAddress()); 1449 return sspReplyNative(addr, AbstractionLayer.BT_SSP_VARIANT_PASSKEY_CONFIRMATION, 1450 accept, 0); 1451 } 1452 1453 void sendConnectionStateChange(BluetoothDevice 1454 device, int profile, int state, int prevState) { 1455 // TODO(BT) permission check? 1456 // Since this is a binder call check if Bluetooth is on still 1457 if (getState() == BluetoothAdapter.STATE_OFF) return; 1458 1459 mAdapterProperties.sendConnectionStateChange(device, profile, state, prevState); 1460 1461 } 1462 1463 ParcelFileDescriptor connectSocket(BluetoothDevice device, int type, 1464 ParcelUuid uuid, int port, int flag) { 1465 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1466 int fd = connectSocketNative(Utils.getBytesFromAddress(device.getAddress()), 1467 type, Utils.uuidToByteArray(uuid), port, flag); 1468 if (fd < 0) { 1469 errorLog("Failed to connect socket"); 1470 return null; 1471 } 1472 return ParcelFileDescriptor.adoptFd(fd); 1473 } 1474 1475 ParcelFileDescriptor createSocketChannel(int type, String serviceName, 1476 ParcelUuid uuid, int port, int flag) { 1477 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1478 int fd = createSocketChannelNative(type, serviceName, 1479 Utils.uuidToByteArray(uuid), port, flag); 1480 if (fd < 0) { 1481 errorLog("Failed to create socket channel"); 1482 return null; 1483 } 1484 return ParcelFileDescriptor.adoptFd(fd); 1485 } 1486 1487 boolean configHciSnoopLog(boolean enable) { 1488 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1489 return configHciSnoopLogNative(enable); 1490 } 1491 1492 void registerCallback(IBluetoothCallback cb) { 1493 mCallbacks.register(cb); 1494 } 1495 1496 void unregisterCallback(IBluetoothCallback cb) { 1497 mCallbacks.unregister(cb); 1498 } 1499 1500 public int getNumOfAdvertisementInstancesSupported() { 1501 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1502 return mAdapterProperties.getNumOfAdvertisementInstancesSupported(); 1503 } 1504 1505 public boolean isRpaOffloadSupported() { 1506 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1507 return mAdapterProperties.isRpaOffloadSupported(); 1508 } 1509 1510 public int getNumOfOffloadedIrkSupported() { 1511 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1512 return mAdapterProperties.getNumOfOffloadedIrkSupported(); 1513 } 1514 1515 public int getNumOfOffloadedScanFilterSupported() { 1516 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1517 return mAdapterProperties.getNumOfOffloadedScanFilterSupported(); 1518 } 1519 1520 public int getOffloadedScanResultStorage() { 1521 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1522 return mAdapterProperties.getOffloadedScanResultStorage(); 1523 } 1524 1525 private static int convertScanModeToHal(int mode) { 1526 switch (mode) { 1527 case BluetoothAdapter.SCAN_MODE_NONE: 1528 return AbstractionLayer.BT_SCAN_MODE_NONE; 1529 case BluetoothAdapter.SCAN_MODE_CONNECTABLE: 1530 return AbstractionLayer.BT_SCAN_MODE_CONNECTABLE; 1531 case BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE: 1532 return AbstractionLayer.BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE; 1533 } 1534 // errorLog("Incorrect scan mode in convertScanModeToHal"); 1535 return -1; 1536 } 1537 1538 static int convertScanModeFromHal(int mode) { 1539 switch (mode) { 1540 case AbstractionLayer.BT_SCAN_MODE_NONE: 1541 return BluetoothAdapter.SCAN_MODE_NONE; 1542 case AbstractionLayer.BT_SCAN_MODE_CONNECTABLE: 1543 return BluetoothAdapter.SCAN_MODE_CONNECTABLE; 1544 case AbstractionLayer.BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE: 1545 return BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE; 1546 } 1547 //errorLog("Incorrect scan mode in convertScanModeFromHal"); 1548 return -1; 1549 } 1550 1551 // This function is called from JNI. It allows native code to set a single wake 1552 // alarm. If an alarm is already pending and a new request comes in, the alarm 1553 // will be rescheduled (i.e. the previously set alarm will be cancelled). 1554 private boolean setWakeAlarm(long delayMillis, boolean shouldWake) { 1555 synchronized (this) { 1556 if (mPendingAlarm != null) { 1557 mAlarmManager.cancel(mPendingAlarm); 1558 } 1559 1560 long wakeupTime = SystemClock.elapsedRealtime() + delayMillis; 1561 int type = shouldWake 1562 ? AlarmManager.ELAPSED_REALTIME_WAKEUP 1563 : AlarmManager.ELAPSED_REALTIME; 1564 1565 Intent intent = new Intent(ACTION_ALARM_WAKEUP); 1566 mPendingAlarm = PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_ONE_SHOT); 1567 mAlarmManager.setExact(type, wakeupTime, mPendingAlarm); 1568 return true; 1569 } 1570 } 1571 1572 // This function is called from JNI. It allows native code to acquire a single wake lock. 1573 // If the wake lock is already held, this function returns success. Although this function 1574 // only supports acquiring a single wake lock at a time right now, it will eventually be 1575 // extended to allow acquiring an arbitrary number of wake locks. The current interface 1576 // takes |lockName| as a parameter in anticipation of that implementation. 1577 private boolean acquireWakeLock(String lockName) { 1578 if (mWakeLock != null) { 1579 if (!lockName.equals(mWakeLockName)) { 1580 errorLog("Multiple wake lock acquisition attempted; aborting: " + lockName); 1581 return false; 1582 } 1583 1584 // We're already holding the desired wake lock so return success. 1585 if (mWakeLock.isHeld()) { 1586 return true; 1587 } 1588 } 1589 1590 mWakeLockName = lockName; 1591 mWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, lockName); 1592 mWakeLock.acquire(); 1593 return true; 1594 } 1595 1596 // This function is called from JNI. It allows native code to release a wake lock acquired 1597 // by |acquireWakeLock|. If the wake lock is not held, this function returns failure. 1598 // Note that the release() call is also invoked by {@link #cleanup()} so a synchronization is 1599 // needed here. See the comment for |acquireWakeLock| for an explanation of the interface. 1600 private boolean releaseWakeLock(String lockName) { 1601 synchronized (this) { 1602 if (mWakeLock == null) { 1603 errorLog("Repeated wake lock release; aborting release: " + lockName); 1604 return false; 1605 } 1606 1607 mWakeLock.release(); 1608 mWakeLock = null; 1609 mWakeLockName = null; 1610 } 1611 return true; 1612 } 1613 1614 private void debugLog(String msg) { 1615 if (DBG) Log.d(TAG +"(" +hashCode()+")", msg); 1616 } 1617 1618 private void errorLog(String msg) { 1619 Log.e(TAG +"(" +hashCode()+")", msg); 1620 } 1621 1622 private final BroadcastReceiver mAlarmBroadcastReceiver = new BroadcastReceiver() { 1623 @Override 1624 public void onReceive(Context context, Intent intent) { 1625 synchronized (AdapterService.this) { 1626 mPendingAlarm = null; 1627 alarmFiredNative(); 1628 } 1629 } 1630 }; 1631 1632 private native static void classInitNative(); 1633 private native boolean initNative(); 1634 private native void cleanupNative(); 1635 /*package*/ native boolean enableNative(); 1636 /*package*/ native boolean disableNative(); 1637 /*package*/ native boolean setAdapterPropertyNative(int type, byte[] val); 1638 /*package*/ native boolean getAdapterPropertiesNative(); 1639 /*package*/ native boolean getAdapterPropertyNative(int type); 1640 /*package*/ native boolean setAdapterPropertyNative(int type); 1641 /*package*/ native boolean 1642 setDevicePropertyNative(byte[] address, int type, byte[] val); 1643 /*package*/ native boolean getDevicePropertyNative(byte[] address, int type); 1644 1645 /*package*/ native boolean createBondNative(byte[] address); 1646 /*package*/ native boolean removeBondNative(byte[] address); 1647 /*package*/ native boolean cancelBondNative(byte[] address); 1648 1649 /*package*/ native boolean isConnectedNative(byte[] address); 1650 1651 private native boolean startDiscoveryNative(); 1652 private native boolean cancelDiscoveryNative(); 1653 1654 private native boolean pinReplyNative(byte[] address, boolean accept, int len, byte[] pin); 1655 private native boolean sspReplyNative(byte[] address, int type, boolean 1656 accept, int passkey); 1657 1658 /*package*/ native boolean getRemoteServicesNative(byte[] address); 1659 /*package*/ native boolean getRemoteMasInstancesNative(byte[] address); 1660 1661 // TODO(BT) move this to ../btsock dir 1662 private native int connectSocketNative(byte[] address, int type, 1663 byte[] uuid, int port, int flag); 1664 private native int createSocketChannelNative(int type, String serviceName, 1665 byte[] uuid, int port, int flag); 1666 1667 /*package*/ native boolean configHciSnoopLogNative(boolean enable); 1668 1669 private native void alarmFiredNative(); 1670 1671 protected void finalize() { 1672 cleanup(); 1673 if (TRACE_REF) { 1674 synchronized (AdapterService.class) { 1675 sRefCount--; 1676 debugLog("finalize() - REFCOUNT: FINALIZED. INSTANCE_COUNT= " + sRefCount); 1677 } 1678 } 1679 } 1680} 1681