// Copyright 2019 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef MOJO_PUBLIC_CPP_BINDINGS_SERVICE_FACTORY_H_ #define MOJO_PUBLIC_CPP_BINDINGS_SERVICE_FACTORY_H_ #include <map> #include <memory> #include "base/component_export.h" #include "base/containers/flat_set.h" #include "base/containers/unique_ptr_adapters.h" #include "base/functional/bind.h" #include "base/functional/callback.h" #include "base/memory/weak_ptr.h" #include "mojo/public/cpp/bindings/generic_pending_receiver.h" #include "mojo/public/cpp/system/message_pipe.h" #include "mojo/public/cpp/system/simple_watcher.h" namespace mojo { namespace internal { template <typename Func> struct ServiceFactoryTraits; } // ServiceFactory is a helper that Mojo consumers can use to conveniently handle // dynamic service interface requests via a GenericPendingReceiver by matching // the receiver's interface type against a series of strongly-typed factory // function pointers, each with the signature: // // std::unique_ptr<T>(mojo::PendingReceiver<Interface>) // // where |T| is any type (generally an implementation of |Interface|), and // |Interface| is a mojom interface. // // Any time |RunService()| is called on the ServiceFactory, it will match the // GenericPendingReceiver argument's interface type against the list of // factories it has available and run the corresponding function, retaining // ownership of the returned object until the corresponding receiver is // disconnected. // // Typical usage might look something like: // // auto RunFooService(mojo::PendingReceiver<foo::mojom::Foo> receiver) { // return std::make_unique<foo::FooImpl>(std::move(receiver)); // } // // auto RunBarService(mojo::PendingReceiver<bar::mojom::Bar> receiver) { // return std::make_unique<bar::BarImpl>(std::move(receiver)); // } // // void RegisterServices(mojo::ServiceFactory& services) { // services.Add(RunFooService); // services.Add(RunBarService); // } // // void HandleServiceRequest(const mojo::ServiceFactory& factory, // mojo::GenericPendingReceiver receiver) { // if (factory.CanRunService(receiver)) { // factory.RunService(std::move(receiver), base::NullCallback()); // return; // } // // // The receiver was for neither the Foo nor Bar service. Sad! // LOG(ERROR) << "Unknown service: " << *receiver.interface_name(); // } // class COMPONENT_EXPORT(MOJO_CPP_BINDINGS) ServiceFactory { … }; namespace internal { ServiceFactoryTraits<std::unique_ptr<ImplType> (*)(PendingReceiver<InterfaceType>)>; } // namespace internal } // namespace mojo #endif // MOJO_PUBLIC_CPP_BINDINGS_SERVICE_FACTORY_H_