OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "modules/media_controls/MediaControlsImpl.h" | 5 #include "modules/media_controls/MediaControlsImpl.h" |
6 | 6 |
7 #include <limits> | 7 #include <limits> |
8 #include <memory> | 8 #include <memory> |
9 | 9 |
10 #include "build/build_config.h" | 10 #include "build/build_config.h" |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
69 WebTimeRanges Seekable() const override { return seekable_; } | 69 WebTimeRanges Seekable() const override { return seekable_; } |
70 bool HasVideo() const override { return true; } | 70 bool HasVideo() const override { return true; } |
71 | 71 |
72 WebTimeRanges seekable_; | 72 WebTimeRanges seekable_; |
73 }; | 73 }; |
74 | 74 |
75 class MockLayoutObject : public LayoutObject { | 75 class MockLayoutObject : public LayoutObject { |
76 public: | 76 public: |
77 MockLayoutObject(Node* node) : LayoutObject(node) {} | 77 MockLayoutObject(Node* node) : LayoutObject(node) {} |
78 | 78 |
| 79 void SetVisible(bool visible) { visible_ = visible; } |
| 80 |
79 const char* GetName() const override { return "MockLayoutObject"; } | 81 const char* GetName() const override { return "MockLayoutObject"; } |
80 void UpdateLayout() override {} | 82 void UpdateLayout() override {} |
81 FloatRect LocalBoundingBoxRectForAccessibility() const override { | 83 FloatRect LocalBoundingBoxRectForAccessibility() const override { |
82 return FloatRect(); | 84 return FloatRect(); |
83 } | 85 } |
| 86 void AbsoluteQuads(Vector<FloatQuad>& quads, |
| 87 MapCoordinatesFlags mode) const override { |
| 88 if (!visible_) |
| 89 return; |
| 90 quads.push_back(FloatQuad(FloatRect(0.f, 0.f, 10.f, 10.f))); |
| 91 } |
| 92 |
| 93 private: |
| 94 bool visible_ = false; |
84 }; | 95 }; |
85 | 96 |
86 class StubLocalFrameClient : public EmptyLocalFrameClient { | 97 class StubLocalFrameClient : public EmptyLocalFrameClient { |
87 public: | 98 public: |
88 static StubLocalFrameClient* Create() { return new StubLocalFrameClient; } | 99 static StubLocalFrameClient* Create() { return new StubLocalFrameClient; } |
89 | 100 |
90 std::unique_ptr<WebMediaPlayer> CreateWebMediaPlayer( | 101 std::unique_ptr<WebMediaPlayer> CreateWebMediaPlayer( |
91 HTMLMediaElement&, | 102 HTMLMediaElement&, |
92 const WebMediaPlayerSource&, | 103 const WebMediaPlayerSource&, |
93 WebMediaPlayerClient*) override { | 104 WebMediaPlayerClient*) override { |
94 return WTF::WrapUnique(new MockVideoWebMediaPlayer); | 105 return WTF::WrapUnique(new MockVideoWebMediaPlayer); |
95 } | 106 } |
96 | 107 |
97 WebRemotePlaybackClient* CreateWebRemotePlaybackClient( | 108 WebRemotePlaybackClient* CreateWebRemotePlaybackClient( |
98 HTMLMediaElement& element) override { | 109 HTMLMediaElement& element) override { |
99 return HTMLMediaElementRemotePlayback::remote(element); | 110 return HTMLMediaElementRemotePlayback::remote(element); |
100 } | 111 } |
101 }; | 112 }; |
102 | 113 |
103 Element* GetElementByShadowPseudoId(Node& root_node, | 114 Element* GetElementByShadowPseudoId(Node& root_node, |
104 const char* shadow_pseudo_id) { | 115 const char* shadow_pseudo_id) { |
105 for (Element& element : ElementTraversal::DescendantsOf(root_node)) { | 116 for (Element& element : ElementTraversal::DescendantsOf(root_node)) { |
106 if (element.ShadowPseudoId() == shadow_pseudo_id) | 117 if (element.ShadowPseudoId() == shadow_pseudo_id) |
107 return &element; | 118 return &element; |
108 } | 119 } |
109 return nullptr; | 120 return nullptr; |
110 } | 121 } |
111 | 122 |
| 123 MediaControlDownloadButtonElement& GetDownloadButton( |
| 124 MediaControlsImpl& controls) { |
| 125 Element* element = GetElementByShadowPseudoId( |
| 126 controls, "-internal-media-controls-download-button"); |
| 127 return static_cast<MediaControlDownloadButtonElement&>(*element); |
| 128 } |
| 129 |
112 bool IsElementVisible(Element& element) { | 130 bool IsElementVisible(Element& element) { |
113 const StylePropertySet* inline_style = element.InlineStyle(); | 131 const StylePropertySet* inline_style = element.InlineStyle(); |
114 | 132 |
115 if (!inline_style) | 133 if (!inline_style) |
116 return true; | 134 return true; |
117 | 135 |
118 if (inline_style->GetPropertyValue(CSSPropertyDisplay) == "none") | 136 if (inline_style->GetPropertyValue(CSSPropertyDisplay) == "none") |
119 return false; | 137 return false; |
120 | 138 |
121 if (inline_style->HasProperty(CSSPropertyOpacity) && | 139 if (inline_style->HasProperty(CSSPropertyOpacity) && |
(...skipping 442 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
564 MediaControls(), "-internal-media-controls-download-button"); | 582 MediaControls(), "-internal-media-controls-download-button"); |
565 ASSERT_NE(nullptr, download_button); | 583 ASSERT_NE(nullptr, download_button); |
566 | 584 |
567 // Download button should not be displayed for HLS streams. | 585 // Download button should not be displayed for HLS streams. |
568 MediaControls().MediaElement().SetSrc("https://example.com/foo.m3u8"); | 586 MediaControls().MediaElement().SetSrc("https://example.com/foo.m3u8"); |
569 testing::RunPendingTasks(); | 587 testing::RunPendingTasks(); |
570 SimulateLoadedMetadata(); | 588 SimulateLoadedMetadata(); |
571 EXPECT_FALSE(IsElementVisible(*download_button)); | 589 EXPECT_FALSE(IsElementVisible(*download_button)); |
572 } | 590 } |
573 | 591 |
| 592 TEST_F(MediaControlsImplTest, DownloadButtonInProductHelp_Settings) { |
| 593 EnsureSizing(); |
| 594 |
| 595 // Inject the LayoutObject for the button to override the rect returned in |
| 596 // visual viewport. |
| 597 MediaControlDownloadButtonElement& button = |
| 598 GetDownloadButton(MediaControls()); |
| 599 MockLayoutObject layout_object(&button); |
| 600 layout_object.SetVisible(true); |
| 601 button.SetLayoutObject(&layout_object); |
| 602 |
| 603 // In-product help not triggered when disabled from the settings. |
| 604 MediaControls().MediaElement().SetSrc("https://example.com/foo.mp4"); |
| 605 testing::RunPendingTasks(); |
| 606 SimulateLoadedMetadata(); |
| 607 MediaControls().MediaElement().Play(); |
| 608 |
| 609 ASSERT_TRUE(button.IsWanted()); |
| 610 EXPECT_FALSE(button.IsShowingInProductHelp()); |
| 611 |
| 612 // Enable the setting which should show the in-product help. |
| 613 MediaControls() |
| 614 .MediaElement() |
| 615 .GetDocument() |
| 616 .GetSettings() |
| 617 ->SetMediaDownloadInProductHelpEnabled(true); |
| 618 button.SetIsWanted(button.IsWanted()); |
| 619 EXPECT_TRUE(button.IsShowingInProductHelp()); |
| 620 EXPECT_TRUE(MediaControls().IsVisible()); |
| 621 |
| 622 // Disable the download button, which dismisses the in-product-help. |
| 623 button.SetIsWanted(false); |
| 624 EXPECT_FALSE(button.IsShowingInProductHelp()); |
| 625 |
| 626 // Re-enable. In-product-help should be restricted to once per element. |
| 627 button.SetIsWanted(true); |
| 628 EXPECT_FALSE(button.IsShowingInProductHelp()); |
| 629 |
| 630 button.SetLayoutObject(nullptr); |
| 631 } |
| 632 |
| 633 TEST_F(MediaControlsImplTest, DownloadButtonInProductHelp_ControlsVisibility) { |
| 634 EnsureSizing(); |
| 635 |
| 636 // Inject the LayoutObject for the button to override the rect returned in |
| 637 // visual viewport. |
| 638 MediaControlDownloadButtonElement& button = |
| 639 GetDownloadButton(MediaControls()); |
| 640 MockLayoutObject layout_object(&button); |
| 641 layout_object.SetVisible(true); |
| 642 button.SetLayoutObject(&layout_object); |
| 643 |
| 644 MediaControls() |
| 645 .MediaElement() |
| 646 .GetDocument() |
| 647 .GetSettings() |
| 648 ->SetMediaDownloadInProductHelpEnabled(true); |
| 649 |
| 650 // The in-product-help should not be shown while the controls are hidden. |
| 651 MediaControls().Hide(); |
| 652 MediaControls().MediaElement().SetSrc("https://example.com/foo.mp4"); |
| 653 testing::RunPendingTasks(); |
| 654 SimulateLoadedMetadata(); |
| 655 MediaControls().MediaElement().Play(); |
| 656 |
| 657 ASSERT_TRUE(button.IsWanted()); |
| 658 EXPECT_FALSE(button.IsShowingInProductHelp()); |
| 659 |
| 660 // Showing the controls initiates showing in-product-help. |
| 661 MediaControls().MaybeShow(); |
| 662 EXPECT_TRUE(button.IsShowingInProductHelp()); |
| 663 EXPECT_TRUE(MediaControls().IsVisible()); |
| 664 |
| 665 // Hiding the controls dismissed in-product-help. |
| 666 MediaControls().Hide(); |
| 667 EXPECT_FALSE(button.IsShowingInProductHelp()); |
| 668 |
| 669 button.SetLayoutObject(nullptr); |
| 670 } |
| 671 |
| 672 TEST_F(MediaControlsImplTest, DownloadButtonInProductHelp_ButtonVisibility) { |
| 673 EnsureSizing(); |
| 674 |
| 675 // Inject the LayoutObject for the button to override the rect returned in |
| 676 // visual viewport. |
| 677 MediaControlDownloadButtonElement& button = |
| 678 GetDownloadButton(MediaControls()); |
| 679 MockLayoutObject layout_object(&button); |
| 680 button.SetLayoutObject(&layout_object); |
| 681 |
| 682 MediaControls() |
| 683 .MediaElement() |
| 684 .GetDocument() |
| 685 .GetSettings() |
| 686 ->SetMediaDownloadInProductHelpEnabled(true); |
| 687 |
| 688 // The in-product-help should not be shown while the button is hidden. |
| 689 layout_object.SetVisible(false); |
| 690 MediaControls().MediaElement().SetSrc("https://example.com/foo.mp4"); |
| 691 testing::RunPendingTasks(); |
| 692 SimulateLoadedMetadata(); |
| 693 MediaControls().MediaElement().Play(); |
| 694 |
| 695 ASSERT_TRUE(button.IsWanted()); |
| 696 EXPECT_FALSE(button.IsShowingInProductHelp()); |
| 697 |
| 698 // Make the button visible to show in-product-help. |
| 699 layout_object.SetVisible(true); |
| 700 button.SetIsWanted(button.IsWanted()); |
| 701 EXPECT_TRUE(button.IsShowingInProductHelp()); |
| 702 EXPECT_TRUE(MediaControls().IsVisible()); |
| 703 |
| 704 button.SetLayoutObject(nullptr); |
| 705 } |
| 706 |
574 TEST_F(MediaControlsImplTest, TimelineSeekToRoundedEnd) { | 707 TEST_F(MediaControlsImplTest, TimelineSeekToRoundedEnd) { |
575 EnsureSizing(); | 708 EnsureSizing(); |
576 | 709 |
577 // Tests the case where the real length of the video, |exact_duration|, gets | 710 // Tests the case where the real length of the video, |exact_duration|, gets |
578 // rounded up slightly to |rounded_up_duration| when setting the timeline's | 711 // rounded up slightly to |rounded_up_duration| when setting the timeline's |
579 // |max| attribute (crbug.com/695065). | 712 // |max| attribute (crbug.com/695065). |
580 double exact_duration = 596.586667; | 713 double exact_duration = 596.586667; |
581 double rounded_up_duration = 596.587; | 714 double rounded_up_duration = 596.587; |
582 LoadMediaWithDuration(exact_duration); | 715 LoadMediaWithDuration(exact_duration); |
583 | 716 |
(...skipping 326 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
910 { | 1043 { |
911 Persistent<HTMLMediaElement> video_holder = element; | 1044 Persistent<HTMLMediaElement> video_holder = element; |
912 page_holder->GetDocument().body()->RemoveChild(element); | 1045 page_holder->GetDocument().body()->RemoveChild(element); |
913 page_holder->GetDocument().body()->AppendChild(video_holder.Get()); | 1046 page_holder->GetDocument().body()->AppendChild(video_holder.Get()); |
914 EXPECT_TRUE(remote_playback->HasEventListeners()); | 1047 EXPECT_TRUE(remote_playback->HasEventListeners()); |
915 EXPECT_TRUE(HasAvailabilityCallbacks(remote_playback)); | 1048 EXPECT_TRUE(HasAvailabilityCallbacks(remote_playback)); |
916 } | 1049 } |
917 } | 1050 } |
918 | 1051 |
919 } // namespace blink | 1052 } // namespace blink |
OLD | NEW |