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

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: ...because tests. Created 4 years, 8 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 189 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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