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