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

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

Issue 2510353004: Deprecating AutoplayExperimentHelper (Closed)
Patch Set: rebased Created 4 years, 1 month 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 268 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()) {
foolip 2016/11/23 12:40:55 This isn't what I had expected, but https://codere
Zhiqiang Zhang (Slow) 2016/11/23 17:18:28 This logic was flattened from AutoplayExperimental
foolip 2016/11/23 19:15:55 Originally it was processingUserGesture(), so that
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 646 matching lines...) Expand 10 before | Expand all | Expand 10 after
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(RecordMetricsBehavior::DoRecord)) {
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 354 matching lines...) Expand 10 before | Expand all | Expand 10 after
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 const RecordMetricsBehavior recordMetrics) {
foolip 2016/11/23 12:40:55 Remove the now unused argument.
Zhiqiang Zhang (Slow) 2016/11/23 18:27:34 Done.
2119 if (m_autoplaying && m_paused && autoplay()) { 2040 if (m_autoplaying && m_paused && autoplay()) {
foolip 2016/11/23 12:40:55 This now ends up looking a bit silly and not trivi
Zhiqiang Zhang (Slow) 2016/11/23 18:27:34 Done.
2120 if (document().isSandboxed(SandboxAutomaticFeatures)) { 2041 if (document().isSandboxed(SandboxAutomaticFeatures))
2121 if (recordMetrics == RecordMetricsBehavior::DoRecord)
2122 m_autoplayHelper->recordSandboxFailure();
2123 return false; 2042 return false;
2124 }
2125
2126 return true; 2043 return true;
2127 } 2044 }
2128 2045
2129 return false; 2046 return false;
2130 } 2047 }
2131 2048
2132 String HTMLMediaElement::preload() const { 2049 String HTMLMediaElement::preload() const {
2133 return preloadTypeToString(preloadType()); 2050 return preloadTypeToString(preloadType());
2134 } 2051 }
2135 2052
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
2228 resolver->reject(DOMException::create(code.get(), message)); 2145 resolver->reject(DOMException::create(code.get(), message));
2229 return promise; 2146 return promise;
2230 } 2147 }
2231 2148
2232 return promise; 2149 return promise;
2233 } 2150 }
2234 2151
2235 Nullable<ExceptionCode> HTMLMediaElement::play() { 2152 Nullable<ExceptionCode> HTMLMediaElement::play() {
2236 BLINK_MEDIA_LOG << "play(" << (void*)this << ")"; 2153 BLINK_MEDIA_LOG << "play(" << (void*)this << ")";
2237 2154
2238 m_autoplayHelper->playMethodCalled();
2239
2240 if (!UserGestureIndicator::processingUserGesture()) { 2155 if (!UserGestureIndicator::processingUserGesture()) {
2241 m_autoplayUmaHelper->onAutoplayInitiated(AutoplaySource::Method); 2156 m_autoplayUmaHelper->onAutoplayInitiated(AutoplaySource::Method);
2242 if (isGestureNeededForPlayback()) { 2157 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. 2158 // If we're already playing, then this play would do nothing anyway.
2249 // Call playInternal to handle scheduling the promise resolution. 2159 // Call playInternal to handle scheduling the promise resolution.
2250 if (!m_paused) { 2160 if (!m_paused) {
2251 playInternal(); 2161 playInternal();
2252 return nullptr; 2162 return nullptr;
2253 } 2163 }
2254 2164
2255 recordAutoplayMetric(PlayMethodFailed);
2256 String message = ExceptionMessages::failedToExecute( 2165 String message = ExceptionMessages::failedToExecute(
2257 "play", "HTMLMediaElement", 2166 "play", "HTMLMediaElement",
2258 "API can only be initiated by a user gesture."); 2167 "API can only be initiated by a user gesture.");
2259 document().addConsoleMessage(ConsoleMessage::create( 2168 document().addConsoleMessage(ConsoleMessage::create(
2260 JSMessageSource, WarningMessageLevel, message)); 2169 JSMessageSource, WarningMessageLevel, message));
2261 return NotAllowedError; 2170 return NotAllowedError;
2262 } 2171 }
2263 } else { 2172 } else {
2264 UserGestureIndicator::utilizeUserGesture(); 2173 UserGestureIndicator::utilizeUserGesture();
foolip 2016/11/23 12:40:55 Optional nit: hoist utilizeUserGesture() to above.
Zhiqiang Zhang (Slow) 2016/11/23 18:27:34 Did you mean to move it to utilizeUserGesture() to
foolip 2016/11/23 19:15:55 Will do, but will base it on your CL since it's go
2265 // We ask the helper to remove the gesture requirement for us, so that 2174 unlockUserGesture();
2266 // it can record the reason.
2267 m_autoplayHelper->unlockUserGesture(GesturelessPlaybackEnabledByPlayMethod);
2268 } 2175 }
2269 2176
2270 if (m_error && m_error->code() == MediaError::kMediaErrSrcNotSupported) 2177 if (m_error && m_error->code() == MediaError::kMediaErrSrcNotSupported)
2271 return NotSupportedError; 2178 return NotSupportedError;
2272 2179
2273 playInternal(); 2180 playInternal();
2274 2181
2275 return nullptr; 2182 return nullptr;
2276 } 2183 }
2277 2184
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
2324 2231
2325 pauseInternal(); 2232 pauseInternal();
2326 } 2233 }
2327 2234
2328 void HTMLMediaElement::pauseInternal() { 2235 void HTMLMediaElement::pauseInternal() {
2329 BLINK_MEDIA_LOG << "pauseInternal(" << (void*)this << ")"; 2236 BLINK_MEDIA_LOG << "pauseInternal(" << (void*)this << ")";
2330 2237
2331 if (m_networkState == kNetworkEmpty) 2238 if (m_networkState == kNetworkEmpty)
2332 invokeResourceSelectionAlgorithm(); 2239 invokeResourceSelectionAlgorithm();
2333 2240
2334 m_autoplayHelper->pauseMethodCalled();
2335
2336 m_autoplaying = false; 2241 m_autoplaying = false;
2337 2242
2338 if (!m_paused) { 2243 if (!m_paused) {
2339 m_paused = true; 2244 m_paused = true;
2340 scheduleTimeupdateEvent(false); 2245 scheduleTimeupdateEvent(false);
2341 scheduleEvent(EventTypeNames::pause); 2246 scheduleEvent(EventTypeNames::pause);
2342 2247
2343 // Force an update to official playback position. Automatic updates from 2248 // Force an update to official playback position. Automatic updates from
2344 // currentPlaybackPosition() will be blocked while m_paused = true. This 2249 // currentPlaybackPosition() will be blocked while m_paused = true. This
2345 // blocking is desired while paused, but its good to update it one final 2250 // 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; 2353 return;
2449 2354
2450 bool wasAutoplayingMuted = isAutoplayingMuted(); 2355 bool wasAutoplayingMuted = isAutoplayingMuted();
2451 bool wasPendingAutoplayMuted = m_autoplayVisibilityObserver && paused() && 2356 bool wasPendingAutoplayMuted = m_autoplayVisibilityObserver && paused() &&
2452 m_muted && isLockedPendingUserGesture(); 2357 m_muted && isLockedPendingUserGesture();
2453 2358
2454 if (UserGestureIndicator::processingUserGesture()) 2359 if (UserGestureIndicator::processingUserGesture())
2455 unlockUserGesture(); 2360 unlockUserGesture();
2456 2361
2457 m_muted = muted; 2362 m_muted = muted;
2458 m_autoplayHelper->mutedChanged();
2459 2363
2460 scheduleEvent(EventTypeNames::volumechange); 2364 scheduleEvent(EventTypeNames::volumechange);
2461 2365
2462 // If an element autoplayed while muted, it needs to be unlocked to unmute, 2366 // If an element autoplayed while muted, it needs to be unlocked to unmute,
2463 // otherwise, it will be paused. 2367 // otherwise, it will be paused.
2464 if (wasAutoplayingMuted) { 2368 if (wasAutoplayingMuted) {
2465 if (isGestureNeededForPlayback()) { 2369 if (isGestureNeededForPlayback()) {
2466 pause(); 2370 pause();
2467 m_autoplayUmaHelper->recordAutoplayUnmuteStatus( 2371 m_autoplayUmaHelper->recordAutoplayUnmuteStatus(
2468 AutoplayUnmuteActionStatus::Failure); 2372 AutoplayUnmuteActionStatus::Failure);
(...skipping 869 matching lines...) Expand 10 before | Expand all | Expand 10 after
3338 if (shouldBePlaying) { 3242 if (shouldBePlaying) {
3339 setDisplayMode(Video); 3243 setDisplayMode(Video);
3340 3244
3341 if (!isPlaying) { 3245 if (!isPlaying) {
3342 // Set rate, muted before calling play in case they were set before the 3246 // 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 3247 // media engine was setup. The media engine should just stash the rate
3344 // and muted values since it isn't already playing. 3248 // and muted values since it isn't already playing.
3345 webMediaPlayer()->setRate(playbackRate()); 3249 webMediaPlayer()->setRate(playbackRate());
3346 webMediaPlayer()->setVolume(effectiveMediaVolume()); 3250 webMediaPlayer()->setVolume(effectiveMediaVolume());
3347 webMediaPlayer()->play(); 3251 webMediaPlayer()->play();
3348 m_autoplayHelper->playbackStarted();
3349 } 3252 }
3350 3253
3351 if (mediaControls()) 3254 if (mediaControls())
3352 mediaControls()->playbackStarted(); 3255 mediaControls()->playbackStarted();
3353 startPlaybackProgressTimer(); 3256 startPlaybackProgressTimer();
3354 m_playing = true; 3257 m_playing = true;
3355 3258
3356 } else { // Should not be playing right now 3259 } else { // Should not be playing right now
3357 if (isPlaying) { 3260 if (isPlaying) {
3358 webMediaPlayer()->pause(); 3261 webMediaPlayer()->pause();
3359 m_autoplayHelper->playbackStopped();
3360 } 3262 }
3361 3263
3362 m_playbackProgressTimer.stop(); 3264 m_playbackProgressTimer.stop();
3363 m_playing = false; 3265 m_playing = false;
3364 double time = currentTime(); 3266 double time = currentTime();
3365 if (time > m_lastSeekTime) 3267 if (time > m_lastSeekTime)
3366 addPlayedRange(m_lastSeekTime, time); 3268 addPlayedRange(m_lastSeekTime, time);
3367 3269
3368 if (mediaControls()) 3270 if (mediaControls())
3369 mediaControls()->playbackStopped(); 3271 mediaControls()->playbackStopped();
(...skipping 461 matching lines...) Expand 10 before | Expand all | Expand 10 after
3831 visitor->trace(m_mediaSource); 3733 visitor->trace(m_mediaSource);
3832 visitor->trace(m_audioTracks); 3734 visitor->trace(m_audioTracks);
3833 visitor->trace(m_videoTracks); 3735 visitor->trace(m_videoTracks);
3834 visitor->trace(m_cueTimeline); 3736 visitor->trace(m_cueTimeline);
3835 visitor->trace(m_textTracks); 3737 visitor->trace(m_textTracks);
3836 visitor->trace(m_textTracksWhenResourceSelectionBegan); 3738 visitor->trace(m_textTracksWhenResourceSelectionBegan);
3837 visitor->trace(m_playPromiseResolvers); 3739 visitor->trace(m_playPromiseResolvers);
3838 visitor->trace(m_playPromiseResolveList); 3740 visitor->trace(m_playPromiseResolveList);
3839 visitor->trace(m_playPromiseRejectList); 3741 visitor->trace(m_playPromiseRejectList);
3840 visitor->trace(m_audioSourceProvider); 3742 visitor->trace(m_audioSourceProvider);
3841 visitor->trace(m_autoplayHelperClient);
3842 visitor->trace(m_autoplayHelper);
3843 visitor->trace(m_autoplayUmaHelper); 3743 visitor->trace(m_autoplayUmaHelper);
3844 visitor->trace(m_srcObject); 3744 visitor->trace(m_srcObject);
3845 visitor->trace(m_autoplayVisibilityObserver); 3745 visitor->trace(m_autoplayVisibilityObserver);
3846 visitor->template registerWeakMembers<HTMLMediaElement, 3746 visitor->template registerWeakMembers<HTMLMediaElement,
3847 &HTMLMediaElement::clearWeakMembers>( 3747 &HTMLMediaElement::clearWeakMembers>(
3848 this); 3748 this);
3849 Supplementable<HTMLMediaElement>::trace(visitor); 3749 Supplementable<HTMLMediaElement>::trace(visitor);
3850 HTMLElement::trace(visitor); 3750 HTMLElement::trace(visitor);
3851 ActiveDOMObject::trace(visitor); 3751 ActiveDOMObject::trace(visitor);
3852 } 3752 }
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
3910 // - Autoplay is enabled in settings; 3810 // - Autoplay is enabled in settings;
3911 if (isHTMLVideoElement() && muted() && 3811 if (isHTMLVideoElement() && muted() &&
3912 RuntimeEnabledFeatures::autoplayMutedVideosEnabled() && 3812 RuntimeEnabledFeatures::autoplayMutedVideosEnabled() &&
3913 !(document().settings() && document().settings()->dataSaverEnabled()) && 3813 !(document().settings() && document().settings()->dataSaverEnabled()) &&
3914 !(document().settings() && 3814 !(document().settings() &&
3915 document().settings()->forcePreloadNoneForMediaElements()) && 3815 document().settings()->forcePreloadNoneForMediaElements()) &&
3916 isAutoplayAllowedPerSettings()) { 3816 isAutoplayAllowedPerSettings()) {
3917 return false; 3817 return false;
3918 } 3818 }
3919 3819
3920 if (m_autoplayHelper->isGestureRequirementOverridden())
3921 return false;
3922
3923 return true; 3820 return true;
3924 } 3821 }
3925 3822
3926 bool HTMLMediaElement::isAutoplayAllowedPerSettings() const { 3823 bool HTMLMediaElement::isAutoplayAllowedPerSettings() const {
3927 LocalFrame* frame = document().frame(); 3824 LocalFrame* frame = document().frame();
3928 if (!frame) 3825 if (!frame)
3929 return false; 3826 return false;
3930 FrameLoaderClient* frameLoaderClient = frame->loader().client(); 3827 FrameLoaderClient* frameLoaderClient = frame->loader().client();
3931 return frameLoaderClient && frameLoaderClient->allowAutoplay(false); 3828 return frameLoaderClient && frameLoaderClient->allowAutoplay(false);
3932 } 3829 }
3933 3830
3934 void HTMLMediaElement::setNetworkState(NetworkState state) { 3831 void HTMLMediaElement::setNetworkState(NetworkState state) {
3935 if (m_networkState != state) { 3832 if (m_networkState != state) {
3936 m_networkState = state; 3833 m_networkState = state;
3937 if (MediaControls* controls = mediaControls()) 3834 if (MediaControls* controls = mediaControls())
3938 controls->networkStateChanged(); 3835 controls->networkStateChanged();
3939 } 3836 }
3940 } 3837 }
3941 3838
3942 void HTMLMediaElement::videoWillBeDrawnToCanvas() const { 3839 void HTMLMediaElement::videoWillBeDrawnToCanvas() const {
3943 DCHECK(isHTMLVideoElement()); 3840 DCHECK(isHTMLVideoElement());
3944 UseCounter::count(document(), UseCounter::VideoInCanvas); 3841 UseCounter::count(document(), UseCounter::VideoInCanvas);
3945 if (m_autoplayUmaHelper->hasSource() && !m_autoplayUmaHelper->isVisible()) 3842 if (m_autoplayUmaHelper->hasSource() && !m_autoplayUmaHelper->isVisible())
3946 UseCounter::count(document(), UseCounter::HiddenAutoplayedVideoInCanvas); 3843 UseCounter::count(document(), UseCounter::HiddenAutoplayedVideoInCanvas);
3947 } 3844 }
3948 3845
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() { 3846 void HTMLMediaElement::scheduleResolvePlayPromises() {
3967 // TODO(mlamouri): per spec, we should create a new task but we can't create 3847 // 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 3848 // 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 3849 // 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 3850 // 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 3851 // latter approach is preferred because it might be the less observable
3972 // change. 3852 // change.
3973 DCHECK(m_playPromiseResolveList.isEmpty() || 3853 DCHECK(m_playPromiseResolveList.isEmpty() ||
3974 m_playPromiseResolveTaskHandle.isActive()); 3854 m_playPromiseResolveTaskHandle.isActive());
3975 if (m_playPromiseResolvers.isEmpty()) 3855 if (m_playPromiseResolvers.isEmpty())
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after
4154 } 4034 }
4155 4035
4156 DEFINE_TRACE(HTMLMediaElement::AudioClientImpl) { 4036 DEFINE_TRACE(HTMLMediaElement::AudioClientImpl) {
4157 visitor->trace(m_client); 4037 visitor->trace(m_client);
4158 } 4038 }
4159 4039
4160 DEFINE_TRACE(HTMLMediaElement::AudioSourceProviderImpl) { 4040 DEFINE_TRACE(HTMLMediaElement::AudioSourceProviderImpl) {
4161 visitor->trace(m_client); 4041 visitor->trace(m_client);
4162 } 4042 }
4163 4043
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 4044 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698