Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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 "modules/presentation/PresentationRequest.h" | 5 #include "modules/presentation/PresentationRequest.h" |
| 6 | 6 |
| 7 #include "bindings/core/v8/CallbackPromiseAdapter.h" | 7 #include "bindings/core/v8/CallbackPromiseAdapter.h" |
| 8 #include "bindings/core/v8/ExceptionState.h" | 8 #include "bindings/core/v8/ExceptionState.h" |
| 9 #include "bindings/core/v8/ScriptPromise.h" | 9 #include "bindings/core/v8/ScriptPromise.h" |
| 10 #include "bindings/core/v8/ScriptPromiseResolver.h" | 10 #include "bindings/core/v8/ScriptPromiseResolver.h" |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 44 return controller ? controller->client() : nullptr; | 44 return controller ? controller->client() : nullptr; |
| 45 } | 45 } |
| 46 | 46 |
| 47 Settings* settings(ExecutionContext* executionContext) { | 47 Settings* settings(ExecutionContext* executionContext) { |
| 48 DCHECK(executionContext); | 48 DCHECK(executionContext); |
| 49 | 49 |
| 50 Document* document = toDocument(executionContext); | 50 Document* document = toDocument(executionContext); |
| 51 return document->settings(); | 51 return document->settings(); |
| 52 } | 52 } |
| 53 | 53 |
| 54 ScriptPromise rejectWithMixedContentException(ScriptState* scriptState, | |
| 55 const String& url) { | |
| 56 return ScriptPromise::rejectWithDOMException( | |
| 57 scriptState, | |
| 58 DOMException::create(SecurityError, | |
| 59 "Presentation of an insecure document [" + url + | |
| 60 "] is prohibited from a secure context.")); | |
| 61 } | |
| 62 | |
| 63 ScriptPromise rejectWithSandBoxException(ScriptState* scriptState) { | 54 ScriptPromise rejectWithSandBoxException(ScriptState* scriptState) { |
| 64 return ScriptPromise::rejectWithDOMException( | 55 return ScriptPromise::rejectWithDOMException( |
| 65 scriptState, DOMException::create(SecurityError, | 56 scriptState, DOMException::create(SecurityError, |
| 66 "The document is sandboxed and lacks " | 57 "The document is sandboxed and lacks " |
| 67 "the 'allow-presentation' flag.")); | 58 "the 'allow-presentation' flag.")); |
| 68 } | 59 } |
| 69 | 60 |
| 70 } // anonymous namespace | 61 } // anonymous namespace |
| 71 | 62 |
| 72 // static | 63 // static |
| 73 PresentationRequest* PresentationRequest::create( | 64 PresentationRequest* PresentationRequest::create( |
| 74 ExecutionContext* executionContext, | 65 ExecutionContext* executionContext, |
| 75 const String& url, | 66 const String& url, |
| 76 ExceptionState& exceptionState) { | 67 ExceptionState& exceptionState) { |
| 77 KURL parsedUrl = KURL(executionContext->url(), url); | 68 WTF::Vector<String> urls(1); |
|
haraken
2017/01/04 23:53:52
Nit: We won't need the WTF:: prefix.
zhaobin
2017/01/06 18:30:34
Done.
| |
| 78 if (!parsedUrl.isValid() || parsedUrl.protocolIsAbout()) { | 69 urls[0] = url; |
| 79 exceptionState.throwTypeError("'" + url + | 70 return create(executionContext, urls, exceptionState); |
| 80 "' can't be resolved to a valid URL."); | 71 } |
| 72 | |
| 73 PresentationRequest* PresentationRequest::create( | |
| 74 ExecutionContext* executionContext, | |
| 75 const WTF::Vector<String>& urls, | |
| 76 ExceptionState& exceptionState) { | |
| 77 if (urls.isEmpty()) { | |
| 78 exceptionState.throwDOMException(NotSupportedError, | |
| 79 "Do not support empty sequence of URLs."); | |
| 81 return nullptr; | 80 return nullptr; |
| 82 } | 81 } |
| 83 | 82 |
| 84 return new PresentationRequest(executionContext, parsedUrl); | 83 WTF::Vector<KURL> parsedUrls(urls.size()); |
| 84 for (size_t i = 0; i < urls.size(); ++i) { | |
| 85 const KURL& parsedUrl = KURL(executionContext->url(), urls[i]); | |
| 86 | |
| 87 if (!parsedUrl.isValid() || parsedUrl.protocolIsAbout()) { | |
| 88 exceptionState.throwDOMException( | |
| 89 SyntaxError, "'" + urls[i] + "' can't be resolved to a valid URL."); | |
| 90 return nullptr; | |
| 91 } | |
| 92 | |
| 93 if (MixedContentChecker::isMixedContent( | |
| 94 executionContext->getSecurityOrigin(), parsedUrl)) { | |
| 95 exceptionState.throwDOMException( | |
| 96 SecurityError, "Presentation of an insecure document [" + urls[i] + | |
| 97 "] is prohibited from a secure context."); | |
| 98 return nullptr; | |
| 99 } | |
| 100 | |
| 101 parsedUrls[i] = parsedUrl; | |
| 102 } | |
| 103 return new PresentationRequest(executionContext, parsedUrls); | |
| 85 } | 104 } |
| 86 | 105 |
| 87 const AtomicString& PresentationRequest::interfaceName() const { | 106 const AtomicString& PresentationRequest::interfaceName() const { |
| 88 return EventTargetNames::PresentationRequest; | 107 return EventTargetNames::PresentationRequest; |
| 89 } | 108 } |
| 90 | 109 |
| 91 ExecutionContext* PresentationRequest::getExecutionContext() const { | 110 ExecutionContext* PresentationRequest::getExecutionContext() const { |
| 92 return ContextClient::getExecutionContext(); | 111 return ContextClient::getExecutionContext(); |
| 93 } | 112 } |
| 94 | 113 |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 113 bool isUserGestureRequired = | 132 bool isUserGestureRequired = |
| 114 !contextSettings || contextSettings->presentationRequiresUserGesture(); | 133 !contextSettings || contextSettings->presentationRequiresUserGesture(); |
| 115 | 134 |
| 116 if (isUserGestureRequired && !UserGestureIndicator::utilizeUserGesture()) | 135 if (isUserGestureRequired && !UserGestureIndicator::utilizeUserGesture()) |
| 117 return ScriptPromise::rejectWithDOMException( | 136 return ScriptPromise::rejectWithDOMException( |
| 118 scriptState, | 137 scriptState, |
| 119 DOMException::create( | 138 DOMException::create( |
| 120 InvalidAccessError, | 139 InvalidAccessError, |
| 121 "PresentationRequest::start() requires user gesture.")); | 140 "PresentationRequest::start() requires user gesture.")); |
| 122 | 141 |
| 123 if (MixedContentChecker::isMixedContent( | |
| 124 getExecutionContext()->getSecurityOrigin(), m_url)) { | |
| 125 return rejectWithMixedContentException(scriptState, m_url.getString()); | |
| 126 } | |
| 127 | |
| 128 if (toDocument(getExecutionContext())->isSandboxed(SandboxPresentation)) | 142 if (toDocument(getExecutionContext())->isSandboxed(SandboxPresentation)) |
| 129 return rejectWithSandBoxException(scriptState); | 143 return rejectWithSandBoxException(scriptState); |
| 130 | 144 |
| 131 WebPresentationClient* client = presentationClient(getExecutionContext()); | 145 WebPresentationClient* client = presentationClient(getExecutionContext()); |
| 132 if (!client) | 146 if (!client) |
| 133 return ScriptPromise::rejectWithDOMException( | 147 return ScriptPromise::rejectWithDOMException( |
| 134 scriptState, | 148 scriptState, |
| 135 DOMException::create( | 149 DOMException::create( |
| 136 InvalidStateError, | 150 InvalidStateError, |
| 137 "The PresentationRequest is no longer associated to a frame.")); | 151 "The PresentationRequest is no longer associated to a frame.")); |
| 138 | 152 |
| 139 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); | 153 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); |
| 140 // TODO(crbug.com/627655): Accept multiple URLs per PresentationRequest. | |
| 141 WebVector<WebURL> presentationUrls(static_cast<size_t>(1U)); | |
| 142 presentationUrls[0] = m_url; | |
| 143 client->startSession( | 154 client->startSession( |
| 144 presentationUrls, | 155 m_urls, WTF::makeUnique<PresentationConnectionCallbacks>(resolver, this)); |
| 145 WTF::makeUnique<PresentationConnectionCallbacks>(resolver, this)); | |
| 146 return resolver->promise(); | 156 return resolver->promise(); |
| 147 } | 157 } |
| 148 | 158 |
| 149 ScriptPromise PresentationRequest::reconnect(ScriptState* scriptState, | 159 ScriptPromise PresentationRequest::reconnect(ScriptState* scriptState, |
| 150 const String& id) { | 160 const String& id) { |
| 151 if (MixedContentChecker::isMixedContent( | |
| 152 getExecutionContext()->getSecurityOrigin(), m_url)) { | |
| 153 return rejectWithMixedContentException(scriptState, m_url.getString()); | |
| 154 } | |
| 155 | |
| 156 if (toDocument(getExecutionContext())->isSandboxed(SandboxPresentation)) | 161 if (toDocument(getExecutionContext())->isSandboxed(SandboxPresentation)) |
| 157 return rejectWithSandBoxException(scriptState); | 162 return rejectWithSandBoxException(scriptState); |
| 158 | 163 |
| 159 WebPresentationClient* client = presentationClient(getExecutionContext()); | 164 WebPresentationClient* client = presentationClient(getExecutionContext()); |
| 160 if (!client) | 165 if (!client) |
| 161 return ScriptPromise::rejectWithDOMException( | 166 return ScriptPromise::rejectWithDOMException( |
| 162 scriptState, | 167 scriptState, |
| 163 DOMException::create( | 168 DOMException::create( |
| 164 InvalidStateError, | 169 InvalidStateError, |
| 165 "The PresentationRequest is no longer associated to a frame.")); | 170 "The PresentationRequest is no longer associated to a frame.")); |
| 166 | 171 |
| 167 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); | 172 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); |
| 168 // TODO(crbug.com/627655): Accept multiple URLs per PresentationRequest. | |
| 169 WebVector<WebURL> presentationUrls(static_cast<size_t>(1U)); | |
| 170 presentationUrls[0] = m_url; | |
| 171 | 173 |
| 172 PresentationController* controller = | 174 PresentationController* controller = |
| 173 presentationController(getExecutionContext()); | 175 presentationController(getExecutionContext()); |
| 174 DCHECK(controller); | 176 DCHECK(controller); |
| 175 | 177 |
| 176 PresentationConnection* existingConnection = | 178 PresentationConnection* existingConnection = |
| 177 controller->findExistingConnection(presentationUrls, id); | 179 controller->findExistingConnection(m_urls, id); |
| 178 if (existingConnection) { | 180 if (existingConnection) { |
| 179 client->joinSession( | 181 client->joinSession( |
| 180 presentationUrls, id, | 182 m_urls, id, WTF::makeUnique<ExistingPresentationConnectionCallbacks>( |
| 181 WTF::makeUnique<ExistingPresentationConnectionCallbacks>( | 183 resolver, existingConnection)); |
| 182 resolver, existingConnection)); | |
| 183 } else { | 184 } else { |
| 184 client->joinSession( | 185 client->joinSession( |
| 185 presentationUrls, id, | 186 m_urls, id, |
| 186 WTF::makeUnique<PresentationConnectionCallbacks>(resolver, this)); | 187 WTF::makeUnique<PresentationConnectionCallbacks>(resolver, this)); |
| 187 } | 188 } |
| 188 return resolver->promise(); | 189 return resolver->promise(); |
| 189 } | 190 } |
| 190 | 191 |
| 191 ScriptPromise PresentationRequest::getAvailability(ScriptState* scriptState) { | 192 ScriptPromise PresentationRequest::getAvailability(ScriptState* scriptState) { |
| 192 if (MixedContentChecker::isMixedContent( | |
| 193 getExecutionContext()->getSecurityOrigin(), m_url)) { | |
| 194 return rejectWithMixedContentException(scriptState, m_url.getString()); | |
| 195 } | |
| 196 | |
| 197 if (toDocument(getExecutionContext())->isSandboxed(SandboxPresentation)) | 193 if (toDocument(getExecutionContext())->isSandboxed(SandboxPresentation)) |
| 198 return rejectWithSandBoxException(scriptState); | 194 return rejectWithSandBoxException(scriptState); |
| 199 | 195 |
| 200 WebPresentationClient* client = presentationClient(getExecutionContext()); | 196 WebPresentationClient* client = presentationClient(getExecutionContext()); |
| 201 if (!client) | 197 if (!client) |
| 202 return ScriptPromise::rejectWithDOMException( | 198 return ScriptPromise::rejectWithDOMException( |
| 203 scriptState, | 199 scriptState, |
| 204 DOMException::create( | 200 DOMException::create( |
| 205 InvalidStateError, | 201 InvalidStateError, |
| 206 "The PresentationRequest is no longer associated to a frame.")); | 202 "The PresentationRequest is no longer associated to a frame.")); |
| 207 | 203 |
| 208 if (!m_availabilityProperty) { | 204 if (!m_availabilityProperty) { |
| 209 m_availabilityProperty = new PresentationAvailabilityProperty( | 205 m_availabilityProperty = new PresentationAvailabilityProperty( |
| 210 scriptState->getExecutionContext(), this, | 206 scriptState->getExecutionContext(), this, |
| 211 PresentationAvailabilityProperty::Ready); | 207 PresentationAvailabilityProperty::Ready); |
| 212 | 208 |
| 213 client->getAvailability(m_url, | 209 client->getAvailability(m_urls, |
| 214 WTF::makeUnique<PresentationAvailabilityCallbacks>( | 210 WTF::makeUnique<PresentationAvailabilityCallbacks>( |
| 215 m_availabilityProperty, m_url)); | 211 m_availabilityProperty, m_urls)); |
| 216 } | 212 } |
| 217 return m_availabilityProperty->promise(scriptState->world()); | 213 return m_availabilityProperty->promise(scriptState->world()); |
| 218 } | 214 } |
| 219 | 215 |
| 220 const KURL& PresentationRequest::url() const { | 216 const WTF::Vector<KURL>& PresentationRequest::urls() const { |
| 221 return m_url; | 217 return m_urls; |
| 222 } | 218 } |
| 223 | 219 |
| 224 DEFINE_TRACE(PresentationRequest) { | 220 DEFINE_TRACE(PresentationRequest) { |
| 225 visitor->trace(m_availabilityProperty); | 221 visitor->trace(m_availabilityProperty); |
| 226 EventTargetWithInlineData::trace(visitor); | 222 EventTargetWithInlineData::trace(visitor); |
| 227 ContextClient::trace(visitor); | 223 ContextClient::trace(visitor); |
| 228 } | 224 } |
| 229 | 225 |
| 230 PresentationRequest::PresentationRequest(ExecutionContext* executionContext, | 226 PresentationRequest::PresentationRequest(ExecutionContext* executionContext, |
| 231 const KURL& url) | 227 const WTF::Vector<KURL>& urls) |
| 232 : ContextClient(executionContext), m_url(url) {} | 228 : ContextClient(executionContext), m_urls(urls) {} |
| 233 | 229 |
| 234 } // namespace blink | 230 } // namespace blink |
| OLD | NEW |