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