More work on ServiceProviderImpl.
* Remove the old AddService<I>().
* Rename AddServiceNew<I>() to AddService<I>().
* Add a getter for the ConnectionContext.
* Add a AddServiceForName() that takes a ServiceConnector.
* Add RemoveService<I>() and RemoveServiceForName().
The additions are basically required to replace the current
ServiceProvider implementation in stuff in ServiceRegistry with just a
ServiceProviderImpl.
R=vardhan@google.com
Review URL: https://codereview.chromium.org/1976063002 .
diff --git a/apps/moterm/moterm_view.cc b/apps/moterm/moterm_view.cc
index 413d486..e9f942f 100644
--- a/apps/moterm/moterm_view.cc
+++ b/apps/moterm/moterm_view.cc
@@ -58,7 +58,11 @@
// connection context argument.
service_provider_impl_.Bind(mojo::ConnectionContext(),
service_provider_request.Pass());
- service_provider_impl_.AddService<mojo::terminal::Terminal>(this);
+ service_provider_impl_.AddService<mojo::terminal::Terminal>([this](
+ const mojo::ConnectionContext& connection_context,
+ mojo::InterfaceRequest<mojo::terminal::Terminal> terminal_request) {
+ terminal_bindings_.AddBinding(this, terminal_request.Pass());
+ });
}
regular_typeface_ = skia::AdoptRef(SkTypeface::CreateFromStream(
@@ -133,12 +137,6 @@
}
}
-void MotermView::Create(
- const mojo::ConnectionContext& connection_context,
- mojo::InterfaceRequest<mojo::terminal::Terminal> request) {
- terminal_bindings_.AddBinding(this, request.Pass());
-}
-
void MotermView::Connect(
mojo::InterfaceRequest<mojo::files::File> terminal_file,
bool force,
diff --git a/apps/moterm/moterm_view.h b/apps/moterm/moterm_view.h
index 692670b..3595c4e 100644
--- a/apps/moterm/moterm_view.h
+++ b/apps/moterm/moterm_view.h
@@ -12,7 +12,6 @@
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "mojo/common/binding_set.h"
-#include "mojo/public/cpp/application/interface_factory.h"
#include "mojo/public/cpp/application/service_provider_impl.h"
#include "mojo/public/cpp/bindings/callback.h"
#include "mojo/public/cpp/bindings/interface_request.h"
@@ -30,7 +29,6 @@
public mojo::ui::InputListener,
public MotermModel::Delegate,
public MotermDriver::Client,
- public mojo::InterfaceFactory<mojo::terminal::Terminal>,
public mojo::terminal::Terminal {
public:
MotermView(
@@ -60,11 +58,6 @@
void OnClosed() override;
void OnDestroyed() override;
- // |mojo::InterfaceFactory<mojo::terminal::Terminal>|:
- void Create(
- const mojo::ConnectionContext& connection_context,
- mojo::InterfaceRequest<mojo::terminal::Terminal> request) override;
-
// |mojo::terminal::Terminal| implementation:
void Connect(mojo::InterfaceRequest<mojo::files::File> terminal_file,
bool force,
diff --git a/mojo/public/cpp/application/service_provider_impl.h b/mojo/public/cpp/application/service_provider_impl.h
index dd24472..54adac7 100644
--- a/mojo/public/cpp/application/service_provider_impl.h
+++ b/mojo/public/cpp/application/service_provider_impl.h
@@ -7,10 +7,9 @@
#include <functional>
#include <string>
+#include <utility>
-#include "mojo/public/cpp/application/application_connection.h"
#include "mojo/public/cpp/application/connection_context.h"
-#include "mojo/public/cpp/application/lib/interface_factory_connector.h"
#include "mojo/public/cpp/application/lib/service_connector_registry.h"
#include "mojo/public/cpp/application/service_connector.h"
#include "mojo/public/cpp/bindings/binding.h"
@@ -53,14 +52,12 @@
// unbound state). This may be called even if this object is already unbound.
void Close();
- // TODO(vtl): Remove this.
- template <typename Interface>
- void AddService(InterfaceFactory<Interface>* factory,
- const std::string& interface_name = Interface::Name_) {
+ // Adds a supported service with the given |name|, using the given
+ // |service_connector|.
+ void AddServiceForName(std::unique_ptr<ServiceConnector> service_connector,
+ const std::string& interface_name) {
service_connector_registry_.SetServiceConnectorForName(
- std::unique_ptr<ServiceConnector>(
- new internal::InterfaceFactoryConnector<Interface>(factory)),
- interface_name);
+ std::move(service_connector), interface_name);
}
// Adds a supported service with the given |name|, using the given
@@ -70,23 +67,34 @@
//
// A typical usage may be:
//
- // service_provider_impl_->AddServiceNew<Foobar>(
+ // service_provider_impl_->AddService<Foobar>(
// [](const ConnectionContext& connection_context,
// InterfaceRequest<FooBar> foobar_request) {
// // |FoobarImpl| owns itself.
// new FoobarImpl(std::move(foobar_request));
// });
- // TODO(vtl): Remove the AddService() above and rename this to AddService().
template <typename Interface>
- void AddServiceNew(
- InterfaceRequestHandler<Interface> interface_request_handler,
- const std::string& name = Interface::Name_) {
- service_connector_registry_.SetServiceConnectorForName(
+ void AddService(InterfaceRequestHandler<Interface> interface_request_handler,
+ const std::string& name = Interface::Name_) {
+ AddServiceForName(
std::unique_ptr<ServiceConnector>(new ServiceConnectorImpl<Interface>(
std::move(interface_request_handler))),
name);
}
+ // Removes support for the service with the given |name|.
+ void RemoveServiceForName(const std::string& name) {
+ service_connector_registry_.RemoveServiceConnectorForName(name);
+ }
+
+ // Like |RemoveServiceForName()| (above), but designed so that it can be used
+ // like |RemoveService<Interface>()| or even |RemoveService<Interface>(name)|
+ // (to parallel |AddService<Interface>()|).
+ template <typename Interface>
+ void RemoveService(const std::string& name = Interface::Name_) {
+ RemoveServiceForName(name);
+ }
+
// This uses the provided |fallback_service_provider| for connection requests
// for services that are not known (haven't been added). (Set it to null to
// not have any fallback.) A fallback must outlive this object (or until it is
@@ -96,6 +104,12 @@
fallback_service_provider_ = fallback_service_provider;
}
+ // Gets the context for the connection that this object is bound to (if not
+ // bound, the context is just a default-initialized |ConnectionContext|).
+ const ConnectionContext& connection_context() const {
+ return connection_context_;
+ }
+
private:
// Objects of this class are used to adapt a generic (untyped) connection
// request (i.e., |ServiceConnector::ConnectToService()|) to the type-safe
diff --git a/mojo/public/cpp/application/tests/service_provider_impl_unittest.cc b/mojo/public/cpp/application/tests/service_provider_impl_unittest.cc
index a66f182..2483fc3 100644
--- a/mojo/public/cpp/application/tests/service_provider_impl_unittest.cc
+++ b/mojo/public/cpp/application/tests/service_provider_impl_unittest.cc
@@ -65,8 +65,11 @@
ServiceProviderImpl impl(ConnectionContext(ConnectionContext::Type::INCOMING,
kRemoteUrl, kConnectionUrl),
GetProxy(&sp));
+ EXPECT_EQ(ConnectionContext::Type::INCOMING, impl.connection_context().type);
+ EXPECT_EQ(kRemoteUrl, impl.connection_context().remote_url);
+ EXPECT_EQ(kConnectionUrl, impl.connection_context().connection_url);
- impl.AddServiceNew<test::PingService>(
+ impl.AddService<test::PingService>(
[&kRemoteUrl, &kConnectionUrl](
const ConnectionContext& connection_context,
InterfaceRequest<test::PingService> ping_service_request) {
@@ -77,7 +80,7 @@
},
kPing1);
- impl.AddServiceNew<test::PingService>(
+ impl.AddService<test::PingService>(
[&kRemoteUrl, &kConnectionUrl](
const ConnectionContext& connection_context,
InterfaceRequest<test::PingService> ping_service_request) {
@@ -116,6 +119,40 @@
}
loop().RunUntilIdle(); // Run stuff caused by destructors.
+ impl.RemoveService<test::PingService>(kPing2);
+
+ // "Ping2" should no longer work.
+ {
+ test::PingServicePtr ping2;
+ ConnectToService(sp.get(), GetProxy(&ping2), kPing2);
+ ping2.set_connection_error_handler([this] { QuitLoop(true); });
+ ping2->Ping([this] { QuitLoop(false); });
+ loop().Run();
+ }
+ loop().RunUntilIdle(); // Run stuff caused by destructors.
+
+ // But "Ping1" should still work.
+ {
+ test::PingServicePtr ping1;
+ ConnectToService(sp.get(), GetProxy(&ping1), kPing1);
+ ping1.set_connection_error_handler([this] { QuitLoop(false); });
+ ping1->Ping([this] { QuitLoop(true); });
+ loop().Run();
+ }
+ loop().RunUntilIdle(); // Run stuff caused by destructors.
+
+ impl.RemoveServiceForName(kPing1);
+
+ // "Ping1" should no longer work.
+ {
+ test::PingServicePtr ping1;
+ ConnectToService(sp.get(), GetProxy(&ping1), kPing1);
+ ping1.set_connection_error_handler([this] { QuitLoop(true); });
+ ping1->Ping([this] { QuitLoop(false); });
+ loop().Run();
+ }
+ loop().RunUntilIdle(); // Run stuff caused by destructors.
+
sp.reset();
loop().RunUntilIdle();
}
@@ -130,8 +167,11 @@
ServiceProviderImpl impl(ConnectionContext(ConnectionContext::Type::INCOMING,
kRemoteUrl1, kConnectionUrl),
GetProxy(&sp1));
+ EXPECT_EQ(ConnectionContext::Type::INCOMING, impl.connection_context().type);
+ EXPECT_EQ(kRemoteUrl1, impl.connection_context().remote_url);
+ EXPECT_EQ(kConnectionUrl, impl.connection_context().connection_url);
- impl.AddServiceNew<test::PingService>(
+ impl.AddService<test::PingService>(
[&kRemoteUrl1, &kRemoteUrl2, &kConnectionUrl](
const ConnectionContext& connection_context,
InterfaceRequest<test::PingService> ping_service_request) {
@@ -153,6 +193,9 @@
loop().RunUntilIdle(); // Run stuff caused by destructors.
impl.Close();
+ EXPECT_EQ(ConnectionContext::Type::UNKNOWN, impl.connection_context().type);
+ EXPECT_EQ(std::string(), impl.connection_context().remote_url);
+ EXPECT_EQ(std::string(), impl.connection_context().connection_url);
sp1.reset();
loop().RunUntilIdle();
@@ -160,6 +203,9 @@
impl.Bind(ConnectionContext(ConnectionContext::Type::INCOMING, kRemoteUrl2,
kConnectionUrl),
GetProxy(&sp2));
+ EXPECT_EQ(ConnectionContext::Type::INCOMING, impl.connection_context().type);
+ EXPECT_EQ(kRemoteUrl2, impl.connection_context().remote_url);
+ EXPECT_EQ(kConnectionUrl, impl.connection_context().connection_url);
{
test::PingServicePtr ping;
@@ -184,12 +230,15 @@
ServiceProviderPtr sp;
ServiceProviderImpl impl;
+ EXPECT_EQ(ConnectionContext::Type::UNKNOWN, impl.connection_context().type);
+ EXPECT_EQ(std::string(), impl.connection_context().remote_url);
+ EXPECT_EQ(std::string(), impl.connection_context().connection_url);
impl.Bind(ConnectionContext(ConnectionContext::Type::INCOMING, kRemoteUrl,
kConnectionUrl),
GetProxy(&sp));
- impl.AddServiceNew<test::PingService>(
+ impl.AddService<test::PingService>(
[&kRemoteUrl, &kConnectionUrl](
const ConnectionContext& connection_context,
InterfaceRequest<test::PingService> request) {
@@ -289,5 +338,7 @@
EXPECT_FALSE(was_run);
}
+// TODO(vtl): Explicitly test |AddServiceForName()|?
+
} // namespace
} // namespace mojo