Index: third_party/WebKit/Source/modules/broadcastchannel/BroadcastChannel.cpp |
diff --git a/third_party/WebKit/Source/modules/broadcastchannel/BroadcastChannel.cpp b/third_party/WebKit/Source/modules/broadcastchannel/BroadcastChannel.cpp |
new file mode 100644 |
index 0000000000000000000000000000000000000000..ac8a679a61dddb43c3b33f1f5d38aaea9904b974 |
--- /dev/null |
+++ b/third_party/WebKit/Source/modules/broadcastchannel/BroadcastChannel.cpp |
@@ -0,0 +1,122 @@ |
+// 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/BroadcastChannel.h" |
+ |
+#include "bindings/core/v8/SerializedScriptValue.h" |
+#include "bindings/core/v8/SerializedScriptValueFactory.h" |
+#include "core/dom/ExceptionCode.h" |
+#include "core/events/MessageEvent.h" |
+#include "platform/ThreadSafeFunctional.h" |
+#include "platform/mojo/MojoHelper.h" |
+#include "public/platform/Platform.h" |
+#include "public/platform/ServiceRegistry.h" |
+#include "public/platform/WebBlobInfo.h" |
+ |
+namespace blink { |
+ |
+namespace { |
+ |
+ void connectToService(mojo::InterfaceRequest<webmessaging::mojom::blink::BroadcastChannelService> 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>); |
+ if (!service.isSet()) { |
+ Platform::current()->mainThread()->getWebTaskRunner()->postTask(BLINK_FROM_HERE, |
+ threadSafeBind(&connectToService, passed(mojo::GetProxy(&*service)))); |
+ } |
+ return *service; |
+ } |
+ |
+} // namespace |
+ |
+// static |
+BroadcastChannel* BroadcastChannel::create(ExecutionContext* executionContext, const String& name) |
+{ |
+ BroadcastChannel* channel = new BroadcastChannel(executionContext, name); |
+ channel->suspendIfNeeded(); |
+ return channel; |
+} |
+ |
+BroadcastChannel::~BroadcastChannel() |
+{ |
+} |
+ |
+void BroadcastChannel::postMessage(const ScriptValue& message, ExceptionState& exceptionState) |
+{ |
+ if (!m_binding.is_bound()) { |
+ exceptionState.throwDOMException(InvalidStateError, "Channel is closed"); |
+ return; |
+ } |
+ WebBlobInfoArray blobInfo; |
+ RefPtr<SerializedScriptValue> value = SerializedScriptValueFactory::instance().create(message.isolate(), message, &blobInfo, exceptionState); |
+ if (exceptionState.hadException()) |
+ return; |
+ |
+ String data = value->toWireString(); |
+ m_remoteClient->OnMessage(data); |
+} |
+ |
+void BroadcastChannel::close() |
+{ |
+ m_remoteClient.reset(); |
+ m_binding.Close(); |
+} |
+ |
+const AtomicString& BroadcastChannel::interfaceName() const |
+{ |
+ return EventTargetNames::BroadcastChannel; |
+} |
+ |
+bool BroadcastChannel::hasPendingActivity() const |
+{ |
+ return m_binding.is_bound() && hasEventListeners(EventTypeNames::message); |
+} |
+ |
+DEFINE_TRACE(BroadcastChannel) |
+{ |
+ ActiveDOMObject::trace(visitor); |
+ EventTargetWithInlineData::trace(visitor); |
+} |
+ |
+BroadcastChannel::BroadcastChannel(ExecutionContext* executionContext, const String& name) |
+ : ActiveScriptWrappable(this) |
+ , ActiveDOMObject(executionContext) |
+ , m_name(name) |
+ , m_binding(this) |
+{ |
+ webmessaging::mojom::blink::BroadcastChannelServicePtr& service = getThreadSpecificService(); |
+ |
+ // m_binding is for messages sent to this instance of the channel. |
+ webmessaging::mojom::blink::BroadcastChannelClientAssociatedPtrInfo localClientInfo; |
+ m_binding.Bind(&localClientInfo, service.associated_group()); |
+ m_binding.set_connection_error_handler(createBaseCallback(bind(&BroadcastChannel::OnError, this))); |
+ |
+ // m_connection is for messages sent from this instance of the channel. |
+ webmessaging::mojom::blink::BroadcastChannelClientAssociatedPtrInfo remoteClientInfo; |
+ mojo::AssociatedInterfaceRequest<webmessaging::mojom::blink::BroadcastChannelClient> remoteCientRequest; |
+ service.associated_group()->CreateAssociatedInterface(mojo::AssociatedGroup::WILL_PASS_REQUEST, &remoteClientInfo, &remoteCientRequest); |
+ m_remoteClient.Bind(std::move(remoteClientInfo)); |
+ m_remoteClient.set_connection_error_handler(createBaseCallback(bind(&BroadcastChannel::OnError, this))); |
+ |
+ service->ConnectToChannel(executionContext->getSecurityOrigin()->toString(), name, std::move(localClientInfo), std::move(remoteCientRequest)); |
+} |
+ |
+void BroadcastChannel::OnMessage(const String& message) |
+{ |
+ RefPtr<SerializedScriptValue> value = SerializedScriptValueFactory::instance().createFromWire(message); |
+ dispatchEvent(MessageEvent::create(nullptr, value.release(), getExecutionContext()->getSecurityOrigin()->toString())); |
+} |
+ |
+void BroadcastChannel::OnError() |
+{ |
+ close(); |
+} |
+ |
+} // namespace blink |