Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5d599a8d authored by Roshan Pius's avatar Roshan Pius Committed by android-build-merger
Browse files

wifi: Helper functions for invoking hidl cont callbacks am: 56476658 am: 1ab8395a

am: 8a9ab30d

Change-Id: I04bc3b3c5138e4ba6830a50967556caecf4118fc
parents 0f3073b9 8a9ab30d
Loading
Loading
Loading
Loading
+109 −0
Original line number Diff line number Diff line
/*
 * 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_
+70 −39
Original line number Diff line number Diff line
@@ -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 hardware {
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<bool> Wifi::isStarted() {
}

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 @@ Return<void> Wifi::start(start_cb hidl_status_cb) {
      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 @@ Return<void> Wifi::stop(stop_cb hidl_status_cb) {
    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
+12 −1
Original line number Diff line number Diff line
@@ -39,9 +39,12 @@ class Wifi : public IWifi {
 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 @@ class Wifi : public IWifi {
 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_;
+1 −4
Original line number Diff line number Diff line
@@ -50,10 +50,7 @@ std::string legacyErrorToString(wifi_error error) {

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) {