Index: chrome/browser/renderer_host/render_widget_host_unittest.cc |
=================================================================== |
--- chrome/browser/renderer_host/render_widget_host_unittest.cc (revision 29767) |
+++ chrome/browser/renderer_host/render_widget_host_unittest.cc (working copy) |
@@ -123,7 +123,9 @@ |
public: |
MockRenderWidgetHost(RenderProcessHost* process, int routing_id) |
: RenderWidgetHost(process, routing_id), |
- unhandled_keyboard_event_called_(false) { |
+ unhandled_keyboard_event_called_(false), |
+ handle_unhandled_keyboard_event_(false), |
+ unhandled_keyboard_event_type_(WebInputEvent::Undefined) { |
} |
// Tests that make sure we ignore keyboard event acknowledgments to events we |
@@ -132,13 +134,25 @@ |
return unhandled_keyboard_event_called_; |
} |
+ WebInputEvent::Type unhandled_keyboard_event_type() const { |
+ return unhandled_keyboard_event_type_; |
+ } |
+ |
+ void set_handle_unhandled_keyboard_event(bool handle) { |
+ handle_unhandled_keyboard_event_ = handle; |
+ } |
+ |
protected: |
- virtual void UnhandledKeyboardEvent(const NativeWebKeyboardEvent& event) { |
+ virtual bool UnhandledKeyboardEvent(const NativeWebKeyboardEvent& event) { |
+ unhandled_keyboard_event_type_ = event.type; |
unhandled_keyboard_event_called_ = true; |
+ return handle_unhandled_keyboard_event_; |
} |
private: |
bool unhandled_keyboard_event_called_; |
+ bool handle_unhandled_keyboard_event_; |
+ WebInputEvent::Type unhandled_keyboard_event_type_; |
}; |
// RenderWidgetHostTest -------------------------------------------------------- |
@@ -170,6 +184,21 @@ |
MessageLoop::current()->RunAllPending(); |
} |
+ void SendInputEventACK(WebInputEvent::Type type, bool processed) { |
+ scoped_ptr<IPC::Message> response( |
+ new ViewHostMsg_HandleInputEvent_ACK(0)); |
+ response->WriteInt(type); |
+ response->WriteBool(processed); |
+ host_->OnMessageReceived(*response); |
+ } |
+ |
+ void SimulateKeyboardEvent(WebInputEvent::Type type) { |
+ NativeWebKeyboardEvent key_event; |
+ key_event.type = type; |
+ key_event.windowsKeyCode = base::VKEY_L; // non-null made up value. |
+ host_->ForwardKeyboardEvent(key_event); |
+ } |
+ |
MessageLoopForUI message_loop_; |
scoped_ptr<TestingProfile> profile_; |
@@ -398,35 +427,274 @@ |
} |
TEST_F(RenderWidgetHostTest, HandleKeyEventsWeSent) { |
- NativeWebKeyboardEvent key_event; |
- key_event.type = WebInputEvent::KeyDown; |
- key_event.modifiers = WebInputEvent::ControlKey; |
- key_event.windowsKeyCode = base::VKEY_L; // non-null made up value. |
+ // Simulate a keyboard event. |
+ SimulateKeyboardEvent(WebInputEvent::RawKeyDown); |
- host_->ForwardKeyboardEvent(key_event); |
- |
// Make sure we sent the input event to the renderer. |
EXPECT_TRUE(process_->sink().GetUniqueMessageMatching( |
ViewMsg_HandleInputEvent::ID)); |
process_->sink().ClearMessages(); |
// Send the simulated response from the renderer back. |
- scoped_ptr<IPC::Message> response( |
- new ViewHostMsg_HandleInputEvent_ACK(0)); |
- response->WriteInt(key_event.type); |
- response->WriteBool(false); |
- host_->OnMessageReceived(*response); |
+ SendInputEventACK(WebInputEvent::RawKeyDown, false); |
EXPECT_TRUE(host_->unhandled_keyboard_event_called()); |
+ EXPECT_EQ(WebInputEvent::RawKeyDown, host_->unhandled_keyboard_event_type()); |
} |
TEST_F(RenderWidgetHostTest, IgnoreKeyEventsWeDidntSend) { |
// Send a simulated, unrequested key response. We should ignore this. |
- scoped_ptr<IPC::Message> response( |
- new ViewHostMsg_HandleInputEvent_ACK(0)); |
- response->WriteInt(WebInputEvent::KeyDown); |
- response->WriteBool(false); |
- host_->OnMessageReceived(*response); |
+ SendInputEventACK(WebInputEvent::RawKeyDown, false); |
EXPECT_FALSE(host_->unhandled_keyboard_event_called()); |
} |
+ |
+TEST_F(RenderWidgetHostTest, IgnoreKeyEventsHandledByRenderer) { |
+ // Simulate a keyboard event. |
+ SimulateKeyboardEvent(WebInputEvent::RawKeyDown); |
+ |
+ // Make sure we sent the input event to the renderer. |
+ EXPECT_TRUE(process_->sink().GetUniqueMessageMatching( |
+ ViewMsg_HandleInputEvent::ID)); |
+ process_->sink().ClearMessages(); |
+ |
+ // Send the simulated response from the renderer back. |
+ SendInputEventACK(WebInputEvent::RawKeyDown, true); |
+ EXPECT_FALSE(host_->unhandled_keyboard_event_called()); |
+} |
+ |
+TEST_F(RenderWidgetHostTest, DontSuppressNextCharEventsNoPending) { |
+ // Simulate a keyboard event. |
+ SimulateKeyboardEvent(WebInputEvent::RawKeyDown); |
+ |
+ // Make sure we sent the input event to the renderer. |
+ EXPECT_TRUE(process_->sink().GetUniqueMessageMatching( |
+ ViewMsg_HandleInputEvent::ID)); |
+ process_->sink().ClearMessages(); |
+ |
+ // Send the simulated response from the renderer back. |
+ SendInputEventACK(WebInputEvent::RawKeyDown, false); |
+ |
+ EXPECT_TRUE(host_->unhandled_keyboard_event_called()); |
+ EXPECT_EQ(WebInputEvent::RawKeyDown, host_->unhandled_keyboard_event_type()); |
+ |
+ // Forward the Char event. |
+ SimulateKeyboardEvent(WebInputEvent::Char); |
+ |
+ // Make sure we sent the input event to the renderer. |
+ EXPECT_TRUE(process_->sink().GetUniqueMessageMatching( |
+ ViewMsg_HandleInputEvent::ID)); |
+ process_->sink().ClearMessages(); |
+ |
+ // Send the simulated response from the renderer back. |
+ SendInputEventACK(WebInputEvent::Char, false); |
+ |
+ EXPECT_TRUE(host_->unhandled_keyboard_event_called()); |
+ EXPECT_EQ(WebInputEvent::Char, host_->unhandled_keyboard_event_type()); |
+ |
+ // Forward the KeyUp event. |
+ SimulateKeyboardEvent(WebInputEvent::KeyUp); |
+ |
+ // Make sure we sent the input event to the renderer. |
+ EXPECT_TRUE(process_->sink().GetUniqueMessageMatching( |
+ ViewMsg_HandleInputEvent::ID)); |
+ process_->sink().ClearMessages(); |
+ |
+ // Send the simulated response from the renderer back. |
+ SendInputEventACK(WebInputEvent::KeyUp, false); |
+ |
+ EXPECT_TRUE(host_->unhandled_keyboard_event_called()); |
+ EXPECT_EQ(WebInputEvent::KeyUp, host_->unhandled_keyboard_event_type()); |
+} |
+ |
+TEST_F(RenderWidgetHostTest, SuppressNextCharEventsNoPending) { |
+ // Simulate a keyboard event. |
+ SimulateKeyboardEvent(WebInputEvent::RawKeyDown); |
+ |
+ // Make sure we sent the input event to the renderer. |
+ EXPECT_TRUE(process_->sink().GetUniqueMessageMatching( |
+ ViewMsg_HandleInputEvent::ID)); |
+ process_->sink().ClearMessages(); |
+ |
+ // Simluate the situation that the browser handled the key down event. |
+ host_->set_handle_unhandled_keyboard_event(true); |
+ |
+ // Send the simulated response from the renderer back. |
+ SendInputEventACK(WebInputEvent::RawKeyDown, false); |
+ |
+ EXPECT_TRUE(host_->unhandled_keyboard_event_called()); |
+ EXPECT_EQ(WebInputEvent::RawKeyDown, host_->unhandled_keyboard_event_type()); |
+ |
+ // Forward the Char event. |
+ SimulateKeyboardEvent(WebInputEvent::Char); |
+ |
+ // Make sure the Char event is suppressed. |
+ EXPECT_EQ(0U, process_->sink().message_count()); |
+ |
+ // Forward another Char event. |
+ SimulateKeyboardEvent(WebInputEvent::Char); |
+ |
+ // Make sure the Char event is suppressed. |
+ EXPECT_EQ(0U, process_->sink().message_count()); |
+ |
+ // Forward the KeyUp event. |
+ SimulateKeyboardEvent(WebInputEvent::KeyUp); |
+ |
+ // Make sure we sent the input event to the renderer. |
+ EXPECT_TRUE(process_->sink().GetUniqueMessageMatching( |
+ ViewMsg_HandleInputEvent::ID)); |
+ process_->sink().ClearMessages(); |
+ |
+ // The browser does not handle KeyUp events. |
+ host_->set_handle_unhandled_keyboard_event(false); |
+ |
+ // Send the simulated response from the renderer back. |
+ SendInputEventACK(WebInputEvent::KeyUp, false); |
+ |
+ EXPECT_TRUE(host_->unhandled_keyboard_event_called()); |
+ EXPECT_EQ(WebInputEvent::KeyUp, host_->unhandled_keyboard_event_type()); |
+} |
+ |
+TEST_F(RenderWidgetHostTest, DontSuppressNextCharEventsPending) { |
+ SimulateKeyboardEvent(WebInputEvent::RawKeyDown); |
+ |
+ // Make sure we sent the input event to the renderer. |
+ EXPECT_TRUE(process_->sink().GetUniqueMessageMatching( |
+ ViewMsg_HandleInputEvent::ID)); |
+ process_->sink().ClearMessages(); |
+ |
+ // Forward the Char event before receiving the ACK of previous KeyDown event. |
+ SimulateKeyboardEvent(WebInputEvent::Char); |
+ |
+ // Make sure the Char event is pending. |
+ EXPECT_EQ(0U, process_->sink().message_count()); |
+ |
+ // Forward the KeyUp event before receiving the ACK of previous KeyDown event. |
+ SimulateKeyboardEvent(WebInputEvent::KeyUp); |
+ |
+ // Make sure the KeyUp event is pending. |
+ EXPECT_EQ(0U, process_->sink().message_count()); |
+ |
+ // Send the simulated response of the KeyDown event from the renderer back. |
+ SendInputEventACK(WebInputEvent::RawKeyDown, false); |
+ |
+ EXPECT_TRUE(host_->unhandled_keyboard_event_called()); |
+ EXPECT_EQ(WebInputEvent::RawKeyDown, host_->unhandled_keyboard_event_type()); |
+ |
+ // Make sure both pending Char and KeyUp were sent to the renderer. |
+ EXPECT_EQ(2U, process_->sink().message_count()); |
+ EXPECT_EQ(ViewMsg_HandleInputEvent::ID, |
+ process_->sink().GetMessageAt(0)->type()); |
+ EXPECT_EQ(ViewMsg_HandleInputEvent::ID, |
+ process_->sink().GetMessageAt(1)->type()); |
+ process_->sink().ClearMessages(); |
+ |
+ // Send the simulated response from the renderer back. |
+ SendInputEventACK(WebInputEvent::Char, false); |
+ |
+ EXPECT_TRUE(host_->unhandled_keyboard_event_called()); |
+ EXPECT_EQ(WebInputEvent::Char, host_->unhandled_keyboard_event_type()); |
+ |
+ // Send the simulated response from the renderer back. |
+ SendInputEventACK(WebInputEvent::KeyUp, false); |
+ |
+ EXPECT_TRUE(host_->unhandled_keyboard_event_called()); |
+ EXPECT_EQ(WebInputEvent::KeyUp, host_->unhandled_keyboard_event_type()); |
+} |
+ |
+TEST_F(RenderWidgetHostTest, SuppressNextCharEventsPending) { |
+ SimulateKeyboardEvent(WebInputEvent::RawKeyDown); |
+ |
+ // Make sure we sent the KeyDown event to the renderer. |
+ EXPECT_TRUE(process_->sink().GetUniqueMessageMatching( |
+ ViewMsg_HandleInputEvent::ID)); |
+ process_->sink().ClearMessages(); |
+ |
+ // Forward the Char event before receiving the ACK of previous KeyDown event. |
+ SimulateKeyboardEvent(WebInputEvent::Char); |
+ |
+ // Make sure the Char event is pending. |
+ EXPECT_EQ(0U, process_->sink().message_count()); |
+ |
+ // Forward another Char event before receiving the ACK of previous KeyDown |
+ // event. |
+ SimulateKeyboardEvent(WebInputEvent::Char); |
+ |
+ // Make sure the Char event is pending. |
+ EXPECT_EQ(0U, process_->sink().message_count()); |
+ |
+ // Forward the KeyUp event before receiving the ACK of previous KeyDown event. |
+ SimulateKeyboardEvent(WebInputEvent::KeyUp); |
+ |
+ // Make sure the KeyUp event is pending. |
+ EXPECT_EQ(0U, process_->sink().message_count()); |
+ |
+ // Simluate the situation that the browser handled the key down event. |
+ host_->set_handle_unhandled_keyboard_event(true); |
+ |
+ // Send the simulated response of the KeyDown event from the renderer back. |
+ SendInputEventACK(WebInputEvent::RawKeyDown, false); |
+ |
+ EXPECT_TRUE(host_->unhandled_keyboard_event_called()); |
+ EXPECT_EQ(WebInputEvent::RawKeyDown, host_->unhandled_keyboard_event_type()); |
+ |
+ // Make sure only pending KeyUp was sent to the renderer. |
+ EXPECT_EQ(1U, process_->sink().message_count()); |
+ EXPECT_EQ(ViewMsg_HandleInputEvent::ID, |
+ process_->sink().GetMessageAt(0)->type()); |
+ process_->sink().ClearMessages(); |
+ |
+ // Send the simulated response from the renderer back. |
+ SendInputEventACK(WebInputEvent::KeyUp, false); |
+ |
+ EXPECT_TRUE(host_->unhandled_keyboard_event_called()); |
+ EXPECT_EQ(WebInputEvent::KeyUp, host_->unhandled_keyboard_event_type()); |
+} |
+ |
+TEST_F(RenderWidgetHostTest, ManyKeyEventsPending) { |
+ process_->sink().ClearMessages(); |
+ |
+ for (int i = 0; i < 10; ++i) { |
+ // Forward a KeyDown event. |
+ SimulateKeyboardEvent(WebInputEvent::RawKeyDown); |
+ |
+ // Forward a Char event before receiving the ACK of previous KeyDown event. |
+ SimulateKeyboardEvent(WebInputEvent::Char); |
+ |
+ // Forward a KeyUp event before receiving the ACK of previous KeyDown event. |
+ SimulateKeyboardEvent(WebInputEvent::KeyUp); |
+ } |
+ |
+ // Make sure only the first KeyDown event was sent to the renderer. All others |
+ // are pending. |
+ EXPECT_EQ(1U, process_->sink().message_count()); |
+ EXPECT_TRUE(process_->sink().GetUniqueMessageMatching( |
+ ViewMsg_HandleInputEvent::ID)); |
+ process_->sink().ClearMessages(); |
+ |
+ for (int i = 0; i < 10; ++i) { |
+ // Send the simulated response of the KeyDown event from the renderer back. |
+ SendInputEventACK(WebInputEvent::RawKeyDown, false); |
+ EXPECT_TRUE(host_->unhandled_keyboard_event_called()); |
+ EXPECT_EQ(WebInputEvent::RawKeyDown, |
+ host_->unhandled_keyboard_event_type()); |
+ |
+ // Make sure the following pending Char, KeyUp and KeyDown event were sent |
+ // to the renderer. |
+ if (i < 9) |
+ EXPECT_EQ(3U, process_->sink().message_count()); |
+ else |
+ EXPECT_EQ(2U, process_->sink().message_count()); |
+ process_->sink().ClearMessages(); |
+ |
+ // Send the simulated response of the Char event from the renderer back. |
+ SendInputEventACK(WebInputEvent::Char, false); |
+ EXPECT_TRUE(host_->unhandled_keyboard_event_called()); |
+ EXPECT_EQ(WebInputEvent::Char, host_->unhandled_keyboard_event_type()); |
+ |
+ // Send the simulated response of the KeyUp event from the renderer back. |
+ SendInputEventACK(WebInputEvent::KeyUp, false); |
+ EXPECT_TRUE(host_->unhandled_keyboard_event_called()); |
+ EXPECT_EQ(WebInputEvent::KeyUp, host_->unhandled_keyboard_event_type()); |
+ } |
+} |