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