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

Commit 10b0e088 authored by Treehugger Robot's avatar Treehugger Robot Committed by Gerrit Code Review
Browse files

Merge "wifi(implementation): Callback death handler"

parents 7748aa1f d37341f1
Loading
Loading
Loading
Loading
+123 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2017 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_CALLBACK_UTIL_H_
#define HIDL_CALLBACK_UTIL_H_

#include <set>

#include <hidl/HidlSupport.h>

namespace {
// Type of callback invoked by the death handler.
using on_death_cb_function = std::function<void(uint64_t)>;

// Private class used to keep track of death of individual
// callbacks stored in HidlCallbackHandler.
template <typename CallbackType>
class HidlDeathHandler : public android::hardware::hidl_death_recipient {
 public:
  HidlDeathHandler(const on_death_cb_function& user_cb_function)
      : cb_function_(user_cb_function) {}
  ~HidlDeathHandler() = default;

  // Death notification for callbacks.
  void serviceDied(
      uint64_t cookie,
      const android::wp<android::hidl::base::V1_0::IBase>& /* who */) override {
    cb_function_(cookie);
  }

 private:
  on_death_cb_function cb_function_;

  DISALLOW_COPY_AND_ASSIGN(HidlDeathHandler);
};
}  // namespace

namespace android {
namespace hardware {
namespace wifi {
namespace V1_0 {
namespace implementation {
namespace hidl_callback_util {
template <typename CallbackType>
// Provides a class to manage callbacks for the various HIDL interfaces and
// handle the death of the process hosting each callback.
class HidlCallbackHandler {
 public:
  HidlCallbackHandler()
      : death_handler_(new HidlDeathHandler<CallbackType>(
            std::bind(&HidlCallbackHandler::onObjectDeath,
                      this,
                      std::placeholders::_1))) {}
  ~HidlCallbackHandler() = default;

  bool addCallback(const sp<CallbackType>& cb) {
    // TODO(b/33818800): Can't compare proxies yet. So, use the cookie
    // (callback proxy's raw pointer) to track the death of individual clients.
    uint64_t cookie = reinterpret_cast<uint64_t>(cb.get());
    if (cb_set_.find(cb) != cb_set_.end()) {
      LOG(WARNING) << "Duplicate death notification registration";
      return true;
    }
    if (!cb->linkToDeath(death_handler_, cookie)) {
      LOG(ERROR) << "Failed to register death notification";
      return false;
    }
    cb_set_.insert(cb);
    return true;
  }

  const std::set<android::sp<CallbackType>> getCallbacks() {
    return cb_set_;
  }

  // Death notification for callbacks.
  void onObjectDeath(uint64_t cookie) {
    CallbackType *cb = reinterpret_cast<CallbackType*>(cookie);
    const auto& iter =  cb_set_.find(cb);
    if (iter == cb_set_.end()) {
      LOG(ERROR) << "Unknown callback death notification received";
      return;
    }
    cb_set_.erase(iter);
    LOG(DEBUG) << "Dead callback removed from list";
  }

  void invalidate() {
    for (const sp<CallbackType>& cb : cb_set_) {
      if (!cb->unlinkToDeath(death_handler_)) {
        LOG(ERROR) << "Failed to deregister death notification";
      }
    }
    cb_set_.clear();
  }

 private:
  std::set<sp<CallbackType>> cb_set_;
  sp<HidlDeathHandler<CallbackType>> death_handler_;

  DISALLOW_COPY_AND_ASSIGN(HidlCallbackHandler);
};

}  // namespace hidl_callback_util
}  // namespace implementation
}  // namespace V1_0
}  // namespace wifi
}  // namespace hardware
}  // namespace android
#endif  // HIDL_CALLBACK_UTIL_H_
+7 −6
Original line number Diff line number Diff line
@@ -85,8 +85,9 @@ Return<void> Wifi::getChip(ChipId chip_id, getChip_cb hidl_status_cb) {

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);
  if (!event_cb_handler_.addCallback(event_callback)) {
    return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
  }
  return createWifiStatus(WifiStatusCode::SUCCESS);
}

@@ -102,13 +103,13 @@ WifiStatus Wifi::startInternal() {
    // Create the chip instance once the HAL is started.
    chip_ = new WifiChip(kChipId, legacy_hal_, mode_controller_);
    run_state_ = RunState::STARTED;
    for (const auto& callback : event_callbacks_) {
    for (const auto& callback : event_cb_handler_.getCallbacks()) {
      if (!callback->onStart().isOk()) {
        LOG(ERROR) << "Failed to invoke onStart callback";
      };
    }
  } else {
    for (const auto& callback : event_callbacks_) {
    for (const auto& callback : event_cb_handler_.getCallbacks()) {
      if (!callback->onFailure(wifi_status).isOk()) {
        LOG(ERROR) << "Failed to invoke onFailure callback";
      }
@@ -126,13 +127,13 @@ WifiStatus Wifi::stopInternal() {
  }
  WifiStatus wifi_status = stopLegacyHalAndDeinitializeModeController();
  if (wifi_status.code == WifiStatusCode::SUCCESS) {
    for (const auto& callback : event_callbacks_) {
    for (const auto& callback : event_cb_handler_.getCallbacks()) {
      if (!callback->onStop().isOk()) {
        LOG(ERROR) << "Failed to invoke onStop callback";
      };
    }
  } else {
    for (const auto& callback : event_callbacks_) {
    for (const auto& callback : event_cb_handler_.getCallbacks()) {
      if (!callback->onFailure(wifi_status).isOk()) {
        LOG(ERROR) << "Failed to invoke onFailure callback";
      }
+2 −1
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@
#include <android/hardware/wifi/1.0/IWifi.h>
#include <utils/Looper.h>

#include "hidl_callback_util.h"
#include "wifi_chip.h"
#include "wifi_legacy_hal.h"
#include "wifi_mode_controller.h"
@@ -71,8 +72,8 @@ class Wifi : public IWifi {
  std::shared_ptr<legacy_hal::WifiLegacyHal> legacy_hal_;
  std::shared_ptr<mode_controller::WifiModeController> mode_controller_;
  RunState run_state_;
  std::vector<sp<IWifiEventCallback>> event_callbacks_;
  sp<WifiChip> chip_;
  hidl_callback_util::HidlCallbackHandler<IWifiEventCallback> event_cb_handler_;

  DISALLOW_COPY_AND_ASSIGN(Wifi);
};
+16 −15
Original line number Diff line number Diff line
@@ -63,7 +63,7 @@ WifiChip::WifiChip(
void WifiChip::invalidate() {
  invalidateAndRemoveAllIfaces();
  legacy_hal_.reset();
  event_callbacks_.clear();
  event_cb_handler_.invalidate();
  is_valid_ = false;
}

@@ -71,8 +71,8 @@ bool WifiChip::isValid() {
  return is_valid_;
}

std::vector<sp<IWifiChipEventCallback>> WifiChip::getEventCallbacks() {
  return event_callbacks_;
std::set<sp<IWifiChipEventCallback>> WifiChip::getEventCallbacks() {
  return event_cb_handler_.getCallbacks();
}

Return<void> WifiChip::getId(getId_cb hidl_status_cb) {
@@ -353,8 +353,9 @@ std::pair<WifiStatus, ChipId> WifiChip::getIdInternal() {

WifiStatus WifiChip::registerEventCallbackInternal(
    const sp<IWifiChipEventCallback>& event_callback) {
  // TODO(b/31632518): remove the callback when the client is destroyed
  event_callbacks_.emplace_back(event_callback);
  if (!event_cb_handler_.addCallback(event_callback)) {
    return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
  }
  return createWifiStatus(WifiStatusCode::SUCCESS);
}

@@ -414,14 +415,14 @@ WifiStatus WifiChip::configureChipInternal(ChipModeId mode_id) {
  }
  WifiStatus status = handleChipConfiguration(mode_id);
  if (status.code != WifiStatusCode::SUCCESS) {
    for (const auto& callback : event_callbacks_) {
    for (const auto& callback : event_cb_handler_.getCallbacks()) {
      if (!callback->onChipReconfigureFailure(status).isOk()) {
        LOG(ERROR) << "Failed to invoke onChipReconfigureFailure callback";
      }
    }
    return status;
  }
  for (const auto& callback : event_callbacks_) {
  for (const auto& callback : event_cb_handler_.getCallbacks()) {
    if (!callback->onChipReconfigured(mode_id).isOk()) {
      LOG(ERROR) << "Failed to invoke onChipReconfigured callback";
    }
@@ -503,7 +504,7 @@ std::pair<WifiStatus, sp<IWifiApIface>> WifiChip::createApIfaceInternal() {
  }
  std::string ifname = legacy_hal_.lock()->getApIfaceName();
  ap_iface_ = new WifiApIface(ifname, legacy_hal_);
  for (const auto& callback : event_callbacks_) {
  for (const auto& callback : event_cb_handler_.getCallbacks()) {
    if (!callback->onIfaceAdded(IfaceType::AP, ifname).isOk()) {
      LOG(ERROR) << "Failed to invoke onIfaceAdded callback";
    }
@@ -533,7 +534,7 @@ WifiStatus WifiChip::removeApIfaceInternal(const std::string& ifname) {
    return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
  }
  invalidateAndClear(ap_iface_);
  for (const auto& callback : event_callbacks_) {
  for (const auto& callback : event_cb_handler_.getCallbacks()) {
    if (!callback->onIfaceRemoved(IfaceType::AP, ifname).isOk()) {
      LOG(ERROR) << "Failed to invoke onIfaceRemoved callback";
    }
@@ -549,7 +550,7 @@ std::pair<WifiStatus, sp<IWifiNanIface>> WifiChip::createNanIfaceInternal() {
  }
  std::string ifname = legacy_hal_.lock()->getNanIfaceName();
  nan_iface_ = new WifiNanIface(ifname, legacy_hal_);
  for (const auto& callback : event_callbacks_) {
  for (const auto& callback : event_cb_handler_.getCallbacks()) {
    if (!callback->onIfaceAdded(IfaceType::NAN, ifname).isOk()) {
      LOG(ERROR) << "Failed to invoke onIfaceAdded callback";
    }
@@ -579,7 +580,7 @@ WifiStatus WifiChip::removeNanIfaceInternal(const std::string& ifname) {
    return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
  }
  invalidateAndClear(nan_iface_);
  for (const auto& callback : event_callbacks_) {
  for (const auto& callback : event_cb_handler_.getCallbacks()) {
    if (!callback->onIfaceRemoved(IfaceType::NAN, ifname).isOk()) {
      LOG(ERROR) << "Failed to invoke onIfaceAdded callback";
    }
@@ -595,7 +596,7 @@ std::pair<WifiStatus, sp<IWifiP2pIface>> WifiChip::createP2pIfaceInternal() {
  }
  std::string ifname = legacy_hal_.lock()->getP2pIfaceName();
  p2p_iface_ = new WifiP2pIface(ifname, legacy_hal_);
  for (const auto& callback : event_callbacks_) {
  for (const auto& callback : event_cb_handler_.getCallbacks()) {
    if (!callback->onIfaceAdded(IfaceType::P2P, ifname).isOk()) {
      LOG(ERROR) << "Failed to invoke onIfaceAdded callback";
    }
@@ -625,7 +626,7 @@ WifiStatus WifiChip::removeP2pIfaceInternal(const std::string& ifname) {
    return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
  }
  invalidateAndClear(p2p_iface_);
  for (const auto& callback : event_callbacks_) {
  for (const auto& callback : event_cb_handler_.getCallbacks()) {
    if (!callback->onIfaceRemoved(IfaceType::P2P, ifname).isOk()) {
      LOG(ERROR) << "Failed to invoke onIfaceRemoved callback";
    }
@@ -639,7 +640,7 @@ std::pair<WifiStatus, sp<IWifiStaIface>> WifiChip::createStaIfaceInternal() {
  }
  std::string ifname = legacy_hal_.lock()->getStaIfaceName();
  sta_iface_ = new WifiStaIface(ifname, legacy_hal_);
  for (const auto& callback : event_callbacks_) {
  for (const auto& callback : event_cb_handler_.getCallbacks()) {
    if (!callback->onIfaceAdded(IfaceType::STA, ifname).isOk()) {
      LOG(ERROR) << "Failed to invoke onIfaceAdded callback";
    }
@@ -669,7 +670,7 @@ WifiStatus WifiChip::removeStaIfaceInternal(const std::string& ifname) {
    return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
  }
  invalidateAndClear(sta_iface_);
  for (const auto& callback : event_callbacks_) {
  for (const auto& callback : event_cb_handler_.getCallbacks()) {
    if (!callback->onIfaceRemoved(IfaceType::STA, ifname).isOk()) {
      LOG(ERROR) << "Failed to invoke onIfaceRemoved callback";
    }
+4 −2
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@
#include <android-base/macros.h>
#include <android/hardware/wifi/1.0/IWifiChip.h>

#include "hidl_callback_util.h"
#include "wifi_ap_iface.h"
#include "wifi_legacy_hal.h"
#include "wifi_mode_controller.h"
@@ -62,7 +63,7 @@ class WifiChip : public IWifiChip {
  // valid before processing them.
  void invalidate();
  bool isValid();
  std::vector<sp<IWifiChipEventCallback>> getEventCallbacks();
  std::set<sp<IWifiChipEventCallback>> getEventCallbacks();

  // HIDL methods exposed.
  Return<void> getId(getId_cb hidl_status_cb) override;
@@ -179,7 +180,6 @@ class WifiChip : public IWifiChip {
  ChipId chip_id_;
  std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal_;
  std::weak_ptr<mode_controller::WifiModeController> mode_controller_;
  std::vector<sp<IWifiChipEventCallback>> event_callbacks_;
  sp<WifiApIface> ap_iface_;
  sp<WifiNanIface> nan_iface_;
  sp<WifiP2pIface> p2p_iface_;
@@ -191,6 +191,8 @@ class WifiChip : public IWifiChip {
  // registration mechanism. Use this to check if we have already
  // registered a callback.
  bool debug_ring_buffer_cb_registered_;
  hidl_callback_util::HidlCallbackHandler<IWifiChipEventCallback>
      event_cb_handler_;

  DISALLOW_COPY_AND_ASSIGN(WifiChip);
};
Loading