// Copyright 2014 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef SERVICES_SERVICE_MANAGER_SERVICE_MANAGER_H_ #define SERVICES_SERVICE_MANAGER_SERVICE_MANAGER_H_ #include #include #include #include "base/containers/unique_ptr_adapters.h" #include "base/files/file_path.h" #include "base/macros.h" #include "base/optional.h" #include "base/process/process.h" #include "base/token.h" #include "mojo/public/cpp/bindings/interface_ptr_set.h" #include "mojo/public/cpp/bindings/pending_receiver.h" #include "mojo/public/cpp/bindings/pending_remote.h" #include "mojo/public/cpp/bindings/remote_set.h" #include "services/service_manager/catalog.h" #include "services/service_manager/public/cpp/identity.h" #include "services/service_manager/public/cpp/manifest.h" #include "services/service_manager/public/cpp/service.h" #include "services/service_manager/public/cpp/service_binding.h" #include "services/service_manager/public/mojom/connector.mojom.h" #include "services/service_manager/public/mojom/interface_provider.mojom.h" #include "services/service_manager/public/mojom/service.mojom.h" #include "services/service_manager/public/mojom/service_manager.mojom.h" #include "services/service_manager/sandbox/sandbox_type.h" #include "services/service_manager/service_instance_registry.h" #include "services/service_manager/service_process_host.h" namespace service_manager { class ServiceInstance; class ServiceManager : public Service { public: // This is an interface a ServiceManager instance can use to delegate certain // operations (like launching in-process services) to its embedding runtime // environment. class Delegate { public: virtual ~Delegate() {} // Asks for a new concrete instance of the service identified by |identity| // to be created in the calling (i.e. the Service Manager's) process. If // created, the instance should bind to |receiver|. Returns |true| if the // instance was created or |false| otherwise (e.g. the service was unknown // or in-process instances are not supported by the runtime environment). // // This is only called for services with the ExecutionMode // |kInProcessBuiltin|. virtual bool RunBuiltinServiceInstanceInCurrentProcess( const Identity& identity, mojo::PendingReceiver receiver) = 0; // Creates a new ServiceProcessHost to host an out-of-process service // instance for a service using ExecuteMode |kOutOfProcessBuiltin|. // // May return null if builtin out-of-process services are not supported by // the runtime environment. // // TODO(https://crbug.com/895615): Process launching should be fully the // responsibility of the Service Manager. This exists because much of the // Chromium process launching logic today is still buried in the Content // layer. virtual std::unique_ptr CreateProcessHostForBuiltinServiceInstance(const Identity& identity) = 0; // Creates a new ServiceProcessHost to host an out-of-process service // instance for a service using a standalone executable (i.e. ExecuteMode in // the manifest is |kStandaloneExecutable|). // // May return null if service executables are not supported by the runtime // environment. // // TODO(https://crbug.com/895615): Process launching should be fully the // responsibility of the Service Manager. This exists because much of the // Chromium process launching logic today is still buried in the Content // layer. virtual std::unique_ptr CreateProcessHostForServiceExecutable( const base::FilePath& executable_path) = 0; }; // Indicates whether standalone service executables are supported by this // ServiceManager instance. Only used when an explicit Delegate is not // specified at construction time. enum class ServiceExecutablePolicy { kSupported, kNotSupported, }; // Constructs a new ServiceManager instance. |delegate| is used to augment // default Service Manager behavior. // // |manifests| is the complete list of manifests for all services available to // the runtime environment. ServiceManager(const std::vector& manifests, std::unique_ptr delegate); // Like above but uses a default internal Delegate implementation. With the // default implementation, only packaged services, manually registered service // instances, or (policy permitting) service executables are supported. No // builtin (in-process or out-of-process) services are supported unless // manually registered with |RegisterService()| below. ServiceManager(const std::vector& manifests, ServiceExecutablePolicy service_executable_policy); ~ServiceManager() override; // Provide a callback to be notified whenever an instance is destroyed. // Typically the creator of the Service Manager will use this to determine // when some set of services it created are destroyed, so it can shut down. void SetInstanceQuitCallback( base::OnceCallback callback); // Directly requests that the Service Manager start a new instance for // |service_name| if one is not already running. // // TODO(https://crbug.com/904240): Remove this method. void StartService(const std::string& service_name); // Creates a service instance for |identity|. This is intended for use by the // Service Manager's embedder to register instances directly, without // requiring a Connector. // // |metadata_receiver| may be null, in which case the Service Manager assumes // the new service is running in the calling process. // // Returns |true| if registration succeeded, or |false| otherwise. bool RegisterService( const Identity& identity, mojo::PendingRemote service, mojo::PendingReceiver metadata_receiver); // Determine information about |service_name| from its manifests. Returns // false if the identity does not have a catalog entry. bool QueryCatalog(const std::string& service_name, const base::Token& instance_group, std::string* sandbox_type); // Attempts to locate a ServiceInstance as a target for a connection request // from |source_instance| by matching against |partial_target_filter|. If a // suitable instance exists it is returned, otherwise the Service Manager // attempts to create a new suitable instance. // // Returns null if a matching instance did not exist and could not be created, // otherwise returns a valid ServiceInstance which matches // |partial_target_filter| from |source_instance|'s perspective. ServiceInstance* FindOrCreateMatchingTargetInstance( const ServiceInstance& source_instance, const ServiceFilter& partial_target_filter); private: friend class ServiceInstance; // Erases |instance| from the instance registry. Following this call it is // impossible for any call to GetExistingInstance() to return |instance| even // though the instance may continue to exist and send requests to the Service // Manager. void MakeInstanceUnreachable(ServiceInstance* instance); // Called when |instance| no longer has any connections to the remote service // instance, or when some other fatal error is encountered in managing the // instance. Deletes |instance|. void DestroyInstance(ServiceInstance* instance); // Called by a ServiceInstance as it's being destroyed. void OnInstanceStopped(const Identity& identity); // Returns a running instance identified by |identity|. ServiceInstance* GetExistingInstance(const Identity& identity) const; void NotifyServiceCreated(const ServiceInstance& instance); void NotifyServiceStarted(const Identity& identity, base::ProcessId pid); void NotifyServiceFailedToStart(const Identity& identity); void NotifyServicePIDReceived(const Identity& identity, base::ProcessId pid); ServiceInstance* CreateServiceInstance(const Identity& identity, const Manifest& manifest); // Called from the instance implementing mojom::ServiceManager. void AddListener(mojo::PendingRemote listener); // Service: void OnBindInterface(const BindSourceInfo& source_info, const std::string& interface_name, mojo::ScopedMessagePipeHandle receiving_pipe) override; const std::unique_ptr delegate_; ServiceBinding service_binding_{this}; // Ownership of all ServiceInstances. using InstanceMap = std::set, base::UniquePtrComparator>; InstanceMap instances_; Catalog catalog_; // Maps service identities to reachable instances, allowing for lookup of // running instances by ServiceFilter. ServiceInstanceRegistry instance_registry_; // Always points to the ServiceManager's own Instance. Note that this // ServiceInstance still has an entry in |instances_|. ServiceInstance* service_manager_instance_; mojo::RemoteSet listeners_; base::OnceCallback instance_quit_callback_; DISALLOW_COPY_AND_ASSIGN(ServiceManager); }; } // namespace service_manager #endif // SERVICES_SERVICE_MANAGER_SERVICE_MANAGER_H_