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