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