wifi: Helper functions for invoking hidl cont callbacks am: 5647665827
am: 1ab8395a21
Change-Id: If7ec3758290dc84797ffecd882f8f95763d3ae0d
diff --git a/wifi/1.0/default/hidl_return_util.h b/wifi/1.0/default/hidl_return_util.h
new file mode 100644
index 0000000..2986165
--- /dev/null
+++ b/wifi/1.0/default/hidl_return_util.h
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef HIDL_RETURN_UTIL_H_
+#define HIDL_RETURN_UTIL_H_
+
+#include "wifi_status_util.h"
+
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace V1_0 {
+namespace implementation {
+namespace hidl_return_util {
+
+/**
+ * These utility functions are used to invoke a method on the provided
+ * HIDL interface object.
+ * These functions checks if the provided HIDL interface object is valid.
+ * a) if valid, Invokes the corresponding internal implementation function of
+ * the HIDL method. It then invokes the HIDL continuation callback with
+ * the status and any returned values.
+ * b) if invalid, invokes the HIDL continuation callback with the
+ * provided error status and default values.
+ */
+// Use for HIDL methods which return only an instance of WifiStatus.
+template <typename ObjT, typename WorkFuncT, typename... Args>
+Return<void> validateAndCall(
+ ObjT* obj,
+ WifiStatusCode status_code_if_invalid,
+ WorkFuncT&& work,
+ const std::function<void(const WifiStatus&)>& hidl_cb,
+ Args&&... args) {
+ if (obj->isValid()) {
+ hidl_cb((obj->*work)(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
+// value.
+template <typename ObjT, typename WorkFuncT, typename ReturnT, typename... Args>
+Return<void> validateAndCall(
+ ObjT* obj,
+ WifiStatusCode status_code_if_invalid,
+ WorkFuncT&& work,
+ const std::function<void(const WifiStatus&, ReturnT)>& hidl_cb,
+ Args&&... args) {
+ if (obj->isValid()) {
+ const auto& ret_pair = (obj->*work)(std::forward<Args>(args)...);
+ const WifiStatus& status = std::get<0>(ret_pair);
+ const auto& ret_value = std::get<1>(ret_pair);
+ hidl_cb(status, ret_value);
+ } else {
+ hidl_cb(createWifiStatus(status_code_if_invalid),
+ typename std::remove_reference<ReturnT>::type());
+ }
+ return Void();
+}
+
+// Use for HIDL methods which return instance of WifiStatus and 2 return
+// values.
+template <typename ObjT,
+ typename WorkFuncT,
+ typename ReturnT1,
+ typename ReturnT2,
+ typename... Args>
+Return<void> validateAndCall(
+ ObjT* obj,
+ WifiStatusCode status_code_if_invalid,
+ WorkFuncT&& work,
+ const std::function<void(const WifiStatus&, ReturnT1, ReturnT2)>& hidl_cb,
+ Args&&... args) {
+ if (obj->isValid()) {
+ const auto& ret_tuple = (obj->*work)(std::forward<Args>(args)...);
+ const WifiStatus& status = std::get<0>(ret_tuple);
+ const auto& ret_value1 = std::get<1>(ret_tuple);
+ const auto& ret_value2 = std::get<2>(ret_tuple);
+ hidl_cb(status, ret_value1, ret_value2);
+ } else {
+ hidl_cb(createWifiStatus(status_code_if_invalid),
+ typename std::remove_reference<ReturnT1>::type(),
+ typename std::remove_reference<ReturnT2>::type());
+ }
+ return Void();
+}
+
+} // namespace hidl_util
+} // namespace implementation
+} // namespace V1_0
+} // namespace wifi
+} // namespace hardware
+} // namespace android
+#endif // HIDL_RETURN_UTIL_H_
diff --git a/wifi/1.0/default/wifi.cpp b/wifi/1.0/default/wifi.cpp
index e10826b..73b921a 100644
--- a/wifi/1.0/default/wifi.cpp
+++ b/wifi/1.0/default/wifi.cpp
@@ -14,11 +14,10 @@
* limitations under the License.
*/
-#include "wifi.h"
-
#include <android-base/logging.h>
-#include "wifi_chip.h"
+#include "hidl_return_util.h"
+#include "wifi.h"
#include "wifi_status_util.h"
namespace {
@@ -31,15 +30,24 @@
namespace wifi {
namespace V1_0 {
namespace implementation {
+using hidl_return_util::validateAndCall;
Wifi::Wifi()
: legacy_hal_(new WifiLegacyHal()), run_state_(RunState::STOPPED) {}
+bool Wifi::isValid() {
+ // This object is always valid.
+ return true;
+}
+
Return<void> Wifi::registerEventCallback(
- const sp<IWifiEventCallback>& event_callback) {
- // TODO(b/31632518): remove the callback when the client is destroyed
- event_callbacks_.emplace_back(event_callback);
- return Void();
+ const sp<IWifiEventCallback>& event_callback,
+ registerEventCallback_cb hidl_status_cb) {
+ return validateAndCall(this,
+ WifiStatusCode::ERROR_UNKNOWN,
+ &Wifi::registerEventCallbackInternal,
+ hidl_status_cb,
+ event_callback);
}
Return<bool> Wifi::isStarted() {
@@ -47,22 +55,53 @@
}
Return<void> Wifi::start(start_cb hidl_status_cb) {
+ return validateAndCall(this,
+ WifiStatusCode::ERROR_UNKNOWN,
+ &Wifi::startInternal,
+ hidl_status_cb);
+}
+
+Return<void> Wifi::stop(stop_cb hidl_status_cb) {
+ return validateAndCall(
+ this, WifiStatusCode::ERROR_UNKNOWN, &Wifi::stopInternal, hidl_status_cb);
+}
+
+Return<void> Wifi::getChipIds(getChipIds_cb hidl_status_cb) {
+ return validateAndCall(this,
+ WifiStatusCode::ERROR_UNKNOWN,
+ &Wifi::getChipIdsInternal,
+ hidl_status_cb);
+}
+
+Return<void> Wifi::getChip(ChipId chip_id, getChip_cb hidl_status_cb) {
+ return validateAndCall(this,
+ WifiStatusCode::ERROR_UNKNOWN,
+ &Wifi::getChipInternal,
+ hidl_status_cb,
+ chip_id);
+}
+
+WifiStatus Wifi::registerEventCallbackInternal(
+ const sp<IWifiEventCallback>& event_callback) {
+ // TODO(b/31632518): remove the callback when the client is destroyed
+ event_callbacks_.emplace_back(event_callback);
+ return createWifiStatus(WifiStatusCode::SUCCESS);
+}
+
+WifiStatus Wifi::startInternal() {
if (run_state_ == RunState::STARTED) {
- hidl_status_cb(createWifiStatus(WifiStatusCode::SUCCESS));
- return Void();
+ return createWifiStatus(WifiStatusCode::SUCCESS);
} else if (run_state_ == RunState::STOPPING) {
- hidl_status_cb(createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE,
- "HAL is stopping"));
- return Void();
+ return createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE,
+ "HAL is stopping");
}
LOG(INFO) << "Starting HAL";
wifi_error legacy_status = legacy_hal_->start();
if (legacy_status != WIFI_SUCCESS) {
LOG(ERROR) << "Failed to start Wifi HAL";
- hidl_status_cb(
- createWifiStatusFromLegacyError(legacy_status, "Failed to start HAL"));
- return Void();
+ return createWifiStatusFromLegacyError(legacy_status,
+ "Failed to start HAL");
}
// Create the chip instance once the HAL is started.
@@ -73,18 +112,15 @@
LOG(ERROR) << "Failed to invoke onStart callback";
};
}
- hidl_status_cb(createWifiStatus(WifiStatusCode::SUCCESS));
- return Void();
+ return createWifiStatus(WifiStatusCode::SUCCESS);
}
-Return<void> Wifi::stop(stop_cb hidl_status_cb) {
+WifiStatus Wifi::stopInternal() {
if (run_state_ == RunState::STOPPED) {
- hidl_status_cb(createWifiStatus(WifiStatusCode::SUCCESS));
- return Void();
+ return createWifiStatus(WifiStatusCode::SUCCESS);
} else if (run_state_ == RunState::STOPPING) {
- hidl_status_cb(createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE,
- "HAL is stopping"));
- return Void();
+ return createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE,
+ "HAL is stopping");
}
LOG(INFO) << "Stopping HAL";
@@ -109,33 +145,28 @@
for (const auto& callback : event_callbacks_) {
callback->onFailure(wifi_status);
}
- hidl_status_cb(wifi_status);
- return Void();
+ return wifi_status;
}
- hidl_status_cb(createWifiStatus(WifiStatusCode::SUCCESS));
- return Void();
+ return createWifiStatus(WifiStatusCode::SUCCESS);
}
-Return<void> Wifi::getChipIds(getChipIds_cb hidl_status_cb) {
+std::pair<WifiStatus, std::vector<ChipId>> Wifi::getChipIdsInternal() {
std::vector<ChipId> chip_ids;
if (chip_.get()) {
chip_ids.emplace_back(kChipId);
}
- hidl_vec<ChipId> hidl_data;
- hidl_data.setToExternal(chip_ids.data(), chip_ids.size());
- hidl_status_cb(hidl_data);
- return Void();
+ return {createWifiStatus(WifiStatusCode::SUCCESS), std::move(chip_ids)};
}
-Return<void> Wifi::getChip(ChipId chip_id, getChip_cb hidl_status_cb) {
- if (chip_.get() && chip_id == kChipId) {
- hidl_status_cb(chip_);
- } else {
- hidl_status_cb(nullptr);
+std::pair<WifiStatus, sp<IWifiChip>> Wifi::getChipInternal(ChipId chip_id) {
+ if (!chip_.get()) {
+ return {createWifiStatus(WifiStatusCode::ERROR_NOT_STARTED), nullptr};
}
- return Void();
+ if (chip_id != kChipId) {
+ return {createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS), nullptr};
+ }
+ return {createWifiStatus(WifiStatusCode::SUCCESS), chip_};
}
-
} // namespace implementation
} // namespace V1_0
} // namespace wifi
diff --git a/wifi/1.0/default/wifi.h b/wifi/1.0/default/wifi.h
index 989b630..c682116 100644
--- a/wifi/1.0/default/wifi.h
+++ b/wifi/1.0/default/wifi.h
@@ -39,9 +39,12 @@
public:
Wifi();
+ bool isValid();
+
// HIDL methods exposed.
Return<void> registerEventCallback(
- const sp<IWifiEventCallback>& event_callback) override;
+ const sp<IWifiEventCallback>& event_callback,
+ registerEventCallback_cb hidl_status_cb) override;
Return<bool> isStarted() override;
Return<void> start(start_cb hidl_status_cb) override;
Return<void> stop(stop_cb hidl_status_cb) override;
@@ -51,6 +54,14 @@
private:
enum class RunState { STOPPED, STARTED, STOPPING };
+ // Corresponding worker functions for the HIDL methods.
+ WifiStatus registerEventCallbackInternal(
+ const sp<IWifiEventCallback>& event_callback);
+ WifiStatus startInternal();
+ WifiStatus stopInternal();
+ std::pair<WifiStatus, std::vector<ChipId>> getChipIdsInternal();
+ std::pair<WifiStatus, sp<IWifiChip>> getChipInternal(ChipId chip_id);
+
// Instance is created in this root level |IWifi| HIDL interface object
// and shared with all the child HIDL interface objects.
std::shared_ptr<WifiLegacyHal> legacy_hal_;
diff --git a/wifi/1.0/default/wifi_status_util.cpp b/wifi/1.0/default/wifi_status_util.cpp
index 21b4eeb..34a1c1d 100644
--- a/wifi/1.0/default/wifi_status_util.cpp
+++ b/wifi/1.0/default/wifi_status_util.cpp
@@ -50,10 +50,7 @@
WifiStatus createWifiStatus(WifiStatusCode code,
const std::string& description) {
- WifiStatus result;
- result.code = code;
- result.description = description.data();
- return result;
+ return {code, description};
}
WifiStatus createWifiStatus(WifiStatusCode code) {