Skip to content

Commit

Permalink
Implement BroadcastChannel as specified in https://html.spec.whatwg.o…
Browse files Browse the repository at this point in the history
…rg/multipage/comms.html#broadcastchannel

BUG=161070

Review-Url: https://codereview.chromium.org/2004643002
Cr-Commit-Position: refs/heads/master@{#403331}
  • Loading branch information
mkruisselbrink authored and Commit bot committed Jun 30, 2016
1 parent 9348eec commit e69cdae
Show file tree
Hide file tree
Showing 41 changed files with 1,028 additions and 7 deletions.
2 changes: 2 additions & 0 deletions components/OWNERS
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,8 @@ per-file web_restrictions.gypi=file://components/web_restrictions/OWNERS
per-file webdata.gypi=file://components/webdata/OWNERS
per-file webdata_services.gypi=file://components/webdata_services/OWNERS

per-file webmessaging.gypi=file://components/webmessaging/OWNERS

per-file webp_transcode.gypi=file://components/webp_transcode/OWNERS

per-file webusb.gypi=file://components/webusb/OWNERS
Expand Down
1 change: 1 addition & 0 deletions components/components.gyp
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@
'web_cache.gypi',
'web_contents_delegate_android.gypi',
'web_modal.gypi',
'webmessaging.gypi',
'webusb.gypi',
'zoom.gypi',
],
Expand Down
69 changes: 69 additions & 0 deletions components/webmessaging.gypi
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# Copyright 2016 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.

{
'variables': {
'chromium_code': 1,
'mojom_files': [
'webmessaging/public/interfaces/broadcast_channel.mojom',
],
},
'targets': [
{
# GN version: //components/webmessaging/webmessaging
'target_name': 'webmessaging',
'type': 'static_library',
'dependencies': [
'webmessaging_mojo_bindings',
'../base/base.gyp:base',
'../url/url.gyp:url_lib',
],
'sources': [
'webmessaging/broadcast_channel_provider.cc',
'webmessaging/broadcast_channel_provider.h',
],
},
{
'target_name': 'webmessaging_mojo_bindings',
'type': 'static_library',
'sources': [ '<@(mojom_files)' ],
'dependencies': [
'../url/url.gyp:url_mojom',
],
'export_dependent_settings': [
'../url/url.gyp:url_mojom',
],
'variables': {
'mojom_typemaps': [
'../url/mojo/gurl.typemap',
'../url/mojo/origin.typemap',
],
},
'includes': [
'../mojo/mojom_bindings_generator.gypi',
],
},
{
'target_name': 'webmessaging_mojo_bindings_for_blink',
'type': 'static_library',
'sources': [ '<@(mojom_files)' ],
'dependencies': [
'../url/url.gyp:url_mojom_for_blink',
],
'export_dependent_settings': [
'../url/url.gyp:url_mojom_for_blink',
],
'variables': {
'for_blink': 'true',
'mojom_typemaps': [
'../third_party/WebKit/Source/platform/mojo/KURL.typemap',
'../third_party/WebKit/Source/platform/mojo/SecurityOrigin.typemap',
],
},
'includes': [
'../mojo/mojom_bindings_generator.gypi',
],
},
],
}
17 changes: 17 additions & 0 deletions components/webmessaging/BUILD.gn
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Copyright 2016 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.

static_library("webmessaging") {
sources = [
"broadcast_channel_provider.cc",
"broadcast_channel_provider.h",
]

deps = [
"//base",
"//components/webmessaging/public/interfaces",
"//mojo/common",
"//url",
]
}
3 changes: 3 additions & 0 deletions components/webmessaging/DEPS
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
include_rules = [
"+mojo/public",
]
1 change: 1 addition & 0 deletions components/webmessaging/OWNERS
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
mek@chromium.org
115 changes: 115 additions & 0 deletions components/webmessaging/broadcast_channel_provider.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
// Copyright 2016 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 "components/webmessaging/broadcast_channel_provider.h"

#include "base/bind.h"
#include "base/stl_util.h"
#include "mojo/public/cpp/bindings/associated_binding.h"
#include "mojo/public/cpp/bindings/interface_ptr_set.h"
#include "mojo/public/cpp/bindings/strong_binding.h"

namespace webmessaging {

// There is a one-to-one mapping of BroadcastChannel instances in the renderer
// and Connection instances in the browser. The Connection is owned by a
// BroadcastChannelProvider.
class BroadcastChannelProvider::Connection
: public mojom::BroadcastChannelClient {
public:
Connection(const url::Origin& origin,
const mojo::String& name,
mojom::BroadcastChannelClientAssociatedPtrInfo client,
mojom::BroadcastChannelClientAssociatedRequest connection,
webmessaging::BroadcastChannelProvider* service);

void OnMessage(const mojo::String& message) override;
void MessageToClient(const mojo::String& message) const {
client_->OnMessage(message);
}
const url::Origin& origin() const { return origin_; }
const std::string& name() const { return name_; }

void set_connection_error_handler(const base::Closure& error_handler) {
binding_.set_connection_error_handler(error_handler);
client_.set_connection_error_handler(error_handler);
}

private:
mojo::AssociatedBinding<mojom::BroadcastChannelClient> binding_;
mojom::BroadcastChannelClientAssociatedPtr client_;

webmessaging::BroadcastChannelProvider* service_;
url::Origin origin_;
std::string name_;
};

BroadcastChannelProvider::Connection::Connection(
const url::Origin& origin,
const mojo::String& name,
mojom::BroadcastChannelClientAssociatedPtrInfo client,
mojom::BroadcastChannelClientAssociatedRequest connection,
webmessaging::BroadcastChannelProvider* service)
: binding_(this, std::move(connection)),
service_(service),
origin_(origin),
name_(name) {
client_.Bind(std::move(client));
}

void BroadcastChannelProvider::Connection::OnMessage(
const mojo::String& message) {
service_->ReceivedMessageOnConnection(this, message);
}

BroadcastChannelProvider::BroadcastChannelProvider() {}

void BroadcastChannelProvider::Connect(
mojo::InterfaceRequest<mojom::BroadcastChannelProvider> request) {
bindings_.AddBinding(this, std::move(request));
}

void BroadcastChannelProvider::ConnectToChannel(
const url::Origin& origin,
const mojo::String& name,
mojom::BroadcastChannelClientAssociatedPtrInfo client,
mojom::BroadcastChannelClientAssociatedRequest connection) {
std::unique_ptr<Connection> c(new Connection(origin, name, std::move(client),
std::move(connection), this));
c->set_connection_error_handler(
base::Bind(&BroadcastChannelProvider::UnregisterConnection,
base::Unretained(this), c.get()));
connections_[origin].insert(std::make_pair(name, std::move(c)));
}

BroadcastChannelProvider::~BroadcastChannelProvider() {}

void BroadcastChannelProvider::UnregisterConnection(Connection* c) {
url::Origin origin = c->origin();
auto& connections = connections_[origin];
for (auto it = connections.lower_bound(c->name()),
end = connections.upper_bound(c->name());
it != end; ++it) {
if (it->second.get() == c) {
connections.erase(it);
break;
}
}
if (connections.empty())
connections_.erase(origin);
}

void BroadcastChannelProvider::ReceivedMessageOnConnection(
Connection* c,
const mojo::String& message) {
auto& connections = connections_[c->origin()];
for (auto it = connections.lower_bound(c->name()),
end = connections.upper_bound(c->name());
it != end; ++it) {
if (it->second.get() != c)
it->second->MessageToClient(message);
}
}

} // namespace webmessaging
46 changes: 46 additions & 0 deletions components/webmessaging/broadcast_channel_provider.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// Copyright 2016 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 COMPONENTS_WEBMESSAGING_BROADCAST_CHANNEL_PROVIDER_H_
#define COMPONENTS_WEBMESSAGING_BROADCAST_CHANNEL_PROVIDER_H_

#include <map>

#include "base/memory/ref_counted.h"
#include "components/webmessaging/public/interfaces/broadcast_channel.mojom.h"
#include "mojo/public/cpp/bindings/binding_set.h"
#include "url/origin.h"

namespace webmessaging {

class BroadcastChannelProvider
: public base::RefCountedThreadSafe<BroadcastChannelProvider>,
public mojom::BroadcastChannelProvider {
public:
BroadcastChannelProvider();
void Connect(mojo::InterfaceRequest<mojom::BroadcastChannelProvider> request);

void ConnectToChannel(
const url::Origin& origin,
const mojo::String& name,
mojom::BroadcastChannelClientAssociatedPtrInfo client,
mojom::BroadcastChannelClientAssociatedRequest connection) override;

private:
friend class base::RefCountedThreadSafe<BroadcastChannelProvider>;
class Connection;

~BroadcastChannelProvider() override;

void UnregisterConnection(Connection*);
void ReceivedMessageOnConnection(Connection*, const mojo::String& message);

mojo::BindingSet<mojom::BroadcastChannelProvider> bindings_;
std::map<url::Origin, std::multimap<std::string, std::unique_ptr<Connection>>>
connections_;
};

} // namespace webmessaging

#endif // COMPONENTS_WEBMESSAGING_BROADCAST_CHANNEL_PROVIDER_H_
14 changes: 14 additions & 0 deletions components/webmessaging/public/interfaces/BUILD.gn
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Copyright 2016 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.

import("//mojo/public/tools/bindings/mojom.gni")

mojom("interfaces") {
sources = [
"broadcast_channel.mojom",
]
deps = [
"//url/mojo:url_mojom_origin",
]
}
2 changes: 2 additions & 0 deletions components/webmessaging/public/interfaces/OWNERS
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
per-file *.mojom=set noparent
per-file *.mojom=file://ipc/SECURITY_OWNERS
34 changes: 34 additions & 0 deletions components/webmessaging/public/interfaces/broadcast_channel.mojom
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// Copyright 2016 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 webmessaging.mojom;

import "url/mojo/origin.mojom";

// A pair of BroadcastChannelClient interfaces is used to represent a connection
// to a particular channel. One client is implemented in the browser, for
// messages sent from the renderer to the browser, and one client is implemented
// in the renderer for messages from the browser to the renderer.
interface BroadcastChannelClient {
// Messages are passed as SerializedScriptValue.
OnMessage(string message);
};

// This interface is used to set up connections to broadcast channels. All
// connections to channels made from the same event loop should be made
// through the same BroadcastChannelProvider connection to ensure correct
// ordering of messages.
// Typically the browser will have one instance of a BroadcastChannelProvider
// per storage partition, to which all connections from renderers in that
// partition are bound. This instance will then forward messages received on a
// particular connection to all other connections in the same storage partition
// with the same origin and name.
interface BroadcastChannelProvider {
// Connect to the channel identified by the |origin| and |name|. Messages can
// be sent to the channel using |sender|, and messages to the channel will be
// received by |receiver|.
ConnectToChannel(url.mojom.Origin origin, string name,
associated BroadcastChannelClient receiver,
associated BroadcastChannelClient& sender);
};
1 change: 1 addition & 0 deletions content/browser/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ source_set("browser") {
"//components/tracing",
"//components/tracing:startup_tracing",
"//components/url_formatter",
"//components/webmessaging",
"//content:resources",
"//content/app/resources",
"//content/app/strings",
Expand Down
1 change: 1 addition & 0 deletions content/browser/DEPS
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ include_rules = [
"+components/scheduler/common",
"+components/tracing",
"+components/url_formatter",
"+components/webmessaging",

"+content/app/strings/grit", # For generated headers
"+content/public/browser",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ class BackgroundSyncManagerTest : public testing::Test {
storage_partition_impl_.reset(new StoragePartitionImpl(
helper_->browser_context(), base::FilePath(), nullptr, nullptr, nullptr,
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
nullptr, nullptr));
nullptr, nullptr, nullptr));
helper_->context_wrapper()->set_storage_partition(
storage_partition_impl_.get());

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ class BackgroundSyncServiceImplTest : public testing::Test {
storage_partition_impl_.reset(new StoragePartitionImpl(
embedded_worker_helper_->browser_context(), base::FilePath(), nullptr,
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
nullptr, nullptr, nullptr, nullptr));
nullptr, nullptr, nullptr, nullptr, nullptr));
embedded_worker_helper_->context_wrapper()->set_storage_partition(
storage_partition_impl_.get());
}
Expand Down
6 changes: 6 additions & 0 deletions content/browser/renderer_host/render_process_host_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
#include "cc/base/switches.h"
#include "components/scheduler/common/scheduler_switches.h"
#include "components/tracing/common/tracing_switches.h"
#include "components/webmessaging/broadcast_channel_provider.h"
#include "content/browser/appcache/appcache_dispatcher_host.h"
#include "content/browser/appcache/chrome_appcache_service.h"
#include "content/browser/background_sync/background_sync_service_impl.h"
Expand Down Expand Up @@ -1062,6 +1063,11 @@ void RenderProcessHostImpl::RegisterMojoInterfaces() {
base::Bind(&RenderProcessHostImpl::CreateStoragePartitionService,
base::Unretained(this)));

GetInterfaceRegistry()->AddInterface(
base::Bind(&webmessaging::BroadcastChannelProvider::Connect,
base::Unretained(
storage_partition_impl_->GetBroadcastChannelProvider())));

GetInterfaceRegistry()->AddInterface(
base::Bind(&MimeRegistryImpl::Create),
BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE));
Expand Down
Loading

0 comments on commit e69cdae

Please sign in to comment.