Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1651)

Unified Diff: Source/modules/presentation/PresentationSession.cpp

Issue 1131463006: [PresentationAPI] Plumbing send(Blob) from PresentationSession IDL to platform/. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: Source/modules/presentation/PresentationSession.cpp
diff --git a/Source/modules/presentation/PresentationSession.cpp b/Source/modules/presentation/PresentationSession.cpp
index 6c6e9380d43916753372d614e9046f7806214c83..dc665e2de1d2b3cb544a6e93db4f90f33a80c907 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);
}
@@ -101,39 +142,81 @@ const AtomicString& PresentationSession::state() const
void PresentationSession::send(const String& message, ExceptionState& exceptionState)
{
- if (m_state == WebPresentationSessionState::Disconnected) {
- throwPresentationDisconnectedError(exceptionState);
+ if (!canSendMessage(exceptionState))
return;
- }
- PresentationController* controller = presentationController();
- if (controller)
- controller->send(m_url, m_id, message);
+ m_messages.append(adoptPtr(new Message(message)));
+ handleMessageQueue();
}
-void PresentationSession::send(PassRefPtr<DOMArrayBuffer> data, ExceptionState& exceptionState)
+void PresentationSession::send(PassRefPtr<DOMArrayBuffer> arrayBuffer, ExceptionState& exceptionState)
{
- ASSERT(data && data->buffer());
- sendInternal(static_cast<const uint8_t*>(data->data()), data->byteLength(), exceptionState);
+ ASSERT(arrayBuffer && arrayBuffer->buffer());
+ if (!canSendMessage(exceptionState))
+ return;
+
+ m_messages.append(adoptPtr(new Message(arrayBuffer)));
+ handleMessageQueue();
}
-void PresentationSession::send(PassRefPtr<DOMArrayBufferView> data, ExceptionState& exceptionState)
+void PresentationSession::send(PassRefPtr<DOMArrayBufferView> arrayBufferView, ExceptionState& exceptionState)
{
- ASSERT(data);
- sendInternal(static_cast<const uint8_t*>(data->baseAddress()), data->byteLength(), exceptionState);
+ ASSERT(arrayBufferView);
+ if (!canSendMessage(exceptionState))
+ return;
+
+ m_messages.append(adoptPtr(new Message(arrayBufferView->buffer())));
+ handleMessageQueue();
}
-void PresentationSession::sendInternal(const uint8_t* data, size_t size, ExceptionState& exceptionState)
+void PresentationSession::send(Blob* data, ExceptionState& exceptionState)
{
ASSERT(data);
+ if (!canSendMessage(exceptionState))
+ return;
+
+ m_messages.append(adoptPtr(new Message(data->blobDataHandle())));
+ handleMessageQueue();
+}
+
+bool PresentationSession::canSendMessage(ExceptionState& exceptionState)
+{
if (m_state == WebPresentationSessionState::Disconnected) {
throwPresentationDisconnectedError(exceptionState);
- return;
+ return false;
}
PresentationController* controller = presentationController();
- if (controller)
- controller->send(m_url, m_id, data, size);
+ if (!controller)
+ return false;
+
+ return true;
+}
+
+void PresentationSession::handleMessageQueue()
+{
+ PresentationController* controller = presentationController();
+ // Extra check just in case.
+ if (!controller)
+ return;
+
+ while (!m_messages.isEmpty() && !m_blobLoader) {
+ Message* message = m_messages.first().get();
+ switch (message->type) {
+ case MessageTypeText:
+ controller->send(m_url, m_id, message->text);
+ m_messages.removeFirst();
+ break;
+ case MessageTypeArrayBuffer:
+ controller->send(m_url, m_id, static_cast<const uint8_t*>(message->arrayBuffer->data()), message->arrayBuffer->byteLength());
+ m_messages.removeFirst();
+ break;
+ case MessageTypeBlob:
+ ASSERT(!m_blobLoader);
+ m_blobLoader = new BlobLoader(message->blobDataHandle, this);
+ break;
+ }
+ }
}
void PresentationSession::didReceiveTextMessage(const String& message)
@@ -148,6 +231,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 message queue.
+ Deque<OwnPtr<Message>> empty;
+ m_messages.swap(empty);
}
bool PresentationSession::matches(WebPresentationSessionClient* client) const
@@ -171,4 +264,28 @@ PresentationController* PresentationSession::presentationController()
return PresentationController::from(*frame());
}
+void PresentationSession::didFinishLoadingBlob(PassRefPtr<DOMArrayBuffer> buffer)
+{
+ ASSERT(!m_messages.isEmpty() && m_messages.first()->type == MessageTypeBlob);
+ ASSERT(buffer && buffer->buffer());
+ // Send the loaded blob immediately here and continue processing the queue.
+ PresentationController* controller = presentationController();
+ if (controller)
+ controller->sendBlobData(m_url, m_id, static_cast<const uint8_t*>(buffer->data()), buffer->byteLength());
+
+ m_messages.removeFirst();
+ m_blobLoader.clear();
USE s.singapati at gmail.com 2015/06/02 16:25:44 Did manual testing. Tried to but could not simulat
+ handleMessageQueue();
+}
+
+void PresentationSession::didFailLoadingBlob(FileError::ErrorCode errorCode)
+{
+ ASSERT(!m_messages.isEmpty() && m_messages.first()->type == MessageTypeBlob);
+ // FIXME: generate error message?
+ // Ignore the current failed blob item and continue with next items.
+ m_messages.removeFirst();
+ m_blobLoader.clear();
+ handleMessageQueue();
+}
+
} // namespace blink
« no previous file with comments | « Source/modules/presentation/PresentationSession.h ('k') | Source/modules/presentation/PresentationSession.idl » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698