| 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());
|
| + }
|
| +}
|
|
|