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