Syncrhonize notification requests of "Bluetooth LE Notify Characteristic".

In between the notification requests from the client, an enable notification
descriptor write could be called before the previous disable notification
descriptor write is completed.  This could prevent enable descriptor writes
from going out properly.  Instead of using a fixed sleep interval, synchronize
the request sequence based on disable notification descriptor write completion.

Bug: 66197001
Change-Id: I34252914ac817743d2cc507c69b3617915889aa5
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleClientService.java b/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleClientService.java
index 972ba43..e61cefe 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleClientService.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleClientService.java
@@ -298,6 +298,9 @@
     // Handler for communicating task with peer.
     private TestTaskQueue mTaskQueue;
 
+    // Lock for synchronization during notification request test.
+    private final Object mRequestNotificationLock = new Object();
+
     private enum ReliableWriteState {
         RELIABLE_WRITE_NONE,
         RELIABLE_WRITE_WRITE_1ST_DATA,
@@ -386,37 +389,37 @@
                         public void run() {
                             mNotifyCount = 16;
                             setNotification(UPDATE_CHARACTERISTIC_UUID, true);
-                            sleep(1000);
+                            waitForDisableNotificationCompletion();
                             setNotification(SERVICE_UUID_ADDITIONAL, UPDATE_CHARACTERISTIC_UUID_1, true);
-                            sleep(1000);
+                            waitForDisableNotificationCompletion();
                             setNotification(SERVICE_UUID_ADDITIONAL, UPDATE_CHARACTERISTIC_UUID_2, true);
-                            sleep(1000);
+                            waitForDisableNotificationCompletion();
                             setNotification(SERVICE_UUID_ADDITIONAL, UPDATE_CHARACTERISTIC_UUID_3, true);
-                            sleep(1000);
+                            waitForDisableNotificationCompletion();
                             setNotification(SERVICE_UUID_ADDITIONAL, UPDATE_CHARACTERISTIC_UUID_4, true);
-                            sleep(1000);
+                            waitForDisableNotificationCompletion();
                             setNotification(SERVICE_UUID_ADDITIONAL, UPDATE_CHARACTERISTIC_UUID_5, true);
-                            sleep(1000);
+                            waitForDisableNotificationCompletion();
                             setNotification(UPDATE_CHARACTERISTIC_UUID_6, true);
-                            sleep(1000);
+                            waitForDisableNotificationCompletion();
                             setNotification(UPDATE_CHARACTERISTIC_UUID_7, true);
-                            sleep(1000);
+                            waitForDisableNotificationCompletion();
                             setNotification(UPDATE_CHARACTERISTIC_UUID_8, true);
-                            sleep(1000);
+                            waitForDisableNotificationCompletion();
                             setNotification(UPDATE_CHARACTERISTIC_UUID_9, true);
-                            sleep(1000);
+                            waitForDisableNotificationCompletion();
                             setNotification(UPDATE_CHARACTERISTIC_UUID_10, true);
-                            sleep(1000);
+                            waitForDisableNotificationCompletion();
                             setNotification(SERVICE_UUID_ADDITIONAL, UPDATE_CHARACTERISTIC_UUID_11, true);
-                            sleep(1000);
+                            waitForDisableNotificationCompletion();
                             setNotification(SERVICE_UUID_ADDITIONAL, UPDATE_CHARACTERISTIC_UUID_12, true);
-                            sleep(1000);
+                            waitForDisableNotificationCompletion();
                             setNotification(SERVICE_UUID_ADDITIONAL, UPDATE_CHARACTERISTIC_UUID_13, true);
-                            sleep(1000);
+                            waitForDisableNotificationCompletion();
                             setNotification(SERVICE_UUID_ADDITIONAL, UPDATE_CHARACTERISTIC_UUID_14, true);
-                            sleep(1000);
+                            waitForDisableNotificationCompletion();
                             setNotification(SERVICE_UUID_ADDITIONAL, UPDATE_CHARACTERISTIC_UUID_15, true);
-                            sleep(1000);
+                            waitForDisableNotificationCompletion();
                         }
                     });
                 break;
@@ -580,6 +583,22 @@
         }
     }
 
+    private void notifyDisableNotificationCompletion() {
+        synchronized (mRequestNotificationLock) {
+            mRequestNotificationLock.notify();
+        }
+    }
+
+    private void waitForDisableNotificationCompletion() {
+        synchronized (mRequestNotificationLock) {
+            try {
+                mRequestNotificationLock.wait();
+            } catch (InterruptedException e) {
+                Log.e(TAG, "Error in waitForDisableNotificationCompletion" + e);
+            }
+        }
+    }
+
     private void setNotification(BluetoothGattCharacteristic characteristic, boolean enable) {
         if (characteristic != null) {
             mBluetoothGatt.setCharacteristicNotification(characteristic, enable);
@@ -597,13 +616,6 @@
         }
     }
 
-    private void setNotification(boolean enable) {
-        BluetoothGattCharacteristic characteristic = getCharacteristic(UPDATE_CHARACTERISTIC_UUID);
-        if (characteristic != null) {
-            setNotification(characteristic, enable);
-        }
-    }
-
     private void setNotification(UUID serviceUid, UUID characteristicUid,  boolean enable) {
         BluetoothGattCharacteristic characteristic = getCharacteristic(serviceUid, characteristicUid);
         if (characteristic != null) {
@@ -1107,6 +1119,9 @@
             if ((status == BluetoothGatt.GATT_SUCCESS)) {
                 if (uid.equals(UPDATE_DESCRIPTOR_UUID)) {
                     Log.d(TAG, "write in update descriptor.");
+                    if (descriptor.getValue() == BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE) {
+                        notifyDisableNotificationCompletion();
+                    }
                 } else if (uid.equals(DESCRIPTOR_UUID)) {
                     // verify
                     if (Arrays.equals(WRITE_VALUE.getBytes(), descriptor.getValue())) {