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