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

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

Issue 2510353004: Deprecating AutoplayExperimentHelper (Closed)
Patch Set: cleaned up the layout code no longer used 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 643 matching lines...) Expand 10 before | Expand all | Expand 10 after
1727 1652
1728 if (m_readyState == kHaveEnoughData && oldState < kHaveEnoughData && 1653 if (m_readyState == kHaveEnoughData && oldState < kHaveEnoughData &&
1729 tracksAreReady) { 1654 tracksAreReady) {
1730 if (oldState <= kHaveCurrentData) { 1655 if (oldState <= kHaveCurrentData) {
1731 scheduleEvent(EventTypeNames::canplay); 1656 scheduleEvent(EventTypeNames::canplay);
1732 if (isPotentiallyPlaying) 1657 if (isPotentiallyPlaying)
1733 scheduleNotifyPlaying(); 1658 scheduleNotifyPlaying();
1734 } 1659 }
1735 1660
1736 // Check for autoplay, and record metrics about it if needed. 1661 // Check for autoplay, and record metrics about it if needed.
1737 if (shouldAutoplay(RecordMetricsBehavior::DoRecord)) { 1662 if (shouldAutoplay()) {
1738 m_autoplayUmaHelper->onAutoplayInitiated(AutoplaySource::Attribute); 1663 m_autoplayUmaHelper->onAutoplayInitiated(AutoplaySource::Attribute);
1739 1664
1740 // If the autoplay experiment says that it's okay to play now,
1741 // then don't require a user gesture.
1742 m_autoplayHelper->becameReadyToPlay();
1743
1744 if (!isGestureNeededForPlayback()) { 1665 if (!isGestureNeededForPlayback()) {
1745 if (isHTMLVideoElement() && muted() && 1666 if (isHTMLVideoElement() && muted() &&
1746 RuntimeEnabledFeatures::autoplayMutedVideosEnabled()) { 1667 RuntimeEnabledFeatures::autoplayMutedVideosEnabled()) {
1747 // We might end up in a situation where the previous 1668 // We might end up in a situation where the previous
1748 // observer didn't had time to fire yet. We can avoid 1669 // observer didn't had time to fire yet. We can avoid
1749 // creating a new one in this case. 1670 // creating a new one in this case.
1750 if (!m_autoplayVisibilityObserver) { 1671 if (!m_autoplayVisibilityObserver) {
1751 m_autoplayVisibilityObserver = new ElementVisibilityObserver( 1672 m_autoplayVisibilityObserver = new ElementVisibilityObserver(
1752 this, 1673 this,
1753 WTF::bind(&HTMLMediaElement::onVisibilityChangedForAutoplay, 1674 WTF::bind(&HTMLMediaElement::onVisibilityChangedForAutoplay,
(...skipping 353 matching lines...) Expand 10 before | Expand all | Expand 10 after
2107 // 4.8.10.8 Playing the media resource 2028 // 4.8.10.8 Playing the media resource
2108 // The ended attribute must return true if the media element has ended 2029 // The ended attribute must return true if the media element has ended
2109 // playback and the direction of playback is forwards, and false otherwise. 2030 // playback and the direction of playback is forwards, and false otherwise.
2110 return endedPlayback() && getDirectionOfPlayback() == Forward; 2031 return endedPlayback() && getDirectionOfPlayback() == Forward;
2111 } 2032 }
2112 2033
2113 bool HTMLMediaElement::autoplay() const { 2034 bool HTMLMediaElement::autoplay() const {
2114 return fastHasAttribute(autoplayAttr); 2035 return fastHasAttribute(autoplayAttr);
2115 } 2036 }
2116 2037
2117 bool HTMLMediaElement::shouldAutoplay( 2038 bool HTMLMediaElement::shouldAutoplay() {
2118 const RecordMetricsBehavior recordMetrics) { 2039 if (document().isSandboxed(SandboxAutomaticFeatures))
2119 if (m_autoplaying && m_paused && autoplay()) { 2040 return false;
2120 if (document().isSandboxed(SandboxAutomaticFeatures)) { 2041 return m_autoplaying && m_paused && autoplay();
2121 if (recordMetrics == RecordMetricsBehavior::DoRecord)
2122 m_autoplayHelper->recordSandboxFailure();
2123 return false;
2124 }
2125
2126 return true;
2127 }
2128
2129 return false;
2130 } 2042 }
2131 2043
2132 String HTMLMediaElement::preload() const { 2044 String HTMLMediaElement::preload() const {
2133 return preloadTypeToString(preloadType()); 2045 return preloadTypeToString(preloadType());
2134 } 2046 }
2135 2047
2136 void HTMLMediaElement::setPreload(const AtomicString& preload) { 2048 void HTMLMediaElement::setPreload(const AtomicString& preload) {
2137 BLINK_MEDIA_LOG << "setPreload(" << (void*)this << ", " << preload << ")"; 2049 BLINK_MEDIA_LOG << "setPreload(" << (void*)this << ", " << preload << ")";
2138 setAttribute(preloadAttr, preload); 2050 setAttribute(preloadAttr, preload);
2139 } 2051 }
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
2228 resolver->reject(DOMException::create(code.get(), message)); 2140 resolver->reject(DOMException::create(code.get(), message));
2229 return promise; 2141 return promise;
2230 } 2142 }
2231 2143
2232 return promise; 2144 return promise;
2233 } 2145 }
2234 2146
2235 Nullable<ExceptionCode> HTMLMediaElement::play() { 2147 Nullable<ExceptionCode> HTMLMediaElement::play() {
2236 BLINK_MEDIA_LOG << "play(" << (void*)this << ")"; 2148 BLINK_MEDIA_LOG << "play(" << (void*)this << ")";
2237 2149
2238 m_autoplayHelper->playMethodCalled();
2239
2240 if (!UserGestureIndicator::processingUserGesture()) { 2150 if (!UserGestureIndicator::processingUserGesture()) {
2241 m_autoplayUmaHelper->onAutoplayInitiated(AutoplaySource::Method); 2151 m_autoplayUmaHelper->onAutoplayInitiated(AutoplaySource::Method);
2242 if (isGestureNeededForPlayback()) { 2152 if (isGestureNeededForPlayback()) {
2243 // If playback is deferred, then don't start playback but don't
2244 // fail yet either.
2245 if (m_autoplayHelper->isPlaybackDeferred())
2246 return nullptr;
2247
2248 // If we're already playing, then this play would do nothing anyway. 2153 // If we're already playing, then this play would do nothing anyway.
2249 // Call playInternal to handle scheduling the promise resolution. 2154 // Call playInternal to handle scheduling the promise resolution.
2250 if (!m_paused) { 2155 if (!m_paused) {
2251 playInternal(); 2156 playInternal();
2252 return nullptr; 2157 return nullptr;
2253 } 2158 }
2254 2159
2255 recordAutoplayMetric(PlayMethodFailed);
2256 String message = ExceptionMessages::failedToExecute( 2160 String message = ExceptionMessages::failedToExecute(
2257 "play", "HTMLMediaElement", 2161 "play", "HTMLMediaElement",
2258 "API can only be initiated by a user gesture."); 2162 "API can only be initiated by a user gesture.");
2259 document().addConsoleMessage(ConsoleMessage::create( 2163 document().addConsoleMessage(ConsoleMessage::create(
2260 JSMessageSource, WarningMessageLevel, message)); 2164 JSMessageSource, WarningMessageLevel, message));
2261 return NotAllowedError; 2165 return NotAllowedError;
2262 } 2166 }
2263 } else { 2167 } else {
2264 UserGestureIndicator::utilizeUserGesture(); 2168 UserGestureIndicator::utilizeUserGesture();
2265 // We ask the helper to remove the gesture requirement for us, so that 2169 unlockUserGesture();
2266 // it can record the reason.
2267 m_autoplayHelper->unlockUserGesture(GesturelessPlaybackEnabledByPlayMethod);
2268 } 2170 }
2269 2171
2270 if (m_error && m_error->code() == MediaError::kMediaErrSrcNotSupported) 2172 if (m_error && m_error->code() == MediaError::kMediaErrSrcNotSupported)
2271 return NotSupportedError; 2173 return NotSupportedError;
2272 2174
2273 playInternal(); 2175 playInternal();
2274 2176
2275 return nullptr; 2177 return nullptr;
2276 } 2178 }
2277 2179
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
2324 2226
2325 pauseInternal(); 2227 pauseInternal();
2326 } 2228 }
2327 2229
2328 void HTMLMediaElement::pauseInternal() { 2230 void HTMLMediaElement::pauseInternal() {
2329 BLINK_MEDIA_LOG << "pauseInternal(" << (void*)this << ")"; 2231 BLINK_MEDIA_LOG << "pauseInternal(" << (void*)this << ")";
2330 2232
2331 if (m_networkState == kNetworkEmpty) 2233 if (m_networkState == kNetworkEmpty)
2332 invokeResourceSelectionAlgorithm(); 2234 invokeResourceSelectionAlgorithm();
2333 2235
2334 m_autoplayHelper->pauseMethodCalled();
2335
2336 m_autoplaying = false; 2236 m_autoplaying = false;
2337 2237
2338 if (!m_paused) { 2238 if (!m_paused) {
2339 m_paused = true; 2239 m_paused = true;
2340 scheduleTimeupdateEvent(false); 2240 scheduleTimeupdateEvent(false);
2341 scheduleEvent(EventTypeNames::pause); 2241 scheduleEvent(EventTypeNames::pause);
2342 2242
2343 // Force an update to official playback position. Automatic updates from 2243 // Force an update to official playback position. Automatic updates from
2344 // currentPlaybackPosition() will be blocked while m_paused = true. This 2244 // currentPlaybackPosition() will be blocked while m_paused = true. This
2345 // blocking is desired while paused, but its good to update it one final 2245 // 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
2448 return; 2348 return;
2449 2349
2450 bool wasAutoplayingMuted = isAutoplayingMuted(); 2350 bool wasAutoplayingMuted = isAutoplayingMuted();
2451 bool wasPendingAutoplayMuted = m_autoplayVisibilityObserver && paused() && 2351 bool wasPendingAutoplayMuted = m_autoplayVisibilityObserver && paused() &&
2452 m_muted && isLockedPendingUserGesture(); 2352 m_muted && isLockedPendingUserGesture();
2453 2353
2454 if (UserGestureIndicator::processingUserGesture()) 2354 if (UserGestureIndicator::processingUserGesture())
2455 unlockUserGesture(); 2355 unlockUserGesture();
2456 2356
2457 m_muted = muted; 2357 m_muted = muted;
2458 m_autoplayHelper->mutedChanged();
2459 2358
2460 scheduleEvent(EventTypeNames::volumechange); 2359 scheduleEvent(EventTypeNames::volumechange);
2461 2360
2462 // If an element autoplayed while muted, it needs to be unlocked to unmute, 2361 // If an element autoplayed while muted, it needs to be unlocked to unmute,
2463 // otherwise, it will be paused. 2362 // otherwise, it will be paused.
2464 if (wasAutoplayingMuted) { 2363 if (wasAutoplayingMuted) {
2465 if (isGestureNeededForPlayback()) { 2364 if (isGestureNeededForPlayback()) {
2466 pause(); 2365 pause();
2467 m_autoplayUmaHelper->recordAutoplayUnmuteStatus( 2366 m_autoplayUmaHelper->recordAutoplayUnmuteStatus(
2468 AutoplayUnmuteActionStatus::Failure); 2367 AutoplayUnmuteActionStatus::Failure);
(...skipping 869 matching lines...) Expand 10 before | Expand all | Expand 10 after
3338 if (shouldBePlaying) { 3237 if (shouldBePlaying) {
3339 setDisplayMode(Video); 3238 setDisplayMode(Video);
3340 3239
3341 if (!isPlaying) { 3240 if (!isPlaying) {
3342 // Set rate, muted before calling play in case they were set before the 3241 // Set rate, muted before calling play in case they were set before the
3343 // media engine was setup. The media engine should just stash the rate 3242 // media engine was setup. The media engine should just stash the rate
3344 // and muted values since it isn't already playing. 3243 // and muted values since it isn't already playing.
3345 webMediaPlayer()->setRate(playbackRate()); 3244 webMediaPlayer()->setRate(playbackRate());
3346 webMediaPlayer()->setVolume(effectiveMediaVolume()); 3245 webMediaPlayer()->setVolume(effectiveMediaVolume());
3347 webMediaPlayer()->play(); 3246 webMediaPlayer()->play();
3348 m_autoplayHelper->playbackStarted();
3349 } 3247 }
3350 3248
3351 if (mediaControls()) 3249 if (mediaControls())
3352 mediaControls()->playbackStarted(); 3250 mediaControls()->playbackStarted();
3353 startPlaybackProgressTimer(); 3251 startPlaybackProgressTimer();
3354 m_playing = true; 3252 m_playing = true;
3355 3253
3356 } else { // Should not be playing right now 3254 } else { // Should not be playing right now
3357 if (isPlaying) { 3255 if (isPlaying) {
3358 webMediaPlayer()->pause(); 3256 webMediaPlayer()->pause();
3359 m_autoplayHelper->playbackStopped();
3360 } 3257 }
3361 3258
3362 m_playbackProgressTimer.stop(); 3259 m_playbackProgressTimer.stop();
3363 m_playing = false; 3260 m_playing = false;
3364 double time = currentTime(); 3261 double time = currentTime();
3365 if (time > m_lastSeekTime) 3262 if (time > m_lastSeekTime)
3366 addPlayedRange(m_lastSeekTime, time); 3263 addPlayedRange(m_lastSeekTime, time);
3367 3264
3368 if (mediaControls()) 3265 if (mediaControls())
3369 mediaControls()->playbackStopped(); 3266 mediaControls()->playbackStopped();
(...skipping 461 matching lines...) Expand 10 before | Expand all | Expand 10 after
3831 visitor->trace(m_mediaSource); 3728 visitor->trace(m_mediaSource);
3832 visitor->trace(m_audioTracks); 3729 visitor->trace(m_audioTracks);
3833 visitor->trace(m_videoTracks); 3730 visitor->trace(m_videoTracks);
3834 visitor->trace(m_cueTimeline); 3731 visitor->trace(m_cueTimeline);
3835 visitor->trace(m_textTracks); 3732 visitor->trace(m_textTracks);
3836 visitor->trace(m_textTracksWhenResourceSelectionBegan); 3733 visitor->trace(m_textTracksWhenResourceSelectionBegan);
3837 visitor->trace(m_playPromiseResolvers); 3734 visitor->trace(m_playPromiseResolvers);
3838 visitor->trace(m_playPromiseResolveList); 3735 visitor->trace(m_playPromiseResolveList);
3839 visitor->trace(m_playPromiseRejectList); 3736 visitor->trace(m_playPromiseRejectList);
3840 visitor->trace(m_audioSourceProvider); 3737 visitor->trace(m_audioSourceProvider);
3841 visitor->trace(m_autoplayHelperClient);
3842 visitor->trace(m_autoplayHelper);
3843 visitor->trace(m_autoplayUmaHelper); 3738 visitor->trace(m_autoplayUmaHelper);
3844 visitor->trace(m_srcObject); 3739 visitor->trace(m_srcObject);
3845 visitor->trace(m_autoplayVisibilityObserver); 3740 visitor->trace(m_autoplayVisibilityObserver);
3846 visitor->template registerWeakMembers<HTMLMediaElement, 3741 visitor->template registerWeakMembers<HTMLMediaElement,
3847 &HTMLMediaElement::clearWeakMembers>( 3742 &HTMLMediaElement::clearWeakMembers>(
3848 this); 3743 this);
3849 Supplementable<HTMLMediaElement>::trace(visitor); 3744 Supplementable<HTMLMediaElement>::trace(visitor);
3850 HTMLElement::trace(visitor); 3745 HTMLElement::trace(visitor);
3851 ActiveDOMObject::trace(visitor); 3746 ActiveDOMObject::trace(visitor);
3852 } 3747 }
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
3910 // - Autoplay is enabled in settings; 3805 // - Autoplay is enabled in settings;
3911 if (isHTMLVideoElement() && muted() && 3806 if (isHTMLVideoElement() && muted() &&
3912 RuntimeEnabledFeatures::autoplayMutedVideosEnabled() && 3807 RuntimeEnabledFeatures::autoplayMutedVideosEnabled() &&
3913 !(document().settings() && document().settings()->dataSaverEnabled()) && 3808 !(document().settings() && document().settings()->dataSaverEnabled()) &&
3914 !(document().settings() && 3809 !(document().settings() &&
3915 document().settings()->forcePreloadNoneForMediaElements()) && 3810 document().settings()->forcePreloadNoneForMediaElements()) &&
3916 isAutoplayAllowedPerSettings()) { 3811 isAutoplayAllowedPerSettings()) {
3917 return false; 3812 return false;
3918 } 3813 }
3919 3814
3920 if (m_autoplayHelper->isGestureRequirementOverridden())
3921 return false;
3922
3923 return true; 3815 return true;
3924 } 3816 }
3925 3817
3926 bool HTMLMediaElement::isAutoplayAllowedPerSettings() const { 3818 bool HTMLMediaElement::isAutoplayAllowedPerSettings() const {
3927 LocalFrame* frame = document().frame(); 3819 LocalFrame* frame = document().frame();
3928 if (!frame) 3820 if (!frame)
3929 return false; 3821 return false;
3930 FrameLoaderClient* frameLoaderClient = frame->loader().client(); 3822 FrameLoaderClient* frameLoaderClient = frame->loader().client();
3931 return frameLoaderClient && frameLoaderClient->allowAutoplay(false); 3823 return frameLoaderClient && frameLoaderClient->allowAutoplay(false);
3932 } 3824 }
3933 3825
3934 void HTMLMediaElement::setNetworkState(NetworkState state) { 3826 void HTMLMediaElement::setNetworkState(NetworkState state) {
3935 if (m_networkState != state) { 3827 if (m_networkState != state) {
3936 m_networkState = state; 3828 m_networkState = state;
3937 if (MediaControls* controls = mediaControls()) 3829 if (MediaControls* controls = mediaControls())
3938 controls->networkStateChanged(); 3830 controls->networkStateChanged();
3939 } 3831 }
3940 } 3832 }
3941 3833
3942 void HTMLMediaElement::videoWillBeDrawnToCanvas() const { 3834 void HTMLMediaElement::videoWillBeDrawnToCanvas() const {
3943 DCHECK(isHTMLVideoElement()); 3835 DCHECK(isHTMLVideoElement());
3944 UseCounter::count(document(), UseCounter::VideoInCanvas); 3836 UseCounter::count(document(), UseCounter::VideoInCanvas);
3945 if (m_autoplayUmaHelper->hasSource() && !m_autoplayUmaHelper->isVisible()) 3837 if (m_autoplayUmaHelper->hasSource() && !m_autoplayUmaHelper->isVisible())
3946 UseCounter::count(document(), UseCounter::HiddenAutoplayedVideoInCanvas); 3838 UseCounter::count(document(), UseCounter::HiddenAutoplayedVideoInCanvas);
3947 } 3839 }
3948 3840
3949 void HTMLMediaElement::notifyPositionMayHaveChanged(
3950 const IntRect& visibleRect) {
3951 m_autoplayHelper->positionChanged(visibleRect);
3952 }
3953
3954 void HTMLMediaElement::updatePositionNotificationRegistration() {
3955 m_autoplayHelper->updatePositionNotificationRegistration();
3956 }
3957
3958 // TODO(liberato): remove once autoplay gesture override experiment concludes.
3959 void HTMLMediaElement::triggerAutoplayViewportCheckForTesting() {
3960 if (FrameView* view = document().view())
3961 m_autoplayHelper->positionChanged(
3962 view->rootFrameToContents(view->computeVisibleArea()));
3963 m_autoplayHelper->triggerAutoplayViewportCheckForTesting();
3964 }
3965
3966 void HTMLMediaElement::scheduleResolvePlayPromises() { 3841 void HTMLMediaElement::scheduleResolvePlayPromises() {
3967 // TODO(mlamouri): per spec, we should create a new task but we can't create 3842 // TODO(mlamouri): per spec, we should create a new task but we can't create
3968 // a new cancellable task without cancelling the previous one. There are two 3843 // a new cancellable task without cancelling the previous one. There are two
3969 // approaches then: cancel the previous task and create a new one with the 3844 // approaches then: cancel the previous task and create a new one with the
3970 // appended promise list or append the new promise to the current list. The 3845 // appended promise list or append the new promise to the current list. The
3971 // latter approach is preferred because it might be the less observable 3846 // latter approach is preferred because it might be the less observable
3972 // change. 3847 // change.
3973 DCHECK(m_playPromiseResolveList.isEmpty() || 3848 DCHECK(m_playPromiseResolveList.isEmpty() ||
3974 m_playPromiseResolveTaskHandle.isActive()); 3849 m_playPromiseResolveTaskHandle.isActive());
3975 if (m_playPromiseResolvers.isEmpty()) 3850 if (m_playPromiseResolvers.isEmpty())
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after
4154 } 4029 }
4155 4030
4156 DEFINE_TRACE(HTMLMediaElement::AudioClientImpl) { 4031 DEFINE_TRACE(HTMLMediaElement::AudioClientImpl) {
4157 visitor->trace(m_client); 4032 visitor->trace(m_client);
4158 } 4033 }
4159 4034
4160 DEFINE_TRACE(HTMLMediaElement::AudioSourceProviderImpl) { 4035 DEFINE_TRACE(HTMLMediaElement::AudioSourceProviderImpl) {
4161 visitor->trace(m_client); 4036 visitor->trace(m_client);
4162 } 4037 }
4163 4038
4164 HTMLMediaElement::AutoplayHelperClientImpl::~AutoplayHelperClientImpl() {}
4165
4166 bool HTMLMediaElement::AutoplayHelperClientImpl::isLegacyViewportType() {
4167 return m_element->document().viewportDescription().isLegacyViewportType();
4168 }
4169
4170 PageVisibilityState
4171 HTMLMediaElement::AutoplayHelperClientImpl::pageVisibilityState() const {
4172 return m_element->document().pageVisibilityState();
4173 }
4174
4175 String HTMLMediaElement::AutoplayHelperClientImpl::autoplayExperimentMode()
4176 const {
4177 String mode;
4178 if (m_element->document().settings())
4179 mode = m_element->document().settings()->autoplayExperimentMode();
4180
4181 return mode;
4182 }
4183
4184 bool HTMLMediaElement::AutoplayHelperClientImpl::isAutoplayAllowedPerSettings()
4185 const {
4186 return m_element->isAutoplayAllowedPerSettings();
4187 }
4188
4189 void HTMLMediaElement::AutoplayHelperClientImpl::setRequestPositionUpdates(
4190 bool request) {
4191 if (LayoutObject* layoutObject = m_element->layoutObject()) {
4192 LayoutMediaItem layoutMediaItem =
4193 LayoutMediaItem(toLayoutMedia(layoutObject));
4194 layoutMediaItem.setRequestPositionUpdates(request);
4195 }
4196 }
4197
4198 IntRect HTMLMediaElement::AutoplayHelperClientImpl::absoluteBoundingBoxRect()
4199 const {
4200 IntRect result;
4201 if (LayoutObject* object = m_element->layoutObject())
4202 result = object->absoluteBoundingBoxRect();
4203 return result;
4204 }
4205
4206 } // namespace blink 4039 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698