1 /* 2 * Copyright (C) 2012 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.server; 18 19 import android.Manifest; 20 import android.app.ActivityManager; 21 import android.bluetooth.BluetoothAdapter; 22 import android.bluetooth.BluetoothProfile; 23 import android.bluetooth.IBluetooth; 24 import android.bluetooth.IBluetoothCallback; 25 import android.bluetooth.IBluetoothGatt; 26 import android.bluetooth.IBluetoothHeadset; 27 import android.bluetooth.IBluetoothManager; 28 import android.bluetooth.IBluetoothManagerCallback; 29 import android.bluetooth.IBluetoothProfileServiceConnection; 30 import android.bluetooth.IBluetoothStateChangeCallback; 31 import android.content.BroadcastReceiver; 32 import android.content.ComponentName; 33 import android.content.ContentResolver; 34 import android.content.Context; 35 import android.content.Intent; 36 import android.content.IntentFilter; 37 import android.content.ServiceConnection; 38 import android.content.pm.PackageManager; 39 import android.content.pm.UserInfo; 40 import android.database.ContentObserver; 41 import android.os.Binder; 42 import android.os.Handler; 43 import android.os.IBinder; 44 import android.os.Looper; 45 import android.os.Message; 46 import android.os.Process; 47 import android.os.RemoteCallbackList; 48 import android.os.RemoteException; 49 import android.os.SystemClock; 50 import android.os.UserHandle; 51 import android.os.UserManager; 52 import android.provider.Settings; 53 import android.provider.Settings.SettingNotFoundException; 54 import android.util.Slog; 55 import java.util.concurrent.locks.ReentrantReadWriteLock; 56 57 import java.io.FileDescriptor; 58 import java.io.PrintWriter; 59 import java.util.HashMap; 60 import java.util.Map; 61 62 class BluetoothManagerService extends IBluetoothManager.Stub { 63 private static final String TAG = "BluetoothManagerService"; 64 private static final boolean DBG = true; 65 66 private static final String BLUETOOTH_ADMIN_PERM = android.Manifest.permission.BLUETOOTH_ADMIN; 67 private static final String BLUETOOTH_PERM = android.Manifest.permission.BLUETOOTH; 68 private static final String ACTION_SERVICE_STATE_CHANGED="com.android.bluetooth.btservice.action.STATE_CHANGED"; 69 private static final String EXTRA_ACTION="action"; 70 private static final String SECURE_SETTINGS_BLUETOOTH_ADDR_VALID="bluetooth_addr_valid"; 71 private static final String SECURE_SETTINGS_BLUETOOTH_ADDRESS="bluetooth_address"; 72 private static final String SECURE_SETTINGS_BLUETOOTH_NAME="bluetooth_name"; 73 private static final int TIMEOUT_BIND_MS = 3000; //Maximum msec to wait for a bind 74 private static final int TIMEOUT_SAVE_MS = 500; //Maximum msec to wait for a save 75 //Maximum msec to wait for service restart 76 private static final int SERVICE_RESTART_TIME_MS = 200; 77 //Maximum msec to wait for restart due to error 78 private static final int ERROR_RESTART_TIME_MS = 3000; 79 //Maximum msec to delay MESSAGE_USER_SWITCHED 80 private static final int USER_SWITCHED_TIME_MS = 200; 81 // Delay for the addProxy function in msec 82 private static final int ADD_PROXY_DELAY_MS = 100; 83 84 private static final int MESSAGE_ENABLE = 1; 85 private static final int MESSAGE_DISABLE = 2; 86 private static final int MESSAGE_REGISTER_ADAPTER = 20; 87 private static final int MESSAGE_UNREGISTER_ADAPTER = 21; 88 private static final int MESSAGE_REGISTER_STATE_CHANGE_CALLBACK = 30; 89 private static final int MESSAGE_UNREGISTER_STATE_CHANGE_CALLBACK = 31; 90 private static final int MESSAGE_BLUETOOTH_SERVICE_CONNECTED = 40; 91 private static final int MESSAGE_BLUETOOTH_SERVICE_DISCONNECTED = 41; 92 private static final int MESSAGE_RESTART_BLUETOOTH_SERVICE = 42; 93 private static final int MESSAGE_BLUETOOTH_STATE_CHANGE = 60; 94 private static final int MESSAGE_TIMEOUT_BIND = 100; 95 private static final int MESSAGE_TIMEOUT_UNBIND = 101; 96 private static final int MESSAGE_GET_NAME_AND_ADDRESS = 200; 97 private static final int MESSAGE_USER_SWITCHED = 300; 98 private static final int MESSAGE_USER_UNLOCKED = 301; 99 private static final int MESSAGE_ADD_PROXY_DELAYED = 400; 100 private static final int MESSAGE_BIND_PROFILE_SERVICE = 401; 101 private static final int MAX_SAVE_RETRIES = 3; 102 private static final int MAX_ERROR_RESTART_RETRIES = 6; 103 104 // Bluetooth persisted setting is off 105 private static final int BLUETOOTH_OFF=0; 106 // Bluetooth persisted setting is on 107 // and Airplane mode won't affect Bluetooth state at start up 108 private static final int BLUETOOTH_ON_BLUETOOTH=1; 109 // Bluetooth persisted setting is on 110 // but Airplane mode will affect Bluetooth state at start up 111 // and Airplane mode will have higher priority. 112 private static final int BLUETOOTH_ON_AIRPLANE=2; 113 114 private static final int SERVICE_IBLUETOOTH = 1; 115 private static final int SERVICE_IBLUETOOTHGATT = 2; 116 117 private final Context mContext; 118 private static int mBleAppCount = 0; 119 120 // Locks are not provided for mName and mAddress. 121 // They are accessed in handler or broadcast receiver, same thread context. 122 private String mAddress; 123 private String mName; 124 private final ContentResolver mContentResolver; 125 private final RemoteCallbackList<IBluetoothManagerCallback> mCallbacks; 126 private final RemoteCallbackList<IBluetoothStateChangeCallback> mStateChangeCallbacks; 127 private IBinder mBluetoothBinder; 128 private IBluetooth mBluetooth; 129 private IBluetoothGatt mBluetoothGatt; 130 private final ReentrantReadWriteLock mBluetoothLock = 131 new ReentrantReadWriteLock(); 132 private boolean mBinding; 133 private boolean mUnbinding; 134 // used inside handler thread 135 private boolean mQuietEnable = false; 136 // configuarion from external IBinder call which is used to 137 // synchronize with broadcast receiver. 138 private boolean mQuietEnableExternal; 139 // configuarion from external IBinder call which is used to 140 // synchronize with broadcast receiver. 141 private boolean mEnableExternal; 142 // used inside handler thread 143 private boolean mEnable; 144 private int mState; 145 private final BluetoothHandler mHandler; 146 private int mErrorRecoveryRetryCounter; 147 private final int mSystemUiUid; 148 149 // Save a ProfileServiceConnections object for each of the bound 150 // bluetooth profile services 151 private final Map <Integer, ProfileServiceConnections> mProfileServices = 152 new HashMap <Integer, ProfileServiceConnections>(); 153 154 private void registerForAirplaneMode(IntentFilter filter) { 155 final ContentResolver resolver = mContext.getContentResolver(); 156 final String airplaneModeRadios = Settings.Global.getString(resolver, 157 Settings.Global.AIRPLANE_MODE_RADIOS); 158 final String toggleableRadios = Settings.Global.getString(resolver, 159 Settings.Global.AIRPLANE_MODE_TOGGLEABLE_RADIOS); 160 boolean mIsAirplaneSensitive = airplaneModeRadios == null ? true : 161 airplaneModeRadios.contains(Settings.Global.RADIO_BLUETOOTH); 162 if (mIsAirplaneSensitive) { 163 filter.addAction(Intent.ACTION_AIRPLANE_MODE_CHANGED); 164 } 165 } 166 167 private final IBluetoothCallback mBluetoothCallback = new IBluetoothCallback.Stub() { 168 @Override 169 public void onBluetoothStateChange(int prevState, int newState) throws RemoteException { 170 Message msg = mHandler.obtainMessage(MESSAGE_BLUETOOTH_STATE_CHANGE,prevState,newState); 171 mHandler.sendMessage(msg); 172 } 173 }; 174 175 private final BroadcastReceiver mReceiver = new BroadcastReceiver() { 176 @Override 177 public void onReceive(Context context, Intent intent) { 178 String action = intent.getAction(); 179 if (BluetoothAdapter.ACTION_LOCAL_NAME_CHANGED.equals(action)) { 180 String newName = intent.getStringExtra(BluetoothAdapter.EXTRA_LOCAL_NAME); 181 if (DBG) Slog.d(TAG, "Bluetooth Adapter name changed to " + newName); 182 if (newName != null) { 183 storeNameAndAddress(newName, null); 184 } 185 } else if (Intent.ACTION_AIRPLANE_MODE_CHANGED.equals(action)) { 186 synchronized(mReceiver) { 187 if (isBluetoothPersistedStateOn()) { 188 if (isAirplaneModeOn()) { 189 persistBluetoothSetting(BLUETOOTH_ON_AIRPLANE); 190 } else { 191 persistBluetoothSetting(BLUETOOTH_ON_BLUETOOTH); 192 } 193 } 194 195 int st = BluetoothAdapter.STATE_OFF; 196 try { 197 mBluetoothLock.readLock().lock(); 198 if (mBluetooth != null) { 199 st = mBluetooth.getState(); 200 } 201 } catch (RemoteException e) { 202 Slog.e(TAG, "Unable to call getState", e); 203 } finally { 204 mBluetoothLock.readLock().unlock(); 205 } 206 Slog.d(TAG, "Airplane Mode change - current state: " + st); 207 208 if (isAirplaneModeOn()) { 209 // Clear registered LE apps to force shut-off 210 synchronized (this) { 211 mBleAppCount = 0; 212 mBleApps.clear(); 213 } 214 if (st == BluetoothAdapter.STATE_BLE_ON) { 215 //if state is BLE_ON make sure you trigger disableBLE part 216 try { 217 mBluetoothLock.readLock().lock(); 218 if (mBluetooth != null) { 219 mBluetooth.onBrEdrDown(); 220 mEnable = false; 221 mEnableExternal = false; 222 } 223 } catch (RemoteException e) { 224 Slog.e(TAG,"Unable to call onBrEdrDown", e); 225 } finally { 226 mBluetoothLock.readLock().unlock(); 227 } 228 } else if (st == BluetoothAdapter.STATE_ON){ 229 // disable without persisting the setting 230 Slog.d(TAG, "Calling disable"); 231 sendDisableMsg(); 232 } 233 } else if (mEnableExternal) { 234 // enable without persisting the setting 235 Slog.d(TAG, "Calling enable"); 236 sendEnableMsg(mQuietEnableExternal); 237 } 238 } 239 } 240 } 241 }; 242 243 BluetoothManagerService(Context context) { 244 mHandler = new BluetoothHandler(IoThread.get().getLooper()); 245 246 mContext = context; 247 mBluetooth = null; 248 mBluetoothBinder = null; 249 mBluetoothGatt = null; 250 mBinding = false; 251 mUnbinding = false; 252 mEnable = false; 253 mState = BluetoothAdapter.STATE_OFF; 254 mQuietEnableExternal = false; 255 mEnableExternal = false; 256 mAddress = null; 257 mName = null; 258 mErrorRecoveryRetryCounter = 0; 259 mContentResolver = context.getContentResolver(); 260 // Observe BLE scan only mode settings change. 261 registerForBleScanModeChange(); 262 mCallbacks = new RemoteCallbackList<IBluetoothManagerCallback>(); 263 mStateChangeCallbacks = new RemoteCallbackList<IBluetoothStateChangeCallback>(); 264 IntentFilter filter = new IntentFilter(BluetoothAdapter.ACTION_LOCAL_NAME_CHANGED); 265 registerForAirplaneMode(filter); 266 filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY); 267 mContext.registerReceiver(mReceiver, filter); 268 loadStoredNameAndAddress(); 269 if (isBluetoothPersistedStateOn()) { 270 if (DBG) Slog.d(TAG, "Startup: Bluetooth persisted state is ON."); 271 mEnableExternal = true; 272 } 273 274 int sysUiUid = -1; 275 try { 276 sysUiUid = mContext.getPackageManager().getPackageUidAsUser("com.android.systemui", 277 PackageManager.MATCH_SYSTEM_ONLY, UserHandle.USER_SYSTEM); 278 } catch (PackageManager.NameNotFoundException e) { 279 // Some platforms, such as wearables do not have a system ui. 280 Slog.w(TAG, "Unable to resolve SystemUI's UID.", e); 281 } 282 mSystemUiUid = sysUiUid; 283 } 284 285 /** 286 * Returns true if airplane mode is currently on 287 */ 288 private final boolean isAirplaneModeOn() { 289 return Settings.Global.getInt(mContext.getContentResolver(), 290 Settings.Global.AIRPLANE_MODE_ON, 0) == 1; 291 } 292 293 /** 294 * Returns true if the Bluetooth saved state is "on" 295 */ 296 private final boolean isBluetoothPersistedStateOn() { 297 int state = Settings.Global.getInt(mContentResolver, 298 Settings.Global.BLUETOOTH_ON, -1); 299 if (DBG) Slog.d(TAG, "Bluetooth persisted state: " + state); 300 return state != BLUETOOTH_OFF; 301 } 302 303 /** 304 * Returns true if the Bluetooth saved state is BLUETOOTH_ON_BLUETOOTH 305 */ 306 private final boolean isBluetoothPersistedStateOnBluetooth() { 307 return Settings.Global.getInt(mContentResolver, 308 Settings.Global.BLUETOOTH_ON, BLUETOOTH_ON_BLUETOOTH) == BLUETOOTH_ON_BLUETOOTH; 309 } 310 311 /** 312 * Save the Bluetooth on/off state 313 * 314 */ 315 private void persistBluetoothSetting(int value) { 316 if (DBG) Slog.d(TAG, "Persisting Bluetooth Setting: " + value); 317 Settings.Global.putInt(mContext.getContentResolver(), 318 Settings.Global.BLUETOOTH_ON, 319 value); 320 } 321 322 /** 323 * Returns true if the Bluetooth Adapter's name and address is 324 * locally cached 325 * @return 326 */ 327 private boolean isNameAndAddressSet() { 328 return mName !=null && mAddress!= null && mName.length()>0 && mAddress.length()>0; 329 } 330 331 /** 332 * Retrieve the Bluetooth Adapter's name and address and save it in 333 * in the local cache 334 */ 335 private void loadStoredNameAndAddress() { 336 if (DBG) Slog.d(TAG, "Loading stored name and address"); 337 if (mContext.getResources().getBoolean 338 (com.android.internal.R.bool.config_bluetooth_address_validation) && 339 Settings.Secure.getInt(mContentResolver, SECURE_SETTINGS_BLUETOOTH_ADDR_VALID, 0) == 0) { 340 // if the valid flag is not set, don't load the address and name 341 if (DBG) Slog.d(TAG, "invalid bluetooth name and address stored"); 342 return; 343 } 344 mName = Settings.Secure.getString(mContentResolver, SECURE_SETTINGS_BLUETOOTH_NAME); 345 mAddress = Settings.Secure.getString(mContentResolver, SECURE_SETTINGS_BLUETOOTH_ADDRESS); 346 if (DBG) Slog.d(TAG, "Stored bluetooth Name=" + mName + ",Address=" + mAddress); 347 } 348 349 /** 350 * Save the Bluetooth name and address in the persistent store. 351 * Only non-null values will be saved. 352 * @param name 353 * @param address 354 */ 355 private void storeNameAndAddress(String name, String address) { 356 if (name != null) { 357 Settings.Secure.putString(mContentResolver, SECURE_SETTINGS_BLUETOOTH_NAME, name); 358 mName = name; 359 if (DBG) Slog.d(TAG,"Stored Bluetooth name: " + 360 Settings.Secure.getString(mContentResolver,SECURE_SETTINGS_BLUETOOTH_NAME)); 361 } 362 363 if (address != null) { 364 Settings.Secure.putString(mContentResolver, SECURE_SETTINGS_BLUETOOTH_ADDRESS, address); 365 mAddress=address; 366 if (DBG) Slog.d(TAG,"Stored Bluetoothaddress: " + 367 Settings.Secure.getString(mContentResolver,SECURE_SETTINGS_BLUETOOTH_ADDRESS)); 368 } 369 370 if ((name != null) && (address != null)) { 371 Settings.Secure.putInt(mContentResolver, SECURE_SETTINGS_BLUETOOTH_ADDR_VALID, 1); 372 } 373 } 374 375 public IBluetooth registerAdapter(IBluetoothManagerCallback callback){ 376 if (callback == null) { 377 Slog.w(TAG, "Callback is null in registerAdapter"); 378 return null; 379 } 380 Message msg = mHandler.obtainMessage(MESSAGE_REGISTER_ADAPTER); 381 msg.obj = callback; 382 mHandler.sendMessage(msg); 383 384 return mBluetooth; 385 } 386 387 public void unregisterAdapter(IBluetoothManagerCallback callback) { 388 if (callback == null) { 389 Slog.w(TAG, "Callback is null in unregisterAdapter"); 390 return; 391 } 392 mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, 393 "Need BLUETOOTH permission"); 394 Message msg = mHandler.obtainMessage(MESSAGE_UNREGISTER_ADAPTER); 395 msg.obj = callback; 396 mHandler.sendMessage(msg); 397 } 398 399 public void registerStateChangeCallback(IBluetoothStateChangeCallback callback) { 400 mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, 401 "Need BLUETOOTH permission"); 402 Message msg = mHandler.obtainMessage(MESSAGE_REGISTER_STATE_CHANGE_CALLBACK); 403 msg.obj = callback; 404 mHandler.sendMessage(msg); 405 } 406 407 public void unregisterStateChangeCallback(IBluetoothStateChangeCallback callback) { 408 mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, 409 "Need BLUETOOTH permission"); 410 Message msg = mHandler.obtainMessage(MESSAGE_UNREGISTER_STATE_CHANGE_CALLBACK); 411 msg.obj = callback; 412 mHandler.sendMessage(msg); 413 } 414 415 public boolean isEnabled() { 416 if ((Binder.getCallingUid() != Process.SYSTEM_UID) && 417 (!checkIfCallerIsForegroundUser())) { 418 Slog.w(TAG,"isEnabled(): not allowed for non-active and non system user"); 419 return false; 420 } 421 422 try { 423 mBluetoothLock.readLock().lock(); 424 if (mBluetooth != null) return mBluetooth.isEnabled(); 425 } catch (RemoteException e) { 426 Slog.e(TAG, "isEnabled()", e); 427 } finally { 428 mBluetoothLock.readLock().unlock(); 429 } 430 return false; 431 } 432 433 public int getState() { 434 if ((Binder.getCallingUid() != Process.SYSTEM_UID) && 435 (!checkIfCallerIsForegroundUser())) { 436 Slog.w(TAG, "getState(): not allowed for non-active and non system user"); 437 return BluetoothAdapter.STATE_OFF; 438 } 439 440 try { 441 mBluetoothLock.readLock().lock(); 442 if (mBluetooth != null) return mBluetooth.getState(); 443 } catch (RemoteException e) { 444 Slog.e(TAG, "getState()", e); 445 } finally { 446 mBluetoothLock.readLock().unlock(); 447 } 448 return BluetoothAdapter.STATE_OFF; 449 } 450 451 class ClientDeathRecipient implements IBinder.DeathRecipient { 452 public void binderDied() { 453 if (DBG) Slog.d(TAG, "Binder is dead - unregister Ble App"); 454 if (mBleAppCount > 0) --mBleAppCount; 455 456 if (mBleAppCount == 0) { 457 if (DBG) Slog.d(TAG, "Disabling LE only mode after application crash"); 458 try { 459 mBluetoothLock.readLock().lock(); 460 if (mBluetooth != null && 461 mBluetooth.getState() == BluetoothAdapter.STATE_BLE_ON) { 462 mEnable = false; 463 mBluetooth.onBrEdrDown(); 464 } 465 } catch (RemoteException e) { 466 Slog.e(TAG,"Unable to call onBrEdrDown", e); 467 } finally { 468 mBluetoothLock.readLock().unlock(); 469 } 470 } 471 } 472 } 473 474 /** Internal death rec list */ 475 Map<IBinder, ClientDeathRecipient> mBleApps = new HashMap<IBinder, ClientDeathRecipient>(); 476 477 @Override 478 public boolean isBleScanAlwaysAvailable() { 479 if (isAirplaneModeOn() && !mEnable) { 480 return false; 481 } 482 try { 483 return (Settings.Global.getInt(mContentResolver, 484 Settings.Global.BLE_SCAN_ALWAYS_AVAILABLE)) != 0; 485 } catch (SettingNotFoundException e) { 486 } 487 return false; 488 } 489 490 // Monitor change of BLE scan only mode settings. 491 private void registerForBleScanModeChange() { 492 ContentObserver contentObserver = new ContentObserver(null) { 493 @Override 494 public void onChange(boolean selfChange) { 495 if (!isBleScanAlwaysAvailable()) { 496 disableBleScanMode(); 497 clearBleApps(); 498 try { 499 mBluetoothLock.readLock().lock(); 500 if (mBluetooth != null) mBluetooth.onBrEdrDown(); 501 } catch (RemoteException e) { 502 Slog.e(TAG, "error when disabling bluetooth", e); 503 } finally { 504 mBluetoothLock.readLock().unlock(); 505 } 506 } 507 } 508 }; 509 510 mContentResolver.registerContentObserver( 511 Settings.Global.getUriFor(Settings.Global.BLE_SCAN_ALWAYS_AVAILABLE), 512 false, contentObserver); 513 } 514 515 // Disable ble scan only mode. 516 private void disableBleScanMode() { 517 try { 518 mBluetoothLock.writeLock().lock(); 519 if (mBluetooth != null && (mBluetooth.getState() != BluetoothAdapter.STATE_ON)) { 520 if (DBG) Slog.d(TAG, "Reseting the mEnable flag for clean disable"); 521 mEnable = false; 522 } 523 } catch (RemoteException e) { 524 Slog.e(TAG, "getState()", e); 525 } finally { 526 mBluetoothLock.writeLock().unlock(); 527 } 528 } 529 530 public int updateBleAppCount(IBinder token, boolean enable) { 531 if (enable) { 532 ClientDeathRecipient r = mBleApps.get(token); 533 if (r == null) { 534 ClientDeathRecipient deathRec = new ClientDeathRecipient(); 535 try { 536 token.linkToDeath(deathRec, 0); 537 } catch (RemoteException ex) { 538 throw new IllegalArgumentException("Wake lock is already dead."); 539 } 540 mBleApps.put(token, deathRec); 541 synchronized (this) { 542 ++mBleAppCount; 543 } 544 if (DBG) Slog.d(TAG, "Registered for death Notification"); 545 } 546 547 } else { 548 ClientDeathRecipient r = mBleApps.get(token); 549 if (r != null) { 550 // Unregister death recipient as the app goes away. 551 token.unlinkToDeath(r, 0); 552 mBleApps.remove(token); 553 synchronized (this) { 554 if (mBleAppCount > 0) --mBleAppCount; 555 } 556 if (DBG) Slog.d(TAG, "Unregistered for death Notification"); 557 } 558 } 559 if (DBG) Slog.d(TAG, "Updated BleAppCount" + mBleAppCount); 560 if (mBleAppCount == 0 && mEnable) { 561 disableBleScanMode(); 562 } 563 return mBleAppCount; 564 } 565 566 // Clear all apps using BLE scan only mode. 567 private void clearBleApps() { 568 synchronized (this) { 569 mBleApps.clear(); 570 mBleAppCount = 0; 571 } 572 } 573 574 /** @hide*/ 575 public boolean isBleAppPresent() { 576 if (DBG) Slog.d(TAG, "isBleAppPresent() count: " + mBleAppCount); 577 return (mBleAppCount > 0); 578 } 579 580 /** 581 * Action taken when GattService is turned off 582 */ 583 private void onBluetoothGattServiceUp() { 584 if (DBG) Slog.d(TAG,"BluetoothGatt Service is Up"); 585 try { 586 mBluetoothLock.readLock().lock(); 587 if (isBleAppPresent() == false && mBluetooth != null 588 && mBluetooth.getState() == BluetoothAdapter.STATE_BLE_ON) { 589 mBluetooth.onLeServiceUp(); 590 591 // waive WRITE_SECURE_SETTINGS permission check 592 long callingIdentity = Binder.clearCallingIdentity(); 593 persistBluetoothSetting(BLUETOOTH_ON_BLUETOOTH); 594 Binder.restoreCallingIdentity(callingIdentity); 595 } 596 } catch (RemoteException e) { 597 Slog.e(TAG,"Unable to call onServiceUp", e); 598 } finally { 599 mBluetoothLock.readLock().unlock(); 600 } 601 } 602 603 /** 604 * Inform BluetoothAdapter instances that BREDR part is down 605 * and turn off all service and stack if no LE app needs it 606 */ 607 private void sendBrEdrDownCallback() { 608 if (DBG) Slog.d(TAG,"Calling sendBrEdrDownCallback callbacks"); 609 610 if (mBluetooth == null) { 611 Slog.w(TAG, "Bluetooth handle is null"); 612 return; 613 } 614 615 if (isBleAppPresent() == false) { 616 try { 617 mBluetoothLock.readLock().lock(); 618 if (mBluetooth != null) mBluetooth.onBrEdrDown(); 619 } catch (RemoteException e) { 620 Slog.e(TAG, "Call to onBrEdrDown() failed.", e); 621 } finally { 622 mBluetoothLock.readLock().unlock(); 623 } 624 } else { 625 // Need to stay at BLE ON. Disconnect all Gatt connections 626 try { 627 mBluetoothGatt.unregAll(); 628 } catch (RemoteException e) { 629 Slog.e(TAG, "Unable to disconnect all apps.", e); 630 } 631 } 632 } 633 634 public boolean enableNoAutoConnect() 635 { 636 mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, 637 "Need BLUETOOTH ADMIN permission"); 638 639 if (DBG) { 640 Slog.d(TAG,"enableNoAutoConnect(): mBluetooth =" + mBluetooth + 641 " mBinding = " + mBinding); 642 } 643 int callingAppId = UserHandle.getAppId(Binder.getCallingUid()); 644 645 if (callingAppId != Process.NFC_UID) { 646 throw new SecurityException("no permission to enable Bluetooth quietly"); 647 } 648 649 synchronized(mReceiver) { 650 mQuietEnableExternal = true; 651 mEnableExternal = true; 652 sendEnableMsg(true); 653 } 654 return true; 655 } 656 657 public boolean enable() { 658 if ((Binder.getCallingUid() != Process.SYSTEM_UID) && 659 (!checkIfCallerIsForegroundUser())) { 660 Slog.w(TAG,"enable(): not allowed for non-active and non system user"); 661 return false; 662 } 663 664 mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, 665 "Need BLUETOOTH ADMIN permission"); 666 if (DBG) { 667 Slog.d(TAG,"enable(): mBluetooth =" + mBluetooth + 668 " mBinding = " + mBinding + " mState = " + mState); 669 } 670 671 synchronized(mReceiver) { 672 mQuietEnableExternal = false; 673 mEnableExternal = true; 674 // waive WRITE_SECURE_SETTINGS permission check 675 sendEnableMsg(false); 676 } 677 if (DBG) Slog.d(TAG, "enable returning"); 678 return true; 679 } 680 681 public boolean disable(boolean persist) { 682 mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, 683 "Need BLUETOOTH ADMIN permissicacheNameAndAddresson"); 684 685 if ((Binder.getCallingUid() != Process.SYSTEM_UID) && 686 (!checkIfCallerIsForegroundUser())) { 687 Slog.w(TAG,"disable(): not allowed for non-active and non system user"); 688 return false; 689 } 690 691 if (DBG) { 692 Slog.d(TAG,"disable(): mBluetooth = " + mBluetooth + 693 " mBinding = " + mBinding); 694 } 695 696 synchronized(mReceiver) { 697 if (persist) { 698 // waive WRITE_SECURE_SETTINGS permission check 699 long callingIdentity = Binder.clearCallingIdentity(); 700 persistBluetoothSetting(BLUETOOTH_OFF); 701 Binder.restoreCallingIdentity(callingIdentity); 702 } 703 mEnableExternal = false; 704 sendDisableMsg(); 705 } 706 return true; 707 } 708 709 public void unbindAndFinish() { 710 if (DBG) { 711 Slog.d(TAG,"unbindAndFinish(): " + mBluetooth + 712 " mBinding = " + mBinding); 713 } 714 715 try { 716 mBluetoothLock.writeLock().lock(); 717 if (mUnbinding) return; 718 mUnbinding = true; 719 mHandler.removeMessages(MESSAGE_BLUETOOTH_STATE_CHANGE); 720 mHandler.removeMessages(MESSAGE_BIND_PROFILE_SERVICE); 721 if (mBluetooth != null) { 722 //Unregister callback object 723 try { 724 mBluetooth.unregisterCallback(mBluetoothCallback); 725 } catch (RemoteException re) { 726 Slog.e(TAG, "Unable to unregister BluetoothCallback",re); 727 } 728 729 if (DBG) Slog.d(TAG, "Sending unbind request."); 730 mBluetoothBinder = null; 731 mBluetooth = null; 732 //Unbind 733 mContext.unbindService(mConnection); 734 mUnbinding = false; 735 mBinding = false; 736 } else { 737 mUnbinding=false; 738 } 739 mBluetoothGatt = null; 740 } finally { 741 mBluetoothLock.writeLock().unlock(); 742 } 743 } 744 745 public IBluetoothGatt getBluetoothGatt() { 746 // sync protection 747 return mBluetoothGatt; 748 } 749 750 @Override 751 public boolean bindBluetoothProfileService(int bluetoothProfile, 752 IBluetoothProfileServiceConnection proxy) { 753 if (!mEnable) { 754 if (DBG) { 755 Slog.d(TAG, "Trying to bind to profile: " + bluetoothProfile + 756 ", while Bluetooth was disabled"); 757 } 758 return false; 759 } 760 synchronized (mProfileServices) { 761 ProfileServiceConnections psc = mProfileServices.get(new Integer(bluetoothProfile)); 762 if (psc == null) { 763 if (DBG) { 764 Slog.d(TAG, "Creating new ProfileServiceConnections object for" 765 + " profile: " + bluetoothProfile); 766 } 767 768 if (bluetoothProfile != BluetoothProfile.HEADSET) return false; 769 770 Intent intent = new Intent(IBluetoothHeadset.class.getName()); 771 psc = new ProfileServiceConnections(intent); 772 if (!psc.bindService()) return false; 773 774 mProfileServices.put(new Integer(bluetoothProfile), psc); 775 } 776 } 777 778 // Introducing a delay to give the client app time to prepare 779 Message addProxyMsg = mHandler.obtainMessage(MESSAGE_ADD_PROXY_DELAYED); 780 addProxyMsg.arg1 = bluetoothProfile; 781 addProxyMsg.obj = proxy; 782 mHandler.sendMessageDelayed(addProxyMsg, ADD_PROXY_DELAY_MS); 783 return true; 784 } 785 786 @Override 787 public void unbindBluetoothProfileService(int bluetoothProfile, 788 IBluetoothProfileServiceConnection proxy) { 789 synchronized (mProfileServices) { 790 ProfileServiceConnections psc = mProfileServices.get(new Integer(bluetoothProfile)); 791 if (psc == null) { 792 return; 793 } 794 psc.removeProxy(proxy); 795 } 796 } 797 798 private void unbindAllBluetoothProfileServices() { 799 synchronized (mProfileServices) { 800 for (Integer i : mProfileServices.keySet()) { 801 ProfileServiceConnections psc = mProfileServices.get(i); 802 try { 803 mContext.unbindService(psc); 804 } catch (IllegalArgumentException e) { 805 Slog.e(TAG, "Unable to unbind service with intent: " + psc.mIntent, e); 806 } 807 psc.removeAllProxies(); 808 } 809 mProfileServices.clear(); 810 } 811 } 812 813 /** 814 * Send enable message and set adapter name and address. Called when the boot phase becomes 815 * PHASE_SYSTEM_SERVICES_READY. 816 */ 817 public void handleOnBootPhase() { 818 if (DBG) Slog.d(TAG, "Bluetooth boot completed"); 819 if (mEnableExternal && isBluetoothPersistedStateOnBluetooth()) { 820 if (DBG) Slog.d(TAG, "Auto-enabling Bluetooth."); 821 sendEnableMsg(mQuietEnableExternal); 822 } else if (!isNameAndAddressSet()) { 823 if (DBG) Slog.d(TAG, "Getting adapter name and address"); 824 Message getMsg = mHandler.obtainMessage(MESSAGE_GET_NAME_AND_ADDRESS); 825 mHandler.sendMessage(getMsg); 826 } 827 } 828 829 /** 830 * Called when switching to a different foreground user. 831 */ 832 public void handleOnSwitchUser(int userHandle) { 833 if (DBG) Slog.d(TAG, "User " + userHandle + " switched"); 834 mHandler.obtainMessage(MESSAGE_USER_SWITCHED, userHandle, 0).sendToTarget(); 835 } 836 837 /** 838 * Called when user is unlocked. 839 */ 840 public void handleOnUnlockUser(int userHandle) { 841 if (DBG) Slog.d(TAG, "User " + userHandle + " unlocked"); 842 mHandler.obtainMessage(MESSAGE_USER_UNLOCKED, userHandle, 0).sendToTarget(); 843 } 844 845 /** 846 * This class manages the clients connected to a given ProfileService 847 * and maintains the connection with that service. 848 */ 849 final private class ProfileServiceConnections implements ServiceConnection, 850 IBinder.DeathRecipient { 851 final RemoteCallbackList<IBluetoothProfileServiceConnection> mProxies = 852 new RemoteCallbackList <IBluetoothProfileServiceConnection>(); 853 IBinder mService; 854 ComponentName mClassName; 855 Intent mIntent; 856 boolean mInvokingProxyCallbacks = false; 857 858 ProfileServiceConnections(Intent intent) { 859 mService = null; 860 mClassName = null; 861 mIntent = intent; 862 } 863 864 private boolean bindService() { 865 if (mIntent != null && mService == null && 866 doBind(mIntent, this, 0, UserHandle.CURRENT_OR_SELF)) { 867 Message msg = mHandler.obtainMessage(MESSAGE_BIND_PROFILE_SERVICE); 868 msg.obj = this; 869 mHandler.sendMessageDelayed(msg, TIMEOUT_BIND_MS); 870 return true; 871 } 872 Slog.w(TAG, "Unable to bind with intent: " + mIntent); 873 return false; 874 } 875 876 private void addProxy(IBluetoothProfileServiceConnection proxy) { 877 mProxies.register(proxy); 878 if (mService != null) { 879 try{ 880 proxy.onServiceConnected(mClassName, mService); 881 } catch (RemoteException e) { 882 Slog.e(TAG, "Unable to connect to proxy", e); 883 } 884 } else { 885 if (!mHandler.hasMessages(MESSAGE_BIND_PROFILE_SERVICE, this)) { 886 Message msg = mHandler.obtainMessage(MESSAGE_BIND_PROFILE_SERVICE); 887 msg.obj = this; 888 mHandler.sendMessage(msg); 889 } 890 } 891 } 892 893 private void removeProxy(IBluetoothProfileServiceConnection proxy) { 894 if (proxy != null) { 895 if (mProxies.unregister(proxy)) { 896 try { 897 proxy.onServiceDisconnected(mClassName); 898 } catch (RemoteException e) { 899 Slog.e(TAG, "Unable to disconnect proxy", e); 900 } 901 } 902 } else { 903 Slog.w(TAG, "Trying to remove a null proxy"); 904 } 905 } 906 907 private void removeAllProxies() { 908 onServiceDisconnected(mClassName); 909 mProxies.kill(); 910 } 911 912 @Override 913 public void onServiceConnected(ComponentName className, IBinder service) { 914 // remove timeout message 915 mHandler.removeMessages(MESSAGE_BIND_PROFILE_SERVICE, this); 916 mService = service; 917 mClassName = className; 918 try { 919 mService.linkToDeath(this, 0); 920 } catch (RemoteException e) { 921 Slog.e(TAG, "Unable to linkToDeath", e); 922 } 923 924 if (mInvokingProxyCallbacks) { 925 Slog.e(TAG, "Proxy callbacks already in progress."); 926 return; 927 } 928 mInvokingProxyCallbacks = true; 929 930 final int n = mProxies.beginBroadcast(); 931 try { 932 for (int i = 0; i < n; i++) { 933 try { 934 mProxies.getBroadcastItem(i).onServiceConnected(className, service); 935 } catch (RemoteException e) { 936 Slog.e(TAG, "Unable to connect to proxy", e); 937 } 938 } 939 } finally { 940 mProxies.finishBroadcast(); 941 mInvokingProxyCallbacks = false; 942 } 943 } 944 945 @Override 946 public void onServiceDisconnected(ComponentName className) { 947 if (mService == null) return; 948 mService.unlinkToDeath(this, 0); 949 mService = null; 950 mClassName = null; 951 952 if (mInvokingProxyCallbacks) { 953 Slog.e(TAG, "Proxy callbacks already in progress."); 954 return; 955 } 956 mInvokingProxyCallbacks = true; 957 958 final int n = mProxies.beginBroadcast(); 959 try { 960 for (int i = 0; i < n; i++) { 961 try { 962 mProxies.getBroadcastItem(i).onServiceDisconnected(className); 963 } catch (RemoteException e) { 964 Slog.e(TAG, "Unable to disconnect from proxy", e); 965 } 966 } 967 } finally { 968 mProxies.finishBroadcast(); 969 mInvokingProxyCallbacks = false; 970 } 971 } 972 973 @Override 974 public void binderDied() { 975 if (DBG) { 976 Slog.w(TAG, "Profile service for profile: " + mClassName 977 + " died."); 978 } 979 onServiceDisconnected(mClassName); 980 // Trigger rebind 981 Message msg = mHandler.obtainMessage(MESSAGE_BIND_PROFILE_SERVICE); 982 msg.obj = this; 983 mHandler.sendMessageDelayed(msg, TIMEOUT_BIND_MS); 984 } 985 } 986 987 private void sendBluetoothStateCallback(boolean isUp) { 988 try { 989 int n = mStateChangeCallbacks.beginBroadcast(); 990 if (DBG) Slog.d(TAG,"Broadcasting onBluetoothStateChange("+isUp+") to " + n + " receivers."); 991 for (int i=0; i <n;i++) { 992 try { 993 mStateChangeCallbacks.getBroadcastItem(i).onBluetoothStateChange(isUp); 994 } catch (RemoteException e) { 995 Slog.e(TAG, "Unable to call onBluetoothStateChange() on callback #" + i , e); 996 } 997 } 998 } finally { 999 mStateChangeCallbacks.finishBroadcast(); 1000 } 1001 } 1002 1003 /** 1004 * Inform BluetoothAdapter instances that Adapter service is up 1005 */ 1006 private void sendBluetoothServiceUpCallback() { 1007 if (DBG) Slog.d(TAG,"Calling onBluetoothServiceUp callbacks"); 1008 try { 1009 int n = mCallbacks.beginBroadcast(); 1010 Slog.d(TAG,"Broadcasting onBluetoothServiceUp() to " + n + " receivers."); 1011 for (int i=0; i <n;i++) { 1012 try { 1013 mCallbacks.getBroadcastItem(i).onBluetoothServiceUp(mBluetooth); 1014 } catch (RemoteException e) { 1015 Slog.e(TAG, "Unable to call onBluetoothServiceUp() on callback #" + i, e); 1016 } 1017 } 1018 } finally { 1019 mCallbacks.finishBroadcast(); 1020 } 1021 } 1022 /** 1023 * Inform BluetoothAdapter instances that Adapter service is down 1024 */ 1025 private void sendBluetoothServiceDownCallback() { 1026 if (DBG) Slog.d(TAG,"Calling onBluetoothServiceDown callbacks"); 1027 try { 1028 int n = mCallbacks.beginBroadcast(); 1029 Slog.d(TAG,"Broadcasting onBluetoothServiceDown() to " + n + " receivers."); 1030 for (int i=0; i <n;i++) { 1031 try { 1032 mCallbacks.getBroadcastItem(i).onBluetoothServiceDown(); 1033 } catch (RemoteException e) { 1034 Slog.e(TAG, "Unable to call onBluetoothServiceDown() on callback #" + i, e); 1035 } 1036 } 1037 } finally { 1038 mCallbacks.finishBroadcast(); 1039 } 1040 } 1041 1042 public String getAddress() { 1043 mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, 1044 "Need BLUETOOTH permission"); 1045 1046 if ((Binder.getCallingUid() != Process.SYSTEM_UID) && 1047 (!checkIfCallerIsForegroundUser())) { 1048 Slog.w(TAG,"getAddress(): not allowed for non-active and non system user"); 1049 return null; 1050 } 1051 1052 if (mContext.checkCallingOrSelfPermission(Manifest.permission.LOCAL_MAC_ADDRESS) 1053 != PackageManager.PERMISSION_GRANTED) { 1054 return BluetoothAdapter.DEFAULT_MAC_ADDRESS; 1055 } 1056 1057 try { 1058 mBluetoothLock.readLock().lock(); 1059 if (mBluetooth != null) return mBluetooth.getAddress(); 1060 } catch (RemoteException e) { 1061 Slog.e(TAG, "getAddress(): Unable to retrieve address remotely. Returning cached address", e); 1062 } finally { 1063 mBluetoothLock.readLock().unlock(); 1064 } 1065 1066 // mAddress is accessed from outside. 1067 // It is alright without a lock. Here, bluetooth is off, no other thread is 1068 // changing mAddress 1069 return mAddress; 1070 } 1071 1072 public String getName() { 1073 mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, 1074 "Need BLUETOOTH permission"); 1075 1076 if ((Binder.getCallingUid() != Process.SYSTEM_UID) && 1077 (!checkIfCallerIsForegroundUser())) { 1078 Slog.w(TAG,"getName(): not allowed for non-active and non system user"); 1079 return null; 1080 } 1081 1082 try { 1083 mBluetoothLock.readLock().lock(); 1084 if (mBluetooth != null) return mBluetooth.getName(); 1085 } catch (RemoteException e) { 1086 Slog.e(TAG, "getName(): Unable to retrieve name remotely. Returning cached name", e); 1087 } finally { 1088 mBluetoothLock.readLock().unlock(); 1089 } 1090 1091 // mName is accessed from outside. 1092 // It alright without a lock. Here, bluetooth is off, no other thread is 1093 // changing mName 1094 return mName; 1095 } 1096 1097 private class BluetoothServiceConnection implements ServiceConnection { 1098 public void onServiceConnected(ComponentName className, IBinder service) { 1099 if (DBG) Slog.d(TAG, "BluetoothServiceConnection: " + className.getClassName()); 1100 Message msg = mHandler.obtainMessage(MESSAGE_BLUETOOTH_SERVICE_CONNECTED); 1101 // TBD if (className.getClassName().equals(IBluetooth.class.getName())) { 1102 if (className.getClassName().equals("com.android.bluetooth.btservice.AdapterService")) { 1103 msg.arg1 = SERVICE_IBLUETOOTH; 1104 // } else if (className.getClassName().equals(IBluetoothGatt.class.getName())) { 1105 } else if (className.getClassName().equals("com.android.bluetooth.gatt.GattService")) { 1106 msg.arg1 = SERVICE_IBLUETOOTHGATT; 1107 } else { 1108 Slog.e(TAG, "Unknown service connected: " + className.getClassName()); 1109 return; 1110 } 1111 msg.obj = service; 1112 mHandler.sendMessage(msg); 1113 } 1114 1115 public void onServiceDisconnected(ComponentName className) { 1116 // Called if we unexpected disconnected. 1117 if (DBG) Slog.d(TAG, "BluetoothServiceConnection, disconnected: " + 1118 className.getClassName()); 1119 Message msg = mHandler.obtainMessage(MESSAGE_BLUETOOTH_SERVICE_DISCONNECTED); 1120 if (className.getClassName().equals("com.android.bluetooth.btservice.AdapterService")) { 1121 msg.arg1 = SERVICE_IBLUETOOTH; 1122 } else if (className.getClassName().equals("com.android.bluetooth.gatt.GattService")) { 1123 msg.arg1 = SERVICE_IBLUETOOTHGATT; 1124 } else { 1125 Slog.e(TAG, "Unknown service disconnected: " + className.getClassName()); 1126 return; 1127 } 1128 mHandler.sendMessage(msg); 1129 } 1130 } 1131 1132 private BluetoothServiceConnection mConnection = new BluetoothServiceConnection(); 1133 1134 private class BluetoothHandler extends Handler { 1135 boolean mGetNameAddressOnly = false; 1136 1137 public BluetoothHandler(Looper looper) { 1138 super(looper); 1139 } 1140 1141 @Override 1142 public void handleMessage(Message msg) { 1143 if (DBG) Slog.d (TAG, "Message: " + msg.what); 1144 switch (msg.what) { 1145 case MESSAGE_GET_NAME_AND_ADDRESS: 1146 if (DBG) Slog.d(TAG, "MESSAGE_GET_NAME_AND_ADDRESS"); 1147 try { 1148 mBluetoothLock.writeLock().lock(); 1149 if ((mBluetooth == null) && (!mBinding)) { 1150 if (DBG) Slog.d(TAG, "Binding to service to get name and address"); 1151 mGetNameAddressOnly = true; 1152 Message timeoutMsg = mHandler.obtainMessage(MESSAGE_TIMEOUT_BIND); 1153 mHandler.sendMessageDelayed(timeoutMsg, TIMEOUT_BIND_MS); 1154 Intent i = new Intent(IBluetooth.class.getName()); 1155 if (!doBind(i, mConnection, 1156 Context.BIND_AUTO_CREATE | Context.BIND_IMPORTANT, 1157 UserHandle.CURRENT)) { 1158 mHandler.removeMessages(MESSAGE_TIMEOUT_BIND); 1159 } else { 1160 mBinding = true; 1161 } 1162 } else if (mBluetooth != null) { 1163 try { 1164 storeNameAndAddress(mBluetooth.getName(), 1165 mBluetooth.getAddress()); 1166 } catch (RemoteException re) { 1167 Slog.e(TAG, "Unable to grab names", re); 1168 } 1169 if (mGetNameAddressOnly && !mEnable) { 1170 unbindAndFinish(); 1171 } 1172 mGetNameAddressOnly = false; 1173 } 1174 } finally { 1175 mBluetoothLock.writeLock().unlock(); 1176 } 1177 break; 1178 1179 case MESSAGE_ENABLE: 1180 if (DBG) { 1181 Slog.d(TAG, "MESSAGE_ENABLE: mBluetooth = " + mBluetooth); 1182 } 1183 mHandler.removeMessages(MESSAGE_RESTART_BLUETOOTH_SERVICE); 1184 mEnable = true; 1185 1186 // Use service interface to get the exact state 1187 try { 1188 mBluetoothLock.readLock().lock(); 1189 if (mBluetooth != null) { 1190 int state = mBluetooth.getState(); 1191 if (state == BluetoothAdapter.STATE_BLE_ON) { 1192 Slog.w(TAG, "BT is in BLE_ON State"); 1193 mBluetooth.onLeServiceUp(); 1194 break; 1195 } 1196 } 1197 } catch (RemoteException e) { 1198 Slog.e(TAG, "", e); 1199 } finally { 1200 mBluetoothLock.readLock().unlock(); 1201 } 1202 1203 mQuietEnable = (msg.arg1 == 1); 1204 if (mBluetooth == null) { 1205 handleEnable(mQuietEnable); 1206 } else { 1207 // 1208 // We need to wait until transitioned to STATE_OFF and 1209 // the previous Bluetooth process has exited. The 1210 // waiting period has three components: 1211 // (a) Wait until the local state is STATE_OFF. This 1212 // is accomplished by "waitForOnOff(false, true)". 1213 // (b) Wait until the STATE_OFF state is updated to 1214 // all components. 1215 // (c) Wait until the Bluetooth process exits, and 1216 // ActivityManager detects it. 1217 // The waiting for (b) and (c) is accomplished by 1218 // delaying the MESSAGE_RESTART_BLUETOOTH_SERVICE 1219 // message. On slower devices, that delay needs to be 1220 // on the order of (2 * SERVICE_RESTART_TIME_MS). 1221 // 1222 waitForOnOff(false, true); 1223 Message restartMsg = mHandler.obtainMessage( 1224 MESSAGE_RESTART_BLUETOOTH_SERVICE); 1225 mHandler.sendMessageDelayed(restartMsg, 1226 2 * SERVICE_RESTART_TIME_MS); 1227 } 1228 break; 1229 1230 case MESSAGE_DISABLE: 1231 mHandler.removeMessages(MESSAGE_RESTART_BLUETOOTH_SERVICE); 1232 if (mEnable && mBluetooth != null) { 1233 waitForOnOff(true, false); 1234 mEnable = false; 1235 handleDisable(); 1236 waitForOnOff(false, false); 1237 } else { 1238 mEnable = false; 1239 handleDisable(); 1240 } 1241 break; 1242 1243 case MESSAGE_REGISTER_ADAPTER: 1244 { 1245 IBluetoothManagerCallback callback = (IBluetoothManagerCallback) msg.obj; 1246 boolean added = mCallbacks.register(callback); 1247 Slog.d(TAG,"Added callback: " + (callback == null? "null": callback) +":" +added ); 1248 } 1249 break; 1250 case MESSAGE_UNREGISTER_ADAPTER: 1251 { 1252 IBluetoothManagerCallback callback = (IBluetoothManagerCallback) msg.obj; 1253 boolean removed = mCallbacks.unregister(callback); 1254 Slog.d(TAG,"Removed callback: " + (callback == null? "null": callback) +":" + removed); 1255 break; 1256 } 1257 case MESSAGE_REGISTER_STATE_CHANGE_CALLBACK: 1258 { 1259 IBluetoothStateChangeCallback callback = (IBluetoothStateChangeCallback) msg.obj; 1260 if (callback != null) { 1261 mStateChangeCallbacks.register(callback); 1262 } 1263 break; 1264 } 1265 case MESSAGE_UNREGISTER_STATE_CHANGE_CALLBACK: 1266 { 1267 IBluetoothStateChangeCallback callback = (IBluetoothStateChangeCallback) msg.obj; 1268 if (callback != null) { 1269 mStateChangeCallbacks.unregister(callback); 1270 } 1271 break; 1272 } 1273 case MESSAGE_ADD_PROXY_DELAYED: 1274 { 1275 ProfileServiceConnections psc = mProfileServices.get( 1276 new Integer(msg.arg1)); 1277 if (psc == null) { 1278 break; 1279 } 1280 IBluetoothProfileServiceConnection proxy = 1281 (IBluetoothProfileServiceConnection) msg.obj; 1282 psc.addProxy(proxy); 1283 break; 1284 } 1285 case MESSAGE_BIND_PROFILE_SERVICE: 1286 { 1287 ProfileServiceConnections psc = (ProfileServiceConnections) msg.obj; 1288 removeMessages(MESSAGE_BIND_PROFILE_SERVICE, msg.obj); 1289 if (psc == null) { 1290 break; 1291 } 1292 psc.bindService(); 1293 break; 1294 } 1295 case MESSAGE_BLUETOOTH_SERVICE_CONNECTED: 1296 { 1297 if (DBG) Slog.d(TAG,"MESSAGE_BLUETOOTH_SERVICE_CONNECTED: " + msg.arg1); 1298 1299 IBinder service = (IBinder) msg.obj; 1300 try { 1301 mBluetoothLock.writeLock().lock(); 1302 if (msg.arg1 == SERVICE_IBLUETOOTHGATT) { 1303 mBluetoothGatt = IBluetoothGatt.Stub.asInterface(service); 1304 onBluetoothGattServiceUp(); 1305 break; 1306 } // else must be SERVICE_IBLUETOOTH 1307 1308 //Remove timeout 1309 mHandler.removeMessages(MESSAGE_TIMEOUT_BIND); 1310 1311 mBinding = false; 1312 mBluetoothBinder = service; 1313 mBluetooth = IBluetooth.Stub.asInterface(service); 1314 1315 if (!isNameAndAddressSet()) { 1316 Message getMsg = mHandler.obtainMessage(MESSAGE_GET_NAME_AND_ADDRESS); 1317 mHandler.sendMessage(getMsg); 1318 if (mGetNameAddressOnly) return; 1319 } 1320 1321 try { 1322 boolean enableHciSnoopLog = (Settings.Secure.getInt(mContentResolver, 1323 Settings.Secure.BLUETOOTH_HCI_LOG, 0) == 1); 1324 if (!mBluetooth.configHciSnoopLog(enableHciSnoopLog)) { 1325 Slog.e(TAG,"IBluetooth.configHciSnoopLog return false"); 1326 } 1327 } catch (RemoteException e) { 1328 Slog.e(TAG,"Unable to call configHciSnoopLog", e); 1329 } 1330 1331 //Register callback object 1332 try { 1333 mBluetooth.registerCallback(mBluetoothCallback); 1334 } catch (RemoteException re) { 1335 Slog.e(TAG, "Unable to register BluetoothCallback",re); 1336 } 1337 //Inform BluetoothAdapter instances that service is up 1338 sendBluetoothServiceUpCallback(); 1339 1340 //Do enable request 1341 try { 1342 if (mQuietEnable == false) { 1343 if(!mBluetooth.enable()) { 1344 Slog.e(TAG,"IBluetooth.enable() returned false"); 1345 } 1346 } 1347 else 1348 { 1349 if(!mBluetooth.enableNoAutoConnect()) { 1350 Slog.e(TAG,"IBluetooth.enableNoAutoConnect() returned false"); 1351 } 1352 } 1353 } catch (RemoteException e) { 1354 Slog.e(TAG,"Unable to call enable()",e); 1355 } 1356 } finally { 1357 mBluetoothLock.writeLock().unlock(); 1358 } 1359 1360 if (!mEnable) { 1361 waitForOnOff(true, false); 1362 handleDisable(); 1363 waitForOnOff(false, false); 1364 } 1365 break; 1366 } 1367 case MESSAGE_TIMEOUT_BIND: { 1368 Slog.e(TAG, "MESSAGE_TIMEOUT_BIND"); 1369 mBluetoothLock.writeLock().lock(); 1370 mBinding = false; 1371 mBluetoothLock.writeLock().unlock(); 1372 1373 break; 1374 } 1375 case MESSAGE_BLUETOOTH_STATE_CHANGE: 1376 { 1377 int prevState = msg.arg1; 1378 int newState = msg.arg2; 1379 if (DBG) Slog.d(TAG, "MESSAGE_BLUETOOTH_STATE_CHANGE: prevState = " + prevState + ", newState =" + newState); 1380 mState = newState; 1381 bluetoothStateChangeHandler(prevState, newState); 1382 // handle error state transition case from TURNING_ON to OFF 1383 // unbind and rebind bluetooth service and enable bluetooth 1384 if ((prevState == BluetoothAdapter.STATE_BLE_TURNING_ON) && 1385 (newState == BluetoothAdapter.STATE_OFF) && 1386 (mBluetooth != null) && mEnable) { 1387 recoverBluetoothServiceFromError(); 1388 } 1389 if ((prevState == BluetoothAdapter.STATE_TURNING_ON) && 1390 (newState == BluetoothAdapter.STATE_BLE_ON) && 1391 (mBluetooth != null) && mEnable) { 1392 recoverBluetoothServiceFromError(); 1393 } 1394 // If we tried to enable BT while BT was in the process of shutting down, 1395 // wait for the BT process to fully tear down and then force a restart 1396 // here. This is a bit of a hack (b/29363429). 1397 if ((prevState == BluetoothAdapter.STATE_BLE_TURNING_OFF) && 1398 (newState == BluetoothAdapter.STATE_OFF)) { 1399 if (mEnable) { 1400 Slog.d(TAG, "Entering STATE_OFF but mEnabled is true; restarting."); 1401 waitForOnOff(false, true); 1402 Message restartMsg = mHandler.obtainMessage( 1403 MESSAGE_RESTART_BLUETOOTH_SERVICE); 1404 mHandler.sendMessageDelayed(restartMsg, 2 * SERVICE_RESTART_TIME_MS); 1405 } 1406 } 1407 if (newState == BluetoothAdapter.STATE_ON || 1408 newState == BluetoothAdapter.STATE_BLE_ON) { 1409 // bluetooth is working, reset the counter 1410 if (mErrorRecoveryRetryCounter != 0) { 1411 Slog.w(TAG, "bluetooth is recovered from error"); 1412 mErrorRecoveryRetryCounter = 0; 1413 } 1414 } 1415 break; 1416 } 1417 case MESSAGE_BLUETOOTH_SERVICE_DISCONNECTED: 1418 { 1419 Slog.e(TAG, "MESSAGE_BLUETOOTH_SERVICE_DISCONNECTED: " + msg.arg1); 1420 try { 1421 mBluetoothLock.writeLock().lock(); 1422 if (msg.arg1 == SERVICE_IBLUETOOTH) { 1423 // if service is unbinded already, do nothing and return 1424 if (mBluetooth == null) break; 1425 mBluetooth = null; 1426 } else if (msg.arg1 == SERVICE_IBLUETOOTHGATT) { 1427 mBluetoothGatt = null; 1428 break; 1429 } else { 1430 Slog.e(TAG, "Bad msg.arg1: " + msg.arg1); 1431 break; 1432 } 1433 } finally { 1434 mBluetoothLock.writeLock().unlock(); 1435 } 1436 1437 if (mEnable) { 1438 mEnable = false; 1439 // Send a Bluetooth Restart message 1440 Message restartMsg = mHandler.obtainMessage( 1441 MESSAGE_RESTART_BLUETOOTH_SERVICE); 1442 mHandler.sendMessageDelayed(restartMsg, 1443 SERVICE_RESTART_TIME_MS); 1444 } 1445 1446 sendBluetoothServiceDownCallback(); 1447 1448 // Send BT state broadcast to update 1449 // the BT icon correctly 1450 if ((mState == BluetoothAdapter.STATE_TURNING_ON) || 1451 (mState == BluetoothAdapter.STATE_ON)) { 1452 bluetoothStateChangeHandler(BluetoothAdapter.STATE_ON, 1453 BluetoothAdapter.STATE_TURNING_OFF); 1454 mState = BluetoothAdapter.STATE_TURNING_OFF; 1455 } 1456 if (mState == BluetoothAdapter.STATE_TURNING_OFF) { 1457 bluetoothStateChangeHandler(BluetoothAdapter.STATE_TURNING_OFF, 1458 BluetoothAdapter.STATE_OFF); 1459 } 1460 1461 mHandler.removeMessages(MESSAGE_BLUETOOTH_STATE_CHANGE); 1462 mState = BluetoothAdapter.STATE_OFF; 1463 break; 1464 } 1465 case MESSAGE_RESTART_BLUETOOTH_SERVICE: 1466 { 1467 Slog.d(TAG, "MESSAGE_RESTART_BLUETOOTH_SERVICE:" 1468 +" Restart IBluetooth service"); 1469 /* Enable without persisting the setting as 1470 it doesnt change when IBluetooth 1471 service restarts */ 1472 mEnable = true; 1473 handleEnable(mQuietEnable); 1474 break; 1475 } 1476 1477 case MESSAGE_TIMEOUT_UNBIND: 1478 { 1479 Slog.e(TAG, "MESSAGE_TIMEOUT_UNBIND"); 1480 mBluetoothLock.writeLock().lock(); 1481 mUnbinding = false; 1482 mBluetoothLock.writeLock().unlock(); 1483 break; 1484 } 1485 1486 case MESSAGE_USER_SWITCHED: { 1487 if (DBG) Slog.d(TAG, "MESSAGE_USER_SWITCHED"); 1488 mHandler.removeMessages(MESSAGE_USER_SWITCHED); 1489 1490 /* disable and enable BT when detect a user switch */ 1491 if (mEnable && mBluetooth != null) { 1492 try { 1493 mBluetoothLock.readLock().lock(); 1494 if (mBluetooth != null) { 1495 mBluetooth.unregisterCallback(mBluetoothCallback); 1496 } 1497 } catch (RemoteException re) { 1498 Slog.e(TAG, "Unable to unregister", re); 1499 } finally { 1500 mBluetoothLock.readLock().unlock(); 1501 } 1502 1503 if (mState == BluetoothAdapter.STATE_TURNING_OFF) { 1504 // MESSAGE_USER_SWITCHED happened right after MESSAGE_ENABLE 1505 bluetoothStateChangeHandler(mState, BluetoothAdapter.STATE_OFF); 1506 mState = BluetoothAdapter.STATE_OFF; 1507 } 1508 if (mState == BluetoothAdapter.STATE_OFF) { 1509 bluetoothStateChangeHandler(mState, BluetoothAdapter.STATE_TURNING_ON); 1510 mState = BluetoothAdapter.STATE_TURNING_ON; 1511 } 1512 1513 waitForOnOff(true, false); 1514 1515 if (mState == BluetoothAdapter.STATE_TURNING_ON) { 1516 bluetoothStateChangeHandler(mState, BluetoothAdapter.STATE_ON); 1517 } 1518 1519 unbindAllBluetoothProfileServices(); 1520 // disable 1521 handleDisable(); 1522 // Pbap service need receive STATE_TURNING_OFF intent to close 1523 bluetoothStateChangeHandler(BluetoothAdapter.STATE_ON, 1524 BluetoothAdapter.STATE_TURNING_OFF); 1525 1526 boolean didDisableTimeout = !waitForOnOff(false, true); 1527 1528 bluetoothStateChangeHandler(BluetoothAdapter.STATE_TURNING_OFF, 1529 BluetoothAdapter.STATE_OFF); 1530 sendBluetoothServiceDownCallback(); 1531 1532 try { 1533 mBluetoothLock.writeLock().lock(); 1534 if (mBluetooth != null) { 1535 mBluetooth = null; 1536 // Unbind 1537 mContext.unbindService(mConnection); 1538 } 1539 mBluetoothGatt = null; 1540 } finally { 1541 mBluetoothLock.writeLock().unlock(); 1542 } 1543 1544 // 1545 // If disabling Bluetooth times out, wait for an 1546 // additional amount of time to ensure the process is 1547 // shut down completely before attempting to restart. 1548 // 1549 if (didDisableTimeout) { 1550 SystemClock.sleep(3000); 1551 } else { 1552 SystemClock.sleep(100); 1553 } 1554 1555 mHandler.removeMessages(MESSAGE_BLUETOOTH_STATE_CHANGE); 1556 mState = BluetoothAdapter.STATE_OFF; 1557 // enable 1558 handleEnable(mQuietEnable); 1559 } else if (mBinding || mBluetooth != null) { 1560 Message userMsg = mHandler.obtainMessage(MESSAGE_USER_SWITCHED); 1561 userMsg.arg2 = 1 + msg.arg2; 1562 // if user is switched when service is being binding 1563 // delay sending MESSAGE_USER_SWITCHED 1564 mHandler.sendMessageDelayed(userMsg, USER_SWITCHED_TIME_MS); 1565 if (DBG) { 1566 Slog.d(TAG, "delay MESSAGE_USER_SWITCHED " + userMsg.arg2); 1567 } 1568 } 1569 break; 1570 } 1571 case MESSAGE_USER_UNLOCKED: { 1572 if (DBG) Slog.d(TAG, "MESSAGE_USER_UNLOCKED"); 1573 mHandler.removeMessages(MESSAGE_USER_SWITCHED); 1574 1575 if (mEnable && !mBinding && (mBluetooth == null)) { 1576 // We should be connected, but we gave up for some 1577 // reason; maybe the Bluetooth service wasn't encryption 1578 // aware, so try binding again. 1579 if (DBG) Slog.d(TAG, "Enabled but not bound; retrying after unlock"); 1580 handleEnable(mQuietEnable); 1581 } 1582 } 1583 } 1584 } 1585 } 1586 1587 private void handleEnable(boolean quietMode) { 1588 mQuietEnable = quietMode; 1589 1590 try { 1591 mBluetoothLock.writeLock().lock(); 1592 if ((mBluetooth == null) && (!mBinding)) { 1593 //Start bind timeout and bind 1594 Message timeoutMsg=mHandler.obtainMessage(MESSAGE_TIMEOUT_BIND); 1595 mHandler.sendMessageDelayed(timeoutMsg,TIMEOUT_BIND_MS); 1596 Intent i = new Intent(IBluetooth.class.getName()); 1597 if (!doBind(i, mConnection,Context.BIND_AUTO_CREATE | Context.BIND_IMPORTANT, 1598 UserHandle.CURRENT)) { 1599 mHandler.removeMessages(MESSAGE_TIMEOUT_BIND); 1600 } else { 1601 mBinding = true; 1602 } 1603 } else if (mBluetooth != null) { 1604 //Enable bluetooth 1605 try { 1606 if (!mQuietEnable) { 1607 if(!mBluetooth.enable()) { 1608 Slog.e(TAG,"IBluetooth.enable() returned false"); 1609 } 1610 } 1611 else { 1612 if(!mBluetooth.enableNoAutoConnect()) { 1613 Slog.e(TAG,"IBluetooth.enableNoAutoConnect() returned false"); 1614 } 1615 } 1616 } catch (RemoteException e) { 1617 Slog.e(TAG,"Unable to call enable()",e); 1618 } 1619 } 1620 } finally { 1621 mBluetoothLock.writeLock().unlock(); 1622 } 1623 } 1624 1625 boolean doBind(Intent intent, ServiceConnection conn, int flags, UserHandle user) { 1626 ComponentName comp = intent.resolveSystemService(mContext.getPackageManager(), 0); 1627 intent.setComponent(comp); 1628 if (comp == null || !mContext.bindServiceAsUser(intent, conn, flags, user)) { 1629 Slog.e(TAG, "Fail to bind to: " + intent); 1630 return false; 1631 } 1632 return true; 1633 } 1634 1635 private void handleDisable() { 1636 try { 1637 mBluetoothLock.readLock().lock(); 1638 if (mBluetooth != null) { 1639 if (DBG) Slog.d(TAG,"Sending off request."); 1640 if (!mBluetooth.disable()) { 1641 Slog.e(TAG,"IBluetooth.disable() returned false"); 1642 } 1643 } 1644 } catch (RemoteException e) { 1645 Slog.e(TAG,"Unable to call disable()",e); 1646 } finally { 1647 mBluetoothLock.readLock().unlock(); 1648 } 1649 } 1650 1651 private boolean checkIfCallerIsForegroundUser() { 1652 int foregroundUser; 1653 int callingUser = UserHandle.getCallingUserId(); 1654 int callingUid = Binder.getCallingUid(); 1655 long callingIdentity = Binder.clearCallingIdentity(); 1656 UserManager um = (UserManager) mContext.getSystemService(Context.USER_SERVICE); 1657 UserInfo ui = um.getProfileParent(callingUser); 1658 int parentUser = (ui != null) ? ui.id : UserHandle.USER_NULL; 1659 int callingAppId = UserHandle.getAppId(callingUid); 1660 boolean valid = false; 1661 try { 1662 foregroundUser = ActivityManager.getCurrentUser(); 1663 valid = (callingUser == foregroundUser) || 1664 parentUser == foregroundUser || 1665 callingAppId == Process.NFC_UID || 1666 callingAppId == mSystemUiUid; 1667 if (DBG) { 1668 Slog.d(TAG, "checkIfCallerIsForegroundUser: valid=" + valid 1669 + " callingUser=" + callingUser 1670 + " parentUser=" + parentUser 1671 + " foregroundUser=" + foregroundUser); 1672 } 1673 } finally { 1674 Binder.restoreCallingIdentity(callingIdentity); 1675 } 1676 return valid; 1677 } 1678 1679 private void sendBleStateChanged(int prevState, int newState) { 1680 if (DBG) Slog.d(TAG,"BLE State Change Intent: " + prevState + " -> " + newState); 1681 // Send broadcast message to everyone else 1682 Intent intent = new Intent(BluetoothAdapter.ACTION_BLE_STATE_CHANGED); 1683 intent.putExtra(BluetoothAdapter.EXTRA_PREVIOUS_STATE, prevState); 1684 intent.putExtra(BluetoothAdapter.EXTRA_STATE, newState); 1685 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); 1686 mContext.sendBroadcastAsUser(intent, UserHandle.ALL, BLUETOOTH_PERM); 1687 } 1688 1689 private void bluetoothStateChangeHandler(int prevState, int newState) { 1690 boolean isStandardBroadcast = true; 1691 if (DBG) Slog.d(TAG, "bluetoothStateChangeHandler: " + prevState + " -> " + newState); 1692 if (prevState != newState) { 1693 //Notify all proxy objects first of adapter state change 1694 if (newState == BluetoothAdapter.STATE_BLE_ON || 1695 newState == BluetoothAdapter.STATE_OFF) { 1696 boolean intermediate_off = (prevState == BluetoothAdapter.STATE_TURNING_OFF 1697 && newState == BluetoothAdapter.STATE_BLE_ON); 1698 1699 if (newState == BluetoothAdapter.STATE_OFF) { 1700 // If Bluetooth is off, send service down event to proxy objects, and unbind 1701 if (DBG) Slog.d(TAG, "Bluetooth is complete turn off"); 1702 sendBluetoothServiceDownCallback(); 1703 unbindAndFinish(); 1704 sendBleStateChanged(prevState, newState); 1705 // Don't broadcast as it has already been broadcast before 1706 isStandardBroadcast = false; 1707 1708 } else if (!intermediate_off) { 1709 // connect to GattService 1710 if (DBG) Slog.d(TAG, "Bluetooth is in LE only mode"); 1711 if (mBluetoothGatt != null) { 1712 if (DBG) Slog.d(TAG, "Calling BluetoothGattServiceUp"); 1713 onBluetoothGattServiceUp(); 1714 } else { 1715 if (DBG) Slog.d(TAG, "Binding Bluetooth GATT service"); 1716 if (mContext.getPackageManager().hasSystemFeature( 1717 PackageManager.FEATURE_BLUETOOTH_LE)) { 1718 Intent i = new Intent(IBluetoothGatt.class.getName()); 1719 doBind(i, mConnection, Context.BIND_AUTO_CREATE | Context.BIND_IMPORTANT, UserHandle.CURRENT); 1720 } 1721 } 1722 sendBleStateChanged(prevState, newState); 1723 //Don't broadcase this as std intent 1724 isStandardBroadcast = false; 1725 1726 } else if (intermediate_off){ 1727 if (DBG) Slog.d(TAG, "Intermediate off, back to LE only mode"); 1728 // For LE only mode, broadcast as is 1729 sendBleStateChanged(prevState, newState); 1730 sendBluetoothStateCallback(false); // BT is OFF for general users 1731 // Broadcast as STATE_OFF 1732 newState = BluetoothAdapter.STATE_OFF; 1733 sendBrEdrDownCallback(); 1734 } 1735 } else if (newState == BluetoothAdapter.STATE_ON) { 1736 boolean isUp = (newState==BluetoothAdapter.STATE_ON); 1737 sendBluetoothStateCallback(isUp); 1738 sendBleStateChanged(prevState, newState); 1739 1740 } else if (newState == BluetoothAdapter.STATE_BLE_TURNING_ON || 1741 newState == BluetoothAdapter.STATE_BLE_TURNING_OFF ) { 1742 sendBleStateChanged(prevState, newState); 1743 isStandardBroadcast = false; 1744 1745 } else if (newState == BluetoothAdapter.STATE_TURNING_ON || 1746 newState == BluetoothAdapter.STATE_TURNING_OFF) { 1747 sendBleStateChanged(prevState, newState); 1748 } 1749 1750 if (isStandardBroadcast) { 1751 if (prevState == BluetoothAdapter.STATE_BLE_ON) { 1752 // Show prevState of BLE_ON as OFF to standard users 1753 prevState = BluetoothAdapter.STATE_OFF; 1754 } 1755 Intent intent = new Intent(BluetoothAdapter.ACTION_STATE_CHANGED); 1756 intent.putExtra(BluetoothAdapter.EXTRA_PREVIOUS_STATE, prevState); 1757 intent.putExtra(BluetoothAdapter.EXTRA_STATE, newState); 1758 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); 1759 mContext.sendBroadcastAsUser(intent, UserHandle.ALL, BLUETOOTH_PERM); 1760 } 1761 } 1762 } 1763 1764 /** 1765 * if on is true, wait for state become ON 1766 * if off is true, wait for state become OFF 1767 * if both on and off are false, wait for state not ON 1768 */ 1769 private boolean waitForOnOff(boolean on, boolean off) { 1770 int i = 0; 1771 while (i < 10) { 1772 try { 1773 mBluetoothLock.readLock().lock(); 1774 if (mBluetooth == null) break; 1775 if (on) { 1776 if (mBluetooth.getState() == BluetoothAdapter.STATE_ON) return true; 1777 } else if (off) { 1778 if (mBluetooth.getState() == BluetoothAdapter.STATE_OFF) return true; 1779 } else { 1780 if (mBluetooth.getState() != BluetoothAdapter.STATE_ON) return true; 1781 } 1782 } catch (RemoteException e) { 1783 Slog.e(TAG, "getState()", e); 1784 break; 1785 } finally { 1786 mBluetoothLock.readLock().unlock(); 1787 } 1788 if (on || off) { 1789 SystemClock.sleep(300); 1790 } else { 1791 SystemClock.sleep(50); 1792 } 1793 i++; 1794 } 1795 Slog.e(TAG,"waitForOnOff time out"); 1796 return false; 1797 } 1798 1799 private void sendDisableMsg() { 1800 mHandler.sendMessage(mHandler.obtainMessage(MESSAGE_DISABLE)); 1801 } 1802 1803 private void sendEnableMsg(boolean quietMode) { 1804 mHandler.sendMessage(mHandler.obtainMessage(MESSAGE_ENABLE, 1805 quietMode ? 1 : 0, 0)); 1806 } 1807 1808 private void recoverBluetoothServiceFromError() { 1809 Slog.e(TAG,"recoverBluetoothServiceFromError"); 1810 try { 1811 mBluetoothLock.readLock().lock(); 1812 if (mBluetooth != null) { 1813 //Unregister callback object 1814 mBluetooth.unregisterCallback(mBluetoothCallback); 1815 } 1816 } catch (RemoteException re) { 1817 Slog.e(TAG, "Unable to unregister", re); 1818 } finally { 1819 mBluetoothLock.readLock().unlock(); 1820 } 1821 1822 SystemClock.sleep(500); 1823 1824 // disable 1825 handleDisable(); 1826 1827 waitForOnOff(false, true); 1828 1829 sendBluetoothServiceDownCallback(); 1830 1831 try { 1832 mBluetoothLock.writeLock().lock(); 1833 if (mBluetooth != null) { 1834 mBluetooth = null; 1835 // Unbind 1836 mContext.unbindService(mConnection); 1837 } 1838 mBluetoothGatt = null; 1839 } finally { 1840 mBluetoothLock.writeLock().unlock(); 1841 } 1842 1843 mHandler.removeMessages(MESSAGE_BLUETOOTH_STATE_CHANGE); 1844 mState = BluetoothAdapter.STATE_OFF; 1845 1846 mEnable = false; 1847 1848 if (mErrorRecoveryRetryCounter++ < MAX_ERROR_RESTART_RETRIES) { 1849 // Send a Bluetooth Restart message to reenable bluetooth 1850 Message restartMsg = mHandler.obtainMessage( 1851 MESSAGE_RESTART_BLUETOOTH_SERVICE); 1852 mHandler.sendMessageDelayed(restartMsg, ERROR_RESTART_TIME_MS); 1853 } else { 1854 // todo: notify user to power down and power up phone to make bluetooth work. 1855 } 1856 } 1857 1858 @Override 1859 public void dump(FileDescriptor fd, PrintWriter writer, String[] args) { 1860 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DUMP, TAG); 1861 String errorMsg = null; 1862 if (mBluetoothBinder == null) { 1863 errorMsg = "Bluetooth Service not connected"; 1864 } else { 1865 try { 1866 mBluetoothBinder.dump(fd, args); 1867 } catch (RemoteException re) { 1868 errorMsg = "RemoteException while calling Bluetooth Service"; 1869 } 1870 } 1871 if (errorMsg != null) { 1872 // Silently return if we are extracting metrics in Protobuf format 1873 if ((args.length > 0) && args[0].startsWith("--proto")) 1874 return; 1875 writer.println(errorMsg); 1876 } 1877 } 1878 } 1879