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 static com.android.bluetooth.Utils.addressToBytes; 20 import static com.android.bluetooth.Utils.callerIsSystemOrActiveOrManagedUser; 21 import static com.android.bluetooth.Utils.callerIsSystemOrActiveUser; 22 import static com.android.bluetooth.Utils.enforceBluetoothAdminPermission; 23 import static com.android.bluetooth.Utils.enforceBluetoothPermission; 24 import static com.android.bluetooth.Utils.enforceBluetoothPrivilegedPermission; 25 import static com.android.bluetooth.Utils.enforceDumpPermission; 26 import static com.android.bluetooth.Utils.enforceLocalMacAddressPermission; 27 28 import android.annotation.Nullable; 29 import android.app.ActivityManager; 30 import android.app.AlarmManager; 31 import android.app.AppOpsManager; 32 import android.app.PendingIntent; 33 import android.app.PropertyInvalidatedCache; 34 import android.app.Service; 35 import android.app.admin.DevicePolicyManager; 36 import android.bluetooth.BluetoothActivityEnergyInfo; 37 import android.bluetooth.BluetoothAdapter; 38 import android.bluetooth.BluetoothAdapter.ActiveDeviceUse; 39 import android.bluetooth.BluetoothClass; 40 import android.bluetooth.BluetoothDevice; 41 import android.bluetooth.BluetoothProfile; 42 import android.bluetooth.BluetoothProtoEnums; 43 import android.bluetooth.BluetoothUuid; 44 import android.bluetooth.IBluetooth; 45 import android.bluetooth.IBluetoothCallback; 46 import android.bluetooth.IBluetoothMetadataListener; 47 import android.bluetooth.IBluetoothSocketManager; 48 import android.bluetooth.OobData; 49 import android.bluetooth.UidTraffic; 50 import android.content.BroadcastReceiver; 51 import android.content.Context; 52 import android.content.Intent; 53 import android.content.IntentFilter; 54 import android.content.SharedPreferences; 55 import android.content.pm.PackageManager; 56 import android.os.AsyncTask; 57 import android.os.BatteryStats; 58 import android.os.Binder; 59 import android.os.Bundle; 60 import android.os.Handler; 61 import android.os.IBinder; 62 import android.os.Looper; 63 import android.os.Message; 64 import android.os.ParcelUuid; 65 import android.os.PowerManager; 66 import android.os.RemoteCallbackList; 67 import android.os.RemoteException; 68 import android.os.ResultReceiver; 69 import android.os.ServiceManager; 70 import android.os.SystemClock; 71 import android.os.SystemProperties; 72 import android.os.UserHandle; 73 import android.os.UserManager; 74 import android.provider.Settings; 75 import android.text.TextUtils; 76 import android.util.Base64; 77 import android.util.Log; 78 import android.util.SparseArray; 79 80 import com.android.bluetooth.BluetoothMetricsProto; 81 import com.android.bluetooth.BluetoothStatsLog; 82 import com.android.bluetooth.Utils; 83 import com.android.bluetooth.a2dp.A2dpService; 84 import com.android.bluetooth.a2dpsink.A2dpSinkService; 85 import com.android.bluetooth.btservice.RemoteDevices.DeviceProperties; 86 import com.android.bluetooth.btservice.bluetoothkeystore.BluetoothKeystoreService; 87 import com.android.bluetooth.btservice.storage.DatabaseManager; 88 import com.android.bluetooth.btservice.storage.MetadataDatabase; 89 import com.android.bluetooth.gatt.GattService; 90 import com.android.bluetooth.hearingaid.HearingAidService; 91 import com.android.bluetooth.hfp.HeadsetService; 92 import com.android.bluetooth.hfpclient.HeadsetClientService; 93 import com.android.bluetooth.hid.HidDeviceService; 94 import com.android.bluetooth.hid.HidHostService; 95 import com.android.bluetooth.map.BluetoothMapService; 96 import com.android.bluetooth.mapclient.MapClientService; 97 import com.android.bluetooth.pan.PanService; 98 import com.android.bluetooth.pbap.BluetoothPbapService; 99 import com.android.bluetooth.pbapclient.PbapClientService; 100 import com.android.bluetooth.sap.SapService; 101 import com.android.bluetooth.sdp.SdpManager; 102 import com.android.internal.R; 103 import com.android.internal.annotations.VisibleForTesting; 104 import com.android.internal.app.IBatteryStats; 105 import com.android.internal.util.ArrayUtils; 106 107 import com.google.protobuf.InvalidProtocolBufferException; 108 109 import java.io.FileDescriptor; 110 import java.io.FileOutputStream; 111 import java.io.IOException; 112 import java.io.PrintWriter; 113 import java.util.ArrayList; 114 import java.util.Arrays; 115 import java.util.HashMap; 116 import java.util.List; 117 118 public class AdapterService extends Service { 119 private static final String TAG = "BluetoothAdapterService"; 120 private static final boolean DBG = true; 121 private static final boolean VERBOSE = false; 122 private static final int MIN_ADVT_INSTANCES_FOR_MA = 5; 123 private static final int MIN_OFFLOADED_FILTERS = 10; 124 private static final int MIN_OFFLOADED_SCAN_STORAGE_BYTES = 1024; 125 126 private final Object mEnergyInfoLock = new Object(); 127 private int mStackReportedState; 128 private long mTxTimeTotalMs; 129 private long mRxTimeTotalMs; 130 private long mIdleTimeTotalMs; 131 private long mEnergyUsedTotalVoltAmpSecMicro; 132 private final SparseArray<UidTraffic> mUidTraffic = new SparseArray<>(); 133 134 private final ArrayList<ProfileService> mRegisteredProfiles = new ArrayList<>(); 135 private final ArrayList<ProfileService> mRunningProfiles = new ArrayList<>(); 136 137 public static final String ACTION_LOAD_ADAPTER_PROPERTIES = 138 "com.android.bluetooth.btservice.action.LOAD_ADAPTER_PROPERTIES"; 139 public static final String ACTION_SERVICE_STATE_CHANGED = 140 "com.android.bluetooth.btservice.action.STATE_CHANGED"; 141 public static final String EXTRA_ACTION = "action"; 142 public static final int PROFILE_CONN_REJECTED = 2; 143 144 private static final String ACTION_ALARM_WAKEUP = 145 "com.android.bluetooth.btservice.action.ALARM_WAKEUP"; 146 147 static final String BLUETOOTH_BTSNOOP_LOG_MODE_PROPERTY = "persist.bluetooth.btsnooplogmode"; 148 static final String BLUETOOTH_BTSNOOP_DEFAULT_MODE_PROPERTY = 149 "persist.bluetooth.btsnoopdefaultmode"; 150 private String mSnoopLogSettingAtEnable = "empty"; 151 private String mDefaultSnoopLogSettingAtEnable = "empty"; 152 153 public static final String BLUETOOTH_ADMIN_PERM = android.Manifest.permission.BLUETOOTH_ADMIN; 154 public static final String BLUETOOTH_PRIVILEGED = 155 android.Manifest.permission.BLUETOOTH_PRIVILEGED; 156 static final String BLUETOOTH_PERM = android.Manifest.permission.BLUETOOTH; 157 static final String LOCAL_MAC_ADDRESS_PERM = android.Manifest.permission.LOCAL_MAC_ADDRESS; 158 static final String RECEIVE_MAP_PERM = android.Manifest.permission.RECEIVE_BLUETOOTH_MAP; 159 160 private static final String PHONEBOOK_ACCESS_PERMISSION_PREFERENCE_FILE = 161 "phonebook_access_permission"; 162 private static final String MESSAGE_ACCESS_PERMISSION_PREFERENCE_FILE = 163 "message_access_permission"; 164 private static final String SIM_ACCESS_PERMISSION_PREFERENCE_FILE = "sim_access_permission"; 165 166 private static final int CONTROLLER_ENERGY_UPDATE_TIMEOUT_MILLIS = 30; 167 168 private final ArrayList<DiscoveringPackage> mDiscoveringPackages = new ArrayList<>(); 169 170 static { classInitNative()171 classInitNative(); 172 } 173 174 private static AdapterService sAdapterService; 175 getAdapterService()176 public static synchronized AdapterService getAdapterService() { 177 Log.d(TAG, "getAdapterService() - returning " + sAdapterService); 178 return sAdapterService; 179 } 180 setAdapterService(AdapterService instance)181 private static synchronized void setAdapterService(AdapterService instance) { 182 Log.d(TAG, "setAdapterService() - trying to set service to " + instance); 183 if (instance == null) { 184 return; 185 } 186 sAdapterService = instance; 187 } 188 clearAdapterService(AdapterService current)189 private static synchronized void clearAdapterService(AdapterService current) { 190 if (sAdapterService == current) { 191 sAdapterService = null; 192 } 193 } 194 195 private AdapterProperties mAdapterProperties; 196 private AdapterState mAdapterStateMachine; 197 private BondStateMachine mBondStateMachine; 198 private JniCallbacks mJniCallbacks; 199 private RemoteDevices mRemoteDevices; 200 201 /* TODO: Consider to remove the search API from this class, if changed to use call-back */ 202 private SdpManager mSdpManager = null; 203 204 private boolean mNativeAvailable; 205 private boolean mCleaningUp; 206 private final HashMap<BluetoothDevice, ArrayList<IBluetoothMetadataListener>> 207 mMetadataListeners = new HashMap<>(); 208 private final HashMap<String, Integer> mProfileServicesState = new HashMap<String, Integer>(); 209 //Only BluetoothManagerService should be registered 210 private RemoteCallbackList<IBluetoothCallback> mCallbacks; 211 private int mCurrentRequestId; 212 private boolean mQuietmode = false; 213 214 private AlarmManager mAlarmManager; 215 private PendingIntent mPendingAlarm; 216 private IBatteryStats mBatteryStats; 217 private PowerManager mPowerManager; 218 private PowerManager.WakeLock mWakeLock; 219 private String mWakeLockName; 220 private UserManager mUserManager; 221 222 private PhonePolicy mPhonePolicy; 223 private ActiveDeviceManager mActiveDeviceManager; 224 private DatabaseManager mDatabaseManager; 225 private SilenceDeviceManager mSilenceDeviceManager; 226 private AppOpsManager mAppOps; 227 228 private BluetoothSocketManagerBinder mBluetoothSocketManagerBinder; 229 230 private BluetoothKeystoreService mBluetoothKeystoreService; 231 private A2dpService mA2dpService; 232 private A2dpSinkService mA2dpSinkService; 233 private HeadsetService mHeadsetService; 234 private HeadsetClientService mHeadsetClientService; 235 private BluetoothMapService mMapService; 236 private MapClientService mMapClientService; 237 private HidDeviceService mHidDeviceService; 238 private HidHostService mHidHostService; 239 private PanService mPanService; 240 private BluetoothPbapService mPbapService; 241 private PbapClientService mPbapClientService; 242 private HearingAidService mHearingAidService; 243 private SapService mSapService; 244 245 /** 246 * Register a {@link ProfileService} with AdapterService. 247 * 248 * @param profile the service being added. 249 */ addProfile(ProfileService profile)250 public void addProfile(ProfileService profile) { 251 mHandler.obtainMessage(MESSAGE_PROFILE_SERVICE_REGISTERED, profile).sendToTarget(); 252 } 253 254 /** 255 * Unregister a ProfileService with AdapterService. 256 * 257 * @param profile the service being removed. 258 */ removeProfile(ProfileService profile)259 public void removeProfile(ProfileService profile) { 260 mHandler.obtainMessage(MESSAGE_PROFILE_SERVICE_UNREGISTERED, profile).sendToTarget(); 261 } 262 263 /** 264 * Notify AdapterService that a ProfileService has started or stopped. 265 * 266 * @param profile the service being removed. 267 * @param state {@link BluetoothAdapter#STATE_ON} or {@link BluetoothAdapter#STATE_OFF} 268 */ onProfileServiceStateChanged(ProfileService profile, int state)269 public void onProfileServiceStateChanged(ProfileService profile, int state) { 270 if (state != BluetoothAdapter.STATE_ON && state != BluetoothAdapter.STATE_OFF) { 271 throw new IllegalArgumentException(BluetoothAdapter.nameForState(state)); 272 } 273 Message m = mHandler.obtainMessage(MESSAGE_PROFILE_SERVICE_STATE_CHANGED); 274 m.obj = profile; 275 m.arg1 = state; 276 mHandler.sendMessage(m); 277 } 278 279 private static final int MESSAGE_PROFILE_SERVICE_STATE_CHANGED = 1; 280 private static final int MESSAGE_PROFILE_SERVICE_REGISTERED = 2; 281 private static final int MESSAGE_PROFILE_SERVICE_UNREGISTERED = 3; 282 283 class AdapterServiceHandler extends Handler { 284 @Override handleMessage(Message msg)285 public void handleMessage(Message msg) { 286 verboseLog("handleMessage() - Message: " + msg.what); 287 288 switch (msg.what) { 289 case MESSAGE_PROFILE_SERVICE_STATE_CHANGED: 290 verboseLog("handleMessage() - MESSAGE_PROFILE_SERVICE_STATE_CHANGED"); 291 processProfileServiceStateChanged((ProfileService) msg.obj, msg.arg1); 292 break; 293 case MESSAGE_PROFILE_SERVICE_REGISTERED: 294 verboseLog("handleMessage() - MESSAGE_PROFILE_SERVICE_REGISTERED"); 295 registerProfileService((ProfileService) msg.obj); 296 break; 297 case MESSAGE_PROFILE_SERVICE_UNREGISTERED: 298 verboseLog("handleMessage() - MESSAGE_PROFILE_SERVICE_UNREGISTERED"); 299 unregisterProfileService((ProfileService) msg.obj); 300 break; 301 } 302 } 303 registerProfileService(ProfileService profile)304 private void registerProfileService(ProfileService profile) { 305 if (mRegisteredProfiles.contains(profile)) { 306 Log.e(TAG, profile.getName() + " already registered."); 307 return; 308 } 309 mRegisteredProfiles.add(profile); 310 } 311 unregisterProfileService(ProfileService profile)312 private void unregisterProfileService(ProfileService profile) { 313 if (!mRegisteredProfiles.contains(profile)) { 314 Log.e(TAG, profile.getName() + " not registered (UNREGISTER)."); 315 return; 316 } 317 mRegisteredProfiles.remove(profile); 318 } 319 processProfileServiceStateChanged(ProfileService profile, int state)320 private void processProfileServiceStateChanged(ProfileService profile, int state) { 321 switch (state) { 322 case BluetoothAdapter.STATE_ON: 323 if (!mRegisteredProfiles.contains(profile)) { 324 Log.e(TAG, profile.getName() + " not registered (STATE_ON)."); 325 return; 326 } 327 if (mRunningProfiles.contains(profile)) { 328 Log.e(TAG, profile.getName() + " already running."); 329 return; 330 } 331 mRunningProfiles.add(profile); 332 if (GattService.class.getSimpleName().equals(profile.getName())) { 333 enableNative(); 334 } else if (mRegisteredProfiles.size() == Config.getSupportedProfiles().length 335 && mRegisteredProfiles.size() == mRunningProfiles.size()) { 336 mAdapterProperties.onBluetoothReady(); 337 updateUuids(); 338 setBluetoothClassFromConfig(); 339 initProfileServices(); 340 getAdapterPropertyNative(AbstractionLayer.BT_PROPERTY_LOCAL_IO_CAPS); 341 getAdapterPropertyNative(AbstractionLayer.BT_PROPERTY_LOCAL_IO_CAPS_BLE); 342 mAdapterStateMachine.sendMessage(AdapterState.BREDR_STARTED); 343 } 344 break; 345 case BluetoothAdapter.STATE_OFF: 346 if (!mRegisteredProfiles.contains(profile)) { 347 Log.e(TAG, profile.getName() + " not registered (STATE_OFF)."); 348 return; 349 } 350 if (!mRunningProfiles.contains(profile)) { 351 Log.e(TAG, profile.getName() + " not running."); 352 return; 353 } 354 mRunningProfiles.remove(profile); 355 // If only GATT is left, send BREDR_STOPPED. 356 if ((mRunningProfiles.size() == 1 && (GattService.class.getSimpleName() 357 .equals(mRunningProfiles.get(0).getName())))) { 358 mAdapterStateMachine.sendMessage(AdapterState.BREDR_STOPPED); 359 } else if (mRunningProfiles.size() == 0) { 360 disableNative(); 361 } 362 break; 363 default: 364 Log.e(TAG, "Unhandled profile state: " + state); 365 } 366 } 367 } 368 369 private final AdapterServiceHandler mHandler = new AdapterServiceHandler(); 370 updateInteropDatabase()371 private void updateInteropDatabase() { 372 interopDatabaseClearNative(); 373 374 String interopString = Settings.Global.getString(getContentResolver(), 375 Settings.Global.BLUETOOTH_INTEROPERABILITY_LIST); 376 if (interopString == null) { 377 return; 378 } 379 Log.d(TAG, "updateInteropDatabase: [" + interopString + "]"); 380 381 String[] entries = interopString.split(";"); 382 for (String entry : entries) { 383 String[] tokens = entry.split(","); 384 if (tokens.length != 2) { 385 continue; 386 } 387 388 // Get feature 389 int feature = 0; 390 try { 391 feature = Integer.parseInt(tokens[1]); 392 } catch (NumberFormatException e) { 393 Log.e(TAG, "updateInteropDatabase: Invalid feature '" + tokens[1] + "'"); 394 continue; 395 } 396 397 // Get address bytes and length 398 int length = (tokens[0].length() + 1) / 3; 399 if (length < 1 || length > 6) { 400 Log.e(TAG, "updateInteropDatabase: Malformed address string '" + tokens[0] + "'"); 401 continue; 402 } 403 404 byte[] addr = new byte[6]; 405 int offset = 0; 406 for (int i = 0; i < tokens[0].length(); ) { 407 if (tokens[0].charAt(i) == ':') { 408 i += 1; 409 } else { 410 try { 411 addr[offset++] = (byte) Integer.parseInt(tokens[0].substring(i, i + 2), 16); 412 } catch (NumberFormatException e) { 413 offset = 0; 414 break; 415 } 416 i += 2; 417 } 418 } 419 420 // Check if address was parsed ok, otherwise, move on... 421 if (offset == 0) { 422 continue; 423 } 424 425 // Add entry 426 interopDatabaseAddNative(feature, addr, length); 427 } 428 } 429 430 @Override onCreate()431 public void onCreate() { 432 super.onCreate(); 433 debugLog("onCreate()"); 434 mRemoteDevices = new RemoteDevices(this, Looper.getMainLooper()); 435 mRemoteDevices.init(); 436 clearDiscoveringPackages(); 437 mBinder = new AdapterServiceBinder(this); 438 mAdapterProperties = new AdapterProperties(this); 439 mAdapterStateMachine = AdapterState.make(this); 440 mJniCallbacks = new JniCallbacks(this, mAdapterProperties); 441 mBluetoothKeystoreService = new BluetoothKeystoreService(isNiapMode()); 442 mBluetoothKeystoreService.start(); 443 int configCompareResult = mBluetoothKeystoreService.getCompareResult(); 444 initNative(isGuest(), isNiapMode(), configCompareResult); 445 mNativeAvailable = true; 446 mCallbacks = new RemoteCallbackList<IBluetoothCallback>(); 447 mAppOps = getSystemService(AppOpsManager.class); 448 //Load the name and address 449 getAdapterPropertyNative(AbstractionLayer.BT_PROPERTY_BDADDR); 450 getAdapterPropertyNative(AbstractionLayer.BT_PROPERTY_BDNAME); 451 getAdapterPropertyNative(AbstractionLayer.BT_PROPERTY_CLASS_OF_DEVICE); 452 mAlarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE); 453 mPowerManager = (PowerManager) getSystemService(Context.POWER_SERVICE); 454 mUserManager = (UserManager) getSystemService(Context.USER_SERVICE); 455 mBatteryStats = IBatteryStats.Stub.asInterface( 456 ServiceManager.getService(BatteryStats.SERVICE_NAME)); 457 458 mBluetoothKeystoreService.initJni(); 459 460 mSdpManager = SdpManager.init(this); 461 registerReceiver(mAlarmBroadcastReceiver, new IntentFilter(ACTION_ALARM_WAKEUP)); 462 463 // Phone policy is specific to phone implementations and hence if a device wants to exclude 464 // it out then it can be disabled by using the flag below. 465 if (getResources().getBoolean(com.android.bluetooth.R.bool.enable_phone_policy)) { 466 Log.i(TAG, "Phone policy enabled"); 467 mPhonePolicy = new PhonePolicy(this, new ServiceFactory()); 468 mPhonePolicy.start(); 469 } else { 470 Log.i(TAG, "Phone policy disabled"); 471 } 472 473 mActiveDeviceManager = new ActiveDeviceManager(this, new ServiceFactory()); 474 mActiveDeviceManager.start(); 475 476 mDatabaseManager = new DatabaseManager(this); 477 mDatabaseManager.start(MetadataDatabase.createDatabase(this)); 478 479 mSilenceDeviceManager = new SilenceDeviceManager(this, new ServiceFactory(), 480 Looper.getMainLooper()); 481 mSilenceDeviceManager.start(); 482 483 mBluetoothSocketManagerBinder = new BluetoothSocketManagerBinder(this); 484 485 setAdapterService(this); 486 487 invalidateBluetoothCaches(); 488 489 // First call to getSharedPreferences will result in a file read into 490 // memory cache. Call it here asynchronously to avoid potential ANR 491 // in the future 492 new AsyncTask<Void, Void, Void>() { 493 @Override 494 protected Void doInBackground(Void... params) { 495 getSharedPreferences(PHONEBOOK_ACCESS_PERMISSION_PREFERENCE_FILE, 496 Context.MODE_PRIVATE); 497 getSharedPreferences(MESSAGE_ACCESS_PERMISSION_PREFERENCE_FILE, 498 Context.MODE_PRIVATE); 499 getSharedPreferences(SIM_ACCESS_PERMISSION_PREFERENCE_FILE, Context.MODE_PRIVATE); 500 return null; 501 } 502 }.execute(); 503 504 try { 505 int systemUiUid = getApplicationContext().getPackageManager().getPackageUid( 506 "com.android.systemui", PackageManager.MATCH_SYSTEM_ONLY); 507 508 Utils.setSystemUiUid(systemUiUid); 509 } catch (PackageManager.NameNotFoundException e) { 510 // Some platforms, such as wearables do not have a system ui. 511 Log.w(TAG, "Unable to resolve SystemUI's UID.", e); 512 } 513 514 IntentFilter filter = new IntentFilter(Intent.ACTION_USER_SWITCHED); 515 getApplicationContext().registerReceiverForAllUsers(sUserSwitchedReceiver, filter, null, null); 516 int fuid = ActivityManager.getCurrentUser(); 517 Utils.setForegroundUserId(fuid); 518 } 519 520 @Override onBind(Intent intent)521 public IBinder onBind(Intent intent) { 522 debugLog("onBind()"); 523 return mBinder; 524 } 525 526 @Override onUnbind(Intent intent)527 public boolean onUnbind(Intent intent) { 528 debugLog("onUnbind() - calling cleanup"); 529 cleanup(); 530 return super.onUnbind(intent); 531 } 532 533 @Override onDestroy()534 public void onDestroy() { 535 debugLog("onDestroy()"); 536 if (!isMock()) { 537 // TODO(b/27859763) 538 Log.i(TAG, "Force exit to cleanup internal state in Bluetooth stack"); 539 System.exit(0); 540 } 541 } 542 543 public static final BroadcastReceiver sUserSwitchedReceiver = new BroadcastReceiver() { 544 @Override 545 public void onReceive(Context context, Intent intent) { 546 if (Intent.ACTION_USER_SWITCHED.equals(intent.getAction())) { 547 int fuid = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0); 548 Utils.setForegroundUserId(fuid); 549 } 550 } 551 }; 552 bringUpBle()553 void bringUpBle() { 554 debugLog("bleOnProcessStart()"); 555 556 if (getResources().getBoolean( 557 R.bool.config_bluetooth_reload_supported_profiles_when_enabled)) { 558 Config.init(getApplicationContext()); 559 } 560 561 // Reset |mRemoteDevices| whenever BLE is turned off then on 562 // This is to replace the fact that |mRemoteDevices| was 563 // reinitialized in previous code. 564 // 565 // TODO(apanicke): The reason is unclear but 566 // I believe it is to clear the variable every time BLE was 567 // turned off then on. The same effect can be achieved by 568 // calling cleanup but this may not be necessary at all 569 // We should figure out why this is needed later 570 mRemoteDevices.reset(); 571 mAdapterProperties.init(mRemoteDevices); 572 573 debugLog("bleOnProcessStart() - Make Bond State Machine"); 574 mBondStateMachine = BondStateMachine.make(this, mAdapterProperties, mRemoteDevices); 575 576 mJniCallbacks.init(mBondStateMachine, mRemoteDevices); 577 578 try { 579 mBatteryStats.noteResetBleScan(); 580 } catch (RemoteException e) { 581 Log.w(TAG, "RemoteException trying to send a reset to BatteryStats"); 582 } 583 BluetoothStatsLog.write_non_chained(BluetoothStatsLog.BLE_SCAN_STATE_CHANGED, -1, null, 584 BluetoothStatsLog.BLE_SCAN_STATE_CHANGED__STATE__RESET, false, false, false); 585 586 //Start Gatt service 587 setProfileServiceState(GattService.class, BluetoothAdapter.STATE_ON); 588 } 589 bringDownBle()590 void bringDownBle() { 591 stopGattProfileService(); 592 } 593 stateChangeCallback(int status)594 void stateChangeCallback(int status) { 595 if (status == AbstractionLayer.BT_STATE_OFF) { 596 debugLog("stateChangeCallback: disableNative() completed"); 597 mAdapterStateMachine.sendMessage(AdapterState.BLE_STOPPED); 598 } else if (status == AbstractionLayer.BT_STATE_ON) { 599 mAdapterStateMachine.sendMessage(AdapterState.BLE_STARTED); 600 } else { 601 Log.e(TAG, "Incorrect status " + status + " in stateChangeCallback"); 602 } 603 } 604 605 /** 606 * Sets the Bluetooth CoD value of the local adapter if there exists a config value for it. 607 */ setBluetoothClassFromConfig()608 void setBluetoothClassFromConfig() { 609 int bluetoothClassConfig = retrieveBluetoothClassConfig(); 610 if (bluetoothClassConfig != 0) { 611 mAdapterProperties.setBluetoothClass(new BluetoothClass(bluetoothClassConfig)); 612 } 613 } 614 retrieveBluetoothClassConfig()615 private int retrieveBluetoothClassConfig() { 616 return Settings.Global.getInt( 617 getContentResolver(), Settings.Global.BLUETOOTH_CLASS_OF_DEVICE, 0); 618 } 619 startProfileServices()620 void startProfileServices() { 621 debugLog("startCoreServices()"); 622 Class[] supportedProfileServices = Config.getSupportedProfiles(); 623 if (supportedProfileServices.length == 1 && GattService.class.getSimpleName() 624 .equals(supportedProfileServices[0].getSimpleName())) { 625 mAdapterProperties.onBluetoothReady(); 626 updateUuids(); 627 setBluetoothClassFromConfig(); 628 mAdapterStateMachine.sendMessage(AdapterState.BREDR_STARTED); 629 } else { 630 setAllProfileServiceStates(supportedProfileServices, BluetoothAdapter.STATE_ON); 631 } 632 } 633 stopProfileServices()634 void stopProfileServices() { 635 // Make sure to stop classic background tasks now 636 cancelDiscoveryNative(); 637 mAdapterProperties.setScanMode(AbstractionLayer.BT_SCAN_MODE_NONE); 638 639 Class[] supportedProfileServices = Config.getSupportedProfiles(); 640 if (supportedProfileServices.length == 1 && (mRunningProfiles.size() == 1 641 && GattService.class.getSimpleName().equals(mRunningProfiles.get(0).getName()))) { 642 debugLog("stopProfileServices() - No profiles services to stop or already stopped."); 643 mAdapterStateMachine.sendMessage(AdapterState.BREDR_STOPPED); 644 } else { 645 setAllProfileServiceStates(supportedProfileServices, BluetoothAdapter.STATE_OFF); 646 } 647 } 648 stopGattProfileService()649 private void stopGattProfileService() { 650 mAdapterProperties.onBleDisable(); 651 if (mRunningProfiles.size() == 0) { 652 debugLog("stopGattProfileService() - No profiles services to stop."); 653 mAdapterStateMachine.sendMessage(AdapterState.BLE_STOPPED); 654 } 655 setProfileServiceState(GattService.class, BluetoothAdapter.STATE_OFF); 656 } 657 invalidateBluetoothGetStateCache()658 private void invalidateBluetoothGetStateCache() { 659 BluetoothAdapter.invalidateBluetoothGetStateCache(); 660 } 661 updateAdapterState(int prevState, int newState)662 void updateAdapterState(int prevState, int newState) { 663 mAdapterProperties.setState(newState); 664 invalidateBluetoothGetStateCache(); 665 if (mCallbacks != null) { 666 int n = mCallbacks.beginBroadcast(); 667 debugLog("updateAdapterState() - Broadcasting state " + BluetoothAdapter.nameForState( 668 newState) + " to " + n + " receivers."); 669 for (int i = 0; i < n; i++) { 670 try { 671 mCallbacks.getBroadcastItem(i).onBluetoothStateChange(prevState, newState); 672 } catch (RemoteException e) { 673 debugLog("updateAdapterState() - Callback #" + i + " failed (" + e + ")"); 674 } 675 } 676 mCallbacks.finishBroadcast(); 677 } 678 679 // Turn the Adapter all the way off if we are disabling and the snoop log setting changed. 680 if (newState == BluetoothAdapter.STATE_BLE_TURNING_ON) { 681 mSnoopLogSettingAtEnable = 682 SystemProperties.get(BLUETOOTH_BTSNOOP_LOG_MODE_PROPERTY, "empty"); 683 mDefaultSnoopLogSettingAtEnable = 684 Settings.Global.getString(getContentResolver(), 685 Settings.Global.BLUETOOTH_BTSNOOP_DEFAULT_MODE); 686 SystemProperties.set(BLUETOOTH_BTSNOOP_DEFAULT_MODE_PROPERTY, 687 mDefaultSnoopLogSettingAtEnable); 688 } else if (newState == BluetoothAdapter.STATE_BLE_ON 689 && prevState != BluetoothAdapter.STATE_OFF) { 690 String snoopLogSetting = 691 SystemProperties.get(BLUETOOTH_BTSNOOP_LOG_MODE_PROPERTY, "empty"); 692 String snoopDefaultModeSetting = 693 Settings.Global.getString(getContentResolver(), 694 Settings.Global.BLUETOOTH_BTSNOOP_DEFAULT_MODE); 695 696 if (!TextUtils.equals(mSnoopLogSettingAtEnable, snoopLogSetting) 697 || !TextUtils.equals(mDefaultSnoopLogSettingAtEnable, 698 snoopDefaultModeSetting)) { 699 mAdapterStateMachine.sendMessage(AdapterState.BLE_TURN_OFF); 700 } 701 } 702 } 703 cleanup()704 void cleanup() { 705 debugLog("cleanup()"); 706 if (mCleaningUp) { 707 errorLog("cleanup() - Service already starting to cleanup, ignoring request..."); 708 return; 709 } 710 711 clearAdapterService(this); 712 713 mCleaningUp = true; 714 invalidateBluetoothCaches(); 715 716 unregisterReceiver(mAlarmBroadcastReceiver); 717 718 if (mPendingAlarm != null) { 719 mAlarmManager.cancel(mPendingAlarm); 720 mPendingAlarm = null; 721 } 722 723 // This wake lock release may also be called concurrently by 724 // {@link #releaseWakeLock(String lockName)}, so a synchronization is needed here. 725 synchronized (this) { 726 if (mWakeLock != null) { 727 if (mWakeLock.isHeld()) { 728 mWakeLock.release(); 729 } 730 mWakeLock = null; 731 } 732 } 733 734 if (mDatabaseManager != null) { 735 mDatabaseManager.cleanup(); 736 } 737 738 if (mAdapterStateMachine != null) { 739 mAdapterStateMachine.doQuit(); 740 } 741 742 if (mBondStateMachine != null) { 743 mBondStateMachine.doQuit(); 744 } 745 746 if (mRemoteDevices != null) { 747 mRemoteDevices.cleanup(); 748 } 749 750 if (mSdpManager != null) { 751 mSdpManager.cleanup(); 752 mSdpManager = null; 753 } 754 755 if (mBluetoothKeystoreService != null) { 756 mBluetoothKeystoreService.cleanup(); 757 } 758 759 if (mNativeAvailable) { 760 debugLog("cleanup() - Cleaning up adapter native"); 761 cleanupNative(); 762 mNativeAvailable = false; 763 } 764 765 if (mAdapterProperties != null) { 766 mAdapterProperties.cleanup(); 767 } 768 769 if (mJniCallbacks != null) { 770 mJniCallbacks.cleanup(); 771 } 772 773 if (mPhonePolicy != null) { 774 mPhonePolicy.cleanup(); 775 } 776 777 if (mSilenceDeviceManager != null) { 778 mSilenceDeviceManager.cleanup(); 779 } 780 781 if (mActiveDeviceManager != null) { 782 mActiveDeviceManager.cleanup(); 783 } 784 785 if (mProfileServicesState != null) { 786 mProfileServicesState.clear(); 787 } 788 789 if (mBluetoothSocketManagerBinder != null) { 790 mBluetoothSocketManagerBinder.cleanUp(); 791 mBluetoothSocketManagerBinder = null; 792 } 793 794 if (mBinder != null) { 795 mBinder.cleanup(); 796 mBinder = null; //Do not remove. Otherwise Binder leak! 797 } 798 799 if (mCallbacks != null) { 800 mCallbacks.kill(); 801 } 802 } 803 invalidateBluetoothCaches()804 private void invalidateBluetoothCaches() { 805 BluetoothAdapter.invalidateGetProfileConnectionStateCache(); 806 BluetoothAdapter.invalidateIsOffloadedFilteringSupportedCache(); 807 BluetoothDevice.invalidateBluetoothGetBondStateCache(); 808 BluetoothAdapter.invalidateBluetoothGetStateCache(); 809 } 810 setProfileServiceState(Class service, int state)811 private void setProfileServiceState(Class service, int state) { 812 Intent intent = new Intent(this, service); 813 intent.putExtra(EXTRA_ACTION, ACTION_SERVICE_STATE_CHANGED); 814 intent.putExtra(BluetoothAdapter.EXTRA_STATE, state); 815 startService(intent); 816 } 817 setAllProfileServiceStates(Class[] services, int state)818 private void setAllProfileServiceStates(Class[] services, int state) { 819 for (Class service : services) { 820 if (GattService.class.getSimpleName().equals(service.getSimpleName())) { 821 continue; 822 } 823 setProfileServiceState(service, state); 824 } 825 } 826 827 /** 828 * Verifies whether the profile is supported by the local bluetooth adapter by checking a 829 * bitmask of its supported profiles 830 * 831 * @param remoteDeviceUuids is an array of all supported profiles by the remote device 832 * @param localDeviceUuids is an array of all supported profiles by the local device 833 * @param profile is the profile we are checking for support 834 * @param device is the remote device we wish to connect to 835 * @return true if the profile is supported by both the local and remote device, false otherwise 836 */ isSupported(ParcelUuid[] localDeviceUuids, ParcelUuid[] remoteDeviceUuids, int profile, BluetoothDevice device)837 private boolean isSupported(ParcelUuid[] localDeviceUuids, ParcelUuid[] remoteDeviceUuids, 838 int profile, BluetoothDevice device) { 839 if (remoteDeviceUuids == null || remoteDeviceUuids.length == 0) { 840 Log.e(TAG, "isSupported: Remote Device Uuids Empty"); 841 } 842 843 if (profile == BluetoothProfile.HEADSET) { 844 return (ArrayUtils.contains(localDeviceUuids, BluetoothUuid.HSP_AG) 845 && ArrayUtils.contains(remoteDeviceUuids, BluetoothUuid.HSP)) 846 || (ArrayUtils.contains(localDeviceUuids, BluetoothUuid.HFP_AG) 847 && ArrayUtils.contains(remoteDeviceUuids, BluetoothUuid.HFP)); 848 } 849 if (profile == BluetoothProfile.HEADSET_CLIENT) { 850 return ArrayUtils.contains(remoteDeviceUuids, BluetoothUuid.HFP_AG) 851 && ArrayUtils.contains(localDeviceUuids, BluetoothUuid.HFP); 852 } 853 if (profile == BluetoothProfile.A2DP) { 854 return ArrayUtils.contains(remoteDeviceUuids, BluetoothUuid.ADV_AUDIO_DIST) 855 || ArrayUtils.contains(remoteDeviceUuids, BluetoothUuid.A2DP_SINK); 856 } 857 if (profile == BluetoothProfile.A2DP_SINK) { 858 return ArrayUtils.contains(remoteDeviceUuids, BluetoothUuid.ADV_AUDIO_DIST) 859 || ArrayUtils.contains(remoteDeviceUuids, BluetoothUuid.A2DP_SOURCE); 860 } 861 if (profile == BluetoothProfile.OPP) { 862 return ArrayUtils.contains(remoteDeviceUuids, BluetoothUuid.OBEX_OBJECT_PUSH); 863 } 864 if (profile == BluetoothProfile.HID_HOST) { 865 return ArrayUtils.contains(remoteDeviceUuids, BluetoothUuid.HID) 866 || ArrayUtils.contains(remoteDeviceUuids, BluetoothUuid.HOGP); 867 } 868 if (profile == BluetoothProfile.HID_DEVICE) { 869 return mHidDeviceService.getConnectionState(device) 870 == BluetoothProfile.STATE_DISCONNECTED; 871 } 872 if (profile == BluetoothProfile.PAN) { 873 return ArrayUtils.contains(remoteDeviceUuids, BluetoothUuid.NAP); 874 } 875 if (profile == BluetoothProfile.MAP) { 876 return mMapService.getConnectionState(device) == BluetoothProfile.STATE_CONNECTED; 877 } 878 if (profile == BluetoothProfile.PBAP) { 879 return mPbapService.getConnectionState(device) == BluetoothProfile.STATE_CONNECTED; 880 } 881 if (profile == BluetoothProfile.MAP_CLIENT) { 882 return true; 883 } 884 if (profile == BluetoothProfile.PBAP_CLIENT) { 885 return ArrayUtils.contains(localDeviceUuids, BluetoothUuid.PBAP_PCE) 886 && ArrayUtils.contains(remoteDeviceUuids, BluetoothUuid.PBAP_PSE); 887 } 888 if (profile == BluetoothProfile.HEARING_AID) { 889 return ArrayUtils.contains(remoteDeviceUuids, BluetoothUuid.HEARING_AID); 890 } 891 if (profile == BluetoothProfile.SAP) { 892 return ArrayUtils.contains(remoteDeviceUuids, BluetoothUuid.SAP); 893 } 894 895 Log.e(TAG, "isSupported: Unexpected profile passed in to function: " + profile); 896 return false; 897 } 898 899 /** 900 * Checks if any profile is enabled for the given device 901 * 902 * @param device is the device for which we are checking if any profiles are enabled 903 * @return true if any profile is enabled, false otherwise 904 */ isAnyProfileEnabled(BluetoothDevice device)905 private boolean isAnyProfileEnabled(BluetoothDevice device) { 906 907 if (mA2dpService != null && mA2dpService.getConnectionPolicy(device) 908 > BluetoothProfile.CONNECTION_POLICY_FORBIDDEN) { 909 return true; 910 } 911 if (mA2dpSinkService != null && mA2dpSinkService.getConnectionPolicy(device) 912 > BluetoothProfile.CONNECTION_POLICY_FORBIDDEN) { 913 return true; 914 } 915 if (mHeadsetService != null && mHeadsetService.getConnectionPolicy(device) 916 > BluetoothProfile.CONNECTION_POLICY_FORBIDDEN) { 917 return true; 918 } 919 if (mHeadsetClientService != null && mHeadsetClientService.getConnectionPolicy(device) 920 > BluetoothProfile.CONNECTION_POLICY_FORBIDDEN) { 921 return true; 922 } 923 if (mMapClientService != null && mMapClientService.getConnectionPolicy(device) 924 > BluetoothProfile.CONNECTION_POLICY_FORBIDDEN) { 925 return true; 926 } 927 if (mHidHostService != null && mHidHostService.getConnectionPolicy(device) 928 > BluetoothProfile.CONNECTION_POLICY_FORBIDDEN) { 929 return true; 930 } 931 if (mPanService != null && mPanService.getConnectionPolicy(device) 932 > BluetoothProfile.CONNECTION_POLICY_FORBIDDEN) { 933 return true; 934 } 935 if (mPbapClientService != null && mPbapClientService.getConnectionPolicy(device) 936 > BluetoothProfile.CONNECTION_POLICY_FORBIDDEN) { 937 return true; 938 } 939 if (mHearingAidService != null && mHearingAidService.getConnectionPolicy(device) 940 > BluetoothProfile.CONNECTION_POLICY_FORBIDDEN) { 941 return true; 942 } 943 944 return false; 945 } 946 947 /** 948 * Connects only available profiles 949 * (those with {@link BluetoothProfile.CONNECTION_POLICY_ALLOWED}) 950 * 951 * @param device is the device with which we are connecting the profiles 952 * @return true 953 */ connectEnabledProfiles(BluetoothDevice device)954 private boolean connectEnabledProfiles(BluetoothDevice device) { 955 ParcelUuid[] remoteDeviceUuids = getRemoteUuids(device); 956 ParcelUuid[] localDeviceUuids = mAdapterProperties.getUuids(); 957 958 if (mA2dpService != null && isSupported(localDeviceUuids, remoteDeviceUuids, 959 BluetoothProfile.A2DP, device) && mA2dpService.getConnectionPolicy(device) 960 > BluetoothProfile.CONNECTION_POLICY_FORBIDDEN) { 961 Log.i(TAG, "connectEnabledProfiles: Connecting A2dp"); 962 mA2dpService.connect(device); 963 } 964 if (mA2dpSinkService != null && isSupported(localDeviceUuids, remoteDeviceUuids, 965 BluetoothProfile.A2DP_SINK, device) && mA2dpSinkService.getConnectionPolicy(device) 966 > BluetoothProfile.CONNECTION_POLICY_FORBIDDEN) { 967 Log.i(TAG, "connectEnabledProfiles: Connecting A2dp Sink"); 968 mA2dpSinkService.connect(device); 969 } 970 if (mHeadsetService != null && isSupported(localDeviceUuids, remoteDeviceUuids, 971 BluetoothProfile.HEADSET, device) && mHeadsetService.getConnectionPolicy(device) 972 > BluetoothProfile.CONNECTION_POLICY_FORBIDDEN) { 973 Log.i(TAG, "connectEnabledProfiles: Connecting Headset Profile"); 974 mHeadsetService.connect(device); 975 } 976 if (mHeadsetClientService != null && isSupported(localDeviceUuids, remoteDeviceUuids, 977 BluetoothProfile.HEADSET_CLIENT, device) 978 && mHeadsetClientService.getConnectionPolicy(device) 979 > BluetoothProfile.CONNECTION_POLICY_FORBIDDEN) { 980 Log.i(TAG, "connectEnabledProfiles: Connecting HFP"); 981 mHeadsetClientService.connect(device); 982 } 983 if (mMapClientService != null && isSupported(localDeviceUuids, remoteDeviceUuids, 984 BluetoothProfile.MAP_CLIENT, device) 985 && mMapClientService.getConnectionPolicy(device) 986 > BluetoothProfile.CONNECTION_POLICY_FORBIDDEN) { 987 Log.i(TAG, "connectEnabledProfiles: Connecting MAP"); 988 mMapClientService.connect(device); 989 } 990 if (mHidHostService != null && isSupported(localDeviceUuids, remoteDeviceUuids, 991 BluetoothProfile.HID_HOST, device) && mHidHostService.getConnectionPolicy(device) 992 > BluetoothProfile.CONNECTION_POLICY_FORBIDDEN) { 993 Log.i(TAG, "connectEnabledProfiles: Connecting Hid Host Profile"); 994 mHidHostService.connect(device); 995 } 996 if (mPanService != null && isSupported(localDeviceUuids, remoteDeviceUuids, 997 BluetoothProfile.PAN, device) && mPanService.getConnectionPolicy(device) 998 > BluetoothProfile.CONNECTION_POLICY_FORBIDDEN) { 999 Log.i(TAG, "connectEnabledProfiles: Connecting Pan Profile"); 1000 mPanService.connect(device); 1001 } 1002 if (mPbapClientService != null && isSupported(localDeviceUuids, remoteDeviceUuids, 1003 BluetoothProfile.PBAP_CLIENT, device) 1004 && mPbapClientService.getConnectionPolicy(device) 1005 > BluetoothProfile.CONNECTION_POLICY_FORBIDDEN) { 1006 Log.i(TAG, "connectEnabledProfiles: Connecting Pbap"); 1007 mPbapClientService.connect(device); 1008 } 1009 if (mHearingAidService != null && isSupported(localDeviceUuids, remoteDeviceUuids, 1010 BluetoothProfile.HEARING_AID, device) 1011 && mHearingAidService.getConnectionPolicy(device) 1012 > BluetoothProfile.CONNECTION_POLICY_FORBIDDEN) { 1013 Log.i(TAG, "connectEnabledProfiles: Connecting Hearing Aid Profile"); 1014 mHearingAidService.connect(device); 1015 } 1016 1017 return true; 1018 } 1019 1020 /** 1021 * Verifies that all bluetooth profile services are running 1022 * 1023 * @return true if all bluetooth profile services running, false otherwise 1024 */ profileServicesRunning()1025 private boolean profileServicesRunning() { 1026 if (mRegisteredProfiles.size() == Config.getSupportedProfiles().length 1027 && mRegisteredProfiles.size() == mRunningProfiles.size()) { 1028 return true; 1029 } 1030 1031 Log.e(TAG, "profileServicesRunning: One or more supported services not running"); 1032 return false; 1033 } 1034 1035 /** 1036 * Initializes all the profile services fields 1037 */ initProfileServices()1038 private void initProfileServices() { 1039 Log.i(TAG, "initProfileServices: Initializing all bluetooth profile services"); 1040 mA2dpService = A2dpService.getA2dpService(); 1041 mA2dpSinkService = A2dpSinkService.getA2dpSinkService(); 1042 mHeadsetService = HeadsetService.getHeadsetService(); 1043 mHeadsetClientService = HeadsetClientService.getHeadsetClientService(); 1044 mMapService = BluetoothMapService.getBluetoothMapService(); 1045 mMapClientService = MapClientService.getMapClientService(); 1046 mHidDeviceService = HidDeviceService.getHidDeviceService(); 1047 mHidHostService = HidHostService.getHidHostService(); 1048 mPanService = PanService.getPanService(); 1049 mPbapService = BluetoothPbapService.getBluetoothPbapService(); 1050 mPbapClientService = PbapClientService.getPbapClientService(); 1051 mHearingAidService = HearingAidService.getHearingAidService(); 1052 mSapService = SapService.getSapService(); 1053 } 1054 isAvailable()1055 private boolean isAvailable() { 1056 return !mCleaningUp; 1057 } 1058 1059 /** 1060 * Handlers for incoming service calls 1061 */ 1062 private AdapterServiceBinder mBinder; 1063 1064 /** 1065 * The Binder implementation must be declared to be a static class, with 1066 * the AdapterService instance passed in the constructor. Furthermore, 1067 * when the AdapterService shuts down, the reference to the AdapterService 1068 * must be explicitly removed. 1069 * 1070 * Otherwise, a memory leak can occur from repeated starting/stopping the 1071 * service...Please refer to android.os.Binder for further details on 1072 * why an inner instance class should be avoided. 1073 * 1074 */ 1075 @VisibleForTesting 1076 public static class AdapterServiceBinder extends IBluetooth.Stub { 1077 private AdapterService mService; 1078 AdapterServiceBinder(AdapterService svc)1079 AdapterServiceBinder(AdapterService svc) { 1080 mService = svc; 1081 mService.invalidateBluetoothGetStateCache(); 1082 BluetoothAdapter.getDefaultAdapter().disableBluetoothGetStateCache(); 1083 } 1084 cleanup()1085 public void cleanup() { 1086 mService = null; 1087 } 1088 getService()1089 public AdapterService getService() { 1090 if (mService != null && mService.isAvailable()) { 1091 return mService; 1092 } 1093 return null; 1094 } 1095 1096 @Override getState()1097 public int getState() { 1098 // don't check caller, may be called from system UI 1099 AdapterService service = getService(); 1100 if (service == null) { 1101 return BluetoothAdapter.STATE_OFF; 1102 } 1103 1104 enforceBluetoothPermission(service); 1105 1106 return service.getState(); 1107 } 1108 1109 @Override enable(boolean quietMode)1110 public boolean enable(boolean quietMode) { 1111 AdapterService service = getService(); 1112 if (service == null || !callerIsSystemOrActiveUser(TAG, "enable")) { 1113 return false; 1114 } 1115 1116 enforceBluetoothAdminPermission(service); 1117 1118 return service.enable(quietMode); 1119 } 1120 1121 @Override disable()1122 public boolean disable() { 1123 AdapterService service = getService(); 1124 if (service == null || !callerIsSystemOrActiveUser(TAG, "disable")) { 1125 return false; 1126 } 1127 1128 enforceBluetoothAdminPermission(service); 1129 1130 return service.disable(); 1131 } 1132 1133 @Override getAddress()1134 public String getAddress() { 1135 AdapterService service = getService(); 1136 if (service == null || !callerIsSystemOrActiveOrManagedUser(service, TAG, "getAddress")) { 1137 return null; 1138 } 1139 1140 enforceBluetoothPermission(service); 1141 enforceLocalMacAddressPermission(service); 1142 1143 return Utils.getAddressStringFromByte(service.mAdapterProperties.getAddress()); 1144 } 1145 1146 @Override getUuids()1147 public ParcelUuid[] getUuids() { 1148 AdapterService service = getService(); 1149 if (service == null || !callerIsSystemOrActiveUser(TAG, "getUuids")) { 1150 return new ParcelUuid[0]; 1151 } 1152 1153 enforceBluetoothPermission(service); 1154 1155 return service.mAdapterProperties.getUuids(); 1156 } 1157 1158 @Override getName()1159 public String getName() { 1160 AdapterService service = getService(); 1161 if (service == null || !callerIsSystemOrActiveUser(TAG, "getName")) { 1162 return null; 1163 } 1164 1165 enforceBluetoothPermission(service); 1166 1167 return service.getName(); 1168 } 1169 1170 @Override setName(String name)1171 public boolean setName(String name) { 1172 AdapterService service = getService(); 1173 if (service == null || !callerIsSystemOrActiveUser(TAG, "setName")) { 1174 return false; 1175 } 1176 1177 enforceBluetoothAdminPermission(service); 1178 1179 return service.mAdapterProperties.setName(name); 1180 } 1181 1182 @Override getBluetoothClass()1183 public BluetoothClass getBluetoothClass() { 1184 AdapterService service = getService(); 1185 if (service == null || !callerIsSystemOrActiveUser(TAG, "getBluetoothClass")) { 1186 return null; 1187 } 1188 1189 enforceBluetoothAdminPermission(service); 1190 1191 return service.mAdapterProperties.getBluetoothClass(); 1192 } 1193 1194 @Override setBluetoothClass(BluetoothClass bluetoothClass)1195 public boolean setBluetoothClass(BluetoothClass bluetoothClass) { 1196 AdapterService service = getService(); 1197 if (service == null || !callerIsSystemOrActiveUser(TAG, "setBluetoothClass")) { 1198 return false; 1199 } 1200 1201 enforceBluetoothPrivilegedPermission(service); 1202 1203 if (!service.mAdapterProperties.setBluetoothClass(bluetoothClass)) { 1204 return false; 1205 } 1206 1207 return Settings.Global.putInt( 1208 service.getContentResolver(), 1209 Settings.Global.BLUETOOTH_CLASS_OF_DEVICE, 1210 bluetoothClass.getClassOfDevice()); 1211 } 1212 1213 @Override getIoCapability()1214 public int getIoCapability() { 1215 AdapterService service = getService(); 1216 if (service == null || !callerIsSystemOrActiveUser(TAG, "getIoCapability")) { 1217 return BluetoothAdapter.IO_CAPABILITY_UNKNOWN; 1218 } 1219 1220 enforceBluetoothAdminPermission(service); 1221 1222 return service.mAdapterProperties.getIoCapability(); 1223 } 1224 1225 @Override setIoCapability(int capability)1226 public boolean setIoCapability(int capability) { 1227 AdapterService service = getService(); 1228 if (service == null || !callerIsSystemOrActiveUser(TAG, "setIoCapability")) { 1229 return false; 1230 } 1231 1232 enforceBluetoothPrivilegedPermission(service); 1233 1234 if (!isValidIoCapability(capability)) { 1235 return false; 1236 } 1237 1238 return service.mAdapterProperties.setIoCapability(capability); 1239 } 1240 1241 @Override getLeIoCapability()1242 public int getLeIoCapability() { 1243 AdapterService service = getService(); 1244 if (service == null || !callerIsSystemOrActiveUser(TAG, "getLeIoCapability")) { 1245 return BluetoothAdapter.IO_CAPABILITY_UNKNOWN; 1246 } 1247 1248 enforceBluetoothAdminPermission(service); 1249 1250 return service.mAdapterProperties.getLeIoCapability(); 1251 } 1252 1253 @Override setLeIoCapability(int capability)1254 public boolean setLeIoCapability(int capability) { 1255 AdapterService service = getService(); 1256 if (service == null || !callerIsSystemOrActiveUser(TAG, "setLeIoCapability")) { 1257 return false; 1258 } 1259 1260 enforceBluetoothPrivilegedPermission(service); 1261 1262 if (!isValidIoCapability(capability)) { 1263 return false; 1264 } 1265 1266 return service.mAdapterProperties.setLeIoCapability(capability); 1267 } 1268 1269 @Override getScanMode()1270 public int getScanMode() { 1271 AdapterService service = getService(); 1272 if (service == null || !callerIsSystemOrActiveOrManagedUser(service, TAG, "getScanMode")) { 1273 return BluetoothAdapter.SCAN_MODE_NONE; 1274 } 1275 1276 enforceBluetoothPermission(service); 1277 1278 return service.mAdapterProperties.getScanMode(); 1279 } 1280 1281 @Override setScanMode(int mode, int duration)1282 public boolean setScanMode(int mode, int duration) { 1283 AdapterService service = getService(); 1284 if (service == null || !callerIsSystemOrActiveUser(TAG, "setScanMode")) { 1285 return false; 1286 } 1287 1288 enforceBluetoothPermission(service); 1289 1290 service.mAdapterProperties.setDiscoverableTimeout(duration); 1291 return service.mAdapterProperties.setScanMode(convertScanModeToHal(mode)); 1292 } 1293 1294 @Override getDiscoverableTimeout()1295 public int getDiscoverableTimeout() { 1296 AdapterService service = getService(); 1297 if (service == null || !callerIsSystemOrActiveUser(TAG, "getDiscoverableTimeout")) { 1298 return 0; 1299 } 1300 1301 enforceBluetoothPermission(service); 1302 1303 return service.mAdapterProperties.getDiscoverableTimeout(); 1304 } 1305 1306 @Override setDiscoverableTimeout(int timeout)1307 public boolean setDiscoverableTimeout(int timeout) { 1308 AdapterService service = getService(); 1309 if (service == null || !callerIsSystemOrActiveUser(TAG, "setDiscoverableTimeout")) { 1310 return false; 1311 } 1312 1313 enforceBluetoothPermission(service); 1314 1315 return service.mAdapterProperties.setDiscoverableTimeout(timeout); 1316 } 1317 1318 @Override startDiscovery(String callingPackage, String callingFeatureId)1319 public boolean startDiscovery(String callingPackage, String callingFeatureId) { 1320 AdapterService service = getService(); 1321 if (service == null || !callerIsSystemOrActiveUser(TAG, "startDiscovery")) { 1322 return false; 1323 } 1324 1325 enforceBluetoothAdminPermission(service); 1326 1327 return service.startDiscovery(callingPackage, callingFeatureId); 1328 } 1329 1330 @Override cancelDiscovery()1331 public boolean cancelDiscovery() { 1332 AdapterService service = getService(); 1333 if (service == null || !callerIsSystemOrActiveUser(TAG, "cancelDiscovery")) { 1334 return false; 1335 } 1336 1337 enforceBluetoothAdminPermission(service); 1338 1339 service.debugLog("cancelDiscovery"); 1340 return service.cancelDiscoveryNative(); 1341 } 1342 1343 @Override isDiscovering()1344 public boolean isDiscovering() { 1345 AdapterService service = getService(); 1346 if (service == null || !callerIsSystemOrActiveOrManagedUser(service, TAG, "isDiscovering")) { 1347 return false; 1348 } 1349 1350 enforceBluetoothPermission(service); 1351 1352 return service.mAdapterProperties.isDiscovering(); 1353 } 1354 1355 @Override getDiscoveryEndMillis()1356 public long getDiscoveryEndMillis() { 1357 AdapterService service = getService(); 1358 if (service == null || !callerIsSystemOrActiveUser(TAG, "getDiscoveryEndMillis")) { 1359 return -1; 1360 } 1361 1362 enforceBluetoothPrivilegedPermission(service); 1363 1364 return service.mAdapterProperties.discoveryEndMillis(); 1365 } 1366 1367 @Override getMostRecentlyConnectedDevices()1368 public List<BluetoothDevice> getMostRecentlyConnectedDevices() { 1369 // don't check caller, may be called from system UI 1370 AdapterService service = getService(); 1371 if (service == null) { 1372 return new ArrayList<>(); 1373 } 1374 1375 enforceBluetoothAdminPermission(service); 1376 1377 return service.mDatabaseManager.getMostRecentlyConnectedDevices(); 1378 } 1379 1380 @Override getBondedDevices()1381 public BluetoothDevice[] getBondedDevices() { 1382 // don't check caller, may be called from system UI 1383 AdapterService service = getService(); 1384 if (service == null) { 1385 return new BluetoothDevice[0]; 1386 } 1387 1388 enforceBluetoothPermission(service); 1389 1390 return service.getBondedDevices(); 1391 } 1392 1393 @Override getAdapterConnectionState()1394 public int getAdapterConnectionState() { 1395 // don't check caller, may be called from system UI 1396 AdapterService service = getService(); 1397 if (service == null) { 1398 return BluetoothAdapter.STATE_DISCONNECTED; 1399 } 1400 1401 enforceBluetoothPermission(service); 1402 1403 return service.mAdapterProperties.getConnectionState(); 1404 } 1405 1406 /** 1407 * This method has an associated binder cache. The invalidation 1408 * methods must be changed if the logic behind this method changes. 1409 */ 1410 @Override getProfileConnectionState(int profile)1411 public int getProfileConnectionState(int profile) { 1412 AdapterService service = getService(); 1413 if (service == null || !callerIsSystemOrActiveOrManagedUser(service, TAG, "getProfileConnectionState")) { 1414 return BluetoothProfile.STATE_DISCONNECTED; 1415 } 1416 1417 enforceBluetoothPermission(service); 1418 1419 return service.mAdapterProperties.getProfileConnectionState(profile); 1420 } 1421 1422 @Override createBond(BluetoothDevice device, int transport, OobData oobData)1423 public boolean createBond(BluetoothDevice device, int transport, OobData oobData) { 1424 AdapterService service = getService(); 1425 if (service == null || !callerIsSystemOrActiveOrManagedUser(service, TAG, "createBond")) { 1426 return false; 1427 } 1428 1429 enforceBluetoothAdminPermission(service); 1430 1431 return service.createBond(device, transport, oobData); 1432 } 1433 1434 @Override cancelBondProcess(BluetoothDevice device)1435 public boolean cancelBondProcess(BluetoothDevice device) { 1436 AdapterService service = getService(); 1437 if (service == null || !callerIsSystemOrActiveUser(TAG, "cancelBondProcess")) { 1438 return false; 1439 } 1440 1441 enforceBluetoothAdminPermission(service); 1442 1443 DeviceProperties deviceProp = service.mRemoteDevices.getDeviceProperties(device); 1444 if (deviceProp != null) { 1445 deviceProp.setBondingInitiatedLocally(false); 1446 } 1447 1448 return service.cancelBondNative(addressToBytes(device.getAddress())); 1449 } 1450 1451 @Override removeBond(BluetoothDevice device)1452 public boolean removeBond(BluetoothDevice device) { 1453 AdapterService service = getService(); 1454 if (service == null || !callerIsSystemOrActiveUser(TAG, "removeBond")) { 1455 return false; 1456 } 1457 1458 enforceBluetoothAdminPermission(service); 1459 1460 DeviceProperties deviceProp = service.mRemoteDevices.getDeviceProperties(device); 1461 if (deviceProp == null || deviceProp.getBondState() != BluetoothDevice.BOND_BONDED) { 1462 return false; 1463 } 1464 deviceProp.setBondingInitiatedLocally(false); 1465 1466 Message msg = service.mBondStateMachine.obtainMessage(BondStateMachine.REMOVE_BOND); 1467 msg.obj = device; 1468 service.mBondStateMachine.sendMessage(msg); 1469 return true; 1470 } 1471 1472 @Override getBondState(BluetoothDevice device)1473 public int getBondState(BluetoothDevice device) { 1474 // don't check caller, may be called from system UI 1475 AdapterService service = getService(); 1476 if (service == null) { 1477 return BluetoothDevice.BOND_NONE; 1478 } 1479 1480 enforceBluetoothPermission(service); 1481 1482 return service.getBondState(device); 1483 } 1484 1485 @Override isBondingInitiatedLocally(BluetoothDevice device)1486 public boolean isBondingInitiatedLocally(BluetoothDevice device) { 1487 // don't check caller, may be called from system UI 1488 AdapterService service = getService(); 1489 if (service == null) { 1490 return false; 1491 } 1492 1493 enforceBluetoothPermission(service); 1494 1495 DeviceProperties deviceProp = service.mRemoteDevices.getDeviceProperties(device); 1496 return deviceProp != null && deviceProp.isBondingInitiatedLocally(); 1497 } 1498 1499 @Override getSupportedProfiles()1500 public long getSupportedProfiles() { 1501 AdapterService service = getService(); 1502 if (service == null) { 1503 return 0; 1504 } 1505 return Config.getSupportedProfilesBitMask(); 1506 } 1507 1508 @Override getConnectionState(BluetoothDevice device)1509 public int getConnectionState(BluetoothDevice device) { 1510 AdapterService service = getService(); 1511 if (service == null) { 1512 return 0; 1513 } 1514 1515 enforceBluetoothPermission(service); 1516 1517 return service.getConnectionState(device); 1518 } 1519 1520 @Override removeActiveDevice(@ctiveDeviceUse int profiles)1521 public boolean removeActiveDevice(@ActiveDeviceUse int profiles) { 1522 if (!Utils.checkCaller()) { 1523 Log.w(TAG, "removeActiveDevice() - Not allowed for non-active user"); 1524 return false; 1525 } 1526 1527 AdapterService service = getService(); 1528 if (service == null) { 1529 return false; 1530 } 1531 return service.setActiveDevice(null, profiles); 1532 } 1533 1534 @Override setActiveDevice(BluetoothDevice device, @ActiveDeviceUse int profiles)1535 public boolean setActiveDevice(BluetoothDevice device, @ActiveDeviceUse int profiles) { 1536 if (!Utils.checkCaller()) { 1537 Log.w(TAG, "setActiveDevice() - Not allowed for non-active user"); 1538 return false; 1539 } 1540 1541 AdapterService service = getService(); 1542 if (service == null) { 1543 return false; 1544 } 1545 return service.setActiveDevice(device, profiles); 1546 } 1547 1548 @Override connectAllEnabledProfiles(BluetoothDevice device)1549 public boolean connectAllEnabledProfiles(BluetoothDevice device) { 1550 AdapterService service = getService(); 1551 if (service == null || !callerIsSystemOrActiveUser(TAG, "connectAllEnabledProfiles")) { 1552 return false; 1553 } 1554 1555 enforceBluetoothPrivilegedPermission(service); 1556 1557 return service.connectAllEnabledProfiles(device); 1558 } 1559 1560 @Override disconnectAllEnabledProfiles(BluetoothDevice device)1561 public boolean disconnectAllEnabledProfiles(BluetoothDevice device) { 1562 AdapterService service = getService(); 1563 if (service == null | !callerIsSystemOrActiveUser(TAG, "disconnectAllEnabledProfiles")) { 1564 return false; 1565 } 1566 1567 enforceBluetoothPrivilegedPermission(service); 1568 1569 return service.disconnectAllEnabledProfiles(device); 1570 } 1571 1572 @Override getRemoteName(BluetoothDevice device)1573 public String getRemoteName(BluetoothDevice device) { 1574 AdapterService service = getService(); 1575 if (service == null || !callerIsSystemOrActiveOrManagedUser(service, TAG, "getRemoteName")) { 1576 return null; 1577 } 1578 1579 enforceBluetoothPermission(service); 1580 1581 return service.getRemoteName(device); 1582 } 1583 1584 @Override getRemoteType(BluetoothDevice device)1585 public int getRemoteType(BluetoothDevice device) { 1586 AdapterService service = getService(); 1587 if (service == null || !callerIsSystemOrActiveOrManagedUser(service, TAG, "getRemoteType")) { 1588 return BluetoothDevice.DEVICE_TYPE_UNKNOWN; 1589 } 1590 1591 enforceBluetoothPermission(service); 1592 1593 DeviceProperties deviceProp = service.mRemoteDevices.getDeviceProperties(device); 1594 return deviceProp != null ? deviceProp.getDeviceType() : BluetoothDevice.DEVICE_TYPE_UNKNOWN; 1595 } 1596 1597 @Override getRemoteAlias(BluetoothDevice device)1598 public String getRemoteAlias(BluetoothDevice device) { 1599 AdapterService service = getService(); 1600 if (service == null || !callerIsSystemOrActiveOrManagedUser(service, TAG, "getRemoteAlias")) { 1601 return null; 1602 } 1603 1604 enforceBluetoothPermission(service); 1605 1606 DeviceProperties deviceProp = service.mRemoteDevices.getDeviceProperties(device); 1607 return deviceProp != null ? deviceProp.getAlias() : null; 1608 } 1609 1610 @Override setRemoteAlias(BluetoothDevice device, String name)1611 public boolean setRemoteAlias(BluetoothDevice device, String name) { 1612 AdapterService service = getService(); 1613 if (service == null || !callerIsSystemOrActiveUser(TAG, "setRemoteAlias")) { 1614 return false; 1615 } 1616 1617 enforceBluetoothPermission(service); 1618 1619 DeviceProperties deviceProp = service.mRemoteDevices.getDeviceProperties(device); 1620 if (deviceProp == null) { 1621 return false; 1622 } 1623 deviceProp.setAlias(device, name); 1624 return true; 1625 } 1626 1627 @Override getRemoteClass(BluetoothDevice device)1628 public int getRemoteClass(BluetoothDevice device) { 1629 AdapterService service = getService(); 1630 if (service == null || !callerIsSystemOrActiveOrManagedUser(service, TAG, "getRemoteClass")) { 1631 return 0; 1632 } 1633 1634 enforceBluetoothPermission(service); 1635 1636 DeviceProperties deviceProp = service.mRemoteDevices.getDeviceProperties(device); 1637 return deviceProp != null ? deviceProp.getBluetoothClass() : 0; 1638 } 1639 1640 @Override getRemoteUuids(BluetoothDevice device)1641 public ParcelUuid[] getRemoteUuids(BluetoothDevice device) { 1642 AdapterService service = getService(); 1643 if (service == null || !callerIsSystemOrActiveOrManagedUser(service, TAG, "getRemoteUuids")) { 1644 return new ParcelUuid[0]; 1645 } 1646 1647 enforceBluetoothPermission(service); 1648 1649 return service.getRemoteUuids(device); 1650 } 1651 1652 @Override fetchRemoteUuids(BluetoothDevice device)1653 public boolean fetchRemoteUuids(BluetoothDevice device) { 1654 AdapterService service = getService(); 1655 if (service == null || !callerIsSystemOrActiveOrManagedUser(service, TAG, "fetchRemoteUuids")) { 1656 return false; 1657 } 1658 1659 enforceBluetoothPermission(service); 1660 1661 service.mRemoteDevices.fetchUuids(device); 1662 return true; 1663 } 1664 1665 1666 @Override setPin(BluetoothDevice device, boolean accept, int len, byte[] pinCode)1667 public boolean setPin(BluetoothDevice device, boolean accept, int len, byte[] pinCode) { 1668 AdapterService service = getService(); 1669 if (service == null || !callerIsSystemOrActiveUser(TAG, "setPin")) { 1670 return false; 1671 } 1672 1673 enforceBluetoothAdminPermission(service); 1674 1675 DeviceProperties deviceProp = service.mRemoteDevices.getDeviceProperties(device); 1676 // Only allow setting a pin in bonding state, or bonded state in case of security upgrade. 1677 if (deviceProp == null || !deviceProp.isBondingOrBonded()) { 1678 return false; 1679 } 1680 if (pinCode.length != len) { 1681 android.util.EventLog.writeEvent(0x534e4554, "139287605", -1, 1682 "PIN code length mismatch"); 1683 return false; 1684 } 1685 service.logUserBondResponse(device, accept, BluetoothProtoEnums.BOND_SUB_STATE_LOCAL_PIN_REPLIED); 1686 return service.pinReplyNative(addressToBytes(device.getAddress()), accept, len, pinCode); 1687 } 1688 1689 @Override setPasskey(BluetoothDevice device, boolean accept, int len, byte[] passkey)1690 public boolean setPasskey(BluetoothDevice device, boolean accept, int len, byte[] passkey) { 1691 AdapterService service = getService(); 1692 if (service == null || !callerIsSystemOrActiveUser(TAG, "setPasskey")) { 1693 return false; 1694 } 1695 1696 enforceBluetoothPermission(service); 1697 1698 DeviceProperties deviceProp = service.mRemoteDevices.getDeviceProperties(device); 1699 if (deviceProp == null || !deviceProp.isBonding()) { 1700 return false; 1701 } 1702 if (passkey.length != len) { 1703 android.util.EventLog.writeEvent(0x534e4554, "139287605", -1, 1704 "Passkey length mismatch"); 1705 return false; 1706 } 1707 service.logUserBondResponse(device, accept, BluetoothProtoEnums.BOND_SUB_STATE_LOCAL_SSP_REPLIED); 1708 return service.sspReplyNative( 1709 addressToBytes(device.getAddress()), 1710 AbstractionLayer.BT_SSP_VARIANT_PASSKEY_ENTRY, 1711 accept, 1712 Utils.byteArrayToInt(passkey)); 1713 } 1714 1715 @Override setPairingConfirmation(BluetoothDevice device, boolean accept)1716 public boolean setPairingConfirmation(BluetoothDevice device, boolean accept) { 1717 AdapterService service = getService(); 1718 if (service == null || !callerIsSystemOrActiveUser(TAG, "setPairingConfirmation")) { 1719 return false; 1720 } 1721 1722 enforceBluetoothPrivilegedPermission(service); 1723 1724 DeviceProperties deviceProp = service.mRemoteDevices.getDeviceProperties(device); 1725 if (deviceProp == null || !deviceProp.isBonding()) { 1726 return false; 1727 } 1728 service.logUserBondResponse(device, accept, BluetoothProtoEnums.BOND_SUB_STATE_LOCAL_SSP_REPLIED); 1729 return service.sspReplyNative( 1730 addressToBytes(device.getAddress()), 1731 AbstractionLayer.BT_SSP_VARIANT_PASSKEY_CONFIRMATION, 1732 accept, 1733 0); 1734 } 1735 1736 @Override getSilenceMode(BluetoothDevice device)1737 public boolean getSilenceMode(BluetoothDevice device) { 1738 AdapterService service = getService(); 1739 if (service == null || !callerIsSystemOrActiveUser(TAG, "getSilenceMode")) { 1740 return false; 1741 } 1742 1743 enforceBluetoothPrivilegedPermission(service); 1744 1745 return service.mSilenceDeviceManager.getSilenceMode(device); 1746 } 1747 1748 1749 @Override setSilenceMode(BluetoothDevice device, boolean silence)1750 public boolean setSilenceMode(BluetoothDevice device, boolean silence) { 1751 AdapterService service = getService(); 1752 if (service == null || !callerIsSystemOrActiveUser(TAG, "setSilenceMode")) { 1753 return false; 1754 } 1755 1756 enforceBluetoothPrivilegedPermission(service); 1757 1758 service.mSilenceDeviceManager.setSilenceMode(device, silence); 1759 return true; 1760 } 1761 1762 @Override getPhonebookAccessPermission(BluetoothDevice device)1763 public int getPhonebookAccessPermission(BluetoothDevice device) { 1764 AdapterService service = getService(); 1765 if (service == null || !callerIsSystemOrActiveUser(TAG, "getPhonebookAccessPermission")) { 1766 return BluetoothDevice.ACCESS_UNKNOWN; 1767 } 1768 1769 enforceBluetoothPermission(service); 1770 1771 return service.getDeviceAccessFromPrefs(device, PHONEBOOK_ACCESS_PERMISSION_PREFERENCE_FILE); 1772 } 1773 1774 @Override setPhonebookAccessPermission(BluetoothDevice device, int value)1775 public boolean setPhonebookAccessPermission(BluetoothDevice device, int value) { 1776 AdapterService service = getService(); 1777 if (service == null || !callerIsSystemOrActiveUser(TAG, "setPhonebookAccessPermission")) { 1778 return false; 1779 } 1780 1781 enforceBluetoothPrivilegedPermission(service); 1782 1783 service.setPhonebookAccessPermission(device, value); 1784 return true; 1785 } 1786 1787 @Override getMessageAccessPermission(BluetoothDevice device)1788 public int getMessageAccessPermission(BluetoothDevice device) { 1789 AdapterService service = getService(); 1790 if (service == null || !callerIsSystemOrActiveUser(TAG, "getMessageAccessPermission")) { 1791 return BluetoothDevice.ACCESS_UNKNOWN; 1792 } 1793 1794 enforceBluetoothPermission(service); 1795 1796 return service.getDeviceAccessFromPrefs(device, MESSAGE_ACCESS_PERMISSION_PREFERENCE_FILE); 1797 } 1798 1799 @Override setMessageAccessPermission(BluetoothDevice device, int value)1800 public boolean setMessageAccessPermission(BluetoothDevice device, int value) { 1801 AdapterService service = getService(); 1802 if (service == null || !callerIsSystemOrActiveUser(TAG, "setMessageAccessPermission")) { 1803 return false; 1804 } 1805 1806 enforceBluetoothPrivilegedPermission(service); 1807 1808 service.setMessageAccessPermission(device, value); 1809 return true; 1810 } 1811 1812 @Override getSimAccessPermission(BluetoothDevice device)1813 public int getSimAccessPermission(BluetoothDevice device) { 1814 AdapterService service = getService(); 1815 if (service == null || !callerIsSystemOrActiveUser(TAG, "getSimAccessPermission")) { 1816 return BluetoothDevice.ACCESS_UNKNOWN; 1817 } 1818 1819 enforceBluetoothPermission(service); 1820 1821 return service.getDeviceAccessFromPrefs(device, SIM_ACCESS_PERMISSION_PREFERENCE_FILE); 1822 } 1823 1824 @Override setSimAccessPermission(BluetoothDevice device, int value)1825 public boolean setSimAccessPermission(BluetoothDevice device, int value) { 1826 AdapterService service = getService(); 1827 if (service == null || !callerIsSystemOrActiveUser(TAG, "setSimAccessPermission")) { 1828 return false; 1829 } 1830 1831 enforceBluetoothPrivilegedPermission(service); 1832 1833 service.setSimAccessPermission(device, value); 1834 return true; 1835 } 1836 1837 @Override getSocketManager()1838 public IBluetoothSocketManager getSocketManager() { 1839 AdapterService service = getService(); 1840 if (service == null) { 1841 return null; 1842 } 1843 1844 return IBluetoothSocketManager.Stub.asInterface(service.mBluetoothSocketManagerBinder); 1845 } 1846 1847 @Override sdpSearch(BluetoothDevice device, ParcelUuid uuid)1848 public boolean sdpSearch(BluetoothDevice device, ParcelUuid uuid) { 1849 AdapterService service = getService(); 1850 if (service == null || !callerIsSystemOrActiveUser(TAG, "sdpSearch")) { 1851 return false; 1852 } 1853 1854 enforceBluetoothPermission(service); 1855 1856 if (service.mSdpManager == null) { 1857 return false; 1858 } 1859 service.mSdpManager.sdpSearch(device, uuid); 1860 return true; 1861 } 1862 1863 @Override getBatteryLevel(BluetoothDevice device)1864 public int getBatteryLevel(BluetoothDevice device) { 1865 AdapterService service = getService(); 1866 if (service == null || !callerIsSystemOrActiveUser(TAG, "getBatteryLevel")) { 1867 return BluetoothDevice.BATTERY_LEVEL_UNKNOWN; 1868 } 1869 1870 enforceBluetoothPermission(service); 1871 1872 DeviceProperties deviceProp = service.mRemoteDevices.getDeviceProperties(device); 1873 if (deviceProp == null) { 1874 return BluetoothDevice.BATTERY_LEVEL_UNKNOWN; 1875 } 1876 return deviceProp.getBatteryLevel(); 1877 } 1878 1879 @Override getMaxConnectedAudioDevices()1880 public int getMaxConnectedAudioDevices() { 1881 // don't check caller, may be called from system UI 1882 AdapterService service = getService(); 1883 if (service == null) { 1884 return AdapterProperties.MAX_CONNECTED_AUDIO_DEVICES_LOWER_BOND; 1885 } 1886 1887 enforceBluetoothPermission(service); 1888 1889 return service.getMaxConnectedAudioDevices(); 1890 } 1891 1892 //@Override isA2dpOffloadEnabled()1893 public boolean isA2dpOffloadEnabled() { 1894 // don't check caller, may be called from system UI 1895 AdapterService service = getService(); 1896 if (service == null) { 1897 return false; 1898 } 1899 1900 enforceBluetoothPermission(service); 1901 1902 return service.isA2dpOffloadEnabled(); 1903 } 1904 1905 @Override factoryReset()1906 public boolean factoryReset() { 1907 AdapterService service = getService(); 1908 if (service == null) { 1909 return false; 1910 } 1911 1912 enforceBluetoothPrivilegedPermission(service); 1913 1914 if (service.mDatabaseManager != null) { 1915 service.mDatabaseManager.factoryReset(); 1916 } 1917 1918 if (service.mBluetoothKeystoreService != null) { 1919 service.mBluetoothKeystoreService.factoryReset(); 1920 } 1921 1922 return service.factoryResetNative(); 1923 } 1924 1925 @Override registerCallback(IBluetoothCallback callback)1926 public void registerCallback(IBluetoothCallback callback) { 1927 AdapterService service = getService(); 1928 if (service == null || !callerIsSystemOrActiveUser(TAG, "registerCallback")) { 1929 return; 1930 } 1931 1932 enforceBluetoothPrivilegedPermission(service); 1933 1934 service.mCallbacks.register(callback); 1935 } 1936 1937 @Override unregisterCallback(IBluetoothCallback callback)1938 public void unregisterCallback(IBluetoothCallback callback) { 1939 AdapterService service = getService(); 1940 if (service == null || service.mCallbacks == null 1941 || !callerIsSystemOrActiveUser(TAG, "unregisterCallback")) { 1942 return; 1943 } 1944 1945 enforceBluetoothPrivilegedPermission(service); 1946 1947 service.mCallbacks.unregister(callback); 1948 } 1949 1950 @Override isMultiAdvertisementSupported()1951 public boolean isMultiAdvertisementSupported() { 1952 AdapterService service = getService(); 1953 if (service == null) { 1954 return false; 1955 } 1956 1957 enforceBluetoothPermission(service); 1958 1959 int val = service.mAdapterProperties.getNumOfAdvertisementInstancesSupported(); 1960 return val >= MIN_ADVT_INSTANCES_FOR_MA; 1961 } 1962 1963 /** 1964 * This method has an associated binder cache. The invalidation 1965 * methods must be changed if the logic behind this method changes. 1966 */ 1967 @Override isOffloadedFilteringSupported()1968 public boolean isOffloadedFilteringSupported() { 1969 AdapterService service = getService(); 1970 if (service == null) { 1971 return false; 1972 } 1973 1974 enforceBluetoothPermission(service); 1975 1976 int val = service.getNumOfOffloadedScanFilterSupported(); 1977 return val >= MIN_OFFLOADED_FILTERS; 1978 } 1979 1980 @Override isOffloadedScanBatchingSupported()1981 public boolean isOffloadedScanBatchingSupported() { 1982 AdapterService service = getService(); 1983 if (service == null) { 1984 return false; 1985 } 1986 1987 enforceBluetoothPermission(service); 1988 1989 int val = service.getOffloadedScanResultStorage(); 1990 return val >= MIN_OFFLOADED_SCAN_STORAGE_BYTES; 1991 } 1992 1993 @Override isLe2MPhySupported()1994 public boolean isLe2MPhySupported() { 1995 AdapterService service = getService(); 1996 if (service == null) { 1997 return false; 1998 } 1999 2000 enforceBluetoothPermission(service); 2001 2002 return service.isLe2MPhySupported(); 2003 } 2004 2005 @Override isLeCodedPhySupported()2006 public boolean isLeCodedPhySupported() { 2007 AdapterService service = getService(); 2008 if (service == null) { 2009 return false; 2010 } 2011 2012 enforceBluetoothPermission(service); 2013 2014 return service.isLeCodedPhySupported(); 2015 } 2016 2017 @Override isLeExtendedAdvertisingSupported()2018 public boolean isLeExtendedAdvertisingSupported() { 2019 AdapterService service = getService(); 2020 if (service == null) { 2021 return false; 2022 } 2023 2024 enforceBluetoothPermission(service); 2025 2026 return service.isLeExtendedAdvertisingSupported(); 2027 } 2028 2029 @Override isLePeriodicAdvertisingSupported()2030 public boolean isLePeriodicAdvertisingSupported() { 2031 AdapterService service = getService(); 2032 if (service == null) { 2033 return false; 2034 } 2035 2036 enforceBluetoothPermission(service); 2037 2038 return service.isLePeriodicAdvertisingSupported(); 2039 } 2040 2041 @Override getLeMaximumAdvertisingDataLength()2042 public int getLeMaximumAdvertisingDataLength() { 2043 AdapterService service = getService(); 2044 if (service == null) { 2045 return 0; 2046 } 2047 2048 enforceBluetoothPermission(service); 2049 2050 return service.getLeMaximumAdvertisingDataLength(); 2051 } 2052 2053 @Override isActivityAndEnergyReportingSupported()2054 public boolean isActivityAndEnergyReportingSupported() { 2055 AdapterService service = getService(); 2056 if (service == null) { 2057 return false; 2058 } 2059 2060 enforceBluetoothPrivilegedPermission(service); 2061 2062 return service.mAdapterProperties.isActivityAndEnergyReportingSupported(); 2063 } 2064 2065 @Override reportActivityInfo()2066 public BluetoothActivityEnergyInfo reportActivityInfo() { 2067 AdapterService service = getService(); 2068 if (service == null) { 2069 return null; 2070 } 2071 2072 enforceBluetoothPrivilegedPermission(service); 2073 2074 return service.reportActivityInfo(); 2075 } 2076 2077 @Override registerMetadataListener(IBluetoothMetadataListener listener, BluetoothDevice device)2078 public boolean registerMetadataListener(IBluetoothMetadataListener listener, 2079 BluetoothDevice device) { 2080 AdapterService service = getService(); 2081 if (service == null || !callerIsSystemOrActiveUser(TAG, "registerMetadataListener")) { 2082 return false; 2083 } 2084 2085 enforceBluetoothPrivilegedPermission(service); 2086 2087 if (service.mMetadataListeners == null) { 2088 return false; 2089 } 2090 ArrayList<IBluetoothMetadataListener> list = service.mMetadataListeners.get(device); 2091 if (list == null) { 2092 list = new ArrayList<>(); 2093 } else if (list.contains(listener)) { 2094 // The device is already registered with this listener 2095 return true; 2096 } 2097 list.add(listener); 2098 service.mMetadataListeners.put(device, list); 2099 return true; 2100 } 2101 2102 @Override unregisterMetadataListener(BluetoothDevice device)2103 public boolean unregisterMetadataListener(BluetoothDevice device) { 2104 AdapterService service = getService(); 2105 if (service == null 2106 || !callerIsSystemOrActiveUser(TAG, "unregisterMetadataListener")) { 2107 return false; 2108 } 2109 2110 enforceBluetoothPrivilegedPermission(service); 2111 2112 if (service.mMetadataListeners == null) { 2113 return false; 2114 } 2115 if (service.mMetadataListeners.containsKey(device)) { 2116 service.mMetadataListeners.remove(device); 2117 } 2118 return true; 2119 } 2120 2121 @Override setMetadata(BluetoothDevice device, int key, byte[] value)2122 public boolean setMetadata(BluetoothDevice device, int key, byte[] value) { 2123 AdapterService service = getService(); 2124 if (service == null || !callerIsSystemOrActiveUser(TAG, "setMetadata")) { 2125 return false; 2126 } 2127 2128 enforceBluetoothPrivilegedPermission(service); 2129 2130 if (value.length > BluetoothDevice.METADATA_MAX_LENGTH) { 2131 return false; 2132 } 2133 return service.mDatabaseManager.setCustomMeta(device, key, value); 2134 } 2135 2136 @Override getMetadata(BluetoothDevice device, int key)2137 public byte[] getMetadata(BluetoothDevice device, int key) { 2138 AdapterService service = getService(); 2139 if (service == null || !callerIsSystemOrActiveUser(TAG, "getMetadata")) { 2140 return null; 2141 } 2142 2143 enforceBluetoothPrivilegedPermission(service); 2144 2145 return service.mDatabaseManager.getCustomMeta(device, key); 2146 } 2147 2148 @Override requestActivityInfo(ResultReceiver result)2149 public void requestActivityInfo(ResultReceiver result) { 2150 Bundle bundle = new Bundle(); 2151 bundle.putParcelable(BatteryStats.RESULT_RECEIVER_CONTROLLER_KEY, reportActivityInfo()); 2152 result.send(0, bundle); 2153 } 2154 2155 @Override onLeServiceUp()2156 public void onLeServiceUp() { 2157 AdapterService service = getService(); 2158 if (service == null || !callerIsSystemOrActiveUser(TAG, "onLeServiceUp")) { 2159 return; 2160 } 2161 2162 enforceBluetoothPrivilegedPermission(service); 2163 2164 service.mAdapterStateMachine.sendMessage(AdapterState.USER_TURN_ON); 2165 } 2166 2167 @Override onBrEdrDown()2168 public void onBrEdrDown() { 2169 AdapterService service = getService(); 2170 if (service == null || !callerIsSystemOrActiveUser(TAG, "onBrEdrDown")) { 2171 return; 2172 } 2173 2174 enforceBluetoothPrivilegedPermission(service); 2175 2176 service.mAdapterStateMachine.sendMessage(AdapterState.BLE_TURN_OFF); 2177 } 2178 2179 @Override dump(FileDescriptor fd, String[] args)2180 public void dump(FileDescriptor fd, String[] args) { 2181 PrintWriter writer = new PrintWriter(new FileOutputStream(fd)); 2182 AdapterService service = getService(); 2183 if (service == null) { 2184 return; 2185 } 2186 2187 enforceDumpPermission(service); 2188 2189 service.dump(fd, writer, args); 2190 writer.close(); 2191 } 2192 } 2193 2194 // ----API Methods-------- 2195 getState()2196 public int getState() { 2197 if (mAdapterProperties != null) { 2198 return mAdapterProperties.getState(); 2199 } 2200 return BluetoothAdapter.STATE_OFF; 2201 } 2202 enable(boolean quietMode)2203 public synchronized boolean enable(boolean quietMode) { 2204 // Enforce the user restriction for disallowing Bluetooth if it was set. 2205 if (mUserManager.hasUserRestriction(UserManager.DISALLOW_BLUETOOTH, UserHandle.SYSTEM)) { 2206 debugLog("enable() called when Bluetooth was disallowed"); 2207 return false; 2208 } 2209 2210 debugLog("enable() - Enable called with quiet mode status = " + quietMode); 2211 mQuietmode = quietMode; 2212 mAdapterStateMachine.sendMessage(AdapterState.BLE_TURN_ON); 2213 return true; 2214 } 2215 disable()2216 boolean disable() { 2217 debugLog("disable() called with mRunningProfiles.size() = " + mRunningProfiles.size()); 2218 mAdapterStateMachine.sendMessage(AdapterState.USER_TURN_OFF); 2219 return true; 2220 } 2221 getName()2222 public String getName() { 2223 return mAdapterProperties.getName(); 2224 } 2225 isValidIoCapability(int capability)2226 private static boolean isValidIoCapability(int capability) { 2227 if (capability < 0 || capability >= BluetoothAdapter.IO_CAPABILITY_MAX) { 2228 Log.e(TAG, "Invalid IO capability value - " + capability); 2229 return false; 2230 } 2231 2232 return true; 2233 } 2234 getDiscoveringPackages()2235 ArrayList<DiscoveringPackage> getDiscoveringPackages() { 2236 return mDiscoveringPackages; 2237 } 2238 clearDiscoveringPackages()2239 void clearDiscoveringPackages() { 2240 synchronized (mDiscoveringPackages) { 2241 mDiscoveringPackages.clear(); 2242 } 2243 } 2244 startDiscovery(String callingPackage, @Nullable String callingFeatureId)2245 boolean startDiscovery(String callingPackage, @Nullable String callingFeatureId) { 2246 UserHandle callingUser = UserHandle.of(UserHandle.getCallingUserId()); 2247 debugLog("startDiscovery"); 2248 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage); 2249 boolean isQApp = Utils.isQApp(this, callingPackage); 2250 String permission = null; 2251 if (Utils.checkCallerHasNetworkSettingsPermission(this)) { 2252 permission = android.Manifest.permission.NETWORK_SETTINGS; 2253 } else if (Utils.checkCallerHasNetworkSetupWizardPermission(this)) { 2254 permission = android.Manifest.permission.NETWORK_SETUP_WIZARD; 2255 } else if (isQApp) { 2256 if (!Utils.checkCallerHasFineLocation(this, mAppOps, callingPackage, callingFeatureId, 2257 callingUser)) { 2258 return false; 2259 } 2260 permission = android.Manifest.permission.ACCESS_FINE_LOCATION; 2261 } else { 2262 if (!Utils.checkCallerHasCoarseLocation(this, mAppOps, callingPackage, callingFeatureId, 2263 callingUser)) { 2264 return false; 2265 } 2266 permission = android.Manifest.permission.ACCESS_COARSE_LOCATION; 2267 } 2268 2269 synchronized (mDiscoveringPackages) { 2270 mDiscoveringPackages.add(new DiscoveringPackage(callingPackage, permission)); 2271 } 2272 return startDiscoveryNative(); 2273 } 2274 2275 /** 2276 * Same as API method {@link BluetoothAdapter#getBondedDevices()} 2277 * 2278 * @return array of bonded {@link BluetoothDevice} or null on error 2279 */ getBondedDevices()2280 public BluetoothDevice[] getBondedDevices() { 2281 return mAdapterProperties.getBondedDevices(); 2282 } 2283 2284 /** 2285 * Get the database manager to access Bluetooth storage 2286 * 2287 * @return {@link DatabaseManager} or null on error 2288 */ 2289 @VisibleForTesting getDatabase()2290 public DatabaseManager getDatabase() { 2291 return mDatabaseManager; 2292 } 2293 createBond(BluetoothDevice device, int transport, OobData oobData)2294 boolean createBond(BluetoothDevice device, int transport, OobData oobData) { 2295 DeviceProperties deviceProp = mRemoteDevices.getDeviceProperties(device); 2296 if (deviceProp != null && deviceProp.getBondState() != BluetoothDevice.BOND_NONE) { 2297 return false; 2298 } 2299 2300 mRemoteDevices.setBondingInitiatedLocally(Utils.getByteAddress(device)); 2301 2302 // Pairing is unreliable while scanning, so cancel discovery 2303 // Note, remove this when native stack improves 2304 cancelDiscoveryNative(); 2305 2306 Message msg = mBondStateMachine.obtainMessage(BondStateMachine.CREATE_BOND); 2307 msg.obj = device; 2308 msg.arg1 = transport; 2309 2310 if (oobData != null) { 2311 Bundle oobDataBundle = new Bundle(); 2312 oobDataBundle.putParcelable(BondStateMachine.OOBDATA, oobData); 2313 msg.setData(oobDataBundle); 2314 } 2315 mBondStateMachine.sendMessage(msg); 2316 return true; 2317 } 2318 isQuietModeEnabled()2319 public boolean isQuietModeEnabled() { 2320 debugLog("isQuetModeEnabled() - Enabled = " + mQuietmode); 2321 return mQuietmode; 2322 } 2323 updateUuids()2324 public void updateUuids() { 2325 debugLog("updateUuids() - Updating UUIDs for bonded devices"); 2326 BluetoothDevice[] bondedDevices = getBondedDevices(); 2327 if (bondedDevices == null) { 2328 return; 2329 } 2330 2331 for (BluetoothDevice device : bondedDevices) { 2332 mRemoteDevices.updateUuids(device); 2333 } 2334 } 2335 2336 /** 2337 * Update device UUID changed to {@link BondStateMachine} 2338 * 2339 * @param device remote device of interest 2340 */ deviceUuidUpdated(BluetoothDevice device)2341 public void deviceUuidUpdated(BluetoothDevice device) { 2342 // Notify BondStateMachine for SDP complete / UUID changed. 2343 Message msg = mBondStateMachine.obtainMessage(BondStateMachine.UUID_UPDATE); 2344 msg.obj = device; 2345 mBondStateMachine.sendMessage(msg); 2346 } 2347 2348 /** 2349 * Get the bond state of a particular {@link BluetoothDevice} 2350 * 2351 * @param device remote device of interest 2352 * @return bond state <p>Possible values are 2353 * {@link BluetoothDevice#BOND_NONE}, 2354 * {@link BluetoothDevice#BOND_BONDING}, 2355 * {@link BluetoothDevice#BOND_BONDED}. 2356 */ 2357 @VisibleForTesting getBondState(BluetoothDevice device)2358 public int getBondState(BluetoothDevice device) { 2359 DeviceProperties deviceProp = mRemoteDevices.getDeviceProperties(device); 2360 if (deviceProp == null) { 2361 return BluetoothDevice.BOND_NONE; 2362 } 2363 return deviceProp.getBondState(); 2364 } 2365 getConnectionState(BluetoothDevice device)2366 int getConnectionState(BluetoothDevice device) { 2367 return getConnectionStateNative(addressToBytes(device.getAddress())); 2368 } 2369 2370 /** 2371 * Sets device as the active devices for the profiles passed into the function 2372 * 2373 * @param device is the remote bluetooth device 2374 * @param profiles is a constant that references for which profiles we'll be setting the remote 2375 * device as our active device. One of the following: 2376 * {@link BluetoothAdapter#ACTIVE_DEVICE_AUDIO}, 2377 * {@link BluetoothAdapter#ACTIVE_DEVICE_PHONE_CALL} 2378 * {@link BluetoothAdapter#ACTIVE_DEVICE_ALL} 2379 * @return false if profiles value is not one of the constants we accept, true otherwise 2380 */ setActiveDevice(BluetoothDevice device, @ActiveDeviceUse int profiles)2381 public boolean setActiveDevice(BluetoothDevice device, @ActiveDeviceUse int profiles) { 2382 enforceCallingOrSelfPermission( 2383 BLUETOOTH_PRIVILEGED, "Need BLUETOOTH_PRIVILEGED permission"); 2384 2385 boolean setA2dp = false; 2386 boolean setHeadset = false; 2387 2388 // Determine for which profiles we want to set device as our active device 2389 switch(profiles) { 2390 case BluetoothAdapter.ACTIVE_DEVICE_AUDIO: 2391 setA2dp = true; 2392 break; 2393 case BluetoothAdapter.ACTIVE_DEVICE_PHONE_CALL: 2394 setHeadset = true; 2395 break; 2396 case BluetoothAdapter.ACTIVE_DEVICE_ALL: 2397 setA2dp = true; 2398 setHeadset = true; 2399 break; 2400 default: 2401 return false; 2402 } 2403 2404 if (setA2dp && mA2dpService != null && (device == null 2405 || mA2dpService.getConnectionPolicy(device) 2406 == BluetoothProfile.CONNECTION_POLICY_ALLOWED)) { 2407 Log.i(TAG, "setActiveDevice: Setting active A2dp device " + device); 2408 mA2dpService.setActiveDevice(device); 2409 } 2410 2411 if (mHearingAidService != null && (device == null 2412 || mHearingAidService.getConnectionPolicy(device) 2413 == BluetoothProfile.CONNECTION_POLICY_ALLOWED)) { 2414 Log.i(TAG, "setActiveDevice: Setting active Hearing Aid " + device); 2415 mHearingAidService.setActiveDevice(device); 2416 } 2417 2418 if (setHeadset && mHeadsetService != null && (device == null 2419 || mHeadsetService.getConnectionPolicy(device) 2420 == BluetoothProfile.CONNECTION_POLICY_ALLOWED)) { 2421 Log.i(TAG, "setActiveDevice: Setting active Headset " + device); 2422 mHeadsetService.setActiveDevice(device); 2423 } 2424 2425 return true; 2426 } 2427 2428 /** 2429 * Connects all enabled and supported bluetooth profiles between the local and remote device 2430 * 2431 * @param device is the remote device with which to connect these profiles 2432 * @return true if all profiles successfully connected, false if an error occurred 2433 */ connectAllEnabledProfiles(BluetoothDevice device)2434 public boolean connectAllEnabledProfiles(BluetoothDevice device) { 2435 if (!profileServicesRunning()) { 2436 Log.e(TAG, "connectAllEnabledProfiles: Not all profile services running"); 2437 return false; 2438 } 2439 2440 // Checks if any profiles are enabled and if so, only connect enabled profiles 2441 if (isAnyProfileEnabled(device)) { 2442 return connectEnabledProfiles(device); 2443 } 2444 2445 int numProfilesConnected = 0; 2446 ParcelUuid[] remoteDeviceUuids = getRemoteUuids(device); 2447 ParcelUuid[] localDeviceUuids = mAdapterProperties.getUuids(); 2448 2449 // All profile toggles disabled, so connects all supported profiles 2450 if (mA2dpService != null && isSupported(localDeviceUuids, remoteDeviceUuids, 2451 BluetoothProfile.A2DP, device)) { 2452 Log.i(TAG, "connectAllEnabledProfiles: Connecting A2dp"); 2453 // Set connection policy also connects the profile with CONNECTION_POLICY_ALLOWED 2454 mA2dpService.setConnectionPolicy(device, BluetoothProfile.CONNECTION_POLICY_ALLOWED); 2455 numProfilesConnected++; 2456 } 2457 if (mA2dpSinkService != null && isSupported(localDeviceUuids, remoteDeviceUuids, 2458 BluetoothProfile.A2DP_SINK, device)) { 2459 Log.i(TAG, "connectAllEnabledProfiles: Connecting A2dp Sink"); 2460 mA2dpSinkService.setConnectionPolicy(device, 2461 BluetoothProfile.CONNECTION_POLICY_ALLOWED); 2462 numProfilesConnected++; 2463 } 2464 if (mHeadsetService != null && isSupported(localDeviceUuids, remoteDeviceUuids, 2465 BluetoothProfile.HEADSET, device)) { 2466 Log.i(TAG, "connectAllEnabledProfiles: Connecting Headset Profile"); 2467 mHeadsetService.setConnectionPolicy(device, BluetoothProfile.CONNECTION_POLICY_ALLOWED); 2468 numProfilesConnected++; 2469 } 2470 if (mHeadsetClientService != null && isSupported(localDeviceUuids, remoteDeviceUuids, 2471 BluetoothProfile.HEADSET_CLIENT, device)) { 2472 Log.i(TAG, "connectAllEnabledProfiles: Connecting HFP"); 2473 mHeadsetClientService.setConnectionPolicy(device, 2474 BluetoothProfile.CONNECTION_POLICY_ALLOWED); 2475 numProfilesConnected++; 2476 } 2477 if (mMapClientService != null && isSupported(localDeviceUuids, remoteDeviceUuids, 2478 BluetoothProfile.MAP_CLIENT, device)) { 2479 Log.i(TAG, "connectAllEnabledProfiles: Connecting MAP"); 2480 mMapClientService.setConnectionPolicy(device, 2481 BluetoothProfile.CONNECTION_POLICY_ALLOWED); 2482 numProfilesConnected++; 2483 } 2484 if (mHidHostService != null && isSupported(localDeviceUuids, remoteDeviceUuids, 2485 BluetoothProfile.HID_HOST, device)) { 2486 Log.i(TAG, "connectAllEnabledProfiles: Connecting Hid Host Profile"); 2487 mHidHostService.setConnectionPolicy(device, BluetoothProfile.CONNECTION_POLICY_ALLOWED); 2488 numProfilesConnected++; 2489 } 2490 if (mPanService != null && isSupported(localDeviceUuids, remoteDeviceUuids, 2491 BluetoothProfile.PAN, device)) { 2492 Log.i(TAG, "connectAllEnabledProfiles: Connecting Pan Profile"); 2493 mPanService.setConnectionPolicy(device, BluetoothProfile.CONNECTION_POLICY_ALLOWED); 2494 numProfilesConnected++; 2495 } 2496 if (mPbapClientService != null && isSupported(localDeviceUuids, remoteDeviceUuids, 2497 BluetoothProfile.PBAP_CLIENT, device)) { 2498 Log.i(TAG, "connectAllEnabledProfiles: Connecting Pbap"); 2499 mPbapClientService.setConnectionPolicy(device, 2500 BluetoothProfile.CONNECTION_POLICY_ALLOWED); 2501 numProfilesConnected++; 2502 } 2503 if (mHearingAidService != null && isSupported(localDeviceUuids, remoteDeviceUuids, 2504 BluetoothProfile.HEARING_AID, device)) { 2505 Log.i(TAG, "connectAllEnabledProfiles: Connecting Hearing Aid Profile"); 2506 mHearingAidService.setConnectionPolicy(device, 2507 BluetoothProfile.CONNECTION_POLICY_ALLOWED); 2508 numProfilesConnected++; 2509 } 2510 2511 Log.i(TAG, "connectAllEnabledProfiles: Number of Profiles Connected: " 2512 + numProfilesConnected); 2513 2514 return true; 2515 } 2516 2517 /** 2518 * Disconnects all enabled and supported bluetooth profiles between the local and remote device 2519 * 2520 * @param device is the remote device with which to disconnect these profiles 2521 * @return true if all profiles successfully disconnected, false if an error occurred 2522 */ disconnectAllEnabledProfiles(BluetoothDevice device)2523 public boolean disconnectAllEnabledProfiles(BluetoothDevice device) { 2524 if (!profileServicesRunning()) { 2525 Log.e(TAG, "disconnectAllEnabledProfiles: Not all profile services bound"); 2526 return false; 2527 } 2528 2529 if (mA2dpService != null && mA2dpService.getConnectionState(device) 2530 == BluetoothProfile.STATE_CONNECTED) { 2531 Log.i(TAG, "disconnectAllEnabledProfiles: Disconnecting A2dp"); 2532 mA2dpService.disconnect(device); 2533 } 2534 if (mA2dpSinkService != null && mA2dpSinkService.getConnectionState(device) 2535 == BluetoothProfile.STATE_CONNECTED) { 2536 Log.i(TAG, "disconnectAllEnabledProfiles: Disconnecting A2dp Sink"); 2537 mA2dpSinkService.disconnect(device); 2538 } 2539 if (mHeadsetService != null && mHeadsetService.getConnectionState(device) 2540 == BluetoothProfile.STATE_CONNECTED) { 2541 Log.i(TAG, 2542 "disconnectAllEnabledProfiles: Disconnecting Headset Profile"); 2543 mHeadsetService.disconnect(device); 2544 } 2545 if (mHeadsetClientService != null && mHeadsetClientService.getConnectionState(device) 2546 == BluetoothProfile.STATE_CONNECTED) { 2547 Log.i(TAG, "disconnectAllEnabledProfiles: Disconnecting HFP"); 2548 mHeadsetClientService.disconnect(device); 2549 } 2550 if (mMapClientService != null && mMapClientService.getConnectionState(device) 2551 == BluetoothProfile.STATE_CONNECTED) { 2552 Log.i(TAG, "disconnectAllEnabledProfiles: Disconnecting MAP Client"); 2553 mMapClientService.disconnect(device); 2554 } 2555 if (mMapService != null && mMapService.getConnectionState(device) 2556 == BluetoothProfile.STATE_CONNECTED) { 2557 Log.i(TAG, "disconnectAllEnabledProfiles: Disconnecting MAP"); 2558 mMapService.disconnect(device); 2559 } 2560 if (mHidDeviceService != null && mHidDeviceService.getConnectionState(device) 2561 == BluetoothProfile.STATE_CONNECTED) { 2562 Log.i(TAG, "disconnectAllEnabledProfiles: Disconnecting Hid Device Profile"); 2563 mHidDeviceService.disconnect(device); 2564 } 2565 if (mHidHostService != null && mHidHostService.getConnectionState(device) 2566 == BluetoothProfile.STATE_CONNECTED) { 2567 Log.i(TAG, "disconnectAllEnabledProfiles: Disconnecting Hid Host Profile"); 2568 mHidHostService.disconnect(device); 2569 } 2570 if (mPanService != null && mPanService.getConnectionState(device) 2571 == BluetoothProfile.STATE_CONNECTED) { 2572 Log.i(TAG, "disconnectAllEnabledProfiles: Disconnecting Pan Profile"); 2573 mPanService.disconnect(device); 2574 } 2575 if (mPbapClientService != null && mPbapClientService.getConnectionState(device) 2576 == BluetoothProfile.STATE_CONNECTED) { 2577 Log.i(TAG, "disconnectAllEnabledProfiles: Disconnecting Pbap Client"); 2578 mPbapClientService.disconnect(device); 2579 } 2580 if (mPbapService != null && mPbapService.getConnectionState(device) 2581 == BluetoothProfile.STATE_CONNECTED) { 2582 Log.i(TAG, "disconnectAllEnabledProfiles: Disconnecting Pbap Server"); 2583 mPbapService.disconnect(device); 2584 } 2585 if (mHearingAidService != null && mHearingAidService.getConnectionState(device) 2586 == BluetoothProfile.STATE_CONNECTED) { 2587 Log.i(TAG, "disconnectAllEnabledProfiles: Disconnecting Hearing Aid Profile"); 2588 mHearingAidService.disconnect(device); 2589 } 2590 2591 return true; 2592 } 2593 2594 /** 2595 * Same as API method {@link BluetoothDevice#getName()} 2596 * 2597 * @param device remote device of interest 2598 * @return remote device name 2599 */ getRemoteName(BluetoothDevice device)2600 public String getRemoteName(BluetoothDevice device) { 2601 if (mRemoteDevices == null) { 2602 return null; 2603 } 2604 DeviceProperties deviceProp = mRemoteDevices.getDeviceProperties(device); 2605 if (deviceProp == null) { 2606 return null; 2607 } 2608 return deviceProp.getName(); 2609 } 2610 2611 /** 2612 * Get UUIDs for service supported by a remote device 2613 * 2614 * @param device the remote device that we want to get UUIDs from 2615 * @return 2616 */ 2617 @VisibleForTesting getRemoteUuids(BluetoothDevice device)2618 public ParcelUuid[] getRemoteUuids(BluetoothDevice device) { 2619 DeviceProperties deviceProp = mRemoteDevices.getDeviceProperties(device); 2620 if (deviceProp == null) { 2621 return null; 2622 } 2623 return deviceProp.getUuids(); 2624 } 2625 logUserBondResponse(BluetoothDevice device, boolean accepted, int event)2626 void logUserBondResponse(BluetoothDevice device, boolean accepted, int event) { 2627 BluetoothStatsLog.write(BluetoothStatsLog.BLUETOOTH_BOND_STATE_CHANGED, 2628 obfuscateAddress(device), 0, device.getType(), 2629 BluetoothDevice.BOND_BONDING, 2630 event, 2631 accepted ? 0 : BluetoothDevice.UNBOND_REASON_AUTH_REJECTED); 2632 } 2633 getDeviceAccessFromPrefs(BluetoothDevice device, String prefFile)2634 int getDeviceAccessFromPrefs(BluetoothDevice device, String prefFile) { 2635 SharedPreferences prefs = getSharedPreferences(prefFile, Context.MODE_PRIVATE); 2636 if (!prefs.contains(device.getAddress())) { 2637 return BluetoothDevice.ACCESS_UNKNOWN; 2638 } 2639 return prefs.getBoolean(device.getAddress(), false) 2640 ? BluetoothDevice.ACCESS_ALLOWED 2641 : BluetoothDevice.ACCESS_REJECTED; 2642 } 2643 setDeviceAccessFromPrefs(BluetoothDevice device, int value, String prefFile)2644 void setDeviceAccessFromPrefs(BluetoothDevice device, int value, String prefFile) { 2645 SharedPreferences pref = getSharedPreferences(prefFile, Context.MODE_PRIVATE); 2646 SharedPreferences.Editor editor = pref.edit(); 2647 if (value == BluetoothDevice.ACCESS_UNKNOWN) { 2648 editor.remove(device.getAddress()); 2649 } else { 2650 editor.putBoolean(device.getAddress(), value == BluetoothDevice.ACCESS_ALLOWED); 2651 } 2652 editor.apply(); 2653 } 2654 setPhonebookAccessPermission(BluetoothDevice device, int value)2655 void setPhonebookAccessPermission(BluetoothDevice device, int value) { 2656 setDeviceAccessFromPrefs(device, value, PHONEBOOK_ACCESS_PERMISSION_PREFERENCE_FILE); 2657 } 2658 setMessageAccessPermission(BluetoothDevice device, int value)2659 void setMessageAccessPermission(BluetoothDevice device, int value) { 2660 setDeviceAccessFromPrefs(device, value, MESSAGE_ACCESS_PERMISSION_PREFERENCE_FILE); 2661 } 2662 setSimAccessPermission(BluetoothDevice device, int value)2663 void setSimAccessPermission(BluetoothDevice device, int value) { 2664 setDeviceAccessFromPrefs(device, value, SIM_ACCESS_PERMISSION_PREFERENCE_FILE); 2665 } 2666 isRpaOffloadSupported()2667 public boolean isRpaOffloadSupported() { 2668 enforceBluetoothPermission(this); 2669 return mAdapterProperties.isRpaOffloadSupported(); 2670 } 2671 getNumOfOffloadedIrkSupported()2672 public int getNumOfOffloadedIrkSupported() { 2673 enforceBluetoothPermission(this); 2674 return mAdapterProperties.getNumOfOffloadedIrkSupported(); 2675 } 2676 getNumOfOffloadedScanFilterSupported()2677 public int getNumOfOffloadedScanFilterSupported() { 2678 return mAdapterProperties.getNumOfOffloadedScanFilterSupported(); 2679 } 2680 getOffloadedScanResultStorage()2681 public int getOffloadedScanResultStorage() { 2682 return mAdapterProperties.getOffloadedScanResultStorage(); 2683 } 2684 isLe2MPhySupported()2685 public boolean isLe2MPhySupported() { 2686 return mAdapterProperties.isLe2MPhySupported(); 2687 } 2688 isLeCodedPhySupported()2689 public boolean isLeCodedPhySupported() { 2690 return mAdapterProperties.isLeCodedPhySupported(); 2691 } 2692 isLeExtendedAdvertisingSupported()2693 public boolean isLeExtendedAdvertisingSupported() { 2694 return mAdapterProperties.isLeExtendedAdvertisingSupported(); 2695 } 2696 isLePeriodicAdvertisingSupported()2697 public boolean isLePeriodicAdvertisingSupported() { 2698 return mAdapterProperties.isLePeriodicAdvertisingSupported(); 2699 } 2700 getLeMaximumAdvertisingDataLength()2701 public int getLeMaximumAdvertisingDataLength() { 2702 return mAdapterProperties.getLeMaximumAdvertisingDataLength(); 2703 } 2704 2705 /** 2706 * Get the maximum number of connected audio devices. 2707 * 2708 * @return the maximum number of connected audio devices 2709 */ getMaxConnectedAudioDevices()2710 public int getMaxConnectedAudioDevices() { 2711 return mAdapterProperties.getMaxConnectedAudioDevices(); 2712 } 2713 2714 /** 2715 * Check whether A2DP offload is enabled. 2716 * 2717 * @return true if A2DP offload is enabled 2718 */ isA2dpOffloadEnabled()2719 public boolean isA2dpOffloadEnabled() { 2720 return mAdapterProperties.isA2dpOffloadEnabled(); 2721 } 2722 reportActivityInfo()2723 private BluetoothActivityEnergyInfo reportActivityInfo() { 2724 if (mAdapterProperties.getState() != BluetoothAdapter.STATE_ON 2725 || !mAdapterProperties.isActivityAndEnergyReportingSupported()) { 2726 return null; 2727 } 2728 2729 // Pull the data. The callback will notify mEnergyInfoLock. 2730 readEnergyInfo(); 2731 2732 synchronized (mEnergyInfoLock) { 2733 try { 2734 mEnergyInfoLock.wait(CONTROLLER_ENERGY_UPDATE_TIMEOUT_MILLIS); 2735 } catch (InterruptedException e) { 2736 // Just continue, the energy data may be stale but we won't miss anything next time 2737 // we query. 2738 } 2739 2740 final BluetoothActivityEnergyInfo info = 2741 new BluetoothActivityEnergyInfo(SystemClock.elapsedRealtime(), 2742 mStackReportedState, mTxTimeTotalMs, mRxTimeTotalMs, mIdleTimeTotalMs, 2743 mEnergyUsedTotalVoltAmpSecMicro); 2744 2745 // Count the number of entries that have byte counts > 0 2746 int arrayLen = 0; 2747 for (int i = 0; i < mUidTraffic.size(); i++) { 2748 final UidTraffic traffic = mUidTraffic.valueAt(i); 2749 if (traffic.getTxBytes() != 0 || traffic.getRxBytes() != 0) { 2750 arrayLen++; 2751 } 2752 } 2753 2754 // Copy the traffic objects whose byte counts are > 0 2755 final UidTraffic[] result = arrayLen > 0 ? new UidTraffic[arrayLen] : null; 2756 int putIdx = 0; 2757 for (int i = 0; i < mUidTraffic.size(); i++) { 2758 final UidTraffic traffic = mUidTraffic.valueAt(i); 2759 if (traffic.getTxBytes() != 0 || traffic.getRxBytes() != 0) { 2760 result[putIdx++] = traffic.clone(); 2761 } 2762 } 2763 2764 info.setUidTraffic(result); 2765 2766 return info; 2767 } 2768 } 2769 getTotalNumOfTrackableAdvertisements()2770 public int getTotalNumOfTrackableAdvertisements() { 2771 enforceBluetoothPermission(this); 2772 return mAdapterProperties.getTotalNumOfTrackableAdvertisements(); 2773 } 2774 convertScanModeToHal(int mode)2775 private static int convertScanModeToHal(int mode) { 2776 switch (mode) { 2777 case BluetoothAdapter.SCAN_MODE_NONE: 2778 return AbstractionLayer.BT_SCAN_MODE_NONE; 2779 case BluetoothAdapter.SCAN_MODE_CONNECTABLE: 2780 return AbstractionLayer.BT_SCAN_MODE_CONNECTABLE; 2781 case BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE: 2782 return AbstractionLayer.BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE; 2783 } 2784 // errorLog("Incorrect scan mode in convertScanModeToHal"); 2785 return -1; 2786 } 2787 convertScanModeFromHal(int mode)2788 static int convertScanModeFromHal(int mode) { 2789 switch (mode) { 2790 case AbstractionLayer.BT_SCAN_MODE_NONE: 2791 return BluetoothAdapter.SCAN_MODE_NONE; 2792 case AbstractionLayer.BT_SCAN_MODE_CONNECTABLE: 2793 return BluetoothAdapter.SCAN_MODE_CONNECTABLE; 2794 case AbstractionLayer.BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE: 2795 return BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE; 2796 } 2797 //errorLog("Incorrect scan mode in convertScanModeFromHal"); 2798 return -1; 2799 } 2800 2801 // This function is called from JNI. It allows native code to set a single wake 2802 // alarm. If an alarm is already pending and a new request comes in, the alarm 2803 // will be rescheduled (i.e. the previously set alarm will be cancelled). setWakeAlarm(long delayMillis, boolean shouldWake)2804 private boolean setWakeAlarm(long delayMillis, boolean shouldWake) { 2805 synchronized (this) { 2806 if (mPendingAlarm != null) { 2807 mAlarmManager.cancel(mPendingAlarm); 2808 } 2809 2810 long wakeupTime = SystemClock.elapsedRealtime() + delayMillis; 2811 int type = shouldWake ? AlarmManager.ELAPSED_REALTIME_WAKEUP 2812 : AlarmManager.ELAPSED_REALTIME; 2813 2814 Intent intent = new Intent(ACTION_ALARM_WAKEUP); 2815 mPendingAlarm = 2816 PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_ONE_SHOT); 2817 mAlarmManager.setExact(type, wakeupTime, mPendingAlarm); 2818 return true; 2819 } 2820 } 2821 2822 // This function is called from JNI. It allows native code to acquire a single wake lock. 2823 // If the wake lock is already held, this function returns success. Although this function 2824 // only supports acquiring a single wake lock at a time right now, it will eventually be 2825 // extended to allow acquiring an arbitrary number of wake locks. The current interface 2826 // takes |lockName| as a parameter in anticipation of that implementation. acquireWakeLock(String lockName)2827 private boolean acquireWakeLock(String lockName) { 2828 synchronized (this) { 2829 if (mWakeLock == null) { 2830 mWakeLockName = lockName; 2831 mWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, lockName); 2832 } 2833 2834 if (!mWakeLock.isHeld()) { 2835 mWakeLock.acquire(); 2836 } 2837 } 2838 return true; 2839 } 2840 2841 // This function is called from JNI. It allows native code to release a wake lock acquired 2842 // by |acquireWakeLock|. If the wake lock is not held, this function returns failure. 2843 // Note that the release() call is also invoked by {@link #cleanup()} so a synchronization is 2844 // needed here. See the comment for |acquireWakeLock| for an explanation of the interface. releaseWakeLock(String lockName)2845 private boolean releaseWakeLock(String lockName) { 2846 synchronized (this) { 2847 if (mWakeLock == null) { 2848 errorLog("Repeated wake lock release; aborting release: " + lockName); 2849 return false; 2850 } 2851 2852 if (mWakeLock.isHeld()) { 2853 mWakeLock.release(); 2854 } 2855 } 2856 return true; 2857 } 2858 energyInfoCallback(int status, int ctrlState, long txTime, long rxTime, long idleTime, long energyUsed, UidTraffic[] data)2859 private void energyInfoCallback(int status, int ctrlState, long txTime, long rxTime, 2860 long idleTime, long energyUsed, UidTraffic[] data) throws RemoteException { 2861 if (ctrlState >= BluetoothActivityEnergyInfo.BT_STACK_STATE_INVALID 2862 && ctrlState <= BluetoothActivityEnergyInfo.BT_STACK_STATE_STATE_IDLE) { 2863 // Energy is product of mA, V and ms. If the chipset doesn't 2864 // report it, we have to compute it from time 2865 if (energyUsed == 0) { 2866 try { 2867 final long txMah = Math.multiplyExact(txTime, getTxCurrentMa()); 2868 final long rxMah = Math.multiplyExact(rxTime, getRxCurrentMa()); 2869 final long idleMah = Math.multiplyExact(idleTime, getIdleCurrentMa()); 2870 energyUsed = (long) (Math.addExact(Math.addExact(txMah, rxMah), idleMah) 2871 * getOperatingVolt()); 2872 } catch (ArithmeticException e) { 2873 Log.wtf(TAG, "overflow in bluetooth energy callback", e); 2874 // Energy is already 0 if the exception was thrown. 2875 } 2876 } 2877 2878 synchronized (mEnergyInfoLock) { 2879 mStackReportedState = ctrlState; 2880 long totalTxTimeMs; 2881 long totalRxTimeMs; 2882 long totalIdleTimeMs; 2883 long totalEnergy; 2884 try { 2885 totalTxTimeMs = Math.addExact(mTxTimeTotalMs, txTime); 2886 totalRxTimeMs = Math.addExact(mRxTimeTotalMs, rxTime); 2887 totalIdleTimeMs = Math.addExact(mIdleTimeTotalMs, idleTime); 2888 totalEnergy = Math.addExact(mEnergyUsedTotalVoltAmpSecMicro, energyUsed); 2889 } catch (ArithmeticException e) { 2890 // This could be because we accumulated a lot of time, or we got a very strange 2891 // value from the controller (more likely). Discard this data. 2892 Log.wtf(TAG, "overflow in bluetooth energy callback", e); 2893 totalTxTimeMs = mTxTimeTotalMs; 2894 totalRxTimeMs = mRxTimeTotalMs; 2895 totalIdleTimeMs = mIdleTimeTotalMs; 2896 totalEnergy = mEnergyUsedTotalVoltAmpSecMicro; 2897 } 2898 2899 mTxTimeTotalMs = totalTxTimeMs; 2900 mRxTimeTotalMs = totalRxTimeMs; 2901 mIdleTimeTotalMs = totalIdleTimeMs; 2902 mEnergyUsedTotalVoltAmpSecMicro = totalEnergy; 2903 2904 for (UidTraffic traffic : data) { 2905 UidTraffic existingTraffic = mUidTraffic.get(traffic.getUid()); 2906 if (existingTraffic == null) { 2907 mUidTraffic.put(traffic.getUid(), traffic); 2908 } else { 2909 existingTraffic.addRxBytes(traffic.getRxBytes()); 2910 existingTraffic.addTxBytes(traffic.getTxBytes()); 2911 } 2912 } 2913 mEnergyInfoLock.notifyAll(); 2914 } 2915 } 2916 2917 verboseLog("energyInfoCallback() status = " + status + "txTime = " + txTime + "rxTime = " 2918 + rxTime + "idleTime = " + idleTime + "energyUsed = " + energyUsed + "ctrlState = " 2919 + ctrlState + "traffic = " + Arrays.toString(data)); 2920 } 2921 2922 /** 2923 * Update metadata change to registered listeners 2924 */ 2925 @VisibleForTesting metadataChanged(String address, int key, byte[] value)2926 public void metadataChanged(String address, int key, byte[] value) { 2927 BluetoothDevice device = mRemoteDevices.getDevice(Utils.getBytesFromAddress(address)); 2928 if (mMetadataListeners.containsKey(device)) { 2929 ArrayList<IBluetoothMetadataListener> list = mMetadataListeners.get(device); 2930 for (IBluetoothMetadataListener listener : list) { 2931 try { 2932 listener.onMetadataChanged(device, key, value); 2933 } catch (RemoteException e) { 2934 Log.w(TAG, "RemoteException when onMetadataChanged"); 2935 } 2936 } 2937 } 2938 } 2939 getIdleCurrentMa()2940 private int getIdleCurrentMa() { 2941 return getResources().getInteger(R.integer.config_bluetooth_idle_cur_ma); 2942 } 2943 getTxCurrentMa()2944 private int getTxCurrentMa() { 2945 return getResources().getInteger(R.integer.config_bluetooth_tx_cur_ma); 2946 } 2947 getRxCurrentMa()2948 private int getRxCurrentMa() { 2949 return getResources().getInteger(R.integer.config_bluetooth_rx_cur_ma); 2950 } 2951 getOperatingVolt()2952 private double getOperatingVolt() { 2953 return getResources().getInteger(R.integer.config_bluetooth_operating_voltage_mv) / 1000.0; 2954 } 2955 2956 @Override dump(FileDescriptor fd, PrintWriter writer, String[] args)2957 protected void dump(FileDescriptor fd, PrintWriter writer, String[] args) { 2958 if (args.length == 0) { 2959 writer.println("Skipping dump in APP SERVICES, see bluetooth_manager section."); 2960 writer.println("Use --print argument for dumpsys direct from AdapterService."); 2961 return; 2962 } 2963 2964 verboseLog("dumpsys arguments, check for protobuf output: " + TextUtils.join(" ", args)); 2965 if (args[0].equals("--proto-bin")) { 2966 dumpMetrics(fd); 2967 return; 2968 } 2969 2970 writer.println(); 2971 mAdapterProperties.dump(fd, writer, args); 2972 writer.println("mSnoopLogSettingAtEnable = " + mSnoopLogSettingAtEnable); 2973 writer.println("mDefaultSnoopLogSettingAtEnable = " + mDefaultSnoopLogSettingAtEnable); 2974 2975 writer.println(); 2976 mAdapterStateMachine.dump(fd, writer, args); 2977 2978 StringBuilder sb = new StringBuilder(); 2979 for (ProfileService profile : mRegisteredProfiles) { 2980 profile.dump(sb); 2981 } 2982 mSilenceDeviceManager.dump(fd, writer, args); 2983 mDatabaseManager.dump(writer); 2984 2985 writer.write(sb.toString()); 2986 writer.flush(); 2987 2988 dumpNative(fd, args); 2989 } 2990 dumpMetrics(FileDescriptor fd)2991 private void dumpMetrics(FileDescriptor fd) { 2992 BluetoothMetricsProto.BluetoothLog.Builder metricsBuilder = 2993 BluetoothMetricsProto.BluetoothLog.newBuilder(); 2994 byte[] nativeMetricsBytes = dumpMetricsNative(); 2995 debugLog("dumpMetrics: native metrics size is " + nativeMetricsBytes.length); 2996 if (nativeMetricsBytes.length > 0) { 2997 try { 2998 metricsBuilder.mergeFrom(nativeMetricsBytes); 2999 } catch (InvalidProtocolBufferException ex) { 3000 Log.w(TAG, "dumpMetrics: problem parsing metrics protobuf, " + ex.getMessage()); 3001 return; 3002 } 3003 } 3004 metricsBuilder.setNumBondedDevices(getBondedDevices().length); 3005 MetricsLogger.dumpProto(metricsBuilder); 3006 for (ProfileService profile : mRegisteredProfiles) { 3007 profile.dumpProto(metricsBuilder); 3008 } 3009 byte[] metricsBytes = Base64.encode(metricsBuilder.build().toByteArray(), Base64.DEFAULT); 3010 debugLog("dumpMetrics: combined metrics size is " + metricsBytes.length); 3011 try (FileOutputStream protoOut = new FileOutputStream(fd)) { 3012 protoOut.write(metricsBytes); 3013 } catch (IOException e) { 3014 errorLog("dumpMetrics: error writing combined protobuf to fd, " + e.getMessage()); 3015 } 3016 } 3017 debugLog(String msg)3018 private void debugLog(String msg) { 3019 if (DBG) { 3020 Log.d(TAG, msg); 3021 } 3022 } 3023 verboseLog(String msg)3024 private void verboseLog(String msg) { 3025 if (VERBOSE) { 3026 Log.v(TAG, msg); 3027 } 3028 } 3029 errorLog(String msg)3030 private void errorLog(String msg) { 3031 Log.e(TAG, msg); 3032 } 3033 3034 private final BroadcastReceiver mAlarmBroadcastReceiver = new BroadcastReceiver() { 3035 @Override 3036 public void onReceive(Context context, Intent intent) { 3037 synchronized (AdapterService.this) { 3038 mPendingAlarm = null; 3039 alarmFiredNative(); 3040 } 3041 } 3042 }; 3043 isGuest()3044 private boolean isGuest() { 3045 return UserManager.get(this).isGuestUser(); 3046 } 3047 isNiapMode()3048 private boolean isNiapMode() { 3049 return ((DevicePolicyManager) getSystemService(Context.DEVICE_POLICY_SERVICE)) 3050 .isCommonCriteriaModeEnabled(null); 3051 } 3052 3053 /** 3054 * Obfuscate Bluetooth MAC address into a PII free ID string 3055 * 3056 * @param device Bluetooth device whose MAC address will be obfuscated 3057 * @return a byte array that is unique to this MAC address on this device, 3058 * or empty byte array when either device is null or obfuscateAddressNative fails 3059 */ obfuscateAddress(BluetoothDevice device)3060 public byte[] obfuscateAddress(BluetoothDevice device) { 3061 if (device == null) { 3062 return new byte[0]; 3063 } 3064 return obfuscateAddressNative(Utils.getByteAddress(device)); 3065 } 3066 3067 /** 3068 * Get an incremental id of Bluetooth metrics and log 3069 * 3070 * @param device Bluetooth device 3071 * @return int of id for Bluetooth metrics and logging, 0 if the device is invalid 3072 */ getMetricId(BluetoothDevice device)3073 public int getMetricId(BluetoothDevice device) { 3074 if (device == null) { 3075 return 0; 3076 } 3077 return getMetricIdNative(Utils.getByteAddress(device)); 3078 } 3079 classInitNative()3080 static native void classInitNative(); 3081 initNative(boolean startRestricted, boolean isNiapMode, int configCompareResult)3082 native boolean initNative(boolean startRestricted, boolean isNiapMode, 3083 int configCompareResult); 3084 cleanupNative()3085 native void cleanupNative(); 3086 3087 /*package*/ enableNative()3088 native boolean enableNative(); 3089 3090 /*package*/ disableNative()3091 native boolean disableNative(); 3092 3093 /*package*/ setAdapterPropertyNative(int type, byte[] val)3094 native boolean setAdapterPropertyNative(int type, byte[] val); 3095 3096 /*package*/ getAdapterPropertiesNative()3097 native boolean getAdapterPropertiesNative(); 3098 3099 /*package*/ getAdapterPropertyNative(int type)3100 native boolean getAdapterPropertyNative(int type); 3101 3102 /*package*/ setAdapterPropertyNative(int type)3103 native boolean setAdapterPropertyNative(int type); 3104 3105 /*package*/ setDevicePropertyNative(byte[] address, int type, byte[] val)3106 native boolean setDevicePropertyNative(byte[] address, int type, byte[] val); 3107 3108 /*package*/ getDevicePropertyNative(byte[] address, int type)3109 native boolean getDevicePropertyNative(byte[] address, int type); 3110 3111 /*package*/ createBondNative(byte[] address, int transport)3112 native boolean createBondNative(byte[] address, int transport); 3113 3114 /*package*/ createBondOutOfBandNative(byte[] address, int transport, OobData oobData)3115 native boolean createBondOutOfBandNative(byte[] address, int transport, OobData oobData); 3116 3117 /*package*/ removeBondNative(byte[] address)3118 native boolean removeBondNative(byte[] address); 3119 3120 /*package*/ cancelBondNative(byte[] address)3121 native boolean cancelBondNative(byte[] address); 3122 3123 /*package*/ sdpSearchNative(byte[] address, byte[] uuid)3124 native boolean sdpSearchNative(byte[] address, byte[] uuid); 3125 3126 /*package*/ getConnectionStateNative(byte[] address)3127 native int getConnectionStateNative(byte[] address); 3128 startDiscoveryNative()3129 private native boolean startDiscoveryNative(); 3130 cancelDiscoveryNative()3131 private native boolean cancelDiscoveryNative(); 3132 pinReplyNative(byte[] address, boolean accept, int len, byte[] pin)3133 private native boolean pinReplyNative(byte[] address, boolean accept, int len, byte[] pin); 3134 sspReplyNative(byte[] address, int type, boolean accept, int passkey)3135 private native boolean sspReplyNative(byte[] address, int type, boolean accept, int passkey); 3136 3137 /*package*/ getRemoteServicesNative(byte[] address)3138 native boolean getRemoteServicesNative(byte[] address); 3139 3140 /*package*/ getRemoteMasInstancesNative(byte[] address)3141 native boolean getRemoteMasInstancesNative(byte[] address); 3142 readEnergyInfo()3143 private native int readEnergyInfo(); 3144 3145 /*package*/ factoryResetNative()3146 native boolean factoryResetNative(); 3147 alarmFiredNative()3148 private native void alarmFiredNative(); 3149 dumpNative(FileDescriptor fd, String[] arguments)3150 private native void dumpNative(FileDescriptor fd, String[] arguments); 3151 dumpMetricsNative()3152 private native byte[] dumpMetricsNative(); 3153 interopDatabaseClearNative()3154 private native void interopDatabaseClearNative(); 3155 interopDatabaseAddNative(int feature, byte[] address, int length)3156 private native void interopDatabaseAddNative(int feature, byte[] address, int length); 3157 obfuscateAddressNative(byte[] address)3158 private native byte[] obfuscateAddressNative(byte[] address); 3159 getMetricIdNative(byte[] address)3160 private native int getMetricIdNative(byte[] address); 3161 connectSocketNative( byte[] address, int type, byte[] uuid, int port, int flag, int callingUid)3162 /*package*/ native int connectSocketNative( 3163 byte[] address, int type, byte[] uuid, int port, int flag, int callingUid); 3164 createSocketChannelNative( int type, String serviceName, byte[] uuid, int port, int flag, int callingUid)3165 /*package*/ native int createSocketChannelNative( 3166 int type, String serviceName, byte[] uuid, int port, int flag, int callingUid); 3167 requestMaximumTxDataLengthNative(byte[] address)3168 /*package*/ native void requestMaximumTxDataLengthNative(byte[] address); 3169 3170 // Returns if this is a mock object. This is currently used in testing so that we may not call 3171 // System.exit() while finalizing the object. Otherwise GC of mock objects unfortunately ends up 3172 // calling finalize() which in turn calls System.exit() and the process crashes. 3173 // 3174 // Mock this in your testing framework to return true to avoid the mentioned behavior. In 3175 // production this has no effect. isMock()3176 public boolean isMock() { 3177 return false; 3178 } 3179 } 3180