| Index: services/service_manager/service_manager.cc
|
| diff --git a/services/service_manager/service_manager.cc b/services/service_manager/service_manager.cc
|
| index cf7885640b29c737956c34133a516480f590eecb..e0eb0b3a549490209474f7da21904958474b7d62 100644
|
| --- a/services/service_manager/service_manager.cc
|
| +++ b/services/service_manager/service_manager.cc
|
| @@ -19,6 +19,7 @@
|
| #include "base/stl_util.h"
|
| #include "base/strings/string_util.h"
|
| #include "base/trace_event/trace_event.h"
|
| +#include "mojo/public/cpp/bindings/associated_binding.h"
|
| #include "mojo/public/cpp/bindings/binding.h"
|
| #include "mojo/public/cpp/bindings/binding_set.h"
|
| #include "services/service_manager/connect_util.h"
|
| @@ -29,6 +30,7 @@
|
| #include "services/service_manager/public/cpp/service_context.h"
|
| #include "services/service_manager/public/interfaces/connector.mojom.h"
|
| #include "services/service_manager/public/interfaces/service.mojom.h"
|
| +#include "services/service_manager/public/interfaces/service_control.mojom.h"
|
| #include "services/service_manager/public/interfaces/service_manager.mojom.h"
|
|
|
| namespace service_manager {
|
| @@ -78,7 +80,8 @@ class ServiceManager::Instance
|
| public mojom::PIDReceiver,
|
| public Service,
|
| public InterfaceFactory<mojom::ServiceManager>,
|
| - public mojom::ServiceManager {
|
| + public mojom::ServiceManager,
|
| + public mojom::ServiceControl {
|
| public:
|
| Instance(service_manager::ServiceManager* service_manager,
|
| const Identity& identity,
|
| @@ -89,6 +92,7 @@ class ServiceManager::Instance
|
| interface_provider_specs_(interface_provider_specs),
|
| allow_any_application_(GetConnectionSpec().requires.count("*") == 1),
|
| pid_receiver_binding_(this),
|
| + control_binding_(this),
|
| state_(State::IDLE),
|
| weak_factory_(this) {
|
| if (identity_.name() == kServiceManagerName ||
|
| @@ -151,11 +155,20 @@ class ServiceManager::Instance
|
| Instance* source = service_manager_->GetExistingInstance(params->source());
|
| if (source)
|
| specs = source->interface_provider_specs_;
|
| +
|
| + pending_service_connections_++;
|
| service_->OnConnect(ServiceInfo(params->source(), specs),
|
| - params->TakeRemoteInterfaces());
|
| + params->TakeRemoteInterfaces(),
|
| + base::Bind(&Instance::OnConnectComplete,
|
| + base::Unretained(this)));
|
| return true;
|
| }
|
|
|
| + void OnConnectComplete() {
|
| + DCHECK_GT(pending_service_connections_, 0);
|
| + pending_service_connections_--;
|
| + }
|
| +
|
| void StartWithService(mojom::ServicePtr service) {
|
| CHECK(!service_);
|
| state_ = State::STARTING;
|
| @@ -164,7 +177,7 @@ class ServiceManager::Instance
|
| base::Bind(&Instance::OnServiceLost, base::Unretained(this),
|
| service_manager_->GetWeakPtr()));
|
| service_->OnStart(ServiceInfo(identity_, interface_provider_specs_),
|
| - base::Bind(&Instance::OnInitializeResponse,
|
| + base::Bind(&Instance::OnStartComplete,
|
| base::Unretained(this)));
|
| }
|
|
|
| @@ -411,7 +424,8 @@ class ServiceManager::Instance
|
| }
|
| }
|
|
|
| - void OnInitializeResponse(mojom::ConnectorRequest connector_request) {
|
| + void OnStartComplete(mojom::ConnectorRequest connector_request,
|
| + mojom::ServiceControlAssociatedRequest control_request) {
|
| state_ = State::STARTED;
|
| if (connector_request.is_pending()) {
|
| connectors_.AddBinding(this, std::move(connector_request));
|
| @@ -419,6 +433,8 @@ class ServiceManager::Instance
|
| base::Bind(&Instance::OnConnectionLost, base::Unretained(this),
|
| service_manager_->GetWeakPtr()));
|
| }
|
| + if (control_request.is_pending())
|
| + control_binding_.Bind(std::move(control_request));
|
| service_manager_->NotifyServiceStarted(identity_, pid_);
|
| }
|
|
|
| @@ -430,6 +446,13 @@ class ServiceManager::Instance
|
| service_manager_->OnInstanceError(this);
|
| }
|
|
|
| + // mojom::ServiceControl:
|
| + void RequestQuit() override {
|
| + // If quit is requested, oblige when there are no pending OnConnects.
|
| + if (!pending_service_connections_)
|
| + OnServiceLost(service_manager_->GetWeakPtr());
|
| + }
|
| +
|
| service_manager::ServiceManager* const service_manager_;
|
|
|
| // An id that identifies this instance. Distinct from pid, as a single process
|
| @@ -445,10 +468,15 @@ class ServiceManager::Instance
|
| mojo::Binding<mojom::PIDReceiver> pid_receiver_binding_;
|
| mojo::BindingSet<mojom::Connector> connectors_;
|
| mojo::BindingSet<mojom::ServiceManager> service_manager_bindings_;
|
| + mojo::AssociatedBinding<mojom::ServiceControl> control_binding_;
|
| base::ProcessId pid_ = base::kNullProcessId;
|
| Instance* parent_ = nullptr;
|
| InstanceMap children_;
|
| State state_;
|
| +
|
| + // The number of outstanding OnConnect requests which are in flight.
|
| + int pending_service_connections_ = 0;
|
| +
|
| base::WeakPtrFactory<Instance> weak_factory_;
|
|
|
| DISALLOW_COPY_AND_ASSIGN(Instance);
|
|
|