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 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 261 case WebMediaPlayer::PreloadAuto: | 263 case WebMediaPlayer::PreloadAuto: |
| 262 return "auto"; | 264 return "auto"; |
| 263 } | 265 } |
| 264 | 266 |
| 265 ASSERT_NOT_REACHED(); | 267 ASSERT_NOT_REACHED(); |
| 266 return String(); | 268 return String(); |
| 267 } | 269 } |
| 268 | 270 |
| 269 } // anonymous namespace | 271 } // anonymous namespace |
| 270 | 272 |
| 273 class HTMLMediaElement::AutoplayHelperClientImpl : | |
| 274 public AutoplayExperimentHelper::Client { | |
| 275 | |
| 276 public: | |
| 277 static PassOwnPtrWillBeRawPtr<AutoplayHelperClientImpl> create(HTMLMediaElem ent* element) | |
| 278 { | |
| 279 return adoptPtrWillBeNoop(new AutoplayHelperClientImpl(element)); | |
| 280 } | |
| 281 | |
| 282 virtual ~AutoplayHelperClientImpl(); | |
| 283 | |
| 284 using RecordMetricsBehavior = HTMLMediaElement::RecordMetricsBehavior; | |
| 285 | |
| 286 double currentTime() const override { return m_element->currentTime(); } | |
| 287 double duration() const override { return m_element->duration(); } | |
| 288 bool complete() const override | |
|
philipj_slow
2016/03/29 06:21:09
Can this simply use HTMLMediaElement::ended()? The
| |
| 289 { | |
| 290 double now = currentTime(); | |
| 291 double dur = duration(); | |
| 292 | |
| 293 return !std::isnan(dur) && dur && now >= dur && m_element->getDirectionO fPlayback() == Forward; | |
| 294 } | |
| 295 bool muted() const override { return m_element->muted(); } | |
| 296 void setMuted(bool muted) override { m_element->setMuted(muted); } | |
| 297 void playInternal() override { m_element->playInternal(); } | |
| 298 bool isUserGestureRequiredForPlay() const override { return m_element->isUse rGestureRequiredForPlay(); } | |
| 299 void removeUserGestureRequirement() override { m_element->removeUserGestureR equirement(); } | |
| 300 void recordAutoplayMetric(AutoplayMetrics metric) override { m_element->reco rdAutoplayMetric(metric); } | |
| 301 bool shouldAutoplay() override | |
| 302 { | |
| 303 return m_element->shouldAutoplay(RecordMetricsBehavior::DoNotRecord); | |
| 304 } | |
| 305 bool isHTMLVideoElement() const override { return m_element->isHTMLVideoElem ent(); } | |
| 306 bool isHTMLAudioElement() const override { return m_element->isHTMLAudioElem ent(); } | |
| 307 | |
| 308 // Document | |
| 309 bool isLegacyViewportType() override; | |
| 310 PageVisibilityState pageVisibilityState() const override; | |
| 311 String autoplayExperimentMode() const override; | |
| 312 | |
| 313 // LayoutObject | |
| 314 void setRequestPositionUpdates(bool) override; | |
| 315 IntRect absoluteBoundingBoxRect() const override; | |
| 316 | |
| 317 DEFINE_INLINE_VIRTUAL_TRACE() | |
| 318 { | |
| 319 visitor->trace(m_element); | |
| 320 Client::trace(visitor); | |
| 321 } | |
| 322 | |
| 323 private: | |
| 324 AutoplayHelperClientImpl(HTMLMediaElement* element) : m_element(element) {} | |
| 325 | |
| 326 RawPtrWillBeMember<HTMLMediaElement> m_element; | |
| 327 }; | |
| 328 | |
| 329 | |
| 271 void HTMLMediaElement::recordAutoplayMetric(AutoplayMetrics metric) | 330 void HTMLMediaElement::recordAutoplayMetric(AutoplayMetrics metric) |
| 272 { | 331 { |
| 273 DEFINE_STATIC_LOCAL(EnumerationHistogram, autoplayHistogram, ("Blink.MediaEl ement.Autoplay", NumberOfAutoplayMetrics)); | 332 DEFINE_STATIC_LOCAL(EnumerationHistogram, autoplayHistogram, ("Blink.MediaEl ement.Autoplay", NumberOfAutoplayMetrics)); |
| 274 autoplayHistogram.count(metric); | 333 autoplayHistogram.count(metric); |
| 275 } | 334 } |
| 276 | 335 |
| 277 WebMimeRegistry::SupportsType HTMLMediaElement::supportsType(const ContentType& contentType) | 336 WebMimeRegistry::SupportsType HTMLMediaElement::supportsType(const ContentType& contentType) |
| 278 { | 337 { |
| 279 DEFINE_STATIC_LOCAL(const String, codecs, ("codecs")); | 338 DEFINE_STATIC_LOCAL(const String, codecs, ("codecs")); |
| 280 | 339 |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 346 , m_seeking(false) | 405 , m_seeking(false) |
| 347 , m_sentStalledEvent(false) | 406 , m_sentStalledEvent(false) |
| 348 , m_sentEndEvent(false) | 407 , m_sentEndEvent(false) |
| 349 , m_closedCaptionsVisible(false) | 408 , m_closedCaptionsVisible(false) |
| 350 , m_ignorePreloadNone(false) | 409 , m_ignorePreloadNone(false) |
| 351 , m_tracksAreReady(true) | 410 , m_tracksAreReady(true) |
| 352 , m_processingPreferenceChange(false) | 411 , m_processingPreferenceChange(false) |
| 353 , m_remoteRoutesAvailable(false) | 412 , m_remoteRoutesAvailable(false) |
| 354 , m_playingRemotely(false) | 413 , m_playingRemotely(false) |
| 355 , m_isFinalizing(false) | 414 , m_isFinalizing(false) |
| 356 , m_initialPlayWithoutUserGesture(false) | |
| 357 , m_autoplayMediaCounted(false) | |
| 358 , m_inOverlayFullscreenVideo(false) | 415 , m_inOverlayFullscreenVideo(false) |
| 359 , m_audioTracks(AudioTrackList::create(*this)) | 416 , m_audioTracks(AudioTrackList::create(*this)) |
| 360 , m_videoTracks(VideoTrackList::create(*this)) | 417 , m_videoTracks(VideoTrackList::create(*this)) |
| 361 , m_textTracks(nullptr) | 418 , m_textTracks(nullptr) |
| 362 , m_playPromiseResolveTask(CancellableTaskFactory::create(this, &HTMLMediaEl ement::resolvePlayPromises)) | 419 , m_playPromiseResolveTask(CancellableTaskFactory::create(this, &HTMLMediaEl ement::resolvePlayPromises)) |
| 363 , m_playPromiseRejectTask(CancellableTaskFactory::create(this, &HTMLMediaEle ment::rejectPlayPromises)) | 420 , m_playPromiseRejectTask(CancellableTaskFactory::create(this, &HTMLMediaEle ment::rejectPlayPromises)) |
| 364 , m_audioSourceNode(nullptr) | 421 , m_audioSourceNode(nullptr) |
| 365 , m_autoplayHelper(*this) | 422 , m_autoplayHelperClient(AutoplayHelperClientImpl::create(this)) |
| 423 , m_autoplayHelper(AutoplayExperimentHelper::create(m_autoplayHelperClient.g et())) | |
| 366 { | 424 { |
| 367 #if ENABLE(OILPAN) | 425 #if ENABLE(OILPAN) |
| 368 ThreadState::current()->registerPreFinalizer(this); | 426 ThreadState::current()->registerPreFinalizer(this); |
| 369 #endif | 427 #endif |
| 370 | 428 |
| 371 WTF_LOG(Media, "HTMLMediaElement::HTMLMediaElement(%p)", this); | 429 WTF_LOG(Media, "HTMLMediaElement::HTMLMediaElement(%p)", this); |
| 372 | 430 |
| 373 if (document.settings() && document.settings()->mediaPlaybackRequiresUserGes ture()) | 431 if (document.settings() && document.settings()->mediaPlaybackRequiresUserGes ture()) |
| 374 m_userGestureRequiredForPlay = true; | 432 m_userGestureRequiredForPlay = true; |
| 375 | 433 |
| 376 setHasCustomStyleCallbacks(); | 434 setHasCustomStyleCallbacks(); |
| 377 addElementToDocumentMap(this, &document); | 435 addElementToDocumentMap(this, &document); |
| 378 | 436 |
| 379 UseCounter::count(document, UseCounter::HTMLMediaElement); | 437 UseCounter::count(document, UseCounter::HTMLMediaElement); |
| 380 } | 438 } |
| 381 | 439 |
| 382 HTMLMediaElement::~HTMLMediaElement() | 440 HTMLMediaElement::~HTMLMediaElement() |
| 383 { | 441 { |
| 384 WTF_LOG(Media, "HTMLMediaElement::~HTMLMediaElement(%p)", this); | 442 WTF_LOG(Media, "HTMLMediaElement::~HTMLMediaElement(%p)", this); |
| 385 | 443 |
| 386 #if !ENABLE(OILPAN) | 444 #if !ENABLE(OILPAN) |
| 445 // Destruction of the autoplay helper requires the client, so be sure that | |
| 446 // this happens before the client is destructed. | |
| 447 if (m_autoplayHelper) | |
| 448 m_autoplayHelper.clear(); | |
| 449 | |
| 387 // HTMLMediaElement and m_asyncEventQueue always become unreachable | 450 // HTMLMediaElement and m_asyncEventQueue always become unreachable |
| 388 // together. So HTMLMediaElement and m_asyncEventQueue are destructed in | 451 // together. So HTMLMediaElement and m_asyncEventQueue are destructed in |
| 389 // the same GC. We don't need to close it explicitly in Oilpan. | 452 // the same GC. We don't need to close it explicitly in Oilpan. |
| 390 m_asyncEventQueue->close(); | 453 m_asyncEventQueue->close(); |
| 391 | 454 |
| 392 setShouldDelayLoadEvent(false); | 455 setShouldDelayLoadEvent(false); |
| 393 | 456 |
| 394 if (m_textTracks) | 457 if (m_textTracks) |
| 395 m_textTracks->clearOwner(); | 458 m_textTracks->clearOwner(); |
| 396 m_audioTracks->shutdown(); | 459 m_audioTracks->shutdown(); |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 416 // m_audioSourceNode is explicitly cleared by AudioNode::dispose(). | 479 // m_audioSourceNode is explicitly cleared by AudioNode::dispose(). |
| 417 // Since AudioNode::dispose() is guaranteed to be always called before | 480 // Since AudioNode::dispose() is guaranteed to be always called before |
| 418 // the AudioNode is destructed, m_audioSourceNode is explicitly cleared | 481 // the AudioNode is destructed, m_audioSourceNode is explicitly cleared |
| 419 // even if the AudioNode and the HTMLMediaElement die together. | 482 // even if the AudioNode and the HTMLMediaElement die together. |
| 420 ASSERT(!m_audioSourceNode); | 483 ASSERT(!m_audioSourceNode); |
| 421 } | 484 } |
| 422 | 485 |
| 423 #if ENABLE(OILPAN) | 486 #if ENABLE(OILPAN) |
| 424 void HTMLMediaElement::dispose() | 487 void HTMLMediaElement::dispose() |
| 425 { | 488 { |
| 489 // This must happen before we're destructed. | |
| 490 if (m_autoplayHelper) | |
| 491 m_autoplayHelper->dispose(); | |
| 492 | |
| 426 // If the HTMLMediaElement dies with the Document we are not | 493 // If the HTMLMediaElement dies with the Document we are not |
| 427 // allowed to touch the Document to adjust delay load event counts | 494 // allowed to touch the Document to adjust delay load event counts |
| 428 // from the destructor, as the Document could have been already | 495 // from the destructor, as the Document could have been already |
| 429 // destructed. | 496 // destructed. |
| 430 // | 497 // |
| 431 // Work around that restriction by accessing the Document from | 498 // Work around that restriction by accessing the Document from |
| 432 // a prefinalizer action instead, updating its delayed load count. | 499 // a prefinalizer action instead, updating its delayed load count. |
| 433 // If needed - if the Document has been detached and informed its | 500 // If needed - if the Document has been detached and informed its |
| 434 // ContextLifecycleObservers (which HTMLMediaElement is) that | 501 // ContextLifecycleObservers (which HTMLMediaElement is) that |
| 435 // it is being destroyed, the connection to the Document will | 502 // it is being destroyed, the connection to the Document will |
| (...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 672 case WebMimeRegistry::IsSupported: | 739 case WebMimeRegistry::IsSupported: |
| 673 canPlay = "probably"; | 740 canPlay = "probably"; |
| 674 break; | 741 break; |
| 675 } | 742 } |
| 676 | 743 |
| 677 WTF_LOG(Media, "HTMLMediaElement::canPlayType(%p, %s) -> %s", this, mimeType .utf8().data(), canPlay.utf8().data()); | 744 WTF_LOG(Media, "HTMLMediaElement::canPlayType(%p, %s) -> %s", this, mimeType .utf8().data(), canPlay.utf8().data()); |
| 678 | 745 |
| 679 return canPlay; | 746 return canPlay; |
| 680 } | 747 } |
| 681 | 748 |
| 682 void HTMLMediaElement::recordMetricsIfPausing() | |
| 683 { | |
| 684 // If not playing, then nothing to record. | |
| 685 // TODO(liberato): test metrics. this was m_paused. | |
| 686 if (m_paused) | |
| 687 return; | |
| 688 | |
| 689 const bool bailout = isBailout(); | |
| 690 | |
| 691 // Record that play was paused. We don't care if it was autoplay, | |
| 692 // play(), or the user manually started it. | |
| 693 recordAutoplayMetric(AnyPlaybackPaused); | |
| 694 if (bailout) | |
| 695 recordAutoplayMetric(AnyPlaybackBailout); | |
| 696 | |
| 697 // If this was a gestureless play, then record that separately. | |
| 698 // These cover attr and play() gestureless starts. | |
| 699 if (m_initialPlayWithoutUserGesture) { | |
| 700 m_initialPlayWithoutUserGesture = false; | |
| 701 | |
| 702 recordAutoplayMetric(AutoplayPaused); | |
| 703 | |
| 704 if (bailout) | |
| 705 recordAutoplayMetric(AutoplayBailout); | |
| 706 } | |
| 707 } | |
| 708 | |
| 709 void HTMLMediaElement::load() | 749 void HTMLMediaElement::load() |
| 710 { | 750 { |
| 711 WTF_LOG(Media, "HTMLMediaElement::load(%p)", this); | 751 WTF_LOG(Media, "HTMLMediaElement::load(%p)", this); |
| 712 | 752 |
| 713 recordMetricsIfPausing(); | 753 m_autoplayHelper->loadMethodCalled(); |
| 714 | |
| 715 if (UserGestureIndicator::processingUserGesture() && m_userGestureRequiredFo rPlay) { | |
| 716 recordAutoplayMetric(AutoplayEnabledThroughLoad); | |
| 717 m_userGestureRequiredForPlay = false; | |
| 718 // While usergesture-initiated load()s technically count as autoplayed, | |
| 719 // they don't feel like such to the users and hence we don't want to | |
| 720 // count them for the purposes of metrics. | |
| 721 m_autoplayMediaCounted = true; | |
| 722 } | |
| 723 | 754 |
| 724 m_ignorePreloadNone = true; | 755 m_ignorePreloadNone = true; |
| 725 invokeLoadAlgorithm(); | 756 invokeLoadAlgorithm(); |
| 726 } | 757 } |
| 727 | 758 |
| 728 // TODO(srirama.m): Currently m_ignorePreloadNone is reset before calling | 759 // TODO(srirama.m): Currently m_ignorePreloadNone is reset before calling |
| 729 // invokeLoadAlgorithm() in all places except load(). Move it inside here | 760 // invokeLoadAlgorithm() in all places except load(). Move it inside here |
| 730 // once microtask is implemented for "Await a stable state" step | 761 // once microtask is implemented for "Await a stable state" step |
| 731 // in resource selection algorithm. | 762 // in resource selection algorithm. |
| 732 void HTMLMediaElement::invokeLoadAlgorithm() | 763 void HTMLMediaElement::invokeLoadAlgorithm() |
| (...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 947 | 978 |
| 948 LocalFrame* frame = document().frame(); | 979 LocalFrame* frame = document().frame(); |
| 949 if (!frame) { | 980 if (!frame) { |
| 950 mediaLoadingFailed(WebMediaPlayer::NetworkStateFormatError); | 981 mediaLoadingFailed(WebMediaPlayer::NetworkStateFormatError); |
| 951 return; | 982 return; |
| 952 } | 983 } |
| 953 | 984 |
| 954 // The resource fetch algorithm | 985 // The resource fetch algorithm |
| 955 setNetworkState(NETWORK_LOADING); | 986 setNetworkState(NETWORK_LOADING); |
| 956 | 987 |
| 988 m_autoplayHelper->loadingStarted(); | |
| 989 | |
| 957 // Set m_currentSrc *before* changing to the cache url, the fact that we are loading from the app | 990 // Set m_currentSrc *before* changing to the cache url, the fact that we are loading from the app |
| 958 // cache is an internal detail not exposed through the media element API. | 991 // cache is an internal detail not exposed through the media element API. |
| 959 m_currentSrc = url; | 992 m_currentSrc = url; |
| 960 | 993 |
| 961 if (m_audioSourceNode) | 994 if (m_audioSourceNode) |
| 962 m_audioSourceNode->onCurrentSrcChanged(m_currentSrc); | 995 m_audioSourceNode->onCurrentSrcChanged(m_currentSrc); |
| 963 | 996 |
| 964 WTF_LOG(Media, "HTMLMediaElement::loadResource(%p) - m_currentSrc -> %s", th is, urlForLoggingMedia(m_currentSrc).utf8().data()); | 997 WTF_LOG(Media, "HTMLMediaElement::loadResource(%p) - m_currentSrc -> %s", th is, urlForLoggingMedia(m_currentSrc).utf8().data()); |
| 965 | 998 |
| 966 startProgressEventTimer(); | 999 startProgressEventTimer(); |
| 967 | 1000 |
| 968 // Reset display mode to force a recalculation of what to show because we ar e resetting the player. | 1001 // Reset display mode to force a recalculation of what to show because we ar e resetting the player. |
| 969 setDisplayMode(Unknown); | 1002 setDisplayMode(Unknown); |
| 970 | 1003 |
| 971 setPlayerPreload(); | 1004 setPlayerPreload(); |
| 972 | 1005 |
| 973 if (fastHasAttribute(mutedAttr)) | 1006 if (fastHasAttribute(mutedAttr)) |
| 974 m_muted = true; | 1007 m_muted = true; |
| 975 updateVolume(); | 1008 updateVolume(); |
| 976 | 1009 |
| 977 ASSERT(!m_mediaSource); | 1010 ASSERT(!m_mediaSource); |
| 978 | 1011 |
| 979 bool attemptLoad = true; | 1012 bool attemptLoad = true; |
| 980 | 1013 |
| 981 if (url.protocolIs(mediaSourceBlobProtocol)) { | 1014 if (url.protocolIs(mediaSourceBlobProtocol)) { |
| 982 if (isMediaStreamURL(url.getString())) { | 1015 if (isMediaStreamURL(url.getString())) { |
| 983 m_userGestureRequiredForPlay = false; | 1016 m_autoplayHelper->removeUserGestureRequirement(GesturelessPlaybackEn abledByStream); |
| 984 } else { | 1017 } else { |
| 985 m_mediaSource = HTMLMediaSource::lookup(url.getString()); | 1018 m_mediaSource = HTMLMediaSource::lookup(url.getString()); |
| 986 | 1019 |
| 987 if (m_mediaSource) { | 1020 if (m_mediaSource) { |
| 988 if (!m_mediaSource->attachToElement(this)) { | 1021 if (!m_mediaSource->attachToElement(this)) { |
| 989 // Forget our reference to the MediaSource, so we leave it a lone | 1022 // Forget our reference to the MediaSource, so we leave it a lone |
| 990 // while processing remainder of load failure. | 1023 // while processing remainder of load failure. |
| 991 m_mediaSource = nullptr; | 1024 m_mediaSource = nullptr; |
| 992 attemptLoad = false; | 1025 attemptLoad = false; |
| 993 } | 1026 } |
| (...skipping 568 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1562 if (oldState <= HAVE_CURRENT_DATA) { | 1595 if (oldState <= HAVE_CURRENT_DATA) { |
| 1563 scheduleEvent(EventTypeNames::canplay); | 1596 scheduleEvent(EventTypeNames::canplay); |
| 1564 if (isPotentiallyPlaying) | 1597 if (isPotentiallyPlaying) |
| 1565 scheduleNotifyPlaying(); | 1598 scheduleNotifyPlaying(); |
| 1566 } | 1599 } |
| 1567 | 1600 |
| 1568 // Check for autoplay, and record metrics about it if needed. | 1601 // Check for autoplay, and record metrics about it if needed. |
| 1569 if (shouldAutoplay(RecordMetricsBehavior::DoRecord)) { | 1602 if (shouldAutoplay(RecordMetricsBehavior::DoRecord)) { |
| 1570 // If the autoplay experiment says that it's okay to play now, | 1603 // If the autoplay experiment says that it's okay to play now, |
| 1571 // then don't require a user gesture. | 1604 // then don't require a user gesture. |
| 1572 m_autoplayHelper.becameReadyToPlay(); | 1605 m_autoplayHelper->becameReadyToPlay(); |
| 1573 | 1606 |
| 1574 if (!m_userGestureRequiredForPlay) { | 1607 if (!m_userGestureRequiredForPlay) { |
| 1575 m_paused = false; | 1608 m_paused = false; |
| 1576 invalidateCachedTime(); | 1609 invalidateCachedTime(); |
| 1577 scheduleEvent(EventTypeNames::play); | 1610 scheduleEvent(EventTypeNames::play); |
| 1578 scheduleNotifyPlaying(); | 1611 scheduleNotifyPlaying(); |
| 1579 m_autoplaying = false; | 1612 m_autoplaying = false; |
| 1580 } | 1613 } |
| 1581 } | 1614 } |
| 1582 | 1615 |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1696 | 1729 |
| 1697 m_lastSeekTime = time; | 1730 m_lastSeekTime = time; |
| 1698 m_sentEndEvent = false; | 1731 m_sentEndEvent = false; |
| 1699 | 1732 |
| 1700 // 10 - Queue a task to fire a simple event named seeking at the element. | 1733 // 10 - Queue a task to fire a simple event named seeking at the element. |
| 1701 scheduleEvent(EventTypeNames::seeking); | 1734 scheduleEvent(EventTypeNames::seeking); |
| 1702 | 1735 |
| 1703 // 11 - Set the current playback position to the given new playback position . | 1736 // 11 - Set the current playback position to the given new playback position . |
| 1704 webMediaPlayer()->seek(time); | 1737 webMediaPlayer()->seek(time); |
| 1705 | 1738 |
| 1706 m_initialPlayWithoutUserGesture = false; | |
| 1707 | |
| 1708 // 14-17 are handled, if necessary, when the engine signals a readystate cha nge or otherwise | 1739 // 14-17 are handled, if necessary, when the engine signals a readystate cha nge or otherwise |
| 1709 // satisfies seek completion and signals a time change. | 1740 // satisfies seek completion and signals a time change. |
| 1710 } | 1741 } |
| 1711 | 1742 |
| 1712 void HTMLMediaElement::finishSeek() | 1743 void HTMLMediaElement::finishSeek() |
| 1713 { | 1744 { |
| 1714 WTF_LOG(Media, "HTMLMediaElement::finishSeek(%p)", this); | 1745 WTF_LOG(Media, "HTMLMediaElement::finishSeek(%p)", this); |
| 1715 | 1746 |
| 1716 // 14 - Set the seeking IDL attribute to false. | 1747 // 14 - Set the seeking IDL attribute to false. |
| 1717 m_seeking = false; | 1748 m_seeking = false; |
| (...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1881 } | 1912 } |
| 1882 | 1913 |
| 1883 bool HTMLMediaElement::autoplay() const | 1914 bool HTMLMediaElement::autoplay() const |
| 1884 { | 1915 { |
| 1885 return fastHasAttribute(autoplayAttr); | 1916 return fastHasAttribute(autoplayAttr); |
| 1886 } | 1917 } |
| 1887 | 1918 |
| 1888 bool HTMLMediaElement::shouldAutoplay(const RecordMetricsBehavior recordMetrics) | 1919 bool HTMLMediaElement::shouldAutoplay(const RecordMetricsBehavior recordMetrics) |
| 1889 { | 1920 { |
| 1890 if (m_autoplaying && m_paused && autoplay()) { | 1921 if (m_autoplaying && m_paused && autoplay()) { |
| 1891 if (recordMetrics == RecordMetricsBehavior::DoRecord) | |
| 1892 autoplayMediaEncountered(); | |
| 1893 | |
| 1894 if (document().isSandboxed(SandboxAutomaticFeatures)) { | 1922 if (document().isSandboxed(SandboxAutomaticFeatures)) { |
| 1895 if (recordMetrics == RecordMetricsBehavior::DoRecord) | 1923 if (recordMetrics == RecordMetricsBehavior::DoRecord) |
| 1896 recordAutoplayMetric(AutoplayDisabledBySandbox); | 1924 m_autoplayHelper->recordSandboxFailure(); |
| 1897 return false; | 1925 return false; |
| 1898 } | 1926 } |
| 1899 | 1927 |
| 1900 return true; | 1928 return true; |
| 1901 } | 1929 } |
| 1902 | 1930 |
| 1903 return false; | 1931 return false; |
| 1904 } | 1932 } |
| 1905 | 1933 |
| 1906 String HTMLMediaElement::preload() const | 1934 String HTMLMediaElement::preload() const |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1988 ScriptPromise promise = resolver->promise(); | 2016 ScriptPromise promise = resolver->promise(); |
| 1989 | 2017 |
| 1990 m_playResolvers.append(resolver); | 2018 m_playResolvers.append(resolver); |
| 1991 return promise; | 2019 return promise; |
| 1992 } | 2020 } |
| 1993 | 2021 |
| 1994 Nullable<ExceptionCode> HTMLMediaElement::play() | 2022 Nullable<ExceptionCode> HTMLMediaElement::play() |
| 1995 { | 2023 { |
| 1996 WTF_LOG(Media, "HTMLMediaElement::play(%p)", this); | 2024 WTF_LOG(Media, "HTMLMediaElement::play(%p)", this); |
| 1997 | 2025 |
| 1998 m_autoplayHelper.playMethodCalled(); | 2026 m_autoplayHelper->playMethodCalled(); |
| 1999 | 2027 |
| 2000 if (!UserGestureIndicator::processingUserGesture()) { | 2028 if (!UserGestureIndicator::processingUserGesture()) { |
| 2001 autoplayMediaEncountered(); | |
| 2002 | |
| 2003 if (m_userGestureRequiredForPlay) { | 2029 if (m_userGestureRequiredForPlay) { |
| 2004 recordAutoplayMetric(PlayMethodFailed); | 2030 recordAutoplayMetric(PlayMethodFailed); |
| 2005 String message = ExceptionMessages::failedToExecute("play", "HTMLMed iaElement", "API can only be initiated by a user gesture."); | 2031 String message = ExceptionMessages::failedToExecute("play", "HTMLMed iaElement", "API can only be initiated by a user gesture."); |
| 2006 document().addConsoleMessage(ConsoleMessage::create(JSMessageSource, WarningMessageLevel, message)); | 2032 document().addConsoleMessage(ConsoleMessage::create(JSMessageSource, WarningMessageLevel, message)); |
| 2007 return NotAllowedError; | 2033 return NotAllowedError; |
| 2008 } | 2034 } |
| 2009 } else { | 2035 } else { |
| 2036 // We ask the helper to remove the gesture requirement for us, so that | |
| 2037 // it can record the reason. | |
| 2010 Platform::current()->recordAction(UserMetricsAction("Media_Play_WithGest ure")); | 2038 Platform::current()->recordAction(UserMetricsAction("Media_Play_WithGest ure")); |
| 2011 if (m_userGestureRequiredForPlay) { | 2039 m_autoplayHelper->removeUserGestureRequirement(GesturelessPlaybackEnable dByPlayMethod); |
| 2012 if (m_autoplayMediaCounted) | |
| 2013 recordAutoplayMetric(AutoplayManualStart); | |
| 2014 m_userGestureRequiredForPlay = false; | |
| 2015 } | |
| 2016 } | 2040 } |
| 2017 | 2041 |
| 2018 if (m_error && m_error->code() == MediaError::MEDIA_ERR_SRC_NOT_SUPPORTED) | 2042 if (m_error && m_error->code() == MediaError::MEDIA_ERR_SRC_NOT_SUPPORTED) |
| 2019 return NotSupportedError; | 2043 return NotSupportedError; |
| 2020 | 2044 |
| 2021 playInternal(); | 2045 playInternal(); |
| 2022 | 2046 |
| 2023 return nullptr; | 2047 return nullptr; |
| 2024 } | 2048 } |
| 2025 | 2049 |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 2055 } else if (m_readyState >= HAVE_FUTURE_DATA) { | 2079 } else if (m_readyState >= HAVE_FUTURE_DATA) { |
| 2056 scheduleResolvePlayPromises(); | 2080 scheduleResolvePlayPromises(); |
| 2057 } | 2081 } |
| 2058 | 2082 |
| 2059 m_autoplaying = false; | 2083 m_autoplaying = false; |
| 2060 | 2084 |
| 2061 setIgnorePreloadNone(); | 2085 setIgnorePreloadNone(); |
| 2062 updatePlayState(); | 2086 updatePlayState(); |
| 2063 } | 2087 } |
| 2064 | 2088 |
| 2065 void HTMLMediaElement::autoplayMediaEncountered() | |
| 2066 { | |
| 2067 if (!m_autoplayMediaCounted) { | |
| 2068 m_autoplayMediaCounted = true; | |
| 2069 recordAutoplayMetric(AutoplayMediaFound); | |
| 2070 | |
| 2071 if (!m_userGestureRequiredForPlay) | |
| 2072 m_initialPlayWithoutUserGesture = true; | |
| 2073 } | |
| 2074 } | |
| 2075 | |
| 2076 bool HTMLMediaElement::isBailout() const | |
| 2077 { | |
| 2078 // We count the user as having bailed-out on the video if they watched | |
| 2079 // less than one minute and less than 50% of it. | |
| 2080 const double playedTime = currentTime(); | |
| 2081 const double progress = playedTime / duration(); | |
| 2082 return (playedTime < 60) && (progress < 0.5); | |
| 2083 } | |
| 2084 | |
| 2085 void HTMLMediaElement::pause() | 2089 void HTMLMediaElement::pause() |
| 2086 { | 2090 { |
| 2087 WTF_LOG(Media, "HTMLMediaElement::pause(%p)", this); | 2091 WTF_LOG(Media, "HTMLMediaElement::pause(%p)", this); |
| 2088 | 2092 |
| 2089 // Only buffer aggressively on a user-initiated pause. Other types of pauses | 2093 // Only buffer aggressively on a user-initiated pause. Other types of pauses |
| 2090 // (which go directly to pauseInternal()) should not cause this behavior. | 2094 // (which go directly to pauseInternal()) should not cause this behavior. |
| 2091 if (webMediaPlayer() && UserGestureIndicator::processingUserGesture()) | 2095 if (webMediaPlayer() && UserGestureIndicator::processingUserGesture()) |
| 2092 webMediaPlayer()->setBufferingStrategy(WebMediaPlayer::BufferingStrategy ::Aggressive); | 2096 webMediaPlayer()->setBufferingStrategy(WebMediaPlayer::BufferingStrategy ::Aggressive); |
| 2093 | 2097 |
| 2094 pauseInternal(); | 2098 pauseInternal(); |
| 2095 } | 2099 } |
| 2096 | 2100 |
| 2097 void HTMLMediaElement::pauseInternal() | 2101 void HTMLMediaElement::pauseInternal() |
| 2098 { | 2102 { |
| 2099 WTF_LOG(Media, "HTMLMediaElement::pauseInternal(%p)", this); | 2103 WTF_LOG(Media, "HTMLMediaElement::pauseInternal(%p)", this); |
| 2100 | 2104 |
| 2101 if (m_networkState == NETWORK_EMPTY) | 2105 if (m_networkState == NETWORK_EMPTY) |
| 2102 invokeResourceSelectionAlgorithm(); | 2106 invokeResourceSelectionAlgorithm(); |
| 2103 | 2107 |
| 2104 m_autoplayHelper.pauseMethodCalled(); | 2108 m_autoplayHelper->pauseMethodCalled(); |
| 2105 | 2109 |
| 2106 m_autoplaying = false; | 2110 m_autoplaying = false; |
| 2107 | 2111 |
| 2108 if (!m_paused) { | 2112 if (!m_paused) { |
| 2109 recordMetricsIfPausing(); | |
| 2110 | |
| 2111 m_paused = true; | 2113 m_paused = true; |
| 2112 scheduleTimeupdateEvent(false); | 2114 scheduleTimeupdateEvent(false); |
| 2113 scheduleEvent(EventTypeNames::pause); | 2115 scheduleEvent(EventTypeNames::pause); |
| 2114 scheduleRejectPlayPromises(AbortError); | 2116 scheduleRejectPlayPromises(AbortError); |
| 2115 } | 2117 } |
| 2116 | 2118 |
| 2117 updatePlayState(); | 2119 updatePlayState(); |
| 2118 } | 2120 } |
| 2119 | 2121 |
| 2120 void HTMLMediaElement::requestRemotePlayback() | 2122 void HTMLMediaElement::requestRemotePlayback() |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2210 | 2212 |
| 2211 void HTMLMediaElement::setMuted(bool muted) | 2213 void HTMLMediaElement::setMuted(bool muted) |
| 2212 { | 2214 { |
| 2213 WTF_LOG(Media, "HTMLMediaElement::setMuted(%p, %s)", this, boolString(muted) ); | 2215 WTF_LOG(Media, "HTMLMediaElement::setMuted(%p, %s)", this, boolString(muted) ); |
| 2214 | 2216 |
| 2215 if (m_muted == muted) | 2217 if (m_muted == muted) |
| 2216 return; | 2218 return; |
| 2217 | 2219 |
| 2218 m_muted = muted; | 2220 m_muted = muted; |
| 2219 | 2221 |
| 2220 m_autoplayHelper.mutedChanged(); | 2222 m_autoplayHelper->mutedChanged(); |
| 2221 | 2223 |
| 2222 updateVolume(); | 2224 updateVolume(); |
| 2223 | 2225 |
| 2224 if (muted) | 2226 if (muted) |
| 2225 Platform::current()->recordAction(UserMetricsAction("Media_Playback_Mute _On")); | 2227 Platform::current()->recordAction(UserMetricsAction("Media_Playback_Mute _On")); |
| 2226 else | 2228 else |
| 2227 Platform::current()->recordAction(UserMetricsAction("Media_Playback_Mute _Off")); | 2229 Platform::current()->recordAction(UserMetricsAction("Media_Playback_Mute _Off")); |
| 2228 | 2230 |
| 2229 scheduleEvent(EventTypeNames::volumechange); | 2231 scheduleEvent(EventTypeNames::volumechange); |
| 2230 } | 2232 } |
| (...skipping 603 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2834 if (!m_paused) { | 2836 if (!m_paused) { |
| 2835 // changes paused to true and fires a simple event named pause a t the media element. | 2837 // changes paused to true and fires a simple event named pause a t the media element. |
| 2836 m_paused = true; | 2838 m_paused = true; |
| 2837 scheduleEvent(EventTypeNames::pause); | 2839 scheduleEvent(EventTypeNames::pause); |
| 2838 } | 2840 } |
| 2839 // Queue a task to fire a simple event named ended at the media elem ent. | 2841 // Queue a task to fire a simple event named ended at the media elem ent. |
| 2840 if (!m_sentEndEvent) { | 2842 if (!m_sentEndEvent) { |
| 2841 m_sentEndEvent = true; | 2843 m_sentEndEvent = true; |
| 2842 scheduleEvent(EventTypeNames::ended); | 2844 scheduleEvent(EventTypeNames::ended); |
| 2843 } | 2845 } |
| 2844 recordMetricsIfPausing(); | |
| 2845 Platform::current()->recordAction(UserMetricsAction("Media_Playback_ Ended")); | 2846 Platform::current()->recordAction(UserMetricsAction("Media_Playback_ Ended")); |
| 2846 } | 2847 } |
| 2847 } else { | 2848 } else { |
| 2848 m_sentEndEvent = false; | 2849 m_sentEndEvent = false; |
| 2849 } | 2850 } |
| 2850 | 2851 |
| 2851 updatePlayState(); | 2852 updatePlayState(); |
| 2852 } | 2853 } |
| 2853 | 2854 |
| 2854 void HTMLMediaElement::durationChanged() | 2855 void HTMLMediaElement::durationChanged() |
| (...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3044 invalidateCachedTime(); | 3045 invalidateCachedTime(); |
| 3045 | 3046 |
| 3046 if (!isPlaying) { | 3047 if (!isPlaying) { |
| 3047 // Set rate, muted before calling play in case they were set before the media engine was setup. | 3048 // Set rate, muted before calling play in case they were set before the media engine was setup. |
| 3048 // The media engine should just stash the rate and muted values sinc e it isn't already playing. | 3049 // The media engine should just stash the rate and muted values sinc e it isn't already playing. |
| 3049 webMediaPlayer()->setRate(playbackRate()); | 3050 webMediaPlayer()->setRate(playbackRate()); |
| 3050 updateVolume(); | 3051 updateVolume(); |
| 3051 webMediaPlayer()->play(); | 3052 webMediaPlayer()->play(); |
| 3052 Platform::current()->recordAction( | 3053 Platform::current()->recordAction( |
| 3053 UserMetricsAction("Media_Playback_Started")); | 3054 UserMetricsAction("Media_Playback_Started")); |
| 3055 m_autoplayHelper->playbackStarted(); | |
| 3054 } | 3056 } |
| 3055 | 3057 |
| 3056 if (mediaControls()) | 3058 if (mediaControls()) |
| 3057 mediaControls()->playbackStarted(); | 3059 mediaControls()->playbackStarted(); |
| 3058 startPlaybackProgressTimer(); | 3060 startPlaybackProgressTimer(); |
| 3059 m_playing = true; | 3061 m_playing = true; |
| 3060 recordAutoplayMetric(AnyPlaybackStarted); | |
| 3061 | 3062 |
| 3062 } else { // Should not be playing right now | 3063 } else { // Should not be playing right now |
| 3063 if (isPlaying) { | 3064 if (isPlaying) { |
| 3064 webMediaPlayer()->pause(); | 3065 webMediaPlayer()->pause(); |
| 3065 Platform::current()->recordAction(UserMetricsAction("Media_Paused")) ; | 3066 Platform::current()->recordAction(UserMetricsAction("Media_Paused")) ; |
| 3067 m_autoplayHelper->playbackStopped(); | |
| 3066 } | 3068 } |
| 3067 | 3069 |
| 3068 refreshCachedTime(); | 3070 refreshCachedTime(); |
| 3069 | 3071 |
| 3070 m_playbackProgressTimer.stop(); | 3072 m_playbackProgressTimer.stop(); |
| 3071 m_playing = false; | 3073 m_playing = false; |
| 3072 double time = currentTime(); | 3074 double time = currentTime(); |
| 3073 if (time > m_lastSeekTime) | 3075 if (time > m_lastSeekTime) |
| 3074 addPlayedRange(m_lastSeekTime, time); | 3076 addPlayedRange(m_lastSeekTime, time); |
| 3075 | 3077 |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3122 mediaControls()->refreshCastButtonVisibilityWithoutUpdate(); | 3124 mediaControls()->refreshCastButtonVisibilityWithoutUpdate(); |
| 3123 | 3125 |
| 3124 if (layoutObject()) | 3126 if (layoutObject()) |
| 3125 layoutObject()->setShouldDoFullPaintInvalidation(); | 3127 layoutObject()->setShouldDoFullPaintInvalidation(); |
| 3126 } | 3128 } |
| 3127 | 3129 |
| 3128 void HTMLMediaElement::stop() | 3130 void HTMLMediaElement::stop() |
| 3129 { | 3131 { |
| 3130 WTF_LOG(Media, "HTMLMediaElement::stop(%p)", this); | 3132 WTF_LOG(Media, "HTMLMediaElement::stop(%p)", this); |
| 3131 | 3133 |
| 3132 recordMetricsIfPausing(); | |
| 3133 | |
| 3134 // Close the async event queue so that no events are enqueued. | 3134 // Close the async event queue so that no events are enqueued. |
| 3135 cancelPendingEventsAndCallbacks(); | 3135 cancelPendingEventsAndCallbacks(); |
| 3136 m_asyncEventQueue->close(); | 3136 m_asyncEventQueue->close(); |
| 3137 | 3137 |
| 3138 // Clear everything in the Media Element | 3138 // Clear everything in the Media Element |
| 3139 clearMediaPlayer(); | 3139 clearMediaPlayer(); |
| 3140 m_readyState = HAVE_NOTHING; | 3140 m_readyState = HAVE_NOTHING; |
| 3141 m_readyStateMaximum = HAVE_NOTHING; | 3141 m_readyStateMaximum = HAVE_NOTHING; |
| 3142 setNetworkState(NETWORK_EMPTY); | 3142 setNetworkState(NETWORK_EMPTY); |
| 3143 setShouldDelayLoadEvent(false); | 3143 setShouldDelayLoadEvent(false); |
| (...skipping 454 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3598 visitor->trace(m_currentSourceNode); | 3598 visitor->trace(m_currentSourceNode); |
| 3599 visitor->trace(m_nextChildNodeToConsider); | 3599 visitor->trace(m_nextChildNodeToConsider); |
| 3600 visitor->trace(m_mediaSource); | 3600 visitor->trace(m_mediaSource); |
| 3601 visitor->trace(m_audioTracks); | 3601 visitor->trace(m_audioTracks); |
| 3602 visitor->trace(m_videoTracks); | 3602 visitor->trace(m_videoTracks); |
| 3603 visitor->trace(m_cueTimeline); | 3603 visitor->trace(m_cueTimeline); |
| 3604 visitor->trace(m_textTracks); | 3604 visitor->trace(m_textTracks); |
| 3605 visitor->trace(m_textTracksWhenResourceSelectionBegan); | 3605 visitor->trace(m_textTracksWhenResourceSelectionBegan); |
| 3606 visitor->trace(m_playResolvers); | 3606 visitor->trace(m_playResolvers); |
| 3607 visitor->trace(m_audioSourceProvider); | 3607 visitor->trace(m_audioSourceProvider); |
| 3608 visitor->trace(m_autoplayHelperClient); | |
| 3609 visitor->trace(m_autoplayHelper); | |
| 3608 visitor->template registerWeakMembers<HTMLMediaElement, &HTMLMediaElement::c learWeakMembers>(this); | 3610 visitor->template registerWeakMembers<HTMLMediaElement, &HTMLMediaElement::c learWeakMembers>(this); |
| 3609 visitor->trace(m_autoplayHelper); | |
| 3610 HeapSupplementable<HTMLMediaElement>::trace(visitor); | 3611 HeapSupplementable<HTMLMediaElement>::trace(visitor); |
| 3611 #endif | 3612 #endif |
| 3612 HTMLElement::trace(visitor); | 3613 HTMLElement::trace(visitor); |
| 3613 ActiveDOMObject::trace(visitor); | 3614 ActiveDOMObject::trace(visitor); |
| 3614 } | 3615 } |
| 3615 | 3616 |
| 3616 void HTMLMediaElement::createPlaceholderTracksIfNecessary() | 3617 void HTMLMediaElement::createPlaceholderTracksIfNecessary() |
| 3617 { | 3618 { |
| 3618 if (!RuntimeEnabledFeatures::audioVideoTracksEnabled()) | 3619 if (!RuntimeEnabledFeatures::audioVideoTracksEnabled()) |
| 3619 return; | 3620 return; |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 3644 bool HTMLMediaElement::isUserGestureRequiredForPlay() const | 3645 bool HTMLMediaElement::isUserGestureRequiredForPlay() const |
| 3645 { | 3646 { |
| 3646 return m_userGestureRequiredForPlay; | 3647 return m_userGestureRequiredForPlay; |
| 3647 } | 3648 } |
| 3648 | 3649 |
| 3649 void HTMLMediaElement::removeUserGestureRequirement() | 3650 void HTMLMediaElement::removeUserGestureRequirement() |
| 3650 { | 3651 { |
| 3651 m_userGestureRequiredForPlay = false; | 3652 m_userGestureRequiredForPlay = false; |
| 3652 } | 3653 } |
| 3653 | 3654 |
| 3654 void HTMLMediaElement::setInitialPlayWithoutUserGestures(bool value) | |
| 3655 { | |
| 3656 m_initialPlayWithoutUserGesture = value; | |
| 3657 } | |
| 3658 | |
| 3659 void HTMLMediaElement::setNetworkState(NetworkState state) | 3655 void HTMLMediaElement::setNetworkState(NetworkState state) |
| 3660 { | 3656 { |
| 3661 if (m_networkState != state) { | 3657 if (m_networkState != state) { |
| 3662 m_networkState = state; | 3658 m_networkState = state; |
| 3663 if (MediaControls* controls = mediaControls()) | 3659 if (MediaControls* controls = mediaControls()) |
| 3664 controls->networkStateChanged(); | 3660 controls->networkStateChanged(); |
| 3665 } | 3661 } |
| 3666 } | 3662 } |
| 3667 | 3663 |
| 3668 void HTMLMediaElement::notifyPositionMayHaveChanged(const IntRect& visibleRect) | 3664 void HTMLMediaElement::notifyPositionMayHaveChanged(const IntRect& visibleRect) |
| 3669 { | 3665 { |
| 3670 m_autoplayHelper.positionChanged(visibleRect); | 3666 m_autoplayHelper->positionChanged(visibleRect); |
| 3671 } | 3667 } |
| 3672 | 3668 |
| 3673 void HTMLMediaElement::updatePositionNotificationRegistration() | 3669 void HTMLMediaElement::updatePositionNotificationRegistration() |
| 3674 { | 3670 { |
| 3675 m_autoplayHelper.updatePositionNotificationRegistration(); | 3671 m_autoplayHelper->updatePositionNotificationRegistration(); |
| 3676 } | 3672 } |
| 3677 | 3673 |
| 3678 // TODO(liberato): remove once autoplay gesture override experiment concludes. | 3674 // TODO(liberato): remove once autoplay gesture override experiment concludes. |
| 3679 void HTMLMediaElement::triggerAutoplayViewportCheckForTesting() | 3675 void HTMLMediaElement::triggerAutoplayViewportCheckForTesting() |
| 3680 { | 3676 { |
| 3681 m_autoplayHelper.triggerAutoplayViewportCheckForTesting(); | 3677 if (FrameView* view = document().view()) |
| 3678 m_autoplayHelper->positionChanged(view->rootFrameToContents(view->comput eVisibleArea())); | |
| 3679 m_autoplayHelper->triggerAutoplayViewportCheckForTesting(); | |
| 3682 } | 3680 } |
| 3683 | 3681 |
| 3684 void HTMLMediaElement::scheduleResolvePlayPromises() | 3682 void HTMLMediaElement::scheduleResolvePlayPromises() |
| 3685 { | 3683 { |
| 3686 // Per spec, if there are two tasks in the queue, the first task will remove | 3684 // Per spec, if there are two tasks in the queue, the first task will remove |
| 3687 // all the pending promises making the second task useless unless a promise | 3685 // all the pending promises making the second task useless unless a promise |
| 3688 // can be added between the first and second task being run which is not | 3686 // can be added between the first and second task being run which is not |
| 3689 // possible at the moment. | 3687 // possible at the moment. |
| 3690 if (m_playPromiseResolveTask->isPending()) | 3688 if (m_playPromiseResolveTask->isPending()) |
| 3691 return; | 3689 return; |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3814 DEFINE_TRACE(HTMLMediaElement::AudioClientImpl) | 3812 DEFINE_TRACE(HTMLMediaElement::AudioClientImpl) |
| 3815 { | 3813 { |
| 3816 visitor->trace(m_client); | 3814 visitor->trace(m_client); |
| 3817 } | 3815 } |
| 3818 | 3816 |
| 3819 DEFINE_TRACE(HTMLMediaElement::AudioSourceProviderImpl) | 3817 DEFINE_TRACE(HTMLMediaElement::AudioSourceProviderImpl) |
| 3820 { | 3818 { |
| 3821 visitor->trace(m_client); | 3819 visitor->trace(m_client); |
| 3822 } | 3820 } |
| 3823 | 3821 |
| 3822 HTMLMediaElement::AutoplayHelperClientImpl::~AutoplayHelperClientImpl() | |
| 3823 { | |
| 3824 } | |
| 3825 | |
| 3826 bool HTMLMediaElement::AutoplayHelperClientImpl::isLegacyViewportType() | |
| 3827 { | |
| 3828 return m_element->document().viewportDescription().isLegacyViewportType(); | |
| 3829 } | |
| 3830 | |
| 3831 PageVisibilityState HTMLMediaElement::AutoplayHelperClientImpl::pageVisibilitySt ate() const | |
| 3832 { | |
| 3833 return m_element->document().pageVisibilityState(); | |
| 3834 } | |
| 3835 | |
| 3836 String HTMLMediaElement::AutoplayHelperClientImpl::autoplayExperimentMode() cons t | |
| 3837 { | |
| 3838 String mode; | |
| 3839 if (m_element->document().settings()) | |
| 3840 mode = m_element->document().settings()->autoplayExperimentMode(); | |
| 3841 | |
| 3842 return mode; | |
| 3843 } | |
| 3844 | |
| 3845 void HTMLMediaElement::AutoplayHelperClientImpl::setRequestPositionUpdates(bool request) | |
| 3846 { | |
| 3847 if (LayoutObject* layoutObject = m_element->layoutObject()) { | |
| 3848 LayoutMediaItem layoutMediaItem = LayoutMediaItem(toLayoutMedia(layoutOb ject)); | |
| 3849 layoutMediaItem.setRequestPositionUpdates(request); | |
| 3850 } | |
| 3851 } | |
| 3852 | |
| 3853 IntRect HTMLMediaElement::AutoplayHelperClientImpl::absoluteBoundingBoxRect() co nst | |
| 3854 { | |
| 3855 IntRect result; | |
| 3856 if (LayoutObject* object = m_element->layoutObject()) | |
| 3857 result = object->absoluteBoundingBoxRect(); | |
| 3858 return result; | |
| 3859 } | |
| 3860 | |
| 3824 } // namespace blink | 3861 } // namespace blink |
| OLD | NEW |