| // 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 SRC_SYS_APPMGR_SERVICE_PROVIDER_DIR_IMPL_H_ |
| #define SRC_SYS_APPMGR_SERVICE_PROVIDER_DIR_IMPL_H_ |
| |
| #include <fuchsia/sys/cpp/fidl.h> |
| #include <lib/syslog/cpp/macros.h> |
| |
| #include <string> |
| #include <unordered_set> |
| #include <utility> |
| #include <vector> |
| |
| #include <fs/pseudo_dir.h> |
| #include <fs/service.h> |
| #include <fs/synchronous_vfs.h> |
| #include <fs/vfs_types.h> |
| |
| #include "lib/fidl/cpp/binding_set.h" |
| #include "src/lib/fxl/macros.h" |
| #include "src/lib/fxl/memory/weak_ptr.h" |
| #include "src/sys/appmgr/log_connector_impl.h" |
| #include "src/sys/appmgr/moniker.h" |
| |
| namespace component { |
| |
| constexpr char kUnknownComponent[] = "<unknown v2 component>"; |
| |
| // A directory-like object which dynamically creates Service vnodes |
| // for any file lookup. It also exposes service provider interface. |
| // |
| // It supports enumeration for only first level of services. |
| class ServiceProviderDirImpl : public fuchsia::sys::ServiceProvider, public fs::Vnode { |
| public: |
| explicit ServiceProviderDirImpl(fbl::RefPtr<LogConnectorImpl> log_connector, |
| const std::vector<std::string>* services = nullptr); |
| ~ServiceProviderDirImpl() override; |
| |
| // Sets the parent of this. Parent should be fully initialized. |
| void set_parent(fbl::RefPtr<ServiceProviderDirImpl> parent); |
| |
| const std::string& component_url() const { return component_url_; } |
| |
| const std::string& component_moniker() const { return component_moniker_; } |
| |
| void set_component_moniker(const Moniker& moniker) { |
| component_moniker_ = moniker.ToString(); |
| component_url_ = moniker.url; |
| } |
| void set_component_id(const std::string& id) { component_id_ = id; } |
| |
| void AddService(const std::string& service_name, fbl::RefPtr<fs::Service> service); |
| |
| void AddBinding(fidl::InterfaceRequest<fuchsia::sys::ServiceProvider> request); |
| |
| // |
| // Overridden from |fs::Vnode|: |
| // |
| |
| fs::VnodeProtocolSet GetProtocols() const final; |
| |
| zx_status_t Lookup(fbl::StringPiece name, fbl::RefPtr<fs::Vnode>* out) final; |
| |
| zx_status_t GetAttributes(fs::VnodeAttributes* a) final; |
| |
| zx_status_t Readdir(fs::VdirCookie* cookie, void* dirents, size_t len, size_t* out_actual) final; |
| |
| zx_status_t GetNodeInfoForProtocol(fs::VnodeProtocol protocol, fs::Rights rights, |
| fs::VnodeRepresentation* representation) final; |
| |
| // |
| // Overridden from |fuchsia::sys::ServiceProvider|: |
| // |
| |
| void ConnectToService(std::string service_name, zx::channel channel) override; |
| |
| // Initialize LogConnector and LogSink services if needed. Should be called *after* |
| // other namespace setup steps so that parent-provided versions of those services will |
| // take precedence. |
| void InitLogging(); |
| |
| bool IsServiceAllowlisted(const std::string& service_name) { |
| return (!has_services_allowlist_ || services_allowlist_.count(service_name) > 0); |
| } |
| |
| private: |
| fidl::BindingSet<fuchsia::sys::ServiceProvider> bindings_; |
| fs::SynchronousVfs vfs_; |
| // |root_| has all services offered by this provider (including those |
| // inherited from the parent, if any). |
| fbl::RefPtr<fs::PseudoDir> root_; |
| fbl::RefPtr<ServiceProviderDirImpl> parent_; |
| fbl::RefPtr<LogConnectorImpl> log_connector_; |
| fxl::WeakPtrFactory<ServiceProviderDirImpl> weak_factory_; |
| |
| bool has_builtin_logsink_ = false; |
| |
| // TODO(fxbug.dev/3924): Remove has_services_allowlist_ when empty services is |
| // equivalent to no services. |
| bool has_services_allowlist_ = false; |
| std::unordered_set<std::string> services_allowlist_; |
| // Secondary storage for services under |root_| in a format that can easily |
| // be consumed by children. Stored as vector to preserve order. |
| typedef std::pair<std::string, fbl::RefPtr<fs::Service>> ServiceHandle; |
| std::vector<ServiceHandle> service_handles_; |
| std::unordered_set<std::string> all_service_names_; |
| |
| std::string component_moniker_ = kUnknownComponent; |
| std::string component_url_ = kUnknownComponent; |
| std::string component_id_ = "-1"; |
| |
| FXL_DISALLOW_COPY_AND_ASSIGN(ServiceProviderDirImpl); |
| }; |
| |
| } // namespace component |
| |
| #endif // SRC_SYS_APPMGR_SERVICE_PROVIDER_DIR_IMPL_H_ |