blob: c647c05fbcbca6641c5bbf2b7f4af6cca1759e6c [file] [log] [blame]
// Copyright 2021 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.
#ifndef SRC_DEVICES_BIN_DRIVER_MANAGER_TESTING_FAKE_DRIVER_INDEX_H_
#define SRC_DEVICES_BIN_DRIVER_MANAGER_TESTING_FAKE_DRIVER_INDEX_H_
#include <fidl/fuchsia.driver.framework/cpp/wire.h>
#include <fidl/fuchsia.driver.index/cpp/fidl.h>
#include <lib/fit/function.h>
#include <lib/zx/result.h>
#include <zircon/errors.h>
#include <unordered_set>
class FakeDriverIndex final : public fidl::WireServer<fuchsia_driver_index::DriverIndex> {
public:
struct MatchResult {
std::string url;
std::optional<fuchsia_driver_framework::CompositeParent> spec;
bool is_fallback = false;
bool colocate = false;
};
using MatchCallback =
fit::function<zx::result<MatchResult>(fuchsia_driver_index::wire::MatchDriverArgs args)>;
FakeDriverIndex(async_dispatcher_t* dispatcher, MatchCallback match_callback)
: dispatcher_(dispatcher), match_callback_(std::move(match_callback)) {}
fidl::ClientEnd<fuchsia_driver_index::DriverIndex> Connect() {
auto [client_end, server_end] = fidl::Endpoints<fuchsia_driver_index::DriverIndex>::Create();
fidl::BindServer(dispatcher_, std::move(server_end), this);
return std::move(client_end);
}
void MatchDriver(MatchDriverRequestView request, MatchDriverCompleter::Sync& completer) override {
auto match = match_callback_(request->args);
if (match.status_value() != ZX_OK) {
completer.ReplyError(match.status_value());
return;
}
if (disabled_driver_urls_.find(match->url) != disabled_driver_urls_.end()) {
completer.ReplyError(ZX_ERR_NOT_FOUND);
return;
}
fidl::Arena arena;
completer.ReplySuccess(GetMatchedDriver(arena, match.value()));
}
void WatchForDriverLoad(WatchForDriverLoadCompleter::Sync& completer) override {
watch_completer_ = completer.ToAsync();
}
void AddCompositeNodeSpec(AddCompositeNodeSpecRequestView request,
AddCompositeNodeSpecCompleter::Sync& completer) override {
completer.ReplySuccess();
}
void RebindCompositeNodeSpec(RebindCompositeNodeSpecRequestView request,
RebindCompositeNodeSpecCompleter::Sync& completer) override {
completer.ReplyError(ZX_ERR_NOT_SUPPORTED);
}
void InvokeWatchDriverResponse() {
ZX_ASSERT(watch_completer_.has_value());
watch_completer_->Reply();
}
void set_match_callback(MatchCallback match_callback) {
match_callback_ = std::move(match_callback);
}
void disable_driver_url(std::string_view url) { disabled_driver_urls_.emplace(url); }
size_t un_disable_driver_url(std::string_view url) {
return disabled_driver_urls_.erase(std::string(url));
}
private:
static fuchsia_driver_index::wire::MatchDriverResult GetMatchedDriver(fidl::AnyArena& arena,
MatchResult match) {
if (match.spec) {
return fuchsia_driver_index::wire::MatchDriverResult::WithCompositeParents(
arena, fidl::ToWire(arena, std::vector<fuchsia_driver_framework::CompositeParent>{
match.spec.value()}));
}
auto driver_info = GetDriverInfo(arena, match);
return fuchsia_driver_index::wire::MatchDriverResult::WithDriver(arena, driver_info);
}
static fuchsia_driver_framework::wire::DriverInfo GetDriverInfo(fidl::AnyArena& arena,
MatchResult match) {
return fuchsia_driver_framework::wire::DriverInfo::Builder(arena)
.url(fidl::ObjectView<fidl::StringView>(arena, arena, match.url))
.is_fallback(match.is_fallback)
.colocate(match.colocate)
.package_type(fuchsia_driver_framework::DriverPackageType::kBoot)
.Build();
}
async_dispatcher_t* dispatcher_;
MatchCallback match_callback_;
std::optional<WatchForDriverLoadCompleter::Async> watch_completer_;
std::unordered_set<std::string> disabled_driver_urls_;
};
#endif // SRC_DEVICES_BIN_DRIVER_MANAGER_TESTING_FAKE_DRIVER_INDEX_H_