AdapterService.java revision 2aad9ef373bb7c4d0415ba2869a72869d22673f4
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 if (!isMock()) { 643 System.exit(0); 644 } 645 } 646 647 private static final int MESSAGE_PROFILE_SERVICE_STATE_CHANGED =1; 648 649 private final Handler mHandler = new Handler() { 650 @Override 651 public void handleMessage(Message msg) { 652 debugLog("handleMessage() - Message: " + msg.what); 653 654 switch (msg.what) { 655 case MESSAGE_PROFILE_SERVICE_STATE_CHANGED: { 656 debugLog("handleMessage() - MESSAGE_PROFILE_SERVICE_STATE_CHANGED"); 657 processProfileServiceStateChanged((String) msg.obj, msg.arg1); 658 } 659 break; 660 } 661 } 662 }; 663 664 @SuppressWarnings("rawtypes") 665 private void setGattProfileServiceState(Class[] services, int state) { 666 if (state != BluetoothAdapter.STATE_ON && state != BluetoothAdapter.STATE_OFF) { 667 Log.w(TAG,"setGattProfileServiceState(): invalid state...Leaving..."); 668 return; 669 } 670 671 int expectedCurrentState= BluetoothAdapter.STATE_OFF; 672 int pendingState = BluetoothAdapter.STATE_TURNING_ON; 673 674 if (state == BluetoothAdapter.STATE_OFF) { 675 expectedCurrentState= BluetoothAdapter.STATE_ON; 676 pendingState = BluetoothAdapter.STATE_TURNING_OFF; 677 } 678 679 for (int i=0; i <services.length;i++) { 680 String serviceName = services[i].getName(); 681 String simpleName = services[i].getSimpleName(); 682 683 if (simpleName.equals("GattService")) { 684 Integer serviceState = mProfileServicesState.get(serviceName); 685 686 if(serviceState != null && serviceState != expectedCurrentState) { 687 debugLog("setProfileServiceState() - Unable to " 688 + (state == BluetoothAdapter.STATE_OFF ? "start" : "stop" ) 689 + " service " + serviceName 690 + ". Invalid state: " + serviceState); 691 continue; 692 } 693 debugLog("setProfileServiceState() - " 694 + (state == BluetoothAdapter.STATE_OFF ? "Stopping" : "Starting") 695 + " service " + serviceName); 696 697 mProfileServicesState.put(serviceName,pendingState); 698 Intent intent = new Intent(this,services[i]); 699 intent.putExtra(EXTRA_ACTION,ACTION_SERVICE_STATE_CHANGED); 700 intent.putExtra(BluetoothAdapter.EXTRA_STATE,state); 701 startService(intent); 702 return; 703 } 704 } 705 } 706 707 708 @SuppressWarnings("rawtypes") 709 private void setProfileServiceState(Class[] services, int state) { 710 if (state != BluetoothAdapter.STATE_ON && state != BluetoothAdapter.STATE_OFF) { 711 debugLog("setProfileServiceState() - Invalid state, leaving..."); 712 return; 713 } 714 715 int expectedCurrentState= BluetoothAdapter.STATE_OFF; 716 int pendingState = BluetoothAdapter.STATE_TURNING_ON; 717 if (state == BluetoothAdapter.STATE_OFF) { 718 expectedCurrentState= BluetoothAdapter.STATE_ON; 719 pendingState = BluetoothAdapter.STATE_TURNING_OFF; 720 } 721 722 for (int i=0; i <services.length;i++) { 723 String serviceName = services[i].getName(); 724 String simpleName = services[i].getSimpleName(); 725 726 if (simpleName.equals("GattService")) continue; 727 728 Integer serviceState = mProfileServicesState.get(serviceName); 729 if(serviceState != null && serviceState != expectedCurrentState) { 730 debugLog("setProfileServiceState() - Unable to " 731 + (state == BluetoothAdapter.STATE_OFF ? "start" : "stop" ) 732 + " service " + serviceName 733 + ". Invalid state: " + serviceState); 734 continue; 735 } 736 737 debugLog("setProfileServiceState() - " 738 + (state == BluetoothAdapter.STATE_OFF ? "Stopping" : "Starting") 739 + " service " + serviceName); 740 741 mProfileServicesState.put(serviceName,pendingState); 742 Intent intent = new Intent(this,services[i]); 743 intent.putExtra(EXTRA_ACTION,ACTION_SERVICE_STATE_CHANGED); 744 intent.putExtra(BluetoothAdapter.EXTRA_STATE,state); 745 startService(intent); 746 } 747 } 748 749 private boolean isAvailable() { 750 return !mCleaningUp; 751 } 752 753 /** 754 * Handlers for incoming service calls 755 */ 756 private AdapterServiceBinder mBinder; 757 758 /** 759 * The Binder implementation must be declared to be a static class, with 760 * the AdapterService instance passed in the constructor. Furthermore, 761 * when the AdapterService shuts down, the reference to the AdapterService 762 * must be explicitly removed. 763 * 764 * Otherwise, a memory leak can occur from repeated starting/stopping the 765 * service...Please refer to android.os.Binder for further details on 766 * why an inner instance class should be avoided. 767 * 768 */ 769 private static class AdapterServiceBinder extends IBluetooth.Stub { 770 private AdapterService mService; 771 772 public AdapterServiceBinder(AdapterService svc) { 773 mService = svc; 774 } 775 public boolean cleanup() { 776 mService = null; 777 return true; 778 } 779 780 public AdapterService getService() { 781 if (mService != null && mService.isAvailable()) { 782 return mService; 783 } 784 return null; 785 } 786 public boolean isEnabled() { 787 // don't check caller, may be called from system UI 788 AdapterService service = getService(); 789 if (service == null) return false; 790 return service.isEnabled(); 791 } 792 793 public int getState() { 794 // don't check caller, may be called from system UI 795 AdapterService service = getService(); 796 if (service == null) return BluetoothAdapter.STATE_OFF; 797 return service.getState(); 798 } 799 800 public boolean enable() { 801 if ((Binder.getCallingUid() != Process.SYSTEM_UID) && 802 (!Utils.checkCaller())) { 803 Log.w(TAG, "enable() - Not allowed for non-active user and non system user"); 804 return false; 805 } 806 AdapterService service = getService(); 807 if (service == null) return false; 808 return service.enable(); 809 } 810 811 public boolean enableNoAutoConnect() { 812 if ((Binder.getCallingUid() != Process.SYSTEM_UID) && 813 (!Utils.checkCaller())) { 814 Log.w(TAG, "enableNoAuto() - Not allowed for non-active user and non system user"); 815 return false; 816 } 817 818 AdapterService service = getService(); 819 if (service == null) return false; 820 return service.enableNoAutoConnect(); 821 } 822 823 public boolean disable() { 824 if ((Binder.getCallingUid() != Process.SYSTEM_UID) && 825 (!Utils.checkCaller())) { 826 Log.w(TAG, "disable() - Not allowed for non-active user and non system user"); 827 return false; 828 } 829 830 AdapterService service = getService(); 831 if (service == null) return false; 832 return service.disable(); 833 } 834 835 public String getAddress() { 836 if ((Binder.getCallingUid() != Process.SYSTEM_UID) && 837 (!Utils.checkCallerAllowManagedProfiles(mService))) { 838 Log.w(TAG, "getAddress() - Not allowed for non-active user and non system user"); 839 return null; 840 } 841 842 AdapterService service = getService(); 843 if (service == null) return null; 844 return service.getAddress(); 845 } 846 847 public ParcelUuid[] getUuids() { 848 if (!Utils.checkCaller()) { 849 Log.w(TAG, "getUuids() - Not allowed for non-active user"); 850 return new ParcelUuid[0]; 851 } 852 853 AdapterService service = getService(); 854 if (service == null) return new ParcelUuid[0]; 855 return service.getUuids(); 856 } 857 858 public String getName() { 859 if ((Binder.getCallingUid() != Process.SYSTEM_UID) && 860 (!Utils.checkCaller())) { 861 Log.w(TAG, "getName() - Not allowed for non-active user and non system user"); 862 return null; 863 } 864 865 AdapterService service = getService(); 866 if (service == null) return null; 867 return service.getName(); 868 } 869 870 public boolean setName(String name) { 871 if (!Utils.checkCaller()) { 872 Log.w(TAG, "setName() - Not allowed for non-active user"); 873 return false; 874 } 875 876 AdapterService service = getService(); 877 if (service == null) return false; 878 return service.setName(name); 879 } 880 881 public int getScanMode() { 882 if (!Utils.checkCallerAllowManagedProfiles(mService)) { 883 Log.w(TAG, "getScanMode() - Not allowed for non-active user"); 884 return BluetoothAdapter.SCAN_MODE_NONE; 885 } 886 887 AdapterService service = getService(); 888 if (service == null) return BluetoothAdapter.SCAN_MODE_NONE; 889 return service.getScanMode(); 890 } 891 892 public boolean setScanMode(int mode, int duration) { 893 if (!Utils.checkCaller()) { 894 Log.w(TAG, "setScanMode() - Not allowed for non-active user"); 895 return false; 896 } 897 898 AdapterService service = getService(); 899 if (service == null) return false; 900 return service.setScanMode(mode,duration); 901 } 902 903 public int getDiscoverableTimeout() { 904 if (!Utils.checkCaller()) { 905 Log.w(TAG, "getDiscoverableTimeout() - Not allowed for non-active user"); 906 return 0; 907 } 908 909 AdapterService service = getService(); 910 if (service == null) return 0; 911 return service.getDiscoverableTimeout(); 912 } 913 914 public boolean setDiscoverableTimeout(int timeout) { 915 if (!Utils.checkCaller()) { 916 Log.w(TAG, "setDiscoverableTimeout() - Not allowed for non-active user"); 917 return false; 918 } 919 920 AdapterService service = getService(); 921 if (service == null) return false; 922 return service.setDiscoverableTimeout(timeout); 923 } 924 925 public boolean startDiscovery() { 926 if (!Utils.checkCaller()) { 927 Log.w(TAG, "startDiscovery() - Not allowed for non-active user"); 928 return false; 929 } 930 931 AdapterService service = getService(); 932 if (service == null) return false; 933 return service.startDiscovery(); 934 } 935 936 public boolean cancelDiscovery() { 937 if (!Utils.checkCaller()) { 938 Log.w(TAG, "cancelDiscovery() - Not allowed for non-active user"); 939 return false; 940 } 941 942 AdapterService service = getService(); 943 if (service == null) return false; 944 return service.cancelDiscovery(); 945 } 946 947 public boolean isDiscovering() { 948 if (!Utils.checkCallerAllowManagedProfiles(mService)) { 949 Log.w(TAG, "isDiscovering() - Not allowed for non-active user"); 950 return false; 951 } 952 953 AdapterService service = getService(); 954 if (service == null) return false; 955 return service.isDiscovering(); 956 } 957 958 public long getDiscoveryEndMillis() { 959 if (!Utils.checkCaller()) { 960 Log.w(TAG, "getDiscoveryEndMillis() - Not allowed for non-active user"); 961 return -1; 962 } 963 964 AdapterService service = getService(); 965 if (service == null) return -1; 966 return service.getDiscoveryEndMillis(); 967 } 968 969 public BluetoothDevice[] getBondedDevices() { 970 // don't check caller, may be called from system UI 971 AdapterService service = getService(); 972 if (service == null) return new BluetoothDevice[0]; 973 return service.getBondedDevices(); 974 } 975 976 public int getAdapterConnectionState() { 977 // don't check caller, may be called from system UI 978 AdapterService service = getService(); 979 if (service == null) return BluetoothAdapter.STATE_DISCONNECTED; 980 return service.getAdapterConnectionState(); 981 } 982 983 public int getProfileConnectionState(int profile) { 984 if (!Utils.checkCallerAllowManagedProfiles(mService)) { 985 Log.w(TAG, "getProfileConnectionState- Not allowed for non-active user"); 986 return BluetoothProfile.STATE_DISCONNECTED; 987 } 988 989 AdapterService service = getService(); 990 if (service == null) return BluetoothProfile.STATE_DISCONNECTED; 991 return service.getProfileConnectionState(profile); 992 } 993 994 public boolean createBond(BluetoothDevice device, int transport) { 995 if (!Utils.checkCallerAllowManagedProfiles(mService)) { 996 Log.w(TAG, "createBond() - Not allowed for non-active user"); 997 return false; 998 } 999 1000 AdapterService service = getService(); 1001 if (service == null) return false; 1002 return service.createBond(device, transport, null); 1003 } 1004 1005 public boolean createBondOutOfBand(BluetoothDevice device, int transport, OobData oobData) { 1006 if (!Utils.checkCallerAllowManagedProfiles(mService)) { 1007 Log.w(TAG, "createBondOutOfBand() - Not allowed for non-active user"); 1008 return false; 1009 } 1010 1011 AdapterService service = getService(); 1012 if (service == null) return false; 1013 return service.createBond(device, transport, oobData); 1014 } 1015 1016 public boolean cancelBondProcess(BluetoothDevice device) { 1017 if (!Utils.checkCaller()) { 1018 Log.w(TAG, "cancelBondProcess() - Not allowed for non-active user"); 1019 return false; 1020 } 1021 1022 AdapterService service = getService(); 1023 if (service == null) return false; 1024 return service.cancelBondProcess(device); 1025 } 1026 1027 public boolean removeBond(BluetoothDevice device) { 1028 if (!Utils.checkCaller()) { 1029 Log.w(TAG, "removeBond() - Not allowed for non-active user"); 1030 return false; 1031 } 1032 1033 AdapterService service = getService(); 1034 if (service == null) return false; 1035 return service.removeBond(device); 1036 } 1037 1038 public int getBondState(BluetoothDevice device) { 1039 // don't check caller, may be called from system UI 1040 AdapterService service = getService(); 1041 if (service == null) return BluetoothDevice.BOND_NONE; 1042 return service.getBondState(device); 1043 } 1044 1045 public boolean isBondingInitiatedLocally(BluetoothDevice device) { 1046 // don't check caller, may be called from system UI 1047 AdapterService service = getService(); 1048 if (service == null) return false; 1049 return service.isBondingInitiatedLocally(device); 1050 } 1051 1052 public long getSupportedProfiles() { 1053 AdapterService service = getService(); 1054 if (service == null) return 0; 1055 return service.getSupportedProfiles(); 1056 } 1057 1058 public int getConnectionState(BluetoothDevice device) { 1059 AdapterService service = getService(); 1060 if (service == null) return 0; 1061 return service.getConnectionState(device); 1062 } 1063 1064 public String getRemoteName(BluetoothDevice device) { 1065 if (!Utils.checkCallerAllowManagedProfiles(mService)) { 1066 Log.w(TAG, "getRemoteName() - Not allowed for non-active user"); 1067 return null; 1068 } 1069 1070 AdapterService service = getService(); 1071 if (service == null) return null; 1072 return service.getRemoteName(device); 1073 } 1074 1075 public int getRemoteType(BluetoothDevice device) { 1076 if (!Utils.checkCallerAllowManagedProfiles(mService)) { 1077 Log.w(TAG, "getRemoteType() - Not allowed for non-active user"); 1078 return BluetoothDevice.DEVICE_TYPE_UNKNOWN; 1079 } 1080 1081 AdapterService service = getService(); 1082 if (service == null) return BluetoothDevice.DEVICE_TYPE_UNKNOWN; 1083 return service.getRemoteType(device); 1084 } 1085 1086 public String getRemoteAlias(BluetoothDevice device) { 1087 if (!Utils.checkCallerAllowManagedProfiles(mService)) { 1088 Log.w(TAG, "getRemoteAlias() - Not allowed for non-active user"); 1089 return null; 1090 } 1091 1092 AdapterService service = getService(); 1093 if (service == null) return null; 1094 return service.getRemoteAlias(device); 1095 } 1096 1097 public boolean setRemoteAlias(BluetoothDevice device, String name) { 1098 if (!Utils.checkCaller()) { 1099 Log.w(TAG, "setRemoteAlias() - Not allowed for non-active user"); 1100 return false; 1101 } 1102 1103 AdapterService service = getService(); 1104 if (service == null) return false; 1105 return service.setRemoteAlias(device, name); 1106 } 1107 1108 public int getRemoteClass(BluetoothDevice device) { 1109 if (!Utils.checkCallerAllowManagedProfiles(mService)) { 1110 Log.w(TAG, "getRemoteClass() - Not allowed for non-active user"); 1111 return 0; 1112 } 1113 1114 AdapterService service = getService(); 1115 if (service == null) return 0; 1116 return service.getRemoteClass(device); 1117 } 1118 1119 public ParcelUuid[] getRemoteUuids(BluetoothDevice device) { 1120 if (!Utils.checkCallerAllowManagedProfiles(mService)) { 1121 Log.w(TAG, "getRemoteUuids() - Not allowed for non-active user"); 1122 return new ParcelUuid[0]; 1123 } 1124 1125 AdapterService service = getService(); 1126 if (service == null) return new ParcelUuid[0]; 1127 return service.getRemoteUuids(device); 1128 } 1129 1130 public boolean fetchRemoteUuids(BluetoothDevice device) { 1131 if (!Utils.checkCallerAllowManagedProfiles(mService)) { 1132 Log.w(TAG, "fetchRemoteUuids() - Not allowed for non-active user"); 1133 return false; 1134 } 1135 1136 AdapterService service = getService(); 1137 if (service == null) return false; 1138 return service.fetchRemoteUuids(device); 1139 } 1140 1141 1142 1143 public boolean setPin(BluetoothDevice device, boolean accept, int len, byte[] pinCode) { 1144 if (!Utils.checkCaller()) { 1145 Log.w(TAG, "setPin() - Not allowed for non-active user"); 1146 return false; 1147 } 1148 1149 AdapterService service = getService(); 1150 if (service == null) return false; 1151 return service.setPin(device, accept, len, pinCode); 1152 } 1153 1154 public boolean setPasskey(BluetoothDevice device, boolean accept, int len, byte[] passkey) { 1155 if (!Utils.checkCaller()) { 1156 Log.w(TAG, "setPasskey() - Not allowed for non-active user"); 1157 return false; 1158 } 1159 1160 AdapterService service = getService(); 1161 if (service == null) return false; 1162 return service.setPasskey(device, accept, len, passkey); 1163 } 1164 1165 public boolean setPairingConfirmation(BluetoothDevice device, boolean accept) { 1166 if (!Utils.checkCaller()) { 1167 Log.w(TAG, "setPairingConfirmation() - Not allowed for non-active user"); 1168 return false; 1169 } 1170 1171 AdapterService service = getService(); 1172 if (service == null) return false; 1173 return service.setPairingConfirmation(device, accept); 1174 } 1175 1176 public int getPhonebookAccessPermission(BluetoothDevice device) { 1177 if (!Utils.checkCaller()) { 1178 Log.w(TAG, "getPhonebookAccessPermission() - Not allowed for non-active user"); 1179 return BluetoothDevice.ACCESS_UNKNOWN; 1180 } 1181 1182 AdapterService service = getService(); 1183 if (service == null) return BluetoothDevice.ACCESS_UNKNOWN; 1184 return service.getPhonebookAccessPermission(device); 1185 } 1186 1187 public boolean setPhonebookAccessPermission(BluetoothDevice device, int value) { 1188 if (!Utils.checkCaller()) { 1189 Log.w(TAG, "setPhonebookAccessPermission() - Not allowed for non-active user"); 1190 return false; 1191 } 1192 1193 AdapterService service = getService(); 1194 if (service == null) return false; 1195 return service.setPhonebookAccessPermission(device, value); 1196 } 1197 1198 public int getMessageAccessPermission(BluetoothDevice device) { 1199 if (!Utils.checkCaller()) { 1200 Log.w(TAG, "getMessageAccessPermission() - Not allowed for non-active user"); 1201 return BluetoothDevice.ACCESS_UNKNOWN; 1202 } 1203 1204 AdapterService service = getService(); 1205 if (service == null) return BluetoothDevice.ACCESS_UNKNOWN; 1206 return service.getMessageAccessPermission(device); 1207 } 1208 1209 public boolean setMessageAccessPermission(BluetoothDevice device, int value) { 1210 if (!Utils.checkCaller()) { 1211 Log.w(TAG, "setMessageAccessPermission() - Not allowed for non-active user"); 1212 return false; 1213 } 1214 1215 AdapterService service = getService(); 1216 if (service == null) return false; 1217 return service.setMessageAccessPermission(device, value); 1218 } 1219 1220 public int getSimAccessPermission(BluetoothDevice device) { 1221 if (!Utils.checkCaller()) { 1222 Log.w(TAG, "getSimAccessPermission() - Not allowed for non-active user"); 1223 return BluetoothDevice.ACCESS_UNKNOWN; 1224 } 1225 1226 AdapterService service = getService(); 1227 if (service == null) return BluetoothDevice.ACCESS_UNKNOWN; 1228 return service.getSimAccessPermission(device); 1229 } 1230 1231 public boolean setSimAccessPermission(BluetoothDevice device, int value) { 1232 if (!Utils.checkCaller()) { 1233 Log.w(TAG, "setSimAccessPermission() - Not allowed for non-active user"); 1234 return false; 1235 } 1236 1237 AdapterService service = getService(); 1238 if (service == null) return false; 1239 return service.setSimAccessPermission(device, value); 1240 } 1241 1242 public void sendConnectionStateChange(BluetoothDevice 1243 device, int profile, int state, int prevState) { 1244 AdapterService service = getService(); 1245 if (service == null) return; 1246 service.sendConnectionStateChange(device, profile, state, prevState); 1247 } 1248 1249 public ParcelFileDescriptor connectSocket(BluetoothDevice device, int type, 1250 ParcelUuid uuid, int port, int flag) { 1251 if (!Utils.checkCallerAllowManagedProfiles(mService)) { 1252 Log.w(TAG, "connectSocket() - Not allowed for non-active user"); 1253 return null; 1254 } 1255 1256 AdapterService service = getService(); 1257 if (service == null) return null; 1258 return service.connectSocket(device, type, uuid, port, flag); 1259 } 1260 1261 public ParcelFileDescriptor createSocketChannel(int type, String serviceName, 1262 ParcelUuid uuid, int port, int flag) { 1263 if (!Utils.checkCallerAllowManagedProfiles(mService)) { 1264 Log.w(TAG, "createSocketChannel() - Not allowed for non-active user"); 1265 return null; 1266 } 1267 1268 AdapterService service = getService(); 1269 if (service == null) return null; 1270 return service.createSocketChannel(type, serviceName, uuid, port, flag); 1271 } 1272 public boolean sdpSearch(BluetoothDevice device, ParcelUuid uuid) { 1273 if (!Utils.checkCaller()) { 1274 Log.w(TAG,"sdpSea(): not allowed for non-active user"); 1275 return false; 1276 } 1277 1278 AdapterService service = getService(); 1279 if (service == null) return false; 1280 return service.sdpSearch(device,uuid); 1281 } 1282 1283 public boolean configHciSnoopLog(boolean enable) { 1284 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 1285 EventLog.writeEvent(0x534e4554 /* SNET */, "Bluetooth", Binder.getCallingUid(), 1286 "configHciSnoopLog() - Not allowed for non-active user b/18643224"); 1287 return false; 1288 } 1289 1290 AdapterService service = getService(); 1291 if (service == null) return false; 1292 return service.configHciSnoopLog(enable); 1293 } 1294 1295 public boolean factoryReset() { 1296 AdapterService service = getService(); 1297 if (service == null) return false; 1298 service.disable(); 1299 return service.factoryReset(); 1300 1301 } 1302 1303 public void registerCallback(IBluetoothCallback cb) { 1304 AdapterService service = getService(); 1305 if (service == null) return ; 1306 service.registerCallback(cb); 1307 } 1308 1309 public void unregisterCallback(IBluetoothCallback cb) { 1310 AdapterService service = getService(); 1311 if (service == null) return ; 1312 service.unregisterCallback(cb); 1313 } 1314 1315 public boolean isMultiAdvertisementSupported() { 1316 AdapterService service = getService(); 1317 if (service == null) return false; 1318 return service.isMultiAdvertisementSupported(); 1319 } 1320 1321 public boolean isOffloadedFilteringSupported() { 1322 AdapterService service = getService(); 1323 if (service == null) return false; 1324 int val = service.getNumOfOffloadedScanFilterSupported(); 1325 return (val >= MIN_OFFLOADED_FILTERS); 1326 } 1327 1328 public boolean isOffloadedScanBatchingSupported() { 1329 AdapterService service = getService(); 1330 if (service == null) return false; 1331 int val = service.getOffloadedScanResultStorage(); 1332 return (val >= MIN_OFFLOADED_SCAN_STORAGE_BYTES); 1333 } 1334 1335 public boolean isActivityAndEnergyReportingSupported() { 1336 AdapterService service = getService(); 1337 if (service == null) return false; 1338 return service.isActivityAndEnergyReportingSupported(); 1339 } 1340 1341 public BluetoothActivityEnergyInfo reportActivityInfo() { 1342 AdapterService service = getService(); 1343 if (service == null) return null; 1344 return service.reportActivityInfo(); 1345 } 1346 1347 public void requestActivityInfo(ResultReceiver result) { 1348 Bundle bundle = new Bundle(); 1349 bundle.putParcelable(BatteryStats.RESULT_RECEIVER_CONTROLLER_KEY, 1350 reportActivityInfo()); 1351 result.send(0, bundle); 1352 } 1353 1354 public void onLeServiceUp(){ 1355 AdapterService service = getService(); 1356 if (service == null) return; 1357 service.onLeServiceUp(); 1358 } 1359 1360 public void onBrEdrDown(){ 1361 AdapterService service = getService(); 1362 if (service == null) return; 1363 service.onBrEdrDown(); 1364 } 1365 1366 public void dump(FileDescriptor fd, String[] args) { 1367 PrintWriter writer = new PrintWriter(new FileOutputStream(fd)); 1368 AdapterService service = getService(); 1369 if (service == null) return; 1370 service.dump(fd, writer, args); 1371 } 1372 }; 1373 1374 // ----API Methods-------- 1375 1376 public boolean isEnabled() { 1377 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1378 return mAdapterProperties.getState() == BluetoothAdapter.STATE_ON; 1379 } 1380 1381 public int getState() { 1382 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1383 if (mAdapterProperties != null) return mAdapterProperties.getState(); 1384 return BluetoothAdapter.STATE_OFF; 1385 } 1386 1387 public boolean enable() { 1388 return enable(false); 1389 } 1390 1391 public boolean enableNoAutoConnect() { 1392 return enable (true); 1393 } 1394 1395 public synchronized boolean enable(boolean quietMode) { 1396 enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, "Need BLUETOOTH ADMIN permission"); 1397 1398 // Enforce the user restriction for disallowing Bluetooth if it was set. 1399 if (mUserManager.hasUserRestriction(UserManager.DISALLOW_BLUETOOTH, UserHandle.SYSTEM)) { 1400 debugLog("enable() called when Bluetooth was disallowed"); 1401 return false; 1402 } 1403 1404 debugLog("enable() - Enable called with quiet mode status = " + mQuietmode); 1405 mQuietmode = quietMode; 1406 Message m = mAdapterStateMachine.obtainMessage(AdapterState.BLE_TURN_ON); 1407 mAdapterStateMachine.sendMessage(m); 1408 mBluetoothStartTime = System.currentTimeMillis(); 1409 return true; 1410 } 1411 1412 boolean disable() { 1413 enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, "Need BLUETOOTH ADMIN permission"); 1414 1415 debugLog("disable() called..."); 1416 Message m = mAdapterStateMachine.obtainMessage(AdapterState.BLE_TURN_OFF); 1417 mAdapterStateMachine.sendMessage(m); 1418 return true; 1419 } 1420 1421 String getAddress() { 1422 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1423 1424 String addrString = null; 1425 byte[] address = mAdapterProperties.getAddress(); 1426 return Utils.getAddressStringFromByte(address); 1427 } 1428 1429 ParcelUuid[] getUuids() { 1430 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1431 1432 return mAdapterProperties.getUuids(); 1433 } 1434 1435 public String getName() { 1436 enforceCallingOrSelfPermission(BLUETOOTH_PERM, 1437 "Need BLUETOOTH permission"); 1438 1439 try { 1440 return mAdapterProperties.getName(); 1441 } catch (Throwable t) { 1442 debugLog("getName() - Unexpected exception (" + t + ")"); 1443 } 1444 return null; 1445 } 1446 1447 boolean setName(String name) { 1448 enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, 1449 "Need BLUETOOTH ADMIN permission"); 1450 1451 return mAdapterProperties.setName(name); 1452 } 1453 1454 int getScanMode() { 1455 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1456 1457 return mAdapterProperties.getScanMode(); 1458 } 1459 1460 boolean setScanMode(int mode, int duration) { 1461 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1462 1463 setDiscoverableTimeout(duration); 1464 1465 int newMode = convertScanModeToHal(mode); 1466 return mAdapterProperties.setScanMode(newMode); 1467 } 1468 1469 int getDiscoverableTimeout() { 1470 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1471 1472 return mAdapterProperties.getDiscoverableTimeout(); 1473 } 1474 1475 boolean setDiscoverableTimeout(int timeout) { 1476 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1477 1478 return mAdapterProperties.setDiscoverableTimeout(timeout); 1479 } 1480 1481 boolean startDiscovery() { 1482 enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, 1483 "Need BLUETOOTH ADMIN permission"); 1484 1485 return startDiscoveryNative(); 1486 } 1487 1488 boolean cancelDiscovery() { 1489 enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, 1490 "Need BLUETOOTH ADMIN permission"); 1491 1492 return cancelDiscoveryNative(); 1493 } 1494 1495 boolean isDiscovering() { 1496 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1497 1498 return mAdapterProperties.isDiscovering(); 1499 } 1500 1501 long getDiscoveryEndMillis() { 1502 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1503 1504 return mAdapterProperties.discoveryEndMillis(); 1505 } 1506 1507 public BluetoothDevice[] getBondedDevices() { 1508 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1509 return mAdapterProperties.getBondedDevices(); 1510 } 1511 1512 int getAdapterConnectionState() { 1513 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1514 return mAdapterProperties.getConnectionState(); 1515 } 1516 1517 int getProfileConnectionState(int profile) { 1518 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1519 1520 return mAdapterProperties.getProfileConnectionState(profile); 1521 } 1522 boolean sdpSearch(BluetoothDevice device,ParcelUuid uuid) { 1523 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1524 if(mSdpManager != null) { 1525 mSdpManager.sdpSearch(device,uuid); 1526 return true; 1527 } else { 1528 return false; 1529 } 1530 } 1531 1532 boolean createBond(BluetoothDevice device, int transport, OobData oobData) { 1533 enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, 1534 "Need BLUETOOTH ADMIN permission"); 1535 DeviceProperties deviceProp = mRemoteDevices.getDeviceProperties(device); 1536 if (deviceProp != null && deviceProp.getBondState() != BluetoothDevice.BOND_NONE) { 1537 return false; 1538 } 1539 1540 mRemoteDevices.setBondingInitiatedLocally(Utils.getByteAddress(device)); 1541 1542 // Pairing is unreliable while scanning, so cancel discovery 1543 // Note, remove this when native stack improves 1544 cancelDiscoveryNative(); 1545 1546 Message msg = mBondStateMachine.obtainMessage(BondStateMachine.CREATE_BOND); 1547 msg.obj = device; 1548 msg.arg1 = transport; 1549 1550 if (oobData != null) { 1551 Bundle oobDataBundle = new Bundle(); 1552 oobDataBundle.putParcelable(BondStateMachine.OOBDATA, oobData); 1553 msg.setData(oobDataBundle); 1554 } 1555 mBondStateMachine.sendMessage(msg); 1556 return true; 1557 } 1558 1559 public boolean isQuietModeEnabled() { 1560 debugLog("isQuetModeEnabled() - Enabled = " + mQuietmode); 1561 return mQuietmode; 1562 } 1563 1564 public void updateUuids() { 1565 debugLog( "updateUuids() - Updating UUIDs for bonded devices"); 1566 BluetoothDevice[] bondedDevices = getBondedDevices(); 1567 if (bondedDevices == null) return; 1568 1569 for (BluetoothDevice device : bondedDevices) { 1570 mRemoteDevices.updateUuids(device); 1571 } 1572 } 1573 1574 boolean cancelBondProcess(BluetoothDevice device) { 1575 enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, "Need BLUETOOTH ADMIN permission"); 1576 byte[] addr = Utils.getBytesFromAddress(device.getAddress()); 1577 1578 DeviceProperties deviceProp = mRemoteDevices.getDeviceProperties(device); 1579 if (deviceProp != null) { 1580 deviceProp.setBondingInitiatedLocally(false); 1581 } 1582 1583 return cancelBondNative(addr); 1584 } 1585 1586 boolean removeBond(BluetoothDevice device) { 1587 enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, "Need BLUETOOTH ADMIN permission"); 1588 DeviceProperties deviceProp = mRemoteDevices.getDeviceProperties(device); 1589 if (deviceProp == null || deviceProp.getBondState() != BluetoothDevice.BOND_BONDED) { 1590 return false; 1591 } 1592 deviceProp.setBondingInitiatedLocally(false); 1593 1594 Message msg = mBondStateMachine.obtainMessage(BondStateMachine.REMOVE_BOND); 1595 msg.obj = device; 1596 mBondStateMachine.sendMessage(msg); 1597 return true; 1598 } 1599 1600 int getBondState(BluetoothDevice device) { 1601 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1602 DeviceProperties deviceProp = mRemoteDevices.getDeviceProperties(device); 1603 if (deviceProp == null) { 1604 return BluetoothDevice.BOND_NONE; 1605 } 1606 return deviceProp.getBondState(); 1607 } 1608 1609 boolean isBondingInitiatedLocally(BluetoothDevice device) { 1610 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1611 DeviceProperties deviceProp = mRemoteDevices.getDeviceProperties(device); 1612 if (deviceProp == null) { 1613 return false; 1614 } 1615 return deviceProp.isBondingInitiatedLocally(); 1616 } 1617 1618 long getSupportedProfiles() { 1619 return Config.getSupportedProfilesBitMask(); 1620 } 1621 1622 int getConnectionState(BluetoothDevice device) { 1623 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1624 byte[] addr = Utils.getBytesFromAddress(device.getAddress()); 1625 return getConnectionStateNative(addr); 1626 } 1627 1628 String getRemoteName(BluetoothDevice device) { 1629 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1630 if (mRemoteDevices == null) return null; 1631 DeviceProperties deviceProp = mRemoteDevices.getDeviceProperties(device); 1632 if (deviceProp == null) return null; 1633 return deviceProp.getName(); 1634 } 1635 1636 int getRemoteType(BluetoothDevice device) { 1637 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1638 DeviceProperties deviceProp = mRemoteDevices.getDeviceProperties(device); 1639 if (deviceProp == null) return BluetoothDevice.DEVICE_TYPE_UNKNOWN; 1640 return deviceProp.getDeviceType(); 1641 } 1642 1643 String getRemoteAlias(BluetoothDevice device) { 1644 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1645 DeviceProperties deviceProp = mRemoteDevices.getDeviceProperties(device); 1646 if (deviceProp == null) return null; 1647 return deviceProp.getAlias(); 1648 } 1649 1650 boolean setRemoteAlias(BluetoothDevice device, String name) { 1651 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1652 DeviceProperties deviceProp = mRemoteDevices.getDeviceProperties(device); 1653 if (deviceProp == null) return false; 1654 deviceProp.setAlias(device, name); 1655 return true; 1656 } 1657 1658 int getRemoteClass(BluetoothDevice device) { 1659 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1660 DeviceProperties deviceProp = mRemoteDevices.getDeviceProperties(device); 1661 if (deviceProp == null) return 0; 1662 1663 return deviceProp.getBluetoothClass(); 1664 } 1665 1666 ParcelUuid[] getRemoteUuids(BluetoothDevice device) { 1667 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1668 DeviceProperties deviceProp = mRemoteDevices.getDeviceProperties(device); 1669 if (deviceProp == null) return null; 1670 return deviceProp.getUuids(); 1671 } 1672 1673 boolean fetchRemoteUuids(BluetoothDevice device) { 1674 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1675 mRemoteDevices.fetchUuids(device); 1676 return true; 1677 } 1678 1679 boolean setPin(BluetoothDevice device, boolean accept, int len, byte[] pinCode) { 1680 enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, "Need BLUETOOTH ADMIN permission"); 1681 DeviceProperties deviceProp = mRemoteDevices.getDeviceProperties(device); 1682 // Only allow setting a pin in bonding state, or bonded state in case of security upgrade. 1683 if (deviceProp == null 1684 || (deviceProp.getBondState() != BluetoothDevice.BOND_BONDING 1685 && deviceProp.getBondState() != BluetoothDevice.BOND_BONDED)) { 1686 return false; 1687 } 1688 1689 byte[] addr = Utils.getBytesFromAddress(device.getAddress()); 1690 return pinReplyNative(addr, accept, len, pinCode); 1691 } 1692 1693 boolean setPasskey(BluetoothDevice device, boolean accept, int len, byte[] passkey) { 1694 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1695 DeviceProperties deviceProp = mRemoteDevices.getDeviceProperties(device); 1696 if (deviceProp == null || deviceProp.getBondState() != BluetoothDevice.BOND_BONDING) { 1697 return false; 1698 } 1699 1700 byte[] addr = Utils.getBytesFromAddress(device.getAddress()); 1701 return sspReplyNative(addr, AbstractionLayer.BT_SSP_VARIANT_PASSKEY_ENTRY, accept, 1702 Utils.byteArrayToInt(passkey)); 1703 } 1704 1705 boolean setPairingConfirmation(BluetoothDevice device, boolean accept) { 1706 enforceCallingOrSelfPermission( 1707 BLUETOOTH_PRIVILEGED, "Need BLUETOOTH PRIVILEGED permission"); 1708 DeviceProperties deviceProp = mRemoteDevices.getDeviceProperties(device); 1709 if (deviceProp == null || deviceProp.getBondState() != BluetoothDevice.BOND_BONDING) { 1710 return false; 1711 } 1712 1713 byte[] addr = Utils.getBytesFromAddress(device.getAddress()); 1714 return sspReplyNative(addr, AbstractionLayer.BT_SSP_VARIANT_PASSKEY_CONFIRMATION, 1715 accept, 0); 1716 } 1717 1718 int getPhonebookAccessPermission(BluetoothDevice device) { 1719 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1720 SharedPreferences pref = getSharedPreferences(PHONEBOOK_ACCESS_PERMISSION_PREFERENCE_FILE, 1721 Context.MODE_PRIVATE); 1722 if (!pref.contains(device.getAddress())) { 1723 return BluetoothDevice.ACCESS_UNKNOWN; 1724 } 1725 return pref.getBoolean(device.getAddress(), false) 1726 ? BluetoothDevice.ACCESS_ALLOWED : BluetoothDevice.ACCESS_REJECTED; 1727 } 1728 1729 boolean setPhonebookAccessPermission(BluetoothDevice device, int value) { 1730 enforceCallingOrSelfPermission( 1731 BLUETOOTH_PRIVILEGED, "Need BLUETOOTH PRIVILEGED permission"); 1732 SharedPreferences pref = getSharedPreferences(PHONEBOOK_ACCESS_PERMISSION_PREFERENCE_FILE, 1733 Context.MODE_PRIVATE); 1734 SharedPreferences.Editor editor = pref.edit(); 1735 if (value == BluetoothDevice.ACCESS_UNKNOWN) { 1736 editor.remove(device.getAddress()); 1737 } else { 1738 editor.putBoolean(device.getAddress(), value == BluetoothDevice.ACCESS_ALLOWED); 1739 } 1740 editor.apply(); 1741 return true; 1742 } 1743 1744 int getMessageAccessPermission(BluetoothDevice device) { 1745 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1746 SharedPreferences pref = getSharedPreferences(MESSAGE_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 setMessageAccessPermission(BluetoothDevice device, int value) { 1756 enforceCallingOrSelfPermission( 1757 BLUETOOTH_PRIVILEGED, "Need BLUETOOTH PRIVILEGED permission"); 1758 SharedPreferences pref = getSharedPreferences(MESSAGE_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 getSimAccessPermission(BluetoothDevice device) { 1771 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1772 SharedPreferences pref = getSharedPreferences(SIM_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 setSimAccessPermission(BluetoothDevice device, int value) { 1782 enforceCallingOrSelfPermission( 1783 BLUETOOTH_PRIVILEGED, "Need BLUETOOTH PRIVILEGED permission"); 1784 SharedPreferences pref = getSharedPreferences(SIM_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 void sendConnectionStateChange(BluetoothDevice device, int profile, int state, int prevState) { 1797 // TODO(BT) permission check? 1798 // Since this is a binder call check if Bluetooth is on still 1799 if (getState() == BluetoothAdapter.STATE_OFF) return; 1800 1801 mAdapterProperties.sendConnectionStateChange(device, profile, state, prevState); 1802 1803 } 1804 1805 ParcelFileDescriptor connectSocket( 1806 BluetoothDevice device, int type, ParcelUuid uuid, int port, int flag) { 1807 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1808 int fd = connectSocketNative(Utils.getBytesFromAddress(device.getAddress()), type, 1809 Utils.uuidToByteArray(uuid), port, flag, Binder.getCallingUid()); 1810 if (fd < 0) { 1811 errorLog("Failed to connect socket"); 1812 return null; 1813 } 1814 return ParcelFileDescriptor.adoptFd(fd); 1815 } 1816 1817 ParcelFileDescriptor createSocketChannel( 1818 int type, String serviceName, ParcelUuid uuid, int port, int flag) { 1819 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1820 int fd = createSocketChannelNative( 1821 type, serviceName, Utils.uuidToByteArray(uuid), port, flag, Binder.getCallingUid()); 1822 if (fd < 0) { 1823 errorLog("Failed to create socket channel"); 1824 return null; 1825 } 1826 return ParcelFileDescriptor.adoptFd(fd); 1827 } 1828 1829 boolean configHciSnoopLog(boolean enable) { 1830 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1831 return configHciSnoopLogNative(enable); 1832 } 1833 1834 boolean factoryReset() { 1835 enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, "Need BLUETOOTH permission"); 1836 return factoryResetNative(); 1837 } 1838 1839 void registerCallback(IBluetoothCallback cb) { 1840 mCallbacks.register(cb); 1841 } 1842 1843 void unregisterCallback(IBluetoothCallback cb) { 1844 mCallbacks.unregister(cb); 1845 } 1846 1847 public int getNumOfAdvertisementInstancesSupported() { 1848 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1849 return mAdapterProperties.getNumOfAdvertisementInstancesSupported(); 1850 } 1851 1852 public boolean isMultiAdvertisementSupported() { 1853 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1854 return getNumOfAdvertisementInstancesSupported() >= MIN_ADVT_INSTANCES_FOR_MA; 1855 } 1856 1857 public boolean isRpaOffloadSupported() { 1858 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1859 return mAdapterProperties.isRpaOffloadSupported(); 1860 } 1861 1862 public int getNumOfOffloadedIrkSupported() { 1863 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1864 return mAdapterProperties.getNumOfOffloadedIrkSupported(); 1865 } 1866 1867 public int getNumOfOffloadedScanFilterSupported() { 1868 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1869 return mAdapterProperties.getNumOfOffloadedScanFilterSupported(); 1870 } 1871 1872 public int getOffloadedScanResultStorage() { 1873 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1874 return mAdapterProperties.getOffloadedScanResultStorage(); 1875 } 1876 1877 private boolean isActivityAndEnergyReportingSupported() { 1878 enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, "Need BLUETOOTH permission"); 1879 return mAdapterProperties.isActivityAndEnergyReportingSupported(); 1880 } 1881 1882 private BluetoothActivityEnergyInfo reportActivityInfo() { 1883 enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, "Need BLUETOOTH permission"); 1884 if (mAdapterProperties.getState() != BluetoothAdapter.STATE_ON || 1885 !mAdapterProperties.isActivityAndEnergyReportingSupported()) { 1886 return null; 1887 } 1888 1889 // Pull the data. The callback will notify mEnergyInfoLock. 1890 readEnergyInfo(); 1891 1892 synchronized (mEnergyInfoLock) { 1893 try { 1894 mEnergyInfoLock.wait(CONTROLLER_ENERGY_UPDATE_TIMEOUT_MILLIS); 1895 } catch (InterruptedException e) { 1896 // Just continue, the energy data may be stale but we won't miss anything next time 1897 // we query. 1898 } 1899 1900 final BluetoothActivityEnergyInfo info = new BluetoothActivityEnergyInfo( 1901 SystemClock.elapsedRealtime(), 1902 mStackReportedState, 1903 mTxTimeTotalMs, mRxTimeTotalMs, mIdleTimeTotalMs, 1904 mEnergyUsedTotalVoltAmpSecMicro); 1905 1906 // Count the number of entries that have byte counts > 0 1907 int arrayLen = 0; 1908 for (int i = 0; i < mUidTraffic.size(); i++) { 1909 final UidTraffic traffic = mUidTraffic.valueAt(i); 1910 if (traffic.getTxBytes() != 0 || traffic.getRxBytes() != 0) { 1911 arrayLen++; 1912 } 1913 } 1914 1915 // Copy the traffic objects whose byte counts are > 0 and reset the originals. 1916 final UidTraffic[] result = arrayLen > 0 ? new UidTraffic[arrayLen] : null; 1917 int putIdx = 0; 1918 for (int i = 0; i < mUidTraffic.size(); i++) { 1919 final UidTraffic traffic = mUidTraffic.valueAt(i); 1920 if (traffic.getTxBytes() != 0 || traffic.getRxBytes() != 0) { 1921 result[putIdx++] = traffic.clone(); 1922 traffic.setRxBytes(0); 1923 traffic.setTxBytes(0); 1924 } 1925 } 1926 1927 info.setUidTraffic(result); 1928 1929 // Read on clear values; a record of data is created with 1930 // timstamp and new samples are collected until read again 1931 mStackReportedState = 0; 1932 mTxTimeTotalMs = 0; 1933 mRxTimeTotalMs = 0; 1934 mIdleTimeTotalMs = 0; 1935 mEnergyUsedTotalVoltAmpSecMicro = 0; 1936 return info; 1937 } 1938 } 1939 1940 public int getTotalNumOfTrackableAdvertisements() { 1941 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1942 return mAdapterProperties.getTotalNumOfTrackableAdvertisements(); 1943 } 1944 1945 public void onLeServiceUp() { 1946 Message m = mAdapterStateMachine.obtainMessage(AdapterState.USER_TURN_ON); 1947 mAdapterStateMachine.sendMessage(m); 1948 } 1949 1950 public void onBrEdrDown() { 1951 Message m = mAdapterStateMachine.obtainMessage(AdapterState.USER_TURN_OFF); 1952 mAdapterStateMachine.sendMessage(m); 1953 } 1954 1955 private static int convertScanModeToHal(int mode) { 1956 switch (mode) { 1957 case BluetoothAdapter.SCAN_MODE_NONE: 1958 return AbstractionLayer.BT_SCAN_MODE_NONE; 1959 case BluetoothAdapter.SCAN_MODE_CONNECTABLE: 1960 return AbstractionLayer.BT_SCAN_MODE_CONNECTABLE; 1961 case BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE: 1962 return AbstractionLayer.BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE; 1963 } 1964 // errorLog("Incorrect scan mode in convertScanModeToHal"); 1965 return -1; 1966 } 1967 1968 static int convertScanModeFromHal(int mode) { 1969 switch (mode) { 1970 case AbstractionLayer.BT_SCAN_MODE_NONE: 1971 return BluetoothAdapter.SCAN_MODE_NONE; 1972 case AbstractionLayer.BT_SCAN_MODE_CONNECTABLE: 1973 return BluetoothAdapter.SCAN_MODE_CONNECTABLE; 1974 case AbstractionLayer.BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE: 1975 return BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE; 1976 } 1977 //errorLog("Incorrect scan mode in convertScanModeFromHal"); 1978 return -1; 1979 } 1980 1981 // This function is called from JNI. It allows native code to set a single wake 1982 // alarm. If an alarm is already pending and a new request comes in, the alarm 1983 // will be rescheduled (i.e. the previously set alarm will be cancelled). 1984 private boolean setWakeAlarm(long delayMillis, boolean shouldWake) { 1985 synchronized (this) { 1986 if (mPendingAlarm != null) { 1987 mAlarmManager.cancel(mPendingAlarm); 1988 } 1989 1990 long wakeupTime = SystemClock.elapsedRealtime() + delayMillis; 1991 int type = shouldWake ? AlarmManager.ELAPSED_REALTIME_WAKEUP 1992 : AlarmManager.ELAPSED_REALTIME; 1993 1994 Intent intent = new Intent(ACTION_ALARM_WAKEUP); 1995 mPendingAlarm = PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_ONE_SHOT); 1996 mAlarmManager.setExact(type, wakeupTime, mPendingAlarm); 1997 return true; 1998 } 1999 } 2000 2001 // This function is called from JNI. It allows native code to acquire a single wake lock. 2002 // If the wake lock is already held, this function returns success. Although this function 2003 // only supports acquiring a single wake lock at a time right now, it will eventually be 2004 // extended to allow acquiring an arbitrary number of wake locks. The current interface 2005 // takes |lockName| as a parameter in anticipation of that implementation. 2006 private boolean acquireWakeLock(String lockName) { 2007 synchronized (this) { 2008 if (mWakeLock == null) { 2009 mWakeLockName = lockName; 2010 mWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, lockName); 2011 } 2012 2013 if (!mWakeLock.isHeld()) 2014 mWakeLock.acquire(); 2015 } 2016 return true; 2017 } 2018 2019 // This function is called from JNI. It allows native code to release a wake lock acquired 2020 // by |acquireWakeLock|. If the wake lock is not held, this function returns failure. 2021 // Note that the release() call is also invoked by {@link #cleanup()} so a synchronization is 2022 // needed here. See the comment for |acquireWakeLock| for an explanation of the interface. 2023 private boolean releaseWakeLock(String lockName) { 2024 synchronized (this) { 2025 if (mWakeLock == null) { 2026 errorLog("Repeated wake lock release; aborting release: " + lockName); 2027 return false; 2028 } 2029 2030 if (mWakeLock.isHeld()) 2031 mWakeLock.release(); 2032 } 2033 return true; 2034 } 2035 2036 private void energyInfoCallback(int status, int ctrl_state, long tx_time, long rx_time, 2037 long idle_time, long energy_used, UidTraffic[] data) throws RemoteException { 2038 if (ctrl_state >= BluetoothActivityEnergyInfo.BT_STACK_STATE_INVALID 2039 && ctrl_state <= BluetoothActivityEnergyInfo.BT_STACK_STATE_STATE_IDLE) { 2040 // Energy is product of mA, V and ms. If the chipset doesn't 2041 // report it, we have to compute it from time 2042 if (energy_used == 0) { 2043 try { 2044 final long txMah = Math.multiplyExact(tx_time, getTxCurrentMa()); 2045 final long rxMah = Math.multiplyExact(rx_time, getRxCurrentMa()); 2046 final long idleMah = Math.multiplyExact(idle_time, getIdleCurrentMa()); 2047 energy_used = (long) (Math.addExact(Math.addExact(txMah, rxMah), idleMah) 2048 * getOperatingVolt()); 2049 } catch (ArithmeticException e) { 2050 Slog.wtf(TAG, "overflow in bluetooth energy callback", e); 2051 // Energy is already 0 if the exception was thrown. 2052 } 2053 } 2054 2055 synchronized (mEnergyInfoLock) { 2056 mStackReportedState = ctrl_state; 2057 long totalTxTimeMs; 2058 long totalRxTimeMs; 2059 long totalIdleTimeMs; 2060 long totalEnergy; 2061 try { 2062 totalTxTimeMs = Math.addExact(mTxTimeTotalMs, tx_time); 2063 totalRxTimeMs = Math.addExact(mRxTimeTotalMs, rx_time); 2064 totalIdleTimeMs = Math.addExact(mIdleTimeTotalMs, idle_time); 2065 totalEnergy = Math.addExact(mEnergyUsedTotalVoltAmpSecMicro, energy_used); 2066 } catch (ArithmeticException e) { 2067 // This could be because we accumulated a lot of time, or we got a very strange 2068 // value from the controller (more likely). Discard this data. 2069 Slog.wtf(TAG, "overflow in bluetooth energy callback", e); 2070 totalTxTimeMs = mTxTimeTotalMs; 2071 totalRxTimeMs = mRxTimeTotalMs; 2072 totalIdleTimeMs = mIdleTimeTotalMs; 2073 totalEnergy = mEnergyUsedTotalVoltAmpSecMicro; 2074 } 2075 2076 mTxTimeTotalMs = totalTxTimeMs; 2077 mRxTimeTotalMs = totalRxTimeMs; 2078 mIdleTimeTotalMs = totalIdleTimeMs; 2079 mEnergyUsedTotalVoltAmpSecMicro = totalEnergy; 2080 2081 for (UidTraffic traffic : data) { 2082 UidTraffic existingTraffic = mUidTraffic.get(traffic.getUid()); 2083 if (existingTraffic == null) { 2084 mUidTraffic.put(traffic.getUid(), traffic); 2085 } else { 2086 existingTraffic.addRxBytes(traffic.getRxBytes()); 2087 existingTraffic.addTxBytes(traffic.getTxBytes()); 2088 } 2089 } 2090 mEnergyInfoLock.notifyAll(); 2091 } 2092 } 2093 2094 verboseLog("energyInfoCallback() status = " + status + "tx_time = " + tx_time + "rx_time = " 2095 + rx_time + "idle_time = " + idle_time + "energy_used = " + energy_used 2096 + "ctrl_state = " + ctrl_state + "traffic = " + Arrays.toString(data)); 2097 } 2098 2099 private int getIdleCurrentMa() { 2100 return getResources().getInteger(R.integer.config_bluetooth_idle_cur_ma); 2101 } 2102 2103 private int getTxCurrentMa() { 2104 return getResources().getInteger(R.integer.config_bluetooth_tx_cur_ma); 2105 } 2106 2107 private int getRxCurrentMa() { 2108 return getResources().getInteger(R.integer.config_bluetooth_rx_cur_ma); 2109 } 2110 2111 private double getOperatingVolt() { 2112 return getResources().getInteger(R.integer.config_bluetooth_operating_voltage_mv) / 1000.0; 2113 } 2114 2115 @Override 2116 protected void dump(FileDescriptor fd, PrintWriter writer, String[] args) { 2117 enforceCallingOrSelfPermission(android.Manifest.permission.DUMP, TAG); 2118 2119 if (args.length == 0) { 2120 writer.println("Skipping dump in APP SERVICES, see bluetooth_manager section."); 2121 writer.println("Use --print argument for dumpsys direct from AdapterService."); 2122 return; 2123 } 2124 2125 if (args.length > 0) { 2126 verboseLog( 2127 "dumpsys arguments, check for protobuf output: " + TextUtils.join(" ", args)); 2128 if (args[0].startsWith("--proto")) { 2129 if (args[0].equals("--proto-java-bin")) { 2130 dumpJava(fd); 2131 } else { 2132 dumpNative(fd, args); 2133 } 2134 return; 2135 } 2136 } 2137 2138 writer.println("Bonded devices:"); 2139 for (BluetoothDevice device : getBondedDevices()) { 2140 writer.println(" " + device.getAddress() + " [" + DEVICE_TYPE_NAMES[device.getType()] 2141 + "] " + device.getName()); 2142 } 2143 2144 // Dump profile information 2145 StringBuilder sb = new StringBuilder(); 2146 synchronized (mProfiles) { 2147 for (ProfileService profile : mProfiles) { 2148 profile.dump(sb); 2149 } 2150 } 2151 2152 writer.write(sb.toString()); 2153 writer.flush(); 2154 2155 dumpNative(fd, args); 2156 } 2157 2158 private void dumpJava(FileDescriptor fd) { 2159 BluetoothProto.BluetoothLog log = new BluetoothProto.BluetoothLog(); 2160 log.setNumBondedDevices(getBondedDevices().length); 2161 2162 for (ProfileService profile : mProfiles) { 2163 profile.dumpProto(log); 2164 } 2165 2166 try { 2167 FileOutputStream protoOut = new FileOutputStream(fd); 2168 String protoOutString = Base64.encodeToString(log.toByteArray(), Base64.DEFAULT); 2169 protoOut.write(protoOutString.getBytes(StandardCharsets.UTF_8)); 2170 protoOut.close(); 2171 } catch (IOException e) { 2172 errorLog("Unable to write Java protobuf to file descriptor."); 2173 } 2174 } 2175 2176 private void debugLog(String msg) { 2177 if (DBG) Log.d(TAG, msg); 2178 } 2179 2180 private void verboseLog(String msg) { 2181 if (VERBOSE) Log.v(TAG, msg); 2182 } 2183 2184 private void errorLog(String msg) { 2185 Log.e(TAG, msg); 2186 } 2187 2188 private final BroadcastReceiver mAlarmBroadcastReceiver = new BroadcastReceiver() { 2189 @Override 2190 public void onReceive(Context context, Intent intent) { 2191 synchronized (AdapterService.this) { 2192 mPendingAlarm = null; 2193 alarmFiredNative(); 2194 } 2195 } 2196 }; 2197 2198 private native static void classInitNative(); 2199 private native boolean initNative(); 2200 private native void cleanupNative(); 2201 /*package*/ native boolean enableNative(boolean startRestricted); 2202 /*package*/ native boolean disableNative(); 2203 /*package*/ native boolean setAdapterPropertyNative(int type, byte[] val); 2204 /*package*/ native boolean getAdapterPropertiesNative(); 2205 /*package*/ native boolean getAdapterPropertyNative(int type); 2206 /*package*/ native boolean setAdapterPropertyNative(int type); 2207 /*package*/ native boolean setDevicePropertyNative(byte[] address, int type, byte[] val); 2208 /*package*/ native boolean getDevicePropertyNative(byte[] address, int type); 2209 2210 /*package*/ native boolean createBondNative(byte[] address, int transport); 2211 /*package*/ native boolean createBondOutOfBandNative(byte[] address, int transport, OobData oobData); 2212 /*package*/ native boolean removeBondNative(byte[] address); 2213 /*package*/ native boolean cancelBondNative(byte[] address); 2214 /*package*/ native boolean sdpSearchNative(byte[] address, byte[] uuid); 2215 2216 /*package*/ native int getConnectionStateNative(byte[] address); 2217 2218 private native boolean startDiscoveryNative(); 2219 private native boolean cancelDiscoveryNative(); 2220 2221 private native boolean pinReplyNative(byte[] address, boolean accept, int len, byte[] pin); 2222 private native boolean sspReplyNative(byte[] address, int type, boolean 2223 accept, int passkey); 2224 2225 /*package*/ native boolean getRemoteServicesNative(byte[] address); 2226 /*package*/ native boolean getRemoteMasInstancesNative(byte[] address); 2227 2228 private native int readEnergyInfo(); 2229 // TODO(BT) move this to ../btsock dir 2230 private native int connectSocketNative( 2231 byte[] address, int type, byte[] uuid, int port, int flag, int callingUid); 2232 private native int createSocketChannelNative( 2233 int type, String serviceName, byte[] uuid, int port, int flag, int callingUid); 2234 2235 /*package*/ native boolean configHciSnoopLogNative(boolean enable); 2236 /*package*/ native boolean factoryResetNative(); 2237 2238 private native void alarmFiredNative(); 2239 private native void dumpNative(FileDescriptor fd, String[] arguments); 2240 2241 private native void interopDatabaseClearNative(); 2242 private native void interopDatabaseAddNative(int feature, byte[] address, int length); 2243 2244 protected void finalize() { 2245 debugLog("finalize() - clean up object " + this); 2246 cleanup(); 2247 if (TRACE_REF) { 2248 synchronized (AdapterService.class) { 2249 sRefCount--; 2250 debugLog("finalize() - REFCOUNT: FINALIZED. INSTANCE_COUNT= " + sRefCount); 2251 } 2252 } 2253 } 2254 2255 // Returns if this is a mock object. This is currently used in testing so that we may not call 2256 // System.exit() while finalizing the object. Otherwise GC of mock objects unfortunately ends up 2257 // calling finalize() which in turn calls System.exit() and the process crashes. 2258 // 2259 // Mock this in your testing framework to return true to avoid the mentioned behavior. In 2260 // production this has no effect. 2261 public boolean isMock() { 2262 return false; 2263 } 2264} 2265