1 // Copyright 2017 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "third_party/blink/renderer/core/html/media/media_custom_controls_fullscreen_detector.h"
6 
7 #include "testing/gtest/include/gtest/gtest.h"
8 #include "third_party/blink/renderer/core/event_type_names.h"
9 #include "third_party/blink/renderer/core/html/media/html_video_element.h"
10 #include "third_party/blink/renderer/core/testing/dummy_page_holder.h"
11 #include "third_party/blink/renderer/platform/geometry/int_rect.h"
12 #include "third_party/blink/renderer/platform/testing/runtime_enabled_features_test_helpers.h"
13 
14 namespace blink {
15 
16 class MediaCustomControlsFullscreenDetectorTest : public testing::Test {
17  protected:
SetUp()18   void SetUp() override {
19     page_holder_ = std::make_unique<DummyPageHolder>();
20     new_page_holder_ = std::make_unique<DummyPageHolder>();
21   }
22 
VideoElement() const23   HTMLVideoElement* VideoElement() const {
24     return To<HTMLVideoElement>(GetDocument().QuerySelector("video"));
25   }
26 
FullscreenDetectorFor(HTMLVideoElement * video_element)27   static MediaCustomControlsFullscreenDetector* FullscreenDetectorFor(
28       HTMLVideoElement* video_element) {
29     return video_element->custom_controls_fullscreen_detector_;
30   }
31 
FullscreenDetector() const32   MediaCustomControlsFullscreenDetector* FullscreenDetector() const {
33     return FullscreenDetectorFor(VideoElement());
34   }
35 
GetDocument() const36   Document& GetDocument() const { return page_holder_->GetDocument(); }
NewDocument() const37   Document& NewDocument() const { return new_page_holder_->GetDocument(); }
38 
CheckEventListenerRegistered(EventTarget & target,const AtomicString & event_type,EventListener * listener)39   bool CheckEventListenerRegistered(EventTarget& target,
40                                     const AtomicString& event_type,
41                                     EventListener* listener) {
42     EventListenerVector* listeners = target.GetEventListeners(event_type);
43     if (!listeners)
44       return false;
45 
46     for (const auto& registered_listener : *listeners) {
47       if (registered_listener.Callback() == listener)
48         return true;
49     }
50     return false;
51   }
52 
IsFullscreen(IntRect target,IntRect screen)53   static bool IsFullscreen(IntRect target, IntRect screen) {
54     IntRect intersection = Intersection(target, screen);
55     return MediaCustomControlsFullscreenDetector::
56         IsFullscreenVideoOfDifferentRatioForTesting(
57             target.Size(), screen.Size(), intersection.Size());
58   }
59 
60  private:
61   std::unique_ptr<DummyPageHolder> page_holder_;
62   std::unique_ptr<DummyPageHolder> new_page_holder_;
63   Persistent<HTMLVideoElement> video_;
64 };
65 
TEST_F(MediaCustomControlsFullscreenDetectorTest,heuristicForAspectRatios)66 TEST_F(MediaCustomControlsFullscreenDetectorTest, heuristicForAspectRatios) {
67   IntRect screen(0, 0, 1920, 1080);
68 
69   EXPECT_TRUE(IsFullscreen({0, 130, 1920, 820}, screen))
70       << "Ultrawide screen (21:9)";
71   EXPECT_TRUE(IsFullscreen({240, 0, 1440, 1080}, screen))
72       << "Standard TV (4:3)";
73   EXPECT_TRUE(IsFullscreen({656, 0, 607, 1080}, screen))
74       << "Full HD, but portrait (9:16)";
75 
76   EXPECT_TRUE(IsFullscreen({0, -100, 1920, 1080}, screen))
77       << "Normal fullscreen video but scrolled a bit up.";
78   EXPECT_TRUE(IsFullscreen({100, 0, 1920, 1080}, screen))
79       << "Normal fullscreen video but scrolled a bit right.";
80 
81   EXPECT_FALSE(IsFullscreen({0, -300, 1920, 1080}, screen))
82       << "Normal fullscreen video but scrolled a great deal up.";
83   EXPECT_FALSE(IsFullscreen({490, 0, 1920, 1080}, screen))
84       << "Normal fullscreen video but scrolled a great deal right.";
85 
86   EXPECT_FALSE(IsFullscreen({0, 0, 800, 600}, screen)) << "Small video";
87   EXPECT_FALSE(IsFullscreen({500, 100, 1024, 768}, screen))
88       << "Another small video";
89   EXPECT_FALSE(IsFullscreen({0, 0, 0, 0}, screen)) << "Hidden video";
90 }
91 
TEST_F(MediaCustomControlsFullscreenDetectorTest,hasNoListenersBeforeAddingToDocument)92 TEST_F(MediaCustomControlsFullscreenDetectorTest,
93        hasNoListenersBeforeAddingToDocument) {
94   auto* video = To<HTMLVideoElement>(
95       GetDocument().CreateRawElement(html_names::kVideoTag));
96 
97   EXPECT_FALSE(CheckEventListenerRegistered(GetDocument(),
98                                             event_type_names::kFullscreenchange,
99                                             FullscreenDetectorFor(video)));
100   EXPECT_FALSE(CheckEventListenerRegistered(
101       GetDocument(), event_type_names::kWebkitfullscreenchange,
102       FullscreenDetectorFor(video)));
103   EXPECT_FALSE(CheckEventListenerRegistered(
104       *video, event_type_names::kLoadedmetadata, FullscreenDetectorFor(video)));
105 }
106 
TEST_F(MediaCustomControlsFullscreenDetectorTest,hasListenersAfterAddToDocumentByScript)107 TEST_F(MediaCustomControlsFullscreenDetectorTest,
108        hasListenersAfterAddToDocumentByScript) {
109   auto* video = To<HTMLVideoElement>(
110       GetDocument().CreateRawElement(html_names::kVideoTag));
111   GetDocument().body()->AppendChild(video);
112 
113   EXPECT_TRUE(CheckEventListenerRegistered(GetDocument(),
114                                            event_type_names::kFullscreenchange,
115                                            FullscreenDetector()));
116   EXPECT_TRUE(CheckEventListenerRegistered(
117       GetDocument(), event_type_names::kWebkitfullscreenchange,
118       FullscreenDetector()));
119   EXPECT_TRUE(CheckEventListenerRegistered(*VideoElement(),
120                                            event_type_names::kLoadedmetadata,
121                                            FullscreenDetector()));
122 }
123 
TEST_F(MediaCustomControlsFullscreenDetectorTest,hasListenersAfterAddToDocumentByParser)124 TEST_F(MediaCustomControlsFullscreenDetectorTest,
125        hasListenersAfterAddToDocumentByParser) {
126   GetDocument().body()->setInnerHTML("<body><video></video></body>");
127 
128   EXPECT_TRUE(CheckEventListenerRegistered(GetDocument(),
129                                            event_type_names::kFullscreenchange,
130                                            FullscreenDetector()));
131   EXPECT_TRUE(CheckEventListenerRegistered(
132       GetDocument(), event_type_names::kWebkitfullscreenchange,
133       FullscreenDetector()));
134   EXPECT_TRUE(CheckEventListenerRegistered(*VideoElement(),
135                                            event_type_names::kLoadedmetadata,
136                                            FullscreenDetector()));
137 }
138 
TEST_F(MediaCustomControlsFullscreenDetectorTest,hasListenersAfterDocumentMove)139 TEST_F(MediaCustomControlsFullscreenDetectorTest,
140        hasListenersAfterDocumentMove) {
141   auto* video = To<HTMLVideoElement>(
142       GetDocument().CreateRawElement(html_names::kVideoTag));
143   GetDocument().body()->AppendChild(video);
144 
145   NewDocument().body()->AppendChild(VideoElement());
146 
147   EXPECT_FALSE(CheckEventListenerRegistered(GetDocument(),
148                                             event_type_names::kFullscreenchange,
149                                             FullscreenDetectorFor(video)));
150   EXPECT_FALSE(CheckEventListenerRegistered(
151       GetDocument(), event_type_names::kWebkitfullscreenchange,
152       FullscreenDetectorFor(video)));
153 
154   EXPECT_TRUE(CheckEventListenerRegistered(NewDocument(),
155                                            event_type_names::kFullscreenchange,
156                                            FullscreenDetectorFor(video)));
157   EXPECT_TRUE(CheckEventListenerRegistered(
158       NewDocument(), event_type_names::kWebkitfullscreenchange,
159       FullscreenDetectorFor(video)));
160 
161   EXPECT_TRUE(CheckEventListenerRegistered(
162       *video, event_type_names::kLoadedmetadata, FullscreenDetectorFor(video)));
163 }
164 
165 }  // namespace blink
166