blob: 21b0efeb9cd1f9755f455f1848f345e5bdbe6d90 [file] [log] [blame]
// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "peridot/bin/ledger/testing/netconnector/netconnector_factory.h"
#include <lib/fidl/cpp/clone.h>
#include <lib/fit/function.h>
#include "peridot/lib/convert/convert.h"
namespace ledger {
class NetConnectorFactory::Holder {
public:
Holder(FakeNetConnector::Delegate* delegate,
fidl::InterfaceRequest<fuchsia::netconnector::NetConnector> request,
std::string device_name, fit::closure on_disconnect);
void set_on_empty(fit::closure on_empty);
FakeNetConnector* impl();
private:
void OnEmpty();
const std::string device_name_;
fidl_helpers::BoundInterface<fuchsia::netconnector::NetConnector,
FakeNetConnector>
interface_;
fit::closure on_empty_;
fit::closure on_disconnect_;
};
NetConnectorFactory::Holder::Holder(
FakeNetConnector::Delegate* delegate,
fidl::InterfaceRequest<fuchsia::netconnector::NetConnector> request,
std::string device_name, fit::closure on_disconnect)
: device_name_(std::move(device_name)),
interface_(std::move(request), delegate),
on_disconnect_(std::move(on_disconnect)) {
interface_.set_on_empty([this] { OnEmpty(); });
}
void NetConnectorFactory::Holder::set_on_empty(fit::closure on_empty) {
on_empty_ = std::move(on_empty);
}
FakeNetConnector* NetConnectorFactory::Holder::impl() {
return interface_.impl();
}
void NetConnectorFactory::Holder::OnEmpty() {
// We need to deregister ourselves from the list of active devices (call
// |on_empty_|) before updating the pending host list callbacks (call
// |on_disconnect_|). As |on_empty_| destroys |this|, we move |on_disconnect_|
// locally to be able to call it later.
auto on_disconnect = std::move(on_disconnect_);
if (on_empty_) {
on_empty_();
}
if (on_disconnect) {
on_disconnect();
}
}
NetConnectorFactory::NetConnectorFactory() {}
NetConnectorFactory::~NetConnectorFactory() {}
void NetConnectorFactory::AddBinding(
std::string host_name,
fidl::InterfaceRequest<fuchsia::netconnector::NetConnector> request) {
net_connectors_.emplace(
std::piecewise_construct, std::forward_as_tuple(host_name),
std::forward_as_tuple(this, std::move(request), host_name,
[this] { UpdatedHostList(); }));
UpdatedHostList();
}
void NetConnectorFactory::UpdatedHostList() {
current_version_++;
if (pending_device_list_callbacks_.empty()) {
return;
}
std::vector<std::string> device_names;
for (const auto& holder_pair : net_connectors_) {
device_names.push_back(holder_pair.first);
}
for (const auto& callback : pending_device_list_callbacks_) {
callback(current_version_, device_names);
}
pending_device_list_callbacks_.clear();
}
void NetConnectorFactory::GetDevicesNames(
uint64_t last_version,
fit::function<void(uint64_t, std::vector<std::string>)> callback) {
FXL_CHECK(last_version <= current_version_)
<< "Last seen version (" << last_version
<< ") is more recent than current version (" << current_version_
<< "). Something is wrong here.";
if (last_version == current_version_) {
pending_device_list_callbacks_.push_back(std::move(callback));
return;
}
std::vector<std::string> device_names;
for (const auto& holder_pair : net_connectors_) {
device_names.push_back(holder_pair.first);
}
callback(current_version_, std::move(device_names));
}
void NetConnectorFactory::ConnectToServiceProvider(
std::string device_name,
fidl::InterfaceRequest<fuchsia::sys::ServiceProvider> request) {
auto it = net_connectors_.find(device_name);
if (it == net_connectors_.end()) {
return;
}
(*it).second.impl()->ConnectToServiceProvider(std::move(request));
}
} // namespace ledger