OLD | NEW |
---|---|
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 20 matching lines...) Expand all Loading... | |
31 #include "bindings/core/v8/Microtask.h" | 31 #include "bindings/core/v8/Microtask.h" |
32 #include "bindings/core/v8/ScriptController.h" | 32 #include "bindings/core/v8/ScriptController.h" |
33 #include "bindings/core/v8/ScriptEventListener.h" | 33 #include "bindings/core/v8/ScriptEventListener.h" |
34 #include "bindings/core/v8/ScriptPromiseResolver.h" | 34 #include "bindings/core/v8/ScriptPromiseResolver.h" |
35 #include "core/HTMLNames.h" | 35 #include "core/HTMLNames.h" |
36 #include "core/css/MediaList.h" | 36 #include "core/css/MediaList.h" |
37 #include "core/dom/Attribute.h" | 37 #include "core/dom/Attribute.h" |
38 #include "core/dom/DOMException.h" | 38 #include "core/dom/DOMException.h" |
39 #include "core/dom/DocumentUserGestureToken.h" | 39 #include "core/dom/DocumentUserGestureToken.h" |
40 #include "core/dom/ElementTraversal.h" | 40 #include "core/dom/ElementTraversal.h" |
41 #include "core/dom/ElementVisibilityObserver.h" | |
42 #include "core/dom/Fullscreen.h" | 41 #include "core/dom/Fullscreen.h" |
43 #include "core/dom/TaskRunnerHelper.h" | 42 #include "core/dom/TaskRunnerHelper.h" |
44 #include "core/dom/shadow/ShadowRoot.h" | 43 #include "core/dom/shadow/ShadowRoot.h" |
45 #include "core/events/Event.h" | 44 #include "core/events/Event.h" |
46 #include "core/frame/ContentSettingsClient.h" | |
47 #include "core/frame/FrameView.h" | 45 #include "core/frame/FrameView.h" |
48 #include "core/frame/LocalFrame.h" | 46 #include "core/frame/LocalFrame.h" |
49 #include "core/frame/LocalFrameClient.h" | 47 #include "core/frame/LocalFrameClient.h" |
50 #include "core/frame/Settings.h" | 48 #include "core/frame/Settings.h" |
51 #include "core/frame/UseCounter.h" | 49 #include "core/frame/UseCounter.h" |
52 #include "core/frame/csp/ContentSecurityPolicy.h" | 50 #include "core/frame/csp/ContentSecurityPolicy.h" |
53 #include "core/html/HTMLSourceElement.h" | 51 #include "core/html/HTMLSourceElement.h" |
54 #include "core/html/HTMLTrackElement.h" | 52 #include "core/html/HTMLTrackElement.h" |
55 #include "core/html/TimeRanges.h" | 53 #include "core/html/TimeRanges.h" |
56 #include "core/html/media/AutoplayUmaHelper.h" | 54 #include "core/html/media/AutoplayPolicy.h" |
57 #include "core/html/media/HTMLMediaElementControlsList.h" | 55 #include "core/html/media/HTMLMediaElementControlsList.h" |
58 #include "core/html/media/HTMLMediaSource.h" | 56 #include "core/html/media/HTMLMediaSource.h" |
59 #include "core/html/media/MediaControls.h" | 57 #include "core/html/media/MediaControls.h" |
60 #include "core/html/media/MediaError.h" | 58 #include "core/html/media/MediaError.h" |
61 #include "core/html/media/MediaFragmentURIParser.h" | 59 #include "core/html/media/MediaFragmentURIParser.h" |
62 #include "core/html/track/AudioTrack.h" | 60 #include "core/html/track/AudioTrack.h" |
63 #include "core/html/track/AudioTrackList.h" | 61 #include "core/html/track/AudioTrackList.h" |
64 #include "core/html/track/AutomaticTrackSelection.h" | 62 #include "core/html/track/AutomaticTrackSelection.h" |
65 #include "core/html/track/CueTimeline.h" | 63 #include "core/html/track/CueTimeline.h" |
66 #include "core/html/track/InbandTextTrack.h" | 64 #include "core/html/track/InbandTextTrack.h" |
(...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
331 | 329 |
332 NOTREACHED(); | 330 NOTREACHED(); |
333 return String(); | 331 return String(); |
334 } | 332 } |
335 | 333 |
336 bool IsDocumentCrossOrigin(Document& document) { | 334 bool IsDocumentCrossOrigin(Document& document) { |
337 const LocalFrame* frame = document.GetFrame(); | 335 const LocalFrame* frame = document.GetFrame(); |
338 return frame && frame->IsCrossOriginSubframe(); | 336 return frame && frame->IsCrossOriginSubframe(); |
339 } | 337 } |
340 | 338 |
341 bool IsDocumentWhitelisted(Document& document) { | |
342 DCHECK(document.GetSettings()); | |
343 | |
344 const String& whitelist_scope = | |
345 document.GetSettings()->GetMediaPlaybackGestureWhitelistScope(); | |
346 if (whitelist_scope.IsNull() || whitelist_scope.IsEmpty()) | |
347 return false; | |
348 | |
349 return document.Url().GetString().StartsWith(whitelist_scope); | |
350 } | |
351 | |
352 // Return true if and only if the document settings specifies media playback | |
353 // requires user gesture. | |
354 bool ComputeLockedPendingUserGesture(Document& document) { | |
355 if (!document.GetSettings()) | |
356 return false; | |
357 | |
358 if (IsDocumentWhitelisted(document)) { | |
359 return false; | |
360 } | |
361 | |
362 if (document.GetSettings() | |
363 ->GetCrossOriginMediaPlaybackRequiresUserGesture() && | |
364 IsDocumentCrossOrigin(document)) { | |
365 return true; | |
366 } | |
367 | |
368 return document.GetSettings()->GetMediaPlaybackRequiresUserGesture(); | |
369 } | |
370 | |
371 std::unique_ptr<MediaControls::Factory>& MediaControlsFactory() { | 339 std::unique_ptr<MediaControls::Factory>& MediaControlsFactory() { |
372 DEFINE_STATIC_LOCAL(std::unique_ptr<MediaControls::Factory>, | 340 DEFINE_STATIC_LOCAL(std::unique_ptr<MediaControls::Factory>, |
373 media_controls_factory, ()); | 341 media_controls_factory, ()); |
374 return media_controls_factory; | 342 return media_controls_factory; |
375 } | 343 } |
376 | 344 |
377 } // anonymous namespace | 345 } // anonymous namespace |
378 | 346 |
379 MIMETypeRegistry::SupportsType HTMLMediaElement::GetSupportsType( | 347 MIMETypeRegistry::SupportsType HTMLMediaElement::GetSupportsType( |
380 const ContentType& content_type) { | 348 const ContentType& content_type) { |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
498 deferred_load_timer_( | 466 deferred_load_timer_( |
499 TaskRunnerHelper::Get(TaskType::kUnthrottled, &document), | 467 TaskRunnerHelper::Get(TaskType::kUnthrottled, &document), |
500 this, | 468 this, |
501 &HTMLMediaElement::DeferredLoadTimerFired), | 469 &HTMLMediaElement::DeferredLoadTimerFired), |
502 web_layer_(nullptr), | 470 web_layer_(nullptr), |
503 display_mode_(kUnknown), | 471 display_mode_(kUnknown), |
504 official_playback_position_(0), | 472 official_playback_position_(0), |
505 official_playback_position_needs_update_(true), | 473 official_playback_position_needs_update_(true), |
506 fragment_end_time_(std::numeric_limits<double>::quiet_NaN()), | 474 fragment_end_time_(std::numeric_limits<double>::quiet_NaN()), |
507 pending_action_flags_(0), | 475 pending_action_flags_(0), |
508 locked_pending_user_gesture_(false), | |
509 locked_pending_user_gesture_if_cross_origin_experiment_enabled_(true), | |
510 playing_(false), | 476 playing_(false), |
511 should_delay_load_event_(false), | 477 should_delay_load_event_(false), |
512 have_fired_loaded_data_(false), | 478 have_fired_loaded_data_(false), |
513 can_autoplay_(true), | 479 can_autoplay_(true), |
514 muted_(false), | 480 muted_(false), |
515 paused_(true), | 481 paused_(true), |
516 seeking_(false), | 482 seeking_(false), |
517 sent_stalled_event_(false), | 483 sent_stalled_event_(false), |
518 ignore_preload_none_(false), | 484 ignore_preload_none_(false), |
519 text_tracks_visible_(false), | 485 text_tracks_visible_(false), |
520 should_perform_automatic_track_selection_(true), | 486 should_perform_automatic_track_selection_(true), |
521 tracks_are_ready_(true), | 487 tracks_are_ready_(true), |
522 processing_preference_change_(false), | 488 processing_preference_change_(false), |
523 playing_remotely_(false), | 489 playing_remotely_(false), |
524 in_overlay_fullscreen_video_(false), | 490 in_overlay_fullscreen_video_(false), |
525 mostly_filling_viewport_(false), | 491 mostly_filling_viewport_(false), |
526 audio_tracks_(this, AudioTrackList::Create(*this)), | 492 audio_tracks_(this, AudioTrackList::Create(*this)), |
527 video_tracks_(this, VideoTrackList::Create(*this)), | 493 video_tracks_(this, VideoTrackList::Create(*this)), |
528 text_tracks_(this, nullptr), | 494 text_tracks_(this, nullptr), |
529 audio_source_node_(nullptr), | 495 audio_source_node_(nullptr), |
530 autoplay_uma_helper_(AutoplayUmaHelper::Create(this)), | 496 autoplay_policy_(new AutoplayPolicy(this)), |
531 remote_playback_client_(nullptr), | 497 remote_playback_client_(nullptr), |
532 autoplay_visibility_observer_(nullptr), | |
533 media_controls_(nullptr), | 498 media_controls_(nullptr), |
534 controls_list_(HTMLMediaElementControlsList::Create(this)) { | 499 controls_list_(HTMLMediaElementControlsList::Create(this)) { |
535 BLINK_MEDIA_LOG << "HTMLMediaElement(" << (void*)this << ")"; | 500 BLINK_MEDIA_LOG << "HTMLMediaElement(" << (void*)this << ")"; |
536 | 501 |
537 locked_pending_user_gesture_ = ComputeLockedPendingUserGesture(document); | |
538 locked_pending_user_gesture_if_cross_origin_experiment_enabled_ = | |
539 IsDocumentCrossOrigin(document); | |
540 | |
541 LocalFrame* frame = document.GetFrame(); | 502 LocalFrame* frame = document.GetFrame(); |
542 if (frame) { | 503 if (frame) { |
543 remote_playback_client_ = | 504 remote_playback_client_ = |
544 frame->Loader().Client()->CreateWebRemotePlaybackClient(*this); | 505 frame->Loader().Client()->CreateWebRemotePlaybackClient(*this); |
545 } | 506 } |
546 | 507 |
547 SetHasCustomStyleCallbacks(); | 508 SetHasCustomStyleCallbacks(); |
548 AddElementToDocumentMap(this, &document); | 509 AddElementToDocumentMap(this, &document); |
549 | 510 |
550 UseCounter::Count(document, UseCounter::kHTMLMediaElement); | 511 UseCounter::Count(document, UseCounter::kHTMLMediaElement); |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
584 TaskRunnerHelper::Get(TaskType::kUnthrottled, &GetDocument())); | 545 TaskRunnerHelper::Get(TaskType::kUnthrottled, &GetDocument())); |
585 audio_tracks_timer_.MoveToNewTaskRunner( | 546 audio_tracks_timer_.MoveToNewTaskRunner( |
586 TaskRunnerHelper::Get(TaskType::kUnthrottled, &GetDocument())); | 547 TaskRunnerHelper::Get(TaskType::kUnthrottled, &GetDocument())); |
587 viewport_fill_debouncer_timer_.MoveToNewTaskRunner( | 548 viewport_fill_debouncer_timer_.MoveToNewTaskRunner( |
588 TaskRunnerHelper::Get(TaskType::kUnthrottled, &GetDocument())); | 549 TaskRunnerHelper::Get(TaskType::kUnthrottled, &GetDocument())); |
589 check_viewport_intersection_timer_.MoveToNewTaskRunner( | 550 check_viewport_intersection_timer_.MoveToNewTaskRunner( |
590 TaskRunnerHelper::Get(TaskType::kUnthrottled, &GetDocument())); | 551 TaskRunnerHelper::Get(TaskType::kUnthrottled, &GetDocument())); |
591 deferred_load_timer_.MoveToNewTaskRunner( | 552 deferred_load_timer_.MoveToNewTaskRunner( |
592 TaskRunnerHelper::Get(TaskType::kUnthrottled, &GetDocument())); | 553 TaskRunnerHelper::Get(TaskType::kUnthrottled, &GetDocument())); |
593 | 554 |
594 autoplay_uma_helper_->DidMoveToNewDocument(old_document); | 555 autoplay_policy_->DidMoveToNewDocument(old_document); |
595 // If any experiment is enabled, then we want to enable a user gesture by | |
596 // default, otherwise the experiment does nothing. | |
597 bool old_document_requires_user_gesture = | |
598 ComputeLockedPendingUserGesture(old_document); | |
599 bool new_document_requires_user_gesture = | |
600 ComputeLockedPendingUserGesture(GetDocument()); | |
601 if (new_document_requires_user_gesture && !old_document_requires_user_gesture) | |
602 locked_pending_user_gesture_ = true; | |
603 | 556 |
604 if (should_delay_load_event_) { | 557 if (should_delay_load_event_) { |
605 GetDocument().IncrementLoadEventDelayCount(); | 558 GetDocument().IncrementLoadEventDelayCount(); |
606 // Note: Keeping the load event delay count increment on oldDocument that | 559 // Note: Keeping the load event delay count increment on oldDocument that |
607 // was added when m_shouldDelayLoadEvent was set so that destruction of | 560 // was added when m_shouldDelayLoadEvent was set so that destruction of |
608 // m_webMediaPlayer can not cause load event dispatching in oldDocument. | 561 // m_webMediaPlayer can not cause load event dispatching in oldDocument. |
609 } else { | 562 } else { |
610 // Incrementing the load event delay count so that destruction of | 563 // Incrementing the load event delay count so that destruction of |
611 // m_webMediaPlayer can not cause load event dispatching in oldDocument. | 564 // m_webMediaPlayer can not cause load event dispatching in oldDocument. |
612 old_document.IncrementLoadEventDelayCount(); | 565 old_document.IncrementLoadEventDelayCount(); |
613 } | 566 } |
614 | 567 |
615 if (IsDocumentCrossOrigin(GetDocument()) && | |
616 !IsDocumentCrossOrigin(old_document)) | |
617 locked_pending_user_gesture_if_cross_origin_experiment_enabled_ = true; | |
618 | |
619 RemoveElementFromDocumentMap(this, &old_document); | 568 RemoveElementFromDocumentMap(this, &old_document); |
620 AddElementToDocumentMap(this, &GetDocument()); | 569 AddElementToDocumentMap(this, &GetDocument()); |
621 | 570 |
622 // FIXME: This is a temporary fix to prevent this object from causing the | 571 // FIXME: This is a temporary fix to prevent this object from causing the |
623 // MediaPlayer to dereference LocalFrame and FrameLoader pointers from the | 572 // MediaPlayer to dereference LocalFrame and FrameLoader pointers from the |
624 // previous document. This restarts the load, as if the src attribute had been | 573 // previous document. This restarts the load, as if the src attribute had been |
625 // set. A proper fix would provide a mechanism to allow this object to | 574 // set. A proper fix would provide a mechanism to allow this object to |
626 // refresh the MediaPlayer's LocalFrame and FrameLoader references on document | 575 // refresh the MediaPlayer's LocalFrame and FrameLoader references on document |
627 // changes so that playback can be resumed properly. | 576 // changes so that playback can be resumed properly. |
628 ignore_preload_none_ = false; | 577 ignore_preload_none_ = false; |
(...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
838 | 787 |
839 BLINK_MEDIA_LOG << "canPlayType(" << (void*)this << ", " << mime_type | 788 BLINK_MEDIA_LOG << "canPlayType(" << (void*)this << ", " << mime_type |
840 << ") -> " << can_play; | 789 << ") -> " << can_play; |
841 | 790 |
842 return can_play; | 791 return can_play; |
843 } | 792 } |
844 | 793 |
845 void HTMLMediaElement::load() { | 794 void HTMLMediaElement::load() { |
846 BLINK_MEDIA_LOG << "load(" << (void*)this << ")"; | 795 BLINK_MEDIA_LOG << "load(" << (void*)this << ")"; |
847 | 796 |
848 if (IsLockedPendingUserGesture() && | 797 autoplay_policy_->TryUnlockingUserGesture(); |
849 UserGestureIndicator::UtilizeUserGesture()) { | |
850 UnlockUserGesture(); | |
851 } | |
852 | 798 |
853 ignore_preload_none_ = true; | 799 ignore_preload_none_ = true; |
854 InvokeLoadAlgorithm(); | 800 InvokeLoadAlgorithm(); |
855 } | 801 } |
856 | 802 |
857 // TODO(srirama.m): Currently m_ignorePreloadNone is reset before calling | 803 // TODO(srirama.m): Currently m_ignorePreloadNone is reset before calling |
858 // invokeLoadAlgorithm() in all places except load(). Move it inside here | 804 // invokeLoadAlgorithm() in all places except load(). Move it inside here |
859 // once microtask is implemented for "Await a stable state" step | 805 // once microtask is implemented for "Await a stable state" step |
860 // in resource selection algorithm. | 806 // in resource selection algorithm. |
861 void HTMLMediaElement::InvokeLoadAlgorithm() { | 807 void HTMLMediaElement::InvokeLoadAlgorithm() { |
(...skipping 970 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1832 } | 1778 } |
1833 | 1779 |
1834 if (ready_state_ == kHaveEnoughData && old_state < kHaveEnoughData && | 1780 if (ready_state_ == kHaveEnoughData && old_state < kHaveEnoughData && |
1835 tracks_are_ready) { | 1781 tracks_are_ready) { |
1836 if (old_state <= kHaveCurrentData) { | 1782 if (old_state <= kHaveCurrentData) { |
1837 ScheduleEvent(EventTypeNames::canplay); | 1783 ScheduleEvent(EventTypeNames::canplay); |
1838 if (is_potentially_playing) | 1784 if (is_potentially_playing) |
1839 ScheduleNotifyPlaying(); | 1785 ScheduleNotifyPlaying(); |
1840 } | 1786 } |
1841 | 1787 |
1842 // Check for autoplay, and record metrics about it if needed. | 1788 if (autoplay_policy_->RequestAutoplayByAttribute()) { |
mlamouri (slow - plz ping)
2017/04/19 14:09:55
So much clean up \o/
| |
1843 if (ShouldAutoplay()) { | 1789 paused_ = false; |
1844 autoplay_uma_helper_->OnAutoplayInitiated(AutoplaySource::kAttribute); | 1790 ScheduleEvent(EventTypeNames::play); |
1845 | 1791 ScheduleNotifyPlaying(); |
1846 if (!IsGestureNeededForPlayback()) { | 1792 can_autoplay_ = false; |
1847 if (IsGestureNeededForPlaybackIfCrossOriginExperimentEnabled()) { | |
1848 autoplay_uma_helper_->RecordCrossOriginAutoplayResult( | |
1849 CrossOriginAutoplayResult::kAutoplayBlocked); | |
1850 } else { | |
1851 autoplay_uma_helper_->RecordCrossOriginAutoplayResult( | |
1852 CrossOriginAutoplayResult::kAutoplayAllowed); | |
1853 } | |
1854 if (IsHTMLVideoElement() && muted() && | |
1855 RuntimeEnabledFeatures::autoplayMutedVideosEnabled()) { | |
1856 // We might end up in a situation where the previous | |
1857 // observer didn't had time to fire yet. We can avoid | |
1858 // creating a new one in this case. | |
1859 if (!autoplay_visibility_observer_) { | |
1860 autoplay_visibility_observer_ = new ElementVisibilityObserver( | |
1861 this, | |
1862 WTF::Bind(&HTMLMediaElement::OnVisibilityChangedForAutoplay, | |
1863 WrapWeakPersistent(this))); | |
1864 autoplay_visibility_observer_->Start(); | |
1865 } | |
1866 } else { | |
1867 paused_ = false; | |
1868 ScheduleEvent(EventTypeNames::play); | |
1869 ScheduleNotifyPlaying(); | |
1870 can_autoplay_ = false; | |
1871 } | |
1872 } else { | |
1873 autoplay_uma_helper_->RecordCrossOriginAutoplayResult( | |
1874 CrossOriginAutoplayResult::kAutoplayBlocked); | |
1875 } | |
1876 } | 1793 } |
1877 | 1794 |
1878 ScheduleEvent(EventTypeNames::canplaythrough); | 1795 ScheduleEvent(EventTypeNames::canplaythrough); |
1879 | 1796 |
1880 should_update_display_state = true; | 1797 should_update_display_state = true; |
1881 } | 1798 } |
1882 | 1799 |
1883 if (should_update_display_state) | 1800 if (should_update_display_state) |
1884 UpdateDisplayState(); | 1801 UpdateDisplayState(); |
1885 | 1802 |
(...skipping 320 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2206 // 4.8.12.8 Playing the media resource | 2123 // 4.8.12.8 Playing the media resource |
2207 // The ended attribute must return true if the media element has ended | 2124 // The ended attribute must return true if the media element has ended |
2208 // playback and the direction of playback is forwards, and false otherwise. | 2125 // playback and the direction of playback is forwards, and false otherwise. |
2209 return EndedPlayback() && GetDirectionOfPlayback() == kForward; | 2126 return EndedPlayback() && GetDirectionOfPlayback() == kForward; |
2210 } | 2127 } |
2211 | 2128 |
2212 bool HTMLMediaElement::Autoplay() const { | 2129 bool HTMLMediaElement::Autoplay() const { |
2213 return FastHasAttribute(autoplayAttr); | 2130 return FastHasAttribute(autoplayAttr); |
2214 } | 2131 } |
2215 | 2132 |
2216 bool HTMLMediaElement::ShouldAutoplay() { | |
2217 if (GetDocument().IsSandboxed(kSandboxAutomaticFeatures)) | |
2218 return false; | |
2219 return can_autoplay_ && paused_ && Autoplay(); | |
2220 } | |
2221 | |
2222 String HTMLMediaElement::preload() const { | 2133 String HTMLMediaElement::preload() const { |
2223 return PreloadTypeToString(PreloadType()); | 2134 return PreloadTypeToString(PreloadType()); |
2224 } | 2135 } |
2225 | 2136 |
2226 void HTMLMediaElement::setPreload(const AtomicString& preload) { | 2137 void HTMLMediaElement::setPreload(const AtomicString& preload) { |
2227 BLINK_MEDIA_LOG << "setPreload(" << (void*)this << ", " << preload << ")"; | 2138 BLINK_MEDIA_LOG << "setPreload(" << (void*)this << ", " << preload << ")"; |
2228 setAttribute(preloadAttr, preload); | 2139 setAttribute(preloadAttr, preload); |
2229 } | 2140 } |
2230 | 2141 |
2231 WebMediaPlayer::Preload HTMLMediaElement::PreloadType() const { | 2142 WebMediaPlayer::Preload HTMLMediaElement::PreloadType() const { |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2276 // https://crbug.com/310450 | 2187 // https://crbug.com/310450 |
2277 UseCounter::Count(GetDocument(), UseCounter::kHTMLMediaElementPreloadDefault); | 2188 UseCounter::Count(GetDocument(), UseCounter::kHTMLMediaElementPreloadDefault); |
2278 return WebMediaPlayer::kPreloadAuto; | 2189 return WebMediaPlayer::kPreloadAuto; |
2279 } | 2190 } |
2280 | 2191 |
2281 String HTMLMediaElement::EffectivePreload() const { | 2192 String HTMLMediaElement::EffectivePreload() const { |
2282 return PreloadTypeToString(EffectivePreloadType()); | 2193 return PreloadTypeToString(EffectivePreloadType()); |
2283 } | 2194 } |
2284 | 2195 |
2285 WebMediaPlayer::Preload HTMLMediaElement::EffectivePreloadType() const { | 2196 WebMediaPlayer::Preload HTMLMediaElement::EffectivePreloadType() const { |
2286 if (Autoplay() && !IsGestureNeededForPlayback()) | 2197 if (Autoplay() && !autoplay_policy_->IsGestureNeededForPlayback()) |
2287 return WebMediaPlayer::kPreloadAuto; | 2198 return WebMediaPlayer::kPreloadAuto; |
2288 | 2199 |
2289 WebMediaPlayer::Preload preload = PreloadType(); | 2200 WebMediaPlayer::Preload preload = PreloadType(); |
2290 if (ignore_preload_none_ && preload == WebMediaPlayer::kPreloadNone) | 2201 if (ignore_preload_none_ && preload == WebMediaPlayer::kPreloadNone) |
2291 return WebMediaPlayer::kPreloadMetaData; | 2202 return WebMediaPlayer::kPreloadMetaData; |
2292 | 2203 |
2293 return preload; | 2204 return preload; |
2294 } | 2205 } |
2295 | 2206 |
2296 ScriptPromise HTMLMediaElement::playForBindings(ScriptState* script_state) { | 2207 ScriptPromise HTMLMediaElement::playForBindings(ScriptState* script_state) { |
(...skipping 25 matching lines...) Expand all Loading... | |
2322 resolver->Reject(DOMException::Create(code.Get(), message)); | 2233 resolver->Reject(DOMException::Create(code.Get(), message)); |
2323 return promise; | 2234 return promise; |
2324 } | 2235 } |
2325 | 2236 |
2326 return promise; | 2237 return promise; |
2327 } | 2238 } |
2328 | 2239 |
2329 Nullable<ExceptionCode> HTMLMediaElement::Play() { | 2240 Nullable<ExceptionCode> HTMLMediaElement::Play() { |
2330 BLINK_MEDIA_LOG << "play(" << (void*)this << ")"; | 2241 BLINK_MEDIA_LOG << "play(" << (void*)this << ")"; |
2331 | 2242 |
2332 if (!UserGestureIndicator::ProcessingUserGesture()) { | 2243 // The only place to call RequestPlay(), don't call from anywhere else! |
mlamouri (slow - plz ping)
2017/04/19 14:09:55
I would move this to the header of AutoplayPolicy.
Zhiqiang Zhang (Slow)
2017/04/20 10:30:45
Done.
| |
2333 autoplay_uma_helper_->OnAutoplayInitiated(AutoplaySource::kMethod); | 2244 Nullable<ExceptionCode> exception_code = autoplay_policy_->RequestPlay(); |
mlamouri (slow - plz ping)
2017/04/19 14:09:55
neat! :)
| |
2334 if (IsGestureNeededForPlayback()) { | |
2335 // If we're already playing, then this play would do nothing anyway. | |
2336 // Call playInternal to handle scheduling the promise resolution. | |
2337 if (!paused_) { | |
2338 PlayInternal(); | |
2339 return nullptr; | |
2340 } | |
2341 | 2245 |
2342 autoplay_uma_helper_->RecordCrossOriginAutoplayResult( | 2246 if (exception_code == kNotAllowedError) { |
2343 CrossOriginAutoplayResult::kAutoplayBlocked); | 2247 // If we're already playing, then this play would do nothing anyway. |
2344 String message = ExceptionMessages::FailedToExecute( | 2248 // Call playInternal to handle scheduling the promise resolution. |
2345 "play", "HTMLMediaElement", | 2249 if (!paused_) { |
2346 "API can only be initiated by a user gesture."); | 2250 PlayInternal(); |
2347 GetDocument().AddConsoleMessage(ConsoleMessage::Create( | 2251 return nullptr; |
2348 kJSMessageSource, kWarningMessageLevel, message)); | |
2349 return kNotAllowedError; | |
2350 } else { | |
2351 if (IsGestureNeededForPlaybackIfCrossOriginExperimentEnabled()) { | |
2352 autoplay_uma_helper_->RecordCrossOriginAutoplayResult( | |
2353 CrossOriginAutoplayResult::kAutoplayBlocked); | |
2354 } else { | |
2355 autoplay_uma_helper_->RecordCrossOriginAutoplayResult( | |
2356 CrossOriginAutoplayResult::kAutoplayAllowed); | |
2357 } | |
2358 } | 2252 } |
2359 } else { | 2253 String message = ExceptionMessages::FailedToExecute( |
2360 autoplay_uma_helper_->RecordCrossOriginAutoplayResult( | 2254 "play", "HTMLMediaElement", |
2361 CrossOriginAutoplayResult::kPlayedWithGesture); | 2255 "API can only be initiated by a user gesture."); |
2362 UserGestureIndicator::UtilizeUserGesture(); | 2256 GetDocument().AddConsoleMessage(ConsoleMessage::Create( |
2363 UnlockUserGesture(); | 2257 kJSMessageSource, kWarningMessageLevel, message)); |
2258 return exception_code; | |
2364 } | 2259 } |
2365 | 2260 |
2261 autoplay_policy_->StopAutoplayMutedWhenVisible(); | |
2262 | |
2366 if (error_ && error_->code() == MediaError::kMediaErrSrcNotSupported) | 2263 if (error_ && error_->code() == MediaError::kMediaErrSrcNotSupported) |
2367 return kNotSupportedError; | 2264 return kNotSupportedError; |
2368 | 2265 |
2369 if (autoplay_visibility_observer_) { | 2266 DCHECK(exception_code.IsNull()); |
2370 autoplay_visibility_observer_->Stop(); | |
2371 autoplay_visibility_observer_ = nullptr; | |
2372 } | |
2373 | 2267 |
2374 PlayInternal(); | 2268 PlayInternal(); |
2375 | 2269 |
2376 return nullptr; | 2270 return nullptr; |
2377 } | 2271 } |
2378 | 2272 |
2379 void HTMLMediaElement::PlayInternal() { | 2273 void HTMLMediaElement::PlayInternal() { |
2380 BLINK_MEDIA_LOG << "playInternal(" << (void*)this << ")"; | 2274 BLINK_MEDIA_LOG << "playInternal(" << (void*)this << ")"; |
2381 | 2275 |
2382 // 4.8.12.8. Playing the media resource | 2276 // 4.8.12.8. Playing the media resource |
(...skipping 20 matching lines...) Expand all Loading... | |
2403 | 2297 |
2404 can_autoplay_ = false; | 2298 can_autoplay_ = false; |
2405 | 2299 |
2406 SetIgnorePreloadNone(); | 2300 SetIgnorePreloadNone(); |
2407 UpdatePlayState(); | 2301 UpdatePlayState(); |
2408 } | 2302 } |
2409 | 2303 |
2410 void HTMLMediaElement::pause() { | 2304 void HTMLMediaElement::pause() { |
2411 BLINK_MEDIA_LOG << "pause(" << (void*)this << ")"; | 2305 BLINK_MEDIA_LOG << "pause(" << (void*)this << ")"; |
2412 | 2306 |
2413 if (autoplay_visibility_observer_) { | 2307 autoplay_policy_->StopAutoplayMutedWhenVisible(); |
2414 autoplay_visibility_observer_->Stop(); | |
2415 autoplay_visibility_observer_ = nullptr; | |
2416 } | |
2417 | |
2418 PauseInternal(); | 2308 PauseInternal(); |
2419 } | 2309 } |
2420 | 2310 |
2421 void HTMLMediaElement::PauseInternal() { | 2311 void HTMLMediaElement::PauseInternal() { |
2422 BLINK_MEDIA_LOG << "pauseInternal(" << (void*)this << ")"; | 2312 BLINK_MEDIA_LOG << "pauseInternal(" << (void*)this << ")"; |
2423 | 2313 |
2424 if (network_state_ == kNetworkEmpty) | 2314 if (network_state_ == kNetworkEmpty) |
2425 InvokeResourceSelectionAlgorithm(); | 2315 InvokeResourceSelectionAlgorithm(); |
2426 | 2316 |
2427 can_autoplay_ = false; | 2317 can_autoplay_ = false; |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2555 return muted_; | 2445 return muted_; |
2556 } | 2446 } |
2557 | 2447 |
2558 void HTMLMediaElement::setMuted(bool muted) { | 2448 void HTMLMediaElement::setMuted(bool muted) { |
2559 BLINK_MEDIA_LOG << "setMuted(" << (void*)this << ", " << BoolString(muted) | 2449 BLINK_MEDIA_LOG << "setMuted(" << (void*)this << ", " << BoolString(muted) |
2560 << ")"; | 2450 << ")"; |
2561 | 2451 |
2562 if (muted_ == muted) | 2452 if (muted_ == muted) |
2563 return; | 2453 return; |
2564 | 2454 |
2565 bool was_autoplaying_muted = IsAutoplayingMuted(); | 2455 // TODO(zqzhang): use TryUnlockingUserGesture? |
2566 bool was_pending_autoplay_muted = autoplay_visibility_observer_ && paused() && | 2456 if (UserGestureIndicator::ProcessingUserGesture()) |
2567 muted_ && IsLockedPendingUserGesture(); | 2457 autoplay_policy_->UnlockUserGesture(); |
2568 | 2458 |
2569 if (UserGestureIndicator::ProcessingUserGesture()) | 2459 bool should_pause_after_unmute = autoplay_policy_->RequestAutoplayUnmute(); |
mlamouri (slow - plz ping)
2017/04/19 14:09:55
This is checking if there is a lock but the lock w
Zhiqiang Zhang (Slow)
2017/04/20 10:30:45
Moved all these logic to AutoplayPolicy. The gestu
| |
2570 UnlockUserGesture(); | |
2571 | 2460 |
2572 muted_ = muted; | 2461 muted_ = muted; |
2573 | 2462 |
2574 ScheduleEvent(EventTypeNames::volumechange); | 2463 ScheduleEvent(EventTypeNames::volumechange); |
2575 | 2464 |
2576 // If an element autoplayed while muted, it needs to be unlocked to unmute, | 2465 if (should_pause_after_unmute) |
2577 // otherwise, it will be paused. | 2466 pause(); |
2578 if (was_autoplaying_muted) { | |
2579 if (IsGestureNeededForPlayback()) { | |
2580 pause(); | |
2581 autoplay_uma_helper_->RecordAutoplayUnmuteStatus( | |
2582 AutoplayUnmuteActionStatus::kFailure); | |
2583 } else { | |
2584 autoplay_uma_helper_->RecordAutoplayUnmuteStatus( | |
2585 AutoplayUnmuteActionStatus::kSuccess); | |
2586 } | |
2587 } | |
2588 | 2467 |
2589 // This is called after the volumechange event to make sure isAutoplayingMuted | 2468 // This is called after the volumechange event to make sure isAutoplayingMuted |
2590 // returns the right value when webMediaPlayer receives the volume update. | 2469 // returns the right value when webMediaPlayer receives the volume update. |
2591 if (GetWebMediaPlayer()) | 2470 if (GetWebMediaPlayer()) |
2592 GetWebMediaPlayer()->SetVolume(EffectiveMediaVolume()); | 2471 GetWebMediaPlayer()->SetVolume(EffectiveMediaVolume()); |
2593 | 2472 |
2594 // If an element was a candidate for autoplay muted but not visible, it will | 2473 autoplay_policy_->StopAutoplayMutedWhenVisible(); |
2595 // have a visibility observer ready to start its playback. | |
2596 if (was_pending_autoplay_muted) { | |
2597 autoplay_visibility_observer_->Stop(); | |
2598 autoplay_visibility_observer_ = nullptr; | |
2599 } | |
2600 } | 2474 } |
2601 | 2475 |
2602 double HTMLMediaElement::EffectiveMediaVolume() const { | 2476 double HTMLMediaElement::EffectiveMediaVolume() const { |
2603 if (muted_) | 2477 if (muted_) |
2604 return 0; | 2478 return 0; |
2605 | 2479 |
2606 return volume_; | 2480 return volume_; |
2607 } | 2481 } |
2608 | 2482 |
2609 // The spec says to fire periodic timeupdate events (those sent while playing) | 2483 // The spec says to fire periodic timeupdate events (those sent while playing) |
(...skipping 701 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3311 WebMediaPlayer::TrackId HTMLMediaElement::GetSelectedVideoTrackId() { | 3185 WebMediaPlayer::TrackId HTMLMediaElement::GetSelectedVideoTrackId() { |
3312 DCHECK(RuntimeEnabledFeatures::backgroundVideoTrackOptimizationEnabled()); | 3186 DCHECK(RuntimeEnabledFeatures::backgroundVideoTrackOptimizationEnabled()); |
3313 DCHECK(HasSelectedVideoTrack()); | 3187 DCHECK(HasSelectedVideoTrack()); |
3314 | 3188 |
3315 int selected_track_index = video_tracks_->selectedIndex(); | 3189 int selected_track_index = video_tracks_->selectedIndex(); |
3316 VideoTrack* track = | 3190 VideoTrack* track = |
3317 video_tracks_->AnonymousIndexedGetter(selected_track_index); | 3191 video_tracks_->AnonymousIndexedGetter(selected_track_index); |
3318 return track->id(); | 3192 return track->id(); |
3319 } | 3193 } |
3320 | 3194 |
3321 bool HTMLMediaElement::IsAutoplayingMuted() { | |
3322 if (!IsHTMLVideoElement() || | |
3323 !RuntimeEnabledFeatures::autoplayMutedVideosEnabled()) { | |
3324 return false; | |
3325 } | |
3326 | |
3327 return !paused() && muted() && IsLockedPendingUserGesture(); | |
3328 } | |
3329 | |
3330 void HTMLMediaElement::RequestReload(const WebURL& new_url) { | 3195 void HTMLMediaElement::RequestReload(const WebURL& new_url) { |
3331 DCHECK(GetWebMediaPlayer()); | 3196 DCHECK(GetWebMediaPlayer()); |
3332 DCHECK(!src_object_); | 3197 DCHECK(!src_object_); |
3333 DCHECK(new_url.IsValid()); | 3198 DCHECK(new_url.IsValid()); |
3334 DCHECK(IsSafeToLoadURL(new_url, kComplain)); | 3199 DCHECK(IsSafeToLoadURL(new_url, kComplain)); |
3335 ResetMediaPlayerAndMediaSource(); | 3200 ResetMediaPlayerAndMediaSource(); |
3336 StartPlayerLoad(new_url); | 3201 StartPlayerLoad(new_url); |
3337 } | 3202 } |
3338 | 3203 |
3204 bool HTMLMediaElement::IsAutoplayingMuted() { | |
3205 return autoplay_policy_->IsAutoplayingMuted(); | |
3206 } | |
3207 | |
3339 // MediaPlayerPresentation methods | 3208 // MediaPlayerPresentation methods |
3340 void HTMLMediaElement::Repaint() { | 3209 void HTMLMediaElement::Repaint() { |
3341 if (web_layer_) | 3210 if (web_layer_) |
3342 web_layer_->Invalidate(); | 3211 web_layer_->Invalidate(); |
3343 | 3212 |
3344 UpdateDisplayState(); | 3213 UpdateDisplayState(); |
3345 if (GetLayoutObject()) | 3214 if (GetLayoutObject()) |
3346 GetLayoutObject()->SetShouldDoFullPaintInvalidation(); | 3215 GetLayoutObject()->SetShouldDoFullPaintInvalidation(); |
3347 } | 3216 } |
3348 | 3217 |
(...skipping 575 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3924 visitor->Trace(media_source_); | 3793 visitor->Trace(media_source_); |
3925 visitor->Trace(audio_tracks_); | 3794 visitor->Trace(audio_tracks_); |
3926 visitor->Trace(video_tracks_); | 3795 visitor->Trace(video_tracks_); |
3927 visitor->Trace(cue_timeline_); | 3796 visitor->Trace(cue_timeline_); |
3928 visitor->Trace(text_tracks_); | 3797 visitor->Trace(text_tracks_); |
3929 visitor->Trace(text_tracks_when_resource_selection_began_); | 3798 visitor->Trace(text_tracks_when_resource_selection_began_); |
3930 visitor->Trace(play_promise_resolvers_); | 3799 visitor->Trace(play_promise_resolvers_); |
3931 visitor->Trace(play_promise_resolve_list_); | 3800 visitor->Trace(play_promise_resolve_list_); |
3932 visitor->Trace(play_promise_reject_list_); | 3801 visitor->Trace(play_promise_reject_list_); |
3933 visitor->Trace(audio_source_provider_); | 3802 visitor->Trace(audio_source_provider_); |
3934 visitor->Trace(autoplay_uma_helper_); | |
3935 visitor->Trace(src_object_); | 3803 visitor->Trace(src_object_); |
3936 visitor->Trace(autoplay_visibility_observer_); | 3804 visitor->Trace(autoplay_policy_); |
3937 visitor->Trace(media_controls_); | 3805 visitor->Trace(media_controls_); |
3938 visitor->Trace(controls_list_); | 3806 visitor->Trace(controls_list_); |
3939 visitor->template RegisterWeakMembers<HTMLMediaElement, | 3807 visitor->template RegisterWeakMembers<HTMLMediaElement, |
3940 &HTMLMediaElement::ClearWeakMembers>( | 3808 &HTMLMediaElement::ClearWeakMembers>( |
3941 this); | 3809 this); |
3942 Supplementable<HTMLMediaElement>::Trace(visitor); | 3810 Supplementable<HTMLMediaElement>::Trace(visitor); |
3943 HTMLElement::Trace(visitor); | 3811 HTMLElement::Trace(visitor); |
3944 SuspendableObject::Trace(visitor); | 3812 SuspendableObject::Trace(visitor); |
3945 } | 3813 } |
3946 | 3814 |
(...skipping 29 matching lines...) Expand all Loading... | |
3976 | 3844 |
3977 // Enable the first audio track if an audio track hasn't been enabled yet. | 3845 // Enable the first audio track if an audio track hasn't been enabled yet. |
3978 if (audioTracks().length() > 0 && !audioTracks().HasEnabledTrack()) | 3846 if (audioTracks().length() > 0 && !audioTracks().HasEnabledTrack()) |
3979 audioTracks().AnonymousIndexedGetter(0)->setEnabled(true); | 3847 audioTracks().AnonymousIndexedGetter(0)->setEnabled(true); |
3980 | 3848 |
3981 // Select the first video track if a video track hasn't been selected yet. | 3849 // Select the first video track if a video track hasn't been selected yet. |
3982 if (videoTracks().length() > 0 && videoTracks().selectedIndex() == -1) | 3850 if (videoTracks().length() > 0 && videoTracks().selectedIndex() == -1) |
3983 videoTracks().AnonymousIndexedGetter(0)->setSelected(true); | 3851 videoTracks().AnonymousIndexedGetter(0)->setSelected(true); |
3984 } | 3852 } |
3985 | 3853 |
3986 bool HTMLMediaElement::IsLockedPendingUserGesture() const { | |
3987 return locked_pending_user_gesture_; | |
3988 } | |
3989 | |
3990 void HTMLMediaElement::UnlockUserGesture() { | |
3991 locked_pending_user_gesture_ = false; | |
3992 locked_pending_user_gesture_if_cross_origin_experiment_enabled_ = false; | |
3993 } | |
3994 | |
3995 bool HTMLMediaElement::IsGestureNeededForPlayback() const { | |
3996 if (!locked_pending_user_gesture_) | |
3997 return false; | |
3998 | |
3999 return IsGestureNeededForPlaybackIfPendingUserGestureIsLocked(); | |
4000 } | |
4001 | |
4002 bool HTMLMediaElement:: | |
4003 IsGestureNeededForPlaybackIfCrossOriginExperimentEnabled() const { | |
4004 if (!locked_pending_user_gesture_if_cross_origin_experiment_enabled_) | |
4005 return false; | |
4006 | |
4007 return IsGestureNeededForPlaybackIfPendingUserGestureIsLocked(); | |
4008 } | |
4009 | |
4010 bool HTMLMediaElement::IsGestureNeededForPlaybackIfPendingUserGestureIsLocked() | |
4011 const { | |
4012 if (GetLoadType() == WebMediaPlayer::kLoadTypeMediaStream) | |
4013 return false; | |
4014 | |
4015 // We want to allow muted video to autoplay if: | |
4016 // - the flag is enabled; | |
4017 // - Data Saver is not enabled; | |
4018 // - Preload was not disabled (low end devices); | |
4019 // - Autoplay is enabled in settings; | |
4020 if (IsHTMLVideoElement() && muted() && | |
4021 RuntimeEnabledFeatures::autoplayMutedVideosEnabled() && | |
4022 !(GetDocument().GetSettings() && | |
4023 GetDocument().GetSettings()->GetDataSaverEnabled()) && | |
4024 !(GetDocument().GetSettings() && | |
4025 GetDocument().GetSettings()->GetForcePreloadNoneForMediaElements()) && | |
4026 IsAutoplayAllowedPerSettings()) { | |
4027 return false; | |
4028 } | |
4029 | |
4030 return true; | |
4031 } | |
4032 | |
4033 bool HTMLMediaElement::IsAutoplayAllowedPerSettings() const { | |
4034 LocalFrame* frame = GetDocument().GetFrame(); | |
4035 if (!frame) | |
4036 return false; | |
4037 return frame->GetContentSettingsClient()->AllowAutoplay(true); | |
4038 } | |
4039 | |
4040 void HTMLMediaElement::SetNetworkState(NetworkState state) { | 3854 void HTMLMediaElement::SetNetworkState(NetworkState state) { |
4041 if (network_state_ == state) | 3855 if (network_state_ == state) |
4042 return; | 3856 return; |
4043 | 3857 |
4044 network_state_ = state; | 3858 network_state_ = state; |
4045 if (GetMediaControls()) | 3859 if (GetMediaControls()) |
4046 GetMediaControls()->NetworkStateChanged(); | 3860 GetMediaControls()->NetworkStateChanged(); |
4047 } | 3861 } |
4048 | 3862 |
4049 void HTMLMediaElement::VideoWillBeDrawnToCanvas() const { | 3863 void HTMLMediaElement::VideoWillBeDrawnToCanvas() const { |
4050 DCHECK(IsHTMLVideoElement()); | 3864 DCHECK(IsHTMLVideoElement()); |
4051 UseCounter::Count(GetDocument(), UseCounter::kVideoInCanvas); | 3865 UseCounter::Count(GetDocument(), UseCounter::kVideoInCanvas); |
4052 if (autoplay_uma_helper_->HasSource() && !autoplay_uma_helper_->IsVisible()) | |
4053 UseCounter::Count(GetDocument(), | |
4054 UseCounter::kHiddenAutoplayedVideoInCanvas); | |
4055 } | 3866 } |
mlamouri (slow - plz ping)
2017/04/19 14:09:55
Aren't you missing the autoplay_policy_ call here?
Zhiqiang Zhang (Slow)
2017/04/20 10:30:45
Yes indeed. Done.
| |
4056 | 3867 |
4057 void HTMLMediaElement::ScheduleResolvePlayPromises() { | 3868 void HTMLMediaElement::ScheduleResolvePlayPromises() { |
4058 // TODO(mlamouri): per spec, we should create a new task but we can't create | 3869 // TODO(mlamouri): per spec, we should create a new task but we can't create |
4059 // a new cancellable task without cancelling the previous one. There are two | 3870 // a new cancellable task without cancelling the previous one. There are two |
4060 // approaches then: cancel the previous task and create a new one with the | 3871 // approaches then: cancel the previous task and create a new one with the |
4061 // appended promise list or append the new promise to the current list. The | 3872 // appended promise list or append the new promise to the current list. The |
4062 // latter approach is preferred because it might be the less observable | 3873 // latter approach is preferred because it might be the less observable |
4063 // change. | 3874 // change. |
4064 DCHECK(play_promise_resolve_list_.IsEmpty() || | 3875 DCHECK(play_promise_resolve_list_.IsEmpty() || |
4065 play_promise_resolve_task_handle_.IsActive()); | 3876 play_promise_resolve_task_handle_.IsActive()); |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4159 DEFINE_STATIC_LOCAL(EnumerationHistogram, histogram, | 3970 DEFINE_STATIC_LOCAL(EnumerationHistogram, histogram, |
4160 ("Media.Controls.Show.Video", kMediaControlsShowMax)); | 3971 ("Media.Controls.Show.Video", kMediaControlsShowMax)); |
4161 return histogram; | 3972 return histogram; |
4162 } | 3973 } |
4163 | 3974 |
4164 DEFINE_STATIC_LOCAL(EnumerationHistogram, histogram, | 3975 DEFINE_STATIC_LOCAL(EnumerationHistogram, histogram, |
4165 ("Media.Controls.Show.Audio", kMediaControlsShowMax)); | 3976 ("Media.Controls.Show.Audio", kMediaControlsShowMax)); |
4166 return histogram; | 3977 return histogram; |
4167 } | 3978 } |
4168 | 3979 |
4169 void HTMLMediaElement::OnVisibilityChangedForAutoplay(bool is_visible) { | |
4170 if (!is_visible) { | |
4171 if (can_autoplay_ && Autoplay()) { | |
4172 PauseInternal(); | |
4173 can_autoplay_ = true; | |
4174 } | |
4175 return; | |
4176 } | |
4177 | |
4178 if (ShouldAutoplay()) { | |
4179 paused_ = false; | |
4180 ScheduleEvent(EventTypeNames::play); | |
4181 ScheduleNotifyPlaying(); | |
4182 | |
4183 UpdatePlayState(); | |
4184 } | |
4185 } | |
4186 | |
4187 void HTMLMediaElement::ClearWeakMembers(Visitor* visitor) { | 3980 void HTMLMediaElement::ClearWeakMembers(Visitor* visitor) { |
4188 if (!ThreadHeap::IsHeapObjectAlive(audio_source_node_)) { | 3981 if (!ThreadHeap::IsHeapObjectAlive(audio_source_node_)) { |
4189 GetAudioSourceProvider().SetClient(nullptr); | 3982 GetAudioSourceProvider().SetClient(nullptr); |
4190 audio_source_node_ = nullptr; | 3983 audio_source_node_ = nullptr; |
4191 } | 3984 } |
4192 } | 3985 } |
4193 | 3986 |
4194 void HTMLMediaElement::AudioSourceProviderImpl::Wrap( | 3987 void HTMLMediaElement::AudioSourceProviderImpl::Wrap( |
4195 WebAudioSourceProvider* provider) { | 3988 WebAudioSourceProvider* provider) { |
4196 MutexLocker locker(provide_input_lock); | 3989 MutexLocker locker(provide_input_lock); |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4289 kMostlyFillViewportBecomeStableSeconds, BLINK_FROM_HERE); | 4082 kMostlyFillViewportBecomeStableSeconds, BLINK_FROM_HERE); |
4290 } | 4083 } |
4291 | 4084 |
4292 void HTMLMediaElement::ViewportFillDebouncerTimerFired(TimerBase*) { | 4085 void HTMLMediaElement::ViewportFillDebouncerTimerFired(TimerBase*) { |
4293 mostly_filling_viewport_ = true; | 4086 mostly_filling_viewport_ = true; |
4294 if (web_media_player_) | 4087 if (web_media_player_) |
4295 web_media_player_->BecameDominantVisibleContent(mostly_filling_viewport_); | 4088 web_media_player_->BecameDominantVisibleContent(mostly_filling_viewport_); |
4296 } | 4089 } |
4297 | 4090 |
4298 } // namespace blink | 4091 } // namespace blink |
OLD | NEW |