GATT Server refactoring (2/4)

Bug: 27999121
Change-Id: Ia5f91298a4b01b62adebc8adc30f27f757259588
diff --git a/core/java/android/bluetooth/BluetoothGatt.java b/core/java/android/bluetooth/BluetoothGatt.java
index 800dd43..abebd63 100644
--- a/core/java/android/bluetooth/BluetoothGatt.java
+++ b/core/java/android/bluetooth/BluetoothGatt.java
@@ -250,9 +250,6 @@
                 if (VDBG) Log.d(TAG, "onCharacteristicRead() - Device=" + address
                             + " handle=" + handle + " Status=" + status);
 
-                 Log.w(TAG, "onCharacteristicRead() - Device=" + address
-                            + " handle=" + handle + " Status=" + status);
-
                 if (!address.equals(mDevice.getAddress())) {
                     return;
                 }
diff --git a/core/java/android/bluetooth/BluetoothGattCharacteristic.java b/core/java/android/bluetooth/BluetoothGattCharacteristic.java
index 01f82e6..1cc2270 100644
--- a/core/java/android/bluetooth/BluetoothGattCharacteristic.java
+++ b/core/java/android/bluetooth/BluetoothGattCharacteristic.java
@@ -321,10 +321,10 @@
     }
 
     /**
-     * Returns the deisred key size.
+     * Returns the desired key size.
      * @hide
      */
-    /*package*/ int getKeySize() {
+    public int getKeySize() {
         return mKeySize;
     }
 
@@ -393,6 +393,14 @@
     }
 
     /**
+     * Force the instance ID.
+     * @hide
+     */
+    public void setInstanceId(int instanceId) {
+        mInstance = instanceId;
+    }
+
+    /**
      * Returns the properties of this characteristic.
      *
      * <p>The properties contain a bit mask of property flags indicating
diff --git a/core/java/android/bluetooth/BluetoothGattDescriptor.java b/core/java/android/bluetooth/BluetoothGattDescriptor.java
index 28317c4..1a4fa48 100644
--- a/core/java/android/bluetooth/BluetoothGattDescriptor.java
+++ b/core/java/android/bluetooth/BluetoothGattDescriptor.java
@@ -227,6 +227,14 @@
     }
 
     /**
+     * Force the instance ID.
+     * @hide
+     */
+    public void setInstanceId(int instanceId) {
+        mInstance = instanceId;
+    }
+
+    /**
      * Returns the permissions for this descriptor.
      *
      * @return Permissions of this descriptor
diff --git a/core/java/android/bluetooth/BluetoothGattServer.java b/core/java/android/bluetooth/BluetoothGattServer.java
index f451340..d3c6444 100644
--- a/core/java/android/bluetooth/BluetoothGattServer.java
+++ b/core/java/android/bluetooth/BluetoothGattServer.java
@@ -52,6 +52,7 @@
     private Object mServerIfLock = new Object();
     private int mServerIf;
     private int mTransport;
+    private BluetoothGattService mPendingService;
     private List<BluetoothGattService> mServices;
 
     private static final int CALLBACK_REG_TIMEOUT = 10000;
@@ -109,17 +110,37 @@
              * Service has been added
              * @hide
              */
-            public void onServiceAdded(int status, int srvcType,
-                                       int srvcInstId, ParcelUuid srvcId) {
-                UUID srvcUuid = srvcId.getUuid();
-                if (DBG) Log.d(TAG, "onServiceAdded() - service=" + srvcUuid
-                    + "status=" + status);
+            public void onServiceAdded(int status, BluetoothGattService service) {
+                if (DBG) Log.d(TAG, "onServiceAdded() - handle=" + service.getInstanceId()
+                    + " uuid=" + service.getUuid() + " status=" + status);
 
-                BluetoothGattService service = getService(srvcUuid, srvcInstId, srvcType);
-                if (service == null) return;
+                if (mPendingService == null)
+                    return;
+
+                BluetoothGattService tmp = mPendingService;
+                mPendingService = null;
+
+                // Rewrite newly assigned handles to existing service.
+                tmp.setInstanceId(service.getInstanceId());
+                List<BluetoothGattCharacteristic> temp_chars = tmp.getCharacteristics();
+                List<BluetoothGattCharacteristic> svc_chars = service.getCharacteristics();
+                for (int i=0; i<svc_chars.size(); i++) {
+                    BluetoothGattCharacteristic temp_char = temp_chars.get(i);
+                    BluetoothGattCharacteristic svc_char = svc_chars.get(i);
+
+                    temp_char.setInstanceId(svc_char.getInstanceId());
+
+                    List<BluetoothGattDescriptor> temp_descs = temp_char.getDescriptors();
+                    List<BluetoothGattDescriptor> svc_descs = svc_char.getDescriptors();
+                    for (int j=0; j<svc_descs.size(); j++) {
+                        temp_descs.get(i).setInstanceId(svc_descs.get(i).getInstanceId());
+                    }
+                }
+
+                mServices.add(tmp);
 
                 try {
-                    mCallback.onServiceAdded((int)status, service);
+                    mCallback.onServiceAdded((int)status, tmp);
                 } catch (Exception ex) {
                     Log.w(TAG, "Unhandled exception in callback", ex);
                 }
@@ -130,19 +151,15 @@
              * @hide
              */
             public void onCharacteristicReadRequest(String address, int transId,
-                            int offset, boolean isLong, int srvcType, int srvcInstId,
-                            ParcelUuid srvcId, int charInstId, ParcelUuid charId) {
-                UUID srvcUuid = srvcId.getUuid();
-                UUID charUuid = charId.getUuid();
-                if (VDBG) Log.d(TAG, "onCharacteristicReadRequest() - "
-                    + "service=" + srvcUuid + ", characteristic=" + charUuid);
+                            int offset, boolean isLong, int handle) {
+                if (VDBG) Log.d(TAG, "onCharacteristicReadRequest() - handle=" + handle);
 
                 BluetoothDevice device = mAdapter.getRemoteDevice(address);
-                BluetoothGattService service = getService(srvcUuid, srvcInstId, srvcType);
-                if (service == null) return;
-
-                BluetoothGattCharacteristic characteristic = service.getCharacteristic(charUuid);
-                if (characteristic == null) return;
+                BluetoothGattCharacteristic characteristic = getCharacteristicByHandle(handle);
+                if (characteristic == null) {
+                    Log.w(TAG, "onCharacteristicReadRequest() no char for handle " + handle);
+                    return;
+                }
 
                 try {
                     mCallback.onCharacteristicReadRequest(device, transId, offset, characteristic);
@@ -156,25 +173,15 @@
              * @hide
              */
             public void onDescriptorReadRequest(String address, int transId,
-                            int offset, boolean isLong, int srvcType, int srvcInstId,
-                            ParcelUuid srvcId, int charInstId, ParcelUuid charId,
-                            ParcelUuid descrId) {
-                UUID srvcUuid = srvcId.getUuid();
-                UUID charUuid = charId.getUuid();
-                UUID descrUuid = descrId.getUuid();
-                if (VDBG) Log.d(TAG, "onCharacteristicReadRequest() - "
-                    + "service=" + srvcUuid + ", characteristic=" + charUuid
-                    + "descriptor=" + descrUuid);
+                            int offset, boolean isLong, int handle) {
+                if (VDBG) Log.d(TAG, "onCharacteristicReadRequest() - handle=" + handle);
 
                 BluetoothDevice device = mAdapter.getRemoteDevice(address);
-                BluetoothGattService service = getService(srvcUuid, srvcInstId, srvcType);
-                if (service == null) return;
-
-                BluetoothGattCharacteristic characteristic = service.getCharacteristic(charUuid);
-                if (characteristic == null) return;
-
-                BluetoothGattDescriptor descriptor = characteristic.getDescriptor(descrUuid);
-                if (descriptor == null) return;
+                BluetoothGattDescriptor descriptor = getDescriptorByHandle(handle);
+                if (descriptor == null) {
+                    Log.w(TAG, "onDescriptorReadRequest() no desc for handle " + handle);
+                    return;
+                }
 
                 try {
                     mCallback.onDescriptorReadRequest(device, transId, offset, descriptor);
@@ -189,19 +196,15 @@
              */
             public void onCharacteristicWriteRequest(String address, int transId,
                             int offset, int length, boolean isPrep, boolean needRsp,
-                            int srvcType, int srvcInstId, ParcelUuid srvcId,
-                            int charInstId, ParcelUuid charId, byte[] value) {
-                UUID srvcUuid = srvcId.getUuid();
-                UUID charUuid = charId.getUuid();
-                if (VDBG) Log.d(TAG, "onCharacteristicWriteRequest() - "
-                    + "service=" + srvcUuid + ", characteristic=" + charUuid);
+                            int handle, byte[] value) {
+                if (VDBG) Log.d(TAG, "onCharacteristicWriteRequest() - handle=" + handle);
 
                 BluetoothDevice device = mAdapter.getRemoteDevice(address);
-                BluetoothGattService service = getService(srvcUuid, srvcInstId, srvcType);
-                if (service == null) return;
-
-                BluetoothGattCharacteristic characteristic = service.getCharacteristic(charUuid);
-                if (characteristic == null) return;
+                BluetoothGattCharacteristic characteristic = getCharacteristicByHandle(handle);
+                if (characteristic == null) {
+                    Log.w(TAG, "onCharacteristicWriteRequest() no char for handle " + handle);
+                    return;
+                }
 
                 try {
                     mCallback.onCharacteristicWriteRequest(device, transId, characteristic,
@@ -216,28 +219,16 @@
              * Remote client descriptor write request.
              * @hide
              */
-            public void onDescriptorWriteRequest(String address, int transId,
-                            int offset, int length, boolean isPrep, boolean needRsp,
-                            int srvcType, int srvcInstId, ParcelUuid srvcId,
-                            int charInstId, ParcelUuid charId, ParcelUuid descrId,
-                            byte[] value) {
-                UUID srvcUuid = srvcId.getUuid();
-                UUID charUuid = charId.getUuid();
-                UUID descrUuid = descrId.getUuid();
-                if (VDBG) Log.d(TAG, "onDescriptorWriteRequest() - "
-                    + "service=" + srvcUuid + ", characteristic=" + charUuid
-                    + "descriptor=" + descrUuid);
+            public void onDescriptorWriteRequest(String address, int transId, int offset,
+                            int length, boolean isPrep, boolean needRsp, int handle, byte[] value) {
+                if (VDBG) Log.d(TAG, "onDescriptorWriteRequest() - handle=" + handle);
 
                 BluetoothDevice device = mAdapter.getRemoteDevice(address);
-
-                BluetoothGattService service = getService(srvcUuid, srvcInstId, srvcType);
-                if (service == null) return;
-
-                BluetoothGattCharacteristic characteristic = service.getCharacteristic(charUuid);
-                if (characteristic == null) return;
-
-                BluetoothGattDescriptor descriptor = characteristic.getDescriptor(descrUuid);
-                if (descriptor == null) return;
+                BluetoothGattDescriptor descriptor = getDescriptorByHandle(handle);
+                if (descriptor == null) {
+                    Log.w(TAG, "onDescriptorWriteRequest() no desc for handle " + handle);
+                    return;
+                }
 
                 try {
                     mCallback.onDescriptorWriteRequest(device, transId, descriptor,
@@ -318,6 +309,36 @@
     }
 
     /**
+     * Returns a characteristic with given handle.
+     * @hide
+     */
+    /*package*/ BluetoothGattCharacteristic getCharacteristicByHandle(int handle) {
+        for(BluetoothGattService svc : mServices) {
+            for(BluetoothGattCharacteristic charac : svc.getCharacteristics()) {
+                if (charac.getInstanceId() == handle)
+                    return charac;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Returns a descriptor with given handle.
+     * @hide
+     */
+    /*package*/ BluetoothGattDescriptor getDescriptorByHandle(int handle) {
+        for(BluetoothGattService svc : mServices) {
+            for(BluetoothGattCharacteristic charac : svc.getCharacteristics()) {
+                for(BluetoothGattDescriptor desc : charac.getDescriptors()) {
+                    if (desc.getInstanceId() == handle)
+                        return desc;
+                }
+            }
+        }
+        return null;
+    }
+
+    /**
      * Close this GATT server instance.
      *
      * Application should call this method as early as possible after it is done with
@@ -537,9 +558,7 @@
 
         try {
             mService.sendNotification(mServerIf, device.getAddress(),
-                    service.getType(), service.getInstanceId(),
-                    new ParcelUuid(service.getUuid()), characteristic.getInstanceId(),
-                    new ParcelUuid(characteristic.getUuid()), confirm,
+                    characteristic.getInstanceId(), confirm,
                     characteristic.getValue());
         } catch (RemoteException e) {
             Log.e(TAG,"",e);
@@ -568,39 +587,10 @@
         if (DBG) Log.d(TAG, "addService() - service: " + service.getUuid());
         if (mService == null || mServerIf == 0) return false;
 
-        mServices.add(service);
+        mPendingService = service;
 
         try {
-            mService.beginServiceDeclaration(mServerIf, service.getType(),
-                service.getInstanceId(), service.getHandles(),
-                new ParcelUuid(service.getUuid()), service.isAdvertisePreferred());
-
-            List<BluetoothGattService> includedServices = service.getIncludedServices();
-            for (BluetoothGattService includedService : includedServices) {
-                mService.addIncludedService(mServerIf,
-                    includedService.getType(),
-                    includedService.getInstanceId(),
-                    new ParcelUuid(includedService.getUuid()));
-            }
-
-            List<BluetoothGattCharacteristic> characteristics = service.getCharacteristics();
-            for (BluetoothGattCharacteristic characteristic : characteristics) {
-                int permission = ((characteristic.getKeySize() - 7) << 12)
-                                    + characteristic.getPermissions();
-                mService.addCharacteristic(mServerIf,
-                    new ParcelUuid(characteristic.getUuid()),
-                    characteristic.getProperties(), permission);
-
-                List<BluetoothGattDescriptor> descriptors = characteristic.getDescriptors();
-                for (BluetoothGattDescriptor descriptor: descriptors) {
-                    permission = ((characteristic.getKeySize() - 7) << 12)
-                                        + descriptor.getPermissions();
-                    mService.addDescriptor(mServerIf,
-                        new ParcelUuid(descriptor.getUuid()), permission);
-                }
-            }
-
-            mService.endServiceDeclaration(mServerIf);
+            mService.addService(mServerIf, service);
         } catch (RemoteException e) {
             Log.e(TAG,"",e);
             return false;
@@ -626,8 +616,7 @@
         if (intService == null) return false;
 
         try {
-            mService.removeService(mServerIf, service.getType(),
-                service.getInstanceId(), new ParcelUuid(service.getUuid()));
+            mService.removeService(mServerIf, service.getInstanceId());
             mServices.remove(intService);
         } catch (RemoteException e) {
             Log.e(TAG,"",e);
diff --git a/core/java/android/bluetooth/BluetoothGattService.java b/core/java/android/bluetooth/BluetoothGattService.java
index a4e1dc0..c888a45 100644
--- a/core/java/android/bluetooth/BluetoothGattService.java
+++ b/core/java/android/bluetooth/BluetoothGattService.java
@@ -250,7 +250,6 @@
 
     /**
      * Force the instance ID.
-     * This is needed for conformance testing only.
      * @hide
      */
     public void setInstanceId(int instanceId) {
diff --git a/core/java/android/bluetooth/IBluetoothGatt.aidl b/core/java/android/bluetooth/IBluetoothGatt.aidl
index 45b5122..d613cd6 100644
--- a/core/java/android/bluetooth/IBluetoothGatt.aidl
+++ b/core/java/android/bluetooth/IBluetoothGatt.aidl
@@ -17,6 +17,7 @@
 package android.bluetooth;
 
 import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothGattService;
 import android.bluetooth.le.AdvertiseSettings;
 import android.bluetooth.le.AdvertiseData;
 import android.bluetooth.le.ScanFilter;
@@ -65,26 +66,14 @@
 
     void registerServer(in ParcelUuid appId, in IBluetoothGattServerCallback callback);
     void unregisterServer(in int serverIf);
-    void serverConnect(in int servertIf, in String address, in boolean isDirect, in int transport);
+    void serverConnect(in int serverIf, in String address, in boolean isDirect, in int transport);
     void serverDisconnect(in int serverIf, in String address);
-    void beginServiceDeclaration(in int serverIf, in int srvcType,
-                            in int srvcInstanceId, in int minHandles,
-                            in ParcelUuid srvcId, boolean advertisePreferred);
-    void addIncludedService(in int serverIf, in int srvcType,
-                            in int srvcInstanceId, in ParcelUuid srvcId);
-    void addCharacteristic(in int serverIf, in ParcelUuid charId,
-                            in int properties, in int permissions);
-    void addDescriptor(in int serverIf, in ParcelUuid descId,
-                            in int permissions);
-    void endServiceDeclaration(in int serverIf);
-    void removeService(in int serverIf, in int srvcType,
-                            in int srvcInstanceId, in ParcelUuid srvcId);
+    void addService(in int serverIf, in BluetoothGattService service);
+    void removeService(in int serverIf, in int handle);
     void clearServices(in int serverIf);
     void sendResponse(in int serverIf, in String address, in int requestId,
                             in int status, in int offset, in byte[] value);
-    void sendNotification(in int serverIf, in String address, in int srvcType,
-                            in int srvcInstanceId, in ParcelUuid srvcId,
-                            in int charInstanceId, in ParcelUuid charId,
+    void sendNotification(in int serverIf, in String address, in int handle,
                             in boolean confirm, in byte[] value);
     void disconnectAll();
     void unregAll();
diff --git a/core/java/android/bluetooth/IBluetoothGattServerCallback.aidl b/core/java/android/bluetooth/IBluetoothGattServerCallback.aidl
index 8b202b2..0bcb07b 100644
--- a/core/java/android/bluetooth/IBluetoothGattServerCallback.aidl
+++ b/core/java/android/bluetooth/IBluetoothGattServerCallback.aidl
@@ -15,8 +15,7 @@
  */
 package android.bluetooth;
 
-import android.os.ParcelUuid;
-
+import android.bluetooth.BluetoothGattService;
 
 /**
  * Callback definitions for interacting with BLE / GATT
@@ -27,36 +26,18 @@
     void onScanResult(in String address, in int rssi, in byte[] advData);
     void onServerConnectionState(in int status, in int serverIf,
                                  in boolean connected, in String address);
-    void onServiceAdded(in int status, in int srvcType,
-                        in int srvcInstId, in ParcelUuid srvcId);
-    void onCharacteristicReadRequest(in String address, in int transId,
-                                     in int offset, in boolean isLong,
-                                     in int srvcType,
-                                     in int srvcInstId, in ParcelUuid srvcId,
-                                     in int charInstId, in ParcelUuid charId);
+    void onServiceAdded(in int status, in BluetoothGattService service);
+    void onCharacteristicReadRequest(in String address, in int transId, in int offset,
+                                     in boolean isLong, in int handle);
     void onDescriptorReadRequest(in String address, in int transId,
                                      in int offset, in boolean isLong,
-                                     in int srvcType,
-                                     in int srvcInstId, in ParcelUuid srvcId,
-                                     in int charInstId, in ParcelUuid charId,
-                                     in ParcelUuid descrId);
-    void onCharacteristicWriteRequest(in String address, in int transId,
-                                     in int offset, in int length,
-                                     in boolean isPrep,
-                                     in boolean needRsp,
-                                     in int srvcType,
-                                     in int srvcInstId, in ParcelUuid srvcId,
-                                     in int charInstId, in ParcelUuid charId,
-                                     in byte[] value);
-    void onDescriptorWriteRequest(in String address, in int transId,
-                                     in int offset, in int length,
-                                     in boolean isPrep,
-                                     in boolean needRsp,
-                                     in int srvcType,
-                                     in int srvcInstId, in ParcelUuid srvcId,
-                                     in int charInstId, in ParcelUuid charId,
-                                     in ParcelUuid descrId,
-                                     in byte[] value);
+                                     in int handle);
+    void onCharacteristicWriteRequest(in String address, in int transId, in int offset,
+                                     in int length, in boolean isPrep, in boolean needRsp,
+                                     in int handle, in byte[] value);
+    void onDescriptorWriteRequest(in String address, in int transId, in int offset,
+                                     in int length, in boolean isPrep, in boolean needRsp,
+                                     in int handle, in byte[] value);
     void onExecuteWrite(in String address, in int transId, in boolean execWrite);
     void onNotificationSent(in String address, in int status);
     void onMtuChanged(in String address, in int mtu);