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