| OLD | NEW | 
| (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, ¶m); | 
 |   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, ¶m); | 
 |   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                                                ¶m)); | 
 |  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 | 
| OLD | NEW |