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

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

Issue 19220002: [WIP] BufferedInputRouter (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix client assignment Created 7 years, 3 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 "base/basictypes.h"
6 #include "content/browser/renderer_host/input/buffered_input_router.h"
7 #include "content/browser/renderer_host/input/input_router_unittest.h"
8 #include "content/common/input/event_packet.h"
9 #include "content/common/input_messages.h"
10 #include "content/common/view_messages.h"
11 #include "testing/gtest/include/gtest/gtest.h"
12
13 using WebKit::WebGestureEvent;
14 using WebKit::WebInputEvent;
15 using WebKit::WebMouseEvent;
16 using WebKit::WebMouseWheelEvent;
17 using WebKit::WebTouchEvent;
18 using WebKit::WebTouchPoint;
19
20 namespace content {
21
22 class TestBufferedInputRouter : public BufferedInputRouter {
23 public:
24 TestBufferedInputRouter(IPC::Sender* sender,
25 InputRouterClient* client,
26 InputAckHandler* ack_handler,
27 int routing_id)
28 : BufferedInputRouter(sender, client, ack_handler, routing_id) {}
29
30
31 size_t QueuedEventCount() const { return input_queue()->QueuedEventCount(); }
32 };
33
34 class BufferedInputRouterTest : public InputRouterTest {
35 public:
36 BufferedInputRouterTest() {}
37 virtual ~BufferedInputRouterTest() {}
38
39 protected:
40 // InputRouterTest
41 virtual scoped_ptr<InputRouter> CreateInputRouter(RenderProcessHost* process,
42 InputRouterClient* client,
43 InputAckHandler* handler,
44 int routing_id) OVERRIDE {
45 return scoped_ptr<InputRouter>(
46 new TestBufferedInputRouter(process, client, handler, routing_id));
47 }
48
49 bool FinishFlush(const InputEventDispositions& dispositions) {
50 if (!process_->sink().message_count())
51 return false;
52 IPC::Message message(*process_->sink().GetMessageAt(0));
53 process_->sink().ClearMessages();
54
55 InputMsg_HandleEventPacket::Param param;
56 InputMsg_HandleEventPacket::Read(&message, &param);
57 EventPacket& packet = param.a;
58
59 return SendEventPacketACK(packet.id(), dispositions);
60 }
61
62 bool FinishFlush(InputEventDisposition disposition) {
63 if (!process_->sink().message_count())
64 return false;
65 IPC::Message message(*process_->sink().GetMessageAt(0));
66 process_->sink().ClearMessages();
67
68 InputMsg_HandleEventPacket::Param param;
69 InputMsg_HandleEventPacket::Read(&message, &param);
70 EventPacket& packet = param.a;
71
72 return SendEventPacketACK(
73 packet.id(), InputEventDispositions(packet.size(), disposition));
74 }
75
76 bool SendEventPacketACK(int id, const InputEventDispositions& dispositions) {
77 return input_router_->OnMessageReceived(
78 InputHostMsg_HandleEventPacket_ACK(0, id, dispositions));
79 }
80
81 size_t QueuedEventCount() const {
82 return buffered_input_router()->QueuedEventCount();
83 }
84
85 TestBufferedInputRouter* buffered_input_router() const {
86 return static_cast<TestBufferedInputRouter*>(input_router_.get());
87 }
88 };
89
90 TEST_F(BufferedInputRouterTest, InputEventsProperlyQueued) {
91 EXPECT_TRUE(input_router_->SendInput(
92 scoped_ptr<IPC::Message>(new InputMsg_Redo(MSG_ROUTING_NONE))));
93 EXPECT_EQ(1U, QueuedEventCount());
94
95 EXPECT_TRUE(input_router_->SendInput(
96 scoped_ptr<IPC::Message>(new InputMsg_Cut(MSG_ROUTING_NONE))));
97 EXPECT_EQ(2U, QueuedEventCount());
98
99 EXPECT_TRUE(input_router_->SendInput(
100 scoped_ptr<IPC::Message>(new InputMsg_Copy(MSG_ROUTING_NONE))));
101 EXPECT_EQ(3U, QueuedEventCount());
102
103 EXPECT_TRUE(input_router_->SendInput(
104 scoped_ptr<IPC::Message>(new InputMsg_Paste(MSG_ROUTING_NONE))));
105 EXPECT_EQ(4U, QueuedEventCount());
106 }
107
108 #define SCOPED_EXPECT(CALL, MESSAGE) { SCOPED_TRACE(MESSAGE); CALL; }
109
110 TEST_F(BufferedInputRouterTest, ClientOnSendEventCalled) {
111 SimulateKeyboardEvent(WebInputEvent::RawKeyDown);
112 EXPECT_EQ(1U, QueuedEventCount());
113
114 SimulateWheelEvent(5, 0, 0, false);
115 EXPECT_EQ(2U, QueuedEventCount());
116
117 SimulateMouseMove(5, 0, 0);
118 EXPECT_EQ(3U, QueuedEventCount());
119
120 SimulateGestureEvent(WebInputEvent::GestureScrollBegin,
121 WebGestureEvent::Touchpad);
122 EXPECT_EQ(4U, QueuedEventCount());
123
124 SimulateTouchEvent(1, 1);
125 EXPECT_EQ(5U, QueuedEventCount());
126 }
127
128 TEST_F(BufferedInputRouterTest, ClientOnSendEventHonored) {
129 client_->set_allow_send_event(false);
130
131 SimulateKeyboardEvent(WebInputEvent::RawKeyDown);
132 EXPECT_EQ(0U, QueuedEventCount());
133
134 SimulateWheelEvent(5, 0, 0, false);
135 EXPECT_EQ(0U, QueuedEventCount());
136
137 SimulateMouseMove(5, 0, 0);
138 EXPECT_EQ(0U, QueuedEventCount());
139
140 SimulateGestureEvent(WebInputEvent::GestureScrollBegin,
141 WebGestureEvent::Touchpad);
142 EXPECT_EQ(0U, QueuedEventCount());
143
144 SimulateTouchEvent(1, 1);
145 EXPECT_EQ(0U, QueuedEventCount());
146 }
147
148 TEST_F(BufferedInputRouterTest, FlightCountIncrementedOnDeliver) {
149 SimulateKeyboardEvent(WebInputEvent::RawKeyDown);
150 EXPECT_EQ(0, client_->in_flight_event_count());
151
152 input_router_->Flush();
153 EXPECT_EQ(1, client_->in_flight_event_count());
154 }
155
156 TEST_F(BufferedInputRouterTest, FlightCountDecrementedOnAck) {
157 SimulateKeyboardEvent(WebInputEvent::RawKeyDown);
158 EXPECT_EQ(0, client_->in_flight_event_count());
159
160 input_router_->Flush();
161 EXPECT_EQ(1, client_->in_flight_event_count());
162
163 // The in-flight count should continue until the flush has finished.
164 ASSERT_TRUE(FinishFlush(INPUT_EVENT_COULD_NOT_DELIVER));
165 EXPECT_EQ(1, client_->in_flight_event_count());
166
167 ASSERT_TRUE(FinishFlush(INPUT_EVENT_IMPL_THREAD_CONSUMED));
168 EXPECT_EQ(0, client_->in_flight_event_count());
169 }
170
171 TEST_F(BufferedInputRouterTest, FilteredEventsNeverQueued) {
172 // Event should not be queued, but should be ack'ed.
173 client_->set_filter_state(INPUT_EVENT_ACK_STATE_CONSUMED);
174 SimulateKeyboardEvent(WebInputEvent::RawKeyDown);
175 SCOPED_EXPECT(ack_handler_->ExpectAckCalled(1), "AckCalled");
176 EXPECT_EQ(0U, QueuedEventCount());
177 ASSERT_EQ(NULL, input_router_->GetLastKeyboardEvent());
178
179 // Event should not be queued, but should be ack'ed.
180 client_->set_filter_state(INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS);
181 SimulateKeyboardEvent(WebInputEvent::RawKeyDown);
182 SCOPED_EXPECT(ack_handler_->ExpectAckCalled(1), "AckCalled");
183 EXPECT_EQ(0U, QueuedEventCount());
184 ASSERT_EQ(NULL, input_router_->GetLastKeyboardEvent());
185
186 // |INPUT_EVENT_DISPOSITION_UNKNOWN| should drop the event without ack'ing.
187 client_->set_filter_state(INPUT_EVENT_ACK_STATE_UNKNOWN);
188 SimulateKeyboardEvent(WebInputEvent::RawKeyDown);
189 SCOPED_EXPECT(ack_handler_->ExpectAckCalled(0), "AckNotCalled");
190 EXPECT_EQ(0U, QueuedEventCount());
191 ASSERT_EQ(NULL, input_router_->GetLastKeyboardEvent());
192
193 // Event should be queued.
194 client_->set_filter_state(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
195 SimulateKeyboardEvent(WebInputEvent::RawKeyDown);
196 SCOPED_EXPECT(ack_handler_->ExpectAckCalled(0), "AckNotCalled");
197 EXPECT_EQ(1U, QueuedEventCount());
198 }
199
200 TEST_F(BufferedInputRouterTest, FollowupEventsInjected) {
201 // Enable a followup gesture event.
202 WebGestureEvent followup_event;
203 followup_event.type = WebInputEvent::GestureScrollBegin;
204 followup_event.data.scrollUpdate.deltaX = 10;
205 ack_handler_->set_followup_touch_event(make_scoped_ptr(
206 new GestureEventWithLatencyInfo(followup_event, ui::LatencyInfo())));
207
208 // Create an initial packet of { Touch, Key } and start flushing.
209 SimulateTouchEvent(1, 1);
210 EXPECT_EQ(1U, QueuedEventCount());
211 SimulateKeyboardEvent(WebInputEvent::RawKeyDown);
212 EXPECT_EQ(2U, QueuedEventCount());
213 input_router_->Flush();
214
215 // Followup only triggered when event handled.
216 ASSERT_TRUE(FinishFlush(INPUT_EVENT_COULD_NOT_DELIVER));
217 SCOPED_EXPECT(client_->ExpectDidFlushCalled(false), "DidFlushNotCalled");
218 EXPECT_EQ(2U, QueuedEventCount());
219
220 // Ack the touch event.
221 InputEventDispositions dispositions;
222 dispositions.push_back(INPUT_EVENT_MAIN_THREAD_NOT_PREVENT_DEFAULTED);
223 dispositions.push_back(INPUT_EVENT_COULD_NOT_DELIVER);
224 ASSERT_TRUE(FinishFlush(dispositions));
225
226 // Ack'ing the touch event should have inserted the followup gesture event;
227 // the flush is not complete until the inserted event is ack'ed.
228 SCOPED_EXPECT(client_->ExpectDidFlushCalled(false), "DidFlushNotCalled");
229 SCOPED_EXPECT(client_->ExpectSendCalled(true), "SendGestureCalled");
230 EXPECT_EQ(followup_event.type, client_->sent_gesture_event().event.type);
231 EXPECT_EQ(2U, QueuedEventCount());
232
233 // Our packet is now { Gesture, Key }.
234 InputMsg_HandleEventPacket::Param param;
235 ASSERT_EQ(1U, process_->sink().message_count());
236 ASSERT_TRUE(InputMsg_HandleEventPacket::Read(process_->sink().GetMessageAt(0),
237 &param));
238 EventPacket& followup_packet = param.a;
239 ASSERT_EQ(2U, followup_packet.size());
240 ASSERT_EQ(InputEvent::Payload::WEB_INPUT_EVENT,
241 followup_packet.events()[0]->payload()->GetType());
242 ASSERT_EQ(InputEvent::Payload::WEB_INPUT_EVENT,
243 followup_packet.events()[1]->payload()->GetType());
244 const WebInputEventPayload* payload0 =
245 WebInputEventPayload::Cast(followup_packet.events()[0]->payload());
246 const WebInputEventPayload* payload1 =
247 WebInputEventPayload::Cast(followup_packet.events()[1]->payload());
248 EXPECT_EQ(followup_event.type, payload0->web_event()->type);
249 EXPECT_EQ(WebInputEvent::RawKeyDown, payload1->web_event()->type);
250
251 // Complete the flush; the gesture should have been ack'ed.
252 ASSERT_TRUE(FinishFlush(INPUT_EVENT_IMPL_THREAD_CONSUMED));
253 SCOPED_EXPECT(client_->ExpectDidFlushCalled(true), "DidFlushCalled");
254 EXPECT_EQ(followup_event.type, ack_handler_->acked_gesture_event().type);
255 EXPECT_EQ(0U, QueuedEventCount());
256 }
257
258 TEST_F(BufferedInputRouterTest, FlushRequestedOnQueue) {
259 // The first queued event should trigger a flush request.
260 SimulateKeyboardEvent(WebInputEvent::RawKeyDown);
261 EXPECT_EQ(1U, QueuedEventCount());
262 SCOPED_EXPECT(client_->ExpectNeedsFlushCalled(true), "SetNeedsFlushCalled");
263
264 // Subsequently queued events will not trigger another flush request.
265 SimulateWheelEvent(5, 0, 0, false);
266 EXPECT_EQ(2U, QueuedEventCount());
267 SCOPED_EXPECT(client_->ExpectNeedsFlushCalled(false), "SetNeedsFlushCalled");
268 }
269
270 TEST_F(BufferedInputRouterTest, HasQueuedGestureEvents) {
271 EXPECT_FALSE(input_router_->HasQueuedGestureEvents());
272 SimulateGestureEvent(WebInputEvent::GestureScrollBegin,
273 WebGestureEvent::Touchpad);
274 EXPECT_TRUE(input_router_->HasQueuedGestureEvents());
275
276 // Only an ack'ed gesture should clear it from the queue.
277 input_router_->Flush();
278 ASSERT_TRUE(FinishFlush(INPUT_EVENT_COULD_NOT_DELIVER));
279 EXPECT_TRUE(input_router_->HasQueuedGestureEvents());
280
281 ASSERT_TRUE(FinishFlush(INPUT_EVENT_IMPL_THREAD_CONSUMED));
282 EXPECT_FALSE(input_router_->HasQueuedGestureEvents());
283 }
284
285 TEST_F(BufferedInputRouterTest, GetLastKeyboardEvent) {
286 EXPECT_EQ(NULL, input_router_->GetLastKeyboardEvent());
287
288 SimulateKeyboardEvent(WebInputEvent::RawKeyDown);
289 EXPECT_EQ(WebInputEvent::RawKeyDown,
290 input_router_->GetLastKeyboardEvent()->type);
291
292 // Queueing another key event does not effect the "last" event.
293 SimulateKeyboardEvent(WebInputEvent::KeyUp);
294 EXPECT_EQ(WebInputEvent::RawKeyDown,
295 input_router_->GetLastKeyboardEvent()->type);
296
297 input_router_->Flush();
298
299 // Ack'ing the first event should make the second event the "last" event.
300 InputEventDispositions dispositions;
301 dispositions.push_back(INPUT_EVENT_IMPL_THREAD_CONSUMED);
302 dispositions.push_back(INPUT_EVENT_COULD_NOT_DELIVER);
303 ASSERT_TRUE(FinishFlush(dispositions));
304 EXPECT_EQ(WebInputEvent::KeyUp, input_router_->GetLastKeyboardEvent()->type);
305
306 // A key event queued during a flush becomes "last" upon flush completion.
307 SimulateKeyboardEvent(WebInputEvent::Char);
308 ASSERT_TRUE(FinishFlush(INPUT_EVENT_IMPL_THREAD_CONSUMED));
309 EXPECT_EQ(WebInputEvent::Char, input_router_->GetLastKeyboardEvent()->type);
310
311 // An empty queue should produce a null "last" event.
312 input_router_->Flush();
313 ASSERT_TRUE(FinishFlush(INPUT_EVENT_IMPL_THREAD_CONSUMED));
314 EXPECT_EQ(NULL, input_router_->GetLastKeyboardEvent());
315 }
316
317 TEST_F(BufferedInputRouterTest, UnexpectedAck) {
318 ASSERT_FALSE(ack_handler_->unexpected_event_ack_called());
319 input_router_->OnMessageReceived(
320 InputHostMsg_HandleEventPacket_ACK(0, 0, InputEventDispositions()));
321 EXPECT_TRUE(ack_handler_->unexpected_event_ack_called());
322 }
323
324 TEST_F(BufferedInputRouterTest, BadAck) {
325 SimulateKeyboardEvent(WebInputEvent::RawKeyDown);
326 input_router_->Flush();
327
328 ASSERT_FALSE(ack_handler_->unexpected_event_ack_called());
329 EventPacket packet;
330 input_router_->OnMessageReceived(
331 InputHostMsg_HandleEventPacket_ACK(0, 0, InputEventDispositions()));
332 EXPECT_TRUE(ack_handler_->unexpected_event_ack_called());
333 }
334
335 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698