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