1 // Copyright 2018 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #ifndef BASE_FUCHSIA_SERVICE_DIRECTORY_H_
6 #define BASE_FUCHSIA_SERVICE_DIRECTORY_H_
8 #include <fuchsia/io/cpp/fidl.h>
9 #include <lib/fidl/cpp/interface_handle.h>
10 #include <lib/zx/channel.h>
14 #include "base/base_export.h"
15 #include "base/bind.h"
16 #include "base/callback.h"
17 #include "base/containers/flat_map.h"
18 #include "base/macros.h"
19 #include "base/strings/string_piece.h"
20 #include "base/threading/thread_checker.h"
22 typedef struct svc_dir svc_dir_t;
27 // Directory of FIDL services published for other processes to consume. Services
28 // published in this directory can be discovered from other processes by name.
29 // Normally this class should be used by creating a ScopedServiceBinding
30 // instance. This ensures that the service is unregistered when the
31 // implementation is destroyed. GetDefault() should be used to get the default
32 // ServiceDirectory for the current process. The default instance exports
33 // services via a channel supplied at process creation time.
34 // Debug services are published to a "debug" sub-directory only accessible by
35 // other services via the Hub.
37 // Not thread-safe. All methods must be called on the thread that created the
39 class BASE_EXPORT ServiceDirectory {
41 // Responds to service requests over the supplied |request| channel.
42 explicit ServiceDirectory(
43 fidl::InterfaceRequest<::fuchsia::io::Directory> request);
45 // Creates an uninitialized ServiceDirectory instance. Initialize must be
46 // called on the instance before any services can be registered. Unless you
47 // need separate construction & initialization for a ServiceDirectory member,
48 // use the all-in-one constructor above.
53 // Returns default ServiceDirectory instance for the current process. It
54 // publishes services to the directory provided by the process creator.
55 static ServiceDirectory* GetDefault();
57 // Configures an uninitialized ServiceDirectory instance to service the
58 // supplied |directory_request| channel.
59 void Initialize(fidl::InterfaceRequest<::fuchsia::io::Directory> request);
61 template <typename Interface>
62 void AddService(RepeatingCallback<void(fidl::InterfaceRequest<Interface>)>
67 [](decltype(connect_callback) callback, zx::channel request) {
69 fidl::InterfaceRequest<Interface>(std::move(request)));
73 void RemoveService(StringPiece name);
74 void RemoveAllServices();
76 // Returns the debug ServiceDirectory.
77 ServiceDirectory* debug() const { return debug_.get(); }
79 // Passes requests for |name| through to a generic |connect_callback|.
80 // This is used only when proxying requests for interfaces not known at
81 // compile-time. Use the type-safe APIs above whenever possible.
82 void AddServiceUnsafe(StringPiece name,
83 RepeatingCallback<void(zx::channel)> connect_callback);
86 // Sub-directory constructor.
87 ServiceDirectory(svc_dir_t* svc_dir, const char* name);
89 // Called by |svc_dir_| to handle service requests.
90 static void HandleConnectRequest(void* context,
91 const char* service_name,
92 zx_handle_t service_request);
94 THREAD_CHECKER(thread_checker_);
96 // Owned by the root directory.
97 svc_dir_t* svc_dir_ = nullptr;
98 flat_map<std::string, RepeatingCallback<void(zx::channel)>> services_;
100 // The debug sub-directory. Empty if this is a sub-directory.
101 std::unique_ptr<ServiceDirectory> debug_;
103 // If mon-null, this directory represents a sub-directory of the root
105 const char* sub_directory_ = nullptr;
107 DISALLOW_COPY_AND_ASSIGN(ServiceDirectory);
110 } // namespace fuchsia
113 #endif // BASE_FUCHSIA_SERVICE_DIRECTORY_H_