blob: a6f765d8904590a6812dc0b558e4dd83eaff6aca [file] [log] [blame] [edit]
// 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.
#ifndef LIB_VFS_CPP_COMPOSED_SERVICE_DIR_H_
#define LIB_VFS_CPP_COMPOSED_SERVICE_DIR_H_
#include <fidl/fuchsia.io/cpp/wire.h>
#include <fuchsia/io/cpp/fidl.h>
#include <lib/fidl/cpp/client.h>
#include <lib/vfs/cpp/node.h>
#include <lib/vfs/cpp/service.h>
#include <zircon/assert.h>
#include <string>
namespace vfs {
// A directory-like object which created a composed `PseudoDir` on top of a `fallback_dir`. It can
// be used to connect to services in `fallback_dir`, but will not enumerate them.
//
// This class is thread-safe.
class ComposedServiceDir final : public Node {
public:
ComposedServiceDir() : Node(MakeComposedServiceDir()) {}
// Serve a new connection to this directory on `server_end` using specified `flags`.
//
// This method must only be used with a single-threaded asynchronous dispatcher. If `dispatcher`
// is `nullptr`, the current thread's default dispatcher will be used via
// `async_get_default_dispatcher`. The same `dispatcher` must be used if multiple connections are
// served for the same node, otherwise `ZX_ERR_INVALID_ARGS` will be returned.
zx_status_t Serve(fuchsia_io::Flags flags, fidl::ServerEnd<fuchsia_io::Directory> server_end,
async_dispatcher_t* dispatcher = nullptr) const {
if (flags & (fuchsia_io::wire::kMaskKnownProtocols ^ fuchsia_io::Flags::kProtocolDirectory)) {
return ZX_ERR_INVALID_ARGS; // Only the directory protocol is allowed with this signature.
}
return ServeInternal(flags | fuchsia_io::Flags::kProtocolDirectory, server_end.TakeChannel(),
dispatcher);
}
// TODO(https://fxbug.dev/336617685): This version of `Serve` is deprecated and should be removed.
using Node::Serve;
// Sets the fallback directory for services. Services in this directory can be connected to, but
// will not be enumerated. This method may only be called once.
void SetFallback(fidl::ClientEnd<fuchsia_io::Directory> fallback_dir) {
ZX_ASSERT(vfs_internal_composed_svc_dir_set_fallback(
handle(), fallback_dir.TakeChannel().release()) == ZX_OK);
}
// Adds a service to this directory. Services added will be preferred over those in the fallback
// directory, and can be enumerated.
void AddService(const std::string& service_name, std::unique_ptr<vfs::Service> service) {
ZX_ASSERT(vfs_internal_composed_svc_dir_add(handle(), service->handle(), service_name.data()) ==
ZX_OK);
}
// Sets the fallback directory for services. Services in this directory can be connected to, but
// will not be enumerated. This method may only be called once.
// TODO(https://fxbug.dev/336617685): Mark this as removed at NEXT once we ship API level 24.
void set_fallback(fidl::InterfaceHandle<fuchsia::io::Directory> fallback_dir)
ZX_REMOVED_SINCE(1, 25, HEAD, "Replaced by SetFallback().") {
ZX_ASSERT(vfs_internal_composed_svc_dir_set_fallback(
handle(), fallback_dir.TakeChannel().release()) == ZX_OK);
}
private:
static vfs_internal_node_t* MakeComposedServiceDir() {
vfs_internal_node_t* dir;
ZX_ASSERT(vfs_internal_composed_svc_dir_create(&dir) == ZX_OK);
return dir;
}
};
} // namespace vfs
#endif // LIB_VFS_CPP_COMPOSED_SERVICE_DIR_H_