blob: d15d3fc71fc65243c83c61631fc64ef63c179bd9 [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 "topaz/runtime/flutter_runner/service_provider_dir.h"
#include <lib/async/default.h>
#include <lib/fdio/directory.h>
#include <zircon/status.h>
namespace flutter {
ServiceProviderDir::ServiceProviderDir() : root_(new vfs::PseudoDir()) {}
ServiceProviderDir::~ServiceProviderDir() {}
void ServiceProviderDir::set_fallback(
fidl::InterfaceHandle<fuchsia::io::Directory> fallback_dir) {
fallback_dir_ = fallback_dir.TakeChannel();
}
void ServiceProviderDir::AddService(const std::string& service_name,
std::unique_ptr<vfs::Service> service) {
root_->AddEntry(service_name, std::move(service));
}
zx_status_t ServiceProviderDir::GetAttr(
fuchsia::io::NodeAttributes* out_attributes) const {
return root_->GetAttr(out_attributes);
}
zx_status_t ServiceProviderDir::Readdir(uint64_t offset, void* data,
uint64_t len, uint64_t* out_offset,
uint64_t* out_actual) {
// TODO(anmittal): enumerate fallback_dir_ in future once we have simple
// implementation of fuchsia.io.Directory.
return root_->Readdir(offset, data, len, out_offset, out_actual);
}
zx_status_t ServiceProviderDir::Lookup(const std::string& name,
vfs::Node** out) const {
zx_status_t status = root_->Lookup(name, out);
if (status == ZX_OK) {
return status;
}
if (fallback_dir_) {
auto entry = fallback_services_.find(name);
if (entry != fallback_services_.end()) {
*out = entry->second.get();
} else {
auto service = std::make_unique<vfs::Service>(
[name = std::string(name.data(), name.length()),
dir = &fallback_dir_](zx::channel request,
async_dispatcher_t* dispatcher) {
fdio_service_connect_at(dir->get(), name.c_str(), request.release());
});
*out = service.get();
fallback_services_[name] = std::move(service);
}
} else {
return ZX_ERR_NOT_FOUND;
}
return ZX_OK;
}
} // namespace flutter