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