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