wpa: Terminate on callback client death
supplicant/hostapd are single client HAL's. So, the daemon should
terminate when the client is dead.
Also, removed a bunch of TODO's/#ifdef guarding death notification
handling in supplicant.
Bug: 169651797
Test: Manual
i) adb shell stop
ii) Ensure wpa_supplicant is killed (via ps-ef & lshal)
Change-Id: I0d32f2a91cbe807145fe0c544460467ff24fa2cc
diff --git a/hostapd/hidl/1.3/hostapd.cpp b/hostapd/hidl/1.3/hostapd.cpp
index 17dd7f5..668d8f4 100644
--- a/hostapd/hidl/1.3/hostapd.cpp
+++ b/hostapd/hidl/1.3/hostapd.cpp
@@ -20,7 +20,6 @@
extern "C"
{
#include "common/wpa_ctrl.h"
-#include "utils/eloop.h"
}
// The HIDL implementation for hostapd creates a hostapd.conf dynamically for
@@ -550,7 +549,8 @@
using hidl_return_util::call;
using namespace android::hardware::wifi::hostapd::V1_0;
-Hostapd::Hostapd(struct hapd_interfaces* interfaces) : interfaces_(interfaces)
+Hostapd::Hostapd(struct hapd_interfaces* interfaces)
+ : interfaces_(interfaces), death_notifier_(sp<DeathNotifier>::make())
{}
Return<void> Hostapd::addAccessPoint(
@@ -779,6 +779,13 @@
V1_2::HostapdStatus Hostapd::registerCallbackInternal_1_3(
const sp<V1_3::IHostapdCallback>& callback)
{
+ if (!callback->linkToDeath(death_notifier_, 0)) {
+ wpa_printf(
+ MSG_ERROR,
+ "Error registering for death notification for "
+ "hostapd callback object");
+ return {V1_2::HostapdStatusCode::FAILURE_UNKNOWN, ""};
+ }
callbacks_.push_back(callback);
return {V1_2::HostapdStatusCode::SUCCESS, ""};
}
diff --git a/hostapd/hidl/1.3/hostapd.h b/hostapd/hidl/1.3/hostapd.h
index 059e24a..79354d3 100644
--- a/hostapd/hidl/1.3/hostapd.h
+++ b/hostapd/hidl/1.3/hostapd.h
@@ -20,12 +20,26 @@
extern "C"
{
#include "utils/common.h"
+#include "utils/eloop.h"
#include "utils/includes.h"
#include "utils/wpa_debug.h"
#include "ap/hostapd.h"
#include "ap/sta_info.h"
}
+class DeathNotifier : public android::hardware::hidl_death_recipient
+{
+public:
+ void serviceDied(
+ uint64_t /*cookie*/,
+ const android::wp<android::hidl::base::V1_0::IBase>
+ & /* who */) override
+ {
+ wpa_printf(MSG_ERROR, "Client died. Terminating...");
+ eloop_terminate();
+ }
+};
+
namespace android {
namespace hardware {
namespace wifi {
@@ -104,6 +118,8 @@
struct hapd_interfaces* interfaces_;
// Callbacks registered.
std::vector<sp<V1_3::IHostapdCallback>> callbacks_;
+ // Death notifier.
+ android::sp<DeathNotifier> death_notifier_;
DISALLOW_COPY_AND_ASSIGN(Hostapd);
};
} // namespace implementation
diff --git a/wpa_supplicant/hidl/1.4/hidl_manager.cpp b/wpa_supplicant/hidl/1.4/hidl_manager.cpp
index 5e74f48..b44f0fd 100644
--- a/wpa_supplicant/hidl/1.4/hidl_manager.cpp
+++ b/wpa_supplicant/hidl/1.4/hidl_manager.cpp
@@ -33,6 +33,7 @@
constexpr size_t kUmtsRandLenBytes = EAP_AKA_RAND_LEN;
constexpr size_t kUmtsAutnLenBytes = EAP_AKA_AUTN_LEN;
constexpr u8 kZeroBssid[6] = {0, 0, 0, 0, 0, 0};
+
/**
* Check if the provided |wpa_supplicant| structure represents a P2P iface or
* not.
@@ -62,32 +63,17 @@
*/
template <class CallbackType>
int registerForDeathAndAddCallbackHidlObjectToList(
+ const android::sp<DeathNotifier> &death_notifier,
const android::sp<CallbackType> &callback,
- const std::function<void(const android::sp<CallbackType> &)>
- &on_hidl_died_fctor,
std::vector<android::sp<CallbackType>> &callback_list)
{
-#if 0 // TODO(b/31632518): HIDL object death notifications.
- auto death_notifier = new CallbackObjectDeathNotifier<CallbackType>(
- callback, on_hidl_died_fctor);
- // Use the |callback.get()| as cookie so that we don't need to
- // store a reference to this |CallbackObjectDeathNotifier| instance
- // to use in |unlinkToDeath| later.
- // NOTE: This may cause an immediate callback if the object is already
- // dead, so add it to the list before we register for callback!
- if (android::hardware::IInterface::asBinder(callback)->linkToDeath(
- death_notifier, callback.get()) != android::OK) {
+ if (!callback->linkToDeath(death_notifier, 0)) {
wpa_printf(
MSG_ERROR,
"Error registering for death notification for "
"supplicant callback object");
- callback_list.erase(
- std::remove(
- callback_list.begin(), callback_list.end(), callback),
- callback_list.end());
return 1;
}
-#endif // TODO(b/31632518): HIDL object death notifications.
callback_list.push_back(callback);
return 0;
}
@@ -122,9 +108,8 @@
template <class CallbackType>
int addIfaceCallbackHidlObjectToMap(
+ const android::sp<DeathNotifier> &death_notifier,
const std::string &ifname, const android::sp<CallbackType> &callback,
- const std::function<void(const android::sp<CallbackType> &)>
- &on_hidl_died_fctor,
std::map<const std::string, std::vector<android::sp<CallbackType>>>
&callbacks_map)
{
@@ -138,15 +123,14 @@
// Register for death notification before we add it to our list.
return registerForDeathAndAddCallbackHidlObjectToList<CallbackType>(
- callback, on_hidl_died_fctor, iface_callback_list);
+ death_notifier, callback, iface_callback_list);
}
template <class CallbackType>
int addNetworkCallbackHidlObjectToMap(
+ const android::sp<DeathNotifier> &death_notifier,
const std::string &ifname, int network_id,
const android::sp<CallbackType> &callback,
- const std::function<void(const android::sp<CallbackType> &)>
- &on_hidl_died_fctor,
std::map<const std::string, std::vector<android::sp<CallbackType>>>
&callbacks_map)
{
@@ -163,11 +147,12 @@
// Register for death notification before we add it to our list.
return registerForDeathAndAddCallbackHidlObjectToList<CallbackType>(
- callback, on_hidl_died_fctor, network_callback_list);
+ death_notifier, callback, network_callback_list);
}
template <class CallbackType>
int removeAllIfaceCallbackHidlObjectsFromMap(
+ const android::sp<DeathNotifier> &death_notifier,
const std::string &ifname,
std::map<const std::string, std::vector<android::sp<CallbackType>>>
&callbacks_map)
@@ -175,25 +160,22 @@
auto iface_callback_map_iter = callbacks_map.find(ifname);
if (iface_callback_map_iter == callbacks_map.end())
return 1;
-#if 0 // TODO(b/31632518): HIDL object death notifications.
const auto &iface_callback_list = iface_callback_map_iter->second;
for (const auto &callback : iface_callback_list) {
- if (android::hardware::IInterface::asBinder(callback)
- ->unlinkToDeath(nullptr, callback.get()) !=
- android::OK) {
+ if (!callback->unlinkToDeath(death_notifier)) {
wpa_printf(
MSG_ERROR,
"Error deregistering for death notification for "
"iface callback object");
}
}
-#endif // TODO(b/31632518): HIDL object death notifications.
callbacks_map.erase(iface_callback_map_iter);
return 0;
}
template <class CallbackType>
int removeAllNetworkCallbackHidlObjectsFromMap(
+ const android::sp<DeathNotifier> &death_notifier,
const std::string &network_key,
std::map<const std::string, std::vector<android::sp<CallbackType>>>
&callbacks_map)
@@ -201,12 +183,9 @@
auto network_callback_map_iter = callbacks_map.find(network_key);
if (network_callback_map_iter == callbacks_map.end())
return 1;
-#if 0 // TODO(b/31632518): HIDL object death notifications.
const auto &network_callback_list = network_callback_map_iter->second;
for (const auto &callback : network_callback_list) {
- if (android::hardware::IInterface::asBinder(callback)
- ->unlinkToDeath(nullptr, callback.get()) !=
- android::OK) {
+ if (!callback->unlinkToDeath(death_notifier)) {
wpa_printf(
MSG_ERROR,
"Error deregistering for death "
@@ -214,7 +193,6 @@
"network callback object");
}
}
-#endif // TODO(b/31632518): HIDL object death notifications.
callbacks_map.erase(network_callback_map_iter);
return 0;
}
@@ -424,6 +402,8 @@
{
// Create the main hidl service object and register it.
supplicant_object_ = new Supplicant(global);
+ wpa_global_ = global;
+ death_notifier_ = sp<DeathNotifier>::make(global);
if (supplicant_object_->registerAsService() != android::NO_ERROR) {
return 1;
}
@@ -518,13 +498,13 @@
!removeHidlObjectFromMap(wpa_s->ifname, p2p_iface_object_map_);
if (success) { // assumed to be P2P
success = !removeAllIfaceCallbackHidlObjectsFromMap(
- wpa_s->ifname, p2p_iface_callbacks_map_);
+ death_notifier_, wpa_s->ifname, p2p_iface_callbacks_map_);
} else { // assumed to be STA
success = !removeHidlObjectFromMap(
wpa_s->ifname, sta_iface_object_map_);
if (success) {
success = !removeAllIfaceCallbackHidlObjectsFromMap(
- wpa_s->ifname, sta_iface_callbacks_map_);
+ death_notifier_, wpa_s->ifname, sta_iface_callbacks_map_);
}
}
if (!success) {
@@ -638,7 +618,7 @@
return 1;
}
if (removeAllNetworkCallbackHidlObjectsFromMap(
- network_key, p2p_network_callbacks_map_))
+ death_notifier_, network_key, p2p_network_callbacks_map_))
return 1;
// Invoke the |onNetworkRemoved| method on all registered
@@ -659,7 +639,7 @@
return 1;
}
if (removeAllNetworkCallbackHidlObjectsFromMap(
- network_key, sta_network_callbacks_map_))
+ death_notifier_, network_key, sta_network_callbacks_map_))
return 1;
// Invoke the |onNetworkRemoved| method on all registered
@@ -1872,13 +1852,9 @@
int HidlManager::addSupplicantCallbackHidlObject(
const android::sp<ISupplicantCallback> &callback)
{
- // Register for death notification before we add it to our list.
- auto on_hidl_died_fctor = std::bind(
- &HidlManager::removeSupplicantCallbackHidlObject, this,
- std::placeholders::_1);
return registerForDeathAndAddCallbackHidlObjectToList<
ISupplicantCallback>(
- callback, on_hidl_died_fctor, supplicant_callbacks_);
+ death_notifier_, callback, supplicant_callbacks_);
}
/**
@@ -1894,13 +1870,8 @@
const std::string &ifname,
const android::sp<ISupplicantP2pIfaceCallback> &callback)
{
- const std::function<void(
- const android::sp<ISupplicantP2pIfaceCallback> &)>
- on_hidl_died_fctor = std::bind(
- &HidlManager::removeP2pIfaceCallbackHidlObject, this, ifname,
- std::placeholders::_1);
return addIfaceCallbackHidlObjectToMap(
- ifname, callback, on_hidl_died_fctor, p2p_iface_callbacks_map_);
+ death_notifier_, ifname, callback, p2p_iface_callbacks_map_);
}
/**
@@ -1916,13 +1887,8 @@
const std::string &ifname,
const android::sp<ISupplicantStaIfaceCallback> &callback)
{
- const std::function<void(
- const android::sp<ISupplicantStaIfaceCallback> &)>
- on_hidl_died_fctor = std::bind(
- &HidlManager::removeStaIfaceCallbackHidlObject, this, ifname,
- std::placeholders::_1);
return addIfaceCallbackHidlObjectToMap(
- ifname, callback, on_hidl_died_fctor, sta_iface_callbacks_map_);
+ death_notifier_, ifname, callback, sta_iface_callbacks_map_);
}
/**
@@ -1939,13 +1905,8 @@
const std::string &ifname, int network_id,
const android::sp<ISupplicantP2pNetworkCallback> &callback)
{
- const std::function<void(
- const android::sp<ISupplicantP2pNetworkCallback> &)>
- on_hidl_died_fctor = std::bind(
- &HidlManager::removeP2pNetworkCallbackHidlObject, this, ifname,
- network_id, std::placeholders::_1);
return addNetworkCallbackHidlObjectToMap(
- ifname, network_id, callback, on_hidl_died_fctor,
+ death_notifier_, ifname, network_id, callback,
p2p_network_callbacks_map_);
}
@@ -1963,13 +1924,8 @@
const std::string &ifname, int network_id,
const android::sp<ISupplicantStaNetworkCallback> &callback)
{
- const std::function<void(
- const android::sp<ISupplicantStaNetworkCallback> &)>
- on_hidl_died_fctor = std::bind(
- &HidlManager::removeStaNetworkCallbackHidlObject, this, ifname,
- network_id, std::placeholders::_1);
return addNetworkCallbackHidlObjectToMap(
- ifname, network_id, callback, on_hidl_died_fctor,
+ death_notifier_, ifname, network_id, callback,
sta_network_callbacks_map_);
}
diff --git a/wpa_supplicant/hidl/1.4/hidl_manager.h b/wpa_supplicant/hidl/1.4/hidl_manager.h
index e024427..496ceae 100644
--- a/wpa_supplicant/hidl/1.4/hidl_manager.h
+++ b/wpa_supplicant/hidl/1.4/hidl_manager.h
@@ -34,6 +34,26 @@
#include "driver_i.h"
}
+class DeathNotifier : public android::hardware::hidl_death_recipient
+{
+public:
+ DeathNotifier(struct wpa_global *wpa_global)
+ : wpa_global_(wpa_global)
+ {}
+
+ void serviceDied(
+ uint64_t /*cookie*/,
+ const android::wp<android::hidl::base::V1_0::IBase>
+ & /* who */) override
+ {
+ wpa_printf(MSG_ERROR, "Client died. Terminating...");
+ wpa_supplicant_terminate_proc(wpa_global_);
+ }
+
+private:
+ struct wpa_global *wpa_global_;
+};
+
namespace android {
namespace hardware {
namespace wifi {
@@ -241,6 +261,10 @@
// Singleton instance of this class.
static HidlManager *instance_;
+ // Raw pointer to the global structure maintained by the core.
+ struct wpa_global *wpa_global_;
+ // Death notifier.
+ android::sp<DeathNotifier> death_notifier_;
// The main hidl service object.
android::sp<Supplicant> supplicant_object_;
// Map of all the P2P interface specific hidl objects controlled by
@@ -294,40 +318,6 @@
const std::string,
std::vector<android::sp<ISupplicantStaNetworkCallback>>>
sta_network_callbacks_map_;
-
-#if 0 // TODO(b/31632518): HIDL object death notifications.
- /**
- * Helper class used to deregister the callback object reference from
- * our callback list on the death of the hidl object.
- * This class stores a reference of the callback hidl object and a
- * function to be called to indicate the death of the hidl object.
- */
- template <class CallbackType>
- class CallbackObjectDeathNotifier
- : public android::hardware::IBinder::DeathRecipient
- {
- public:
- CallbackObjectDeathNotifier(
- const android::sp<CallbackType> &callback,
- const std::function<void(const android::sp<CallbackType> &)>
- &on_hidl_died)
- : callback_(callback), on_hidl_died_(on_hidl_died)
- {
- }
- void binderDied(const android::wp<android::hardware::IBinder>
- & /* who */) override
- {
- on_hidl_died_(callback_);
- }
-
- private:
- // The callback hidl object reference.
- const android::sp<CallbackType> callback_;
- // Callback function to be called when the hidl dies.
- const std::function<void(const android::sp<CallbackType> &)>
- on_hidl_died_;
- };
-#endif
};
// The hidl interface uses some values which are the same as internal ones to