binder: Notify iface add/remove to binder

Notify |BinderManager| about any new iface addition/removal from
|wpa_supplicant| core.
|Iface| objects are stateless in the sense that they only
hold the name of the iface it controls. Every RPC call through the iface object
will first invoke |wpa_supplicant_get_iface| to ensure that the iface still
exists in the wpa_supplicant core.

While there,
1. Add some debug logs in binder.cpp.
2. Change C style comments to c++ style.
3. Add @utf8incpp annotation at the interface level in all the aidl files.

BUG: 29998764
TEST: Tested using the |gTest| integration tests. Will upload these under
|wificond|

Change-Id: If69bfaece7a6f69640fe8cbf90d1006a88aef8af
Signed-off-by: Roshan Pius <rpius@google.com>
diff --git a/wpa_supplicant/binder/binder.cpp b/wpa_supplicant/binder/binder.cpp
index 750e878..eb6006c 100644
--- a/wpa_supplicant/binder/binder.cpp
+++ b/wpa_supplicant/binder/binder.cpp
@@ -41,12 +41,16 @@
 		return NULL;
 	priv->global = global;
 
+	wpa_printf(MSG_DEBUG, "Initing binder control");
+
 	android::ProcessState::self()->setThreadPoolMaxThreadCount(0);
 	android::IPCThreadState::self()->disableBackgroundScheduling(true);
 	android::IPCThreadState::self()->setupPolling(&priv->binder_fd);
-	wpa_printf(MSG_INFO, "Process binder events on FD %d", priv->binder_fd);
 	if (priv->binder_fd < 0)
 		goto err;
+
+	wpa_printf(
+	    MSG_INFO, "Processing binder events on FD %d", priv->binder_fd);
 	/* Look for read events from the binder socket in the eloop. */
 	if (eloop_register_read_sock(
 		priv->binder_fd, wpas_binder_sock_handler, global, priv) < 0)
@@ -72,6 +76,8 @@
 	if (!priv)
 		return;
 
+	wpa_printf(MSG_DEBUG, "Deiniting binder control");
+
 	wpa_supplicant_binder::BinderManager::destroyInstance();
 	eloop_unregister_read_sock(priv->binder_fd);
 	android::IPCThreadState::shutdown();
@@ -82,6 +88,10 @@
 	if (!wpa_s->global->binder)
 		return 1;
 
+	wpa_printf(
+	    MSG_DEBUG, "Registering interface to binder control: %s",
+	    wpa_s->ifname);
+
 	wpa_supplicant_binder::BinderManager *binder_manager =
 	    wpa_supplicant_binder::BinderManager::getInstance();
 	if (!binder_manager)
@@ -95,6 +105,10 @@
 	if (!wpa_s->global->binder)
 		return 1;
 
+	wpa_printf(
+	    MSG_DEBUG, "Deregistering interface from binder control: %s",
+	    wpa_s->ifname);
+
 	wpa_supplicant_binder::BinderManager *binder_manager =
 	    wpa_supplicant_binder::BinderManager::getInstance();
 	if (!binder_manager)
diff --git a/wpa_supplicant/binder/binder_manager.cpp b/wpa_supplicant/binder/binder_manager.cpp
index 27e8ded..6551b50 100644
--- a/wpa_supplicant/binder/binder_manager.cpp
+++ b/wpa_supplicant/binder/binder_manager.cpp
@@ -59,7 +59,7 @@
 	if (iface_object_map_.find(iface_key) != iface_object_map_.end())
 		return 1;
 
-	iface_object_map_[iface_key] = new Iface(wpa_s);
+	iface_object_map_[iface_key] = new Iface(wpa_s->global, wpa_s->ifname);
 	if (!iface_object_map_[iface_key].get())
 		return 1;
 
diff --git a/wpa_supplicant/binder/fi/w1/wpa_supplicant/IIface.aidl b/wpa_supplicant/binder/fi/w1/wpa_supplicant/IIface.aidl
index ea11d42..fb77ffa 100644
--- a/wpa_supplicant/binder/fi/w1/wpa_supplicant/IIface.aidl
+++ b/wpa_supplicant/binder/fi/w1/wpa_supplicant/IIface.aidl
@@ -12,5 +12,17 @@
 /**
  * Interface exposed by wpa_supplicant for each network interface it controls.
  */
+@utf8InCpp
 interface IIface {
+	/* Error values returned by the service to RPC method calls. */
+	const int ERROR_INVALID_ARGS = 1;
+	const int ERROR_UNKNOWN = 2;
+	const int ERROR_IFACE_UNKNOWN = 3;
+
+	/**
+	 * Retrieves the name of the iface this object controls.
+	 *
+	 * @return Name of the network interface, e.g., wlan0
+	 */
+	String GetName();
 }
diff --git a/wpa_supplicant/binder/fi/w1/wpa_supplicant/ISupplicant.aidl b/wpa_supplicant/binder/fi/w1/wpa_supplicant/ISupplicant.aidl
index 1cbee20..a52f857 100644
--- a/wpa_supplicant/binder/fi/w1/wpa_supplicant/ISupplicant.aidl
+++ b/wpa_supplicant/binder/fi/w1/wpa_supplicant/ISupplicant.aidl
@@ -16,6 +16,7 @@
  * Interface exposed by the wpa_supplicant binder service registered
  * with the service manager with name: fi.w1.wpa_supplicant.
  */
+@utf8InCpp
 interface ISupplicant {
 	/* Error values returned by the service to RPC method calls. */
 	const int ERROR_INVALID_ARGS = 1;
@@ -45,7 +46,7 @@
 	 *
 	 * @param ifname Name of the network interface, e.g., wlan0
 	 */
-	void RemoveInterface(in @utf8InCpp String ifname);
+	void RemoveInterface(in String ifname);
 
 	/**
 	 * Gets a binder object for the interface corresponding to ifname
@@ -55,5 +56,5 @@
 	 *
 	 * @return Binder object representing the interface.
 	 */
-	IIface GetInterface(in @utf8InCpp String ifname);
+	IIface GetInterface(in String ifname);
 }
diff --git a/wpa_supplicant/binder/fi/w1/wpa_supplicant/ISupplicantCallbacks.aidl b/wpa_supplicant/binder/fi/w1/wpa_supplicant/ISupplicantCallbacks.aidl
index d624d91..02261c7 100644
--- a/wpa_supplicant/binder/fi/w1/wpa_supplicant/ISupplicantCallbacks.aidl
+++ b/wpa_supplicant/binder/fi/w1/wpa_supplicant/ISupplicantCallbacks.aidl
@@ -16,5 +16,6 @@
  * 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 c61b3b0..4faa147 100644
--- a/wpa_supplicant/binder/iface.cpp
+++ b/wpa_supplicant/binder/iface.cpp
@@ -11,6 +11,36 @@
 
 namespace wpa_supplicant_binder {
 
-Iface::Iface(struct wpa_supplicant *wpa_s) : wpa_s_(wpa_s) {}
+Iface::Iface(struct wpa_global *wpa_global, const char ifname[])
+    : wpa_global_(wpa_global), ifname_(ifname)
+{
+}
 
-} /* namespace wpa_supplicant_binder */
+android::binder::Status Iface::GetName(std::string *iface_name_out)
+{
+	// We could directly return the name we hold, but let's verify
+	// if the underlying iface still exists.
+	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+	if (!wpa_s) {
+		return android::binder::Status::fromServiceSpecificError(
+		    ERROR_IFACE_UNKNOWN,
+		    "wpa_supplicant does not control this interface.");
+	}
+
+	*iface_name_out = ifname_;
+	return android::binder::Status::ok();
+}
+
+/**
+ * Retrieve the underlying |wpa_supplicant| struct pointer for
+ * this iface.
+ * If the underlying iface is removed, then all RPC method calls
+ * on this object will return failure.
+ */
+wpa_supplicant *Iface::retrieveIfacePtr()
+{
+	return wpa_supplicant_get_iface(
+	    (struct wpa_global *)wpa_global_, ifname_.c_str());
+}
+
+} // namespace wpa_supplicant_binder
diff --git a/wpa_supplicant/binder/iface.h b/wpa_supplicant/binder/iface.h
index c0ee12c..f87f19f 100644
--- a/wpa_supplicant/binder/iface.h
+++ b/wpa_supplicant/binder/iface.h
@@ -28,15 +28,22 @@
 class Iface : public fi::w1::wpa_supplicant::BnIface
 {
 public:
-	Iface(struct wpa_supplicant *wpa_s);
+	Iface(struct wpa_global *wpa_global, const char ifname[]);
 	virtual ~Iface() = default;
 
+	// Binder methods exposed in aidl.
+	android::binder::Status GetName(std::string *iface_name_out) override;
+
 private:
-	/* Raw pointer to the structure maintained by the core for this
-	 * interface. */
-	struct wpa_supplicant *wpa_s_;
+	// Reference to the global wpa_struct. This is assumed to be valid for
+	// the lifetime of the process.
+	const struct wpa_global *wpa_global_;
+	// Name of the iface this binder object controls
+	const std::string ifname_;
+
+	struct wpa_supplicant *retrieveIfacePtr();
 };
 
-} /* namespace wpa_supplicant_binder */
+} // namespace wpa_supplicant_binder
 
-#endif /* WPA_SUPPLICANT_BINDER_IFACE_H */
+#endif // WPA_SUPPLICANT_BINDER_IFACE_H
diff --git a/wpa_supplicant/notify.c b/wpa_supplicant/notify.c
index 67e36ae..536f3e6 100644
--- a/wpa_supplicant/notify.c
+++ b/wpa_supplicant/notify.c
@@ -70,6 +70,9 @@
 	if (wpas_dbus_register_interface(wpa_s))
 		return -1;
 
+	if (wpas_binder_register_interface(wpa_s))
+		return -1;
+
 	return 0;
 }
 
@@ -84,6 +87,8 @@
 
 	/* unregister interface in new DBus ctrl iface */
 	wpas_dbus_unregister_interface(wpa_s);
+
+	wpas_binder_unregister_interface(wpa_s);
 }