blob: 4336d6b2d50fc038d380f7f8dc28cd6c102b09ab [file] [log] [blame]
// 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 <memory>
#include <set>
#include <vector>
#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 "sandbox/policy/sandbox_type.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_receiver.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/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<mojom::Service> 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<ServiceProcessHost>
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<ServiceProcessHost>
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<Manifest>& manifests,
std::unique_ptr<Delegate> 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<Manifest>& manifests,
ServiceExecutablePolicy service_executable_policy);
~ServiceManager() override;
// 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<mojom::Service> service,
mojo::PendingReceiver<mojom::ProcessMetadata> 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<mojom::ServiceManagerListener> listener);
// Service:
void OnBindInterface(const BindSourceInfo& source_info,
const std::string& interface_name,
mojo::ScopedMessagePipeHandle receiving_pipe) override;
const std::unique_ptr<Delegate> delegate_;
ServiceReceiver service_receiver_{this};
// Ownership of all ServiceInstances.
using InstanceMap =
std::set<std::unique_ptr<ServiceInstance>, 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<mojom::ServiceManagerListener> listeners_;
DISALLOW_COPY_AND_ASSIGN(ServiceManager);
};
} // namespace service_manager
#endif // SERVICES_SERVICE_MANAGER_SERVICE_MANAGER_H_