Separate advertiser from GATT client (1/4)

Bug: 30622771
Change-Id: I08c0498f8a1ea04423d3e864e9a60c7c78f1dbad
diff --git a/Android.mk b/Android.mk
index 69e57b6..e7037c9 100644
--- a/Android.mk
+++ b/Android.mk
@@ -125,6 +125,7 @@
 	core/java/android/bluetooth/IBluetoothGatt.aidl \
 	core/java/android/bluetooth/IBluetoothGattCallback.aidl \
 	core/java/android/bluetooth/IBluetoothGattServerCallback.aidl \
+	core/java/android/bluetooth/le/IAdvertiserCallback.aidl \
 	core/java/android/content/IClipboard.aidl \
 	core/java/android/content/IContentService.aidl \
 	core/java/android/content/IIntentReceiver.aidl \
diff --git a/core/java/android/bluetooth/BluetoothGattCallbackWrapper.java b/core/java/android/bluetooth/BluetoothGattCallbackWrapper.java
index 17e533a..da81569 100644
--- a/core/java/android/bluetooth/BluetoothGattCallbackWrapper.java
+++ b/core/java/android/bluetooth/BluetoothGattCallbackWrapper.java
@@ -83,11 +83,6 @@
     }
 
     @Override
-    public void onMultiAdvertiseCallback(int status, boolean isStart,
-            AdvertiseSettings advertiseSettings) throws RemoteException {
-    }
-
-    @Override
     public void onConfigureMTU(String address, int mtu, int status) throws RemoteException {
     }
 
diff --git a/core/java/android/bluetooth/IBluetoothGatt.aidl b/core/java/android/bluetooth/IBluetoothGatt.aidl
index 7498038..f4ebcaf 100644
--- a/core/java/android/bluetooth/IBluetoothGatt.aidl
+++ b/core/java/android/bluetooth/IBluetoothGatt.aidl
@@ -28,6 +28,7 @@
 
 import android.bluetooth.IBluetoothGattCallback;
 import android.bluetooth.IBluetoothGattServerCallback;
+import android.bluetooth.le.IAdvertiserCallback;
 
 /**
  * API for interacting with BLE / GATT
@@ -41,11 +42,15 @@
                    in String callingPackage);
     void stopScan(in int appIf, in boolean isServer);
     void flushPendingBatchResults(in int appIf, in boolean isServer);
-    void startMultiAdvertising(in int appIf,
+
+    void registerAdvertiser(in IAdvertiserCallback callback);
+    void unregisterAdvertiser(in int advertiserId);
+    void startMultiAdvertising(in int advertiserId,
                                in AdvertiseData advertiseData,
                                in AdvertiseData scanResponse,
                                in AdvertiseSettings settings);
-    void stopMultiAdvertising(in int appIf);
+    void stopMultiAdvertising(in int advertiserId);
+
     void registerClient(in ParcelUuid appId, in IBluetoothGattCallback callback);
     void unregisterClient(in int clientIf);
     void clientConnect(in int clientIf, in String address, in boolean isDirect, in int transport);
diff --git a/core/java/android/bluetooth/IBluetoothGattCallback.aidl b/core/java/android/bluetooth/IBluetoothGattCallback.aidl
index 7163c37..efda08e 100644
--- a/core/java/android/bluetooth/IBluetoothGattCallback.aidl
+++ b/core/java/android/bluetooth/IBluetoothGattCallback.aidl
@@ -38,8 +38,6 @@
     void onDescriptorWrite(in String address, in int status, in int handle);
     void onNotify(in String address, in int handle, in byte[] value);
     void onReadRemoteRssi(in String address, in int rssi, in int status);
-    void onMultiAdvertiseCallback(in int status, boolean isStart,
-                                  in AdvertiseSettings advertiseSettings);
     void onScanManagerErrorCallback(in int errorCode);
     void onConfigureMTU(in String address, in int mtu, in int status);
     void onFoundOrLost(in boolean onFound, in ScanResult scanResult);
diff --git a/core/java/android/bluetooth/le/BluetoothLeAdvertiser.java b/core/java/android/bluetooth/le/BluetoothLeAdvertiser.java
index d468bd4..048f791 100644
--- a/core/java/android/bluetooth/le/BluetoothLeAdvertiser.java
+++ b/core/java/android/bluetooth/le/BluetoothLeAdvertiser.java
@@ -22,6 +22,7 @@
 import android.bluetooth.BluetoothUuid;
 import android.bluetooth.IBluetoothGatt;
 import android.bluetooth.IBluetoothManager;
+import android.bluetooth.le.IAdvertiserCallback;
 import android.os.Handler;
 import android.os.Looper;
 import android.os.ParcelUuid;
@@ -162,7 +163,7 @@
     }
 
     /**
-     * Cleans up advertise clients. Should be called when bluetooth is down.
+     * Cleans up advertisers. Should be called when bluetooth is down.
      *
      * @hide
      */
@@ -228,7 +229,7 @@
     /**
      * Bluetooth GATT interface callbacks for advertising.
      */
-    private class AdvertiseCallbackWrapper extends BluetoothGattCallbackWrapper {
+    private class AdvertiseCallbackWrapper extends IAdvertiserCallback.Stub {
         private static final int LE_CALLBACK_TIMEOUT_MILLIS = 2000;
         private final AdvertiseCallback mAdvertiseCallback;
         private final AdvertiseData mAdvertisement;
@@ -236,10 +237,10 @@
         private final AdvertiseSettings mSettings;
         private final IBluetoothGatt mBluetoothGatt;
 
-        // mClientIf 0: not registered
+        // mAdvertiserId 0: not registered
         // -1: advertise stopped or registration timeout
         // >0: registered and advertising started
-        private int mClientIf;
+        private int mAdvertiserId;
         private boolean mIsAdvertising = false;
 
         public AdvertiseCallbackWrapper(AdvertiseCallback advertiseCallback,
@@ -251,35 +252,34 @@
             mScanResponse = scanResponse;
             mSettings = settings;
             mBluetoothGatt = bluetoothGatt;
-            mClientIf = 0;
+            mAdvertiserId = 0;
         }
 
         public void startRegisteration() {
             synchronized (this) {
-                if (mClientIf == -1) return;
+                if (mAdvertiserId == -1) return;
 
                 try {
-                    UUID uuid = UUID.randomUUID();
-                    mBluetoothGatt.registerClient(new ParcelUuid(uuid), this);
+                    mBluetoothGatt.registerAdvertiser(this);
                     wait(LE_CALLBACK_TIMEOUT_MILLIS);
                 } catch (InterruptedException | RemoteException e) {
                     Log.e(TAG, "Failed to start registeration", e);
                 }
-                if (mClientIf > 0 && mIsAdvertising) {
+                if (mAdvertiserId > 0 && mIsAdvertising) {
                     mLeAdvertisers.put(mAdvertiseCallback, this);
-                } else if (mClientIf <= 0) {
+                } else if (mAdvertiserId <= 0) {
 
                     // Registration timeout, reset mClientIf to -1 so no subsequent operations can
                     // proceed.
-                    if (mClientIf == 0) mClientIf = -1;
+                    if (mAdvertiserId == 0) mAdvertiserId = -1;
                     // Post internal error if registration failed.
                     postStartFailure(mAdvertiseCallback,
                             AdvertiseCallback.ADVERTISE_FAILED_INTERNAL_ERROR);
                 } else {
                     // Unregister application if it's already registered but advertise failed.
                     try {
-                        mBluetoothGatt.unregisterClient(mClientIf);
-                        mClientIf = -1;
+                        mBluetoothGatt.unregisterAdvertiser(mAdvertiserId);
+                        mAdvertiserId = -1;
                     } catch (RemoteException e) {
                         Log.e(TAG, "remote exception when unregistering", e);
                     }
@@ -290,7 +290,7 @@
         public void stopAdvertising() {
             synchronized (this) {
                 try {
-                    mBluetoothGatt.stopMultiAdvertising(mClientIf);
+                    mBluetoothGatt.stopMultiAdvertising(mAdvertiserId);
                     wait(LE_CALLBACK_TIMEOUT_MILLIS);
                 } catch (InterruptedException | RemoteException e) {
                     Log.e(TAG, "Failed to stop advertising", e);
@@ -305,20 +305,20 @@
         }
 
         /**
-         * Application interface registered - app is ready to go
+         * Advertiser interface registered - app is ready to go
          */
         @Override
-        public void onClientRegistered(int status, int clientIf) {
-            Log.d(TAG, "onClientRegistered() - status=" + status + " clientIf=" + clientIf);
+        public void onAdvertiserRegistered(int status, int advertiserId) {
+            Log.d(TAG, "onAdvertiserRegistered() - status=" + status + " advertiserId=" + advertiserId);
             synchronized (this) {
                 if (status == BluetoothGatt.GATT_SUCCESS) {
                     try {
-                        if (mClientIf == -1) {
-                            // Registration succeeds after timeout, unregister client.
-                            mBluetoothGatt.unregisterClient(clientIf);
+                        if (mAdvertiserId == -1) {
+                            // Registration succeeds after timeout, unregister advertiser.
+                            mBluetoothGatt.unregisterAdvertiser(advertiserId);
                         } else {
-                            mClientIf = clientIf;
-                            mBluetoothGatt.startMultiAdvertising(mClientIf, mAdvertisement,
+                            mAdvertiserId = advertiserId;
+                            mBluetoothGatt.startMultiAdvertising(mAdvertiserId, mAdvertisement,
                                     mScanResponse, mSettings);
                         }
                         return;
@@ -327,7 +327,7 @@
                     }
                 }
                 // Registration failed.
-                mClientIf = -1;
+                mAdvertiserId = -1;
                 notifyAll();
             }
         }
@@ -346,10 +346,10 @@
                         postStartFailure(mAdvertiseCallback, status);
                     }
                 } else {
-                    // unregister client for stop.
+                    // unregister advertiser for stop.
                     try {
-                        mBluetoothGatt.unregisterClient(mClientIf);
-                        mClientIf = -1;
+                        mBluetoothGatt.unregisterAdvertiser(mAdvertiserId);
+                        mAdvertiserId = -1;
                         mIsAdvertising = false;
                         mLeAdvertisers.remove(mAdvertiseCallback);
                     } catch (RemoteException e) {
diff --git a/core/java/android/bluetooth/le/IAdvertiserCallback.aidl b/core/java/android/bluetooth/le/IAdvertiserCallback.aidl
new file mode 100644
index 0000000..c58b1df
--- /dev/null
+++ b/core/java/android/bluetooth/le/IAdvertiserCallback.aidl
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.bluetooth.le;
+
+import android.bluetooth.le.AdvertiseSettings;
+
+/**
+ * Callback definitions for interacting with Advertiser
+ * @hide
+ */
+oneway interface IAdvertiserCallback {
+    void onAdvertiserRegistered(in int status, in int advertiserId);
+
+    void onMultiAdvertiseCallback(in int status, boolean isStart,
+                                  in AdvertiseSettings advertiseSettings);
+}