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