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