summaryrefslogtreecommitdiff
path: root/core/java/android/bluetooth/BluetoothDevice.java
diff options
context:
space:
mode:
authorJeff Sharkey <jsharkey@android.com>2021-04-02 08:06:09 -0600
committerJeff Sharkey <jsharkey@android.com>2021-04-14 21:13:24 -0600
commit4acdb1beffc41b1fdc163b0e5182ec5f75ddf05e (patch)
tree5291bbae79518eaf21be48f8806b9605d85677af /core/java/android/bluetooth/BluetoothDevice.java
parent71463a4cb133c1344ab0921561e11b7d5565e617 (diff)
Update Bluetooth API annotations.
Recent work has introduced a new "Nearby devices" runtime permission which protects all existing Bluetooth APIs; we've done this by defining a <split-permission> to convert the old BLUETOOTH and BLUETOOTH_ADMIN permissions into one of three new permissions: * BLUETOOTH_ADVERTISE: Required to be able to advertise to nearby Bluetooth devices. * BLUETOOTH_CONNECT: Allows applications to connect to paired bluetooth devices. * BLUETOOTH_SCAN: Required to be able to discover and pair nearby Bluetooth devices. At its core, this change begins updating the Bluetooth APIs to have correct @RequiresPermission indicating which permission is actually enforced internally. To ensure alignment across Binder, the newly added "RequiresPermissionChecker" Error Prone checker was used to discover any inconsistencies, ensuring correctness from server-side enforcement up through to the public APIs. In addition, since developers will continue building apps for both modern and legacy platforms, this change introduces new auto-doc annotations which will emit helpful consistent documentation describing the behavior of older devices that are still using the old permission model. Bug: 183626724 Test: ./build/soong/soong_ui.bash --make-mode Bluetooth RUN_ERROR_PRONE=true Change-Id: I02aa127e8e07f239561f4f2a3bbdfc6fccb82f7f
Diffstat (limited to 'core/java/android/bluetooth/BluetoothDevice.java')
-rw-r--r--core/java/android/bluetooth/BluetoothDevice.java226
1 files changed, 164 insertions, 62 deletions
diff --git a/core/java/android/bluetooth/BluetoothDevice.java b/core/java/android/bluetooth/BluetoothDevice.java
index 0c208fd71aed..1201663d1d10 100644
--- a/core/java/android/bluetooth/BluetoothDevice.java
+++ b/core/java/android/bluetooth/BluetoothDevice.java
@@ -16,7 +16,6 @@
package android.bluetooth;
-import android.Manifest;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -26,6 +25,11 @@ import android.annotation.SdkConstant.SdkConstantType;
import android.annotation.SuppressLint;
import android.annotation.SystemApi;
import android.app.PropertyInvalidatedCache;
+import android.bluetooth.annotations.RequiresBluetoothConnectPermission;
+import android.bluetooth.annotations.RequiresBluetoothLocationPermission;
+import android.bluetooth.annotations.RequiresBluetoothScanPermission;
+import android.bluetooth.annotations.RequiresLegacyBluetoothAdminPermission;
+import android.bluetooth.annotations.RequiresLegacyBluetoothPermission;
import android.companion.AssociationRequest;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.Context;
@@ -66,9 +70,6 @@ import java.util.UUID;
* {@link #createRfcommSocketToServiceRecord(UUID)} over Bluetooth BR/EDR or using
* {@link #createL2capChannel(int)} over Bluetooth LE.
*
- * <p class="note"><strong>Note:</strong>
- * Requires the {@link android.Manifest.permission#BLUETOOTH} permission.
- *
* <div class="special reference">
* <h3>Developer Guides</h3>
* <p>
@@ -108,10 +109,12 @@ public final class BluetoothDevice implements Parcelable {
* <p>Always contains the extra fields {@link #EXTRA_DEVICE} and {@link
* #EXTRA_CLASS}. Can contain the extra fields {@link #EXTRA_NAME} and/or
* {@link #EXTRA_RSSI} if they are available.
- * <p>Requires {@link android.Manifest.permission#BLUETOOTH} and
- * {@link android.Manifest.permission#ACCESS_COARSE_LOCATION} to receive.
*/
// TODO: Change API to not broadcast RSSI if not available (incoming connection)
+ @RequiresLegacyBluetoothPermission
+ @RequiresBluetoothScanPermission
+ @RequiresBluetoothLocationPermission
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN)
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
public static final String ACTION_FOUND =
"android.bluetooth.device.action.FOUND";
@@ -120,9 +123,11 @@ public final class BluetoothDevice implements Parcelable {
* Broadcast Action: Bluetooth class of a remote device has changed.
* <p>Always contains the extra fields {@link #EXTRA_DEVICE} and {@link
* #EXTRA_CLASS}.
- * <p>Requires {@link android.Manifest.permission#BLUETOOTH} to receive.
* {@see BluetoothClass}
*/
+ @RequiresLegacyBluetoothPermission
+ @RequiresBluetoothConnectPermission
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
public static final String ACTION_CLASS_CHANGED =
"android.bluetooth.device.action.CLASS_CHANGED";
@@ -133,8 +138,10 @@ public final class BluetoothDevice implements Parcelable {
* <p>Always contains the extra field {@link #EXTRA_DEVICE}.
* <p>ACL connections are managed automatically by the Android Bluetooth
* stack.
- * <p>Requires {@link android.Manifest.permission#BLUETOOTH} to receive.
*/
+ @RequiresLegacyBluetoothPermission
+ @RequiresBluetoothConnectPermission
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
public static final String ACTION_ACL_CONNECTED =
"android.bluetooth.device.action.ACL_CONNECTED";
@@ -146,8 +153,10 @@ public final class BluetoothDevice implements Parcelable {
* this intent as a hint to immediately terminate higher level connections
* (RFCOMM, L2CAP, or profile connections) to the remote device.
* <p>Always contains the extra field {@link #EXTRA_DEVICE}.
- * <p>Requires {@link android.Manifest.permission#BLUETOOTH} to receive.
*/
+ @RequiresLegacyBluetoothPermission
+ @RequiresBluetoothConnectPermission
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
public static final String ACTION_ACL_DISCONNECT_REQUESTED =
"android.bluetooth.device.action.ACL_DISCONNECT_REQUESTED";
@@ -158,8 +167,10 @@ public final class BluetoothDevice implements Parcelable {
* <p>Always contains the extra field {@link #EXTRA_DEVICE}.
* <p>ACL connections are managed automatically by the Android Bluetooth
* stack.
- * <p>Requires {@link android.Manifest.permission#BLUETOOTH} to receive.
*/
+ @RequiresLegacyBluetoothPermission
+ @RequiresBluetoothConnectPermission
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
public static final String ACTION_ACL_DISCONNECTED =
"android.bluetooth.device.action.ACL_DISCONNECTED";
@@ -169,8 +180,10 @@ public final class BluetoothDevice implements Parcelable {
* been retrieved for the first time, or changed since the last retrieval.
* <p>Always contains the extra fields {@link #EXTRA_DEVICE} and {@link
* #EXTRA_NAME}.
- * <p>Requires {@link android.Manifest.permission#BLUETOOTH} to receive.
*/
+ @RequiresLegacyBluetoothPermission
+ @RequiresBluetoothConnectPermission
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
public static final String ACTION_NAME_CHANGED =
"android.bluetooth.device.action.NAME_CHANGED";
@@ -179,9 +192,11 @@ public final class BluetoothDevice implements Parcelable {
* Broadcast Action: Indicates the alias of a remote device has been
* changed.
* <p>Always contains the extra field {@link #EXTRA_DEVICE}.
- * <p>Requires {@link android.Manifest.permission#BLUETOOTH} to receive.
*/
@SuppressLint("ActionValue")
+ @RequiresLegacyBluetoothPermission
+ @RequiresBluetoothConnectPermission
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
public static final String ACTION_ALIAS_CHANGED =
"android.bluetooth.device.action.ALIAS_CHANGED";
@@ -191,10 +206,12 @@ public final class BluetoothDevice implements Parcelable {
* device. For example, if a device is bonded (paired).
* <p>Always contains the extra fields {@link #EXTRA_DEVICE}, {@link
* #EXTRA_BOND_STATE} and {@link #EXTRA_PREVIOUS_BOND_STATE}.
- * <p>Requires {@link android.Manifest.permission#BLUETOOTH} to receive.
*/
// Note: When EXTRA_BOND_STATE is BOND_NONE then this will also
// contain a hidden extra field EXTRA_REASON with the result code.
+ @RequiresLegacyBluetoothPermission
+ @RequiresBluetoothConnectPermission
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
public static final String ACTION_BOND_STATE_CHANGED =
"android.bluetooth.device.action.BOND_STATE_CHANGED";
@@ -204,10 +221,12 @@ public final class BluetoothDevice implements Parcelable {
* been retrieved for the first time, or changed since the last retrieval
* <p>Always contains the extra fields {@link #EXTRA_DEVICE} and {@link
* #EXTRA_BATTERY_LEVEL}.
- * <p>Requires {@link android.Manifest.permission#BLUETOOTH} to receive.
*
* @hide
*/
+ @RequiresLegacyBluetoothPermission
+ @RequiresBluetoothConnectPermission
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
public static final String ACTION_BATTERY_LEVEL_CHANGED =
"android.bluetooth.device.action.BATTERY_LEVEL_CHANGED";
@@ -642,8 +661,10 @@ public final class BluetoothDevice implements Parcelable {
* device are requested to be fetched using Service Discovery Protocol
* <p> Always contains the extra field {@link #EXTRA_DEVICE}
* <p> Always contains the extra field {@link #EXTRA_UUID}
- * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN} to receive.
*/
+ @RequiresLegacyBluetoothAdminPermission
+ @RequiresBluetoothScanPermission
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN)
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
public static final String ACTION_UUID =
"android.bluetooth.device.action.UUID";
@@ -657,20 +678,23 @@ public final class BluetoothDevice implements Parcelable {
* Broadcast Action: Indicates a failure to retrieve the name of a remote
* device.
* <p>Always contains the extra field {@link #EXTRA_DEVICE}.
- * <p>Requires {@link android.Manifest.permission#BLUETOOTH} to receive.
*
* @hide
*/
//TODO: is this actually useful?
+ @RequiresLegacyBluetoothPermission
+ @RequiresBluetoothConnectPermission
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
public static final String ACTION_NAME_FAILED =
"android.bluetooth.device.action.NAME_FAILED";
/**
* Broadcast Action: This intent is used to broadcast PAIRING REQUEST
- * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN} to
- * receive.
*/
+ @RequiresLegacyBluetoothAdminPermission
+ @RequiresBluetoothScanPermission
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN)
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
public static final String ACTION_PAIRING_REQUEST =
"android.bluetooth.device.action.PAIRING_REQUEST";
@@ -1206,7 +1230,9 @@ public final class BluetoothDevice implements Parcelable {
*
* @return the Bluetooth name, or null if there was a problem.
*/
- @RequiresPermission(Manifest.permission.BLUETOOTH)
+ @RequiresLegacyBluetoothPermission
+ @RequiresBluetoothConnectPermission
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public String getName() {
final IBluetooth service = sService;
if (service == null) {
@@ -1235,7 +1261,9 @@ public final class BluetoothDevice implements Parcelable {
* @return the device type {@link #DEVICE_TYPE_CLASSIC}, {@link #DEVICE_TYPE_LE} {@link
* #DEVICE_TYPE_DUAL}. {@link #DEVICE_TYPE_UNKNOWN} if it's not available
*/
- @RequiresPermission(Manifest.permission.BLUETOOTH)
+ @RequiresLegacyBluetoothPermission
+ @RequiresBluetoothConnectPermission
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public int getType() {
final IBluetooth service = sService;
if (service == null) {
@@ -1257,7 +1285,9 @@ public final class BluetoothDevice implements Parcelable {
* null if there was a problem
*/
@Nullable
- @RequiresPermission(Manifest.permission.BLUETOOTH)
+ @RequiresLegacyBluetoothPermission
+ @RequiresBluetoothConnectPermission
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public String getAlias() {
final IBluetooth service = sService;
if (service == null) {
@@ -1293,7 +1323,9 @@ public final class BluetoothDevice implements Parcelable {
* @return {@code true} if the alias is successfully set, {@code false} on error
* @throws IllegalArgumentException if the alias is {@code null} or the empty string
*/
- @RequiresPermission(Manifest.permission.BLUETOOTH)
+ @RequiresLegacyBluetoothPermission
+ @RequiresBluetoothConnectPermission
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public boolean setAlias(@NonNull String alias) {
if (alias == null || alias.isEmpty()) {
throw new IllegalArgumentException("Cannot set the alias to null or the empty string");
@@ -1321,7 +1353,9 @@ public final class BluetoothDevice implements Parcelable {
* @hide
*/
@UnsupportedAppUsage
- @RequiresPermission(Manifest.permission.BLUETOOTH)
+ @RequiresLegacyBluetoothPermission
+ @RequiresBluetoothConnectPermission
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public int getBatteryLevel() {
final IBluetooth service = sService;
if (service == null) {
@@ -1346,7 +1380,9 @@ public final class BluetoothDevice implements Parcelable {
*
* @return false on immediate error, true if bonding will begin
*/
- @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN)
+ @RequiresLegacyBluetoothAdminPermission
+ @RequiresBluetoothConnectPermission
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public boolean createBond() {
return createBond(TRANSPORT_AUTO);
}
@@ -1367,7 +1403,9 @@ public final class BluetoothDevice implements Parcelable {
* @hide
*/
@UnsupportedAppUsage
- @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN)
+ @RequiresLegacyBluetoothAdminPermission
+ @RequiresBluetoothConnectPermission
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public boolean createBond(int transport) {
return createBondInternal(transport, null, null);
}
@@ -1395,7 +1433,7 @@ public final class BluetoothDevice implements Parcelable {
* @hide
*/
@SystemApi
- @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public boolean createBondOutOfBand(int transport, @Nullable OobData remoteP192Data,
@Nullable OobData remoteP256Data) {
if (remoteP192Data == null && remoteP256Data == null) {
@@ -1406,6 +1444,7 @@ public final class BluetoothDevice implements Parcelable {
return createBondInternal(transport, remoteP192Data, remoteP256Data);
}
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
private boolean createBondInternal(int transport, @Nullable OobData remoteP192Data,
@Nullable OobData remoteP256Data) {
final IBluetooth service = sService;
@@ -1430,7 +1469,9 @@ public final class BluetoothDevice implements Parcelable {
* @hide
*/
@UnsupportedAppUsage
- @RequiresPermission(Manifest.permission.BLUETOOTH)
+ @RequiresLegacyBluetoothPermission
+ @RequiresBluetoothConnectPermission
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public boolean isBondingInitiatedLocally() {
final IBluetooth service = sService;
if (service == null) {
@@ -1452,7 +1493,7 @@ public final class BluetoothDevice implements Parcelable {
* @hide
*/
@SystemApi
- @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public boolean cancelBondProcess() {
final IBluetooth service = sService;
if (service == null) {
@@ -1480,7 +1521,7 @@ public final class BluetoothDevice implements Parcelable {
* @hide
*/
@SystemApi
- @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public boolean removeBond() {
final IBluetooth service = sService;
if (service == null) {
@@ -1504,6 +1545,7 @@ public final class BluetoothDevice implements Parcelable {
new PropertyInvalidatedCache<BluetoothDevice, Integer>(
8, BLUETOOTH_BONDING_CACHE_PROPERTY) {
@Override
+ @SuppressLint("AndroidFrameworkRequiresPermission")
protected Integer recompute(BluetoothDevice query) {
try {
return sService.getBondState(query);
@@ -1532,7 +1574,10 @@ public final class BluetoothDevice implements Parcelable {
*
* @return the bond state
*/
- @RequiresPermission(Manifest.permission.BLUETOOTH)
+ @RequiresLegacyBluetoothPermission
+ @RequiresBluetoothConnectPermission
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
+ @SuppressLint("AndroidFrameworkRequiresPermission")
public int getBondState() {
final IBluetooth service = sService;
if (service == null) {
@@ -1560,7 +1605,7 @@ public final class BluetoothDevice implements Parcelable {
* @hide
*/
@SystemApi
- @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED)
public boolean canBondWithoutDialog() {
final IBluetooth service = sService;
if (service == null) {
@@ -1583,7 +1628,9 @@ public final class BluetoothDevice implements Parcelable {
* @hide
*/
@SystemApi
- @RequiresPermission(Manifest.permission.BLUETOOTH)
+ @RequiresLegacyBluetoothPermission
+ @RequiresBluetoothConnectPermission
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public boolean isConnected() {
final IBluetooth service = sService;
if (service == null) {
@@ -1606,7 +1653,9 @@ public final class BluetoothDevice implements Parcelable {
* @hide
*/
@SystemApi
- @RequiresPermission(Manifest.permission.BLUETOOTH)
+ @RequiresLegacyBluetoothPermission
+ @RequiresBluetoothConnectPermission
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public boolean isEncrypted() {
final IBluetooth service = sService;
if (service == null) {
@@ -1626,7 +1675,9 @@ public final class BluetoothDevice implements Parcelable {
*
* @return Bluetooth class object, or null on error
*/
- @RequiresPermission(Manifest.permission.BLUETOOTH)
+ @RequiresLegacyBluetoothPermission
+ @RequiresBluetoothConnectPermission
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public BluetoothClass getBluetoothClass() {
final IBluetooth service = sService;
if (service == null) {
@@ -1653,7 +1704,9 @@ public final class BluetoothDevice implements Parcelable {
*
* @return the supported features (UUIDs) of the remote device, or null on error
*/
- @RequiresPermission(Manifest.permission.BLUETOOTH)
+ @RequiresLegacyBluetoothPermission
+ @RequiresBluetoothConnectPermission
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public ParcelUuid[] getUuids() {
final IBluetooth service = sService;
if (service == null || !isBluetoothEnabled()) {
@@ -1681,7 +1734,9 @@ public final class BluetoothDevice implements Parcelable {
* @return False if the check fails, True if the process of initiating an ACL connection
* to the remote device was started.
*/
- @RequiresPermission(Manifest.permission.BLUETOOTH)
+ @RequiresLegacyBluetoothPermission
+ @RequiresBluetoothConnectPermission
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public boolean fetchUuidsWithSdp() {
final IBluetooth service = sService;
if (service == null || !isBluetoothEnabled()) {
@@ -1707,8 +1762,7 @@ public final class BluetoothDevice implements Parcelable {
* {@link #EXTRA_SDP_SEARCH_STATUS} different from 0.
* Detailed status error codes can be found by members of the Bluetooth package in
* the AbstractionLayer class.
- * <p>Requires {@link android.Manifest.permission#BLUETOOTH}.
- * The SDP record data will be stored in the intent as {@link #EXTRA_SDP_RECORD}.
+ * <p>The SDP record data will be stored in the intent as {@link #EXTRA_SDP_RECORD}.
* The object type will match one of the SdpXxxRecord types, depending on the UUID searched
* for.
*
@@ -1717,6 +1771,9 @@ public final class BluetoothDevice implements Parcelable {
* was started.
*/
/** @hide */
+ @RequiresLegacyBluetoothPermission
+ @RequiresBluetoothConnectPermission
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public boolean sdpSearch(ParcelUuid uuid) {
final IBluetooth service = sService;
if (service == null) {
@@ -1733,10 +1790,12 @@ public final class BluetoothDevice implements Parcelable {
/**
* Set the pin during pairing when the pairing method is {@link #PAIRING_VARIANT_PIN}
- * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}.
*
* @return true pin has been set false for error
*/
+ @RequiresLegacyBluetoothAdminPermission
+ @RequiresBluetoothConnectPermission
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public boolean setPin(byte[] pin) {
final IBluetooth service = sService;
if (service == null) {
@@ -1758,7 +1817,9 @@ public final class BluetoothDevice implements Parcelable {
* @hide
*/
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
- @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN)
+ @RequiresLegacyBluetoothAdminPermission
+ @RequiresBluetoothConnectPermission
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public boolean setPin(@NonNull String pin) {
byte[] pinBytes = convertPinToBytes(pin);
if (pinBytes == null) {
@@ -1772,7 +1833,7 @@ public final class BluetoothDevice implements Parcelable {
*
* @return true confirmation has been sent out false for error
*/
- @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED)
public boolean setPairingConfirmation(boolean confirm) {
final IBluetooth service = sService;
if (service == null) {
@@ -1795,7 +1856,9 @@ public final class BluetoothDevice implements Parcelable {
* @hide
*/
@UnsupportedAppUsage
- @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN)
+ @RequiresLegacyBluetoothAdminPermission
+ @RequiresBluetoothConnectPermission
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public boolean cancelPairing() {
final IBluetooth service = sService;
if (service == null) {
@@ -1827,7 +1890,9 @@ public final class BluetoothDevice implements Parcelable {
* @hide
*/
@UnsupportedAppUsage
- @RequiresPermission(Manifest.permission.BLUETOOTH)
+ @RequiresLegacyBluetoothPermission
+ @RequiresBluetoothConnectPermission
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public @AccessPermission int getPhonebookAccessPermission() {
final IBluetooth service = sService;
if (service == null) {
@@ -1859,8 +1924,6 @@ public final class BluetoothDevice implements Parcelable {
* If the {@link BluetoothDevice} is not connected with A2DP or HFP, it cannot
* enter silence mode.
*
- * <p> Requires {@link android.Manifest.permission#BLUETOOTH_PRIVILEGED}.
- *
* @param silence true to enter silence mode, false to exit
* @return true on success, false on error.
* @throws IllegalStateException if Bluetooth is not turned ON.
@@ -1884,8 +1947,6 @@ public final class BluetoothDevice implements Parcelable {
/**
* Check whether the {@link BluetoothDevice} is in silence mode
*
- * <p> Requires {@link android.Manifest.permission#BLUETOOTH_PRIVILEGED}.
- *
* @return true on device in silence mode, otherwise false.
* @throws IllegalStateException if Bluetooth is not turned ON.
* @hide
@@ -1935,7 +1996,9 @@ public final class BluetoothDevice implements Parcelable {
* @hide
*/
@UnsupportedAppUsage
- @RequiresPermission(Manifest.permission.BLUETOOTH)
+ @RequiresLegacyBluetoothPermission
+ @RequiresBluetoothConnectPermission
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public @AccessPermission int getMessageAccessPermission() {
final IBluetooth service = sService;
if (service == null) {
@@ -1959,7 +2022,7 @@ public final class BluetoothDevice implements Parcelable {
* @hide
*/
@SystemApi
- @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED)
public boolean setMessageAccessPermission(@AccessPermission int value) {
// Validates param value is one of the accepted constants
if (value != ACCESS_ALLOWED && value != ACCESS_REJECTED && value != ACCESS_UNKNOWN) {
@@ -1984,7 +2047,9 @@ public final class BluetoothDevice implements Parcelable {
* @hide
*/
@SystemApi
- @RequiresPermission(Manifest.permission.BLUETOOTH)
+ @RequiresLegacyBluetoothPermission
+ @RequiresBluetoothConnectPermission
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public @AccessPermission int getSimAccessPermission() {
final IBluetooth service = sService;
if (service == null) {
@@ -2008,7 +2073,7 @@ public final class BluetoothDevice implements Parcelable {
* @hide
*/
@SystemApi
- @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED)
public boolean setSimAccessPermission(int value) {
final IBluetooth service = sService;
if (service == null) {
@@ -2039,7 +2104,6 @@ public final class BluetoothDevice implements Parcelable {
* <p>Use {@link BluetoothSocket#connect} to initiate the outgoing
* connection.
* <p>Valid RFCOMM channels are in range 1 to 30.
- * <p>Requires {@link android.Manifest.permission#BLUETOOTH}
*
* @param channel RFCOMM channel to connect to
* @return a RFCOMM BluetoothServerSocket ready for an outgoing connection
@@ -2048,6 +2112,10 @@ public final class BluetoothDevice implements Parcelable {
* @hide
*/
@UnsupportedAppUsage
+ @RequiresLegacyBluetoothPermission
+ @RequiresBluetoothConnectPermission
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
+ @SuppressLint("AndroidFrameworkRequiresPermission")
public BluetoothSocket createRfcommSocket(int channel) throws IOException {
if (!isBluetoothEnabled()) {
Log.e(TAG, "Bluetooth is not enabled");
@@ -2074,7 +2142,6 @@ public final class BluetoothDevice implements Parcelable {
* <p>Use {@link BluetoothSocket#connect} to initiate the outgoing
* connection.
* <p>Valid L2CAP PSM channels are in range 1 to 2^16.
- * <p>Requires {@link android.Manifest.permission#BLUETOOTH}
*
* @param channel L2cap PSM/channel to connect to
* @return a RFCOMM BluetoothServerSocket ready for an outgoing connection
@@ -2082,6 +2149,10 @@ public final class BluetoothDevice implements Parcelable {
* permissions
* @hide
*/
+ @RequiresLegacyBluetoothPermission
+ @RequiresBluetoothConnectPermission
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
+ @SuppressLint("AndroidFrameworkRequiresPermission")
public BluetoothSocket createL2capSocket(int channel) throws IOException {
return new BluetoothSocket(BluetoothSocket.TYPE_L2CAP, -1, true, true, this, channel,
null);
@@ -2095,7 +2166,6 @@ public final class BluetoothDevice implements Parcelable {
* <p>Use {@link BluetoothSocket#connect} to initiate the outgoing
* connection.
* <p>Valid L2CAP PSM channels are in range 1 to 2^16.
- * <p>Requires {@link android.Manifest.permission#BLUETOOTH}
*
* @param channel L2cap PSM/channel to connect to
* @return a RFCOMM BluetoothServerSocket ready for an outgoing connection
@@ -2103,6 +2173,10 @@ public final class BluetoothDevice implements Parcelable {
* permissions
* @hide
*/
+ @RequiresLegacyBluetoothPermission
+ @RequiresBluetoothConnectPermission
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
+ @SuppressLint("AndroidFrameworkRequiresPermission")
public BluetoothSocket createInsecureL2capSocket(int channel) throws IOException {
return new BluetoothSocket(BluetoothSocket.TYPE_L2CAP, -1, false, false, this, channel,
null);
@@ -2138,7 +2212,10 @@ public final class BluetoothDevice implements Parcelable {
* @throws IOException on error, for example Bluetooth not available, or insufficient
* permissions
*/
- @RequiresPermission(Manifest.permission.BLUETOOTH)
+ @RequiresLegacyBluetoothPermission
+ @RequiresBluetoothConnectPermission
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
+ @SuppressLint("AndroidFrameworkRequiresPermission")
public BluetoothSocket createRfcommSocketToServiceRecord(UUID uuid) throws IOException {
if (!isBluetoothEnabled()) {
Log.e(TAG, "Bluetooth is not enabled");
@@ -2176,7 +2253,10 @@ public final class BluetoothDevice implements Parcelable {
* @throws IOException on error, for example Bluetooth not available, or insufficient
* permissions
*/
- @RequiresPermission(Manifest.permission.BLUETOOTH)
+ @RequiresLegacyBluetoothPermission
+ @RequiresBluetoothConnectPermission
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
+ @SuppressLint("AndroidFrameworkRequiresPermission")
public BluetoothSocket createInsecureRfcommSocketToServiceRecord(UUID uuid) throws IOException {
if (!isBluetoothEnabled()) {
Log.e(TAG, "Bluetooth is not enabled");
@@ -2192,7 +2272,6 @@ public final class BluetoothDevice implements Parcelable {
* Call #connect on the returned #BluetoothSocket to begin the connection.
* The remote device will not be authenticated and communication on this
* socket will not be encrypted.
- * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}
*
* @param port remote port
* @return An RFCOMM BluetoothSocket
@@ -2202,6 +2281,10 @@ public final class BluetoothDevice implements Parcelable {
*/
@UnsupportedAppUsage(publicAlternatives = "Use "
+ "{@link #createInsecureRfcommSocketToServiceRecord} instead.")
+ @RequiresLegacyBluetoothAdminPermission
+ @RequiresBluetoothConnectPermission
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
+ @SuppressLint("AndroidFrameworkRequiresPermission")
public BluetoothSocket createInsecureRfcommSocket(int port) throws IOException {
if (!isBluetoothEnabled()) {
Log.e(TAG, "Bluetooth is not enabled");
@@ -2214,7 +2297,6 @@ public final class BluetoothDevice implements Parcelable {
/**
* Construct a SCO socket ready to start an outgoing connection.
* Call #connect on the returned #BluetoothSocket to begin the connection.
- * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}
*
* @return a SCO BluetoothSocket
* @throws IOException on error, for example Bluetooth not available, or insufficient
@@ -2222,6 +2304,10 @@ public final class BluetoothDevice implements Parcelable {
* @hide
*/
@UnsupportedAppUsage
+ @RequiresLegacyBluetoothAdminPermission
+ @RequiresBluetoothConnectPermission
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
+ @SuppressLint("AndroidFrameworkRequiresPermission")
public BluetoothSocket createScoSocket() throws IOException {
if (!isBluetoothEnabled()) {
Log.e(TAG, "Bluetooth is not enabled");
@@ -2269,6 +2355,8 @@ public final class BluetoothDevice implements Parcelable {
* automatically connect as soon as the remote device becomes available (true).
* @throws IllegalArgumentException if callback is null
*/
+ @RequiresBluetoothConnectPermission
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public BluetoothGatt connectGatt(Context context, boolean autoConnect,
BluetoothGattCallback callback) {
return (connectGatt(context, autoConnect, callback, TRANSPORT_AUTO));
@@ -2289,6 +2377,8 @@ public final class BluetoothDevice implements Parcelable {
* BluetoothDevice#TRANSPORT_LE}
* @throws IllegalArgumentException if callback is null
*/
+ @RequiresBluetoothConnectPermission
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public BluetoothGatt connectGatt(Context context, boolean autoConnect,
BluetoothGattCallback callback, int transport) {
return (connectGatt(context, autoConnect, callback, transport, PHY_LE_1M_MASK));
@@ -2313,6 +2403,8 @@ public final class BluetoothDevice implements Parcelable {
* is set to true.
* @throws NullPointerException if callback is null
*/
+ @RequiresBluetoothConnectPermission
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public BluetoothGatt connectGatt(Context context, boolean autoConnect,
BluetoothGattCallback callback, int transport, int phy) {
return connectGatt(context, autoConnect, callback, transport, phy, null);
@@ -2339,6 +2431,8 @@ public final class BluetoothDevice implements Parcelable {
* an un-specified background thread.
* @throws NullPointerException if callback is null
*/
+ @RequiresBluetoothConnectPermission
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public BluetoothGatt connectGatt(Context context, boolean autoConnect,
BluetoothGattCallback callback, int transport, int phy,
Handler handler) {
@@ -2372,6 +2466,8 @@ public final class BluetoothDevice implements Parcelable {
* @hide
*/
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+ @RequiresBluetoothConnectPermission
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public BluetoothGatt connectGatt(Context context, boolean autoConnect,
BluetoothGattCallback callback, int transport,
boolean opportunistic, int phy, Handler handler) {
@@ -2416,7 +2512,10 @@ public final class BluetoothDevice implements Parcelable {
* @throws IOException on error, for example Bluetooth not available, or insufficient
* permissions
*/
- @RequiresPermission(Manifest.permission.BLUETOOTH)
+ @RequiresLegacyBluetoothPermission
+ @RequiresBluetoothConnectPermission
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
+ @SuppressLint("AndroidFrameworkRequiresPermission")
public @NonNull BluetoothSocket createL2capChannel(int psm) throws IOException {
if (!isBluetoothEnabled()) {
Log.e(TAG, "createL2capChannel: Bluetooth is not enabled");
@@ -2444,7 +2543,10 @@ public final class BluetoothDevice implements Parcelable {
* @throws IOException on error, for example Bluetooth not available, or insufficient
* permissions
*/
- @RequiresPermission(Manifest.permission.BLUETOOTH)
+ @RequiresLegacyBluetoothPermission
+ @RequiresBluetoothConnectPermission
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
+ @SuppressLint("AndroidFrameworkRequiresPermission")
public @NonNull BluetoothSocket createInsecureL2capChannel(int psm) throws IOException {
if (!isBluetoothEnabled()) {
Log.e(TAG, "createInsecureL2capChannel: Bluetooth is not enabled");
@@ -2472,7 +2574,7 @@ public final class BluetoothDevice implements Parcelable {
* @hide
*/
@SystemApi
- @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED)
public boolean setMetadata(@MetadataKey int key, @NonNull byte[] value) {
final IBluetooth service = sService;
if (service == null) {
@@ -2500,7 +2602,7 @@ public final class BluetoothDevice implements Parcelable {
*/
@SystemApi
@Nullable
- @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED)
public byte[] getMetadata(@MetadataKey int key) {
final IBluetooth service = sService;
if (service == null) {