Upload upstream chromium 76.0.3809.146
[platform/framework/web/chromium-efl.git] / base / fuchsia / service_directory.h
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.
4
5 #ifndef BASE_FUCHSIA_SERVICE_DIRECTORY_H_
6 #define BASE_FUCHSIA_SERVICE_DIRECTORY_H_
7
8 #include <fuchsia/io/cpp/fidl.h>
9 #include <lib/fidl/cpp/interface_handle.h>
10 #include <lib/zx/channel.h>
11 #include <string>
12 #include <utility>
13
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"
21
22 typedef struct svc_dir svc_dir_t;
23
24 namespace base {
25 namespace fuchsia {
26
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.
36 //
37 // Not thread-safe. All methods must be called on the thread that created the
38 // object.
39 class BASE_EXPORT ServiceDirectory {
40  public:
41   // Responds to service requests over the supplied |request| channel.
42   explicit ServiceDirectory(
43       fidl::InterfaceRequest<::fuchsia::io::Directory> request);
44
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.
49   ServiceDirectory();
50
51   ~ServiceDirectory();
52
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();
56
57   // Configures an uninitialized ServiceDirectory instance to service the
58   // supplied |directory_request| channel.
59   void Initialize(fidl::InterfaceRequest<::fuchsia::io::Directory> request);
60
61   template <typename Interface>
62   void AddService(RepeatingCallback<void(fidl::InterfaceRequest<Interface>)>
63                       connect_callback) {
64     AddServiceUnsafe(
65         Interface::Name_,
66         BindRepeating(
67             [](decltype(connect_callback) callback, zx::channel request) {
68               callback.Run(
69                   fidl::InterfaceRequest<Interface>(std::move(request)));
70             },
71             connect_callback));
72   }
73   void RemoveService(StringPiece name);
74   void RemoveAllServices();
75
76   // Returns the debug ServiceDirectory.
77   ServiceDirectory* debug() const { return debug_.get(); }
78
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);
84
85  private:
86   // Sub-directory constructor.
87   ServiceDirectory(svc_dir_t* svc_dir, const char* name);
88
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);
93
94   THREAD_CHECKER(thread_checker_);
95
96   // Owned by the root directory.
97   svc_dir_t* svc_dir_ = nullptr;
98   flat_map<std::string, RepeatingCallback<void(zx::channel)>> services_;
99
100   // The debug sub-directory. Empty if this is a sub-directory.
101   std::unique_ptr<ServiceDirectory> debug_;
102
103   // If mon-null, this directory represents a sub-directory of the root
104   // ServiceDirectory.
105   const char* sub_directory_ = nullptr;
106
107   DISALLOW_COPY_AND_ASSIGN(ServiceDirectory);
108 };
109
110 }  // namespace fuchsia
111 }  // namespace base
112
113 #endif  // BASE_FUCHSIA_SERVICE_DIRECTORY_H_