AdapterService.java revision 24181aba0a5a45ab554c9fcc9bfa97981bcf75a2
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.bluetooth.BluetoothActivityEnergyInfo; 36import android.content.BroadcastReceiver; 37import android.content.ContentResolver; 38import android.content.Context; 39import android.content.Intent; 40import android.content.IntentFilter; 41import android.content.SharedPreferences; 42import android.os.Binder; 43import android.os.Bundle; 44import android.os.Handler; 45import android.os.IBinder; 46import android.os.Message; 47import android.os.ParcelFileDescriptor; 48import android.os.ParcelUuid; 49import android.os.PowerManager; 50import android.os.Process; 51import android.os.RemoteCallbackList; 52import android.os.RemoteException; 53import android.os.SystemClock; 54import android.provider.Settings; 55import android.util.EventLog; 56import android.util.Log; 57import android.util.Pair; 58 59import com.android.bluetooth.a2dp.A2dpService; 60import com.android.bluetooth.hid.HidService; 61import com.android.bluetooth.hfp.HeadsetService; 62import com.android.bluetooth.hdp.HealthService; 63import com.android.bluetooth.pan.PanService; 64import com.android.bluetooth.sdp.SdpManager; 65import com.android.internal.R; 66import com.android.bluetooth.Utils; 67import com.android.bluetooth.btservice.RemoteDevices.DeviceProperties; 68 69import java.io.FileDescriptor; 70import java.io.IOException; 71import java.util.ArrayList; 72import java.util.HashMap; 73import java.util.Set; 74import java.util.Map; 75import java.util.Iterator; 76import java.util.Map.Entry; 77import java.util.List; 78 79import android.content.pm.PackageManager; 80import android.os.ServiceManager; 81 82public class AdapterService extends Service { 83 private static final String TAG = "BluetoothAdapterService"; 84 private static final boolean DBG = true; 85 private static final boolean TRACE_REF = true; 86 private static final int MIN_ADVT_INSTANCES_FOR_MA = 5; 87 private static final int MIN_OFFLOADED_FILTERS = 10; 88 private static final int MIN_OFFLOADED_SCAN_STORAGE_BYTES = 1024; 89 //For Debugging only 90 private static int sRefCount=0; 91 92 private int mStackReportedState; 93 private int mTxTimeTotalMs; 94 private int mRxTimeTotalMs; 95 private int mIdleTimeTotalMs; 96 private int mEnergyUsedTotalVoltAmpSecMicro; 97 98 private final ArrayList<ProfileService> mProfiles = new ArrayList<ProfileService>(); 99 100 public static final String ACTION_LOAD_ADAPTER_PROPERTIES = 101 "com.android.bluetooth.btservice.action.LOAD_ADAPTER_PROPERTIES"; 102 public static final String ACTION_SERVICE_STATE_CHANGED = 103 "com.android.bluetooth.btservice.action.STATE_CHANGED"; 104 public static final String EXTRA_ACTION="action"; 105 public static final int PROFILE_CONN_CONNECTED = 1; 106 public static final int PROFILE_CONN_REJECTED = 2; 107 108 private static final String ACTION_ALARM_WAKEUP = 109 "com.android.bluetooth.btservice.action.ALARM_WAKEUP"; 110 111 public static final String BLUETOOTH_ADMIN_PERM = 112 android.Manifest.permission.BLUETOOTH_ADMIN; 113 public static final String BLUETOOTH_PRIVILEGED = 114 android.Manifest.permission.BLUETOOTH_PRIVILEGED; 115 static final String BLUETOOTH_PERM = android.Manifest.permission.BLUETOOTH; 116 static final String RECEIVE_MAP_PERM = android.Manifest.permission.RECEIVE_BLUETOOTH_MAP; 117 118 private static final String PHONEBOOK_ACCESS_PERMISSION_PREFERENCE_FILE = 119 "phonebook_access_permission"; 120 private static final String MESSAGE_ACCESS_PERMISSION_PREFERENCE_FILE = 121 "message_access_permission"; 122 private static final String SIM_ACCESS_PERMISSION_PREFERENCE_FILE = 123 "sim_access_permission"; 124 125 private static final int ADAPTER_SERVICE_TYPE=Service.START_STICKY; 126 127 static { 128 classInitNative(); 129 } 130 131 private static AdapterService sAdapterService; 132 public static synchronized AdapterService getAdapterService(){ 133 if (sAdapterService != null && !sAdapterService.mCleaningUp) { 134 Log.d(TAG, "getAdapterService() - returning " + sAdapterService); 135 return sAdapterService; 136 } 137 if (DBG) { 138 if (sAdapterService == null) { 139 Log.d(TAG, "getAdapterService() - Service not available"); 140 } else if (sAdapterService.mCleaningUp) { 141 Log.d(TAG,"getAdapterService() - Service is cleaning up"); 142 } 143 } 144 return null; 145 } 146 147 private static synchronized void setAdapterService(AdapterService instance) { 148 if (instance != null && !instance.mCleaningUp) { 149 if (DBG) Log.d(TAG, "setAdapterService() - set to: " + sAdapterService); 150 sAdapterService = instance; 151 } else { 152 if (DBG) { 153 if (sAdapterService == null) { 154 Log.d(TAG, "setAdapterService() - Service not available"); 155 } else if (sAdapterService.mCleaningUp) { 156 Log.d(TAG,"setAdapterService() - Service is cleaning up"); 157 } 158 } 159 } 160 } 161 162 private static synchronized void clearAdapterService() { 163 sAdapterService = null; 164 } 165 166 private AdapterProperties mAdapterProperties; 167 private AdapterState mAdapterStateMachine; 168 private BondStateMachine mBondStateMachine; 169 private JniCallbacks mJniCallbacks; 170 private RemoteDevices mRemoteDevices; 171 172 /* TODO: Consider to remove the search API from this class, if changed to use call-back */ 173 private SdpManager mSdpManager = null; 174 175 private boolean mProfilesStarted; 176 private boolean mNativeAvailable; 177 private boolean mCleaningUp; 178 private HashMap<String,Integer> mProfileServicesState = new HashMap<String,Integer>(); 179 //Only BluetoothManagerService should be registered 180 private RemoteCallbackList<IBluetoothCallback> mCallbacks; 181 private int mCurrentRequestId; 182 private boolean mQuietmode = false; 183 184 private AlarmManager mAlarmManager; 185 private PendingIntent mPendingAlarm; 186 private PowerManager mPowerManager; 187 private PowerManager.WakeLock mWakeLock; 188 private String mWakeLockName; 189 190 public AdapterService() { 191 super(); 192 if (TRACE_REF) { 193 synchronized (AdapterService.class) { 194 sRefCount++; 195 debugLog("AdapterService() - REFCOUNT: CREATED. INSTANCE_COUNT" + sRefCount); 196 } 197 } 198 } 199 200 public void onProfileConnectionStateChanged(BluetoothDevice device, int profileId, int newState, int prevState) { 201 Message m = mHandler.obtainMessage(MESSAGE_PROFILE_CONNECTION_STATE_CHANGED); 202 m.obj = device; 203 m.arg1 = profileId; 204 m.arg2 = newState; 205 Bundle b = new Bundle(1); 206 b.putInt("prevState", prevState); 207 m.setData(b); 208 mHandler.sendMessage(m); 209 } 210 211 public void initProfilePriorities(BluetoothDevice device, ParcelUuid[] mUuids) { 212 if(mUuids == null) return; 213 Message m = mHandler.obtainMessage(MESSAGE_PROFILE_INIT_PRIORITIES); 214 m.obj = device; 215 m.arg1 = mUuids.length; 216 Bundle b = new Bundle(1); 217 for(int i=0; i<mUuids.length; i++) { 218 b.putParcelable("uuids" + i, mUuids[i]); 219 } 220 m.setData(b); 221 mHandler.sendMessage(m); 222 } 223 224 private void processInitProfilePriorities (BluetoothDevice device, ParcelUuid[] uuids){ 225 HidService hidService = HidService.getHidService(); 226 A2dpService a2dpService = A2dpService.getA2dpService(); 227 HeadsetService headsetService = HeadsetService.getHeadsetService(); 228 229 // Set profile priorities only for the profiles discovered on the remote device. 230 // This avoids needless auto-connect attempts to profiles non-existent on the remote device 231 if ((hidService != null) && 232 (BluetoothUuid.isUuidPresent(uuids, BluetoothUuid.Hid) || 233 BluetoothUuid.isUuidPresent(uuids, BluetoothUuid.Hogp)) && 234 (hidService.getPriority(device) == BluetoothProfile.PRIORITY_UNDEFINED)){ 235 hidService.setPriority(device,BluetoothProfile.PRIORITY_ON); 236 } 237 238 // If we do not have a stored priority for A2DP then default to on. 239 if ((a2dpService != null) && 240 (BluetoothUuid.isUuidPresent(uuids, BluetoothUuid.AudioSink) || 241 BluetoothUuid.isUuidPresent(uuids, BluetoothUuid.AdvAudioDist)) && 242 (a2dpService.getPriority(device) == BluetoothProfile.PRIORITY_UNDEFINED)){ 243 a2dpService.setPriority(device,BluetoothProfile.PRIORITY_ON); 244 } 245 246 if ((headsetService != null) && 247 ((BluetoothUuid.isUuidPresent(uuids, BluetoothUuid.HSP) || 248 BluetoothUuid.isUuidPresent(uuids, BluetoothUuid.Handsfree)) && 249 (headsetService.getPriority(device) == BluetoothProfile.PRIORITY_UNDEFINED))){ 250 headsetService.setPriority(device,BluetoothProfile.PRIORITY_ON); 251 } 252 } 253 254 private void processProfileStateChanged(BluetoothDevice device, int profileId, int newState, int prevState) { 255 if (((profileId == BluetoothProfile.A2DP) ||(profileId == BluetoothProfile.HEADSET)) && 256 (newState == BluetoothProfile.STATE_CONNECTED)){ 257 debugLog( "Profile connected. Schedule missing profile connection if any"); 258 connectOtherProfile(device, PROFILE_CONN_CONNECTED); 259 setProfileAutoConnectionPriority(device, profileId); 260 } 261 IBluetooth.Stub binder = mBinder; 262 if (binder != null) { 263 try { 264 binder.sendConnectionStateChange(device, profileId, newState,prevState); 265 } catch (RemoteException re) { 266 errorLog("" + re); 267 } 268 } 269 } 270 271 public void addProfile(ProfileService profile) { 272 synchronized (mProfiles) { 273 mProfiles.add(profile); 274 } 275 } 276 277 public void removeProfile(ProfileService profile) { 278 synchronized (mProfiles) { 279 mProfiles.remove(profile); 280 } 281 } 282 283 public void onProfileServiceStateChanged(String serviceName, int state) { 284 Message m = mHandler.obtainMessage(MESSAGE_PROFILE_SERVICE_STATE_CHANGED); 285 m.obj=serviceName; 286 m.arg1 = state; 287 mHandler.sendMessage(m); 288 } 289 290 private void processProfileServiceStateChanged(String serviceName, int state) { 291 boolean doUpdate=false; 292 boolean isBleTurningOn; 293 boolean isBleTurningOff; 294 boolean isTurningOn; 295 boolean isTurningOff; 296 297 synchronized (mProfileServicesState) { 298 Integer prevState = mProfileServicesState.get(serviceName); 299 if (prevState != null && prevState != state) { 300 mProfileServicesState.put(serviceName,state); 301 doUpdate=true; 302 } 303 } 304 debugLog("onProfileServiceStateChange() serviceName=" + serviceName 305 + ", state=" + state +", doUpdate=" + doUpdate); 306 307 if (!doUpdate) { 308 return; 309 } 310 311 synchronized (mAdapterStateMachine) { 312 isTurningOff = mAdapterStateMachine.isTurningOff(); 313 isTurningOn = mAdapterStateMachine.isTurningOn(); 314 isBleTurningOn = mAdapterStateMachine.isBleTurningOn(); 315 isBleTurningOff = mAdapterStateMachine.isBleTurningOff(); 316 } 317 318 debugLog("processProfileServiceStateChanged() - serviceName=" + serviceName + 319 " isTurningOn=" + isTurningOn + " isTurningOff=" + isTurningOff + 320 " isBleTurningOn=" + isBleTurningOn + " isBleTurningOff=" + isBleTurningOff); 321 322 if (isBleTurningOn) { 323 if (serviceName.equals("com.android.bluetooth.gatt.GattService")) { 324 debugLog("GattService is started"); 325 mAdapterStateMachine.sendMessage(mAdapterStateMachine.obtainMessage(AdapterState.BLE_STARTED)); 326 return; 327 } 328 329 } else if(isBleTurningOff) { 330 if (serviceName.equals("com.android.bluetooth.gatt.GattService")) { 331 debugLog("GattService stopped"); 332 mAdapterStateMachine.sendMessage(mAdapterStateMachine.obtainMessage(AdapterState.BLE_STOPPED)); 333 return; 334 } 335 336 } else if (isTurningOff) { 337 //On to BLE_ON 338 //Process stop or disable pending 339 //Check if all services are stopped if so, do cleanup 340 synchronized (mProfileServicesState) { 341 Iterator<Map.Entry<String,Integer>> i = mProfileServicesState.entrySet().iterator(); 342 while (i.hasNext()) { 343 Map.Entry<String,Integer> entry = i.next(); 344 debugLog("Service: " + entry.getKey()); 345 if (entry.getKey().equals("com.android.bluetooth.gatt.GattService")) { 346 debugLog("Skip GATT service - already started before"); 347 continue; 348 } 349 if (BluetoothAdapter.STATE_OFF != entry.getValue()) { 350 debugLog("onProfileServiceStateChange() - Profile still running: " 351 + entry.getKey()); 352 return; 353 } 354 } 355 } 356 debugLog("onProfileServiceStateChange() - All profile services stopped..."); 357 //Send message to state machine 358 mProfilesStarted=false; 359 mAdapterStateMachine.sendMessage(mAdapterStateMachine.obtainMessage(AdapterState.BREDR_STOPPED)); 360 361 } else if (isTurningOn) { 362 //Process start pending 363 //Check if all services are started if so, update state 364 synchronized (mProfileServicesState) { 365 Iterator<Map.Entry<String,Integer>> i = mProfileServicesState.entrySet().iterator(); 366 while (i.hasNext()) { 367 Map.Entry<String,Integer> entry = i.next(); 368 debugLog("Service: " + entry.getKey()); 369 if (entry.getKey().equals("com.android.bluetooth.gatt.GattService")) { 370 debugLog("Skip GATT service - already started before"); 371 continue; 372 } 373 if (BluetoothAdapter.STATE_ON != entry.getValue()) { 374 debugLog("onProfileServiceStateChange() - Profile still not running:" 375 + entry.getKey()); 376 return; 377 } 378 } 379 } 380 debugLog("onProfileServiceStateChange() - All profile services started."); 381 mProfilesStarted=true; 382 //Send message to state machine 383 mAdapterStateMachine.sendMessage(mAdapterStateMachine.obtainMessage(AdapterState.BREDR_STARTED)); 384 } 385 } 386 387 @Override 388 public void onCreate() { 389 super.onCreate(); 390 debugLog("onCreate()"); 391 mBinder = new AdapterServiceBinder(this); 392 mAdapterProperties = new AdapterProperties(this); 393 mAdapterStateMachine = AdapterState.make(this, mAdapterProperties); 394 mJniCallbacks = new JniCallbacks(mAdapterStateMachine, mAdapterProperties); 395 initNative(); 396 mNativeAvailable=true; 397 mCallbacks = new RemoteCallbackList<IBluetoothCallback>(); 398 //Load the name and address 399 getAdapterPropertyNative(AbstractionLayer.BT_PROPERTY_BDADDR); 400 getAdapterPropertyNative(AbstractionLayer.BT_PROPERTY_BDNAME); 401 mAlarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE); 402 mPowerManager = (PowerManager) getSystemService(Context.POWER_SERVICE); 403 404 mSdpManager = SdpManager.init(this); 405 registerReceiver(mAlarmBroadcastReceiver, new IntentFilter(ACTION_ALARM_WAKEUP)); 406 407 408 409 } 410 411 @Override 412 public IBinder onBind(Intent intent) { 413 debugLog("onBind()"); 414 return mBinder; 415 } 416 public boolean onUnbind(Intent intent) { 417 debugLog("onUnbind() - calling cleanup"); 418 cleanup(); 419 return super.onUnbind(intent); 420 } 421 422 public void onDestroy() { 423 debugLog("onDestroy()"); 424 } 425 426 void BleOnProcessStart() { 427 debugLog("BleOnProcessStart()"); 428 Class[] supportedProfileServices = Config.getSupportedProfiles(); 429 //Initialize data objects 430 for (int i=0; i < supportedProfileServices.length;i++) { 431 mProfileServicesState.put(supportedProfileServices[i].getName(),BluetoothAdapter.STATE_OFF); 432 } 433 mRemoteDevices = new RemoteDevices(this); 434 mAdapterProperties.init(mRemoteDevices); 435 436 debugLog("BleOnProcessStart() - Make Bond State Machine"); 437 mBondStateMachine = BondStateMachine.make(this, mAdapterProperties, mRemoteDevices); 438 439 mJniCallbacks.init(mBondStateMachine,mRemoteDevices); 440 441 //FIXME: Set static instance here??? 442 setAdapterService(this); 443 444 //Start Gatt service 445 setGattProfileServiceState(supportedProfileServices,BluetoothAdapter.STATE_ON); 446 } 447 448 void startCoreServices() 449 { 450 debugLog("startCoreServices()"); 451 Class[] supportedProfileServices = Config.getSupportedProfiles(); 452 453 //Start profile services 454 if (!mProfilesStarted && supportedProfileServices.length >0) { 455 //Startup all profile services 456 setProfileServiceState(supportedProfileServices,BluetoothAdapter.STATE_ON); 457 }else { 458 debugLog("startCoreProfiles(): Profile Services alreay started"); 459 mAdapterStateMachine.sendMessage(mAdapterStateMachine.obtainMessage(AdapterState.BREDR_STARTED)); 460 } 461 } 462 463 void startBluetoothDisable() { 464 mAdapterStateMachine.sendMessage(mAdapterStateMachine.obtainMessage(AdapterState.BEGIN_DISABLE)); 465 } 466 467 boolean stopProfileServices() { 468 Class[] supportedProfileServices = Config.getSupportedProfiles(); 469 if (mProfilesStarted && supportedProfileServices.length>0) { 470 setProfileServiceState(supportedProfileServices,BluetoothAdapter.STATE_OFF); 471 return true; 472 } 473 debugLog("stopProfileServices() - No profiles services to stop or already stopped."); 474 return false; 475 } 476 477 boolean stopGattProfileService() { 478 //TODO: can optimize this instead of looping around all supported profiles 479 debugLog("stopGattProfileService()"); 480 Class[] supportedProfileServices = Config.getSupportedProfiles(); 481 482 setGattProfileServiceState(supportedProfileServices,BluetoothAdapter.STATE_OFF); 483 return true; 484 } 485 486 487 void updateAdapterState(int prevState, int newState){ 488 if (mCallbacks !=null) { 489 int n=mCallbacks.beginBroadcast(); 490 debugLog("updateAdapterState() - Broadcasting state to " + n + " receivers."); 491 for (int i=0; i <n;i++) { 492 try { 493 mCallbacks.getBroadcastItem(i).onBluetoothStateChange(prevState,newState); 494 } catch (RemoteException e) { 495 debugLog("updateAdapterState() - Callback #" + i + " failed (" + e + ")"); 496 } 497 } 498 mCallbacks.finishBroadcast(); 499 } 500 } 501 502 void cleanup () { 503 debugLog("cleanup()"); 504 if (mCleaningUp) { 505 errorLog("cleanup() - Service already starting to cleanup, ignoring request..."); 506 return; 507 } 508 509 mCleaningUp = true; 510 511 unregisterReceiver(mAlarmBroadcastReceiver); 512 513 if (mPendingAlarm != null) { 514 mAlarmManager.cancel(mPendingAlarm); 515 mPendingAlarm = null; 516 } 517 518 // This wake lock release may also be called concurrently by 519 // {@link #releaseWakeLock(String lockName)}, so a synchronization is needed here. 520 synchronized (this) { 521 if (mWakeLock != null) { 522 mWakeLock.release(); 523 mWakeLock = null; 524 } 525 } 526 527 if (mAdapterStateMachine != null) { 528 mAdapterStateMachine.doQuit(); 529 mAdapterStateMachine.cleanup(); 530 } 531 532 if (mBondStateMachine != null) { 533 mBondStateMachine.doQuit(); 534 mBondStateMachine.cleanup(); 535 } 536 537 if (mRemoteDevices != null) { 538 mRemoteDevices.cleanup(); 539 } 540 541 if(mSdpManager != null) { 542 mSdpManager.cleanup(); 543 mSdpManager = null; 544 } 545 546 if (mNativeAvailable) { 547 debugLog("cleanup() - Cleaning up adapter native"); 548 cleanupNative(); 549 mNativeAvailable=false; 550 } 551 552 if (mAdapterProperties != null) { 553 mAdapterProperties.cleanup(); 554 } 555 556 if (mJniCallbacks != null) { 557 mJniCallbacks.cleanup(); 558 } 559 560 if (mProfileServicesState != null) { 561 mProfileServicesState.clear(); 562 } 563 564 clearAdapterService(); 565 566 if (mBinder != null) { 567 mBinder.cleanup(); 568 mBinder = null; //Do not remove. Otherwise Binder leak! 569 } 570 571 if (mCallbacks !=null) { 572 mCallbacks.kill(); 573 } 574 575 System.exit(0); 576 } 577 578 private static final int MESSAGE_PROFILE_SERVICE_STATE_CHANGED =1; 579 private static final int MESSAGE_PROFILE_CONNECTION_STATE_CHANGED=20; 580 private static final int MESSAGE_CONNECT_OTHER_PROFILES = 30; 581 private static final int MESSAGE_PROFILE_INIT_PRIORITIES=40; 582 private static final int MESSAGE_SET_WAKE_ALARM = 100; 583 private static final int MESSAGE_RELEASE_WAKE_ALARM = 110; 584 private static final int CONNECT_OTHER_PROFILES_TIMEOUT= 6000; 585 586 private final Handler mHandler = new Handler() { 587 @Override 588 public void handleMessage(Message msg) { 589 debugLog("handleMessage() - Message: " + msg.what); 590 591 switch (msg.what) { 592 case MESSAGE_PROFILE_SERVICE_STATE_CHANGED: { 593 debugLog("handleMessage() - MESSAGE_PROFILE_SERVICE_STATE_CHANGED"); 594 processProfileServiceStateChanged((String) msg.obj, msg.arg1); 595 } 596 break; 597 case MESSAGE_PROFILE_CONNECTION_STATE_CHANGED: { 598 debugLog( "handleMessage() - MESSAGE_PROFILE_CONNECTION_STATE_CHANGED"); 599 processProfileStateChanged((BluetoothDevice) msg.obj, msg.arg1,msg.arg2, msg.getData().getInt("prevState",BluetoothAdapter.ERROR)); 600 } 601 break; 602 case MESSAGE_PROFILE_INIT_PRIORITIES: { 603 debugLog( "handleMessage() - MESSAGE_PROFILE_INIT_PRIORITIES"); 604 ParcelUuid[] mUuids = new ParcelUuid[msg.arg1]; 605 for(int i=0; i<mUuids.length; i++) { 606 mUuids[i] = msg.getData().getParcelable("uuids" + i); 607 } 608 processInitProfilePriorities((BluetoothDevice) msg.obj, 609 mUuids); 610 } 611 break; 612 case MESSAGE_CONNECT_OTHER_PROFILES: { 613 debugLog( "handleMessage() - MESSAGE_CONNECT_OTHER_PROFILES"); 614 processConnectOtherProfiles((BluetoothDevice) msg.obj,msg.arg1); 615 } 616 break; 617 case MESSAGE_SET_WAKE_ALARM: { 618 debugLog( "handleMessage() - MESSAGE_SET_WAKE_ALARM"); 619 processSetWakeAlarm((Long) msg.obj, msg.arg1); 620 } 621 break; 622 case MESSAGE_RELEASE_WAKE_ALARM: { 623 debugLog( "handleMessage() - MESSAGE_RELEASE_WAKE_ALARM"); 624 mPendingAlarm = null; 625 alarmFiredNative(); 626 } 627 break; 628 } 629 } 630 }; 631 632 @SuppressWarnings("rawtypes") 633 private void setGattProfileServiceState(Class[] services, int state) { 634 if (state != BluetoothAdapter.STATE_ON && state != BluetoothAdapter.STATE_OFF) { 635 Log.w(TAG,"setGattProfileServiceState(): invalid state...Leaving..."); 636 return; 637 } 638 639 int expectedCurrentState= BluetoothAdapter.STATE_OFF; 640 int pendingState = BluetoothAdapter.STATE_TURNING_ON; 641 642 if (state == BluetoothAdapter.STATE_OFF) { 643 expectedCurrentState= BluetoothAdapter.STATE_ON; 644 pendingState = BluetoothAdapter.STATE_TURNING_OFF; 645 } 646 647 for (int i=0; i <services.length;i++) { 648 String serviceName = services[i].getName(); 649 String simpleName = services[i].getSimpleName(); 650 651 if (simpleName.equals("GattService")) { 652 if (DBG) Log.d(TAG, "It is gaTT service"); 653 Integer serviceState = mProfileServicesState.get(serviceName); 654 655 if(serviceState != null && serviceState != expectedCurrentState) { 656 debugLog("setProfileServiceState() - Unable to " 657 + (state == BluetoothAdapter.STATE_OFF ? "start" : "stop" ) 658 + " service " + serviceName 659 + ". Invalid state: " + serviceState); 660 continue; 661 } 662 debugLog("setProfileServiceState() - " 663 + (state == BluetoothAdapter.STATE_OFF ? "Stopping" : "Starting") 664 + " service " + serviceName); 665 666 mProfileServicesState.put(serviceName,pendingState); 667 Intent intent = new Intent(this,services[i]); 668 intent.putExtra(EXTRA_ACTION,ACTION_SERVICE_STATE_CHANGED); 669 intent.putExtra(BluetoothAdapter.EXTRA_STATE,state); 670 startService(intent); 671 return; 672 } 673 } 674 } 675 676 677 @SuppressWarnings("rawtypes") 678 private void setProfileServiceState(Class[] services, int state) { 679 if (state != BluetoothAdapter.STATE_ON && state != BluetoothAdapter.STATE_OFF) { 680 debugLog("setProfileServiceState() - Invalid state, leaving..."); 681 return; 682 } 683 684 int expectedCurrentState= BluetoothAdapter.STATE_OFF; 685 int pendingState = BluetoothAdapter.STATE_TURNING_ON; 686 if (state == BluetoothAdapter.STATE_OFF) { 687 expectedCurrentState= BluetoothAdapter.STATE_ON; 688 pendingState = BluetoothAdapter.STATE_TURNING_OFF; 689 } 690 691 for (int i=0; i <services.length;i++) { 692 String serviceName = services[i].getName(); 693 String simpleName = services[i].getSimpleName(); 694 695 if (simpleName.equals("GattService")) { 696 if (DBG) Log.d(TAG, "It is gaTT service. SKIP IT"); 697 continue; 698 } 699 Integer serviceState = mProfileServicesState.get(serviceName); 700 if(serviceState != null && serviceState != expectedCurrentState) { 701 debugLog("setProfileServiceState() - Unable to " 702 + (state == BluetoothAdapter.STATE_OFF ? "start" : "stop" ) 703 + " service " + serviceName 704 + ". Invalid state: " + serviceState); 705 continue; 706 } 707 708 debugLog("setProfileServiceState() - " 709 + (state == BluetoothAdapter.STATE_OFF ? "Stopping" : "Starting") 710 + " service " + serviceName); 711 712 mProfileServicesState.put(serviceName,pendingState); 713 Intent intent = new Intent(this,services[i]); 714 intent.putExtra(EXTRA_ACTION,ACTION_SERVICE_STATE_CHANGED); 715 intent.putExtra(BluetoothAdapter.EXTRA_STATE,state); 716 startService(intent); 717 } 718 } 719 720 private boolean isAvailable() { 721 return !mCleaningUp; 722 } 723 724 /** 725 * Handlers for incoming service calls 726 */ 727 private AdapterServiceBinder mBinder; 728 729 /** 730 * The Binder implementation must be declared to be a static class, with 731 * the AdapterService instance passed in the constructor. Furthermore, 732 * when the AdapterService shuts down, the reference to the AdapterService 733 * must be explicitly removed. 734 * 735 * Otherwise, a memory leak can occur from repeated starting/stopping the 736 * service...Please refer to android.os.Binder for further details on 737 * why an inner instance class should be avoided. 738 * 739 */ 740 private static class AdapterServiceBinder extends IBluetooth.Stub { 741 private AdapterService mService; 742 743 public AdapterServiceBinder(AdapterService svc) { 744 mService = svc; 745 } 746 public boolean cleanup() { 747 mService = null; 748 return true; 749 } 750 751 public AdapterService getService() { 752 if (mService != null && mService.isAvailable()) { 753 return mService; 754 } 755 return null; 756 } 757 public boolean isEnabled() { 758 // don't check caller, may be called from system UI 759 AdapterService service = getService(); 760 if (service == null) return false; 761 return service.isEnabled(); 762 } 763 764 public int getState() { 765 // don't check caller, may be called from system UI 766 AdapterService service = getService(); 767 if (service == null) return BluetoothAdapter.STATE_OFF; 768 return service.getState(); 769 } 770 771 public boolean enable() { 772 if ((Binder.getCallingUid() != Process.SYSTEM_UID) && 773 (!Utils.checkCaller())) { 774 Log.w(TAG, "enable() - Not allowed for non-active user and non system user"); 775 return false; 776 } 777 AdapterService service = getService(); 778 if (service == null) return false; 779 return service.enable(); 780 } 781 782 public boolean enableNoAutoConnect() { 783 if ((Binder.getCallingUid() != Process.SYSTEM_UID) && 784 (!Utils.checkCaller())) { 785 Log.w(TAG, "enableNoAuto() - Not allowed for non-active user and non system user"); 786 return false; 787 } 788 789 AdapterService service = getService(); 790 if (service == null) return false; 791 return service.enableNoAutoConnect(); 792 } 793 794 public boolean disable() { 795 if ((Binder.getCallingUid() != Process.SYSTEM_UID) && 796 (!Utils.checkCaller())) { 797 Log.w(TAG, "disable() - Not allowed for non-active user and non system user"); 798 return false; 799 } 800 801 AdapterService service = getService(); 802 if (service == null) return false; 803 return service.disable(); 804 } 805 806 public String getAddress() { 807 if ((Binder.getCallingUid() != Process.SYSTEM_UID) && 808 (!Utils.checkCallerAllowManagedProfiles(mService))) { 809 Log.w(TAG, "getAddress() - Not allowed for non-active user and non system user"); 810 return null; 811 } 812 813 AdapterService service = getService(); 814 if (service == null) return null; 815 return service.getAddress(); 816 } 817 818 public ParcelUuid[] getUuids() { 819 if (!Utils.checkCaller()) { 820 Log.w(TAG, "getUuids() - Not allowed for non-active user"); 821 return new ParcelUuid[0]; 822 } 823 824 AdapterService service = getService(); 825 if (service == null) return new ParcelUuid[0]; 826 return service.getUuids(); 827 } 828 829 public String getName() { 830 if ((Binder.getCallingUid() != Process.SYSTEM_UID) && 831 (!Utils.checkCaller())) { 832 Log.w(TAG, "getName() - Not allowed for non-active user and non system user"); 833 return null; 834 } 835 836 AdapterService service = getService(); 837 if (service == null) return null; 838 return service.getName(); 839 } 840 841 public boolean setName(String name) { 842 if (!Utils.checkCaller()) { 843 Log.w(TAG, "setName() - Not allowed for non-active user"); 844 return false; 845 } 846 847 AdapterService service = getService(); 848 if (service == null) return false; 849 return service.setName(name); 850 } 851 852 public int getScanMode() { 853 if (!Utils.checkCallerAllowManagedProfiles(mService)) { 854 Log.w(TAG, "getScanMode() - Not allowed for non-active user"); 855 return BluetoothAdapter.SCAN_MODE_NONE; 856 } 857 858 AdapterService service = getService(); 859 if (service == null) return BluetoothAdapter.SCAN_MODE_NONE; 860 return service.getScanMode(); 861 } 862 863 public boolean setScanMode(int mode, int duration) { 864 if (!Utils.checkCaller()) { 865 Log.w(TAG, "setScanMode() - Not allowed for non-active user"); 866 return false; 867 } 868 869 AdapterService service = getService(); 870 if (service == null) return false; 871 return service.setScanMode(mode,duration); 872 } 873 874 public int getDiscoverableTimeout() { 875 if (!Utils.checkCaller()) { 876 Log.w(TAG, "getDiscoverableTimeout() - Not allowed for non-active user"); 877 return 0; 878 } 879 880 AdapterService service = getService(); 881 if (service == null) return 0; 882 return service.getDiscoverableTimeout(); 883 } 884 885 public boolean setDiscoverableTimeout(int timeout) { 886 if (!Utils.checkCaller()) { 887 Log.w(TAG, "setDiscoverableTimeout() - Not allowed for non-active user"); 888 return false; 889 } 890 891 AdapterService service = getService(); 892 if (service == null) return false; 893 return service.setDiscoverableTimeout(timeout); 894 } 895 896 public boolean startDiscovery() { 897 if (!Utils.checkCaller()) { 898 Log.w(TAG, "startDiscovery() - Not allowed for non-active user"); 899 return false; 900 } 901 902 AdapterService service = getService(); 903 if (service == null) return false; 904 return service.startDiscovery(); 905 } 906 907 public boolean cancelDiscovery() { 908 if (!Utils.checkCaller()) { 909 Log.w(TAG, "cancelDiscovery() - Not allowed for non-active user"); 910 return false; 911 } 912 913 AdapterService service = getService(); 914 if (service == null) return false; 915 return service.cancelDiscovery(); 916 } 917 public boolean isDiscovering() { 918 if (!Utils.checkCallerAllowManagedProfiles(mService)) { 919 Log.w(TAG, "isDiscovering() - Not allowed for non-active user"); 920 return false; 921 } 922 923 AdapterService service = getService(); 924 if (service == null) return false; 925 return service.isDiscovering(); 926 } 927 928 public BluetoothDevice[] getBondedDevices() { 929 // don't check caller, may be called from system UI 930 AdapterService service = getService(); 931 if (service == null) return new BluetoothDevice[0]; 932 return service.getBondedDevices(); 933 } 934 935 public int getAdapterConnectionState() { 936 // don't check caller, may be called from system UI 937 AdapterService service = getService(); 938 if (service == null) return BluetoothAdapter.STATE_DISCONNECTED; 939 return service.getAdapterConnectionState(); 940 } 941 942 public int getProfileConnectionState(int profile) { 943 if (!Utils.checkCallerAllowManagedProfiles(mService)) { 944 Log.w(TAG, "getProfileConnectionState- Not allowed for non-active user"); 945 return BluetoothProfile.STATE_DISCONNECTED; 946 } 947 948 AdapterService service = getService(); 949 if (service == null) return BluetoothProfile.STATE_DISCONNECTED; 950 return service.getProfileConnectionState(profile); 951 } 952 953 public boolean createBond(BluetoothDevice device, int transport) { 954 if (!Utils.checkCaller()) { 955 Log.w(TAG, "createBond() - Not allowed for non-active user"); 956 return false; 957 } 958 959 AdapterService service = getService(); 960 if (service == null) return false; 961 return service.createBond(device, transport); 962 } 963 964 public boolean cancelBondProcess(BluetoothDevice device) { 965 if (!Utils.checkCaller()) { 966 Log.w(TAG, "cancelBondProcess() - Not allowed for non-active user"); 967 return false; 968 } 969 970 AdapterService service = getService(); 971 if (service == null) return false; 972 return service.cancelBondProcess(device); 973 } 974 975 public boolean removeBond(BluetoothDevice device) { 976 if (!Utils.checkCaller()) { 977 Log.w(TAG, "removeBond() - Not allowed for non-active user"); 978 return false; 979 } 980 981 AdapterService service = getService(); 982 if (service == null) return false; 983 return service.removeBond(device); 984 } 985 986 public int getBondState(BluetoothDevice device) { 987 // don't check caller, may be called from system UI 988 AdapterService service = getService(); 989 if (service == null) return BluetoothDevice.BOND_NONE; 990 return service.getBondState(device); 991 } 992 993 public int getConnectionState(BluetoothDevice device) { 994 AdapterService service = getService(); 995 if (service == null) return 0; 996 return service.getConnectionState(device); 997 } 998 999 public String getRemoteName(BluetoothDevice device) { 1000 if (!Utils.checkCallerAllowManagedProfiles(mService)) { 1001 Log.w(TAG, "getRemoteName() - Not allowed for non-active user"); 1002 return null; 1003 } 1004 1005 AdapterService service = getService(); 1006 if (service == null) return null; 1007 return service.getRemoteName(device); 1008 } 1009 1010 public int getRemoteType(BluetoothDevice device) { 1011 if (!Utils.checkCallerAllowManagedProfiles(mService)) { 1012 Log.w(TAG, "getRemoteType() - Not allowed for non-active user"); 1013 return BluetoothDevice.DEVICE_TYPE_UNKNOWN; 1014 } 1015 1016 AdapterService service = getService(); 1017 if (service == null) return BluetoothDevice.DEVICE_TYPE_UNKNOWN; 1018 return service.getRemoteType(device); 1019 } 1020 1021 public String getRemoteAlias(BluetoothDevice device) { 1022 if (!Utils.checkCallerAllowManagedProfiles(mService)) { 1023 Log.w(TAG, "getRemoteAlias() - Not allowed for non-active user"); 1024 return null; 1025 } 1026 1027 AdapterService service = getService(); 1028 if (service == null) return null; 1029 return service.getRemoteAlias(device); 1030 } 1031 1032 public boolean setRemoteAlias(BluetoothDevice device, String name) { 1033 if (!Utils.checkCaller()) { 1034 Log.w(TAG, "setRemoteAlias() - Not allowed for non-active user"); 1035 return false; 1036 } 1037 1038 AdapterService service = getService(); 1039 if (service == null) return false; 1040 return service.setRemoteAlias(device, name); 1041 } 1042 1043 public int getRemoteClass(BluetoothDevice device) { 1044 if (!Utils.checkCallerAllowManagedProfiles(mService)) { 1045 Log.w(TAG, "getRemoteClass() - Not allowed for non-active user"); 1046 return 0; 1047 } 1048 1049 AdapterService service = getService(); 1050 if (service == null) return 0; 1051 return service.getRemoteClass(device); 1052 } 1053 1054 public ParcelUuid[] getRemoteUuids(BluetoothDevice device) { 1055 if (!Utils.checkCallerAllowManagedProfiles(mService)) { 1056 Log.w(TAG, "getRemoteUuids() - Not allowed for non-active user"); 1057 return new ParcelUuid[0]; 1058 } 1059 1060 AdapterService service = getService(); 1061 if (service == null) return new ParcelUuid[0]; 1062 return service.getRemoteUuids(device); 1063 } 1064 1065 public boolean fetchRemoteUuids(BluetoothDevice device) { 1066 if (!Utils.checkCallerAllowManagedProfiles(mService)) { 1067 Log.w(TAG, "fetchRemoteUuids() - Not allowed for non-active user"); 1068 return false; 1069 } 1070 1071 AdapterService service = getService(); 1072 if (service == null) return false; 1073 return service.fetchRemoteUuids(device); 1074 } 1075 1076 1077 1078 public boolean setPin(BluetoothDevice device, boolean accept, int len, byte[] pinCode) { 1079 if (!Utils.checkCaller()) { 1080 Log.w(TAG, "setPin() - Not allowed for non-active user"); 1081 return false; 1082 } 1083 1084 AdapterService service = getService(); 1085 if (service == null) return false; 1086 return service.setPin(device, accept, len, pinCode); 1087 } 1088 1089 public boolean setPasskey(BluetoothDevice device, boolean accept, int len, byte[] passkey) { 1090 if (!Utils.checkCaller()) { 1091 Log.w(TAG, "setPasskey() - Not allowed for non-active user"); 1092 return false; 1093 } 1094 1095 AdapterService service = getService(); 1096 if (service == null) return false; 1097 return service.setPasskey(device, accept, len, passkey); 1098 } 1099 1100 public boolean setPairingConfirmation(BluetoothDevice device, boolean accept) { 1101 if (!Utils.checkCaller()) { 1102 Log.w(TAG, "setPairingConfirmation() - Not allowed for non-active user"); 1103 return false; 1104 } 1105 1106 AdapterService service = getService(); 1107 if (service == null) return false; 1108 return service.setPairingConfirmation(device, accept); 1109 } 1110 1111 public int getPhonebookAccessPermission(BluetoothDevice device) { 1112 if (!Utils.checkCaller()) { 1113 Log.w(TAG, "getPhonebookAccessPermission() - Not allowed for non-active user"); 1114 return BluetoothDevice.ACCESS_UNKNOWN; 1115 } 1116 1117 AdapterService service = getService(); 1118 if (service == null) return BluetoothDevice.ACCESS_UNKNOWN; 1119 return service.getPhonebookAccessPermission(device); 1120 } 1121 1122 public boolean setPhonebookAccessPermission(BluetoothDevice device, int value) { 1123 if (!Utils.checkCaller()) { 1124 Log.w(TAG, "setPhonebookAccessPermission() - Not allowed for non-active user"); 1125 return false; 1126 } 1127 1128 AdapterService service = getService(); 1129 if (service == null) return false; 1130 return service.setPhonebookAccessPermission(device, value); 1131 } 1132 1133 public int getMessageAccessPermission(BluetoothDevice device) { 1134 if (!Utils.checkCaller()) { 1135 Log.w(TAG, "getMessageAccessPermission() - Not allowed for non-active user"); 1136 return BluetoothDevice.ACCESS_UNKNOWN; 1137 } 1138 1139 AdapterService service = getService(); 1140 if (service == null) return BluetoothDevice.ACCESS_UNKNOWN; 1141 return service.getMessageAccessPermission(device); 1142 } 1143 1144 public boolean setMessageAccessPermission(BluetoothDevice device, int value) { 1145 if (!Utils.checkCaller()) { 1146 Log.w(TAG, "setMessageAccessPermission() - Not allowed for non-active user"); 1147 return false; 1148 } 1149 1150 AdapterService service = getService(); 1151 if (service == null) return false; 1152 return service.setMessageAccessPermission(device, value); 1153 } 1154 1155 public int getSimAccessPermission(BluetoothDevice device) { 1156 if (!Utils.checkCaller()) { 1157 Log.w(TAG, "getSimAccessPermission() - Not allowed for non-active user"); 1158 return BluetoothDevice.ACCESS_UNKNOWN; 1159 } 1160 1161 AdapterService service = getService(); 1162 if (service == null) return BluetoothDevice.ACCESS_UNKNOWN; 1163 return service.getSimAccessPermission(device); 1164 } 1165 1166 public boolean setSimAccessPermission(BluetoothDevice device, int value) { 1167 if (!Utils.checkCaller()) { 1168 Log.w(TAG, "setSimAccessPermission() - Not allowed for non-active user"); 1169 return false; 1170 } 1171 1172 AdapterService service = getService(); 1173 if (service == null) return false; 1174 return service.setSimAccessPermission(device, value); 1175 } 1176 1177 public void sendConnectionStateChange(BluetoothDevice 1178 device, int profile, int state, int prevState) { 1179 AdapterService service = getService(); 1180 if (service == null) return; 1181 service.sendConnectionStateChange(device, profile, state, prevState); 1182 } 1183 1184 public ParcelFileDescriptor connectSocket(BluetoothDevice device, int type, 1185 ParcelUuid uuid, int port, int flag) { 1186 if (!Utils.checkCallerAllowManagedProfiles(mService)) { 1187 Log.w(TAG, "connectSocket() - Not allowed for non-active user"); 1188 return null; 1189 } 1190 1191 AdapterService service = getService(); 1192 if (service == null) return null; 1193 return service.connectSocket(device, type, uuid, port, flag); 1194 } 1195 1196 public ParcelFileDescriptor createSocketChannel(int type, String serviceName, 1197 ParcelUuid uuid, int port, int flag) { 1198 if (!Utils.checkCallerAllowManagedProfiles(mService)) { 1199 Log.w(TAG, "createSocketChannel() - Not allowed for non-active user"); 1200 return null; 1201 } 1202 1203 AdapterService service = getService(); 1204 if (service == null) return null; 1205 return service.createSocketChannel(type, serviceName, uuid, port, flag); 1206 } 1207 public boolean sdpSearch(BluetoothDevice device, ParcelUuid uuid) { 1208 if (!Utils.checkCaller()) { 1209 Log.w(TAG,"sdpSea(): not allowed for non-active user"); 1210 return false; 1211 } 1212 1213 AdapterService service = getService(); 1214 if (service == null) return false; 1215 return service.sdpSearch(device,uuid); 1216 } 1217 1218 public boolean configHciSnoopLog(boolean enable) { 1219 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 1220 EventLog.writeEvent(0x534e4554 /* SNET */, "Bluetooth", Binder.getCallingUid(), 1221 "configHciSnoopLog() - Not allowed for non-active user b/18643224"); 1222 return false; 1223 } 1224 1225 AdapterService service = getService(); 1226 if (service == null) return false; 1227 return service.configHciSnoopLog(enable); 1228 } 1229 1230 public void registerCallback(IBluetoothCallback cb) { 1231 AdapterService service = getService(); 1232 if (service == null) return ; 1233 service.registerCallback(cb); 1234 } 1235 1236 public void unregisterCallback(IBluetoothCallback cb) { 1237 AdapterService service = getService(); 1238 if (service == null) return ; 1239 service.unregisterCallback(cb); 1240 } 1241 1242 public boolean isMultiAdvertisementSupported() { 1243 AdapterService service = getService(); 1244 if (service == null) return false; 1245 return service.isMultiAdvertisementSupported(); 1246 } 1247 1248 public boolean isPeripheralModeSupported() { 1249 AdapterService service = getService(); 1250 if (service == null) return false; 1251 return service.isPeripheralModeSupported(); 1252 } 1253 1254 public boolean isOffloadedFilteringSupported() { 1255 AdapterService service = getService(); 1256 if (service == null) return false; 1257 int val = service.getNumOfOffloadedScanFilterSupported(); 1258 return (val >= MIN_OFFLOADED_FILTERS); 1259 } 1260 1261 public boolean isOffloadedScanBatchingSupported() { 1262 AdapterService service = getService(); 1263 if (service == null) return false; 1264 int val = service.getOffloadedScanResultStorage(); 1265 return (val >= MIN_OFFLOADED_SCAN_STORAGE_BYTES); 1266 } 1267 1268 public boolean isActivityAndEnergyReportingSupported() { 1269 AdapterService service = getService(); 1270 if (service == null) return false; 1271 return service.isActivityAndEnergyReportingSupported(); 1272 } 1273 1274 public void getActivityEnergyInfoFromController() { 1275 AdapterService service = getService(); 1276 if (service == null) return; 1277 service.getActivityEnergyInfoFromController(); 1278 } 1279 1280 public BluetoothActivityEnergyInfo reportActivityInfo() { 1281 AdapterService service = getService(); 1282 if (service == null) return null; 1283 return service.reportActivityInfo(); 1284 } 1285 1286 public int numOfHwTrackFiltersAvailable() { 1287 AdapterService service = getService(); 1288 if (service == null) return 0; 1289 //ToDo: Accounting of how many filters hw can do, capability, 1290 //vs how many have been used by current filters by ScanManager 1291 return 5; 1292 } 1293 1294 public String dump() { 1295 AdapterService service = getService(); 1296 if (service == null) { 1297 return "AdapterService is null"; 1298 } 1299 return service.dump(); 1300 } 1301 1302 public void onLeServiceUp(){ 1303 AdapterService service = getService(); 1304 if (service == null) return; 1305 service.onLeServiceUp(); 1306 } 1307 1308 public void onBrEdrDown(){ 1309 AdapterService service = getService(); 1310 if (service == null) return; 1311 service.onBrEdrDown(); 1312 } 1313 }; 1314 1315 // ----API Methods-------- 1316 1317 boolean isEnabled() { 1318 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1319 return mAdapterProperties.getState() == BluetoothAdapter.STATE_ON; 1320 } 1321 1322 int getState() { 1323 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1324 if (mAdapterProperties != null) return mAdapterProperties.getState(); 1325 return BluetoothAdapter.STATE_OFF; 1326 } 1327 1328 boolean enable() { 1329 return enable (false); 1330 } 1331 1332 public boolean enableNoAutoConnect() { 1333 return enable (true); 1334 } 1335 1336 public synchronized boolean enable(boolean quietMode) { 1337 enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, "Need BLUETOOTH ADMIN permission"); 1338 1339 debugLog("enable() - Enable called with quiet mode status = " + mQuietmode); 1340 mQuietmode = quietMode; 1341 Message m = mAdapterStateMachine.obtainMessage(AdapterState.BLE_TURN_ON); 1342 mAdapterStateMachine.sendMessage(m); 1343 return true; 1344 } 1345 1346 boolean disable() { 1347 enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, "Need BLUETOOTH ADMIN permission"); 1348 1349 debugLog("disable() called..."); 1350 Message m = mAdapterStateMachine.obtainMessage(AdapterState.BLE_TURN_OFF); 1351 mAdapterStateMachine.sendMessage(m); 1352 return true; 1353 } 1354 1355 String getAddress() { 1356 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1357 1358 String addrString = null; 1359 byte[] address = mAdapterProperties.getAddress(); 1360 return Utils.getAddressStringFromByte(address); 1361 } 1362 1363 ParcelUuid[] getUuids() { 1364 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1365 1366 return mAdapterProperties.getUuids(); 1367 } 1368 1369 String getName() { 1370 enforceCallingOrSelfPermission(BLUETOOTH_PERM, 1371 "Need BLUETOOTH permission"); 1372 1373 try { 1374 return mAdapterProperties.getName(); 1375 } catch (Throwable t) { 1376 debugLog("getName() - Unexpected exception (" + t + ")"); 1377 } 1378 return null; 1379 } 1380 1381 boolean setName(String name) { 1382 enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, 1383 "Need BLUETOOTH ADMIN permission"); 1384 1385 return mAdapterProperties.setName(name); 1386 } 1387 1388 int getScanMode() { 1389 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1390 1391 return mAdapterProperties.getScanMode(); 1392 } 1393 1394 boolean setScanMode(int mode, int duration) { 1395 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1396 1397 setDiscoverableTimeout(duration); 1398 1399 int newMode = convertScanModeToHal(mode); 1400 return mAdapterProperties.setScanMode(newMode); 1401 } 1402 1403 int getDiscoverableTimeout() { 1404 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1405 1406 return mAdapterProperties.getDiscoverableTimeout(); 1407 } 1408 1409 boolean setDiscoverableTimeout(int timeout) { 1410 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1411 1412 return mAdapterProperties.setDiscoverableTimeout(timeout); 1413 } 1414 1415 boolean startDiscovery() { 1416 enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, 1417 "Need BLUETOOTH ADMIN permission"); 1418 1419 return startDiscoveryNative(); 1420 } 1421 1422 boolean cancelDiscovery() { 1423 enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, 1424 "Need BLUETOOTH ADMIN permission"); 1425 1426 return cancelDiscoveryNative(); 1427 } 1428 1429 boolean isDiscovering() { 1430 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1431 1432 return mAdapterProperties.isDiscovering(); 1433 } 1434 1435 BluetoothDevice[] getBondedDevices() { 1436 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1437 return mAdapterProperties.getBondedDevices(); 1438 } 1439 1440 int getAdapterConnectionState() { 1441 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1442 return mAdapterProperties.getConnectionState(); 1443 } 1444 1445 int getProfileConnectionState(int profile) { 1446 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1447 1448 return mAdapterProperties.getProfileConnectionState(profile); 1449 } 1450 boolean sdpSearch(BluetoothDevice device,ParcelUuid uuid) { 1451 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1452 if(mSdpManager != null) { 1453 mSdpManager.sdpSearch(device,uuid); 1454 return true; 1455 } else { 1456 return false; 1457 } 1458 } 1459 1460 1461 boolean createBond(BluetoothDevice device, int transport) { 1462 enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, 1463 "Need BLUETOOTH ADMIN permission"); 1464 DeviceProperties deviceProp = mRemoteDevices.getDeviceProperties(device); 1465 if (deviceProp != null && deviceProp.getBondState() != BluetoothDevice.BOND_NONE) { 1466 return false; 1467 } 1468 1469 // Pairing is unreliable while scanning, so cancel discovery 1470 // Note, remove this when native stack improves 1471 cancelDiscoveryNative(); 1472 1473 Message msg = mBondStateMachine.obtainMessage(BondStateMachine.CREATE_BOND); 1474 msg.obj = device; 1475 msg.arg1 = transport; 1476 mBondStateMachine.sendMessage(msg); 1477 return true; 1478 } 1479 1480 public boolean isQuietModeEnabled() { 1481 debugLog("isQuetModeEnabled() - Enabled = " + mQuietmode); 1482 return mQuietmode; 1483 } 1484 1485 public void autoConnect(){ 1486 if (getState() != BluetoothAdapter.STATE_ON){ 1487 errorLog("autoConnect() - BT is not ON. Exiting autoConnect"); 1488 return; 1489 } 1490 if (isQuietModeEnabled() == false) { 1491 debugLog( "autoConnect() - Initiate auto connection on BT on..."); 1492 autoConnectHeadset(); 1493 autoConnectA2dp(); 1494 } 1495 else { 1496 debugLog( "autoConnect() - BT is in quiet mode. Not initiating auto connections"); 1497 } 1498 } 1499 1500 private void autoConnectHeadset(){ 1501 HeadsetService hsService = HeadsetService.getHeadsetService(); 1502 1503 BluetoothDevice bondedDevices[] = getBondedDevices(); 1504 if ((bondedDevices == null) ||(hsService == null)) { 1505 return; 1506 } 1507 for (BluetoothDevice device : bondedDevices) { 1508 if (hsService.getPriority(device) == BluetoothProfile.PRIORITY_AUTO_CONNECT ){ 1509 debugLog("autoConnectHeadset() - Connecting HFP with " + device.toString()); 1510 hsService.connect(device); 1511 } 1512 } 1513 } 1514 1515 private void autoConnectA2dp(){ 1516 A2dpService a2dpSservice = A2dpService.getA2dpService(); 1517 BluetoothDevice bondedDevices[] = getBondedDevices(); 1518 if ((bondedDevices == null) ||(a2dpSservice == null)) { 1519 return; 1520 } 1521 for (BluetoothDevice device : bondedDevices) { 1522 if (a2dpSservice.getPriority(device) == BluetoothProfile.PRIORITY_AUTO_CONNECT ){ 1523 debugLog("autoConnectA2dp() - Connecting A2DP with " + device.toString()); 1524 a2dpSservice.connect(device); 1525 } 1526 } 1527 } 1528 1529 public void connectOtherProfile(BluetoothDevice device, int firstProfileStatus){ 1530 if ((mHandler.hasMessages(MESSAGE_CONNECT_OTHER_PROFILES) == false) && 1531 (isQuietModeEnabled()== false)){ 1532 Message m = mHandler.obtainMessage(MESSAGE_CONNECT_OTHER_PROFILES); 1533 m.obj = device; 1534 m.arg1 = (int)firstProfileStatus; 1535 mHandler.sendMessageDelayed(m,CONNECT_OTHER_PROFILES_TIMEOUT); 1536 } 1537 } 1538 1539 private void processConnectOtherProfiles (BluetoothDevice device, int firstProfileStatus){ 1540 if (getState()!= BluetoothAdapter.STATE_ON){ 1541 return; 1542 } 1543 HeadsetService hsService = HeadsetService.getHeadsetService(); 1544 A2dpService a2dpService = A2dpService.getA2dpService(); 1545 1546 // if any of the profile service is null, second profile connection not required 1547 if ((hsService == null) ||(a2dpService == null )){ 1548 return; 1549 } 1550 List<BluetoothDevice> a2dpConnDevList= a2dpService.getConnectedDevices(); 1551 List<BluetoothDevice> hfConnDevList= hsService.getConnectedDevices(); 1552 // Check if the device is in disconnected state and if so return 1553 // We ned to connect other profile only if one of the profile is still in connected state 1554 // This is required to avoide a race condition in which profiles would 1555 // automaticlly connect if the disconnection is initiated within 6 seconds of connection 1556 //First profile connection being rejected is an exception 1557 if((hfConnDevList.isEmpty() && a2dpConnDevList.isEmpty())&& 1558 (PROFILE_CONN_CONNECTED == firstProfileStatus)){ 1559 return; 1560 } 1561 if((hfConnDevList.isEmpty()) && 1562 (hsService.getPriority(device) >= BluetoothProfile.PRIORITY_ON)){ 1563 hsService.connect(device); 1564 } 1565 else if((a2dpConnDevList.isEmpty()) && 1566 (a2dpService.getPriority(device) >= BluetoothProfile.PRIORITY_ON)){ 1567 a2dpService.connect(device); 1568 } 1569 } 1570 1571 private void adjustOtherHeadsetPriorities(HeadsetService hsService, 1572 List<BluetoothDevice> connectedDeviceList) { 1573 for (BluetoothDevice device : getBondedDevices()) { 1574 if (hsService.getPriority(device) >= BluetoothProfile.PRIORITY_AUTO_CONNECT && 1575 !connectedDeviceList.contains(device)) { 1576 hsService.setPriority(device, BluetoothProfile.PRIORITY_ON); 1577 } 1578 } 1579 } 1580 1581 private void adjustOtherSinkPriorities(A2dpService a2dpService, 1582 BluetoothDevice connectedDevice) { 1583 for (BluetoothDevice device : getBondedDevices()) { 1584 if (a2dpService.getPriority(device) >= BluetoothProfile.PRIORITY_AUTO_CONNECT && 1585 !device.equals(connectedDevice)) { 1586 a2dpService.setPriority(device, BluetoothProfile.PRIORITY_ON); 1587 } 1588 } 1589 } 1590 1591 void setProfileAutoConnectionPriority (BluetoothDevice device, int profileId){ 1592 if (profileId == BluetoothProfile.HEADSET) { 1593 HeadsetService hsService = HeadsetService.getHeadsetService(); 1594 List<BluetoothDevice> deviceList = hsService.getConnectedDevices(); 1595 if ((hsService != null) && 1596 (BluetoothProfile.PRIORITY_AUTO_CONNECT != hsService.getPriority(device))){ 1597 adjustOtherHeadsetPriorities(hsService, deviceList); 1598 hsService.setPriority(device,BluetoothProfile.PRIORITY_AUTO_CONNECT); 1599 } 1600 } 1601 else if (profileId == BluetoothProfile.A2DP) { 1602 A2dpService a2dpService = A2dpService.getA2dpService(); 1603 if ((a2dpService != null) && 1604 (BluetoothProfile.PRIORITY_AUTO_CONNECT != a2dpService.getPriority(device))){ 1605 adjustOtherSinkPriorities(a2dpService, device); 1606 a2dpService.setPriority(device,BluetoothProfile.PRIORITY_AUTO_CONNECT); 1607 } 1608 } 1609 } 1610 1611 boolean cancelBondProcess(BluetoothDevice device) { 1612 enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, "Need BLUETOOTH ADMIN permission"); 1613 byte[] addr = Utils.getBytesFromAddress(device.getAddress()); 1614 return cancelBondNative(addr); 1615 } 1616 1617 boolean removeBond(BluetoothDevice device) { 1618 enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, "Need BLUETOOTH ADMIN permission"); 1619 DeviceProperties deviceProp = mRemoteDevices.getDeviceProperties(device); 1620 if (deviceProp == null || deviceProp.getBondState() != BluetoothDevice.BOND_BONDED) { 1621 return false; 1622 } 1623 Message msg = mBondStateMachine.obtainMessage(BondStateMachine.REMOVE_BOND); 1624 msg.obj = device; 1625 mBondStateMachine.sendMessage(msg); 1626 return true; 1627 } 1628 1629 int getBondState(BluetoothDevice device) { 1630 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1631 DeviceProperties deviceProp = mRemoteDevices.getDeviceProperties(device); 1632 if (deviceProp == null) { 1633 return BluetoothDevice.BOND_NONE; 1634 } 1635 return deviceProp.getBondState(); 1636 } 1637 1638 int getConnectionState(BluetoothDevice device) { 1639 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1640 byte[] addr = Utils.getBytesFromAddress(device.getAddress()); 1641 return getConnectionStateNative(addr); 1642 } 1643 1644 String getRemoteName(BluetoothDevice device) { 1645 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1646 DeviceProperties deviceProp = mRemoteDevices.getDeviceProperties(device); 1647 if (deviceProp == null) return null; 1648 return deviceProp.getName(); 1649 } 1650 1651 int getRemoteType(BluetoothDevice device) { 1652 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1653 DeviceProperties deviceProp = mRemoteDevices.getDeviceProperties(device); 1654 if (deviceProp == null) return BluetoothDevice.DEVICE_TYPE_UNKNOWN; 1655 return deviceProp.getDeviceType(); 1656 } 1657 1658 String getRemoteAlias(BluetoothDevice device) { 1659 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1660 DeviceProperties deviceProp = mRemoteDevices.getDeviceProperties(device); 1661 if (deviceProp == null) return null; 1662 return deviceProp.getAlias(); 1663 } 1664 1665 boolean setRemoteAlias(BluetoothDevice device, String name) { 1666 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1667 DeviceProperties deviceProp = mRemoteDevices.getDeviceProperties(device); 1668 if (deviceProp == null) return false; 1669 deviceProp.setAlias(name); 1670 return true; 1671 } 1672 1673 int getRemoteClass(BluetoothDevice device) { 1674 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1675 DeviceProperties deviceProp = mRemoteDevices.getDeviceProperties(device); 1676 if (deviceProp == null) return 0; 1677 1678 return deviceProp.getBluetoothClass(); 1679 } 1680 1681 ParcelUuid[] getRemoteUuids(BluetoothDevice device) { 1682 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1683 DeviceProperties deviceProp = mRemoteDevices.getDeviceProperties(device); 1684 if (deviceProp == null) return null; 1685 return deviceProp.getUuids(); 1686 } 1687 1688 boolean fetchRemoteUuids(BluetoothDevice device) { 1689 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1690 mRemoteDevices.fetchUuids(device); 1691 return true; 1692 } 1693 1694 1695 boolean setPin(BluetoothDevice device, boolean accept, int len, byte[] pinCode) { 1696 enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, 1697 "Need BLUETOOTH ADMIN permission"); 1698 DeviceProperties deviceProp = mRemoteDevices.getDeviceProperties(device); 1699 if (deviceProp == null || deviceProp.getBondState() != BluetoothDevice.BOND_BONDING) { 1700 return false; 1701 } 1702 1703 byte[] addr = Utils.getBytesFromAddress(device.getAddress()); 1704 return pinReplyNative(addr, accept, len, pinCode); 1705 } 1706 1707 boolean setPasskey(BluetoothDevice device, boolean accept, int len, byte[] passkey) { 1708 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1709 DeviceProperties deviceProp = mRemoteDevices.getDeviceProperties(device); 1710 if (deviceProp == null || deviceProp.getBondState() != BluetoothDevice.BOND_BONDING) { 1711 return false; 1712 } 1713 1714 byte[] addr = Utils.getBytesFromAddress(device.getAddress()); 1715 return sspReplyNative(addr, AbstractionLayer.BT_SSP_VARIANT_PASSKEY_ENTRY, accept, 1716 Utils.byteArrayToInt(passkey)); 1717 } 1718 1719 boolean setPairingConfirmation(BluetoothDevice device, boolean accept) { 1720 enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, 1721 "Need BLUETOOTH ADMIN permission"); 1722 DeviceProperties deviceProp = mRemoteDevices.getDeviceProperties(device); 1723 if (deviceProp == null || deviceProp.getBondState() != BluetoothDevice.BOND_BONDING) { 1724 return false; 1725 } 1726 1727 byte[] addr = Utils.getBytesFromAddress(device.getAddress()); 1728 return sspReplyNative(addr, AbstractionLayer.BT_SSP_VARIANT_PASSKEY_CONFIRMATION, 1729 accept, 0); 1730 } 1731 1732 int getPhonebookAccessPermission(BluetoothDevice device) { 1733 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1734 SharedPreferences pref = getSharedPreferences(PHONEBOOK_ACCESS_PERMISSION_PREFERENCE_FILE, 1735 Context.MODE_PRIVATE); 1736 if (!pref.contains(device.getAddress())) { 1737 return BluetoothDevice.ACCESS_UNKNOWN; 1738 } 1739 return pref.getBoolean(device.getAddress(), false) 1740 ? BluetoothDevice.ACCESS_ALLOWED : BluetoothDevice.ACCESS_REJECTED; 1741 } 1742 1743 boolean setPhonebookAccessPermission(BluetoothDevice device, int value) { 1744 enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, 1745 "Need BLUETOOTH PRIVILEGED permission"); 1746 SharedPreferences pref = getSharedPreferences(PHONEBOOK_ACCESS_PERMISSION_PREFERENCE_FILE, 1747 Context.MODE_PRIVATE); 1748 SharedPreferences.Editor editor = pref.edit(); 1749 if (value == BluetoothDevice.ACCESS_UNKNOWN) { 1750 editor.remove(device.getAddress()); 1751 } else { 1752 editor.putBoolean(device.getAddress(), value == BluetoothDevice.ACCESS_ALLOWED); 1753 } 1754 return editor.commit(); 1755 } 1756 1757 int getMessageAccessPermission(BluetoothDevice device) { 1758 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1759 SharedPreferences pref = getSharedPreferences(MESSAGE_ACCESS_PERMISSION_PREFERENCE_FILE, 1760 Context.MODE_PRIVATE); 1761 if (!pref.contains(device.getAddress())) { 1762 return BluetoothDevice.ACCESS_UNKNOWN; 1763 } 1764 return pref.getBoolean(device.getAddress(), false) 1765 ? BluetoothDevice.ACCESS_ALLOWED : BluetoothDevice.ACCESS_REJECTED; 1766 } 1767 1768 boolean setMessageAccessPermission(BluetoothDevice device, int value) { 1769 enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, 1770 "Need BLUETOOTH PRIVILEGED permission"); 1771 SharedPreferences pref = getSharedPreferences(MESSAGE_ACCESS_PERMISSION_PREFERENCE_FILE, 1772 Context.MODE_PRIVATE); 1773 SharedPreferences.Editor editor = pref.edit(); 1774 if (value == BluetoothDevice.ACCESS_UNKNOWN) { 1775 editor.remove(device.getAddress()); 1776 } else { 1777 editor.putBoolean(device.getAddress(), value == BluetoothDevice.ACCESS_ALLOWED); 1778 } 1779 return editor.commit(); 1780 } 1781 1782 int getSimAccessPermission(BluetoothDevice device) { 1783 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1784 SharedPreferences pref = getSharedPreferences(SIM_ACCESS_PERMISSION_PREFERENCE_FILE, 1785 Context.MODE_PRIVATE); 1786 if (!pref.contains(device.getAddress())) { 1787 return BluetoothDevice.ACCESS_UNKNOWN; 1788 } 1789 return pref.getBoolean(device.getAddress(), false) 1790 ? BluetoothDevice.ACCESS_ALLOWED : BluetoothDevice.ACCESS_REJECTED; 1791 } 1792 1793 boolean setSimAccessPermission(BluetoothDevice device, int value) { 1794 enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, 1795 "Need BLUETOOTH PRIVILEGED permission"); 1796 SharedPreferences pref = getSharedPreferences(SIM_ACCESS_PERMISSION_PREFERENCE_FILE, 1797 Context.MODE_PRIVATE); 1798 SharedPreferences.Editor editor = pref.edit(); 1799 if (value == BluetoothDevice.ACCESS_UNKNOWN) { 1800 editor.remove(device.getAddress()); 1801 } else { 1802 editor.putBoolean(device.getAddress(), value == BluetoothDevice.ACCESS_ALLOWED); 1803 } 1804 return editor.commit(); 1805 } 1806 1807 void sendConnectionStateChange(BluetoothDevice 1808 device, int profile, int state, int prevState) { 1809 // TODO(BT) permission check? 1810 // Since this is a binder call check if Bluetooth is on still 1811 if (getState() == BluetoothAdapter.STATE_OFF) return; 1812 1813 mAdapterProperties.sendConnectionStateChange(device, profile, state, prevState); 1814 1815 } 1816 1817 ParcelFileDescriptor connectSocket(BluetoothDevice device, int type, 1818 ParcelUuid uuid, int port, int flag) { 1819 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1820 int fd = connectSocketNative(Utils.getBytesFromAddress(device.getAddress()), 1821 type, Utils.uuidToByteArray(uuid), port, flag); 1822 if (fd < 0) { 1823 errorLog("Failed to connect socket"); 1824 return null; 1825 } 1826 return ParcelFileDescriptor.adoptFd(fd); 1827 } 1828 1829 ParcelFileDescriptor createSocketChannel(int type, String serviceName, 1830 ParcelUuid uuid, int port, int flag) { 1831 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1832 int fd = createSocketChannelNative(type, serviceName, 1833 Utils.uuidToByteArray(uuid), port, flag); 1834 if (fd < 0) { 1835 errorLog("Failed to create socket channel"); 1836 return null; 1837 } 1838 return ParcelFileDescriptor.adoptFd(fd); 1839 } 1840 1841 boolean configHciSnoopLog(boolean enable) { 1842 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1843 return configHciSnoopLogNative(enable); 1844 } 1845 1846 void registerCallback(IBluetoothCallback cb) { 1847 mCallbacks.register(cb); 1848 } 1849 1850 void unregisterCallback(IBluetoothCallback cb) { 1851 mCallbacks.unregister(cb); 1852 } 1853 1854 public int getNumOfAdvertisementInstancesSupported() { 1855 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1856 return mAdapterProperties.getNumOfAdvertisementInstancesSupported(); 1857 } 1858 1859 public boolean isMultiAdvertisementSupported() { 1860 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1861 return getNumOfAdvertisementInstancesSupported() >= MIN_ADVT_INSTANCES_FOR_MA; 1862 } 1863 1864 public boolean isRpaOffloadSupported() { 1865 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1866 return mAdapterProperties.isRpaOffloadSupported(); 1867 } 1868 1869 public int getNumOfOffloadedIrkSupported() { 1870 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1871 return mAdapterProperties.getNumOfOffloadedIrkSupported(); 1872 } 1873 1874 public int getNumOfOffloadedScanFilterSupported() { 1875 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1876 return mAdapterProperties.getNumOfOffloadedScanFilterSupported(); 1877 } 1878 1879 public boolean isPeripheralModeSupported() { 1880 return getResources().getBoolean(R.bool.config_bluetooth_le_peripheral_mode_supported); 1881 } 1882 1883 public int getOffloadedScanResultStorage() { 1884 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1885 return mAdapterProperties.getOffloadedScanResultStorage(); 1886 } 1887 1888 private boolean isActivityAndEnergyReportingSupported() { 1889 enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, "Need BLUETOOTH permission"); 1890 return mAdapterProperties.isActivityAndEnergyReportingSupported(); 1891 } 1892 1893 private void getActivityEnergyInfoFromController() { 1894 enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, "Need BLUETOOTH permission"); 1895 if (isActivityAndEnergyReportingSupported()) { 1896 readEnergyInfo(); 1897 } 1898 } 1899 1900 private BluetoothActivityEnergyInfo reportActivityInfo() { 1901 enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, "Need BLUETOOTH permission"); 1902 BluetoothActivityEnergyInfo info = 1903 new BluetoothActivityEnergyInfo(mStackReportedState, mTxTimeTotalMs, 1904 mRxTimeTotalMs, mIdleTimeTotalMs, mEnergyUsedTotalVoltAmpSecMicro); 1905 // Read on clear values; a record of data is created with 1906 // timstamp and new samples are collected until read again 1907 mStackReportedState = 0; 1908 mTxTimeTotalMs = 0; 1909 mRxTimeTotalMs = 0; 1910 mIdleTimeTotalMs = 0; 1911 mEnergyUsedTotalVoltAmpSecMicro = 0; 1912 return info; 1913 } 1914 1915 private String dump() { 1916 StringBuilder sb = new StringBuilder(); 1917 synchronized (mProfiles) { 1918 for (ProfileService profile : mProfiles) { 1919 profile.dump(sb); 1920 } 1921 } 1922 return sb.toString(); 1923 } 1924 1925 public void onLeServiceUp() { 1926 Message m = mAdapterStateMachine.obtainMessage(AdapterState.USER_TURN_ON); 1927 mAdapterStateMachine.sendMessage(m); 1928 } 1929 1930 public void onBrEdrDown() { 1931 Message m = mAdapterStateMachine.obtainMessage(AdapterState.USER_TURN_OFF); 1932 mAdapterStateMachine.sendMessage(m); 1933 } 1934 1935 private static int convertScanModeToHal(int mode) { 1936 switch (mode) { 1937 case BluetoothAdapter.SCAN_MODE_NONE: 1938 return AbstractionLayer.BT_SCAN_MODE_NONE; 1939 case BluetoothAdapter.SCAN_MODE_CONNECTABLE: 1940 return AbstractionLayer.BT_SCAN_MODE_CONNECTABLE; 1941 case BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE: 1942 return AbstractionLayer.BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE; 1943 } 1944 // errorLog("Incorrect scan mode in convertScanModeToHal"); 1945 return -1; 1946 } 1947 1948 static int convertScanModeFromHal(int mode) { 1949 switch (mode) { 1950 case AbstractionLayer.BT_SCAN_MODE_NONE: 1951 return BluetoothAdapter.SCAN_MODE_NONE; 1952 case AbstractionLayer.BT_SCAN_MODE_CONNECTABLE: 1953 return BluetoothAdapter.SCAN_MODE_CONNECTABLE; 1954 case AbstractionLayer.BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE: 1955 return BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE; 1956 } 1957 //errorLog("Incorrect scan mode in convertScanModeFromHal"); 1958 return -1; 1959 } 1960 1961 // This function is called from JNI. It allows native code to set a single wake 1962 // alarm. 1963 private boolean setWakeAlarm(long delayMillis, boolean shouldWake) { 1964 Message m = mHandler.obtainMessage(MESSAGE_SET_WAKE_ALARM); 1965 m.obj = new Long(delayMillis); 1966 // alarm type 1967 m.arg1 = shouldWake ? AlarmManager.ELAPSED_REALTIME_WAKEUP 1968 : AlarmManager.ELAPSED_REALTIME; 1969 mHandler.sendMessage(m); 1970 1971 return true; 1972 } 1973 1974 // If an alarm is already pending and a new request comes in, the alarm 1975 // will be rescheduled (i.e. the previously set alarm will be cancelled). 1976 private void processSetWakeAlarm(long delayMillis, int alarmType) { 1977 if (mPendingAlarm != null) { 1978 mAlarmManager.cancel(mPendingAlarm); 1979 } 1980 1981 long wakeupTime = SystemClock.elapsedRealtime() + delayMillis; 1982 1983 Intent intent = new Intent(ACTION_ALARM_WAKEUP); 1984 mPendingAlarm = PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_ONE_SHOT); 1985 mAlarmManager.setExact(alarmType, wakeupTime, mPendingAlarm); 1986 } 1987 1988 // This function is called from JNI. It allows native code to acquire a single wake lock. 1989 // If the wake lock is already held, this function returns success. Although this function 1990 // only supports acquiring a single wake lock at a time right now, it will eventually be 1991 // extended to allow acquiring an arbitrary number of wake locks. The current interface 1992 // takes |lockName| as a parameter in anticipation of that implementation. 1993 private boolean acquireWakeLock(String lockName) { 1994 if (mWakeLock != null) { 1995 if (!lockName.equals(mWakeLockName)) { 1996 errorLog("Multiple wake lock acquisition attempted; aborting: " + lockName); 1997 return false; 1998 } 1999 2000 // We're already holding the desired wake lock so return success. 2001 if (mWakeLock.isHeld()) { 2002 return true; 2003 } 2004 } 2005 2006 mWakeLockName = lockName; 2007 mWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, lockName); 2008 mWakeLock.acquire(); 2009 return true; 2010 } 2011 2012 // This function is called from JNI. It allows native code to release a wake lock acquired 2013 // by |acquireWakeLock|. If the wake lock is not held, this function returns failure. 2014 // Note that the release() call is also invoked by {@link #cleanup()} so a synchronization is 2015 // needed here. See the comment for |acquireWakeLock| for an explanation of the interface. 2016 private boolean releaseWakeLock(String lockName) { 2017 synchronized (this) { 2018 if (mWakeLock == null) { 2019 errorLog("Repeated wake lock release; aborting release: " + lockName); 2020 return false; 2021 } 2022 2023 mWakeLock.release(); 2024 mWakeLock = null; 2025 mWakeLockName = null; 2026 } 2027 return true; 2028 } 2029 2030 private void energyInfoCallback (int status, int ctrl_state, 2031 long tx_time, long rx_time, long idle_time, long energy_used) 2032 throws RemoteException { 2033 if (ctrl_state >= BluetoothActivityEnergyInfo.BT_STACK_STATE_INVALID && 2034 ctrl_state <= BluetoothActivityEnergyInfo.BT_STACK_STATE_STATE_IDLE) { 2035 mStackReportedState = ctrl_state; 2036 mTxTimeTotalMs += tx_time; 2037 mRxTimeTotalMs += rx_time; 2038 mIdleTimeTotalMs += idle_time; 2039 // Energy is product of mA, V and ms. If the chipset doesn't 2040 // report it, we have to compute it from time 2041 if (energy_used == 0) { 2042 energy_used = ((mTxTimeTotalMs * getTxCurrentMa() 2043 + mRxTimeTotalMs * getRxCurrentMa() 2044 + mIdleTimeTotalMs * getIdleCurrentMa()) * getOperatingMilliVolt())/1000; 2045 } 2046 mEnergyUsedTotalVoltAmpSecMicro += energy_used; 2047 } 2048 2049 if (DBG) { 2050 Log.d(TAG, "energyInfoCallback " + "status = " + status + 2051 "tx_time = " + tx_time + "rx_time = " + rx_time + 2052 "idle_time = " + idle_time + "energy_used = " + energy_used + 2053 "ctrl_state = " + ctrl_state); 2054 } 2055 } 2056 2057 private int getIdleCurrentMa() { 2058 return getResources().getInteger(R.integer.config_bluetooth_idle_cur_ma); 2059 } 2060 2061 private int getTxCurrentMa() { 2062 return getResources().getInteger(R.integer.config_bluetooth_tx_cur_ma); 2063 } 2064 2065 private int getRxCurrentMa() { 2066 return getResources().getInteger(R.integer.config_bluetooth_rx_cur_ma); 2067 } 2068 2069 private int getOperatingMilliVolt() { 2070 return getResources().getInteger(R.integer.config_bluetooth_operating_voltage_mv); 2071 } 2072 2073 private void debugLog(String msg) { 2074 if (DBG) Log.d(TAG, msg); 2075 } 2076 2077 private void errorLog(String msg) { 2078 Log.e(TAG, msg); 2079 } 2080 2081 private final BroadcastReceiver mAlarmBroadcastReceiver = new BroadcastReceiver() { 2082 @Override 2083 public void onReceive(Context context, Intent intent) { 2084 mHandler.sendMessage(mHandler.obtainMessage(MESSAGE_RELEASE_WAKE_ALARM)); 2085 } 2086 }; 2087 2088 private native static void classInitNative(); 2089 private native boolean initNative(); 2090 private native void cleanupNative(); 2091 /*package*/ native boolean enableNative(); 2092 /*package*/ native boolean disableNative(); 2093 /*package*/ native boolean setAdapterPropertyNative(int type, byte[] val); 2094 /*package*/ native boolean getAdapterPropertiesNative(); 2095 /*package*/ native boolean getAdapterPropertyNative(int type); 2096 /*package*/ native boolean setAdapterPropertyNative(int type); 2097 /*package*/ native boolean 2098 setDevicePropertyNative(byte[] address, int type, byte[] val); 2099 /*package*/ native boolean getDevicePropertyNative(byte[] address, int type); 2100 2101 /*package*/ native boolean createBondNative(byte[] address, int transport); 2102 /*package*/ native boolean removeBondNative(byte[] address); 2103 /*package*/ native boolean cancelBondNative(byte[] address); 2104 /*package*/ native boolean sdpSearchNative(byte[] address, byte[] uuid); 2105 2106 /*package*/ native int getConnectionStateNative(byte[] address); 2107 2108 private native boolean startDiscoveryNative(); 2109 private native boolean cancelDiscoveryNative(); 2110 2111 private native boolean pinReplyNative(byte[] address, boolean accept, int len, byte[] pin); 2112 private native boolean sspReplyNative(byte[] address, int type, boolean 2113 accept, int passkey); 2114 2115 /*package*/ native boolean getRemoteServicesNative(byte[] address); 2116 /*package*/ native boolean getRemoteMasInstancesNative(byte[] address); 2117 2118 private native int readEnergyInfo(); 2119 // TODO(BT) move this to ../btsock dir 2120 private native int connectSocketNative(byte[] address, int type, 2121 byte[] uuid, int port, int flag); 2122 private native int createSocketChannelNative(int type, String serviceName, 2123 byte[] uuid, int port, int flag); 2124 2125 /*package*/ native boolean configHciSnoopLogNative(boolean enable); 2126 2127 private native void alarmFiredNative(); 2128 2129 protected void finalize() { 2130 cleanup(); 2131 if (TRACE_REF) { 2132 synchronized (AdapterService.class) { 2133 sRefCount--; 2134 debugLog("finalize() - REFCOUNT: FINALIZED. INSTANCE_COUNT= " + sRefCount); 2135 } 2136 } 2137 } 2138} 2139