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