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