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 |