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