OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012, 2013 Apple Inc. All rights
reserved. | 2 * Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012, 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 19 matching lines...) Expand all Loading... |
30 #include "bindings/core/v8/ScriptController.h" | 30 #include "bindings/core/v8/ScriptController.h" |
31 #include "bindings/core/v8/ScriptEventListener.h" | 31 #include "bindings/core/v8/ScriptEventListener.h" |
32 #include "bindings/core/v8/ScriptPromiseResolver.h" | 32 #include "bindings/core/v8/ScriptPromiseResolver.h" |
33 #include "core/HTMLNames.h" | 33 #include "core/HTMLNames.h" |
34 #include "core/css/MediaList.h" | 34 #include "core/css/MediaList.h" |
35 #include "core/dom/Attribute.h" | 35 #include "core/dom/Attribute.h" |
36 #include "core/dom/ElementTraversal.h" | 36 #include "core/dom/ElementTraversal.h" |
37 #include "core/dom/Fullscreen.h" | 37 #include "core/dom/Fullscreen.h" |
38 #include "core/dom/shadow/ShadowRoot.h" | 38 #include "core/dom/shadow/ShadowRoot.h" |
39 #include "core/events/Event.h" | 39 #include "core/events/Event.h" |
| 40 #include "core/frame/FrameView.h" |
40 #include "core/frame/LocalFrame.h" | 41 #include "core/frame/LocalFrame.h" |
41 #include "core/frame/Settings.h" | 42 #include "core/frame/Settings.h" |
42 #include "core/frame/UseCounter.h" | 43 #include "core/frame/UseCounter.h" |
43 #include "core/frame/csp/ContentSecurityPolicy.h" | 44 #include "core/frame/csp/ContentSecurityPolicy.h" |
44 #include "core/html/HTMLMediaSource.h" | 45 #include "core/html/HTMLMediaSource.h" |
45 #include "core/html/HTMLSourceElement.h" | 46 #include "core/html/HTMLSourceElement.h" |
46 #include "core/html/HTMLTrackElement.h" | 47 #include "core/html/HTMLTrackElement.h" |
47 #include "core/html/MediaError.h" | 48 #include "core/html/MediaError.h" |
48 #include "core/html/MediaFragmentURIParser.h" | 49 #include "core/html/MediaFragmentURIParser.h" |
49 #include "core/html/TimeRanges.h" | 50 #include "core/html/TimeRanges.h" |
50 #include "core/html/shadow/MediaControls.h" | 51 #include "core/html/shadow/MediaControls.h" |
51 #include "core/html/track/AudioTrack.h" | 52 #include "core/html/track/AudioTrack.h" |
52 #include "core/html/track/AudioTrackList.h" | 53 #include "core/html/track/AudioTrackList.h" |
53 #include "core/html/track/AutomaticTrackSelection.h" | 54 #include "core/html/track/AutomaticTrackSelection.h" |
54 #include "core/html/track/CueTimeline.h" | 55 #include "core/html/track/CueTimeline.h" |
55 #include "core/html/track/InbandTextTrack.h" | 56 #include "core/html/track/InbandTextTrack.h" |
56 #include "core/html/track/TextTrackContainer.h" | 57 #include "core/html/track/TextTrackContainer.h" |
57 #include "core/html/track/TextTrackList.h" | 58 #include "core/html/track/TextTrackList.h" |
58 #include "core/html/track/VideoTrack.h" | 59 #include "core/html/track/VideoTrack.h" |
59 #include "core/html/track/VideoTrackList.h" | 60 #include "core/html/track/VideoTrackList.h" |
60 #include "core/inspector/ConsoleMessage.h" | 61 #include "core/inspector/ConsoleMessage.h" |
61 #include "core/layout/LayoutVideo.h" | 62 #include "core/layout/LayoutVideo.h" |
62 #include "core/layout/LayoutView.h" | 63 #include "core/layout/LayoutView.h" |
| 64 #include "core/layout/api/LayoutMediaItem.h" |
63 #include "core/layout/compositing/PaintLayerCompositor.h" | 65 #include "core/layout/compositing/PaintLayerCompositor.h" |
64 #include "core/loader/FrameLoader.h" | 66 #include "core/loader/FrameLoader.h" |
65 #include "core/loader/FrameLoaderClient.h" | 67 #include "core/loader/FrameLoaderClient.h" |
66 #include "core/page/ChromeClient.h" | 68 #include "core/page/ChromeClient.h" |
67 #include "core/page/NetworkStateNotifier.h" | 69 #include "core/page/NetworkStateNotifier.h" |
68 #include "platform/ContentType.h" | 70 #include "platform/ContentType.h" |
69 #include "platform/Histogram.h" | 71 #include "platform/Histogram.h" |
70 #include "platform/LayoutTestSupport.h" | 72 #include "platform/LayoutTestSupport.h" |
71 #include "platform/Logging.h" | 73 #include "platform/Logging.h" |
72 #include "platform/MIMETypeFromURL.h" | 74 #include "platform/MIMETypeFromURL.h" |
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
262 case WebMediaPlayer::PreloadAuto: | 264 case WebMediaPlayer::PreloadAuto: |
263 return "auto"; | 265 return "auto"; |
264 } | 266 } |
265 | 267 |
266 ASSERT_NOT_REACHED(); | 268 ASSERT_NOT_REACHED(); |
267 return String(); | 269 return String(); |
268 } | 270 } |
269 | 271 |
270 } // anonymous namespace | 272 } // anonymous namespace |
271 | 273 |
| 274 class HTMLMediaElement::AutoplayHelperClientImpl : |
| 275 public AutoplayExperimentHelper::Client { |
| 276 |
| 277 public: |
| 278 static PassOwnPtrWillBeRawPtr<AutoplayHelperClientImpl> create(HTMLMediaElem
ent* element) |
| 279 { |
| 280 return adoptPtrWillBeNoop(new AutoplayHelperClientImpl(element)); |
| 281 } |
| 282 |
| 283 virtual ~AutoplayHelperClientImpl(); |
| 284 |
| 285 using RecordMetricsBehavior = HTMLMediaElement::RecordMetricsBehavior; |
| 286 |
| 287 double currentTime() const override { return m_element->currentTime(); } |
| 288 double duration() const override { return m_element->duration(); } |
| 289 bool ended() const override { return m_element->ended(); } |
| 290 bool muted() const override { return m_element->muted(); } |
| 291 void setMuted(bool muted) override { m_element->setMuted(muted); } |
| 292 void playInternal() override { m_element->playInternal(); } |
| 293 bool isUserGestureRequiredForPlay() const override { return m_element->isUse
rGestureRequiredForPlay(); } |
| 294 void removeUserGestureRequirement() override { m_element->removeUserGestureR
equirement(); } |
| 295 void recordAutoplayMetric(AutoplayMetrics metric) override { m_element->reco
rdAutoplayMetric(metric); } |
| 296 bool shouldAutoplay() override |
| 297 { |
| 298 return m_element->shouldAutoplay(RecordMetricsBehavior::DoNotRecord); |
| 299 } |
| 300 bool isHTMLVideoElement() const override { return m_element->isHTMLVideoElem
ent(); } |
| 301 bool isHTMLAudioElement() const override { return m_element->isHTMLAudioElem
ent(); } |
| 302 |
| 303 // Document |
| 304 bool isLegacyViewportType() override; |
| 305 PageVisibilityState pageVisibilityState() const override; |
| 306 String autoplayExperimentMode() const override; |
| 307 |
| 308 // LayoutObject |
| 309 void setRequestPositionUpdates(bool) override; |
| 310 IntRect absoluteBoundingBoxRect() const override; |
| 311 |
| 312 DEFINE_INLINE_VIRTUAL_TRACE() |
| 313 { |
| 314 visitor->trace(m_element); |
| 315 Client::trace(visitor); |
| 316 } |
| 317 |
| 318 private: |
| 319 AutoplayHelperClientImpl(HTMLMediaElement* element) : m_element(element) {} |
| 320 |
| 321 RawPtrWillBeMember<HTMLMediaElement> m_element; |
| 322 }; |
| 323 |
| 324 |
272 void HTMLMediaElement::recordAutoplayMetric(AutoplayMetrics metric) | 325 void HTMLMediaElement::recordAutoplayMetric(AutoplayMetrics metric) |
273 { | 326 { |
274 DEFINE_STATIC_LOCAL(EnumerationHistogram, autoplayHistogram, ("Blink.MediaEl
ement.Autoplay", NumberOfAutoplayMetrics)); | 327 DEFINE_STATIC_LOCAL(EnumerationHistogram, autoplayHistogram, ("Blink.MediaEl
ement.Autoplay", NumberOfAutoplayMetrics)); |
275 autoplayHistogram.count(metric); | 328 autoplayHistogram.count(metric); |
276 } | 329 } |
277 | 330 |
278 WebMimeRegistry::SupportsType HTMLMediaElement::supportsType(const ContentType&
contentType) | 331 WebMimeRegistry::SupportsType HTMLMediaElement::supportsType(const ContentType&
contentType) |
279 { | 332 { |
280 DEFINE_STATIC_LOCAL(const String, codecs, ("codecs")); | 333 DEFINE_STATIC_LOCAL(const String, codecs, ("codecs")); |
281 | 334 |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
348 , m_seeking(false) | 401 , m_seeking(false) |
349 , m_sentStalledEvent(false) | 402 , m_sentStalledEvent(false) |
350 , m_sentEndEvent(false) | 403 , m_sentEndEvent(false) |
351 , m_closedCaptionsVisible(false) | 404 , m_closedCaptionsVisible(false) |
352 , m_ignorePreloadNone(false) | 405 , m_ignorePreloadNone(false) |
353 , m_tracksAreReady(true) | 406 , m_tracksAreReady(true) |
354 , m_processingPreferenceChange(false) | 407 , m_processingPreferenceChange(false) |
355 , m_remoteRoutesAvailable(false) | 408 , m_remoteRoutesAvailable(false) |
356 , m_playingRemotely(false) | 409 , m_playingRemotely(false) |
357 , m_isFinalizing(false) | 410 , m_isFinalizing(false) |
358 , m_initialPlayWithoutUserGesture(false) | |
359 , m_autoplayMediaCounted(false) | |
360 , m_inOverlayFullscreenVideo(false) | 411 , m_inOverlayFullscreenVideo(false) |
361 , m_audioTracks(AudioTrackList::create(*this)) | 412 , m_audioTracks(AudioTrackList::create(*this)) |
362 , m_videoTracks(VideoTrackList::create(*this)) | 413 , m_videoTracks(VideoTrackList::create(*this)) |
363 , m_textTracks(nullptr) | 414 , m_textTracks(nullptr) |
364 , m_playPromiseResolveTask(CancellableTaskFactory::create(this, &HTMLMediaEl
ement::resolvePlayPromises)) | 415 , m_playPromiseResolveTask(CancellableTaskFactory::create(this, &HTMLMediaEl
ement::resolvePlayPromises)) |
365 , m_playPromiseRejectTask(CancellableTaskFactory::create(this, &HTMLMediaEle
ment::rejectPlayPromises)) | 416 , m_playPromiseRejectTask(CancellableTaskFactory::create(this, &HTMLMediaEle
ment::rejectPlayPromises)) |
366 , m_audioSourceNode(nullptr) | 417 , m_audioSourceNode(nullptr) |
367 , m_autoplayHelper(*this) | 418 , m_autoplayHelperClient(AutoplayHelperClientImpl::create(this)) |
| 419 , m_autoplayHelper(AutoplayExperimentHelper::create(m_autoplayHelperClient.g
et())) |
368 , m_remotePlaybackClient(nullptr) | 420 , m_remotePlaybackClient(nullptr) |
369 { | 421 { |
370 #if ENABLE(OILPAN) | 422 #if ENABLE(OILPAN) |
371 ThreadState::current()->registerPreFinalizer(this); | 423 ThreadState::current()->registerPreFinalizer(this); |
372 #endif | 424 #endif |
373 | 425 |
374 WTF_LOG(Media, "HTMLMediaElement::HTMLMediaElement(%p)", this); | 426 WTF_LOG(Media, "HTMLMediaElement::HTMLMediaElement(%p)", this); |
375 | 427 |
376 if (document.settings() && document.settings()->mediaPlaybackRequiresUserGes
ture()) | 428 if (document.settings() && document.settings()->mediaPlaybackRequiresUserGes
ture()) |
377 m_userGestureRequiredForPlay = true; | 429 m_userGestureRequiredForPlay = true; |
378 | 430 |
379 setHasCustomStyleCallbacks(); | 431 setHasCustomStyleCallbacks(); |
380 addElementToDocumentMap(this, &document); | 432 addElementToDocumentMap(this, &document); |
381 | 433 |
382 UseCounter::count(document, UseCounter::HTMLMediaElement); | 434 UseCounter::count(document, UseCounter::HTMLMediaElement); |
383 } | 435 } |
384 | 436 |
385 HTMLMediaElement::~HTMLMediaElement() | 437 HTMLMediaElement::~HTMLMediaElement() |
386 { | 438 { |
387 WTF_LOG(Media, "HTMLMediaElement::~HTMLMediaElement(%p)", this); | 439 WTF_LOG(Media, "HTMLMediaElement::~HTMLMediaElement(%p)", this); |
388 | 440 |
389 #if !ENABLE(OILPAN) | 441 #if !ENABLE(OILPAN) |
| 442 // Destruction of the autoplay helper requires the client, so be sure that |
| 443 // this happens before the client is destructed. |
| 444 if (m_autoplayHelper) |
| 445 m_autoplayHelper.clear(); |
| 446 |
390 // HTMLMediaElement and m_asyncEventQueue always become unreachable | 447 // HTMLMediaElement and m_asyncEventQueue always become unreachable |
391 // together. So HTMLMediaElement and m_asyncEventQueue are destructed in | 448 // together. So HTMLMediaElement and m_asyncEventQueue are destructed in |
392 // the same GC. We don't need to close it explicitly in Oilpan. | 449 // the same GC. We don't need to close it explicitly in Oilpan. |
393 m_asyncEventQueue->close(); | 450 m_asyncEventQueue->close(); |
394 | 451 |
395 setShouldDelayLoadEvent(false); | 452 setShouldDelayLoadEvent(false); |
396 | 453 |
397 if (m_textTracks) | 454 if (m_textTracks) |
398 m_textTracks->clearOwner(); | 455 m_textTracks->clearOwner(); |
399 m_audioTracks->shutdown(); | 456 m_audioTracks->shutdown(); |
(...skipping 19 matching lines...) Expand all Loading... |
419 // m_audioSourceNode is explicitly cleared by AudioNode::dispose(). | 476 // m_audioSourceNode is explicitly cleared by AudioNode::dispose(). |
420 // Since AudioNode::dispose() is guaranteed to be always called before | 477 // Since AudioNode::dispose() is guaranteed to be always called before |
421 // the AudioNode is destructed, m_audioSourceNode is explicitly cleared | 478 // the AudioNode is destructed, m_audioSourceNode is explicitly cleared |
422 // even if the AudioNode and the HTMLMediaElement die together. | 479 // even if the AudioNode and the HTMLMediaElement die together. |
423 ASSERT(!m_audioSourceNode); | 480 ASSERT(!m_audioSourceNode); |
424 } | 481 } |
425 | 482 |
426 #if ENABLE(OILPAN) | 483 #if ENABLE(OILPAN) |
427 void HTMLMediaElement::dispose() | 484 void HTMLMediaElement::dispose() |
428 { | 485 { |
| 486 // This must happen before we're destructed. |
| 487 if (m_autoplayHelper) |
| 488 m_autoplayHelper->dispose(); |
| 489 |
429 // If the HTMLMediaElement dies with the Document we are not | 490 // If the HTMLMediaElement dies with the Document we are not |
430 // allowed to touch the Document to adjust delay load event counts | 491 // allowed to touch the Document to adjust delay load event counts |
431 // from the destructor, as the Document could have been already | 492 // from the destructor, as the Document could have been already |
432 // destructed. | 493 // destructed. |
433 // | 494 // |
434 // Work around that restriction by accessing the Document from | 495 // Work around that restriction by accessing the Document from |
435 // a prefinalizer action instead, updating its delayed load count. | 496 // a prefinalizer action instead, updating its delayed load count. |
436 // If needed - if the Document has been detached and informed its | 497 // If needed - if the Document has been detached and informed its |
437 // ContextLifecycleObservers (which HTMLMediaElement is) that | 498 // ContextLifecycleObservers (which HTMLMediaElement is) that |
438 // it is being destroyed, the connection to the Document will | 499 // it is being destroyed, the connection to the Document will |
(...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
675 case WebMimeRegistry::IsSupported: | 736 case WebMimeRegistry::IsSupported: |
676 canPlay = "probably"; | 737 canPlay = "probably"; |
677 break; | 738 break; |
678 } | 739 } |
679 | 740 |
680 WTF_LOG(Media, "HTMLMediaElement::canPlayType(%p, %s) -> %s", this, mimeType
.utf8().data(), canPlay.utf8().data()); | 741 WTF_LOG(Media, "HTMLMediaElement::canPlayType(%p, %s) -> %s", this, mimeType
.utf8().data(), canPlay.utf8().data()); |
681 | 742 |
682 return canPlay; | 743 return canPlay; |
683 } | 744 } |
684 | 745 |
685 void HTMLMediaElement::recordMetricsIfPausing() | |
686 { | |
687 // If not playing, then nothing to record. | |
688 // TODO(liberato): test metrics. this was m_paused. | |
689 if (m_paused) | |
690 return; | |
691 | |
692 const bool bailout = isBailout(); | |
693 | |
694 // Record that play was paused. We don't care if it was autoplay, | |
695 // play(), or the user manually started it. | |
696 recordAutoplayMetric(AnyPlaybackPaused); | |
697 if (bailout) | |
698 recordAutoplayMetric(AnyPlaybackBailout); | |
699 | |
700 // If this was a gestureless play, then record that separately. | |
701 // These cover attr and play() gestureless starts. | |
702 if (m_initialPlayWithoutUserGesture) { | |
703 m_initialPlayWithoutUserGesture = false; | |
704 | |
705 recordAutoplayMetric(AutoplayPaused); | |
706 | |
707 if (bailout) | |
708 recordAutoplayMetric(AutoplayBailout); | |
709 } | |
710 } | |
711 | |
712 void HTMLMediaElement::load() | 746 void HTMLMediaElement::load() |
713 { | 747 { |
714 WTF_LOG(Media, "HTMLMediaElement::load(%p)", this); | 748 WTF_LOG(Media, "HTMLMediaElement::load(%p)", this); |
715 | 749 |
716 recordMetricsIfPausing(); | 750 m_autoplayHelper->loadMethodCalled(); |
717 | |
718 if (UserGestureIndicator::processingUserGesture() && m_userGestureRequiredFo
rPlay) { | |
719 recordAutoplayMetric(AutoplayEnabledThroughLoad); | |
720 m_userGestureRequiredForPlay = false; | |
721 // While usergesture-initiated load()s technically count as autoplayed, | |
722 // they don't feel like such to the users and hence we don't want to | |
723 // count them for the purposes of metrics. | |
724 m_autoplayMediaCounted = true; | |
725 } | |
726 | 751 |
727 m_ignorePreloadNone = true; | 752 m_ignorePreloadNone = true; |
728 invokeLoadAlgorithm(); | 753 invokeLoadAlgorithm(); |
729 } | 754 } |
730 | 755 |
731 // TODO(srirama.m): Currently m_ignorePreloadNone is reset before calling | 756 // TODO(srirama.m): Currently m_ignorePreloadNone is reset before calling |
732 // invokeLoadAlgorithm() in all places except load(). Move it inside here | 757 // invokeLoadAlgorithm() in all places except load(). Move it inside here |
733 // once microtask is implemented for "Await a stable state" step | 758 // once microtask is implemented for "Await a stable state" step |
734 // in resource selection algorithm. | 759 // in resource selection algorithm. |
735 void HTMLMediaElement::invokeLoadAlgorithm() | 760 void HTMLMediaElement::invokeLoadAlgorithm() |
(...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
957 | 982 |
958 LocalFrame* frame = document().frame(); | 983 LocalFrame* frame = document().frame(); |
959 if (!frame) { | 984 if (!frame) { |
960 mediaLoadingFailed(WebMediaPlayer::NetworkStateFormatError); | 985 mediaLoadingFailed(WebMediaPlayer::NetworkStateFormatError); |
961 return; | 986 return; |
962 } | 987 } |
963 | 988 |
964 // The resource fetch algorithm | 989 // The resource fetch algorithm |
965 setNetworkState(NETWORK_LOADING); | 990 setNetworkState(NETWORK_LOADING); |
966 | 991 |
| 992 m_autoplayHelper->loadingStarted(); |
| 993 |
967 // Set m_currentSrc *before* changing to the cache url, the fact that we are
loading from the app | 994 // Set m_currentSrc *before* changing to the cache url, the fact that we are
loading from the app |
968 // cache is an internal detail not exposed through the media element API. | 995 // cache is an internal detail not exposed through the media element API. |
969 m_currentSrc = url; | 996 m_currentSrc = url; |
970 | 997 |
971 if (m_audioSourceNode) | 998 if (m_audioSourceNode) |
972 m_audioSourceNode->onCurrentSrcChanged(m_currentSrc); | 999 m_audioSourceNode->onCurrentSrcChanged(m_currentSrc); |
973 | 1000 |
974 WTF_LOG(Media, "HTMLMediaElement::loadResource(%p) - m_currentSrc -> %s", th
is, urlForLoggingMedia(m_currentSrc).utf8().data()); | 1001 WTF_LOG(Media, "HTMLMediaElement::loadResource(%p) - m_currentSrc -> %s", th
is, urlForLoggingMedia(m_currentSrc).utf8().data()); |
975 | 1002 |
976 startProgressEventTimer(); | 1003 startProgressEventTimer(); |
977 | 1004 |
978 // Reset display mode to force a recalculation of what to show because we ar
e resetting the player. | 1005 // Reset display mode to force a recalculation of what to show because we ar
e resetting the player. |
979 setDisplayMode(Unknown); | 1006 setDisplayMode(Unknown); |
980 | 1007 |
981 setPlayerPreload(); | 1008 setPlayerPreload(); |
982 | 1009 |
983 if (fastHasAttribute(mutedAttr)) | 1010 if (fastHasAttribute(mutedAttr)) |
984 m_muted = true; | 1011 m_muted = true; |
985 updateVolume(); | 1012 updateVolume(); |
986 | 1013 |
987 ASSERT(!m_mediaSource); | 1014 ASSERT(!m_mediaSource); |
988 | 1015 |
989 bool attemptLoad = true; | 1016 bool attemptLoad = true; |
990 | 1017 |
991 if (url.protocolIs(mediaSourceBlobProtocol)) { | 1018 if (url.protocolIs(mediaSourceBlobProtocol)) { |
992 if (isMediaStreamURL(url.getString())) { | 1019 if (isMediaStreamURL(url.getString())) { |
993 m_userGestureRequiredForPlay = false; | 1020 m_autoplayHelper->removeUserGestureRequirement(GesturelessPlaybackEn
abledByStream); |
994 } else { | 1021 } else { |
995 m_mediaSource = HTMLMediaSource::lookup(url.getString()); | 1022 m_mediaSource = HTMLMediaSource::lookup(url.getString()); |
996 | 1023 |
997 if (m_mediaSource) { | 1024 if (m_mediaSource) { |
998 if (!m_mediaSource->attachToElement(this)) { | 1025 if (!m_mediaSource->attachToElement(this)) { |
999 // Forget our reference to the MediaSource, so we leave it a
lone | 1026 // Forget our reference to the MediaSource, so we leave it a
lone |
1000 // while processing remainder of load failure. | 1027 // while processing remainder of load failure. |
1001 m_mediaSource = nullptr; | 1028 m_mediaSource = nullptr; |
1002 attemptLoad = false; | 1029 attemptLoad = false; |
1003 } | 1030 } |
(...skipping 568 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1572 if (oldState <= HAVE_CURRENT_DATA) { | 1599 if (oldState <= HAVE_CURRENT_DATA) { |
1573 scheduleEvent(EventTypeNames::canplay); | 1600 scheduleEvent(EventTypeNames::canplay); |
1574 if (isPotentiallyPlaying) | 1601 if (isPotentiallyPlaying) |
1575 scheduleNotifyPlaying(); | 1602 scheduleNotifyPlaying(); |
1576 } | 1603 } |
1577 | 1604 |
1578 // Check for autoplay, and record metrics about it if needed. | 1605 // Check for autoplay, and record metrics about it if needed. |
1579 if (shouldAutoplay(RecordMetricsBehavior::DoRecord)) { | 1606 if (shouldAutoplay(RecordMetricsBehavior::DoRecord)) { |
1580 // If the autoplay experiment says that it's okay to play now, | 1607 // If the autoplay experiment says that it's okay to play now, |
1581 // then don't require a user gesture. | 1608 // then don't require a user gesture. |
1582 m_autoplayHelper.becameReadyToPlay(); | 1609 m_autoplayHelper->becameReadyToPlay(); |
1583 | 1610 |
1584 if (!m_userGestureRequiredForPlay) { | 1611 if (!m_userGestureRequiredForPlay) { |
1585 m_paused = false; | 1612 m_paused = false; |
1586 invalidateCachedTime(); | 1613 invalidateCachedTime(); |
1587 scheduleEvent(EventTypeNames::play); | 1614 scheduleEvent(EventTypeNames::play); |
1588 scheduleNotifyPlaying(); | 1615 scheduleNotifyPlaying(); |
1589 m_autoplaying = false; | 1616 m_autoplaying = false; |
1590 } | 1617 } |
1591 } | 1618 } |
1592 | 1619 |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1706 | 1733 |
1707 m_lastSeekTime = time; | 1734 m_lastSeekTime = time; |
1708 m_sentEndEvent = false; | 1735 m_sentEndEvent = false; |
1709 | 1736 |
1710 // 10 - Queue a task to fire a simple event named seeking at the element. | 1737 // 10 - Queue a task to fire a simple event named seeking at the element. |
1711 scheduleEvent(EventTypeNames::seeking); | 1738 scheduleEvent(EventTypeNames::seeking); |
1712 | 1739 |
1713 // 11 - Set the current playback position to the given new playback position
. | 1740 // 11 - Set the current playback position to the given new playback position
. |
1714 webMediaPlayer()->seek(time); | 1741 webMediaPlayer()->seek(time); |
1715 | 1742 |
1716 m_initialPlayWithoutUserGesture = false; | |
1717 | |
1718 // 14-17 are handled, if necessary, when the engine signals a readystate cha
nge or otherwise | 1743 // 14-17 are handled, if necessary, when the engine signals a readystate cha
nge or otherwise |
1719 // satisfies seek completion and signals a time change. | 1744 // satisfies seek completion and signals a time change. |
1720 } | 1745 } |
1721 | 1746 |
1722 void HTMLMediaElement::finishSeek() | 1747 void HTMLMediaElement::finishSeek() |
1723 { | 1748 { |
1724 WTF_LOG(Media, "HTMLMediaElement::finishSeek(%p)", this); | 1749 WTF_LOG(Media, "HTMLMediaElement::finishSeek(%p)", this); |
1725 | 1750 |
1726 // 14 - Set the seeking IDL attribute to false. | 1751 // 14 - Set the seeking IDL attribute to false. |
1727 m_seeking = false; | 1752 m_seeking = false; |
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1891 } | 1916 } |
1892 | 1917 |
1893 bool HTMLMediaElement::autoplay() const | 1918 bool HTMLMediaElement::autoplay() const |
1894 { | 1919 { |
1895 return fastHasAttribute(autoplayAttr); | 1920 return fastHasAttribute(autoplayAttr); |
1896 } | 1921 } |
1897 | 1922 |
1898 bool HTMLMediaElement::shouldAutoplay(const RecordMetricsBehavior recordMetrics) | 1923 bool HTMLMediaElement::shouldAutoplay(const RecordMetricsBehavior recordMetrics) |
1899 { | 1924 { |
1900 if (m_autoplaying && m_paused && autoplay()) { | 1925 if (m_autoplaying && m_paused && autoplay()) { |
1901 if (recordMetrics == RecordMetricsBehavior::DoRecord) | |
1902 autoplayMediaEncountered(); | |
1903 | |
1904 if (document().isSandboxed(SandboxAutomaticFeatures)) { | 1926 if (document().isSandboxed(SandboxAutomaticFeatures)) { |
1905 if (recordMetrics == RecordMetricsBehavior::DoRecord) | 1927 if (recordMetrics == RecordMetricsBehavior::DoRecord) |
1906 recordAutoplayMetric(AutoplayDisabledBySandbox); | 1928 m_autoplayHelper->recordSandboxFailure(); |
1907 return false; | 1929 return false; |
1908 } | 1930 } |
1909 | 1931 |
1910 return true; | 1932 return true; |
1911 } | 1933 } |
1912 | 1934 |
1913 return false; | 1935 return false; |
1914 } | 1936 } |
1915 | 1937 |
1916 String HTMLMediaElement::preload() const | 1938 String HTMLMediaElement::preload() const |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1998 ScriptPromise promise = resolver->promise(); | 2020 ScriptPromise promise = resolver->promise(); |
1999 | 2021 |
2000 m_playResolvers.append(resolver); | 2022 m_playResolvers.append(resolver); |
2001 return promise; | 2023 return promise; |
2002 } | 2024 } |
2003 | 2025 |
2004 Nullable<ExceptionCode> HTMLMediaElement::play() | 2026 Nullable<ExceptionCode> HTMLMediaElement::play() |
2005 { | 2027 { |
2006 WTF_LOG(Media, "HTMLMediaElement::play(%p)", this); | 2028 WTF_LOG(Media, "HTMLMediaElement::play(%p)", this); |
2007 | 2029 |
2008 m_autoplayHelper.playMethodCalled(); | 2030 m_autoplayHelper->playMethodCalled(); |
2009 | 2031 |
2010 if (!UserGestureIndicator::processingUserGesture()) { | 2032 if (!UserGestureIndicator::processingUserGesture()) { |
2011 autoplayMediaEncountered(); | |
2012 | |
2013 if (m_userGestureRequiredForPlay) { | 2033 if (m_userGestureRequiredForPlay) { |
2014 recordAutoplayMetric(PlayMethodFailed); | 2034 recordAutoplayMetric(PlayMethodFailed); |
2015 String message = ExceptionMessages::failedToExecute("play", "HTMLMed
iaElement", "API can only be initiated by a user gesture."); | 2035 String message = ExceptionMessages::failedToExecute("play", "HTMLMed
iaElement", "API can only be initiated by a user gesture."); |
2016 document().addConsoleMessage(ConsoleMessage::create(JSMessageSource,
WarningMessageLevel, message)); | 2036 document().addConsoleMessage(ConsoleMessage::create(JSMessageSource,
WarningMessageLevel, message)); |
2017 return NotAllowedError; | 2037 return NotAllowedError; |
2018 } | 2038 } |
2019 } else { | 2039 } else { |
| 2040 // We ask the helper to remove the gesture requirement for us, so that |
| 2041 // it can record the reason. |
2020 Platform::current()->recordAction(UserMetricsAction("Media_Play_WithGest
ure")); | 2042 Platform::current()->recordAction(UserMetricsAction("Media_Play_WithGest
ure")); |
2021 if (m_userGestureRequiredForPlay) { | 2043 m_autoplayHelper->removeUserGestureRequirement(GesturelessPlaybackEnable
dByPlayMethod); |
2022 if (m_autoplayMediaCounted) | |
2023 recordAutoplayMetric(AutoplayManualStart); | |
2024 m_userGestureRequiredForPlay = false; | |
2025 } | |
2026 } | 2044 } |
2027 | 2045 |
2028 if (m_error && m_error->code() == MediaError::MEDIA_ERR_SRC_NOT_SUPPORTED) | 2046 if (m_error && m_error->code() == MediaError::MEDIA_ERR_SRC_NOT_SUPPORTED) |
2029 return NotSupportedError; | 2047 return NotSupportedError; |
2030 | 2048 |
2031 playInternal(); | 2049 playInternal(); |
2032 | 2050 |
2033 return nullptr; | 2051 return nullptr; |
2034 } | 2052 } |
2035 | 2053 |
(...skipping 29 matching lines...) Expand all Loading... |
2065 } else if (m_readyState >= HAVE_FUTURE_DATA) { | 2083 } else if (m_readyState >= HAVE_FUTURE_DATA) { |
2066 scheduleResolvePlayPromises(); | 2084 scheduleResolvePlayPromises(); |
2067 } | 2085 } |
2068 | 2086 |
2069 m_autoplaying = false; | 2087 m_autoplaying = false; |
2070 | 2088 |
2071 setIgnorePreloadNone(); | 2089 setIgnorePreloadNone(); |
2072 updatePlayState(); | 2090 updatePlayState(); |
2073 } | 2091 } |
2074 | 2092 |
2075 void HTMLMediaElement::autoplayMediaEncountered() | |
2076 { | |
2077 if (!m_autoplayMediaCounted) { | |
2078 m_autoplayMediaCounted = true; | |
2079 recordAutoplayMetric(AutoplayMediaFound); | |
2080 | |
2081 if (!m_userGestureRequiredForPlay) | |
2082 m_initialPlayWithoutUserGesture = true; | |
2083 } | |
2084 } | |
2085 | |
2086 bool HTMLMediaElement::isBailout() const | |
2087 { | |
2088 // We count the user as having bailed-out on the video if they watched | |
2089 // less than one minute and less than 50% of it. | |
2090 const double playedTime = currentTime(); | |
2091 const double progress = playedTime / duration(); | |
2092 return (playedTime < 60) && (progress < 0.5); | |
2093 } | |
2094 | |
2095 void HTMLMediaElement::pause() | 2093 void HTMLMediaElement::pause() |
2096 { | 2094 { |
2097 WTF_LOG(Media, "HTMLMediaElement::pause(%p)", this); | 2095 WTF_LOG(Media, "HTMLMediaElement::pause(%p)", this); |
2098 | 2096 |
2099 // Only buffer aggressively on a user-initiated pause. Other types of pauses | 2097 // Only buffer aggressively on a user-initiated pause. Other types of pauses |
2100 // (which go directly to pauseInternal()) should not cause this behavior. | 2098 // (which go directly to pauseInternal()) should not cause this behavior. |
2101 if (webMediaPlayer() && UserGestureIndicator::processingUserGesture()) | 2099 if (webMediaPlayer() && UserGestureIndicator::processingUserGesture()) |
2102 webMediaPlayer()->setBufferingStrategy(WebMediaPlayer::BufferingStrategy
::Aggressive); | 2100 webMediaPlayer()->setBufferingStrategy(WebMediaPlayer::BufferingStrategy
::Aggressive); |
2103 | 2101 |
2104 pauseInternal(); | 2102 pauseInternal(); |
2105 } | 2103 } |
2106 | 2104 |
2107 void HTMLMediaElement::pauseInternal() | 2105 void HTMLMediaElement::pauseInternal() |
2108 { | 2106 { |
2109 WTF_LOG(Media, "HTMLMediaElement::pauseInternal(%p)", this); | 2107 WTF_LOG(Media, "HTMLMediaElement::pauseInternal(%p)", this); |
2110 | 2108 |
2111 if (m_networkState == NETWORK_EMPTY) | 2109 if (m_networkState == NETWORK_EMPTY) |
2112 invokeResourceSelectionAlgorithm(); | 2110 invokeResourceSelectionAlgorithm(); |
2113 | 2111 |
2114 m_autoplayHelper.pauseMethodCalled(); | 2112 m_autoplayHelper->pauseMethodCalled(); |
2115 | 2113 |
2116 m_autoplaying = false; | 2114 m_autoplaying = false; |
2117 | 2115 |
2118 if (!m_paused) { | 2116 if (!m_paused) { |
2119 recordMetricsIfPausing(); | |
2120 | |
2121 m_paused = true; | 2117 m_paused = true; |
2122 scheduleTimeupdateEvent(false); | 2118 scheduleTimeupdateEvent(false); |
2123 scheduleEvent(EventTypeNames::pause); | 2119 scheduleEvent(EventTypeNames::pause); |
2124 scheduleRejectPlayPromises(AbortError); | 2120 scheduleRejectPlayPromises(AbortError); |
2125 } | 2121 } |
2126 | 2122 |
2127 updatePlayState(); | 2123 updatePlayState(); |
2128 } | 2124 } |
2129 | 2125 |
2130 void HTMLMediaElement::requestRemotePlayback() | 2126 void HTMLMediaElement::requestRemotePlayback() |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2220 | 2216 |
2221 void HTMLMediaElement::setMuted(bool muted) | 2217 void HTMLMediaElement::setMuted(bool muted) |
2222 { | 2218 { |
2223 WTF_LOG(Media, "HTMLMediaElement::setMuted(%p, %s)", this, boolString(muted)
); | 2219 WTF_LOG(Media, "HTMLMediaElement::setMuted(%p, %s)", this, boolString(muted)
); |
2224 | 2220 |
2225 if (m_muted == muted) | 2221 if (m_muted == muted) |
2226 return; | 2222 return; |
2227 | 2223 |
2228 m_muted = muted; | 2224 m_muted = muted; |
2229 | 2225 |
2230 m_autoplayHelper.mutedChanged(); | 2226 m_autoplayHelper->mutedChanged(); |
2231 | 2227 |
2232 updateVolume(); | 2228 updateVolume(); |
2233 | 2229 |
2234 if (muted) | 2230 if (muted) |
2235 Platform::current()->recordAction(UserMetricsAction("Media_Playback_Mute
_On")); | 2231 Platform::current()->recordAction(UserMetricsAction("Media_Playback_Mute
_On")); |
2236 else | 2232 else |
2237 Platform::current()->recordAction(UserMetricsAction("Media_Playback_Mute
_Off")); | 2233 Platform::current()->recordAction(UserMetricsAction("Media_Playback_Mute
_Off")); |
2238 | 2234 |
2239 scheduleEvent(EventTypeNames::volumechange); | 2235 scheduleEvent(EventTypeNames::volumechange); |
2240 } | 2236 } |
(...skipping 603 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2844 if (!m_paused) { | 2840 if (!m_paused) { |
2845 // changes paused to true and fires a simple event named pause a
t the media element. | 2841 // changes paused to true and fires a simple event named pause a
t the media element. |
2846 m_paused = true; | 2842 m_paused = true; |
2847 scheduleEvent(EventTypeNames::pause); | 2843 scheduleEvent(EventTypeNames::pause); |
2848 } | 2844 } |
2849 // Queue a task to fire a simple event named ended at the media elem
ent. | 2845 // Queue a task to fire a simple event named ended at the media elem
ent. |
2850 if (!m_sentEndEvent) { | 2846 if (!m_sentEndEvent) { |
2851 m_sentEndEvent = true; | 2847 m_sentEndEvent = true; |
2852 scheduleEvent(EventTypeNames::ended); | 2848 scheduleEvent(EventTypeNames::ended); |
2853 } | 2849 } |
2854 recordMetricsIfPausing(); | |
2855 Platform::current()->recordAction(UserMetricsAction("Media_Playback_
Ended")); | 2850 Platform::current()->recordAction(UserMetricsAction("Media_Playback_
Ended")); |
2856 } | 2851 } |
2857 } else { | 2852 } else { |
2858 m_sentEndEvent = false; | 2853 m_sentEndEvent = false; |
2859 } | 2854 } |
2860 | 2855 |
2861 updatePlayState(); | 2856 updatePlayState(); |
2862 } | 2857 } |
2863 | 2858 |
2864 void HTMLMediaElement::durationChanged() | 2859 void HTMLMediaElement::durationChanged() |
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3060 invalidateCachedTime(); | 3055 invalidateCachedTime(); |
3061 | 3056 |
3062 if (!isPlaying) { | 3057 if (!isPlaying) { |
3063 // Set rate, muted before calling play in case they were set before
the media engine was setup. | 3058 // Set rate, muted before calling play in case they were set before
the media engine was setup. |
3064 // The media engine should just stash the rate and muted values sinc
e it isn't already playing. | 3059 // The media engine should just stash the rate and muted values sinc
e it isn't already playing. |
3065 webMediaPlayer()->setRate(playbackRate()); | 3060 webMediaPlayer()->setRate(playbackRate()); |
3066 updateVolume(); | 3061 updateVolume(); |
3067 webMediaPlayer()->play(); | 3062 webMediaPlayer()->play(); |
3068 Platform::current()->recordAction( | 3063 Platform::current()->recordAction( |
3069 UserMetricsAction("Media_Playback_Started")); | 3064 UserMetricsAction("Media_Playback_Started")); |
| 3065 m_autoplayHelper->playbackStarted(); |
3070 } | 3066 } |
3071 | 3067 |
3072 if (mediaControls()) | 3068 if (mediaControls()) |
3073 mediaControls()->playbackStarted(); | 3069 mediaControls()->playbackStarted(); |
3074 startPlaybackProgressTimer(); | 3070 startPlaybackProgressTimer(); |
3075 m_playing = true; | 3071 m_playing = true; |
3076 recordAutoplayMetric(AnyPlaybackStarted); | |
3077 | 3072 |
3078 } else { // Should not be playing right now | 3073 } else { // Should not be playing right now |
3079 if (isPlaying) { | 3074 if (isPlaying) { |
3080 webMediaPlayer()->pause(); | 3075 webMediaPlayer()->pause(); |
3081 Platform::current()->recordAction(UserMetricsAction("Media_Paused"))
; | 3076 Platform::current()->recordAction(UserMetricsAction("Media_Paused"))
; |
| 3077 m_autoplayHelper->playbackStopped(); |
3082 } | 3078 } |
3083 | 3079 |
3084 refreshCachedTime(); | 3080 refreshCachedTime(); |
3085 | 3081 |
3086 m_playbackProgressTimer.stop(); | 3082 m_playbackProgressTimer.stop(); |
3087 m_playing = false; | 3083 m_playing = false; |
3088 double time = currentTime(); | 3084 double time = currentTime(); |
3089 if (time > m_lastSeekTime) | 3085 if (time > m_lastSeekTime) |
3090 addPlayedRange(m_lastSeekTime, time); | 3086 addPlayedRange(m_lastSeekTime, time); |
3091 | 3087 |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3138 mediaControls()->refreshCastButtonVisibilityWithoutUpdate(); | 3134 mediaControls()->refreshCastButtonVisibilityWithoutUpdate(); |
3139 | 3135 |
3140 if (layoutObject()) | 3136 if (layoutObject()) |
3141 layoutObject()->setShouldDoFullPaintInvalidation(); | 3137 layoutObject()->setShouldDoFullPaintInvalidation(); |
3142 } | 3138 } |
3143 | 3139 |
3144 void HTMLMediaElement::stop() | 3140 void HTMLMediaElement::stop() |
3145 { | 3141 { |
3146 WTF_LOG(Media, "HTMLMediaElement::stop(%p)", this); | 3142 WTF_LOG(Media, "HTMLMediaElement::stop(%p)", this); |
3147 | 3143 |
3148 recordMetricsIfPausing(); | |
3149 | |
3150 // Close the async event queue so that no events are enqueued. | 3144 // Close the async event queue so that no events are enqueued. |
3151 cancelPendingEventsAndCallbacks(); | 3145 cancelPendingEventsAndCallbacks(); |
3152 m_asyncEventQueue->close(); | 3146 m_asyncEventQueue->close(); |
3153 | 3147 |
3154 // Clear everything in the Media Element | 3148 // Clear everything in the Media Element |
3155 clearMediaPlayer(); | 3149 clearMediaPlayer(); |
3156 m_readyState = HAVE_NOTHING; | 3150 m_readyState = HAVE_NOTHING; |
3157 m_readyStateMaximum = HAVE_NOTHING; | 3151 m_readyStateMaximum = HAVE_NOTHING; |
3158 setNetworkState(NETWORK_EMPTY); | 3152 setNetworkState(NETWORK_EMPTY); |
3159 setShouldDelayLoadEvent(false); | 3153 setShouldDelayLoadEvent(false); |
(...skipping 454 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3614 visitor->trace(m_currentSourceNode); | 3608 visitor->trace(m_currentSourceNode); |
3615 visitor->trace(m_nextChildNodeToConsider); | 3609 visitor->trace(m_nextChildNodeToConsider); |
3616 visitor->trace(m_mediaSource); | 3610 visitor->trace(m_mediaSource); |
3617 visitor->trace(m_audioTracks); | 3611 visitor->trace(m_audioTracks); |
3618 visitor->trace(m_videoTracks); | 3612 visitor->trace(m_videoTracks); |
3619 visitor->trace(m_cueTimeline); | 3613 visitor->trace(m_cueTimeline); |
3620 visitor->trace(m_textTracks); | 3614 visitor->trace(m_textTracks); |
3621 visitor->trace(m_textTracksWhenResourceSelectionBegan); | 3615 visitor->trace(m_textTracksWhenResourceSelectionBegan); |
3622 visitor->trace(m_playResolvers); | 3616 visitor->trace(m_playResolvers); |
3623 visitor->trace(m_audioSourceProvider); | 3617 visitor->trace(m_audioSourceProvider); |
| 3618 visitor->trace(m_autoplayHelperClient); |
| 3619 visitor->trace(m_autoplayHelper); |
3624 visitor->template registerWeakMembers<HTMLMediaElement, &HTMLMediaElement::c
learWeakMembers>(this); | 3620 visitor->template registerWeakMembers<HTMLMediaElement, &HTMLMediaElement::c
learWeakMembers>(this); |
3625 visitor->trace(m_autoplayHelper); | |
3626 HeapSupplementable<HTMLMediaElement>::trace(visitor); | 3621 HeapSupplementable<HTMLMediaElement>::trace(visitor); |
3627 #endif | 3622 #endif |
3628 HTMLElement::trace(visitor); | 3623 HTMLElement::trace(visitor); |
3629 ActiveDOMObject::trace(visitor); | 3624 ActiveDOMObject::trace(visitor); |
3630 } | 3625 } |
3631 | 3626 |
3632 void HTMLMediaElement::createPlaceholderTracksIfNecessary() | 3627 void HTMLMediaElement::createPlaceholderTracksIfNecessary() |
3633 { | 3628 { |
3634 if (!RuntimeEnabledFeatures::audioVideoTracksEnabled()) | 3629 if (!RuntimeEnabledFeatures::audioVideoTracksEnabled()) |
3635 return; | 3630 return; |
(...skipping 24 matching lines...) Expand all Loading... |
3660 bool HTMLMediaElement::isUserGestureRequiredForPlay() const | 3655 bool HTMLMediaElement::isUserGestureRequiredForPlay() const |
3661 { | 3656 { |
3662 return m_userGestureRequiredForPlay; | 3657 return m_userGestureRequiredForPlay; |
3663 } | 3658 } |
3664 | 3659 |
3665 void HTMLMediaElement::removeUserGestureRequirement() | 3660 void HTMLMediaElement::removeUserGestureRequirement() |
3666 { | 3661 { |
3667 m_userGestureRequiredForPlay = false; | 3662 m_userGestureRequiredForPlay = false; |
3668 } | 3663 } |
3669 | 3664 |
3670 void HTMLMediaElement::setInitialPlayWithoutUserGestures(bool value) | |
3671 { | |
3672 m_initialPlayWithoutUserGesture = value; | |
3673 } | |
3674 | |
3675 void HTMLMediaElement::setNetworkState(NetworkState state) | 3665 void HTMLMediaElement::setNetworkState(NetworkState state) |
3676 { | 3666 { |
3677 if (m_networkState != state) { | 3667 if (m_networkState != state) { |
3678 m_networkState = state; | 3668 m_networkState = state; |
3679 if (MediaControls* controls = mediaControls()) | 3669 if (MediaControls* controls = mediaControls()) |
3680 controls->networkStateChanged(); | 3670 controls->networkStateChanged(); |
3681 } | 3671 } |
3682 } | 3672 } |
3683 | 3673 |
3684 void HTMLMediaElement::notifyPositionMayHaveChanged(const IntRect& visibleRect) | 3674 void HTMLMediaElement::notifyPositionMayHaveChanged(const IntRect& visibleRect) |
3685 { | 3675 { |
3686 m_autoplayHelper.positionChanged(visibleRect); | 3676 m_autoplayHelper->positionChanged(visibleRect); |
3687 } | 3677 } |
3688 | 3678 |
3689 void HTMLMediaElement::updatePositionNotificationRegistration() | 3679 void HTMLMediaElement::updatePositionNotificationRegistration() |
3690 { | 3680 { |
3691 m_autoplayHelper.updatePositionNotificationRegistration(); | 3681 m_autoplayHelper->updatePositionNotificationRegistration(); |
3692 } | 3682 } |
3693 | 3683 |
3694 void HTMLMediaElement::setRemotePlaybackClient(WebRemotePlaybackClient* client) | 3684 void HTMLMediaElement::setRemotePlaybackClient(WebRemotePlaybackClient* client) |
3695 { | 3685 { |
3696 m_remotePlaybackClient = client; | 3686 m_remotePlaybackClient = client; |
3697 } | 3687 } |
3698 | 3688 |
3699 // TODO(liberato): remove once autoplay gesture override experiment concludes. | 3689 // TODO(liberato): remove once autoplay gesture override experiment concludes. |
3700 void HTMLMediaElement::triggerAutoplayViewportCheckForTesting() | 3690 void HTMLMediaElement::triggerAutoplayViewportCheckForTesting() |
3701 { | 3691 { |
3702 m_autoplayHelper.triggerAutoplayViewportCheckForTesting(); | 3692 if (FrameView* view = document().view()) |
| 3693 m_autoplayHelper->positionChanged(view->rootFrameToContents(view->comput
eVisibleArea())); |
| 3694 m_autoplayHelper->triggerAutoplayViewportCheckForTesting(); |
3703 } | 3695 } |
3704 | 3696 |
3705 void HTMLMediaElement::scheduleResolvePlayPromises() | 3697 void HTMLMediaElement::scheduleResolvePlayPromises() |
3706 { | 3698 { |
3707 // Per spec, if there are two tasks in the queue, the first task will remove | 3699 // Per spec, if there are two tasks in the queue, the first task will remove |
3708 // all the pending promises making the second task useless unless a promise | 3700 // all the pending promises making the second task useless unless a promise |
3709 // can be added between the first and second task being run which is not | 3701 // can be added between the first and second task being run which is not |
3710 // possible at the moment. | 3702 // possible at the moment. |
3711 if (m_playPromiseResolveTask->isPending()) | 3703 if (m_playPromiseResolveTask->isPending()) |
3712 return; | 3704 return; |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3824 DEFINE_TRACE(HTMLMediaElement::AudioClientImpl) | 3816 DEFINE_TRACE(HTMLMediaElement::AudioClientImpl) |
3825 { | 3817 { |
3826 visitor->trace(m_client); | 3818 visitor->trace(m_client); |
3827 } | 3819 } |
3828 | 3820 |
3829 DEFINE_TRACE(HTMLMediaElement::AudioSourceProviderImpl) | 3821 DEFINE_TRACE(HTMLMediaElement::AudioSourceProviderImpl) |
3830 { | 3822 { |
3831 visitor->trace(m_client); | 3823 visitor->trace(m_client); |
3832 } | 3824 } |
3833 | 3825 |
| 3826 HTMLMediaElement::AutoplayHelperClientImpl::~AutoplayHelperClientImpl() |
| 3827 { |
| 3828 } |
| 3829 |
| 3830 bool HTMLMediaElement::AutoplayHelperClientImpl::isLegacyViewportType() |
| 3831 { |
| 3832 return m_element->document().viewportDescription().isLegacyViewportType(); |
| 3833 } |
| 3834 |
| 3835 PageVisibilityState HTMLMediaElement::AutoplayHelperClientImpl::pageVisibilitySt
ate() const |
| 3836 { |
| 3837 return m_element->document().pageVisibilityState(); |
| 3838 } |
| 3839 |
| 3840 String HTMLMediaElement::AutoplayHelperClientImpl::autoplayExperimentMode() cons
t |
| 3841 { |
| 3842 String mode; |
| 3843 if (m_element->document().settings()) |
| 3844 mode = m_element->document().settings()->autoplayExperimentMode(); |
| 3845 |
| 3846 return mode; |
| 3847 } |
| 3848 |
| 3849 void HTMLMediaElement::AutoplayHelperClientImpl::setRequestPositionUpdates(bool
request) |
| 3850 { |
| 3851 if (LayoutObject* layoutObject = m_element->layoutObject()) { |
| 3852 LayoutMediaItem layoutMediaItem = LayoutMediaItem(toLayoutMedia(layoutOb
ject)); |
| 3853 layoutMediaItem.setRequestPositionUpdates(request); |
| 3854 } |
| 3855 } |
| 3856 |
| 3857 IntRect HTMLMediaElement::AutoplayHelperClientImpl::absoluteBoundingBoxRect() co
nst |
| 3858 { |
| 3859 IntRect result; |
| 3860 if (LayoutObject* object = m_element->layoutObject()) |
| 3861 result = object->absoluteBoundingBoxRect(); |
| 3862 return result; |
| 3863 } |
| 3864 |
3834 } // namespace blink | 3865 } // namespace blink |
OLD | NEW |