| 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 18 matching lines...) Expand all Loading... |
| 29 #include <limits> | 29 #include <limits> |
| 30 #include "bindings/core/v8/ExceptionState.h" | 30 #include "bindings/core/v8/ExceptionState.h" |
| 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" | |
| 40 #include "core/dom/ElementTraversal.h" | 39 #include "core/dom/ElementTraversal.h" |
| 41 #include "core/dom/ElementVisibilityObserver.h" | |
| 42 #include "core/dom/Fullscreen.h" | 40 #include "core/dom/Fullscreen.h" |
| 43 #include "core/dom/TaskRunnerHelper.h" | 41 #include "core/dom/TaskRunnerHelper.h" |
| 44 #include "core/dom/shadow/ShadowRoot.h" | 42 #include "core/dom/shadow/ShadowRoot.h" |
| 45 #include "core/events/Event.h" | 43 #include "core/events/Event.h" |
| 46 #include "core/frame/ContentSettingsClient.h" | |
| 47 #include "core/frame/FrameView.h" | 44 #include "core/frame/FrameView.h" |
| 48 #include "core/frame/LocalFrame.h" | 45 #include "core/frame/LocalFrame.h" |
| 49 #include "core/frame/LocalFrameClient.h" | 46 #include "core/frame/LocalFrameClient.h" |
| 50 #include "core/frame/Settings.h" | 47 #include "core/frame/Settings.h" |
| 51 #include "core/frame/UseCounter.h" | 48 #include "core/frame/UseCounter.h" |
| 52 #include "core/frame/csp/ContentSecurityPolicy.h" | 49 #include "core/frame/csp/ContentSecurityPolicy.h" |
| 53 #include "core/html/HTMLSourceElement.h" | 50 #include "core/html/HTMLSourceElement.h" |
| 54 #include "core/html/HTMLTrackElement.h" | 51 #include "core/html/HTMLTrackElement.h" |
| 55 #include "core/html/TimeRanges.h" | 52 #include "core/html/TimeRanges.h" |
| 56 #include "core/html/media/AutoplayUmaHelper.h" | 53 #include "core/html/media/AutoplayPolicy.h" |
| 57 #include "core/html/media/HTMLMediaElementControlsList.h" | 54 #include "core/html/media/HTMLMediaElementControlsList.h" |
| 58 #include "core/html/media/HTMLMediaSource.h" | 55 #include "core/html/media/HTMLMediaSource.h" |
| 59 #include "core/html/media/MediaControls.h" | 56 #include "core/html/media/MediaControls.h" |
| 60 #include "core/html/media/MediaError.h" | 57 #include "core/html/media/MediaError.h" |
| 61 #include "core/html/media/MediaFragmentURIParser.h" | 58 #include "core/html/media/MediaFragmentURIParser.h" |
| 62 #include "core/html/track/AudioTrack.h" | 59 #include "core/html/track/AudioTrack.h" |
| 63 #include "core/html/track/AudioTrackList.h" | 60 #include "core/html/track/AudioTrackList.h" |
| 64 #include "core/html/track/AutomaticTrackSelection.h" | 61 #include "core/html/track/AutomaticTrackSelection.h" |
| 65 #include "core/html/track/CueTimeline.h" | 62 #include "core/html/track/CueTimeline.h" |
| 66 #include "core/html/track/InbandTextTrack.h" | 63 #include "core/html/track/InbandTextTrack.h" |
| 67 #include "core/html/track/TextTrackContainer.h" | 64 #include "core/html/track/TextTrackContainer.h" |
| 68 #include "core/html/track/TextTrackList.h" | 65 #include "core/html/track/TextTrackList.h" |
| 69 #include "core/html/track/VideoTrack.h" | 66 #include "core/html/track/VideoTrack.h" |
| 70 #include "core/html/track/VideoTrackList.h" | 67 #include "core/html/track/VideoTrackList.h" |
| 71 #include "core/inspector/ConsoleMessage.h" | 68 #include "core/inspector/ConsoleMessage.h" |
| 72 #include "core/layout/IntersectionGeometry.h" | 69 #include "core/layout/IntersectionGeometry.h" |
| 73 #include "core/layout/LayoutMedia.h" | 70 #include "core/layout/LayoutMedia.h" |
| 74 #include "core/layout/api/LayoutViewItem.h" | 71 #include "core/layout/api/LayoutViewItem.h" |
| 75 #include "core/layout/compositing/PaintLayerCompositor.h" | 72 #include "core/layout/compositing/PaintLayerCompositor.h" |
| 76 #include "core/loader/FrameLoader.h" | 73 #include "core/loader/FrameLoader.h" |
| 77 #include "core/page/ChromeClient.h" | 74 #include "core/page/ChromeClient.h" |
| 78 #include "platform/Histogram.h" | 75 #include "platform/Histogram.h" |
| 79 #include "platform/LayoutTestSupport.h" | 76 #include "platform/LayoutTestSupport.h" |
| 80 #include "platform/RuntimeEnabledFeatures.h" | 77 #include "platform/RuntimeEnabledFeatures.h" |
| 81 #include "platform/UserGestureIndicator.h" | |
| 82 #include "platform/audio/AudioBus.h" | 78 #include "platform/audio/AudioBus.h" |
| 83 #include "platform/audio/AudioSourceProviderClient.h" | 79 #include "platform/audio/AudioSourceProviderClient.h" |
| 84 #include "platform/graphics/GraphicsLayer.h" | 80 #include "platform/graphics/GraphicsLayer.h" |
| 85 #include "platform/mediastream/MediaStreamDescriptor.h" | 81 #include "platform/mediastream/MediaStreamDescriptor.h" |
| 86 #include "platform/network/NetworkStateNotifier.h" | 82 #include "platform/network/NetworkStateNotifier.h" |
| 87 #include "platform/network/ParsedContentType.h" | 83 #include "platform/network/ParsedContentType.h" |
| 88 #include "platform/network/mime/ContentType.h" | 84 #include "platform/network/mime/ContentType.h" |
| 89 #include "platform/network/mime/MIMETypeFromURL.h" | 85 #include "platform/network/mime/MIMETypeFromURL.h" |
| 90 #include "platform/weborigin/SecurityOrigin.h" | 86 #include "platform/weborigin/SecurityOrigin.h" |
| 91 #include "platform/wtf/AutoReset.h" | 87 #include "platform/wtf/AutoReset.h" |
| (...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 331 | 327 |
| 332 NOTREACHED(); | 328 NOTREACHED(); |
| 333 return String(); | 329 return String(); |
| 334 } | 330 } |
| 335 | 331 |
| 336 bool IsDocumentCrossOrigin(Document& document) { | 332 bool IsDocumentCrossOrigin(Document& document) { |
| 337 const LocalFrame* frame = document.GetFrame(); | 333 const LocalFrame* frame = document.GetFrame(); |
| 338 return frame && frame->IsCrossOriginSubframe(); | 334 return frame && frame->IsCrossOriginSubframe(); |
| 339 } | 335 } |
| 340 | 336 |
| 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() { | 337 std::unique_ptr<MediaControls::Factory>& MediaControlsFactory() { |
| 372 DEFINE_STATIC_LOCAL(std::unique_ptr<MediaControls::Factory>, | 338 DEFINE_STATIC_LOCAL(std::unique_ptr<MediaControls::Factory>, |
| 373 media_controls_factory, ()); | 339 media_controls_factory, ()); |
| 374 return media_controls_factory; | 340 return media_controls_factory; |
| 375 } | 341 } |
| 376 | 342 |
| 377 } // anonymous namespace | 343 } // anonymous namespace |
| 378 | 344 |
| 379 MIMETypeRegistry::SupportsType HTMLMediaElement::GetSupportsType( | 345 MIMETypeRegistry::SupportsType HTMLMediaElement::GetSupportsType( |
| 380 const ContentType& content_type) { | 346 const ContentType& content_type) { |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 498 deferred_load_timer_( | 464 deferred_load_timer_( |
| 499 TaskRunnerHelper::Get(TaskType::kUnthrottled, &document), | 465 TaskRunnerHelper::Get(TaskType::kUnthrottled, &document), |
| 500 this, | 466 this, |
| 501 &HTMLMediaElement::DeferredLoadTimerFired), | 467 &HTMLMediaElement::DeferredLoadTimerFired), |
| 502 web_layer_(nullptr), | 468 web_layer_(nullptr), |
| 503 display_mode_(kUnknown), | 469 display_mode_(kUnknown), |
| 504 official_playback_position_(0), | 470 official_playback_position_(0), |
| 505 official_playback_position_needs_update_(true), | 471 official_playback_position_needs_update_(true), |
| 506 fragment_end_time_(std::numeric_limits<double>::quiet_NaN()), | 472 fragment_end_time_(std::numeric_limits<double>::quiet_NaN()), |
| 507 pending_action_flags_(0), | 473 pending_action_flags_(0), |
| 508 locked_pending_user_gesture_(false), | |
| 509 locked_pending_user_gesture_if_cross_origin_experiment_enabled_(true), | |
| 510 playing_(false), | 474 playing_(false), |
| 511 should_delay_load_event_(false), | 475 should_delay_load_event_(false), |
| 512 have_fired_loaded_data_(false), | 476 have_fired_loaded_data_(false), |
| 513 can_autoplay_(true), | 477 can_autoplay_(true), |
| 514 muted_(false), | 478 muted_(false), |
| 515 paused_(true), | 479 paused_(true), |
| 516 seeking_(false), | 480 seeking_(false), |
| 517 sent_stalled_event_(false), | 481 sent_stalled_event_(false), |
| 518 ignore_preload_none_(false), | 482 ignore_preload_none_(false), |
| 519 text_tracks_visible_(false), | 483 text_tracks_visible_(false), |
| 520 should_perform_automatic_track_selection_(true), | 484 should_perform_automatic_track_selection_(true), |
| 521 tracks_are_ready_(true), | 485 tracks_are_ready_(true), |
| 522 processing_preference_change_(false), | 486 processing_preference_change_(false), |
| 523 playing_remotely_(false), | 487 playing_remotely_(false), |
| 524 in_overlay_fullscreen_video_(false), | 488 in_overlay_fullscreen_video_(false), |
| 525 mostly_filling_viewport_(false), | 489 mostly_filling_viewport_(false), |
| 526 audio_tracks_(this, AudioTrackList::Create(*this)), | 490 audio_tracks_(this, AudioTrackList::Create(*this)), |
| 527 video_tracks_(this, VideoTrackList::Create(*this)), | 491 video_tracks_(this, VideoTrackList::Create(*this)), |
| 528 text_tracks_(this, nullptr), | 492 text_tracks_(this, nullptr), |
| 529 audio_source_node_(nullptr), | 493 audio_source_node_(nullptr), |
| 530 autoplay_uma_helper_(AutoplayUmaHelper::Create(this)), | 494 autoplay_policy_(new AutoplayPolicy(this)), |
| 531 remote_playback_client_(nullptr), | 495 remote_playback_client_(nullptr), |
| 532 autoplay_visibility_observer_(nullptr), | |
| 533 media_controls_(nullptr), | 496 media_controls_(nullptr), |
| 534 controls_list_(HTMLMediaElementControlsList::Create(this)) { | 497 controls_list_(HTMLMediaElementControlsList::Create(this)) { |
| 535 BLINK_MEDIA_LOG << "HTMLMediaElement(" << (void*)this << ")"; | 498 BLINK_MEDIA_LOG << "HTMLMediaElement(" << (void*)this << ")"; |
| 536 | 499 |
| 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(); | 500 LocalFrame* frame = document.GetFrame(); |
| 542 if (frame) { | 501 if (frame) { |
| 543 remote_playback_client_ = | 502 remote_playback_client_ = |
| 544 frame->Loader().Client()->CreateWebRemotePlaybackClient(*this); | 503 frame->Loader().Client()->CreateWebRemotePlaybackClient(*this); |
| 545 } | 504 } |
| 546 | 505 |
| 547 SetHasCustomStyleCallbacks(); | 506 SetHasCustomStyleCallbacks(); |
| 548 AddElementToDocumentMap(this, &document); | 507 AddElementToDocumentMap(this, &document); |
| 549 | 508 |
| 550 UseCounter::Count(document, UseCounter::kHTMLMediaElement); | 509 UseCounter::Count(document, UseCounter::kHTMLMediaElement); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 584 TaskRunnerHelper::Get(TaskType::kUnthrottled, &GetDocument())); | 543 TaskRunnerHelper::Get(TaskType::kUnthrottled, &GetDocument())); |
| 585 audio_tracks_timer_.MoveToNewTaskRunner( | 544 audio_tracks_timer_.MoveToNewTaskRunner( |
| 586 TaskRunnerHelper::Get(TaskType::kUnthrottled, &GetDocument())); | 545 TaskRunnerHelper::Get(TaskType::kUnthrottled, &GetDocument())); |
| 587 viewport_fill_debouncer_timer_.MoveToNewTaskRunner( | 546 viewport_fill_debouncer_timer_.MoveToNewTaskRunner( |
| 588 TaskRunnerHelper::Get(TaskType::kUnthrottled, &GetDocument())); | 547 TaskRunnerHelper::Get(TaskType::kUnthrottled, &GetDocument())); |
| 589 check_viewport_intersection_timer_.MoveToNewTaskRunner( | 548 check_viewport_intersection_timer_.MoveToNewTaskRunner( |
| 590 TaskRunnerHelper::Get(TaskType::kUnthrottled, &GetDocument())); | 549 TaskRunnerHelper::Get(TaskType::kUnthrottled, &GetDocument())); |
| 591 deferred_load_timer_.MoveToNewTaskRunner( | 550 deferred_load_timer_.MoveToNewTaskRunner( |
| 592 TaskRunnerHelper::Get(TaskType::kUnthrottled, &GetDocument())); | 551 TaskRunnerHelper::Get(TaskType::kUnthrottled, &GetDocument())); |
| 593 | 552 |
| 594 autoplay_uma_helper_->DidMoveToNewDocument(old_document); | 553 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 | 554 |
| 604 if (should_delay_load_event_) { | 555 if (should_delay_load_event_) { |
| 605 GetDocument().IncrementLoadEventDelayCount(); | 556 GetDocument().IncrementLoadEventDelayCount(); |
| 606 // Note: Keeping the load event delay count increment on oldDocument that | 557 // Note: Keeping the load event delay count increment on oldDocument that |
| 607 // was added when m_shouldDelayLoadEvent was set so that destruction of | 558 // was added when m_shouldDelayLoadEvent was set so that destruction of |
| 608 // m_webMediaPlayer can not cause load event dispatching in oldDocument. | 559 // m_webMediaPlayer can not cause load event dispatching in oldDocument. |
| 609 } else { | 560 } else { |
| 610 // Incrementing the load event delay count so that destruction of | 561 // Incrementing the load event delay count so that destruction of |
| 611 // m_webMediaPlayer can not cause load event dispatching in oldDocument. | 562 // m_webMediaPlayer can not cause load event dispatching in oldDocument. |
| 612 old_document.IncrementLoadEventDelayCount(); | 563 old_document.IncrementLoadEventDelayCount(); |
| 613 } | 564 } |
| 614 | 565 |
| 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); | 566 RemoveElementFromDocumentMap(this, &old_document); |
| 620 AddElementToDocumentMap(this, &GetDocument()); | 567 AddElementToDocumentMap(this, &GetDocument()); |
| 621 | 568 |
| 622 // FIXME: This is a temporary fix to prevent this object from causing the | 569 // FIXME: This is a temporary fix to prevent this object from causing the |
| 623 // MediaPlayer to dereference LocalFrame and FrameLoader pointers from the | 570 // MediaPlayer to dereference LocalFrame and FrameLoader pointers from the |
| 624 // previous document. This restarts the load, as if the src attribute had been | 571 // 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 | 572 // set. A proper fix would provide a mechanism to allow this object to |
| 626 // refresh the MediaPlayer's LocalFrame and FrameLoader references on document | 573 // refresh the MediaPlayer's LocalFrame and FrameLoader references on document |
| 627 // changes so that playback can be resumed properly. | 574 // changes so that playback can be resumed properly. |
| 628 ignore_preload_none_ = false; | 575 ignore_preload_none_ = false; |
| (...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 838 | 785 |
| 839 BLINK_MEDIA_LOG << "canPlayType(" << (void*)this << ", " << mime_type | 786 BLINK_MEDIA_LOG << "canPlayType(" << (void*)this << ", " << mime_type |
| 840 << ") -> " << can_play; | 787 << ") -> " << can_play; |
| 841 | 788 |
| 842 return can_play; | 789 return can_play; |
| 843 } | 790 } |
| 844 | 791 |
| 845 void HTMLMediaElement::load() { | 792 void HTMLMediaElement::load() { |
| 846 BLINK_MEDIA_LOG << "load(" << (void*)this << ")"; | 793 BLINK_MEDIA_LOG << "load(" << (void*)this << ")"; |
| 847 | 794 |
| 848 if (IsLockedPendingUserGesture() && | 795 autoplay_policy_->TryUnlockingUserGesture(); |
| 849 UserGestureIndicator::UtilizeUserGesture()) { | |
| 850 UnlockUserGesture(); | |
| 851 } | |
| 852 | 796 |
| 853 ignore_preload_none_ = true; | 797 ignore_preload_none_ = true; |
| 854 InvokeLoadAlgorithm(); | 798 InvokeLoadAlgorithm(); |
| 855 } | 799 } |
| 856 | 800 |
| 857 // TODO(srirama.m): Currently m_ignorePreloadNone is reset before calling | 801 // TODO(srirama.m): Currently m_ignorePreloadNone is reset before calling |
| 858 // invokeLoadAlgorithm() in all places except load(). Move it inside here | 802 // invokeLoadAlgorithm() in all places except load(). Move it inside here |
| 859 // once microtask is implemented for "Await a stable state" step | 803 // once microtask is implemented for "Await a stable state" step |
| 860 // in resource selection algorithm. | 804 // in resource selection algorithm. |
| 861 void HTMLMediaElement::InvokeLoadAlgorithm() { | 805 void HTMLMediaElement::InvokeLoadAlgorithm() { |
| (...skipping 970 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1832 } | 1776 } |
| 1833 | 1777 |
| 1834 if (ready_state_ == kHaveEnoughData && old_state < kHaveEnoughData && | 1778 if (ready_state_ == kHaveEnoughData && old_state < kHaveEnoughData && |
| 1835 tracks_are_ready) { | 1779 tracks_are_ready) { |
| 1836 if (old_state <= kHaveCurrentData) { | 1780 if (old_state <= kHaveCurrentData) { |
| 1837 ScheduleEvent(EventTypeNames::canplay); | 1781 ScheduleEvent(EventTypeNames::canplay); |
| 1838 if (is_potentially_playing) | 1782 if (is_potentially_playing) |
| 1839 ScheduleNotifyPlaying(); | 1783 ScheduleNotifyPlaying(); |
| 1840 } | 1784 } |
| 1841 | 1785 |
| 1842 // Check for autoplay, and record metrics about it if needed. | 1786 if (autoplay_policy_->RequestAutoplayByAttribute()) { |
| 1843 if (ShouldAutoplay()) { | 1787 paused_ = false; |
| 1844 autoplay_uma_helper_->OnAutoplayInitiated(AutoplaySource::kAttribute); | 1788 ScheduleEvent(EventTypeNames::play); |
| 1845 | 1789 ScheduleNotifyPlaying(); |
| 1846 if (!IsGestureNeededForPlayback()) { | 1790 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 } | 1791 } |
| 1877 | 1792 |
| 1878 ScheduleEvent(EventTypeNames::canplaythrough); | 1793 ScheduleEvent(EventTypeNames::canplaythrough); |
| 1879 | 1794 |
| 1880 should_update_display_state = true; | 1795 should_update_display_state = true; |
| 1881 } | 1796 } |
| 1882 | 1797 |
| 1883 if (should_update_display_state) | 1798 if (should_update_display_state) |
| 1884 UpdateDisplayState(); | 1799 UpdateDisplayState(); |
| 1885 | 1800 |
| (...skipping 320 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2206 // 4.8.12.8 Playing the media resource | 2121 // 4.8.12.8 Playing the media resource |
| 2207 // The ended attribute must return true if the media element has ended | 2122 // The ended attribute must return true if the media element has ended |
| 2208 // playback and the direction of playback is forwards, and false otherwise. | 2123 // playback and the direction of playback is forwards, and false otherwise. |
| 2209 return EndedPlayback() && GetDirectionOfPlayback() == kForward; | 2124 return EndedPlayback() && GetDirectionOfPlayback() == kForward; |
| 2210 } | 2125 } |
| 2211 | 2126 |
| 2212 bool HTMLMediaElement::Autoplay() const { | 2127 bool HTMLMediaElement::Autoplay() const { |
| 2213 return FastHasAttribute(autoplayAttr); | 2128 return FastHasAttribute(autoplayAttr); |
| 2214 } | 2129 } |
| 2215 | 2130 |
| 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 { | 2131 String HTMLMediaElement::preload() const { |
| 2223 return PreloadTypeToString(PreloadType()); | 2132 return PreloadTypeToString(PreloadType()); |
| 2224 } | 2133 } |
| 2225 | 2134 |
| 2226 void HTMLMediaElement::setPreload(const AtomicString& preload) { | 2135 void HTMLMediaElement::setPreload(const AtomicString& preload) { |
| 2227 BLINK_MEDIA_LOG << "setPreload(" << (void*)this << ", " << preload << ")"; | 2136 BLINK_MEDIA_LOG << "setPreload(" << (void*)this << ", " << preload << ")"; |
| 2228 setAttribute(preloadAttr, preload); | 2137 setAttribute(preloadAttr, preload); |
| 2229 } | 2138 } |
| 2230 | 2139 |
| 2231 WebMediaPlayer::Preload HTMLMediaElement::PreloadType() const { | 2140 WebMediaPlayer::Preload HTMLMediaElement::PreloadType() const { |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2276 // https://crbug.com/310450 | 2185 // https://crbug.com/310450 |
| 2277 UseCounter::Count(GetDocument(), UseCounter::kHTMLMediaElementPreloadDefault); | 2186 UseCounter::Count(GetDocument(), UseCounter::kHTMLMediaElementPreloadDefault); |
| 2278 return WebMediaPlayer::kPreloadAuto; | 2187 return WebMediaPlayer::kPreloadAuto; |
| 2279 } | 2188 } |
| 2280 | 2189 |
| 2281 String HTMLMediaElement::EffectivePreload() const { | 2190 String HTMLMediaElement::EffectivePreload() const { |
| 2282 return PreloadTypeToString(EffectivePreloadType()); | 2191 return PreloadTypeToString(EffectivePreloadType()); |
| 2283 } | 2192 } |
| 2284 | 2193 |
| 2285 WebMediaPlayer::Preload HTMLMediaElement::EffectivePreloadType() const { | 2194 WebMediaPlayer::Preload HTMLMediaElement::EffectivePreloadType() const { |
| 2286 if (Autoplay() && !IsGestureNeededForPlayback()) | 2195 if (Autoplay() && !autoplay_policy_->IsGestureNeededForPlayback()) |
| 2287 return WebMediaPlayer::kPreloadAuto; | 2196 return WebMediaPlayer::kPreloadAuto; |
| 2288 | 2197 |
| 2289 WebMediaPlayer::Preload preload = PreloadType(); | 2198 WebMediaPlayer::Preload preload = PreloadType(); |
| 2290 if (ignore_preload_none_ && preload == WebMediaPlayer::kPreloadNone) | 2199 if (ignore_preload_none_ && preload == WebMediaPlayer::kPreloadNone) |
| 2291 return WebMediaPlayer::kPreloadMetaData; | 2200 return WebMediaPlayer::kPreloadMetaData; |
| 2292 | 2201 |
| 2293 return preload; | 2202 return preload; |
| 2294 } | 2203 } |
| 2295 | 2204 |
| 2296 ScriptPromise HTMLMediaElement::playForBindings(ScriptState* script_state) { | 2205 ScriptPromise HTMLMediaElement::playForBindings(ScriptState* script_state) { |
| (...skipping 25 matching lines...) Expand all Loading... |
| 2322 resolver->Reject(DOMException::Create(code.Get(), message)); | 2231 resolver->Reject(DOMException::Create(code.Get(), message)); |
| 2323 return promise; | 2232 return promise; |
| 2324 } | 2233 } |
| 2325 | 2234 |
| 2326 return promise; | 2235 return promise; |
| 2327 } | 2236 } |
| 2328 | 2237 |
| 2329 Nullable<ExceptionCode> HTMLMediaElement::Play() { | 2238 Nullable<ExceptionCode> HTMLMediaElement::Play() { |
| 2330 BLINK_MEDIA_LOG << "play(" << (void*)this << ")"; | 2239 BLINK_MEDIA_LOG << "play(" << (void*)this << ")"; |
| 2331 | 2240 |
| 2332 if (!UserGestureIndicator::ProcessingUserGesture()) { | 2241 Nullable<ExceptionCode> exception_code = autoplay_policy_->RequestPlay(); |
| 2333 autoplay_uma_helper_->OnAutoplayInitiated(AutoplaySource::kMethod); | |
| 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 | 2242 |
| 2342 autoplay_uma_helper_->RecordCrossOriginAutoplayResult( | 2243 if (exception_code == kNotAllowedError) { |
| 2343 CrossOriginAutoplayResult::kAutoplayBlocked); | 2244 // If we're already playing, then this play would do nothing anyway. |
| 2344 String message = ExceptionMessages::FailedToExecute( | 2245 // Call playInternal to handle scheduling the promise resolution. |
| 2345 "play", "HTMLMediaElement", | 2246 if (!paused_) { |
| 2346 "API can only be initiated by a user gesture."); | 2247 PlayInternal(); |
| 2347 GetDocument().AddConsoleMessage(ConsoleMessage::Create( | 2248 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 } | 2249 } |
| 2359 } else { | 2250 String message = ExceptionMessages::FailedToExecute( |
| 2360 autoplay_uma_helper_->RecordCrossOriginAutoplayResult( | 2251 "play", "HTMLMediaElement", |
| 2361 CrossOriginAutoplayResult::kPlayedWithGesture); | 2252 "API can only be initiated by a user gesture."); |
| 2362 UserGestureIndicator::UtilizeUserGesture(); | 2253 GetDocument().AddConsoleMessage(ConsoleMessage::Create( |
| 2363 UnlockUserGesture(); | 2254 kJSMessageSource, kWarningMessageLevel, message)); |
| 2255 return exception_code; |
| 2364 } | 2256 } |
| 2365 | 2257 |
| 2258 autoplay_policy_->StopAutoplayMutedWhenVisible(); |
| 2259 |
| 2366 if (error_ && error_->code() == MediaError::kMediaErrSrcNotSupported) | 2260 if (error_ && error_->code() == MediaError::kMediaErrSrcNotSupported) |
| 2367 return kNotSupportedError; | 2261 return kNotSupportedError; |
| 2368 | 2262 |
| 2369 if (autoplay_visibility_observer_) { | 2263 DCHECK(exception_code.IsNull()); |
| 2370 autoplay_visibility_observer_->Stop(); | |
| 2371 autoplay_visibility_observer_ = nullptr; | |
| 2372 } | |
| 2373 | 2264 |
| 2374 PlayInternal(); | 2265 PlayInternal(); |
| 2375 | 2266 |
| 2376 return nullptr; | 2267 return nullptr; |
| 2377 } | 2268 } |
| 2378 | 2269 |
| 2379 void HTMLMediaElement::PlayInternal() { | 2270 void HTMLMediaElement::PlayInternal() { |
| 2380 BLINK_MEDIA_LOG << "playInternal(" << (void*)this << ")"; | 2271 BLINK_MEDIA_LOG << "playInternal(" << (void*)this << ")"; |
| 2381 | 2272 |
| 2382 // 4.8.12.8. Playing the media resource | 2273 // 4.8.12.8. Playing the media resource |
| (...skipping 20 matching lines...) Expand all Loading... |
| 2403 | 2294 |
| 2404 can_autoplay_ = false; | 2295 can_autoplay_ = false; |
| 2405 | 2296 |
| 2406 SetIgnorePreloadNone(); | 2297 SetIgnorePreloadNone(); |
| 2407 UpdatePlayState(); | 2298 UpdatePlayState(); |
| 2408 } | 2299 } |
| 2409 | 2300 |
| 2410 void HTMLMediaElement::pause() { | 2301 void HTMLMediaElement::pause() { |
| 2411 BLINK_MEDIA_LOG << "pause(" << (void*)this << ")"; | 2302 BLINK_MEDIA_LOG << "pause(" << (void*)this << ")"; |
| 2412 | 2303 |
| 2413 if (autoplay_visibility_observer_) { | 2304 autoplay_policy_->StopAutoplayMutedWhenVisible(); |
| 2414 autoplay_visibility_observer_->Stop(); | |
| 2415 autoplay_visibility_observer_ = nullptr; | |
| 2416 } | |
| 2417 | |
| 2418 PauseInternal(); | 2305 PauseInternal(); |
| 2419 } | 2306 } |
| 2420 | 2307 |
| 2421 void HTMLMediaElement::PauseInternal() { | 2308 void HTMLMediaElement::PauseInternal() { |
| 2422 BLINK_MEDIA_LOG << "pauseInternal(" << (void*)this << ")"; | 2309 BLINK_MEDIA_LOG << "pauseInternal(" << (void*)this << ")"; |
| 2423 | 2310 |
| 2424 if (network_state_ == kNetworkEmpty) | 2311 if (network_state_ == kNetworkEmpty) |
| 2425 InvokeResourceSelectionAlgorithm(); | 2312 InvokeResourceSelectionAlgorithm(); |
| 2426 | 2313 |
| 2427 can_autoplay_ = false; | 2314 can_autoplay_ = false; |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2555 return muted_; | 2442 return muted_; |
| 2556 } | 2443 } |
| 2557 | 2444 |
| 2558 void HTMLMediaElement::setMuted(bool muted) { | 2445 void HTMLMediaElement::setMuted(bool muted) { |
| 2559 BLINK_MEDIA_LOG << "setMuted(" << (void*)this << ", " << BoolString(muted) | 2446 BLINK_MEDIA_LOG << "setMuted(" << (void*)this << ", " << BoolString(muted) |
| 2560 << ")"; | 2447 << ")"; |
| 2561 | 2448 |
| 2562 if (muted_ == muted) | 2449 if (muted_ == muted) |
| 2563 return; | 2450 return; |
| 2564 | 2451 |
| 2565 bool was_autoplaying_muted = IsAutoplayingMuted(); | 2452 bool request_result = autoplay_policy_->RequestAutoplayUnmute(); |
| 2566 bool was_pending_autoplay_muted = autoplay_visibility_observer_ && paused() && | |
| 2567 muted_ && IsLockedPendingUserGesture(); | |
| 2568 | |
| 2569 if (UserGestureIndicator::ProcessingUserGesture()) | |
| 2570 UnlockUserGesture(); | |
| 2571 | 2453 |
| 2572 muted_ = muted; | 2454 muted_ = muted; |
| 2573 | 2455 |
| 2574 ScheduleEvent(EventTypeNames::volumechange); | 2456 ScheduleEvent(EventTypeNames::volumechange); |
| 2575 | 2457 |
| 2576 // If an element autoplayed while muted, it needs to be unlocked to unmute, | 2458 if (!request_result) |
| 2577 // otherwise, it will be paused. | 2459 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 | 2460 |
| 2589 // This is called after the volumechange event to make sure isAutoplayingMuted | 2461 // This is called after the volumechange event to make sure isAutoplayingMuted |
| 2590 // returns the right value when webMediaPlayer receives the volume update. | 2462 // returns the right value when webMediaPlayer receives the volume update. |
| 2591 if (GetWebMediaPlayer()) | 2463 if (GetWebMediaPlayer()) |
| 2592 GetWebMediaPlayer()->SetVolume(EffectiveMediaVolume()); | 2464 GetWebMediaPlayer()->SetVolume(EffectiveMediaVolume()); |
| 2593 | 2465 |
| 2594 // If an element was a candidate for autoplay muted but not visible, it will | 2466 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 } | 2467 } |
| 2601 | 2468 |
| 2602 double HTMLMediaElement::EffectiveMediaVolume() const { | 2469 double HTMLMediaElement::EffectiveMediaVolume() const { |
| 2603 if (muted_) | 2470 if (muted_) |
| 2604 return 0; | 2471 return 0; |
| 2605 | 2472 |
| 2606 return volume_; | 2473 return volume_; |
| 2607 } | 2474 } |
| 2608 | 2475 |
| 2609 // The spec says to fire periodic timeupdate events (those sent while playing) | 2476 // 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() { | 3178 WebMediaPlayer::TrackId HTMLMediaElement::GetSelectedVideoTrackId() { |
| 3312 DCHECK(RuntimeEnabledFeatures::backgroundVideoTrackOptimizationEnabled()); | 3179 DCHECK(RuntimeEnabledFeatures::backgroundVideoTrackOptimizationEnabled()); |
| 3313 DCHECK(HasSelectedVideoTrack()); | 3180 DCHECK(HasSelectedVideoTrack()); |
| 3314 | 3181 |
| 3315 int selected_track_index = video_tracks_->selectedIndex(); | 3182 int selected_track_index = video_tracks_->selectedIndex(); |
| 3316 VideoTrack* track = | 3183 VideoTrack* track = |
| 3317 video_tracks_->AnonymousIndexedGetter(selected_track_index); | 3184 video_tracks_->AnonymousIndexedGetter(selected_track_index); |
| 3318 return track->id(); | 3185 return track->id(); |
| 3319 } | 3186 } |
| 3320 | 3187 |
| 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) { | 3188 void HTMLMediaElement::RequestReload(const WebURL& new_url) { |
| 3331 DCHECK(GetWebMediaPlayer()); | 3189 DCHECK(GetWebMediaPlayer()); |
| 3332 DCHECK(!src_object_); | 3190 DCHECK(!src_object_); |
| 3333 DCHECK(new_url.IsValid()); | 3191 DCHECK(new_url.IsValid()); |
| 3334 DCHECK(IsSafeToLoadURL(new_url, kComplain)); | 3192 DCHECK(IsSafeToLoadURL(new_url, kComplain)); |
| 3335 ResetMediaPlayerAndMediaSource(); | 3193 ResetMediaPlayerAndMediaSource(); |
| 3336 StartPlayerLoad(new_url); | 3194 StartPlayerLoad(new_url); |
| 3337 } | 3195 } |
| 3338 | 3196 |
| 3197 bool HTMLMediaElement::IsAutoplayingMuted() { |
| 3198 return autoplay_policy_->IsAutoplayingMuted(); |
| 3199 } |
| 3200 |
| 3339 // MediaPlayerPresentation methods | 3201 // MediaPlayerPresentation methods |
| 3340 void HTMLMediaElement::Repaint() { | 3202 void HTMLMediaElement::Repaint() { |
| 3341 if (web_layer_) | 3203 if (web_layer_) |
| 3342 web_layer_->Invalidate(); | 3204 web_layer_->Invalidate(); |
| 3343 | 3205 |
| 3344 UpdateDisplayState(); | 3206 UpdateDisplayState(); |
| 3345 if (GetLayoutObject()) | 3207 if (GetLayoutObject()) |
| 3346 GetLayoutObject()->SetShouldDoFullPaintInvalidation(); | 3208 GetLayoutObject()->SetShouldDoFullPaintInvalidation(); |
| 3347 } | 3209 } |
| 3348 | 3210 |
| (...skipping 575 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3924 visitor->Trace(media_source_); | 3786 visitor->Trace(media_source_); |
| 3925 visitor->Trace(audio_tracks_); | 3787 visitor->Trace(audio_tracks_); |
| 3926 visitor->Trace(video_tracks_); | 3788 visitor->Trace(video_tracks_); |
| 3927 visitor->Trace(cue_timeline_); | 3789 visitor->Trace(cue_timeline_); |
| 3928 visitor->Trace(text_tracks_); | 3790 visitor->Trace(text_tracks_); |
| 3929 visitor->Trace(text_tracks_when_resource_selection_began_); | 3791 visitor->Trace(text_tracks_when_resource_selection_began_); |
| 3930 visitor->Trace(play_promise_resolvers_); | 3792 visitor->Trace(play_promise_resolvers_); |
| 3931 visitor->Trace(play_promise_resolve_list_); | 3793 visitor->Trace(play_promise_resolve_list_); |
| 3932 visitor->Trace(play_promise_reject_list_); | 3794 visitor->Trace(play_promise_reject_list_); |
| 3933 visitor->Trace(audio_source_provider_); | 3795 visitor->Trace(audio_source_provider_); |
| 3934 visitor->Trace(autoplay_uma_helper_); | |
| 3935 visitor->Trace(src_object_); | 3796 visitor->Trace(src_object_); |
| 3936 visitor->Trace(autoplay_visibility_observer_); | 3797 visitor->Trace(autoplay_policy_); |
| 3937 visitor->Trace(media_controls_); | 3798 visitor->Trace(media_controls_); |
| 3938 visitor->Trace(controls_list_); | 3799 visitor->Trace(controls_list_); |
| 3939 visitor->template RegisterWeakMembers<HTMLMediaElement, | 3800 visitor->template RegisterWeakMembers<HTMLMediaElement, |
| 3940 &HTMLMediaElement::ClearWeakMembers>( | 3801 &HTMLMediaElement::ClearWeakMembers>( |
| 3941 this); | 3802 this); |
| 3942 Supplementable<HTMLMediaElement>::Trace(visitor); | 3803 Supplementable<HTMLMediaElement>::Trace(visitor); |
| 3943 HTMLElement::Trace(visitor); | 3804 HTMLElement::Trace(visitor); |
| 3944 SuspendableObject::Trace(visitor); | 3805 SuspendableObject::Trace(visitor); |
| 3945 } | 3806 } |
| 3946 | 3807 |
| (...skipping 29 matching lines...) Expand all Loading... |
| 3976 | 3837 |
| 3977 // Enable the first audio track if an audio track hasn't been enabled yet. | 3838 // Enable the first audio track if an audio track hasn't been enabled yet. |
| 3978 if (audioTracks().length() > 0 && !audioTracks().HasEnabledTrack()) | 3839 if (audioTracks().length() > 0 && !audioTracks().HasEnabledTrack()) |
| 3979 audioTracks().AnonymousIndexedGetter(0)->setEnabled(true); | 3840 audioTracks().AnonymousIndexedGetter(0)->setEnabled(true); |
| 3980 | 3841 |
| 3981 // Select the first video track if a video track hasn't been selected yet. | 3842 // Select the first video track if a video track hasn't been selected yet. |
| 3982 if (videoTracks().length() > 0 && videoTracks().selectedIndex() == -1) | 3843 if (videoTracks().length() > 0 && videoTracks().selectedIndex() == -1) |
| 3983 videoTracks().AnonymousIndexedGetter(0)->setSelected(true); | 3844 videoTracks().AnonymousIndexedGetter(0)->setSelected(true); |
| 3984 } | 3845 } |
| 3985 | 3846 |
| 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) { | 3847 void HTMLMediaElement::SetNetworkState(NetworkState state) { |
| 4041 if (network_state_ == state) | 3848 if (network_state_ == state) |
| 4042 return; | 3849 return; |
| 4043 | 3850 |
| 4044 network_state_ = state; | 3851 network_state_ = state; |
| 4045 if (GetMediaControls()) | 3852 if (GetMediaControls()) |
| 4046 GetMediaControls()->NetworkStateChanged(); | 3853 GetMediaControls()->NetworkStateChanged(); |
| 4047 } | 3854 } |
| 4048 | 3855 |
| 4049 void HTMLMediaElement::VideoWillBeDrawnToCanvas() const { | 3856 void HTMLMediaElement::VideoWillBeDrawnToCanvas() const { |
| 4050 DCHECK(IsHTMLVideoElement()); | 3857 DCHECK(IsHTMLVideoElement()); |
| 4051 UseCounter::Count(GetDocument(), UseCounter::kVideoInCanvas); | 3858 UseCounter::Count(GetDocument(), UseCounter::kVideoInCanvas); |
| 4052 if (autoplay_uma_helper_->HasSource() && !autoplay_uma_helper_->IsVisible()) | 3859 autoplay_policy_->VideoWillBeDrawnToCanvas(); |
| 4053 UseCounter::Count(GetDocument(), | |
| 4054 UseCounter::kHiddenAutoplayedVideoInCanvas); | |
| 4055 } | 3860 } |
| 4056 | 3861 |
| 4057 void HTMLMediaElement::ScheduleResolvePlayPromises() { | 3862 void HTMLMediaElement::ScheduleResolvePlayPromises() { |
| 4058 // TODO(mlamouri): per spec, we should create a new task but we can't create | 3863 // 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 | 3864 // 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 | 3865 // 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 | 3866 // 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 | 3867 // latter approach is preferred because it might be the less observable |
| 4063 // change. | 3868 // change. |
| 4064 DCHECK(play_promise_resolve_list_.IsEmpty() || | 3869 DCHECK(play_promise_resolve_list_.IsEmpty() || |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4159 DEFINE_STATIC_LOCAL(EnumerationHistogram, histogram, | 3964 DEFINE_STATIC_LOCAL(EnumerationHistogram, histogram, |
| 4160 ("Media.Controls.Show.Video", kMediaControlsShowMax)); | 3965 ("Media.Controls.Show.Video", kMediaControlsShowMax)); |
| 4161 return histogram; | 3966 return histogram; |
| 4162 } | 3967 } |
| 4163 | 3968 |
| 4164 DEFINE_STATIC_LOCAL(EnumerationHistogram, histogram, | 3969 DEFINE_STATIC_LOCAL(EnumerationHistogram, histogram, |
| 4165 ("Media.Controls.Show.Audio", kMediaControlsShowMax)); | 3970 ("Media.Controls.Show.Audio", kMediaControlsShowMax)); |
| 4166 return histogram; | 3971 return histogram; |
| 4167 } | 3972 } |
| 4168 | 3973 |
| 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) { | 3974 void HTMLMediaElement::ClearWeakMembers(Visitor* visitor) { |
| 4188 if (!ThreadHeap::IsHeapObjectAlive(audio_source_node_)) { | 3975 if (!ThreadHeap::IsHeapObjectAlive(audio_source_node_)) { |
| 4189 GetAudioSourceProvider().SetClient(nullptr); | 3976 GetAudioSourceProvider().SetClient(nullptr); |
| 4190 audio_source_node_ = nullptr; | 3977 audio_source_node_ = nullptr; |
| 4191 } | 3978 } |
| 4192 } | 3979 } |
| 4193 | 3980 |
| 4194 void HTMLMediaElement::AudioSourceProviderImpl::Wrap( | 3981 void HTMLMediaElement::AudioSourceProviderImpl::Wrap( |
| 4195 WebAudioSourceProvider* provider) { | 3982 WebAudioSourceProvider* provider) { |
| 4196 MutexLocker locker(provide_input_lock); | 3983 MutexLocker locker(provide_input_lock); |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4289 kMostlyFillViewportBecomeStableSeconds, BLINK_FROM_HERE); | 4076 kMostlyFillViewportBecomeStableSeconds, BLINK_FROM_HERE); |
| 4290 } | 4077 } |
| 4291 | 4078 |
| 4292 void HTMLMediaElement::ViewportFillDebouncerTimerFired(TimerBase*) { | 4079 void HTMLMediaElement::ViewportFillDebouncerTimerFired(TimerBase*) { |
| 4293 mostly_filling_viewport_ = true; | 4080 mostly_filling_viewport_ = true; |
| 4294 if (web_media_player_) | 4081 if (web_media_player_) |
| 4295 web_media_player_->BecameDominantVisibleContent(mostly_filling_viewport_); | 4082 web_media_player_->BecameDominantVisibleContent(mostly_filling_viewport_); |
| 4296 } | 4083 } |
| 4297 | 4084 |
| 4298 } // namespace blink | 4085 } // namespace blink |
| OLD | NEW |