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/encryptedmedia/NavigatorRequestMediaKeySystemAccess.h" | 6 #include "modules/encryptedmedia/NavigatorRequestMediaKeySystemAccess.h" |
7 | 7 |
8 #include "bindings/core/v8/ScriptPromiseResolver.h" | 8 #include "bindings/core/v8/ScriptPromiseResolver.h" |
9 #include "bindings/core/v8/ScriptState.h" | 9 #include "bindings/core/v8/ScriptState.h" |
10 #include "core/dom/DOMException.h" | 10 #include "core/dom/DOMException.h" |
11 #include "core/dom/Document.h" | 11 #include "core/dom/Document.h" |
12 #include "core/dom/ExceptionCode.h" | 12 #include "core/dom/ExceptionCode.h" |
13 #include "core/frame/OriginsUsingFeatures.h" | 13 #include "core/frame/OriginsUsingFeatures.h" |
14 #include "core/frame/UseCounter.h" | 14 #include "core/frame/UseCounter.h" |
| 15 #include "core/inspector/ConsoleMessage.h" |
15 #include "modules/encryptedmedia/EncryptedMediaUtils.h" | 16 #include "modules/encryptedmedia/EncryptedMediaUtils.h" |
16 #include "modules/encryptedmedia/MediaKeySession.h" | 17 #include "modules/encryptedmedia/MediaKeySession.h" |
17 #include "modules/encryptedmedia/MediaKeySystemAccess.h" | 18 #include "modules/encryptedmedia/MediaKeySystemAccess.h" |
18 #include "modules/encryptedmedia/MediaKeysController.h" | 19 #include "modules/encryptedmedia/MediaKeysController.h" |
19 #include "platform/EncryptedMediaRequest.h" | 20 #include "platform/EncryptedMediaRequest.h" |
20 #include "platform/Logging.h" | 21 #include "platform/Logging.h" |
21 #include "platform/network/ParsedContentType.h" | 22 #include "platform/network/ParsedContentType.h" |
| 23 #include "public/platform/Platform.h" |
22 #include "public/platform/WebEncryptedMediaClient.h" | 24 #include "public/platform/WebEncryptedMediaClient.h" |
23 #include "public/platform/WebEncryptedMediaRequest.h" | 25 #include "public/platform/WebEncryptedMediaRequest.h" |
24 #include "public/platform/WebMediaKeySystemConfiguration.h" | 26 #include "public/platform/WebMediaKeySystemConfiguration.h" |
25 #include "public/platform/WebMediaKeySystemMediaCapability.h" | 27 #include "public/platform/WebMediaKeySystemMediaCapability.h" |
26 #include "public/platform/WebVector.h" | 28 #include "public/platform/WebVector.h" |
27 #include "wtf/Vector.h" | 29 #include "wtf/Vector.h" |
28 #include "wtf/text/WTFString.h" | 30 #include "wtf/text/WTFString.h" |
29 | 31 |
30 namespace blink { | 32 namespace blink { |
31 | 33 |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
96 | 98 |
97 ScriptPromise promise() { return m_resolver->promise(); } | 99 ScriptPromise promise() { return m_resolver->promise(); } |
98 | 100 |
99 DEFINE_INLINE_VIRTUAL_TRACE() | 101 DEFINE_INLINE_VIRTUAL_TRACE() |
100 { | 102 { |
101 visitor->trace(m_resolver); | 103 visitor->trace(m_resolver); |
102 EncryptedMediaRequest::trace(visitor); | 104 EncryptedMediaRequest::trace(visitor); |
103 } | 105 } |
104 | 106 |
105 private: | 107 private: |
| 108 // For widevine key system, generate warning and report to UMA if |
| 109 // |m_supportedConfigurations| contains any video capability with empty |
| 110 // robustness string. |
| 111 // TODO(xhwang): Remove after we handle empty robustness correctly. |
| 112 // See http://crbug.com/482277 |
| 113 void checkVideoCapabilityRobustness() const; |
| 114 |
106 Member<ScriptPromiseResolver> m_resolver; | 115 Member<ScriptPromiseResolver> m_resolver; |
107 const String m_keySystem; | 116 const String m_keySystem; |
108 WebVector<WebMediaKeySystemConfiguration> m_supportedConfigurations; | 117 WebVector<WebMediaKeySystemConfiguration> m_supportedConfigurations; |
109 }; | 118 }; |
110 | 119 |
111 MediaKeySystemAccessInitializer::MediaKeySystemAccessInitializer(ScriptState* sc
riptState, const String& keySystem, const HeapVector<MediaKeySystemConfiguration
>& supportedConfigurations) | 120 MediaKeySystemAccessInitializer::MediaKeySystemAccessInitializer(ScriptState* sc
riptState, const String& keySystem, const HeapVector<MediaKeySystemConfiguration
>& supportedConfigurations) |
112 : m_resolver(ScriptPromiseResolver::create(scriptState)) | 121 : m_resolver(ScriptPromiseResolver::create(scriptState)) |
113 , m_keySystem(keySystem) | 122 , m_keySystem(keySystem) |
114 , m_supportedConfigurations(supportedConfigurations.size()) | 123 , m_supportedConfigurations(supportedConfigurations.size()) |
115 { | 124 { |
(...skipping 17 matching lines...) Expand all Loading... |
133 ASSERT(config.hasPersistentState()); | 142 ASSERT(config.hasPersistentState()); |
134 webConfig.persistentState = convertMediaKeysRequirement(config.persisten
tState()); | 143 webConfig.persistentState = convertMediaKeysRequirement(config.persisten
tState()); |
135 if (config.hasSessionTypes()) { | 144 if (config.hasSessionTypes()) { |
136 webConfig.hasSessionTypes = true; | 145 webConfig.hasSessionTypes = true; |
137 webConfig.sessionTypes = convertSessionTypes(config.sessionTypes()); | 146 webConfig.sessionTypes = convertSessionTypes(config.sessionTypes()); |
138 } | 147 } |
139 // If |label| is not present, it will be a null string. | 148 // If |label| is not present, it will be a null string. |
140 webConfig.label = config.label(); | 149 webConfig.label = config.label(); |
141 m_supportedConfigurations[i] = webConfig; | 150 m_supportedConfigurations[i] = webConfig; |
142 } | 151 } |
| 152 |
| 153 checkVideoCapabilityRobustness(); |
143 } | 154 } |
144 | 155 |
145 void MediaKeySystemAccessInitializer::requestSucceeded(WebContentDecryptionModul
eAccess* access) | 156 void MediaKeySystemAccessInitializer::requestSucceeded(WebContentDecryptionModul
eAccess* access) |
146 { | 157 { |
147 m_resolver->resolve(new MediaKeySystemAccess(m_keySystem, adoptPtr(access)))
; | 158 m_resolver->resolve(new MediaKeySystemAccess(m_keySystem, adoptPtr(access)))
; |
148 m_resolver.clear(); | 159 m_resolver.clear(); |
149 } | 160 } |
150 | 161 |
151 void MediaKeySystemAccessInitializer::requestNotSupported(const WebString& error
Message) | 162 void MediaKeySystemAccessInitializer::requestNotSupported(const WebString& error
Message) |
152 { | 163 { |
153 m_resolver->reject(DOMException::create(NotSupportedError, errorMessage)); | 164 m_resolver->reject(DOMException::create(NotSupportedError, errorMessage)); |
154 m_resolver.clear(); | 165 m_resolver.clear(); |
155 } | 166 } |
156 | 167 |
| 168 void MediaKeySystemAccessInitializer::checkVideoCapabilityRobustness() const |
| 169 { |
| 170 // Only check for widevine key system. |
| 171 if (keySystem() != "com.widevine.alpha") |
| 172 return; |
| 173 |
| 174 bool hasVideoCapabilities = false; |
| 175 bool hasEmptyRobustness = false; |
| 176 |
| 177 for (const auto& config : m_supportedConfigurations) { |
| 178 if (!config.hasVideoCapabilities) |
| 179 continue; |
| 180 |
| 181 hasVideoCapabilities = true; |
| 182 |
| 183 for (const auto& capability : config.videoCapabilities) { |
| 184 if (capability.robustness.isEmpty()) { |
| 185 hasEmptyRobustness = true; |
| 186 break; |
| 187 } |
| 188 } |
| 189 |
| 190 if (hasEmptyRobustness) |
| 191 break; |
| 192 } |
| 193 |
| 194 if (hasVideoCapabilities) |
| 195 Platform::current()->histogramEnumeration("Media.EME.Widevine.VideoCapab
ility.HasEmptyRobustness", hasEmptyRobustness, 2); |
| 196 |
| 197 if (hasEmptyRobustness) { |
| 198 m_resolver->executionContext()->addConsoleMessage(ConsoleMessage::create
(JSMessageSource, WarningMessageLevel, |
| 199 "It is recommended that a robustness level be specified. Not specify
ing the robustness level could " |
| 200 "result in unexpected behavior in the future, potentially including
failure to play.")); |
| 201 } |
| 202 } |
| 203 |
157 } // namespace | 204 } // namespace |
158 | 205 |
159 ScriptPromise NavigatorRequestMediaKeySystemAccess::requestMediaKeySystemAccess( | 206 ScriptPromise NavigatorRequestMediaKeySystemAccess::requestMediaKeySystemAccess( |
160 ScriptState* scriptState, | 207 ScriptState* scriptState, |
161 Navigator& navigator, | 208 Navigator& navigator, |
162 const String& keySystem, | 209 const String& keySystem, |
163 const HeapVector<MediaKeySystemConfiguration>& supportedConfigurations) | 210 const HeapVector<MediaKeySystemConfiguration>& supportedConfigurations) |
164 { | 211 { |
165 WTF_LOG(Media, "NavigatorRequestMediaKeySystemAccess::requestMediaKeySystemA
ccess()"); | 212 WTF_LOG(Media, "NavigatorRequestMediaKeySystemAccess::requestMediaKeySystemA
ccess()"); |
166 | 213 |
(...skipping 18 matching lines...) Expand all Loading... |
185 ExecutionContext* executionContext = scriptState->executionContext(); | 232 ExecutionContext* executionContext = scriptState->executionContext(); |
186 String errorMessage; | 233 String errorMessage; |
187 if (executionContext->isSecureContext(errorMessage)) { | 234 if (executionContext->isSecureContext(errorMessage)) { |
188 UseCounter::count(executionContext, UseCounter::EncryptedMediaSecureOrig
in); | 235 UseCounter::count(executionContext, UseCounter::EncryptedMediaSecureOrig
in); |
189 } else { | 236 } else { |
190 UseCounter::countDeprecation(executionContext, UseCounter::EncryptedMedi
aInsecureOrigin); | 237 UseCounter::countDeprecation(executionContext, UseCounter::EncryptedMedi
aInsecureOrigin); |
191 // TODO(ddorwin): Implement the following: | 238 // TODO(ddorwin): Implement the following: |
192 // Reject promise with a new DOMException whose name is NotSupportedErro
r. | 239 // Reject promise with a new DOMException whose name is NotSupportedErro
r. |
193 } | 240 } |
194 | 241 |
195 | |
196 // 5. Let origin be the origin of document. | 242 // 5. Let origin be the origin of document. |
197 // (Passed with the execution context in step 7.) | 243 // (Passed with the execution context in step 7.) |
198 | 244 |
199 // 6. Let promise be a new promise. | 245 // 6. Let promise be a new promise. |
200 Document* document = toDocument(executionContext); | 246 Document* document = toDocument(executionContext); |
201 if (!document->page()) { | 247 if (!document->page()) { |
202 return ScriptPromise::rejectWithDOMException( | 248 return ScriptPromise::rejectWithDOMException( |
203 scriptState, DOMException::create(InvalidStateError, "The context pr
ovided is not associated with a page.")); | 249 scriptState, DOMException::create(InvalidStateError, "The context pr
ovided is not associated with a page.")); |
204 } | 250 } |
205 | 251 |
206 MediaKeySystemAccessInitializer* initializer = new MediaKeySystemAccessIniti
alizer(scriptState, keySystem, supportedConfigurations); | 252 MediaKeySystemAccessInitializer* initializer = new MediaKeySystemAccessIniti
alizer(scriptState, keySystem, supportedConfigurations); |
207 ScriptPromise promise = initializer->promise(); | 253 ScriptPromise promise = initializer->promise(); |
208 | 254 |
209 // 7. Asynchronously determine support, and if allowed, create and | 255 // 7. Asynchronously determine support, and if allowed, create and |
210 // initialize the MediaKeySystemAccess object. | 256 // initialize the MediaKeySystemAccess object. |
211 MediaKeysController* controller = MediaKeysController::from(document->page()
); | 257 MediaKeysController* controller = MediaKeysController::from(document->page()
); |
212 WebEncryptedMediaClient* mediaClient = controller->encryptedMediaClient(exec
utionContext); | 258 WebEncryptedMediaClient* mediaClient = controller->encryptedMediaClient(exec
utionContext); |
213 mediaClient->requestMediaKeySystemAccess(WebEncryptedMediaRequest(initialize
r)); | 259 mediaClient->requestMediaKeySystemAccess(WebEncryptedMediaRequest(initialize
r)); |
214 | 260 |
215 // 8. Return promise. | 261 // 8. Return promise. |
216 return promise; | 262 return promise; |
217 } | 263 } |
218 | 264 |
219 } // namespace blink | 265 } // namespace blink |
OLD | NEW |