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