Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(13)

Side by Side Diff: third_party/WebKit/Source/core/html/HTMLMediaElement.cpp

Issue 1470153004: Autoplay experiment metric fixes and additions. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: simplified paused logic Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/core/html/HTMLMediaElement.h ('k') | tools/metrics/histograms/histograms.xml » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698