Index: Source/modules/presentation/PresentationSession.cpp |
diff --git a/Source/modules/presentation/PresentationSession.cpp b/Source/modules/presentation/PresentationSession.cpp |
index 6c6e9380d43916753372d614e9046f7806214c83..11990926b21c62cb47a0e00fcda6ef6a662f0840 100644 |
--- a/Source/modules/presentation/PresentationSession.cpp |
+++ b/Source/modules/presentation/PresentationSession.cpp |
@@ -11,6 +11,8 @@ |
#include "core/dom/ExceptionCode.h" |
#include "core/events/Event.h" |
#include "core/events/MessageEvent.h" |
+#include "core/fileapi/FileReaderLoader.h" |
+#include "core/fileapi/FileReaderLoaderClient.h" |
#include "core/frame/LocalFrame.h" |
#include "modules/EventTargetModules.h" |
#include "modules/presentation/Presentation.h" |
@@ -47,6 +49,43 @@ void throwPresentationDisconnectedError(ExceptionState& exceptionState) |
} // namespace |
+class PresentationSession::BlobLoader final : public GarbageCollectedFinalized<PresentationSession::BlobLoader>, public FileReaderLoaderClient { |
+public: |
+ BlobLoader(PassRefPtr<BlobDataHandle> blobDataHandle, PresentationSession* presentationSession) |
+ : m_presentationSession(presentationSession) |
+ , m_loader(FileReaderLoader::ReadAsArrayBuffer, this) |
+ { |
+ m_loader.start(m_presentationSession->executionContext(), blobDataHandle); |
+ } |
+ ~BlobLoader() override { } |
+ |
+ // FileReaderLoaderClient functions. |
+ void didStartLoading() override { } |
+ void didReceiveData() override { } |
+ void didFinishLoading() override |
+ { |
+ m_presentationSession->didFinishLoadingBlob(m_loader.arrayBufferResult()); |
+ } |
+ void didFail(FileError::ErrorCode errorCode) override |
+ { |
+ m_presentationSession->didFailLoadingBlob(errorCode); |
+ } |
+ |
+ void cancel() |
+ { |
+ m_loader.cancel(); |
+ } |
+ |
+ DEFINE_INLINE_TRACE() |
+ { |
+ visitor->trace(m_presentationSession); |
+ } |
+ |
+private: |
+ Member<PresentationSession> m_presentationSession; |
+ FileReaderLoader m_loader; |
+}; |
+ |
PresentationSession::PresentationSession(LocalFrame* frame, const String& id, const String& url) |
: DOMWindowProperty(frame) |
, m_id(id) |
@@ -57,6 +96,7 @@ PresentationSession::PresentationSession(LocalFrame* frame, const String& id, co |
PresentationSession::~PresentationSession() |
{ |
+ ASSERT(!m_blobLoader); |
} |
// static |
@@ -90,6 +130,7 @@ ExecutionContext* PresentationSession::executionContext() const |
DEFINE_TRACE(PresentationSession) |
{ |
+ visitor->trace(m_blobLoader); |
RefCountedGarbageCollectedEventTargetWithInlineData<PresentationSession>::trace(visitor); |
DOMWindowProperty::trace(visitor); |
} |
@@ -136,6 +177,28 @@ void PresentationSession::sendInternal(const uint8_t* data, size_t size, Excepti |
controller->send(m_url, m_id, data, size); |
} |
+void PresentationSession::send(Blob* data, ExceptionState& exceptionState) |
+{ |
+ ASSERT(data); |
+ if (m_state == WebPresentationSessionState::Disconnected) { |
+ throwPresentationDisconnectedError(exceptionState); |
+ return; |
+ } |
+ |
+ m_messages.append(adoptPtr(new Message(data->blobDataHandle()))); |
+ handleMessageQueue(); |
+} |
+ |
+void PresentationSession::handleMessageQueue() |
+{ |
+ if (m_messages.isEmpty() || m_blobLoader) |
+ return; |
+ |
+ Message* message = m_messages.first().get(); |
+ ASSERT(!m_blobLoader); |
mark a. foltz
2015/05/26 20:41:48
I don't think this is necessary because of the ret
USE s.singapati at gmail.com
2015/05/27 19:37:51
Done.
|
+ m_blobLoader = new BlobLoader(message->blobDataHandle, this); |
+} |
+ |
void PresentationSession::didReceiveTextMessage(const String& message) |
{ |
dispatchEvent(MessageEvent::create(message)); |
@@ -148,6 +211,16 @@ void PresentationSession::close() |
PresentationController* controller = presentationController(); |
if (controller) |
controller->closeSession(m_url, m_id); |
+ |
+ // Cancel current Blob loading if any. |
+ if (m_blobLoader) { |
+ m_blobLoader->cancel(); |
+ m_blobLoader.clear(); |
+ } |
+ |
+ // Clear Blob message queue. |
+ Deque<OwnPtr<Message>> empty; |
+ m_messages.swap(empty); |
} |
bool PresentationSession::matches(WebPresentationSessionClient* client) const |
@@ -171,4 +244,28 @@ PresentationController* PresentationSession::presentationController() |
return PresentationController::from(*frame()); |
} |
+void PresentationSession::didFinishLoadingBlob(PassRefPtr<DOMArrayBuffer> buffer) |
+{ |
+ ASSERT(!m_messages.isEmpty()); |
+ m_blobLoader.clear(); |
+ ASSERT(buffer && buffer->buffer()); |
+ |
+ PresentationController* controller = presentationController(); |
+ if (controller) |
+ controller->sendBlobData(m_url, m_id, static_cast<const uint8_t*>(buffer->data()), buffer->byteLength()); |
+ |
+ m_messages.removeFirst(); |
+ handleMessageQueue(); |
+} |
+ |
+void PresentationSession::didFailLoadingBlob(FileError::ErrorCode errorCode) |
+{ |
+ ASSERT(!m_messages.isEmpty()); |
+ m_blobLoader.clear(); |
+ // FIXME: generate error message? |
mark a. foltz
2015/05/26 20:41:48
There's currently no clean way to signal to the pa
|
+ // Ignore the current failed blob item and continue with next items. |
+ m_messages.removeFirst(); |
+ handleMessageQueue(); |
+} |
+ |
} // namespace blink |