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