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/modules/media_controls/elements/media_control_timeline_element.h"
6 
7 #include "third_party/blink/public/common/input/web_pointer_properties.h"
8 #include "third_party/blink/renderer/bindings/core/v8/v8_pointer_event_init.h"
9 #include "third_party/blink/renderer/bindings/core/v8/v8_touch_event_init.h"
10 #include "third_party/blink/renderer/core/events/pointer_event.h"
11 #include "third_party/blink/renderer/core/events/touch_event.h"
12 #include "third_party/blink/renderer/core/html/media/html_video_element.h"
13 #include "third_party/blink/renderer/core/testing/page_test_base.h"
14 #include "third_party/blink/renderer/modules/media_controls/media_controls_impl.h"
15 #include "third_party/blink/renderer/platform/heap/heap.h"
16 
17 namespace blink {
18 
19 class MediaControlTimelineElementTest : public PageTestBase {
20  public:
GetValidPointerEventInit()21   static PointerEventInit* GetValidPointerEventInit() {
22     PointerEventInit* init = PointerEventInit::Create();
23     init->setIsPrimary(true);
24     init->setButton(static_cast<int>(WebPointerProperties::Button::kLeft));
25     return init;
26   }
27 
GetValidTouchEventInit()28   static TouchEventInit* GetValidTouchEventInit() {
29     return TouchEventInit::Create();
30   }
31 
SetUp()32   void SetUp() override {
33     PageTestBase::SetUp(IntSize(100, 100));
34 
35     video_ = MakeGarbageCollected<HTMLVideoElement>(GetDocument());
36     controls_ = MakeGarbageCollected<MediaControlsImpl>(*video_);
37     timeline_ = MakeGarbageCollected<MediaControlTimelineElement>(*controls_);
38 
39     controls_->InitializeControls();
40 
41     // Connects the timeline element. Ideally, we should be able to set the
42     // NodeFlags::kConnectedFlag.
43     GetDocument().body()->AppendChild(timeline_);
44   }
45 
Video() const46   HTMLVideoElement* Video() const { return video_; }
47 
Timeline() const48   MediaControlTimelineElement* Timeline() const { return timeline_; }
49 
50  private:
51   Persistent<HTMLVideoElement> video_;
52   Persistent<MediaControlTimelineElement> timeline_;
53   Persistent<MediaControlsImpl> controls_;
54 };
55 
TEST_F(MediaControlTimelineElementTest,PointerDownPausesPlayback)56 TEST_F(MediaControlTimelineElementTest, PointerDownPausesPlayback) {
57   Video()->Play();
58   ASSERT_FALSE(Video()->paused());
59 
60   Timeline()->DispatchEvent(
61       *PointerEvent::Create("pointerdown", GetValidPointerEventInit()));
62   EXPECT_TRUE(Video()->paused());
63 }
64 
TEST_F(MediaControlTimelineElementTest,PointerDownRightClickNoOp)65 TEST_F(MediaControlTimelineElementTest, PointerDownRightClickNoOp) {
66   Video()->Play();
67   ASSERT_FALSE(Video()->paused());
68 
69   PointerEventInit* init = GetValidPointerEventInit();
70   init->setButton(static_cast<int>(WebPointerProperties::Button::kRight));
71   Timeline()->DispatchEvent(*PointerEvent::Create("pointerdown", init));
72   EXPECT_FALSE(Video()->paused());
73 }
74 
TEST_F(MediaControlTimelineElementTest,PointerDownNotPrimaryNoOp)75 TEST_F(MediaControlTimelineElementTest, PointerDownNotPrimaryNoOp) {
76   Video()->Play();
77   ASSERT_FALSE(Video()->paused());
78 
79   PointerEventInit* init = GetValidPointerEventInit();
80   init->setIsPrimary(false);
81   Timeline()->DispatchEvent(*PointerEvent::Create("pointerdown", init));
82   EXPECT_FALSE(Video()->paused());
83 }
84 
TEST_F(MediaControlTimelineElementTest,PointerUpResumesPlayback)85 TEST_F(MediaControlTimelineElementTest, PointerUpResumesPlayback) {
86   Video()->Play();
87   ASSERT_FALSE(Video()->paused());
88 
89   Timeline()->DispatchEvent(
90       *PointerEvent::Create("pointerdown", GetValidPointerEventInit()));
91   Timeline()->DispatchEvent(
92       *PointerEvent::Create("pointerup", GetValidPointerEventInit()));
93   EXPECT_FALSE(Video()->paused());
94 }
95 
TEST_F(MediaControlTimelineElementTest,PointerUpRightClickNoOp)96 TEST_F(MediaControlTimelineElementTest, PointerUpRightClickNoOp) {
97   Video()->Play();
98   ASSERT_FALSE(Video()->paused());
99 
100   Timeline()->DispatchEvent(
101       *PointerEvent::Create("pointerdown", GetValidPointerEventInit()));
102 
103   PointerEventInit* init = GetValidPointerEventInit();
104   init->setButton(static_cast<int>(WebPointerProperties::Button::kRight));
105   Timeline()->DispatchEvent(*PointerEvent::Create("pointerup", init));
106   EXPECT_TRUE(Video()->paused());
107 }
108 
TEST_F(MediaControlTimelineElementTest,PointerUpNotPrimaryNoOp)109 TEST_F(MediaControlTimelineElementTest, PointerUpNotPrimaryNoOp) {
110   Video()->Play();
111   ASSERT_FALSE(Video()->paused());
112 
113   Timeline()->DispatchEvent(
114       *PointerEvent::Create("pointerdown", GetValidPointerEventInit()));
115 
116   PointerEventInit* init = GetValidPointerEventInit();
117   init->setIsPrimary(false);
118   Timeline()->DispatchEvent(*PointerEvent::Create("pointerup", init));
119   EXPECT_TRUE(Video()->paused());
120 }
121 
TEST_F(MediaControlTimelineElementTest,PointerOutDoesNotResume)122 TEST_F(MediaControlTimelineElementTest, PointerOutDoesNotResume) {
123   Video()->Play();
124   ASSERT_FALSE(Video()->paused());
125 
126   Timeline()->DispatchEvent(
127       *PointerEvent::Create("pointerdown", GetValidPointerEventInit()));
128   Timeline()->DispatchEvent(
129       *PointerEvent::Create("pointerout", GetValidPointerEventInit()));
130   EXPECT_TRUE(Video()->paused());
131 }
132 
TEST_F(MediaControlTimelineElementTest,PointerMoveDoesNotResume)133 TEST_F(MediaControlTimelineElementTest, PointerMoveDoesNotResume) {
134   Video()->Play();
135   ASSERT_FALSE(Video()->paused());
136 
137   Timeline()->DispatchEvent(
138       *PointerEvent::Create("pointerdown", GetValidPointerEventInit()));
139   Timeline()->DispatchEvent(
140       *PointerEvent::Create("pointermove", GetValidPointerEventInit()));
141   EXPECT_TRUE(Video()->paused());
142 }
143 
TEST_F(MediaControlTimelineElementTest,PointerCancelResumesPlayback)144 TEST_F(MediaControlTimelineElementTest, PointerCancelResumesPlayback) {
145   Video()->Play();
146   ASSERT_FALSE(Video()->paused());
147 
148   Timeline()->DispatchEvent(
149       *PointerEvent::Create("pointerdown", GetValidPointerEventInit()));
150   Timeline()->DispatchEvent(
151       *PointerEvent::Create("pointercancel", GetValidPointerEventInit()));
152   EXPECT_FALSE(Video()->paused());
153 }
154 
TEST_F(MediaControlTimelineElementTest,TouchStartPausesPlayback)155 TEST_F(MediaControlTimelineElementTest, TouchStartPausesPlayback) {
156   Video()->Play();
157   ASSERT_FALSE(Video()->paused());
158 
159   Timeline()->DispatchEvent(
160       *TouchEvent::Create("touchstart", GetValidTouchEventInit()));
161   EXPECT_TRUE(Video()->paused());
162 }
163 
TEST_F(MediaControlTimelineElementTest,TouchEndResumesPlayback)164 TEST_F(MediaControlTimelineElementTest, TouchEndResumesPlayback) {
165   Video()->Play();
166   ASSERT_FALSE(Video()->paused());
167 
168   Timeline()->DispatchEvent(
169       *TouchEvent::Create("touchstart", GetValidTouchEventInit()));
170   Timeline()->DispatchEvent(
171       *TouchEvent::Create("touchend", GetValidTouchEventInit()));
172   EXPECT_FALSE(Video()->paused());
173 }
174 
TEST_F(MediaControlTimelineElementTest,TouchCancelResumesPlayback)175 TEST_F(MediaControlTimelineElementTest, TouchCancelResumesPlayback) {
176   Video()->Play();
177   ASSERT_FALSE(Video()->paused());
178 
179   Timeline()->DispatchEvent(
180       *TouchEvent::Create("touchstart", GetValidTouchEventInit()));
181   Timeline()->DispatchEvent(
182       *TouchEvent::Create("touchcancel", GetValidTouchEventInit()));
183   EXPECT_FALSE(Video()->paused());
184 }
185 
TEST_F(MediaControlTimelineElementTest,ChangeResumesPlayback)186 TEST_F(MediaControlTimelineElementTest, ChangeResumesPlayback) {
187   Video()->Play();
188   ASSERT_FALSE(Video()->paused());
189 
190   Timeline()->DispatchEvent(
191       *TouchEvent::Create("touchstart", GetValidTouchEventInit()));
192   Timeline()->DispatchEvent(*Event::Create("change", GetValidTouchEventInit()));
193   EXPECT_FALSE(Video()->paused());
194 }
195 
TEST_F(MediaControlTimelineElementTest,TouchMoveDoesNotResume)196 TEST_F(MediaControlTimelineElementTest, TouchMoveDoesNotResume) {
197   Video()->Play();
198   ASSERT_FALSE(Video()->paused());
199 
200   Timeline()->DispatchEvent(
201       *TouchEvent::Create("touchstart", GetValidTouchEventInit()));
202   Timeline()->DispatchEvent(
203       *TouchEvent::Create("touchmove", GetValidTouchEventInit()));
204   EXPECT_TRUE(Video()->paused());
205 }
206 
TEST_F(MediaControlTimelineElementTest,TouchMoveAfterPointerDoesNotResume)207 TEST_F(MediaControlTimelineElementTest, TouchMoveAfterPointerDoesNotResume) {
208   Video()->Play();
209   ASSERT_FALSE(Video()->paused());
210 
211   Timeline()->DispatchEvent(
212       *PointerEvent::Create("pointerdown", GetValidPointerEventInit()));
213   Timeline()->DispatchEvent(
214       *TouchEvent::Create("touchmove", GetValidTouchEventInit()));
215   EXPECT_TRUE(Video()->paused());
216 }
217 
TEST_F(MediaControlTimelineElementTest,TouchEndAfterPointerDoesNotResume)218 TEST_F(MediaControlTimelineElementTest, TouchEndAfterPointerDoesNotResume) {
219   Video()->Play();
220   ASSERT_FALSE(Video()->paused());
221 
222   Timeline()->DispatchEvent(
223       *PointerEvent::Create("pointerdown", GetValidPointerEventInit()));
224   Timeline()->DispatchEvent(
225       *TouchEvent::Create("touchend", GetValidTouchEventInit()));
226   EXPECT_TRUE(Video()->paused());
227 }
228 
TEST_F(MediaControlTimelineElementTest,TouchCancelAfterPointerDoesNotResume)229 TEST_F(MediaControlTimelineElementTest, TouchCancelAfterPointerDoesNotResume) {
230   Video()->Play();
231   ASSERT_FALSE(Video()->paused());
232 
233   Timeline()->DispatchEvent(
234       *PointerEvent::Create("pointerdown", GetValidPointerEventInit()));
235   Timeline()->DispatchEvent(
236       *TouchEvent::Create("touchcancel", GetValidTouchEventInit()));
237   EXPECT_TRUE(Video()->paused());
238 }
239 
TEST_F(MediaControlTimelineElementTest,ChangeAfterPointerDoesNotResume)240 TEST_F(MediaControlTimelineElementTest, ChangeAfterPointerDoesNotResume) {
241   Video()->Play();
242   ASSERT_FALSE(Video()->paused());
243 
244   Timeline()->DispatchEvent(
245       *PointerEvent::Create("pointerdown", GetValidPointerEventInit()));
246   Timeline()->DispatchEvent(*Event::Create("change", GetValidTouchEventInit()));
247   EXPECT_TRUE(Video()->paused());
248 }
249 
TEST_F(MediaControlTimelineElementTest,PointerUpAfterTouchDoesNotResume)250 TEST_F(MediaControlTimelineElementTest, PointerUpAfterTouchDoesNotResume) {
251   Video()->Play();
252   ASSERT_FALSE(Video()->paused());
253 
254   Timeline()->DispatchEvent(
255       *TouchEvent::Create("touchstart", GetValidTouchEventInit()));
256   Timeline()->DispatchEvent(
257       *PointerEvent::Create("pointerup", GetValidPointerEventInit()));
258   EXPECT_TRUE(Video()->paused());
259 }
260 
TEST_F(MediaControlTimelineElementTest,PointerCancelAfterTouchDoesNotResume)261 TEST_F(MediaControlTimelineElementTest, PointerCancelAfterTouchDoesNotResume) {
262   Video()->Play();
263   ASSERT_FALSE(Video()->paused());
264 
265   Timeline()->DispatchEvent(
266       *TouchEvent::Create("touchstart", GetValidTouchEventInit()));
267   Timeline()->DispatchEvent(
268       *PointerEvent::Create("pointercancel", GetValidPointerEventInit()));
269   EXPECT_TRUE(Video()->paused());
270 }
271 
TEST_F(MediaControlTimelineElementTest,UpgradePointerEventToTouchAllowed)272 TEST_F(MediaControlTimelineElementTest, UpgradePointerEventToTouchAllowed) {
273   Video()->Play();
274   ASSERT_FALSE(Video()->paused());
275 
276   Timeline()->DispatchEvent(
277       *PointerEvent::Create("pointerdown", GetValidPointerEventInit()));
278   Timeline()->DispatchEvent(
279       *TouchEvent::Create("touchstart", GetValidTouchEventInit()));
280   Timeline()->DispatchEvent(
281       *TouchEvent::Create("touchend", GetValidTouchEventInit()));
282   EXPECT_FALSE(Video()->paused());
283 }
284 
TEST_F(MediaControlTimelineElementTest,UpgradeTouchEventToPointerDenied)285 TEST_F(MediaControlTimelineElementTest, UpgradeTouchEventToPointerDenied) {
286   Video()->Play();
287   ASSERT_FALSE(Video()->paused());
288 
289   Timeline()->DispatchEvent(
290       *TouchEvent::Create("touchstart", GetValidTouchEventInit()));
291   Timeline()->DispatchEvent(
292       *PointerEvent::Create("pointerdown", GetValidPointerEventInit()));
293   Timeline()->DispatchEvent(
294       *PointerEvent::Create("pointerup", GetValidPointerEventInit()));
295   EXPECT_TRUE(Video()->paused());
296 }
297 
298 }  // namespace blink
299