Index: Source/modules/navigatorconnect/AcceptConnectionObserver.cpp |
diff --git a/Source/modules/navigatorconnect/AcceptConnectionObserver.cpp b/Source/modules/navigatorconnect/AcceptConnectionObserver.cpp |
index 9807f0dde6d0391eac241ebcaf67ae3939dcdaa8..f8511c6c40b0d14be80d9e7fc16860c9cb5c2ff2 100644 |
--- a/Source/modules/navigatorconnect/AcceptConnectionObserver.cpp |
+++ b/Source/modules/navigatorconnect/AcceptConnectionObserver.cpp |
@@ -9,7 +9,11 @@ |
#include "bindings/core/v8/ScriptFunction.h" |
#include "bindings/core/v8/ScriptPromise.h" |
#include "bindings/core/v8/ScriptValue.h" |
+#include "bindings/core/v8/SerializedScriptValueFactory.h" |
+#include "core/dom/DOMException.h" |
#include "core/dom/ExceptionCode.h" |
+#include "modules/navigatorconnect/ServicePort.h" |
+#include "modules/navigatorconnect/ServicePortConnectResponse.h" |
#include "modules/serviceworkers/ServiceWorkerGlobalScopeClient.h" |
namespace blink { |
@@ -49,9 +53,9 @@ private: |
ASSERT(m_observer); |
ASSERT(m_resolveType == Fulfilled || m_resolveType == Rejected); |
if (m_resolveType == Rejected) |
- m_observer->connectionWasRejected(); |
+ m_observer->responseWasRejected(); |
else |
- m_observer->connectionWasAccepted(value); |
+ m_observer->responseWasResolved(value); |
m_observer = nullptr; |
return value; |
} |
@@ -65,6 +69,11 @@ AcceptConnectionObserver* AcceptConnectionObserver::create(ExecutionContext* con |
return new AcceptConnectionObserver(context, eventID); |
} |
+AcceptConnectionObserver* AcceptConnectionObserver::create(ServicePortCollection* collection, PassOwnPtr<WebServicePortConnectEventCallbacks> callbacks, WebServicePortID portID, const KURL& targetURL) |
+{ |
+ return new AcceptConnectionObserver(collection, callbacks, portID, targetURL); |
+} |
+ |
void AcceptConnectionObserver::contextDestroyed() |
{ |
ContextLifecycleObserver::contextDestroyed(); |
@@ -76,7 +85,7 @@ void AcceptConnectionObserver::didDispatchEvent() |
ASSERT(executionContext()); |
if (m_state != Initial) |
return; |
- connectionWasRejected(); |
+ responseWasRejected(); |
} |
void AcceptConnectionObserver::acceptConnection(ScriptState* scriptState, ScriptPromise value, ExceptionState& exceptionState) |
@@ -92,33 +101,105 @@ void AcceptConnectionObserver::acceptConnection(ScriptState* scriptState, Script |
ThenFunction::createFunction(scriptState, this, ThenFunction::Rejected)); |
} |
-void AcceptConnectionObserver::connectionWasRejected() |
+ScriptPromise AcceptConnectionObserver::respondWith(ScriptState* scriptState, ScriptPromise value, ExceptionState& exceptionState) |
+{ |
+ if (m_state != Initial) { |
+ return ScriptPromise::rejectWithDOMException(scriptState, DOMException::create(InvalidStateError, "respondWith was already called.")); |
+ } |
+ |
+ m_state = Pending; |
+ m_resolver = ScriptPromiseResolver::create(scriptState); |
+ ScriptPromise promise = m_resolver->promise(); |
+ value.then( |
+ ThenFunction::createFunction(scriptState, this, ThenFunction::Fulfilled), |
+ ThenFunction::createFunction(scriptState, this, ThenFunction::Rejected)); |
+ return promise; |
+} |
+ |
+void AcceptConnectionObserver::responseWasRejected() |
{ |
ASSERT(executionContext()); |
- ServiceWorkerGlobalScopeClient::from(executionContext())->didHandleCrossOriginConnectEvent(m_eventID, false); |
+ if (m_resolver) |
+ m_resolver->reject(DOMException::create(AbortError)); |
+ if (m_callbacks) { |
+ m_callbacks->onError(); |
+ } else { |
+ ServiceWorkerGlobalScopeClient::from(executionContext())->didHandleCrossOriginConnectEvent(m_eventID, false); |
+ } |
m_state = Done; |
} |
-void AcceptConnectionObserver::connectionWasAccepted(const ScriptValue& value) |
+void AcceptConnectionObserver::responseWasResolved(const ScriptValue& value) |
{ |
ASSERT(executionContext()); |
- if (!value.v8Value()->IsTrue()) { |
- connectionWasRejected(); |
+ if (!m_resolver) { |
+ // TODO(mek): Get rid of this block when observer is only used for |
+ // service port connect events. |
+ if (!value.v8Value()->IsTrue()) { |
+ responseWasRejected(); |
+ return; |
+ } |
+ ServiceWorkerGlobalScopeClient::from(executionContext())->didHandleCrossOriginConnectEvent(m_eventID, true); |
+ m_state = Done; |
+ return; |
+ } |
+ |
+ ScriptState* scriptState = m_resolver->scriptState(); |
+ ExceptionState exceptionState(ExceptionState::UnknownContext, nullptr, nullptr, scriptState->context()->Global(), scriptState->isolate()); |
+ ServicePortConnectResponse response = ScriptValue::to<ServicePortConnectResponse>(scriptState->isolate(), value, exceptionState); |
+ if (exceptionState.hadException()) { |
+ exceptionState.reject(m_resolver.get()); |
+ m_resolver = nullptr; |
+ responseWasRejected(); |
+ return; |
+ } |
+ if (!response.hasAccept() || !response.accept()) { |
+ responseWasRejected(); |
return; |
} |
- ServiceWorkerGlobalScopeClient::from(executionContext())->didHandleCrossOriginConnectEvent(m_eventID, true); |
+ WebServicePort webPort; |
+ webPort.targetUrl = m_targetURL; |
+ if (response.hasName()) |
+ webPort.name = response.name(); |
+ if (response.hasData()) { |
+ webPort.data = SerializedScriptValueFactory::instance().create(scriptState->isolate(), response.data(), nullptr, exceptionState)->toWireString(); |
+ if (exceptionState.hadException()) { |
+ exceptionState.reject(m_resolver.get()); |
+ m_resolver = nullptr; |
+ responseWasRejected(); |
+ return; |
+ } |
+ } |
+ webPort.id = m_portID; |
+ ServicePort* port = ServicePort::create(m_collection, webPort); |
+ m_collection->addPort(port); |
+ m_resolver->resolve(port); |
+ m_callbacks->onSuccess(&webPort); |
m_state = Done; |
} |
AcceptConnectionObserver::AcceptConnectionObserver(ExecutionContext* context, int eventID) |
: ContextLifecycleObserver(context) |
, m_eventID(eventID) |
+ , m_portID(-1) |
+ , m_state(Initial) |
+{ |
+} |
+ |
+AcceptConnectionObserver::AcceptConnectionObserver(ServicePortCollection* collection, PassOwnPtr<WebServicePortConnectEventCallbacks> callbacks, WebServicePortID portID, const KURL& targetURL) |
+ : ContextLifecycleObserver(collection->executionContext()) |
+ , m_eventID(-1) |
+ , m_callbacks(callbacks) |
+ , m_collection(collection) |
+ , m_portID(portID) |
+ , m_targetURL(targetURL) |
, m_state(Initial) |
{ |
} |
DEFINE_TRACE(AcceptConnectionObserver) |
{ |
+ visitor->trace(m_collection); |
ContextLifecycleObserver::trace(visitor); |
} |