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