binder: Callback registration for interfaces

Add callback registration for each binder interface type:
ISupplicant, IIface, INetwork.

BUG: 30093041
Change-Id: I9043d9a033bcfbee5a80f61cf58e564249edf3a7
diff --git a/wpa_supplicant/Android.mk b/wpa_supplicant/Android.mk
index a54c45a..e232e10 100644
--- a/wpa_supplicant/Android.mk
+++ b/wpa_supplicant/Android.mk
@@ -1657,9 +1657,11 @@
     binder/binder_constants.cpp \
     binder/parcelable_iface_params.cpp \
     binder/fi/w1/wpa_supplicant/IIface.aidl \
+    binder/fi/w1/wpa_supplicant/IIfaceCallback.aidl \
     binder/fi/w1/wpa_supplicant/INetwork.aidl \
+    binder/fi/w1/wpa_supplicant/INetworkCallback.aidl \
     binder/fi/w1/wpa_supplicant/ISupplicant.aidl \
-    binder/fi/w1/wpa_supplicant/ISupplicantCallbacks.aidl
+    binder/fi/w1/wpa_supplicant/ISupplicantCallback.aidl
 LOCAL_SHARED_LIBRARIES := libbinder
 LOCAL_EXPORT_C_INCLUDE_DIRS := \
     $(LOCAL_PATH)/binder/include
diff --git a/wpa_supplicant/binder/binder_manager.cpp b/wpa_supplicant/binder/binder_manager.cpp
index 5152ed9..bc6c556 100644
--- a/wpa_supplicant/binder/binder_manager.cpp
+++ b/wpa_supplicant/binder/binder_manager.cpp
@@ -201,6 +201,52 @@
 }
 
 /**
+ * Add a new |ISupplicantCallback| binder object reference to our
+ * global callback list.
+ *
+ * @param callback Binder reference of the |ISupplicantCallback| object.
+ *
+ * @return 0 on success, 1 on failure.
+ */
+int BinderManager::addSupplicantCallbackBinderObject(
+    const android::sp<fi::w1::wpa_supplicant::ISupplicantCallback> &callback)
+{
+	return 0;
+}
+/**
+ * Add a new |IIfaceCallback| binder object reference to our
+ * interface callback list.
+ *
+ * @param ifname Name of the corresponding interface.
+ * @param callback Binder reference of the |IIfaceCallback| object.
+ *
+ * @return 0 on success, 1 on failure.
+ */
+int BinderManager::addIfaceCallbackBinderObject(
+    const std::string &ifname,
+    const android::sp<fi::w1::wpa_supplicant::IIfaceCallback> &callback)
+{
+	return 0;
+}
+
+/**
+ * Add a new |INetworkCallback| binder object reference to our
+ * network callback list.
+ *
+ * @param ifname Name of the corresponding interface.
+ * @param network_id ID of the corresponding network.
+ * @param callback Binder reference of the |INetworkCallback| object.
+ *
+ * @return 0 on success, 1 on failure.
+ */
+int BinderManager::addNetworkCallbackBinderObject(
+    const std::string &ifname, int network_id,
+    const android::sp<fi::w1::wpa_supplicant::INetworkCallback> &callback)
+{
+	return 0;
+}
+
+/**
  * Creates a unique key for the network using the provided |ifname| and
  * |network_id| to be used
  * in the internal map of |INetwork| objects.
diff --git a/wpa_supplicant/binder/binder_manager.h b/wpa_supplicant/binder/binder_manager.h
index 377c94f..99fa510 100644
--- a/wpa_supplicant/binder/binder_manager.h
+++ b/wpa_supplicant/binder/binder_manager.h
@@ -13,6 +13,10 @@
 #include <map>
 #include <string>
 
+#include "fi/w1/wpa_supplicant/IIfaceCallback.h"
+#include "fi/w1/wpa_supplicant/INetworkCallback.h"
+#include "fi/w1/wpa_supplicant/ISupplicantCallback.h"
+
 #include "iface.h"
 #include "network.h"
 #include "supplicant.h"
@@ -34,6 +38,7 @@
 	static BinderManager *getInstance();
 	static void destroyInstance();
 
+	// Methods called from wpa_supplicant core.
 	int registerBinderService(struct wpa_global *global);
 	int registerInterface(struct wpa_supplicant *wpa_s);
 	int unregisterInterface(struct wpa_supplicant *wpa_s);
@@ -41,12 +46,25 @@
 	registerNetwork(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid);
 	int
 	unregisterNetwork(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid);
+
+	// Methods called from binder objects.
 	int getIfaceBinderObjectByIfname(
 	    const std::string &ifname,
 	    android::sp<fi::w1::wpa_supplicant::IIface> *iface_object);
 	int getNetworkBinderObjectByIfnameAndNetworkId(
 	    const std::string &ifname, int network_id,
 	    android::sp<fi::w1::wpa_supplicant::INetwork> *network_object);
+	int addSupplicantCallbackBinderObject(
+	    const android::sp<fi::w1::wpa_supplicant::ISupplicantCallback>
+		&callback);
+	int addIfaceCallbackBinderObject(
+	    const std::string &ifname,
+	    const android::sp<fi::w1::wpa_supplicant::IIfaceCallback>
+		&callback);
+	int addNetworkCallbackBinderObject(
+	    const std::string &ifname, int network_id,
+	    const android::sp<fi::w1::wpa_supplicant::INetworkCallback>
+		&callback);
 
 private:
 	BinderManager() = default;
diff --git a/wpa_supplicant/binder/fi/w1/wpa_supplicant/IIface.aidl b/wpa_supplicant/binder/fi/w1/wpa_supplicant/IIface.aidl
index 4e486ea..da8d130 100644
--- a/wpa_supplicant/binder/fi/w1/wpa_supplicant/IIface.aidl
+++ b/wpa_supplicant/binder/fi/w1/wpa_supplicant/IIface.aidl
@@ -9,6 +9,7 @@
 
 package fi.w1.wpa_supplicant;
 
+import fi.w1.wpa_supplicant.IIfaceCallback;
 import fi.w1.wpa_supplicant.INetwork;
 
 /**
@@ -58,4 +59,14 @@
 	 * @return Binder object representing the network.
 	 */
 	INetwork GetNetwork(in int id);
+
+	/**
+	 * Register for callbacks from this interface.
+	 *
+	 * These callbacks are invoked for events that are specific to this interface.
+	 *
+	 * @param callback Binder object reference to a |IIfaceCallback|
+	 *        instance.
+	 */
+	void RegisterCallback(in IIfaceCallback callback);
 }
diff --git a/wpa_supplicant/binder/fi/w1/wpa_supplicant/IIfaceCallback.aidl b/wpa_supplicant/binder/fi/w1/wpa_supplicant/IIfaceCallback.aidl
new file mode 100644
index 0000000..0e2e071
--- /dev/null
+++ b/wpa_supplicant/binder/fi/w1/wpa_supplicant/IIfaceCallback.aidl
@@ -0,0 +1,22 @@
+/*
+ * binder interface for wpa_supplicant daemon
+ * Copyright (c) 2004-2016, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2004-2016, Roshan Pius <rpius@google.com>
+ *
+ * This software may be distributed under the terms of the BSD license.
+ * See README for more details.
+ */
+
+package fi.w1.wpa_supplicant;
+
+/**
+ * Callback Interface exposed by the wpa_supplicant service
+ * for each interface (IIface).
+ *
+ * Clients need to host an instance of this binder object and
+ * pass a reference of the object to wpa_supplicant via the
+ * corresponding |IIface.registerCallback| method.
+ */
+@utf8InCpp
+interface IIfaceCallback {
+}
diff --git a/wpa_supplicant/binder/fi/w1/wpa_supplicant/INetwork.aidl b/wpa_supplicant/binder/fi/w1/wpa_supplicant/INetwork.aidl
index 74aa9ad..08e5783 100644
--- a/wpa_supplicant/binder/fi/w1/wpa_supplicant/INetwork.aidl
+++ b/wpa_supplicant/binder/fi/w1/wpa_supplicant/INetwork.aidl
@@ -9,6 +9,8 @@
 
 package fi.w1.wpa_supplicant;
 
+import fi.w1.wpa_supplicant.INetworkCallback;
+
 /**
  * Interface exposed by wpa_supplicant for each network configuration it controls.
  * A network is wpa_supplicant's way of representing the configuration parameters of a Wifi
@@ -38,4 +40,14 @@
 	 * @return Name of the network interface, e.g., wlan0
 	 */
 	String GetInterfaceName();
+
+	/**
+	 * Register for callbacks from this network.
+	 *
+	 * These callbacks are invoked for events that are specific to this network.
+	 *
+	 * @param callback Binder object reference to a |INetworkCallback|
+	 *        instance.
+	 */
+	void RegisterCallback(in INetworkCallback callback);
 }
diff --git a/wpa_supplicant/binder/fi/w1/wpa_supplicant/INetworkCallback.aidl b/wpa_supplicant/binder/fi/w1/wpa_supplicant/INetworkCallback.aidl
new file mode 100644
index 0000000..147f0a6
--- /dev/null
+++ b/wpa_supplicant/binder/fi/w1/wpa_supplicant/INetworkCallback.aidl
@@ -0,0 +1,22 @@
+/*
+ * binder interface for wpa_supplicant daemon
+ * Copyright (c) 2004-2016, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2004-2016, Roshan Pius <rpius@google.com>
+ *
+ * This software may be distributed under the terms of the BSD license.
+ * See README for more details.
+ */
+
+package fi.w1.wpa_supplicant;
+
+/**
+ * Callback Interface exposed by the wpa_supplicant service
+ * for each network (INetwork).
+ *
+ * Clients need to host an instance of this binder object and
+ * pass a reference of the object to wpa_supplicant via the
+ * corresponding |INetwork.registerCallback| method.
+ */
+@utf8InCpp
+interface INetworkCallback {
+}
diff --git a/wpa_supplicant/binder/fi/w1/wpa_supplicant/ISupplicant.aidl b/wpa_supplicant/binder/fi/w1/wpa_supplicant/ISupplicant.aidl
index 84edc0a..3445cda 100644
--- a/wpa_supplicant/binder/fi/w1/wpa_supplicant/ISupplicant.aidl
+++ b/wpa_supplicant/binder/fi/w1/wpa_supplicant/ISupplicant.aidl
@@ -10,11 +10,12 @@
 package fi.w1.wpa_supplicant;
 
 import fi.w1.wpa_supplicant.ParcelableIfaceParams;
+import fi.w1.wpa_supplicant.ISupplicantCallback;
 import fi.w1.wpa_supplicant.IIface;
 
 /**
  * Interface exposed by the wpa_supplicant binder service registered
- * with the service manager with name: fi.w1.wpa_supplicant.
+ * with the service manager with name: wpa_supplicant.
  */
 @utf8InCpp
 interface ISupplicant {
@@ -97,4 +98,15 @@
 	 * @return true if set, false otherwise.
 	 */
 	boolean GetDebugShowKeys();
+
+	/**
+	 * Register for callbacks from the wpa_supplicant service.
+	 *
+	 * These callbacks are invoked for global events that are not specific
+	 * to any interface or network.
+	 *
+	 * @param callback Binder object reference to a |ISupplicantCallback|
+	 *        instance.
+	 */
+	void RegisterCallback(in ISupplicantCallback callback);
 }
diff --git a/wpa_supplicant/binder/fi/w1/wpa_supplicant/ISupplicantCallback.aidl b/wpa_supplicant/binder/fi/w1/wpa_supplicant/ISupplicantCallback.aidl
new file mode 100644
index 0000000..99aca3d
--- /dev/null
+++ b/wpa_supplicant/binder/fi/w1/wpa_supplicant/ISupplicantCallback.aidl
@@ -0,0 +1,21 @@
+/*
+ * binder interface for wpa_supplicant daemon
+ * Copyright (c) 2004-2016, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2004-2016, Roshan Pius <rpius@google.com>
+ *
+ * This software may be distributed under the terms of the BSD license.
+ * See README for more details.
+ */
+
+package fi.w1.wpa_supplicant;
+
+/**
+ * Callback Interface exposed by the wpa_supplicant service (ISupplicant).
+ *
+ * Clients need to host an instance of this binder object and
+ * pass a reference of the object to wpa_supplicant via the
+ * |ISupplicant.registerCallback| method.
+ */
+@utf8InCpp
+interface ISupplicantCallback {
+}
diff --git a/wpa_supplicant/binder/fi/w1/wpa_supplicant/ISupplicantCallbacks.aidl b/wpa_supplicant/binder/fi/w1/wpa_supplicant/ISupplicantCallbacks.aidl
deleted file mode 100644
index 02261c7..0000000
--- a/wpa_supplicant/binder/fi/w1/wpa_supplicant/ISupplicantCallbacks.aidl
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * binder interface for wpa_supplicant daemon
- * Copyright (c) 2004-2016, Jouni Malinen <j@w1.fi>
- * Copyright (c) 2004-2016, Roshan Pius <rpius@google.com>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-package fi.w1.wpa_supplicant;
-
-import android.os.PersistableBundle;
-
-/**
- * Callback Interface exposed by the wpa_supplicant service. Clients need
- * to host an instance of this binder object and pass a reference of the object
- * to wpa_supplicant via the registerCallbacksObject method.
- */
-@utf8InCpp
-interface ISupplicantCallbacks {
-}
diff --git a/wpa_supplicant/binder/iface.cpp b/wpa_supplicant/binder/iface.cpp
index 267b90b..5b5a68e 100644
--- a/wpa_supplicant/binder/iface.cpp
+++ b/wpa_supplicant/binder/iface.cpp
@@ -120,6 +120,25 @@
 	return android::binder::Status::ok();
 }
 
+android::binder::Status Iface::RegisterCallback(
+    const android::sp<fi::w1::wpa_supplicant::IIfaceCallback> &callback)
+{
+	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+	if (!wpa_s) {
+		return android::binder::Status::fromServiceSpecificError(
+		    ERROR_IFACE_INVALID,
+		    "wpa_supplicant does not control this interface.");
+	}
+	BinderManager *binder_manager = BinderManager::getInstance();
+	if (!binder_manager ||
+	    binder_manager->addIfaceCallbackBinderObject(ifname_, callback)) {
+		return android::binder::Status::fromServiceSpecificError(
+		    ERROR_GENERIC,
+		    "wpa_supplicant encountered a binder error.");
+	}
+	return android::binder::Status::ok();
+}
+
 /**
  * Retrieve the underlying |wpa_supplicant| struct pointer for
  * this iface.
diff --git a/wpa_supplicant/binder/iface.h b/wpa_supplicant/binder/iface.h
index 13dd4b0..6db4609 100644
--- a/wpa_supplicant/binder/iface.h
+++ b/wpa_supplicant/binder/iface.h
@@ -46,6 +46,9 @@
 	    int network_id,
 	    android::sp<fi::w1::wpa_supplicant::INetwork> *network_object_out)
 	    override;
+	android::binder::Status RegisterCallback(
+	    const android::sp<fi::w1::wpa_supplicant::IIfaceCallback> &callback)
+	    override;
 
 private:
 	struct wpa_supplicant *retrieveIfacePtr();
diff --git a/wpa_supplicant/binder/network.cpp b/wpa_supplicant/binder/network.cpp
index 5a87ca1..000204d 100644
--- a/wpa_supplicant/binder/network.cpp
+++ b/wpa_supplicant/binder/network.cpp
@@ -7,6 +7,7 @@
  * See README for more details.
  */
 
+#include "binder_manager.h"
 #include "network.h"
 
 namespace wpa_supplicant_binder {
@@ -43,6 +44,26 @@
 	return android::binder::Status::ok();
 }
 
+android::binder::Status Network::RegisterCallback(
+    const android::sp<fi::w1::wpa_supplicant::INetworkCallback> &callback)
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	if (!wpa_ssid) {
+		return android::binder::Status::fromServiceSpecificError(
+		    ERROR_NETWORK_INVALID,
+		    "wpa_supplicant does not control this network.");
+	}
+	BinderManager *binder_manager = BinderManager::getInstance();
+	if (!binder_manager ||
+	    binder_manager->addNetworkCallbackBinderObject(
+		ifname_, network_id_, callback)) {
+		return android::binder::Status::fromServiceSpecificError(
+		    ERROR_GENERIC,
+		    "wpa_supplicant encountered a binder error.");
+	}
+	return android::binder::Status::ok();
+}
+
 /**
  * Retrieve the underlying |wpa_ssid| struct pointer for
  * this network.
diff --git a/wpa_supplicant/binder/network.h b/wpa_supplicant/binder/network.h
index dfc1698..ae47639 100644
--- a/wpa_supplicant/binder/network.h
+++ b/wpa_supplicant/binder/network.h
@@ -39,6 +39,9 @@
 	android::binder::Status GetId(int *network_id_out) override;
 	android::binder::Status
 	GetInterfaceName(std::string *ifname_out) override;
+	android::binder::Status RegisterCallback(
+	    const android::sp<fi::w1::wpa_supplicant::INetworkCallback>
+		&callback) override;
 
 private:
 	struct wpa_ssid *retrieveNetworkPtr();
diff --git a/wpa_supplicant/binder/supplicant.cpp b/wpa_supplicant/binder/supplicant.cpp
index 38b7e44..9588f40 100644
--- a/wpa_supplicant/binder/supplicant.cpp
+++ b/wpa_supplicant/binder/supplicant.cpp
@@ -7,8 +7,8 @@
  * See README for more details.
  */
 
-#include "supplicant.h"
 #include "binder_manager.h"
+#include "supplicant.h"
 
 namespace wpa_supplicant_binder {
 
@@ -161,6 +161,19 @@
 	return android::binder::Status::ok();
 }
 
+android::binder::Status Supplicant::RegisterCallback(
+    const android::sp<fi::w1::wpa_supplicant::ISupplicantCallback> &callback)
+{
+	BinderManager *binder_manager = BinderManager::getInstance();
+	if (!binder_manager ||
+	    binder_manager->addSupplicantCallbackBinderObject(callback)) {
+		return android::binder::Status::fromServiceSpecificError(
+		    ERROR_GENERIC,
+		    "wpa_supplicant encountered a binder error.");
+	}
+	return android::binder::Status::ok();
+}
+
 /**
  * Helper function to convert the debug level parameter from the binder
  * interface values to internal values.
diff --git a/wpa_supplicant/binder/supplicant.h b/wpa_supplicant/binder/supplicant.h
index de85594..33ba3b0 100644
--- a/wpa_supplicant/binder/supplicant.h
+++ b/wpa_supplicant/binder/supplicant.h
@@ -14,7 +14,7 @@
 
 #include "fi/w1/wpa_supplicant/BnSupplicant.h"
 #include "fi/w1/wpa_supplicant/IIface.h"
-#include "fi/w1/wpa_supplicant/ISupplicantCallbacks.h"
+#include "fi/w1/wpa_supplicant/ISupplicantCallback.h"
 
 extern "C" {
 #include "utils/common.h"
@@ -52,6 +52,9 @@
 	android::binder::Status
 	GetDebugShowTimestamp(bool *show_timestamp_out) override;
 	android::binder::Status GetDebugShowKeys(bool *show_keys_out) override;
+	android::binder::Status RegisterCallback(
+	    const android::sp<fi::w1::wpa_supplicant::ISupplicantCallback>
+		&callback) override;
 
 private:
 	int convertDebugLevelToInternalLevel(
@@ -62,7 +65,7 @@
 	/* Raw pointer to the global structure maintained by the core. */
 	struct wpa_global *wpa_global_;
 	/* All the callback objects registered by the clients. */
-	std::vector<android::sp<fi::w1::wpa_supplicant::ISupplicantCallbacks>>
+	std::vector<android::sp<fi::w1::wpa_supplicant::ISupplicantCallback>>
 	    callbacks_;
 
 	DISALLOW_COPY_AND_ASSIGN(Supplicant);