binder: Add iface/network addition/removal callbacks

Add generic functions to invoke callbacks on all registered
|ISupplicantCallback|, |IIfaceCallback| & |INetworkCallback| objects.

Invoke callbacks to indicate:
1. Creation of new interfaces.
2. Removal of interfaces.
3. Addition of networks.
4. Removal of networks.

BUG: 30093041
Change-Id: I5e7c4a8470a3886b89c85d8851ae9f3cb7d5a820
TEST: Ran integration tests under wificond.
Signed-off-by: Roshan Pius <rpius@google.com>
diff --git a/wpa_supplicant/binder/binder_manager.cpp b/wpa_supplicant/binder/binder_manager.cpp
index f9ed805..d5a502c 100644
--- a/wpa_supplicant/binder/binder_manager.cpp
+++ b/wpa_supplicant/binder/binder_manager.cpp
@@ -75,6 +75,12 @@
 	// Initialize the vector of callbacks for this object.
 	iface_callbacks_map_[ifname] =
 	    std::vector<android::sp<fi::w1::wpa_supplicant::IIfaceCallback>>();
+
+	// Invoke the |OnInterfaceCreated| method on all registered callbacks.
+	callWithEachSupplicantCallback(std::bind(
+	    &fi::w1::wpa_supplicant::ISupplicantCallback::OnInterfaceCreated,
+	    std::placeholders::_1,
+	    ifname));
 	return 0;
 }
 
@@ -113,6 +119,12 @@
 		}
 	}
 	iface_callbacks_map_.erase(iface_callback_map_iter);
+
+	// Invoke the |OnInterfaceRemoved| method on all registered callbacks.
+	callWithEachSupplicantCallback(std::bind(
+	    &fi::w1::wpa_supplicant::ISupplicantCallback::OnInterfaceRemoved,
+		std::placeholders::_1,
+	    ifname));
 	return 0;
 }
 
@@ -146,6 +158,14 @@
 	// Initialize the vector of callbacks for this object.
 	network_callbacks_map_[network_key] = std::vector<
 	    android::sp<fi::w1::wpa_supplicant::INetworkCallback>>();
+
+	// Invoke the |OnNetworkAdded| method on all registered callbacks.
+	callWithEachIfaceCallback(
+	    wpa_s->ifname,
+	    std::bind(
+		&fi::w1::wpa_supplicant::IIfaceCallback::OnNetworkAdded,
+		std::placeholders::_1,
+		ssid->id));
 	return 0;
 }
 
@@ -190,6 +210,14 @@
 		}
 	}
 	network_callbacks_map_.erase(network_callback_map_iter);
+
+	// Invoke the |OnNetworkRemoved| method on all registered callbacks.
+	callWithEachIfaceCallback(
+	    wpa_s->ifname,
+	    std::bind(
+		&fi::w1::wpa_supplicant::IIfaceCallback::OnNetworkRemoved,
+		std::placeholders::_1,
+		ssid->id));
 	return 0;
 }
 
@@ -454,4 +482,75 @@
 	}
 	return 0;
 }
+
+/**
+ * Helper function to invoke the provided callback method on all the
+ * registered |ISupplicantCallback| callback binder objects.
+ *
+ * @param method Pointer to the required binder method from
+ * |ISupplicantCallback|.
+ */
+void BinderManager::callWithEachSupplicantCallback(
+    const std::function<android::binder::Status(
+	android::sp<fi::w1::wpa_supplicant::ISupplicantCallback>)> &method)
+{
+	for (const auto &callback : supplicant_callbacks_) {
+		method(callback);
+	}
+}
+
+/**
+ * Helper fucntion to invoke the provided callback method on all the
+ * registered |IIfaceCallback| callback binder objects for the specified
+ * |ifname|.
+ *
+ * @param ifname Name of the corresponding interface.
+ * @param method Pointer to the required binder method from |IIfaceCallback|.
+ */
+void BinderManager::callWithEachIfaceCallback(
+    const std::string &ifname,
+    const std::function<android::binder::Status(
+	android::sp<fi::w1::wpa_supplicant::IIfaceCallback>)> &method)
+{
+	if (ifname.empty())
+		return;
+
+	auto iface_callback_map_iter = iface_callbacks_map_.find(ifname);
+	if (iface_callback_map_iter == iface_callbacks_map_.end())
+		return;
+	const auto &iface_callback_list = iface_callback_map_iter->second;
+	for (const auto &callback : iface_callback_list) {
+		method(callback);
+	}
+}
+
+/**
+ * Helper function to invoke the provided callback method on all the
+ * registered |INetworkCallback| callback binder objects for the specified
+ * |ifname| & |network_id|.
+ *
+ * @param ifname Name of the corresponding interface.
+ * @param network_id ID of the corresponding network.
+ * @param method Pointer to the required binder method from |INetworkCallback|.
+ */
+void BinderManager::callWithEachNetworkCallback(
+    const std::string &ifname, int network_id,
+    const std::function<android::binder::Status(
+	android::sp<fi::w1::wpa_supplicant::INetworkCallback>)> &method)
+{
+	if (ifname.empty() || network_id < 0)
+		return;
+
+	// Generate the key to be used to lookup the network.
+	const std::string network_key =
+	    getNetworkObjectMapKey(ifname, network_id);
+	auto network_callback_map_iter =
+	    network_callbacks_map_.find(network_key);
+	if (network_callback_map_iter == network_callbacks_map_.end())
+		return;
+	const auto &network_callback_list = network_callback_map_iter->second;
+	for (const auto &callback : network_callback_list) {
+		method(callback);
+	}
+}
 } // namespace wpa_supplicant_binder
diff --git a/wpa_supplicant/binder/binder_manager.h b/wpa_supplicant/binder/binder_manager.h
index 1d9485b..0d5a914 100644
--- a/wpa_supplicant/binder/binder_manager.h
+++ b/wpa_supplicant/binder/binder_manager.h
@@ -93,6 +93,20 @@
 		&on_binder_died_fctor,
 	    std::vector<android::sp<CallbackType>> &callback_list);
 
+	void callWithEachSupplicantCallback(
+	    const std::function<android::binder::Status(
+		android::sp<fi::w1::wpa_supplicant::ISupplicantCallback>)>
+		&method);
+	void callWithEachIfaceCallback(
+	    const std::string &ifname,
+	    const std::function<android::binder::Status(
+		android::sp<fi::w1::wpa_supplicant::IIfaceCallback>)> &method);
+	void callWithEachNetworkCallback(
+	    const std::string &ifname, int network_id,
+	    const std::function<android::binder::Status(
+		android::sp<fi::w1::wpa_supplicant::INetworkCallback>)>
+		&method);
+
 	// Singleton instance of this class.
 	static BinderManager *instance_;
 	// The main binder service object.
diff --git a/wpa_supplicant/binder/fi/w1/wpa_supplicant/IIfaceCallback.aidl b/wpa_supplicant/binder/fi/w1/wpa_supplicant/IIfaceCallback.aidl
index 0e2e071..f740b94 100644
--- a/wpa_supplicant/binder/fi/w1/wpa_supplicant/IIfaceCallback.aidl
+++ b/wpa_supplicant/binder/fi/w1/wpa_supplicant/IIfaceCallback.aidl
@@ -19,4 +19,17 @@
  */
 @utf8InCpp
 interface IIfaceCallback {
+	/**
+	 * Used to indicate that a new network has been added.
+	 *
+	 * @param id Network ID allocated to the corresponding network.
+	 */
+	oneway void OnNetworkAdded(int id);
+
+	/**
+	 * Used to indicate that a network has been removed.
+	 *
+	 * @param id Network ID allocated to the corresponding network.
+	 */
+	oneway void OnNetworkRemoved(int network_id);
 }
diff --git a/wpa_supplicant/binder/fi/w1/wpa_supplicant/ISupplicantCallback.aidl b/wpa_supplicant/binder/fi/w1/wpa_supplicant/ISupplicantCallback.aidl
index 99aca3d..c607f0d 100644
--- a/wpa_supplicant/binder/fi/w1/wpa_supplicant/ISupplicantCallback.aidl
+++ b/wpa_supplicant/binder/fi/w1/wpa_supplicant/ISupplicantCallback.aidl
@@ -18,4 +18,17 @@
  */
 @utf8InCpp
 interface ISupplicantCallback {
+	/**
+	 * Used to indicate that a new interface has been created.
+	 *
+	 * @param ifname Name of the network interface, e.g., wlan0
+	 */
+	oneway void OnInterfaceCreated(String ifname);
+
+	/**
+	 * Used to indicate that an interface has been removed.
+	 *
+	 * @param ifname Name of the network interface, e.g., wlan0
+	 */
+	oneway void OnInterfaceRemoved(String ifname);
 }