Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4422794e authored by Johanna Ye's avatar Johanna Ye Committed by Automerger Merge Worker
Browse files

Merge "Fix long characteristic write concurrency bug." am: cfa6f144

Original change: https://android-review.googlesource.com/c/platform/frameworks/base/+/1752680

Change-Id: Ibf0f60dd5fbb78836f5c6b262d7653e507c8724d
parents d21dfb5e cfa6f144
Loading
Loading
Loading
Loading
+52 −6
Original line number Diff line number Diff line
@@ -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 */
@@ -126,6 +129,27 @@ 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.
     *
@@ -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,
                            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;
    }

    /**