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

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

Issue 2510353004: Deprecating AutoplayExperimentHelper (Closed)
Patch Set: rebased Created 4 years 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 2 * Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012, 2013 Apple Inc. All rights
3 * reserved. 3 * reserved.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions 6 * modification, are permitted provided that the following conditions
7 * are met: 7 * are met:
8 * 1. Redistributions of source code must retain the above copyright 8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
58 #include "core/html/track/AudioTrack.h" 58 #include "core/html/track/AudioTrack.h"
59 #include "core/html/track/AudioTrackList.h" 59 #include "core/html/track/AudioTrackList.h"
60 #include "core/html/track/AutomaticTrackSelection.h" 60 #include "core/html/track/AutomaticTrackSelection.h"
61 #include "core/html/track/CueTimeline.h" 61 #include "core/html/track/CueTimeline.h"
62 #include "core/html/track/InbandTextTrack.h" 62 #include "core/html/track/InbandTextTrack.h"
63 #include "core/html/track/TextTrackContainer.h" 63 #include "core/html/track/TextTrackContainer.h"
64 #include "core/html/track/TextTrackList.h" 64 #include "core/html/track/TextTrackList.h"
65 #include "core/html/track/VideoTrack.h" 65 #include "core/html/track/VideoTrack.h"
66 #include "core/html/track/VideoTrackList.h" 66 #include "core/html/track/VideoTrackList.h"
67 #include "core/inspector/ConsoleMessage.h" 67 #include "core/inspector/ConsoleMessage.h"
68 #include "core/layout/api/LayoutMediaItem.h" 68 #include "core/layout/LayoutMedia.h"
69 #include "core/layout/api/LayoutViewItem.h" 69 #include "core/layout/api/LayoutViewItem.h"
70 #include "core/layout/compositing/PaintLayerCompositor.h" 70 #include "core/layout/compositing/PaintLayerCompositor.h"
71 #include "core/loader/FrameLoader.h" 71 #include "core/loader/FrameLoader.h"
72 #include "core/loader/FrameLoaderClient.h" 72 #include "core/loader/FrameLoaderClient.h"
73 #include "core/page/ChromeClient.h" 73 #include "core/page/ChromeClient.h"
74 #include "core/page/NetworkStateNotifier.h" 74 #include "core/page/NetworkStateNotifier.h"
75 #include "platform/ContentType.h" 75 #include "platform/ContentType.h"
76 #include "platform/Histogram.h" 76 #include "platform/Histogram.h"
77 #include "platform/LayoutTestSupport.h" 77 #include "platform/LayoutTestSupport.h"
78 #include "platform/MIMETypeFromURL.h" 78 #include "platform/MIMETypeFromURL.h"
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after
279 case WebMediaPlayer::PreloadAuto: 279 case WebMediaPlayer::PreloadAuto:
280 return "auto"; 280 return "auto";
281 } 281 }
282 282
283 NOTREACHED(); 283 NOTREACHED();
284 return String(); 284 return String();
285 } 285 }
286 286
287 } // anonymous namespace 287 } // anonymous namespace
288 288
289 class HTMLMediaElement::AutoplayHelperClientImpl
290 : public AutoplayExperimentHelper::Client {
291 public:
292 static AutoplayHelperClientImpl* create(HTMLMediaElement* element) {
293 return new AutoplayHelperClientImpl(element);
294 }
295
296 virtual ~AutoplayHelperClientImpl();
297
298 using RecordMetricsBehavior = HTMLMediaElement::RecordMetricsBehavior;
299
300 double currentTime() const override { return m_element->currentTime(); }
301 double duration() const override { return m_element->duration(); }
302 bool paused() const override { return m_element->paused(); }
303 bool ended() const override { return m_element->ended(); }
304 bool muted() const override { return m_element->muted(); }
305 void setMuted(bool muted) override { m_element->setMuted(muted); }
306 void playInternal() override { m_element->playInternal(); }
307 void pauseInternal() override { m_element->pauseInternal(); }
308 bool isLockedPendingUserGesture() const override {
309 return m_element->isLockedPendingUserGesture();
310 }
311 void unlockUserGesture() override { m_element->unlockUserGesture(); }
312 void recordAutoplayMetric(AutoplayMetrics metric) override {
313 m_element->recordAutoplayMetric(metric);
314 }
315 bool shouldAutoplay() override {
316 return m_element->shouldAutoplay(RecordMetricsBehavior::DoNotRecord);
317 }
318 bool isHTMLVideoElement() const override {
319 return m_element->isHTMLVideoElement();
320 }
321 bool isHTMLAudioElement() const override {
322 return m_element->isHTMLAudioElement();
323 }
324
325 // Document
326 bool isLegacyViewportType() override;
327 PageVisibilityState pageVisibilityState() const override;
328 String autoplayExperimentMode() const override;
329
330 // Frame
331 bool isCrossOrigin() const override {
332 const LocalFrame* frame = m_element->document().frame();
333 return frame && frame->isCrossOriginSubframe();
334 }
335
336 bool isAutoplayAllowedPerSettings() const override;
337
338 // LayoutObject
339 void setRequestPositionUpdates(bool) override;
340 IntRect absoluteBoundingBoxRect() const override;
341
342 DEFINE_INLINE_VIRTUAL_TRACE() {
343 visitor->trace(m_element);
344 Client::trace(visitor);
345 }
346
347 private:
348 AutoplayHelperClientImpl(HTMLMediaElement* element) : m_element(element) {}
349
350 Member<HTMLMediaElement> m_element;
351 };
352
353 void HTMLMediaElement::recordAutoplayMetric(AutoplayMetrics metric) {
354 DEFINE_STATIC_LOCAL(EnumerationHistogram, autoplayHistogram,
355 ("Blink.MediaElement.Autoplay", NumberOfAutoplayMetrics));
356 autoplayHistogram.count(metric);
357 }
358
359 MIMETypeRegistry::SupportsType HTMLMediaElement::supportsType( 289 MIMETypeRegistry::SupportsType HTMLMediaElement::supportsType(
360 const ContentType& contentType) { 290 const ContentType& contentType) {
361 DEFINE_STATIC_LOCAL(const String, codecs, ("codecs")); 291 DEFINE_STATIC_LOCAL(const String, codecs, ("codecs"));
362 292
363 String type = contentType.type().lower(); 293 String type = contentType.type().lower();
364 // The codecs string is not lower-cased because MP4 values are case sensitive 294 // The codecs string is not lower-cased because MP4 values are case sensitive
365 // per http://tools.ietf.org/html/rfc4281#page-7. 295 // per http://tools.ietf.org/html/rfc4281#page-7.
366 String typeCodecs = contentType.parameter(codecs); 296 String typeCodecs = contentType.parameter(codecs);
367 297
368 if (type.isEmpty()) 298 if (type.isEmpty())
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
445 m_textTracksVisible(false), 375 m_textTracksVisible(false),
446 m_shouldPerformAutomaticTrackSelection(true), 376 m_shouldPerformAutomaticTrackSelection(true),
447 m_tracksAreReady(true), 377 m_tracksAreReady(true),
448 m_processingPreferenceChange(false), 378 m_processingPreferenceChange(false),
449 m_playingRemotely(false), 379 m_playingRemotely(false),
450 m_inOverlayFullscreenVideo(false), 380 m_inOverlayFullscreenVideo(false),
451 m_audioTracks(this, AudioTrackList::create(*this)), 381 m_audioTracks(this, AudioTrackList::create(*this)),
452 m_videoTracks(this, VideoTrackList::create(*this)), 382 m_videoTracks(this, VideoTrackList::create(*this)),
453 m_textTracks(this, nullptr), 383 m_textTracks(this, nullptr),
454 m_audioSourceNode(nullptr), 384 m_audioSourceNode(nullptr),
455 m_autoplayHelperClient(AutoplayHelperClientImpl::create(this)),
456 m_autoplayHelper(
457 AutoplayExperimentHelper::create(m_autoplayHelperClient.get())),
458 m_autoplayUmaHelper(AutoplayUmaHelper::create(this)), 385 m_autoplayUmaHelper(AutoplayUmaHelper::create(this)),
459 m_remotePlaybackClient(nullptr), 386 m_remotePlaybackClient(nullptr),
460 m_autoplayVisibilityObserver(nullptr) { 387 m_autoplayVisibilityObserver(nullptr) {
461 ThreadState::current()->registerPreFinalizer(this); 388 ThreadState::current()->registerPreFinalizer(this);
462 389
463 BLINK_MEDIA_LOG << "HTMLMediaElement(" << (void*)this << ")"; 390 BLINK_MEDIA_LOG << "HTMLMediaElement(" << (void*)this << ")";
464 391
465 // If any experiment is enabled, then we want to enable a user gesture by 392 // If any experiment is enabled, then we want to enable a user gesture by
466 // default, otherwise the experiment does nothing. 393 // default, otherwise the experiment does nothing.
467 if ((document.settings() && 394 if ((document.settings() &&
468 document.settings()->mediaPlaybackRequiresUserGesture()) || 395 document.settings()->mediaPlaybackRequiresUserGesture())) {
469 m_autoplayHelper->isExperimentEnabled()) {
470 m_lockedPendingUserGesture = true; 396 m_lockedPendingUserGesture = true;
471 } 397 }
472 398
473 LocalFrame* frame = document.frame(); 399 LocalFrame* frame = document.frame();
474 if (frame) { 400 if (frame) {
475 m_remotePlaybackClient = 401 m_remotePlaybackClient =
476 frame->loader().client()->createWebRemotePlaybackClient(*this); 402 frame->loader().client()->createWebRemotePlaybackClient(*this);
477 } 403 }
478 404
479 setHasCustomStyleCallbacks(); 405 setHasCustomStyleCallbacks();
(...skipping 26 matching lines...) Expand all
506 } 432 }
507 433
508 void HTMLMediaElement::didMoveToNewDocument(Document& oldDocument) { 434 void HTMLMediaElement::didMoveToNewDocument(Document& oldDocument) {
509 BLINK_MEDIA_LOG << "didMoveToNewDocument(" << (void*)this << ")"; 435 BLINK_MEDIA_LOG << "didMoveToNewDocument(" << (void*)this << ")";
510 436
511 m_autoplayUmaHelper->didMoveToNewDocument(oldDocument); 437 m_autoplayUmaHelper->didMoveToNewDocument(oldDocument);
512 // If any experiment is enabled, then we want to enable a user gesture by 438 // If any experiment is enabled, then we want to enable a user gesture by
513 // default, otherwise the experiment does nothing. 439 // default, otherwise the experiment does nothing.
514 bool oldDocumentRequiresUserGesture = 440 bool oldDocumentRequiresUserGesture =
515 (oldDocument.settings() && 441 (oldDocument.settings() &&
516 oldDocument.settings()->mediaPlaybackRequiresUserGesture()) || 442 oldDocument.settings()->mediaPlaybackRequiresUserGesture());
517 m_autoplayHelper->isExperimentEnabled();
518 bool newDocumentRequiresUserGesture = 443 bool newDocumentRequiresUserGesture =
519 (document().settings() && 444 (document().settings() &&
520 document().settings()->mediaPlaybackRequiresUserGesture()) || 445 document().settings()->mediaPlaybackRequiresUserGesture());
521 m_autoplayHelper->isExperimentEnabled();
522 if (newDocumentRequiresUserGesture && !oldDocumentRequiresUserGesture) { 446 if (newDocumentRequiresUserGesture && !oldDocumentRequiresUserGesture) {
523 m_lockedPendingUserGesture = true; 447 m_lockedPendingUserGesture = true;
524 } 448 }
525 449
526 if (m_shouldDelayLoadEvent) { 450 if (m_shouldDelayLoadEvent) {
527 document().incrementLoadEventDelayCount(); 451 document().incrementLoadEventDelayCount();
528 // Note: Keeping the load event delay count increment on oldDocument that 452 // Note: Keeping the load event delay count increment on oldDocument that
529 // was added when m_shouldDelayLoadEvent was set so that destruction of 453 // was added when m_shouldDelayLoadEvent was set so that destruction of
530 // m_webMediaPlayer can not cause load event dispatching in oldDocument. 454 // m_webMediaPlayer can not cause load event dispatching in oldDocument.
531 } else { 455 } else {
(...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after
741 665
742 BLINK_MEDIA_LOG << "canPlayType(" << (void*)this << ", " << mimeType 666 BLINK_MEDIA_LOG << "canPlayType(" << (void*)this << ", " << mimeType
743 << ") -> " << canPlay; 667 << ") -> " << canPlay;
744 668
745 return canPlay; 669 return canPlay;
746 } 670 }
747 671
748 void HTMLMediaElement::load() { 672 void HTMLMediaElement::load() {
749 BLINK_MEDIA_LOG << "load(" << (void*)this << ")"; 673 BLINK_MEDIA_LOG << "load(" << (void*)this << ")";
750 674
751 m_autoplayHelper->loadMethodCalled(); 675 if (isLockedPendingUserGesture() &&
676 UserGestureIndicator::utilizeUserGesture()) {
677 unlockUserGesture();
678 }
752 679
753 m_ignorePreloadNone = true; 680 m_ignorePreloadNone = true;
754 invokeLoadAlgorithm(); 681 invokeLoadAlgorithm();
755 } 682 }
756 683
757 // TODO(srirama.m): Currently m_ignorePreloadNone is reset before calling 684 // TODO(srirama.m): Currently m_ignorePreloadNone is reset before calling
758 // invokeLoadAlgorithm() in all places except load(). Move it inside here 685 // invokeLoadAlgorithm() in all places except load(). Move it inside here
759 // once microtask is implemented for "Await a stable state" step 686 // once microtask is implemented for "Await a stable state" step
760 // in resource selection algorithm. 687 // in resource selection algorithm.
761 void HTMLMediaElement::invokeLoadAlgorithm() { 688 void HTMLMediaElement::invokeLoadAlgorithm() {
(...skipping 300 matching lines...) Expand 10 before | Expand all | Expand 10 after
1062 989
1063 LocalFrame* frame = document().frame(); 990 LocalFrame* frame = document().frame();
1064 if (!frame) { 991 if (!frame) {
1065 mediaLoadingFailed(WebMediaPlayer::NetworkStateFormatError); 992 mediaLoadingFailed(WebMediaPlayer::NetworkStateFormatError);
1066 return; 993 return;
1067 } 994 }
1068 995
1069 // The resource fetch algorithm 996 // The resource fetch algorithm
1070 setNetworkState(kNetworkLoading); 997 setNetworkState(kNetworkLoading);
1071 998
1072 m_autoplayHelper->loadingStarted();
1073
1074 // Set m_currentSrc *before* changing to the cache url, the fact that we are 999 // Set m_currentSrc *before* changing to the cache url, the fact that we are
1075 // loading from the app cache is an internal detail not exposed through the 1000 // loading from the app cache is an internal detail not exposed through the
1076 // media element API. 1001 // media element API.
1077 m_currentSrc = url; 1002 m_currentSrc = url;
1078 1003
1079 if (m_audioSourceNode) 1004 if (m_audioSourceNode)
1080 m_audioSourceNode->onCurrentSrcChanged(m_currentSrc); 1005 m_audioSourceNode->onCurrentSrcChanged(m_currentSrc);
1081 1006
1082 BLINK_MEDIA_LOG << "loadResource(" << (void*)this << ") - m_currentSrc -> " 1007 BLINK_MEDIA_LOG << "loadResource(" << (void*)this << ") - m_currentSrc -> "
1083 << urlForLoggingMedia(m_currentSrc); 1008 << urlForLoggingMedia(m_currentSrc);
(...skipping 641 matching lines...) Expand 10 before | Expand all | Expand 10 after
1725 1650
1726 if (m_readyState == kHaveEnoughData && oldState < kHaveEnoughData && 1651 if (m_readyState == kHaveEnoughData && oldState < kHaveEnoughData &&
1727 tracksAreReady) { 1652 tracksAreReady) {
1728 if (oldState <= kHaveCurrentData) { 1653 if (oldState <= kHaveCurrentData) {
1729 scheduleEvent(EventTypeNames::canplay); 1654 scheduleEvent(EventTypeNames::canplay);
1730 if (isPotentiallyPlaying) 1655 if (isPotentiallyPlaying)
1731 scheduleNotifyPlaying(); 1656 scheduleNotifyPlaying();
1732 } 1657 }
1733 1658
1734 // Check for autoplay, and record metrics about it if needed. 1659 // Check for autoplay, and record metrics about it if needed.
1735 if (shouldAutoplay(RecordMetricsBehavior::DoRecord)) { 1660 if (shouldAutoplay()) {
1736 m_autoplayUmaHelper->onAutoplayInitiated(AutoplaySource::Attribute); 1661 m_autoplayUmaHelper->onAutoplayInitiated(AutoplaySource::Attribute);
1737 1662
1738 // If the autoplay experiment says that it's okay to play now,
1739 // then don't require a user gesture.
1740 m_autoplayHelper->becameReadyToPlay();
1741
1742 if (!isGestureNeededForPlayback()) { 1663 if (!isGestureNeededForPlayback()) {
1743 if (isHTMLVideoElement() && muted() && 1664 if (isHTMLVideoElement() && muted() &&
1744 RuntimeEnabledFeatures::autoplayMutedVideosEnabled()) { 1665 RuntimeEnabledFeatures::autoplayMutedVideosEnabled()) {
1745 // We might end up in a situation where the previous 1666 // We might end up in a situation where the previous
1746 // observer didn't had time to fire yet. We can avoid 1667 // observer didn't had time to fire yet. We can avoid
1747 // creating a new one in this case. 1668 // creating a new one in this case.
1748 if (!m_autoplayVisibilityObserver) { 1669 if (!m_autoplayVisibilityObserver) {
1749 m_autoplayVisibilityObserver = new ElementVisibilityObserver( 1670 m_autoplayVisibilityObserver = new ElementVisibilityObserver(
1750 this, 1671 this,
1751 WTF::bind(&HTMLMediaElement::onVisibilityChangedForAutoplay, 1672 WTF::bind(&HTMLMediaElement::onVisibilityChangedForAutoplay,
(...skipping 353 matching lines...) Expand 10 before | Expand all | Expand 10 after
2105 // 4.8.10.8 Playing the media resource 2026 // 4.8.10.8 Playing the media resource
2106 // The ended attribute must return true if the media element has ended 2027 // The ended attribute must return true if the media element has ended
2107 // playback and the direction of playback is forwards, and false otherwise. 2028 // playback and the direction of playback is forwards, and false otherwise.
2108 return endedPlayback() && getDirectionOfPlayback() == Forward; 2029 return endedPlayback() && getDirectionOfPlayback() == Forward;
2109 } 2030 }
2110 2031
2111 bool HTMLMediaElement::autoplay() const { 2032 bool HTMLMediaElement::autoplay() const {
2112 return fastHasAttribute(autoplayAttr); 2033 return fastHasAttribute(autoplayAttr);
2113 } 2034 }
2114 2035
2115 bool HTMLMediaElement::shouldAutoplay( 2036 bool HTMLMediaElement::shouldAutoplay() {
2116 const RecordMetricsBehavior recordMetrics) { 2037 if (document().isSandboxed(SandboxAutomaticFeatures))
2117 if (m_autoplaying && m_paused && autoplay()) { 2038 return false;
2118 if (document().isSandboxed(SandboxAutomaticFeatures)) { 2039 return m_autoplaying && m_paused && autoplay();
2119 if (recordMetrics == RecordMetricsBehavior::DoRecord)
2120 m_autoplayHelper->recordSandboxFailure();
2121 return false;
2122 }
2123
2124 return true;
2125 }
2126
2127 return false;
2128 } 2040 }
2129 2041
2130 String HTMLMediaElement::preload() const { 2042 String HTMLMediaElement::preload() const {
2131 return preloadTypeToString(preloadType()); 2043 return preloadTypeToString(preloadType());
2132 } 2044 }
2133 2045
2134 void HTMLMediaElement::setPreload(const AtomicString& preload) { 2046 void HTMLMediaElement::setPreload(const AtomicString& preload) {
2135 BLINK_MEDIA_LOG << "setPreload(" << (void*)this << ", " << preload << ")"; 2047 BLINK_MEDIA_LOG << "setPreload(" << (void*)this << ", " << preload << ")";
2136 setAttribute(preloadAttr, preload); 2048 setAttribute(preloadAttr, preload);
2137 } 2049 }
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
2226 resolver->reject(DOMException::create(code.get(), message)); 2138 resolver->reject(DOMException::create(code.get(), message));
2227 return promise; 2139 return promise;
2228 } 2140 }
2229 2141
2230 return promise; 2142 return promise;
2231 } 2143 }
2232 2144
2233 Nullable<ExceptionCode> HTMLMediaElement::play() { 2145 Nullable<ExceptionCode> HTMLMediaElement::play() {
2234 BLINK_MEDIA_LOG << "play(" << (void*)this << ")"; 2146 BLINK_MEDIA_LOG << "play(" << (void*)this << ")";
2235 2147
2236 m_autoplayHelper->playMethodCalled();
2237
2238 if (!UserGestureIndicator::processingUserGesture()) { 2148 if (!UserGestureIndicator::processingUserGesture()) {
2239 m_autoplayUmaHelper->onAutoplayInitiated(AutoplaySource::Method); 2149 m_autoplayUmaHelper->onAutoplayInitiated(AutoplaySource::Method);
2240 if (isGestureNeededForPlayback()) { 2150 if (isGestureNeededForPlayback()) {
2241 // If playback is deferred, then don't start playback but don't
2242 // fail yet either.
2243 if (m_autoplayHelper->isPlaybackDeferred())
2244 return nullptr;
2245
2246 // If we're already playing, then this play would do nothing anyway. 2151 // If we're already playing, then this play would do nothing anyway.
2247 // Call playInternal to handle scheduling the promise resolution. 2152 // Call playInternal to handle scheduling the promise resolution.
2248 if (!m_paused) { 2153 if (!m_paused) {
2249 playInternal(); 2154 playInternal();
2250 return nullptr; 2155 return nullptr;
2251 } 2156 }
2252 2157
2253 recordAutoplayMetric(PlayMethodFailed);
2254 String message = ExceptionMessages::failedToExecute( 2158 String message = ExceptionMessages::failedToExecute(
2255 "play", "HTMLMediaElement", 2159 "play", "HTMLMediaElement",
2256 "API can only be initiated by a user gesture."); 2160 "API can only be initiated by a user gesture.");
2257 document().addConsoleMessage(ConsoleMessage::create( 2161 document().addConsoleMessage(ConsoleMessage::create(
2258 JSMessageSource, WarningMessageLevel, message)); 2162 JSMessageSource, WarningMessageLevel, message));
2259 return NotAllowedError; 2163 return NotAllowedError;
2260 } 2164 }
2261 } else { 2165 } else {
2262 UserGestureIndicator::utilizeUserGesture(); 2166 UserGestureIndicator::utilizeUserGesture();
2263 // We ask the helper to remove the gesture requirement for us, so that 2167 unlockUserGesture();
2264 // it can record the reason.
2265 m_autoplayHelper->unlockUserGesture(GesturelessPlaybackEnabledByPlayMethod);
2266 } 2168 }
2267 2169
2268 if (m_error && m_error->code() == MediaError::kMediaErrSrcNotSupported) 2170 if (m_error && m_error->code() == MediaError::kMediaErrSrcNotSupported)
2269 return NotSupportedError; 2171 return NotSupportedError;
2270 2172
2271 playInternal(); 2173 playInternal();
2272 2174
2273 return nullptr; 2175 return nullptr;
2274 } 2176 }
2275 2177
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
2322 2224
2323 pauseInternal(); 2225 pauseInternal();
2324 } 2226 }
2325 2227
2326 void HTMLMediaElement::pauseInternal() { 2228 void HTMLMediaElement::pauseInternal() {
2327 BLINK_MEDIA_LOG << "pauseInternal(" << (void*)this << ")"; 2229 BLINK_MEDIA_LOG << "pauseInternal(" << (void*)this << ")";
2328 2230
2329 if (m_networkState == kNetworkEmpty) 2231 if (m_networkState == kNetworkEmpty)
2330 invokeResourceSelectionAlgorithm(); 2232 invokeResourceSelectionAlgorithm();
2331 2233
2332 m_autoplayHelper->pauseMethodCalled();
2333
2334 m_autoplaying = false; 2234 m_autoplaying = false;
2335 2235
2336 if (!m_paused) { 2236 if (!m_paused) {
2337 m_paused = true; 2237 m_paused = true;
2338 scheduleTimeupdateEvent(false); 2238 scheduleTimeupdateEvent(false);
2339 scheduleEvent(EventTypeNames::pause); 2239 scheduleEvent(EventTypeNames::pause);
2340 2240
2341 // Force an update to official playback position. Automatic updates from 2241 // Force an update to official playback position. Automatic updates from
2342 // currentPlaybackPosition() will be blocked while m_paused = true. This 2242 // currentPlaybackPosition() will be blocked while m_paused = true. This
2343 // blocking is desired while paused, but its good to update it one final 2243 // blocking is desired while paused, but its good to update it one final
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
2446 return; 2346 return;
2447 2347
2448 bool wasAutoplayingMuted = isAutoplayingMuted(); 2348 bool wasAutoplayingMuted = isAutoplayingMuted();
2449 bool wasPendingAutoplayMuted = m_autoplayVisibilityObserver && paused() && 2349 bool wasPendingAutoplayMuted = m_autoplayVisibilityObserver && paused() &&
2450 m_muted && isLockedPendingUserGesture(); 2350 m_muted && isLockedPendingUserGesture();
2451 2351
2452 if (UserGestureIndicator::processingUserGesture()) 2352 if (UserGestureIndicator::processingUserGesture())
2453 unlockUserGesture(); 2353 unlockUserGesture();
2454 2354
2455 m_muted = muted; 2355 m_muted = muted;
2456 m_autoplayHelper->mutedChanged();
2457 2356
2458 scheduleEvent(EventTypeNames::volumechange); 2357 scheduleEvent(EventTypeNames::volumechange);
2459 2358
2460 // If an element autoplayed while muted, it needs to be unlocked to unmute, 2359 // If an element autoplayed while muted, it needs to be unlocked to unmute,
2461 // otherwise, it will be paused. 2360 // otherwise, it will be paused.
2462 if (wasAutoplayingMuted) { 2361 if (wasAutoplayingMuted) {
2463 if (isGestureNeededForPlayback()) { 2362 if (isGestureNeededForPlayback()) {
2464 pause(); 2363 pause();
2465 m_autoplayUmaHelper->recordAutoplayUnmuteStatus( 2364 m_autoplayUmaHelper->recordAutoplayUnmuteStatus(
2466 AutoplayUnmuteActionStatus::Failure); 2365 AutoplayUnmuteActionStatus::Failure);
(...skipping 867 matching lines...) Expand 10 before | Expand all | Expand 10 after
3334 if (shouldBePlaying) { 3233 if (shouldBePlaying) {
3335 setDisplayMode(Video); 3234 setDisplayMode(Video);
3336 3235
3337 if (!isPlaying) { 3236 if (!isPlaying) {
3338 // Set rate, muted before calling play in case they were set before the 3237 // Set rate, muted before calling play in case they were set before the
3339 // media engine was setup. The media engine should just stash the rate 3238 // media engine was setup. The media engine should just stash the rate
3340 // and muted values since it isn't already playing. 3239 // and muted values since it isn't already playing.
3341 webMediaPlayer()->setRate(playbackRate()); 3240 webMediaPlayer()->setRate(playbackRate());
3342 webMediaPlayer()->setVolume(effectiveMediaVolume()); 3241 webMediaPlayer()->setVolume(effectiveMediaVolume());
3343 webMediaPlayer()->play(); 3242 webMediaPlayer()->play();
3344 m_autoplayHelper->playbackStarted();
3345 } 3243 }
3346 3244
3347 startPlaybackProgressTimer(); 3245 startPlaybackProgressTimer();
3348 m_playing = true; 3246 m_playing = true;
3349 } else { // Should not be playing right now 3247 } else { // Should not be playing right now
3350 if (isPlaying) { 3248 if (isPlaying) {
3351 webMediaPlayer()->pause(); 3249 webMediaPlayer()->pause();
3352 m_autoplayHelper->playbackStopped();
3353 } 3250 }
3354 3251
3355 m_playbackProgressTimer.stop(); 3252 m_playbackProgressTimer.stop();
3356 m_playing = false; 3253 m_playing = false;
3357 double time = currentTime(); 3254 double time = currentTime();
3358 if (time > m_lastSeekTime) 3255 if (time > m_lastSeekTime)
3359 addPlayedRange(m_lastSeekTime, time); 3256 addPlayedRange(m_lastSeekTime, time);
3360 } 3257 }
3361 3258
3362 if (layoutObject()) 3259 if (layoutObject())
(...skipping 458 matching lines...) Expand 10 before | Expand all | Expand 10 after
3821 visitor->trace(m_mediaSource); 3718 visitor->trace(m_mediaSource);
3822 visitor->trace(m_audioTracks); 3719 visitor->trace(m_audioTracks);
3823 visitor->trace(m_videoTracks); 3720 visitor->trace(m_videoTracks);
3824 visitor->trace(m_cueTimeline); 3721 visitor->trace(m_cueTimeline);
3825 visitor->trace(m_textTracks); 3722 visitor->trace(m_textTracks);
3826 visitor->trace(m_textTracksWhenResourceSelectionBegan); 3723 visitor->trace(m_textTracksWhenResourceSelectionBegan);
3827 visitor->trace(m_playPromiseResolvers); 3724 visitor->trace(m_playPromiseResolvers);
3828 visitor->trace(m_playPromiseResolveList); 3725 visitor->trace(m_playPromiseResolveList);
3829 visitor->trace(m_playPromiseRejectList); 3726 visitor->trace(m_playPromiseRejectList);
3830 visitor->trace(m_audioSourceProvider); 3727 visitor->trace(m_audioSourceProvider);
3831 visitor->trace(m_autoplayHelperClient);
3832 visitor->trace(m_autoplayHelper);
3833 visitor->trace(m_autoplayUmaHelper); 3728 visitor->trace(m_autoplayUmaHelper);
3834 visitor->trace(m_srcObject); 3729 visitor->trace(m_srcObject);
3835 visitor->trace(m_autoplayVisibilityObserver); 3730 visitor->trace(m_autoplayVisibilityObserver);
3836 visitor->template registerWeakMembers<HTMLMediaElement, 3731 visitor->template registerWeakMembers<HTMLMediaElement,
3837 &HTMLMediaElement::clearWeakMembers>( 3732 &HTMLMediaElement::clearWeakMembers>(
3838 this); 3733 this);
3839 Supplementable<HTMLMediaElement>::trace(visitor); 3734 Supplementable<HTMLMediaElement>::trace(visitor);
3840 HTMLElement::trace(visitor); 3735 HTMLElement::trace(visitor);
3841 ActiveDOMObject::trace(visitor); 3736 ActiveDOMObject::trace(visitor);
3842 } 3737 }
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
3904 // - Autoplay is enabled in settings; 3799 // - Autoplay is enabled in settings;
3905 if (isHTMLVideoElement() && muted() && 3800 if (isHTMLVideoElement() && muted() &&
3906 RuntimeEnabledFeatures::autoplayMutedVideosEnabled() && 3801 RuntimeEnabledFeatures::autoplayMutedVideosEnabled() &&
3907 !(document().settings() && document().settings()->dataSaverEnabled()) && 3802 !(document().settings() && document().settings()->dataSaverEnabled()) &&
3908 !(document().settings() && 3803 !(document().settings() &&
3909 document().settings()->forcePreloadNoneForMediaElements()) && 3804 document().settings()->forcePreloadNoneForMediaElements()) &&
3910 isAutoplayAllowedPerSettings()) { 3805 isAutoplayAllowedPerSettings()) {
3911 return false; 3806 return false;
3912 } 3807 }
3913 3808
3914 if (m_autoplayHelper->isGestureRequirementOverridden())
3915 return false;
3916
3917 return true; 3809 return true;
3918 } 3810 }
3919 3811
3920 bool HTMLMediaElement::isAutoplayAllowedPerSettings() const { 3812 bool HTMLMediaElement::isAutoplayAllowedPerSettings() const {
3921 LocalFrame* frame = document().frame(); 3813 LocalFrame* frame = document().frame();
3922 if (!frame) 3814 if (!frame)
3923 return false; 3815 return false;
3924 FrameLoaderClient* frameLoaderClient = frame->loader().client(); 3816 FrameLoaderClient* frameLoaderClient = frame->loader().client();
3925 return frameLoaderClient && frameLoaderClient->allowAutoplay(false); 3817 return frameLoaderClient && frameLoaderClient->allowAutoplay(false);
3926 } 3818 }
3927 3819
3928 void HTMLMediaElement::setNetworkState(NetworkState state) { 3820 void HTMLMediaElement::setNetworkState(NetworkState state) {
3929 if (m_networkState != state) { 3821 if (m_networkState != state) {
3930 m_networkState = state; 3822 m_networkState = state;
3931 if (MediaControls* controls = mediaControls()) 3823 if (MediaControls* controls = mediaControls())
3932 controls->networkStateChanged(); 3824 controls->networkStateChanged();
3933 } 3825 }
3934 } 3826 }
3935 3827
3936 void HTMLMediaElement::videoWillBeDrawnToCanvas() const { 3828 void HTMLMediaElement::videoWillBeDrawnToCanvas() const {
3937 DCHECK(isHTMLVideoElement()); 3829 DCHECK(isHTMLVideoElement());
3938 UseCounter::count(document(), UseCounter::VideoInCanvas); 3830 UseCounter::count(document(), UseCounter::VideoInCanvas);
3939 if (m_autoplayUmaHelper->hasSource() && !m_autoplayUmaHelper->isVisible()) 3831 if (m_autoplayUmaHelper->hasSource() && !m_autoplayUmaHelper->isVisible())
3940 UseCounter::count(document(), UseCounter::HiddenAutoplayedVideoInCanvas); 3832 UseCounter::count(document(), UseCounter::HiddenAutoplayedVideoInCanvas);
3941 } 3833 }
3942 3834
3943 void HTMLMediaElement::notifyPositionMayHaveChanged(
3944 const IntRect& visibleRect) {
3945 m_autoplayHelper->positionChanged(visibleRect);
3946 }
3947
3948 void HTMLMediaElement::updatePositionNotificationRegistration() {
3949 m_autoplayHelper->updatePositionNotificationRegistration();
3950 }
3951
3952 // TODO(liberato): remove once autoplay gesture override experiment concludes.
3953 void HTMLMediaElement::triggerAutoplayViewportCheckForTesting() {
3954 if (FrameView* view = document().view())
3955 m_autoplayHelper->positionChanged(
3956 view->rootFrameToContents(view->computeVisibleArea()));
3957 m_autoplayHelper->triggerAutoplayViewportCheckForTesting();
3958 }
3959
3960 void HTMLMediaElement::scheduleResolvePlayPromises() { 3835 void HTMLMediaElement::scheduleResolvePlayPromises() {
3961 // TODO(mlamouri): per spec, we should create a new task but we can't create 3836 // TODO(mlamouri): per spec, we should create a new task but we can't create
3962 // a new cancellable task without cancelling the previous one. There are two 3837 // a new cancellable task without cancelling the previous one. There are two
3963 // approaches then: cancel the previous task and create a new one with the 3838 // approaches then: cancel the previous task and create a new one with the
3964 // appended promise list or append the new promise to the current list. The 3839 // appended promise list or append the new promise to the current list. The
3965 // latter approach is preferred because it might be the less observable 3840 // latter approach is preferred because it might be the less observable
3966 // change. 3841 // change.
3967 DCHECK(m_playPromiseResolveList.isEmpty() || 3842 DCHECK(m_playPromiseResolveList.isEmpty() ||
3968 m_playPromiseResolveTaskHandle.isActive()); 3843 m_playPromiseResolveTaskHandle.isActive());
3969 if (m_playPromiseResolvers.isEmpty()) 3844 if (m_playPromiseResolvers.isEmpty())
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after
4148 } 4023 }
4149 4024
4150 DEFINE_TRACE(HTMLMediaElement::AudioClientImpl) { 4025 DEFINE_TRACE(HTMLMediaElement::AudioClientImpl) {
4151 visitor->trace(m_client); 4026 visitor->trace(m_client);
4152 } 4027 }
4153 4028
4154 DEFINE_TRACE(HTMLMediaElement::AudioSourceProviderImpl) { 4029 DEFINE_TRACE(HTMLMediaElement::AudioSourceProviderImpl) {
4155 visitor->trace(m_client); 4030 visitor->trace(m_client);
4156 } 4031 }
4157 4032
4158 HTMLMediaElement::AutoplayHelperClientImpl::~AutoplayHelperClientImpl() {}
4159
4160 bool HTMLMediaElement::AutoplayHelperClientImpl::isLegacyViewportType() {
4161 return m_element->document().viewportDescription().isLegacyViewportType();
4162 }
4163
4164 PageVisibilityState
4165 HTMLMediaElement::AutoplayHelperClientImpl::pageVisibilityState() const {
4166 return m_element->document().pageVisibilityState();
4167 }
4168
4169 String HTMLMediaElement::AutoplayHelperClientImpl::autoplayExperimentMode()
4170 const {
4171 String mode;
4172 if (m_element->document().settings())
4173 mode = m_element->document().settings()->autoplayExperimentMode();
4174
4175 return mode;
4176 }
4177
4178 bool HTMLMediaElement::AutoplayHelperClientImpl::isAutoplayAllowedPerSettings()
4179 const {
4180 return m_element->isAutoplayAllowedPerSettings();
4181 }
4182
4183 void HTMLMediaElement::AutoplayHelperClientImpl::setRequestPositionUpdates(
4184 bool request) {
4185 if (LayoutObject* layoutObject = m_element->layoutObject()) {
4186 LayoutMediaItem layoutMediaItem =
4187 LayoutMediaItem(toLayoutMedia(layoutObject));
4188 layoutMediaItem.setRequestPositionUpdates(request);
4189 }
4190 }
4191
4192 IntRect HTMLMediaElement::AutoplayHelperClientImpl::absoluteBoundingBoxRect()
4193 const {
4194 IntRect result;
4195 if (LayoutObject* object = m_element->layoutObject())
4196 result = object->absoluteBoundingBoxRect();
4197 return result;
4198 }
4199
4200 } // namespace blink 4033 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/core/html/HTMLMediaElement.h ('k') | third_party/WebKit/Source/core/layout/BUILD.gn » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698