Migrate FastPair to memory safe writeCharacteristic and writeDescriptor
APIs

Bug: 195157393
Test: atest NearbyUnitTests
Change-Id: I4a05d02eef907501795a385524a33418ce44137a
diff --git a/nearby/service/java/com/android/server/nearby/common/bluetooth/gatt/BluetoothGattConnection.java b/nearby/service/java/com/android/server/nearby/common/bluetooth/gatt/BluetoothGattConnection.java
index 8e66ff2..de131e4 100644
--- a/nearby/service/java/com/android/server/nearby/common/bluetooth/gatt/BluetoothGattConnection.java
+++ b/nearby/service/java/com/android/server/nearby/common/bluetooth/gatt/BluetoothGattConnection.java
@@ -19,6 +19,7 @@
 import android.bluetooth.BluetoothGattCharacteristic;
 import android.bluetooth.BluetoothGattDescriptor;
 import android.bluetooth.BluetoothGattService;
+import android.bluetooth.BluetoothStatusCodes;
 import android.util.Log;
 
 import androidx.annotation.VisibleForTesting;
@@ -31,7 +32,7 @@
 import com.android.server.nearby.common.bluetooth.gatt.BluetoothGattHelper.ConnectionOptions;
 import com.android.server.nearby.common.bluetooth.gatt.BluetoothGattHelper.OperationType;
 import com.android.server.nearby.common.bluetooth.testability.android.bluetooth.BluetoothDevice;
-import com.android.server.nearby.common.bluetooth.testability.android.bluetooth.BluetoothGatt;
+import com.android.server.nearby.common.bluetooth.testability.android.bluetooth.BluetoothGattWrapper;
 import com.android.server.nearby.common.bluetooth.util.BluetoothGattUtils;
 import com.android.server.nearby.common.bluetooth.util.BluetoothOperationExecutor;
 import com.android.server.nearby.common.bluetooth.util.BluetoothOperationExecutor.Operation;
@@ -68,7 +69,7 @@
     @VisibleForTesting
     static final int GATT_ERROR = 133;
 
-    private final BluetoothGatt mGatt;
+    private final BluetoothGattWrapper mGatt;
     private final BluetoothOperationExecutor mBluetoothOperationExecutor;
     private final ConnectionOptions mConnectionOptions;
 
@@ -86,7 +87,7 @@
     private long mOperationTimeoutMillis = OPERATION_TIMEOUT_MILLIS;
 
     BluetoothGattConnection(
-            BluetoothGatt gatt,
+            BluetoothGattWrapper gatt,
             BluetoothOperationExecutor bluetoothOperationExecutor,
             ConnectionOptions connectionOptions) {
         mGatt = gatt;
@@ -400,13 +401,12 @@
                     new Operation<Void>(OperationType.WRITE_CHARACTERISTIC, mGatt, characteristic) {
                         @Override
                         public void run() throws BluetoothException {
-                            BluetoothGattCharacteristic characteristiClone =
-                                    BluetoothGattUtils.clone(characteristic);
-                            characteristiClone.setValue(value);
-                            boolean success = mGatt.writeCharacteristic(characteristiClone);
-                            if (!success) {
+                            int writeCharacteristicResponseCode = mGatt.writeCharacteristic(
+                                    characteristic, value, characteristic.getWriteType());
+                            if (writeCharacteristicResponseCode != BluetoothStatusCodes.SUCCESS) {
                                 throw new BluetoothException(
-                                        "gatt.writeCharacteristic returned false.");
+                                        "gatt.writeCharacteristic returned "
+                                        + writeCharacteristicResponseCode);
                             }
                         }
                     },
@@ -478,13 +478,12 @@
                     new Operation<Void>(OperationType.WRITE_DESCRIPTOR, mGatt, descriptor) {
                         @Override
                         public void run() throws BluetoothException {
-                            BluetoothGattDescriptor descriptorClone =
-                                    BluetoothGattUtils.clone(descriptor);
-                            descriptorClone.setValue(value);
-                            boolean success = mGatt.writeDescriptor(descriptorClone);
-                            if (!success) {
+                            int writeDescriptorResponseCode = mGatt.writeDescriptor(descriptor,
+                                    value);
+                            if (writeDescriptorResponseCode != BluetoothStatusCodes.SUCCESS) {
                                 throw new BluetoothException(
-                                        "gatt.writeDescriptor returned false.");
+                                        "gatt.writeDescriptor returned "
+                                        + writeDescriptorResponseCode);
                             }
                         }
                     },
diff --git a/nearby/service/java/com/android/server/nearby/common/bluetooth/gatt/BluetoothGattHelper.java b/nearby/service/java/com/android/server/nearby/common/bluetooth/gatt/BluetoothGattHelper.java
index 04a9a58..18a9f5f 100644
--- a/nearby/service/java/com/android/server/nearby/common/bluetooth/gatt/BluetoothGattHelper.java
+++ b/nearby/service/java/com/android/server/nearby/common/bluetooth/gatt/BluetoothGattHelper.java
@@ -16,6 +16,7 @@
 
 package com.android.server.nearby.common.bluetooth.gatt;
 
+import android.bluetooth.BluetoothGatt;
 import android.bluetooth.BluetoothGattCharacteristic;
 import android.bluetooth.BluetoothGattDescriptor;
 import android.bluetooth.le.ScanFilter;
@@ -30,8 +31,8 @@
 import com.android.server.nearby.common.bluetooth.BluetoothException;
 import com.android.server.nearby.common.bluetooth.testability.android.bluetooth.BluetoothAdapter;
 import com.android.server.nearby.common.bluetooth.testability.android.bluetooth.BluetoothDevice;
-import com.android.server.nearby.common.bluetooth.testability.android.bluetooth.BluetoothGatt;
 import com.android.server.nearby.common.bluetooth.testability.android.bluetooth.BluetoothGattCallback;
+import com.android.server.nearby.common.bluetooth.testability.android.bluetooth.BluetoothGattWrapper;
 import com.android.server.nearby.common.bluetooth.testability.android.bluetooth.le.BluetoothLeScanner;
 import com.android.server.nearby.common.bluetooth.testability.android.bluetooth.le.ScanCallback;
 import com.android.server.nearby.common.bluetooth.testability.android.bluetooth.le.ScanResult;
@@ -56,7 +57,8 @@
 import javax.annotation.concurrent.GuardedBy;
 
 /**
- * Wrapper of {@link BluetoothGatt} that provides blocking methods, errors and timeout handling.
+ * Wrapper of {@link BluetoothGattWrapper} that provides blocking methods, errors and timeout
+ * handling.
  */
 @SuppressWarnings("Guava") // java.util.Optional is not available until API 24
 public class BluetoothGattHelper {
@@ -109,7 +111,7 @@
     final BluetoothGattCallback mBluetoothGattCallback =
             new InternalBluetoothGattCallback();
     @VisibleForTesting
-    final ConcurrentMap<BluetoothGatt, BluetoothGattConnection> mConnections =
+    final ConcurrentMap<BluetoothGattWrapper, BluetoothGattConnection> mConnections =
             new ConcurrentHashMap<>();
 
     private final Context mApplicationContext;
@@ -233,7 +235,7 @@
 
                     @GuardedBy("mLock")
                     @Nullable(/* null before operation is executed */)
-                    private BluetoothGatt mBluetoothGatt;
+                    private BluetoothGattWrapper mBluetoothGatt;
 
                     @Override
                     public void run() throws BluetoothException {
@@ -241,15 +243,15 @@
                             if (mIsCanceled) {
                                 return;
                             }
-                            BluetoothGatt bluetoothGatt;
+                            BluetoothGattWrapper bluetoothGattWrapper;
                             Log.d(TAG, "Use LE transport");
-                            bluetoothGatt =
+                            bluetoothGattWrapper =
                                     bluetoothDevice.connectGatt(
                                             mApplicationContext,
                                             options.autoConnect(),
                                             mBluetoothGattCallback,
                                             android.bluetooth.BluetoothDevice.TRANSPORT_LE);
-                            if (bluetoothGatt == null) {
+                            if (bluetoothGattWrapper == null) {
                                 throw new BluetoothException("connectGatt() returned null.");
                             }
 
@@ -270,7 +272,7 @@
                                     // here until true is returned.
                                     int connectionPriority = connectionPriorityOption.get();
                                     long startTimeMillis = System.currentTimeMillis();
-                                    while (!bluetoothGatt.requestConnectionPriority(
+                                    while (!bluetoothGattWrapper.requestConnectionPriority(
                                             connectionPriority)) {
                                         if (System.currentTimeMillis() - startTimeMillis
                                                 > options.connectionTimeoutMillis()) {
@@ -292,15 +294,15 @@
                                 }
                             } catch (Exception e) {
                                 // Make sure to clean connection.
-                                bluetoothGatt.disconnect();
-                                bluetoothGatt.close();
+                                bluetoothGattWrapper.disconnect();
+                                bluetoothGattWrapper.close();
                                 throw e;
                             }
 
                             BluetoothGattConnection connection = new BluetoothGattConnection(
-                                    bluetoothGatt, mBluetoothOperationExecutor, options);
-                            mConnections.put(bluetoothGatt, connection);
-                            mBluetoothGatt = bluetoothGatt;
+                                    bluetoothGattWrapper, mBluetoothOperationExecutor, options);
+                            mConnections.put(bluetoothGattWrapper, connection);
+                            mBluetoothGatt = bluetoothGattWrapper;
                         }
                     }
 
@@ -312,13 +314,13 @@
                                 return;
                             }
                             mIsCanceled = true;
-                            BluetoothGatt bluetoothGatt = mBluetoothGatt;
-                            if (bluetoothGatt == null) {
+                            BluetoothGattWrapper bluetoothGattWrapper = mBluetoothGatt;
+                            if (bluetoothGattWrapper == null) {
                                 return;
                             }
-                            mConnections.remove(bluetoothGatt);
-                            bluetoothGatt.disconnect();
-                            bluetoothGatt.close();
+                            mConnections.remove(bluetoothGattWrapper);
+                            bluetoothGattWrapper.disconnect();
+                            bluetoothGattWrapper.close();
                         }
                     }
                 };
@@ -335,7 +337,7 @@
         return result;
     }
 
-    private BluetoothGattConnection getConnectionByGatt(BluetoothGatt gatt)
+    private BluetoothGattConnection getConnectionByGatt(BluetoothGattWrapper gatt)
             throws BluetoothException {
         BluetoothGattConnection connection = mConnections.get(gatt);
         if (connection == null) {
@@ -347,7 +349,7 @@
     private class InternalBluetoothGattCallback extends BluetoothGattCallback {
 
         @Override
-        public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
+        public void onConnectionStateChange(BluetoothGattWrapper gatt, int status, int newState) {
             BluetoothGattConnection connection;
             BluetoothDevice device = gatt.getDevice();
             switch (newState) {
@@ -430,7 +432,7 @@
         }
 
         @Override
-        public void onMtuChanged(BluetoothGatt gatt, int mtu, int status) {
+        public void onMtuChanged(BluetoothGattWrapper gatt, int mtu, int status) {
             BluetoothGattConnection connection = mConnections.get(gatt);
             BluetoothDevice device = gatt.getDevice();
             if (connection == null) {
@@ -460,13 +462,13 @@
         }
 
         @Override
-        public void onServicesDiscovered(BluetoothGatt gatt, int status) {
+        public void onServicesDiscovered(BluetoothGattWrapper gatt, int status) {
             mBluetoothOperationExecutor.notifyCompletion(
                     new Operation<Void>(OperationType.DISCOVER_SERVICES_INTERNAL, gatt), status);
         }
 
         @Override
-        public void onCharacteristicRead(BluetoothGatt gatt,
+        public void onCharacteristicRead(BluetoothGattWrapper gatt,
                 BluetoothGattCharacteristic characteristic, int status) {
             mBluetoothOperationExecutor.notifyCompletion(
                     new Operation<byte[]>(OperationType.READ_CHARACTERISTIC, gatt, characteristic),
@@ -474,14 +476,14 @@
         }
 
         @Override
-        public void onCharacteristicWrite(BluetoothGatt gatt,
+        public void onCharacteristicWrite(BluetoothGattWrapper gatt,
                 BluetoothGattCharacteristic characteristic, int status) {
             mBluetoothOperationExecutor.notifyCompletion(new Operation<Void>(
                     OperationType.WRITE_CHARACTERISTIC, gatt, characteristic), status);
         }
 
         @Override
-        public void onDescriptorRead(BluetoothGatt gatt, BluetoothGattDescriptor descriptor,
+        public void onDescriptorRead(BluetoothGattWrapper gatt, BluetoothGattDescriptor descriptor,
                 int status) {
             mBluetoothOperationExecutor.notifyCompletion(
                     new Operation<byte[]>(OperationType.READ_DESCRIPTOR, gatt, descriptor), status,
@@ -489,7 +491,7 @@
         }
 
         @Override
-        public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor,
+        public void onDescriptorWrite(BluetoothGattWrapper gatt, BluetoothGattDescriptor descriptor,
                 int status) {
             Log.d(TAG, String.format("onDescriptorWrite %s, %s, %d",
                     gatt.getDevice(), descriptor.getUuid(), status));
@@ -498,19 +500,19 @@
         }
 
         @Override
-        public void onReadRemoteRssi(BluetoothGatt gatt, int rssi, int status) {
+        public void onReadRemoteRssi(BluetoothGattWrapper gatt, int rssi, int status) {
             mBluetoothOperationExecutor.notifyCompletion(
                     new Operation<Integer>(OperationType.READ_RSSI, gatt), status, rssi);
         }
 
         @Override
-        public void onReliableWriteCompleted(BluetoothGatt gatt, int status) {
+        public void onReliableWriteCompleted(BluetoothGattWrapper gatt, int status) {
             mBluetoothOperationExecutor.notifyCompletion(
                     new Operation<Void>(OperationType.WRITE_RELIABLE, gatt), status);
         }
 
         @Override
-        public void onCharacteristicChanged(BluetoothGatt gatt,
+        public void onCharacteristicChanged(BluetoothGattWrapper gatt,
                 BluetoothGattCharacteristic characteristic) {
             byte[] value = characteristic.getValue();
             if (value == null) {
diff --git a/nearby/service/java/com/android/server/nearby/common/bluetooth/testability/android/bluetooth/BluetoothDevice.java b/nearby/service/java/com/android/server/nearby/common/bluetooth/testability/android/bluetooth/BluetoothDevice.java
index c767af6..5b45f61 100644
--- a/nearby/service/java/com/android/server/nearby/common/bluetooth/testability/android/bluetooth/BluetoothDevice.java
+++ b/nearby/service/java/com/android/server/nearby/common/bluetooth/testability/android/bluetooth/BluetoothDevice.java
@@ -144,14 +144,14 @@
      * android.bluetooth.BluetoothGattCallback)}.
      */
     @Nullable(/* when bt service is not available */)
-    public BluetoothGatt connectGatt(Context context, boolean autoConnect,
+    public BluetoothGattWrapper connectGatt(Context context, boolean autoConnect,
             BluetoothGattCallback callback) {
         android.bluetooth.BluetoothGatt gatt =
                 mWrappedBluetoothDevice.connectGatt(context, autoConnect, callback.unwrap());
         if (gatt == null) {
             return null;
         }
-        return BluetoothGatt.wrap(gatt);
+        return BluetoothGattWrapper.wrap(gatt);
     }
 
     /**
@@ -160,7 +160,7 @@
      */
     @TargetApi(23)
     @Nullable(/* when bt service is not available */)
-    public BluetoothGatt connectGatt(Context context, boolean autoConnect,
+    public BluetoothGattWrapper connectGatt(Context context, boolean autoConnect,
             BluetoothGattCallback callback, int transport) {
         android.bluetooth.BluetoothGatt gatt =
                 mWrappedBluetoothDevice.connectGatt(
@@ -168,7 +168,7 @@
         if (gatt == null) {
             return null;
         }
-        return BluetoothGatt.wrap(gatt);
+        return BluetoothGattWrapper.wrap(gatt);
     }
 
 
diff --git a/nearby/service/java/com/android/server/nearby/common/bluetooth/testability/android/bluetooth/BluetoothGattCallback.java b/nearby/service/java/com/android/server/nearby/common/bluetooth/testability/android/bluetooth/BluetoothGattCallback.java
index 33d68cd..d36cfa2 100644
--- a/nearby/service/java/com/android/server/nearby/common/bluetooth/testability/android/bluetooth/BluetoothGattCallback.java
+++ b/nearby/service/java/com/android/server/nearby/common/bluetooth/testability/android/bluetooth/BluetoothGattCallback.java
@@ -31,26 +31,26 @@
      * See {@link android.bluetooth.BluetoothGattCallback#onConnectionStateChange(
      * android.bluetooth.BluetoothGatt, int, int)}
      */
-    public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {}
+    public void onConnectionStateChange(BluetoothGattWrapper gatt, int status, int newState) {}
 
     /**
      * See {@link android.bluetooth.BluetoothGattCallback#onServicesDiscovered(
      * android.bluetooth.BluetoothGatt,int)}
      */
-    public void onServicesDiscovered(BluetoothGatt gatt, int status) {}
+    public void onServicesDiscovered(BluetoothGattWrapper gatt, int status) {}
 
     /**
      * See {@link android.bluetooth.BluetoothGattCallback#onCharacteristicRead(
      * android.bluetooth.BluetoothGatt, BluetoothGattCharacteristic, int)}
      */
-    public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic,
-            int status) {}
+    public void onCharacteristicRead(BluetoothGattWrapper gatt, BluetoothGattCharacteristic
+            characteristic, int status) {}
 
     /**
      * See {@link android.bluetooth.BluetoothGattCallback#onCharacteristicWrite(
      * android.bluetooth.BluetoothGatt, BluetoothGattCharacteristic, int)}
      */
-    public void onCharacteristicWrite(BluetoothGatt gatt,
+    public void onCharacteristicWrite(BluetoothGattWrapper gatt,
             BluetoothGattCharacteristic characteristic, int status) {}
 
     /**
@@ -58,40 +58,40 @@
      * android.bluetooth.BluetoothGatt, BluetoothGattDescriptor, int)}
      */
     public void onDescriptorRead(
-            BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {}
+            BluetoothGattWrapper gatt, BluetoothGattDescriptor descriptor, int status) {}
 
     /**
      * See {@link android.bluetooth.BluetoothGattCallback#onDescriptorWrite(
      * android.bluetooth.BluetoothGatt, BluetoothGattDescriptor, int)}
      */
-    public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor,
+    public void onDescriptorWrite(BluetoothGattWrapper gatt, BluetoothGattDescriptor descriptor,
             int status) {}
 
     /**
      * See {@link android.bluetooth.BluetoothGattCallback#onReadRemoteRssi(
      * android.bluetooth.BluetoothGatt, int, int)}
      */
-    public void onReadRemoteRssi(BluetoothGatt gatt, int rssi, int status) {}
+    public void onReadRemoteRssi(BluetoothGattWrapper gatt, int rssi, int status) {}
 
     /**
      * See {@link android.bluetooth.BluetoothGattCallback#onReliableWriteCompleted(
      * android.bluetooth.BluetoothGatt, int)}
      */
-    public void onReliableWriteCompleted(BluetoothGatt gatt, int status) {}
+    public void onReliableWriteCompleted(BluetoothGattWrapper gatt, int status) {}
 
     /**
      * See
      * {@link android.bluetooth.BluetoothGattCallback#onMtuChanged(android.bluetooth.BluetoothGatt,
      * int, int)}
      */
-    public void onMtuChanged(BluetoothGatt gatt, int mtu, int status) {}
+    public void onMtuChanged(BluetoothGattWrapper gatt, int mtu, int status) {}
 
     /**
      * See
      * {@link android.bluetooth.BluetoothGattCallback#onCharacteristicChanged(
      * android.bluetooth.BluetoothGatt, BluetoothGattCharacteristic)}
      */
-    public void onCharacteristicChanged(BluetoothGatt gatt,
+    public void onCharacteristicChanged(BluetoothGattWrapper gatt,
             BluetoothGattCharacteristic characteristic) {}
 
     /** Unwraps a Bluetooth Gatt callback. */
@@ -104,63 +104,66 @@
         @Override
         public void onConnectionStateChange(android.bluetooth.BluetoothGatt gatt, int status,
                 int newState) {
-            BluetoothGattCallback.this.onConnectionStateChange(BluetoothGatt.wrap(gatt), status,
-                    newState);
+            BluetoothGattCallback.this.onConnectionStateChange(BluetoothGattWrapper.wrap(gatt),
+                    status, newState);
         }
 
         @Override
         public void onServicesDiscovered(android.bluetooth.BluetoothGatt gatt, int status) {
-            BluetoothGattCallback.this.onServicesDiscovered(BluetoothGatt.wrap(gatt), status);
+            BluetoothGattCallback.this.onServicesDiscovered(BluetoothGattWrapper.wrap(gatt),
+                    status);
         }
 
         @Override
         public void onCharacteristicRead(android.bluetooth.BluetoothGatt gatt,
                 BluetoothGattCharacteristic characteristic, int status) {
             BluetoothGattCallback.this.onCharacteristicRead(
-                    BluetoothGatt.wrap(gatt), characteristic, status);
+                    BluetoothGattWrapper.wrap(gatt), characteristic, status);
         }
 
         @Override
         public void onCharacteristicWrite(android.bluetooth.BluetoothGatt gatt,
                 BluetoothGattCharacteristic characteristic, int status) {
             BluetoothGattCallback.this.onCharacteristicWrite(
-                    BluetoothGatt.wrap(gatt), characteristic, status);
+                    BluetoothGattWrapper.wrap(gatt), characteristic, status);
         }
 
         @Override
         public void onDescriptorRead(android.bluetooth.BluetoothGatt gatt,
                 BluetoothGattDescriptor descriptor, int status) {
             BluetoothGattCallback.this.onDescriptorRead(
-                    BluetoothGatt.wrap(gatt), descriptor, status);
+                    BluetoothGattWrapper.wrap(gatt), descriptor, status);
         }
 
         @Override
         public void onDescriptorWrite(android.bluetooth.BluetoothGatt gatt,
                 BluetoothGattDescriptor descriptor, int status) {
             BluetoothGattCallback.this.onDescriptorWrite(
-                    BluetoothGatt.wrap(gatt), descriptor, status);
+                    BluetoothGattWrapper.wrap(gatt), descriptor, status);
         }
 
         @Override
         public void onReadRemoteRssi(android.bluetooth.BluetoothGatt gatt, int rssi, int status) {
-            BluetoothGattCallback.this.onReadRemoteRssi(BluetoothGatt.wrap(gatt), rssi, status);
+            BluetoothGattCallback.this.onReadRemoteRssi(BluetoothGattWrapper.wrap(gatt), rssi,
+                    status);
         }
 
         @Override
         public void onReliableWriteCompleted(android.bluetooth.BluetoothGatt gatt, int status) {
-            BluetoothGattCallback.this.onReliableWriteCompleted(BluetoothGatt.wrap(gatt), status);
+            BluetoothGattCallback.this.onReliableWriteCompleted(BluetoothGattWrapper.wrap(gatt),
+                    status);
         }
 
         @Override
         public void onMtuChanged(android.bluetooth.BluetoothGatt gatt, int mtu, int status) {
-            BluetoothGattCallback.this.onMtuChanged(BluetoothGatt.wrap(gatt), mtu, status);
+            BluetoothGattCallback.this.onMtuChanged(BluetoothGattWrapper.wrap(gatt), mtu, status);
         }
 
         @Override
         public void onCharacteristicChanged(android.bluetooth.BluetoothGatt gatt,
                 BluetoothGattCharacteristic characteristic) {
             BluetoothGattCallback.this.onCharacteristicChanged(
-                    BluetoothGatt.wrap(gatt), characteristic);
+                    BluetoothGattWrapper.wrap(gatt), characteristic);
         }
     }
 }
diff --git a/nearby/service/java/com/android/server/nearby/common/bluetooth/testability/android/bluetooth/BluetoothGatt.java b/nearby/service/java/com/android/server/nearby/common/bluetooth/testability/android/bluetooth/BluetoothGattWrapper.java
similarity index 69%
rename from nearby/service/java/com/android/server/nearby/common/bluetooth/testability/android/bluetooth/BluetoothGatt.java
rename to nearby/service/java/com/android/server/nearby/common/bluetooth/testability/android/bluetooth/BluetoothGattWrapper.java
index bec762a..453ee5d 100644
--- a/nearby/service/java/com/android/server/nearby/common/bluetooth/testability/android/bluetooth/BluetoothGatt.java
+++ b/nearby/service/java/com/android/server/nearby/common/bluetooth/testability/android/bluetooth/BluetoothGattWrapper.java
@@ -30,40 +30,11 @@
 import javax.annotation.Nullable;
 
 /** Mockable wrapper of {@link android.bluetooth.BluetoothGatt}. */
-@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2)
-public class BluetoothGatt {
-
-    /** See {@link android.bluetooth.BluetoothGatt#STATE_CONNECTED}. */
-    public static final int STATE_CONNECTED = android.bluetooth.BluetoothGatt.STATE_CONNECTED;
-
-    /** See {@link android.bluetooth.BluetoothGatt#STATE_DISCONNECTED}. */
-    public static final int STATE_DISCONNECTED = android.bluetooth.BluetoothGatt.STATE_DISCONNECTED;
-
-    /** See {@link android.bluetooth.BluetoothGatt#GATT_REQUEST_NOT_SUPPORTED}. */
-    public static final int GATT_REQUEST_NOT_SUPPORTED =
-            android.bluetooth.BluetoothGatt.GATT_REQUEST_NOT_SUPPORTED;
-
-    /** See {@link android.bluetooth.BluetoothGatt#GATT_SUCCESS}. */
-    public static final int GATT_SUCCESS = android.bluetooth.BluetoothGatt.GATT_SUCCESS;
-
-    /** See {@link android.bluetooth.BluetoothGatt#GATT_FAILURE}. */
-    public static final int GATT_FAILURE = android.bluetooth.BluetoothGatt.GATT_FAILURE;
-
-    /** See {@link android.bluetooth.BluetoothGatt#CONNECTION_PRIORITY_BALANCED}. */
-    public static final int CONNECTION_PRIORITY_BALANCED =
-            android.bluetooth.BluetoothGatt.CONNECTION_PRIORITY_BALANCED;
-
-    /** See {@link android.bluetooth.BluetoothGatt#CONNECTION_PRIORITY_HIGH}. */
-    public static final int CONNECTION_PRIORITY_HIGH =
-            android.bluetooth.BluetoothGatt.CONNECTION_PRIORITY_HIGH;
-
-    /** See {@link android.bluetooth.BluetoothGatt#CONNECTION_PRIORITY_LOW_POWER}. */
-    public static final int CONNECTION_PRIORITY_LOW_POWER =
-            android.bluetooth.BluetoothGatt.CONNECTION_PRIORITY_LOW_POWER;
-
+@TargetApi(Build.VERSION_CODES.TIRAMISU)
+public class BluetoothGattWrapper {
     private final android.bluetooth.BluetoothGatt mWrappedBluetoothGatt;
 
-    private BluetoothGatt(android.bluetooth.BluetoothGatt bluetoothGatt) {
+    private BluetoothGattWrapper(android.bluetooth.BluetoothGatt bluetoothGatt) {
         mWrappedBluetoothGatt = bluetoothGatt;
     }
 
@@ -113,10 +84,12 @@
     }
 
     /**
-     * See {@link android.bluetooth.BluetoothGatt#writeCharacteristic(BluetoothGattCharacteristic)}.
+     * See {@link android.bluetooth.BluetoothGatt#writeCharacteristic(BluetoothGattCharacteristic,
+     * byte[], int)} .
      */
-    public boolean writeCharacteristic(BluetoothGattCharacteristic characteristic) {
-        return mWrappedBluetoothGatt.writeCharacteristic(characteristic);
+    public int writeCharacteristic(BluetoothGattCharacteristic characteristic, byte[] value,
+            int writeType) {
+        return mWrappedBluetoothGatt.writeCharacteristic(characteristic, value, writeType);
     }
 
     /** See {@link android.bluetooth.BluetoothGatt#readDescriptor(BluetoothGattDescriptor)}. */
@@ -124,9 +97,12 @@
         return mWrappedBluetoothGatt.readDescriptor(descriptor);
     }
 
-    /** See {@link android.bluetooth.BluetoothGatt#writeDescriptor(BluetoothGattDescriptor)}. */
-    public boolean writeDescriptor(BluetoothGattDescriptor descriptor) {
-        return mWrappedBluetoothGatt.writeDescriptor(descriptor);
+    /**
+     * See {@link android.bluetooth.BluetoothGatt#writeDescriptor(BluetoothGattDescriptor,
+     * byte[])}.
+     */
+    public int writeDescriptor(BluetoothGattDescriptor descriptor, byte[] value) {
+        return mWrappedBluetoothGatt.writeDescriptor(descriptor, value);
     }
 
     /** See {@link android.bluetooth.BluetoothGatt#readRemoteRssi()}. */
@@ -172,10 +148,10 @@
         if (o == this) {
             return true;
         }
-        if (!(o instanceof BluetoothGatt)) {
+        if (!(o instanceof BluetoothGattWrapper)) {
             return false;
         }
-        return mWrappedBluetoothGatt.equals(((BluetoothGatt) o).unwrap());
+        return mWrappedBluetoothGatt.equals(((BluetoothGattWrapper) o).unwrap());
     }
 
     /** Unwraps a Bluetooth Gatt instance. */
@@ -184,7 +160,7 @@
     }
 
     /** Wraps a Bluetooth Gatt instance. */
-    public static BluetoothGatt wrap(android.bluetooth.BluetoothGatt gatt) {
-        return new BluetoothGatt(gatt);
+    public static BluetoothGattWrapper wrap(android.bluetooth.BluetoothGatt gatt) {
+        return new BluetoothGattWrapper(gatt);
     }
 }
diff --git a/nearby/service/java/com/android/server/nearby/common/bluetooth/util/BluetoothGattUtils.java b/nearby/service/java/com/android/server/nearby/common/bluetooth/util/BluetoothGattUtils.java
index 1094060..bb51920 100644
--- a/nearby/service/java/com/android/server/nearby/common/bluetooth/util/BluetoothGattUtils.java
+++ b/nearby/service/java/com/android/server/nearby/common/bluetooth/util/BluetoothGattUtils.java
@@ -21,11 +21,6 @@
 import android.bluetooth.BluetoothGattDescriptor;
 import android.bluetooth.BluetoothGattService;
 
-import com.android.server.nearby.common.bluetooth.BluetoothException;
-
-import java.lang.reflect.Field;
-import java.util.Arrays;
-
 import javax.annotation.Nullable;
 
 /**
@@ -65,76 +60,6 @@
         }
     }
 
-    /** Clones a {@link BluetoothGattDescriptor} so the value can be changed thread-safely. */
-    public static BluetoothGattDescriptor clone(BluetoothGattDescriptor descriptor)
-            throws BluetoothException {
-        BluetoothGattDescriptor result =
-                new BluetoothGattDescriptor(descriptor.getUuid(), descriptor.getPermissions());
-        try {
-            try {
-                // TODO(b/201463121): remove usage of reflection.
-                Field instanceIdField = BluetoothGattDescriptor.class.getDeclaredField("mInstance");
-                instanceIdField.setAccessible(true);
-                instanceIdField.set(result, instanceIdField.get(descriptor));
-            } catch (NoSuchFieldException e) {
-                // This field doesn't seem to exist in early implementation so just ignore
-                // instanceId in this case.
-            }
-
-            // TODO(b/201463121): remove usage of reflection.
-            Field characteristicField =
-                    BluetoothGattDescriptor.class.getDeclaredField("mCharacteristic");
-            characteristicField.setAccessible(true);
-            characteristicField.set(result, characteristicField.get(descriptor));
-            byte[] value = descriptor.getValue();
-            if (value != null) {
-                result.setValue(Arrays.copyOf(value, value.length));
-            }
-        } catch (NoSuchFieldException e) {
-            throw new BluetoothException("Cannot clone descriptor.", e);
-        } catch (IllegalAccessException e) {
-            throw new BluetoothException("Cannot clone descriptor.", e);
-        } catch (IllegalArgumentException e) {
-            throw new BluetoothException("Cannot clone descriptor.", e);
-        }
-        return result;
-    }
-
-    /** Clones a {@link BluetoothGattCharacteristic} so the value can be changed thread-safely. */
-    public static BluetoothGattCharacteristic clone(BluetoothGattCharacteristic characteristic)
-            throws BluetoothException {
-        BluetoothGattCharacteristic result =
-                new BluetoothGattCharacteristic(characteristic.getUuid(),
-                        characteristic.getProperties(), characteristic.getPermissions());
-        try {
-            // TODO(b/201463121): remove usage of reflection.
-            Field instanceIdField = BluetoothGattCharacteristic.class.getDeclaredField("mInstance");
-            // TODO(b/201463121): remove usage of reflection.
-            Field serviceField = BluetoothGattCharacteristic.class.getDeclaredField("mService");
-            // TODO(b/201463121): remove usage of reflection.
-            Field descriptorField =
-                    BluetoothGattCharacteristic.class.getDeclaredField("mDescriptors");
-            instanceIdField.setAccessible(true);
-            serviceField.setAccessible(true);
-            descriptorField.setAccessible(true);
-            instanceIdField.set(result, instanceIdField.get(characteristic));
-            serviceField.set(result, serviceField.get(characteristic));
-            descriptorField.set(result, descriptorField.get(characteristic));
-            byte[] value = characteristic.getValue();
-            if (value != null) {
-                result.setValue(Arrays.copyOf(value, value.length));
-            }
-            result.setWriteType(characteristic.getWriteType());
-        } catch (NoSuchFieldException e) {
-            throw new BluetoothException("Cannot clone characteristic.", e);
-        } catch (IllegalAccessException e) {
-            throw new BluetoothException("Cannot clone characteristic.", e);
-        } catch (IllegalArgumentException e) {
-            throw new BluetoothException("Cannot clone characteristic.", e);
-        }
-        return result;
-    }
-
     /** Creates a user-readable string from a {@link BluetoothGattDescriptor}. */
     public static String toString(@Nullable BluetoothGattDescriptor descriptor) {
         if (descriptor == null) {
diff --git a/nearby/tests/src/com/android/server/nearby/common/bluetooth/gatt/BluetoothGattConnectionTest.java b/nearby/tests/src/com/android/server/nearby/common/bluetooth/gatt/BluetoothGattConnectionTest.java
index 9776836..13802ee 100644
--- a/nearby/tests/src/com/android/server/nearby/common/bluetooth/gatt/BluetoothGattConnectionTest.java
+++ b/nearby/tests/src/com/android/server/nearby/common/bluetooth/gatt/BluetoothGattConnectionTest.java
@@ -18,6 +18,8 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.anyLong;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.ArgumentMatchers.isA;
@@ -33,6 +35,7 @@
 import android.bluetooth.BluetoothGattCharacteristic;
 import android.bluetooth.BluetoothGattDescriptor;
 import android.bluetooth.BluetoothGattService;
+import android.bluetooth.BluetoothStatusCodes;
 import android.os.Build.VERSION;
 import android.os.Build.VERSION_CODES;
 
@@ -43,7 +46,7 @@
 import com.android.server.nearby.common.bluetooth.gatt.BluetoothGattConnection.ChangeObserver;
 import com.android.server.nearby.common.bluetooth.gatt.BluetoothGattHelper.OperationType;
 import com.android.server.nearby.common.bluetooth.testability.android.bluetooth.BluetoothDevice;
-import com.android.server.nearby.common.bluetooth.testability.android.bluetooth.BluetoothGatt;
+import com.android.server.nearby.common.bluetooth.testability.android.bluetooth.BluetoothGattWrapper;
 import com.android.server.nearby.common.bluetooth.util.BluetoothOperationExecutor;
 import com.android.server.nearby.common.bluetooth.util.BluetoothOperationExecutor.Operation;
 import com.android.server.nearby.common.bluetooth.util.BluetoothOperationExecutor.SynchronousOperation;
@@ -75,7 +78,7 @@
             BluetoothGattHelper.ConnectionOptions.builder().build();
 
     @Mock
-    private BluetoothGatt mMockBluetoothGatt;
+    private BluetoothGattWrapper mMockBluetoothGattWrapper;
     @Mock
     private BluetoothDevice mMockBluetoothDevice;
     @Mock
@@ -115,26 +118,31 @@
         initMocks(this);
 
         mBluetoothGattConnection = new BluetoothGattConnection(
-                mMockBluetoothGatt,
+                mMockBluetoothGattWrapper,
                 mMockBluetoothOperationExecutor,
                 CONNECTION_OPTIONS);
         mBluetoothGattConnection.onConnected();
 
-        when(mMockBluetoothGatt.getDevice()).thenReturn(mMockBluetoothDevice);
-        when(mMockBluetoothGatt.discoverServices()).thenReturn(true);
-        when(mMockBluetoothGatt.refresh()).thenReturn(true);
-        when(mMockBluetoothGatt.readCharacteristic(mMockBluetoothGattCharacteristic))
+        when(mMockBluetoothGattWrapper.getDevice()).thenReturn(mMockBluetoothDevice);
+        when(mMockBluetoothGattWrapper.discoverServices()).thenReturn(true);
+        when(mMockBluetoothGattWrapper.refresh()).thenReturn(true);
+        when(mMockBluetoothGattWrapper.readCharacteristic(mMockBluetoothGattCharacteristic))
                 .thenReturn(true);
-        when(mMockBluetoothGatt
-                .writeCharacteristic(ArgumentMatchers.<BluetoothGattCharacteristic>any()))
+        when(mMockBluetoothGattWrapper
+                .writeCharacteristic(ArgumentMatchers.<BluetoothGattCharacteristic>any(), any(),
+                        anyInt()))
+                .thenReturn(BluetoothStatusCodes.SUCCESS);
+        when(mMockBluetoothGattWrapper.readDescriptor(mMockBluetoothGattDescriptor))
                 .thenReturn(true);
-        when(mMockBluetoothGatt.readDescriptor(mMockBluetoothGattDescriptor)).thenReturn(true);
-        when(mMockBluetoothGatt.writeDescriptor(ArgumentMatchers.<BluetoothGattDescriptor>any()))
+        when(mMockBluetoothGattWrapper.writeDescriptor(
+                ArgumentMatchers.<BluetoothGattDescriptor>any(), any()))
+                .thenReturn(BluetoothStatusCodes.SUCCESS);
+        when(mMockBluetoothGattWrapper.readRemoteRssi()).thenReturn(true);
+        when(mMockBluetoothGattWrapper.requestConnectionPriority(CONNECTION_PRIORITY))
                 .thenReturn(true);
-        when(mMockBluetoothGatt.readRemoteRssi()).thenReturn(true);
-        when(mMockBluetoothGatt.requestConnectionPriority(CONNECTION_PRIORITY)).thenReturn(true);
-        when(mMockBluetoothGatt.requestMtu(MTU_REQUEST)).thenReturn(true);
-        when(mMockBluetoothGatt.getServices()).thenReturn(Arrays.asList(mMockBluetoothGattService));
+        when(mMockBluetoothGattWrapper.requestMtu(MTU_REQUEST)).thenReturn(true);
+        when(mMockBluetoothGattWrapper.getServices())
+                .thenReturn(Arrays.asList(mMockBluetoothGattService));
         when(mMockBluetoothGattService.getUuid()).thenReturn(SERVICE_UUID);
         when(mMockBluetoothGattService.getCharacteristics())
                 .thenReturn(Arrays.asList(mMockBluetoothGattCharacteristic));
@@ -171,7 +179,7 @@
 
     public void test_isConnected_false_beforeConnection() {
         mBluetoothGattConnection = new BluetoothGattConnection(
-                mMockBluetoothGatt,
+                mMockBluetoothGattWrapper,
                 mMockBluetoothOperationExecutor,
                 CONNECTION_OPTIONS);
 
@@ -205,7 +213,7 @@
         mOperationCaptor.getValue().run();
 
         assertThat(result).isEqualTo(mMockBluetoothGattService);
-        verify(mMockBluetoothGatt).discoverServices();
+        verify(mMockBluetoothGattWrapper).discoverServices();
     }
 
     public void test_getService_alreadyDiscovered() throws Exception {
@@ -222,7 +230,8 @@
     }
 
     public void test_getService_notFound() throws Exception {
-        when(mMockBluetoothGatt.getServices()).thenReturn(Arrays.<BluetoothGattService>asList());
+        when(mMockBluetoothGattWrapper.getServices()).thenReturn(
+                Arrays.<BluetoothGattService>asList());
 
         try {
             mBluetoothGattConnection.getService(SERVICE_UUID);
@@ -232,7 +241,7 @@
     }
 
     public void test_getService_moreThanOne() throws Exception {
-        when(mMockBluetoothGatt.getServices())
+        when(mMockBluetoothGattWrapper.getServices())
                 .thenReturn(Arrays.asList(mMockBluetoothGattService, mMockBluetoothGattService));
 
         try {
@@ -276,7 +285,7 @@
     public void test_getCharacteristic_moreThanOneService() throws Exception {
         // Add a new service with the same service UUID as our existing one, but add a different
         // characteristic inside of it.
-        when(mMockBluetoothGatt.getServices())
+        when(mMockBluetoothGattWrapper.getServices())
                 .thenReturn(Arrays.asList(mMockBluetoothGattService, mMockBluetoothGattService2));
         when(mMockBluetoothGattService2.getUuid()).thenReturn(SERVICE_UUID);
         when(mMockBluetoothGattService2.getCharacteristics())
@@ -345,12 +354,12 @@
                         mOperationCaptor.capture(),
                         eq(BluetoothGattConnection.SLOW_OPERATION_TIMEOUT_MILLIS));
         mOperationCaptor.getValue().run();
-        verify(mMockBluetoothGatt).discoverServices();
-        verify(mMockBluetoothGatt, never()).refresh();
+        verify(mMockBluetoothGattWrapper).discoverServices();
+        verify(mMockBluetoothGattWrapper, never()).refresh();
     }
 
     public void test_discoverServices_serviceChange() throws Exception {
-        when(mMockBluetoothGatt.getService(ReservedUuids.Services.GENERIC_ATTRIBUTE))
+        when(mMockBluetoothGattWrapper.getService(ReservedUuids.Services.GENERIC_ATTRIBUTE))
                 .thenReturn(mMockBluetoothGattService);
         when(mMockBluetoothGattService
                 .getCharacteristic(ReservedUuids.Characteristics.SERVICE_CHANGE))
@@ -364,11 +373,11 @@
                 .execute(
                         mOperationCaptor.capture(),
                         eq(BluetoothGattConnection.SLOW_OPERATION_TIMEOUT_MILLIS));
-        verify(mMockBluetoothGatt).refresh();
+        verify(mMockBluetoothGattWrapper).refresh();
     }
 
     public void test_discoverServices_SelfDefinedServiceDynamic() throws Exception {
-        when(mMockBluetoothGatt.getService(BluetoothConsts.SERVICE_DYNAMIC_SERVICE))
+        when(mMockBluetoothGattWrapper.getService(BluetoothConsts.SERVICE_DYNAMIC_SERVICE))
                 .thenReturn(mMockBluetoothGattService);
         when(mMockBluetoothGattService
                 .getCharacteristic(BluetoothConsts.SERVICE_DYNAMIC_CHARACTERISTIC))
@@ -382,7 +391,7 @@
                 .execute(
                         mOperationCaptor.capture(),
                         eq(BluetoothGattConnection.SLOW_OPERATION_TIMEOUT_MILLIS));
-        verify(mMockBluetoothGatt).refresh();
+        verify(mMockBluetoothGattWrapper).refresh();
     }
 
     public void test_discoverServices_refreshWithGattErrorOnMncAbove() throws Exception {
@@ -402,7 +411,7 @@
                 .execute(
                         mOperationCaptor.capture(),
                         eq(BluetoothGattConnection.SLOW_OPERATION_TIMEOUT_MILLIS));
-        verify(mMockBluetoothGatt).refresh();
+        verify(mMockBluetoothGattWrapper).refresh();
     }
 
     public void test_discoverServices_refreshWithGattInternalErrorOnMncAbove() throws Exception {
@@ -422,11 +431,11 @@
                 .execute(
                         mOperationCaptor.capture(),
                         eq(BluetoothGattConnection.SLOW_OPERATION_TIMEOUT_MILLIS));
-        verify(mMockBluetoothGatt).refresh();
+        verify(mMockBluetoothGattWrapper).refresh();
     }
 
     public void test_discoverServices_dynamicServices_notBonded() throws Exception {
-        when(mMockBluetoothGatt.getService(ReservedUuids.Services.GENERIC_ATTRIBUTE))
+        when(mMockBluetoothGattWrapper.getService(ReservedUuids.Services.GENERIC_ATTRIBUTE))
                 .thenReturn(mMockBluetoothGattService);
         when(mMockBluetoothGattService
                 .getCharacteristic(ReservedUuids.Characteristics.SERVICE_CHANGE))
@@ -435,14 +444,14 @@
 
         mBluetoothGattConnection.discoverServices();
 
-        verify(mMockBluetoothGatt, never()).refresh();
+        verify(mMockBluetoothGattWrapper, never()).refresh();
     }
 
     public void test_readCharacteristic() throws Exception {
         when(mMockBluetoothOperationExecutor.executeNonnull(
                 new Operation<byte[]>(
                         OperationType.READ_CHARACTERISTIC,
-                        mMockBluetoothGatt,
+                        mMockBluetoothGattWrapper,
                         mMockBluetoothGattCharacteristic),
                 BluetoothGattConnection.OPERATION_TIMEOUT_MILLIS))
                 .thenReturn(DATA);
@@ -454,14 +463,14 @@
         verify(mMockBluetoothOperationExecutor)
                 .executeNonnull(mOperationCaptor.capture(), anyLong());
         mOperationCaptor.getValue().run();
-        verify(mMockBluetoothGatt).readCharacteristic(mMockBluetoothGattCharacteristic);
+        verify(mMockBluetoothGattWrapper).readCharacteristic(mMockBluetoothGattCharacteristic);
     }
 
     public void test_readCharacteristic_by_uuid() throws Exception {
         when(mMockBluetoothOperationExecutor.executeNonnull(
                 new Operation<byte[]>(
                         OperationType.READ_CHARACTERISTIC,
-                        mMockBluetoothGatt,
+                        mMockBluetoothGattWrapper,
                         mMockBluetoothGattCharacteristic),
                 BluetoothGattConnection.OPERATION_TIMEOUT_MILLIS))
                 .thenReturn(DATA);
@@ -473,7 +482,7 @@
         verify(mMockBluetoothOperationExecutor)
                 .executeNonnull(mOperationCaptor.capture(), anyLong());
         mOperationCaptor.getValue().run();
-        verify(mMockBluetoothGatt).readCharacteristic(mMockBluetoothGattCharacteristic);
+        verify(mMockBluetoothGattWrapper).readCharacteristic(mMockBluetoothGattCharacteristic);
     }
 
     public void test_writeCharacteristic() throws Exception {
@@ -486,11 +495,11 @@
                 .execute(mOperationCaptor.capture(),
                         eq(BluetoothGattConnection.OPERATION_TIMEOUT_MILLIS));
         mOperationCaptor.getValue().run();
-        verify(mMockBluetoothGatt).writeCharacteristic(mCharacteristicCaptor.capture());
+        verify(mMockBluetoothGattWrapper).writeCharacteristic(mCharacteristicCaptor.capture(),
+                eq(DATA), eq(characteristic.getWriteType()));
         BluetoothGattCharacteristic writtenCharacteristic = mCharacteristicCaptor.getValue();
-        assertThat(writtenCharacteristic.getValue()).isEqualTo(DATA);
         assertThat(writtenCharacteristic.getUuid()).isEqualTo(CHARACTERISTIC_UUID);
-        assertThat(writtenCharacteristic).isNotEqualTo(characteristic);
+        assertThat(writtenCharacteristic).isEqualTo(characteristic);
     }
 
     public void test_writeCharacteristic_by_uuid() throws Exception {
@@ -500,16 +509,16 @@
                 .execute(mOperationCaptor.capture(),
                         eq(BluetoothGattConnection.OPERATION_TIMEOUT_MILLIS));
         mOperationCaptor.getValue().run();
-        verify(mMockBluetoothGatt).writeCharacteristic(mCharacteristicCaptor.capture());
+        verify(mMockBluetoothGattWrapper).writeCharacteristic(mCharacteristicCaptor.capture(),
+                eq(DATA), anyInt());
         BluetoothGattCharacteristic writtenCharacteristic = mCharacteristicCaptor.getValue();
-        assertThat(writtenCharacteristic.getValue()).isEqualTo(DATA);
         assertThat(writtenCharacteristic.getUuid()).isEqualTo(CHARACTERISTIC_UUID);
     }
 
     public void test_readDescriptor() throws Exception {
         when(mMockBluetoothOperationExecutor.executeNonnull(
                 new Operation<byte[]>(
-                        OperationType.READ_DESCRIPTOR, mMockBluetoothGatt,
+                        OperationType.READ_DESCRIPTOR, mMockBluetoothGattWrapper,
                         mMockBluetoothGattDescriptor),
                 BluetoothGattConnection.OPERATION_TIMEOUT_MILLIS))
                 .thenReturn(DATA);
@@ -520,13 +529,13 @@
         verify(mMockBluetoothOperationExecutor)
                 .executeNonnull(mOperationCaptor.capture(), anyLong());
         mOperationCaptor.getValue().run();
-        verify(mMockBluetoothGatt).readDescriptor(mMockBluetoothGattDescriptor);
+        verify(mMockBluetoothGattWrapper).readDescriptor(mMockBluetoothGattDescriptor);
     }
 
     public void test_readDescriptor_by_uuid() throws Exception {
         when(mMockBluetoothOperationExecutor.executeNonnull(
                 new Operation<byte[]>(
-                        OperationType.READ_DESCRIPTOR, mMockBluetoothGatt,
+                        OperationType.READ_DESCRIPTOR, mMockBluetoothGattWrapper,
                         mMockBluetoothGattDescriptor),
                 BluetoothGattConnection.OPERATION_TIMEOUT_MILLIS))
                 .thenReturn(DATA);
@@ -539,7 +548,7 @@
         verify(mMockBluetoothOperationExecutor)
                 .executeNonnull(mOperationCaptor.capture(), anyLong());
         mOperationCaptor.getValue().run();
-        verify(mMockBluetoothGatt).readDescriptor(mMockBluetoothGattDescriptor);
+        verify(mMockBluetoothGattWrapper).readDescriptor(mMockBluetoothGattDescriptor);
     }
 
     public void test_writeDescriptor() throws Exception {
@@ -550,11 +559,10 @@
                 .execute(mOperationCaptor.capture(),
                         eq(BluetoothGattConnection.OPERATION_TIMEOUT_MILLIS));
         mOperationCaptor.getValue().run();
-        verify(mMockBluetoothGatt).writeDescriptor(mDescriptorCaptor.capture());
+        verify(mMockBluetoothGattWrapper).writeDescriptor(mDescriptorCaptor.capture(), eq(DATA));
         BluetoothGattDescriptor writtenDescriptor = mDescriptorCaptor.getValue();
-        assertThat(writtenDescriptor.getValue()).isEqualTo(DATA);
         assertThat(writtenDescriptor.getUuid()).isEqualTo(DESCRIPTOR_UUID);
-        assertThat(writtenDescriptor).isNotEqualTo(descriptor);
+        assertThat(writtenDescriptor).isEqualTo(descriptor);
     }
 
     public void test_writeDescriptor_by_uuid() throws Exception {
@@ -565,15 +573,14 @@
                 .execute(mOperationCaptor.capture(),
                         eq(BluetoothGattConnection.OPERATION_TIMEOUT_MILLIS));
         mOperationCaptor.getValue().run();
-        verify(mMockBluetoothGatt).writeDescriptor(mDescriptorCaptor.capture());
+        verify(mMockBluetoothGattWrapper).writeDescriptor(mDescriptorCaptor.capture(), eq(DATA));
         BluetoothGattDescriptor writtenDescriptor = mDescriptorCaptor.getValue();
-        assertThat(writtenDescriptor.getValue()).isEqualTo(DATA);
         assertThat(writtenDescriptor.getUuid()).isEqualTo(DESCRIPTOR_UUID);
     }
 
     public void test_readRemoteRssi() throws Exception {
         when(mMockBluetoothOperationExecutor.executeNonnull(
-                new Operation<Integer>(OperationType.READ_RSSI, mMockBluetoothGatt),
+                new Operation<Integer>(OperationType.READ_RSSI, mMockBluetoothGattWrapper),
                 BluetoothGattConnection.OPERATION_TIMEOUT_MILLIS))
                 .thenReturn(RSSI);
 
@@ -585,7 +592,7 @@
                         mOperationCaptor.capture(),
                         eq(BluetoothGattConnection.OPERATION_TIMEOUT_MILLIS));
         mOperationCaptor.getValue().run();
-        verify(mMockBluetoothGatt).readRemoteRssi();
+        verify(mMockBluetoothGattWrapper).readRemoteRssi();
     }
 
     public void test_getMaxDataPacketSize() throws Exception {
@@ -600,14 +607,13 @@
 
         mBluetoothGattConnection.setNotificationEnabled(mMockBluetoothGattCharacteristic, true);
 
-        verify(mMockBluetoothGatt)
+        verify(mMockBluetoothGattWrapper)
                 .setCharacteristicNotification(mMockBluetoothGattCharacteristic, true);
         verify(mMockBluetoothOperationExecutor).execute(mOperationCaptor.capture(), anyLong());
         mOperationCaptor.getValue().run();
-        verify(mMockBluetoothGatt).writeDescriptor(mDescriptorCaptor.capture());
+        verify(mMockBluetoothGattWrapper).writeDescriptor(mDescriptorCaptor.capture(),
+                eq(BluetoothGattDescriptor.ENABLE_INDICATION_VALUE));
         BluetoothGattDescriptor writtenDescriptor = mDescriptorCaptor.getValue();
-        assertThat(writtenDescriptor.getValue())
-                .isEqualTo(BluetoothGattDescriptor.ENABLE_INDICATION_VALUE);
         assertThat(writtenDescriptor.getUuid())
                 .isEqualTo(ReservedUuids.Descriptors.CLIENT_CHARACTERISTIC_CONFIGURATION);
     }
@@ -615,14 +621,13 @@
     public void test_getNotificationEnabled_notification_enable() throws Exception {
         mBluetoothGattConnection.setNotificationEnabled(mMockBluetoothGattCharacteristic, true);
 
-        verify(mMockBluetoothGatt)
+        verify(mMockBluetoothGattWrapper)
                 .setCharacteristicNotification(mMockBluetoothGattCharacteristic, true);
         verify(mMockBluetoothOperationExecutor).execute(mOperationCaptor.capture(), anyLong());
         mOperationCaptor.getValue().run();
-        verify(mMockBluetoothGatt).writeDescriptor(mDescriptorCaptor.capture());
+        verify(mMockBluetoothGattWrapper).writeDescriptor(mDescriptorCaptor.capture(),
+                eq(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE));
         BluetoothGattDescriptor writtenDescriptor = mDescriptorCaptor.getValue();
-        assertThat(writtenDescriptor.getValue())
-                .isEqualTo(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
         assertThat(writtenDescriptor.getUuid())
                 .isEqualTo(ReservedUuids.Descriptors.CLIENT_CHARACTERISTIC_CONFIGURATION);
     }
@@ -633,14 +638,13 @@
 
         mBluetoothGattConnection.setNotificationEnabled(mMockBluetoothGattCharacteristic, false);
 
-        verify(mMockBluetoothGatt)
+        verify(mMockBluetoothGattWrapper)
                 .setCharacteristicNotification(mMockBluetoothGattCharacteristic, false);
         verify(mMockBluetoothOperationExecutor).execute(mOperationCaptor.capture(), anyLong());
         mOperationCaptor.getValue().run();
-        verify(mMockBluetoothGatt).writeDescriptor(mDescriptorCaptor.capture());
+        verify(mMockBluetoothGattWrapper).writeDescriptor(mDescriptorCaptor.capture(),
+                eq(BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE));
         BluetoothGattDescriptor writtenDescriptor = mDescriptorCaptor.getValue();
-        assertThat(writtenDescriptor.getValue())
-                .isEqualTo(BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE);
         assertThat(writtenDescriptor.getUuid())
                 .isEqualTo(ReservedUuids.Descriptors.CLIENT_CHARACTERISTIC_CONFIGURATION);
     }
@@ -648,14 +652,13 @@
     public void test_setNotificationEnabled_notification_disable() throws Exception {
         mBluetoothGattConnection.setNotificationEnabled(mMockBluetoothGattCharacteristic, false);
 
-        verify(mMockBluetoothGatt)
+        verify(mMockBluetoothGattWrapper)
                 .setCharacteristicNotification(mMockBluetoothGattCharacteristic, false);
         verify(mMockBluetoothOperationExecutor).execute(mOperationCaptor.capture(), anyLong());
         mOperationCaptor.getValue().run();
-        verify(mMockBluetoothGatt).writeDescriptor(mDescriptorCaptor.capture());
+        verify(mMockBluetoothGattWrapper).writeDescriptor(mDescriptorCaptor.capture(),
+                eq(BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE));
         BluetoothGattDescriptor writtenDescriptor = mDescriptorCaptor.getValue();
-        assertThat(writtenDescriptor.getValue())
-                .isEqualTo(BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE);
         assertThat(writtenDescriptor.getUuid())
                 .isEqualTo(ReservedUuids.Descriptors.CLIENT_CHARACTERISTIC_CONFIGURATION);
     }
@@ -665,7 +668,8 @@
                 .thenReturn(BluetoothGattCharacteristic.PROPERTY_READ);
 
         try {
-            mBluetoothGattConnection.setNotificationEnabled(mMockBluetoothGattCharacteristic, true);
+            mBluetoothGattConnection.setNotificationEnabled(mMockBluetoothGattCharacteristic,
+                    true);
             fail("BluetoothException was expected");
         } catch (BluetoothException expected) {
         }
@@ -782,8 +786,8 @@
                 .execute(mOperationCaptor.capture(),
                         eq(BluetoothGattConnection.OPERATION_TIMEOUT_MILLIS));
         mOperationCaptor.getValue().run();
-        verify(mMockBluetoothGatt).disconnect();
-        verify(mMockBluetoothGatt).close();
+        verify(mMockBluetoothGattWrapper).disconnect();
+        verify(mMockBluetoothGattWrapper).close();
     }
 
     public void test_onClosed() throws Exception {
@@ -791,6 +795,6 @@
 
         verify(mMockBluetoothOperationExecutor, never())
                 .execute(mOperationCaptor.capture(), anyLong());
-        verify(mMockBluetoothGatt).close();
+        verify(mMockBluetoothGattWrapper).close();
     }
 }
diff --git a/nearby/tests/src/com/android/server/nearby/common/bluetooth/gatt/BluetoothGattHelperTest.java b/nearby/tests/src/com/android/server/nearby/common/bluetooth/gatt/BluetoothGattHelperTest.java
index a60f0b2..60cac57 100644
--- a/nearby/tests/src/com/android/server/nearby/common/bluetooth/gatt/BluetoothGattHelperTest.java
+++ b/nearby/tests/src/com/android/server/nearby/common/bluetooth/gatt/BluetoothGattHelperTest.java
@@ -33,6 +33,7 @@
 import static org.mockito.Mockito.when;
 import static org.mockito.MockitoAnnotations.initMocks;
 
+import android.bluetooth.BluetoothGatt;
 import android.bluetooth.BluetoothGattCharacteristic;
 import android.bluetooth.BluetoothGattDescriptor;
 import android.bluetooth.le.ScanFilter;
@@ -46,7 +47,7 @@
 import com.android.server.nearby.common.bluetooth.gatt.BluetoothGattHelper.OperationType;
 import com.android.server.nearby.common.bluetooth.testability.android.bluetooth.BluetoothAdapter;
 import com.android.server.nearby.common.bluetooth.testability.android.bluetooth.BluetoothDevice;
-import com.android.server.nearby.common.bluetooth.testability.android.bluetooth.BluetoothGatt;
+import com.android.server.nearby.common.bluetooth.testability.android.bluetooth.BluetoothGattWrapper;
 import com.android.server.nearby.common.bluetooth.testability.android.bluetooth.le.BluetoothLeScanner;
 import com.android.server.nearby.common.bluetooth.testability.android.bluetooth.le.ScanCallback;
 import com.android.server.nearby.common.bluetooth.testability.android.bluetooth.le.ScanResult;
@@ -90,7 +91,7 @@
     @Mock
     private BluetoothGattConnection mMockBluetoothGattConnection;
     @Mock
-    private BluetoothGatt mMockBluetoothGatt;
+    private BluetoothGattWrapper mMockBluetoothGattWrapper;
     @Mock
     private BluetoothGattCharacteristic mMockBluetoothGattCharacteristic;
     @Mock
@@ -132,12 +133,13 @@
         when(mMockBluetoothGattCharacteristic.getValue()).thenReturn(CHARACTERISTIC_VALUE);
         when(mMockBluetoothGattDescriptor.getValue()).thenReturn(DESCRIPTOR_VALUE);
         when(mMockScanResult.getDevice()).thenReturn(mMockBluetoothDevice);
-        when(mMockBluetoothGatt.getDevice()).thenReturn(mMockBluetoothDevice);
+        when(mMockBluetoothGattWrapper.getDevice()).thenReturn(mMockBluetoothDevice);
         when(mMockBluetoothDevice.connectGatt(eq(mMockApplicationContext), anyBoolean(),
-                eq(mBluetoothGattHelper.mBluetoothGattCallback))).thenReturn(mMockBluetoothGatt);
+                eq(mBluetoothGattHelper.mBluetoothGattCallback))).thenReturn(
+                mMockBluetoothGattWrapper);
         when(mMockBluetoothDevice.connectGatt(eq(mMockApplicationContext), anyBoolean(),
                 eq(mBluetoothGattHelper.mBluetoothGattCallback), anyInt()))
-                .thenReturn(mMockBluetoothGatt);
+                .thenReturn(mMockBluetoothGattWrapper);
         when(mMockBluetoothGattConnection.getConnectionOptions())
                 .thenReturn(ConnectionOptions.builder().build());
     }
@@ -245,7 +247,7 @@
         verify(mMockBluetoothDevice).connectGatt(mMockApplicationContext, false,
                 mBluetoothGattHelper.mBluetoothGattCallback,
                 android.bluetooth.BluetoothDevice.TRANSPORT_LE);
-        assertThat(mBluetoothGattHelper.mConnections.get(mMockBluetoothGatt).getDevice())
+        assertThat(mBluetoothGattHelper.mConnections.get(mMockBluetoothGattWrapper).getDevice())
                 .isEqualTo(mMockBluetoothDevice);
     }
 
@@ -263,7 +265,8 @@
         verify(mMockBluetoothDevice).connectGatt(mMockApplicationContext, true,
                 mBluetoothGattHelper.mBluetoothGattCallback,
                 android.bluetooth.BluetoothDevice.TRANSPORT_LE);
-        assertThat(mBluetoothGattHelper.mConnections.get(mMockBluetoothGatt).getConnectionOptions())
+        assertThat(mBluetoothGattHelper.mConnections.get(mMockBluetoothGattWrapper)
+                .getConnectionOptions())
                 .isEqualTo(ConnectionOptions.builder()
                         .setAutoConnect(true)
                         .build());
@@ -290,7 +293,8 @@
 
     public void test_connect_withOptionRequestConnectionPriority_success() throws Exception {
         // Operation succeeds on the 3rd try.
-        when(mMockBluetoothGatt.requestConnectionPriority(BluetoothGatt.CONNECTION_PRIORITY_HIGH))
+        when(mMockBluetoothGattWrapper
+                .requestConnectionPriority(BluetoothGatt.CONNECTION_PRIORITY_HIGH))
                 .thenReturn(false)
                 .thenReturn(false)
                 .thenReturn(true);
@@ -309,11 +313,12 @@
         verify(mMockBluetoothDevice).connectGatt(mMockApplicationContext, false,
                 mBluetoothGattHelper.mBluetoothGattCallback,
                 android.bluetooth.BluetoothDevice.TRANSPORT_LE);
-        assertThat(mBluetoothGattHelper.mConnections.get(mMockBluetoothGatt).getConnectionOptions())
+        assertThat(mBluetoothGattHelper.mConnections.get(mMockBluetoothGattWrapper)
+                .getConnectionOptions())
                 .isEqualTo(ConnectionOptions.builder()
                         .setConnectionPriority(BluetoothGatt.CONNECTION_PRIORITY_HIGH)
                         .build());
-        verify(mMockBluetoothGatt, times(3))
+        verify(mMockBluetoothGattWrapper, times(3))
                 .requestConnectionPriority(BluetoothGatt.CONNECTION_PRIORITY_HIGH);
     }
 
@@ -326,16 +331,18 @@
         operation.run();
         operation.cancel();
 
-        verify(mMockBluetoothGatt).disconnect();
-        verify(mMockBluetoothGatt).close();
-        assertThat(mBluetoothGattHelper.mConnections.get(mMockBluetoothGatt)).isNull();
+        verify(mMockBluetoothGattWrapper).disconnect();
+        verify(mMockBluetoothGattWrapper).close();
+        assertThat(mBluetoothGattHelper.mConnections.get(mMockBluetoothGattWrapper)).isNull();
     }
 
     public void test_BluetoothGattCallback_onConnectionStateChange_connected_success()
             throws Exception {
-        mBluetoothGattHelper.mConnections.put(mMockBluetoothGatt, mMockBluetoothGattConnection);
+        mBluetoothGattHelper.mConnections.put(mMockBluetoothGattWrapper,
+                mMockBluetoothGattConnection);
 
-        mBluetoothGattHelper.mBluetoothGattCallback.onConnectionStateChange(mMockBluetoothGatt,
+        mBluetoothGattHelper.mBluetoothGattCallback.onConnectionStateChange(
+                mMockBluetoothGattWrapper,
                 BluetoothGatt.GATT_SUCCESS, BluetoothGatt.STATE_CONNECTED);
 
         verify(mMockBluetoothOperationExecutor).notifyCompletion(
@@ -347,45 +354,50 @@
 
     public void test_BluetoothGattCallback_onConnectionStateChange_connected_success_withMtuOption()
             throws Exception {
-        mBluetoothGattHelper.mConnections.put(mMockBluetoothGatt, mMockBluetoothGattConnection);
+        mBluetoothGattHelper.mConnections.put(mMockBluetoothGattWrapper,
+                mMockBluetoothGattConnection);
         when(mMockBluetoothGattConnection.getConnectionOptions())
                 .thenReturn(BluetoothGattHelper.ConnectionOptions.builder()
                         .setMtu(MTU)
                         .build());
-        when(mMockBluetoothGatt.requestMtu(MTU)).thenReturn(true);
+        when(mMockBluetoothGattWrapper.requestMtu(MTU)).thenReturn(true);
 
-        mBluetoothGattHelper.mBluetoothGattCallback.onConnectionStateChange(mMockBluetoothGatt,
+        mBluetoothGattHelper.mBluetoothGattCallback.onConnectionStateChange(
+                mMockBluetoothGattWrapper,
                 BluetoothGatt.GATT_SUCCESS, BluetoothGatt.STATE_CONNECTED);
 
         verifyZeroInteractions(mMockBluetoothOperationExecutor);
         verify(mMockBluetoothGattConnection, never()).onConnected();
-        verify(mMockBluetoothGatt).requestMtu(MTU);
+        verify(mMockBluetoothGattWrapper).requestMtu(MTU);
     }
 
     public void test_BluetoothGattCallback_onConnectionStateChange_connected_success_failMtuOption()
             throws Exception {
-        mBluetoothGattHelper.mConnections.put(mMockBluetoothGatt, mMockBluetoothGattConnection);
+        mBluetoothGattHelper.mConnections.put(mMockBluetoothGattWrapper,
+                mMockBluetoothGattConnection);
         when(mMockBluetoothGattConnection.getConnectionOptions())
                 .thenReturn(BluetoothGattHelper.ConnectionOptions.builder()
                         .setMtu(MTU)
                         .build());
-        when(mMockBluetoothGatt.requestMtu(MTU)).thenReturn(false);
+        when(mMockBluetoothGattWrapper.requestMtu(MTU)).thenReturn(false);
 
-        mBluetoothGattHelper.mBluetoothGattCallback.onConnectionStateChange(mMockBluetoothGatt,
+        mBluetoothGattHelper.mBluetoothGattCallback.onConnectionStateChange(
+                mMockBluetoothGattWrapper,
                 BluetoothGatt.GATT_SUCCESS, BluetoothGatt.STATE_CONNECTED);
 
         verify(mMockBluetoothOperationExecutor).notifyFailure(
                 eq(new Operation<>(OperationType.CONNECT, mMockBluetoothDevice)),
                 any(BluetoothException.class));
         verify(mMockBluetoothGattConnection, never()).onConnected();
-        verify(mMockBluetoothGatt).disconnect();
-        verify(mMockBluetoothGatt).close();
-        assertThat(mBluetoothGattHelper.mConnections.get(mMockBluetoothGatt)).isNull();
+        verify(mMockBluetoothGattWrapper).disconnect();
+        verify(mMockBluetoothGattWrapper).close();
+        assertThat(mBluetoothGattHelper.mConnections.get(mMockBluetoothGattWrapper)).isNull();
     }
 
     public void test_BluetoothGattCallback_onConnectionStateChange_connected_unexpectedSuccess()
             throws Exception {
-        mBluetoothGattHelper.mBluetoothGattCallback.onConnectionStateChange(mMockBluetoothGatt,
+        mBluetoothGattHelper.mBluetoothGattCallback.onConnectionStateChange(
+                mMockBluetoothGattWrapper,
                 BluetoothGatt.GATT_SUCCESS, BluetoothGatt.STATE_CONNECTED);
 
         verifyZeroInteractions(mMockBluetoothOperationExecutor);
@@ -393,11 +405,12 @@
 
     public void test_BluetoothGattCallback_onConnectionStateChange_connected_failure()
             throws Exception {
-        mBluetoothGattHelper.mConnections.put(mMockBluetoothGatt, mMockBluetoothGattConnection);
+        mBluetoothGattHelper.mConnections.put(mMockBluetoothGattWrapper,
+                mMockBluetoothGattConnection);
 
         mBluetoothGattHelper.mBluetoothGattCallback
                 .onConnectionStateChange(
-                        mMockBluetoothGatt,
+                        mMockBluetoothGattWrapper,
                         BluetoothGatt.GATT_FAILURE,
                         BluetoothGatt.STATE_CONNECTED);
 
@@ -406,16 +419,16 @@
                         new Operation<>(OperationType.CONNECT, mMockBluetoothDevice),
                         BluetoothGatt.GATT_FAILURE,
                         null);
-        verify(mMockBluetoothGatt).disconnect();
-        verify(mMockBluetoothGatt).close();
-        assertThat(mBluetoothGattHelper.mConnections.get(mMockBluetoothGatt)).isNull();
+        verify(mMockBluetoothGattWrapper).disconnect();
+        verify(mMockBluetoothGattWrapper).close();
+        assertThat(mBluetoothGattHelper.mConnections.get(mMockBluetoothGattWrapper)).isNull();
     }
 
     public void test_BluetoothGattCallback_onConnectionStateChange_disconnected_unexpectedSuccess()
             throws Exception {
         mBluetoothGattHelper.mBluetoothGattCallback
                 .onConnectionStateChange(
-                        mMockBluetoothGatt,
+                        mMockBluetoothGattWrapper,
                         BluetoothGatt.GATT_SUCCESS,
                         BluetoothGatt.STATE_DISCONNECTED);
 
@@ -424,12 +437,13 @@
 
     public void test_BluetoothGattCallback_onConnectionStateChange_disconnected_notConnected()
             throws Exception {
-        mBluetoothGattHelper.mConnections.put(mMockBluetoothGatt, mMockBluetoothGattConnection);
+        mBluetoothGattHelper.mConnections.put(mMockBluetoothGattWrapper,
+                mMockBluetoothGattConnection);
         when(mMockBluetoothGattConnection.isConnected()).thenReturn(false);
 
         mBluetoothGattHelper.mBluetoothGattCallback
                 .onConnectionStateChange(
-                        mMockBluetoothGatt,
+                        mMockBluetoothGattWrapper,
                         GATT_STATUS,
                         BluetoothGatt.STATE_DISCONNECTED);
 
@@ -438,125 +452,135 @@
                         new Operation<>(OperationType.CONNECT, mMockBluetoothDevice),
                         GATT_STATUS,
                         null);
-        verify(mMockBluetoothGatt).disconnect();
-        verify(mMockBluetoothGatt).close();
-        assertThat(mBluetoothGattHelper.mConnections.get(mMockBluetoothGatt)).isNull();
+        verify(mMockBluetoothGattWrapper).disconnect();
+        verify(mMockBluetoothGattWrapper).close();
+        assertThat(mBluetoothGattHelper.mConnections.get(mMockBluetoothGattWrapper)).isNull();
     }
 
     public void test_BluetoothGattCallback_onConnectionStateChange_disconnected_success()
             throws Exception {
-        mBluetoothGattHelper.mConnections.put(mMockBluetoothGatt, mMockBluetoothGattConnection);
+        mBluetoothGattHelper.mConnections.put(mMockBluetoothGattWrapper,
+                mMockBluetoothGattConnection);
         when(mMockBluetoothGattConnection.isConnected()).thenReturn(true);
 
-        mBluetoothGattHelper.mBluetoothGattCallback.onConnectionStateChange(mMockBluetoothGatt,
+        mBluetoothGattHelper.mBluetoothGattCallback.onConnectionStateChange(
+                mMockBluetoothGattWrapper,
                 BluetoothGatt.GATT_SUCCESS, BluetoothGatt.STATE_DISCONNECTED);
 
         verify(mMockBluetoothOperationExecutor).notifyCompletion(
                 new Operation<>(OperationType.DISCONNECT, mMockBluetoothDevice),
                 BluetoothGatt.GATT_SUCCESS);
         verify(mMockBluetoothGattConnection).onClosed();
-        assertThat(mBluetoothGattHelper.mConnections.get(mMockBluetoothGatt)).isNull();
+        assertThat(mBluetoothGattHelper.mConnections.get(mMockBluetoothGattWrapper)).isNull();
     }
 
     public void test_BluetoothGattCallback_onConnectionStateChange_disconnected_failure()
             throws Exception {
-        mBluetoothGattHelper.mConnections.put(mMockBluetoothGatt, mMockBluetoothGattConnection);
+        mBluetoothGattHelper.mConnections.put(mMockBluetoothGattWrapper,
+                mMockBluetoothGattConnection);
         when(mMockBluetoothGattConnection.isConnected()).thenReturn(true);
 
-        mBluetoothGattHelper.mBluetoothGattCallback.onConnectionStateChange(mMockBluetoothGatt,
+        mBluetoothGattHelper.mBluetoothGattCallback.onConnectionStateChange(
+                mMockBluetoothGattWrapper,
                 BluetoothGatt.GATT_FAILURE, BluetoothGatt.STATE_DISCONNECTED);
 
         verify(mMockBluetoothOperationExecutor).notifyCompletion(
                 new Operation<>(OperationType.DISCONNECT, mMockBluetoothDevice),
                 BluetoothGatt.GATT_FAILURE);
         verify(mMockBluetoothGattConnection).onClosed();
-        assertThat(mBluetoothGattHelper.mConnections.get(mMockBluetoothGatt)).isNull();
+        assertThat(mBluetoothGattHelper.mConnections.get(mMockBluetoothGattWrapper)).isNull();
     }
 
     public void test_BluetoothGattCallback_onServicesDiscovered() throws Exception {
-        mBluetoothGattHelper.mBluetoothGattCallback.onServicesDiscovered(mMockBluetoothGatt,
+        mBluetoothGattHelper.mBluetoothGattCallback.onServicesDiscovered(mMockBluetoothGattWrapper,
                 GATT_STATUS);
 
         verify(mMockBluetoothOperationExecutor).notifyCompletion(
-                new Operation<Void>(OperationType.DISCOVER_SERVICES_INTERNAL, mMockBluetoothGatt),
+                new Operation<Void>(OperationType.DISCOVER_SERVICES_INTERNAL,
+                        mMockBluetoothGattWrapper),
                 GATT_STATUS);
     }
 
     public void test_BluetoothGattCallback_onCharacteristicRead() throws Exception {
-        mBluetoothGattHelper.mBluetoothGattCallback.onCharacteristicRead(mMockBluetoothGatt,
+        mBluetoothGattHelper.mBluetoothGattCallback.onCharacteristicRead(mMockBluetoothGattWrapper,
                 mMockBluetoothGattCharacteristic, GATT_STATUS);
 
         verify(mMockBluetoothOperationExecutor).notifyCompletion(new Operation<byte[]>(
-                        OperationType.READ_CHARACTERISTIC, mMockBluetoothGatt,
+                        OperationType.READ_CHARACTERISTIC, mMockBluetoothGattWrapper,
                         mMockBluetoothGattCharacteristic),
                 GATT_STATUS, CHARACTERISTIC_VALUE);
     }
 
     public void test_BluetoothGattCallback_onCharacteristicWrite() throws Exception {
-        mBluetoothGattHelper.mBluetoothGattCallback.onCharacteristicWrite(mMockBluetoothGatt,
+        mBluetoothGattHelper.mBluetoothGattCallback.onCharacteristicWrite(mMockBluetoothGattWrapper,
                 mMockBluetoothGattCharacteristic, GATT_STATUS);
 
         verify(mMockBluetoothOperationExecutor).notifyCompletion(new Operation<Void>(
-                        OperationType.WRITE_CHARACTERISTIC, mMockBluetoothGatt,
+                        OperationType.WRITE_CHARACTERISTIC, mMockBluetoothGattWrapper,
                         mMockBluetoothGattCharacteristic),
                 GATT_STATUS);
     }
 
     public void test_BluetoothGattCallback_onDescriptorRead() throws Exception {
-        mBluetoothGattHelper.mBluetoothGattCallback.onDescriptorRead(mMockBluetoothGatt,
+        mBluetoothGattHelper.mBluetoothGattCallback.onDescriptorRead(mMockBluetoothGattWrapper,
                 mMockBluetoothGattDescriptor, GATT_STATUS);
 
         verify(mMockBluetoothOperationExecutor).notifyCompletion(new Operation<byte[]>(
-                        OperationType.READ_DESCRIPTOR, mMockBluetoothGatt,
+                        OperationType.READ_DESCRIPTOR, mMockBluetoothGattWrapper,
                         mMockBluetoothGattDescriptor),
                 GATT_STATUS,
                 DESCRIPTOR_VALUE);
     }
 
     public void test_BluetoothGattCallback_onDescriptorWrite() throws Exception {
-        mBluetoothGattHelper.mBluetoothGattCallback.onDescriptorWrite(mMockBluetoothGatt,
+        mBluetoothGattHelper.mBluetoothGattCallback.onDescriptorWrite(mMockBluetoothGattWrapper,
                 mMockBluetoothGattDescriptor, GATT_STATUS);
 
         verify(mMockBluetoothOperationExecutor).notifyCompletion(new Operation<Void>(
-                        OperationType.WRITE_DESCRIPTOR, mMockBluetoothGatt,
+                        OperationType.WRITE_DESCRIPTOR, mMockBluetoothGattWrapper,
                         mMockBluetoothGattDescriptor),
                 GATT_STATUS);
     }
 
     public void test_BluetoothGattCallback_onReadRemoteRssi() throws Exception {
-        mBluetoothGattHelper.mBluetoothGattCallback.onReadRemoteRssi(mMockBluetoothGatt, RSSI,
-                GATT_STATUS);
+        mBluetoothGattHelper.mBluetoothGattCallback.onReadRemoteRssi(mMockBluetoothGattWrapper,
+                RSSI, GATT_STATUS);
 
         verify(mMockBluetoothOperationExecutor).notifyCompletion(
-                new Operation<Integer>(OperationType.READ_RSSI, mMockBluetoothGatt), GATT_STATUS,
-                RSSI);
+                new Operation<Integer>(OperationType.READ_RSSI, mMockBluetoothGattWrapper),
+                GATT_STATUS, RSSI);
     }
 
     public void test_BluetoothGattCallback_onReliableWriteCompleted() throws Exception {
-        mBluetoothGattHelper.mBluetoothGattCallback.onReliableWriteCompleted(mMockBluetoothGatt,
+        mBluetoothGattHelper.mBluetoothGattCallback.onReliableWriteCompleted(
+                mMockBluetoothGattWrapper,
                 GATT_STATUS);
 
         verify(mMockBluetoothOperationExecutor).notifyCompletion(
-                new Operation<Void>(OperationType.WRITE_RELIABLE, mMockBluetoothGatt), GATT_STATUS);
+                new Operation<Void>(OperationType.WRITE_RELIABLE, mMockBluetoothGattWrapper),
+                GATT_STATUS);
     }
 
     public void test_BluetoothGattCallback_onMtuChanged() throws Exception {
-        mBluetoothGattHelper.mConnections.put(mMockBluetoothGatt, mMockBluetoothGattConnection);
+        mBluetoothGattHelper.mConnections.put(mMockBluetoothGattWrapper,
+                mMockBluetoothGattConnection);
         when(mMockBluetoothGattConnection.isConnected()).thenReturn(true);
 
         mBluetoothGattHelper.mBluetoothGattCallback
-                .onMtuChanged(mMockBluetoothGatt, MTU, GATT_STATUS);
+                .onMtuChanged(mMockBluetoothGattWrapper, MTU, GATT_STATUS);
 
         verify(mMockBluetoothOperationExecutor).notifyCompletion(
-                new Operation<>(OperationType.CHANGE_MTU, mMockBluetoothGatt), GATT_STATUS, MTU);
+                new Operation<>(OperationType.CHANGE_MTU, mMockBluetoothGattWrapper), GATT_STATUS,
+                MTU);
     }
 
     public void testBluetoothGattCallback_onMtuChangedDuringConnection_success() throws Exception {
-        mBluetoothGattHelper.mConnections.put(mMockBluetoothGatt, mMockBluetoothGattConnection);
+        mBluetoothGattHelper.mConnections.put(mMockBluetoothGattWrapper,
+                mMockBluetoothGattConnection);
         when(mMockBluetoothGattConnection.isConnected()).thenReturn(false);
 
         mBluetoothGattHelper.mBluetoothGattCallback.onMtuChanged(
-                mMockBluetoothGatt, MTU, BluetoothGatt.GATT_SUCCESS);
+                mMockBluetoothGattWrapper, MTU, BluetoothGatt.GATT_SUCCESS);
 
         verify(mMockBluetoothGattConnection).onConnected();
         verify(mMockBluetoothOperationExecutor)
@@ -567,11 +591,12 @@
     }
 
     public void testBluetoothGattCallback_onMtuChangedDuringConnection_fail() throws Exception {
-        mBluetoothGattHelper.mConnections.put(mMockBluetoothGatt, mMockBluetoothGattConnection);
+        mBluetoothGattHelper.mConnections.put(mMockBluetoothGattWrapper,
+                mMockBluetoothGattConnection);
         when(mMockBluetoothGattConnection.isConnected()).thenReturn(false);
 
         mBluetoothGattHelper.mBluetoothGattCallback
-                .onMtuChanged(mMockBluetoothGatt, MTU, GATT_STATUS);
+                .onMtuChanged(mMockBluetoothGattWrapper, MTU, GATT_STATUS);
 
         verify(mMockBluetoothGattConnection).onConnected();
         verify(mMockBluetoothOperationExecutor)
@@ -579,15 +604,17 @@
                         new Operation<>(OperationType.CONNECT, mMockBluetoothDevice),
                         GATT_STATUS,
                         mMockBluetoothGattConnection);
-        verify(mMockBluetoothGatt).disconnect();
-        verify(mMockBluetoothGatt).close();
-        assertThat(mBluetoothGattHelper.mConnections.get(mMockBluetoothGatt)).isNull();
+        verify(mMockBluetoothGattWrapper).disconnect();
+        verify(mMockBluetoothGattWrapper).close();
+        assertThat(mBluetoothGattHelper.mConnections.get(mMockBluetoothGattWrapper)).isNull();
     }
 
     public void test_BluetoothGattCallback_onCharacteristicChanged() throws Exception {
-        mBluetoothGattHelper.mConnections.put(mMockBluetoothGatt, mMockBluetoothGattConnection);
+        mBluetoothGattHelper.mConnections.put(mMockBluetoothGattWrapper,
+                mMockBluetoothGattConnection);
 
-        mBluetoothGattHelper.mBluetoothGattCallback.onCharacteristicChanged(mMockBluetoothGatt,
+        mBluetoothGattHelper.mBluetoothGattCallback.onCharacteristicChanged(
+                mMockBluetoothGattWrapper,
                 mMockBluetoothGattCharacteristic);
 
         verify(mMockBluetoothGattConnection).onCharacteristicChanged(
diff --git a/nearby/tests/src/com/android/server/nearby/common/bluetooth/util/BluetoothGattUtilsTest.java b/nearby/tests/src/com/android/server/nearby/common/bluetooth/util/BluetoothGattUtilsTest.java
index a6fbe2a..53c7615 100644
--- a/nearby/tests/src/com/android/server/nearby/common/bluetooth/util/BluetoothGattUtilsTest.java
+++ b/nearby/tests/src/com/android/server/nearby/common/bluetooth/util/BluetoothGattUtilsTest.java
@@ -21,16 +21,11 @@
 import static com.google.common.truth.Truth.assertThat;
 
 import android.bluetooth.BluetoothGatt;
-import android.bluetooth.BluetoothGattCharacteristic;
-import android.bluetooth.BluetoothGattDescriptor;
-import android.bluetooth.BluetoothGattService;
 import android.platform.test.annotations.Presubmit;
 
 import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
 
-import com.android.server.nearby.common.bluetooth.BluetoothException;
-
 import com.google.common.collect.ImmutableSet;
 
 import org.junit.Test;
@@ -65,41 +60,4 @@
             assertThat(getMessageForStatusCode(fieldValue)).isEqualTo(fieldName);
         }
     }
-
-    @Test
-    public void testCloneDescriptor() throws BluetoothException {
-        BluetoothGattCharacteristic characteristic = new BluetoothGattCharacteristic(TEST_UUID,
-                BluetoothGattCharacteristic.PROPERTY_INDICATE,
-                BluetoothGattCharacteristic.PERMISSION_READ_ENCRYPTED
-                        | BluetoothGattCharacteristic.PERMISSION_WRITE_SIGNED_MITM);
-        BluetoothGattDescriptor descriptor = new BluetoothGattDescriptor(TEST_UUID,
-                BluetoothGattDescriptor.PERMISSION_READ_ENCRYPTED
-                        | BluetoothGattDescriptor.PERMISSION_WRITE_SIGNED_MITM);
-        characteristic.addDescriptor(descriptor);
-
-        BluetoothGattDescriptor result = BluetoothGattUtils.clone(descriptor);
-
-        assertThat(result.getUuid()).isEqualTo(descriptor.getUuid());
-        assertThat(result.getPermissions()).isEqualTo(descriptor.getPermissions());
-        assertThat(result.getCharacteristic()).isEqualTo(descriptor.getCharacteristic());
-    }
-
-    @Test
-    public void testCloneCharacteristic() throws BluetoothException {
-        BluetoothGattService service =
-                new BluetoothGattService(TEST_UUID, BluetoothGattService.SERVICE_TYPE_PRIMARY);
-        BluetoothGattCharacteristic characteristic = new BluetoothGattCharacteristic(TEST_UUID,
-                BluetoothGattCharacteristic.PROPERTY_INDICATE,
-                BluetoothGattCharacteristic.PERMISSION_READ_ENCRYPTED
-                        | BluetoothGattCharacteristic.PERMISSION_WRITE_SIGNED_MITM);
-        characteristic.setWriteType(BluetoothGattCharacteristic.WRITE_TYPE_DEFAULT);
-        service.addCharacteristic(characteristic);
-        BluetoothGattCharacteristic result = BluetoothGattUtils.clone(characteristic);
-
-        assertThat(result.getUuid()).isEqualTo(characteristic.getUuid());
-        assertThat(result.getPermissions()).isEqualTo(characteristic.getPermissions());
-        assertThat(result.getProperties()).isEqualTo(characteristic.getProperties());
-        assertThat(result.getService()).isEqualTo(characteristic.getService());
-        assertThat(result.getInstanceId()).isEqualTo(characteristic.getInstanceId());
-        assertThat(result.getWriteType()).isEqualTo(characteristic.getWriteType());    }
 }