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