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