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