Chromium Code Reviews| 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 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 246 if (contentMIMEType != "application/octet-stream" || contentTypeCodecs.isEmp ty()) { | 248 if (contentMIMEType != "application/octet-stream" || contentTypeCodecs.isEmp ty()) { |
| 247 WebMimeRegistry::SupportsType supported = Platform::current()->mimeRegis try()->supportsMediaMIMEType(contentMIMEType, contentTypeCodecs); | 249 WebMimeRegistry::SupportsType supported = Platform::current()->mimeRegis try()->supportsMediaMIMEType(contentMIMEType, contentTypeCodecs); |
| 248 return supported > WebMimeRegistry::IsNotSupported; | 250 return supported > WebMimeRegistry::IsNotSupported; |
| 249 } | 251 } |
| 250 | 252 |
| 251 return false; | 253 return false; |
| 252 } | 254 } |
| 253 | 255 |
| 254 } // anonymous namespace | 256 } // anonymous namespace |
| 255 | 257 |
| 258 class HTMLMediaElement::AutoplayHelperClientImpl : | |
| 259 public AutoplayExperimentHelper::Client { | |
| 260 | |
| 261 public: | |
| 262 static PassOwnPtrWillBeRawPtr<AutoplayHelperClientImpl> create(HTMLMediaElem ent* element) | |
| 263 { | |
| 264 return adoptPtrWillBeNoop(new AutoplayHelperClientImpl(element)); | |
| 265 } | |
| 266 | |
| 267 virtual ~AutoplayHelperClientImpl(); | |
| 268 | |
| 269 using RecordMetricsBehavior = HTMLMediaElement::RecordMetricsBehavior; | |
| 270 | |
| 271 double currentTime() const override { return m_element->currentTime(); } | |
| 272 double duration() const override { return m_element->duration(); } | |
| 273 bool paused() const override | |
| 274 { | |
| 275 bool isPlaying = m_element->webMediaPlayer() | |
| 276 &&!m_element->webMediaPlayer()->paused(); | |
|
liberato (no reviews please)
2016/03/15 14:10:49
here. sorry, i forgot that i rebased somewhere in
philipj_slow
2016/03/16 11:37:43
Looks a bit odd to check both the paused state (wh
liberato (no reviews please)
2016/03/16 14:59:58
i added a comment. i also tried removing m_paused
| |
| 277 return m_element->paused() || !isPlaying; | |
| 278 } | |
| 279 bool muted() const override { return m_element->muted(); } | |
| 280 void setMuted(bool muted) override { m_element->setMuted(muted); } | |
| 281 void playInternal() override { m_element->playInternal(); } | |
| 282 bool isUserGestureRequiredForPlay() const override { return m_element->isUse rGestureRequiredForPlay(); } | |
| 283 void removeUserGestureRequirement() override { m_element->removeUserGestureR equirement(); } | |
| 284 void recordAutoplayMetric(AutoplayMetrics metric) override { m_element->reco rdAutoplayMetric(metric); } | |
| 285 bool shouldAutoplay() override | |
| 286 { | |
| 287 return m_element->shouldAutoplay(RecordMetricsBehavior::DoNotRecord); | |
| 288 } | |
| 289 bool isHTMLVideoElement() const override { return m_element->isHTMLVideoElem ent(); } | |
| 290 bool isHTMLAudioElement() const override { return m_element->isHTMLAudioElem ent(); } | |
| 291 | |
| 292 // Document | |
| 293 bool isLegacyViewportType() override; | |
| 294 PageVisibilityState pageVisibilityState() const override; | |
| 295 String autoplayExperimentMode() const override; | |
| 296 | |
| 297 // LayoutObject | |
| 298 void setRequestPositionUpdates(bool) override; | |
| 299 IntRect absoluteBoundingBoxRect() const override; | |
| 300 | |
| 301 DEFINE_INLINE_VIRTUAL_TRACE() | |
| 302 { | |
| 303 visitor->trace(m_element); | |
| 304 Client::trace(visitor); | |
| 305 } | |
| 306 | |
| 307 private: | |
| 308 AutoplayHelperClientImpl(HTMLMediaElement* element) : m_element(element) {} | |
| 309 | |
| 310 RawPtrWillBeMember<HTMLMediaElement> m_element; | |
| 311 }; | |
| 312 | |
| 313 | |
| 256 void HTMLMediaElement::recordAutoplayMetric(AutoplayMetrics metric) | 314 void HTMLMediaElement::recordAutoplayMetric(AutoplayMetrics metric) |
| 257 { | 315 { |
| 258 DEFINE_STATIC_LOCAL(EnumerationHistogram, autoplayHistogram, ("Blink.MediaEl ement.Autoplay", NumberOfAutoplayMetrics)); | 316 DEFINE_STATIC_LOCAL(EnumerationHistogram, autoplayHistogram, ("Blink.MediaEl ement.Autoplay", NumberOfAutoplayMetrics)); |
| 259 autoplayHistogram.count(metric); | 317 autoplayHistogram.count(metric); |
| 260 } | 318 } |
| 261 | 319 |
| 262 WebMimeRegistry::SupportsType HTMLMediaElement::supportsType(const ContentType& contentType) | 320 WebMimeRegistry::SupportsType HTMLMediaElement::supportsType(const ContentType& contentType) |
| 263 { | 321 { |
| 264 DEFINE_STATIC_LOCAL(const String, codecs, ("codecs")); | 322 DEFINE_STATIC_LOCAL(const String, codecs, ("codecs")); |
| 265 | 323 |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 331 , m_seeking(false) | 389 , m_seeking(false) |
| 332 , m_sentStalledEvent(false) | 390 , m_sentStalledEvent(false) |
| 333 , m_sentEndEvent(false) | 391 , m_sentEndEvent(false) |
| 334 , m_closedCaptionsVisible(false) | 392 , m_closedCaptionsVisible(false) |
| 335 , m_havePreparedToPlay(false) | 393 , m_havePreparedToPlay(false) |
| 336 , m_tracksAreReady(true) | 394 , m_tracksAreReady(true) |
| 337 , m_processingPreferenceChange(false) | 395 , m_processingPreferenceChange(false) |
| 338 , m_remoteRoutesAvailable(false) | 396 , m_remoteRoutesAvailable(false) |
| 339 , m_playingRemotely(false) | 397 , m_playingRemotely(false) |
| 340 , m_isFinalizing(false) | 398 , m_isFinalizing(false) |
| 341 , m_initialPlayWithoutUserGesture(false) | |
| 342 , m_autoplayMediaCounted(false) | |
| 343 , m_inOverlayFullscreenVideo(false) | 399 , m_inOverlayFullscreenVideo(false) |
| 344 , m_audioTracks(AudioTrackList::create(*this)) | 400 , m_audioTracks(AudioTrackList::create(*this)) |
| 345 , m_videoTracks(VideoTrackList::create(*this)) | 401 , m_videoTracks(VideoTrackList::create(*this)) |
| 346 , m_textTracks(nullptr) | 402 , m_textTracks(nullptr) |
| 347 , m_playPromiseResolveTask(CancellableTaskFactory::create(this, &HTMLMediaEl ement::resolvePlayPromises)) | 403 , m_playPromiseResolveTask(CancellableTaskFactory::create(this, &HTMLMediaEl ement::resolvePlayPromises)) |
| 348 , m_playPromiseRejectTask(CancellableTaskFactory::create(this, &HTMLMediaEle ment::rejectPlayPromises)) | 404 , m_playPromiseRejectTask(CancellableTaskFactory::create(this, &HTMLMediaEle ment::rejectPlayPromises)) |
| 349 , m_audioSourceNode(nullptr) | 405 , m_audioSourceNode(nullptr) |
| 350 , m_autoplayHelper(*this) | 406 , m_autoplayHelperClient(AutoplayHelperClientImpl::create(this)) |
| 407 , m_autoplayHelper(AutoplayExperimentHelper::create(m_autoplayHelperClient.g et())) | |
| 351 { | 408 { |
| 352 #if ENABLE(OILPAN) | 409 #if ENABLE(OILPAN) |
| 353 ThreadState::current()->registerPreFinalizer(this); | 410 ThreadState::current()->registerPreFinalizer(this); |
| 354 #endif | 411 #endif |
| 355 | 412 |
| 356 WTF_LOG(Media, "HTMLMediaElement::HTMLMediaElement(%p)", this); | 413 WTF_LOG(Media, "HTMLMediaElement::HTMLMediaElement(%p)", this); |
| 357 | 414 |
| 358 if (document.settings() && document.settings()->mediaPlaybackRequiresUserGes ture()) | 415 if (document.settings() && document.settings()->mediaPlaybackRequiresUserGes ture()) |
| 359 m_userGestureRequiredForPlay = true; | 416 m_userGestureRequiredForPlay = true; |
| 360 | 417 |
| 361 setHasCustomStyleCallbacks(); | 418 setHasCustomStyleCallbacks(); |
| 362 addElementToDocumentMap(this, &document); | 419 addElementToDocumentMap(this, &document); |
| 363 | 420 |
| 364 UseCounter::count(document, UseCounter::HTMLMediaElement); | 421 UseCounter::count(document, UseCounter::HTMLMediaElement); |
| 365 } | 422 } |
| 366 | 423 |
| 367 HTMLMediaElement::~HTMLMediaElement() | 424 HTMLMediaElement::~HTMLMediaElement() |
| 368 { | 425 { |
| 369 WTF_LOG(Media, "HTMLMediaElement::~HTMLMediaElement(%p)", this); | 426 WTF_LOG(Media, "HTMLMediaElement::~HTMLMediaElement(%p)", this); |
| 370 | 427 |
| 371 #if !ENABLE(OILPAN) | 428 #if !ENABLE(OILPAN) |
| 429 // Destruction of the autoplay helper requires the client, so be sure that | |
| 430 // this happens before the client is destructed. | |
| 431 if (m_autoplayHelper) | |
| 432 m_autoplayHelper.clear(); | |
| 433 | |
| 372 // HTMLMediaElement and m_asyncEventQueue always become unreachable | 434 // HTMLMediaElement and m_asyncEventQueue always become unreachable |
| 373 // together. So HTMLMediaElement and m_asyncEventQueue are destructed in | 435 // together. So HTMLMediaElement and m_asyncEventQueue are destructed in |
| 374 // the same GC. We don't need to close it explicitly in Oilpan. | 436 // the same GC. We don't need to close it explicitly in Oilpan. |
| 375 m_asyncEventQueue->close(); | 437 m_asyncEventQueue->close(); |
| 376 | 438 |
| 377 setShouldDelayLoadEvent(false); | 439 setShouldDelayLoadEvent(false); |
| 378 | 440 |
| 379 if (m_textTracks) | 441 if (m_textTracks) |
| 380 m_textTracks->clearOwner(); | 442 m_textTracks->clearOwner(); |
| 381 m_audioTracks->shutdown(); | 443 m_audioTracks->shutdown(); |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 401 // m_audioSourceNode is explicitly cleared by AudioNode::dispose(). | 463 // m_audioSourceNode is explicitly cleared by AudioNode::dispose(). |
| 402 // Since AudioNode::dispose() is guaranteed to be always called before | 464 // Since AudioNode::dispose() is guaranteed to be always called before |
| 403 // the AudioNode is destructed, m_audioSourceNode is explicitly cleared | 465 // the AudioNode is destructed, m_audioSourceNode is explicitly cleared |
| 404 // even if the AudioNode and the HTMLMediaElement die together. | 466 // even if the AudioNode and the HTMLMediaElement die together. |
| 405 ASSERT(!m_audioSourceNode); | 467 ASSERT(!m_audioSourceNode); |
| 406 } | 468 } |
| 407 | 469 |
| 408 #if ENABLE(OILPAN) | 470 #if ENABLE(OILPAN) |
| 409 void HTMLMediaElement::dispose() | 471 void HTMLMediaElement::dispose() |
| 410 { | 472 { |
| 473 // This must happen before we're destructed. | |
| 474 if (m_autoplayHelper) | |
| 475 m_autoplayHelper->dispose(); | |
| 476 | |
| 411 // If the HTMLMediaElement dies with the Document we are not | 477 // If the HTMLMediaElement dies with the Document we are not |
| 412 // allowed to touch the Document to adjust delay load event counts | 478 // allowed to touch the Document to adjust delay load event counts |
| 413 // from the destructor, as the Document could have been already | 479 // from the destructor, as the Document could have been already |
| 414 // destructed. | 480 // destructed. |
| 415 // | 481 // |
| 416 // Work around that restriction by accessing the Document from | 482 // Work around that restriction by accessing the Document from |
| 417 // a prefinalizer action instead, updating its delayed load count. | 483 // a prefinalizer action instead, updating its delayed load count. |
| 418 // If needed - if the Document has been detached and informed its | 484 // If needed - if the Document has been detached and informed its |
| 419 // ContextLifecycleObservers (which HTMLMediaElement is) that | 485 // ContextLifecycleObservers (which HTMLMediaElement is) that |
| 420 // it is being destroyed, the connection to the Document will | 486 // it is being destroyed, the connection to the Document will |
| (...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 661 case WebMimeRegistry::IsSupported: | 727 case WebMimeRegistry::IsSupported: |
| 662 canPlay = "probably"; | 728 canPlay = "probably"; |
| 663 break; | 729 break; |
| 664 } | 730 } |
| 665 | 731 |
| 666 WTF_LOG(Media, "HTMLMediaElement::canPlayType(%p, %s) -> %s", this, mimeType .utf8().data(), canPlay.utf8().data()); | 732 WTF_LOG(Media, "HTMLMediaElement::canPlayType(%p, %s) -> %s", this, mimeType .utf8().data(), canPlay.utf8().data()); |
| 667 | 733 |
| 668 return canPlay; | 734 return canPlay; |
| 669 } | 735 } |
| 670 | 736 |
| 671 void HTMLMediaElement::recordMetricsIfPausing() | |
| 672 { | |
| 673 // If not playing, then nothing to record. | |
| 674 // TODO(liberato): test metrics. this was m_paused. | |
| 675 if (m_paused) | |
| 676 return; | |
| 677 | |
| 678 const bool bailout = isBailout(); | |
| 679 | |
| 680 // Record that play was paused. We don't care if it was autoplay, | |
| 681 // play(), or the user manually started it. | |
| 682 recordAutoplayMetric(AnyPlaybackPaused); | |
| 683 if (bailout) | |
| 684 recordAutoplayMetric(AnyPlaybackBailout); | |
| 685 | |
| 686 // If this was a gestureless play, then record that separately. | |
| 687 // These cover attr and play() gestureless starts. | |
| 688 if (m_initialPlayWithoutUserGesture) { | |
| 689 m_initialPlayWithoutUserGesture = false; | |
| 690 | |
| 691 recordAutoplayMetric(AutoplayPaused); | |
| 692 | |
| 693 if (bailout) | |
| 694 recordAutoplayMetric(AutoplayBailout); | |
| 695 } | |
| 696 } | |
| 697 | |
| 698 void HTMLMediaElement::load() | 737 void HTMLMediaElement::load() |
| 699 { | 738 { |
| 700 WTF_LOG(Media, "HTMLMediaElement::load(%p)", this); | 739 WTF_LOG(Media, "HTMLMediaElement::load(%p)", this); |
| 701 | 740 |
| 702 recordMetricsIfPausing(); | 741 m_autoplayHelper->loadMethodCalled(); |
| 703 | |
| 704 if (UserGestureIndicator::processingUserGesture() && m_userGestureRequiredFo rPlay) { | |
| 705 recordAutoplayMetric(AutoplayEnabledThroughLoad); | |
| 706 m_userGestureRequiredForPlay = false; | |
| 707 // While usergesture-initiated load()s technically count as autoplayed, | |
| 708 // they don't feel like such to the users and hence we don't want to | |
| 709 // count them for the purposes of metrics. | |
| 710 m_autoplayMediaCounted = true; | |
| 711 } | |
| 712 | 742 |
| 713 prepareForLoad(); | 743 prepareForLoad(); |
| 714 loadInternal(); | 744 loadInternal(); |
| 715 prepareToPlay(); | 745 prepareToPlay(); |
| 716 } | 746 } |
| 717 | 747 |
| 718 void HTMLMediaElement::prepareForLoad() | 748 void HTMLMediaElement::prepareForLoad() |
| 719 { | 749 { |
| 720 WTF_LOG(Media, "HTMLMediaElement::prepareForLoad(%p)", this); | 750 WTF_LOG(Media, "HTMLMediaElement::prepareForLoad(%p)", this); |
| 721 | 751 |
| (...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 925 | 955 |
| 926 LocalFrame* frame = document().frame(); | 956 LocalFrame* frame = document().frame(); |
| 927 if (!frame) { | 957 if (!frame) { |
| 928 mediaLoadingFailed(WebMediaPlayer::NetworkStateFormatError); | 958 mediaLoadingFailed(WebMediaPlayer::NetworkStateFormatError); |
| 929 return; | 959 return; |
| 930 } | 960 } |
| 931 | 961 |
| 932 // The resource fetch algorithm | 962 // The resource fetch algorithm |
| 933 setNetworkState(NETWORK_LOADING); | 963 setNetworkState(NETWORK_LOADING); |
| 934 | 964 |
| 965 m_autoplayHelper->loadingStarted(); | |
| 966 | |
| 935 // Set m_currentSrc *before* changing to the cache url, the fact that we are loading from the app | 967 // Set m_currentSrc *before* changing to the cache url, the fact that we are loading from the app |
| 936 // cache is an internal detail not exposed through the media element API. | 968 // cache is an internal detail not exposed through the media element API. |
| 937 m_currentSrc = url; | 969 m_currentSrc = url; |
| 938 | 970 |
| 939 if (m_audioSourceNode) | 971 if (m_audioSourceNode) |
| 940 m_audioSourceNode->onCurrentSrcChanged(m_currentSrc); | 972 m_audioSourceNode->onCurrentSrcChanged(m_currentSrc); |
| 941 | 973 |
| 942 WTF_LOG(Media, "HTMLMediaElement::loadResource(%p) - m_currentSrc -> %s", th is, urlForLoggingMedia(m_currentSrc).utf8().data()); | 974 WTF_LOG(Media, "HTMLMediaElement::loadResource(%p) - m_currentSrc -> %s", th is, urlForLoggingMedia(m_currentSrc).utf8().data()); |
| 943 | 975 |
| 944 startProgressEventTimer(); | 976 startProgressEventTimer(); |
| 945 | 977 |
| 946 // Reset display mode to force a recalculation of what to show because we ar e resetting the player. | 978 // Reset display mode to force a recalculation of what to show because we ar e resetting the player. |
| 947 setDisplayMode(Unknown); | 979 setDisplayMode(Unknown); |
| 948 | 980 |
| 949 setPlayerPreload(); | 981 setPlayerPreload(); |
| 950 | 982 |
| 951 if (fastHasAttribute(mutedAttr)) | 983 if (fastHasAttribute(mutedAttr)) |
| 952 m_muted = true; | 984 m_muted = true; |
| 953 updateVolume(); | 985 updateVolume(); |
| 954 | 986 |
| 955 ASSERT(!m_mediaSource); | 987 ASSERT(!m_mediaSource); |
| 956 | 988 |
| 957 bool attemptLoad = true; | 989 bool attemptLoad = true; |
| 958 | 990 |
| 959 if (url.protocolIs(mediaSourceBlobProtocol)) { | 991 if (url.protocolIs(mediaSourceBlobProtocol)) { |
| 960 if (isMediaStreamURL(url.getString())) { | 992 if (isMediaStreamURL(url.getString())) { |
| 961 m_userGestureRequiredForPlay = false; | 993 m_autoplayHelper->removeUserGestureRequirement(GesturelessPlaybackEn abledByStream); |
| 962 } else { | 994 } else { |
| 963 m_mediaSource = HTMLMediaSource::lookup(url.getString()); | 995 m_mediaSource = HTMLMediaSource::lookup(url.getString()); |
| 964 | 996 |
| 965 if (m_mediaSource) { | 997 if (m_mediaSource) { |
| 966 if (!m_mediaSource->attachToElement(this)) { | 998 if (!m_mediaSource->attachToElement(this)) { |
| 967 // Forget our reference to the MediaSource, so we leave it a lone | 999 // Forget our reference to the MediaSource, so we leave it a lone |
| 968 // while processing remainder of load failure. | 1000 // while processing remainder of load failure. |
| 969 m_mediaSource = nullptr; | 1001 m_mediaSource = nullptr; |
| 970 attemptLoad = false; | 1002 attemptLoad = false; |
| 971 } | 1003 } |
| (...skipping 568 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1540 if (oldState <= HAVE_CURRENT_DATA) { | 1572 if (oldState <= HAVE_CURRENT_DATA) { |
| 1541 scheduleEvent(EventTypeNames::canplay); | 1573 scheduleEvent(EventTypeNames::canplay); |
| 1542 if (isPotentiallyPlaying) | 1574 if (isPotentiallyPlaying) |
| 1543 scheduleNotifyPlaying(); | 1575 scheduleNotifyPlaying(); |
| 1544 } | 1576 } |
| 1545 | 1577 |
| 1546 // Check for autoplay, and record metrics about it if needed. | 1578 // Check for autoplay, and record metrics about it if needed. |
| 1547 if (shouldAutoplay(RecordMetricsBehavior::DoRecord)) { | 1579 if (shouldAutoplay(RecordMetricsBehavior::DoRecord)) { |
| 1548 // If the autoplay experiment says that it's okay to play now, | 1580 // If the autoplay experiment says that it's okay to play now, |
| 1549 // then don't require a user gesture. | 1581 // then don't require a user gesture. |
| 1550 m_autoplayHelper.becameReadyToPlay(); | 1582 m_autoplayHelper->becameReadyToPlay(); |
| 1551 | 1583 |
| 1552 if (!m_userGestureRequiredForPlay) { | 1584 if (!m_userGestureRequiredForPlay) { |
| 1553 m_paused = false; | 1585 m_paused = false; |
| 1554 invalidateCachedTime(); | 1586 invalidateCachedTime(); |
| 1555 scheduleEvent(EventTypeNames::play); | 1587 scheduleEvent(EventTypeNames::play); |
| 1556 scheduleNotifyPlaying(); | 1588 scheduleNotifyPlaying(); |
| 1557 m_autoplaying = false; | 1589 m_autoplaying = false; |
| 1558 } | 1590 } |
| 1559 } | 1591 } |
| 1560 | 1592 |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1679 | 1711 |
| 1680 m_lastSeekTime = time; | 1712 m_lastSeekTime = time; |
| 1681 m_sentEndEvent = false; | 1713 m_sentEndEvent = false; |
| 1682 | 1714 |
| 1683 // 10 - Queue a task to fire a simple event named seeking at the element. | 1715 // 10 - Queue a task to fire a simple event named seeking at the element. |
| 1684 scheduleEvent(EventTypeNames::seeking); | 1716 scheduleEvent(EventTypeNames::seeking); |
| 1685 | 1717 |
| 1686 // 11 - Set the current playback position to the given new playback position . | 1718 // 11 - Set the current playback position to the given new playback position . |
| 1687 webMediaPlayer()->seek(time); | 1719 webMediaPlayer()->seek(time); |
| 1688 | 1720 |
| 1689 m_initialPlayWithoutUserGesture = false; | |
| 1690 | |
| 1691 // 14-17 are handled, if necessary, when the engine signals a readystate cha nge or otherwise | 1721 // 14-17 are handled, if necessary, when the engine signals a readystate cha nge or otherwise |
| 1692 // satisfies seek completion and signals a time change. | 1722 // satisfies seek completion and signals a time change. |
| 1693 } | 1723 } |
| 1694 | 1724 |
| 1695 void HTMLMediaElement::finishSeek() | 1725 void HTMLMediaElement::finishSeek() |
| 1696 { | 1726 { |
| 1697 WTF_LOG(Media, "HTMLMediaElement::finishSeek(%p)", this); | 1727 WTF_LOG(Media, "HTMLMediaElement::finishSeek(%p)", this); |
| 1698 | 1728 |
| 1699 // 14 - Set the seeking IDL attribute to false. | 1729 // 14 - Set the seeking IDL attribute to false. |
| 1700 m_seeking = false; | 1730 m_seeking = false; |
| (...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1864 } | 1894 } |
| 1865 | 1895 |
| 1866 bool HTMLMediaElement::autoplay() const | 1896 bool HTMLMediaElement::autoplay() const |
| 1867 { | 1897 { |
| 1868 return fastHasAttribute(autoplayAttr); | 1898 return fastHasAttribute(autoplayAttr); |
| 1869 } | 1899 } |
| 1870 | 1900 |
| 1871 bool HTMLMediaElement::shouldAutoplay(const RecordMetricsBehavior recordMetrics) | 1901 bool HTMLMediaElement::shouldAutoplay(const RecordMetricsBehavior recordMetrics) |
| 1872 { | 1902 { |
| 1873 if (m_autoplaying && m_paused && autoplay()) { | 1903 if (m_autoplaying && m_paused && autoplay()) { |
| 1874 if (recordMetrics == RecordMetricsBehavior::DoRecord) | |
| 1875 autoplayMediaEncountered(); | |
| 1876 | |
| 1877 if (document().isSandboxed(SandboxAutomaticFeatures)) { | 1904 if (document().isSandboxed(SandboxAutomaticFeatures)) { |
| 1878 if (recordMetrics == RecordMetricsBehavior::DoRecord) | 1905 if (recordMetrics == RecordMetricsBehavior::DoRecord) |
| 1879 recordAutoplayMetric(AutoplayDisabledBySandbox); | 1906 m_autoplayHelper->recordSandboxFailure(); |
| 1880 return false; | 1907 return false; |
| 1881 } | 1908 } |
| 1882 | 1909 |
| 1883 return true; | 1910 return true; |
| 1884 } | 1911 } |
| 1885 | 1912 |
| 1886 return false; | 1913 return false; |
| 1887 } | 1914 } |
| 1888 | 1915 |
| 1889 String HTMLMediaElement::preload() const | 1916 String HTMLMediaElement::preload() const |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1969 ScriptPromise promise = resolver->promise(); | 1996 ScriptPromise promise = resolver->promise(); |
| 1970 | 1997 |
| 1971 m_playResolvers.append(resolver); | 1998 m_playResolvers.append(resolver); |
| 1972 return promise; | 1999 return promise; |
| 1973 } | 2000 } |
| 1974 | 2001 |
| 1975 Nullable<ExceptionCode> HTMLMediaElement::play() | 2002 Nullable<ExceptionCode> HTMLMediaElement::play() |
| 1976 { | 2003 { |
| 1977 WTF_LOG(Media, "HTMLMediaElement::play(%p)", this); | 2004 WTF_LOG(Media, "HTMLMediaElement::play(%p)", this); |
| 1978 | 2005 |
| 1979 m_autoplayHelper.playMethodCalled(); | 2006 m_autoplayHelper->playMethodCalled(); |
| 1980 | 2007 |
| 1981 if (!UserGestureIndicator::processingUserGesture()) { | 2008 if (!UserGestureIndicator::processingUserGesture()) { |
| 1982 autoplayMediaEncountered(); | |
| 1983 | |
| 1984 if (m_userGestureRequiredForPlay) { | 2009 if (m_userGestureRequiredForPlay) { |
| 1985 recordAutoplayMetric(PlayMethodFailed); | 2010 recordAutoplayMetric(PlayMethodFailed); |
| 1986 String message = ExceptionMessages::failedToExecute("play", "HTMLMed iaElement", "API can only be initiated by a user gesture."); | 2011 String message = ExceptionMessages::failedToExecute("play", "HTMLMed iaElement", "API can only be initiated by a user gesture."); |
| 1987 document().addConsoleMessage(ConsoleMessage::create(JSMessageSource, WarningMessageLevel, message)); | 2012 document().addConsoleMessage(ConsoleMessage::create(JSMessageSource, WarningMessageLevel, message)); |
| 1988 return NotAllowedError; | 2013 return NotAllowedError; |
| 1989 } | 2014 } |
| 1990 } else { | 2015 } else { |
| 2016 // We ask the helper to remove the gesture requirement for us, so that | |
| 2017 // it can record the reason. | |
| 1991 Platform::current()->recordAction(UserMetricsAction("Media_Play_WithGest ure")); | 2018 Platform::current()->recordAction(UserMetricsAction("Media_Play_WithGest ure")); |
| 1992 if (m_userGestureRequiredForPlay) { | 2019 m_autoplayHelper->removeUserGestureRequirement(GesturelessPlaybackEnable dByPlayMethod); |
| 1993 if (m_autoplayMediaCounted) | |
| 1994 recordAutoplayMetric(AutoplayManualStart); | |
| 1995 m_userGestureRequiredForPlay = false; | |
| 1996 } | |
| 1997 } | 2020 } |
| 1998 | 2021 |
| 1999 if (m_error && m_error->code() == MediaError::MEDIA_ERR_SRC_NOT_SUPPORTED) | 2022 if (m_error && m_error->code() == MediaError::MEDIA_ERR_SRC_NOT_SUPPORTED) |
| 2000 return NotSupportedError; | 2023 return NotSupportedError; |
| 2001 | 2024 |
| 2002 playInternal(); | 2025 playInternal(); |
| 2003 | 2026 |
| 2004 return nullptr; | 2027 return nullptr; |
| 2005 } | 2028 } |
| 2006 | 2029 |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 2035 scheduleNotifyPlaying(); | 2058 scheduleNotifyPlaying(); |
| 2036 } else if (m_readyState >= HAVE_FUTURE_DATA) { | 2059 } else if (m_readyState >= HAVE_FUTURE_DATA) { |
| 2037 scheduleResolvePlayPromises(); | 2060 scheduleResolvePlayPromises(); |
| 2038 } | 2061 } |
| 2039 | 2062 |
| 2040 m_autoplaying = false; | 2063 m_autoplaying = false; |
| 2041 | 2064 |
| 2042 updatePlayState(); | 2065 updatePlayState(); |
| 2043 } | 2066 } |
| 2044 | 2067 |
| 2045 void HTMLMediaElement::autoplayMediaEncountered() | |
| 2046 { | |
| 2047 if (!m_autoplayMediaCounted) { | |
| 2048 m_autoplayMediaCounted = true; | |
| 2049 recordAutoplayMetric(AutoplayMediaFound); | |
| 2050 | |
| 2051 if (!m_userGestureRequiredForPlay) | |
| 2052 m_initialPlayWithoutUserGesture = true; | |
| 2053 } | |
| 2054 } | |
| 2055 | |
| 2056 bool HTMLMediaElement::isBailout() const | |
| 2057 { | |
| 2058 // We count the user as having bailed-out on the video if they watched | |
| 2059 // less than one minute and less than 50% of it. | |
| 2060 const double playedTime = currentTime(); | |
| 2061 const double progress = playedTime / duration(); | |
| 2062 return (playedTime < 60) && (progress < 0.5); | |
| 2063 } | |
| 2064 | |
| 2065 void HTMLMediaElement::pause() | 2068 void HTMLMediaElement::pause() |
| 2066 { | 2069 { |
| 2067 WTF_LOG(Media, "HTMLMediaElement::pause(%p)", this); | 2070 WTF_LOG(Media, "HTMLMediaElement::pause(%p)", this); |
| 2068 | 2071 |
| 2069 // Only buffer aggressively on a user-initiated pause. Other types of pauses | 2072 // Only buffer aggressively on a user-initiated pause. Other types of pauses |
| 2070 // (which go directly to pauseInternal()) should not cause this behavior. | 2073 // (which go directly to pauseInternal()) should not cause this behavior. |
| 2071 if (webMediaPlayer() && UserGestureIndicator::processingUserGesture()) | 2074 if (webMediaPlayer() && UserGestureIndicator::processingUserGesture()) |
| 2072 webMediaPlayer()->setBufferingStrategy(WebMediaPlayer::BufferingStrategy ::Aggressive); | 2075 webMediaPlayer()->setBufferingStrategy(WebMediaPlayer::BufferingStrategy ::Aggressive); |
| 2073 | 2076 |
| 2074 pauseInternal(); | 2077 pauseInternal(); |
| 2075 } | 2078 } |
| 2076 | 2079 |
| 2077 void HTMLMediaElement::pauseInternal() | 2080 void HTMLMediaElement::pauseInternal() |
| 2078 { | 2081 { |
| 2079 WTF_LOG(Media, "HTMLMediaElement::pauseInternal(%p)", this); | 2082 WTF_LOG(Media, "HTMLMediaElement::pauseInternal(%p)", this); |
| 2080 | 2083 |
| 2081 if (m_networkState == NETWORK_EMPTY) | 2084 if (m_networkState == NETWORK_EMPTY) |
| 2082 scheduleDelayedAction(LoadMediaResource); | 2085 scheduleDelayedAction(LoadMediaResource); |
| 2083 | 2086 |
| 2084 m_autoplayHelper.pauseMethodCalled(); | 2087 m_autoplayHelper->pauseMethodCalled(); |
| 2085 | 2088 |
| 2086 m_autoplaying = false; | 2089 m_autoplaying = false; |
| 2087 | 2090 |
| 2088 if (!m_paused) { | 2091 if (!m_paused) { |
| 2089 recordMetricsIfPausing(); | |
| 2090 | |
| 2091 m_paused = true; | 2092 m_paused = true; |
| 2092 scheduleTimeupdateEvent(false); | 2093 scheduleTimeupdateEvent(false); |
| 2093 scheduleEvent(EventTypeNames::pause); | 2094 scheduleEvent(EventTypeNames::pause); |
| 2094 scheduleRejectPlayPromises(AbortError); | 2095 scheduleRejectPlayPromises(AbortError); |
| 2095 } | 2096 } |
| 2096 | 2097 |
| 2097 updatePlayState(); | 2098 updatePlayState(); |
| 2098 } | 2099 } |
| 2099 | 2100 |
| 2100 void HTMLMediaElement::requestRemotePlayback() | 2101 void HTMLMediaElement::requestRemotePlayback() |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2190 | 2191 |
| 2191 void HTMLMediaElement::setMuted(bool muted) | 2192 void HTMLMediaElement::setMuted(bool muted) |
| 2192 { | 2193 { |
| 2193 WTF_LOG(Media, "HTMLMediaElement::setMuted(%p, %s)", this, boolString(muted) ); | 2194 WTF_LOG(Media, "HTMLMediaElement::setMuted(%p, %s)", this, boolString(muted) ); |
| 2194 | 2195 |
| 2195 if (m_muted == muted) | 2196 if (m_muted == muted) |
| 2196 return; | 2197 return; |
| 2197 | 2198 |
| 2198 m_muted = muted; | 2199 m_muted = muted; |
| 2199 | 2200 |
| 2200 m_autoplayHelper.mutedChanged(); | 2201 m_autoplayHelper->mutedChanged(); |
| 2201 | 2202 |
| 2202 updateVolume(); | 2203 updateVolume(); |
| 2203 | 2204 |
| 2204 if (muted) | 2205 if (muted) |
| 2205 Platform::current()->recordAction(UserMetricsAction("Media_Playback_Mute _On")); | 2206 Platform::current()->recordAction(UserMetricsAction("Media_Playback_Mute _On")); |
| 2206 else | 2207 else |
| 2207 Platform::current()->recordAction(UserMetricsAction("Media_Playback_Mute _Off")); | 2208 Platform::current()->recordAction(UserMetricsAction("Media_Playback_Mute _Off")); |
| 2208 | 2209 |
| 2209 scheduleEvent(EventTypeNames::volumechange); | 2210 scheduleEvent(EventTypeNames::volumechange); |
| 2210 } | 2211 } |
| (...skipping 592 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2803 // If the media element has a loop attribute specified | 2804 // If the media element has a loop attribute specified |
| 2804 if (loop()) { | 2805 if (loop()) { |
| 2805 m_sentEndEvent = false; | 2806 m_sentEndEvent = false; |
| 2806 // then seek to the earliest possible position of the media resourc e and abort these steps. | 2807 // then seek to the earliest possible position of the media resourc e and abort these steps. |
| 2807 seek(0); | 2808 seek(0); |
| 2808 } else { | 2809 } else { |
| 2809 // If the media element has still ended playback, and the direction of playback is still | 2810 // If the media element has still ended playback, and the direction of playback is still |
| 2810 // forwards, and paused is false, | 2811 // forwards, and paused is false, |
| 2811 if (!m_paused) { | 2812 if (!m_paused) { |
| 2812 // changes paused to true and fires a simple event named pause a t the media element. | 2813 // changes paused to true and fires a simple event named pause a t the media element. |
| 2814 m_autoplayHelper->playbackEnded(); | |
| 2813 m_paused = true; | 2815 m_paused = true; |
| 2814 scheduleEvent(EventTypeNames::pause); | 2816 scheduleEvent(EventTypeNames::pause); |
| 2815 } | 2817 } |
| 2816 // Queue a task to fire a simple event named ended at the media elem ent. | 2818 // Queue a task to fire a simple event named ended at the media elem ent. |
| 2817 if (!m_sentEndEvent) { | 2819 if (!m_sentEndEvent) { |
| 2818 m_sentEndEvent = true; | 2820 m_sentEndEvent = true; |
| 2819 scheduleEvent(EventTypeNames::ended); | 2821 scheduleEvent(EventTypeNames::ended); |
| 2820 } | 2822 } |
| 2821 recordMetricsIfPausing(); | |
| 2822 Platform::current()->recordAction(UserMetricsAction("Media_Playback_ Ended")); | 2823 Platform::current()->recordAction(UserMetricsAction("Media_Playback_ Ended")); |
| 2823 } | 2824 } |
| 2824 } else { | 2825 } else { |
| 2825 m_sentEndEvent = false; | 2826 m_sentEndEvent = false; |
| 2826 } | 2827 } |
| 2827 | 2828 |
| 2828 updatePlayState(); | 2829 updatePlayState(); |
| 2829 } | 2830 } |
| 2830 | 2831 |
| 2831 void HTMLMediaElement::durationChanged() | 2832 void HTMLMediaElement::durationChanged() |
| (...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3021 invalidateCachedTime(); | 3022 invalidateCachedTime(); |
| 3022 | 3023 |
| 3023 if (!isPlaying) { | 3024 if (!isPlaying) { |
| 3024 // Set rate, muted before calling play in case they were set before the media engine was setup. | 3025 // Set rate, muted before calling play in case they were set before the media engine was setup. |
| 3025 // The media engine should just stash the rate and muted values sinc e it isn't already playing. | 3026 // The media engine should just stash the rate and muted values sinc e it isn't already playing. |
| 3026 webMediaPlayer()->setRate(playbackRate()); | 3027 webMediaPlayer()->setRate(playbackRate()); |
| 3027 updateVolume(); | 3028 updateVolume(); |
| 3028 webMediaPlayer()->play(); | 3029 webMediaPlayer()->play(); |
| 3029 Platform::current()->recordAction( | 3030 Platform::current()->recordAction( |
| 3030 UserMetricsAction("Media_Playback_Started")); | 3031 UserMetricsAction("Media_Playback_Started")); |
| 3032 m_autoplayHelper->playbackStarted(); | |
| 3031 } | 3033 } |
| 3032 | 3034 |
| 3033 if (mediaControls()) | 3035 if (mediaControls()) |
| 3034 mediaControls()->playbackStarted(); | 3036 mediaControls()->playbackStarted(); |
| 3035 startPlaybackProgressTimer(); | 3037 startPlaybackProgressTimer(); |
| 3036 m_playing = true; | 3038 m_playing = true; |
| 3037 recordAutoplayMetric(AnyPlaybackStarted); | |
| 3038 | 3039 |
| 3039 } else { // Should not be playing right now | 3040 } else { // Should not be playing right now |
| 3040 if (isPlaying) { | 3041 if (isPlaying) { |
| 3041 webMediaPlayer()->pause(); | 3042 webMediaPlayer()->pause(); |
| 3042 Platform::current()->recordAction(UserMetricsAction("Media_Paused")) ; | 3043 Platform::current()->recordAction(UserMetricsAction("Media_Paused")) ; |
| 3043 } | 3044 } |
| 3044 | 3045 |
| 3045 refreshCachedTime(); | 3046 refreshCachedTime(); |
| 3046 | 3047 |
| 3047 m_playbackProgressTimer.stop(); | 3048 m_playbackProgressTimer.stop(); |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3102 mediaControls()->refreshCastButtonVisibilityWithoutUpdate(); | 3103 mediaControls()->refreshCastButtonVisibilityWithoutUpdate(); |
| 3103 | 3104 |
| 3104 if (layoutObject()) | 3105 if (layoutObject()) |
| 3105 layoutObject()->setShouldDoFullPaintInvalidation(); | 3106 layoutObject()->setShouldDoFullPaintInvalidation(); |
| 3106 } | 3107 } |
| 3107 | 3108 |
| 3108 void HTMLMediaElement::stop() | 3109 void HTMLMediaElement::stop() |
| 3109 { | 3110 { |
| 3110 WTF_LOG(Media, "HTMLMediaElement::stop(%p)", this); | 3111 WTF_LOG(Media, "HTMLMediaElement::stop(%p)", this); |
| 3111 | 3112 |
| 3112 recordMetricsIfPausing(); | |
| 3113 | |
| 3114 // Close the async event queue so that no events are enqueued. | 3113 // Close the async event queue so that no events are enqueued. |
| 3115 cancelPendingEventsAndCallbacks(); | 3114 cancelPendingEventsAndCallbacks(); |
| 3116 m_asyncEventQueue->close(); | 3115 m_asyncEventQueue->close(); |
| 3117 | 3116 |
| 3118 // Stop the playback without generating events | 3117 // Stop the playback without generating events |
| 3119 clearMediaPlayer(-1); | 3118 clearMediaPlayer(-1); |
| 3120 m_readyState = HAVE_NOTHING; | 3119 m_readyState = HAVE_NOTHING; |
| 3121 m_readyStateMaximum = HAVE_NOTHING; | 3120 m_readyStateMaximum = HAVE_NOTHING; |
| 3122 setNetworkState(NETWORK_EMPTY); | 3121 setNetworkState(NETWORK_EMPTY); |
| 3123 setShouldDelayLoadEvent(false); | 3122 setShouldDelayLoadEvent(false); |
| (...skipping 454 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3578 visitor->trace(m_currentSourceNode); | 3577 visitor->trace(m_currentSourceNode); |
| 3579 visitor->trace(m_nextChildNodeToConsider); | 3578 visitor->trace(m_nextChildNodeToConsider); |
| 3580 visitor->trace(m_mediaSource); | 3579 visitor->trace(m_mediaSource); |
| 3581 visitor->trace(m_audioTracks); | 3580 visitor->trace(m_audioTracks); |
| 3582 visitor->trace(m_videoTracks); | 3581 visitor->trace(m_videoTracks); |
| 3583 visitor->trace(m_cueTimeline); | 3582 visitor->trace(m_cueTimeline); |
| 3584 visitor->trace(m_textTracks); | 3583 visitor->trace(m_textTracks); |
| 3585 visitor->trace(m_textTracksWhenResourceSelectionBegan); | 3584 visitor->trace(m_textTracksWhenResourceSelectionBegan); |
| 3586 visitor->trace(m_playResolvers); | 3585 visitor->trace(m_playResolvers); |
| 3587 visitor->trace(m_audioSourceProvider); | 3586 visitor->trace(m_audioSourceProvider); |
| 3587 visitor->trace(m_autoplayHelperClient); | |
| 3588 visitor->trace(m_autoplayHelper); | |
| 3588 visitor->template registerWeakMembers<HTMLMediaElement, &HTMLMediaElement::c learWeakMembers>(this); | 3589 visitor->template registerWeakMembers<HTMLMediaElement, &HTMLMediaElement::c learWeakMembers>(this); |
| 3589 visitor->trace(m_autoplayHelper); | |
| 3590 HeapSupplementable<HTMLMediaElement>::trace(visitor); | 3590 HeapSupplementable<HTMLMediaElement>::trace(visitor); |
| 3591 #endif | 3591 #endif |
| 3592 HTMLElement::trace(visitor); | 3592 HTMLElement::trace(visitor); |
| 3593 ActiveDOMObject::trace(visitor); | 3593 ActiveDOMObject::trace(visitor); |
| 3594 } | 3594 } |
| 3595 | 3595 |
| 3596 void HTMLMediaElement::createPlaceholderTracksIfNecessary() | 3596 void HTMLMediaElement::createPlaceholderTracksIfNecessary() |
| 3597 { | 3597 { |
| 3598 if (!RuntimeEnabledFeatures::audioVideoTracksEnabled()) | 3598 if (!RuntimeEnabledFeatures::audioVideoTracksEnabled()) |
| 3599 return; | 3599 return; |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 3624 bool HTMLMediaElement::isUserGestureRequiredForPlay() const | 3624 bool HTMLMediaElement::isUserGestureRequiredForPlay() const |
| 3625 { | 3625 { |
| 3626 return m_userGestureRequiredForPlay; | 3626 return m_userGestureRequiredForPlay; |
| 3627 } | 3627 } |
| 3628 | 3628 |
| 3629 void HTMLMediaElement::removeUserGestureRequirement() | 3629 void HTMLMediaElement::removeUserGestureRequirement() |
| 3630 { | 3630 { |
| 3631 m_userGestureRequiredForPlay = false; | 3631 m_userGestureRequiredForPlay = false; |
| 3632 } | 3632 } |
| 3633 | 3633 |
| 3634 void HTMLMediaElement::setInitialPlayWithoutUserGestures(bool value) | |
| 3635 { | |
| 3636 m_initialPlayWithoutUserGesture = value; | |
| 3637 } | |
| 3638 | |
| 3639 void HTMLMediaElement::setNetworkState(NetworkState state) | 3634 void HTMLMediaElement::setNetworkState(NetworkState state) |
| 3640 { | 3635 { |
| 3641 if (m_networkState != state) { | 3636 if (m_networkState != state) { |
| 3642 m_networkState = state; | 3637 m_networkState = state; |
| 3643 if (MediaControls* controls = mediaControls()) | 3638 if (MediaControls* controls = mediaControls()) |
| 3644 controls->networkStateChanged(); | 3639 controls->networkStateChanged(); |
| 3645 } | 3640 } |
| 3646 } | 3641 } |
| 3647 | 3642 |
| 3648 void HTMLMediaElement::notifyPositionMayHaveChanged(const IntRect& visibleRect) | 3643 void HTMLMediaElement::notifyPositionMayHaveChanged(const IntRect& visibleRect) |
| 3649 { | 3644 { |
| 3650 m_autoplayHelper.positionChanged(visibleRect); | 3645 m_autoplayHelper->positionChanged(visibleRect); |
| 3651 } | 3646 } |
| 3652 | 3647 |
| 3653 void HTMLMediaElement::updatePositionNotificationRegistration() | 3648 void HTMLMediaElement::updatePositionNotificationRegistration() |
| 3654 { | 3649 { |
| 3655 m_autoplayHelper.updatePositionNotificationRegistration(); | 3650 m_autoplayHelper->updatePositionNotificationRegistration(); |
| 3656 } | 3651 } |
| 3657 | 3652 |
| 3658 // TODO(liberato): remove once autoplay gesture override experiment concludes. | 3653 // TODO(liberato): remove once autoplay gesture override experiment concludes. |
| 3659 void HTMLMediaElement::triggerAutoplayViewportCheckForTesting() | 3654 void HTMLMediaElement::triggerAutoplayViewportCheckForTesting() |
| 3660 { | 3655 { |
| 3661 m_autoplayHelper.triggerAutoplayViewportCheckForTesting(); | 3656 if (FrameView* view = document().view()) |
| 3657 m_autoplayHelper->positionChanged(view->rootFrameToContents(view->comput eVisibleArea())); | |
| 3658 m_autoplayHelper->triggerAutoplayViewportCheckForTesting(); | |
| 3662 } | 3659 } |
| 3663 | 3660 |
| 3664 void HTMLMediaElement::scheduleResolvePlayPromises() | 3661 void HTMLMediaElement::scheduleResolvePlayPromises() |
| 3665 { | 3662 { |
| 3666 // Per spec, if there are two tasks in the queue, the first task will remove | 3663 // Per spec, if there are two tasks in the queue, the first task will remove |
| 3667 // all the pending promises making the second task useless unless a promise | 3664 // all the pending promises making the second task useless unless a promise |
| 3668 // can be added between the first and second task being run which is not | 3665 // can be added between the first and second task being run which is not |
| 3669 // possible at the moment. | 3666 // possible at the moment. |
| 3670 if (m_playPromiseResolveTask->isPending()) | 3667 if (m_playPromiseResolveTask->isPending()) |
| 3671 return; | 3668 return; |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3794 DEFINE_TRACE(HTMLMediaElement::AudioClientImpl) | 3791 DEFINE_TRACE(HTMLMediaElement::AudioClientImpl) |
| 3795 { | 3792 { |
| 3796 visitor->trace(m_client); | 3793 visitor->trace(m_client); |
| 3797 } | 3794 } |
| 3798 | 3795 |
| 3799 DEFINE_TRACE(HTMLMediaElement::AudioSourceProviderImpl) | 3796 DEFINE_TRACE(HTMLMediaElement::AudioSourceProviderImpl) |
| 3800 { | 3797 { |
| 3801 visitor->trace(m_client); | 3798 visitor->trace(m_client); |
| 3802 } | 3799 } |
| 3803 | 3800 |
| 3801 HTMLMediaElement::AutoplayHelperClientImpl::~AutoplayHelperClientImpl() | |
| 3802 { | |
| 3803 } | |
| 3804 | |
| 3805 bool HTMLMediaElement::AutoplayHelperClientImpl::isLegacyViewportType() | |
| 3806 { | |
| 3807 return m_element->document().viewportDescription().isLegacyViewportType(); | |
| 3808 } | |
| 3809 | |
| 3810 PageVisibilityState HTMLMediaElement::AutoplayHelperClientImpl::pageVisibilitySt ate() const | |
| 3811 { | |
| 3812 return m_element->document().pageVisibilityState(); | |
| 3813 } | |
| 3814 | |
| 3815 String HTMLMediaElement::AutoplayHelperClientImpl::autoplayExperimentMode() cons t | |
| 3816 { | |
| 3817 String mode; | |
| 3818 if (m_element->document().settings()) | |
| 3819 mode = m_element->document().settings()->autoplayExperimentMode(); | |
| 3820 | |
| 3821 return mode; | |
| 3822 } | |
| 3823 | |
| 3824 void HTMLMediaElement::AutoplayHelperClientImpl::setRequestPositionUpdates(bool request) | |
| 3825 { | |
| 3826 if (LayoutObject* layoutObject = m_element->layoutObject()) { | |
| 3827 LayoutMediaItem layoutMediaItem = LayoutMediaItem(toLayoutMedia(layoutOb ject)); | |
| 3828 layoutMediaItem.setRequestPositionUpdates(request); | |
| 3829 } | |
| 3830 } | |
| 3831 | |
| 3832 IntRect HTMLMediaElement::AutoplayHelperClientImpl::absoluteBoundingBoxRect() co nst | |
| 3833 { | |
| 3834 IntRect result; | |
| 3835 if (LayoutObject* object = m_element->layoutObject()) | |
| 3836 result = object->absoluteBoundingBoxRect(); | |
| 3837 return result; | |
| 3838 } | |
| 3839 | |
| 3804 } // namespace blink | 3840 } // namespace blink |
| OLD | NEW |