Merge "Deprecate GATT callbacks and methods that were not memory safe and replace with memory safe versions."
This commit is contained in:
@@ -9125,8 +9125,10 @@ package android.bluetooth {
|
||||
method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean requestMtu(int);
|
||||
method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean setCharacteristicNotification(android.bluetooth.BluetoothGattCharacteristic, boolean);
|
||||
method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public void setPreferredPhy(int, int, int);
|
||||
method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean writeCharacteristic(android.bluetooth.BluetoothGattCharacteristic);
|
||||
method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean writeDescriptor(android.bluetooth.BluetoothGattDescriptor);
|
||||
method @Deprecated @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean writeCharacteristic(android.bluetooth.BluetoothGattCharacteristic);
|
||||
method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public int writeCharacteristic(@NonNull android.bluetooth.BluetoothGattCharacteristic, @NonNull byte[], int);
|
||||
method @Deprecated @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean writeDescriptor(android.bluetooth.BluetoothGattDescriptor);
|
||||
method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public int writeDescriptor(@NonNull android.bluetooth.BluetoothGattDescriptor, @NonNull byte[]);
|
||||
field public static final int CONNECTION_PRIORITY_BALANCED = 0; // 0x0
|
||||
field public static final int CONNECTION_PRIORITY_HIGH = 1; // 0x1
|
||||
field public static final int CONNECTION_PRIORITY_LOW_POWER = 2; // 0x2
|
||||
@@ -9145,11 +9147,14 @@ package android.bluetooth {
|
||||
|
||||
public abstract class BluetoothGattCallback {
|
||||
ctor public BluetoothGattCallback();
|
||||
method public void onCharacteristicChanged(android.bluetooth.BluetoothGatt, android.bluetooth.BluetoothGattCharacteristic);
|
||||
method public void onCharacteristicRead(android.bluetooth.BluetoothGatt, android.bluetooth.BluetoothGattCharacteristic, int);
|
||||
method @Deprecated public void onCharacteristicChanged(android.bluetooth.BluetoothGatt, android.bluetooth.BluetoothGattCharacteristic);
|
||||
method public void onCharacteristicChanged(@NonNull android.bluetooth.BluetoothGatt, @NonNull android.bluetooth.BluetoothGattCharacteristic, @NonNull byte[]);
|
||||
method @Deprecated public void onCharacteristicRead(android.bluetooth.BluetoothGatt, android.bluetooth.BluetoothGattCharacteristic, int);
|
||||
method public void onCharacteristicRead(@NonNull android.bluetooth.BluetoothGatt, @NonNull android.bluetooth.BluetoothGattCharacteristic, @NonNull byte[], int);
|
||||
method public void onCharacteristicWrite(android.bluetooth.BluetoothGatt, android.bluetooth.BluetoothGattCharacteristic, int);
|
||||
method public void onConnectionStateChange(android.bluetooth.BluetoothGatt, int, int);
|
||||
method public void onDescriptorRead(android.bluetooth.BluetoothGatt, android.bluetooth.BluetoothGattDescriptor, int);
|
||||
method @Deprecated public void onDescriptorRead(android.bluetooth.BluetoothGatt, android.bluetooth.BluetoothGattDescriptor, int);
|
||||
method public void onDescriptorRead(@NonNull android.bluetooth.BluetoothGatt, @NonNull android.bluetooth.BluetoothGattDescriptor, int, @NonNull byte[]);
|
||||
method public void onDescriptorWrite(android.bluetooth.BluetoothGatt, android.bluetooth.BluetoothGattDescriptor, int);
|
||||
method public void onMtuChanged(android.bluetooth.BluetoothGatt, int, int);
|
||||
method public void onPhyRead(android.bluetooth.BluetoothGatt, int, int, int);
|
||||
@@ -9166,20 +9171,20 @@ package android.bluetooth {
|
||||
method public int describeContents();
|
||||
method public android.bluetooth.BluetoothGattDescriptor getDescriptor(java.util.UUID);
|
||||
method public java.util.List<android.bluetooth.BluetoothGattDescriptor> getDescriptors();
|
||||
method public Float getFloatValue(int, int);
|
||||
method @Deprecated public Float getFloatValue(int, int);
|
||||
method public int getInstanceId();
|
||||
method public Integer getIntValue(int, int);
|
||||
method @Deprecated public Integer getIntValue(int, int);
|
||||
method public int getPermissions();
|
||||
method public int getProperties();
|
||||
method public android.bluetooth.BluetoothGattService getService();
|
||||
method public String getStringValue(int);
|
||||
method @Deprecated public String getStringValue(int);
|
||||
method public java.util.UUID getUuid();
|
||||
method public byte[] getValue();
|
||||
method @Deprecated public byte[] getValue();
|
||||
method public int getWriteType();
|
||||
method public boolean setValue(byte[]);
|
||||
method public boolean setValue(int, int, int);
|
||||
method public boolean setValue(int, int, int, int);
|
||||
method public boolean setValue(String);
|
||||
method @Deprecated public boolean setValue(byte[]);
|
||||
method @Deprecated public boolean setValue(int, int, int);
|
||||
method @Deprecated public boolean setValue(int, int, int, int);
|
||||
method @Deprecated public boolean setValue(String);
|
||||
method public void setWriteType(int);
|
||||
method public void writeToParcel(android.os.Parcel, int);
|
||||
field @NonNull public static final android.os.Parcelable.Creator<android.bluetooth.BluetoothGattCharacteristic> CREATOR;
|
||||
@@ -9219,8 +9224,8 @@ package android.bluetooth {
|
||||
method public android.bluetooth.BluetoothGattCharacteristic getCharacteristic();
|
||||
method public int getPermissions();
|
||||
method public java.util.UUID getUuid();
|
||||
method public byte[] getValue();
|
||||
method public boolean setValue(byte[]);
|
||||
method @Deprecated public byte[] getValue();
|
||||
method @Deprecated public boolean setValue(byte[]);
|
||||
method public void writeToParcel(android.os.Parcel, int);
|
||||
field @NonNull public static final android.os.Parcelable.Creator<android.bluetooth.BluetoothGattDescriptor> CREATOR;
|
||||
field public static final byte[] DISABLE_NOTIFICATION_VALUE;
|
||||
@@ -9508,8 +9513,12 @@ package android.bluetooth {
|
||||
field public static final int ERROR_BLUETOOTH_NOT_ALLOWED = 2; // 0x2
|
||||
field public static final int ERROR_BLUETOOTH_NOT_ENABLED = 1; // 0x1
|
||||
field public static final int ERROR_DEVICE_NOT_BONDED = 3; // 0x3
|
||||
field public static final int ERROR_FEATURE_NOT_SUPPORTED = 8; // 0x8
|
||||
field public static final int ERROR_FEATURE_NOT_SUPPORTED = 10; // 0xa
|
||||
field public static final int ERROR_GATT_WRITE_NOT_ALLOWED = 101; // 0x65
|
||||
field public static final int ERROR_GATT_WRITE_REQUEST_BUSY = 102; // 0x66
|
||||
field public static final int ERROR_MISSING_BLUETOOTH_CONNECT_PERMISSION = 6; // 0x6
|
||||
field public static final int ERROR_MISSING_BLUETOOTH_PRIVILEGED_PERMISSION = 8; // 0x8
|
||||
field public static final int ERROR_PROFILE_SERVICE_NOT_BOUND = 9; // 0x9
|
||||
field public static final int ERROR_UNKNOWN = 2147483647; // 0x7fffffff
|
||||
field public static final int SUCCESS = 0; // 0x0
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
package android.bluetooth;
|
||||
|
||||
import android.annotation.IntDef;
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.RequiresNoPermission;
|
||||
import android.annotation.RequiresPermission;
|
||||
import android.annotation.SuppressLint;
|
||||
@@ -29,6 +31,8 @@ import android.os.ParcelUuid;
|
||||
import android.os.RemoteException;
|
||||
import android.util.Log;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
@@ -139,27 +143,6 @@ public final class BluetoothGatt implements BluetoothProfile {
|
||||
/** Connection parameter update - Request low power, reduced data rate connection parameters. */
|
||||
public static final int CONNECTION_PRIORITY_LOW_POWER = 2;
|
||||
|
||||
/**
|
||||
* A GATT writeCharacteristic request is started successfully.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public static final int GATT_WRITE_REQUEST_SUCCESS = 0;
|
||||
|
||||
/**
|
||||
* A GATT writeCharacteristic request failed to start.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public static final int GATT_WRITE_REQUEST_FAIL = 1;
|
||||
|
||||
/**
|
||||
* A GATT writeCharacteristic request is issued to a busy remote device.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public static final int GATT_WRITE_REQUEST_BUSY = 2;
|
||||
|
||||
/**
|
||||
* No authentication required.
|
||||
*
|
||||
@@ -429,6 +412,9 @@ public final class BluetoothGatt implements BluetoothProfile {
|
||||
final BluetoothGattCallback callback = mCallback;
|
||||
if (callback != null) {
|
||||
if (status == 0) characteristic.setValue(value);
|
||||
callback.onCharacteristicRead(BluetoothGatt.this, characteristic,
|
||||
value, status);
|
||||
// Keep calling deprecated callback to maintain app compatibility
|
||||
callback.onCharacteristicRead(BluetoothGatt.this, characteristic,
|
||||
status);
|
||||
}
|
||||
@@ -443,7 +429,8 @@ public final class BluetoothGatt implements BluetoothProfile {
|
||||
*/
|
||||
@Override
|
||||
@SuppressLint("AndroidFrameworkRequiresPermission")
|
||||
public void onCharacteristicWrite(String address, int status, int handle) {
|
||||
public void onCharacteristicWrite(String address, int status, int handle,
|
||||
byte[] value) {
|
||||
if (VDBG) {
|
||||
Log.d(TAG, "onCharacteristicWrite() - Device=" + address
|
||||
+ " handle=" + handle + " Status=" + status);
|
||||
@@ -467,12 +454,13 @@ public final class BluetoothGatt implements BluetoothProfile {
|
||||
try {
|
||||
final int authReq = (mAuthRetryState == AUTH_RETRY_STATE_IDLE)
|
||||
? AUTHENTICATION_NO_MITM : AUTHENTICATION_MITM;
|
||||
int requestStatus = GATT_WRITE_REQUEST_FAIL;
|
||||
int requestStatus = BluetoothStatusCodes.ERROR_UNKNOWN;
|
||||
for (int i = 0; i < WRITE_CHARACTERISTIC_MAX_RETRIES; i++) {
|
||||
requestStatus = mService.writeCharacteristic(mClientIf, address,
|
||||
handle, characteristic.getWriteType(), authReq,
|
||||
characteristic.getValue(), mAttributionSource);
|
||||
if (requestStatus != GATT_WRITE_REQUEST_BUSY) {
|
||||
value, mAttributionSource);
|
||||
if (requestStatus
|
||||
!= BluetoothStatusCodes.ERROR_GATT_WRITE_REQUEST_BUSY) {
|
||||
break;
|
||||
}
|
||||
try {
|
||||
@@ -488,7 +476,6 @@ public final class BluetoothGatt implements BluetoothProfile {
|
||||
}
|
||||
|
||||
mAuthRetryState = AUTH_RETRY_STATE_IDLE;
|
||||
|
||||
runOrQueueCallback(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
@@ -524,6 +511,9 @@ public final class BluetoothGatt implements BluetoothProfile {
|
||||
final BluetoothGattCallback callback = mCallback;
|
||||
if (callback != null) {
|
||||
characteristic.setValue(value);
|
||||
callback.onCharacteristicChanged(BluetoothGatt.this,
|
||||
characteristic, value);
|
||||
// Keep calling deprecated callback to maintain app compatibility
|
||||
callback.onCharacteristicChanged(BluetoothGatt.this,
|
||||
characteristic);
|
||||
}
|
||||
@@ -578,6 +568,9 @@ public final class BluetoothGatt implements BluetoothProfile {
|
||||
final BluetoothGattCallback callback = mCallback;
|
||||
if (callback != null) {
|
||||
if (status == 0) descriptor.setValue(value);
|
||||
callback.onDescriptorRead(BluetoothGatt.this, descriptor, status,
|
||||
value);
|
||||
// Keep calling deprecated callback to maintain app compatibility
|
||||
callback.onDescriptorRead(BluetoothGatt.this, descriptor, status);
|
||||
}
|
||||
}
|
||||
@@ -590,7 +583,8 @@ public final class BluetoothGatt implements BluetoothProfile {
|
||||
*/
|
||||
@Override
|
||||
@SuppressLint("AndroidFrameworkRequiresPermission")
|
||||
public void onDescriptorWrite(String address, int status, int handle) {
|
||||
public void onDescriptorWrite(String address, int status, int handle,
|
||||
byte[] value) {
|
||||
if (VDBG) {
|
||||
Log.d(TAG,
|
||||
"onDescriptorWrite() - Device=" + address + " handle=" + handle);
|
||||
@@ -614,7 +608,7 @@ public final class BluetoothGatt implements BluetoothProfile {
|
||||
final int authReq = (mAuthRetryState == AUTH_RETRY_STATE_IDLE)
|
||||
? AUTHENTICATION_NO_MITM : AUTHENTICATION_MITM;
|
||||
mService.writeDescriptor(mClientIf, address, handle,
|
||||
authReq, descriptor.getValue(), mAttributionSource);
|
||||
authReq, value, mAttributionSource);
|
||||
mAuthRetryState++;
|
||||
return;
|
||||
} catch (RemoteException e) {
|
||||
@@ -1194,8 +1188,8 @@ public final class BluetoothGatt implements BluetoothProfile {
|
||||
* Reads the requested characteristic from the associated remote device.
|
||||
*
|
||||
* <p>This is an asynchronous operation. The result of the read operation
|
||||
* is reported by the {@link BluetoothGattCallback#onCharacteristicRead}
|
||||
* callback.
|
||||
* is reported by the {@link BluetoothGattCallback#onCharacteristicRead(BluetoothGatt,
|
||||
* BluetoothGattCharacteristic, byte[], int)} callback.
|
||||
*
|
||||
* @param characteristic Characteristic to read from the remote device
|
||||
* @return true, if the read operation was initiated successfully
|
||||
@@ -1240,8 +1234,8 @@ public final class BluetoothGatt implements BluetoothProfile {
|
||||
* Reads the characteristic using its UUID from the associated remote device.
|
||||
*
|
||||
* <p>This is an asynchronous operation. The result of the read operation
|
||||
* is reported by the {@link BluetoothGattCallback#onCharacteristicRead}
|
||||
* callback.
|
||||
* is reported by the {@link BluetoothGattCallback#onCharacteristicRead(BluetoothGatt,
|
||||
* BluetoothGattCharacteristic, byte[], int)} callback.
|
||||
*
|
||||
* @param uuid UUID of characteristic to read from the remote device
|
||||
* @return true, if the read operation was initiated successfully
|
||||
@@ -1284,40 +1278,94 @@ public final class BluetoothGatt implements BluetoothProfile {
|
||||
*
|
||||
* @param characteristic Characteristic to write on the remote device
|
||||
* @return true, if the write operation was initiated successfully
|
||||
* @throws IllegalArgumentException if characteristic or its value are null
|
||||
*
|
||||
* @deprecated Use {@link BluetoothGatt#writeCharacteristic(BluetoothGattCharacteristic, byte[],
|
||||
* int)} as this is not memory safe.
|
||||
*/
|
||||
@Deprecated
|
||||
@RequiresLegacyBluetoothPermission
|
||||
@RequiresBluetoothConnectPermission
|
||||
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
|
||||
public boolean writeCharacteristic(BluetoothGattCharacteristic characteristic) {
|
||||
try {
|
||||
return writeCharacteristic(characteristic, characteristic.getValue(),
|
||||
characteristic.getWriteType()) == BluetoothStatusCodes.SUCCESS;
|
||||
} catch (Exception e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@IntDef(value = {
|
||||
BluetoothStatusCodes.SUCCESS,
|
||||
BluetoothStatusCodes.ERROR_MISSING_BLUETOOTH_CONNECT_PERMISSION,
|
||||
BluetoothStatusCodes.ERROR_MISSING_BLUETOOTH_PRIVILEGED_PERMISSION,
|
||||
BluetoothStatusCodes.ERROR_DEVICE_NOT_CONNECTED,
|
||||
BluetoothStatusCodes.ERROR_PROFILE_SERVICE_NOT_BOUND,
|
||||
BluetoothStatusCodes.ERROR_GATT_WRITE_NOT_ALLOWED,
|
||||
BluetoothStatusCodes.ERROR_GATT_WRITE_REQUEST_BUSY,
|
||||
BluetoothStatusCodes.ERROR_UNKNOWN
|
||||
})
|
||||
public @interface WriteOperationReturnValues{}
|
||||
|
||||
/**
|
||||
* Writes a given characteristic and its values to the associated remote device.
|
||||
*
|
||||
* <p>Once the write operation has been completed, the
|
||||
* {@link BluetoothGattCallback#onCharacteristicWrite} callback is invoked,
|
||||
* reporting the result of the operation.
|
||||
*
|
||||
* @param characteristic Characteristic to write on the remote device
|
||||
* @return whether the characteristic was successfully written to
|
||||
* @throws IllegalArgumentException if characteristic or value are null
|
||||
*/
|
||||
@RequiresBluetoothConnectPermission
|
||||
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
|
||||
@WriteOperationReturnValues
|
||||
public int writeCharacteristic(@NonNull BluetoothGattCharacteristic characteristic,
|
||||
@NonNull byte[] value, int writeType) {
|
||||
if (characteristic == null) {
|
||||
throw new IllegalArgumentException("characteristic must not be null");
|
||||
}
|
||||
if (value == null) {
|
||||
throw new IllegalArgumentException("value must not be null");
|
||||
}
|
||||
if (VDBG) Log.d(TAG, "writeCharacteristic() - uuid: " + characteristic.getUuid());
|
||||
if ((characteristic.getProperties() & BluetoothGattCharacteristic.PROPERTY_WRITE) == 0
|
||||
&& (characteristic.getProperties()
|
||||
& BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE) == 0) {
|
||||
return false;
|
||||
return BluetoothStatusCodes.ERROR_GATT_WRITE_NOT_ALLOWED;
|
||||
}
|
||||
if (mService == null || mClientIf == 0) {
|
||||
return BluetoothStatusCodes.ERROR_PROFILE_SERVICE_NOT_BOUND;
|
||||
}
|
||||
|
||||
if (VDBG) Log.d(TAG, "writeCharacteristic() - uuid: " + characteristic.getUuid());
|
||||
if (mService == null || mClientIf == 0 || characteristic.getValue() == null) return false;
|
||||
|
||||
BluetoothGattService service = characteristic.getService();
|
||||
if (service == null) return false;
|
||||
if (service == null) {
|
||||
throw new IllegalArgumentException("Characteristic must have a non-null service");
|
||||
}
|
||||
|
||||
BluetoothDevice device = service.getDevice();
|
||||
if (device == null) return false;
|
||||
if (device == null) {
|
||||
throw new IllegalArgumentException("Service must have a non-null device");
|
||||
}
|
||||
|
||||
synchronized (mDeviceBusyLock) {
|
||||
if (mDeviceBusy) {
|
||||
return false;
|
||||
return BluetoothStatusCodes.ERROR_GATT_WRITE_REQUEST_BUSY;
|
||||
}
|
||||
mDeviceBusy = true;
|
||||
}
|
||||
|
||||
int requestStatus = GATT_WRITE_REQUEST_FAIL;
|
||||
int requestStatus = BluetoothStatusCodes.ERROR_UNKNOWN;
|
||||
try {
|
||||
for (int i = 0; i < WRITE_CHARACTERISTIC_MAX_RETRIES; i++) {
|
||||
requestStatus = mService.writeCharacteristic(mClientIf, device.getAddress(),
|
||||
characteristic.getInstanceId(), characteristic.getWriteType(),
|
||||
AUTHENTICATION_NONE, characteristic.getValue(), mAttributionSource);
|
||||
if (requestStatus != GATT_WRITE_REQUEST_BUSY) {
|
||||
characteristic.getInstanceId(), writeType, AUTHENTICATION_NONE, value,
|
||||
mAttributionSource);
|
||||
if (requestStatus != BluetoothStatusCodes.ERROR_GATT_WRITE_REQUEST_BUSY) {
|
||||
break;
|
||||
}
|
||||
try {
|
||||
@@ -1330,10 +1378,10 @@ public final class BluetoothGatt implements BluetoothProfile {
|
||||
synchronized (mDeviceBusyLock) {
|
||||
mDeviceBusy = false;
|
||||
}
|
||||
return false;
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
|
||||
return requestStatus == GATT_WRITE_REQUEST_SUCCESS;
|
||||
return requestStatus;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1384,45 +1432,86 @@ public final class BluetoothGatt implements BluetoothProfile {
|
||||
/**
|
||||
* Write the value of a given descriptor to the associated remote device.
|
||||
*
|
||||
* <p>A {@link BluetoothGattCallback#onDescriptorWrite} callback is
|
||||
* triggered to report the result of the write operation.
|
||||
* <p>A {@link BluetoothGattCallback#onDescriptorWrite} callback is triggered to report the
|
||||
* result of the write operation.
|
||||
*
|
||||
* @param descriptor Descriptor to write to the associated remote device
|
||||
* @return true, if the write operation was initiated successfully
|
||||
* @throws IllegalArgumentException if descriptor or its value are null
|
||||
*
|
||||
* @deprecated Use {@link BluetoothGatt#writeDescriptor(BluetoothGattDescriptor, byte[])} as
|
||||
* this is not memory safe.
|
||||
*/
|
||||
@Deprecated
|
||||
@RequiresLegacyBluetoothPermission
|
||||
@RequiresBluetoothConnectPermission
|
||||
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
|
||||
public boolean writeDescriptor(BluetoothGattDescriptor descriptor) {
|
||||
try {
|
||||
return writeDescriptor(descriptor, descriptor.getValue())
|
||||
== BluetoothStatusCodes.SUCCESS;
|
||||
} catch (Exception e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the value of a given descriptor to the associated remote device.
|
||||
*
|
||||
* <p>A {@link BluetoothGattCallback#onDescriptorWrite} callback is triggered to report the
|
||||
* result of the write operation.
|
||||
*
|
||||
* @param descriptor Descriptor to write to the associated remote device
|
||||
* @return true, if the write operation was initiated successfully
|
||||
* @throws IllegalArgumentException if descriptor or value are null
|
||||
*/
|
||||
@RequiresBluetoothConnectPermission
|
||||
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
|
||||
@WriteOperationReturnValues
|
||||
public int writeDescriptor(@NonNull BluetoothGattDescriptor descriptor,
|
||||
@NonNull byte[] value) {
|
||||
if (descriptor == null) {
|
||||
throw new IllegalArgumentException("descriptor must not be null");
|
||||
}
|
||||
if (value == null) {
|
||||
throw new IllegalArgumentException("value must not be null");
|
||||
}
|
||||
if (VDBG) Log.d(TAG, "writeDescriptor() - uuid: " + descriptor.getUuid());
|
||||
if (mService == null || mClientIf == 0 || descriptor.getValue() == null) return false;
|
||||
if (mService == null || mClientIf == 0) {
|
||||
return BluetoothStatusCodes.ERROR_PROFILE_SERVICE_NOT_BOUND;
|
||||
}
|
||||
|
||||
BluetoothGattCharacteristic characteristic = descriptor.getCharacteristic();
|
||||
if (characteristic == null) return false;
|
||||
if (characteristic == null) {
|
||||
throw new IllegalArgumentException("Descriptor must have a non-null characteristic");
|
||||
}
|
||||
|
||||
BluetoothGattService service = characteristic.getService();
|
||||
if (service == null) return false;
|
||||
if (service == null) {
|
||||
throw new IllegalArgumentException("Characteristic must have a non-null service");
|
||||
}
|
||||
|
||||
BluetoothDevice device = service.getDevice();
|
||||
if (device == null) return false;
|
||||
if (device == null) {
|
||||
throw new IllegalArgumentException("Service must have a non-null device");
|
||||
}
|
||||
|
||||
synchronized (mDeviceBusyLock) {
|
||||
if (mDeviceBusy) return false;
|
||||
if (mDeviceBusy) return BluetoothStatusCodes.ERROR_GATT_WRITE_REQUEST_BUSY;
|
||||
mDeviceBusy = true;
|
||||
}
|
||||
|
||||
try {
|
||||
mService.writeDescriptor(mClientIf, device.getAddress(), descriptor.getInstanceId(),
|
||||
AUTHENTICATION_NONE, descriptor.getValue(), mAttributionSource);
|
||||
return mService.writeDescriptor(mClientIf, device.getAddress(),
|
||||
descriptor.getInstanceId(), AUTHENTICATION_NONE, value, mAttributionSource);
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "", e);
|
||||
synchronized (mDeviceBusyLock) {
|
||||
mDeviceBusy = false;
|
||||
}
|
||||
return false;
|
||||
e.rethrowFromSystemServer();
|
||||
}
|
||||
|
||||
return true;
|
||||
return BluetoothStatusCodes.ERROR_UNKNOWN;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1431,9 +1520,9 @@ public final class BluetoothGatt implements BluetoothProfile {
|
||||
* <p>Once a reliable write transaction has been initiated, all calls
|
||||
* to {@link #writeCharacteristic} are sent to the remote device for
|
||||
* verification and queued up for atomic execution. The application will
|
||||
* receive an {@link BluetoothGattCallback#onCharacteristicWrite} callback
|
||||
* in response to every {@link #writeCharacteristic} call and is responsible
|
||||
* for verifying if the value has been transmitted accurately.
|
||||
* receive a {@link BluetoothGattCallback#onCharacteristicWrite} callback in response to every
|
||||
* {@link #writeCharacteristic(BluetoothGattCharacteristic, byte[], int)} call and is
|
||||
* responsible for verifying if the value has been transmitted accurately.
|
||||
*
|
||||
* <p>After all characteristics have been queued up and verified,
|
||||
* {@link #executeReliableWrite} will execute all writes. If a characteristic
|
||||
@@ -1530,9 +1619,9 @@ public final class BluetoothGatt implements BluetoothProfile {
|
||||
* Enable or disable notifications/indications for a given characteristic.
|
||||
*
|
||||
* <p>Once notifications are enabled for a characteristic, a
|
||||
* {@link BluetoothGattCallback#onCharacteristicChanged} callback will be
|
||||
* triggered if the remote device indicates that the given characteristic
|
||||
* has changed.
|
||||
* {@link BluetoothGattCallback#onCharacteristicChanged(BluetoothGatt,
|
||||
* BluetoothGattCharacteristic, byte[])} callback will be triggered if the remote device
|
||||
* indicates that the given characteristic has changed.
|
||||
*
|
||||
* @param characteristic The characteristic for which to enable notifications
|
||||
* @param enable Set to true to enable notifications/indications
|
||||
|
||||
@@ -80,15 +80,33 @@ public abstract class BluetoothGattCallback {
|
||||
/**
|
||||
* Callback reporting the result of a characteristic read operation.
|
||||
*
|
||||
* @param gatt GATT client invoked {@link BluetoothGatt#readCharacteristic}
|
||||
* @param gatt GATT client invoked
|
||||
* {@link BluetoothGatt#readCharacteristic(BluetoothGattCharacteristic)}
|
||||
* @param characteristic Characteristic that was read from the associated remote device.
|
||||
* @param status {@link BluetoothGatt#GATT_SUCCESS} if the read operation was completed
|
||||
* successfully.
|
||||
* @param status {@link BluetoothGatt#GATT_SUCCESS} if the read operation was completed
|
||||
* successfully.
|
||||
* @deprecated Use {@link BluetoothGattCallback#onCharacteristicRead(BluetoothGatt,
|
||||
* BluetoothGattCharacteristic, byte[], int)} as it is memory safe
|
||||
*/
|
||||
@Deprecated
|
||||
public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic,
|
||||
int status) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback reporting the result of a characteristic read operation.
|
||||
*
|
||||
* @param gatt GATT client invoked
|
||||
* {@link BluetoothGatt#readCharacteristic(BluetoothGattCharacteristic)}
|
||||
* @param characteristic Characteristic that was read from the associated remote device.
|
||||
* @param value the value of the characteristic
|
||||
* @param status {@link BluetoothGatt#GATT_SUCCESS} if the read operation was completed
|
||||
* successfully.
|
||||
*/
|
||||
public void onCharacteristicRead(@NonNull BluetoothGatt gatt, @NonNull
|
||||
BluetoothGattCharacteristic characteristic, @NonNull byte[] value, int status) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback indicating the result of a characteristic write operation.
|
||||
*
|
||||
@@ -98,10 +116,13 @@ public abstract class BluetoothGattCallback {
|
||||
* value to the desired value to be written. If the values don't match,
|
||||
* the application must abort the reliable write transaction.
|
||||
*
|
||||
* @param gatt GATT client invoked {@link BluetoothGatt#writeCharacteristic}
|
||||
* @param gatt GATT client that invoked
|
||||
* {@link BluetoothGatt#writeCharacteristic(BluetoothGattCharacteristic,
|
||||
* byte[], int)}
|
||||
* @param characteristic Characteristic that was written to the associated remote device.
|
||||
* @param status The result of the write operation {@link BluetoothGatt#GATT_SUCCESS} if the
|
||||
* operation succeeds.
|
||||
* @param status The result of the write operation {@link BluetoothGatt#GATT_SUCCESS} if
|
||||
* the
|
||||
* operation succeeds.
|
||||
*/
|
||||
public void onCharacteristicWrite(BluetoothGatt gatt,
|
||||
BluetoothGattCharacteristic characteristic, int status) {
|
||||
@@ -110,33 +131,68 @@ public abstract class BluetoothGattCallback {
|
||||
/**
|
||||
* Callback triggered as a result of a remote characteristic notification.
|
||||
*
|
||||
* @param gatt GATT client the characteristic is associated with
|
||||
* @param gatt GATT client the characteristic is associated with
|
||||
* @param characteristic Characteristic that has been updated as a result of a remote
|
||||
* notification event.
|
||||
* notification event.
|
||||
* @deprecated Use {@link BluetoothGattCallback#onCharacteristicChanged(BluetoothGatt,
|
||||
* BluetoothGattCharacteristic, byte[])} as it is memory safe by providing the characteristic
|
||||
* value at the time of notification.
|
||||
*/
|
||||
@Deprecated
|
||||
public void onCharacteristicChanged(BluetoothGatt gatt,
|
||||
BluetoothGattCharacteristic characteristic) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback triggered as a result of a remote characteristic notification. Note that the value
|
||||
* within the characteristic object may have changed since receiving the remote characteristic
|
||||
* notification, so check the parameter value for the value at the time of notification.
|
||||
*
|
||||
* @param gatt GATT client the characteristic is associated with
|
||||
* @param characteristic Characteristic that has been updated as a result of a remote
|
||||
* notification event.
|
||||
* @param value notified characteristic value
|
||||
*/
|
||||
public void onCharacteristicChanged(@NonNull BluetoothGatt gatt,
|
||||
@NonNull BluetoothGattCharacteristic characteristic, @NonNull byte[] value) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback reporting the result of a descriptor read operation.
|
||||
*
|
||||
* @param gatt GATT client invoked {@link BluetoothGatt#readDescriptor}
|
||||
* @param gatt GATT client invoked {@link BluetoothGatt#readDescriptor}
|
||||
* @param descriptor Descriptor that was read from the associated remote device.
|
||||
* @param status {@link BluetoothGatt#GATT_SUCCESS} if the read operation was completed
|
||||
* successfully
|
||||
* @param status {@link BluetoothGatt#GATT_SUCCESS} if the read operation was completed
|
||||
* successfully
|
||||
* @deprecated Use {@link BluetoothGattCallback#onDescriptorRead(BluetoothGatt,
|
||||
* BluetoothGattDescriptor, int, byte[])} as it is memory safe by providing the descriptor
|
||||
* value at the time it was read.
|
||||
*/
|
||||
@Deprecated
|
||||
public void onDescriptorRead(BluetoothGatt gatt, BluetoothGattDescriptor descriptor,
|
||||
int status) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback reporting the result of a descriptor read operation.
|
||||
*
|
||||
* @param gatt GATT client invoked {@link BluetoothGatt#readDescriptor}
|
||||
* @param descriptor Descriptor that was read from the associated remote device.
|
||||
* @param status {@link BluetoothGatt#GATT_SUCCESS} if the read operation was completed
|
||||
* successfully
|
||||
* @param value the descriptor value at the time of the read operation
|
||||
*/
|
||||
public void onDescriptorRead(@NonNull BluetoothGatt gatt,
|
||||
@NonNull BluetoothGattDescriptor descriptor, int status, @NonNull byte[] value) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback indicating the result of a descriptor write operation.
|
||||
*
|
||||
* @param gatt GATT client invoked {@link BluetoothGatt#writeDescriptor}
|
||||
* @param gatt GATT client invoked {@link BluetoothGatt#writeDescriptor}
|
||||
* @param descriptor Descriptor that was writte to the associated remote device.
|
||||
* @param status The result of the write operation {@link BluetoothGatt#GATT_SUCCESS} if the
|
||||
* operation succeeds.
|
||||
* @param status The result of the write operation {@link BluetoothGatt#GATT_SUCCESS} if the
|
||||
* operation succeeds.
|
||||
*/
|
||||
public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor,
|
||||
int status) {
|
||||
|
||||
@@ -451,8 +451,8 @@ public class BluetoothGattCharacteristic implements Parcelable {
|
||||
* Set the write type for this characteristic
|
||||
*
|
||||
* <p>Setting the write type of a characteristic determines how the
|
||||
* {@link BluetoothGatt#writeCharacteristic} function write this
|
||||
* characteristic.
|
||||
* {@link BluetoothGatt#writeCharacteristic(BluetoothGattCharacteristic, byte[], int)} function
|
||||
* write this characteristic.
|
||||
*
|
||||
* @param writeType The write type to for this characteristic. Can be one of: {@link
|
||||
* #WRITE_TYPE_DEFAULT}, {@link #WRITE_TYPE_NO_RESPONSE} or {@link #WRITE_TYPE_SIGNED}.
|
||||
@@ -504,7 +504,10 @@ public class BluetoothGattCharacteristic implements Parcelable {
|
||||
* operation or if a characteristic update notification has been received.
|
||||
*
|
||||
* @return Cached value of the characteristic
|
||||
*
|
||||
* @deprecated Use {@link BluetoothGatt#readCharacteristic(BluetoothGattCharacteristic)} instead
|
||||
*/
|
||||
@Deprecated
|
||||
public byte[] getValue() {
|
||||
return mValue;
|
||||
}
|
||||
@@ -521,7 +524,11 @@ public class BluetoothGattCharacteristic implements Parcelable {
|
||||
* @param formatType The format type used to interpret the characteristic value.
|
||||
* @param offset Offset at which the integer value can be found.
|
||||
* @return Cached value of the characteristic or null of offset exceeds value size.
|
||||
*
|
||||
* @deprecated Use {@link BluetoothGatt#readCharacteristic(BluetoothGattCharacteristic)} to get
|
||||
* the characteristic value
|
||||
*/
|
||||
@Deprecated
|
||||
public Integer getIntValue(int formatType, int offset) {
|
||||
if ((offset + getTypeLen(formatType)) > mValue.length) return null;
|
||||
|
||||
@@ -558,7 +565,11 @@ public class BluetoothGattCharacteristic implements Parcelable {
|
||||
* @param offset Offset at which the float value can be found.
|
||||
* @return Cached value of the characteristic at a given offset or null if the requested offset
|
||||
* exceeds the value size.
|
||||
*
|
||||
* @deprecated Use {@link BluetoothGatt#readCharacteristic(BluetoothGattCharacteristic)} to get
|
||||
* the characteristic value
|
||||
*/
|
||||
@Deprecated
|
||||
public Float getFloatValue(int formatType, int offset) {
|
||||
if ((offset + getTypeLen(formatType)) > mValue.length) return null;
|
||||
|
||||
@@ -580,7 +591,11 @@ public class BluetoothGattCharacteristic implements Parcelable {
|
||||
*
|
||||
* @param offset Offset at which the string value can be found.
|
||||
* @return Cached value of the characteristic
|
||||
*
|
||||
* @deprecated Use {@link BluetoothGatt#readCharacteristic(BluetoothGattCharacteristic)} to get
|
||||
* the characteristic value
|
||||
*/
|
||||
@Deprecated
|
||||
public String getStringValue(int offset) {
|
||||
if (mValue == null || offset > mValue.length) return null;
|
||||
byte[] strBytes = new byte[mValue.length - offset];
|
||||
@@ -599,7 +614,11 @@ public class BluetoothGattCharacteristic implements Parcelable {
|
||||
* @param value New value for this characteristic
|
||||
* @return true if the locally stored value has been set, false if the requested value could not
|
||||
* be stored locally.
|
||||
*
|
||||
* @deprecated Pass the characteristic value directly into
|
||||
* {@link BluetoothGatt#writeCharacteristic(BluetoothGattCharacteristic, byte[], int)}
|
||||
*/
|
||||
@Deprecated
|
||||
public boolean setValue(byte[] value) {
|
||||
mValue = value;
|
||||
return true;
|
||||
@@ -613,7 +632,11 @@ public class BluetoothGattCharacteristic implements Parcelable {
|
||||
* @param formatType Integer format type used to transform the value parameter
|
||||
* @param offset Offset at which the value should be placed
|
||||
* @return true if the locally stored value has been set
|
||||
*
|
||||
* @deprecated Pass the characteristic value directly into
|
||||
* {@link BluetoothGatt#writeCharacteristic(BluetoothGattCharacteristic, byte[], int)}
|
||||
*/
|
||||
@Deprecated
|
||||
public boolean setValue(int value, int formatType, int offset) {
|
||||
int len = offset + getTypeLen(formatType);
|
||||
if (mValue == null) mValue = new byte[len];
|
||||
@@ -660,7 +683,11 @@ public class BluetoothGattCharacteristic implements Parcelable {
|
||||
* @param formatType Float format type used to transform the value parameter
|
||||
* @param offset Offset at which the value should be placed
|
||||
* @return true if the locally stored value has been set
|
||||
*
|
||||
* @deprecated Pass the characteristic value directly into
|
||||
* {@link BluetoothGatt#writeCharacteristic(BluetoothGattCharacteristic, byte[], int)}
|
||||
*/
|
||||
@Deprecated
|
||||
public boolean setValue(int mantissa, int exponent, int formatType, int offset) {
|
||||
int len = offset + getTypeLen(formatType);
|
||||
if (mValue == null) mValue = new byte[len];
|
||||
@@ -697,7 +724,11 @@ public class BluetoothGattCharacteristic implements Parcelable {
|
||||
*
|
||||
* @param value New value for this characteristic
|
||||
* @return true if the locally stored value has been set
|
||||
*
|
||||
* @deprecated Pass the characteristic value directly into
|
||||
* {@link BluetoothGatt#writeCharacteristic(BluetoothGattCharacteristic, byte[], int)}
|
||||
*/
|
||||
@Deprecated
|
||||
public boolean setValue(String value) {
|
||||
mValue = value.getBytes();
|
||||
return true;
|
||||
|
||||
@@ -260,7 +260,10 @@ public class BluetoothGattDescriptor implements Parcelable {
|
||||
* operation.
|
||||
*
|
||||
* @return Cached value of the descriptor
|
||||
*
|
||||
* @deprecated Use {@link BluetoothGatt#readDescriptor(BluetoothGattDescriptor)} instead
|
||||
*/
|
||||
@Deprecated
|
||||
public byte[] getValue() {
|
||||
return mValue;
|
||||
}
|
||||
@@ -276,7 +279,11 @@ public class BluetoothGattDescriptor implements Parcelable {
|
||||
* @param value New value for this descriptor
|
||||
* @return true if the locally stored value has been set, false if the requested value could not
|
||||
* be stored locally.
|
||||
*
|
||||
* @deprecated Pass the descriptor value directly into
|
||||
* {@link BluetoothGatt#writeDescriptor(BluetoothGattDescriptor, byte[])}
|
||||
*/
|
||||
@Deprecated
|
||||
public boolean setValue(byte[] value) {
|
||||
mValue = value;
|
||||
return true;
|
||||
|
||||
@@ -78,10 +78,32 @@ public final class BluetoothStatusCodes {
|
||||
*/
|
||||
public static final int ERROR_MISSING_BLUETOOTH_SCAN_PERMISSION = 7;
|
||||
|
||||
/**
|
||||
* Error code indicating that the caller does not have the
|
||||
* {@link android.Manifest.permission#BLUETOOTH_PRIVILEGED} permission
|
||||
*/
|
||||
public static final int ERROR_MISSING_BLUETOOTH_PRIVILEGED_PERMISSION = 8;
|
||||
|
||||
/**
|
||||
* Error code indicating that the profile service is not bound. You can bind a profile service
|
||||
* by calling {@link BluetoothAdapter#getProfileProxy}
|
||||
*/
|
||||
public static final int ERROR_PROFILE_SERVICE_NOT_BOUND = 9;
|
||||
|
||||
/**
|
||||
* Error code indicating that the feature is not supported.
|
||||
*/
|
||||
public static final int ERROR_FEATURE_NOT_SUPPORTED = 8;
|
||||
public static final int ERROR_FEATURE_NOT_SUPPORTED = 10;
|
||||
|
||||
/**
|
||||
* A GATT writeCharacteristic request is not permitted on the remote device.
|
||||
*/
|
||||
public static final int ERROR_GATT_WRITE_NOT_ALLOWED = 101;
|
||||
|
||||
/**
|
||||
* A GATT writeCharacteristic request is issued to a busy remote device.
|
||||
*/
|
||||
public static final int ERROR_GATT_WRITE_REQUEST_BUSY = 102;
|
||||
|
||||
/**
|
||||
* If another application has already requested {@link OobData} then another fetch will be
|
||||
|
||||
Reference in New Issue
Block a user