summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohanna Ye <xincheny@google.com>2021-07-09 15:39:32 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2021-07-09 15:39:32 +0000
commitcfa6f14403a6abc613b0aa15c3de149b423fb843 (patch)
tree678386f14aa0bc95865d8d4d4343879606165b74
parent5755c2ad32a64026ac40b372bcaed13df675cad7 (diff)
parent9eeafe9d52bd4c0c9e03271d8f2c36c6b796b211 (diff)
downloadbase-cfa6f14403a6abc613b0aa15c3de149b423fb843.tar.gz
Merge "Fix long characteristic write concurrency bug."
-rw-r--r--core/java/android/bluetooth/BluetoothGatt.java58
1 files changed, 52 insertions, 6 deletions
diff --git a/core/java/android/bluetooth/BluetoothGatt.java b/core/java/android/bluetooth/BluetoothGatt.java
index 1d08ddb65cf4..b3a7c8830d7d 100644
--- a/core/java/android/bluetooth/BluetoothGatt.java
+++ b/core/java/android/bluetooth/BluetoothGatt.java
@@ -75,6 +75,9 @@ public final class BluetoothGatt implements BluetoothProfile {
private static final int CONN_STATE_DISCONNECTING = 3;
private static final int CONN_STATE_CLOSED = 4;
+ private static final int WRITE_CHARACTERISTIC_MAX_RETRIES = 5;
+ private static final int WRITE_CHARACTERISTIC_TIME_TO_WAIT = 1000; // milliseconds
+
private List<BluetoothGattService> mServices;
/** A GATT operation completed successfully */
@@ -127,6 +130,27 @@ public final class BluetoothGatt implements BluetoothProfile {
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.
*
* @hide
@@ -428,9 +452,19 @@ public final class BluetoothGatt implements BluetoothProfile {
try {
final int authReq = (mAuthRetryState == AUTH_RETRY_STATE_IDLE)
? AUTHENTICATION_NO_MITM : AUTHENTICATION_MITM;
- mService.writeCharacteristic(mClientIf, address, handle,
- characteristic.getWriteType(), authReq,
- characteristic.getValue());
+ int requestStatus = GATT_WRITE_REQUEST_FAIL;
+ for (int i = 0; i < WRITE_CHARACTERISTIC_MAX_RETRIES; i++) {
+ requestStatus = mService.writeCharacteristic(mClientIf, address,
+ handle, characteristic.getWriteType(), authReq,
+ characteristic.getValue());
+ if (requestStatus != GATT_WRITE_REQUEST_BUSY) {
+ break;
+ }
+ try {
+ Thread.sleep(WRITE_CHARACTERISTIC_TIME_TO_WAIT);
+ } catch (InterruptedException e) {
+ }
+ }
mAuthRetryState++;
return;
} catch (RemoteException e) {
@@ -1228,14 +1262,26 @@ public final class BluetoothGatt implements BluetoothProfile {
if (device == null) return false;
synchronized (mDeviceBusyLock) {
- if (mDeviceBusy) return false;
+ if (mDeviceBusy) {
+ return false;
+ }
mDeviceBusy = true;
}
+ int requestStatus = GATT_WRITE_REQUEST_FAIL;
try {
- mService.writeCharacteristic(mClientIf, device.getAddress(),
+ for (int i = 0; i < WRITE_CHARACTERISTIC_MAX_RETRIES; i++) {
+ requestStatus = mService.writeCharacteristic(mClientIf, device.getAddress(),
characteristic.getInstanceId(), characteristic.getWriteType(),
AUTHENTICATION_NONE, characteristic.getValue());
+ if (requestStatus != GATT_WRITE_REQUEST_BUSY) {
+ break;
+ }
+ try {
+ Thread.sleep(WRITE_CHARACTERISTIC_TIME_TO_WAIT);
+ } catch (InterruptedException e) {
+ }
+ }
} catch (RemoteException e) {
Log.e(TAG, "", e);
synchronized (mDeviceBusyLock) {
@@ -1244,7 +1290,7 @@ public final class BluetoothGatt implements BluetoothProfile {
return false;
}
- return true;
+ return requestStatus == GATT_WRITE_REQUEST_SUCCESS;
}
/**