Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(198)

Side by Side Diff: content/browser/renderer_host/input/input_queue_unittest.cc

Issue 25385002: Remove the BufferedInputRouter (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Space removal Created 7 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2013 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 <vector>
6
7 #include "base/memory/scoped_ptr.h"
8 #include "content/browser/renderer_host/input/browser_input_event.h"
9 #include "content/browser/renderer_host/input/input_queue.h"
10 #include "content/browser/renderer_host/input/input_queue_client.h"
11 #include "content/common/input/event_packet.h"
12 #include "content/common/input/input_event.h"
13 #include "content/common/input/ipc_input_event_payload.h"
14 #include "content/common/input/web_input_event_payload.h"
15 #include "content/common/input_messages.h"
16 #include "testing/gtest/include/gtest/gtest.h"
17 #include "ui/events/latency_info.h"
18
19 namespace content {
20 namespace {
21
22 using WebKit::WebGestureEvent;
23 using WebKit::WebInputEvent;
24 using WebKit::WebKeyboardEvent;
25 using WebKit::WebMouseEvent;
26 using WebKit::WebMouseWheelEvent;
27 using WebKit::WebTouchEvent;
28
29 class InputQueueTest : public testing::Test,
30 public InputQueueClient,
31 public BrowserInputEventClient {
32 public:
33 InputQueueTest()
34 : queue_(new InputQueue(this)),
35 routing_id_(0),
36 num_flush_completions_(0),
37 num_flush_requests_(0),
38 num_packet_deliveries_(0),
39 next_input_id_(1) {}
40
41 // InputQueueClient
42 virtual void Deliver(const EventPacket& packet) OVERRIDE {
43 EXPECT_LT(0u, packet.size());
44 ++num_packet_deliveries_;
45 current_packet_id_ = packet.id();
46 current_packet_dispositions_.resize(packet.size(), INPUT_EVENT_UNHANDLED);
47 }
48
49 virtual void DidFinishFlush() OVERRIDE { ++num_flush_completions_; }
50 virtual void SetNeedsFlush() OVERRIDE { ++num_flush_requests_; }
51
52 // BrowserInputEventClient
53 virtual void OnDispatched(const BrowserInputEvent& event,
54 InputEventDisposition disposition) OVERRIDE {
55 acked_dispositions_.push_back(disposition);
56 }
57
58 virtual void OnDispatched(
59 const BrowserInputEvent& event,
60 InputEventDisposition disposition,
61 ScopedVector<BrowserInputEvent>* followup) OVERRIDE {
62 acked_followup_dispositions_.push_back(disposition);
63 if (event_to_inject_)
64 followup->push_back(event_to_inject_.release());
65 }
66
67 int num_flush_requests() const { return num_flush_requests_; }
68 int num_flush_completions() const { return num_flush_completions_; }
69 int num_packet_deliveries() const { return num_packet_deliveries_; }
70
71 protected:
72 scoped_ptr<BrowserInputEvent> CreateIPCInputEvent(IPC::Message* message) {
73 return BrowserInputEvent::Create(
74 NextInputID(),
75 IPCInputEventPayload::Create(make_scoped_ptr(message)),
76 this);
77 }
78
79 scoped_ptr<BrowserInputEvent> CreateWebInputEvent(
80 WebInputEvent::Type web_type) {
81 WebKit::WebMouseEvent mouse;
82 WebKit::WebMouseWheelEvent wheel;
83 WebKit::WebTouchEvent touch;
84 WebKit::WebGestureEvent gesture;
85 WebKit::WebKeyboardEvent keyboard;
86
87 WebKit::WebInputEvent* web_event = NULL;
88 if (WebInputEvent::isMouseEventType(web_type))
89 web_event = &mouse;
90 else if (WebInputEvent::isKeyboardEventType(web_type))
91 web_event = &keyboard;
92 else if (WebInputEvent::isTouchEventType(web_type))
93 web_event = &touch;
94 else if (WebInputEvent::isGestureEventType(web_type))
95 web_event = &gesture;
96 else
97 web_event = &wheel;
98 web_event->type = web_type;
99
100 return BrowserInputEvent::Create(
101 NextInputID(),
102 WebInputEventPayload::Create(*web_event, ui::LatencyInfo(), false),
103 this);
104 }
105
106 void QueueEvent(IPC::Message* message) {
107 queue_->QueueEvent(CreateIPCInputEvent(message));
108 }
109
110 void QueueEvent(WebInputEvent::Type web_type) {
111 queue_->QueueEvent(CreateWebInputEvent(web_type));
112 }
113
114 bool Flush(InputEventDisposition disposition) {
115 StartFlush();
116 return FinishFlush(disposition);
117 }
118
119 void StartFlush() {
120 acked_dispositions_.clear();
121 acked_followup_dispositions_.clear();
122 current_packet_id_ = 0;
123 current_packet_dispositions_.clear();
124 queue_->BeginFlush();
125 }
126
127 bool FinishFlush(InputEventDisposition disposition) {
128 if (!current_packet_id_)
129 return false;
130 current_packet_dispositions_ = InputEventDispositions(
131 current_packet_dispositions_.size(), disposition);
132 return InputQueue::ACK_OK ==
133 queue_->OnEventPacketAck(current_packet_id_,
134 current_packet_dispositions_);
135 }
136
137 int64 NextInputID() { return next_input_id_++; }
138
139 scoped_ptr<InputQueue> queue_;
140
141 int routing_id_;
142 int64 current_packet_id_;
143 InputEventDispositions current_packet_dispositions_;
144
145 InputEventDispositions acked_dispositions_;
146 InputEventDispositions acked_followup_dispositions_;
147 scoped_ptr<BrowserInputEvent> event_to_inject_;
148
149 int num_flush_completions_;
150 int num_flush_requests_;
151 int num_packet_deliveries_;
152 int next_input_id_;
153 };
154
155 TEST_F(InputQueueTest, SetNeedsFlushOnQueueEvent) {
156 EXPECT_EQ(0, num_flush_requests());
157
158 QueueEvent(WebInputEvent::MouseDown);
159 EXPECT_EQ(1, num_flush_requests());
160
161 // Additional queued events should not trigger additional flush requests.
162 QueueEvent(WebInputEvent::MouseUp);
163 EXPECT_EQ(1, num_flush_requests());
164 QueueEvent(WebInputEvent::TouchStart);
165 EXPECT_EQ(1, num_flush_requests());
166 }
167
168 TEST_F(InputQueueTest, NoSetNeedsFlushOnQueueIfFlushing) {
169 QueueEvent(WebInputEvent::GestureScrollBegin);
170 EXPECT_EQ(1, num_flush_requests());
171
172 StartFlush();
173 EXPECT_EQ(1, num_flush_requests());
174 EXPECT_EQ(1, num_packet_deliveries());
175
176 // Events queued after a flush will not trigger an additional flush request.
177 QueueEvent(WebInputEvent::GestureScrollBegin);
178 EXPECT_EQ(1, num_flush_requests());
179 QueueEvent(WebInputEvent::GestureScrollEnd);
180 EXPECT_EQ(1, num_flush_requests());
181 }
182
183 TEST_F(InputQueueTest, SetNeedsFlushAfterDidFinishFlushIfEventsQueued) {
184 QueueEvent(WebInputEvent::GestureScrollBegin);
185 EXPECT_EQ(1, num_flush_requests());
186
187 StartFlush();
188 EXPECT_EQ(1, num_packet_deliveries());
189
190 QueueEvent(WebInputEvent::GestureScrollBegin);
191 EXPECT_EQ(1, num_flush_requests());
192
193 // An additional flush request is sent for the event queued after the flush.
194 ASSERT_TRUE(current_packet_id_);
195 ASSERT_TRUE(FinishFlush(INPUT_EVENT_IMPL_THREAD_CONSUMED));
196 EXPECT_EQ(1, num_flush_completions());
197 EXPECT_EQ(2, num_flush_requests());
198 }
199
200 TEST_F(InputQueueTest, EventPacketSentAfterFlush) {
201 EXPECT_EQ(0, num_packet_deliveries());
202 QueueEvent(WebInputEvent::GestureScrollBegin);
203 EXPECT_EQ(0, num_packet_deliveries());
204 StartFlush();
205 EXPECT_EQ(1, num_packet_deliveries());
206 }
207
208 TEST_F(InputQueueTest, AcksHandledInProperOrder) {
209 QueueEvent(WebInputEvent::GestureScrollBegin);
210 QueueEvent(WebInputEvent::GestureScrollEnd);
211 QueueEvent(WebInputEvent::GestureFlingStart);
212
213 queue_->BeginFlush();
214 ASSERT_EQ(3u, current_packet_dispositions_.size());
215 current_packet_dispositions_[0] = INPUT_EVENT_IMPL_THREAD_CONSUMED;
216 current_packet_dispositions_[1] = INPUT_EVENT_MAIN_THREAD_CONSUMED;
217 current_packet_dispositions_[2] = INPUT_EVENT_MAIN_THREAD_NO_CONSUMER_EXISTS;
218 queue_->OnEventPacketAck(current_packet_id_, current_packet_dispositions_);
219 EXPECT_EQ(1, num_flush_completions());
220
221 ASSERT_EQ(3u, acked_dispositions_.size());
222 EXPECT_EQ(acked_dispositions_[0], INPUT_EVENT_IMPL_THREAD_CONSUMED);
223 EXPECT_EQ(acked_dispositions_[1], INPUT_EVENT_MAIN_THREAD_CONSUMED);
224 EXPECT_EQ(acked_dispositions_[2], INPUT_EVENT_MAIN_THREAD_NO_CONSUMER_EXISTS);
225 }
226
227 TEST_F(InputQueueTest, FollowupWhenFollowupEventNotConsumed) {
228 InputEventDisposition unconsumed_dispositions[] = {
229 INPUT_EVENT_IMPL_THREAD_NO_CONSUMER_EXISTS,
230 INPUT_EVENT_MAIN_THREAD_NOT_PREVENT_DEFAULTED,
231 INPUT_EVENT_MAIN_THREAD_NO_CONSUMER_EXISTS
232 };
233 for (size_t i = 0; i < arraysize(unconsumed_dispositions); ++i) {
234 QueueEvent(WebInputEvent::GestureScrollBegin);
235 QueueEvent(WebInputEvent::TouchStart);
236 QueueEvent(WebInputEvent::TouchMove);
237
238 Flush(unconsumed_dispositions[i]);
239 EXPECT_EQ(1u, acked_dispositions_.size()) << i;
240 EXPECT_EQ(2u, acked_followup_dispositions_.size()) << i;
241 }
242 }
243
244 TEST_F(InputQueueTest, NoFollowupWhenFollowupEventConsumed) {
245 InputEventDisposition consumed_dispositions[] = {
246 INPUT_EVENT_IMPL_THREAD_CONSUMED,
247 INPUT_EVENT_MAIN_THREAD_PREVENT_DEFAULTED,
248 INPUT_EVENT_MAIN_THREAD_CONSUMED
249 };
250 for (size_t i = 0; i < arraysize(consumed_dispositions); ++i) {
251 QueueEvent(WebInputEvent::GestureScrollBegin);
252 QueueEvent(WebInputEvent::TouchStart);
253 QueueEvent(WebInputEvent::TouchMove);
254
255 Flush(consumed_dispositions[i]);
256 EXPECT_EQ(3u, acked_dispositions_.size()) << i;
257 EXPECT_EQ(0u, acked_followup_dispositions_.size()) << i;
258 }
259 }
260
261 TEST_F(InputQueueTest, FlushOnEmptyQueueIgnored) {
262 Flush(INPUT_EVENT_MAIN_THREAD_CONSUMED);
263 EXPECT_EQ(0, num_flush_requests());
264 EXPECT_EQ(0, num_flush_completions());
265
266 QueueEvent(WebInputEvent::GestureScrollBegin);
267 Flush(INPUT_EVENT_MAIN_THREAD_CONSUMED);
268 EXPECT_EQ(1, num_flush_requests());
269 EXPECT_EQ(1, num_flush_completions());
270
271 Flush(INPUT_EVENT_MAIN_THREAD_CONSUMED);
272 EXPECT_EQ(1, num_flush_requests());
273 EXPECT_EQ(1, num_flush_completions());
274 }
275
276 TEST_F(InputQueueTest, FlushContinuesUntilAllEventsProcessed) {
277 QueueEvent(WebInputEvent::GestureScrollBegin);
278 QueueEvent(WebInputEvent::GestureScrollEnd);
279 QueueEvent(WebInputEvent::GestureFlingStart);
280
281 EXPECT_EQ(1, num_flush_requests());
282 Flush(INPUT_EVENT_COULD_NOT_DELIVER);
283 EXPECT_EQ(0, num_flush_completions());
284
285 FinishFlush(INPUT_EVENT_COULD_NOT_DELIVER);
286 EXPECT_EQ(0, num_flush_completions());
287
288 ASSERT_TRUE(FinishFlush(INPUT_EVENT_MAIN_THREAD_CONSUMED));
289 EXPECT_EQ(1, num_flush_completions());
290 }
291
292 TEST_F(InputQueueTest, InvalidPacketAckIgnored) {
293 // Packet never flushed, any ack should be ignored.
294 InputQueue::AckResult result =
295 queue_->OnEventPacketAck(0, InputEventDispositions());
296 EXPECT_EQ(InputQueue::ACK_UNEXPECTED, result);
297
298 QueueEvent(WebInputEvent::GestureScrollBegin);
299 StartFlush();
300 // Tamper with the sent packet by adding an extra event.
301 current_packet_dispositions_.push_back(INPUT_EVENT_MAIN_THREAD_CONSUMED);
302 bool valid_packet_ack = FinishFlush(INPUT_EVENT_MAIN_THREAD_CONSUMED);
303 EXPECT_EQ(0, num_flush_completions());
304 EXPECT_FALSE(valid_packet_ack);
305
306 // Fix the packet.
307 current_packet_dispositions_.pop_back();
308 valid_packet_ack = FinishFlush(INPUT_EVENT_MAIN_THREAD_CONSUMED);
309 EXPECT_EQ(1, num_flush_completions());
310 EXPECT_TRUE(valid_packet_ack);
311
312 // Tamper with the packet by changing the id.
313 QueueEvent(WebInputEvent::GestureScrollBegin);
314 StartFlush();
315 int64 packet_ack_id = -1;
316 std::swap(current_packet_id_, packet_ack_id);
317 valid_packet_ack = FinishFlush(INPUT_EVENT_MAIN_THREAD_CONSUMED);
318 EXPECT_EQ(1, num_flush_completions());
319 EXPECT_FALSE(valid_packet_ack);
320
321 // Fix the packet.
322 std::swap(current_packet_id_, packet_ack_id);
323 valid_packet_ack = FinishFlush(INPUT_EVENT_MAIN_THREAD_CONSUMED);
324 EXPECT_EQ(2, num_flush_completions());
325 EXPECT_TRUE(valid_packet_ack);
326 }
327
328 TEST_F(InputQueueTest, InjectedEventsAckedBeforeDidFinishFlush) {
329 QueueEvent(WebInputEvent::GestureScrollBegin);
330 QueueEvent(WebInputEvent::TouchMove);
331
332 event_to_inject_ = CreateIPCInputEvent(new InputMsg_Copy(routing_id_));
333 Flush(INPUT_EVENT_IMPL_THREAD_NO_CONSUMER_EXISTS);
334 EXPECT_EQ(0, num_flush_completions());
335
336 // The injected event should now be in the event packet.
337 EXPECT_EQ(1u, current_packet_dispositions_.size());
338 EXPECT_EQ(1u, acked_followup_dispositions_.size());
339 ASSERT_TRUE(FinishFlush(INPUT_EVENT_MAIN_THREAD_CONSUMED));
340 EXPECT_EQ(1, num_flush_completions());
341
342 QueueEvent(WebInputEvent::GestureScrollBegin);
343 QueueEvent(WebInputEvent::TouchStart);
344 event_to_inject_ = CreateWebInputEvent(WebInputEvent::TouchMove);
345 Flush(INPUT_EVENT_MAIN_THREAD_NO_CONSUMER_EXISTS);
346 // |event_to_inject_| is now in the event packet.
347 EXPECT_EQ(1u, acked_followup_dispositions_.size());
348 EXPECT_EQ(1u, current_packet_dispositions_.size());
349
350 event_to_inject_ = CreateWebInputEvent(WebInputEvent::TouchMove);
351 // the next |event_to_inject_| is now in the event packet.
352 ASSERT_TRUE(FinishFlush(INPUT_EVENT_MAIN_THREAD_NO_CONSUMER_EXISTS));
353
354 EXPECT_EQ(2u, acked_followup_dispositions_.size());
355 EXPECT_EQ(1u, current_packet_dispositions_.size());
356 EXPECT_EQ(1, num_flush_completions());
357
358 ASSERT_TRUE(FinishFlush(INPUT_EVENT_MAIN_THREAD_CONSUMED));
359 EXPECT_EQ(2, num_flush_completions());
360 }
361
362 } // namespace
363 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/renderer_host/input/input_queue_client.h ('k') | content/browser/renderer_host/render_process_host_impl.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698