Chromium Code Reviews| Index: third_party/WebKit/Source/modules/broadcastchannel/BroadcastChannelConnection.cpp |
| diff --git a/third_party/WebKit/Source/modules/broadcastchannel/BroadcastChannelConnection.cpp b/third_party/WebKit/Source/modules/broadcastchannel/BroadcastChannelConnection.cpp |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..5d60e99c34bff7dfeee63b06dbc5dcb219ae50e3 |
| --- /dev/null |
| +++ b/third_party/WebKit/Source/modules/broadcastchannel/BroadcastChannelConnection.cpp |
| @@ -0,0 +1,120 @@ |
| +// 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 "modules/broadcastchannel/BroadcastChannelConnection.h" |
| + |
| +#include "platform/ThreadSafeFunctional.h" |
| +#include "platform/mojo/MojoHelper.h" |
| +#include "public/platform/Platform.h" |
| +#include "public/platform/ServiceRegistry.h" |
| +#include "public/platform/WebTaskRunner.h" |
| +#include "public/platform/WebTraceLocation.h" |
| + |
| +namespace blink { |
| + |
| +namespace { |
| + |
| +void connectToService(webmessaging::mojom::blink::BroadcastChannelServiceRequest request) |
| +{ |
| + DCHECK(Platform::current()->mainThread()->isCurrentThread()); |
| + Platform::current()->serviceRegistry()->connectToRemoteService(std::move(request)); |
| +} |
| + |
| +webmessaging::mojom::blink::BroadcastChannelServicePtr& getThreadSpecificService() |
| +{ |
| + DEFINE_THREAD_SAFE_STATIC_LOCAL(ThreadSpecific<webmessaging::mojom::blink::BroadcastChannelServicePtr>, service, new ThreadSpecific<webmessaging::mojom::blink::BroadcastChannelServicePtr>); |
|
esprehn
2016/06/06 02:29:42
Hmm why do we need statics for this? I don't think
Marijn Kruisselbrink
2016/06/06 20:05:29
Because in mojo every interface is its own pipe wi
haraken
2016/06/07 00:53:26
OK. Another option would be to use Page for the ma
Marijn Kruisselbrink
2016/06/07 01:18:39
Yeah, anything more contained than a service conne
|
| + if (!service.isSet()) { |
| + Platform::current()->mainThread()->getWebTaskRunner()->postTask(BLINK_FROM_HERE, |
| + threadSafeBind(&connectToService, passed(mojo::GetProxy(&*service)))); |
| + } |
| + return *service; |
| +} |
| + |
| +// BroadcastChannelConnection instances are jointly owned by the clients using |
| +// the connection. This map is merely a way for new clients to lookup the |
| +// connection to use, hence it stores weak references to connections. |
| +using ConnectionKey = std::pair<RefPtr<SecurityOrigin>, String>; |
| +using ConnectionMap = HeapHashMap<ConnectionKey, WeakMember<BroadcastChannelConnection>>; |
| + |
| +ConnectionMap* getConnectionMap() |
| +{ |
| + DEFINE_THREAD_SAFE_STATIC_LOCAL(ThreadSpecific<Persistent<ConnectionMap>>, connectionMap, new ThreadSpecific<Persistent<ConnectionMap>>); |
|
haraken
2016/06/06 02:05:47
+sigbjornf@: Please check if this usage is correct
sof
2016/06/06 06:35:45
Usage is exemplary; we don't try to hide very many
|
| + if (!connectionMap.isSet()) { |
| + *connectionMap = new ConnectionMap; |
| + connectionMap->registerAsStaticReference(); |
| + } |
| + return *connectionMap; |
| +} |
| + |
| +} // namespace |
| + |
| +// static |
| +BroadcastChannelConnection* BroadcastChannelConnection::getForChannel(const RefPtr<SecurityOrigin>& origin, const String& name) |
| +{ |
| + ConnectionMap* connectionMap = getConnectionMap(); |
| + auto it = connectionMap->find(ConnectionKey(origin, name)); |
| + if (it != connectionMap->end()) |
| + return it->value; |
| + |
| + webmessaging::mojom::blink::BroadcastChannelServicePtr& service = getThreadSpecificService(); |
| + webmessaging::mojom::blink::BroadcastChannelClientAssociatedPtrInfo localClientInfo; |
| + BroadcastChannelConnection* connection = new BroadcastChannelConnection(name, origin, &localClientInfo, service.associated_group()); |
| + service->Subscribe(origin, name, std::move(localClientInfo)); |
| + return connection; |
| +} |
| + |
| +BroadcastChannelConnection::~BroadcastChannelConnection() |
| +{ |
| +} |
| + |
| +void BroadcastChannelConnection::registerClient(Client* client) |
| +{ |
| + m_clients.add(client); |
| +} |
| + |
| +void BroadcastChannelConnection::unregisterClient(Client* client) |
| +{ |
| + m_clients.remove(client); |
| +} |
| + |
| +void BroadcastChannelConnection::broadcast(Client* from, const String& message) |
| +{ |
| + for (Client* client : m_clients) { |
| + if (client != from) |
| + client->onMessage(message); |
| + } |
| + getThreadSpecificService()->Broadcast(from->origin(), from->name(), message); |
| +} |
| + |
| +DEFINE_TRACE(BroadcastChannelConnection) |
| +{ |
| + visitor->trace(m_clients); |
| +} |
| + |
| +BroadcastChannelConnection::BroadcastChannelConnection(const String& name, const RefPtr<SecurityOrigin>& origin, webmessaging::mojom::blink::BroadcastChannelClientAssociatedPtrInfo* clientInfo, mojo::AssociatedGroup* associatedGroup) |
| + : m_name(name) |
| + , m_origin(origin) |
| + , m_binding(this, clientInfo, associatedGroup) |
| +{ |
| + m_binding.set_connection_error_handler(createBaseCallback(bind(&BroadcastChannelConnection::onError, WeakPersistentThisPointer<BroadcastChannelConnection>(this)))); |
|
haraken
2016/06/06 02:05:47
+hiroshige@: Is this a correct usage to bind a Bli
Marijn Kruisselbrink
2016/06/06 20:05:29
fwiw this is how at least PaymentRequest does it (
|
| + auto result = getConnectionMap()->set(ConnectionKey(m_origin, m_name), this); |
| + DCHECK(result.isNewEntry) << "There should only be one connection per channel per thread."; |
| + ALLOW_UNUSED_LOCAL(result); |
|
haraken
2016/06/06 02:05:47
Nit: Is this needed?
Marijn Kruisselbrink
2016/06/06 20:05:29
Not sure. Assertions.h seems to suggest so though
|
| +} |
| + |
| +void BroadcastChannelConnection::OnMessage(const String& message) |
| +{ |
| + for (Client* client : m_clients) |
| + client->onMessage(message); |
| +} |
| + |
| +void BroadcastChannelConnection::onError() |
| +{ |
| + for (Client* client : m_clients) |
| + client->onError(); |
| + m_clients.clear(); |
| + getConnectionMap()->remove(ConnectionKey(m_origin, m_name)); |
| +} |
| + |
| +} // namespace blink |