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