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