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