OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2013 Apple Inc. All rights reserved. | 2 * Copyright (C) 2013 Apple Inc. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
6 * are met: | 6 * are met: |
7 * 1. Redistributions of source code must retain the above copyright | 7 * 1. Redistributions of source code must retain the above copyright |
8 * notice, this list of conditions and the following disclaimer. | 8 * notice, this list of conditions and the following disclaimer. |
9 * 2. Redistributions in binary form must reproduce the above copyright | 9 * 2. Redistributions in binary form must reproduce the above copyright |
10 * notice, this list of conditions and the following disclaimer in the | 10 * notice, this list of conditions and the following disclaimer in the |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
129 }; | 129 }; |
130 | 130 |
131 // This class allows a MediaKeySession object to be created asynchronously. | 131 // This class allows a MediaKeySession object to be created asynchronously. |
132 class MediaKeySessionInitializer : public ScriptPromiseResolver { | 132 class MediaKeySessionInitializer : public ScriptPromiseResolver { |
133 WTF_MAKE_NONCOPYABLE(MediaKeySessionInitializer); | 133 WTF_MAKE_NONCOPYABLE(MediaKeySessionInitializer); |
134 | 134 |
135 public: | 135 public: |
136 static ScriptPromise create(ScriptState*, MediaKeys*, const String& initData
Type, PassRefPtr<ArrayBuffer> initData, const String& sessionType); | 136 static ScriptPromise create(ScriptState*, MediaKeys*, const String& initData
Type, PassRefPtr<ArrayBuffer> initData, const String& sessionType); |
137 virtual ~MediaKeySessionInitializer(); | 137 virtual ~MediaKeySessionInitializer(); |
138 | 138 |
139 void completeWithSession(blink::WebContentDecryptionModuleResult::SessionSta
tus); | 139 void completeWithSession(WebContentDecryptionModuleResult::SessionStatus); |
140 void completeWithDOMException(ExceptionCode, const String& errorMessage); | 140 void completeWithDOMException(ExceptionCode, const String& errorMessage); |
141 | 141 |
142 private: | 142 private: |
143 MediaKeySessionInitializer(ScriptState*, MediaKeys*, const String& initDataT
ype, PassRefPtr<ArrayBuffer> initData, const String& sessionType); | 143 MediaKeySessionInitializer(ScriptState*, MediaKeys*, const String& initDataT
ype, PassRefPtr<ArrayBuffer> initData, const String& sessionType); |
144 void timerFired(Timer<MediaKeySessionInitializer>*); | 144 void timerFired(Timer<MediaKeySessionInitializer>*); |
145 | 145 |
146 Persistent<MediaKeys> m_mediaKeys; | 146 Persistent<MediaKeys> m_mediaKeys; |
147 OwnPtr<blink::WebContentDecryptionModuleSession> m_cdmSession; | 147 OwnPtr<WebContentDecryptionModuleSession> m_cdmSession; |
148 | 148 |
149 // The next 3 values are simply the initialization data saved so that the | 149 // The next 3 values are simply the initialization data saved so that the |
150 // asynchronous creation has the data needed. | 150 // asynchronous creation has the data needed. |
151 String m_initDataType; | 151 String m_initDataType; |
152 RefPtr<ArrayBuffer> m_initData; | 152 RefPtr<ArrayBuffer> m_initData; |
153 String m_sessionType; | 153 String m_sessionType; |
154 | 154 |
155 Timer<MediaKeySessionInitializer> m_timer; | 155 Timer<MediaKeySessionInitializer> m_timer; |
156 }; | 156 }; |
157 | 157 |
158 // Represents the result used when a new WebContentDecryptionModuleSession | 158 // Represents the result used when a new WebContentDecryptionModuleSession |
159 // object has been created. Needed as MediaKeySessionInitializer can't be both | 159 // object has been created. Needed as MediaKeySessionInitializer can't be both |
160 // a ScriptPromiseResolver and ContentDecryptionModuleResult at the same time. | 160 // a ScriptPromiseResolver and ContentDecryptionModuleResult at the same time. |
161 class NewMediaKeySessionResult FINAL : public ContentDecryptionModuleResult { | 161 class NewMediaKeySessionResult FINAL : public ContentDecryptionModuleResult { |
162 public: | 162 public: |
163 NewMediaKeySessionResult(MediaKeySessionInitializer* initializer) | 163 NewMediaKeySessionResult(MediaKeySessionInitializer* initializer) |
164 : m_initializer(initializer) | 164 : m_initializer(initializer) |
165 { | 165 { |
166 } | 166 } |
167 | 167 |
168 // ContentDecryptionModuleResult implementation. | 168 // ContentDecryptionModuleResult implementation. |
169 virtual void complete() OVERRIDE | 169 virtual void complete() OVERRIDE |
170 { | 170 { |
171 ASSERT_NOT_REACHED(); | 171 ASSERT_NOT_REACHED(); |
172 m_initializer->completeWithDOMException(InvalidStateError, "Unexpected c
ompletion."); | 172 m_initializer->completeWithDOMException(InvalidStateError, "Unexpected c
ompletion."); |
173 } | 173 } |
174 | 174 |
175 virtual void completeWithSession(blink::WebContentDecryptionModuleResult::Se
ssionStatus status) OVERRIDE | 175 virtual void completeWithSession(WebContentDecryptionModuleResult::SessionSt
atus status) OVERRIDE |
176 { | 176 { |
177 m_initializer->completeWithSession(status); | 177 m_initializer->completeWithSession(status); |
178 } | 178 } |
179 | 179 |
180 virtual void completeWithError(blink::WebContentDecryptionModuleException co
de, unsigned long systemCode, const blink::WebString& message) OVERRIDE | 180 virtual void completeWithError(WebContentDecryptionModuleException code, uns
igned long systemCode, const WebString& message) OVERRIDE |
181 { | 181 { |
182 m_initializer->completeWithDOMException(WebCdmExceptionToExceptionCode(c
ode), message); | 182 m_initializer->completeWithDOMException(WebCdmExceptionToExceptionCode(c
ode), message); |
183 } | 183 } |
184 | 184 |
185 private: | 185 private: |
186 MediaKeySessionInitializer* m_initializer; | 186 MediaKeySessionInitializer* m_initializer; |
187 }; | 187 }; |
188 | 188 |
189 ScriptPromise MediaKeySessionInitializer::create(ScriptState* scriptState, Media
Keys* mediaKeys, const String& initDataType, PassRefPtr<ArrayBuffer> initData, c
onst String& sessionType) | 189 ScriptPromise MediaKeySessionInitializer::create(ScriptState* scriptState, Media
Keys* mediaKeys, const String& initDataType, PassRefPtr<ArrayBuffer> initData, c
onst String& sessionType) |
190 { | 190 { |
(...skipping 24 matching lines...) Expand all Loading... |
215 | 215 |
216 void MediaKeySessionInitializer::timerFired(Timer<MediaKeySessionInitializer>*) | 216 void MediaKeySessionInitializer::timerFired(Timer<MediaKeySessionInitializer>*) |
217 { | 217 { |
218 WTF_LOG(Media, "MediaKeySessionInitializer::timerFired"); | 218 WTF_LOG(Media, "MediaKeySessionInitializer::timerFired"); |
219 | 219 |
220 // Continue MediaKeys::createSession() at step 7. | 220 // Continue MediaKeys::createSession() at step 7. |
221 // 7.1 Let request be null. (Request provided by cdm in message event). | 221 // 7.1 Let request be null. (Request provided by cdm in message event). |
222 // 7.2 Let default URL be null. (Also provided by cdm in message event). | 222 // 7.2 Let default URL be null. (Also provided by cdm in message event). |
223 | 223 |
224 // 7.3 Let cdm be the cdm loaded in create(). | 224 // 7.3 Let cdm be the cdm loaded in create(). |
225 blink::WebContentDecryptionModule* cdm = m_mediaKeys->contentDecryptionModul
e(); | 225 WebContentDecryptionModule* cdm = m_mediaKeys->contentDecryptionModule(); |
226 | 226 |
227 // 7.4 Use the cdm to execute the following steps: | 227 // 7.4 Use the cdm to execute the following steps: |
228 // 7.4.1 If the init data is not valid for initDataType, reject promise | 228 // 7.4.1 If the init data is not valid for initDataType, reject promise |
229 // with a new DOMException whose name is "InvalidAccessError". | 229 // with a new DOMException whose name is "InvalidAccessError". |
230 // 7.4.2 If the init data is not supported by the cdm, reject promise with | 230 // 7.4.2 If the init data is not supported by the cdm, reject promise with |
231 // a new DOMException whose name is "NotSupportedError". | 231 // a new DOMException whose name is "NotSupportedError". |
232 // 7.4.3 Let request be a request (e.g. a license request) generated based | 232 // 7.4.3 Let request be a request (e.g. a license request) generated based |
233 // on the init data, which is interpreteted per initDataType, and | 233 // on the init data, which is interpreteted per initDataType, and |
234 // sessionType. If sessionType is "temporary", the request is for a | 234 // sessionType. If sessionType is "temporary", the request is for a |
235 // temporary non-persisted license. If sessionType is "persistent", | 235 // temporary non-persisted license. If sessionType is "persistent", |
236 // the request is for a persistable license. | 236 // the request is for a persistable license. |
237 // 7.4.4 If the init data indicates a default URL, let default URL be | 237 // 7.4.4 If the init data indicates a default URL, let default URL be |
238 // that URL. The URL may be validated and/or normalized. | 238 // that URL. The URL may be validated and/or normalized. |
239 m_cdmSession = adoptPtr(cdm->createSession()); | 239 m_cdmSession = adoptPtr(cdm->createSession()); |
240 NewMediaKeySessionResult* result = new NewMediaKeySessionResult(this); | 240 NewMediaKeySessionResult* result = new NewMediaKeySessionResult(this); |
241 m_cdmSession->initializeNewSession(m_initDataType, static_cast<unsigned char
*>(m_initData->data()), m_initData->byteLength(), m_sessionType, result->result(
)); | 241 m_cdmSession->initializeNewSession(m_initDataType, static_cast<unsigned char
*>(m_initData->data()), m_initData->byteLength(), m_sessionType, result->result(
)); |
242 | 242 |
243 WTF_LOG(Media, "MediaKeySessionInitializer::timerFired done"); | 243 WTF_LOG(Media, "MediaKeySessionInitializer::timerFired done"); |
244 // Note: As soon as the promise is resolved (or rejected), the | 244 // Note: As soon as the promise is resolved (or rejected), the |
245 // ScriptPromiseResolver object (|this|) is freed. So if | 245 // ScriptPromiseResolver object (|this|) is freed. So if |
246 // initializeNewSession() is synchronous, access to any members will crash. | 246 // initializeNewSession() is synchronous, access to any members will crash. |
247 } | 247 } |
248 | 248 |
249 void MediaKeySessionInitializer::completeWithSession(blink::WebContentDecryption
ModuleResult::SessionStatus status) | 249 void MediaKeySessionInitializer::completeWithSession(WebContentDecryptionModuleR
esult::SessionStatus status) |
250 { | 250 { |
251 WTF_LOG(Media, "MediaKeySessionInitializer::completeWithSession"); | 251 WTF_LOG(Media, "MediaKeySessionInitializer::completeWithSession"); |
252 | 252 |
253 switch (status) { | 253 switch (status) { |
254 case blink::WebContentDecryptionModuleResult::NewSession: { | 254 case WebContentDecryptionModuleResult::NewSession: { |
255 // Resume MediaKeys::createSession(). | 255 // Resume MediaKeys::createSession(). |
256 // 7.5 Let the session ID be a unique Session ID string. It may be | 256 // 7.5 Let the session ID be a unique Session ID string. It may be |
257 // obtained from cdm (it is). | 257 // obtained from cdm (it is). |
258 // 7.6 Let session be a new MediaKeySession object, and initialize it. | 258 // 7.6 Let session be a new MediaKeySession object, and initialize it. |
259 // (Object was created previously, complete the steps for 7.6). | 259 // (Object was created previously, complete the steps for 7.6). |
260 RefPtrWillBeRawPtr<MediaKeySession> session = adoptRefCountedGarbageColl
ectedWillBeNoop(new MediaKeySession(executionContext(), m_mediaKeys, m_cdmSessio
n.release())); | 260 RefPtrWillBeRawPtr<MediaKeySession> session = adoptRefCountedGarbageColl
ectedWillBeNoop(new MediaKeySession(executionContext(), m_mediaKeys, m_cdmSessio
n.release())); |
261 session->suspendIfNeeded(); | 261 session->suspendIfNeeded(); |
262 | 262 |
263 // 7.7 If any of the preceding steps failed, reject promise with a | 263 // 7.7 If any of the preceding steps failed, reject promise with a |
264 // new DOMException whose name is the appropriate error name | 264 // new DOMException whose name is the appropriate error name |
265 // and that has an appropriate message. | 265 // and that has an appropriate message. |
266 // (Implemented by CDM/Chromium calling completeWithError()). | 266 // (Implemented by CDM/Chromium calling completeWithError()). |
267 | 267 |
268 // 7.8 Add an entry for the value of the sessionId attribute to the | 268 // 7.8 Add an entry for the value of the sessionId attribute to the |
269 // list of active session IDs for this object. | 269 // list of active session IDs for this object. |
270 // (Implemented in SessionIdAdapter). | 270 // (Implemented in SessionIdAdapter). |
271 | 271 |
272 // 7.9 Run the Queue a "message" Event algorithm on the session, | 272 // 7.9 Run the Queue a "message" Event algorithm on the session, |
273 // providing request and default URL. | 273 // providing request and default URL. |
274 // (Done by the CDM). | 274 // (Done by the CDM). |
275 | 275 |
276 // 7.10 Resolve promise with session. | 276 // 7.10 Resolve promise with session. |
277 resolve(session.release()); | 277 resolve(session.release()); |
278 WTF_LOG(Media, "MediaKeySessionInitializer::completeWithSession done w/s
ession"); | 278 WTF_LOG(Media, "MediaKeySessionInitializer::completeWithSession done w/s
ession"); |
279 return; | 279 return; |
280 } | 280 } |
281 | 281 |
282 case blink::WebContentDecryptionModuleResult::SessionNotFound: | 282 case WebContentDecryptionModuleResult::SessionNotFound: |
283 // Step 4.7.1 of MediaKeys::loadSession(): If there is no data | 283 // Step 4.7.1 of MediaKeys::loadSession(): If there is no data |
284 // stored for the sessionId in the origin, resolve promise with | 284 // stored for the sessionId in the origin, resolve promise with |
285 // undefined. | 285 // undefined. |
286 resolve(V8UndefinedType()); | 286 resolve(V8UndefinedType()); |
287 WTF_LOG(Media, "MediaKeySessionInitializer::completeWithSession done w/u
ndefined"); | 287 WTF_LOG(Media, "MediaKeySessionInitializer::completeWithSession done w/u
ndefined"); |
288 return; | 288 return; |
289 | 289 |
290 case blink::WebContentDecryptionModuleResult::SessionAlreadyExists: | 290 case WebContentDecryptionModuleResult::SessionAlreadyExists: |
291 // If a session already exists, resolve the promise with null. | 291 // If a session already exists, resolve the promise with null. |
292 resolve(V8NullType()); | 292 resolve(V8NullType()); |
293 WTF_LOG(Media, "MediaKeySessionInitializer::completeWithSession done w/n
ull"); | 293 WTF_LOG(Media, "MediaKeySessionInitializer::completeWithSession done w/n
ull"); |
294 return; | 294 return; |
295 } | 295 } |
296 ASSERT_NOT_REACHED(); | 296 ASSERT_NOT_REACHED(); |
297 } | 297 } |
298 | 298 |
299 void MediaKeySessionInitializer::completeWithDOMException(ExceptionCode code, co
nst String& errorMessage) | 299 void MediaKeySessionInitializer::completeWithDOMException(ExceptionCode code, co
nst String& errorMessage) |
300 { | 300 { |
301 WTF_LOG(Media, "MediaKeySessionInitializer::completeWithDOMException"); | 301 WTF_LOG(Media, "MediaKeySessionInitializer::completeWithDOMException"); |
302 reject(DOMException::create(code, errorMessage)); | 302 reject(DOMException::create(code, errorMessage)); |
303 } | 303 } |
304 | 304 |
305 ScriptPromise MediaKeySession::create(ScriptState* scriptState, MediaKeys* media
Keys, const String& initDataType, PassRefPtr<ArrayBuffer> initData, const String
& sessionType) | 305 ScriptPromise MediaKeySession::create(ScriptState* scriptState, MediaKeys* media
Keys, const String& initDataType, PassRefPtr<ArrayBuffer> initData, const String
& sessionType) |
306 { | 306 { |
307 // Since creation is done asynchronously, use MediaKeySessionInitializer | 307 // Since creation is done asynchronously, use MediaKeySessionInitializer |
308 // to do it. | 308 // to do it. |
309 return MediaKeySessionInitializer::create(scriptState, mediaKeys, initDataTy
pe, initData, sessionType); | 309 return MediaKeySessionInitializer::create(scriptState, mediaKeys, initDataTy
pe, initData, sessionType); |
310 } | 310 } |
311 | 311 |
312 MediaKeySession::MediaKeySession(ExecutionContext* context, MediaKeys* keys, Pas
sOwnPtr<blink::WebContentDecryptionModuleSession> cdmSession) | 312 MediaKeySession::MediaKeySession(ExecutionContext* context, MediaKeys* keys, Pas
sOwnPtr<WebContentDecryptionModuleSession> cdmSession) |
313 : ActiveDOMObject(context) | 313 : ActiveDOMObject(context) |
314 , m_keySystem(keys->keySystem()) | 314 , m_keySystem(keys->keySystem()) |
315 , m_asyncEventQueue(GenericEventQueue::create(this)) | 315 , m_asyncEventQueue(GenericEventQueue::create(this)) |
316 , m_session(cdmSession) | 316 , m_session(cdmSession) |
317 , m_keys(keys) | 317 , m_keys(keys) |
318 , m_isClosed(false) | 318 , m_isClosed(false) |
319 , m_closedPromise(new ClosedPromise(context, this, ClosedPromise::Closed)) | 319 , m_closedPromise(new ClosedPromise(context, this, ClosedPromise::Closed)) |
320 , m_actionTimer(this, &MediaKeySession::actionTimerFired) | 320 , m_actionTimer(this, &MediaKeySession::actionTimerFired) |
321 { | 321 { |
322 WTF_LOG(Media, "MediaKeySession(%p)::MediaKeySession", this); | 322 WTF_LOG(Media, "MediaKeySession(%p)::MediaKeySession", this); |
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
476 break; | 476 break; |
477 case PendingAction::Message: | 477 case PendingAction::Message: |
478 WTF_LOG(Media, "MediaKeySession(%p)::actionTimerFired: Message", thi
s); | 478 WTF_LOG(Media, "MediaKeySession(%p)::actionTimerFired: Message", thi
s); |
479 m_asyncEventQueue->enqueueEvent(action->event().release()); | 479 m_asyncEventQueue->enqueueEvent(action->event().release()); |
480 break; | 480 break; |
481 } | 481 } |
482 } | 482 } |
483 } | 483 } |
484 | 484 |
485 // Queue a task to fire a simple event named keymessage at the new object | 485 // Queue a task to fire a simple event named keymessage at the new object |
486 void MediaKeySession::message(const unsigned char* message, size_t messageLength
, const blink::WebURL& destinationURL) | 486 void MediaKeySession::message(const unsigned char* message, size_t messageLength
, const WebURL& destinationURL) |
487 { | 487 { |
488 WTF_LOG(Media, "MediaKeySession(%p)::message", this); | 488 WTF_LOG(Media, "MediaKeySession(%p)::message", this); |
489 | 489 |
490 MediaKeyMessageEventInit init; | 490 MediaKeyMessageEventInit init; |
491 init.bubbles = false; | 491 init.bubbles = false; |
492 init.cancelable = false; | 492 init.cancelable = false; |
493 init.message = ArrayBuffer::create(static_cast<const void*>(message), messag
eLength); | 493 init.message = ArrayBuffer::create(static_cast<const void*>(message), messag
eLength); |
494 init.destinationURL = destinationURL.string(); | 494 init.destinationURL = destinationURL.string(); |
495 | 495 |
496 RefPtrWillBeRawPtr<MediaKeyMessageEvent> event = MediaKeyMessageEvent::creat
e(EventTypeNames::message, init); | 496 RefPtrWillBeRawPtr<MediaKeyMessageEvent> event = MediaKeyMessageEvent::creat
e(EventTypeNames::message, init); |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
554 // systemCode = a Key System-specific value, if provided, and 0 otherwise | 554 // systemCode = a Key System-specific value, if provided, and 0 otherwise |
555 // 2. Set the MediaKeySession object's error attribute to the error object c
reated in the previous step. | 555 // 2. Set the MediaKeySession object's error attribute to the error object c
reated in the previous step. |
556 m_error = MediaKeyError::create(mediaKeyErrorCode, systemCode); | 556 m_error = MediaKeyError::create(mediaKeyErrorCode, systemCode); |
557 | 557 |
558 // 3. queue a task to fire a simple event named keyerror at the MediaKeySess
ion object. | 558 // 3. queue a task to fire a simple event named keyerror at the MediaKeySess
ion object. |
559 RefPtrWillBeRawPtr<Event> event = Event::create(EventTypeNames::error); | 559 RefPtrWillBeRawPtr<Event> event = Event::create(EventTypeNames::error); |
560 event->setTarget(this); | 560 event->setTarget(this); |
561 m_asyncEventQueue->enqueueEvent(event.release()); | 561 m_asyncEventQueue->enqueueEvent(event.release()); |
562 } | 562 } |
563 | 563 |
564 void MediaKeySession::error(blink::WebContentDecryptionModuleException exception
, unsigned long systemCode, const blink::WebString& errorMessage) | 564 void MediaKeySession::error(WebContentDecryptionModuleException exception, unsig
ned long systemCode, const WebString& errorMessage) |
565 { | 565 { |
566 WTF_LOG(Media, "MediaKeySession::error: exception=%d, systemCode=%lu", excep
tion, systemCode); | 566 WTF_LOG(Media, "MediaKeySession::error: exception=%d, systemCode=%lu", excep
tion, systemCode); |
567 | 567 |
568 // FIXME: EME-WD MediaKeyError now derives from DOMException. Figure out how | 568 // FIXME: EME-WD MediaKeyError now derives from DOMException. Figure out how |
569 // to implement this without breaking prefixed EME, which has a totally | 569 // to implement this without breaking prefixed EME, which has a totally |
570 // different definition. The spec may also change to be just a DOMException. | 570 // different definition. The spec may also change to be just a DOMException. |
571 // For now, simply generate an existing MediaKeyError. | 571 // For now, simply generate an existing MediaKeyError. |
572 MediaKeyErrorCode errorCode; | 572 MediaKeyErrorCode errorCode; |
573 switch (exception) { | 573 switch (exception) { |
574 case blink::WebContentDecryptionModuleExceptionClientError: | 574 case WebContentDecryptionModuleExceptionClientError: |
575 errorCode = MediaKeyErrorCodeClient; | 575 errorCode = MediaKeyErrorCodeClient; |
576 break; | 576 break; |
577 default: | 577 default: |
578 // All other exceptions get converted into Unknown. | 578 // All other exceptions get converted into Unknown. |
579 errorCode = MediaKeyErrorCodeUnknown; | 579 errorCode = MediaKeyErrorCodeUnknown; |
580 break; | 580 break; |
581 } | 581 } |
582 error(errorCode, systemCode); | 582 error(errorCode, systemCode); |
583 } | 583 } |
584 | 584 |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
623 void MediaKeySession::trace(Visitor* visitor) | 623 void MediaKeySession::trace(Visitor* visitor) |
624 { | 624 { |
625 visitor->trace(m_error); | 625 visitor->trace(m_error); |
626 visitor->trace(m_asyncEventQueue); | 626 visitor->trace(m_asyncEventQueue); |
627 visitor->trace(m_pendingActions); | 627 visitor->trace(m_pendingActions); |
628 visitor->trace(m_keys); | 628 visitor->trace(m_keys); |
629 visitor->trace(m_closedPromise); | 629 visitor->trace(m_closedPromise); |
630 EventTargetWithInlineData::trace(visitor); | 630 EventTargetWithInlineData::trace(visitor); |
631 } | 631 } |
632 | 632 |
633 } | 633 } // namespace blink |
OLD | NEW |