Commit 2d03edf7 authored by Marijn Kruisselbrink's avatar Marijn Kruisselbrink Committed by Commit Bot

Revert "[service-manager] Introduce ServiceBinding"

This reverts commit cf9baf41.

Reason for revert: Seemed to cause test failures on Fuchsia https://ci.chromium.org/p/chromium/builders/luci.chromium.ci/Fuchsia%20x64/20283

Original change's description:
> [service-manager] Introduce ServiceBinding
> 
> Adds a new ServiceBinding helper to the Service Manager's client
> library. This is intended as a replacement for ServiceContext, because
> ServiceContext is cumbersome in its insistence to own the
> corresponding Service object.
> 
> ServiceBinding, like ServiceContext, deals with the IPC interface
> between a local Service instance and the Service Manager, exposing
> interesting events to the Service implementation while also providing
> it access to its Connector and assigned Identity.
> 
> Some particularly gnarly tests have been updated to use ServiceBinding
> in lieu of ServiceContext. Furthermore, without ServiceContext and with
> a lot of its legacy motivations gone, ServiceRunner isn't terribly
> useful either. The tests have also been trivially updated to manage
> their own MessageLoop instead of using ServiceRunner.
> 
> This is the first in a series of patches which aim to completely
> eliminate ServiceContext, ForwardingService (in service.h), and
> ServiceRunner, requiring Service implementations to write a little more
> boilerplate in exchange for flexibility with ownership semantics.
> 
> Bug: 891780
> Change-Id: Ib0c1d3263f34a5e33a167a8187edad1d52413f73
> Reviewed-on: https://chromium-review.googlesource.com/c/1259485
> Reviewed-by: Reilly Grant <reillyg@chromium.org>
> Commit-Queue: Ken Rockot <rockot@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#597324}

TBR=rockot@chromium.org,reillyg@chromium.org

Change-Id: Ib638e97e13b4d0ab24b0123323ff9941da6eb1fc
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Bug: 891780
Reviewed-on: https://chromium-review.googlesource.com/c/1266135Reviewed-by: default avatarMarijn Kruisselbrink <mek@chromium.org>
Commit-Queue: Marijn Kruisselbrink <mek@chromium.org>
Cr-Commit-Position: refs/heads/master@{#597362}
parent 838777d5
...@@ -17,8 +17,6 @@ component("cpp") { ...@@ -17,8 +17,6 @@ component("cpp") {
"local_interface_provider.h", "local_interface_provider.h",
"service.cc", "service.cc",
"service.h", "service.h",
"service_binding.cc",
"service_binding.h",
"service_context.cc", "service_context.cc",
"service_context.h", "service_context.h",
"service_context_ref.cc", "service_context_ref.cc",
...@@ -39,12 +37,7 @@ component("cpp") { ...@@ -39,12 +37,7 @@ component("cpp") {
"//url", "//url",
] ]
defines = [ defines = [ "SERVICE_MANAGER_PUBLIC_CPP_IMPL" ]
"IS_SERVICE_MANAGER_CPP_IMPL",
# TODO: Use COMPONENT_EXPORT everywhere here and remove this.
"SERVICE_MANAGER_PUBLIC_CPP_IMPL",
]
} }
# A component for types which the public interfaces depend on for typemapping. # A component for types which the public interfaces depend on for typemapping.
......
...@@ -19,8 +19,6 @@ void Service::OnBindInterface(const BindSourceInfo& source, ...@@ -19,8 +19,6 @@ void Service::OnBindInterface(const BindSourceInfo& source,
const std::string& interface_name, const std::string& interface_name,
mojo::ScopedMessagePipeHandle interface_pipe) {} mojo::ScopedMessagePipeHandle interface_pipe) {}
void Service::OnDisconnected() {}
bool Service::OnServiceManagerConnectionLost() { bool Service::OnServiceManagerConnectionLost() {
return true; return true;
} }
......
...@@ -7,9 +7,9 @@ ...@@ -7,9 +7,9 @@
#include <string> #include <string>
#include "base/component_export.h"
#include "base/macros.h" #include "base/macros.h"
#include "mojo/public/cpp/system/message_pipe.h" #include "mojo/public/cpp/system/message_pipe.h"
#include "services/service_manager/public/cpp/export.h"
namespace service_manager { namespace service_manager {
...@@ -18,7 +18,7 @@ struct BindSourceInfo; ...@@ -18,7 +18,7 @@ struct BindSourceInfo;
// The primary contract between a Service and the Service Manager, receiving // The primary contract between a Service and the Service Manager, receiving
// lifecycle notifications and connection requests. // lifecycle notifications and connection requests.
class COMPONENT_EXPORT(SERVICE_MANAGER_CPP) Service { class SERVICE_MANAGER_PUBLIC_CPP_EXPORT Service {
public: public:
Service(); Service();
virtual ~Service(); virtual ~Service();
...@@ -37,14 +37,6 @@ class COMPONENT_EXPORT(SERVICE_MANAGER_CPP) Service { ...@@ -37,14 +37,6 @@ class COMPONENT_EXPORT(SERVICE_MANAGER_CPP) Service {
const std::string& interface_name, const std::string& interface_name,
mojo::ScopedMessagePipeHandle interface_pipe); mojo::ScopedMessagePipeHandle interface_pipe);
// Called when the Service Manager has stopped tracking this instance. Once
// invoked, no further Service interface methods will be called on this
// Service, and no further communication with the Service Manager is possible.
//
// The Service may continue to operate and service existing client connections
// as it deems appropriate.
virtual void OnDisconnected();
// Called when the Service Manager has stopped tracking this instance. The // Called when the Service Manager has stopped tracking this instance. The
// service should use this as a signal to shut down, and in fact its process // service should use this as a signal to shut down, and in fact its process
// may be reaped shortly afterward if applicable. // may be reaped shortly afterward if applicable.
...@@ -57,9 +49,6 @@ class COMPONENT_EXPORT(SERVICE_MANAGER_CPP) Service { ...@@ -57,9 +49,6 @@ class COMPONENT_EXPORT(SERVICE_MANAGER_CPP) Service {
// //
// NOTE: This may be called at any time, and once it's been called, none of // NOTE: This may be called at any time, and once it's been called, none of
// the other public Service methods will be invoked by the ServiceContext. // the other public Service methods will be invoked by the ServiceContext.
//
// This is ONLY invoked when using a ServiceContext and is therefore
// deprecated.
virtual bool OnServiceManagerConnectionLost(); virtual bool OnServiceManagerConnectionLost();
protected: protected:
...@@ -83,7 +72,7 @@ class COMPONENT_EXPORT(SERVICE_MANAGER_CPP) Service { ...@@ -83,7 +72,7 @@ class COMPONENT_EXPORT(SERVICE_MANAGER_CPP) Service {
// TODO(rockot): Remove this. It's here to satisfy a few remaining use cases // TODO(rockot): Remove this. It's here to satisfy a few remaining use cases
// where a Service impl is owned by something other than its ServiceContext. // where a Service impl is owned by something other than its ServiceContext.
class COMPONENT_EXPORT(SERVICE_MANAGER_CPP) ForwardingService : public Service { class SERVICE_MANAGER_PUBLIC_CPP_EXPORT ForwardingService : public Service {
public: public:
// |target| must outlive this object. // |target| must outlive this object.
explicit ForwardingService(Service* target); explicit ForwardingService(Service* target);
......
// Copyright 2018 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.
#include "services/service_manager/public/cpp/service_binding.h"
#include <utility>
#include "base/bind.h"
#include "services/service_manager/public/cpp/service.h"
#include "base/debug/stack_trace.h"
namespace service_manager {
ServiceBinding::ServiceBinding(service_manager::Service* service)
: service_(service), binding_(this) {
DCHECK(service_);
}
ServiceBinding::ServiceBinding(service_manager::Service* service,
mojom::ServiceRequest request)
: ServiceBinding(service) {
if (request.is_pending())
Bind(std::move(request));
}
ServiceBinding::~ServiceBinding() = default;
Connector* ServiceBinding::GetConnector() {
if (!connector_)
connector_ = Connector::Create(&pending_connector_request_);
return connector_.get();
}
void ServiceBinding::Bind(mojom::ServiceRequest request) {
DCHECK(!is_bound());
binding_.Bind(std::move(request));
binding_.set_connection_error_handler(base::BindOnce(
&ServiceBinding::OnConnectionError, base::Unretained(this)));
}
void ServiceBinding::RequestClose() {
DCHECK(is_bound());
if (service_control_.is_bound()) {
service_control_->RequestQuit();
} else {
// It's possible that the service may request closure before receiving the
// initial |OnStart()| event, in which case there is not yet a control
// interface on which to request closure. In that case we defer until
// |OnStart()| is received.
request_closure_on_start_ = true;
}
}
void ServiceBinding::Close() {
DCHECK(is_bound());
binding_.Close();
service_control_.reset();
connector_.reset();
}
void ServiceBinding::OnConnectionError() {
service_->OnDisconnected();
}
void ServiceBinding::OnStart(const Identity& identity,
OnStartCallback callback) {
identity_ = identity;
service_->OnStart();
if (!pending_connector_request_.is_pending())
connector_ = Connector::Create(&pending_connector_request_);
std::move(callback).Run(std::move(pending_connector_request_),
mojo::MakeRequest(&service_control_));
// Execute any prior |RequestClose()| request on the service's behalf.
if (request_closure_on_start_)
service_control_->RequestQuit();
}
void ServiceBinding::OnBindInterface(
const BindSourceInfo& source_info,
const std::string& interface_name,
mojo::ScopedMessagePipeHandle interface_pipe,
OnBindInterfaceCallback callback) {
// Acknowledge this request.
std::move(callback).Run();
service_->OnBindInterface(source_info, interface_name,
std::move(interface_pipe));
}
} // namespace service_manager
// Copyright 2018 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_PUBLIC_CPP_SERVICE_BINDING_H_
#define SERVICES_SERVICE_MANAGER_PUBLIC_CPP_SERVICE_BINDING_H_
#include <memory>
#include "base/callback.h"
#include "base/component_export.h"
#include "base/macros.h"
#include "mojo/public/cpp/bindings/binding.h"
#include "services/service_manager/public/cpp/connector.h"
#include "services/service_manager/public/mojom/connector.mojom.h"
#include "services/service_manager/public/mojom/service.mojom.h"
#include "services/service_manager/public/mojom/service_control.mojom.h"
namespace service_manager {
class Service;
// Encapsulates service-side bindings to Service Manager interfaces. Namely,
// this helps receive and dispatch Service interface events to a service
// implementation, while also exposing a working Connector interface the service
// can use to make outgoing interface requests.
//
// A ServiceBinding is considered to be "bound" after |Bind()| is invoked with a
// valid ServiceRequest (or the equivalent constructor is used -- see below).
// Upon connection error or an explicit call to |Close()|, the ServiceBinding
// will be considered "unbound" until another call to |Bind()| is made.
//
// NOTE: A well-behaved service should aim to always close its ServiceBinding
// gracefully by calling |RequestClose()|. Closing a ServiceBinding abruptly
// (by either destroying it or explicitly calling |Close()|) introduces inherent
// flakiness into the system unless the Service's |OnDisconnected()| has already
// been invoked, because otherwise the Service Manager may have in-flight
// interface requests directed at your service instance and these will be
// dropped to the dismay of the service instance which issued them. Exceptions
// can reasonably be made for system-wide shutdown situations where even the
// Service Manager itself will be imminently torn down.
class COMPONENT_EXPORT(SERVICE_MANAGER_CPP) ServiceBinding
: public mojom::Service {
public:
// Creates a new ServiceBinding bound to |service|. The service will not
// receive any Service interface calls until |Bind()| is called, but its
// |connector()| is usable immediately upon construction.
//
// |service| is not owned and must outlive this ServiceBinding.
explicit ServiceBinding(service_manager::Service* service);
// Same as above, but behaves as if |Bind(request)| is also called immediately
// after construction. See below.
ServiceBinding(service_manager::Service* service,
mojom::ServiceRequest request);
~ServiceBinding() override;
bool is_bound() const { return binding_.is_bound(); }
Identity identity() const { return identity_; }
// Returns a usable Connector which can make outgoing interface requests
// identifying as the service to which this ServiceBinding is bound.
Connector* GetConnector();
// Binds this ServiceBinding to a new ServiceRequest. Once a ServiceBinding
// is bound, its target Service will begin receiving Service events. The
// order of events received is:
//
// - OnStart() exactly once
// - OnIdentityKnown() exactly once
// - OnBindInterface() zero or more times
//
// The target Service will be able to receive these events until this
// ServiceBinding is either unbound or destroyed.
//
// If |request| is invalid, this call does nothing.
//
// Must only be called on an unbound ServiceBinding.
void Bind(mojom::ServiceRequest request);
// Asks the Service Manager nicely if it's OK for this service instance to
// disappear now. If the Service Manager thinks it's OK, it will sever the
// binding's connection, ultimately triggering an |OnDisconnected()| call on
// the bound Service object.
//
// Must only be called on a bound ServiceBinding.
void RequestClose();
// Immediately severs the connection to the Service Manager. No further
// incoming interface requests will be received until this ServiceBinding is
// bound again. Always prefer |RequestClose()| under normal circumstances,
// unless |OnDisconnected()| has already been invoked on the Service. See the
// note in the class documentation above regarding graceful binding closure.
//
// Must only be called on a bound ServiceBinding.
void Close();
private:
void OnConnectionError();
// mojom::Service:
void OnStart(const Identity& identity, OnStartCallback callback) override;
void OnBindInterface(const BindSourceInfo& source_info,
const std::string& interface_name,
mojo::ScopedMessagePipeHandle interface_pipe,
OnBindInterfaceCallback callback) override;
// The Service instance to which all incoming events from the Service Manager
// should be directed. Typically this is the object which owns this
// ServiceBinding.
service_manager::Service* const service_;
// A pending Connector request which will eventually be passed to the Service
// Manager. Created preemptively by every unbound ServiceBinding so that
// |connector()| may begin pipelining outgoing requests even before the
// ServiceBinding is bound to a ServiceRequest.
mojom::ConnectorRequest pending_connector_request_;
mojo::Binding<mojom::Service> binding_;
Identity identity_;
std::unique_ptr<Connector> connector_;
// This instance's control interface to the service manager. Note that this
// is unbound and therefore invalid until OnStart() is called.
mojom::ServiceControlAssociatedPtr service_control_;
// Tracks whether |RequestClose()| has been called at least once prior to
// receiving |OnStart()| on a bound ServiceBinding. This ensures that the
// closure request is actually issued once |OnStart()| is invoked.
bool request_closure_on_start_ = false;
DISALLOW_COPY_AND_ASSIGN(ServiceBinding);
};
} // namespace service_manager
#endif // SERVICES_SERVICE_MANAGER_PUBLIC_CPP_SERVICE_CONTEXT_H_
...@@ -10,7 +10,6 @@ ...@@ -10,7 +10,6 @@
#include "base/bind.h" #include "base/bind.h"
#include "base/macros.h" #include "base/macros.h"
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h" #include "base/run_loop.h"
#include "base/threading/simple_thread.h" #include "base/threading/simple_thread.h"
#include "mojo/public/cpp/bindings/binding_set.h" #include "mojo/public/cpp/bindings/binding_set.h"
...@@ -18,7 +17,8 @@ ...@@ -18,7 +17,8 @@
#include "services/service_manager/public/cpp/binder_registry.h" #include "services/service_manager/public/cpp/binder_registry.h"
#include "services/service_manager/public/cpp/connector.h" #include "services/service_manager/public/cpp/connector.h"
#include "services/service_manager/public/cpp/service.h" #include "services/service_manager/public/cpp/service.h"
#include "services/service_manager/public/cpp/service_binding.h" #include "services/service_manager/public/cpp/service_context.h"
#include "services/service_manager/public/cpp/service_runner.h"
#include "services/service_manager/public/mojom/service_factory.mojom.h" #include "services/service_manager/public/mojom/service_factory.mojom.h"
#include "services/service_manager/tests/connect/connect_test.mojom.h" #include "services/service_manager/tests/connect/connect_test.mojom.h"
...@@ -74,7 +74,6 @@ class ProvidedService : public Service, ...@@ -74,7 +74,6 @@ class ProvidedService : public Service,
registry_.AddInterface<test::mojom::UserIdTest>(base::Bind( registry_.AddInterface<test::mojom::UserIdTest>(base::Bind(
&ProvidedService::BindUserIdTestRequest, base::Unretained(this))); &ProvidedService::BindUserIdTestRequest, base::Unretained(this)));
} }
void OnBindInterface(const BindSourceInfo& source_info, void OnBindInterface(const BindSourceInfo& source_info,
const std::string& interface_name, const std::string& interface_name,
mojo::ScopedMessagePipeHandle interface_pipe) override { mojo::ScopedMessagePipeHandle interface_pipe) override {
...@@ -82,11 +81,6 @@ class ProvidedService : public Service, ...@@ -82,11 +81,6 @@ class ProvidedService : public Service,
source_info); source_info);
} }
void OnDisconnected() override {
service_binding_.Close();
run_loop_->Quit();
}
void BindConnectTestServiceRequest( void BindConnectTestServiceRequest(
test::mojom::ConnectTestServiceRequest request, test::mojom::ConnectTestServiceRequest request,
const BindSourceInfo& source_info) { const BindSourceInfo& source_info) {
...@@ -94,11 +88,10 @@ class ProvidedService : public Service, ...@@ -94,11 +88,10 @@ class ProvidedService : public Service,
test::mojom::ConnectionStatePtr state(test::mojom::ConnectionState::New()); test::mojom::ConnectionStatePtr state(test::mojom::ConnectionState::New());
state->connection_remote_name = source_info.identity.name(); state->connection_remote_name = source_info.identity.name();
state->connection_remote_userid = source_info.identity.user_id(); state->connection_remote_userid = source_info.identity.user_id();
state->initialize_local_name = service_binding_.identity().name(); state->initialize_local_name = context()->identity().name();
state->initialize_userid = service_binding_.identity().user_id(); state->initialize_userid = context()->identity().user_id();
service_binding_.GetConnector()->BindInterface(source_info.identity, context()->connector()->BindInterface(source_info.identity, &caller_);
&caller_);
caller_->ConnectionAccepted(std::move(state)); caller_->ConnectionAccepted(std::move(state));
} }
...@@ -118,7 +111,7 @@ class ProvidedService : public Service, ...@@ -118,7 +111,7 @@ class ProvidedService : public Service,
} }
void GetInstance(GetInstanceCallback callback) override { void GetInstance(GetInstanceCallback callback) override {
std::move(callback).Run(service_binding_.identity().instance()); std::move(callback).Run(context()->identity().instance());
} }
// test::mojom::BlockedInterface: // test::mojom::BlockedInterface:
...@@ -130,12 +123,12 @@ class ProvidedService : public Service, ...@@ -130,12 +123,12 @@ class ProvidedService : public Service,
void ConnectToClassAppAsDifferentUser( void ConnectToClassAppAsDifferentUser(
const service_manager::Identity& target, const service_manager::Identity& target,
ConnectToClassAppAsDifferentUserCallback callback) override { ConnectToClassAppAsDifferentUserCallback callback) override {
service_binding_.GetConnector()->StartService(target); context()->connector()->StartService(target);
mojom::ConnectResult result; mojom::ConnectResult result;
Identity resolved_identity; Identity resolved_identity;
{ {
base::RunLoop loop(base::RunLoop::Type::kNestableTasksAllowed); base::RunLoop loop(base::RunLoop::Type::kNestableTasksAllowed);
Connector::TestApi test_api(service_binding_.GetConnector()); Connector::TestApi test_api(context()->connector());
test_api.SetStartServiceCallback( test_api.SetStartServiceCallback(
base::Bind(&QuitLoop, &loop, &result, &resolved_identity)); base::Bind(&QuitLoop, &loop, &result, &resolved_identity));
loop.Run(); loop.Run();
...@@ -145,13 +138,8 @@ class ProvidedService : public Service, ...@@ -145,13 +138,8 @@ class ProvidedService : public Service,
// base::SimpleThread: // base::SimpleThread:
void Run() override { void Run() override {
base::MessageLoop message_loop; ServiceRunner(new ForwardingService(this)).Run(
base::RunLoop run_loop; request_.PassMessagePipe().release().value(), false);
run_loop_ = &run_loop;
service_binding_.Bind(std::move(request_));
run_loop.Run();
run_loop_ = nullptr;
caller_.reset(); caller_.reset();
bindings_.CloseAllBindings(); bindings_.CloseAllBindings();
blocked_bindings_.CloseAllBindings(); blocked_bindings_.CloseAllBindings();
...@@ -159,15 +147,10 @@ class ProvidedService : public Service, ...@@ -159,15 +147,10 @@ class ProvidedService : public Service,
} }
void OnConnectionError() { void OnConnectionError() {
if (bindings_.empty()) { if (bindings_.empty())
if (service_binding_.is_bound()) context()->QuitNow();
service_binding_.Close();
run_loop_->Quit();
}
} }
base::RunLoop* run_loop_;
service_manager::ServiceBinding service_binding_{this};
const std::string title_; const std::string title_;
mojom::ServiceRequest request_; mojom::ServiceRequest request_;
test::mojom::ExposedInterfacePtr caller_; test::mojom::ExposedInterfacePtr caller_;
...@@ -183,11 +166,8 @@ class ConnectTestService : public Service, ...@@ -183,11 +166,8 @@ class ConnectTestService : public Service,
public mojom::ServiceFactory, public mojom::ServiceFactory,
public test::mojom::ConnectTestService { public test::mojom::ConnectTestService {
public: public:
ConnectTestService(service_manager::mojom::ServiceRequest request, ConnectTestService() {}
base::OnceClosure quit_closure) ~ConnectTestService() override {}
: service_binding_(this, std::move(request)),
quit_closure_(std::move(quit_closure)) {}
~ConnectTestService() override = default;
private: private:
// service_manager::Service: // service_manager::Service:
...@@ -204,16 +184,15 @@ class ConnectTestService : public Service, ...@@ -204,16 +184,15 @@ class ConnectTestService : public Service,
base::Bind(&ConnectTestService::BindConnectTestServiceRequest, base::Bind(&ConnectTestService::BindConnectTestServiceRequest,
base::Unretained(this))); base::Unretained(this)));
} }
void OnBindInterface(const BindSourceInfo& source_info, void OnBindInterface(const BindSourceInfo& source_info,
const std::string& interface_name, const std::string& interface_name,
mojo::ScopedMessagePipeHandle interface_pipe) override { mojo::ScopedMessagePipeHandle interface_pipe) override {
registry_.BindInterface(interface_name, std::move(interface_pipe)); registry_.BindInterface(interface_name, std::move(interface_pipe));
} }
void OnDisconnected() override { bool OnServiceManagerConnectionLost() override {
provided_services_.clear(); provided_services_.clear();
std::move(quit_closure_).Run(); return true;
} }
void BindServiceFactoryRequest(mojom::ServiceFactoryRequest request) { void BindServiceFactoryRequest(mojom::ServiceFactoryRequest request) {
...@@ -244,16 +223,14 @@ class ConnectTestService : public Service, ...@@ -244,16 +223,14 @@ class ConnectTestService : public Service,
} }
void GetInstance(GetInstanceCallback callback) override { void GetInstance(GetInstanceCallback callback) override {
std::move(callback).Run(service_binding_.identity().instance()); std::move(callback).Run(context()->identity().instance());
} }
void OnConnectionError() { void OnConnectionError() {
if (bindings_.empty() && service_factory_bindings_.empty()) if (bindings_.empty() && service_factory_bindings_.empty())
service_binding_.RequestClose(); context()->CreateQuitClosure().Run();
} }
service_manager::ServiceBinding service_binding_;
base::OnceClosure quit_closure_;
std::vector<std::unique_ptr<Service>> delegates_; std::vector<std::unique_ptr<Service>> delegates_;
mojo::BindingSet<mojom::ServiceFactory> service_factory_bindings_; mojo::BindingSet<mojom::ServiceFactory> service_factory_bindings_;
BinderRegistry registry_; BinderRegistry registry_;
...@@ -266,12 +243,7 @@ class ConnectTestService : public Service, ...@@ -266,12 +243,7 @@ class ConnectTestService : public Service,
} // namespace service_manager } // namespace service_manager
MojoResult ServiceMain(MojoHandle service_request_handle) { MojoResult ServiceMain(MojoHandle service_request_handle) {
base::MessageLoop message_loop; service_manager::ServiceRunner runner(
base::RunLoop run_loop; new service_manager::ConnectTestService);
service_manager::ConnectTestService service( return runner.Run(service_request_handle);
service_manager::mojom::ServiceRequest(mojo::MakeScopedHandle(
mojo::MessagePipeHandle(service_request_handle))),
run_loop.QuitClosure());
run_loop.Run();
return MOJO_RESULT_OK;
} }
...@@ -2,19 +2,11 @@ ...@@ -2,19 +2,11 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "services/service_manager/public/c/main.h" #include "services/service_manager/public/c/main.h"
#include "services/service_manager/public/mojom/service.mojom.h" #include "services/service_manager/public/cpp/service_runner.h"
#include "services/service_manager/tests/lifecycle/app_client.h" #include "services/service_manager/tests/lifecycle/app_client.h"
MojoResult ServiceMain(MojoHandle service_request_handle) { MojoResult ServiceMain(MojoHandle service_request_handle) {
base::MessageLoop message_loop; service_manager::ServiceRunner runner(new service_manager::test::AppClient);
base::RunLoop run_loop; return runner.Run(service_request_handle);
service_manager::test::AppClient app_client(
service_manager::mojom::ServiceRequest(mojo::MakeScopedHandle(
mojo::MessagePipeHandle(service_request_handle))),
run_loop.QuitClosure());
run_loop.Run();
return MOJO_RESULT_OK;
} }
...@@ -6,20 +6,14 @@ ...@@ -6,20 +6,14 @@
#include "base/macros.h" #include "base/macros.h"
#include "base/run_loop.h" #include "base/run_loop.h"
#include "services/service_manager/public/cpp/service_binding.h" #include "services/service_manager/public/cpp/service_context.h"
namespace service_manager { namespace service_manager {
namespace test { namespace test {
AppClient::AppClient(service_manager::mojom::ServiceRequest request, AppClient::AppClient() {
base::OnceClosure quit_closure)
: service_binding_(this, std::move(request)),
quit_closure_(std::move(quit_closure)) {
bindings_.set_connection_error_handler(base::BindRepeating(
&AppClient::LifecycleControlBindingLost, base::Unretained(this)));
registry_.AddInterface<mojom::LifecycleControl>( registry_.AddInterface<mojom::LifecycleControl>(
base::BindRepeating(&AppClient::Create, base::Unretained(this))); base::Bind(&AppClient::Create, base::Unretained(this)));
} }
AppClient::~AppClient() {} AppClient::~AppClient() {}
...@@ -30,12 +24,9 @@ void AppClient::OnBindInterface(const BindSourceInfo& source_info, ...@@ -30,12 +24,9 @@ void AppClient::OnBindInterface(const BindSourceInfo& source_info,
registry_.BindInterface(interface_name, std::move(interface_pipe)); registry_.BindInterface(interface_name, std::move(interface_pipe));
} }
void AppClient::OnDisconnected() { bool AppClient::OnServiceManagerConnectionLost() {
DCHECK(service_binding_.is_bound()); context()->QuitNow();
service_binding_.Close(); return true;
if (quit_closure_)
std::move(quit_closure_).Run();
} }
void AppClient::Create(mojom::LifecycleControlRequest request) { void AppClient::Create(mojom::LifecycleControlRequest request) {
...@@ -47,10 +38,7 @@ void AppClient::Ping(PingCallback callback) { ...@@ -47,10 +38,7 @@ void AppClient::Ping(PingCallback callback) {
} }
void AppClient::GracefulQuit() { void AppClient::GracefulQuit() {
if (service_binding_.is_bound()) context()->CreateQuitClosure().Run();
service_binding_.RequestClose();
else if (quit_closure_)
std::move(quit_closure_).Run();
} }
void AppClient::Crash() { void AppClient::Crash() {
...@@ -61,13 +49,14 @@ void AppClient::Crash() { ...@@ -61,13 +49,14 @@ void AppClient::Crash() {
} }
void AppClient::CloseServiceManagerConnection() { void AppClient::CloseServiceManagerConnection() {
if (service_binding_.is_bound()) context()->DisconnectFromServiceManager();
service_binding_.Close(); bindings_.set_connection_error_handler(
base::Bind(&AppClient::BindingLost, base::Unretained(this)));
} }
void AppClient::LifecycleControlBindingLost() { void AppClient::BindingLost() {
if (!service_binding_.is_bound() && bindings_.empty() && quit_closure_) if (bindings_.empty())
std::move(quit_closure_).Run(); OnServiceManagerConnectionLost();
} }
} // namespace test } // namespace test
......
...@@ -8,12 +8,11 @@ ...@@ -8,12 +8,11 @@
#include <memory> #include <memory>
#include "base/bind.h" #include "base/bind.h"
#include "base/callback.h"
#include "base/macros.h" #include "base/macros.h"
#include "mojo/public/cpp/bindings/binding_set.h" #include "mojo/public/cpp/bindings/binding_set.h"
#include "services/service_manager/public/cpp/binder_registry.h" #include "services/service_manager/public/cpp/binder_registry.h"
#include "services/service_manager/public/cpp/service.h" #include "services/service_manager/public/cpp/service.h"
#include "services/service_manager/public/cpp/service_binding.h" #include "services/service_manager/public/cpp/service_runner.h"
#include "services/service_manager/public/mojom/service.mojom.h" #include "services/service_manager/public/mojom/service.mojom.h"
#include "services/service_manager/tests/lifecycle/lifecycle_unittest.mojom.h" #include "services/service_manager/tests/lifecycle/lifecycle_unittest.mojom.h"
...@@ -23,15 +22,16 @@ namespace test { ...@@ -23,15 +22,16 @@ namespace test {
class AppClient : public Service, class AppClient : public Service,
public mojom::LifecycleControl { public mojom::LifecycleControl {
public: public:
explicit AppClient(service_manager::mojom::ServiceRequest request, AppClient();
base::OnceClosure quit_closure);
~AppClient() override; ~AppClient() override;
void set_runner(ServiceRunner* runner) { runner_ = runner; }
// Service: // Service:
void OnBindInterface(const BindSourceInfo& source_info, void OnBindInterface(const BindSourceInfo& source_info,
const std::string& interface_name, const std::string& interface_name,
mojo::ScopedMessagePipeHandle interface_pipe) override; mojo::ScopedMessagePipeHandle interface_pipe) override;
void OnDisconnected() override; bool OnServiceManagerConnectionLost() override;
void Create(mojom::LifecycleControlRequest request); void Create(mojom::LifecycleControlRequest request);
...@@ -44,11 +44,9 @@ class AppClient : public Service, ...@@ -44,11 +44,9 @@ class AppClient : public Service,
private: private:
class ServiceImpl; class ServiceImpl;
void LifecycleControlBindingLost(); void BindingLost();
ServiceBinding service_binding_;
base::OnceClosure quit_closure_;
ServiceRunner* runner_ = nullptr;
BinderRegistry registry_; BinderRegistry registry_;
mojo::BindingSet<mojom::LifecycleControl> bindings_; mojo::BindingSet<mojom::LifecycleControl> bindings_;
......
...@@ -2,19 +2,11 @@ ...@@ -2,19 +2,11 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "services/service_manager/public/c/main.h" #include "services/service_manager/public/c/main.h"
#include "services/service_manager/public/mojom/service.mojom.h" #include "services/service_manager/public/cpp/service_runner.h"
#include "services/service_manager/tests/lifecycle/app_client.h" #include "services/service_manager/tests/lifecycle/app_client.h"
MojoResult ServiceMain(MojoHandle service_request_handle) { MojoResult ServiceMain(MojoHandle service_request_handle) {
base::MessageLoop message_loop; service_manager::ServiceRunner runner(new service_manager::test::AppClient);
base::RunLoop run_loop; return runner.Run(service_request_handle);
service_manager::test::AppClient app_client(
service_manager::mojom::ServiceRequest(mojo::MakeScopedHandle(
mojo::MessagePipeHandle(service_request_handle))),
run_loop.QuitClosure());
run_loop.Run();
return MOJO_RESULT_OK;
} }
...@@ -7,12 +7,12 @@ ...@@ -7,12 +7,12 @@
#include "base/bind.h" #include "base/bind.h"
#include "base/macros.h" #include "base/macros.h"
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h" #include "base/run_loop.h"
#include "mojo/public/cpp/bindings/binding_set.h" #include "mojo/public/cpp/bindings/binding_set.h"
#include "services/service_manager/public/c/main.h" #include "services/service_manager/public/c/main.h"
#include "services/service_manager/public/cpp/binder_registry.h" #include "services/service_manager/public/cpp/binder_registry.h"
#include "services/service_manager/public/cpp/service_binding.h" #include "services/service_manager/public/cpp/service_context.h"
#include "services/service_manager/public/cpp/service_runner.h"
#include "services/service_manager/public/mojom/service_factory.mojom.h" #include "services/service_manager/public/mojom/service_factory.mojom.h"
#include "services/service_manager/tests/lifecycle/app_client.h" #include "services/service_manager/tests/lifecycle/app_client.h"
#include "services/service_manager/tests/lifecycle/lifecycle_unittest.mojom.h" #include "services/service_manager/tests/lifecycle/lifecycle_unittest.mojom.h"
...@@ -22,20 +22,19 @@ namespace { ...@@ -22,20 +22,19 @@ namespace {
class PackagedApp : public service_manager::Service, class PackagedApp : public service_manager::Service,
public service_manager::test::mojom::LifecycleControl { public service_manager::test::mojom::LifecycleControl {
public: public:
PackagedApp(service_manager::mojom::ServiceRequest request, PackagedApp(
base::OnceClosure service_manager_connection_closed_callback, const base::Closure& service_manager_connection_closed_callback,
base::OnceClosure destruct_callback) const base::Closure& destruct_callback)
: service_binding_(this, std::move(request)), : service_manager_connection_closed_callback_(
service_manager_connection_closed_callback_( service_manager_connection_closed_callback),
std::move(service_manager_connection_closed_callback)), destruct_callback_(destruct_callback) {
destruct_callback_(std::move(destruct_callback)) { bindings_.set_connection_error_handler(base::Bind(&PackagedApp::BindingLost,
bindings_.set_connection_error_handler( base::Unretained(this)));
base::BindRepeating(&PackagedApp::MaybeQuit, base::Unretained(this)));
registry_.AddInterface<service_manager::test::mojom::LifecycleControl>( registry_.AddInterface<service_manager::test::mojom::LifecycleControl>(
base::Bind(&PackagedApp::Create, base::Unretained(this))); base::Bind(&PackagedApp::Create, base::Unretained(this)));
} }
~PackagedApp() override = default; ~PackagedApp() override {}
private: private:
// service_manager::Service: // service_manager::Service:
...@@ -45,11 +44,6 @@ class PackagedApp : public service_manager::Service, ...@@ -45,11 +44,6 @@ class PackagedApp : public service_manager::Service,
registry_.BindInterface(interface_name, std::move(interface_pipe)); registry_.BindInterface(interface_name, std::move(interface_pipe));
} }
void OnDisconnected() override {
std::move(service_manager_connection_closed_callback_).Run();
std::move(destruct_callback_).Run();
}
void Create(service_manager::test::mojom::LifecycleControlRequest request) { void Create(service_manager::test::mojom::LifecycleControlRequest request) {
bindings_.AddBinding(this, std::move(request)); bindings_.AddBinding(this, std::move(request));
} }
...@@ -57,7 +51,12 @@ class PackagedApp : public service_manager::Service, ...@@ -57,7 +51,12 @@ class PackagedApp : public service_manager::Service,
// LifecycleControl: // LifecycleControl:
void Ping(PingCallback callback) override { std::move(callback).Run(); } void Ping(PingCallback callback) override { std::move(callback).Run(); }
void GracefulQuit() override { service_binding_.RequestClose(); } void GracefulQuit() override {
service_manager_connection_closed_callback_.Run();
// Deletes |this|.
destruct_callback_.Run();
}
void Crash() override { void Crash() override {
// When multiple instances are vended from the same package instance, this // When multiple instances are vended from the same package instance, this
...@@ -66,68 +65,50 @@ class PackagedApp : public service_manager::Service, ...@@ -66,68 +65,50 @@ class PackagedApp : public service_manager::Service,
} }
void CloseServiceManagerConnection() override { void CloseServiceManagerConnection() override {
std::move(service_manager_connection_closed_callback_).Run(); service_manager_connection_closed_callback_.Run();
context()->QuitNow();
if (service_binding_.is_bound())
service_binding_.Close();
// This only closed our relationship with the service manager, existing // This only closed our relationship with the service manager, existing
// |bindings_| remain active. // |bindings_| remain active.
MaybeQuit();
} }
void MaybeQuit() { void BindingLost() {
if (service_binding_.is_bound() || !bindings_.empty()) if (bindings_.empty()) {
return; // Deletes |this|.
destruct_callback_.Run();
// Deletes |this|. }
std::move(destruct_callback_).Run();
} }
service_manager::ServiceBinding service_binding_;
service_manager::BinderRegistry registry_; service_manager::BinderRegistry registry_;
mojo::BindingSet<service_manager::test::mojom::LifecycleControl> bindings_; mojo::BindingSet<service_manager::test::mojom::LifecycleControl> bindings_;
// Run when this object's connection to the service manager is closed. // Run when this object's connection to the service manager is closed.
base::OnceClosure service_manager_connection_closed_callback_; base::Closure service_manager_connection_closed_callback_;
// Run when this object is destructed. // Run when this object is destructed.
base::OnceClosure destruct_callback_; base::Closure destruct_callback_;
DISALLOW_COPY_AND_ASSIGN(PackagedApp); DISALLOW_COPY_AND_ASSIGN(PackagedApp);
}; };
class Package : public service_manager::Service, class Package : public service_manager::ForwardingService,
public service_manager::mojom::ServiceFactory { public service_manager::mojom::ServiceFactory {
public: public:
explicit Package(service_manager::mojom::ServiceRequest request, Package() : ForwardingService(&app_client_) {
base::OnceClosure quit_closure)
: service_binding_(this, std::move(request)),
quit_closure_(std::move(quit_closure)),
app_client_(service_manager::mojom::ServiceRequest(),
base::BindOnce(&Package::QuitFromAppClient,
base::Unretained(this))) {
registry_.AddInterface<service_manager::mojom::ServiceFactory>( registry_.AddInterface<service_manager::mojom::ServiceFactory>(
base::BindRepeating(&Package::Create, base::Unretained(this))); base::Bind(&Package::Create, base::Unretained(this)));
} }
~Package() override {}
~Package() override = default;
private: private:
void QuitFromAppClient() { std::move(quit_closure_).Run(); } // ForwardingService:
// service_manager::Service:
void OnBindInterface(const service_manager::BindSourceInfo& source_info, void OnBindInterface(const service_manager::BindSourceInfo& source_info,
const std::string& interface_name, const std::string& interface_name,
mojo::ScopedMessagePipeHandle interface_pipe) override { mojo::ScopedMessagePipeHandle interface_pipe) override {
if (!registry_.TryBindInterface(interface_name, &interface_pipe)) { if (!registry_.TryBindInterface(interface_name, &interface_pipe)) {
app_client_.OnBindInterface(source_info, interface_name, ForwardingService::OnBindInterface(source_info, interface_name,
std::move(interface_pipe)); std::move(interface_pipe));
} }
} }
void OnDisconnected() override { std::move(quit_closure_).Run(); }
void Create(service_manager::mojom::ServiceFactoryRequest request) { void Create(service_manager::mojom::ServiceFactoryRequest request) {
bindings_.AddBinding(this, std::move(request)); bindings_.AddBinding(this, std::move(request));
} }
...@@ -139,35 +120,48 @@ class Package : public service_manager::Service, ...@@ -139,35 +120,48 @@ class Package : public service_manager::Service,
service_manager::mojom::PIDReceiverPtr pid_receiver) override { service_manager::mojom::PIDReceiverPtr pid_receiver) override {
++service_manager_connection_refcount_; ++service_manager_connection_refcount_;
int id = next_id_++; int id = next_id_++;
auto app = std::make_unique<PackagedApp>( std::unique_ptr<service_manager::ServiceContext> context =
std::move(request), std::make_unique<service_manager::ServiceContext>(
base::BindOnce(&Package::OnAppInstanceDisconnected, std::make_unique<PackagedApp>(
base::Unretained(this)), base::Bind(&Package::AppServiceManagerConnectionClosed,
base::BindOnce(&Package::DestroyAppInstance, base::Unretained(this), base::Unretained(this)),
id)); base::Bind(&Package::DestroyService, base::Unretained(this),
app_instances_.emplace(id, std::move(app)); id)),
std::move(request));
service_manager::ServiceContext* raw_context = context.get();
contexts_.insert(std::make_pair(raw_context, std::move(context)));
id_to_context_.insert(std::make_pair(id, raw_context));
} }
void OnAppInstanceDisconnected() { void AppServiceManagerConnectionClosed() {
if (--service_manager_connection_refcount_ == 0) if (!--service_manager_connection_refcount_)
service_binding_.RequestClose(); app_client_.CloseServiceManagerConnection();
} }
void DestroyAppInstance(int id) { void DestroyService(int id) {
app_instances_.erase(id); auto id_it = id_to_context_.find(id);
if (app_instances_.empty()) DCHECK(id_it != id_to_context_.end());
std::move(quit_closure_).Run();
auto it = contexts_.find(id_it->second);
DCHECK(it != contexts_.end());
contexts_.erase(it);
id_to_context_.erase(id_it);
if (contexts_.empty() && base::RunLoop::IsRunningOnCurrentThread())
context()->QuitNow();
} }
service_manager::ServiceBinding service_binding_;
base::OnceClosure quit_closure_;
service_manager::test::AppClient app_client_; service_manager::test::AppClient app_client_;
int service_manager_connection_refcount_ = 0; int service_manager_connection_refcount_ = 0;
service_manager::BinderRegistry registry_; service_manager::BinderRegistry registry_;
mojo::BindingSet<service_manager::mojom::ServiceFactory> bindings_; mojo::BindingSet<service_manager::mojom::ServiceFactory> bindings_;
using ServiceContextMap =
std::map<service_manager::ServiceContext*,
std::unique_ptr<service_manager::ServiceContext>>;
ServiceContextMap contexts_;
int next_id_ = 0; int next_id_ = 0;
std::map<int, std::unique_ptr<PackagedApp>> app_instances_; std::map<int, service_manager::ServiceContext*> id_to_context_;
DISALLOW_COPY_AND_ASSIGN(Package); DISALLOW_COPY_AND_ASSIGN(Package);
}; };
...@@ -175,11 +169,6 @@ class Package : public service_manager::Service, ...@@ -175,11 +169,6 @@ class Package : public service_manager::Service,
} // namespace } // namespace
MojoResult ServiceMain(MojoHandle service_request_handle) { MojoResult ServiceMain(MojoHandle service_request_handle) {
base::MessageLoop message_loop; service_manager::ServiceRunner runner(new Package);
base::RunLoop run_loop; return runner.Run(service_request_handle);
Package package(service_manager::mojom::ServiceRequest(mojo::MakeScopedHandle(
mojo::MessagePipeHandle(service_request_handle))),
run_loop.QuitClosure());
run_loop.Run();
return MOJO_RESULT_OK;
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment