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