summaryrefslogtreecommitdiff
path: root/framework/java/android/bluetooth/BluetoothGatt.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
commit8f80e4a05b3f1b227f40de5ec0e9a6297154ffc0 (patch)
tree03263d64510c4477b5cc75eeda52a0c9b547fe21 /framework/java/android/bluetooth/BluetoothGatt.java
parenta95b9490ca30736c3b508e102f8d92bf9aea4ad3 (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 'framework/java/android/bluetooth/BluetoothGatt.java')
-rw-r--r--framework/java/android/bluetooth/BluetoothGatt.java113
1 files changed, 75 insertions, 38 deletions
diff --git a/framework/java/android/bluetooth/BluetoothGatt.java b/framework/java/android/bluetooth/BluetoothGatt.java
index 381318b26d..942f843263 100644
--- a/framework/java/android/bluetooth/BluetoothGatt.java
+++ b/framework/java/android/bluetooth/BluetoothGatt.java
@@ -17,6 +17,14 @@
package android.bluetooth;
import android.compat.annotation.UnsupportedAppUsage;
+import android.annotation.RequiresPermission;
+import android.annotation.SuppressLint;
+import android.annotation.RequiresPermission;
+import android.bluetooth.annotations.RequiresLegacyBluetoothAdminPermission;
+import android.bluetooth.annotations.RequiresBluetoothConnectPermission;
+import android.bluetooth.annotations.RequiresBluetoothLocationPermission;
+import android.bluetooth.annotations.RequiresLegacyBluetoothPermission;
+import android.bluetooth.annotations.RequiresBluetoothScanPermission;
import android.os.Build;
import android.os.Handler;
import android.os.ParcelUuid;
@@ -157,6 +165,7 @@ public final class BluetoothGatt implements BluetoothProfile {
* @hide
*/
@Override
+ @SuppressLint("AndroidFrameworkRequiresPermission")
public void onClientRegistered(int status, int clientIf) {
if (DBG) {
Log.d(TAG, "onClientRegistered() - status=" + status
@@ -347,6 +356,7 @@ public final class BluetoothGatt implements BluetoothProfile {
* @hide
*/
@Override
+ @SuppressLint("AndroidFrameworkRequiresPermission")
public void onCharacteristicRead(String address, int status, int handle,
byte[] value) {
if (VDBG) {
@@ -404,6 +414,7 @@ public final class BluetoothGatt implements BluetoothProfile {
* @hide
*/
@Override
+ @SuppressLint("AndroidFrameworkRequiresPermission")
public void onCharacteristicWrite(String address, int status, int handle) {
if (VDBG) {
Log.d(TAG, "onCharacteristicWrite() - Device=" + address
@@ -487,6 +498,7 @@ public final class BluetoothGatt implements BluetoothProfile {
* @hide
*/
@Override
+ @SuppressLint("AndroidFrameworkRequiresPermission")
public void onDescriptorRead(String address, int status, int handle, byte[] value) {
if (VDBG) {
Log.d(TAG,
@@ -538,6 +550,7 @@ public final class BluetoothGatt implements BluetoothProfile {
* @hide
*/
@Override
+ @SuppressLint("AndroidFrameworkRequiresPermission")
public void onDescriptorWrite(String address, int status, int handle) {
if (VDBG) {
Log.d(TAG,
@@ -734,6 +747,7 @@ public final class BluetoothGatt implements BluetoothProfile {
* Application should call this method as early as possible after it is done with
* this GATT client.
*/
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public void close() {
if (DBG) Log.d(TAG, "close()");
@@ -817,12 +831,13 @@ public final class BluetoothGatt implements BluetoothProfile {
* <p>This is an asynchronous call. The callback {@link BluetoothGattCallback#onAppRegistered}
* is used to notify success or failure if the function returns true.
*
- * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
- *
* @param callback GATT callback handler that will receive asynchronous callbacks.
* @return If true, the callback will be called to notify success or failure, false on immediate
* error
*/
+ @RequiresLegacyBluetoothPermission
+ @RequiresBluetoothConnectPermission
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
private boolean registerApp(BluetoothGattCallback callback, Handler handler) {
return registerApp(callback, handler, false);
}
@@ -833,14 +848,15 @@ public final class BluetoothGatt implements BluetoothProfile {
* <p>This is an asynchronous call. The callback {@link BluetoothGattCallback#onAppRegistered}
* is used to notify success or failure if the function returns true.
*
- * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
- *
* @param callback GATT callback handler that will receive asynchronous callbacks.
* @param eatt_support indicate to allow for eatt support
* @return If true, the callback will be called to notify success or failure, false on immediate
* error
* @hide
*/
+ @RequiresLegacyBluetoothPermission
+ @RequiresBluetoothConnectPermission
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
private boolean registerApp(BluetoothGattCallback callback, Handler handler,
boolean eatt_support) {
if (DBG) Log.d(TAG, "registerApp()");
@@ -865,6 +881,7 @@ public final class BluetoothGatt implements BluetoothProfile {
* Unregister the current application and callbacks.
*/
@UnsupportedAppUsage
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
private void unregisterApp() {
if (DBG) Log.d(TAG, "unregisterApp() - mClientIf=" + mClientIf);
if (mService == null || mClientIf == 0) return;
@@ -893,14 +910,15 @@ public final class BluetoothGatt implements BluetoothProfile {
* subsequent connections to known devices should be invoked with the
* autoConnect parameter set to true.
*
- * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
- *
* @param device Remote device to connect to
* @param autoConnect Whether to directly connect to the remote device (false) or to
* automatically connect as soon as the remote device becomes available (true).
* @return true, if the connection attempt was initiated successfully
*/
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+ @RequiresLegacyBluetoothPermission
+ @RequiresBluetoothConnectPermission
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
/*package*/ boolean connect(Boolean autoConnect, BluetoothGattCallback callback,
Handler handler) {
if (DBG) {
@@ -931,9 +949,10 @@ public final class BluetoothGatt implements BluetoothProfile {
/**
* Disconnects an established connection, or cancels a connection attempt
* currently in progress.
- *
- * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
*/
+ @RequiresLegacyBluetoothPermission
+ @RequiresBluetoothConnectPermission
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public void disconnect() {
if (DBG) Log.d(TAG, "cancelOpen() - device: " + mDevice.getAddress());
if (mService == null || mClientIf == 0) return;
@@ -954,6 +973,7 @@ public final class BluetoothGatt implements BluetoothProfile {
*
* @return true, if the connection attempt was initiated successfully
*/
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public boolean connect() {
try {
mService.clientConnect(mClientIf, mDevice.getAddress(), false, mTransport,
@@ -983,6 +1003,7 @@ public final class BluetoothGatt implements BluetoothProfile {
* of {@link BluetoothDevice#PHY_OPTION_NO_PREFERRED}, {@link BluetoothDevice#PHY_OPTION_S2} or
* {@link BluetoothDevice#PHY_OPTION_S8}
*/
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public void setPreferredPhy(int txPhy, int rxPhy, int phyOptions) {
try {
mService.clientSetPreferredPhy(mClientIf, mDevice.getAddress(), txPhy, rxPhy,
@@ -996,6 +1017,7 @@ public final class BluetoothGatt implements BluetoothProfile {
* Read the current transmitter PHY and receiver PHY of the connection. The values are returned
* in {@link BluetoothGattCallback#onPhyRead}
*/
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public void readPhy() {
try {
mService.clientReadPhy(mClientIf, mDevice.getAddress());
@@ -1022,10 +1044,11 @@ public final class BluetoothGatt implements BluetoothProfile {
* triggered. If the discovery was successful, the remote services can be
* retrieved using the {@link #getServices} function.
*
- * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
- *
* @return true, if the remote service discovery has been started
*/
+ @RequiresLegacyBluetoothPermission
+ @RequiresBluetoothConnectPermission
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public boolean discoverServices() {
if (DBG) Log.d(TAG, "discoverServices() - device: " + mDevice.getAddress());
if (mService == null || mClientIf == 0) return false;
@@ -1047,11 +1070,12 @@ public final class BluetoothGatt implements BluetoothProfile {
* It should never be used by real applications. The service is not searched
* for characteristics and descriptors, or returned in any callback.
*
- * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
- *
* @return true, if the remote service discovery has been started
* @hide
*/
+ @RequiresLegacyBluetoothPermission
+ @RequiresBluetoothConnectPermission
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public boolean discoverServiceByUuid(UUID uuid) {
if (DBG) Log.d(TAG, "discoverServiceByUuid() - device: " + mDevice.getAddress());
if (mService == null || mClientIf == 0) return false;
@@ -1073,11 +1097,10 @@ public final class BluetoothGatt implements BluetoothProfile {
* <p>This function requires that service discovery has been completed
* for the given device.
*
- * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
- *
* @return List of services on the remote device. Returns an empty list if service discovery has
* not yet been performed.
*/
+ @RequiresLegacyBluetoothPermission
public List<BluetoothGattService> getServices() {
List<BluetoothGattService> result =
new ArrayList<BluetoothGattService>();
@@ -1101,12 +1124,11 @@ public final class BluetoothGatt implements BluetoothProfile {
* <p>If multiple instances of the same service (as identified by UUID)
* exist, the first instance of the service is returned.
*
- * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
- *
* @param uuid UUID of the requested service
* @return BluetoothGattService if supported, or null if the requested service is not offered by
* the remote device.
*/
+ @RequiresLegacyBluetoothPermission
public BluetoothGattService getService(UUID uuid) {
for (BluetoothGattService service : mServices) {
if (service.getDevice().equals(mDevice) && service.getUuid().equals(uuid)) {
@@ -1124,11 +1146,12 @@ public final class BluetoothGatt implements BluetoothProfile {
* is reported by the {@link BluetoothGattCallback#onCharacteristicRead}
* callback.
*
- * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
- *
* @param characteristic Characteristic to read from the remote device
* @return true, if the read operation was initiated successfully
*/
+ @RequiresLegacyBluetoothPermission
+ @RequiresBluetoothConnectPermission
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public boolean readCharacteristic(BluetoothGattCharacteristic characteristic) {
if ((characteristic.getProperties() & BluetoothGattCharacteristic.PROPERTY_READ) == 0) {
return false;
@@ -1167,12 +1190,13 @@ public final class BluetoothGatt implements BluetoothProfile {
* is reported by the {@link BluetoothGattCallback#onCharacteristicRead}
* callback.
*
- * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
- *
* @param uuid UUID of characteristic to read from the remote device
* @return true, if the read operation was initiated successfully
* @hide
*/
+ @RequiresLegacyBluetoothPermission
+ @RequiresBluetoothConnectPermission
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public boolean readUsingCharacteristicUuid(UUID uuid, int startHandle, int endHandle) {
if (VDBG) Log.d(TAG, "readUsingCharacteristicUuid() - uuid: " + uuid);
if (mService == null || mClientIf == 0) return false;
@@ -1202,11 +1226,12 @@ public final class BluetoothGatt implements BluetoothProfile {
* {@link BluetoothGattCallback#onCharacteristicWrite} callback is invoked,
* reporting the result of the operation.
*
- * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
- *
* @param characteristic Characteristic to write on the remote device
* @return true, if the write operation was initiated successfully
*/
+ @RequiresLegacyBluetoothPermission
+ @RequiresBluetoothConnectPermission
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public boolean writeCharacteristic(BluetoothGattCharacteristic characteristic) {
if ((characteristic.getProperties() & BluetoothGattCharacteristic.PROPERTY_WRITE) == 0
&& (characteristic.getProperties()
@@ -1248,11 +1273,12 @@ public final class BluetoothGatt implements BluetoothProfile {
* {@link BluetoothGattCallback#onDescriptorRead} callback is
* triggered, signaling the result of the operation.
*
- * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
- *
* @param descriptor Descriptor value to read from the remote device
* @return true, if the read operation was initiated successfully
*/
+ @RequiresLegacyBluetoothPermission
+ @RequiresBluetoothConnectPermission
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public boolean readDescriptor(BluetoothGattDescriptor descriptor) {
if (VDBG) Log.d(TAG, "readDescriptor() - uuid: " + descriptor.getUuid());
if (mService == null || mClientIf == 0) return false;
@@ -1289,11 +1315,12 @@ public final class BluetoothGatt implements BluetoothProfile {
* <p>A {@link BluetoothGattCallback#onDescriptorWrite} callback is
* triggered to report the result of the write operation.
*
- * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
- *
* @param descriptor Descriptor to write to the associated remote device
* @return true, if the write operation was initiated successfully
*/
+ @RequiresLegacyBluetoothPermission
+ @RequiresBluetoothConnectPermission
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public boolean writeDescriptor(BluetoothGattDescriptor descriptor) {
if (VDBG) Log.d(TAG, "writeDescriptor() - uuid: " + descriptor.getUuid());
if (mService == null || mClientIf == 0 || descriptor.getValue() == null) return false;
@@ -1340,10 +1367,11 @@ public final class BluetoothGatt implements BluetoothProfile {
* cancel the current transaction without committing any values on the
* remote device.
*
- * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
- *
* @return true, if the reliable write transaction has been initiated
*/
+ @RequiresLegacyBluetoothPermission
+ @RequiresBluetoothConnectPermission
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public boolean beginReliableWrite() {
if (VDBG) Log.d(TAG, "beginReliableWrite() - device: " + mDevice.getAddress());
if (mService == null || mClientIf == 0) return false;
@@ -1367,10 +1395,11 @@ public final class BluetoothGatt implements BluetoothProfile {
* <p>A {@link BluetoothGattCallback#onReliableWriteCompleted} callback is
* invoked to indicate whether the transaction has been executed correctly.
*
- * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
- *
* @return true, if the request to execute the transaction has been sent
*/
+ @RequiresLegacyBluetoothPermission
+ @RequiresBluetoothConnectPermission
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public boolean executeReliableWrite() {
if (VDBG) Log.d(TAG, "executeReliableWrite() - device: " + mDevice.getAddress());
if (mService == null || mClientIf == 0) return false;
@@ -1396,9 +1425,10 @@ public final class BluetoothGatt implements BluetoothProfile {
*
* <p>Calling this function will discard all queued characteristic write
* operations for a given remote device.
- *
- * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
*/
+ @RequiresLegacyBluetoothPermission
+ @RequiresBluetoothConnectPermission
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public void abortReliableWrite() {
if (VDBG) Log.d(TAG, "abortReliableWrite() - device: " + mDevice.getAddress());
if (mService == null || mClientIf == 0) return;
@@ -1414,6 +1444,7 @@ public final class BluetoothGatt implements BluetoothProfile {
* @deprecated Use {@link #abortReliableWrite()}
*/
@Deprecated
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public void abortReliableWrite(BluetoothDevice mDevice) {
abortReliableWrite();
}
@@ -1426,12 +1457,13 @@ public final class BluetoothGatt implements BluetoothProfile {
* triggered if the remote device indicates that the given characteristic
* has changed.
*
- * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
- *
* @param characteristic The characteristic for which to enable notifications
* @param enable Set to true to enable notifications/indications
* @return true, if the requested notification status was set successfully
*/
+ @RequiresLegacyBluetoothPermission
+ @RequiresBluetoothConnectPermission
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public boolean setCharacteristicNotification(BluetoothGattCharacteristic characteristic,
boolean enable) {
if (DBG) {
@@ -1464,6 +1496,7 @@ public final class BluetoothGatt implements BluetoothProfile {
* @hide
*/
@UnsupportedAppUsage
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public boolean refresh() {
if (DBG) Log.d(TAG, "refresh() - device: " + mDevice.getAddress());
if (mService == null || mClientIf == 0) return false;
@@ -1484,10 +1517,11 @@ public final class BluetoothGatt implements BluetoothProfile {
* <p>The {@link BluetoothGattCallback#onReadRemoteRssi} callback will be
* invoked when the RSSI value has been read.
*
- * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
- *
* @return true, if the RSSI value has been requested successfully
*/
+ @RequiresLegacyBluetoothPermission
+ @RequiresBluetoothConnectPermission
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public boolean readRemoteRssi() {
if (DBG) Log.d(TAG, "readRssi() - device: " + mDevice.getAddress());
if (mService == null || mClientIf == 0) return false;
@@ -1512,10 +1546,11 @@ public final class BluetoothGatt implements BluetoothProfile {
* <p>A {@link BluetoothGattCallback#onMtuChanged} callback will indicate
* whether this operation was successful.
*
- * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
- *
* @return true, if the new MTU value has been requested successfully
*/
+ @RequiresLegacyBluetoothPermission
+ @RequiresBluetoothConnectPermission
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public boolean requestMtu(int mtu) {
if (DBG) {
Log.d(TAG, "configureMTU() - device: " + mDevice.getAddress()
@@ -1544,6 +1579,7 @@ public final class BluetoothGatt implements BluetoothProfile {
* or {@link BluetoothGatt#CONNECTION_PRIORITY_LOW_POWER}.
* @throws IllegalArgumentException If the parameters are outside of their specified range.
*/
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public boolean requestConnectionPriority(int connectionPriority) {
if (connectionPriority < CONNECTION_PRIORITY_BALANCED
|| connectionPriority > CONNECTION_PRIORITY_LOW_POWER) {
@@ -1571,6 +1607,7 @@ public final class BluetoothGatt implements BluetoothProfile {
* @return true, if the request is send to the Bluetooth stack.
* @hide
*/
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public boolean requestLeConnectionUpdate(int minConnectionInterval, int maxConnectionInterval,
int slaveLatency, int supervisionTimeout,
int minConnectionEventLen, int maxConnectionEventLen) {