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 android.text.format.DateUtils.MINUTE_IN_MILLIS; 20 import static android.text.format.DateUtils.SECOND_IN_MILLIS; 21 22 import static com.android.bluetooth.Utils.addressToBytes; 23 import static com.android.bluetooth.Utils.callerIsSystemOrActiveOrManagedUser; 24 import static com.android.bluetooth.Utils.callerIsSystemOrActiveUser; 25 import static com.android.bluetooth.Utils.enforceBluetoothPrivilegedPermission; 26 import static com.android.bluetooth.Utils.enforceCdmAssociation; 27 import static com.android.bluetooth.Utils.enforceDumpPermission; 28 import static com.android.bluetooth.Utils.enforceLocalMacAddressPermission; 29 import static com.android.bluetooth.Utils.hasBluetoothPrivilegedPermission; 30 import static com.android.bluetooth.Utils.isPackageNameAccurate; 31 32 import android.annotation.NonNull; 33 import android.annotation.RequiresPermission; 34 import android.annotation.SuppressLint; 35 import android.app.ActivityManager; 36 import android.app.AlarmManager; 37 import android.app.AppOpsManager; 38 import android.app.PendingIntent; 39 import android.app.Service; 40 import android.app.admin.DevicePolicyManager; 41 import android.bluetooth.BluetoothA2dp; 42 import android.bluetooth.BluetoothActivityEnergyInfo; 43 import android.bluetooth.BluetoothAdapter; 44 import android.bluetooth.BluetoothAdapter.ActiveDeviceUse; 45 import android.bluetooth.BluetoothClass; 46 import android.bluetooth.BluetoothDevice; 47 import android.bluetooth.BluetoothProfile; 48 import android.bluetooth.BluetoothProtoEnums; 49 import android.bluetooth.BluetoothStatusCodes; 50 import android.bluetooth.BluetoothUuid; 51 import android.bluetooth.BufferConstraints; 52 import android.bluetooth.IBluetooth; 53 import android.bluetooth.IBluetoothCallback; 54 import android.bluetooth.IBluetoothConnectionCallback; 55 import android.bluetooth.IBluetoothMetadataListener; 56 import android.bluetooth.IBluetoothOobDataCallback; 57 import android.bluetooth.IBluetoothSocketManager; 58 import android.bluetooth.OobData; 59 import android.bluetooth.UidTraffic; 60 import android.companion.CompanionDeviceManager; 61 import android.content.Attributable; 62 import android.content.AttributionSource; 63 import android.content.BroadcastReceiver; 64 import android.content.ComponentName; 65 import android.content.Context; 66 import android.content.Intent; 67 import android.content.IntentFilter; 68 import android.content.SharedPreferences; 69 import android.content.pm.PackageManager; 70 import android.os.AsyncTask; 71 import android.os.BatteryStats; 72 import android.os.Binder; 73 import android.os.Bundle; 74 import android.os.BytesMatcher; 75 import android.os.Handler; 76 import android.os.IBinder; 77 import android.os.Looper; 78 import android.os.Message; 79 import android.os.ParcelUuid; 80 import android.os.PowerManager; 81 import android.os.RemoteCallbackList; 82 import android.os.RemoteException; 83 import android.os.ResultReceiver; 84 import android.os.ServiceManager; 85 import android.os.SystemClock; 86 import android.os.SystemProperties; 87 import android.os.UserHandle; 88 import android.os.UserManager; 89 import android.provider.DeviceConfig; 90 import android.provider.Settings; 91 import android.text.TextUtils; 92 import android.util.Base64; 93 import android.util.Log; 94 import android.util.SparseArray; 95 96 import com.android.bluetooth.BluetoothMetricsProto; 97 import com.android.bluetooth.BluetoothStatsLog; 98 import com.android.bluetooth.Utils; 99 import com.android.bluetooth.a2dp.A2dpService; 100 import com.android.bluetooth.a2dpsink.A2dpSinkService; 101 import com.android.bluetooth.btservice.RemoteDevices.DeviceProperties; 102 import com.android.bluetooth.btservice.activityattribution.ActivityAttributionService; 103 import com.android.bluetooth.btservice.bluetoothkeystore.BluetoothKeystoreService; 104 import com.android.bluetooth.btservice.storage.DatabaseManager; 105 import com.android.bluetooth.btservice.storage.MetadataDatabase; 106 import com.android.bluetooth.gatt.GattService; 107 import com.android.bluetooth.hearingaid.HearingAidService; 108 import com.android.bluetooth.hfp.HeadsetService; 109 import com.android.bluetooth.hfpclient.HeadsetClientService; 110 import com.android.bluetooth.hid.HidDeviceService; 111 import com.android.bluetooth.hid.HidHostService; 112 import com.android.bluetooth.map.BluetoothMapService; 113 import com.android.bluetooth.mapclient.MapClientService; 114 import com.android.bluetooth.pan.PanService; 115 import com.android.bluetooth.pbap.BluetoothPbapService; 116 import com.android.bluetooth.pbapclient.PbapClientService; 117 import com.android.bluetooth.sap.SapService; 118 import com.android.bluetooth.sdp.SdpManager; 119 import com.android.bluetooth.telephony.BluetoothInCallService; 120 import com.android.internal.R; 121 import com.android.internal.annotations.GuardedBy; 122 import com.android.internal.annotations.VisibleForTesting; 123 import com.android.internal.app.IBatteryStats; 124 import com.android.internal.os.BackgroundThread; 125 import com.android.internal.os.BinderCallsStats; 126 import com.android.internal.util.ArrayUtils; 127 128 import com.google.protobuf.InvalidProtocolBufferException; 129 130 import libcore.util.SneakyThrow; 131 132 import java.io.FileDescriptor; 133 import java.io.FileOutputStream; 134 import java.io.IOException; 135 import java.io.PrintWriter; 136 import java.util.ArrayDeque; 137 import java.util.ArrayList; 138 import java.util.Arrays; 139 import java.util.HashMap; 140 import java.util.HashSet; 141 import java.util.List; 142 import java.util.Set; 143 import java.util.function.Predicate; 144 import java.util.regex.Pattern; 145 146 public class AdapterService extends Service { 147 private static final String TAG = "BluetoothAdapterService"; 148 private static final boolean DBG = true; 149 private static final boolean VERBOSE = false; 150 private static final int MIN_ADVT_INSTANCES_FOR_MA = 5; 151 private static final int MIN_OFFLOADED_FILTERS = 10; 152 private static final int MIN_OFFLOADED_SCAN_STORAGE_BYTES = 1024; 153 154 private final Object mEnergyInfoLock = new Object(); 155 private int mStackReportedState; 156 private long mTxTimeTotalMs; 157 private long mRxTimeTotalMs; 158 private long mIdleTimeTotalMs; 159 private long mEnergyUsedTotalVoltAmpSecMicro; 160 private final SparseArray<UidTraffic> mUidTraffic = new SparseArray<>(); 161 162 private final ArrayList<String> mStartedProfiles = new ArrayList<>(); 163 private final ArrayList<ProfileService> mRegisteredProfiles = new ArrayList<>(); 164 private final ArrayList<ProfileService> mRunningProfiles = new ArrayList<>(); 165 166 public static final String ACTION_LOAD_ADAPTER_PROPERTIES = 167 "com.android.bluetooth.btservice.action.LOAD_ADAPTER_PROPERTIES"; 168 public static final String ACTION_SERVICE_STATE_CHANGED = 169 "com.android.bluetooth.btservice.action.STATE_CHANGED"; 170 public static final String EXTRA_ACTION = "action"; 171 public static final int PROFILE_CONN_REJECTED = 2; 172 173 private static final String ACTION_ALARM_WAKEUP = 174 "com.android.bluetooth.btservice.action.ALARM_WAKEUP"; 175 176 static final String BLUETOOTH_BTSNOOP_LOG_MODE_PROPERTY = "persist.bluetooth.btsnooplogmode"; 177 static final String BLUETOOTH_BTSNOOP_DEFAULT_MODE_PROPERTY = 178 "persist.bluetooth.btsnoopdefaultmode"; 179 private String mSnoopLogSettingAtEnable = "empty"; 180 private String mDefaultSnoopLogSettingAtEnable = "empty"; 181 182 public static final String BLUETOOTH_PRIVILEGED = 183 android.Manifest.permission.BLUETOOTH_PRIVILEGED; 184 static final String LOCAL_MAC_ADDRESS_PERM = android.Manifest.permission.LOCAL_MAC_ADDRESS; 185 static final String RECEIVE_MAP_PERM = android.Manifest.permission.RECEIVE_BLUETOOTH_MAP; 186 187 private static final String PHONEBOOK_ACCESS_PERMISSION_PREFERENCE_FILE = 188 "phonebook_access_permission"; 189 private static final String MESSAGE_ACCESS_PERMISSION_PREFERENCE_FILE = 190 "message_access_permission"; 191 private static final String SIM_ACCESS_PERMISSION_PREFERENCE_FILE = "sim_access_permission"; 192 193 private static final int CONTROLLER_ENERGY_UPDATE_TIMEOUT_MILLIS = 30; 194 195 private static final ComponentName BLUETOOTH_INCALLSERVICE_COMPONENT = 196 new ComponentName("com.android.bluetooth", 197 BluetoothInCallService.class.getCanonicalName()); 198 199 // Report ID definition 200 public enum BqrQualityReportId { 201 QUALITY_REPORT_ID_MONITOR_MODE(0x01), 202 QUALITY_REPORT_ID_APPROACH_LSTO(0x02), 203 QUALITY_REPORT_ID_A2DP_AUDIO_CHOPPY(0x03), 204 QUALITY_REPORT_ID_SCO_VOICE_CHOPPY(0x04), 205 QUALITY_REPORT_ID_ROOT_INFLAMMATION(0x05), 206 QUALITY_REPORT_ID_LMP_LL_MESSAGE_TRACE(0x11), 207 QUALITY_REPORT_ID_BT_SCHEDULING_TRACE(0x12), 208 QUALITY_REPORT_ID_CONTROLLER_DBG_INFO(0x13); 209 210 private final int value; BqrQualityReportId(int value)211 private BqrQualityReportId(int value) { 212 this.value = value; 213 } getValue()214 public int getValue() { 215 return value; 216 } 217 }; 218 219 private final ArrayList<DiscoveringPackage> mDiscoveringPackages = new ArrayList<>(); 220 221 static { classInitNative()222 classInitNative(); 223 } 224 225 private static AdapterService sAdapterService; 226 getAdapterService()227 public static synchronized AdapterService getAdapterService() { 228 return sAdapterService; 229 } 230 setAdapterService(AdapterService instance)231 private static synchronized void setAdapterService(AdapterService instance) { 232 Log.d(TAG, "setAdapterService() - trying to set service to " + instance); 233 if (instance == null) { 234 return; 235 } 236 sAdapterService = instance; 237 } 238 clearAdapterService(AdapterService current)239 private static synchronized void clearAdapterService(AdapterService current) { 240 if (sAdapterService == current) { 241 sAdapterService = null; 242 } 243 } 244 245 private AdapterProperties mAdapterProperties; 246 private AdapterState mAdapterStateMachine; 247 private BondStateMachine mBondStateMachine; 248 private JniCallbacks mJniCallbacks; 249 private RemoteDevices mRemoteDevices; 250 251 /* TODO: Consider to remove the search API from this class, if changed to use call-back */ 252 private SdpManager mSdpManager = null; 253 254 private boolean mNativeAvailable; 255 private boolean mCleaningUp; 256 private final HashMap<BluetoothDevice, ArrayList<IBluetoothMetadataListener>> 257 mMetadataListeners = new HashMap<>(); 258 private final HashMap<String, Integer> mProfileServicesState = new HashMap<String, Integer>(); 259 private Set<IBluetoothConnectionCallback> mBluetoothConnectionCallbacks = new HashSet<>(); 260 //Only BluetoothManagerService should be registered 261 private RemoteCallbackList<IBluetoothCallback> mCallbacks; 262 private int mCurrentRequestId; 263 private boolean mQuietmode = false; 264 private HashMap<String, CallerInfo> mBondAttemptCallerInfo = new HashMap<>(); 265 266 private AlarmManager mAlarmManager; 267 private PendingIntent mPendingAlarm; 268 private IBatteryStats mBatteryStats; 269 private PowerManager mPowerManager; 270 private PowerManager.WakeLock mWakeLock; 271 private String mWakeLockName; 272 private UserManager mUserManager; 273 private CompanionDeviceManager mCompanionDeviceManager; 274 275 private PhonePolicy mPhonePolicy; 276 private ActiveDeviceManager mActiveDeviceManager; 277 private DatabaseManager mDatabaseManager; 278 private SilenceDeviceManager mSilenceDeviceManager; 279 private AppOpsManager mAppOps; 280 281 private BluetoothSocketManagerBinder mBluetoothSocketManagerBinder; 282 283 private BluetoothKeystoreService mBluetoothKeystoreService; 284 private A2dpService mA2dpService; 285 private A2dpSinkService mA2dpSinkService; 286 private ActivityAttributionService mActivityAttributionService; 287 private HeadsetService mHeadsetService; 288 private HeadsetClientService mHeadsetClientService; 289 private BluetoothMapService mMapService; 290 private MapClientService mMapClientService; 291 private HidDeviceService mHidDeviceService; 292 private HidHostService mHidHostService; 293 private PanService mPanService; 294 private BluetoothPbapService mPbapService; 295 private PbapClientService mPbapClientService; 296 private HearingAidService mHearingAidService; 297 private SapService mSapService; 298 299 private BinderCallsStats.SettingsObserver mBinderCallsSettingsObserver; 300 301 private volatile boolean mTestModeEnabled = false; 302 303 /** 304 * Register a {@link ProfileService} with AdapterService. 305 * 306 * @param profile the service being added. 307 */ addProfile(ProfileService profile)308 public void addProfile(ProfileService profile) { 309 mHandler.obtainMessage(MESSAGE_PROFILE_SERVICE_REGISTERED, profile).sendToTarget(); 310 } 311 312 /** 313 * Unregister a ProfileService with AdapterService. 314 * 315 * @param profile the service being removed. 316 */ removeProfile(ProfileService profile)317 public void removeProfile(ProfileService profile) { 318 mHandler.obtainMessage(MESSAGE_PROFILE_SERVICE_UNREGISTERED, profile).sendToTarget(); 319 } 320 321 /** 322 * Notify AdapterService that a ProfileService has started or stopped. 323 * 324 * @param profile the service being removed. 325 * @param state {@link BluetoothAdapter#STATE_ON} or {@link BluetoothAdapter#STATE_OFF} 326 */ onProfileServiceStateChanged(ProfileService profile, int state)327 public void onProfileServiceStateChanged(ProfileService profile, int state) { 328 if (state != BluetoothAdapter.STATE_ON && state != BluetoothAdapter.STATE_OFF) { 329 throw new IllegalArgumentException(BluetoothAdapter.nameForState(state)); 330 } 331 Message m = mHandler.obtainMessage(MESSAGE_PROFILE_SERVICE_STATE_CHANGED); 332 m.obj = profile; 333 m.arg1 = state; 334 mHandler.sendMessage(m); 335 } 336 337 /** 338 * Confirm whether the ProfileService is started expectedly. 339 * 340 * @param string the service simple name. 341 * @return true if the service is started expectedly, false otherwise. 342 */ isStartedProfile(String serviceSampleName)343 public boolean isStartedProfile(String serviceSampleName) { 344 return mStartedProfiles.contains(serviceSampleName); 345 } 346 347 private static final int MESSAGE_PROFILE_SERVICE_STATE_CHANGED = 1; 348 private static final int MESSAGE_PROFILE_SERVICE_REGISTERED = 2; 349 private static final int MESSAGE_PROFILE_SERVICE_UNREGISTERED = 3; 350 351 class AdapterServiceHandler extends Handler { 352 @Override handleMessage(Message msg)353 public void handleMessage(Message msg) { 354 verboseLog("handleMessage() - Message: " + msg.what); 355 356 switch (msg.what) { 357 case MESSAGE_PROFILE_SERVICE_STATE_CHANGED: 358 verboseLog("handleMessage() - MESSAGE_PROFILE_SERVICE_STATE_CHANGED"); 359 processProfileServiceStateChanged((ProfileService) msg.obj, msg.arg1); 360 break; 361 case MESSAGE_PROFILE_SERVICE_REGISTERED: 362 verboseLog("handleMessage() - MESSAGE_PROFILE_SERVICE_REGISTERED"); 363 registerProfileService((ProfileService) msg.obj); 364 break; 365 case MESSAGE_PROFILE_SERVICE_UNREGISTERED: 366 verboseLog("handleMessage() - MESSAGE_PROFILE_SERVICE_UNREGISTERED"); 367 unregisterProfileService((ProfileService) msg.obj); 368 break; 369 } 370 } 371 registerProfileService(ProfileService profile)372 private void registerProfileService(ProfileService profile) { 373 if (mRegisteredProfiles.contains(profile)) { 374 Log.e(TAG, profile.getName() + " already registered."); 375 return; 376 } 377 mRegisteredProfiles.add(profile); 378 } 379 unregisterProfileService(ProfileService profile)380 private void unregisterProfileService(ProfileService profile) { 381 if (!mRegisteredProfiles.contains(profile)) { 382 Log.e(TAG, profile.getName() + " not registered (UNREGISTER)."); 383 return; 384 } 385 mRegisteredProfiles.remove(profile); 386 } 387 processProfileServiceStateChanged(ProfileService profile, int state)388 private void processProfileServiceStateChanged(ProfileService profile, int state) { 389 switch (state) { 390 case BluetoothAdapter.STATE_ON: 391 if (!mRegisteredProfiles.contains(profile)) { 392 Log.e(TAG, profile.getName() + " not registered (STATE_ON)."); 393 return; 394 } 395 if (mRunningProfiles.contains(profile)) { 396 Log.e(TAG, profile.getName() + " already running."); 397 return; 398 } 399 mRunningProfiles.add(profile); 400 if (GattService.class.getSimpleName().equals(profile.getName())) { 401 enableNative(); 402 } else if (mRegisteredProfiles.size() == Config.getSupportedProfiles().length 403 && mRegisteredProfiles.size() == mRunningProfiles.size()) { 404 mAdapterProperties.onBluetoothReady(); 405 updateUuids(); 406 setBluetoothClassFromConfig(); 407 initProfileServices(); 408 getAdapterPropertyNative(AbstractionLayer.BT_PROPERTY_LOCAL_IO_CAPS); 409 getAdapterPropertyNative(AbstractionLayer.BT_PROPERTY_LOCAL_IO_CAPS_BLE); 410 getAdapterPropertyNative(AbstractionLayer.BT_PROPERTY_DYNAMIC_AUDIO_BUFFER); 411 mAdapterStateMachine.sendMessage(AdapterState.BREDR_STARTED); 412 } 413 break; 414 case BluetoothAdapter.STATE_OFF: 415 if (!mRegisteredProfiles.contains(profile)) { 416 Log.e(TAG, profile.getName() + " not registered (STATE_OFF)."); 417 return; 418 } 419 if (!mRunningProfiles.contains(profile)) { 420 Log.e(TAG, profile.getName() + " not running."); 421 return; 422 } 423 mRunningProfiles.remove(profile); 424 // If only GATT is left, send BREDR_STOPPED. 425 if ((mRunningProfiles.size() == 1 && (GattService.class.getSimpleName() 426 .equals(mRunningProfiles.get(0).getName())))) { 427 mAdapterStateMachine.sendMessage(AdapterState.BREDR_STOPPED); 428 } else if (mRunningProfiles.size() == 0) { 429 disableNative(); 430 } 431 break; 432 default: 433 Log.e(TAG, "Unhandled profile state: " + state); 434 } 435 } 436 } 437 438 private final AdapterServiceHandler mHandler = new AdapterServiceHandler(); 439 updateInteropDatabase()440 private void updateInteropDatabase() { 441 interopDatabaseClearNative(); 442 443 String interopString = Settings.Global.getString(getContentResolver(), 444 Settings.Global.BLUETOOTH_INTEROPERABILITY_LIST); 445 if (interopString == null) { 446 return; 447 } 448 Log.d(TAG, "updateInteropDatabase: [" + interopString + "]"); 449 450 String[] entries = interopString.split(";"); 451 for (String entry : entries) { 452 String[] tokens = entry.split(","); 453 if (tokens.length != 2) { 454 continue; 455 } 456 457 // Get feature 458 int feature = 0; 459 try { 460 feature = Integer.parseInt(tokens[1]); 461 } catch (NumberFormatException e) { 462 Log.e(TAG, "updateInteropDatabase: Invalid feature '" + tokens[1] + "'"); 463 continue; 464 } 465 466 // Get address bytes and length 467 int length = (tokens[0].length() + 1) / 3; 468 if (length < 1 || length > 6) { 469 Log.e(TAG, "updateInteropDatabase: Malformed address string '" + tokens[0] + "'"); 470 continue; 471 } 472 473 byte[] addr = new byte[6]; 474 int offset = 0; 475 for (int i = 0; i < tokens[0].length(); ) { 476 if (tokens[0].charAt(i) == ':') { 477 i += 1; 478 } else { 479 try { 480 addr[offset++] = (byte) Integer.parseInt(tokens[0].substring(i, i + 2), 16); 481 } catch (NumberFormatException e) { 482 offset = 0; 483 break; 484 } 485 i += 2; 486 } 487 } 488 489 // Check if address was parsed ok, otherwise, move on... 490 if (offset == 0) { 491 continue; 492 } 493 494 // Add entry 495 interopDatabaseAddNative(feature, addr, length); 496 } 497 } 498 499 @Override onCreate()500 public void onCreate() { 501 super.onCreate(); 502 debugLog("onCreate()"); 503 mDeviceConfigListener.start(); 504 mRemoteDevices = new RemoteDevices(this, Looper.getMainLooper()); 505 mRemoteDevices.init(); 506 clearDiscoveringPackages(); 507 mBinder = new AdapterServiceBinder(this); 508 mAdapterProperties = new AdapterProperties(this); 509 mAdapterStateMachine = AdapterState.make(this); 510 mJniCallbacks = new JniCallbacks(this, mAdapterProperties); 511 mBluetoothKeystoreService = new BluetoothKeystoreService(isCommonCriteriaMode()); 512 mBluetoothKeystoreService.start(); 513 mActivityAttributionService = new ActivityAttributionService(); 514 mActivityAttributionService.start(); 515 int configCompareResult = mBluetoothKeystoreService.getCompareResult(); 516 517 // Start tracking Binder latency for the bluetooth process. 518 mBinderCallsSettingsObserver = new BinderCallsStats.SettingsObserver( 519 getApplicationContext(), 520 new BinderCallsStats( 521 new BinderCallsStats.Injector(), 522 com.android.internal.os.BinderLatencyProto.Dims.BLUETOOTH)); 523 524 // Android TV doesn't show consent dialogs for just works and encryption only le pairing 525 boolean isAtvDevice = getApplicationContext().getPackageManager().hasSystemFeature( 526 PackageManager.FEATURE_LEANBACK_ONLY); 527 initNative(isGuest(), isCommonCriteriaMode(), configCompareResult, getInitFlags(), 528 isAtvDevice); 529 mNativeAvailable = true; 530 mCallbacks = new RemoteCallbackList<IBluetoothCallback>(); 531 mAppOps = getSystemService(AppOpsManager.class); 532 //Load the name and address 533 getAdapterPropertyNative(AbstractionLayer.BT_PROPERTY_BDADDR); 534 getAdapterPropertyNative(AbstractionLayer.BT_PROPERTY_BDNAME); 535 getAdapterPropertyNative(AbstractionLayer.BT_PROPERTY_CLASS_OF_DEVICE); 536 mAlarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE); 537 mPowerManager = (PowerManager) getSystemService(Context.POWER_SERVICE); 538 mUserManager = (UserManager) getSystemService(Context.USER_SERVICE); 539 mBatteryStats = IBatteryStats.Stub.asInterface( 540 ServiceManager.getService(BatteryStats.SERVICE_NAME)); 541 mCompanionDeviceManager = getSystemService(CompanionDeviceManager.class); 542 543 mBluetoothKeystoreService.initJni(); 544 545 mSdpManager = SdpManager.init(this); 546 registerReceiver(mAlarmBroadcastReceiver, new IntentFilter(ACTION_ALARM_WAKEUP)); 547 548 mDatabaseManager = new DatabaseManager(this); 549 mDatabaseManager.start(MetadataDatabase.createDatabase(this)); 550 551 // Phone policy is specific to phone implementations and hence if a device wants to exclude 552 // it out then it can be disabled by using the flag below. 553 if (getResources().getBoolean(com.android.bluetooth.R.bool.enable_phone_policy)) { 554 Log.i(TAG, "Phone policy enabled"); 555 mPhonePolicy = new PhonePolicy(this, new ServiceFactory()); 556 mPhonePolicy.start(); 557 } else { 558 Log.i(TAG, "Phone policy disabled"); 559 } 560 561 mActiveDeviceManager = new ActiveDeviceManager(this, new ServiceFactory()); 562 mActiveDeviceManager.start(); 563 564 mSilenceDeviceManager = new SilenceDeviceManager(this, new ServiceFactory(), 565 Looper.getMainLooper()); 566 mSilenceDeviceManager.start(); 567 568 mBluetoothSocketManagerBinder = new BluetoothSocketManagerBinder(this); 569 570 setAdapterService(this); 571 572 invalidateBluetoothCaches(); 573 574 // First call to getSharedPreferences will result in a file read into 575 // memory cache. Call it here asynchronously to avoid potential ANR 576 // in the future 577 new AsyncTask<Void, Void, Void>() { 578 @Override 579 protected Void doInBackground(Void... params) { 580 getSharedPreferences(PHONEBOOK_ACCESS_PERMISSION_PREFERENCE_FILE, 581 Context.MODE_PRIVATE); 582 getSharedPreferences(MESSAGE_ACCESS_PERMISSION_PREFERENCE_FILE, 583 Context.MODE_PRIVATE); 584 getSharedPreferences(SIM_ACCESS_PERMISSION_PREFERENCE_FILE, Context.MODE_PRIVATE); 585 return null; 586 } 587 }.execute(); 588 589 try { 590 int systemUiUid = getApplicationContext() 591 .createContextAsUser(UserHandle.SYSTEM, /* flags= */ 0) 592 .getPackageManager() 593 .getPackageUid("com.android.systemui", PackageManager.MATCH_SYSTEM_ONLY); 594 595 Utils.setSystemUiUid(systemUiUid); 596 } catch (PackageManager.NameNotFoundException e) { 597 // Some platforms, such as wearables do not have a system ui. 598 Log.w(TAG, "Unable to resolve SystemUI's UID.", e); 599 } 600 601 IntentFilter filter = new IntentFilter(Intent.ACTION_USER_SWITCHED); 602 getApplicationContext().registerReceiverForAllUsers(sUserSwitchedReceiver, filter, null, null); 603 int fuid = ActivityManager.getCurrentUser(); 604 Utils.setForegroundUserId(fuid); 605 } 606 607 @Override onBind(Intent intent)608 public IBinder onBind(Intent intent) { 609 debugLog("onBind()"); 610 return mBinder; 611 } 612 613 @Override onUnbind(Intent intent)614 public boolean onUnbind(Intent intent) { 615 debugLog("onUnbind() - calling cleanup"); 616 cleanup(); 617 return super.onUnbind(intent); 618 } 619 620 @Override onDestroy()621 public void onDestroy() { 622 debugLog("onDestroy()"); 623 if (!isMock()) { 624 // TODO(b/27859763) 625 Log.i(TAG, "Force exit to cleanup internal state in Bluetooth stack"); 626 System.exit(0); 627 } 628 } 629 630 public static final BroadcastReceiver sUserSwitchedReceiver = new BroadcastReceiver() { 631 @Override 632 public void onReceive(Context context, Intent intent) { 633 if (Intent.ACTION_USER_SWITCHED.equals(intent.getAction())) { 634 int fuid = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0); 635 Utils.setForegroundUserId(fuid); 636 } 637 } 638 }; 639 bringUpBle()640 void bringUpBle() { 641 debugLog("bleOnProcessStart()"); 642 643 if (getResources().getBoolean( 644 R.bool.config_bluetooth_reload_supported_profiles_when_enabled)) { 645 Config.init(getApplicationContext()); 646 } 647 648 // Reset |mRemoteDevices| whenever BLE is turned off then on 649 // This is to replace the fact that |mRemoteDevices| was 650 // reinitialized in previous code. 651 // 652 // TODO(apanicke): The reason is unclear but 653 // I believe it is to clear the variable every time BLE was 654 // turned off then on. The same effect can be achieved by 655 // calling cleanup but this may not be necessary at all 656 // We should figure out why this is needed later 657 mRemoteDevices.reset(); 658 mAdapterProperties.init(mRemoteDevices); 659 660 debugLog("bleOnProcessStart() - Make Bond State Machine"); 661 mBondStateMachine = BondStateMachine.make(this, mAdapterProperties, mRemoteDevices); 662 663 mJniCallbacks.init(mBondStateMachine, mRemoteDevices); 664 665 try { 666 mBatteryStats.noteResetBleScan(); 667 } catch (RemoteException e) { 668 Log.w(TAG, "RemoteException trying to send a reset to BatteryStats"); 669 } 670 BluetoothStatsLog.write_non_chained(BluetoothStatsLog.BLE_SCAN_STATE_CHANGED, -1, null, 671 BluetoothStatsLog.BLE_SCAN_STATE_CHANGED__STATE__RESET, false, false, false); 672 673 //Start Gatt service 674 setProfileServiceState(GattService.class, BluetoothAdapter.STATE_ON); 675 } 676 bringDownBle()677 void bringDownBle() { 678 stopGattProfileService(); 679 } 680 stateChangeCallback(int status)681 void stateChangeCallback(int status) { 682 if (status == AbstractionLayer.BT_STATE_OFF) { 683 debugLog("stateChangeCallback: disableNative() completed"); 684 mAdapterStateMachine.sendMessage(AdapterState.BLE_STOPPED); 685 } else if (status == AbstractionLayer.BT_STATE_ON) { 686 mAdapterStateMachine.sendMessage(AdapterState.BLE_STARTED); 687 } else { 688 Log.e(TAG, "Incorrect status " + status + " in stateChangeCallback"); 689 } 690 } 691 692 /** 693 * Sets the Bluetooth CoD value of the local adapter if there exists a config value for it. 694 */ setBluetoothClassFromConfig()695 void setBluetoothClassFromConfig() { 696 int bluetoothClassConfig = retrieveBluetoothClassConfig(); 697 if (bluetoothClassConfig != 0) { 698 mAdapterProperties.setBluetoothClass(new BluetoothClass(bluetoothClassConfig)); 699 } 700 } 701 retrieveBluetoothClassConfig()702 private int retrieveBluetoothClassConfig() { 703 return Settings.Global.getInt( 704 getContentResolver(), Settings.Global.BLUETOOTH_CLASS_OF_DEVICE, 0); 705 } 706 startProfileServices()707 void startProfileServices() { 708 debugLog("startCoreServices()"); 709 Class[] supportedProfileServices = Config.getSupportedProfiles(); 710 if (supportedProfileServices.length == 1 && GattService.class.getSimpleName() 711 .equals(supportedProfileServices[0].getSimpleName())) { 712 mAdapterProperties.onBluetoothReady(); 713 updateUuids(); 714 setBluetoothClassFromConfig(); 715 mAdapterStateMachine.sendMessage(AdapterState.BREDR_STARTED); 716 } else { 717 setAllProfileServiceStates(supportedProfileServices, BluetoothAdapter.STATE_ON); 718 } 719 } 720 stopProfileServices()721 void stopProfileServices() { 722 // Make sure to stop classic background tasks now 723 cancelDiscoveryNative(); 724 mAdapterProperties.setScanMode(AbstractionLayer.BT_SCAN_MODE_NONE); 725 726 Class[] supportedProfileServices = Config.getSupportedProfiles(); 727 if (supportedProfileServices.length == 1 && (mRunningProfiles.size() == 1 728 && GattService.class.getSimpleName().equals(mRunningProfiles.get(0).getName()))) { 729 debugLog("stopProfileServices() - No profiles services to stop or already stopped."); 730 mAdapterStateMachine.sendMessage(AdapterState.BREDR_STOPPED); 731 } else { 732 setAllProfileServiceStates(supportedProfileServices, BluetoothAdapter.STATE_OFF); 733 } 734 } 735 stopGattProfileService()736 private void stopGattProfileService() { 737 mAdapterProperties.onBleDisable(); 738 if (mRunningProfiles.size() == 0) { 739 debugLog("stopGattProfileService() - No profiles services to stop."); 740 mAdapterStateMachine.sendMessage(AdapterState.BLE_STOPPED); 741 } 742 setProfileServiceState(GattService.class, BluetoothAdapter.STATE_OFF); 743 } 744 invalidateBluetoothGetStateCache()745 private void invalidateBluetoothGetStateCache() { 746 BluetoothAdapter.invalidateBluetoothGetStateCache(); 747 } 748 updateAdapterState(int prevState, int newState)749 void updateAdapterState(int prevState, int newState) { 750 mAdapterProperties.setState(newState); 751 invalidateBluetoothGetStateCache(); 752 if (mCallbacks != null) { 753 int n = mCallbacks.beginBroadcast(); 754 debugLog("updateAdapterState() - Broadcasting state " + BluetoothAdapter.nameForState( 755 newState) + " to " + n + " receivers."); 756 for (int i = 0; i < n; i++) { 757 try { 758 mCallbacks.getBroadcastItem(i).onBluetoothStateChange(prevState, newState); 759 } catch (RemoteException e) { 760 debugLog("updateAdapterState() - Callback #" + i + " failed (" + e + ")"); 761 } 762 } 763 mCallbacks.finishBroadcast(); 764 } 765 766 // Turn the Adapter all the way off if we are disabling and the snoop log setting changed. 767 if (newState == BluetoothAdapter.STATE_BLE_TURNING_ON) { 768 mSnoopLogSettingAtEnable = 769 SystemProperties.get(BLUETOOTH_BTSNOOP_LOG_MODE_PROPERTY, "empty"); 770 mDefaultSnoopLogSettingAtEnable = 771 Settings.Global.getString(getContentResolver(), 772 Settings.Global.BLUETOOTH_BTSNOOP_DEFAULT_MODE); 773 SystemProperties.set(BLUETOOTH_BTSNOOP_DEFAULT_MODE_PROPERTY, 774 mDefaultSnoopLogSettingAtEnable); 775 } else if (newState == BluetoothAdapter.STATE_BLE_ON 776 && prevState != BluetoothAdapter.STATE_OFF) { 777 String snoopLogSetting = 778 SystemProperties.get(BLUETOOTH_BTSNOOP_LOG_MODE_PROPERTY, "empty"); 779 String snoopDefaultModeSetting = 780 Settings.Global.getString(getContentResolver(), 781 Settings.Global.BLUETOOTH_BTSNOOP_DEFAULT_MODE); 782 783 if (!TextUtils.equals(mSnoopLogSettingAtEnable, snoopLogSetting) 784 || !TextUtils.equals(mDefaultSnoopLogSettingAtEnable, 785 snoopDefaultModeSetting)) { 786 mAdapterStateMachine.sendMessage(AdapterState.BLE_TURN_OFF); 787 } 788 } 789 } 790 linkQualityReportCallback( long timestamp, int reportId, int rssi, int snr, int retransmissionCount, int packetsNotReceiveCount, int negativeAcknowledgementCount)791 void linkQualityReportCallback( 792 long timestamp, 793 int reportId, 794 int rssi, 795 int snr, 796 int retransmissionCount, 797 int packetsNotReceiveCount, 798 int negativeAcknowledgementCount) { 799 BluetoothInCallService bluetoothInCallService = BluetoothInCallService.getInstance(); 800 801 if (reportId == BqrQualityReportId.QUALITY_REPORT_ID_SCO_VOICE_CHOPPY.getValue()) { 802 if (bluetoothInCallService == null) { 803 Log.w(TAG, "No BluetoothInCallService while trying to send BQR." 804 + " timestamp: " + timestamp + " reportId: " + reportId 805 + " rssi: " + rssi + " snr: " + snr 806 + " retransmissionCount: " + retransmissionCount 807 + " packetsNotReceiveCount: " + packetsNotReceiveCount 808 + " negativeAcknowledgementCount: " + negativeAcknowledgementCount); 809 return; 810 } 811 bluetoothInCallService.sendBluetoothCallQualityReport( 812 timestamp, rssi, snr, retransmissionCount, 813 packetsNotReceiveCount, negativeAcknowledgementCount); 814 } 815 } 816 817 /** 818 * Enable/disable BluetoothInCallService 819 * 820 * @param enable to enable/disable BluetoothInCallService. 821 */ enableBluetoothInCallService(boolean enable)822 public void enableBluetoothInCallService(boolean enable) { 823 debugLog("enableBluetoothInCallService() - Enable = " + enable); 824 getPackageManager().setComponentEnabledSetting( 825 BLUETOOTH_INCALLSERVICE_COMPONENT, 826 enable ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED 827 : PackageManager.COMPONENT_ENABLED_STATE_DISABLED, 828 PackageManager.DONT_KILL_APP); 829 } 830 cleanup()831 void cleanup() { 832 debugLog("cleanup()"); 833 if (mCleaningUp) { 834 errorLog("cleanup() - Service already starting to cleanup, ignoring request..."); 835 return; 836 } 837 838 clearAdapterService(this); 839 840 mCleaningUp = true; 841 invalidateBluetoothCaches(); 842 843 unregisterReceiver(mAlarmBroadcastReceiver); 844 845 if (mPendingAlarm != null) { 846 mAlarmManager.cancel(mPendingAlarm); 847 mPendingAlarm = null; 848 } 849 850 // This wake lock release may also be called concurrently by 851 // {@link #releaseWakeLock(String lockName)}, so a synchronization is needed here. 852 synchronized (this) { 853 if (mWakeLock != null) { 854 if (mWakeLock.isHeld()) { 855 mWakeLock.release(); 856 } 857 mWakeLock = null; 858 } 859 } 860 861 if (mDatabaseManager != null) { 862 mDatabaseManager.cleanup(); 863 } 864 865 if (mAdapterStateMachine != null) { 866 mAdapterStateMachine.doQuit(); 867 } 868 869 if (mBondStateMachine != null) { 870 mBondStateMachine.doQuit(); 871 } 872 873 if (mRemoteDevices != null) { 874 mRemoteDevices.cleanup(); 875 } 876 877 if (mSdpManager != null) { 878 mSdpManager.cleanup(); 879 mSdpManager = null; 880 } 881 882 if (mBluetoothKeystoreService != null) { 883 mBluetoothKeystoreService.cleanup(); 884 } 885 886 if (mActivityAttributionService != null) { 887 mActivityAttributionService.cleanup(); 888 } 889 890 if (mNativeAvailable) { 891 debugLog("cleanup() - Cleaning up adapter native"); 892 cleanupNative(); 893 mNativeAvailable = false; 894 } 895 896 if (mAdapterProperties != null) { 897 mAdapterProperties.cleanup(); 898 } 899 900 if (mJniCallbacks != null) { 901 mJniCallbacks.cleanup(); 902 } 903 904 if (mPhonePolicy != null) { 905 mPhonePolicy.cleanup(); 906 } 907 908 if (mSilenceDeviceManager != null) { 909 mSilenceDeviceManager.cleanup(); 910 } 911 912 if (mActiveDeviceManager != null) { 913 mActiveDeviceManager.cleanup(); 914 } 915 916 if (mProfileServicesState != null) { 917 mProfileServicesState.clear(); 918 } 919 920 if (mBluetoothSocketManagerBinder != null) { 921 mBluetoothSocketManagerBinder.cleanUp(); 922 mBluetoothSocketManagerBinder = null; 923 } 924 925 if (mBinder != null) { 926 mBinder.cleanup(); 927 mBinder = null; //Do not remove. Otherwise Binder leak! 928 } 929 930 if (mCallbacks != null) { 931 mCallbacks.kill(); 932 } 933 } 934 invalidateBluetoothCaches()935 private void invalidateBluetoothCaches() { 936 BluetoothAdapter.invalidateGetProfileConnectionStateCache(); 937 BluetoothAdapter.invalidateIsOffloadedFilteringSupportedCache(); 938 BluetoothDevice.invalidateBluetoothGetBondStateCache(); 939 BluetoothAdapter.invalidateBluetoothGetStateCache(); 940 BluetoothAdapter.invalidateGetAdapterConnectionStateCache(); 941 } 942 setProfileServiceState(Class service, int state)943 private void setProfileServiceState(Class service, int state) { 944 if (state == BluetoothAdapter.STATE_ON) { 945 mStartedProfiles.add(service.getSimpleName()); 946 } else if (state == BluetoothAdapter.STATE_OFF) { 947 mStartedProfiles.remove(service.getSimpleName()); 948 } 949 Intent intent = new Intent(this, service); 950 intent.putExtra(EXTRA_ACTION, ACTION_SERVICE_STATE_CHANGED); 951 intent.putExtra(BluetoothAdapter.EXTRA_STATE, state); 952 startService(intent); 953 } 954 setAllProfileServiceStates(Class[] services, int state)955 private void setAllProfileServiceStates(Class[] services, int state) { 956 for (Class service : services) { 957 if (GattService.class.getSimpleName().equals(service.getSimpleName())) { 958 continue; 959 } 960 setProfileServiceState(service, state); 961 } 962 } 963 964 /** 965 * Verifies whether the profile is supported by the local bluetooth adapter by checking a 966 * bitmask of its supported profiles 967 * 968 * @param remoteDeviceUuids is an array of all supported profiles by the remote device 969 * @param localDeviceUuids is an array of all supported profiles by the local device 970 * @param profile is the profile we are checking for support 971 * @param device is the remote device we wish to connect to 972 * @return true if the profile is supported by both the local and remote device, false otherwise 973 */ 974 @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) isSupported(ParcelUuid[] localDeviceUuids, ParcelUuid[] remoteDeviceUuids, int profile, BluetoothDevice device)975 private boolean isSupported(ParcelUuid[] localDeviceUuids, ParcelUuid[] remoteDeviceUuids, 976 int profile, BluetoothDevice device) { 977 if (remoteDeviceUuids == null || remoteDeviceUuids.length == 0) { 978 Log.e(TAG, "isSupported: Remote Device Uuids Empty"); 979 } 980 981 if (profile == BluetoothProfile.HEADSET) { 982 return (ArrayUtils.contains(localDeviceUuids, BluetoothUuid.HSP_AG) 983 && ArrayUtils.contains(remoteDeviceUuids, BluetoothUuid.HSP)) 984 || (ArrayUtils.contains(localDeviceUuids, BluetoothUuid.HFP_AG) 985 && ArrayUtils.contains(remoteDeviceUuids, BluetoothUuid.HFP)); 986 } 987 if (profile == BluetoothProfile.HEADSET_CLIENT) { 988 return ArrayUtils.contains(remoteDeviceUuids, BluetoothUuid.HFP_AG) 989 && ArrayUtils.contains(localDeviceUuids, BluetoothUuid.HFP); 990 } 991 if (profile == BluetoothProfile.A2DP) { 992 return ArrayUtils.contains(remoteDeviceUuids, BluetoothUuid.ADV_AUDIO_DIST) 993 || ArrayUtils.contains(remoteDeviceUuids, BluetoothUuid.A2DP_SINK); 994 } 995 if (profile == BluetoothProfile.A2DP_SINK) { 996 return ArrayUtils.contains(remoteDeviceUuids, BluetoothUuid.ADV_AUDIO_DIST) 997 || ArrayUtils.contains(remoteDeviceUuids, BluetoothUuid.A2DP_SOURCE); 998 } 999 if (profile == BluetoothProfile.OPP) { 1000 return ArrayUtils.contains(remoteDeviceUuids, BluetoothUuid.OBEX_OBJECT_PUSH); 1001 } 1002 if (profile == BluetoothProfile.HID_HOST) { 1003 return ArrayUtils.contains(remoteDeviceUuids, BluetoothUuid.HID) 1004 || ArrayUtils.contains(remoteDeviceUuids, BluetoothUuid.HOGP); 1005 } 1006 if (profile == BluetoothProfile.HID_DEVICE) { 1007 return mHidDeviceService.getConnectionState(device) 1008 == BluetoothProfile.STATE_DISCONNECTED; 1009 } 1010 if (profile == BluetoothProfile.PAN) { 1011 return ArrayUtils.contains(remoteDeviceUuids, BluetoothUuid.NAP); 1012 } 1013 if (profile == BluetoothProfile.MAP) { 1014 return mMapService.getConnectionState(device) == BluetoothProfile.STATE_CONNECTED; 1015 } 1016 if (profile == BluetoothProfile.PBAP) { 1017 return mPbapService.getConnectionState(device) == BluetoothProfile.STATE_CONNECTED; 1018 } 1019 if (profile == BluetoothProfile.MAP_CLIENT) { 1020 return true; 1021 } 1022 if (profile == BluetoothProfile.PBAP_CLIENT) { 1023 return ArrayUtils.contains(localDeviceUuids, BluetoothUuid.PBAP_PCE) 1024 && ArrayUtils.contains(remoteDeviceUuids, BluetoothUuid.PBAP_PSE); 1025 } 1026 if (profile == BluetoothProfile.HEARING_AID) { 1027 return ArrayUtils.contains(remoteDeviceUuids, BluetoothUuid.HEARING_AID); 1028 } 1029 if (profile == BluetoothProfile.SAP) { 1030 return ArrayUtils.contains(remoteDeviceUuids, BluetoothUuid.SAP); 1031 } 1032 1033 Log.e(TAG, "isSupported: Unexpected profile passed in to function: " + profile); 1034 return false; 1035 } 1036 1037 /** 1038 * Checks if any profile is enabled for the given device 1039 * 1040 * @param device is the device for which we are checking if any profiles are enabled 1041 * @return true if any profile is enabled, false otherwise 1042 */ 1043 @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) isAnyProfileEnabled(BluetoothDevice device)1044 private boolean isAnyProfileEnabled(BluetoothDevice device) { 1045 1046 if (mA2dpService != null && mA2dpService.getConnectionPolicy(device) 1047 > BluetoothProfile.CONNECTION_POLICY_FORBIDDEN) { 1048 return true; 1049 } 1050 if (mA2dpSinkService != null && mA2dpSinkService.getConnectionPolicy(device) 1051 > BluetoothProfile.CONNECTION_POLICY_FORBIDDEN) { 1052 return true; 1053 } 1054 if (mHeadsetService != null && mHeadsetService.getConnectionPolicy(device) 1055 > BluetoothProfile.CONNECTION_POLICY_FORBIDDEN) { 1056 return true; 1057 } 1058 if (mHeadsetClientService != null && mHeadsetClientService.getConnectionPolicy(device) 1059 > BluetoothProfile.CONNECTION_POLICY_FORBIDDEN) { 1060 return true; 1061 } 1062 if (mMapClientService != null && mMapClientService.getConnectionPolicy(device) 1063 > BluetoothProfile.CONNECTION_POLICY_FORBIDDEN) { 1064 return true; 1065 } 1066 if (mHidHostService != null && mHidHostService.getConnectionPolicy(device) 1067 > BluetoothProfile.CONNECTION_POLICY_FORBIDDEN) { 1068 return true; 1069 } 1070 if (mPanService != null && mPanService.getConnectionPolicy(device) 1071 > BluetoothProfile.CONNECTION_POLICY_FORBIDDEN) { 1072 return true; 1073 } 1074 if (mPbapClientService != null && mPbapClientService.getConnectionPolicy(device) 1075 > BluetoothProfile.CONNECTION_POLICY_FORBIDDEN) { 1076 return true; 1077 } 1078 if (mHearingAidService != null && mHearingAidService.getConnectionPolicy(device) 1079 > BluetoothProfile.CONNECTION_POLICY_FORBIDDEN) { 1080 return true; 1081 } 1082 1083 return false; 1084 } 1085 1086 /** 1087 * Connects only available profiles 1088 * (those with {@link BluetoothProfile.CONNECTION_POLICY_ALLOWED}) 1089 * 1090 * @param device is the device with which we are connecting the profiles 1091 * @return true 1092 */ 1093 @RequiresPermission(allOf = { 1094 android.Manifest.permission.BLUETOOTH_PRIVILEGED, 1095 android.Manifest.permission.MODIFY_PHONE_STATE, 1096 }) connectEnabledProfiles(BluetoothDevice device)1097 private boolean connectEnabledProfiles(BluetoothDevice device) { 1098 ParcelUuid[] remoteDeviceUuids = getRemoteUuids(device); 1099 ParcelUuid[] localDeviceUuids = mAdapterProperties.getUuids(); 1100 1101 if (mA2dpService != null && isSupported(localDeviceUuids, remoteDeviceUuids, 1102 BluetoothProfile.A2DP, device) && mA2dpService.getConnectionPolicy(device) 1103 > BluetoothProfile.CONNECTION_POLICY_FORBIDDEN) { 1104 Log.i(TAG, "connectEnabledProfiles: Connecting A2dp"); 1105 mA2dpService.connect(device); 1106 } 1107 if (mA2dpSinkService != null && isSupported(localDeviceUuids, remoteDeviceUuids, 1108 BluetoothProfile.A2DP_SINK, device) && mA2dpSinkService.getConnectionPolicy(device) 1109 > BluetoothProfile.CONNECTION_POLICY_FORBIDDEN) { 1110 Log.i(TAG, "connectEnabledProfiles: Connecting A2dp Sink"); 1111 mA2dpSinkService.connect(device); 1112 } 1113 if (mHeadsetService != null && isSupported(localDeviceUuids, remoteDeviceUuids, 1114 BluetoothProfile.HEADSET, device) && mHeadsetService.getConnectionPolicy(device) 1115 > BluetoothProfile.CONNECTION_POLICY_FORBIDDEN) { 1116 Log.i(TAG, "connectEnabledProfiles: Connecting Headset Profile"); 1117 mHeadsetService.connect(device); 1118 } 1119 if (mHeadsetClientService != null && isSupported(localDeviceUuids, remoteDeviceUuids, 1120 BluetoothProfile.HEADSET_CLIENT, device) 1121 && mHeadsetClientService.getConnectionPolicy(device) 1122 > BluetoothProfile.CONNECTION_POLICY_FORBIDDEN) { 1123 Log.i(TAG, "connectEnabledProfiles: Connecting HFP"); 1124 mHeadsetClientService.connect(device); 1125 } 1126 if (mMapClientService != null && isSupported(localDeviceUuids, remoteDeviceUuids, 1127 BluetoothProfile.MAP_CLIENT, device) 1128 && mMapClientService.getConnectionPolicy(device) 1129 > BluetoothProfile.CONNECTION_POLICY_FORBIDDEN) { 1130 Log.i(TAG, "connectEnabledProfiles: Connecting MAP"); 1131 mMapClientService.connect(device); 1132 } 1133 if (mHidHostService != null && isSupported(localDeviceUuids, remoteDeviceUuids, 1134 BluetoothProfile.HID_HOST, device) && mHidHostService.getConnectionPolicy(device) 1135 > BluetoothProfile.CONNECTION_POLICY_FORBIDDEN) { 1136 Log.i(TAG, "connectEnabledProfiles: Connecting Hid Host Profile"); 1137 mHidHostService.connect(device); 1138 } 1139 if (mPanService != null && isSupported(localDeviceUuids, remoteDeviceUuids, 1140 BluetoothProfile.PAN, device) && mPanService.getConnectionPolicy(device) 1141 > BluetoothProfile.CONNECTION_POLICY_FORBIDDEN) { 1142 Log.i(TAG, "connectEnabledProfiles: Connecting Pan Profile"); 1143 mPanService.connect(device); 1144 } 1145 if (mPbapClientService != null && isSupported(localDeviceUuids, remoteDeviceUuids, 1146 BluetoothProfile.PBAP_CLIENT, device) 1147 && mPbapClientService.getConnectionPolicy(device) 1148 > BluetoothProfile.CONNECTION_POLICY_FORBIDDEN) { 1149 Log.i(TAG, "connectEnabledProfiles: Connecting Pbap"); 1150 mPbapClientService.connect(device); 1151 } 1152 if (mHearingAidService != null && isSupported(localDeviceUuids, remoteDeviceUuids, 1153 BluetoothProfile.HEARING_AID, device) 1154 && mHearingAidService.getConnectionPolicy(device) 1155 > BluetoothProfile.CONNECTION_POLICY_FORBIDDEN) { 1156 Log.i(TAG, "connectEnabledProfiles: Connecting Hearing Aid Profile"); 1157 mHearingAidService.connect(device); 1158 } 1159 1160 return true; 1161 } 1162 1163 /** 1164 * Verifies that all bluetooth profile services are running 1165 * 1166 * @return true if all bluetooth profile services running, false otherwise 1167 */ profileServicesRunning()1168 private boolean profileServicesRunning() { 1169 if (mRegisteredProfiles.size() == Config.getSupportedProfiles().length 1170 && mRegisteredProfiles.size() == mRunningProfiles.size()) { 1171 return true; 1172 } 1173 1174 Log.e(TAG, "profileServicesRunning: One or more supported services not running"); 1175 return false; 1176 } 1177 1178 /** 1179 * Initializes all the profile services fields 1180 */ initProfileServices()1181 private void initProfileServices() { 1182 Log.i(TAG, "initProfileServices: Initializing all bluetooth profile services"); 1183 mA2dpService = A2dpService.getA2dpService(); 1184 mA2dpSinkService = A2dpSinkService.getA2dpSinkService(); 1185 mHeadsetService = HeadsetService.getHeadsetService(); 1186 mHeadsetClientService = HeadsetClientService.getHeadsetClientService(); 1187 mMapService = BluetoothMapService.getBluetoothMapService(); 1188 mMapClientService = MapClientService.getMapClientService(); 1189 mHidDeviceService = HidDeviceService.getHidDeviceService(); 1190 mHidHostService = HidHostService.getHidHostService(); 1191 mPanService = PanService.getPanService(); 1192 mPbapService = BluetoothPbapService.getBluetoothPbapService(); 1193 mPbapClientService = PbapClientService.getPbapClientService(); 1194 mHearingAidService = HearingAidService.getHearingAidService(); 1195 mSapService = SapService.getSapService(); 1196 } 1197 isAvailable()1198 private boolean isAvailable() { 1199 return !mCleaningUp; 1200 } 1201 1202 /** 1203 * Handlers for incoming service calls 1204 */ 1205 private AdapterServiceBinder mBinder; 1206 1207 /** 1208 * The Binder implementation must be declared to be a static class, with 1209 * the AdapterService instance passed in the constructor. Furthermore, 1210 * when the AdapterService shuts down, the reference to the AdapterService 1211 * must be explicitly removed. 1212 * 1213 * Otherwise, a memory leak can occur from repeated starting/stopping the 1214 * service...Please refer to android.os.Binder for further details on 1215 * why an inner instance class should be avoided. 1216 * 1217 */ 1218 @VisibleForTesting 1219 public static class AdapterServiceBinder extends IBluetooth.Stub { 1220 private AdapterService mService; 1221 AdapterServiceBinder(AdapterService svc)1222 AdapterServiceBinder(AdapterService svc) { 1223 mService = svc; 1224 mService.invalidateBluetoothGetStateCache(); 1225 BluetoothAdapter.getDefaultAdapter().disableBluetoothGetStateCache(); 1226 } 1227 cleanup()1228 public void cleanup() { 1229 mService = null; 1230 } 1231 getService()1232 public AdapterService getService() { 1233 if (mService != null && mService.isAvailable()) { 1234 return mService; 1235 } 1236 return null; 1237 } 1238 1239 @Override getState()1240 public int getState() { 1241 // don't check caller, may be called from system UI 1242 AdapterService service = getService(); 1243 if (service == null) { 1244 return BluetoothAdapter.STATE_OFF; 1245 } 1246 1247 return service.getState(); 1248 } 1249 1250 @Override enable(boolean quietMode, AttributionSource attributionSource)1251 public boolean enable(boolean quietMode, AttributionSource attributionSource) { 1252 AdapterService service = getService(); 1253 if (service == null || !callerIsSystemOrActiveUser(TAG, "enable") 1254 || !Utils.checkConnectPermissionForDataDelivery( 1255 service, attributionSource, "AdapterService enable")) { 1256 return false; 1257 } 1258 1259 return service.enable(quietMode); 1260 } 1261 1262 @Override disable(AttributionSource attributionSource)1263 public boolean disable(AttributionSource attributionSource) { 1264 AdapterService service = getService(); 1265 if (service == null || !callerIsSystemOrActiveUser(TAG, "disable") 1266 || !Utils.checkConnectPermissionForDataDelivery( 1267 service, attributionSource, "AdapterService disable")) { 1268 return false; 1269 } 1270 1271 return service.disable(); 1272 } 1273 1274 @Override getAddress()1275 public String getAddress() { 1276 return getAddressWithAttribution(Utils.getCallingAttributionSource()); 1277 } 1278 1279 @Override getAddressWithAttribution(AttributionSource attributionSource)1280 public String getAddressWithAttribution(AttributionSource attributionSource) { 1281 AdapterService service = getService(); 1282 if (service == null || !callerIsSystemOrActiveOrManagedUser(service, TAG, "getAddress") 1283 || !Utils.checkConnectPermissionForDataDelivery( 1284 service, attributionSource, "AdapterService getAddress")) { 1285 return null; 1286 } 1287 1288 enforceLocalMacAddressPermission(service); 1289 1290 return Utils.getAddressStringFromByte(service.mAdapterProperties.getAddress()); 1291 } 1292 1293 @Override getUuids(AttributionSource attributionSource)1294 public ParcelUuid[] getUuids(AttributionSource attributionSource) { 1295 AdapterService service = getService(); 1296 if (service == null || !callerIsSystemOrActiveUser(TAG, "getUuids") 1297 || !Utils.checkConnectPermissionForDataDelivery( 1298 service, attributionSource, "AdapterService getUuids")) { 1299 return new ParcelUuid[0]; 1300 } 1301 1302 return service.mAdapterProperties.getUuids(); 1303 } 1304 1305 @Override getName(AttributionSource attributionSource)1306 public String getName(AttributionSource attributionSource) { 1307 AdapterService service = getService(); 1308 if (service == null || !callerIsSystemOrActiveUser(TAG, "getName") 1309 || !Utils.checkConnectPermissionForDataDelivery( 1310 service, attributionSource, "AdapterService getName")) { 1311 return null; 1312 } 1313 1314 return service.getName(); 1315 } 1316 1317 @Override getNameLengthForAdvertise(AttributionSource attributionSource)1318 public int getNameLengthForAdvertise(AttributionSource attributionSource) { 1319 AdapterService service = getService(); 1320 if (service == null || !callerIsSystemOrActiveUser(TAG, "getNameLengthForAdvertise") 1321 || !Utils.checkAdvertisePermissionForDataDelivery( 1322 service, attributionSource, TAG)) { 1323 return -1; 1324 } 1325 1326 return service.getNameLengthForAdvertise(); 1327 } 1328 1329 @Override setName(String name, AttributionSource attributionSource)1330 public boolean setName(String name, AttributionSource attributionSource) { 1331 AdapterService service = getService(); 1332 if (service == null || !callerIsSystemOrActiveUser(TAG, "setName") 1333 || !Utils.checkConnectPermissionForDataDelivery( 1334 service, attributionSource, "AdapterService setName")) { 1335 return false; 1336 } 1337 1338 return service.mAdapterProperties.setName(name); 1339 } 1340 1341 @Override getBluetoothClass(AttributionSource attributionSource)1342 public BluetoothClass getBluetoothClass(AttributionSource attributionSource) { 1343 AdapterService service = getService(); 1344 if (service == null || !callerIsSystemOrActiveUser(TAG, "getBluetoothClass") 1345 || !Utils.checkConnectPermissionForDataDelivery( 1346 service, attributionSource, "AdapterSource getBluetoothClass")) { 1347 return null; 1348 } 1349 1350 return service.mAdapterProperties.getBluetoothClass(); 1351 } 1352 1353 @Override setBluetoothClass(BluetoothClass bluetoothClass, AttributionSource source)1354 public boolean setBluetoothClass(BluetoothClass bluetoothClass, AttributionSource source) { 1355 AdapterService service = getService(); 1356 if (service == null 1357 || !Utils.checkCallerIsSystemOrActiveUser(TAG) 1358 || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) { 1359 return false; 1360 } 1361 1362 enforceBluetoothPrivilegedPermission(service); 1363 1364 if (!service.mAdapterProperties.setBluetoothClass(bluetoothClass)) { 1365 return false; 1366 } 1367 1368 return Settings.Global.putInt( 1369 service.getContentResolver(), 1370 Settings.Global.BLUETOOTH_CLASS_OF_DEVICE, 1371 bluetoothClass.getClassOfDevice()); 1372 } 1373 1374 @Override getIoCapability(AttributionSource attributionSource)1375 public int getIoCapability(AttributionSource attributionSource) { 1376 AdapterService service = getService(); 1377 if (service == null || !callerIsSystemOrActiveUser(TAG, "getIoCapability") 1378 || !Utils.checkConnectPermissionForDataDelivery( 1379 service, attributionSource, "AdapterService getIoCapability")) { 1380 return BluetoothAdapter.IO_CAPABILITY_UNKNOWN; 1381 } 1382 1383 return service.mAdapterProperties.getIoCapability(); 1384 } 1385 1386 @Override setIoCapability(int capability, AttributionSource source)1387 public boolean setIoCapability(int capability, AttributionSource source) { 1388 AdapterService service = getService(); 1389 if (service == null 1390 || !Utils.checkCallerIsSystemOrActiveUser(TAG) 1391 || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) { 1392 return false; 1393 } 1394 1395 enforceBluetoothPrivilegedPermission(service); 1396 1397 if (!isValidIoCapability(capability)) { 1398 return false; 1399 } 1400 1401 return service.mAdapterProperties.setIoCapability(capability); 1402 } 1403 1404 @Override getLeIoCapability(AttributionSource attributionSource)1405 public int getLeIoCapability(AttributionSource attributionSource) { 1406 AdapterService service = getService(); 1407 if (service == null || !callerIsSystemOrActiveUser(TAG, "getLeIoCapability") 1408 || !Utils.checkConnectPermissionForDataDelivery( 1409 service, attributionSource, "AdapterService getLeIoCapability")) { 1410 return BluetoothAdapter.IO_CAPABILITY_UNKNOWN; 1411 } 1412 1413 return service.mAdapterProperties.getLeIoCapability(); 1414 } 1415 1416 @Override setLeIoCapability(int capability, AttributionSource source)1417 public boolean setLeIoCapability(int capability, AttributionSource source) { 1418 AdapterService service = getService(); 1419 if (service == null 1420 || !Utils.checkCallerIsSystemOrActiveUser(TAG) 1421 || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) { 1422 return false; 1423 } 1424 1425 enforceBluetoothPrivilegedPermission(service); 1426 1427 if (!isValidIoCapability(capability)) { 1428 return false; 1429 } 1430 1431 return service.mAdapterProperties.setLeIoCapability(capability); 1432 } 1433 1434 @Override getScanMode(AttributionSource attributionSource)1435 public int getScanMode(AttributionSource attributionSource) { 1436 AdapterService service = getService(); 1437 if (service == null || !callerIsSystemOrActiveOrManagedUser(service, TAG, "getScanMode") 1438 || !Utils.checkScanPermissionForDataDelivery( 1439 service, attributionSource, "AdapterService getScanMode")) { 1440 return BluetoothAdapter.SCAN_MODE_NONE; 1441 } 1442 1443 return service.mAdapterProperties.getScanMode(); 1444 } 1445 1446 @Override setScanMode(int mode, int duration, AttributionSource attributionSource)1447 public boolean setScanMode(int mode, int duration, AttributionSource attributionSource) { 1448 AdapterService service = getService(); 1449 if (service == null || !callerIsSystemOrActiveUser(TAG, "setScanMode") 1450 || !Utils.checkScanPermissionForDataDelivery( 1451 service, attributionSource, "AdapterService setScanMode")) { 1452 return false; 1453 } 1454 1455 enforceBluetoothPrivilegedPermission(service); 1456 1457 service.mAdapterProperties.setDiscoverableTimeout(duration); 1458 return service.mAdapterProperties.setScanMode(convertScanModeToHal(mode)); 1459 } 1460 1461 @Override getDiscoverableTimeout(AttributionSource attributionSource)1462 public int getDiscoverableTimeout(AttributionSource attributionSource) { 1463 AdapterService service = getService(); 1464 if (service == null || !callerIsSystemOrActiveUser(TAG, "getDiscoverableTimeout") 1465 || !Utils.checkScanPermissionForDataDelivery( 1466 service, attributionSource, "AdapterService getDiscoverableTimeout")) { 1467 return 0; 1468 } 1469 1470 return service.mAdapterProperties.getDiscoverableTimeout(); 1471 } 1472 1473 @Override setDiscoverableTimeout(int timeout, AttributionSource attributionSource)1474 public boolean setDiscoverableTimeout(int timeout, AttributionSource attributionSource) { 1475 AdapterService service = getService(); 1476 if (service == null || !callerIsSystemOrActiveUser(TAG, "setDiscoverableTimeout") 1477 || !Utils.checkScanPermissionForDataDelivery( 1478 service, attributionSource, "AdapterService setDiscoverableTimeout")) { 1479 return false; 1480 } 1481 1482 enforceBluetoothPrivilegedPermission(service); 1483 1484 return service.mAdapterProperties.setDiscoverableTimeout(timeout); 1485 } 1486 1487 @Override startDiscovery(AttributionSource attributionSource)1488 public boolean startDiscovery(AttributionSource attributionSource) { 1489 AdapterService service = getService(); 1490 if (service == null || !callerIsSystemOrActiveUser(TAG, "startDiscovery")) { 1491 return false; 1492 } 1493 1494 if (!Utils.checkScanPermissionForDataDelivery( 1495 service, attributionSource, "Starting discovery.")) { 1496 return false; 1497 } 1498 1499 return service.startDiscovery(attributionSource); 1500 } 1501 1502 @Override cancelDiscovery(AttributionSource attributionSource)1503 public boolean cancelDiscovery(AttributionSource attributionSource) { 1504 AdapterService service = getService(); 1505 if (service == null || !callerIsSystemOrActiveUser(TAG, "cancelDiscovery") 1506 || !Utils.checkScanPermissionForDataDelivery( 1507 service, attributionSource, "AdapterService cancelDiscovery")) { 1508 return false; 1509 } 1510 1511 service.debugLog("cancelDiscovery"); 1512 return service.cancelDiscoveryNative(); 1513 } 1514 1515 @Override isDiscovering(AttributionSource attributionSource)1516 public boolean isDiscovering(AttributionSource attributionSource) { 1517 AdapterService service = getService(); 1518 if (service == null 1519 || !callerIsSystemOrActiveOrManagedUser(service, TAG, "isDiscovering") 1520 || !Utils.checkScanPermissionForDataDelivery( 1521 service, attributionSource, "AdapterService isDiscovering")) { 1522 return false; 1523 } 1524 1525 return service.mAdapterProperties.isDiscovering(); 1526 } 1527 1528 @Override getDiscoveryEndMillis(AttributionSource source)1529 public long getDiscoveryEndMillis(AttributionSource source) { 1530 AdapterService service = getService(); 1531 if (service == null 1532 || !Utils.checkCallerIsSystemOrActiveUser(TAG) 1533 || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) { 1534 return -1; 1535 } 1536 1537 enforceBluetoothPrivilegedPermission(service); 1538 1539 return service.mAdapterProperties.discoveryEndMillis(); 1540 } 1541 1542 @Override getMostRecentlyConnectedDevices( AttributionSource attributionSource)1543 public List<BluetoothDevice> getMostRecentlyConnectedDevices( 1544 AttributionSource attributionSource) { 1545 // don't check caller, may be called from system UI 1546 AdapterService service = getService(); 1547 if (service == null || !Utils.checkConnectPermissionForDataDelivery( 1548 service, attributionSource, "AdapterService getMostRecentlyConnectedDevices")) { 1549 return new ArrayList<>(); 1550 } 1551 1552 return service.mDatabaseManager.getMostRecentlyConnectedDevices(); 1553 } 1554 1555 @Override getBondedDevices(AttributionSource attributionSource)1556 public BluetoothDevice[] getBondedDevices(AttributionSource attributionSource) { 1557 // don't check caller, may be called from system UI 1558 AdapterService service = getService(); 1559 if (service == null || !Utils.checkConnectPermissionForDataDelivery( 1560 service, attributionSource, "AdapterService getBondedDevices")) { 1561 return new BluetoothDevice[0]; 1562 } 1563 1564 return service.getBondedDevices(); 1565 } 1566 1567 @Override getAdapterConnectionState()1568 public int getAdapterConnectionState() { 1569 // don't check caller, may be called from system UI 1570 AdapterService service = getService(); 1571 if (service == null) { 1572 return BluetoothAdapter.STATE_DISCONNECTED; 1573 } 1574 1575 return service.mAdapterProperties.getConnectionState(); 1576 } 1577 1578 /** 1579 * This method has an associated binder cache. The invalidation 1580 * methods must be changed if the logic behind this method changes. 1581 */ 1582 @Override getProfileConnectionState(int profile)1583 public int getProfileConnectionState(int profile) { 1584 AdapterService service = getService(); 1585 if (service == null 1586 || !callerIsSystemOrActiveOrManagedUser( 1587 service, TAG, "getProfileConnectionState")) { 1588 return BluetoothProfile.STATE_DISCONNECTED; 1589 } 1590 1591 return service.mAdapterProperties.getProfileConnectionState(profile); 1592 } 1593 1594 @Override createBond(BluetoothDevice device, int transport, OobData remoteP192Data, OobData remoteP256Data, AttributionSource attributionSource)1595 public boolean createBond(BluetoothDevice device, int transport, OobData remoteP192Data, 1596 OobData remoteP256Data, AttributionSource attributionSource) { 1597 Attributable.setAttributionSource(device, attributionSource); 1598 AdapterService service = getService(); 1599 if (service == null || !callerIsSystemOrActiveOrManagedUser(service, TAG, "createBond") 1600 || !Utils.checkConnectPermissionForDataDelivery( 1601 service, attributionSource, "AdapterService createBond")) { 1602 return false; 1603 } 1604 1605 // This conditional is required to satisfy permission dependencies 1606 // since createBond calls createBondOutOfBand with null value passed as data. 1607 // BluetoothDevice#createBond requires BLUETOOTH_ADMIN only. 1608 service.enforceBluetoothPrivilegedPermissionIfNeeded(remoteP192Data, remoteP256Data); 1609 1610 return service.createBond(device, transport, remoteP192Data, remoteP256Data, 1611 attributionSource.getPackageName()); 1612 } 1613 1614 @Override cancelBondProcess( BluetoothDevice device, AttributionSource attributionSource)1615 public boolean cancelBondProcess( 1616 BluetoothDevice device, AttributionSource attributionSource) { 1617 Attributable.setAttributionSource(device, attributionSource); 1618 AdapterService service = getService(); 1619 if (service == null || !callerIsSystemOrActiveUser(TAG, "cancelBondProcess") 1620 || !Utils.checkConnectPermissionForDataDelivery( 1621 service, attributionSource, "AdapterService cancelBondProcess")) { 1622 return false; 1623 } 1624 1625 DeviceProperties deviceProp = service.mRemoteDevices.getDeviceProperties(device); 1626 if (deviceProp != null) { 1627 deviceProp.setBondingInitiatedLocally(false); 1628 } 1629 1630 return service.cancelBondNative(addressToBytes(device.getAddress())); 1631 } 1632 1633 @Override removeBond(BluetoothDevice device, AttributionSource attributionSource)1634 public boolean removeBond(BluetoothDevice device, AttributionSource attributionSource) { 1635 Attributable.setAttributionSource(device, attributionSource); 1636 AdapterService service = getService(); 1637 if (service == null || !callerIsSystemOrActiveUser(TAG, "removeBond") 1638 || !Utils.checkConnectPermissionForDataDelivery( 1639 service, attributionSource, "AdapterService removeBond")) { 1640 return false; 1641 } 1642 1643 DeviceProperties deviceProp = service.mRemoteDevices.getDeviceProperties(device); 1644 if (deviceProp == null || deviceProp.getBondState() != BluetoothDevice.BOND_BONDED) { 1645 return false; 1646 } 1647 service.mBondAttemptCallerInfo.remove(device.getAddress()); 1648 deviceProp.setBondingInitiatedLocally(false); 1649 1650 Message msg = service.mBondStateMachine.obtainMessage(BondStateMachine.REMOVE_BOND); 1651 msg.obj = device; 1652 service.mBondStateMachine.sendMessage(msg); 1653 return true; 1654 } 1655 1656 @Override getBondState(BluetoothDevice device, AttributionSource attributionSource)1657 public int getBondState(BluetoothDevice device, AttributionSource attributionSource) { 1658 // don't check caller, may be called from system UI 1659 Attributable.setAttributionSource(device, attributionSource); 1660 AdapterService service = getService(); 1661 if (service == null || !Utils.checkConnectPermissionForDataDelivery( 1662 service, attributionSource, "AdapterService getBondState")) { 1663 return BluetoothDevice.BOND_NONE; 1664 } 1665 1666 return service.getBondState(device); 1667 } 1668 1669 @Override isBondingInitiatedLocally( BluetoothDevice device, AttributionSource attributionSource)1670 public boolean isBondingInitiatedLocally( 1671 BluetoothDevice device, AttributionSource attributionSource) { 1672 // don't check caller, may be called from system UI 1673 Attributable.setAttributionSource(device, attributionSource); 1674 AdapterService service = getService(); 1675 if (service == null || !Utils.checkConnectPermissionForDataDelivery( 1676 service, attributionSource, "AdapterService isBondingInitiatedLocally")) { 1677 return false; 1678 } 1679 1680 DeviceProperties deviceProp = service.mRemoteDevices.getDeviceProperties(device); 1681 return deviceProp != null && deviceProp.isBondingInitiatedLocally(); 1682 } 1683 1684 @Override generateLocalOobData(int transport, IBluetoothOobDataCallback callback, AttributionSource source)1685 public void generateLocalOobData(int transport, IBluetoothOobDataCallback callback, 1686 AttributionSource source) { 1687 AdapterService service = getService(); 1688 if (service == null 1689 || !Utils.checkCallerIsSystemOrActiveOrManagedUser(service, TAG) 1690 || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) { 1691 return; 1692 } 1693 enforceBluetoothPrivilegedPermission(service); 1694 service.generateLocalOobData(transport, callback); 1695 } 1696 1697 @Override getSupportedProfiles()1698 public long getSupportedProfiles() { 1699 AdapterService service = getService(); 1700 if (service == null) { 1701 return 0; 1702 } 1703 return Config.getSupportedProfilesBitMask(); 1704 } 1705 1706 @Override getConnectionState(BluetoothDevice device)1707 public int getConnectionState(BluetoothDevice device) { 1708 return getConnectionStateWithAttribution(device, Utils.getCallingAttributionSource()); 1709 } 1710 1711 @Override getConnectionStateWithAttribution( BluetoothDevice device, AttributionSource attributionSource)1712 public int getConnectionStateWithAttribution( 1713 BluetoothDevice device, AttributionSource attributionSource) { 1714 Attributable.setAttributionSource(device, attributionSource); 1715 AdapterService service = getService(); 1716 if (service == null || !Utils.checkConnectPermissionForDataDelivery( 1717 service, attributionSource, "AdapterService getConnectionState")) { 1718 return 0; 1719 } 1720 1721 return service.getConnectionState(device); 1722 } 1723 1724 @Override canBondWithoutDialog(BluetoothDevice device, AttributionSource source)1725 public boolean canBondWithoutDialog(BluetoothDevice device, AttributionSource source) { 1726 Attributable.setAttributionSource(device, source); 1727 AdapterService service = getService(); 1728 if (service == null 1729 || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) { 1730 return false; 1731 } 1732 1733 enforceBluetoothPrivilegedPermission(service); 1734 1735 return service.canBondWithoutDialog(device); 1736 } 1737 1738 @Override removeActiveDevice(@ctiveDeviceUse int profiles, AttributionSource source)1739 public boolean removeActiveDevice(@ActiveDeviceUse int profiles, 1740 AttributionSource source) { 1741 AdapterService service = getService(); 1742 if (service == null 1743 || !Utils.checkCallerIsSystemOrActiveUser(TAG) 1744 || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) { 1745 return false; 1746 } 1747 return service.setActiveDevice(null, profiles); 1748 } 1749 1750 @Override setActiveDevice(BluetoothDevice device, @ActiveDeviceUse int profiles, AttributionSource source)1751 public boolean setActiveDevice(BluetoothDevice device, @ActiveDeviceUse int profiles, 1752 AttributionSource source) { 1753 Attributable.setAttributionSource(device, source); 1754 AdapterService service = getService(); 1755 if (service == null 1756 || !Utils.checkCallerIsSystemOrActiveUser(TAG) 1757 || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) { 1758 return false; 1759 } 1760 return service.setActiveDevice(device, profiles); 1761 } 1762 1763 @Override connectAllEnabledProfiles(BluetoothDevice device, AttributionSource source)1764 public boolean connectAllEnabledProfiles(BluetoothDevice device, 1765 AttributionSource source) { 1766 Attributable.setAttributionSource(device, source); 1767 AdapterService service = getService(); 1768 if (service == null 1769 || !Utils.checkCallerIsSystemOrActiveUser(TAG) 1770 || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) { 1771 return false; 1772 } 1773 1774 enforceBluetoothPrivilegedPermission(service); 1775 1776 try { 1777 return service.connectAllEnabledProfiles(device); 1778 } catch (Exception e) { 1779 Log.v(TAG, "connectAllEnabledProfiles() failed", e); 1780 SneakyThrow.sneakyThrow(e); 1781 throw new RuntimeException(e); 1782 } 1783 } 1784 1785 @Override disconnectAllEnabledProfiles(BluetoothDevice device, AttributionSource source)1786 public boolean disconnectAllEnabledProfiles(BluetoothDevice device, 1787 AttributionSource source) { 1788 Attributable.setAttributionSource(device, source); 1789 AdapterService service = getService(); 1790 if (service == null 1791 || !Utils.checkCallerIsSystemOrActiveUser(TAG) 1792 || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) { 1793 return false; 1794 } 1795 1796 enforceBluetoothPrivilegedPermission(service); 1797 1798 try { 1799 return service.disconnectAllEnabledProfiles(device); 1800 } catch (Exception e) { 1801 Log.v(TAG, "disconnectAllEnabledProfiles() failed", e); 1802 SneakyThrow.sneakyThrow(e); 1803 throw new RuntimeException(e); 1804 } 1805 } 1806 1807 @Override getRemoteName(BluetoothDevice device, AttributionSource attributionSource)1808 public String getRemoteName(BluetoothDevice device, AttributionSource attributionSource) { 1809 Attributable.setAttributionSource(device, attributionSource); 1810 AdapterService service = getService(); 1811 if (service == null 1812 || !callerIsSystemOrActiveOrManagedUser(service, TAG, "getRemoteName") 1813 || !Utils.checkConnectPermissionForDataDelivery( 1814 service, attributionSource, "AdapterService getRemoteName")) { 1815 return null; 1816 } 1817 1818 return service.getRemoteName(device); 1819 } 1820 1821 @Override getRemoteType(BluetoothDevice device, AttributionSource attributionSource)1822 public int getRemoteType(BluetoothDevice device, AttributionSource attributionSource) { 1823 Attributable.setAttributionSource(device, attributionSource); 1824 AdapterService service = getService(); 1825 if (service == null 1826 || !callerIsSystemOrActiveOrManagedUser(service, TAG, "getRemoteType") 1827 || !Utils.checkConnectPermissionForDataDelivery( 1828 service, attributionSource, "AdapterService getRemoteType")) { 1829 return BluetoothDevice.DEVICE_TYPE_UNKNOWN; 1830 } 1831 1832 DeviceProperties deviceProp = service.mRemoteDevices.getDeviceProperties(device); 1833 return deviceProp != null ? deviceProp.getDeviceType() : BluetoothDevice.DEVICE_TYPE_UNKNOWN; 1834 } 1835 1836 @Override getRemoteAlias(BluetoothDevice device)1837 public String getRemoteAlias(BluetoothDevice device) { 1838 return getRemoteAliasWithAttribution(device, Utils.getCallingAttributionSource()); 1839 } 1840 1841 @Override getRemoteAliasWithAttribution( BluetoothDevice device, AttributionSource attributionSource)1842 public String getRemoteAliasWithAttribution( 1843 BluetoothDevice device, AttributionSource attributionSource) { 1844 Attributable.setAttributionSource(device, attributionSource); 1845 AdapterService service = getService(); 1846 if (service == null 1847 || !callerIsSystemOrActiveOrManagedUser(service, TAG, "getRemoteAlias") 1848 || !Utils.checkConnectPermissionForDataDelivery( 1849 service, attributionSource, "AdapterService getRemoteAlias")) { 1850 return null; 1851 } 1852 1853 DeviceProperties deviceProp = service.mRemoteDevices.getDeviceProperties(device); 1854 return deviceProp != null ? deviceProp.getAlias() : null; 1855 } 1856 1857 @Override setRemoteAlias(BluetoothDevice device, String name, AttributionSource attributionSource)1858 public int setRemoteAlias(BluetoothDevice device, String name, 1859 AttributionSource attributionSource) { 1860 Attributable.setAttributionSource(device, attributionSource); 1861 AdapterService service = getService(); 1862 if (service == null) { 1863 return BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ENABLED; 1864 } 1865 if (!callerIsSystemOrActiveUser(TAG, "setRemoteAlias")) { 1866 return BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ALLOWED; 1867 } 1868 if (name != null && name.isEmpty()) { 1869 throw new IllegalArgumentException("alias cannot be the empty string"); 1870 } 1871 1872 if (!hasBluetoothPrivilegedPermission(service)) { 1873 if (!Utils.checkConnectPermissionForDataDelivery( 1874 service, attributionSource, "AdapterService setRemoteAlias")) { 1875 return BluetoothStatusCodes.ERROR_MISSING_BLUETOOTH_CONNECT_PERMISSION; 1876 } 1877 enforceCdmAssociation(service.mCompanionDeviceManager, service, 1878 attributionSource.getPackageName(), Binder.getCallingUid(), device); 1879 } 1880 1881 DeviceProperties deviceProp = service.mRemoteDevices.getDeviceProperties(device); 1882 if (deviceProp == null) { 1883 return BluetoothStatusCodes.ERROR_DEVICE_NOT_BONDED; 1884 } 1885 deviceProp.setAlias(device, name); 1886 return BluetoothStatusCodes.SUCCESS; 1887 } 1888 1889 @Override getRemoteClass(BluetoothDevice device, AttributionSource attributionSource)1890 public int getRemoteClass(BluetoothDevice device, AttributionSource attributionSource) { 1891 Attributable.setAttributionSource(device, attributionSource); 1892 AdapterService service = getService(); 1893 if (service == null 1894 || !callerIsSystemOrActiveOrManagedUser(service, TAG, "getRemoteClass") 1895 || !Utils.checkConnectPermissionForDataDelivery( 1896 service, attributionSource, "AdapterService getRemoteClass")) { 1897 return 0; 1898 } 1899 1900 DeviceProperties deviceProp = service.mRemoteDevices.getDeviceProperties(device); 1901 return deviceProp != null ? deviceProp.getBluetoothClass() : 0; 1902 } 1903 1904 @Override getRemoteUuids( BluetoothDevice device, AttributionSource attributionSource)1905 public ParcelUuid[] getRemoteUuids( 1906 BluetoothDevice device, AttributionSource attributionSource) { 1907 Attributable.setAttributionSource(device, attributionSource); 1908 AdapterService service = getService(); 1909 if (service == null 1910 || !callerIsSystemOrActiveOrManagedUser(service, TAG, "getRemoteUuids") 1911 || !Utils.checkConnectPermissionForDataDelivery( 1912 service, attributionSource, "AdapterService getRemoteUuids")) { 1913 return new ParcelUuid[0]; 1914 } 1915 1916 return service.getRemoteUuids(device); 1917 } 1918 1919 @Override fetchRemoteUuids(BluetoothDevice device)1920 public boolean fetchRemoteUuids(BluetoothDevice device) { 1921 return fetchRemoteUuidsWithAttribution(device, Utils.getCallingAttributionSource()); 1922 } 1923 1924 @Override fetchRemoteUuidsWithAttribution( BluetoothDevice device, AttributionSource attributionSource)1925 public boolean fetchRemoteUuidsWithAttribution( 1926 BluetoothDevice device, AttributionSource attributionSource) { 1927 Attributable.setAttributionSource(device, attributionSource); 1928 AdapterService service = getService(); 1929 if (service == null 1930 || !callerIsSystemOrActiveOrManagedUser(service, TAG, "fetchRemoteUuids") 1931 || !Utils.checkConnectPermissionForDataDelivery( 1932 service, attributionSource, "AdapterService fetchRemoteUuids")) { 1933 return false; 1934 } 1935 1936 service.mRemoteDevices.fetchUuids(device); 1937 return true; 1938 } 1939 1940 1941 @Override setPin(BluetoothDevice device, boolean accept, int len, byte[] pinCode, AttributionSource attributionSource)1942 public boolean setPin(BluetoothDevice device, boolean accept, int len, byte[] pinCode, 1943 AttributionSource attributionSource) { 1944 Attributable.setAttributionSource(device, attributionSource); 1945 AdapterService service = getService(); 1946 if (service == null || !callerIsSystemOrActiveUser(TAG, "setPin") 1947 || !Utils.checkConnectPermissionForDataDelivery( 1948 service, attributionSource, "AdapterService setPin")) { 1949 return false; 1950 } 1951 1952 DeviceProperties deviceProp = service.mRemoteDevices.getDeviceProperties(device); 1953 // Only allow setting a pin in bonding state, or bonded state in case of security 1954 // upgrade. 1955 if (deviceProp == null || !deviceProp.isBondingOrBonded()) { 1956 return false; 1957 } 1958 if (pinCode.length != len) { 1959 android.util.EventLog.writeEvent(0x534e4554, "139287605", -1, 1960 "PIN code length mismatch"); 1961 return false; 1962 } 1963 service.logUserBondResponse(device, accept, BluetoothProtoEnums.BOND_SUB_STATE_LOCAL_PIN_REPLIED); 1964 return service.pinReplyNative(addressToBytes(device.getAddress()), accept, len, pinCode); 1965 } 1966 1967 @Override setPasskey(BluetoothDevice device, boolean accept, int len, byte[] passkey, AttributionSource attributionSource)1968 public boolean setPasskey(BluetoothDevice device, boolean accept, int len, byte[] passkey, 1969 AttributionSource attributionSource) { 1970 Attributable.setAttributionSource(device, attributionSource); 1971 AdapterService service = getService(); 1972 if (service == null || !callerIsSystemOrActiveUser(TAG, "setPasskey") 1973 || !Utils.checkConnectPermissionForDataDelivery( 1974 service, attributionSource, "AdapterService setPasskey")) { 1975 return false; 1976 } 1977 1978 DeviceProperties deviceProp = service.mRemoteDevices.getDeviceProperties(device); 1979 if (deviceProp == null || !deviceProp.isBonding()) { 1980 return false; 1981 } 1982 if (passkey.length != len) { 1983 android.util.EventLog.writeEvent(0x534e4554, "139287605", -1, 1984 "Passkey length mismatch"); 1985 return false; 1986 } 1987 service.logUserBondResponse(device, accept, BluetoothProtoEnums.BOND_SUB_STATE_LOCAL_SSP_REPLIED); 1988 return service.sspReplyNative( 1989 addressToBytes(device.getAddress()), 1990 AbstractionLayer.BT_SSP_VARIANT_PASSKEY_ENTRY, 1991 accept, 1992 Utils.byteArrayToInt(passkey)); 1993 } 1994 1995 @Override setPairingConfirmation(BluetoothDevice device, boolean accept, AttributionSource source)1996 public boolean setPairingConfirmation(BluetoothDevice device, boolean accept, 1997 AttributionSource source) { 1998 Attributable.setAttributionSource(device, source); 1999 AdapterService service = getService(); 2000 if (service == null 2001 || !Utils.checkCallerIsSystemOrActiveUser(TAG) 2002 || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) { 2003 return false; 2004 } 2005 2006 enforceBluetoothPrivilegedPermission(service); 2007 2008 DeviceProperties deviceProp = service.mRemoteDevices.getDeviceProperties(device); 2009 if (deviceProp == null || !deviceProp.isBonding()) { 2010 return false; 2011 } 2012 service.logUserBondResponse(device, accept, BluetoothProtoEnums.BOND_SUB_STATE_LOCAL_SSP_REPLIED); 2013 return service.sspReplyNative( 2014 addressToBytes(device.getAddress()), 2015 AbstractionLayer.BT_SSP_VARIANT_PASSKEY_CONFIRMATION, 2016 accept, 2017 0); 2018 } 2019 2020 @Override getSilenceMode(BluetoothDevice device, AttributionSource source)2021 public boolean getSilenceMode(BluetoothDevice device, AttributionSource source) { 2022 Attributable.setAttributionSource(device, source); 2023 AdapterService service = getService(); 2024 if (service == null 2025 || !Utils.checkCallerIsSystemOrActiveUser(TAG) 2026 || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) { 2027 return false; 2028 } 2029 2030 enforceBluetoothPrivilegedPermission(service); 2031 2032 return service.mSilenceDeviceManager.getSilenceMode(device); 2033 } 2034 2035 2036 @Override setSilenceMode(BluetoothDevice device, boolean silence, AttributionSource source)2037 public boolean setSilenceMode(BluetoothDevice device, boolean silence, 2038 AttributionSource source) { 2039 Attributable.setAttributionSource(device, source); 2040 AdapterService service = getService(); 2041 if (service == null 2042 || !Utils.checkCallerIsSystemOrActiveUser(TAG) 2043 || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) { 2044 return false; 2045 } 2046 2047 enforceBluetoothPrivilegedPermission(service); 2048 2049 service.mSilenceDeviceManager.setSilenceMode(device, silence); 2050 return true; 2051 } 2052 2053 @Override getPhonebookAccessPermission( BluetoothDevice device, AttributionSource attributionSource)2054 public int getPhonebookAccessPermission( 2055 BluetoothDevice device, AttributionSource attributionSource) { 2056 Attributable.setAttributionSource(device, attributionSource); 2057 AdapterService service = getService(); 2058 if (service == null || !callerIsSystemOrActiveUser(TAG, "getPhonebookAccessPermission") 2059 || !Utils.checkConnectPermissionForDataDelivery( 2060 service, attributionSource, "AdapterService getPhonebookAccessPermission")) { 2061 return BluetoothDevice.ACCESS_UNKNOWN; 2062 } 2063 2064 return service.getDeviceAccessFromPrefs(device, PHONEBOOK_ACCESS_PERMISSION_PREFERENCE_FILE); 2065 } 2066 2067 @Override setPhonebookAccessPermission(BluetoothDevice device, int value, AttributionSource source)2068 public boolean setPhonebookAccessPermission(BluetoothDevice device, int value, 2069 AttributionSource source) { 2070 Attributable.setAttributionSource(device, source); 2071 AdapterService service = getService(); 2072 if (service == null 2073 || !Utils.checkCallerIsSystemOrActiveUser(TAG) 2074 || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) { 2075 return false; 2076 } 2077 2078 enforceBluetoothPrivilegedPermission(service); 2079 2080 service.setPhonebookAccessPermission(device, value); 2081 return true; 2082 } 2083 2084 @Override getMessageAccessPermission( BluetoothDevice device, AttributionSource attributionSource)2085 public int getMessageAccessPermission( 2086 BluetoothDevice device, AttributionSource attributionSource) { 2087 Attributable.setAttributionSource(device, attributionSource); 2088 AdapterService service = getService(); 2089 if (service == null || !callerIsSystemOrActiveUser(TAG, "getMessageAccessPermission") 2090 || !Utils.checkConnectPermissionForDataDelivery( 2091 service, attributionSource, "AdapterService getMessageAccessPermission")) { 2092 return BluetoothDevice.ACCESS_UNKNOWN; 2093 } 2094 2095 return service.getDeviceAccessFromPrefs(device, MESSAGE_ACCESS_PERMISSION_PREFERENCE_FILE); 2096 } 2097 2098 @Override setMessageAccessPermission(BluetoothDevice device, int value, AttributionSource source)2099 public boolean setMessageAccessPermission(BluetoothDevice device, int value, 2100 AttributionSource source) { 2101 Attributable.setAttributionSource(device, source); 2102 AdapterService service = getService(); 2103 if (service == null 2104 || !Utils.checkCallerIsSystemOrActiveUser(TAG) 2105 || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) { 2106 return false; 2107 } 2108 2109 enforceBluetoothPrivilegedPermission(service); 2110 2111 service.setMessageAccessPermission(device, value); 2112 return true; 2113 } 2114 2115 @Override getSimAccessPermission( BluetoothDevice device, AttributionSource attributionSource)2116 public int getSimAccessPermission( 2117 BluetoothDevice device, AttributionSource attributionSource) { 2118 Attributable.setAttributionSource(device, attributionSource); 2119 AdapterService service = getService(); 2120 if (service == null || !callerIsSystemOrActiveUser(TAG, "getSimAccessPermission") 2121 || !Utils.checkConnectPermissionForDataDelivery( 2122 service, attributionSource, "AdapterService getSimAccessPermission")) { 2123 return BluetoothDevice.ACCESS_UNKNOWN; 2124 } 2125 2126 return service.getDeviceAccessFromPrefs(device, SIM_ACCESS_PERMISSION_PREFERENCE_FILE); 2127 } 2128 2129 @Override setSimAccessPermission(BluetoothDevice device, int value, AttributionSource source)2130 public boolean setSimAccessPermission(BluetoothDevice device, int value, 2131 AttributionSource source) { 2132 Attributable.setAttributionSource(device, source); 2133 AdapterService service = getService(); 2134 if (service == null 2135 || !Utils.checkCallerIsSystemOrActiveUser(TAG) 2136 || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) { 2137 return false; 2138 } 2139 2140 enforceBluetoothPrivilegedPermission(service); 2141 2142 service.setSimAccessPermission(device, value); 2143 return true; 2144 } 2145 2146 @Override getSocketManager()2147 public IBluetoothSocketManager getSocketManager() { 2148 AdapterService service = getService(); 2149 if (service == null) { 2150 return null; 2151 } 2152 2153 return IBluetoothSocketManager.Stub.asInterface(service.mBluetoothSocketManagerBinder); 2154 } 2155 2156 @Override sdpSearch( BluetoothDevice device, ParcelUuid uuid, AttributionSource attributionSource)2157 public boolean sdpSearch( 2158 BluetoothDevice device, ParcelUuid uuid, AttributionSource attributionSource) { 2159 Attributable.setAttributionSource(device, attributionSource); 2160 AdapterService service = getService(); 2161 if (service == null || !callerIsSystemOrActiveUser(TAG, "sdpSearch") 2162 || !Utils.checkConnectPermissionForDataDelivery( 2163 service, attributionSource, "AdapterService sdpSearch")) { 2164 return false; 2165 } 2166 2167 if (service.mSdpManager == null) { 2168 return false; 2169 } 2170 service.mSdpManager.sdpSearch(device, uuid); 2171 return true; 2172 } 2173 2174 @Override getBatteryLevel(BluetoothDevice device, AttributionSource attributionSource)2175 public int getBatteryLevel(BluetoothDevice device, AttributionSource attributionSource) { 2176 Attributable.setAttributionSource(device, attributionSource); 2177 AdapterService service = getService(); 2178 if (service == null || !callerIsSystemOrActiveUser(TAG, "getBatteryLevel") 2179 || !Utils.checkConnectPermissionForDataDelivery( 2180 service, attributionSource, "AdapterService getBatteryLevel")) { 2181 return BluetoothDevice.BATTERY_LEVEL_UNKNOWN; 2182 } 2183 2184 DeviceProperties deviceProp = service.mRemoteDevices.getDeviceProperties(device); 2185 if (deviceProp == null) { 2186 return BluetoothDevice.BATTERY_LEVEL_UNKNOWN; 2187 } 2188 return deviceProp.getBatteryLevel(); 2189 } 2190 2191 @Override getMaxConnectedAudioDevices(AttributionSource attributionSource)2192 public int getMaxConnectedAudioDevices(AttributionSource attributionSource) { 2193 // don't check caller, may be called from system UI 2194 AdapterService service = getService(); 2195 if (service == null || !Utils.checkConnectPermissionForDataDelivery( 2196 service, attributionSource, "AdapterService getMaxConnectedAudioDevices")) { 2197 return AdapterProperties.MAX_CONNECTED_AUDIO_DEVICES_LOWER_BOND; 2198 } 2199 2200 return service.getMaxConnectedAudioDevices(); 2201 } 2202 2203 //@Override 2204 @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) isA2dpOffloadEnabled(AttributionSource attributionSource)2205 public boolean isA2dpOffloadEnabled(AttributionSource attributionSource) { 2206 // don't check caller, may be called from system UI 2207 AdapterService service = getService(); 2208 if (service == null || !Utils.checkConnectPermissionForDataDelivery( 2209 service, attributionSource, "AdapterService isA2dpOffloadEnabled")) { 2210 return false; 2211 } 2212 2213 return service.isA2dpOffloadEnabled(); 2214 } 2215 2216 @Override factoryReset(AttributionSource source)2217 public boolean factoryReset(AttributionSource source) { 2218 AdapterService service = getService(); 2219 if (service == null 2220 || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) { 2221 return false; 2222 } 2223 2224 enforceBluetoothPrivilegedPermission(service); 2225 2226 if (service.mDatabaseManager != null) { 2227 service.mDatabaseManager.factoryReset(); 2228 } 2229 2230 if (service.mBluetoothKeystoreService != null) { 2231 service.mBluetoothKeystoreService.factoryReset(); 2232 } 2233 2234 return service.factoryResetNative(); 2235 } 2236 2237 @Override registerBluetoothConnectionCallback(IBluetoothConnectionCallback callback, AttributionSource source)2238 public boolean registerBluetoothConnectionCallback(IBluetoothConnectionCallback callback, 2239 AttributionSource source) { 2240 AdapterService service = getService(); 2241 if (service == null 2242 || !Utils.checkCallerIsSystemOrActiveUser(TAG) 2243 || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) { 2244 return false; 2245 } 2246 enforceBluetoothPrivilegedPermission(service); 2247 service.mBluetoothConnectionCallbacks.add(callback); 2248 return true; 2249 } 2250 2251 @Override unregisterBluetoothConnectionCallback(IBluetoothConnectionCallback callback, AttributionSource source)2252 public boolean unregisterBluetoothConnectionCallback(IBluetoothConnectionCallback callback, 2253 AttributionSource source) { 2254 AdapterService service = getService(); 2255 if (service == null 2256 || !Utils.checkCallerIsSystemOrActiveUser(TAG) 2257 || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) { 2258 return false; 2259 } 2260 enforceBluetoothPrivilegedPermission(service); 2261 return service.mBluetoothConnectionCallbacks.remove(callback); 2262 } 2263 2264 @Override registerCallback(IBluetoothCallback callback, AttributionSource source)2265 public void registerCallback(IBluetoothCallback callback, AttributionSource source) { 2266 AdapterService service = getService(); 2267 if (service == null 2268 || !Utils.checkCallerIsSystemOrActiveUser(TAG) 2269 || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) { 2270 return; 2271 } 2272 2273 enforceBluetoothPrivilegedPermission(service); 2274 2275 service.mCallbacks.register(callback); 2276 } 2277 2278 @Override unregisterCallback(IBluetoothCallback callback, AttributionSource source)2279 public void unregisterCallback(IBluetoothCallback callback, AttributionSource source) { 2280 AdapterService service = getService(); 2281 if (service == null || service.mCallbacks == null 2282 || !Utils.checkCallerIsSystemOrActiveUser(TAG) 2283 || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) { 2284 return; 2285 } 2286 2287 enforceBluetoothPrivilegedPermission(service); 2288 2289 service.mCallbacks.unregister(callback); 2290 } 2291 2292 @Override isMultiAdvertisementSupported()2293 public boolean isMultiAdvertisementSupported() { 2294 AdapterService service = getService(); 2295 if (service == null) { 2296 return false; 2297 } 2298 2299 int val = service.mAdapterProperties.getNumOfAdvertisementInstancesSupported(); 2300 return val >= MIN_ADVT_INSTANCES_FOR_MA; 2301 } 2302 2303 /** 2304 * This method has an associated binder cache. The invalidation 2305 * methods must be changed if the logic behind this method changes. 2306 */ 2307 @Override isOffloadedFilteringSupported()2308 public boolean isOffloadedFilteringSupported() { 2309 AdapterService service = getService(); 2310 if (service == null) { 2311 return false; 2312 } 2313 2314 int val = service.getNumOfOffloadedScanFilterSupported(); 2315 return val >= MIN_OFFLOADED_FILTERS; 2316 } 2317 2318 @Override isOffloadedScanBatchingSupported()2319 public boolean isOffloadedScanBatchingSupported() { 2320 AdapterService service = getService(); 2321 if (service == null) { 2322 return false; 2323 } 2324 2325 int val = service.getOffloadedScanResultStorage(); 2326 return val >= MIN_OFFLOADED_SCAN_STORAGE_BYTES; 2327 } 2328 2329 @Override isLe2MPhySupported()2330 public boolean isLe2MPhySupported() { 2331 AdapterService service = getService(); 2332 if (service == null) { 2333 return false; 2334 } 2335 2336 return service.isLe2MPhySupported(); 2337 } 2338 2339 @Override isLeCodedPhySupported()2340 public boolean isLeCodedPhySupported() { 2341 AdapterService service = getService(); 2342 if (service == null) { 2343 return false; 2344 } 2345 2346 return service.isLeCodedPhySupported(); 2347 } 2348 2349 @Override isLeExtendedAdvertisingSupported()2350 public boolean isLeExtendedAdvertisingSupported() { 2351 AdapterService service = getService(); 2352 if (service == null) { 2353 return false; 2354 } 2355 2356 return service.isLeExtendedAdvertisingSupported(); 2357 } 2358 2359 @Override isLePeriodicAdvertisingSupported()2360 public boolean isLePeriodicAdvertisingSupported() { 2361 AdapterService service = getService(); 2362 if (service == null) { 2363 return false; 2364 } 2365 2366 return service.isLePeriodicAdvertisingSupported(); 2367 } 2368 2369 @Override getLeMaximumAdvertisingDataLength()2370 public int getLeMaximumAdvertisingDataLength() { 2371 AdapterService service = getService(); 2372 if (service == null) { 2373 return 0; 2374 } 2375 2376 return service.getLeMaximumAdvertisingDataLength(); 2377 } 2378 2379 @Override isActivityAndEnergyReportingSupported()2380 public boolean isActivityAndEnergyReportingSupported() { 2381 AdapterService service = getService(); 2382 if (service == null) { 2383 return false; 2384 } 2385 2386 return service.mAdapterProperties.isActivityAndEnergyReportingSupported(); 2387 } 2388 2389 @Override reportActivityInfo(AttributionSource source)2390 public BluetoothActivityEnergyInfo reportActivityInfo(AttributionSource source) { 2391 AdapterService service = getService(); 2392 if (service == null 2393 || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) { 2394 return null; 2395 } 2396 2397 enforceBluetoothPrivilegedPermission(service); 2398 2399 return service.reportActivityInfo(); 2400 } 2401 2402 @Override registerMetadataListener(IBluetoothMetadataListener listener, BluetoothDevice device, AttributionSource source)2403 public boolean registerMetadataListener(IBluetoothMetadataListener listener, 2404 BluetoothDevice device, AttributionSource source) { 2405 Attributable.setAttributionSource(device, source); 2406 AdapterService service = getService(); 2407 if (service == null 2408 || !Utils.checkCallerIsSystemOrActiveUser(TAG) 2409 || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) { 2410 return false; 2411 } 2412 2413 enforceBluetoothPrivilegedPermission(service); 2414 2415 if (service.mMetadataListeners == null) { 2416 return false; 2417 } 2418 ArrayList<IBluetoothMetadataListener> list = service.mMetadataListeners.get(device); 2419 if (list == null) { 2420 list = new ArrayList<>(); 2421 } else if (list.contains(listener)) { 2422 // The device is already registered with this listener 2423 return true; 2424 } 2425 list.add(listener); 2426 service.mMetadataListeners.put(device, list); 2427 return true; 2428 } 2429 2430 @Override unregisterMetadataListener(BluetoothDevice device, AttributionSource source)2431 public boolean unregisterMetadataListener(BluetoothDevice device, 2432 AttributionSource source) { 2433 Attributable.setAttributionSource(device, source); 2434 AdapterService service = getService(); 2435 if (service == null 2436 || !Utils.checkCallerIsSystemOrActiveUser(TAG) 2437 || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) { 2438 return false; 2439 } 2440 2441 enforceBluetoothPrivilegedPermission(service); 2442 2443 if (service.mMetadataListeners == null) { 2444 return false; 2445 } 2446 if (service.mMetadataListeners.containsKey(device)) { 2447 service.mMetadataListeners.remove(device); 2448 } 2449 return true; 2450 } 2451 2452 @Override setMetadata(BluetoothDevice device, int key, byte[] value, AttributionSource source)2453 public boolean setMetadata(BluetoothDevice device, int key, byte[] value, 2454 AttributionSource source) { 2455 Attributable.setAttributionSource(device, source); 2456 AdapterService service = getService(); 2457 if (service == null 2458 || !Utils.checkCallerIsSystemOrActiveUser(TAG) 2459 || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) { 2460 return false; 2461 } 2462 2463 enforceBluetoothPrivilegedPermission(service); 2464 2465 if (value.length > BluetoothDevice.METADATA_MAX_LENGTH) { 2466 return false; 2467 } 2468 return service.mDatabaseManager.setCustomMeta(device, key, value); 2469 } 2470 2471 @Override getMetadata(BluetoothDevice device, int key, AttributionSource source)2472 public byte[] getMetadata(BluetoothDevice device, int key, 2473 AttributionSource source) { 2474 Attributable.setAttributionSource(device, source); 2475 AdapterService service = getService(); 2476 if (service == null 2477 || !Utils.checkCallerIsSystemOrActiveUser(TAG) 2478 || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) { 2479 return null; 2480 } 2481 2482 enforceBluetoothPrivilegedPermission(service); 2483 2484 return service.mDatabaseManager.getCustomMeta(device, key); 2485 } 2486 2487 @Override requestActivityInfo(ResultReceiver result, AttributionSource source)2488 public void requestActivityInfo(ResultReceiver result, AttributionSource source) { 2489 Bundle bundle = new Bundle(); 2490 bundle.putParcelable(BatteryStats.RESULT_RECEIVER_CONTROLLER_KEY, 2491 reportActivityInfo(source)); 2492 result.send(0, bundle); 2493 } 2494 2495 @Override onLeServiceUp(AttributionSource source)2496 public void onLeServiceUp(AttributionSource source) { 2497 AdapterService service = getService(); 2498 if (service == null 2499 || !Utils.checkCallerIsSystemOrActiveUser(TAG) 2500 || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) { 2501 return; 2502 } 2503 2504 enforceBluetoothPrivilegedPermission(service); 2505 2506 service.mAdapterStateMachine.sendMessage(AdapterState.USER_TURN_ON); 2507 } 2508 2509 @Override onBrEdrDown(AttributionSource source)2510 public void onBrEdrDown(AttributionSource source) { 2511 AdapterService service = getService(); 2512 if (service == null 2513 || !Utils.checkCallerIsSystemOrActiveUser(TAG) 2514 || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) { 2515 return; 2516 } 2517 2518 enforceBluetoothPrivilegedPermission(service); 2519 2520 service.mAdapterStateMachine.sendMessage(AdapterState.BLE_TURN_OFF); 2521 } 2522 2523 @Override dump(FileDescriptor fd, String[] args)2524 public void dump(FileDescriptor fd, String[] args) { 2525 PrintWriter writer = new PrintWriter(new FileOutputStream(fd)); 2526 AdapterService service = getService(); 2527 if (service == null) { 2528 return; 2529 } 2530 2531 enforceDumpPermission(service); 2532 2533 service.dump(fd, writer, args); 2534 writer.close(); 2535 } 2536 } 2537 2538 // ----API Methods-------- 2539 isEnabled()2540 public boolean isEnabled() { 2541 return getState() == BluetoothAdapter.STATE_ON; 2542 } 2543 getState()2544 public int getState() { 2545 if (mAdapterProperties != null) { 2546 return mAdapterProperties.getState(); 2547 } 2548 return BluetoothAdapter.STATE_OFF; 2549 } 2550 enable(boolean quietMode)2551 public synchronized boolean enable(boolean quietMode) { 2552 // Enforce the user restriction for disallowing Bluetooth if it was set. 2553 if (mUserManager.hasUserRestriction(UserManager.DISALLOW_BLUETOOTH, UserHandle.SYSTEM)) { 2554 debugLog("enable() called when Bluetooth was disallowed"); 2555 return false; 2556 } 2557 2558 debugLog("enable() - Enable called with quiet mode status = " + quietMode); 2559 mQuietmode = quietMode; 2560 mAdapterStateMachine.sendMessage(AdapterState.BLE_TURN_ON); 2561 return true; 2562 } 2563 disable()2564 boolean disable() { 2565 debugLog("disable() called with mRunningProfiles.size() = " + mRunningProfiles.size()); 2566 mAdapterStateMachine.sendMessage(AdapterState.USER_TURN_OFF); 2567 return true; 2568 } 2569 getName()2570 public String getName() { 2571 return mAdapterProperties.getName(); 2572 } 2573 getNameLengthForAdvertise()2574 public int getNameLengthForAdvertise() { 2575 return mAdapterProperties.getName().length(); 2576 } 2577 isValidIoCapability(int capability)2578 private static boolean isValidIoCapability(int capability) { 2579 if (capability < 0 || capability >= BluetoothAdapter.IO_CAPABILITY_MAX) { 2580 Log.e(TAG, "Invalid IO capability value - " + capability); 2581 return false; 2582 } 2583 2584 return true; 2585 } 2586 getDiscoveringPackages()2587 ArrayList<DiscoveringPackage> getDiscoveringPackages() { 2588 return mDiscoveringPackages; 2589 } 2590 clearDiscoveringPackages()2591 void clearDiscoveringPackages() { 2592 synchronized (mDiscoveringPackages) { 2593 mDiscoveringPackages.clear(); 2594 } 2595 } 2596 startDiscovery(AttributionSource attributionSource)2597 boolean startDiscovery(AttributionSource attributionSource) { 2598 UserHandle callingUser = UserHandle.of(UserHandle.getCallingUserId()); 2599 debugLog("startDiscovery"); 2600 String callingPackage = attributionSource.getPackageName(); 2601 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage); 2602 boolean isQApp = Utils.isQApp(this, callingPackage); 2603 boolean hasDisavowedLocation = 2604 Utils.hasDisavowedLocationForScan(this, attributionSource, mTestModeEnabled); 2605 String permission = null; 2606 if (Utils.checkCallerHasNetworkSettingsPermission(this)) { 2607 permission = android.Manifest.permission.NETWORK_SETTINGS; 2608 } else if (Utils.checkCallerHasNetworkSetupWizardPermission(this)) { 2609 permission = android.Manifest.permission.NETWORK_SETUP_WIZARD; 2610 } else if (!hasDisavowedLocation) { 2611 if (isQApp) { 2612 if (!Utils.checkCallerHasFineLocation(this, attributionSource, callingUser)) { 2613 return false; 2614 } 2615 permission = android.Manifest.permission.ACCESS_FINE_LOCATION; 2616 } else { 2617 if (!Utils.checkCallerHasCoarseLocation(this, attributionSource, callingUser)) { 2618 return false; 2619 } 2620 permission = android.Manifest.permission.ACCESS_COARSE_LOCATION; 2621 } 2622 } 2623 2624 synchronized (mDiscoveringPackages) { 2625 mDiscoveringPackages.add( 2626 new DiscoveringPackage(callingPackage, permission, hasDisavowedLocation)); 2627 } 2628 return startDiscoveryNative(); 2629 } 2630 2631 /** 2632 * Same as API method {@link BluetoothAdapter#getBondedDevices()} 2633 * 2634 * @return array of bonded {@link BluetoothDevice} or null on error 2635 */ getBondedDevices()2636 public BluetoothDevice[] getBondedDevices() { 2637 return mAdapterProperties.getBondedDevices(); 2638 } 2639 2640 /** 2641 * Get the database manager to access Bluetooth storage 2642 * 2643 * @return {@link DatabaseManager} or null on error 2644 */ 2645 @VisibleForTesting getDatabase()2646 public DatabaseManager getDatabase() { 2647 return mDatabaseManager; 2648 } 2649 2650 private class CallerInfo { 2651 public String callerPackageName; 2652 public UserHandle user; 2653 } 2654 createBond(BluetoothDevice device, int transport, OobData remoteP192Data, OobData remoteP256Data, String callingPackage)2655 boolean createBond(BluetoothDevice device, int transport, OobData remoteP192Data, 2656 OobData remoteP256Data, String callingPackage) { 2657 DeviceProperties deviceProp = mRemoteDevices.getDeviceProperties(device); 2658 if (deviceProp != null && deviceProp.getBondState() != BluetoothDevice.BOND_NONE) { 2659 return false; 2660 } 2661 2662 if (!isPackageNameAccurate(this, callingPackage, Binder.getCallingUid())) { 2663 return false; 2664 } 2665 2666 CallerInfo createBondCaller = new CallerInfo(); 2667 createBondCaller.callerPackageName = callingPackage; 2668 createBondCaller.user = UserHandle.of(UserHandle.getCallingUserId()); 2669 mBondAttemptCallerInfo.put(device.getAddress(), createBondCaller); 2670 2671 mRemoteDevices.setBondingInitiatedLocally(Utils.getByteAddress(device)); 2672 2673 // Pairing is unreliable while scanning, so cancel discovery 2674 // Note, remove this when native stack improves 2675 cancelDiscoveryNative(); 2676 2677 Message msg = mBondStateMachine.obtainMessage(BondStateMachine.CREATE_BOND); 2678 msg.obj = device; 2679 msg.arg1 = transport; 2680 2681 Bundle remoteOobDatasBundle = new Bundle(); 2682 boolean setData = false; 2683 if (remoteP192Data != null) { 2684 remoteOobDatasBundle.putParcelable(BondStateMachine.OOBDATAP192, remoteP192Data); 2685 setData = true; 2686 } 2687 if (remoteP256Data != null) { 2688 remoteOobDatasBundle.putParcelable(BondStateMachine.OOBDATAP256, remoteP256Data); 2689 setData = true; 2690 } 2691 if (setData) { 2692 msg.setData(remoteOobDatasBundle); 2693 } 2694 mBondStateMachine.sendMessage(msg); 2695 return true; 2696 } 2697 2698 private final ArrayDeque<IBluetoothOobDataCallback> mOobDataCallbackQueue = 2699 new ArrayDeque<>(); 2700 2701 /** 2702 * Fetches the local OOB data to give out to remote. 2703 * 2704 * @param transport - specify data transport. 2705 * @param callback - callback used to receive the requested {@link Oobdata}; null will be 2706 * ignored silently. 2707 * 2708 * @hide 2709 */ generateLocalOobData(int transport, IBluetoothOobDataCallback callback)2710 public synchronized void generateLocalOobData(int transport, 2711 IBluetoothOobDataCallback callback) { 2712 if (callback == null) { 2713 Log.e(TAG, "'callback' argument must not be null!"); 2714 return; 2715 } 2716 if (mOobDataCallbackQueue.peek() != null) { 2717 try { 2718 callback.onError(BluetoothStatusCodes.ERROR_ANOTHER_ACTIVE_OOB_REQUEST); 2719 return; 2720 } catch (RemoteException e) { 2721 Log.e(TAG, "Failed to make callback", e); 2722 } 2723 } 2724 mOobDataCallbackQueue.offer(callback); 2725 generateLocalOobDataNative(transport); 2726 } 2727 notifyOobDataCallback(int transport, OobData oobData)2728 /* package */ synchronized void notifyOobDataCallback(int transport, OobData oobData) { 2729 if (mOobDataCallbackQueue.peek() == null) { 2730 Log.e(TAG, "Failed to make callback, no callback exists"); 2731 return; 2732 } 2733 if (oobData == null) { 2734 try { 2735 mOobDataCallbackQueue.poll().onError(BluetoothStatusCodes.ERROR_UNKNOWN); 2736 } catch (RemoteException e) { 2737 Log.e(TAG, "Failed to make callback", e); 2738 } 2739 } else { 2740 try { 2741 mOobDataCallbackQueue.poll().onOobData(transport, oobData); 2742 } catch (RemoteException e) { 2743 Log.e(TAG, "Failed to make callback", e); 2744 } 2745 } 2746 } 2747 isQuietModeEnabled()2748 public boolean isQuietModeEnabled() { 2749 debugLog("isQuetModeEnabled() - Enabled = " + mQuietmode); 2750 return mQuietmode; 2751 } 2752 updateUuids()2753 public void updateUuids() { 2754 debugLog("updateUuids() - Updating UUIDs for bonded devices"); 2755 BluetoothDevice[] bondedDevices = getBondedDevices(); 2756 if (bondedDevices == null) { 2757 return; 2758 } 2759 2760 for (BluetoothDevice device : bondedDevices) { 2761 mRemoteDevices.updateUuids(device); 2762 } 2763 } 2764 2765 /** 2766 * Update device UUID changed to {@link BondStateMachine} 2767 * 2768 * @param device remote device of interest 2769 */ deviceUuidUpdated(BluetoothDevice device)2770 public void deviceUuidUpdated(BluetoothDevice device) { 2771 // Notify BondStateMachine for SDP complete / UUID changed. 2772 Message msg = mBondStateMachine.obtainMessage(BondStateMachine.UUID_UPDATE); 2773 msg.obj = device; 2774 mBondStateMachine.sendMessage(msg); 2775 } 2776 2777 /** 2778 * Get the bond state of a particular {@link BluetoothDevice} 2779 * 2780 * @param device remote device of interest 2781 * @return bond state <p>Possible values are 2782 * {@link BluetoothDevice#BOND_NONE}, 2783 * {@link BluetoothDevice#BOND_BONDING}, 2784 * {@link BluetoothDevice#BOND_BONDED}. 2785 */ 2786 @VisibleForTesting getBondState(BluetoothDevice device)2787 public int getBondState(BluetoothDevice device) { 2788 DeviceProperties deviceProp = mRemoteDevices.getDeviceProperties(device); 2789 if (deviceProp == null) { 2790 return BluetoothDevice.BOND_NONE; 2791 } 2792 return deviceProp.getBondState(); 2793 } 2794 getConnectionState(BluetoothDevice device)2795 int getConnectionState(BluetoothDevice device) { 2796 return getConnectionStateNative(addressToBytes(device.getAddress())); 2797 } 2798 2799 /** 2800 * Checks whether the device was recently associated with the comapnion app that called 2801 * {@link BluetoothDevice#createBond}. This allows these devices to skip the pairing dialog if 2802 * their pairing variant is {@link BluetoothDevice#PAIRING_VARIANT_CONSENT}. 2803 * 2804 * @param device the bluetooth device that is being bonded 2805 * @return true if it was recently associated and we can bypass the dialog, false otherwise 2806 */ canBondWithoutDialog(BluetoothDevice device)2807 public boolean canBondWithoutDialog(BluetoothDevice device) { 2808 if (mBondAttemptCallerInfo.containsKey(device.getAddress())) { 2809 CallerInfo bondCallerInfo = mBondAttemptCallerInfo.get(device.getAddress()); 2810 2811 return mCompanionDeviceManager.canPairWithoutPrompt(bondCallerInfo.callerPackageName, 2812 device.getAddress(), bondCallerInfo.user); 2813 } 2814 return false; 2815 } 2816 2817 /** 2818 * Sets device as the active devices for the profiles passed into the function 2819 * 2820 * @param device is the remote bluetooth device 2821 * @param profiles is a constant that references for which profiles we'll be setting the remote 2822 * device as our active device. One of the following: 2823 * {@link BluetoothAdapter#ACTIVE_DEVICE_AUDIO}, 2824 * {@link BluetoothAdapter#ACTIVE_DEVICE_PHONE_CALL} 2825 * {@link BluetoothAdapter#ACTIVE_DEVICE_ALL} 2826 * @return false if profiles value is not one of the constants we accept, true otherwise 2827 */ 2828 @RequiresPermission(allOf = { 2829 android.Manifest.permission.BLUETOOTH_PRIVILEGED, 2830 android.Manifest.permission.MODIFY_PHONE_STATE, 2831 }) setActiveDevice(BluetoothDevice device, @ActiveDeviceUse int profiles)2832 public boolean setActiveDevice(BluetoothDevice device, @ActiveDeviceUse int profiles) { 2833 enforceCallingOrSelfPermission( 2834 BLUETOOTH_PRIVILEGED, "Need BLUETOOTH_PRIVILEGED permission"); 2835 2836 boolean setA2dp = false; 2837 boolean setHeadset = false; 2838 2839 // Determine for which profiles we want to set device as our active device 2840 switch(profiles) { 2841 case BluetoothAdapter.ACTIVE_DEVICE_AUDIO: 2842 setA2dp = true; 2843 break; 2844 case BluetoothAdapter.ACTIVE_DEVICE_PHONE_CALL: 2845 setHeadset = true; 2846 break; 2847 case BluetoothAdapter.ACTIVE_DEVICE_ALL: 2848 setA2dp = true; 2849 setHeadset = true; 2850 break; 2851 default: 2852 return false; 2853 } 2854 2855 if (setA2dp && mA2dpService != null && (device == null 2856 || mA2dpService.getConnectionPolicy(device) 2857 == BluetoothProfile.CONNECTION_POLICY_ALLOWED)) { 2858 Log.i(TAG, "setActiveDevice: Setting active A2dp device " + device); 2859 mA2dpService.setActiveDevice(device); 2860 } 2861 2862 if (mHearingAidService != null && (device == null 2863 || mHearingAidService.getConnectionPolicy(device) 2864 == BluetoothProfile.CONNECTION_POLICY_ALLOWED)) { 2865 Log.i(TAG, "setActiveDevice: Setting active Hearing Aid " + device); 2866 mHearingAidService.setActiveDevice(device); 2867 } 2868 2869 if (setHeadset && mHeadsetService != null && (device == null 2870 || mHeadsetService.getConnectionPolicy(device) 2871 == BluetoothProfile.CONNECTION_POLICY_ALLOWED)) { 2872 Log.i(TAG, "setActiveDevice: Setting active Headset " + device); 2873 mHeadsetService.setActiveDevice(device); 2874 } 2875 2876 return true; 2877 } 2878 2879 /** 2880 * Connects all enabled and supported bluetooth profiles between the local and remote device 2881 * 2882 * @param device is the remote device with which to connect these profiles 2883 * @return true if all profiles successfully connected, false if an error occurred 2884 */ 2885 @RequiresPermission(allOf = { 2886 android.Manifest.permission.BLUETOOTH_PRIVILEGED, 2887 android.Manifest.permission.MODIFY_PHONE_STATE, 2888 }) connectAllEnabledProfiles(BluetoothDevice device)2889 public boolean connectAllEnabledProfiles(BluetoothDevice device) { 2890 if (!profileServicesRunning()) { 2891 Log.e(TAG, "connectAllEnabledProfiles: Not all profile services running"); 2892 return false; 2893 } 2894 2895 // Checks if any profiles are enabled and if so, only connect enabled profiles 2896 if (isAnyProfileEnabled(device)) { 2897 return connectEnabledProfiles(device); 2898 } 2899 2900 int numProfilesConnected = 0; 2901 ParcelUuid[] remoteDeviceUuids = getRemoteUuids(device); 2902 ParcelUuid[] localDeviceUuids = mAdapterProperties.getUuids(); 2903 2904 // All profile toggles disabled, so connects all supported profiles 2905 if (mA2dpService != null && isSupported(localDeviceUuids, remoteDeviceUuids, 2906 BluetoothProfile.A2DP, device)) { 2907 Log.i(TAG, "connectAllEnabledProfiles: Connecting A2dp"); 2908 // Set connection policy also connects the profile with CONNECTION_POLICY_ALLOWED 2909 mA2dpService.setConnectionPolicy(device, BluetoothProfile.CONNECTION_POLICY_ALLOWED); 2910 numProfilesConnected++; 2911 } 2912 if (mA2dpSinkService != null && isSupported(localDeviceUuids, remoteDeviceUuids, 2913 BluetoothProfile.A2DP_SINK, device)) { 2914 Log.i(TAG, "connectAllEnabledProfiles: Connecting A2dp Sink"); 2915 mA2dpSinkService.setConnectionPolicy(device, 2916 BluetoothProfile.CONNECTION_POLICY_ALLOWED); 2917 numProfilesConnected++; 2918 } 2919 if (mHeadsetService != null && isSupported(localDeviceUuids, remoteDeviceUuids, 2920 BluetoothProfile.HEADSET, device)) { 2921 Log.i(TAG, "connectAllEnabledProfiles: Connecting Headset Profile"); 2922 mHeadsetService.setConnectionPolicy(device, BluetoothProfile.CONNECTION_POLICY_ALLOWED); 2923 numProfilesConnected++; 2924 } 2925 if (mHeadsetClientService != null && isSupported(localDeviceUuids, remoteDeviceUuids, 2926 BluetoothProfile.HEADSET_CLIENT, device)) { 2927 Log.i(TAG, "connectAllEnabledProfiles: Connecting HFP"); 2928 mHeadsetClientService.setConnectionPolicy(device, 2929 BluetoothProfile.CONNECTION_POLICY_ALLOWED); 2930 numProfilesConnected++; 2931 } 2932 if (mMapClientService != null && isSupported(localDeviceUuids, remoteDeviceUuids, 2933 BluetoothProfile.MAP_CLIENT, device)) { 2934 Log.i(TAG, "connectAllEnabledProfiles: Connecting MAP"); 2935 mMapClientService.setConnectionPolicy(device, 2936 BluetoothProfile.CONNECTION_POLICY_ALLOWED); 2937 numProfilesConnected++; 2938 } 2939 if (mHidHostService != null && isSupported(localDeviceUuids, remoteDeviceUuids, 2940 BluetoothProfile.HID_HOST, device)) { 2941 Log.i(TAG, "connectAllEnabledProfiles: Connecting Hid Host Profile"); 2942 mHidHostService.setConnectionPolicy(device, BluetoothProfile.CONNECTION_POLICY_ALLOWED); 2943 numProfilesConnected++; 2944 } 2945 if (mPanService != null && isSupported(localDeviceUuids, remoteDeviceUuids, 2946 BluetoothProfile.PAN, device)) { 2947 Log.i(TAG, "connectAllEnabledProfiles: Connecting Pan Profile"); 2948 mPanService.setConnectionPolicy(device, BluetoothProfile.CONNECTION_POLICY_ALLOWED); 2949 numProfilesConnected++; 2950 } 2951 if (mPbapClientService != null && isSupported(localDeviceUuids, remoteDeviceUuids, 2952 BluetoothProfile.PBAP_CLIENT, device)) { 2953 Log.i(TAG, "connectAllEnabledProfiles: Connecting Pbap"); 2954 mPbapClientService.setConnectionPolicy(device, 2955 BluetoothProfile.CONNECTION_POLICY_ALLOWED); 2956 numProfilesConnected++; 2957 } 2958 if (mHearingAidService != null && isSupported(localDeviceUuids, remoteDeviceUuids, 2959 BluetoothProfile.HEARING_AID, device)) { 2960 Log.i(TAG, "connectAllEnabledProfiles: Connecting Hearing Aid Profile"); 2961 mHearingAidService.setConnectionPolicy(device, 2962 BluetoothProfile.CONNECTION_POLICY_ALLOWED); 2963 numProfilesConnected++; 2964 } 2965 2966 Log.i(TAG, "connectAllEnabledProfiles: Number of Profiles Connected: " 2967 + numProfilesConnected); 2968 2969 return true; 2970 } 2971 2972 /** 2973 * Disconnects all enabled and supported bluetooth profiles between the local and remote device 2974 * 2975 * @param device is the remote device with which to disconnect these profiles 2976 * @return true if all profiles successfully disconnected, false if an error occurred 2977 */ 2978 @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) disconnectAllEnabledProfiles(BluetoothDevice device)2979 public boolean disconnectAllEnabledProfiles(BluetoothDevice device) { 2980 if (!profileServicesRunning()) { 2981 Log.e(TAG, "disconnectAllEnabledProfiles: Not all profile services bound"); 2982 return false; 2983 } 2984 2985 if (mA2dpService != null && mA2dpService.getConnectionState(device) 2986 == BluetoothProfile.STATE_CONNECTED) { 2987 Log.i(TAG, "disconnectAllEnabledProfiles: Disconnecting A2dp"); 2988 mA2dpService.disconnect(device); 2989 } 2990 if (mA2dpSinkService != null && mA2dpSinkService.getConnectionState(device) 2991 == BluetoothProfile.STATE_CONNECTED) { 2992 Log.i(TAG, "disconnectAllEnabledProfiles: Disconnecting A2dp Sink"); 2993 mA2dpSinkService.disconnect(device); 2994 } 2995 if (mHeadsetService != null && mHeadsetService.getConnectionState(device) 2996 == BluetoothProfile.STATE_CONNECTED) { 2997 Log.i(TAG, 2998 "disconnectAllEnabledProfiles: Disconnecting Headset Profile"); 2999 mHeadsetService.disconnect(device); 3000 } 3001 if (mHeadsetClientService != null && mHeadsetClientService.getConnectionState(device) 3002 == BluetoothProfile.STATE_CONNECTED) { 3003 Log.i(TAG, "disconnectAllEnabledProfiles: Disconnecting HFP"); 3004 mHeadsetClientService.disconnect(device); 3005 } 3006 if (mMapClientService != null && mMapClientService.getConnectionState(device) 3007 == BluetoothProfile.STATE_CONNECTED) { 3008 Log.i(TAG, "disconnectAllEnabledProfiles: Disconnecting MAP Client"); 3009 mMapClientService.disconnect(device); 3010 } 3011 if (mMapService != null && mMapService.getConnectionState(device) 3012 == BluetoothProfile.STATE_CONNECTED) { 3013 Log.i(TAG, "disconnectAllEnabledProfiles: Disconnecting MAP"); 3014 mMapService.disconnect(device); 3015 } 3016 if (mHidDeviceService != null && mHidDeviceService.getConnectionState(device) 3017 == BluetoothProfile.STATE_CONNECTED) { 3018 Log.i(TAG, "disconnectAllEnabledProfiles: Disconnecting Hid Device Profile"); 3019 mHidDeviceService.disconnect(device); 3020 } 3021 if (mHidHostService != null && mHidHostService.getConnectionState(device) 3022 == BluetoothProfile.STATE_CONNECTED) { 3023 Log.i(TAG, "disconnectAllEnabledProfiles: Disconnecting Hid Host Profile"); 3024 mHidHostService.disconnect(device); 3025 } 3026 if (mPanService != null && mPanService.getConnectionState(device) 3027 == BluetoothProfile.STATE_CONNECTED) { 3028 Log.i(TAG, "disconnectAllEnabledProfiles: Disconnecting Pan Profile"); 3029 mPanService.disconnect(device); 3030 } 3031 if (mPbapClientService != null && mPbapClientService.getConnectionState(device) 3032 == BluetoothProfile.STATE_CONNECTED) { 3033 Log.i(TAG, "disconnectAllEnabledProfiles: Disconnecting Pbap Client"); 3034 mPbapClientService.disconnect(device); 3035 } 3036 if (mPbapService != null && mPbapService.getConnectionState(device) 3037 == BluetoothProfile.STATE_CONNECTED) { 3038 Log.i(TAG, "disconnectAllEnabledProfiles: Disconnecting Pbap Server"); 3039 mPbapService.disconnect(device); 3040 } 3041 if (mHearingAidService != null && mHearingAidService.getConnectionState(device) 3042 == BluetoothProfile.STATE_CONNECTED) { 3043 Log.i(TAG, "disconnectAllEnabledProfiles: Disconnecting Hearing Aid Profile"); 3044 mHearingAidService.disconnect(device); 3045 } 3046 if (mSapService != null && mSapService.getConnectionState(device) 3047 == BluetoothProfile.STATE_CONNECTED) { 3048 Log.i(TAG, "disconnectAllEnabledProfiles: Disconnecting Sap Profile"); 3049 mSapService.disconnect(device); 3050 } 3051 3052 return true; 3053 } 3054 3055 /** 3056 * Same as API method {@link BluetoothDevice#getName()} 3057 * 3058 * @param device remote device of interest 3059 * @return remote device name 3060 */ getRemoteName(BluetoothDevice device)3061 public String getRemoteName(BluetoothDevice device) { 3062 if (mRemoteDevices == null) { 3063 return null; 3064 } 3065 DeviceProperties deviceProp = mRemoteDevices.getDeviceProperties(device); 3066 if (deviceProp == null) { 3067 return null; 3068 } 3069 return deviceProp.getName(); 3070 } 3071 3072 /** 3073 * Get UUIDs for service supported by a remote device 3074 * 3075 * @param device the remote device that we want to get UUIDs from 3076 * @return 3077 */ 3078 @VisibleForTesting getRemoteUuids(BluetoothDevice device)3079 public ParcelUuid[] getRemoteUuids(BluetoothDevice device) { 3080 DeviceProperties deviceProp = mRemoteDevices.getDeviceProperties(device); 3081 if (deviceProp == null) { 3082 return null; 3083 } 3084 return deviceProp.getUuids(); 3085 } 3086 getBluetoothConnectionCallbacks()3087 public Set<IBluetoothConnectionCallback> getBluetoothConnectionCallbacks() { 3088 return mBluetoothConnectionCallbacks; 3089 } 3090 3091 /** 3092 * Converts HCI disconnect reasons to Android disconnect reasons. 3093 * <p> 3094 * The HCI Error Codes used for ACL disconnect reasons propagated up from native code were 3095 * copied from: {@link system/bt/stack/include/hci_error_code.h}. 3096 * <p> 3097 * These error codes are specified and described in Bluetooth Core Spec v5.1, Vol 2, Part D. 3098 * 3099 * @param hciReason is the raw HCI disconnect reason from native. 3100 * @return the Android disconnect reason for apps. 3101 */ 3102 static @BluetoothAdapter.BluetoothConnectionCallback.DisconnectReason int hciToAndroidDisconnectReason(int hciReason)3103 hciToAndroidDisconnectReason(int hciReason) { 3104 switch(hciReason) { 3105 case /*HCI_SUCCESS*/ 0x00: 3106 case /*HCI_ERR_UNSPECIFIED*/ 0x1F: 3107 case /*HCI_ERR_UNDEFINED*/ 0xff: 3108 return BluetoothStatusCodes.ERROR_UNKNOWN; 3109 case /*HCI_ERR_ILLEGAL_COMMAND*/ 0x01: 3110 case /*HCI_ERR_NO_CONNECTION*/ 0x02: 3111 case /*HCI_ERR_HW_FAILURE*/ 0x03: 3112 case /*HCI_ERR_DIFF_TRANSACTION_COLLISION*/ 0x2A: 3113 case /*HCI_ERR_ROLE_SWITCH_PENDING*/ 0x32: 3114 case /*HCI_ERR_ROLE_SWITCH_FAILED*/ 0x35: 3115 return BluetoothStatusCodes.ERROR_DISCONNECT_REASON_LOCAL; 3116 case /*HCI_ERR_PAGE_TIMEOUT*/ 0x04: 3117 case /*HCI_ERR_CONNECTION_TOUT*/ 0x08: 3118 case /*HCI_ERR_HOST_TIMEOUT*/ 0x10: 3119 case /*HCI_ERR_LMP_RESPONSE_TIMEOUT*/ 0x22: 3120 case /*HCI_ERR_ADVERTISING_TIMEOUT*/ 0x3C: 3121 case /*HCI_ERR_CONN_FAILED_ESTABLISHMENT*/ 0x3E: 3122 return BluetoothStatusCodes.ERROR_DISCONNECT_REASON_TIMEOUT; 3123 case /*HCI_ERR_AUTH_FAILURE*/ 0x05: 3124 case /*HCI_ERR_KEY_MISSING*/ 0x06: 3125 case /*HCI_ERR_HOST_REJECT_SECURITY*/ 0x0E: 3126 case /*HCI_ERR_REPEATED_ATTEMPTS*/ 0x17: 3127 case /*HCI_ERR_PAIRING_NOT_ALLOWED*/ 0x18: 3128 case /*HCI_ERR_ENCRY_MODE_NOT_ACCEPTABLE*/ 0x25: 3129 case /*HCI_ERR_UNIT_KEY_USED*/ 0x26: 3130 case /*HCI_ERR_PAIRING_WITH_UNIT_KEY_NOT_SUPPORTED*/ 0x29: 3131 case /*HCI_ERR_INSUFFCIENT_SECURITY*/ 0x2F: 3132 case /*HCI_ERR_HOST_BUSY_PAIRING*/ 0x38: 3133 return BluetoothStatusCodes.ERROR_DISCONNECT_REASON_SECURITY; 3134 case /*HCI_ERR_MEMORY_FULL*/ 0x07: 3135 case /*HCI_ERR_MAX_NUM_OF_CONNECTIONS*/ 0x09: 3136 case /*HCI_ERR_MAX_NUM_OF_SCOS*/ 0x0A: 3137 case /*HCI_ERR_COMMAND_DISALLOWED*/ 0x0C: 3138 case /*HCI_ERR_HOST_REJECT_RESOURCES*/ 0x0D: 3139 case /*HCI_ERR_LIMIT_REACHED*/ 0x43: 3140 return BluetoothStatusCodes.ERROR_DISCONNECT_REASON_RESOURCE_LIMIT_REACHED; 3141 case /*HCI_ERR_CONNECTION_EXISTS*/ 0x0B: 3142 return BluetoothStatusCodes.ERROR_DISCONNECT_REASON_CONNECTION_ALREADY_EXISTS; 3143 case /*HCI_ERR_HOST_REJECT_DEVICE*/ 0x0F: 3144 return BluetoothStatusCodes.ERROR_DISCONNECT_REASON_SYSTEM_POLICY; 3145 case /*HCI_ERR_ILLEGAL_PARAMETER_FMT*/ 0x12: 3146 return BluetoothStatusCodes.ERROR_DISCONNECT_REASON_BAD_PARAMETERS; 3147 case /*HCI_ERR_PEER_USER*/ 0x13: 3148 return BluetoothStatusCodes.ERROR_DISCONNECT_REASON_REMOTE_REQUEST; 3149 case /*HCI_ERR_CONN_CAUSE_LOCAL_HOST*/ 0x16: 3150 return BluetoothStatusCodes.ERROR_DISCONNECT_REASON_LOCAL_REQUEST; 3151 case /*HCI_ERR_UNSUPPORTED_REM_FEATURE*/ 0x1A: 3152 return BluetoothStatusCodes.ERROR_DISCONNECT_REASON_REMOTE; 3153 case /*HCI_ERR_UNACCEPT_CONN_INTERVAL*/ 0x3B: 3154 return BluetoothStatusCodes.ERROR_DISCONNECT_REASON_BAD_PARAMETERS; 3155 default: 3156 Log.e(TAG, "Invalid HCI disconnect reason: " + hciReason); 3157 return BluetoothStatusCodes.ERROR_UNKNOWN; 3158 } 3159 } 3160 logUserBondResponse(BluetoothDevice device, boolean accepted, int event)3161 void logUserBondResponse(BluetoothDevice device, boolean accepted, int event) { 3162 final long token = Binder.clearCallingIdentity(); 3163 try { 3164 BluetoothStatsLog.write(BluetoothStatsLog.BLUETOOTH_BOND_STATE_CHANGED, 3165 obfuscateAddress(device), 0, device.getType(), 3166 BluetoothDevice.BOND_BONDING, 3167 event, 3168 accepted ? 0 : BluetoothDevice.UNBOND_REASON_AUTH_REJECTED); 3169 } finally { 3170 Binder.restoreCallingIdentity(token); 3171 } 3172 } 3173 getDeviceAccessFromPrefs(BluetoothDevice device, String prefFile)3174 int getDeviceAccessFromPrefs(BluetoothDevice device, String prefFile) { 3175 SharedPreferences prefs = getSharedPreferences(prefFile, Context.MODE_PRIVATE); 3176 if (!prefs.contains(device.getAddress())) { 3177 return BluetoothDevice.ACCESS_UNKNOWN; 3178 } 3179 return prefs.getBoolean(device.getAddress(), false) 3180 ? BluetoothDevice.ACCESS_ALLOWED 3181 : BluetoothDevice.ACCESS_REJECTED; 3182 } 3183 setDeviceAccessFromPrefs(BluetoothDevice device, int value, String prefFile)3184 void setDeviceAccessFromPrefs(BluetoothDevice device, int value, String prefFile) { 3185 SharedPreferences pref = getSharedPreferences(prefFile, Context.MODE_PRIVATE); 3186 SharedPreferences.Editor editor = pref.edit(); 3187 if (value == BluetoothDevice.ACCESS_UNKNOWN) { 3188 editor.remove(device.getAddress()); 3189 } else { 3190 editor.putBoolean(device.getAddress(), value == BluetoothDevice.ACCESS_ALLOWED); 3191 } 3192 editor.apply(); 3193 } 3194 setPhonebookAccessPermission(BluetoothDevice device, int value)3195 public void setPhonebookAccessPermission(BluetoothDevice device, int value) { 3196 setDeviceAccessFromPrefs(device, value, PHONEBOOK_ACCESS_PERMISSION_PREFERENCE_FILE); 3197 } 3198 setMessageAccessPermission(BluetoothDevice device, int value)3199 public void setMessageAccessPermission(BluetoothDevice device, int value) { 3200 setDeviceAccessFromPrefs(device, value, MESSAGE_ACCESS_PERMISSION_PREFERENCE_FILE); 3201 } 3202 setSimAccessPermission(BluetoothDevice device, int value)3203 public void setSimAccessPermission(BluetoothDevice device, int value) { 3204 setDeviceAccessFromPrefs(device, value, SIM_ACCESS_PERMISSION_PREFERENCE_FILE); 3205 } 3206 isRpaOffloadSupported()3207 public boolean isRpaOffloadSupported() { 3208 return mAdapterProperties.isRpaOffloadSupported(); 3209 } 3210 getNumOfOffloadedIrkSupported()3211 public int getNumOfOffloadedIrkSupported() { 3212 return mAdapterProperties.getNumOfOffloadedIrkSupported(); 3213 } 3214 getNumOfOffloadedScanFilterSupported()3215 public int getNumOfOffloadedScanFilterSupported() { 3216 return mAdapterProperties.getNumOfOffloadedScanFilterSupported(); 3217 } 3218 getOffloadedScanResultStorage()3219 public int getOffloadedScanResultStorage() { 3220 return mAdapterProperties.getOffloadedScanResultStorage(); 3221 } 3222 isLe2MPhySupported()3223 public boolean isLe2MPhySupported() { 3224 return mAdapterProperties.isLe2MPhySupported(); 3225 } 3226 isLeCodedPhySupported()3227 public boolean isLeCodedPhySupported() { 3228 return mAdapterProperties.isLeCodedPhySupported(); 3229 } 3230 isLeExtendedAdvertisingSupported()3231 public boolean isLeExtendedAdvertisingSupported() { 3232 return mAdapterProperties.isLeExtendedAdvertisingSupported(); 3233 } 3234 isLePeriodicAdvertisingSupported()3235 public boolean isLePeriodicAdvertisingSupported() { 3236 return mAdapterProperties.isLePeriodicAdvertisingSupported(); 3237 } 3238 getLeMaximumAdvertisingDataLength()3239 public int getLeMaximumAdvertisingDataLength() { 3240 return mAdapterProperties.getLeMaximumAdvertisingDataLength(); 3241 } 3242 3243 /** 3244 * Get the maximum number of connected audio devices. 3245 * 3246 * @return the maximum number of connected audio devices 3247 */ getMaxConnectedAudioDevices()3248 public int getMaxConnectedAudioDevices() { 3249 return mAdapterProperties.getMaxConnectedAudioDevices(); 3250 } 3251 3252 /** 3253 * Check whether A2DP offload is enabled. 3254 * 3255 * @return true if A2DP offload is enabled 3256 */ isA2dpOffloadEnabled()3257 public boolean isA2dpOffloadEnabled() { 3258 return mAdapterProperties.isA2dpOffloadEnabled(); 3259 } 3260 reportActivityInfo()3261 private BluetoothActivityEnergyInfo reportActivityInfo() { 3262 if (mAdapterProperties.getState() != BluetoothAdapter.STATE_ON 3263 || !mAdapterProperties.isActivityAndEnergyReportingSupported()) { 3264 return null; 3265 } 3266 3267 // Pull the data. The callback will notify mEnergyInfoLock. 3268 readEnergyInfo(); 3269 3270 synchronized (mEnergyInfoLock) { 3271 try { 3272 mEnergyInfoLock.wait(CONTROLLER_ENERGY_UPDATE_TIMEOUT_MILLIS); 3273 } catch (InterruptedException e) { 3274 // Just continue, the energy data may be stale but we won't miss anything next time 3275 // we query. 3276 } 3277 3278 final BluetoothActivityEnergyInfo info = 3279 new BluetoothActivityEnergyInfo(SystemClock.elapsedRealtime(), 3280 mStackReportedState, mTxTimeTotalMs, mRxTimeTotalMs, mIdleTimeTotalMs, 3281 mEnergyUsedTotalVoltAmpSecMicro); 3282 3283 // Count the number of entries that have byte counts > 0 3284 int arrayLen = 0; 3285 for (int i = 0; i < mUidTraffic.size(); i++) { 3286 final UidTraffic traffic = mUidTraffic.valueAt(i); 3287 if (traffic.getTxBytes() != 0 || traffic.getRxBytes() != 0) { 3288 arrayLen++; 3289 } 3290 } 3291 3292 // Copy the traffic objects whose byte counts are > 0 3293 final UidTraffic[] result = arrayLen > 0 ? new UidTraffic[arrayLen] : null; 3294 int putIdx = 0; 3295 for (int i = 0; i < mUidTraffic.size(); i++) { 3296 final UidTraffic traffic = mUidTraffic.valueAt(i); 3297 if (traffic.getTxBytes() != 0 || traffic.getRxBytes() != 0) { 3298 result[putIdx++] = traffic.clone(); 3299 } 3300 } 3301 3302 info.setUidTraffic(result); 3303 3304 return info; 3305 } 3306 } 3307 getTotalNumOfTrackableAdvertisements()3308 public int getTotalNumOfTrackableAdvertisements() { 3309 return mAdapterProperties.getTotalNumOfTrackableAdvertisements(); 3310 } 3311 convertScanModeToHal(int mode)3312 private static int convertScanModeToHal(int mode) { 3313 switch (mode) { 3314 case BluetoothAdapter.SCAN_MODE_NONE: 3315 return AbstractionLayer.BT_SCAN_MODE_NONE; 3316 case BluetoothAdapter.SCAN_MODE_CONNECTABLE: 3317 return AbstractionLayer.BT_SCAN_MODE_CONNECTABLE; 3318 case BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE: 3319 return AbstractionLayer.BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE; 3320 } 3321 // errorLog("Incorrect scan mode in convertScanModeToHal"); 3322 return -1; 3323 } 3324 convertScanModeFromHal(int mode)3325 static int convertScanModeFromHal(int mode) { 3326 switch (mode) { 3327 case AbstractionLayer.BT_SCAN_MODE_NONE: 3328 return BluetoothAdapter.SCAN_MODE_NONE; 3329 case AbstractionLayer.BT_SCAN_MODE_CONNECTABLE: 3330 return BluetoothAdapter.SCAN_MODE_CONNECTABLE; 3331 case AbstractionLayer.BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE: 3332 return BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE; 3333 } 3334 //errorLog("Incorrect scan mode in convertScanModeFromHal"); 3335 return -1; 3336 } 3337 3338 // This function is called from JNI. It allows native code to set a single wake 3339 // alarm. If an alarm is already pending and a new request comes in, the alarm 3340 // will be rescheduled (i.e. the previously set alarm will be cancelled). setWakeAlarm(long delayMillis, boolean shouldWake)3341 private boolean setWakeAlarm(long delayMillis, boolean shouldWake) { 3342 synchronized (this) { 3343 if (mPendingAlarm != null) { 3344 mAlarmManager.cancel(mPendingAlarm); 3345 } 3346 3347 long wakeupTime = SystemClock.elapsedRealtime() + delayMillis; 3348 int type = shouldWake ? AlarmManager.ELAPSED_REALTIME_WAKEUP 3349 : AlarmManager.ELAPSED_REALTIME; 3350 3351 Intent intent = new Intent(ACTION_ALARM_WAKEUP); 3352 // TODO(b/171825892) Please replace FLAG_MUTABLE_UNAUDITED below 3353 // with either FLAG_IMMUTABLE (recommended) or FLAG_MUTABLE. 3354 mPendingAlarm = 3355 PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_ONE_SHOT 3356 | PendingIntent.FLAG_IMMUTABLE); 3357 mAlarmManager.setExact(type, wakeupTime, mPendingAlarm); 3358 return true; 3359 } 3360 } 3361 3362 // This function is called from JNI. It allows native code to acquire a single wake lock. 3363 // If the wake lock is already held, this function returns success. Although this function 3364 // only supports acquiring a single wake lock at a time right now, it will eventually be 3365 // extended to allow acquiring an arbitrary number of wake locks. The current interface 3366 // takes |lockName| as a parameter in anticipation of that implementation. acquireWakeLock(String lockName)3367 private boolean acquireWakeLock(String lockName) { 3368 synchronized (this) { 3369 if (mWakeLock == null) { 3370 mWakeLockName = lockName; 3371 mWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, lockName); 3372 } 3373 3374 if (!mWakeLock.isHeld()) { 3375 mWakeLock.acquire(); 3376 } 3377 } 3378 return true; 3379 } 3380 3381 // This function is called from JNI. It allows native code to release a wake lock acquired 3382 // by |acquireWakeLock|. If the wake lock is not held, this function returns failure. 3383 // Note that the release() call is also invoked by {@link #cleanup()} so a synchronization is 3384 // needed here. See the comment for |acquireWakeLock| for an explanation of the interface. releaseWakeLock(String lockName)3385 private boolean releaseWakeLock(String lockName) { 3386 synchronized (this) { 3387 if (mWakeLock == null) { 3388 errorLog("Repeated wake lock release; aborting release: " + lockName); 3389 return false; 3390 } 3391 3392 if (mWakeLock.isHeld()) { 3393 mWakeLock.release(); 3394 } 3395 } 3396 return true; 3397 } 3398 energyInfoCallback(int status, int ctrlState, long txTime, long rxTime, long idleTime, long energyUsed, UidTraffic[] data)3399 private void energyInfoCallback(int status, int ctrlState, long txTime, long rxTime, 3400 long idleTime, long energyUsed, UidTraffic[] data) throws RemoteException { 3401 if (ctrlState >= BluetoothActivityEnergyInfo.BT_STACK_STATE_INVALID 3402 && ctrlState <= BluetoothActivityEnergyInfo.BT_STACK_STATE_STATE_IDLE) { 3403 // Energy is product of mA, V and ms. If the chipset doesn't 3404 // report it, we have to compute it from time 3405 if (energyUsed == 0) { 3406 try { 3407 final long txMah = Math.multiplyExact(txTime, getTxCurrentMa()); 3408 final long rxMah = Math.multiplyExact(rxTime, getRxCurrentMa()); 3409 final long idleMah = Math.multiplyExact(idleTime, getIdleCurrentMa()); 3410 energyUsed = (long) (Math.addExact(Math.addExact(txMah, rxMah), idleMah) 3411 * getOperatingVolt()); 3412 } catch (ArithmeticException e) { 3413 Log.wtf(TAG, "overflow in bluetooth energy callback", e); 3414 // Energy is already 0 if the exception was thrown. 3415 } 3416 } 3417 3418 synchronized (mEnergyInfoLock) { 3419 mStackReportedState = ctrlState; 3420 long totalTxTimeMs; 3421 long totalRxTimeMs; 3422 long totalIdleTimeMs; 3423 long totalEnergy; 3424 try { 3425 totalTxTimeMs = Math.addExact(mTxTimeTotalMs, txTime); 3426 totalRxTimeMs = Math.addExact(mRxTimeTotalMs, rxTime); 3427 totalIdleTimeMs = Math.addExact(mIdleTimeTotalMs, idleTime); 3428 totalEnergy = Math.addExact(mEnergyUsedTotalVoltAmpSecMicro, energyUsed); 3429 } catch (ArithmeticException e) { 3430 // This could be because we accumulated a lot of time, or we got a very strange 3431 // value from the controller (more likely). Discard this data. 3432 Log.wtf(TAG, "overflow in bluetooth energy callback", e); 3433 totalTxTimeMs = mTxTimeTotalMs; 3434 totalRxTimeMs = mRxTimeTotalMs; 3435 totalIdleTimeMs = mIdleTimeTotalMs; 3436 totalEnergy = mEnergyUsedTotalVoltAmpSecMicro; 3437 } 3438 3439 mTxTimeTotalMs = totalTxTimeMs; 3440 mRxTimeTotalMs = totalRxTimeMs; 3441 mIdleTimeTotalMs = totalIdleTimeMs; 3442 mEnergyUsedTotalVoltAmpSecMicro = totalEnergy; 3443 3444 for (UidTraffic traffic : data) { 3445 UidTraffic existingTraffic = mUidTraffic.get(traffic.getUid()); 3446 if (existingTraffic == null) { 3447 mUidTraffic.put(traffic.getUid(), traffic); 3448 } else { 3449 existingTraffic.addRxBytes(traffic.getRxBytes()); 3450 existingTraffic.addTxBytes(traffic.getTxBytes()); 3451 } 3452 } 3453 mEnergyInfoLock.notifyAll(); 3454 } 3455 } 3456 3457 verboseLog("energyInfoCallback() status = " + status + "txTime = " + txTime + "rxTime = " 3458 + rxTime + "idleTime = " + idleTime + "energyUsed = " + energyUsed + "ctrlState = " 3459 + ctrlState + "traffic = " + Arrays.toString(data)); 3460 } 3461 3462 /** 3463 * Update metadata change to registered listeners 3464 */ 3465 @VisibleForTesting metadataChanged(String address, int key, byte[] value)3466 public void metadataChanged(String address, int key, byte[] value) { 3467 BluetoothDevice device = mRemoteDevices.getDevice(Utils.getBytesFromAddress(address)); 3468 if (mMetadataListeners.containsKey(device)) { 3469 ArrayList<IBluetoothMetadataListener> list = mMetadataListeners.get(device); 3470 for (IBluetoothMetadataListener listener : list) { 3471 try { 3472 listener.onMetadataChanged(device, key, value); 3473 } catch (RemoteException e) { 3474 Log.w(TAG, "RemoteException when onMetadataChanged"); 3475 } 3476 } 3477 } 3478 } 3479 getIdleCurrentMa()3480 private int getIdleCurrentMa() { 3481 return getResources().getInteger(R.integer.config_bluetooth_idle_cur_ma); 3482 } 3483 getTxCurrentMa()3484 private int getTxCurrentMa() { 3485 return getResources().getInteger(R.integer.config_bluetooth_tx_cur_ma); 3486 } 3487 getRxCurrentMa()3488 private int getRxCurrentMa() { 3489 return getResources().getInteger(R.integer.config_bluetooth_rx_cur_ma); 3490 } 3491 getOperatingVolt()3492 private double getOperatingVolt() { 3493 return getResources().getInteger(R.integer.config_bluetooth_operating_voltage_mv) / 1000.0; 3494 } 3495 3496 @Override dump(FileDescriptor fd, PrintWriter writer, String[] args)3497 protected void dump(FileDescriptor fd, PrintWriter writer, String[] args) { 3498 if (args.length == 0) { 3499 writer.println("Skipping dump in APP SERVICES, see bluetooth_manager section."); 3500 writer.println("Use --print argument for dumpsys direct from AdapterService."); 3501 return; 3502 } 3503 3504 if ("set-test-mode".equals(args[0])) { 3505 final boolean testModeEnabled = "enabled".equalsIgnoreCase(args[1]); 3506 for (ProfileService profile : mRunningProfiles) { 3507 profile.setTestModeEnabled(testModeEnabled); 3508 } 3509 mTestModeEnabled = testModeEnabled; 3510 return; 3511 } 3512 3513 verboseLog("dumpsys arguments, check for protobuf output: " + TextUtils.join(" ", args)); 3514 if (args[0].equals("--proto-bin")) { 3515 dumpMetrics(fd); 3516 return; 3517 } 3518 3519 writer.println(); 3520 mAdapterProperties.dump(fd, writer, args); 3521 writer.println("mSnoopLogSettingAtEnable = " + mSnoopLogSettingAtEnable); 3522 writer.println("mDefaultSnoopLogSettingAtEnable = " + mDefaultSnoopLogSettingAtEnable); 3523 3524 writer.println(); 3525 mAdapterStateMachine.dump(fd, writer, args); 3526 3527 StringBuilder sb = new StringBuilder(); 3528 for (ProfileService profile : mRegisteredProfiles) { 3529 profile.dump(sb); 3530 } 3531 mSilenceDeviceManager.dump(fd, writer, args); 3532 mDatabaseManager.dump(writer); 3533 3534 writer.write(sb.toString()); 3535 writer.flush(); 3536 3537 dumpNative(fd, args); 3538 } 3539 dumpMetrics(FileDescriptor fd)3540 private void dumpMetrics(FileDescriptor fd) { 3541 BluetoothMetricsProto.BluetoothLog.Builder metricsBuilder = 3542 BluetoothMetricsProto.BluetoothLog.newBuilder(); 3543 byte[] nativeMetricsBytes = dumpMetricsNative(); 3544 debugLog("dumpMetrics: native metrics size is " + nativeMetricsBytes.length); 3545 if (nativeMetricsBytes.length > 0) { 3546 try { 3547 metricsBuilder.mergeFrom(nativeMetricsBytes); 3548 } catch (InvalidProtocolBufferException ex) { 3549 Log.w(TAG, "dumpMetrics: problem parsing metrics protobuf, " + ex.getMessage()); 3550 return; 3551 } 3552 } 3553 metricsBuilder.setNumBondedDevices(getBondedDevices().length); 3554 MetricsLogger.dumpProto(metricsBuilder); 3555 for (ProfileService profile : mRegisteredProfiles) { 3556 profile.dumpProto(metricsBuilder); 3557 } 3558 byte[] metricsBytes = Base64.encode(metricsBuilder.build().toByteArray(), Base64.DEFAULT); 3559 debugLog("dumpMetrics: combined metrics size is " + metricsBytes.length); 3560 try (FileOutputStream protoOut = new FileOutputStream(fd)) { 3561 protoOut.write(metricsBytes); 3562 } catch (IOException e) { 3563 errorLog("dumpMetrics: error writing combined protobuf to fd, " + e.getMessage()); 3564 } 3565 } 3566 debugLog(String msg)3567 private void debugLog(String msg) { 3568 if (DBG) { 3569 Log.d(TAG, msg); 3570 } 3571 } 3572 verboseLog(String msg)3573 private void verboseLog(String msg) { 3574 if (VERBOSE) { 3575 Log.v(TAG, msg); 3576 } 3577 } 3578 errorLog(String msg)3579 private void errorLog(String msg) { 3580 Log.e(TAG, msg); 3581 } 3582 3583 private final BroadcastReceiver mAlarmBroadcastReceiver = new BroadcastReceiver() { 3584 @Override 3585 public void onReceive(Context context, Intent intent) { 3586 synchronized (AdapterService.this) { 3587 mPendingAlarm = null; 3588 alarmFiredNative(); 3589 } 3590 } 3591 }; 3592 isGuest()3593 private boolean isGuest() { 3594 return UserManager.get(this).isGuestUser(); 3595 } 3596 isCommonCriteriaMode()3597 private boolean isCommonCriteriaMode() { 3598 return ((DevicePolicyManager) getSystemService(Context.DEVICE_POLICY_SERVICE)) 3599 .isCommonCriteriaModeEnabled(null); 3600 } 3601 3602 @SuppressLint("AndroidFrameworkRequiresPermission") enforceBluetoothPrivilegedPermissionIfNeeded(OobData remoteP192Data, OobData remoteP256Data)3603 private void enforceBluetoothPrivilegedPermissionIfNeeded(OobData remoteP192Data, 3604 OobData remoteP256Data) { 3605 if (remoteP192Data != null || remoteP256Data != null) { 3606 enforceBluetoothPrivilegedPermission(this); 3607 } 3608 } 3609 3610 // Boolean flags 3611 private static final String GD_CORE_FLAG = "INIT_gd_core"; 3612 private static final String GD_ADVERTISING_FLAG = "INIT_gd_advertising"; 3613 private static final String GD_SCANNING_FLAG = "INIT_gd_scanning"; 3614 private static final String GD_HCI_FLAG = "INIT_gd_hci"; 3615 private static final String GD_CONTROLLER_FLAG = "INIT_gd_controller"; 3616 private static final String GD_ACL_FLAG = "INIT_gd_acl"; 3617 private static final String GD_L2CAP_FLAG = "INIT_gd_l2cap"; 3618 private static final String GD_RUST_FLAG = "INIT_gd_rust"; 3619 private static final String GD_LINK_POLICY_FLAG = "INIT_gd_link_policy"; 3620 3621 /** 3622 * Logging flags logic (only applies to DEBUG and VERBOSE levels): 3623 * if LOG_TAG in LOGGING_DEBUG_DISABLED_FOR_TAGS_FLAG: 3624 * DO NOT LOG 3625 * else if LOG_TAG in LOGGING_DEBUG_ENABLED_FOR_TAGS_FLAG: 3626 * DO LOG 3627 * else if LOGGING_DEBUG_ENABLED_FOR_ALL_FLAG: 3628 * DO LOG 3629 * else: 3630 * DO NOT LOG 3631 */ 3632 private static final String LOGGING_DEBUG_ENABLED_FOR_ALL_FLAG = 3633 "INIT_logging_debug_enabled_for_all"; 3634 // String flags 3635 // Comma separated tags 3636 private static final String LOGGING_DEBUG_ENABLED_FOR_TAGS_FLAG = 3637 "INIT_logging_debug_enabled_for_tags"; 3638 private static final String LOGGING_DEBUG_DISABLED_FOR_TAGS_FLAG = 3639 "INIT_logging_debug_disabled_for_tags"; 3640 private static final String BTAA_HCI_LOG_FLAG = "INIT_btaa_hci"; 3641 getInitFlags()3642 private String[] getInitFlags() { 3643 ArrayList<String> initFlags = new ArrayList<>(); 3644 if (DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_BLUETOOTH, GD_CORE_FLAG, false)) { 3645 initFlags.add(String.format("%s=%s", GD_CORE_FLAG, "true")); 3646 } 3647 if (DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_BLUETOOTH, GD_ADVERTISING_FLAG, false)) { 3648 initFlags.add(String.format("%s=%s", GD_ADVERTISING_FLAG, "true")); 3649 } 3650 if (DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_BLUETOOTH, GD_SCANNING_FLAG, 3651 Config.isGdEnabledUpToScanningLayer())) { 3652 initFlags.add(String.format("%s=%s", GD_SCANNING_FLAG, "true")); 3653 } 3654 if (DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_BLUETOOTH, GD_HCI_FLAG, false)) { 3655 initFlags.add(String.format("%s=%s", GD_HCI_FLAG, "true")); 3656 } 3657 if (DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_BLUETOOTH, GD_CONTROLLER_FLAG, false)) { 3658 initFlags.add(String.format("%s=%s", GD_CONTROLLER_FLAG, "true")); 3659 } 3660 if (DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_BLUETOOTH, GD_ACL_FLAG, false)) { 3661 initFlags.add(String.format("%s=%s", GD_ACL_FLAG, "true")); 3662 } 3663 if (DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_BLUETOOTH, GD_L2CAP_FLAG, false)) { 3664 initFlags.add(String.format("%s=%s", GD_L2CAP_FLAG, "true")); 3665 } 3666 if (DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_BLUETOOTH, GD_RUST_FLAG, false)) { 3667 initFlags.add(String.format("%s=%s", GD_RUST_FLAG, "true")); 3668 } 3669 if (DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_BLUETOOTH, GD_LINK_POLICY_FLAG, false)) { 3670 initFlags.add(String.format("%s=%s", GD_LINK_POLICY_FLAG, "true")); 3671 } 3672 if (DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_BLUETOOTH, 3673 LOGGING_DEBUG_ENABLED_FOR_ALL_FLAG, false)) { 3674 initFlags.add(String.format("%s=%s", LOGGING_DEBUG_ENABLED_FOR_ALL_FLAG, "true")); 3675 mIsVerboseLoggingEnabledForAll = true; 3676 } 3677 String debugLoggingEnabledTags = DeviceConfig.getString(DeviceConfig.NAMESPACE_BLUETOOTH, 3678 LOGGING_DEBUG_ENABLED_FOR_TAGS_FLAG, ""); 3679 if (!debugLoggingEnabledTags.isEmpty()) { 3680 initFlags.add(String.format("%s=%s", LOGGING_DEBUG_ENABLED_FOR_TAGS_FLAG, 3681 debugLoggingEnabledTags)); 3682 } 3683 String debugLoggingDisabledTags = DeviceConfig.getString(DeviceConfig.NAMESPACE_BLUETOOTH, 3684 LOGGING_DEBUG_DISABLED_FOR_TAGS_FLAG, ""); 3685 if (!debugLoggingDisabledTags.isEmpty()) { 3686 initFlags.add(String.format("%s=%s", LOGGING_DEBUG_DISABLED_FOR_TAGS_FLAG, 3687 debugLoggingDisabledTags)); 3688 } 3689 if (DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_BLUETOOTH, BTAA_HCI_LOG_FLAG, false)) { 3690 initFlags.add(String.format("%s=%s", BTAA_HCI_LOG_FLAG, "true")); 3691 } 3692 return initFlags.toArray(new String[0]); 3693 } 3694 3695 private boolean mIsVerboseLoggingEnabledForAll = false; 3696 getIsVerboseLoggingEnabledForAll()3697 public boolean getIsVerboseLoggingEnabledForAll() { 3698 return mIsVerboseLoggingEnabledForAll; 3699 } 3700 3701 private final Object mDeviceConfigLock = new Object(); 3702 3703 /** 3704 * Predicate that can be applied to names to determine if a device is 3705 * well-known to be used for physical location. 3706 */ 3707 @GuardedBy("mDeviceConfigLock") 3708 private Predicate<String> mLocationDenylistName = (v) -> false; 3709 3710 /** 3711 * Predicate that can be applied to MAC addresses to determine if a device 3712 * is well-known to be used for physical location. 3713 */ 3714 @GuardedBy("mDeviceConfigLock") 3715 private Predicate<byte[]> mLocationDenylistMac = (v) -> false; 3716 3717 /** 3718 * Predicate that can be applied to Advertising Data payloads to determine 3719 * if a device is well-known to be used for physical location. 3720 */ 3721 @GuardedBy("mDeviceConfigLock") 3722 private Predicate<byte[]> mLocationDenylistAdvertisingData = (v) -> false; 3723 3724 @GuardedBy("mDeviceConfigLock") 3725 private int mScanQuotaCount = DeviceConfigListener.DEFAULT_SCAN_QUOTA_COUNT; 3726 @GuardedBy("mDeviceConfigLock") 3727 private long mScanQuotaWindowMillis = DeviceConfigListener.DEFAULT_SCAN_QUOTA_WINDOW_MILLIS; 3728 @GuardedBy("mDeviceConfigLock") 3729 private long mScanTimeoutMillis = DeviceConfigListener.DEFAULT_SCAN_TIMEOUT_MILLIS; 3730 getLocationDenylistName()3731 public @NonNull Predicate<String> getLocationDenylistName() { 3732 synchronized (mDeviceConfigLock) { 3733 return mLocationDenylistName; 3734 } 3735 } 3736 getLocationDenylistMac()3737 public @NonNull Predicate<byte[]> getLocationDenylistMac() { 3738 synchronized (mDeviceConfigLock) { 3739 return mLocationDenylistMac; 3740 } 3741 } 3742 getLocationDenylistAdvertisingData()3743 public @NonNull Predicate<byte[]> getLocationDenylistAdvertisingData() { 3744 synchronized (mDeviceConfigLock) { 3745 return mLocationDenylistAdvertisingData; 3746 } 3747 } 3748 getScanQuotaCount()3749 public int getScanQuotaCount() { 3750 synchronized (mDeviceConfigLock) { 3751 return mScanQuotaCount; 3752 } 3753 } 3754 getScanQuotaWindowMillis()3755 public long getScanQuotaWindowMillis() { 3756 synchronized (mDeviceConfigLock) { 3757 return mScanQuotaWindowMillis; 3758 } 3759 } 3760 getScanTimeoutMillis()3761 public long getScanTimeoutMillis() { 3762 synchronized (mDeviceConfigLock) { 3763 return mScanTimeoutMillis; 3764 } 3765 } 3766 3767 private final DeviceConfigListener mDeviceConfigListener = new DeviceConfigListener(); 3768 3769 private class DeviceConfigListener implements DeviceConfig.OnPropertiesChangedListener { 3770 private static final String LOCATION_DENYLIST_NAME = 3771 "location_denylist_name"; 3772 private static final String LOCATION_DENYLIST_MAC = 3773 "location_denylist_mac"; 3774 private static final String LOCATION_DENYLIST_ADVERTISING_DATA = 3775 "location_denylist_advertising_data"; 3776 private static final String SCAN_QUOTA_COUNT = 3777 "scan_quota_count"; 3778 private static final String SCAN_QUOTA_WINDOW_MILLIS = 3779 "scan_quota_window_millis"; 3780 private static final String SCAN_TIMEOUT_MILLIS = 3781 "scan_timeout_millis"; 3782 3783 /** 3784 * Default denylist which matches Eddystone and iBeacon payloads. 3785 */ 3786 private static final String DEFAULT_LOCATION_DENYLIST_ADVERTISING_DATA = 3787 "⊆0016AAFE/00FFFFFF,⊆00FF4C0002/00FFFFFFFF"; 3788 3789 private static final int DEFAULT_SCAN_QUOTA_COUNT = 5; 3790 private static final long DEFAULT_SCAN_QUOTA_WINDOW_MILLIS = 30 * SECOND_IN_MILLIS; 3791 private static final long DEFAULT_SCAN_TIMEOUT_MILLIS = 30 * MINUTE_IN_MILLIS; 3792 start()3793 public void start() { 3794 DeviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_BLUETOOTH, 3795 BackgroundThread.getExecutor(), this); 3796 onPropertiesChanged(DeviceConfig.getProperties(DeviceConfig.NAMESPACE_BLUETOOTH)); 3797 } 3798 3799 @Override onPropertiesChanged(DeviceConfig.Properties properties)3800 public void onPropertiesChanged(DeviceConfig.Properties properties) { 3801 synchronized (mDeviceConfigLock) { 3802 final String name = properties.getString(LOCATION_DENYLIST_NAME, null); 3803 mLocationDenylistName = !TextUtils.isEmpty(name) 3804 ? Pattern.compile(name).asPredicate() 3805 : (v) -> false; 3806 mLocationDenylistMac = BytesMatcher 3807 .decode(properties.getString(LOCATION_DENYLIST_MAC, null)); 3808 mLocationDenylistAdvertisingData = BytesMatcher 3809 .decode(properties.getString(LOCATION_DENYLIST_ADVERTISING_DATA, 3810 DEFAULT_LOCATION_DENYLIST_ADVERTISING_DATA)); 3811 mScanQuotaCount = properties.getInt(SCAN_QUOTA_COUNT, 3812 DEFAULT_SCAN_QUOTA_COUNT); 3813 mScanQuotaWindowMillis = properties.getLong(SCAN_QUOTA_WINDOW_MILLIS, 3814 DEFAULT_SCAN_QUOTA_WINDOW_MILLIS); 3815 mScanTimeoutMillis = properties.getLong(SCAN_TIMEOUT_MILLIS, 3816 DEFAULT_SCAN_TIMEOUT_MILLIS); 3817 } 3818 } 3819 } 3820 3821 /** 3822 * Obfuscate Bluetooth MAC address into a PII free ID string 3823 * 3824 * @param device Bluetooth device whose MAC address will be obfuscated 3825 * @return a byte array that is unique to this MAC address on this device, 3826 * or empty byte array when either device is null or obfuscateAddressNative fails 3827 */ obfuscateAddress(BluetoothDevice device)3828 public byte[] obfuscateAddress(BluetoothDevice device) { 3829 if (device == null) { 3830 return new byte[0]; 3831 } 3832 return obfuscateAddressNative(Utils.getByteAddress(device)); 3833 } 3834 3835 /** 3836 * Get dynamic audio buffer size supported type 3837 * 3838 * @return support <p>Possible values are 3839 * {@link BluetoothA2dp#DYNAMIC_BUFFER_SUPPORT_NONE}, 3840 * {@link BluetoothA2dp#DYNAMIC_BUFFER_SUPPORT_A2DP_OFFLOAD}, 3841 * {@link BluetoothA2dp#DYNAMIC_BUFFER_SUPPORT_A2DP_SOFTWARE_ENCODING}. 3842 */ getDynamicBufferSupport()3843 public int getDynamicBufferSupport() { 3844 return mAdapterProperties.getDynamicBufferSupport(); 3845 } 3846 3847 /** 3848 * Get dynamic audio buffer size 3849 * 3850 * @return BufferConstraints 3851 */ getBufferConstraints()3852 public BufferConstraints getBufferConstraints() { 3853 return mAdapterProperties.getBufferConstraints(); 3854 } 3855 3856 /** 3857 * Set dynamic audio buffer size 3858 * 3859 * @param codec Audio codec 3860 * @param value buffer millis 3861 * @return true if the settings is successful, false otherwise 3862 */ setBufferLengthMillis(int codec, int value)3863 public boolean setBufferLengthMillis(int codec, int value) { 3864 return mAdapterProperties.setBufferLengthMillis(codec, value); 3865 } 3866 3867 /** 3868 * Get an incremental id of Bluetooth metrics and log 3869 * 3870 * @param device Bluetooth device 3871 * @return int of id for Bluetooth metrics and logging, 0 if the device is invalid 3872 */ getMetricId(BluetoothDevice device)3873 public int getMetricId(BluetoothDevice device) { 3874 if (device == null) { 3875 return 0; 3876 } 3877 return getMetricIdNative(Utils.getByteAddress(device)); 3878 } 3879 classInitNative()3880 static native void classInitNative(); 3881 initNative(boolean startRestricted, boolean isCommonCriteriaMode, int configCompareResult, String[] initFlags, boolean isAtvDevice)3882 native boolean initNative(boolean startRestricted, boolean isCommonCriteriaMode, 3883 int configCompareResult, String[] initFlags, boolean isAtvDevice); 3884 cleanupNative()3885 native void cleanupNative(); 3886 3887 /*package*/ enableNative()3888 native boolean enableNative(); 3889 3890 /*package*/ disableNative()3891 native boolean disableNative(); 3892 3893 /*package*/ setAdapterPropertyNative(int type, byte[] val)3894 native boolean setAdapterPropertyNative(int type, byte[] val); 3895 3896 /*package*/ getAdapterPropertiesNative()3897 native boolean getAdapterPropertiesNative(); 3898 3899 /*package*/ getAdapterPropertyNative(int type)3900 native boolean getAdapterPropertyNative(int type); 3901 3902 /*package*/ setAdapterPropertyNative(int type)3903 native boolean setAdapterPropertyNative(int type); 3904 3905 /*package*/ setDevicePropertyNative(byte[] address, int type, byte[] val)3906 native boolean setDevicePropertyNative(byte[] address, int type, byte[] val); 3907 3908 /*package*/ getDevicePropertyNative(byte[] address, int type)3909 native boolean getDevicePropertyNative(byte[] address, int type); 3910 3911 /*package*/ createBondNative(byte[] address, int transport)3912 public native boolean createBondNative(byte[] address, int transport); 3913 3914 /*package*/ createBondOutOfBandNative(byte[] address, int transport, OobData p192Data, OobData p256Data)3915 native boolean createBondOutOfBandNative(byte[] address, int transport, 3916 OobData p192Data, OobData p256Data); 3917 3918 /*package*/ removeBondNative(byte[] address)3919 public native boolean removeBondNative(byte[] address); 3920 3921 /*package*/ cancelBondNative(byte[] address)3922 native boolean cancelBondNative(byte[] address); 3923 3924 /*package*/ generateLocalOobDataNative(int transport)3925 native void generateLocalOobDataNative(int transport); 3926 3927 /*package*/ sdpSearchNative(byte[] address, byte[] uuid)3928 native boolean sdpSearchNative(byte[] address, byte[] uuid); 3929 3930 /*package*/ getConnectionStateNative(byte[] address)3931 native int getConnectionStateNative(byte[] address); 3932 startDiscoveryNative()3933 private native boolean startDiscoveryNative(); 3934 cancelDiscoveryNative()3935 private native boolean cancelDiscoveryNative(); 3936 pinReplyNative(byte[] address, boolean accept, int len, byte[] pin)3937 private native boolean pinReplyNative(byte[] address, boolean accept, int len, byte[] pin); 3938 sspReplyNative(byte[] address, int type, boolean accept, int passkey)3939 private native boolean sspReplyNative(byte[] address, int type, boolean accept, int passkey); 3940 3941 /*package*/ getRemoteServicesNative(byte[] address)3942 native boolean getRemoteServicesNative(byte[] address); 3943 3944 /*package*/ getRemoteMasInstancesNative(byte[] address)3945 native boolean getRemoteMasInstancesNative(byte[] address); 3946 readEnergyInfo()3947 private native int readEnergyInfo(); 3948 3949 /*package*/ factoryResetNative()3950 native boolean factoryResetNative(); 3951 alarmFiredNative()3952 private native void alarmFiredNative(); 3953 dumpNative(FileDescriptor fd, String[] arguments)3954 private native void dumpNative(FileDescriptor fd, String[] arguments); 3955 dumpMetricsNative()3956 private native byte[] dumpMetricsNative(); 3957 interopDatabaseClearNative()3958 private native void interopDatabaseClearNative(); 3959 interopDatabaseAddNative(int feature, byte[] address, int length)3960 private native void interopDatabaseAddNative(int feature, byte[] address, int length); 3961 obfuscateAddressNative(byte[] address)3962 private native byte[] obfuscateAddressNative(byte[] address); 3963 setBufferLengthMillisNative(int codec, int value)3964 native boolean setBufferLengthMillisNative(int codec, int value); 3965 getMetricIdNative(byte[] address)3966 private native int getMetricIdNative(byte[] address); 3967 connectSocketNative( byte[] address, int type, byte[] uuid, int port, int flag, int callingUid)3968 /*package*/ native int connectSocketNative( 3969 byte[] address, int type, byte[] uuid, int port, int flag, int callingUid); 3970 createSocketChannelNative( int type, String serviceName, byte[] uuid, int port, int flag, int callingUid)3971 /*package*/ native int createSocketChannelNative( 3972 int type, String serviceName, byte[] uuid, int port, int flag, int callingUid); 3973 requestMaximumTxDataLengthNative(byte[] address)3974 /*package*/ native void requestMaximumTxDataLengthNative(byte[] address); 3975 3976 // Returns if this is a mock object. This is currently used in testing so that we may not call 3977 // System.exit() while finalizing the object. Otherwise GC of mock objects unfortunately ends up 3978 // calling finalize() which in turn calls System.exit() and the process crashes. 3979 // 3980 // Mock this in your testing framework to return true to avoid the mentioned behavior. In 3981 // production this has no effect. isMock()3982 public boolean isMock() { 3983 return false; 3984 } 3985 } 3986