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