Chromium Code Reviews| 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" |
| 54 #include "core/html/media/AutoplayPolicy.h" | |
| 56 #include "core/html/media/AutoplayUmaHelper.h" | 55 #include "core/html/media/AutoplayUmaHelper.h" |
| 57 #include "core/html/media/HTMLMediaElementControlsList.h" | 56 #include "core/html/media/HTMLMediaElementControlsList.h" |
| 58 #include "core/html/media/HTMLMediaSource.h" | 57 #include "core/html/media/HTMLMediaSource.h" |
| 59 #include "core/html/media/MediaControls.h" | 58 #include "core/html/media/MediaControls.h" |
| 60 #include "core/html/media/MediaError.h" | 59 #include "core/html/media/MediaError.h" |
| 61 #include "core/html/media/MediaFragmentURIParser.h" | 60 #include "core/html/media/MediaFragmentURIParser.h" |
| 62 #include "core/html/track/AudioTrack.h" | 61 #include "core/html/track/AudioTrack.h" |
| 63 #include "core/html/track/AudioTrackList.h" | 62 #include "core/html/track/AudioTrackList.h" |
| 64 #include "core/html/track/AutomaticTrackSelection.h" | 63 #include "core/html/track/AutomaticTrackSelection.h" |
| 65 #include "core/html/track/CueTimeline.h" | 64 #include "core/html/track/CueTimeline.h" |
| (...skipping 260 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 326 case WebMediaPlayer::kPreloadMetaData: | 325 case WebMediaPlayer::kPreloadMetaData: |
| 327 return "metadata"; | 326 return "metadata"; |
| 328 case WebMediaPlayer::kPreloadAuto: | 327 case WebMediaPlayer::kPreloadAuto: |
| 329 return "auto"; | 328 return "auto"; |
| 330 } | 329 } |
| 331 | 330 |
| 332 NOTREACHED(); | 331 NOTREACHED(); |
| 333 return String(); | 332 return String(); |
| 334 } | 333 } |
| 335 | 334 |
| 336 bool IsDocumentCrossOrigin(Document& document) { | |
| 337 const LocalFrame* frame = document.GetFrame(); | |
| 338 return frame && frame->IsCrossOriginSubframe(); | |
| 339 } | |
| 340 | |
| 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() { | 335 std::unique_ptr<MediaControls::Factory>& MediaControlsFactory() { |
| 372 DEFINE_STATIC_LOCAL(std::unique_ptr<MediaControls::Factory>, | 336 DEFINE_STATIC_LOCAL(std::unique_ptr<MediaControls::Factory>, |
| 373 media_controls_factory, ()); | 337 media_controls_factory, ()); |
| 374 return media_controls_factory; | 338 return media_controls_factory; |
| 375 } | 339 } |
| 376 | 340 |
| 377 } // anonymous namespace | 341 } // anonymous namespace |
| 378 | 342 |
| 379 MIMETypeRegistry::SupportsType HTMLMediaElement::GetSupportsType( | 343 MIMETypeRegistry::SupportsType HTMLMediaElement::GetSupportsType( |
| 380 const ContentType& content_type) { | 344 const ContentType& content_type) { |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 498 deferred_load_timer_( | 462 deferred_load_timer_( |
| 499 TaskRunnerHelper::Get(TaskType::kUnthrottled, &document), | 463 TaskRunnerHelper::Get(TaskType::kUnthrottled, &document), |
| 500 this, | 464 this, |
| 501 &HTMLMediaElement::DeferredLoadTimerFired), | 465 &HTMLMediaElement::DeferredLoadTimerFired), |
| 502 web_layer_(nullptr), | 466 web_layer_(nullptr), |
| 503 display_mode_(kUnknown), | 467 display_mode_(kUnknown), |
| 504 official_playback_position_(0), | 468 official_playback_position_(0), |
| 505 official_playback_position_needs_update_(true), | 469 official_playback_position_needs_update_(true), |
| 506 fragment_end_time_(std::numeric_limits<double>::quiet_NaN()), | 470 fragment_end_time_(std::numeric_limits<double>::quiet_NaN()), |
| 507 pending_action_flags_(0), | 471 pending_action_flags_(0), |
| 508 locked_pending_user_gesture_(false), | |
| 509 locked_pending_user_gesture_if_cross_origin_experiment_enabled_(true), | |
| 510 playing_(false), | 472 playing_(false), |
| 511 should_delay_load_event_(false), | 473 should_delay_load_event_(false), |
| 512 have_fired_loaded_data_(false), | 474 have_fired_loaded_data_(false), |
| 513 can_autoplay_(true), | 475 can_autoplay_(true), |
| 514 muted_(false), | 476 muted_(false), |
| 515 paused_(true), | 477 paused_(true), |
| 516 seeking_(false), | 478 seeking_(false), |
| 517 sent_stalled_event_(false), | 479 sent_stalled_event_(false), |
| 518 ignore_preload_none_(false), | 480 ignore_preload_none_(false), |
| 519 text_tracks_visible_(false), | 481 text_tracks_visible_(false), |
| 520 should_perform_automatic_track_selection_(true), | 482 should_perform_automatic_track_selection_(true), |
| 521 tracks_are_ready_(true), | 483 tracks_are_ready_(true), |
| 522 processing_preference_change_(false), | 484 processing_preference_change_(false), |
| 523 playing_remotely_(false), | 485 playing_remotely_(false), |
| 524 in_overlay_fullscreen_video_(false), | 486 in_overlay_fullscreen_video_(false), |
| 525 mostly_filling_viewport_(false), | 487 mostly_filling_viewport_(false), |
| 526 audio_tracks_(this, AudioTrackList::Create(*this)), | 488 audio_tracks_(this, AudioTrackList::Create(*this)), |
| 527 video_tracks_(this, VideoTrackList::Create(*this)), | 489 video_tracks_(this, VideoTrackList::Create(*this)), |
| 528 text_tracks_(this, nullptr), | 490 text_tracks_(this, nullptr), |
| 529 audio_source_node_(nullptr), | 491 audio_source_node_(nullptr), |
| 492 autoplay_policy_(new AutoplayPolicy(this)), | |
| 530 autoplay_uma_helper_(AutoplayUmaHelper::Create(this)), | 493 autoplay_uma_helper_(AutoplayUmaHelper::Create(this)), |
| 531 remote_playback_client_(nullptr), | 494 remote_playback_client_(nullptr), |
| 532 autoplay_visibility_observer_(nullptr), | |
| 533 media_controls_(nullptr), | 495 media_controls_(nullptr), |
| 534 controls_list_(HTMLMediaElementControlsList::Create(this)) { | 496 controls_list_(HTMLMediaElementControlsList::Create(this)) { |
| 535 BLINK_MEDIA_LOG << "HTMLMediaElement(" << (void*)this << ")"; | 497 BLINK_MEDIA_LOG << "HTMLMediaElement(" << (void*)this << ")"; |
| 536 | 498 |
| 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(); | 499 LocalFrame* frame = document.GetFrame(); |
| 542 if (frame) { | 500 if (frame) { |
| 543 remote_playback_client_ = | 501 remote_playback_client_ = |
| 544 frame->Loader().Client()->CreateWebRemotePlaybackClient(*this); | 502 frame->Loader().Client()->CreateWebRemotePlaybackClient(*this); |
| 545 } | 503 } |
| 546 | 504 |
| 547 SetHasCustomStyleCallbacks(); | 505 SetHasCustomStyleCallbacks(); |
| 548 AddElementToDocumentMap(this, &document); | 506 AddElementToDocumentMap(this, &document); |
| 549 | 507 |
| 550 UseCounter::Count(document, UseCounter::kHTMLMediaElement); | 508 UseCounter::Count(document, UseCounter::kHTMLMediaElement); |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 585 audio_tracks_timer_.MoveToNewTaskRunner( | 543 audio_tracks_timer_.MoveToNewTaskRunner( |
| 586 TaskRunnerHelper::Get(TaskType::kUnthrottled, &GetDocument())); | 544 TaskRunnerHelper::Get(TaskType::kUnthrottled, &GetDocument())); |
| 587 viewport_fill_debouncer_timer_.MoveToNewTaskRunner( | 545 viewport_fill_debouncer_timer_.MoveToNewTaskRunner( |
| 588 TaskRunnerHelper::Get(TaskType::kUnthrottled, &GetDocument())); | 546 TaskRunnerHelper::Get(TaskType::kUnthrottled, &GetDocument())); |
| 589 check_viewport_intersection_timer_.MoveToNewTaskRunner( | 547 check_viewport_intersection_timer_.MoveToNewTaskRunner( |
| 590 TaskRunnerHelper::Get(TaskType::kUnthrottled, &GetDocument())); | 548 TaskRunnerHelper::Get(TaskType::kUnthrottled, &GetDocument())); |
| 591 deferred_load_timer_.MoveToNewTaskRunner( | 549 deferred_load_timer_.MoveToNewTaskRunner( |
| 592 TaskRunnerHelper::Get(TaskType::kUnthrottled, &GetDocument())); | 550 TaskRunnerHelper::Get(TaskType::kUnthrottled, &GetDocument())); |
| 593 | 551 |
| 594 autoplay_uma_helper_->DidMoveToNewDocument(old_document); | 552 autoplay_uma_helper_->DidMoveToNewDocument(old_document); |
| 595 // If any experiment is enabled, then we want to enable a user gesture by | 553 autoplay_policy_->DidMoveToNewDocument(old_document); |
| 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 612 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1474 // (vs. non-CORS-enabled or failed). | 1418 // (vs. non-CORS-enabled or failed). |
| 1475 // taintsCanvas() does checkAccess() on the URL plus allow data sources, | 1419 // taintsCanvas() does checkAccess() on the URL plus allow data sources, |
| 1476 // to ensure that it is not a URL that requires CORS (basically same | 1420 // to ensure that it is not a URL that requires CORS (basically same |
| 1477 // origin). | 1421 // origin). |
| 1478 return HasSingleSecurityOrigin() && | 1422 return HasSingleSecurityOrigin() && |
| 1479 ((GetWebMediaPlayer() && | 1423 ((GetWebMediaPlayer() && |
| 1480 GetWebMediaPlayer()->DidPassCORSAccessCheck()) || | 1424 GetWebMediaPlayer()->DidPassCORSAccessCheck()) || |
| 1481 !origin->TaintsCanvas(currentSrc())); | 1425 !origin->TaintsCanvas(currentSrc())); |
| 1482 } | 1426 } |
| 1483 | 1427 |
| 1484 bool HTMLMediaElement::IsInCrossOriginFrame() const { | |
| 1485 return IsDocumentCrossOrigin(GetDocument()); | |
| 1486 } | |
| 1487 | |
| 1488 void HTMLMediaElement::StartProgressEventTimer() { | 1428 void HTMLMediaElement::StartProgressEventTimer() { |
| 1489 if (progress_event_timer_.IsActive()) | 1429 if (progress_event_timer_.IsActive()) |
| 1490 return; | 1430 return; |
| 1491 | 1431 |
| 1492 previous_progress_time_ = WTF::CurrentTime(); | 1432 previous_progress_time_ = WTF::CurrentTime(); |
| 1493 // 350ms is not magic, it is in the spec! | 1433 // 350ms is not magic, it is in the spec! |
| 1494 progress_event_timer_.StartRepeating(0.350, BLINK_FROM_HERE); | 1434 progress_event_timer_.StartRepeating(0.350, BLINK_FROM_HERE); |
| 1495 } | 1435 } |
| 1496 | 1436 |
| 1497 void HTMLMediaElement::WaitForSourceChange() { | 1437 void HTMLMediaElement::WaitForSourceChange() { |
| (...skipping 338 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1836 if (old_state <= kHaveCurrentData) { | 1776 if (old_state <= kHaveCurrentData) { |
| 1837 ScheduleEvent(EventTypeNames::canplay); | 1777 ScheduleEvent(EventTypeNames::canplay); |
| 1838 if (is_potentially_playing) | 1778 if (is_potentially_playing) |
| 1839 ScheduleNotifyPlaying(); | 1779 ScheduleNotifyPlaying(); |
| 1840 } | 1780 } |
| 1841 | 1781 |
| 1842 // Check for autoplay, and record metrics about it if needed. | 1782 // Check for autoplay, and record metrics about it if needed. |
| 1843 if (ShouldAutoplay()) { | 1783 if (ShouldAutoplay()) { |
| 1844 autoplay_uma_helper_->OnAutoplayInitiated(AutoplaySource::kAttribute); | 1784 autoplay_uma_helper_->OnAutoplayInitiated(AutoplaySource::kAttribute); |
| 1845 | 1785 |
| 1846 if (!IsGestureNeededForPlayback()) { | 1786 if (!autoplay_policy_->IsGestureNeededForPlayback()) { |
| 1847 if (IsGestureNeededForPlaybackIfCrossOriginExperimentEnabled()) { | 1787 if (autoplay_policy_ |
| 1788 ->IsGestureNeededForPlaybackIfCrossOriginExperimentEnabled()) { | |
| 1848 autoplay_uma_helper_->RecordCrossOriginAutoplayResult( | 1789 autoplay_uma_helper_->RecordCrossOriginAutoplayResult( |
| 1849 CrossOriginAutoplayResult::kAutoplayBlocked); | 1790 CrossOriginAutoplayResult::kAutoplayBlocked); |
| 1850 } else { | 1791 } else { |
| 1851 autoplay_uma_helper_->RecordCrossOriginAutoplayResult( | 1792 autoplay_uma_helper_->RecordCrossOriginAutoplayResult( |
| 1852 CrossOriginAutoplayResult::kAutoplayAllowed); | 1793 CrossOriginAutoplayResult::kAutoplayAllowed); |
| 1853 } | 1794 } |
| 1854 if (IsHTMLVideoElement() && muted() && | 1795 if (autoplay_policy_->IsEligibleForAutoplayMuted()) { |
| 1855 RuntimeEnabledFeatures::autoplayMutedVideosEnabled()) { | 1796 autoplay_policy_->StartAutoplayMutedWhenVisible(); |
| 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 { | 1797 } else { |
| 1867 paused_ = false; | 1798 paused_ = false; |
| 1868 ScheduleEvent(EventTypeNames::play); | 1799 ScheduleEvent(EventTypeNames::play); |
| 1869 ScheduleNotifyPlaying(); | 1800 ScheduleNotifyPlaying(); |
| 1870 can_autoplay_ = false; | 1801 can_autoplay_ = false; |
| 1871 } | 1802 } |
| 1872 } else { | 1803 } else { |
| 1873 autoplay_uma_helper_->RecordCrossOriginAutoplayResult( | 1804 autoplay_uma_helper_->RecordCrossOriginAutoplayResult( |
| 1874 CrossOriginAutoplayResult::kAutoplayBlocked); | 1805 CrossOriginAutoplayResult::kAutoplayBlocked); |
| 1875 } | 1806 } |
| (...skipping 400 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2276 // https://crbug.com/310450 | 2207 // https://crbug.com/310450 |
| 2277 UseCounter::Count(GetDocument(), UseCounter::kHTMLMediaElementPreloadDefault); | 2208 UseCounter::Count(GetDocument(), UseCounter::kHTMLMediaElementPreloadDefault); |
| 2278 return WebMediaPlayer::kPreloadAuto; | 2209 return WebMediaPlayer::kPreloadAuto; |
| 2279 } | 2210 } |
| 2280 | 2211 |
| 2281 String HTMLMediaElement::EffectivePreload() const { | 2212 String HTMLMediaElement::EffectivePreload() const { |
| 2282 return PreloadTypeToString(EffectivePreloadType()); | 2213 return PreloadTypeToString(EffectivePreloadType()); |
| 2283 } | 2214 } |
| 2284 | 2215 |
| 2285 WebMediaPlayer::Preload HTMLMediaElement::EffectivePreloadType() const { | 2216 WebMediaPlayer::Preload HTMLMediaElement::EffectivePreloadType() const { |
| 2286 if (Autoplay() && !IsGestureNeededForPlayback()) | 2217 if (Autoplay() && !autoplay_policy_->IsGestureNeededForPlayback()) |
| 2287 return WebMediaPlayer::kPreloadAuto; | 2218 return WebMediaPlayer::kPreloadAuto; |
| 2288 | 2219 |
| 2289 WebMediaPlayer::Preload preload = PreloadType(); | 2220 WebMediaPlayer::Preload preload = PreloadType(); |
| 2290 if (ignore_preload_none_ && preload == WebMediaPlayer::kPreloadNone) | 2221 if (ignore_preload_none_ && preload == WebMediaPlayer::kPreloadNone) |
| 2291 return WebMediaPlayer::kPreloadMetaData; | 2222 return WebMediaPlayer::kPreloadMetaData; |
| 2292 | 2223 |
| 2293 return preload; | 2224 return preload; |
| 2294 } | 2225 } |
| 2295 | 2226 |
| 2296 ScriptPromise HTMLMediaElement::playForBindings(ScriptState* script_state) { | 2227 ScriptPromise HTMLMediaElement::playForBindings(ScriptState* script_state) { |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 2322 resolver->Reject(DOMException::Create(code.Get(), message)); | 2253 resolver->Reject(DOMException::Create(code.Get(), message)); |
| 2323 return promise; | 2254 return promise; |
| 2324 } | 2255 } |
| 2325 | 2256 |
| 2326 return promise; | 2257 return promise; |
| 2327 } | 2258 } |
| 2328 | 2259 |
| 2329 Nullable<ExceptionCode> HTMLMediaElement::Play() { | 2260 Nullable<ExceptionCode> HTMLMediaElement::Play() { |
| 2330 BLINK_MEDIA_LOG << "play(" << (void*)this << ")"; | 2261 BLINK_MEDIA_LOG << "play(" << (void*)this << ")"; |
| 2331 | 2262 |
| 2332 if (!UserGestureIndicator::ProcessingUserGesture()) { | 2263 // If we're already playing, then this play would do nothing anyway. |
| 2333 autoplay_uma_helper_->OnAutoplayInitiated(AutoplaySource::kMethod); | 2264 // Call playInternal to handle scheduling the promise resolution. |
| 2334 if (IsGestureNeededForPlayback()) { | 2265 if (!paused_) { |
| 2335 // If we're already playing, then this play would do nothing anyway. | 2266 PlayInternal(); |
| 2336 // Call playInternal to handle scheduling the promise resolution. | 2267 return nullptr; |
| 2337 if (!paused_) { | 2268 } |
|
mlamouri (slow - plz ping)
2017/04/18 13:28:28
The logic is slightly changing with this change. I
Zhiqiang Zhang (Slow)
2017/04/18 16:56:44
OK, I moved the code a bit so it should have the s
| |
| 2338 PlayInternal(); | |
| 2339 return nullptr; | |
| 2340 } | |
| 2341 | 2269 |
| 2342 autoplay_uma_helper_->RecordCrossOriginAutoplayResult( | 2270 autoplay_policy_->StopAutoplayMutedWhenVisible(); |
| 2343 CrossOriginAutoplayResult::kAutoplayBlocked); | |
| 2344 String message = ExceptionMessages::FailedToExecute( | |
| 2345 "play", "HTMLMediaElement", | |
| 2346 "API can only be initiated by a user gesture."); | |
| 2347 GetDocument().AddConsoleMessage(ConsoleMessage::Create( | |
| 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 } | |
| 2359 } else { | |
| 2360 autoplay_uma_helper_->RecordCrossOriginAutoplayResult( | |
| 2361 CrossOriginAutoplayResult::kPlayedWithGesture); | |
| 2362 UserGestureIndicator::UtilizeUserGesture(); | |
| 2363 UnlockUserGesture(); | |
| 2364 } | |
| 2365 | 2271 |
| 2366 if (error_ && error_->code() == MediaError::kMediaErrSrcNotSupported) | 2272 if (error_ && error_->code() == MediaError::kMediaErrSrcNotSupported) |
| 2367 return kNotSupportedError; | 2273 return kNotSupportedError; |
| 2368 | 2274 |
| 2369 if (autoplay_visibility_observer_) { | 2275 // The only place to call IsAutoplayAllowedFromPlayMethod(), don't call from |
| 2370 autoplay_visibility_observer_->Stop(); | 2276 // anywhere else! |
|
mlamouri (slow - plz ping)
2017/04/18 13:28:28
Comment is out of date, right?
Zhiqiang Zhang (Slow)
2017/04/18 16:56:44
Done.
| |
| 2371 autoplay_visibility_observer_ = nullptr; | 2277 Nullable<ExceptionCode> exception_code = |
| 2278 autoplay_policy_->CheckPlayMethodAllowed(); | |
| 2279 | |
| 2280 if (exception_code == kNotAllowedError) { | |
| 2281 String message = ExceptionMessages::FailedToExecute( | |
| 2282 "play", "HTMLMediaElement", | |
| 2283 "API can only be initiated by a user gesture."); | |
| 2284 GetDocument().AddConsoleMessage(ConsoleMessage::Create( | |
| 2285 kJSMessageSource, kWarningMessageLevel, message)); | |
| 2286 return exception_code; | |
| 2372 } | 2287 } |
| 2373 | 2288 |
| 2289 DCHECK(exception_code.IsNull()); | |
| 2290 | |
| 2374 PlayInternal(); | 2291 PlayInternal(); |
| 2375 | 2292 |
| 2376 return nullptr; | 2293 return nullptr; |
| 2377 } | 2294 } |
| 2378 | 2295 |
| 2379 void HTMLMediaElement::PlayInternal() { | 2296 void HTMLMediaElement::PlayInternal() { |
| 2380 BLINK_MEDIA_LOG << "playInternal(" << (void*)this << ")"; | 2297 BLINK_MEDIA_LOG << "playInternal(" << (void*)this << ")"; |
| 2381 | 2298 |
| 2382 // 4.8.12.8. Playing the media resource | 2299 // 4.8.12.8. Playing the media resource |
| 2383 if (network_state_ == kNetworkEmpty) | 2300 if (network_state_ == kNetworkEmpty) |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 2403 | 2320 |
| 2404 can_autoplay_ = false; | 2321 can_autoplay_ = false; |
| 2405 | 2322 |
| 2406 SetIgnorePreloadNone(); | 2323 SetIgnorePreloadNone(); |
| 2407 UpdatePlayState(); | 2324 UpdatePlayState(); |
| 2408 } | 2325 } |
| 2409 | 2326 |
| 2410 void HTMLMediaElement::pause() { | 2327 void HTMLMediaElement::pause() { |
| 2411 BLINK_MEDIA_LOG << "pause(" << (void*)this << ")"; | 2328 BLINK_MEDIA_LOG << "pause(" << (void*)this << ")"; |
| 2412 | 2329 |
| 2413 if (autoplay_visibility_observer_) { | 2330 autoplay_policy_->StopAutoplayMutedWhenVisible(); |
| 2414 autoplay_visibility_observer_->Stop(); | |
| 2415 autoplay_visibility_observer_ = nullptr; | |
| 2416 } | |
| 2417 | |
| 2418 PauseInternal(); | 2331 PauseInternal(); |
| 2419 } | 2332 } |
| 2420 | 2333 |
| 2421 void HTMLMediaElement::PauseInternal() { | 2334 void HTMLMediaElement::PauseInternal() { |
| 2422 BLINK_MEDIA_LOG << "pauseInternal(" << (void*)this << ")"; | 2335 BLINK_MEDIA_LOG << "pauseInternal(" << (void*)this << ")"; |
| 2423 | 2336 |
| 2424 if (network_state_ == kNetworkEmpty) | 2337 if (network_state_ == kNetworkEmpty) |
| 2425 InvokeResourceSelectionAlgorithm(); | 2338 InvokeResourceSelectionAlgorithm(); |
| 2426 | 2339 |
| 2427 can_autoplay_ = false; | 2340 can_autoplay_ = false; |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2555 return muted_; | 2468 return muted_; |
| 2556 } | 2469 } |
| 2557 | 2470 |
| 2558 void HTMLMediaElement::setMuted(bool muted) { | 2471 void HTMLMediaElement::setMuted(bool muted) { |
| 2559 BLINK_MEDIA_LOG << "setMuted(" << (void*)this << ", " << BoolString(muted) | 2472 BLINK_MEDIA_LOG << "setMuted(" << (void*)this << ", " << BoolString(muted) |
| 2560 << ")"; | 2473 << ")"; |
| 2561 | 2474 |
| 2562 if (muted_ == muted) | 2475 if (muted_ == muted) |
| 2563 return; | 2476 return; |
| 2564 | 2477 |
| 2565 bool was_autoplaying_muted = IsAutoplayingMuted(); | 2478 // TODO(zqzhang): use TryUnlockingUserGesture? |
| 2566 bool was_pending_autoplay_muted = autoplay_visibility_observer_ && paused() && | 2479 if (UserGestureIndicator::ProcessingUserGesture()) |
| 2567 muted_ && IsLockedPendingUserGesture(); | 2480 autoplay_policy_->UnlockUserGesture(); |
| 2568 | 2481 |
| 2569 if (UserGestureIndicator::ProcessingUserGesture()) | 2482 bool should_pause_after_unmute = |
| 2570 UnlockUserGesture(); | 2483 autoplay_policy_->CheckUnmuteShouldPauseAutoplay(); |
|
mlamouri (slow - plz ping)
2017/04/18 13:28:28
Not sure this is at the right place. Should this b
Zhiqiang Zhang (Slow)
2017/04/18 16:56:44
The logic won't change actually.
The original logi
| |
| 2571 | 2484 |
| 2572 muted_ = muted; | 2485 muted_ = muted; |
| 2573 | 2486 |
| 2574 ScheduleEvent(EventTypeNames::volumechange); | 2487 ScheduleEvent(EventTypeNames::volumechange); |
| 2575 | 2488 |
| 2576 // If an element autoplayed while muted, it needs to be unlocked to unmute, | 2489 if (should_pause_after_unmute) |
| 2577 // otherwise, it will be paused. | 2490 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 | 2491 |
| 2589 // This is called after the volumechange event to make sure isAutoplayingMuted | 2492 // This is called after the volumechange event to make sure isAutoplayingMuted |
| 2590 // returns the right value when webMediaPlayer receives the volume update. | 2493 // returns the right value when webMediaPlayer receives the volume update. |
| 2591 if (GetWebMediaPlayer()) | 2494 if (GetWebMediaPlayer()) |
| 2592 GetWebMediaPlayer()->SetVolume(EffectiveMediaVolume()); | 2495 GetWebMediaPlayer()->SetVolume(EffectiveMediaVolume()); |
| 2593 | 2496 |
| 2594 // If an element was a candidate for autoplay muted but not visible, it will | 2497 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 } | 2498 } |
| 2601 | 2499 |
| 2602 double HTMLMediaElement::EffectiveMediaVolume() const { | 2500 double HTMLMediaElement::EffectiveMediaVolume() const { |
| 2603 if (muted_) | 2501 if (muted_) |
| 2604 return 0; | 2502 return 0; |
| 2605 | 2503 |
| 2606 return volume_; | 2504 return volume_; |
| 2607 } | 2505 } |
| 2608 | 2506 |
| 2609 // The spec says to fire periodic timeupdate events (those sent while playing) | 2507 // 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() { | 3209 WebMediaPlayer::TrackId HTMLMediaElement::GetSelectedVideoTrackId() { |
| 3312 DCHECK(RuntimeEnabledFeatures::backgroundVideoTrackOptimizationEnabled()); | 3210 DCHECK(RuntimeEnabledFeatures::backgroundVideoTrackOptimizationEnabled()); |
| 3313 DCHECK(HasSelectedVideoTrack()); | 3211 DCHECK(HasSelectedVideoTrack()); |
| 3314 | 3212 |
| 3315 int selected_track_index = video_tracks_->selectedIndex(); | 3213 int selected_track_index = video_tracks_->selectedIndex(); |
| 3316 VideoTrack* track = | 3214 VideoTrack* track = |
| 3317 video_tracks_->AnonymousIndexedGetter(selected_track_index); | 3215 video_tracks_->AnonymousIndexedGetter(selected_track_index); |
| 3318 return track->id(); | 3216 return track->id(); |
| 3319 } | 3217 } |
| 3320 | 3218 |
| 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) { | 3219 void HTMLMediaElement::RequestReload(const WebURL& new_url) { |
| 3331 DCHECK(GetWebMediaPlayer()); | 3220 DCHECK(GetWebMediaPlayer()); |
| 3332 DCHECK(!src_object_); | 3221 DCHECK(!src_object_); |
| 3333 DCHECK(new_url.IsValid()); | 3222 DCHECK(new_url.IsValid()); |
| 3334 DCHECK(IsSafeToLoadURL(new_url, kComplain)); | 3223 DCHECK(IsSafeToLoadURL(new_url, kComplain)); |
| 3335 ResetMediaPlayerAndMediaSource(); | 3224 ResetMediaPlayerAndMediaSource(); |
| 3336 StartPlayerLoad(new_url); | 3225 StartPlayerLoad(new_url); |
| 3337 } | 3226 } |
| 3338 | 3227 |
| 3228 bool HTMLMediaElement::IsAutoplayingMuted() { | |
| 3229 return autoplay_policy_->IsAutoplayingMuted(); | |
| 3230 } | |
| 3231 | |
| 3339 // MediaPlayerPresentation methods | 3232 // MediaPlayerPresentation methods |
| 3340 void HTMLMediaElement::Repaint() { | 3233 void HTMLMediaElement::Repaint() { |
| 3341 if (web_layer_) | 3234 if (web_layer_) |
| 3342 web_layer_->Invalidate(); | 3235 web_layer_->Invalidate(); |
| 3343 | 3236 |
| 3344 UpdateDisplayState(); | 3237 UpdateDisplayState(); |
| 3345 if (GetLayoutObject()) | 3238 if (GetLayoutObject()) |
| 3346 GetLayoutObject()->SetShouldDoFullPaintInvalidation(); | 3239 GetLayoutObject()->SetShouldDoFullPaintInvalidation(); |
| 3347 } | 3240 } |
| 3348 | 3241 |
| (...skipping 577 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3926 visitor->Trace(video_tracks_); | 3819 visitor->Trace(video_tracks_); |
| 3927 visitor->Trace(cue_timeline_); | 3820 visitor->Trace(cue_timeline_); |
| 3928 visitor->Trace(text_tracks_); | 3821 visitor->Trace(text_tracks_); |
| 3929 visitor->Trace(text_tracks_when_resource_selection_began_); | 3822 visitor->Trace(text_tracks_when_resource_selection_began_); |
| 3930 visitor->Trace(play_promise_resolvers_); | 3823 visitor->Trace(play_promise_resolvers_); |
| 3931 visitor->Trace(play_promise_resolve_list_); | 3824 visitor->Trace(play_promise_resolve_list_); |
| 3932 visitor->Trace(play_promise_reject_list_); | 3825 visitor->Trace(play_promise_reject_list_); |
| 3933 visitor->Trace(audio_source_provider_); | 3826 visitor->Trace(audio_source_provider_); |
| 3934 visitor->Trace(autoplay_uma_helper_); | 3827 visitor->Trace(autoplay_uma_helper_); |
| 3935 visitor->Trace(src_object_); | 3828 visitor->Trace(src_object_); |
| 3936 visitor->Trace(autoplay_visibility_observer_); | 3829 visitor->Trace(autoplay_policy_); |
| 3937 visitor->Trace(media_controls_); | 3830 visitor->Trace(media_controls_); |
| 3938 visitor->Trace(controls_list_); | 3831 visitor->Trace(controls_list_); |
| 3939 visitor->template RegisterWeakMembers<HTMLMediaElement, | 3832 visitor->template RegisterWeakMembers<HTMLMediaElement, |
| 3940 &HTMLMediaElement::ClearWeakMembers>( | 3833 &HTMLMediaElement::ClearWeakMembers>( |
| 3941 this); | 3834 this); |
| 3942 Supplementable<HTMLMediaElement>::Trace(visitor); | 3835 Supplementable<HTMLMediaElement>::Trace(visitor); |
| 3943 HTMLElement::Trace(visitor); | 3836 HTMLElement::Trace(visitor); |
| 3944 SuspendableObject::Trace(visitor); | 3837 SuspendableObject::Trace(visitor); |
| 3945 } | 3838 } |
| 3946 | 3839 |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 3976 | 3869 |
| 3977 // Enable the first audio track if an audio track hasn't been enabled yet. | 3870 // Enable the first audio track if an audio track hasn't been enabled yet. |
| 3978 if (audioTracks().length() > 0 && !audioTracks().HasEnabledTrack()) | 3871 if (audioTracks().length() > 0 && !audioTracks().HasEnabledTrack()) |
| 3979 audioTracks().AnonymousIndexedGetter(0)->setEnabled(true); | 3872 audioTracks().AnonymousIndexedGetter(0)->setEnabled(true); |
| 3980 | 3873 |
| 3981 // Select the first video track if a video track hasn't been selected yet. | 3874 // Select the first video track if a video track hasn't been selected yet. |
| 3982 if (videoTracks().length() > 0 && videoTracks().selectedIndex() == -1) | 3875 if (videoTracks().length() > 0 && videoTracks().selectedIndex() == -1) |
| 3983 videoTracks().AnonymousIndexedGetter(0)->setSelected(true); | 3876 videoTracks().AnonymousIndexedGetter(0)->setSelected(true); |
| 3984 } | 3877 } |
| 3985 | 3878 |
| 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) { | 3879 void HTMLMediaElement::SetNetworkState(NetworkState state) { |
| 4041 if (network_state_ == state) | 3880 if (network_state_ == state) |
| 4042 return; | 3881 return; |
| 4043 | 3882 |
| 4044 network_state_ = state; | 3883 network_state_ = state; |
| 4045 if (GetMediaControls()) | 3884 if (GetMediaControls()) |
| 4046 GetMediaControls()->NetworkStateChanged(); | 3885 GetMediaControls()->NetworkStateChanged(); |
| 4047 } | 3886 } |
| 4048 | 3887 |
| 4049 void HTMLMediaElement::VideoWillBeDrawnToCanvas() const { | 3888 void HTMLMediaElement::VideoWillBeDrawnToCanvas() const { |
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4159 DEFINE_STATIC_LOCAL(EnumerationHistogram, histogram, | 3998 DEFINE_STATIC_LOCAL(EnumerationHistogram, histogram, |
| 4160 ("Media.Controls.Show.Video", kMediaControlsShowMax)); | 3999 ("Media.Controls.Show.Video", kMediaControlsShowMax)); |
| 4161 return histogram; | 4000 return histogram; |
| 4162 } | 4001 } |
| 4163 | 4002 |
| 4164 DEFINE_STATIC_LOCAL(EnumerationHistogram, histogram, | 4003 DEFINE_STATIC_LOCAL(EnumerationHistogram, histogram, |
| 4165 ("Media.Controls.Show.Audio", kMediaControlsShowMax)); | 4004 ("Media.Controls.Show.Audio", kMediaControlsShowMax)); |
| 4166 return histogram; | 4005 return histogram; |
| 4167 } | 4006 } |
| 4168 | 4007 |
| 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) { | 4008 void HTMLMediaElement::ClearWeakMembers(Visitor* visitor) { |
| 4188 if (!ThreadHeap::IsHeapObjectAlive(audio_source_node_)) { | 4009 if (!ThreadHeap::IsHeapObjectAlive(audio_source_node_)) { |
| 4189 GetAudioSourceProvider().SetClient(nullptr); | 4010 GetAudioSourceProvider().SetClient(nullptr); |
| 4190 audio_source_node_ = nullptr; | 4011 audio_source_node_ = nullptr; |
| 4191 } | 4012 } |
| 4192 } | 4013 } |
| 4193 | 4014 |
| 4194 void HTMLMediaElement::AudioSourceProviderImpl::Wrap( | 4015 void HTMLMediaElement::AudioSourceProviderImpl::Wrap( |
| 4195 WebAudioSourceProvider* provider) { | 4016 WebAudioSourceProvider* provider) { |
| 4196 MutexLocker locker(provide_input_lock); | 4017 MutexLocker locker(provide_input_lock); |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4289 kMostlyFillViewportBecomeStableSeconds, BLINK_FROM_HERE); | 4110 kMostlyFillViewportBecomeStableSeconds, BLINK_FROM_HERE); |
| 4290 } | 4111 } |
| 4291 | 4112 |
| 4292 void HTMLMediaElement::ViewportFillDebouncerTimerFired(TimerBase*) { | 4113 void HTMLMediaElement::ViewportFillDebouncerTimerFired(TimerBase*) { |
| 4293 mostly_filling_viewport_ = true; | 4114 mostly_filling_viewport_ = true; |
| 4294 if (web_media_player_) | 4115 if (web_media_player_) |
| 4295 web_media_player_->BecameDominantVisibleContent(mostly_filling_viewport_); | 4116 web_media_player_->BecameDominantVisibleContent(mostly_filling_viewport_); |
| 4296 } | 4117 } |
| 4297 | 4118 |
| 4298 } // namespace blink | 4119 } // namespace blink |
| OLD | NEW |