OLD | NEW |
(Empty) | |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "modules/broadcastchannel/BroadcastChannel.h" |
| 6 |
| 7 #include "bindings/core/v8/SerializedScriptValue.h" |
| 8 #include "bindings/core/v8/SerializedScriptValueFactory.h" |
| 9 #include "core/dom/ExceptionCode.h" |
| 10 #include "core/events/MessageEvent.h" |
| 11 #include "platform/ThreadSafeFunctional.h" |
| 12 #include "platform/mojo/MojoHelper.h" |
| 13 #include "public/platform/Platform.h" |
| 14 #include "public/platform/ServiceRegistry.h" |
| 15 #include "public/platform/WebBlobInfo.h" |
| 16 |
| 17 namespace blink { |
| 18 |
| 19 namespace { |
| 20 |
| 21 void connectToService(mojo::InterfaceRequest<webmessaging::mojom::blink::Bro
adcastChannelService> request) |
| 22 { |
| 23 DCHECK(Platform::current()->mainThread()->isCurrentThread()); |
| 24 Platform::current()->serviceRegistry()->connectToRemoteService(std::move
(request)); |
| 25 } |
| 26 |
| 27 webmessaging::mojom::blink::BroadcastChannelServicePtr& getThreadSpecificSer
vice() |
| 28 { |
| 29 DEFINE_THREAD_SAFE_STATIC_LOCAL(ThreadSpecific<webmessaging::mojom::blin
k::BroadcastChannelServicePtr>, service, new ThreadSpecific<webmessaging::mojom:
:blink::BroadcastChannelServicePtr>); |
| 30 if (!service.isSet()) { |
| 31 Platform::current()->mainThread()->getWebTaskRunner()->postTask(BLIN
K_FROM_HERE, |
| 32 threadSafeBind(&connectToService, passed(mojo::GetProxy(&*servic
e)))); |
| 33 } |
| 34 return *service; |
| 35 } |
| 36 |
| 37 } // namespace |
| 38 |
| 39 // static |
| 40 BroadcastChannel* BroadcastChannel::create(ExecutionContext* executionContext, c
onst String& name) |
| 41 { |
| 42 BroadcastChannel* channel = new BroadcastChannel(executionContext, name); |
| 43 channel->suspendIfNeeded(); |
| 44 return channel; |
| 45 } |
| 46 |
| 47 BroadcastChannel::~BroadcastChannel() |
| 48 { |
| 49 } |
| 50 |
| 51 void BroadcastChannel::postMessage(const ScriptValue& message, ExceptionState& e
xceptionState) |
| 52 { |
| 53 if (!m_binding.is_bound()) { |
| 54 exceptionState.throwDOMException(InvalidStateError, "Channel is closed")
; |
| 55 return; |
| 56 } |
| 57 WebBlobInfoArray blobInfo; |
| 58 RefPtr<SerializedScriptValue> value = SerializedScriptValueFactory::instance
().create(message.isolate(), message, &blobInfo, exceptionState); |
| 59 if (exceptionState.hadException()) |
| 60 return; |
| 61 |
| 62 String data = value->toWireString(); |
| 63 m_remoteClient->OnMessage(data); |
| 64 } |
| 65 |
| 66 void BroadcastChannel::close() |
| 67 { |
| 68 m_remoteClient.reset(); |
| 69 m_binding.Close(); |
| 70 } |
| 71 |
| 72 const AtomicString& BroadcastChannel::interfaceName() const |
| 73 { |
| 74 return EventTargetNames::BroadcastChannel; |
| 75 } |
| 76 |
| 77 bool BroadcastChannel::hasPendingActivity() const |
| 78 { |
| 79 return m_binding.is_bound() && hasEventListeners(EventTypeNames::message); |
| 80 } |
| 81 |
| 82 DEFINE_TRACE(BroadcastChannel) |
| 83 { |
| 84 ActiveDOMObject::trace(visitor); |
| 85 EventTargetWithInlineData::trace(visitor); |
| 86 } |
| 87 |
| 88 BroadcastChannel::BroadcastChannel(ExecutionContext* executionContext, const Str
ing& name) |
| 89 : ActiveScriptWrappable(this) |
| 90 , ActiveDOMObject(executionContext) |
| 91 , m_name(name) |
| 92 , m_binding(this) |
| 93 { |
| 94 webmessaging::mojom::blink::BroadcastChannelServicePtr& service = getThreadS
pecificService(); |
| 95 |
| 96 // m_binding is for messages sent to this instance of the channel. |
| 97 webmessaging::mojom::blink::BroadcastChannelClientAssociatedPtrInfo localCli
entInfo; |
| 98 m_binding.Bind(&localClientInfo, service.associated_group()); |
| 99 m_binding.set_connection_error_handler(createBaseCallback(bind(&BroadcastCha
nnel::OnError, this))); |
| 100 |
| 101 // m_connection is for messages sent from this instance of the channel. |
| 102 webmessaging::mojom::blink::BroadcastChannelClientAssociatedPtrInfo remoteCl
ientInfo; |
| 103 mojo::AssociatedInterfaceRequest<webmessaging::mojom::blink::BroadcastChanne
lClient> remoteCientRequest; |
| 104 service.associated_group()->CreateAssociatedInterface(mojo::AssociatedGroup:
:WILL_PASS_REQUEST, &remoteClientInfo, &remoteCientRequest); |
| 105 m_remoteClient.Bind(std::move(remoteClientInfo)); |
| 106 m_remoteClient.set_connection_error_handler(createBaseCallback(bind(&Broadca
stChannel::OnError, this))); |
| 107 |
| 108 service->ConnectToChannel(executionContext->getSecurityOrigin()->toString(),
name, std::move(localClientInfo), std::move(remoteCientRequest)); |
| 109 } |
| 110 |
| 111 void BroadcastChannel::OnMessage(const String& message) |
| 112 { |
| 113 RefPtr<SerializedScriptValue> value = SerializedScriptValueFactory::instance
().createFromWire(message); |
| 114 dispatchEvent(MessageEvent::create(nullptr, value.release(), getExecutionCon
text()->getSecurityOrigin()->toString())); |
| 115 } |
| 116 |
| 117 void BroadcastChannel::OnError() |
| 118 { |
| 119 close(); |
| 120 } |
| 121 |
| 122 } // namespace blink |
OLD | NEW |