mirror of
https://github.com/Evolution-X/hardware_interfaces
synced 2026-02-01 16:50:18 +00:00
Merge "wifi(implementation): Make WifiLegacyHal.stop() blocking" into oc-mr1-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
ac2cd9e8ea
@@ -55,6 +55,25 @@ Return<void> validateAndCall(
|
|||||||
return Void();
|
return Void();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Use for HIDL methods which return only an instance of WifiStatus.
|
||||||
|
// This version passes the global lock acquired to the body of the method.
|
||||||
|
// Note: Only used by IWifi::stop() currently.
|
||||||
|
template <typename ObjT, typename WorkFuncT, typename... Args>
|
||||||
|
Return<void> validateAndCallWithLock(
|
||||||
|
ObjT* obj,
|
||||||
|
WifiStatusCode status_code_if_invalid,
|
||||||
|
WorkFuncT&& work,
|
||||||
|
const std::function<void(const WifiStatus&)>& hidl_cb,
|
||||||
|
Args&&... args) {
|
||||||
|
auto lock = hidl_sync_util::acquireGlobalLock();
|
||||||
|
if (obj->isValid()) {
|
||||||
|
hidl_cb((obj->*work)(&lock, std::forward<Args>(args)...));
|
||||||
|
} else {
|
||||||
|
hidl_cb(createWifiStatus(status_code_if_invalid));
|
||||||
|
}
|
||||||
|
return Void();
|
||||||
|
}
|
||||||
|
|
||||||
// Use for HIDL methods which return instance of WifiStatus and a single return
|
// Use for HIDL methods which return instance of WifiStatus and a single return
|
||||||
// value.
|
// value.
|
||||||
template <typename ObjT, typename WorkFuncT, typename ReturnT, typename... Args>
|
template <typename ObjT, typename WorkFuncT, typename ReturnT, typename... Args>
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ namespace wifi {
|
|||||||
namespace V1_1 {
|
namespace V1_1 {
|
||||||
namespace implementation {
|
namespace implementation {
|
||||||
using hidl_return_util::validateAndCall;
|
using hidl_return_util::validateAndCall;
|
||||||
|
using hidl_return_util::validateAndCallWithLock;
|
||||||
|
|
||||||
Wifi::Wifi()
|
Wifi::Wifi()
|
||||||
: legacy_hal_(new legacy_hal::WifiLegacyHal()),
|
: legacy_hal_(new legacy_hal::WifiLegacyHal()),
|
||||||
@@ -64,8 +65,8 @@ Return<void> Wifi::start(start_cb hidl_status_cb) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Return<void> Wifi::stop(stop_cb hidl_status_cb) {
|
Return<void> Wifi::stop(stop_cb hidl_status_cb) {
|
||||||
return validateAndCall(
|
return validateAndCallWithLock(this, WifiStatusCode::ERROR_UNKNOWN,
|
||||||
this, WifiStatusCode::ERROR_UNKNOWN, &Wifi::stopInternal, hidl_status_cb);
|
&Wifi::stopInternal, hidl_status_cb);
|
||||||
}
|
}
|
||||||
|
|
||||||
Return<void> Wifi::getChipIds(getChipIds_cb hidl_status_cb) {
|
Return<void> Wifi::getChipIds(getChipIds_cb hidl_status_cb) {
|
||||||
@@ -120,7 +121,8 @@ WifiStatus Wifi::startInternal() {
|
|||||||
return wifi_status;
|
return wifi_status;
|
||||||
}
|
}
|
||||||
|
|
||||||
WifiStatus Wifi::stopInternal() {
|
WifiStatus Wifi::stopInternal(
|
||||||
|
/* NONNULL */ std::unique_lock<std::recursive_mutex>* lock) {
|
||||||
if (run_state_ == RunState::STOPPED) {
|
if (run_state_ == RunState::STOPPED) {
|
||||||
return createWifiStatus(WifiStatusCode::SUCCESS);
|
return createWifiStatus(WifiStatusCode::SUCCESS);
|
||||||
} else if (run_state_ == RunState::STOPPING) {
|
} else if (run_state_ == RunState::STOPPING) {
|
||||||
@@ -133,7 +135,7 @@ WifiStatus Wifi::stopInternal() {
|
|||||||
chip_->invalidate();
|
chip_->invalidate();
|
||||||
chip_.clear();
|
chip_.clear();
|
||||||
}
|
}
|
||||||
WifiStatus wifi_status = stopLegacyHalAndDeinitializeModeController();
|
WifiStatus wifi_status = stopLegacyHalAndDeinitializeModeController(lock);
|
||||||
if (wifi_status.code == WifiStatusCode::SUCCESS) {
|
if (wifi_status.code == WifiStatusCode::SUCCESS) {
|
||||||
for (const auto& callback : event_cb_handler_.getCallbacks()) {
|
for (const auto& callback : event_cb_handler_.getCallbacks()) {
|
||||||
if (!callback->onStop().isOk()) {
|
if (!callback->onStop().isOk()) {
|
||||||
@@ -180,11 +182,12 @@ WifiStatus Wifi::initializeLegacyHal() {
|
|||||||
return createWifiStatus(WifiStatusCode::SUCCESS);
|
return createWifiStatus(WifiStatusCode::SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
WifiStatus Wifi::stopLegacyHalAndDeinitializeModeController() {
|
WifiStatus Wifi::stopLegacyHalAndDeinitializeModeController(
|
||||||
|
/* NONNULL */ std::unique_lock<std::recursive_mutex>* lock) {
|
||||||
run_state_ = RunState::STOPPING;
|
run_state_ = RunState::STOPPING;
|
||||||
const auto on_complete_callback_ = [&]() { run_state_ = RunState::STOPPED; };
|
const auto on_complete_callback_ = [&]() { run_state_ = RunState::STOPPED; };
|
||||||
legacy_hal::wifi_error legacy_status =
|
legacy_hal::wifi_error legacy_status =
|
||||||
legacy_hal_->stop(on_complete_callback_);
|
legacy_hal_->stop(lock, on_complete_callback_);
|
||||||
if (legacy_status != legacy_hal::WIFI_SUCCESS) {
|
if (legacy_status != legacy_hal::WIFI_SUCCESS) {
|
||||||
LOG(ERROR) << "Failed to stop legacy HAL: "
|
LOG(ERROR) << "Failed to stop legacy HAL: "
|
||||||
<< legacyErrorToString(legacy_status);
|
<< legacyErrorToString(legacy_status);
|
||||||
|
|||||||
@@ -61,12 +61,13 @@ class Wifi : public V1_1::IWifi {
|
|||||||
WifiStatus registerEventCallbackInternal(
|
WifiStatus registerEventCallbackInternal(
|
||||||
const sp<IWifiEventCallback>& event_callback);
|
const sp<IWifiEventCallback>& event_callback);
|
||||||
WifiStatus startInternal();
|
WifiStatus startInternal();
|
||||||
WifiStatus stopInternal();
|
WifiStatus stopInternal(std::unique_lock<std::recursive_mutex>* lock);
|
||||||
std::pair<WifiStatus, std::vector<ChipId>> getChipIdsInternal();
|
std::pair<WifiStatus, std::vector<ChipId>> getChipIdsInternal();
|
||||||
std::pair<WifiStatus, sp<IWifiChip>> getChipInternal(ChipId chip_id);
|
std::pair<WifiStatus, sp<IWifiChip>> getChipInternal(ChipId chip_id);
|
||||||
|
|
||||||
WifiStatus initializeLegacyHal();
|
WifiStatus initializeLegacyHal();
|
||||||
WifiStatus stopLegacyHalAndDeinitializeModeController();
|
WifiStatus stopLegacyHalAndDeinitializeModeController(
|
||||||
|
std::unique_lock<std::recursive_mutex>* lock);
|
||||||
|
|
||||||
// Instance is created in this root level |IWifi| HIDL interface object
|
// Instance is created in this root level |IWifi| HIDL interface object
|
||||||
// and shared with all the child HIDL interface objects.
|
// and shared with all the child HIDL interface objects.
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
|
#include <chrono>
|
||||||
|
|
||||||
#include <android-base/logging.h>
|
#include <android-base/logging.h>
|
||||||
#include <cutils/properties.h>
|
#include <cutils/properties.h>
|
||||||
@@ -34,6 +35,7 @@ static constexpr uint32_t kMaxGscanFrequenciesForBand = 64;
|
|||||||
static constexpr uint32_t kLinkLayerStatsDataMpduSizeThreshold = 128;
|
static constexpr uint32_t kLinkLayerStatsDataMpduSizeThreshold = 128;
|
||||||
static constexpr uint32_t kMaxWakeReasonStatsArraySize = 32;
|
static constexpr uint32_t kMaxWakeReasonStatsArraySize = 32;
|
||||||
static constexpr uint32_t kMaxRingBuffers = 10;
|
static constexpr uint32_t kMaxRingBuffers = 10;
|
||||||
|
static constexpr uint32_t kMaxStopCompleteWaitMs = 50;
|
||||||
|
|
||||||
// Helper function to create a non-const char* for legacy Hal API's.
|
// Helper function to create a non-const char* for legacy Hal API's.
|
||||||
std::vector<char> makeCharVec(const std::string& str) {
|
std::vector<char> makeCharVec(const std::string& str) {
|
||||||
@@ -53,7 +55,8 @@ namespace legacy_hal {
|
|||||||
// Legacy HAL functions accept "C" style function pointers, so use global
|
// Legacy HAL functions accept "C" style function pointers, so use global
|
||||||
// functions to pass to the legacy HAL function and store the corresponding
|
// functions to pass to the legacy HAL function and store the corresponding
|
||||||
// std::function methods to be invoked.
|
// std::function methods to be invoked.
|
||||||
// Callback to be invoked once |stop| is complete.
|
//
|
||||||
|
// Callback to be invoked once |stop| is complete
|
||||||
std::function<void(wifi_handle handle)> on_stop_complete_internal_callback;
|
std::function<void(wifi_handle handle)> on_stop_complete_internal_callback;
|
||||||
void onAsyncStopComplete(wifi_handle handle) {
|
void onAsyncStopComplete(wifi_handle handle) {
|
||||||
const auto lock = hidl_sync_util::acquireGlobalLock();
|
const auto lock = hidl_sync_util::acquireGlobalLock();
|
||||||
@@ -369,6 +372,7 @@ wifi_error WifiLegacyHal::start() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
wifi_error WifiLegacyHal::stop(
|
wifi_error WifiLegacyHal::stop(
|
||||||
|
/* NONNULL */ std::unique_lock<std::recursive_mutex>* lock,
|
||||||
const std::function<void()>& on_stop_complete_user_callback) {
|
const std::function<void()>& on_stop_complete_user_callback) {
|
||||||
if (!is_started_) {
|
if (!is_started_) {
|
||||||
LOG(DEBUG) << "Legacy HAL already stopped";
|
LOG(DEBUG) << "Legacy HAL already stopped";
|
||||||
@@ -376,19 +380,27 @@ wifi_error WifiLegacyHal::stop(
|
|||||||
return WIFI_SUCCESS;
|
return WIFI_SUCCESS;
|
||||||
}
|
}
|
||||||
LOG(DEBUG) << "Stopping legacy HAL";
|
LOG(DEBUG) << "Stopping legacy HAL";
|
||||||
on_stop_complete_internal_callback = [on_stop_complete_user_callback,
|
on_stop_complete_internal_callback =
|
||||||
this](wifi_handle handle) {
|
[on_stop_complete_user_callback, this](wifi_handle handle) {
|
||||||
CHECK_EQ(global_handle_, handle) << "Handle mismatch";
|
CHECK_EQ(global_handle_, handle) << "Handle mismatch";
|
||||||
|
LOG(INFO) << "Legacy HAL stop complete callback received";
|
||||||
// Invalidate all the internal pointers now that the HAL is
|
// Invalidate all the internal pointers now that the HAL is
|
||||||
// stopped.
|
// stopped.
|
||||||
invalidate();
|
invalidate();
|
||||||
iface_tool_.SetWifiUpState(false);
|
iface_tool_.SetWifiUpState(false);
|
||||||
on_stop_complete_user_callback();
|
on_stop_complete_user_callback();
|
||||||
|
is_started_ = false;
|
||||||
};
|
};
|
||||||
awaiting_event_loop_termination_ = true;
|
awaiting_event_loop_termination_ = true;
|
||||||
global_func_table_.wifi_cleanup(global_handle_, onAsyncStopComplete);
|
global_func_table_.wifi_cleanup(global_handle_, onAsyncStopComplete);
|
||||||
|
const auto status = stop_wait_cv_.wait_for(
|
||||||
|
*lock, std::chrono::milliseconds(kMaxStopCompleteWaitMs),
|
||||||
|
[this] { return !awaiting_event_loop_termination_; });
|
||||||
|
if (!status) {
|
||||||
|
LOG(ERROR) << "Legacy HAL stop failed or timed out";
|
||||||
|
return WIFI_ERROR_UNKNOWN;
|
||||||
|
}
|
||||||
LOG(DEBUG) << "Legacy HAL stop complete";
|
LOG(DEBUG) << "Legacy HAL stop complete";
|
||||||
is_started_ = false;
|
|
||||||
return WIFI_SUCCESS;
|
return WIFI_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1257,11 +1269,13 @@ wifi_error WifiLegacyHal::retrieveWlanInterfaceHandle() {
|
|||||||
void WifiLegacyHal::runEventLoop() {
|
void WifiLegacyHal::runEventLoop() {
|
||||||
LOG(DEBUG) << "Starting legacy HAL event loop";
|
LOG(DEBUG) << "Starting legacy HAL event loop";
|
||||||
global_func_table_.wifi_event_loop(global_handle_);
|
global_func_table_.wifi_event_loop(global_handle_);
|
||||||
|
const auto lock = hidl_sync_util::acquireGlobalLock();
|
||||||
if (!awaiting_event_loop_termination_) {
|
if (!awaiting_event_loop_termination_) {
|
||||||
LOG(FATAL) << "Legacy HAL event loop terminated, but HAL was not stopping";
|
LOG(FATAL) << "Legacy HAL event loop terminated, but HAL was not stopping";
|
||||||
}
|
}
|
||||||
LOG(DEBUG) << "Legacy HAL event loop terminated";
|
LOG(DEBUG) << "Legacy HAL event loop terminated";
|
||||||
awaiting_event_loop_termination_ = false;
|
awaiting_event_loop_termination_ = false;
|
||||||
|
stop_wait_cv_.notify_one();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<wifi_error, std::vector<wifi_cached_scan_results>>
|
std::pair<wifi_error, std::vector<wifi_cached_scan_results>>
|
||||||
|
|||||||
@@ -20,6 +20,7 @@
|
|||||||
#include <functional>
|
#include <functional>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <condition_variable>
|
||||||
|
|
||||||
#include <wifi_system/interface_tool.h>
|
#include <wifi_system/interface_tool.h>
|
||||||
|
|
||||||
@@ -149,8 +150,10 @@ class WifiLegacyHal {
|
|||||||
wifi_error initialize();
|
wifi_error initialize();
|
||||||
// Start the legacy HAL and the event looper thread.
|
// Start the legacy HAL and the event looper thread.
|
||||||
wifi_error start();
|
wifi_error start();
|
||||||
// Deinitialize the legacy HAL and stop the event looper thread.
|
// Deinitialize the legacy HAL and wait for the event loop thread to exit
|
||||||
wifi_error stop(const std::function<void()>& on_complete_callback);
|
// using a predefined timeout.
|
||||||
|
wifi_error stop(std::unique_lock<std::recursive_mutex>* lock,
|
||||||
|
const std::function<void()>& on_complete_callback);
|
||||||
// Wrappers for all the functions in the legacy HAL function table.
|
// Wrappers for all the functions in the legacy HAL function table.
|
||||||
std::pair<wifi_error, std::string> getDriverVersion();
|
std::pair<wifi_error, std::string> getDriverVersion();
|
||||||
std::pair<wifi_error, std::string> getFirmwareVersion();
|
std::pair<wifi_error, std::string> getFirmwareVersion();
|
||||||
@@ -293,6 +296,7 @@ class WifiLegacyHal {
|
|||||||
wifi_interface_handle wlan_interface_handle_;
|
wifi_interface_handle wlan_interface_handle_;
|
||||||
// Flag to indicate if we have initiated the cleanup of legacy HAL.
|
// Flag to indicate if we have initiated the cleanup of legacy HAL.
|
||||||
std::atomic<bool> awaiting_event_loop_termination_;
|
std::atomic<bool> awaiting_event_loop_termination_;
|
||||||
|
std::condition_variable_any stop_wait_cv_;
|
||||||
// Flag to indicate if the legacy HAL has been started.
|
// Flag to indicate if the legacy HAL has been started.
|
||||||
bool is_started_;
|
bool is_started_;
|
||||||
wifi_system::InterfaceTool iface_tool_;
|
wifi_system::InterfaceTool iface_tool_;
|
||||||
|
|||||||
Reference in New Issue
Block a user