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