Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "config.h" | 5 #include "config.h" |
| 6 #include "modules/presentation/PresentationSession.h" | 6 #include "modules/presentation/PresentationSession.h" |
| 7 | 7 |
| 8 #include "core/dom/DOMArrayBuffer.h" | 8 #include "core/dom/DOMArrayBuffer.h" |
| 9 #include "core/dom/DOMArrayBufferView.h" | 9 #include "core/dom/DOMArrayBufferView.h" |
| 10 #include "core/dom/Document.h" | 10 #include "core/dom/Document.h" |
| 11 #include "core/dom/ExceptionCode.h" | 11 #include "core/dom/ExceptionCode.h" |
| 12 #include "core/events/Event.h" | 12 #include "core/events/Event.h" |
| 13 #include "core/events/MessageEvent.h" | 13 #include "core/events/MessageEvent.h" |
| 14 #include "core/fileapi/FileReaderLoader.h" | |
| 15 #include "core/fileapi/FileReaderLoaderClient.h" | |
| 14 #include "core/frame/LocalFrame.h" | 16 #include "core/frame/LocalFrame.h" |
| 15 #include "modules/EventTargetModules.h" | 17 #include "modules/EventTargetModules.h" |
| 16 #include "modules/presentation/Presentation.h" | 18 #include "modules/presentation/Presentation.h" |
| 17 #include "modules/presentation/PresentationController.h" | 19 #include "modules/presentation/PresentationController.h" |
| 18 #include "public/platform/modules/presentation/WebPresentationSessionClient.h" | 20 #include "public/platform/modules/presentation/WebPresentationSessionClient.h" |
| 19 #include "wtf/Assertions.h" | 21 #include "wtf/Assertions.h" |
| 20 #include "wtf/OwnPtr.h" | 22 #include "wtf/OwnPtr.h" |
| 21 #include "wtf/text/AtomicString.h" | 23 #include "wtf/text/AtomicString.h" |
| 22 | 24 |
| 23 namespace blink { | 25 namespace blink { |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 40 return disconnectedValue; | 42 return disconnectedValue; |
| 41 } | 43 } |
| 42 | 44 |
| 43 void throwPresentationDisconnectedError(ExceptionState& exceptionState) | 45 void throwPresentationDisconnectedError(ExceptionState& exceptionState) |
| 44 { | 46 { |
| 45 exceptionState.throwDOMException(InvalidStateError, "Presentation session is disconnected."); | 47 exceptionState.throwDOMException(InvalidStateError, "Presentation session is disconnected."); |
| 46 } | 48 } |
| 47 | 49 |
| 48 } // namespace | 50 } // namespace |
| 49 | 51 |
| 52 class PresentationSession::BlobLoader final : public GarbageCollectedFinalized<P resentationSession::BlobLoader>, public FileReaderLoaderClient { | |
| 53 public: | |
| 54 BlobLoader(PassRefPtr<BlobDataHandle> blobDataHandle, PresentationSession* p resentationSession) | |
| 55 : m_presentationSession(presentationSession) | |
| 56 , m_loader(FileReaderLoader::ReadAsArrayBuffer, this) | |
| 57 { | |
| 58 m_loader.start(m_presentationSession->executionContext(), blobDataHandle ); | |
| 59 } | |
| 60 ~BlobLoader() override { } | |
| 61 | |
| 62 // FileReaderLoaderClient functions. | |
| 63 void didStartLoading() override { } | |
| 64 void didReceiveData() override { } | |
| 65 void didFinishLoading() override | |
| 66 { | |
| 67 m_presentationSession->didFinishLoadingBlob(m_loader.arrayBufferResult() ); | |
| 68 } | |
| 69 void didFail(FileError::ErrorCode errorCode) override | |
| 70 { | |
| 71 m_presentationSession->didFailLoadingBlob(errorCode); | |
| 72 } | |
| 73 | |
| 74 void cancel() | |
| 75 { | |
| 76 m_loader.cancel(); | |
| 77 } | |
| 78 | |
| 79 DEFINE_INLINE_TRACE() | |
| 80 { | |
| 81 visitor->trace(m_presentationSession); | |
| 82 } | |
| 83 | |
| 84 private: | |
| 85 Member<PresentationSession> m_presentationSession; | |
| 86 FileReaderLoader m_loader; | |
| 87 }; | |
| 88 | |
| 50 PresentationSession::PresentationSession(LocalFrame* frame, const String& id, co nst String& url) | 89 PresentationSession::PresentationSession(LocalFrame* frame, const String& id, co nst String& url) |
| 51 : DOMWindowProperty(frame) | 90 : DOMWindowProperty(frame) |
| 52 , m_id(id) | 91 , m_id(id) |
| 53 , m_url(url) | 92 , m_url(url) |
| 54 , m_state(WebPresentationSessionState::Disconnected) | 93 , m_state(WebPresentationSessionState::Disconnected) |
| 55 { | 94 { |
| 56 } | 95 } |
| 57 | 96 |
| 58 PresentationSession::~PresentationSession() | 97 PresentationSession::~PresentationSession() |
| 59 { | 98 { |
| 99 ASSERT(!m_blobLoader); | |
| 60 } | 100 } |
| 61 | 101 |
| 62 // static | 102 // static |
| 63 PresentationSession* PresentationSession::take(WebPresentationSessionClient* cli entRaw, Presentation* presentation) | 103 PresentationSession* PresentationSession::take(WebPresentationSessionClient* cli entRaw, Presentation* presentation) |
| 64 { | 104 { |
| 65 ASSERT(clientRaw); | 105 ASSERT(clientRaw); |
| 66 ASSERT(presentation); | 106 ASSERT(presentation); |
| 67 OwnPtr<WebPresentationSessionClient> client = adoptPtr(clientRaw); | 107 OwnPtr<WebPresentationSessionClient> client = adoptPtr(clientRaw); |
| 68 | 108 |
| 69 PresentationSession* session = new PresentationSession(presentation->frame() , client->getId(), client->getUrl()); | 109 PresentationSession* session = new PresentationSession(presentation->frame() , client->getId(), client->getUrl()); |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 83 } | 123 } |
| 84 | 124 |
| 85 ExecutionContext* PresentationSession::executionContext() const | 125 ExecutionContext* PresentationSession::executionContext() const |
| 86 { | 126 { |
| 87 if (!frame()) | 127 if (!frame()) |
| 88 return nullptr; | 128 return nullptr; |
| 89 return frame()->document();} | 129 return frame()->document();} |
| 90 | 130 |
| 91 DEFINE_TRACE(PresentationSession) | 131 DEFINE_TRACE(PresentationSession) |
| 92 { | 132 { |
| 133 visitor->trace(m_blobLoader); | |
| 93 RefCountedGarbageCollectedEventTargetWithInlineData<PresentationSession>::tr ace(visitor); | 134 RefCountedGarbageCollectedEventTargetWithInlineData<PresentationSession>::tr ace(visitor); |
| 94 DOMWindowProperty::trace(visitor); | 135 DOMWindowProperty::trace(visitor); |
| 95 } | 136 } |
| 96 | 137 |
| 97 const AtomicString& PresentationSession::state() const | 138 const AtomicString& PresentationSession::state() const |
| 98 { | 139 { |
| 99 return SessionStateToString(m_state); | 140 return SessionStateToString(m_state); |
| 100 } | 141 } |
| 101 | 142 |
| 102 void PresentationSession::send(const String& message, ExceptionState& exceptionS tate) | 143 void PresentationSession::send(const String& message, ExceptionState& exceptionS tate) |
| 103 { | 144 { |
| 145 if (!canSendMessage(exceptionState)) | |
| 146 return; | |
| 147 | |
| 148 m_messages.append(adoptPtr(new Message(message))); | |
| 149 handleMessageQueue(); | |
| 150 } | |
| 151 | |
| 152 void PresentationSession::send(PassRefPtr<DOMArrayBuffer> arrayBuffer, Exception State& exceptionState) | |
| 153 { | |
| 154 ASSERT(arrayBuffer && arrayBuffer->buffer()); | |
| 155 if (!canSendMessage(exceptionState)) | |
| 156 return; | |
| 157 | |
| 158 m_messages.append(adoptPtr(new Message(arrayBuffer))); | |
| 159 handleMessageQueue(); | |
| 160 } | |
| 161 | |
| 162 void PresentationSession::send(PassRefPtr<DOMArrayBufferView> arrayBufferView, E xceptionState& exceptionState) | |
| 163 { | |
| 164 ASSERT(arrayBufferView); | |
| 165 if (!canSendMessage(exceptionState)) | |
| 166 return; | |
| 167 | |
| 168 m_messages.append(adoptPtr(new Message(arrayBufferView->buffer()))); | |
| 169 handleMessageQueue(); | |
| 170 } | |
| 171 | |
| 172 void PresentationSession::send(Blob* data, ExceptionState& exceptionState) | |
| 173 { | |
| 174 ASSERT(data); | |
| 175 if (!canSendMessage(exceptionState)) | |
| 176 return; | |
| 177 | |
| 178 m_messages.append(adoptPtr(new Message(data->blobDataHandle()))); | |
| 179 handleMessageQueue(); | |
| 180 } | |
| 181 | |
| 182 bool PresentationSession::canSendMessage(ExceptionState& exceptionState) | |
| 183 { | |
| 104 if (m_state == WebPresentationSessionState::Disconnected) { | 184 if (m_state == WebPresentationSessionState::Disconnected) { |
| 105 throwPresentationDisconnectedError(exceptionState); | 185 throwPresentationDisconnectedError(exceptionState); |
| 106 return; | 186 return false; |
| 107 } | 187 } |
| 108 | 188 |
| 109 PresentationController* controller = presentationController(); | 189 PresentationController* controller = presentationController(); |
| 110 if (controller) | 190 if (!controller) |
| 111 controller->send(m_url, m_id, message); | 191 return false; |
| 192 | |
| 193 return true; | |
| 112 } | 194 } |
| 113 | 195 |
| 114 void PresentationSession::send(PassRefPtr<DOMArrayBuffer> data, ExceptionState& exceptionState) | 196 void PresentationSession::handleMessageQueue() |
| 115 { | 197 { |
| 116 ASSERT(data && data->buffer()); | 198 PresentationController* controller = presentationController(); |
| 117 sendInternal(static_cast<const uint8_t*>(data->data()), data->byteLength(), exceptionState); | 199 // Extra check just in case. |
| 118 } | 200 if (!controller) |
| 201 return; | |
| 119 | 202 |
| 120 void PresentationSession::send(PassRefPtr<DOMArrayBufferView> data, ExceptionSta te& exceptionState) | 203 while (!m_messages.isEmpty() && !m_blobLoader) { |
| 121 { | 204 Message* message = m_messages.first().get(); |
| 122 ASSERT(data); | 205 switch (message->type) { |
| 123 sendInternal(static_cast<const uint8_t*>(data->baseAddress()), data->byteLen gth(), exceptionState); | 206 case MessageTypeText: |
| 124 } | 207 controller->send(m_url, m_id, message->text); |
| 125 | 208 m_messages.removeFirst(); |
| 126 void PresentationSession::sendInternal(const uint8_t* data, size_t size, Excepti onState& exceptionState) | 209 break; |
| 127 { | 210 case MessageTypeArrayBuffer: |
| 128 ASSERT(data); | 211 controller->send(m_url, m_id, static_cast<const uint8_t*>(message->a rrayBuffer->data()), message->arrayBuffer->byteLength()); |
| 129 if (m_state == WebPresentationSessionState::Disconnected) { | 212 m_messages.removeFirst(); |
| 130 throwPresentationDisconnectedError(exceptionState); | 213 break; |
| 131 return; | 214 case MessageTypeBlob: |
| 215 ASSERT(!m_blobLoader); | |
| 216 m_blobLoader = new BlobLoader(message->blobDataHandle, this); | |
| 217 break; | |
| 218 } | |
| 132 } | 219 } |
| 133 | |
| 134 PresentationController* controller = presentationController(); | |
| 135 if (controller) | |
| 136 controller->send(m_url, m_id, data, size); | |
| 137 } | 220 } |
| 138 | 221 |
| 139 void PresentationSession::didReceiveTextMessage(const String& message) | 222 void PresentationSession::didReceiveTextMessage(const String& message) |
| 140 { | 223 { |
| 141 dispatchEvent(MessageEvent::create(message)); | 224 dispatchEvent(MessageEvent::create(message)); |
| 142 } | 225 } |
| 143 | 226 |
| 144 void PresentationSession::close() | 227 void PresentationSession::close() |
| 145 { | 228 { |
| 146 if (m_state != WebPresentationSessionState::Connected) | 229 if (m_state != WebPresentationSessionState::Connected) |
| 147 return; | 230 return; |
| 148 PresentationController* controller = presentationController(); | 231 PresentationController* controller = presentationController(); |
| 149 if (controller) | 232 if (controller) |
| 150 controller->closeSession(m_url, m_id); | 233 controller->closeSession(m_url, m_id); |
| 234 | |
| 235 // Cancel current Blob loading if any. | |
| 236 if (m_blobLoader) { | |
| 237 m_blobLoader->cancel(); | |
| 238 m_blobLoader.clear(); | |
| 239 } | |
| 240 | |
| 241 // Clear message queue. | |
| 242 Deque<OwnPtr<Message>> empty; | |
| 243 m_messages.swap(empty); | |
| 151 } | 244 } |
| 152 | 245 |
| 153 bool PresentationSession::matches(WebPresentationSessionClient* client) const | 246 bool PresentationSession::matches(WebPresentationSessionClient* client) const |
| 154 { | 247 { |
| 155 return client && m_url == static_cast<String>(client->getUrl()) && m_id == s tatic_cast<String>(client->getId()); | 248 return client && m_url == static_cast<String>(client->getUrl()) && m_id == s tatic_cast<String>(client->getId()); |
| 156 } | 249 } |
| 157 | 250 |
| 158 void PresentationSession::didChangeState(WebPresentationSessionState state) | 251 void PresentationSession::didChangeState(WebPresentationSessionState state) |
| 159 { | 252 { |
| 160 if (m_state == state) | 253 if (m_state == state) |
| 161 return; | 254 return; |
| 162 | 255 |
| 163 m_state = state; | 256 m_state = state; |
| 164 dispatchEvent(Event::create(EventTypeNames::statechange)); | 257 dispatchEvent(Event::create(EventTypeNames::statechange)); |
| 165 } | 258 } |
| 166 | 259 |
| 167 PresentationController* PresentationSession::presentationController() | 260 PresentationController* PresentationSession::presentationController() |
| 168 { | 261 { |
| 169 if (!frame()) | 262 if (!frame()) |
| 170 return nullptr; | 263 return nullptr; |
| 171 return PresentationController::from(*frame()); | 264 return PresentationController::from(*frame()); |
| 172 } | 265 } |
| 173 | 266 |
| 267 void PresentationSession::didFinishLoadingBlob(PassRefPtr<DOMArrayBuffer> buffer ) | |
| 268 { | |
| 269 ASSERT(!m_messages.isEmpty() && m_messages.first()->type == MessageTypeBlob) ; | |
| 270 ASSERT(buffer && buffer->buffer()); | |
| 271 // Send the loaded blob immediately here and continue processing the queue. | |
| 272 PresentationController* controller = presentationController(); | |
| 273 if (controller) | |
| 274 controller->sendBlobData(m_url, m_id, static_cast<const uint8_t*>(buffer ->data()), buffer->byteLength()); | |
| 275 | |
| 276 m_messages.removeFirst(); | |
| 277 m_blobLoader.clear(); | |
|
USE s.singapati at gmail.com
2015/06/02 16:25:44
Did manual testing. Tried to but could not simulat
| |
| 278 handleMessageQueue(); | |
| 279 } | |
| 280 | |
| 281 void PresentationSession::didFailLoadingBlob(FileError::ErrorCode errorCode) | |
| 282 { | |
| 283 ASSERT(!m_messages.isEmpty() && m_messages.first()->type == MessageTypeBlob) ; | |
| 284 // FIXME: generate error message? | |
| 285 // Ignore the current failed blob item and continue with next items. | |
| 286 m_messages.removeFirst(); | |
| 287 m_blobLoader.clear(); | |
| 288 handleMessageQueue(); | |
| 289 } | |
| 290 | |
| 174 } // namespace blink | 291 } // namespace blink |
| OLD | NEW |