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/HTMLMediaElementEncryptedMedia.h" | 6 #include "modules/encryptedmedia/HTMLMediaElementEncryptedMedia.h" |
7 | 7 |
8 #include "bindings/core/v8/ExceptionState.h" | 8 #include "bindings/core/v8/ExceptionState.h" |
| 9 #include "bindings/core/v8/ScriptPromise.h" |
| 10 #include "bindings/core/v8/ScriptPromiseResolver.h" |
| 11 #include "bindings/core/v8/ScriptState.h" |
| 12 #include "core/dom/DOMException.h" |
9 #include "core/dom/ExceptionCode.h" | 13 #include "core/dom/ExceptionCode.h" |
10 #include "core/html/HTMLMediaElement.h" | 14 #include "core/html/HTMLMediaElement.h" |
11 #include "core/html/MediaKeyError.h" | 15 #include "core/html/MediaKeyError.h" |
12 #include "core/html/MediaKeyEvent.h" | 16 #include "core/html/MediaKeyEvent.h" |
13 #include "modules/encryptedmedia/MediaKeyNeededEvent.h" | 17 #include "modules/encryptedmedia/MediaKeyNeededEvent.h" |
14 #include "modules/encryptedmedia/MediaKeys.h" | 18 #include "modules/encryptedmedia/MediaKeys.h" |
| 19 #include "modules/encryptedmedia/SimpleContentDecryptionModuleResult.h" |
| 20 #include "platform/ContentDecryptionModuleResult.h" |
15 #include "platform/Logging.h" | 21 #include "platform/Logging.h" |
16 #include "platform/RuntimeEnabledFeatures.h" | 22 #include "platform/RuntimeEnabledFeatures.h" |
| 23 #include "wtf/Functional.h" |
17 #include "wtf/Uint8Array.h" | 24 #include "wtf/Uint8Array.h" |
18 | 25 |
19 namespace blink { | 26 namespace blink { |
20 | 27 |
21 static void throwExceptionIfMediaKeyExceptionOccurred(const String& keySystem, c
onst String& sessionId, WebMediaPlayer::MediaKeyException exception, ExceptionSt
ate& exceptionState) | 28 static void throwExceptionIfMediaKeyExceptionOccurred(const String& keySystem, c
onst String& sessionId, WebMediaPlayer::MediaKeyException exception, ExceptionSt
ate& exceptionState) |
22 { | 29 { |
23 switch (exception) { | 30 switch (exception) { |
24 case WebMediaPlayer::MediaKeyExceptionNoError: | 31 case WebMediaPlayer::MediaKeyExceptionNoError: |
25 return; | 32 return; |
26 case WebMediaPlayer::MediaKeyExceptionInvalidPlayerState: | 33 case WebMediaPlayer::MediaKeyExceptionInvalidPlayerState: |
27 exceptionState.throwDOMException(InvalidStateError, "The player is in an
invalid state."); | 34 exceptionState.throwDOMException(InvalidStateError, "The player is in an
invalid state."); |
28 return; | 35 return; |
29 case WebMediaPlayer::MediaKeyExceptionKeySystemNotSupported: | 36 case WebMediaPlayer::MediaKeyExceptionKeySystemNotSupported: |
30 exceptionState.throwDOMException(NotSupportedError, "The key system prov
ided ('" + keySystem +"') is not supported."); | 37 exceptionState.throwDOMException(NotSupportedError, "The key system prov
ided ('" + keySystem +"') is not supported."); |
31 return; | 38 return; |
32 case WebMediaPlayer::MediaKeyExceptionInvalidAccess: | 39 case WebMediaPlayer::MediaKeyExceptionInvalidAccess: |
33 exceptionState.throwDOMException(InvalidAccessError, "The session ID pro
vided ('" + sessionId + "') is invalid."); | 40 exceptionState.throwDOMException(InvalidAccessError, "The session ID pro
vided ('" + sessionId + "') is invalid."); |
34 return; | 41 return; |
35 } | 42 } |
36 | 43 |
37 ASSERT_NOT_REACHED(); | 44 ASSERT_NOT_REACHED(); |
38 return; | 45 return; |
39 } | 46 } |
40 | 47 |
| 48 // This class allows MediaKeys to be set asynchronously. |
| 49 class SetMediaKeysHandler : public ScriptPromiseResolver { |
| 50 WTF_MAKE_NONCOPYABLE(SetMediaKeysHandler); |
| 51 |
| 52 public: |
| 53 static ScriptPromise create(ScriptState*, HTMLMediaElement&, MediaKeys*); |
| 54 virtual ~SetMediaKeysHandler(); |
| 55 |
| 56 private: |
| 57 SetMediaKeysHandler(ScriptState*, HTMLMediaElement&, MediaKeys*); |
| 58 void timerFired(Timer<SetMediaKeysHandler>*); |
| 59 |
| 60 void clearExistingMediaKeys(); |
| 61 void setNewMediaKeys(); |
| 62 void finish(); |
| 63 |
| 64 void reportSetFailed(ExceptionCode, const String& errorMessage); |
| 65 |
| 66 RawPtrWillBeMember<HTMLMediaElement> m_element; |
| 67 Persistent<MediaKeys> m_newMediaKeys; |
| 68 Timer<SetMediaKeysHandler> m_timer; |
| 69 }; |
| 70 |
| 71 typedef Function<void()> SuccessCallback; |
| 72 typedef Function<void(ExceptionCode, const String&)> FailureCallback; |
| 73 |
| 74 // Represents the result used when setContentDecryptionModule() is called. |
| 75 // Calls |success| if result is resolved, |failure| is result is rejected. |
| 76 class SetContentDecryptionModuleResult FINAL : public ContentDecryptionModuleRes
ult { |
| 77 public: |
| 78 SetContentDecryptionModuleResult(SuccessCallback success, FailureCallback fa
ilure) |
| 79 : m_successCallback(success) |
| 80 , m_failureCallback(failure) |
| 81 { |
| 82 } |
| 83 |
| 84 // ContentDecryptionModuleResult implementation. |
| 85 virtual void complete() OVERRIDE |
| 86 { |
| 87 m_successCallback(); |
| 88 } |
| 89 |
| 90 virtual void completeWithSession(blink::WebContentDecryptionModuleResult::Se
ssionStatus status) OVERRIDE |
| 91 { |
| 92 ASSERT_NOT_REACHED(); |
| 93 m_failureCallback(InvalidStateError, "Unexpected completion."); |
| 94 } |
| 95 |
| 96 virtual void completeWithError(blink::WebContentDecryptionModuleException co
de, unsigned long systemCode, const blink::WebString& message) OVERRIDE |
| 97 { |
| 98 m_failureCallback(WebCdmExceptionToExceptionCode(code), message); |
| 99 } |
| 100 |
| 101 private: |
| 102 SuccessCallback m_successCallback; |
| 103 FailureCallback m_failureCallback; |
| 104 }; |
| 105 |
| 106 ScriptPromise SetMediaKeysHandler::create(ScriptState* scriptState, HTMLMediaEle
ment& element, MediaKeys* mediaKeys) |
| 107 { |
| 108 RefPtr<SetMediaKeysHandler> handler = adoptRef(new SetMediaKeysHandler(scrip
tState, element, mediaKeys)); |
| 109 handler->suspendIfNeeded(); |
| 110 handler->keepAliveWhilePending(); |
| 111 return handler->promise(); |
| 112 } |
| 113 |
| 114 SetMediaKeysHandler::SetMediaKeysHandler(ScriptState* scriptState, HTMLMediaElem
ent& element, MediaKeys* mediaKeys) |
| 115 : ScriptPromiseResolver(scriptState) |
| 116 , m_element(element) |
| 117 , m_newMediaKeys(mediaKeys) |
| 118 , m_timer(this, &SetMediaKeysHandler::timerFired) |
| 119 { |
| 120 WTF_LOG(Media, "SetMediaKeysHandler::SetMediaKeysHandler"); |
| 121 |
| 122 // 3. Run the remaining steps asynchronously. |
| 123 m_timer.startOneShot(0, FROM_HERE); |
| 124 } |
| 125 |
| 126 SetMediaKeysHandler::~SetMediaKeysHandler() |
| 127 { |
| 128 } |
| 129 |
| 130 void SetMediaKeysHandler::timerFired(Timer<SetMediaKeysHandler>*) |
| 131 { |
| 132 clearExistingMediaKeys(); |
| 133 } |
| 134 |
| 135 void SetMediaKeysHandler::clearExistingMediaKeys() |
| 136 { |
| 137 WTF_LOG(Media, "SetMediaKeysHandler::clearExistingMediaKeys"); |
| 138 HTMLMediaElementEncryptedMedia& thisElement = HTMLMediaElementEncryptedMedia
::from(*m_element); |
| 139 |
| 140 // 3.1 If mediaKeys is not null, it is already in use by another media |
| 141 // element, and the user agent is unable to use it with this element, |
| 142 // reject promise with a new DOMException whose name is |
| 143 // "QuotaExceededError". |
| 144 // FIXME: Need to check whether mediaKeys is already in use by another |
| 145 // media element. |
| 146 // 3.2 If the mediaKeys attribute is not null, run the following steps: |
| 147 if (thisElement.m_mediaKeys) { |
| 148 // 3.2.1 If the user agent or CDM do not support removing the |
| 149 // association, return a promise rejected with a new DOMException |
| 150 // whose name is "NotSupportedError". |
| 151 // (supported by blink). |
| 152 // 3.2.2 If the association cannot currently be removed (i.e. during |
| 153 // playback), return a promise rejected with a new DOMException |
| 154 // whose name is "InvalidStateError". |
| 155 if (m_element->webMediaPlayer()) { |
| 156 reject(DOMException::create(InvalidStateError, "The existing MediaKe
ys object cannot be removed while a media resource is loaded.")); |
| 157 return; |
| 158 } |
| 159 |
| 160 // (next 2 steps not required as there is no player connected). |
| 161 // 3.2.3 Stop using the CDM instance represented by the mediaKeys |
| 162 // attribute to decrypt media data and remove the association |
| 163 // with the media element. |
| 164 // 3.2.4 If the preceding step failed, reject promise with a new |
| 165 // DOMException whose name is the appropriate error name and |
| 166 // that has an appropriate message. |
| 167 } |
| 168 |
| 169 // MediaKeys not currently set or no player connected, so continue on. |
| 170 setNewMediaKeys(); |
| 171 } |
| 172 |
| 173 void SetMediaKeysHandler::setNewMediaKeys() |
| 174 { |
| 175 WTF_LOG(Media, "SetMediaKeysHandler::setNewMediaKeys"); |
| 176 |
| 177 // 3.3 If mediaKeys is not null, run the following steps: |
| 178 if (m_newMediaKeys) { |
| 179 // 3.3.1 Associate the CDM instance represented by mediaKeys with the |
| 180 // media element for decrypting media data. |
| 181 // 3.3.2 If the preceding step failed, run the following steps: |
| 182 // (done in reportSetFailed()). |
| 183 // 3.3.3 Run the Attempt to Resume Playback If Necessary algorithm on |
| 184 // the media element. The user agent may choose to skip this |
| 185 // step if it knows resuming will fail (i.e. mediaKeys has no |
| 186 // sessions). |
| 187 // (Handled in Chromium). |
| 188 if (m_element->webMediaPlayer()) { |
| 189 SuccessCallback successCallback = bind(&SetMediaKeysHandler::finish,
this); |
| 190 FailureCallback failureCallback = bind<ExceptionCode, const String&>
(&SetMediaKeysHandler::reportSetFailed, this); |
| 191 ContentDecryptionModuleResult* result = new SetContentDecryptionModu
leResult(successCallback, failureCallback); |
| 192 m_element->webMediaPlayer()->setContentDecryptionModule(m_newMediaKe
ys->contentDecryptionModule(), result->result()); |
| 193 |
| 194 // Don't do anything more until |result| is resolved (or rejected). |
| 195 return; |
| 196 } |
| 197 } |
| 198 |
| 199 // MediaKeys doesn't need to be set on the player, so continue on. |
| 200 finish(); |
| 201 } |
| 202 |
| 203 void SetMediaKeysHandler::finish() |
| 204 { |
| 205 WTF_LOG(Media, "SetMediaKeysHandler::finish"); |
| 206 HTMLMediaElementEncryptedMedia& thisElement = HTMLMediaElementEncryptedMedia
::from(*m_element); |
| 207 |
| 208 // 3.4 Set the mediaKeys attribute to mediaKeys. |
| 209 thisElement.m_mediaKeys = m_newMediaKeys; |
| 210 |
| 211 // 3.5 Resolve promise with undefined. |
| 212 resolve(); |
| 213 } |
| 214 |
| 215 void SetMediaKeysHandler::reportSetFailed(ExceptionCode code, const String& erro
rMessage) |
| 216 { |
| 217 WTF_LOG(Media, "SetMediaKeysHandler::reportSetFailed"); |
| 218 HTMLMediaElementEncryptedMedia& thisElement = HTMLMediaElementEncryptedMedia
::from(*m_element); |
| 219 |
| 220 // 3.3.2 If the preceding step failed, run the following steps: |
| 221 // 3.3.2.1 Set the mediaKeys attribute to null. |
| 222 thisElement.m_mediaKeys.clear(); |
| 223 |
| 224 // 3.3.2.2 Reject promise with a new DOMException whose name is the |
| 225 // appropriate error name and that has an appropriate message. |
| 226 reject(DOMException::create(code, errorMessage)); |
| 227 } |
| 228 |
41 HTMLMediaElementEncryptedMedia::HTMLMediaElementEncryptedMedia() | 229 HTMLMediaElementEncryptedMedia::HTMLMediaElementEncryptedMedia() |
42 : m_emeMode(EmeModeNotSelected) | 230 : m_emeMode(EmeModeNotSelected) |
43 { | 231 { |
44 } | 232 } |
45 | 233 |
46 DEFINE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(HTMLMediaElementEncryptedMedia) | 234 DEFINE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(HTMLMediaElementEncryptedMedia) |
47 | 235 |
48 const char* HTMLMediaElementEncryptedMedia::supplementName() | 236 const char* HTMLMediaElementEncryptedMedia::supplementName() |
49 { | 237 { |
50 return "HTMLMediaElementEncryptedMedia"; | 238 return "HTMLMediaElementEncryptedMedia"; |
51 } | 239 } |
52 | 240 |
53 HTMLMediaElementEncryptedMedia& HTMLMediaElementEncryptedMedia::from(HTMLMediaEl
ement& element) | 241 HTMLMediaElementEncryptedMedia& HTMLMediaElementEncryptedMedia::from(HTMLMediaEl
ement& element) |
54 { | 242 { |
55 HTMLMediaElementEncryptedMedia* supplement = static_cast<HTMLMediaElementEnc
ryptedMedia*>(WillBeHeapSupplement<HTMLMediaElement>::from(element, supplementNa
me())); | 243 HTMLMediaElementEncryptedMedia* supplement = static_cast<HTMLMediaElementEnc
ryptedMedia*>(WillBeHeapSupplement<HTMLMediaElement>::from(element, supplementNa
me())); |
56 if (!supplement) { | 244 if (!supplement) { |
57 supplement = new HTMLMediaElementEncryptedMedia(); | 245 supplement = new HTMLMediaElementEncryptedMedia(); |
58 provideTo(element, supplementName(), adoptPtrWillBeNoop(supplement)); | 246 provideTo(element, supplementName(), adoptPtrWillBeNoop(supplement)); |
59 } | 247 } |
60 return *supplement; | 248 return *supplement; |
61 } | 249 } |
62 | 250 |
63 bool HTMLMediaElementEncryptedMedia::setEmeMode(EmeMode emeMode, ExceptionState&
exceptionState) | 251 bool HTMLMediaElementEncryptedMedia::setEmeMode(EmeMode emeMode) |
64 { | 252 { |
65 if (m_emeMode != EmeModeNotSelected && m_emeMode != emeMode) { | 253 if (m_emeMode != EmeModeNotSelected && m_emeMode != emeMode) |
66 exceptionState.throwDOMException(InvalidStateError, "Mixed use of EME pr
efixed and unprefixed API not allowed."); | |
67 return false; | 254 return false; |
68 } | 255 |
69 m_emeMode = emeMode; | 256 m_emeMode = emeMode; |
70 return true; | 257 return true; |
71 } | 258 } |
72 | 259 |
73 WebContentDecryptionModule* HTMLMediaElementEncryptedMedia::contentDecryptionMod
ule() | 260 WebContentDecryptionModule* HTMLMediaElementEncryptedMedia::contentDecryptionMod
ule() |
74 { | 261 { |
75 return m_mediaKeys ? m_mediaKeys->contentDecryptionModule() : 0; | 262 return m_mediaKeys ? m_mediaKeys->contentDecryptionModule() : 0; |
76 } | 263 } |
77 | 264 |
78 MediaKeys* HTMLMediaElementEncryptedMedia::mediaKeys(HTMLMediaElement& element) | 265 MediaKeys* HTMLMediaElementEncryptedMedia::mediaKeys(HTMLMediaElement& element) |
79 { | 266 { |
80 HTMLMediaElementEncryptedMedia& thisElement = HTMLMediaElementEncryptedMedia
::from(element); | 267 HTMLMediaElementEncryptedMedia& thisElement = HTMLMediaElementEncryptedMedia
::from(element); |
81 return thisElement.m_mediaKeys.get(); | 268 return thisElement.m_mediaKeys.get(); |
82 } | 269 } |
83 | 270 |
84 void HTMLMediaElementEncryptedMedia::setMediaKeysInternal(HTMLMediaElement& elem
ent, MediaKeys* mediaKeys) | 271 ScriptPromise HTMLMediaElementEncryptedMedia::setMediaKeys(ScriptState* scriptSt
ate, HTMLMediaElement& element, MediaKeys* mediaKeys) |
85 { | 272 { |
86 if (m_mediaKeys == mediaKeys) | 273 HTMLMediaElementEncryptedMedia& thisElement = HTMLMediaElementEncryptedMedia
::from(element); |
87 return; | 274 WTF_LOG(Media, "HTMLMediaElementEncryptedMedia::setMediaKeys current(%p), ne
w(%p)", thisElement.m_mediaKeys.get(), mediaKeys); |
88 | 275 |
89 ASSERT(m_emeMode == EmeModeUnprefixed); | 276 if (!thisElement.setEmeMode(EmeModeUnprefixed)) |
90 m_mediaKeys = mediaKeys; | 277 return ScriptPromise::rejectWithDOMException(scriptState, DOMException::
create(InvalidStateError, "Mixed use of EME prefixed and unprefixed API not allo
wed.")); |
91 | 278 |
92 // If a player is connected, tell it that the CDM has changed. | 279 // 1. If mediaKeys and the mediaKeys attribute are the same object, return |
93 if (element.webMediaPlayer()) | 280 // a promise resolved with undefined. |
94 element.webMediaPlayer()->setContentDecryptionModule(contentDecryptionMo
dule()); | 281 if (thisElement.m_mediaKeys == mediaKeys) |
95 } | 282 return ScriptPromise::cast(scriptState, V8ValueTraits<V8UndefinedType>::
toV8Value(V8UndefinedType(), scriptState->context()->Global(), scriptState->isol
ate())); |
96 | 283 |
97 void HTMLMediaElementEncryptedMedia::setMediaKeys(HTMLMediaElement& element, Med
iaKeys* mediaKeys, ExceptionState& exceptionState) | 284 // 2. Let promise be a new promise. Remaining steps done in handler. |
98 { | 285 return SetMediaKeysHandler::create(scriptState, element, mediaKeys); |
99 WTF_LOG(Media, "HTMLMediaElementEncryptedMedia::setMediaKeys"); | |
100 HTMLMediaElementEncryptedMedia& thisElement = HTMLMediaElementEncryptedMedia
::from(element); | |
101 | |
102 if (!thisElement.setEmeMode(EmeModeUnprefixed, exceptionState)) | |
103 return; | |
104 | |
105 thisElement.setMediaKeysInternal(element, mediaKeys); | |
106 } | 286 } |
107 | 287 |
108 // Create a MediaKeyNeededEvent for WD EME. | 288 // Create a MediaKeyNeededEvent for WD EME. |
109 static PassRefPtrWillBeRawPtr<Event> createNeedKeyEvent(const String& contentTyp
e, const unsigned char* initData, unsigned initDataLength) | 289 static PassRefPtrWillBeRawPtr<Event> createNeedKeyEvent(const String& contentTyp
e, const unsigned char* initData, unsigned initDataLength) |
110 { | 290 { |
111 MediaKeyNeededEventInit initializer; | 291 MediaKeyNeededEventInit initializer; |
112 initializer.contentType = contentType; | 292 initializer.contentType = contentType; |
113 initializer.initData = Uint8Array::create(initData, initDataLength); | 293 initializer.initData = Uint8Array::create(initData, initDataLength); |
114 initializer.bubbles = false; | 294 initializer.bubbles = false; |
115 initializer.cancelable = false; | 295 initializer.cancelable = false; |
(...skipping 16 matching lines...) Expand all Loading... |
132 | 312 |
133 void HTMLMediaElementEncryptedMedia::webkitGenerateKeyRequest(HTMLMediaElement&
element, const String& keySystem, PassRefPtr<Uint8Array> initData, ExceptionStat
e& exceptionState) | 313 void HTMLMediaElementEncryptedMedia::webkitGenerateKeyRequest(HTMLMediaElement&
element, const String& keySystem, PassRefPtr<Uint8Array> initData, ExceptionStat
e& exceptionState) |
134 { | 314 { |
135 HTMLMediaElementEncryptedMedia::from(element).generateKeyRequest(element.web
MediaPlayer(), keySystem, initData, exceptionState); | 315 HTMLMediaElementEncryptedMedia::from(element).generateKeyRequest(element.web
MediaPlayer(), keySystem, initData, exceptionState); |
136 } | 316 } |
137 | 317 |
138 void HTMLMediaElementEncryptedMedia::generateKeyRequest(WebMediaPlayer* webMedia
Player, const String& keySystem, PassRefPtr<Uint8Array> initData, ExceptionState
& exceptionState) | 318 void HTMLMediaElementEncryptedMedia::generateKeyRequest(WebMediaPlayer* webMedia
Player, const String& keySystem, PassRefPtr<Uint8Array> initData, ExceptionState
& exceptionState) |
139 { | 319 { |
140 WTF_LOG(Media, "HTMLMediaElementEncryptedMedia::webkitGenerateKeyRequest"); | 320 WTF_LOG(Media, "HTMLMediaElementEncryptedMedia::webkitGenerateKeyRequest"); |
141 | 321 |
142 if (!setEmeMode(EmeModePrefixed, exceptionState)) | 322 if (!setEmeMode(EmeModePrefixed)) { |
| 323 exceptionState.throwDOMException(InvalidStateError, "Mixed use of EME pr
efixed and unprefixed API not allowed."); |
143 return; | 324 return; |
| 325 } |
144 | 326 |
145 if (keySystem.isEmpty()) { | 327 if (keySystem.isEmpty()) { |
146 exceptionState.throwDOMException(SyntaxError, "The key system provided i
s empty."); | 328 exceptionState.throwDOMException(SyntaxError, "The key system provided i
s empty."); |
147 return; | 329 return; |
148 } | 330 } |
149 | 331 |
150 if (!webMediaPlayer) { | 332 if (!webMediaPlayer) { |
151 exceptionState.throwDOMException(InvalidStateError, "No media has been l
oaded."); | 333 exceptionState.throwDOMException(InvalidStateError, "No media has been l
oaded."); |
152 return; | 334 return; |
153 } | 335 } |
(...skipping 16 matching lines...) Expand all Loading... |
170 | 352 |
171 void HTMLMediaElementEncryptedMedia::webkitAddKey(HTMLMediaElement& element, con
st String& keySystem, PassRefPtr<Uint8Array> key, PassRefPtr<Uint8Array> initDat
a, const String& sessionId, ExceptionState& exceptionState) | 353 void HTMLMediaElementEncryptedMedia::webkitAddKey(HTMLMediaElement& element, con
st String& keySystem, PassRefPtr<Uint8Array> key, PassRefPtr<Uint8Array> initDat
a, const String& sessionId, ExceptionState& exceptionState) |
172 { | 354 { |
173 HTMLMediaElementEncryptedMedia::from(element).addKey(element.webMediaPlayer(
), keySystem, key, initData, sessionId, exceptionState); | 355 HTMLMediaElementEncryptedMedia::from(element).addKey(element.webMediaPlayer(
), keySystem, key, initData, sessionId, exceptionState); |
174 } | 356 } |
175 | 357 |
176 void HTMLMediaElementEncryptedMedia::addKey(WebMediaPlayer* webMediaPlayer, cons
t String& keySystem, PassRefPtr<Uint8Array> key, PassRefPtr<Uint8Array> initData
, const String& sessionId, ExceptionState& exceptionState) | 358 void HTMLMediaElementEncryptedMedia::addKey(WebMediaPlayer* webMediaPlayer, cons
t String& keySystem, PassRefPtr<Uint8Array> key, PassRefPtr<Uint8Array> initData
, const String& sessionId, ExceptionState& exceptionState) |
177 { | 359 { |
178 WTF_LOG(Media, "HTMLMediaElementEncryptedMedia::webkitAddKey"); | 360 WTF_LOG(Media, "HTMLMediaElementEncryptedMedia::webkitAddKey"); |
179 | 361 |
180 if (!setEmeMode(EmeModePrefixed, exceptionState)) | 362 if (!setEmeMode(EmeModePrefixed)) { |
| 363 exceptionState.throwDOMException(InvalidStateError, "Mixed use of EME pr
efixed and unprefixed API not allowed."); |
181 return; | 364 return; |
| 365 } |
182 | 366 |
183 if (keySystem.isEmpty()) { | 367 if (keySystem.isEmpty()) { |
184 exceptionState.throwDOMException(SyntaxError, "The key system provided i
s empty."); | 368 exceptionState.throwDOMException(SyntaxError, "The key system provided i
s empty."); |
185 return; | 369 return; |
186 } | 370 } |
187 | 371 |
188 if (!key) { | 372 if (!key) { |
189 exceptionState.throwDOMException(SyntaxError, "The key provided is inval
id."); | 373 exceptionState.throwDOMException(SyntaxError, "The key provided is inval
id."); |
190 return; | 374 return; |
191 } | 375 } |
(...skipping 26 matching lines...) Expand all Loading... |
218 | 402 |
219 void HTMLMediaElementEncryptedMedia::webkitCancelKeyRequest(HTMLMediaElement& el
ement, const String& keySystem, const String& sessionId, ExceptionState& excepti
onState) | 403 void HTMLMediaElementEncryptedMedia::webkitCancelKeyRequest(HTMLMediaElement& el
ement, const String& keySystem, const String& sessionId, ExceptionState& excepti
onState) |
220 { | 404 { |
221 HTMLMediaElementEncryptedMedia::from(element).cancelKeyRequest(element.webMe
diaPlayer(), keySystem, sessionId, exceptionState); | 405 HTMLMediaElementEncryptedMedia::from(element).cancelKeyRequest(element.webMe
diaPlayer(), keySystem, sessionId, exceptionState); |
222 } | 406 } |
223 | 407 |
224 void HTMLMediaElementEncryptedMedia::cancelKeyRequest(WebMediaPlayer* webMediaPl
ayer, const String& keySystem, const String& sessionId, ExceptionState& exceptio
nState) | 408 void HTMLMediaElementEncryptedMedia::cancelKeyRequest(WebMediaPlayer* webMediaPl
ayer, const String& keySystem, const String& sessionId, ExceptionState& exceptio
nState) |
225 { | 409 { |
226 WTF_LOG(Media, "HTMLMediaElementEncryptedMedia::webkitCancelKeyRequest"); | 410 WTF_LOG(Media, "HTMLMediaElementEncryptedMedia::webkitCancelKeyRequest"); |
227 | 411 |
228 if (!setEmeMode(EmeModePrefixed, exceptionState)) | 412 if (!setEmeMode(EmeModePrefixed)) { |
| 413 exceptionState.throwDOMException(InvalidStateError, "Mixed use of EME pr
efixed and unprefixed API not allowed."); |
229 return; | 414 return; |
| 415 } |
230 | 416 |
231 if (keySystem.isEmpty()) { | 417 if (keySystem.isEmpty()) { |
232 exceptionState.throwDOMException(SyntaxError, "The key system provided i
s empty."); | 418 exceptionState.throwDOMException(SyntaxError, "The key system provided i
s empty."); |
233 return; | 419 return; |
234 } | 420 } |
235 | 421 |
236 if (!webMediaPlayer) { | 422 if (!webMediaPlayer) { |
237 exceptionState.throwDOMException(InvalidStateError, "No media has been l
oaded."); | 423 exceptionState.throwDOMException(InvalidStateError, "No media has been l
oaded."); |
238 return; | 424 return; |
239 } | 425 } |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
334 | 520 |
335 void HTMLMediaElementEncryptedMedia::playerDestroyed(HTMLMediaElement& element) | 521 void HTMLMediaElementEncryptedMedia::playerDestroyed(HTMLMediaElement& element) |
336 { | 522 { |
337 #if ENABLE(OILPAN) | 523 #if ENABLE(OILPAN) |
338 // FIXME: Oilpan: remove this once the media player is on the heap. crbug.co
m/378229 | 524 // FIXME: Oilpan: remove this once the media player is on the heap. crbug.co
m/378229 |
339 if (element.isFinalizing()) | 525 if (element.isFinalizing()) |
340 return; | 526 return; |
341 #endif | 527 #endif |
342 | 528 |
343 HTMLMediaElementEncryptedMedia& thisElement = HTMLMediaElementEncryptedMedia
::from(element); | 529 HTMLMediaElementEncryptedMedia& thisElement = HTMLMediaElementEncryptedMedia
::from(element); |
344 thisElement.setMediaKeysInternal(element, 0); | 530 if (!thisElement.m_mediaKeys) |
| 531 return; |
| 532 |
| 533 ASSERT(thisElement.m_emeMode == EmeModeUnprefixed); |
| 534 thisElement.m_mediaKeys.clear(); |
345 } | 535 } |
346 | 536 |
347 WebContentDecryptionModule* HTMLMediaElementEncryptedMedia::contentDecryptionMod
ule(HTMLMediaElement& element) | 537 WebContentDecryptionModule* HTMLMediaElementEncryptedMedia::contentDecryptionMod
ule(HTMLMediaElement& element) |
348 { | 538 { |
349 HTMLMediaElementEncryptedMedia& thisElement = HTMLMediaElementEncryptedMedia
::from(element); | 539 HTMLMediaElementEncryptedMedia& thisElement = HTMLMediaElementEncryptedMedia
::from(element); |
350 return thisElement.contentDecryptionModule(); | 540 return thisElement.contentDecryptionModule(); |
351 } | 541 } |
352 | 542 |
353 void HTMLMediaElementEncryptedMedia::trace(Visitor* visitor) | 543 void HTMLMediaElementEncryptedMedia::trace(Visitor* visitor) |
354 { | 544 { |
355 visitor->trace(m_mediaKeys); | 545 visitor->trace(m_mediaKeys); |
356 WillBeHeapSupplement<HTMLMediaElement>::trace(visitor); | 546 WillBeHeapSupplement<HTMLMediaElement>::trace(visitor); |
357 } | 547 } |
358 | 548 |
359 } // namespace blink | 549 } // namespace blink |
OLD | NEW |