• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2020 The Chromium Authors
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_SCOPED_SERVICE_PUBLISHER_H_
6 #define BASE_FUCHSIA_SCOPED_SERVICE_PUBLISHER_H_
7 
8 #include <lib/async/dispatcher.h>
9 #include <lib/fidl/cpp/interface_request.h>
10 #include <lib/fidl/cpp/wire/connect_service.h>
11 #include <lib/sys/cpp/outgoing_directory.h>
12 #include <lib/vfs/cpp/pseudo_dir.h>
13 #include <lib/vfs/cpp/service.h>
14 #include <lib/zx/channel.h>
15 
16 #include <memory>
17 #include <string>
18 #include <string_view>
19 #include <utility>
20 
21 #include "base/base_export.h"
22 #include "base/fuchsia/fuchsia_logging.h"
23 #include "base/memory/raw_ptr.h"
24 
25 namespace base {
26 
27 template <typename Interface>
28 class BASE_EXPORT ScopedServicePublisher {
29  public:
30   // Publishes a public service in the specified |outgoing_directory|.
31   // |outgoing_directory| and |handler| must outlive the binding.
32   ScopedServicePublisher(sys::OutgoingDirectory* outgoing_directory,
33                          fidl::InterfaceRequestHandler<Interface> handler,
34                          std::string_view name = Interface::Name_)
35       : ScopedServicePublisher(outgoing_directory->GetOrCreateDirectory("svc"),
36                                std::move(handler),
37                                name) {}
38 
39   // Publishes a service in the specified |pseudo_dir|. |pseudo_dir| and
40   // |handler| must outlive the binding.
41   ScopedServicePublisher(vfs::PseudoDir* pseudo_dir,
42                          fidl::InterfaceRequestHandler<Interface> handler,
43                          std::string_view name = Interface::Name_)
pseudo_dir_(pseudo_dir)44       : pseudo_dir_(pseudo_dir), name_(name) {
45     zx_status_t status = pseudo_dir_->AddEntry(
46         name_, std::make_unique<vfs::Service>(std::move(handler)));
47     ZX_DCHECK(status == ZX_OK, status) << "vfs::PseudoDir::AddEntry";
48   }
49 
50   ScopedServicePublisher(const ScopedServicePublisher&) = delete;
51   ScopedServicePublisher& operator=(const ScopedServicePublisher&) = delete;
52 
~ScopedServicePublisher()53   ~ScopedServicePublisher() { pseudo_dir_->RemoveEntry(name_); }
54 
55  private:
56   const raw_ptr<vfs::PseudoDir> pseudo_dir_ = nullptr;
57   std::string name_;
58 };
59 
60 template <typename Protocol>
61 class BASE_EXPORT ScopedNaturalServicePublisher {
62  public:
63   // Publishes a public service in the specified |outgoing_directory|.
64   // |outgoing_directory| and |handler| must outlive the binding. The service is
65   // unpublished on destruction.
66   ScopedNaturalServicePublisher(
67       sys::OutgoingDirectory* outgoing_directory,
68       fidl::ProtocolHandler<Protocol> handler,
69       std::string_view name = fidl::DiscoverableProtocolName<Protocol>)
70       : ScopedNaturalServicePublisher(
71             outgoing_directory->GetOrCreateDirectory("svc"),
72             std::move(handler),
73             name) {}
74 
75   // Publishes a service in the specified |pseudo_dir|. |pseudo_dir| and
76   // |handler| must outlive the binding. The service is unpublished on
77   // destruction.
78   ScopedNaturalServicePublisher(
79       vfs::PseudoDir* pseudo_dir,
80       fidl::ProtocolHandler<Protocol> handler,
81       std::string_view name = fidl::DiscoverableProtocolName<Protocol>)
pseudo_dir_(pseudo_dir)82       : pseudo_dir_(pseudo_dir), name_(name) {
83     zx_status_t status = pseudo_dir_->AddEntry(
84         name_, std::make_unique<vfs::Service>(
85                    [handler = std::move(handler)](
86                        zx::channel channel, async_dispatcher_t* dispatcher) {
87                      handler(fidl::ServerEnd<Protocol>(std::move(channel)));
88                    }));
89     ZX_DCHECK(status == ZX_OK, status) << "vfs::PseudoDir::AddEntry";
90   }
91 
92   ScopedNaturalServicePublisher(const ScopedNaturalServicePublisher&) = delete;
93   ScopedNaturalServicePublisher& operator=(
94       const ScopedNaturalServicePublisher&) = delete;
95 
~ScopedNaturalServicePublisher()96   ~ScopedNaturalServicePublisher() { pseudo_dir_->RemoveEntry(name_); }
97 
98  private:
99   const raw_ptr<vfs::PseudoDir> pseudo_dir_ = nullptr;
100   std::string name_;
101 };
102 
103 }  // namespace base
104 
105 #endif  // BASE_FUCHSIA_SCOPED_SERVICE_PUBLISHER_H_
106