summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorrockot <rockot@chromium.org>2015-01-27 10:35:01 -0800
committerCommit bot <commit-bot@chromium.org>2015-01-27 18:37:01 +0000
commit775ce0d866ddd61b0474b83d6ed7fb12601b6320 (patch)
treee71b40cf1ba0fe910b216e5bd414292cab8365ee
parentda4f04df85adfca79a30c283bcc29af4d9a39156 (diff)
downloadchromium_src-775ce0d866ddd61b0474b83d6ed7fb12601b6320.zip
chromium_src-775ce0d866ddd61b0474b83d6ed7fb12601b6320.tar.gz
chromium_src-775ce0d866ddd61b0474b83d6ed7fb12601b6320.tar.bz2
Update mojo sdk to rev a85a2cea82d816de115e15253742b0f88a9924eb
BUG=None TBR=aa@chromium.org for html_viewer TBR=darin@chromium.org Review URL: https://codereview.chromium.org/866263004 Cr-Commit-Position: refs/heads/master@{#313314}
-rw-r--r--content/browser/frame_host/render_frame_host_impl.cc13
-rw-r--r--content/browser/mojo/mojo_application_host.cc31
-rw-r--r--content/browser/mojo/mojo_application_host.h4
-rw-r--r--content/child/BUILD.gn1
-rw-r--r--content/child/mojo/mojo_application.cc13
-rw-r--r--content/common/BUILD.gn1
-rw-r--r--content/common/application_setup.mojom12
-rw-r--r--content/common/mojo/service_registry_impl.cc30
-rw-r--r--content/common/mojo/service_registry_impl.h17
-rw-r--r--content/common/render_frame_setup.mojom5
-rw-r--r--content/content_common_mojo_bindings.gyp1
-rw-r--r--content/renderer/render_frame_impl.cc6
-rw-r--r--content/renderer/render_frame_impl.h6
-rw-r--r--content/renderer/render_thread_impl.cc49
-rw-r--r--content/renderer/render_thread_impl.h26
-rw-r--r--content/shell/browser/shell_mojo_test_utils_android.cc12
-rw-r--r--mojo/services/html_viewer/html_document.cc8
-rw-r--r--mojo/services/html_viewer/html_document.h9
-rw-r--r--mojo/services/html_viewer/html_viewer.cc2
-rw-r--r--mojo/services/public/js/application.js29
-rw-r--r--mojo/services/public/js/service_provider.js3
-rw-r--r--mojo/services/public/js/shell.js6
-rw-r--r--mojo/services/view_manager/public/cpp/lib/view.cc18
-rw-r--r--mojo/services/view_manager/public/cpp/lib/view_manager_client_impl.cc31
-rw-r--r--mojo/services/view_manager/public/cpp/lib/view_manager_client_impl.h6
-rw-r--r--mojo/services/view_manager/public/cpp/lib/view_manager_context.cc20
-rw-r--r--mojo/services/view_manager/public/cpp/tests/view_manager_unittest.cc4
-rw-r--r--mojo/services/view_manager/public/cpp/view.h6
-rw-r--r--mojo/services/view_manager/public/cpp/view_manager_context.h14
-rw-r--r--mojo/services/view_manager/public/cpp/view_manager_delegate.h21
-rw-r--r--mojo/services/view_manager/public/interfaces/view_manager.mojom18
-rw-r--r--mojo/services/window_manager/public/interfaces/window_manager.mojom5
-rw-r--r--third_party/mojo/mojo_public.gyp2
-rw-r--r--third_party/mojo/src/mojo/edk/system/BUILD.gn7
-rw-r--r--third_party/mojo/src/mojo/edk/system/raw_channel.cc43
-rw-r--r--third_party/mojo/src/mojo/edk/system/raw_channel.h23
-rw-r--r--third_party/mojo/src/mojo/edk/system/raw_channel_posix.cc30
-rw-r--r--third_party/mojo/src/mojo/edk/system/raw_channel_unittest.cc66
-rw-r--r--third_party/mojo/src/mojo/edk/system/raw_channel_win.cc2
-rw-r--r--third_party/mojo/src/mojo/edk/test/BUILD.gn2
-rw-r--r--third_party/mojo/src/mojo/public/VERSION2
-rw-r--r--third_party/mojo/src/mojo/public/cpp/application/BUILD.gn2
-rw-r--r--third_party/mojo/src/mojo/public/cpp/application/application_connection.h9
-rw-r--r--third_party/mojo/src/mojo/public/cpp/application/application_impl.h1
-rw-r--r--third_party/mojo/src/mojo/public/cpp/application/lib/application_impl.cc4
-rw-r--r--third_party/mojo/src/mojo/public/cpp/application/lib/service_provider_impl.cc26
-rw-r--r--third_party/mojo/src/mojo/public/cpp/application/lib/weak_service_provider.cc36
-rw-r--r--third_party/mojo/src/mojo/public/cpp/application/lib/weak_service_provider.h41
-rw-r--r--third_party/mojo/src/mojo/public/cpp/application/service_provider_impl.h25
-rw-r--r--third_party/mojo/src/mojo/public/cpp/bindings/array.h50
-rw-r--r--third_party/mojo/src/mojo/public/cpp/bindings/binding.h60
-rw-r--r--third_party/mojo/src/mojo/public/cpp/bindings/interface_request.h5
-rw-r--r--third_party/mojo/src/mojo/public/dart/README16
-rw-r--r--third_party/mojo/src/mojo/public/dart/bindings.dart1
-rw-r--r--third_party/mojo/src/mojo/public/dart/core.dart1
-rw-r--r--third_party/mojo/src/mojo/public/dart/src/drain_data.dart68
-rw-r--r--third_party/mojo/src/mojo/public/dart/src/event_stream.dart6
-rw-r--r--third_party/mojo/src/mojo/public/dart/src/types.dart9
-rw-r--r--third_party/mojo/src/mojo/public/go/system/c_allocators.c12
-rw-r--r--third_party/mojo/src/mojo/public/go/system/c_allocators.h7
-rw-r--r--third_party/mojo/src/mojo/public/go/system/data_pipe.go79
-rw-r--r--third_party/mojo/src/mojo/public/interfaces/application/application.mojom38
-rw-r--r--third_party/mojo/src/mojo/public/interfaces/application/service_provider.mojom13
-rw-r--r--third_party/mojo/src/mojo/public/interfaces/application/shell.mojom31
-rw-r--r--third_party/mojo/src/mojo/public/mojo.gni3
-rw-r--r--third_party/mojo/src/mojo/public/tools/bindings/generators/dart_templates/interface_definition.tmpl31
-rw-r--r--third_party/mojo/src/mojo/public/tools/bindings/generators/mojom_dart_generator.py4
67 files changed, 784 insertions, 398 deletions
diff --git a/content/browser/frame_host/render_frame_host_impl.cc b/content/browser/frame_host/render_frame_host_impl.cc
index faaca99..d417c3c 100644
--- a/content/browser/frame_host/render_frame_host_impl.cc
+++ b/content/browser/frame_host/render_frame_host_impl.cc
@@ -1545,11 +1545,14 @@ void RenderFrameHostImpl::SetUpMojoIfNeeded() {
RegisterMojoServices();
RenderFrameSetupPtr setup;
GetProcess()->GetServiceRegistry()->ConnectToRemoteService(&setup);
- mojo::ServiceProviderPtr service_provider;
- setup->GetServiceProviderForFrame(routing_id_,
- mojo::GetProxy(&service_provider));
- service_registry_->BindRemoteServiceProvider(
- service_provider.PassMessagePipe());
+
+ mojo::ServiceProviderPtr exposed_services;
+ service_registry_->Bind(GetProxy(&exposed_services));
+
+ mojo::ServiceProviderPtr services;
+ setup->ExchangeServiceProviders(routing_id_, GetProxy(&services),
+ exposed_services.Pass());
+ service_registry_->BindRemoteServiceProvider(services.Pass());
#if defined(OS_ANDROID)
service_registry_android_.reset(
diff --git a/content/browser/mojo/mojo_application_host.cc b/content/browser/mojo/mojo_application_host.cc
index e5a9b0b..883945f 100644
--- a/content/browser/mojo/mojo_application_host.cc
+++ b/content/browser/mojo/mojo_application_host.cc
@@ -21,9 +21,34 @@ base::PlatformFile PlatformFileFromScopedPlatformHandle(
#endif
}
+class ApplicationSetupImpl : public ApplicationSetup {
+ public:
+ ApplicationSetupImpl(ServiceRegistryImpl* service_registry,
+ mojo::InterfaceRequest<ApplicationSetup> request)
+ : binding_(this, request.Pass()),
+ service_registry_(service_registry) {
+ }
+
+ ~ApplicationSetupImpl() override {
+ }
+
+ private:
+ // ApplicationSetup implementation.
+ void ExchangeServiceProviders(
+ mojo::InterfaceRequest<mojo::ServiceProvider> services,
+ mojo::ServiceProviderPtr exposed_services) override {
+ service_registry_->Bind(services.Pass());
+ service_registry_->BindRemoteServiceProvider(exposed_services.Pass());
+ }
+
+ mojo::Binding<ApplicationSetup> binding_;
+ ServiceRegistryImpl* service_registry_;
+};
+
} // namespace
-MojoApplicationHost::MojoApplicationHost() : did_activate_(false) {
+MojoApplicationHost::MojoApplicationHost()
+ : did_activate_(false) {
#if defined(OS_ANDROID)
service_registry_android_.reset(
new ServiceRegistryAndroid(&service_registry_));
@@ -47,7 +72,9 @@ bool MojoApplicationHost::Init() {
// Forward this to the client once we know its process handle.
client_handle_ = channel_pair.PassClientHandle();
- service_registry_.BindRemoteServiceProvider(message_pipe.Pass());
+ application_setup_.reset(new ApplicationSetupImpl(
+ &service_registry_,
+ mojo::MakeRequest<ApplicationSetup>(message_pipe.Pass())));
return true;
}
diff --git a/content/browser/mojo/mojo_application_host.h b/content/browser/mojo/mojo_application_host.h
index 53e150a..fc0693a 100644
--- a/content/browser/mojo/mojo_application_host.h
+++ b/content/browser/mojo/mojo_application_host.h
@@ -7,6 +7,7 @@
#include "base/memory/scoped_ptr.h"
#include "base/process/process_handle.h"
+#include "content/common/application_setup.mojom.h"
#include "content/common/mojo/service_registry_impl.h"
#include "third_party/mojo/src/mojo/edk/embedder/channel_init.h"
#include "third_party/mojo/src/mojo/edk/embedder/scoped_platform_handle.h"
@@ -29,7 +30,7 @@ namespace content {
class CONTENT_EXPORT MojoApplicationHost {
public:
MojoApplicationHost();
- virtual ~MojoApplicationHost();
+ ~MojoApplicationHost();
// Two-phase initialization:
// 1- Init makes service_registry() available synchronously.
@@ -53,6 +54,7 @@ class CONTENT_EXPORT MojoApplicationHost {
bool did_activate_;
+ scoped_ptr<ApplicationSetup> application_setup_;
ServiceRegistryImpl service_registry_;
#if defined(OS_ANDROID)
diff --git a/content/child/BUILD.gn b/content/child/BUILD.gn
index c8478a9..9a1f71f 100644
--- a/content/child/BUILD.gn
+++ b/content/child/BUILD.gn
@@ -23,6 +23,7 @@ source_set("child") {
deps = [
"//base",
"//components/tracing",
+ "//content/common:mojo_bindings",
"//mojo/common",
"//mojo/environment:chromium",
"//skia",
diff --git a/content/child/mojo/mojo_application.cc b/content/child/mojo/mojo_application.cc
index bc1426f..34fc314 100644
--- a/content/child/mojo/mojo_application.cc
+++ b/content/child/mojo/mojo_application.cc
@@ -5,8 +5,10 @@
#include "content/child/mojo/mojo_application.h"
#include "content/child/child_process.h"
+#include "content/common/application_setup.mojom.h"
#include "content/common/mojo/mojo_messages.h"
#include "ipc/ipc_message.h"
+#include "third_party/mojo/src/mojo/public/cpp/bindings/interface_ptr.h"
namespace content {
@@ -36,7 +38,16 @@ void MojoApplication::OnActivate(
channel_init_.Init(handle,
ChildProcess::current()->io_message_loop_proxy());
DCHECK(message_pipe.is_valid());
- service_registry_.BindRemoteServiceProvider(message_pipe.Pass());
+
+ ApplicationSetupPtr application_setup;
+ application_setup.Bind(message_pipe.Pass());
+
+ mojo::ServiceProviderPtr services;
+ mojo::ServiceProviderPtr exposed_services;
+ service_registry_.Bind(GetProxy(&exposed_services));
+ application_setup->ExchangeServiceProviders(GetProxy(&services),
+ exposed_services.Pass());
+ service_registry_.BindRemoteServiceProvider(services.Pass());
}
} // namespace content
diff --git a/content/common/BUILD.gn b/content/common/BUILD.gn
index c80a5d5..27aa6d3 100644
--- a/content/common/BUILD.gn
+++ b/content/common/BUILD.gn
@@ -406,6 +406,7 @@ source_set("common") {
mojom("mojo_bindings") {
sources = [
+ "application_setup.mojom",
"geolocation_service.mojom",
"permission_service.mojom",
"render_frame_setup.mojom",
diff --git a/content/common/application_setup.mojom b/content/common/application_setup.mojom
new file mode 100644
index 0000000..4e094a0
--- /dev/null
+++ b/content/common/application_setup.mojom
@@ -0,0 +1,12 @@
+// Copyright 2015 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.
+
+module content;
+
+import "third_party/mojo/src/mojo/public/interfaces/application/service_provider.mojom";
+
+interface ApplicationSetup {
+ ExchangeServiceProviders(mojo.ServiceProvider& services,
+ mojo.ServiceProvider exposed_services);
+};
diff --git a/content/common/mojo/service_registry_impl.cc b/content/common/mojo/service_registry_impl.cc
index 348d1d45..eec7640 100644
--- a/content/common/mojo/service_registry_impl.cc
+++ b/content/common/mojo/service_registry_impl.cc
@@ -9,12 +9,7 @@
namespace content {
ServiceRegistryImpl::ServiceRegistryImpl()
- : bound_(false), weak_factory_(this) {
-}
-
-ServiceRegistryImpl::ServiceRegistryImpl(mojo::ScopedMessagePipeHandle handle)
- : bound_(false), weak_factory_(this) {
- BindRemoteServiceProvider(handle.Pass());
+ : binding_(this), weak_factory_(this) {
}
ServiceRegistryImpl::~ServiceRegistryImpl() {
@@ -24,23 +19,23 @@ ServiceRegistryImpl::~ServiceRegistryImpl() {
}
}
+void ServiceRegistryImpl::Bind(
+ mojo::InterfaceRequest<mojo::ServiceProvider> request) {
+ binding_.Bind(request.Pass());
+}
+
void ServiceRegistryImpl::BindRemoteServiceProvider(
- mojo::ScopedMessagePipeHandle handle) {
- CHECK(!bound_);
- bound_ = true;
- mojo::WeakBindToPipe(this, handle.Pass());
+ mojo::ServiceProviderPtr service_provider) {
+ CHECK(!remote_provider_);
+ remote_provider_ = service_provider.Pass();
while (!pending_connects_.empty()) {
- client()->ConnectToService(
+ remote_provider_->ConnectToService(
mojo::String::From(pending_connects_.front().first),
mojo::ScopedMessagePipeHandle(pending_connects_.front().second));
pending_connects_.pop();
}
}
-void ServiceRegistryImpl::OnConnectionError() {
- // TODO(sammc): Support reporting this to our owner.
-}
-
void ServiceRegistryImpl::AddService(
const std::string& service_name,
const base::Callback<void(mojo::ScopedMessagePipeHandle)> service_factory) {
@@ -54,12 +49,13 @@ void ServiceRegistryImpl::RemoveService(const std::string& service_name) {
void ServiceRegistryImpl::ConnectToRemoteService(
const base::StringPiece& service_name,
mojo::ScopedMessagePipeHandle handle) {
- if (!bound_) {
+ if (!remote_provider_) {
pending_connects_.push(
std::make_pair(service_name.as_string(), handle.release()));
return;
}
- client()->ConnectToService(mojo::String::From(service_name), handle.Pass());
+ remote_provider_->ConnectToService(mojo::String::From(service_name),
+ handle.Pass());
}
base::WeakPtr<ServiceRegistry> ServiceRegistryImpl::GetWeakPtr() {
diff --git a/content/common/mojo/service_registry_impl.h b/content/common/mojo/service_registry_impl.h
index 16426c7..13aba81 100644
--- a/content/common/mojo/service_registry_impl.h
+++ b/content/common/mojo/service_registry_impl.h
@@ -14,7 +14,7 @@
#include "base/compiler_specific.h"
#include "base/memory/weak_ptr.h"
#include "content/public/common/service_registry.h"
-#include "third_party/mojo/src/mojo/public/cpp/bindings/interface_impl.h"
+#include "third_party/mojo/src/mojo/public/cpp/bindings/binding.h"
#include "third_party/mojo/src/mojo/public/cpp/system/core.h"
#include "third_party/mojo/src/mojo/public/interfaces/application/service_provider.mojom.h"
@@ -22,17 +22,19 @@ namespace content {
class CONTENT_EXPORT ServiceRegistryImpl
: public ServiceRegistry,
- public NON_EXPORTED_BASE(mojo::InterfaceImpl<mojo::ServiceProvider>) {
+ public NON_EXPORTED_BASE(mojo::ServiceProvider) {
public:
ServiceRegistryImpl();
- explicit ServiceRegistryImpl(mojo::ScopedMessagePipeHandle handle);
~ServiceRegistryImpl() override;
+ // Binds this ServiceProvider implementation to a message pipe endpoint.
+ void Bind(mojo::InterfaceRequest<mojo::ServiceProvider> request);
+
// Binds to a remote ServiceProvider. This will expose added services to the
// remote ServiceProvider with the corresponding handle and enable
// ConnectToRemoteService to provide access to services exposed by the remote
// ServiceProvider.
- void BindRemoteServiceProvider(mojo::ScopedMessagePipeHandle handle);
+ void BindRemoteServiceProvider(mojo::ServiceProviderPtr service_provider);
// ServiceRegistry overrides.
void AddService(const std::string& service_name,
@@ -45,16 +47,17 @@ class CONTENT_EXPORT ServiceRegistryImpl
base::WeakPtr<ServiceRegistry> GetWeakPtr();
private:
- // mojo::InterfaceImpl<mojo::ServiceProvider> overrides.
+ // mojo::ServiceProvider overrides.
void ConnectToService(const mojo::String& name,
mojo::ScopedMessagePipeHandle client_handle) override;
- void OnConnectionError() override;
+
+ mojo::Binding<mojo::ServiceProvider> binding_;
+ mojo::ServiceProviderPtr remote_provider_;
std::map<std::string, base::Callback<void(mojo::ScopedMessagePipeHandle)> >
service_factories_;
std::queue<std::pair<std::string, mojo::MessagePipeHandle> >
pending_connects_;
- bool bound_;
base::WeakPtrFactory<ServiceRegistry> weak_factory_;
};
diff --git a/content/common/render_frame_setup.mojom b/content/common/render_frame_setup.mojom
index 22f01ea..fcf8936 100644
--- a/content/common/render_frame_setup.mojom
+++ b/content/common/render_frame_setup.mojom
@@ -7,6 +7,7 @@ module content;
import "third_party/mojo/src/mojo/public/interfaces/application/service_provider.mojom";
interface RenderFrameSetup {
- GetServiceProviderForFrame(int32 frame_routing_id,
- mojo.ServiceProvider& service_provider);
+ ExchangeServiceProviders(int32 frame_routing_id,
+ mojo.ServiceProvider& services,
+ mojo.ServiceProvider exposed_services);
};
diff --git a/content/content_common_mojo_bindings.gyp b/content/content_common_mojo_bindings.gyp
index f166301..40895d0 100644
--- a/content/content_common_mojo_bindings.gyp
+++ b/content/content_common_mojo_bindings.gyp
@@ -11,6 +11,7 @@
'variables': {
'mojom_files': [
# NOTE: Sources duplicated in //content/common/BUILD.gn:mojo_bindings.
+ 'common/application_setup.mojom',
'common/geolocation_service.mojom',
'common/permission_service.mojom',
'common/render_frame_setup.mojom',
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc
index ac991b4..6334f57 100644
--- a/content/renderer/render_frame_impl.cc
+++ b/content/renderer/render_frame_impl.cc
@@ -1177,8 +1177,10 @@ void RenderFrameImpl::NavigateToSwappedOutURL() {
}
void RenderFrameImpl::BindServiceRegistry(
- mojo::ScopedMessagePipeHandle service_provider_handle) {
- service_registry_.BindRemoteServiceProvider(service_provider_handle.Pass());
+ mojo::InterfaceRequest<mojo::ServiceProvider> services,
+ mojo::ServiceProviderPtr exposed_services) {
+ service_registry_.Bind(services.Pass());
+ service_registry_.BindRemoteServiceProvider(exposed_services.Pass());
}
ManifestManager* RenderFrameImpl::manifest_manager() {
diff --git a/content/renderer/render_frame_impl.h b/content/renderer/render_frame_impl.h
index 6fd6820..ffe14f5 100644
--- a/content/renderer/render_frame_impl.h
+++ b/content/renderer/render_frame_impl.h
@@ -534,10 +534,10 @@ class CONTENT_EXPORT RenderFrameImpl
// TODO(nasko): Remove this method once swapped out state is no longer used.
void NavigateToSwappedOutURL();
- // Binds this render frame's service registry to a handle to the remote
- // service registry.
+ // Binds this render frame's service registry.
void BindServiceRegistry(
- mojo::ScopedMessagePipeHandle service_provider_handle);
+ mojo::InterfaceRequest<mojo::ServiceProvider> services,
+ mojo::ServiceProviderPtr exposed_services);
ManifestManager* manifest_manager();
diff --git a/content/renderer/render_thread_impl.cc b/content/renderer/render_thread_impl.cc
index ef6dae7..07598f1 100644
--- a/content/renderer/render_thread_impl.cc
+++ b/content/renderer/render_thread_impl.cc
@@ -313,9 +313,11 @@ class RenderFrameSetupImpl : public mojo::InterfaceImpl<RenderFrameSetup> {
: routing_id_highmark_(-1) {
}
- void GetServiceProviderForFrame(
+ void ExchangeServiceProviders(
int32_t frame_routing_id,
- mojo::InterfaceRequest<mojo::ServiceProvider> request) override {
+ mojo::InterfaceRequest<mojo::ServiceProvider> services,
+ mojo::ServiceProviderPtr exposed_services)
+ override {
// TODO(morrita): This is for investigating http://crbug.com/415059 and
// should be removed once it is fixed.
CHECK_LT(routing_id_highmark_, frame_routing_id);
@@ -327,11 +329,11 @@ class RenderFrameSetupImpl : public mojo::InterfaceImpl<RenderFrameSetup> {
// triggers creation of the RenderFrame we want.
if (!frame) {
RenderThreadImpl::current()->RegisterPendingRenderFrameConnect(
- frame_routing_id, request.PassMessagePipe());
+ frame_routing_id, services.Pass(), exposed_services.Pass());
return;
}
- frame->BindServiceRegistry(request.PassMessagePipe());
+ frame->BindServiceRegistry(services.Pass(), exposed_services.Pass());
}
private:
@@ -656,12 +658,6 @@ void RenderThreadImpl::Init() {
}
RenderThreadImpl::~RenderThreadImpl() {
- for (std::map<int, mojo::MessagePipeHandle>::iterator it =
- pending_render_frame_connects_.begin();
- it != pending_render_frame_connects_.end();
- ++it) {
- mojo::CloseRaw(it->second);
- }
}
void RenderThreadImpl::Shutdown() {
@@ -859,7 +855,7 @@ scoped_refptr<base::MessageLoopProxy>
void RenderThreadImpl::AddRoute(int32 routing_id, IPC::Listener* listener) {
ChildThread::GetRouter()->AddRoute(routing_id, listener);
- std::map<int, mojo::MessagePipeHandle>::iterator it =
+ PendingRenderFrameConnectMap::iterator it =
pending_render_frame_connects_.find(routing_id);
if (it == pending_render_frame_connects_.end())
return;
@@ -868,9 +864,14 @@ void RenderThreadImpl::AddRoute(int32 routing_id, IPC::Listener* listener) {
if (!frame)
return;
- mojo::ScopedMessagePipeHandle handle(it->second);
+ scoped_refptr<PendingRenderFrameConnect> connection(it->second);
+ mojo::InterfaceRequest<mojo::ServiceProvider> services(
+ connection->services.Pass());
+ mojo::ServiceProviderPtr exposed_services(
+ connection->exposed_services.Pass());
pending_render_frame_connects_.erase(it);
- frame->BindServiceRegistry(handle.Pass());
+
+ frame->BindServiceRegistry(services.Pass(), exposed_services.Pass());
}
void RenderThreadImpl::RemoveRoute(int32 routing_id) {
@@ -896,10 +897,14 @@ void RenderThreadImpl::RemoveEmbeddedWorkerRoute(int32 routing_id) {
void RenderThreadImpl::RegisterPendingRenderFrameConnect(
int routing_id,
- mojo::ScopedMessagePipeHandle handle) {
- std::pair<std::map<int, mojo::MessagePipeHandle>::iterator, bool> result =
- pending_render_frame_connects_.insert(
- std::make_pair(routing_id, handle.release()));
+ mojo::InterfaceRequest<mojo::ServiceProvider> services,
+ mojo::ServiceProviderPtr exposed_services) {
+ std::pair<PendingRenderFrameConnectMap::iterator, bool> result =
+ pending_render_frame_connects_.insert(std::make_pair(
+ routing_id,
+ make_scoped_refptr(new PendingRenderFrameConnect(
+ services.Pass(),
+ exposed_services.Pass()))));
CHECK(result.second) << "Inserting a duplicate item.";
}
@@ -1781,4 +1786,14 @@ void RenderThreadImpl::WidgetRestored() {
ScheduleIdleHandler(kLongIdleHandlerDelayMs);
}
+RenderThreadImpl::PendingRenderFrameConnect::PendingRenderFrameConnect(
+ mojo::InterfaceRequest<mojo::ServiceProvider> services,
+ mojo::ServiceProviderPtr exposed_services)
+ : services(services.Pass()),
+ exposed_services(exposed_services.Pass()) {
+}
+
+RenderThreadImpl::PendingRenderFrameConnect::~PendingRenderFrameConnect() {
+}
+
} // namespace content
diff --git a/content/renderer/render_thread_impl.h b/content/renderer/render_thread_impl.h
index e6f4b88..483d5a3 100644
--- a/content/renderer/render_thread_impl.h
+++ b/content/renderer/render_thread_impl.h
@@ -11,6 +11,7 @@
#include "base/cancelable_callback.h"
#include "base/memory/memory_pressure_listener.h"
+#include "base/memory/ref_counted.h"
#include "base/metrics/user_metrics_action.h"
#include "base/observer_list.h"
#include "base/strings/string16.h"
@@ -404,8 +405,10 @@ class CONTENT_EXPORT RenderThreadImpl
void AddEmbeddedWorkerRoute(int32 routing_id, IPC::Listener* listener);
void RemoveEmbeddedWorkerRoute(int32 routing_id);
- void RegisterPendingRenderFrameConnect(int routing_id,
- mojo::ScopedMessagePipeHandle handle);
+ void RegisterPendingRenderFrameConnect(
+ int routing_id,
+ mojo::InterfaceRequest<mojo::ServiceProvider> services,
+ mojo::ServiceProviderPtr exposed_services);
protected:
virtual void SetResourceDispatchTaskQueue(
@@ -597,7 +600,24 @@ class CONTENT_EXPORT RenderThreadImpl
bool is_elastic_overscroll_enabled_;
unsigned use_image_texture_target_;
- std::map<int, mojo::MessagePipeHandle> pending_render_frame_connects_;
+ struct PendingRenderFrameConnect
+ : public base::RefCounted<PendingRenderFrameConnect> {
+ PendingRenderFrameConnect(
+ mojo::InterfaceRequest<mojo::ServiceProvider> services,
+ mojo::ServiceProviderPtr exposed_services);
+
+ mojo::InterfaceRequest<mojo::ServiceProvider> services;
+ mojo::ServiceProviderPtr exposed_services;
+
+ private:
+ friend class base::RefCounted<PendingRenderFrameConnect>;
+
+ ~PendingRenderFrameConnect();
+ };
+
+ typedef std::map<int, scoped_refptr<PendingRenderFrameConnect>>
+ PendingRenderFrameConnectMap;
+ PendingRenderFrameConnectMap pending_render_frame_connects_;
DISALLOW_COPY_AND_ASSIGN(RenderThreadImpl);
};
diff --git a/content/shell/browser/shell_mojo_test_utils_android.cc b/content/shell/browser/shell_mojo_test_utils_android.cc
index eeae444..966aa5b 100644
--- a/content/shell/browser/shell_mojo_test_utils_android.cc
+++ b/content/shell/browser/shell_mojo_test_utils_android.cc
@@ -44,11 +44,13 @@ static jobject CreateServiceRegistryPair(JNIEnv* env,
content::ServiceRegistryImpl* registry_b = new ServiceRegistryImpl();
test_environment->registries.push_back(registry_b);
- mojo::ScopedMessagePipeHandle handle_a;
- mojo::ScopedMessagePipeHandle handle_b;
- mojo::CreateMessagePipe(NULL, &handle_a, &handle_b);
- registry_a->BindRemoteServiceProvider(handle_a.Pass());
- registry_b->BindRemoteServiceProvider(handle_b.Pass());
+ mojo::ServiceProviderPtr exposed_services_a;
+ registry_a->Bind(GetProxy(&exposed_services_a));
+ registry_b->BindRemoteServiceProvider(exposed_services_a.Pass());
+
+ mojo::ServiceProviderPtr exposed_services_b;
+ registry_b->Bind(GetProxy(&exposed_services_b));
+ registry_a->BindRemoteServiceProvider(exposed_services_b.Pass());
content::ServiceRegistryAndroid* wrapper_a =
new ServiceRegistryAndroid(registry_a);
diff --git a/mojo/services/html_viewer/html_document.cc b/mojo/services/html_viewer/html_document.cc
index eca0d00..3b13a45 100644
--- a/mojo/services/html_viewer/html_document.cc
+++ b/mojo/services/html_viewer/html_document.cc
@@ -111,7 +111,7 @@ HTMLDocument::HTMLDocument(
web_media_player_factory_(web_media_player_factory) {
exported_services_.AddService(this);
exported_services_.AddService(&view_manager_client_factory_);
- WeakBindToPipe(&exported_services_, services.PassMessagePipe());
+ exported_services_.Bind(services.Pass());
Load(response_.Pass());
}
@@ -126,10 +126,10 @@ HTMLDocument::~HTMLDocument() {
void HTMLDocument::OnEmbed(
View* root,
- mojo::ServiceProviderImpl* embedee_service_provider_impl,
- scoped_ptr<mojo::ServiceProvider> embedder_service_provider) {
+ mojo::InterfaceRequest<mojo::ServiceProvider> services,
+ mojo::ServiceProviderPtr exposed_services) {
root_ = root;
- embedder_service_provider_ = embedder_service_provider.Pass();
+ embedder_service_provider_ = exposed_services.Pass();
navigator_host_.set_service_provider(embedder_service_provider_.get());
blink::WebSize root_size(root_->bounds().width, root_->bounds().height);
diff --git a/mojo/services/html_viewer/html_document.h b/mojo/services/html_viewer/html_document.h
index 40515b6..3d1be63 100644
--- a/mojo/services/html_viewer/html_document.h
+++ b/mojo/services/html_viewer/html_document.h
@@ -110,10 +110,9 @@ class HTMLDocument : public blink::WebViewClient,
virtual blink::WebEncryptedMediaClient* encryptedMediaClient();
// ViewManagerDelegate methods:
- void OnEmbed(
- mojo::View* root,
- mojo::ServiceProviderImpl* embedee_service_provider_impl,
- scoped_ptr<mojo::ServiceProvider> embedder_service_provider) override;
+ void OnEmbed(mojo::View* root,
+ mojo::InterfaceRequest<mojo::ServiceProvider> services,
+ mojo::ServiceProviderPtr exposed_services) override;
void OnViewManagerDisconnected(mojo::ViewManager* view_manager) override;
// ViewObserver methods:
@@ -131,7 +130,7 @@ class HTMLDocument : public blink::WebViewClient,
mojo::URLResponsePtr response_;
mojo::ServiceProviderImpl exported_services_;
- scoped_ptr<mojo::ServiceProvider> embedder_service_provider_;
+ mojo::ServiceProviderPtr embedder_service_provider_;
mojo::Shell* shell_;
mojo::LazyInterfacePtr<mojo::NavigatorHost> navigator_host_;
blink::WebView* web_view_;
diff --git a/mojo/services/html_viewer/html_viewer.cc b/mojo/services/html_viewer/html_viewer.cc
index 55d4c39..06df351 100644
--- a/mojo/services/html_viewer/html_viewer.cc
+++ b/mojo/services/html_viewer/html_viewer.cc
@@ -102,6 +102,8 @@ class HTMLViewerApplication : public mojo::Application {
}
}
+ void RequestQuit() override {}
+
private:
void OnResponseReceived(URLLoaderPtr loader,
InterfaceRequest<ServiceProvider> services,
diff --git a/mojo/services/public/js/application.js b/mojo/services/public/js/application.js
index a50f84c..ed41628 100644
--- a/mojo/services/public/js/application.js
+++ b/mojo/services/public/js/application.js
@@ -3,11 +3,13 @@
// found in the LICENSE file.
define("mojo/services/public/js/application", [
+ "mojo/public/js/bindings",
+ "mojo/public/js/threading",
"mojo/services/public/js/service_provider",
"mojo/services/public/js/shell",
- "mojo/public/js/threading",
-], function(serviceProvider, shell, threading) {
+], function(bindings, threading, serviceProvider, shell) {
+ const ProxyBindings = bindings.ProxyBindings;
const ServiceProvider = serviceProvider.ServiceProvider;
const Shell = shell.Shell;
@@ -26,18 +28,27 @@ define("mojo/services/public/js/application", [
initialize(args) {
}
- doAcceptConnection(url, serviceProviderProxy, exposedServiceProviderProxy) {
- var serviceProvider = new ServiceProvider(serviceProviderProxy);
+ // The mojom signature of this function is:
+ // AcceptConnection(string requestor_url,
+ // ServiceProvider&? services,
+ // ServiceProvider? exposed_services);
+ //
+ // We want to bind |services| to our js implementation of ServiceProvider
+ // and store |exposed_services| so we can request services of the connecting
+ // application.
+ doAcceptConnection(requestorUrl, servicesRequest, exposedServicesProxy) {
+ // Construct a new js ServiceProvider that can make outgoing calls on
+ // exposedServicesProxy.
+ var serviceProvider = new ServiceProvider(exposedServicesProxy);
this.serviceProviders.push(serviceProvider);
- var exposedServiceProvider =
- new ServiceProvider(exposedServiceProviderProxy);
- this.exposedServiceProviders.push(exposedServiceProvider);
+ // Then associate incoming calls with the serviceProvider.
+ ProxyBindings(servicesRequest).setLocalDelegate(serviceProvider);
- this.acceptConnection(url, serviceProvider, exposedServiceProvider);
+ this.acceptConnection(requestorUrl, serviceProvider);
}
- acceptConnection(url, serviceProvider, exposedServiceProvider) {
+ acceptConnection(requestorUrl, serviceProvider) {
}
quit() {
diff --git a/mojo/services/public/js/service_provider.js b/mojo/services/public/js/service_provider.js
index 1f8fab2c..9566583 100644
--- a/mojo/services/public/js/service_provider.js
+++ b/mojo/services/public/js/service_provider.js
@@ -19,10 +19,7 @@ define("mojo/services/public/js/service_provider", [
class ServiceProvider {
constructor(service) {
- if (!(service instanceof ServiceProviderInterface.proxyClass))
- throw new Error("service must be a ServiceProvider proxy");
this.proxy = service;
- ProxyBindings(this.proxy).setLocalDelegate(this);
this.providers_ = new Map(); // serviceName => see provideService() below
this.pendingRequests_ = new Map(); // serviceName => serviceHandle
}
diff --git a/mojo/services/public/js/shell.js b/mojo/services/public/js/shell.js
index 8d90dcb..9fc8552 100644
--- a/mojo/services/public/js/shell.js
+++ b/mojo/services/public/js/shell.js
@@ -33,8 +33,10 @@ define("mojo/services/public/js/shell", [
if (application)
return application;
- this.proxy.connectToApplication(url, function(sp) {
- application = new ServiceProvider(sp);
+ this.proxy.connectToApplication(url, function(services) {
+ application = new ServiceProvider(services);
+ }, function() {
+ return application;
});
this.applications_.set(url, application);
return application;
diff --git a/mojo/services/view_manager/public/cpp/lib/view.cc b/mojo/services/view_manager/public/cpp/lib/view.cc
index 5f7d22a..929eec4 100644
--- a/mojo/services/view_manager/public/cpp/lib/view.cc
+++ b/mojo/services/view_manager/public/cpp/lib/view.cc
@@ -359,19 +359,11 @@ void View::Embed(const String& url) {
static_cast<ViewManagerClientImpl*>(manager_)->Embed(url, id_);
}
-scoped_ptr<ServiceProvider>
- View::Embed(const String& url,
- scoped_ptr<ServiceProviderImpl> exported_services) {
- scoped_ptr<ServiceProvider> imported_services;
- // BindToProxy() takes ownership of |exported_services|.
- ServiceProviderImpl* registry = exported_services.release();
- ServiceProviderPtr sp;
- if (registry) {
- BindToProxy(registry, &sp);
- imported_services.reset(registry->CreateRemoteServiceProvider());
- }
- static_cast<ViewManagerClientImpl*>(manager_)->Embed(url, id_, sp.Pass());
- return imported_services.Pass();
+void View::Embed(const String& url,
+ InterfaceRequest<ServiceProvider> services,
+ ServiceProviderPtr exposed_services) {
+ static_cast<ViewManagerClientImpl*>(manager_)
+ ->Embed(url, id_, services.Pass(), exposed_services.Pass());
}
////////////////////////////////////////////////////////////////////////////////
diff --git a/mojo/services/view_manager/public/cpp/lib/view_manager_client_impl.cc b/mojo/services/view_manager/public/cpp/lib/view_manager_client_impl.cc
index ef043e0..78daeb3 100644
--- a/mojo/services/view_manager/public/cpp/lib/view_manager_client_impl.cc
+++ b/mojo/services/view_manager/public/cpp/lib/view_manager_client_impl.cc
@@ -195,19 +195,16 @@ void ViewManagerClientImpl::SetProperty(
}
void ViewManagerClientImpl::Embed(const String& url, Id view_id) {
- ServiceProviderPtr sp;
- BindToProxy(new ServiceProviderImpl, &sp);
- Embed(url, view_id, sp.Pass());
+ Embed(url, view_id, nullptr, nullptr);
}
-void ViewManagerClientImpl::Embed(
- const String& url,
- Id view_id,
- ServiceProviderPtr service_provider) {
+void ViewManagerClientImpl::Embed(const String& url,
+ Id view_id,
+ InterfaceRequest<ServiceProvider> services,
+ ServiceProviderPtr exposed_services) {
DCHECK(connected_);
- service_->Embed(url, view_id,
- MakeRequest<ServiceProvider>(service_provider.PassMessagePipe()),
- ActionCompletedCallback());
+ service_->Embed(url, view_id, services.Pass(), exposed_services.Pass(),
+ ActionCompletedCallback());
}
void ViewManagerClientImpl::AddView(View* view) {
@@ -261,7 +258,8 @@ void ViewManagerClientImpl::OnEmbed(
ConnectionSpecificId connection_id,
const String& creator_url,
ViewDataPtr root_data,
- InterfaceRequest<ServiceProvider> parent_services,
+ InterfaceRequest<ServiceProvider> services,
+ ServiceProviderPtr exposed_services,
ScopedMessagePipeHandle window_manager_pipe) {
DCHECK(!connected_);
connected_ = true;
@@ -272,14 +270,6 @@ void ViewManagerClientImpl::OnEmbed(
root_ = AddViewToViewManager(this, nullptr, root_data);
root_->AddObserver(new RootObserver(root_));
- ServiceProviderImpl* exported_services = nullptr;
- scoped_ptr<ServiceProvider> remote;
-
- // BindToRequest() binds the lifetime of |exported_services| to the pipe.
- exported_services = new ServiceProviderImpl;
- BindToRequest(exported_services, &parent_services);
- remote.reset(exported_services->CreateRemoteServiceProvider());
-
window_manager_.Bind(window_manager_pipe.Pass());
window_manager_.set_client(this);
// base::Unretained() is safe here as |window_manager_| is bound to our
@@ -287,7 +277,8 @@ void ViewManagerClientImpl::OnEmbed(
window_manager_->GetFocusedAndActiveViews(
base::Bind(&ViewManagerClientImpl::OnGotFocusedAndActiveViews,
base::Unretained(this)));
- delegate_->OnEmbed(root_, exported_services, remote.Pass());
+
+ delegate_->OnEmbed(root_, services.Pass(), exposed_services.Pass());
}
void ViewManagerClientImpl::OnEmbeddedAppDisconnected(Id view_id) {
diff --git a/mojo/services/view_manager/public/cpp/lib/view_manager_client_impl.h b/mojo/services/view_manager/public/cpp/lib/view_manager_client_impl.h
index cbc0086..c8ae5c4 100644
--- a/mojo/services/view_manager/public/cpp/lib/view_manager_client_impl.h
+++ b/mojo/services/view_manager/public/cpp/lib/view_manager_client_impl.h
@@ -63,7 +63,8 @@ class ViewManagerClientImpl : public ViewManager,
void Embed(const String& url, Id view_id);
void Embed(const String& url,
Id view_id,
- ServiceProviderPtr service_provider);
+ InterfaceRequest<ServiceProvider> services,
+ ServiceProviderPtr exposed_services);
void set_change_acked_callback(const base::Callback<void(void)>& callback) {
change_acked_callback_ = callback;
@@ -95,7 +96,8 @@ class ViewManagerClientImpl : public ViewManager,
void OnEmbed(ConnectionSpecificId connection_id,
const String& creator_url,
ViewDataPtr root,
- InterfaceRequest<ServiceProvider> parent_services,
+ InterfaceRequest<ServiceProvider> services,
+ ServiceProviderPtr exposed_services,
ScopedMessagePipeHandle window_manager_pipe) override;
void OnEmbeddedAppDisconnected(Id view_id) override;
void OnViewBoundsChanged(Id view_id,
diff --git a/mojo/services/view_manager/public/cpp/lib/view_manager_context.cc b/mojo/services/view_manager/public/cpp/lib/view_manager_context.cc
index 45752f5..a47f59a 100644
--- a/mojo/services/view_manager/public/cpp/lib/view_manager_context.cc
+++ b/mojo/services/view_manager/public/cpp/lib/view_manager_context.cc
@@ -31,23 +31,13 @@ ViewManagerContext::ViewManagerContext(ApplicationImpl* application_impl)
ViewManagerContext::~ViewManagerContext() {}
void ViewManagerContext::Embed(const String& url) {
- scoped_ptr<ServiceProviderImpl> spi(new ServiceProviderImpl);
- Embed(url, spi.Pass());
+ Embed(url, nullptr, nullptr);
}
-scoped_ptr<ServiceProvider> ViewManagerContext::Embed(
- const String& url,
- scoped_ptr<ServiceProviderImpl> exported_services) {
- scoped_ptr<ServiceProvider> imported_services;
- // BindToProxy() takes ownership of |exported_services|.
- ServiceProviderImpl* registry = exported_services.release();
- ServiceProviderPtr sp;
- if (registry) {
- BindToProxy(registry, &sp);
- imported_services.reset(registry->CreateRemoteServiceProvider());
- }
- state_->wm()->Embed(url, MakeRequest<ServiceProvider>(sp.PassMessagePipe()));
- return imported_services.Pass();
+void ViewManagerContext::Embed(const String& url,
+ InterfaceRequest<ServiceProvider> services,
+ ServiceProviderPtr exposed_services) {
+ state_->wm()->Embed(url, services.Pass(), exposed_services.Pass());
}
} // namespace mojo
diff --git a/mojo/services/view_manager/public/cpp/tests/view_manager_unittest.cc b/mojo/services/view_manager/public/cpp/tests/view_manager_unittest.cc
index bbfc742..d9e4db8 100644
--- a/mojo/services/view_manager/public/cpp/tests/view_manager_unittest.cc
+++ b/mojo/services/view_manager/public/cpp/tests/view_manager_unittest.cc
@@ -81,8 +81,8 @@ class ConnectApplicationLoader : public ApplicationLoader,
// Overridden from ViewManagerDelegate:
void OnEmbed(View* root,
- ServiceProviderImpl* exported_services,
- scoped_ptr<ServiceProvider> imported_services) override {
+ InterfaceRequest<ServiceProvider> services,
+ ServiceProviderPtr exposed_services) override {
callback_.Run(root);
}
void OnViewManagerDisconnected(ViewManager* view_manager) override {}
diff --git a/mojo/services/view_manager/public/cpp/view.h b/mojo/services/view_manager/public/cpp/view.h
index 9917fca..1215a3b 100644
--- a/mojo/services/view_manager/public/cpp/view.h
+++ b/mojo/services/view_manager/public/cpp/view.h
@@ -124,9 +124,9 @@ class View {
// Embedding.
void Embed(const String& url);
- scoped_ptr<ServiceProvider> Embed(
- const String& url,
- scoped_ptr<ServiceProviderImpl> exported_services);
+ void Embed(const String& url,
+ InterfaceRequest<ServiceProvider> services,
+ ServiceProviderPtr exposed_services);
protected:
// This class is subclassed only by test classes that provide a public ctor.
diff --git a/mojo/services/view_manager/public/cpp/view_manager_context.h b/mojo/services/view_manager/public/cpp/view_manager_context.h
index ed8f23e..1976598 100644
--- a/mojo/services/view_manager/public/cpp/view_manager_context.h
+++ b/mojo/services/view_manager/public/cpp/view_manager_context.h
@@ -26,14 +26,14 @@ class ViewManagerContext {
// Subsequent times, the implementation of this method is delegated to the
// application embedded at the service root View. This application will have a
// specific definition of where within its View hierarchy to embed an
- // un-parented URL. |exported_services| encapsulates services offered by the
- // application calling Embed() to the application being embedded. Returns
- // an object implementing ServiceProvider encapsulating services offered by
- // the embedded application to the embedder.
+ // un-parented URL.
+ // |services| encapsulates services offered by the embedder to the embedded
+ // app alongside this Embed() call. |exposed_services| provides a means for
+ // the embedder to connect to services exposed by the embedded app.
void Embed(const String& url);
- scoped_ptr<ServiceProvider> Embed(
- const String& url,
- scoped_ptr<ServiceProviderImpl> exported_services);
+ void Embed(const String& url,
+ InterfaceRequest<ServiceProvider> services,
+ ServiceProviderPtr exposed_Services);
private:
class InternalState;
diff --git a/mojo/services/view_manager/public/cpp/view_manager_delegate.h b/mojo/services/view_manager/public/cpp/view_manager_delegate.h
index 1160861..e78e925 100644
--- a/mojo/services/view_manager/public/cpp/view_manager_delegate.h
+++ b/mojo/services/view_manager/public/cpp/view_manager_delegate.h
@@ -5,12 +5,10 @@
#ifndef MOJO_SERVICES_VIEW_MANAGER_PUBLIC_CPP_VIEW_MANAGER_DELEGATE_H_
#define MOJO_SERVICES_VIEW_MANAGER_PUBLIC_CPP_VIEW_MANAGER_DELEGATE_H_
-#include "base/memory/scoped_ptr.h"
#include "mojo/public/interfaces/application/service_provider.mojom.h"
namespace mojo {
-class ServiceProviderImpl;
class View;
class ViewManager;
@@ -22,15 +20,18 @@ class ViewManagerDelegate {
// created. |root| and it's corresponding ViewManager are valid until
// OnViewManagerDisconnected() is called with the same object.
//
- // |exported_services| is an object that the delegate can add services to
- // expose to the embedder. |imported_services| exposes the services offered by
- // the embedder to the delegate. Note that if a different application is
- // subsequently embedded at |root|, the pipe(s) connecting |imported_services|
- // to the embedder and any services obtained from it are not broken and will
- // continue to be valid.
+ // |services| exposes the services offered by the embedder to the delegate.
+ //
+ // |exposed_services| is an object that the delegate can add services to
+ // expose to the embedder.
+ //
+ // Note that if a different application is subsequently embedded at |root|,
+ // the pipes connecting |services| and |exposed_services| to the embedder and
+ // any services obtained from them are not broken and will continue to be
+ // valid.
virtual void OnEmbed(View* root,
- ServiceProviderImpl* exported_services,
- scoped_ptr<ServiceProvider> imported_services) = 0;
+ InterfaceRequest<ServiceProvider> services,
+ ServiceProviderPtr exposed_services) = 0;
// Called when a connection to the view manager service is closed.
// |view_manager| is not valid after this function returns.
diff --git a/mojo/services/view_manager/public/interfaces/view_manager.mojom b/mojo/services/view_manager/public/interfaces/view_manager.mojom
index 0f5c51d..55552f8 100644
--- a/mojo/services/view_manager/public/interfaces/view_manager.mojom
+++ b/mojo/services/view_manager/public/interfaces/view_manager.mojom
@@ -124,15 +124,16 @@ interface ViewManagerService {
// children the children are removed. The one exception is the root
// connection.
//
- // |service_provider| encapsulates services offered by the embedder to the
- // embedded app alongside this Embed() call. It also provides a means for
- // the embedder to connect to services symmetrically exposed by the embedded
- // app. Note that if a different app is subsequently embedded at |view_id|
- // the |service_provider|'s connection to its client in the embedded app and
- // any services it provided are not broken and continue to be valid.
+ // |services| encapsulates services offered by the embedder to the embedded
+ // app alongside this Embed() call. |exposed_services| provides a means for
+ // the embedder to connect to services exposed by the embedded app. Note that
+ // if a different app is subsequently embedded at |view_id| the
+ // ServiceProvider connections to its client in the embedded app and any
+ // services it provided are not broken and continue to be valid.
Embed(string url,
uint32 view_id,
- ServiceProvider& service_provider) => (bool success);
+ ServiceProvider&? services,
+ ServiceProvider? exposed_services) => (bool success);
};
// Changes to views are not sent to the connection that originated the
@@ -146,7 +147,8 @@ interface ViewManagerClient {
OnEmbed(uint16 connection_id,
string embedder_url,
ViewData root,
- ServiceProvider& parent_service_provider,
+ ServiceProvider&? services,
+ ServiceProvider? exposed_services,
handle<message_pipe> window_manager_pipe);
// Invoked when the application embedded at |view| is disconnected.
diff --git a/mojo/services/window_manager/public/interfaces/window_manager.mojom b/mojo/services/window_manager/public/interfaces/window_manager.mojom
index a2ef594..e365fb6 100644
--- a/mojo/services/window_manager/public/interfaces/window_manager.mojom
+++ b/mojo/services/window_manager/public/interfaces/window_manager.mojom
@@ -10,8 +10,9 @@ import "mojo/public/interfaces/application/service_provider.mojom";
[Client=WindowManagerClient]
interface WindowManager {
// Requests the WindowManager to embed the app for |url| at an appropriate
- // View. See ViewMangerService::Embed() for details on |service_provider|.
- Embed(string url, ServiceProvider& service_provider);
+ // View. See ViewMangerService::Embed() for details on |services| and
+ // |exposed_services|.
+ Embed(string url, ServiceProvider&? services, ServiceProvider? exposed_services);
SetCapture(uint32 view_id) => (bool success);
FocusWindow(uint32 view_id) => (bool success);
diff --git a/third_party/mojo/mojo_public.gyp b/third_party/mojo/mojo_public.gyp
index 3114ac9..0ab9e87 100644
--- a/third_party/mojo/mojo_public.gyp
+++ b/third_party/mojo/mojo_public.gyp
@@ -237,8 +237,6 @@
'src/mojo/public/cpp/application/lib/service_connector.h',
'src/mojo/public/cpp/application/lib/service_registry.cc',
'src/mojo/public/cpp/application/lib/service_registry.h',
- 'src/mojo/public/cpp/application/lib/weak_service_provider.cc',
- 'src/mojo/public/cpp/application/lib/weak_service_provider.h',
'src/mojo/public/cpp/application/service_provider_impl.h',
],
'dependencies': [
diff --git a/third_party/mojo/src/mojo/edk/system/BUILD.gn b/third_party/mojo/src/mojo/edk/system/BUILD.gn
index eab85a2..67310c8 100644
--- a/third_party/mojo/src/mojo/edk/system/BUILD.gn
+++ b/third_party/mojo/src/mojo/edk/system/BUILD.gn
@@ -2,8 +2,13 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
-import("//testing/test.gni")
import("../mojo_edk.gni")
+import("//testing/test.gni")
+
+if (is_android) {
+ import("//build/config/android/config.gni")
+ import("//build/config/android/rules.gni")
+}
config("system_config") {
defines = [
diff --git a/third_party/mojo/src/mojo/edk/system/raw_channel.cc b/third_party/mojo/src/mojo/edk/system/raw_channel.cc
index aff1110..383a743 100644
--- a/third_party/mojo/src/mojo/edk/system/raw_channel.cc
+++ b/third_party/mojo/src/mojo/edk/system/raw_channel.cc
@@ -156,7 +156,7 @@ void RawChannel::WriteBuffer::GetBuffers(std::vector<Buffer>* buffers) const {
RawChannel::RawChannel()
: message_loop_for_io_(nullptr),
delegate_(nullptr),
- read_stopped_(false),
+ set_on_shutdown_(nullptr),
write_stopped_(false),
weak_ptr_factory_(this) {
}
@@ -212,7 +212,10 @@ void RawChannel::Shutdown() {
// Reset the delegate so that it won't receive further calls.
delegate_ = nullptr;
- read_stopped_ = true;
+ if (set_on_shutdown_) {
+ *set_on_shutdown_ = true;
+ set_on_shutdown_ = nullptr;
+ }
write_stopped_ = true;
weak_ptr_factory_.InvalidateWeakPtrs();
@@ -264,11 +267,6 @@ bool RawChannel::IsWriteBufferEmpty() {
void RawChannel::OnReadCompleted(IOResult io_result, size_t bytes_read) {
DCHECK_EQ(base::MessageLoop::current(), message_loop_for_io_);
- if (read_stopped_) {
- NOTREACHED();
- return;
- }
-
// Keep reading data in a loop, and dispatch messages if enough data is
// received. Exit the loop if any of the following happens:
// - one or more messages were dispatched;
@@ -281,9 +279,8 @@ void RawChannel::OnReadCompleted(IOResult io_result, size_t bytes_read) {
case IO_FAILED_SHUTDOWN:
case IO_FAILED_BROKEN:
case IO_FAILED_UNKNOWN:
- read_stopped_ = true;
CallOnError(ReadIOResultToError(io_result));
- return;
+ return; // |this| may have been destroyed in |CallOnError()|.
case IO_PENDING:
NOTREACHED();
return;
@@ -318,16 +315,14 @@ void RawChannel::OnReadCompleted(IOResult io_result, size_t bytes_read) {
&error_message)) {
DCHECK(error_message);
LOG(ERROR) << "Received invalid message: " << error_message;
- read_stopped_ = true;
CallOnError(Delegate::ERROR_READ_BAD_MESSAGE);
- return;
+ return; // |this| may have been destroyed in |CallOnError()|.
}
if (message_view.type() == MessageInTransit::kTypeRawChannel) {
if (!OnReadMessageForRawChannel(message_view)) {
- read_stopped_ = true;
CallOnError(Delegate::ERROR_READ_BAD_MESSAGE);
- return;
+ return; // |this| may have been destroyed in |CallOnError()|.
}
} else {
embedder::ScopedPlatformHandleVectorPtr platform_handles;
@@ -344,9 +339,8 @@ void RawChannel::OnReadCompleted(IOResult io_result, size_t bytes_read) {
platform_handle_table).Pass();
if (!platform_handles) {
LOG(ERROR) << "Invalid number of platform handles received";
- read_stopped_ = true;
CallOnError(Delegate::ERROR_READ_BAD_MESSAGE);
- return;
+ return; // |this| may have been destroyed in |CallOnError()|.
}
}
}
@@ -355,13 +349,16 @@ void RawChannel::OnReadCompleted(IOResult io_result, size_t bytes_read) {
// for the POSIX implementation, we should confirm that none are stored.
// Dispatch the message.
+ // Detect the case when |Shutdown()| is called; subsequent destruction
+ // is also permitted then.
+ bool shutdown_called = false;
+ DCHECK(!set_on_shutdown_);
+ set_on_shutdown_ = &shutdown_called;
DCHECK(delegate_);
delegate_->OnReadMessage(message_view, platform_handles.Pass());
- if (read_stopped_) {
- // |Shutdown()| was called in |OnReadMessage()|.
- // TODO(vtl): Add test for this case.
+ if (shutdown_called)
return;
- }
+ set_on_shutdown_ = nullptr;
}
did_dispatch_message = true;
@@ -429,8 +426,10 @@ void RawChannel::OnWriteCompleted(IOResult io_result,
bytes_written);
}
- if (did_fail)
+ if (did_fail) {
CallOnError(Delegate::ERROR_WRITE);
+ return; // |this| may have been destroyed in |CallOnError()|.
+ }
}
void RawChannel::EnqueueMessageNoLock(scoped_ptr<MessageInTransit> message) {
@@ -467,8 +466,10 @@ RawChannel::Delegate::Error RawChannel::ReadIOResultToError(
void RawChannel::CallOnError(Delegate::Error error) {
DCHECK_EQ(base::MessageLoop::current(), message_loop_for_io_);
// TODO(vtl): Add a "write_lock_.AssertNotAcquired()"?
- if (delegate_)
+ if (delegate_) {
delegate_->OnError(error);
+ return; // |this| may have been destroyed in |OnError()|.
+ }
}
bool RawChannel::OnWriteCompletedNoLock(IOResult io_result,
diff --git a/third_party/mojo/src/mojo/edk/system/raw_channel.h b/third_party/mojo/src/mojo/edk/system/raw_channel.h
index f567767..91feaab 100644
--- a/third_party/mojo/src/mojo/edk/system/raw_channel.h
+++ b/third_party/mojo/src/mojo/edk/system/raw_channel.h
@@ -41,6 +41,8 @@ namespace system {
// on which |Init()| is called).
class MOJO_SYSTEM_IMPL_EXPORT RawChannel {
public:
+ // This object may be destroyed on any thread (if |Init()| was called, after
+ // |Shutdown()| was called).
virtual ~RawChannel();
// The |Delegate| is only accessed on the same thread as the message loop
@@ -61,14 +63,14 @@ class MOJO_SYSTEM_IMPL_EXPORT RawChannel {
ERROR_WRITE
};
- // Called when a message is read. This may call |Shutdown()| (on the
- // |RawChannel|), but must not destroy it.
+ // Called when a message is read. This may call the |RawChannel|'s
+ // |Shutdown()| and then (if desired) destroy it.
virtual void OnReadMessage(
const MessageInTransit::View& message_view,
embedder::ScopedPlatformHandleVectorPtr platform_handles) = 0;
- // Called when there's a (fatal) error. This may call the raw channel's
- // |Shutdown()|, but must not destroy it.
+ // Called when there's a (fatal) error. This may call the |RawChannel|'s
+ // |Shutdown()| and then (if desired) destroy it.
//
// For each raw channel, there'll be at most one |ERROR_READ_...| and at
// most one |ERROR_WRITE| notification. After |OnError(ERROR_READ_...)|,
@@ -197,10 +199,10 @@ class MOJO_SYSTEM_IMPL_EXPORT RawChannel {
RawChannel();
// |result| must not be |IO_PENDING|. Must be called on the I/O thread WITHOUT
- // |write_lock_| held.
+ // |write_lock_| held. This object may be destroyed by this call.
void OnReadCompleted(IOResult io_result, size_t bytes_read);
// |result| must not be |IO_PENDING|. Must be called on the I/O thread WITHOUT
- // |write_lock_| held.
+ // |write_lock_| held. This object may be destroyed by this call.
void OnWriteCompleted(IOResult io_result,
size_t platform_handles_written,
size_t bytes_written);
@@ -280,8 +282,9 @@ class MOJO_SYSTEM_IMPL_EXPORT RawChannel {
// Must be called on the I/O thread WITHOUT |write_lock_| held.
virtual void OnInit() = 0;
// On shutdown, passes the ownership of the buffers to subclasses, which may
- // want to preserve them if there are pending read/write. Must be called on
- // the I/O thread under |write_lock_|.
+ // want to preserve them if there are pending read/writes. After this is
+ // called, |OnReadCompleted()| must no longer be called. Must be called on the
+ // I/O thread under |write_lock_|.
virtual void OnShutdownNoLock(scoped_ptr<ReadBuffer> read_buffer,
scoped_ptr<WriteBuffer> write_buffer) = 0;
@@ -290,7 +293,7 @@ class MOJO_SYSTEM_IMPL_EXPORT RawChannel {
static Delegate::Error ReadIOResultToError(IOResult io_result);
// Calls |delegate_->OnError(error)|. Must be called on the I/O thread WITHOUT
- // |write_lock_| held.
+ // |write_lock_| held. This object may be destroyed by this call.
void CallOnError(Delegate::Error error);
// If |io_result| is |IO_SUCCESS|, updates the write buffer and schedules a
@@ -308,7 +311,7 @@ class MOJO_SYSTEM_IMPL_EXPORT RawChannel {
// Only used on the I/O thread:
Delegate* delegate_;
- bool read_stopped_;
+ bool* set_on_shutdown_;
scoped_ptr<ReadBuffer> read_buffer_;
base::Lock write_lock_; // Protects the following members.
diff --git a/third_party/mojo/src/mojo/edk/system/raw_channel_posix.cc b/third_party/mojo/src/mojo/edk/system/raw_channel_posix.cc
index 078f8cb..d8c55d56 100644
--- a/third_party/mojo/src/mojo/edk/system/raw_channel_posix.cc
+++ b/third_party/mojo/src/mojo/edk/system/raw_channel_posix.cc
@@ -356,18 +356,23 @@ void RawChannelPosix::OnFileCanReadWithoutBlocking(int fd) {
pending_read_ = false;
size_t bytes_read = 0;
IOResult io_result = Read(&bytes_read);
- if (io_result != IO_PENDING)
+ if (io_result != IO_PENDING) {
OnReadCompleted(io_result, bytes_read);
+ // TODO(vtl): If we weren't destroyed, we'd like to do
+ //
+ // DCHECK(!read_watcher_ || pending_read_);
+ //
+ // On failure, |read_watcher_| must have been reset; on success, we assume
+ // that |OnReadCompleted()| always schedules another read. Otherwise, we
+ // could end up spinning -- getting |OnFileCanReadWithoutBlocking()| again
+ // and again but not doing any actual read.
+ // TODO(yzshen): An alternative is to stop watching if RawChannel doesn't
+ // schedule a new read. But that code won't be reached under the current
+ // RawChannel implementation.
+ return; // |this| may have been destroyed in |OnReadCompleted()|.
+ }
- // On failure, |read_watcher_| must have been reset; on success,
- // we assume that |OnReadCompleted()| always schedules another read.
- // Otherwise, we could end up spinning -- getting
- // |OnFileCanReadWithoutBlocking()| again and again but not doing any actual
- // read.
- // TODO(yzshen): An alternative is to stop watching if RawChannel doesn't
- // schedule a new read. But that code won't be reached under the current
- // RawChannel implementation.
- DCHECK(!read_watcher_ || pending_read_);
+ DCHECK(pending_read_);
}
void RawChannelPosix::OnFileCanWriteWithoutBlocking(int fd) {
@@ -386,8 +391,10 @@ void RawChannelPosix::OnFileCanWriteWithoutBlocking(int fd) {
io_result = WriteNoLock(&platform_handles_written, &bytes_written);
}
- if (io_result != IO_PENDING)
+ if (io_result != IO_PENDING) {
OnWriteCompleted(io_result, platform_handles_written, bytes_written);
+ return; // |this| may have been destroyed in |OnWriteCompleted()|.
+ }
}
RawChannel::IOResult RawChannelPosix::ReadImpl(size_t* bytes_read) {
@@ -451,6 +458,7 @@ void RawChannelPosix::WaitToWrite() {
pending_write_ = false;
}
OnWriteCompleted(IO_FAILED_UNKNOWN, 0, 0);
+ return; // |this| may have been destroyed in |OnWriteCompleted()|.
}
}
diff --git a/third_party/mojo/src/mojo/edk/system/raw_channel_unittest.cc b/third_party/mojo/src/mojo/edk/system/raw_channel_unittest.cc
index a8cbcba..a95ce30 100644
--- a/third_party/mojo/src/mojo/edk/system/raw_channel_unittest.cc
+++ b/third_party/mojo/src/mojo/edk/system/raw_channel_unittest.cc
@@ -555,12 +555,14 @@ TEST_F(RawChannelTest, WriteMessageAfterShutdown) {
EXPECT_FALSE(rc->WriteMessage(MakeTestMessage(1)));
}
-// RawChannelTest.ShutdownOnReadMessage ----------------------------------------
+// RawChannelTest.{Shutdown, ShutdownAndDestroy}OnReadMessage ------------------
class ShutdownOnReadMessageRawChannelDelegate : public RawChannel::Delegate {
public:
- explicit ShutdownOnReadMessageRawChannelDelegate(RawChannel* raw_channel)
+ explicit ShutdownOnReadMessageRawChannelDelegate(RawChannel* raw_channel,
+ bool should_destroy)
: raw_channel_(raw_channel),
+ should_destroy_(should_destroy),
done_event_(false, false),
did_shutdown_(false) {}
~ShutdownOnReadMessageRawChannelDelegate() override {}
@@ -574,6 +576,8 @@ class ShutdownOnReadMessageRawChannelDelegate : public RawChannel::Delegate {
EXPECT_TRUE(
CheckMessageData(message_view.bytes(), message_view.num_bytes()));
raw_channel_->Shutdown();
+ if (should_destroy_)
+ delete raw_channel_;
did_shutdown_ = true;
done_event_.Signal();
}
@@ -589,6 +593,7 @@ class ShutdownOnReadMessageRawChannelDelegate : public RawChannel::Delegate {
private:
RawChannel* const raw_channel_;
+ const bool should_destroy_;
base::WaitableEvent done_event_;
bool did_shutdown_;
@@ -601,7 +606,7 @@ TEST_F(RawChannelTest, ShutdownOnReadMessage) {
EXPECT_TRUE(WriteTestMessageToHandle(handles[1].get(), 10));
scoped_ptr<RawChannel> rc(RawChannel::Create(handles[0].Pass()));
- ShutdownOnReadMessageRawChannelDelegate delegate(rc.get());
+ ShutdownOnReadMessageRawChannelDelegate delegate(rc.get(), false);
io_thread()->PostTaskAndWait(
FROM_HERE,
base::Bind(&InitOnIOThread, rc.get(), base::Unretained(&delegate)));
@@ -610,13 +615,29 @@ TEST_F(RawChannelTest, ShutdownOnReadMessage) {
delegate.Wait();
}
-// RawChannelTest.ShutdownOnError{Read, Write} ---------------------------------
+TEST_F(RawChannelTest, ShutdownAndDestroyOnReadMessage) {
+ // Write a message into the other end.
+ EXPECT_TRUE(WriteTestMessageToHandle(handles[1].get(), 10));
+
+ // The delegate will destroy |rc|.
+ RawChannel* rc = RawChannel::Create(handles[0].Pass()).release();
+ ShutdownOnReadMessageRawChannelDelegate delegate(rc, true);
+ io_thread()->PostTaskAndWait(
+ FROM_HERE, base::Bind(&InitOnIOThread, rc, base::Unretained(&delegate)));
+
+ // Wait for the delegate, which will shut the |RawChannel| down.
+ delegate.Wait();
+}
+
+// RawChannelTest.{Shutdown, ShutdownAndDestroy}OnError{Read, Write} -----------
class ShutdownOnErrorRawChannelDelegate : public RawChannel::Delegate {
public:
ShutdownOnErrorRawChannelDelegate(RawChannel* raw_channel,
+ bool should_destroy,
Error shutdown_on_error_type)
: raw_channel_(raw_channel),
+ should_destroy_(should_destroy),
shutdown_on_error_type_(shutdown_on_error_type),
done_event_(false, false),
did_shutdown_(false) {}
@@ -633,6 +654,8 @@ class ShutdownOnErrorRawChannelDelegate : public RawChannel::Delegate {
if (error != shutdown_on_error_type_)
return;
raw_channel_->Shutdown();
+ if (should_destroy_)
+ delete raw_channel_;
did_shutdown_ = true;
done_event_.Signal();
}
@@ -645,6 +668,7 @@ class ShutdownOnErrorRawChannelDelegate : public RawChannel::Delegate {
private:
RawChannel* const raw_channel_;
+ const bool should_destroy_;
const Error shutdown_on_error_type_;
base::WaitableEvent done_event_;
bool did_shutdown_;
@@ -655,7 +679,7 @@ class ShutdownOnErrorRawChannelDelegate : public RawChannel::Delegate {
TEST_F(RawChannelTest, ShutdownOnErrorRead) {
scoped_ptr<RawChannel> rc(RawChannel::Create(handles[0].Pass()));
ShutdownOnErrorRawChannelDelegate delegate(
- rc.get(), RawChannel::Delegate::ERROR_READ_SHUTDOWN);
+ rc.get(), false, RawChannel::Delegate::ERROR_READ_SHUTDOWN);
io_thread()->PostTaskAndWait(
FROM_HERE,
base::Bind(&InitOnIOThread, rc.get(), base::Unretained(&delegate)));
@@ -667,9 +691,23 @@ TEST_F(RawChannelTest, ShutdownOnErrorRead) {
delegate.Wait();
}
+TEST_F(RawChannelTest, ShutdownAndDestroyOnErrorRead) {
+ RawChannel* rc = RawChannel::Create(handles[0].Pass()).release();
+ ShutdownOnErrorRawChannelDelegate delegate(
+ rc, true, RawChannel::Delegate::ERROR_READ_SHUTDOWN);
+ io_thread()->PostTaskAndWait(
+ FROM_HERE, base::Bind(&InitOnIOThread, rc, base::Unretained(&delegate)));
+
+ // Close the handle of the other end, which should stuff fail.
+ handles[1].reset();
+
+ // Wait for the delegate, which will shut the |RawChannel| down.
+ delegate.Wait();
+}
+
TEST_F(RawChannelTest, ShutdownOnErrorWrite) {
scoped_ptr<RawChannel> rc(RawChannel::Create(handles[0].Pass()));
- ShutdownOnErrorRawChannelDelegate delegate(rc.get(),
+ ShutdownOnErrorRawChannelDelegate delegate(rc.get(), false,
RawChannel::Delegate::ERROR_WRITE);
io_thread()->PostTaskAndWait(
FROM_HERE,
@@ -684,6 +722,22 @@ TEST_F(RawChannelTest, ShutdownOnErrorWrite) {
delegate.Wait();
}
+TEST_F(RawChannelTest, ShutdownAndDestroyOnErrorWrite) {
+ RawChannel* rc = RawChannel::Create(handles[0].Pass()).release();
+ ShutdownOnErrorRawChannelDelegate delegate(rc, true,
+ RawChannel::Delegate::ERROR_WRITE);
+ io_thread()->PostTaskAndWait(
+ FROM_HERE, base::Bind(&InitOnIOThread, rc, base::Unretained(&delegate)));
+
+ // Close the handle of the other end, which should stuff fail.
+ handles[1].reset();
+
+ EXPECT_FALSE(rc->WriteMessage(MakeTestMessage(1)));
+
+ // Wait for the delegate, which will shut the |RawChannel| down.
+ delegate.Wait();
+}
+
// RawChannelTest.ReadWritePlatformHandles -------------------------------------
class ReadPlatformHandlesCheckerRawChannelDelegate
diff --git a/third_party/mojo/src/mojo/edk/system/raw_channel_win.cc b/third_party/mojo/src/mojo/edk/system/raw_channel_win.cc
index 7ec7ad7..4417937 100644
--- a/third_party/mojo/src/mojo/edk/system/raw_channel_win.cc
+++ b/third_party/mojo/src/mojo/edk/system/raw_channel_win.cc
@@ -303,6 +303,7 @@ void RawChannelWin::RawChannelIOHandler::OnReadCompleted(DWORD bytes_read,
if (!owner_)
return;
+ // Note: |OnReadCompleted()| may detach us from |owner_|.
if (error == ERROR_SUCCESS) {
DCHECK_GT(bytes_read, 0u);
owner_->OnReadCompleted(IO_SUCCEEDED, bytes_read);
@@ -335,6 +336,7 @@ void RawChannelWin::RawChannelIOHandler::OnWriteCompleted(DWORD bytes_written,
pending_write_ = false;
}
+ // Note: |OnWriteCompleted()| may detach us from |owner_|.
if (error == ERROR_SUCCESS) {
owner_->OnWriteCompleted(IO_SUCCEEDED, 0, bytes_written);
} else if (error == ERROR_BROKEN_PIPE) {
diff --git a/third_party/mojo/src/mojo/edk/test/BUILD.gn b/third_party/mojo/src/mojo/edk/test/BUILD.gn
index ea323c6..b130440 100644
--- a/third_party/mojo/src/mojo/edk/test/BUILD.gn
+++ b/third_party/mojo/src/mojo/edk/test/BUILD.gn
@@ -2,8 +2,8 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
-import("//testing/test.gni")
import("../mojo_edk.gni")
+import("//testing/test.gni")
mojo_edk_source_set("test_support") {
testonly = true
diff --git a/third_party/mojo/src/mojo/public/VERSION b/third_party/mojo/src/mojo/public/VERSION
index c4ab015..928bc42 100644
--- a/third_party/mojo/src/mojo/public/VERSION
+++ b/third_party/mojo/src/mojo/public/VERSION
@@ -1 +1 @@
-53d4413e27ba6767cb6da33ab4342c419c725086 \ No newline at end of file
+a85a2cea82d816de115e15253742b0f88a9924eb \ No newline at end of file
diff --git a/third_party/mojo/src/mojo/public/cpp/application/BUILD.gn b/third_party/mojo/src/mojo/public/cpp/application/BUILD.gn
index 1c8842d..8741c694 100644
--- a/third_party/mojo/src/mojo/public/cpp/application/BUILD.gn
+++ b/third_party/mojo/src/mojo/public/cpp/application/BUILD.gn
@@ -22,8 +22,6 @@ mojo_sdk_source_set("application") {
"lib/service_connector.h",
"lib/service_registry.cc",
"lib/service_registry.h",
- "lib/weak_service_provider.cc",
- "lib/weak_service_provider.h",
]
mojo_sdk_deps = [
diff --git a/third_party/mojo/src/mojo/public/cpp/application/application_connection.h b/third_party/mojo/src/mojo/public/cpp/application/application_connection.h
index d5d6dde..ca6ea07 100644
--- a/third_party/mojo/src/mojo/public/cpp/application/application_connection.h
+++ b/third_party/mojo/src/mojo/public/cpp/application/application_connection.h
@@ -47,10 +47,11 @@ class ApplicationConnection {
// Connect to the service implementing |Interface|.
template <typename Interface>
void ConnectToService(InterfacePtr<Interface>* ptr) {
- MessagePipe pipe;
- ptr->Bind(pipe.handle0.Pass());
- GetServiceProvider()->ConnectToService(Interface::Name_,
- pipe.handle1.Pass());
+ if (ServiceProvider* sp = GetServiceProvider()) {
+ MessagePipe pipe;
+ ptr->Bind(pipe.handle0.Pass());
+ sp->ConnectToService(Interface::Name_, pipe.handle1.Pass());
+ }
}
// The url identifying the application on the other end of this connection.
diff --git a/third_party/mojo/src/mojo/public/cpp/application/application_impl.h b/third_party/mojo/src/mojo/public/cpp/application/application_impl.h
index 0ea22c9..430a124 100644
--- a/third_party/mojo/src/mojo/public/cpp/application/application_impl.h
+++ b/third_party/mojo/src/mojo/public/cpp/application/application_impl.h
@@ -100,6 +100,7 @@ class ApplicationImpl : public InterfaceImpl<Application> {
void AcceptConnection(const String& requestor_url,
InterfaceRequest<ServiceProvider> services,
ServiceProviderPtr exposed_services) override;
+ void RequestQuit() override;
typedef std::vector<internal::ServiceRegistry*> ServiceRegistryList;
diff --git a/third_party/mojo/src/mojo/public/cpp/application/lib/application_impl.cc b/third_party/mojo/src/mojo/public/cpp/application/lib/application_impl.cc
index 6677003..894060d 100644
--- a/third_party/mojo/src/mojo/public/cpp/application/lib/application_impl.cc
+++ b/third_party/mojo/src/mojo/public/cpp/application/lib/application_impl.cc
@@ -114,4 +114,8 @@ void ApplicationImpl::AcceptConnection(
incoming_service_registries_.push_back(registry);
}
+void ApplicationImpl::RequestQuit() {
+ Terminate();
+}
+
} // namespace mojo
diff --git a/third_party/mojo/src/mojo/public/cpp/application/lib/service_provider_impl.cc b/third_party/mojo/src/mojo/public/cpp/application/lib/service_provider_impl.cc
index 08a0648..db55710 100644
--- a/third_party/mojo/src/mojo/public/cpp/application/lib/service_provider_impl.cc
+++ b/third_party/mojo/src/mojo/public/cpp/application/lib/service_provider_impl.cc
@@ -5,22 +5,23 @@
#include "mojo/public/cpp/application/service_provider_impl.h"
#include "mojo/public/cpp/application/lib/service_connector.h"
-#include "mojo/public/cpp/application/lib/weak_service_provider.h"
#include "mojo/public/cpp/environment/logging.h"
namespace mojo {
-ServiceProviderImpl::ServiceProviderImpl() : remote_(nullptr) {
+ServiceProviderImpl::ServiceProviderImpl() : binding_(this) {
+}
+
+ServiceProviderImpl::ServiceProviderImpl(
+ InterfaceRequest<ServiceProvider> request)
+ : binding_(this, request.Pass()) {
}
ServiceProviderImpl::~ServiceProviderImpl() {
}
-ServiceProvider* ServiceProviderImpl::CreateRemoteServiceProvider() {
- // TODO(beng): it sure would be nice if this method could return a scoped_ptr.
- MOJO_DCHECK(!remote_);
- remote_ = new internal::WeakServiceProvider(this, client());
- return remote_;
+void ServiceProviderImpl::Bind(InterfaceRequest<ServiceProvider> request) {
+ binding_.Bind(request.Pass());
}
void ServiceProviderImpl::ConnectToService(
@@ -37,10 +38,6 @@ void ServiceProviderImpl::ConnectToService(
client_handle.Pass());
}
-void ServiceProviderImpl::OnConnectionError() {
- ClearRemote();
-}
-
void ServiceProviderImpl::AddServiceConnector(
internal::ServiceConnectorBase* service_connector) {
RemoveServiceConnector(service_connector);
@@ -59,11 +56,4 @@ void ServiceProviderImpl::RemoveServiceConnector(
service_connectors_.erase(it);
}
-void ServiceProviderImpl::ClearRemote() {
- if (remote_) {
- remote_->Clear();
- remote_ = nullptr;
- }
-}
-
} // namespace mojo
diff --git a/third_party/mojo/src/mojo/public/cpp/application/lib/weak_service_provider.cc b/third_party/mojo/src/mojo/public/cpp/application/lib/weak_service_provider.cc
deleted file mode 100644
index de0cb6c..0000000
--- a/third_party/mojo/src/mojo/public/cpp/application/lib/weak_service_provider.cc
+++ /dev/null
@@ -1,36 +0,0 @@
-// 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.
-
-#include "mojo/public/cpp/application/lib/weak_service_provider.h"
-
-#include "mojo/public/cpp/application/service_provider_impl.h"
-#include "mojo/public/interfaces/application/service_provider.mojom.h"
-
-namespace mojo {
-namespace internal {
-
-WeakServiceProvider::WeakServiceProvider(ServiceProviderImpl* creator,
- ServiceProvider* service_provider)
- : creator_(creator), service_provider_(service_provider) {
-}
-
-WeakServiceProvider::~WeakServiceProvider() {
- if (creator_)
- creator_->ClearRemote();
-}
-
-void WeakServiceProvider::Clear() {
- creator_ = nullptr;
- service_provider_ = nullptr;
-}
-
-void WeakServiceProvider::ConnectToService(
- const String& service_name,
- ScopedMessagePipeHandle client_handle) {
- if (service_provider_)
- service_provider_->ConnectToService(service_name, client_handle.Pass());
-}
-
-} // namespace internal
-} // namespace mojo
diff --git a/third_party/mojo/src/mojo/public/cpp/application/lib/weak_service_provider.h b/third_party/mojo/src/mojo/public/cpp/application/lib/weak_service_provider.h
deleted file mode 100644
index 3d959d1..0000000
--- a/third_party/mojo/src/mojo/public/cpp/application/lib/weak_service_provider.h
+++ /dev/null
@@ -1,41 +0,0 @@
-// 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 MOJO_PUBLIC_APPLICATION_LIB_WEAK_SERVICE_PROVIDER_H_
-#define MOJO_PUBLIC_APPLICATION_LIB_WEAK_SERVICE_PROVIDER_H_
-
-#include "mojo/public/interfaces/application/service_provider.mojom.h"
-
-namespace mojo {
-class ServiceProviderImpl;
-namespace internal {
-class ServiceConnectorBase;
-
-// Implements a weak pointer to a ServiceProvider. Necessary as the lifetime of
-// the ServiceProviderImpl is bound to that of its pipe, but code may continue
-// to reference a remote service provider beyond the lifetime of said pipe.
-// Calls to ConnectToService() are silently dropped when the pipe is closed.
-class WeakServiceProvider : public ServiceProvider {
- public:
- WeakServiceProvider(ServiceProviderImpl* creator,
- ServiceProvider* service_provider);
- ~WeakServiceProvider() override;
-
- void Clear();
-
- private:
- // Overridden from ServiceProvider:
- void ConnectToService(const String& service_name,
- ScopedMessagePipeHandle client_handle) override;
-
- ServiceProviderImpl* creator_;
- ServiceProvider* service_provider_;
-
- MOJO_DISALLOW_COPY_AND_ASSIGN(WeakServiceProvider);
-};
-
-} // namespace internal
-} // namespace mojo
-
-#endif // MOJO_PUBLIC_APPLICATION_LIB_WEAK_SERVICE_PROVIDER_H_
diff --git a/third_party/mojo/src/mojo/public/cpp/application/service_provider_impl.h b/third_party/mojo/src/mojo/public/cpp/application/service_provider_impl.h
index 45ad7b8..a449124 100644
--- a/third_party/mojo/src/mojo/public/cpp/application/service_provider_impl.h
+++ b/third_party/mojo/src/mojo/public/cpp/application/service_provider_impl.h
@@ -6,57 +6,44 @@
#define MOJO_PUBLIC_APPLICATION_SERVICE_PROVIDER_IMPL_H_
#include "mojo/public/cpp/application/lib/service_connector.h"
+#include "mojo/public/cpp/bindings/binding.h"
#include "mojo/public/interfaces/application/service_provider.mojom.h"
namespace mojo {
namespace internal {
-class WeakServiceProvider;
class ServiceConnectorBase;
}
// Implements a registry that can be used to expose services to another app.
-class ServiceProviderImpl : public InterfaceImpl<ServiceProvider> {
+class ServiceProviderImpl : public ServiceProvider {
public:
ServiceProviderImpl();
+ explicit ServiceProviderImpl(InterfaceRequest<ServiceProvider> request);
~ServiceProviderImpl() override;
+ void Bind(InterfaceRequest<ServiceProvider> request);
+
template <typename Interface>
void AddService(InterfaceFactory<Interface>* factory) {
AddServiceConnector(
new internal::InterfaceFactoryConnector<Interface>(factory));
}
- // Returns an instance of a ServiceProvider that weakly wraps this impl's
- // connection to some other app. Whereas the lifetime of an instance of
- // ServiceProviderImpl is bound to the lifetime of the pipe it
- // encapsulates, the lifetime of the ServiceProvider instance returned by this
- // method is assumed by the caller. After the pipe is closed
- // ConnectToService() calls on this object will be silently dropped.
- // This method must only be called once per ServiceProviderImpl.
- ServiceProvider* CreateRemoteServiceProvider();
-
private:
typedef std::map<std::string, internal::ServiceConnectorBase*>
NameToServiceConnectorMap;
- friend class internal::WeakServiceProvider;
-
// Overridden from ServiceProvider:
void ConnectToService(const String& service_name,
ScopedMessagePipeHandle client_handle) override;
- // Overridden from InterfaceImpl:
- void OnConnectionError() override;
-
void AddServiceConnector(internal::ServiceConnectorBase* service_connector);
void RemoveServiceConnector(
internal::ServiceConnectorBase* service_connector);
- void ClearRemote();
-
NameToServiceConnectorMap service_connectors_;
- internal::WeakServiceProvider* remote_;
+ Binding<ServiceProvider> binding_;
MOJO_DISALLOW_COPY_AND_ASSIGN(ServiceProviderImpl);
};
diff --git a/third_party/mojo/src/mojo/public/cpp/bindings/array.h b/third_party/mojo/src/mojo/public/cpp/bindings/array.h
index ca4e9cc..5194663 100644
--- a/third_party/mojo/src/mojo/public/cpp/bindings/array.h
+++ b/third_party/mojo/src/mojo/public/cpp/bindings/array.h
@@ -18,6 +18,8 @@
namespace mojo {
+// Represents a moveable array with contents of type |T|. The array can be null,
+// meaning that no value has been assigned to it. Null is distinct from empty.
template <typename T>
class Array {
MOJO_MOVE_ONLY_TYPE(Array)
@@ -31,30 +33,42 @@ class Array {
typedef internal::Array_Data<typename internal::WrapperTraits<T>::DataType>
Data_;
+ // Constructs a new array that is null.
Array() : is_null_(true) {}
+
+ // Constructs a new non-null array of the specified size. The elements will
+ // be value-initialized (meaning that they will be initialized by their
+ // default constructor, if any, or else zero-initialized).
explicit Array(size_t size) : vec_(size), is_null_(false) {
Traits::Initialize(&vec_);
}
~Array() { Traits::Finalize(&vec_); }
+ // Moves the contents of |other| into this array.
Array(Array&& other) : is_null_(true) { Take(&other); }
Array& operator=(Array&& other) {
Take(&other);
return *this;
}
+ // Creates a non-null array of the specified size. The elements will be
+ // value-initialized (meaning that they will be initialized by their default
+ // constructor, if any, or else zero-initialized).
static Array New(size_t size) { return Array(size).Pass(); }
+ // Creates a new array with a copy of the contents of |other|.
template <typename U>
static Array From(const U& other) {
return TypeConverter<Array, U>::Convert(other);
}
+ // Copies the contents of this array to a new object of type |U|.
template <typename U>
U To() const {
return TypeConverter<U, Array>::Convert(*this);
}
+ // Resets the contents of this array back to null.
void reset() {
if (!vec_.empty()) {
Traits::Finalize(&vec_);
@@ -63,41 +77,65 @@ class Array {
is_null_ = true;
}
+ // Indicates whether the array is null (which is distinct from empty).
bool is_null() const { return is_null_; }
+ // Returns a reference to the first element of the array. Calling this on a
+ // null or empty array causes undefined behavior.
ConstRefType front() const { return vec_.front(); }
RefType front() { return vec_.front(); }
+ // Returns the size of the array, which will be zero if the array is null.
size_t size() const { return vec_.size(); }
+ // Returns a reference to the element at zero-based |offset|. Calling this on
+ // an array with size less than |offset|+1 causes undefined behavior.
ConstRefType at(size_t offset) const { return Traits::at(&vec_, offset); }
ConstRefType operator[](size_t offset) const { return at(offset); }
-
RefType at(size_t offset) { return Traits::at(&vec_, offset); }
RefType operator[](size_t offset) { return at(offset); }
+ // Pushes |value| onto the back of the array. If this array was null, it will
+ // become non-null with a size of 1.
void push_back(ForwardType value) {
is_null_ = false;
Traits::PushBack(&vec_, value);
}
+ // Resizes the array to |size| and makes it non-null. Otherwise, works just
+ // like the resize method of |std::vector|.
void resize(size_t size) {
is_null_ = false;
Traits::Resize(&vec_, size);
}
+ // Returns a const reference to the |std::vector| managed by this class. If
+ // the array is null, this will be an empty vector.
const std::vector<StorageType>& storage() const { return vec_; }
operator const std::vector<StorageType>&() const { return vec_; }
+ // Swaps the contents of this array with the |other| array, including
+ // nullness.
void Swap(Array* other) {
std::swap(is_null_, other->is_null_);
vec_.swap(other->vec_);
}
+
+ // Swaps the contents of this array with the specified vector, making this
+ // array non-null. Since the vector cannot represent null, it will just be
+ // made empty if this array is null.
void Swap(std::vector<StorageType>* other) {
is_null_ = false;
vec_.swap(*other);
}
+ // Returns a copy of the array where each value of the new array has been
+ // "cloned" from the corresponding value of this array. If this array contains
+ // primitive data types, this is equivalent to simply copying the contents.
+ // However, if the array contains objects, then each new element is created by
+ // calling the |Clone| method of the source element, which should make a copy
+ // of the element.
+ //
// Please note that calling this method will fail compilation if the element
// type cannot be cloned (which usually means that it is a Mojo handle type or
// a type contains Mojo handles).
@@ -108,6 +146,10 @@ class Array {
return result.Pass();
}
+ // Indicates whether the contents of this array are equal to |other|. A null
+ // array is only equal to another null array. Elements are compared using the
+ // |ValueTraits::Equals| method, which in most cases calls the |Equals| method
+ // of the element.
bool Equals(const Array& other) const {
if (is_null() != other.is_null())
return false;
@@ -136,6 +178,9 @@ class Array {
bool is_null_;
};
+// A |TypeConverter| that will create an |Array<T>| containing a copy of the
+// contents of an |std::vector<E>|, using |TypeConverter<T, E>| to copy each
+// element. The returned array will always be non-null.
template <typename T, typename E>
struct TypeConverter<Array<T>, std::vector<E>> {
static Array<T> Convert(const std::vector<E>& input) {
@@ -146,6 +191,9 @@ struct TypeConverter<Array<T>, std::vector<E>> {
}
};
+// A |TypeConverter| that will create an |std::vector<E>| containing a copy of
+// the contents of an |Array<T>|, using |TypeConverter<E, T>| to copy each
+// element. If the input array is null, the output vector will be empty.
template <typename E, typename T>
struct TypeConverter<std::vector<E>, Array<T>> {
static std::vector<E> Convert(const Array<T>& input) {
diff --git a/third_party/mojo/src/mojo/public/cpp/bindings/binding.h b/third_party/mojo/src/mojo/public/cpp/bindings/binding.h
index 4ecc6a8..658b6a0 100644
--- a/third_party/mojo/src/mojo/public/cpp/bindings/binding.h
+++ b/third_party/mojo/src/mojo/public/cpp/bindings/binding.h
@@ -17,8 +17,10 @@
namespace mojo {
-// This binds an interface implementation a pipe. Deleting the binding closes
-// the pipe.
+// Represents the binding of an interface implementation to a message pipe.
+// When the |Binding| object is destroyed, the binding between the message pipe
+// and the interface is torn down and the message pipe is closed, leaving the
+// interface implementation in an unbound state.
//
// Example:
//
@@ -43,13 +45,29 @@ namespace mojo {
// // delete FooImpl on connection errors.
// }
// };
+//
+// The caller may specify a |MojoAsyncWaiter| to be used by the connection when
+// waiting for calls to arrive. Normally it is fine to use the default waiter.
+// However, the caller may provide their own implementation if needed. The
+// |Binding| will not take ownership of the waiter, and the waiter must outlive
+// the |Binding|.
+//
+// TODO(ggowan): Find out under what circumstances the caller may need to
+// provide their own implementation of MojoAsyncWaiter, and then describe those
+// circumstances.
template <typename Interface>
class Binding : public ErrorHandler {
public:
using Client = typename Interface::Client;
+ // Constructs an incomplete binding that will use the implementation |impl|.
+ // The binding may be completed with a subsequent call to the |Bind| method.
+ // Does not take ownership of |impl|, which must outlive the binding.
explicit Binding(Interface* impl) : impl_(impl) { stub_.set_sink(impl_); }
+ // Constructs a completed binding of message pipe |handle| to implementation
+ // |impl|. Does not take ownership of |impl|, which must outlive the binding.
+ // See class comment for definition of |waiter|.
Binding(Interface* impl,
ScopedMessagePipeHandle handle,
const MojoAsyncWaiter* waiter = Environment::GetDefaultAsyncWaiter())
@@ -57,6 +75,12 @@ class Binding : public ErrorHandler {
Bind(handle.Pass(), waiter);
}
+ // Constructs a completed binding of |impl| to a new message pipe, passing the
+ // client end to |ptr|, which takes ownership of it. The caller is expected to
+ // pass |ptr| on to the client of the service. Does not take ownership of any
+ // of the parameters. |impl| must outlive the binding. |ptr| only needs to
+ // last until the constructor returns. See class comment for definition of
+ // |waiter|.
Binding(Interface* impl,
InterfacePtr<Interface>* ptr,
const MojoAsyncWaiter* waiter = Environment::GetDefaultAsyncWaiter())
@@ -64,6 +88,10 @@ class Binding : public ErrorHandler {
Bind(ptr, waiter);
}
+ // Constructs a completed binding of |impl| to the message pipe endpoint in
+ // |request|, taking ownership of the endpoint. Does not take ownership of
+ // |impl|, which must outlive the binding. See class comment for definition of
+ // |waiter|.
Binding(Interface* impl,
InterfaceRequest<Interface> request,
const MojoAsyncWaiter* waiter = Environment::GetDefaultAsyncWaiter())
@@ -71,6 +99,8 @@ class Binding : public ErrorHandler {
Bind(request.PassMessagePipe(), waiter);
}
+ // Tears down the binding, closing the message pipe and leaving the interface
+ // implementation unbound.
~Binding() override {
delete proxy_;
if (internal_router_) {
@@ -79,6 +109,9 @@ class Binding : public ErrorHandler {
}
}
+ // Completes a binding that was constructed with only an interface
+ // implementation. Takes ownership of |handle| and binds it to the previously
+ // specified implementation. See class comment for definition of |waiter|.
void Bind(
ScopedMessagePipeHandle handle,
const MojoAsyncWaiter* waiter = Environment::GetDefaultAsyncWaiter()) {
@@ -95,6 +128,12 @@ class Binding : public ErrorHandler {
proxy_ = new typename Client::Proxy_(internal_router_);
}
+ // Completes a binding that was constructed with only an interface
+ // implementation by creating a new message pipe, binding one end of it to the
+ // previously specified implementation, and passing the other to |ptr|, which
+ // takes ownership of it. The caller is expected to pass |ptr| on to the
+ // eventual client of the service. Does not take ownership of |ptr|. See
+ // class comment for definition of |waiter|.
void Bind(
InterfacePtr<Interface>* ptr,
const MojoAsyncWaiter* waiter = Environment::GetDefaultAsyncWaiter()) {
@@ -103,35 +142,50 @@ class Binding : public ErrorHandler {
Bind(pipe.handle1.Pass(), waiter);
}
+ // Completes a binding that was constructed with only an interface
+ // implementation by removing the message pipe endpoint from |request| and
+ // binding it to the previously specified implementation. See class comment
+ // for definition of |waiter|.
void Bind(
InterfaceRequest<Interface> request,
const MojoAsyncWaiter* waiter = Environment::GetDefaultAsyncWaiter()) {
Bind(request.PassMessagePipe(), waiter);
}
+ // Blocks the calling thread until either a call arrives on the previously
+ // bound message pipe, or an error occurs.
bool WaitForIncomingMethodCall() {
MOJO_DCHECK(internal_router_);
return internal_router_->WaitForIncomingMessage();
}
+ // Closes the message pipe that was previously bound.
void Close() {
MOJO_DCHECK(internal_router_);
internal_router_->CloseMessagePipe();
}
+ // Sets an error handler that will be called if a connection error occurs on
+ // the bound message pipe.
void set_error_handler(ErrorHandler* error_handler) {
error_handler_ = error_handler;
}
- // ErrorHandler implementation
+ // Implements the |Binding|'s response to a connection error.
void OnConnectionError() override {
if (error_handler_)
error_handler_->OnConnectionError();
}
+ // Returns the interface implementation that was previously specified. Caller
+ // does not take ownership.
Interface* impl() { return impl_; }
+
+ // Returns the client's interface.
Client* client() { return proxy_; }
+ // Indicates whether the binding has been completed (i.e., whether a message
+ // pipe has been bound to the implementation).
bool is_bound() const { return !!internal_router_; }
// Exposed for testing, should not generally be used.
diff --git a/third_party/mojo/src/mojo/public/cpp/bindings/interface_request.h b/third_party/mojo/src/mojo/public/cpp/bindings/interface_request.h
index 1723330..0b89103 100644
--- a/third_party/mojo/src/mojo/public/cpp/bindings/interface_request.h
+++ b/third_party/mojo/src/mojo/public/cpp/bindings/interface_request.h
@@ -16,7 +16,12 @@ class InterfaceRequest {
public:
InterfaceRequest() {}
+ InterfaceRequest(decltype(nullptr)) {}
InterfaceRequest(InterfaceRequest&& other) { handle_ = other.handle_.Pass(); }
+ InterfaceRequest& operator=(decltype(nullptr)) {
+ handle_.reset();
+ return *this;
+ }
InterfaceRequest& operator=(InterfaceRequest&& other) {
handle_ = other.handle_.Pass();
return *this;
diff --git a/third_party/mojo/src/mojo/public/dart/README b/third_party/mojo/src/mojo/public/dart/README
index f9cd6e6..fd75b8f 100644
--- a/third_party/mojo/src/mojo/public/dart/README
+++ b/third_party/mojo/src/mojo/public/dart/README
@@ -2,26 +2,16 @@ These are interim instructions for building and testing Dart's Mojo bindings.
These instructions currently only work for Linux, and assume you already have a
Mojo checkout.
-1.) Add a Dart VM source checkout to your client:
-
- Edit your .gclient file. Replace "DEPS" with "DEPS.dart".
- Then, run:
-
- $ gclient sync
-
- You should now have a directory //dart
-
-
-2.) Configure Mojo with Dart.
+1.) Configure Mojo with Dart.
$ ./mojo/tools/mojob.py gn --release --with-dart
-3.) Build Mojo with Dart.
+2.) Build Mojo with Dart.
$ ./mojo/tools/mojob.py build --release
-4.) Run Dart tests.
+3.) Run Dart tests.
$ ./mojo/tools/mojob.py darttest --release
diff --git a/third_party/mojo/src/mojo/public/dart/bindings.dart b/third_party/mojo/src/mojo/public/dart/bindings.dart
index 5d6298e..0637737 100644
--- a/third_party/mojo/src/mojo/public/dart/bindings.dart
+++ b/third_party/mojo/src/mojo/public/dart/bindings.dart
@@ -6,7 +6,6 @@ library bindings;
import 'dart:async';
import 'dart:convert';
-import 'dart:mirrors';
import 'dart:mojo_core' as core;
import 'dart:typed_data';
diff --git a/third_party/mojo/src/mojo/public/dart/core.dart b/third_party/mojo/src/mojo/public/dart/core.dart
index e9fb716..ecd671d 100644
--- a/third_party/mojo/src/mojo/public/dart/core.dart
+++ b/third_party/mojo/src/mojo/public/dart/core.dart
@@ -11,6 +11,7 @@ import 'dart:typed_data';
part 'src/buffer.dart';
part 'src/data_pipe.dart';
+part 'src/drain_data.dart';
part 'src/event_stream.dart';
part 'src/handle.dart';
part 'src/handle_watcher.dart';
diff --git a/third_party/mojo/src/mojo/public/dart/src/drain_data.dart b/third_party/mojo/src/mojo/public/dart/src/drain_data.dart
new file mode 100644
index 0000000..ffc56e5
--- /dev/null
+++ b/third_party/mojo/src/mojo/public/dart/src/drain_data.dart
@@ -0,0 +1,68 @@
+// 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.
+
+part of core;
+
+class DataPipeDrainer {
+ MojoDataPipeConsumer _consumer;
+ MojoEventStream _eventStream;
+ List<ByteData> _dataList;
+ int _dataSize;
+
+ DataPipeDrainer(this._consumer) {
+ _eventStream = new MojoEventStream(_consumer.handle);
+ _dataList = new List();
+ _dataSize = 0;
+ }
+
+ MojoResult _doRead() {
+ ByteData thisRead = _consumer.beginRead();
+ if (thisRead == null) {
+ throw 'Data pipe beginRead failed: ${_consumer.status}';
+ }
+ _dataList.add(thisRead);
+ _dataSize += thisRead.lengthInBytes;
+ return _consumer.endRead(thisRead.lengthInBytes);
+ }
+
+ ByteData _concatData() {
+ var data = new ByteData(_dataSize);
+ int end = 0;
+ for (var chunk in _dataList) {
+ data.buffer.asUint8List().setRange(
+ end, end + chunk.lengthInBytes, chunk.buffer.asUint8List());
+ end += chunk.lengthInBytes;
+ }
+ return data;
+ }
+
+ Future<ByteData> drain() {
+ var completer = new Completer();
+ _eventStream.listen((List<int> event) {
+ var mojoSignals = new MojoHandleSignals(event[1]);
+ if (mojoSignals.isReadable) {
+ var result = _doRead();
+ if (!result.isOk) {
+ _eventStream.close();
+ _eventStream = null;
+ completer.complete(_concatData());
+ } else {
+ _eventStream.enableReadEvents();
+ }
+ } else if (mojoSignals.isPeerClosed) {
+ _eventStream.close();
+ _eventStream = null;
+ completer.complete(_concatData());
+ } else {
+ throw 'Unexpected handle event: $mojoSignals';
+ }
+ });
+ return completer.future;
+ }
+
+ static Future<ByteData> drainHandle(MojoDataPipeConsumer consumer) {
+ var drainer = new DataPipeDrainer(consumer);
+ return drainer.drain();
+ }
+}
diff --git a/third_party/mojo/src/mojo/public/dart/src/event_stream.dart b/third_party/mojo/src/mojo/public/dart/src/event_stream.dart
index 797f0e6..7016b31 100644
--- a/third_party/mojo/src/mojo/public/dart/src/event_stream.dart
+++ b/third_party/mojo/src/mojo/public/dart/src/event_stream.dart
@@ -176,8 +176,10 @@ class MojoEventStreamListener {
assert(_eventStream.readyWrite);
handleWrite();
}
- _eventStream.enableSignals(enableSignals(
- signalsWatched, signalsReceived));
+ if (_isOpen) {
+ _eventStream.enableSignals(enableSignals(
+ signalsWatched, signalsReceived));
+ }
_isInHandler = false;
});
}
diff --git a/third_party/mojo/src/mojo/public/dart/src/types.dart b/third_party/mojo/src/mojo/public/dart/src/types.dart
index 54c5319..49f0398 100644
--- a/third_party/mojo/src/mojo/public/dart/src/types.dart
+++ b/third_party/mojo/src/mojo/public/dart/src/types.dart
@@ -127,11 +127,12 @@ class MojoHandleSignals {
static const int kReadWrite = kReadable | kWritable;
static const int kAll = kReadable | kWritable | kPeerClosed;
- // TODO(zra): Does PEER_CLOSED | anything else make sense?
static const NONE = const MojoHandleSignals._(kNone);
static const READABLE = const MojoHandleSignals._(kReadable);
static const WRITABLE = const MojoHandleSignals._(kWritable);
static const PEER_CLOSED = const MojoHandleSignals._(kPeerClosed);
+ static const PEER_CLOSED_READABLE =
+ const MojoHandleSignals._(kPeerClosed | kReadable);
static const READWRITE = const MojoHandleSignals._(kReadWrite);
static const ALL = const MojoHandleSignals._(kAll);
@@ -146,9 +147,10 @@ class MojoHandleSignals {
case kWritable: return WRITABLE;
case kPeerClosed: return PEER_CLOSED;
case kReadWrite: return READWRITE;
+ case kPeerClosed | kReadable: return PEER_CLOSED_READABLE;
case kAll: return ALL;
default:
- throw 'Invalid handle signal';
+ throw 'Invalid handle signal: $value';
}
}
@@ -174,8 +176,9 @@ class MojoHandleSignals {
case kWritable: return "WRITABLE";
case kPeerClosed: return "PEER_CLOSED";
case kReadWrite: return "READWRITE";
+ case kPeerClosed | kReadable: return "PEER_CLOSED_READABLE";
case kAll: return "ALL";
- default: return "<invalid signal>";
+ default: return "<invalid signals>";
}
}
}
diff --git a/third_party/mojo/src/mojo/public/go/system/c_allocators.c b/third_party/mojo/src/mojo/public/go/system/c_allocators.c
index 7af7bb2..2f93908 100644
--- a/third_party/mojo/src/mojo/public/go/system/c_allocators.c
+++ b/third_party/mojo/src/mojo/public/go/system/c_allocators.c
@@ -157,3 +157,15 @@ void FreeWriteDataParams(struct WriteDataParams p) {
free(p.num_bytes);
free(p.elements);
}
+
+struct TwoPhaseActionParams MallocTwoPhaseActionParams() {
+ struct TwoPhaseActionParams p;
+ p.buffer = (void**)malloc(sizeof(void*));
+ p.num_bytes = (uint32_t*)malloc(sizeof(uint32_t));
+ return p;
+}
+
+void FreeTwoPhaseActionParams(struct TwoPhaseActionParams p) {
+ free(p.buffer);
+ free(p.num_bytes);
+}
diff --git a/third_party/mojo/src/mojo/public/go/system/c_allocators.h b/third_party/mojo/src/mojo/public/go/system/c_allocators.h
index f915e6b..6050507 100644
--- a/third_party/mojo/src/mojo/public/go/system/c_allocators.h
+++ b/third_party/mojo/src/mojo/public/go/system/c_allocators.h
@@ -126,4 +126,11 @@ struct WriteDataParams {
struct WriteDataParams MallocWriteDataParams(uint32_t length);
void FreeWriteDataParams(struct WriteDataParams p);
+struct TwoPhaseActionParams {
+ void** buffer;
+ uint32_t* num_bytes;
+};
+struct TwoPhaseActionParams MallocTwoPhaseActionParams();
+void FreeTwoPhaseActionParams(struct TwoPhaseActionParams p);
+
#endif // MOJO_PUBLIC_GO_SYSTEM_C_ALLOCATORS_H_
diff --git a/third_party/mojo/src/mojo/public/go/system/data_pipe.go b/third_party/mojo/src/mojo/public/go/system/data_pipe.go
index 7de27d1..b79a1e0 100644
--- a/third_party/mojo/src/mojo/public/go/system/data_pipe.go
+++ b/third_party/mojo/src/mojo/public/go/system/data_pipe.go
@@ -16,6 +16,31 @@ type ConsumerHandle interface {
// ReadData reads data from the data pipe consumer handle with the
// given flags. On success, returns the data that was read.
ReadData(flags MojoReadDataFlags) (MojoResult, []byte)
+
+ // BeginReadData begins a two-phase read from the data pipe consumer.
+ // On success, returns a slice from which the caller can read up to its
+ // length bytes of data. If flags has |MOJO_READ_DATA_FLAG_ALL_OR_NONE|
+ // set, then the slice length will be at least as large as |numBytes|,
+ // which must also be a multiple of the element size (otherwise the
+ // caller must check the length of the slice).
+ //
+ // During a two-phase read, this handle is *not* readable. E.g., read
+ // from this handle will return |MOJO_RESULT_BUSY|.
+ //
+ // Once the caller has finished reading data from the slice, it should
+ // call |EndReadData()| to specify the amount read and to complete the
+ // two-phase read.
+ BeginReadData(numBytes int, flags MojoReadDataFlags) (MojoResult, []byte)
+
+ // EndReadData ends a two-phase read from the data pipe consumer that
+ // was begun by a call to |BeginReadData()| on the same handle.
+ // |numBytesRead| should indicate the amount of data actually read; it
+ // must be less than or equal to the length of the slice returned by
+ // |BeginReadData()| and must be a multiple of the element size.
+ //
+ // On failure, the two-phase read (if any) is ended (so the handle may
+ // become readable again) but no data is "removed" from the data pipe.
+ EndReadData(numBytesRead int) MojoResult
}
// ProducerHandle is a handle for the producer part of a data pipe.
@@ -26,6 +51,34 @@ type ProducerHandle interface {
// given flags. On success, returns the number of bytes that were
// actually written.
WriteData(data []byte, flags MojoWriteDataFlags) (MojoResult, int)
+
+ // BeginWriteData begins a two-phase write to the data pipe producer.
+ // On success, returns a slice to which the caller can write. If flags
+ // has |MOJO_READ_DATA_FLAG_ALL_OR_NONE| set, then the slice length will
+ // be at least as large as |numBytes|, which must also be a multiple of
+ // the element size (otherwise the caller must check the length of the
+ // slice).
+ //
+ // During a two-phase write, this handle is *not* writable. E.g., write
+ // to this handle will return |MOJO_RESULT_BUSY|.
+ //
+ // Once the caller has finished writing data to the buffer, it should
+ // call |EndWriteData()| to specify the amount written and to complete
+ // the two-phase write.
+ BeginWriteData(numBytes int, flags MojoWriteDataFlags) (MojoResult, []byte)
+
+ // EndWriteData ends a two-phase write to the data pipe producer that
+ // was begun by a call to |BeginWriteData()| on the same handle.
+ // |numBytesWritten| should indicate the amount of data actually
+ // written; it must be less than or equal to the length of the slice
+ // returned by |BeginWriteData()| and must be a multiple of the element
+ // size. The slice returned from |BeginWriteData()| must have been
+ // filled with exactly |numBytesWritten| bytes of data.
+ //
+ // On failure, the two-phase write (if any) is ended (so the handle may
+ // become writable again, if there's space available) but no data
+ // written to the slice is "put into" the data pipe.
+ EndWriteData(numBytesWritten int) MojoResult
}
type dataPipeConsumer struct {
@@ -49,6 +102,19 @@ func (h *dataPipeConsumer) ReadData(flags MojoReadDataFlags) (MojoResult, []byte
return MojoResult(result), data
}
+func (h *dataPipeConsumer) BeginReadData(numBytes int, flags MojoReadDataFlags) (MojoResult, []byte) {
+ cParams := C.MallocTwoPhaseActionParams()
+ defer C.FreeTwoPhaseActionParams(cParams)
+ *cParams.num_bytes = C.uint32_t(numBytes)
+ result := C.MojoBeginReadData(h.mojoHandle.cValue(), cParams.buffer, cParams.num_bytes, flags.cValue())
+ buffer := unsafeByteSlice(unsafe.Pointer(*cParams.buffer), int(*cParams.num_bytes))
+ return MojoResult(result), buffer
+}
+
+func (h *dataPipeConsumer) EndReadData(numBytesRead int) MojoResult {
+ return MojoResult(C.MojoEndReadData(h.mojoHandle.cValue(), C.uint32_t(numBytesRead)))
+}
+
type dataPipeProducer struct {
baseHandle
}
@@ -62,3 +128,16 @@ func (h *dataPipeProducer) WriteData(data []byte, flags MojoWriteDataFlags) (Moj
result := C.MojoWriteData(h.mojoHandle.cValue(), cParams.elements, cParams.num_bytes, flags.cValue())
return MojoResult(result), int(*cParams.num_bytes)
}
+
+func (h *dataPipeProducer) BeginWriteData(numBytes int, flags MojoWriteDataFlags) (MojoResult, []byte) {
+ cParams := C.MallocTwoPhaseActionParams()
+ defer C.FreeTwoPhaseActionParams(cParams)
+ *cParams.num_bytes = C.uint32_t(numBytes)
+ result := C.MojoBeginWriteData(h.mojoHandle.cValue(), cParams.buffer, cParams.num_bytes, flags.cValue())
+ buffer := unsafeByteSlice(unsafe.Pointer(*cParams.buffer), int(*cParams.num_bytes))
+ return MojoResult(result), buffer
+}
+
+func (h *dataPipeProducer) EndWriteData(numBytesWritten int) MojoResult {
+ return MojoResult(C.MojoEndWriteData(h.mojoHandle.cValue(), C.uint32_t(numBytesWritten)))
+}
diff --git a/third_party/mojo/src/mojo/public/interfaces/application/application.mojom b/third_party/mojo/src/mojo/public/interfaces/application/application.mojom
index d389ae2..b1508a8e 100644
--- a/third_party/mojo/src/mojo/public/interfaces/application/application.mojom
+++ b/third_party/mojo/src/mojo/public/interfaces/application/application.mojom
@@ -6,19 +6,39 @@ module mojo;
import "mojo/public/interfaces/application/service_provider.mojom";
-// Applications vend Services through the ServiceProvider interface. Services
-// implement Interfaces.
+// This is the primary interface implemented by every Mojo application. It
+// allows the application to receive its startup arguments from the shell, and
+// to be notified of events that occur during its execution.
interface Application {
- // Initialize is guaranteed to be called before any AcceptConnection calls.
+ // Initializes the application with the specified arguments. This method is
+ // guaranteed to be called before any other method is called, and will only be
+ // called once.
Initialize(array<string>? args);
- // Called in response to a call to mojo.Shell.ConnectToApplication().
- // The |services| and |exposed_services| parameters are the same as those on
- // mojo.Shell.ConnectToApplication().
- // |services| will be used to look up services provided by this application.
- // |exposed_services| can be used to look up services exposed by the
- // application at |requestor_url|.
+ // Called when another application (identified by |requestor_url|) attempts to
+ // open a connection to this application.
+ //
+ // If the other application wants to request services from this application,
+ // it will have passed a valid interface request through the |services|
+ // parameter (i.e. one containing a valid message pipe endpoint). This
+ // application may then bind an implementation of |ServiceProvider| to that
+ // request in order to make services available to the other application.
+ //
+ // If the other application wants to offer services to this application, it
+ // will have passed a bound interface through the |exposed_services|
+ // parameter. This application may then request services through that
+ // interface.
+ //
+ // It is possible that both parameters will be valid/bound if the other
+ // application wants to both request services from and offer services to this
+ // application.
+ //
+ // This application is free to ignore the |services| or |exposed_services|
+ // parameters if it does not wish to offer or request services.
AcceptConnection(string requestor_url,
ServiceProvider&? services,
ServiceProvider? exposed_services);
+
+ // Called to request the application shut itself down gracefully.
+ RequestQuit();
};
diff --git a/third_party/mojo/src/mojo/public/interfaces/application/service_provider.mojom b/third_party/mojo/src/mojo/public/interfaces/application/service_provider.mojom
index b862d35..8c81879 100644
--- a/third_party/mojo/src/mojo/public/interfaces/application/service_provider.mojom
+++ b/third_party/mojo/src/mojo/public/interfaces/application/service_provider.mojom
@@ -4,11 +4,14 @@
module mojo;
-// ServiceProvider is used to establish connections to services in a bi-
-// directional fashion between two applications.
-[Client=ServiceProvider]
+// An interface through which a client may request services from a host.
+// Instances of this interface are created within the context of an
+// already-identified client and host pair, so there is no need to explicitly
+// identify the client or host in the methods below.
interface ServiceProvider {
- // Connect the given message pipe handle to the named service. If the named
- // service does not exist, then the handle will be closed.
+ // Asks the host to provide the service identified by |interface_name| through
+ // the message |pipe| endpoint supplied by the caller. If the host is not
+ // willing or able to provide the requested service, it should close the
+ // |pipe|.
ConnectToService(string interface_name, handle<message_pipe> pipe);
};
diff --git a/third_party/mojo/src/mojo/public/interfaces/application/shell.mojom b/third_party/mojo/src/mojo/public/interfaces/application/shell.mojom
index 1adf1e6..7804b9f 100644
--- a/third_party/mojo/src/mojo/public/interfaces/application/shell.mojom
+++ b/third_party/mojo/src/mojo/public/interfaces/application/shell.mojom
@@ -7,14 +7,33 @@ module mojo;
import "mojo/public/interfaces/application/application.mojom";
import "mojo/public/interfaces/application/service_provider.mojom";
-// The Shell is the finder and launcher of Applications. An Application uses
-// it's Shell interface to connect to other Applications.
+// An interface through which a Mojo application may communicate with the Mojo
+// system and request connections to other applications.
[Client=Application]
interface Shell {
- // Loads |application_url|. mojo:{service} will result in the user of the value of the
- // --origin flag to the shell being used.
- // |services| can be used to look up services provided by the application at |application_url|.
- // |exposed_services| can be used to expose services to the application at |application_url|.
+ // Establishes a connection with another application (identified by
+ // |application_url|) through which the calling application and the other
+ // application may request services from one another.
+ //
+ // If the calling application would like to request services from the other
+ // application, it should pass a valid interface request in the |services|
+ // parameter (i.e. one containing a valid message pipe endpoint). If the other
+ // application does not wish to offer services, it may either not bind an
+ // implementation to the interface request, or else bind an implementation
+ // that will reject some or all service requests.
+ //
+ // If the calling application would like to offer services to the other
+ // application, it should pass a bound interface through the
+ // |exposed_services| parameter. The other application may then request
+ // services through that interface.
+ //
+ // At least one of |services| or |exposed_services| should be valid/bound in
+ // the call.
+ //
+ // If the |application_url| does not contain a domain, but is of the form
+ // "mojo:{service}", it is up to the Mojo shell to select an appropriate
+ // application for the service. Currently, the shell does this based on the
+ // value of its --origin flag.
ConnectToApplication(string application_url,
ServiceProvider&? services,
ServiceProvider? exposed_services);
diff --git a/third_party/mojo/src/mojo/public/mojo.gni b/third_party/mojo/src/mojo/public/mojo.gni
index b310260..b87c463 100644
--- a/third_party/mojo/src/mojo/public/mojo.gni
+++ b/third_party/mojo/src/mojo/public/mojo.gni
@@ -6,9 +6,6 @@ declare_args() {
# Whether to use a prebuilt mojo_shell binary instead of one built from
# source.
use_prebuilt_mojo_shell = false
-
- # Whether to build the dart bindings.
- mojo_use_dart = false
}
# The absolute path to the directory containing the mojo public SDK (i.e., the
diff --git a/third_party/mojo/src/mojo/public/tools/bindings/generators/dart_templates/interface_definition.tmpl b/third_party/mojo/src/mojo/public/tools/bindings/generators/dart_templates/interface_definition.tmpl
index d9fee1c..0289345 100644
--- a/third_party/mojo/src/mojo/public/tools/bindings/generators/dart_templates/interface_definition.tmpl
+++ b/third_party/mojo/src/mojo/public/tools/bindings/generators/dart_templates/interface_definition.tmpl
@@ -79,7 +79,10 @@ class {{interface|name}}Client extends bindings.Client with {{interface|name}}Ca
}
}
-
+{#--- TODO(zra): Remove Interface suffix from the name of this class.
+ This is tricky because some mojom files have interfaces named both
+ X and XClient. This leads to an XClient for the Client of X, and an
+ XClient for the Interface of XClient, which conflict with eachother. #}
class {{interface|name}}Interface extends bindings.Interface
{% if interface.client != None -%}
with {{imported_from[interface.client]}}{{interface.client|upper_camel_case}}Calls
@@ -114,16 +117,29 @@ with {{imported_from[interface.client]}}{{interface.client|upper_camel_case}}Cal
}
{%- else %}
{%- set response_struct = method|response_struct_from_method %}
+ {{response_struct|name}} _{{response_struct|name}}Factory(
+ {%- for param in method.response_parameters -%}
+ {{param.kind|dart_type}} {{param|name}}{% if not loop.last %}, {% endif %}
+ {%- endfor -%}
+ ) {
+ var result = new {{response_struct|name}}();
+ {%- for param in method.response_parameters %}
+ result.{{param|name}} = {{param|name}};
+ {%- endfor %}
+ return result;
+ }
+
Future<{{response_struct|name}}> {{method|name}}(
{%- for parameter in method.parameters -%}
- {{parameter.kind|dart_type}} {{parameter|name}}{% if not loop.last %}, {% endif %}
+ {{parameter.kind|dart_type}} {{parameter|name}},
{%- endfor -%}
- ) {
+ Function responseFactory) {
assert(_delegate != null);
return _delegate.{{method|name}}(
{%- for parameter in method.parameters -%}
- {{parameter|name}}{% if not loop.last %}, {% endif %}
- {%- endfor %});
+ {{parameter|name}},
+ {%- endfor %}
+ responseFactory);
}
{%- endif %}
{%- endfor %}
@@ -142,11 +158,12 @@ with {{imported_from[interface.client]}}{{interface.client|upper_camel_case}}Cal
{%- endfor -%}
);
{%- else %}
+{%- set response_struct = method|response_struct_from_method %}
return {{method|name}}(
{%- for parameter in method.parameters -%}
- params.{{parameter|name}}{% if not loop.last %}, {% endif %}
+ params.{{parameter|name}},
{%- endfor -%}
- ).then((response) {
+ _{{response_struct|name}}Factory).then((response) {
if (response != null) {
return buildResponseWithId(
response,
diff --git a/third_party/mojo/src/mojo/public/tools/bindings/generators/mojom_dart_generator.py b/third_party/mojo/src/mojo/public/tools/bindings/generators/mojom_dart_generator.py
index 893e665..9862943 100644
--- a/third_party/mojo/src/mojo/public/tools/bindings/generators/mojom_dart_generator.py
+++ b/third_party/mojo/src/mojo/public/tools/bindings/generators/mojom_dart_generator.py
@@ -121,8 +121,8 @@ _spec_to_encode_method = {
def GetDartType(kind):
if kind.imported_from:
- return kind.imported_from["unique_name"] + "." + kind.name
- return kind.name
+ return kind.imported_from["unique_name"] + "." + GetNameForElement(kind)
+ return GetNameForElement(kind)
def DartDefaultValue(field):
if field.default: