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