1 // Copyright (c) 2012 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 "base/bind.h" 7 #include "base/command_line.h" 8 #include "base/memory/scoped_ptr.h" 9 #include "base/memory/shared_memory.h" 10 #include "base/timer/timer.h" 11 #include "content/browser/browser_thread_impl.h" 12 #include "content/browser/gpu/compositor_util.h" 13 #include "content/browser/renderer_host/input/input_router_impl.h" 14 #include "content/browser/renderer_host/render_widget_host_delegate.h" 15 #include "content/browser/renderer_host/render_widget_host_view_base.h" 16 #include "content/common/input/synthetic_web_input_event_builders.h" 17 #include "content/common/input_messages.h" 18 #include "content/common/view_messages.h" 19 #include "content/public/common/content_switches.h" 20 #include "content/public/test/mock_render_process_host.h" 21 #include "content/public/test/test_browser_context.h" 22 #include "content/test/test_render_view_host.h" 23 #include "testing/gtest/include/gtest/gtest.h" 24 #include "ui/events/keycodes/keyboard_codes.h" 25 #include "ui/gfx/canvas.h" 26 #include "ui/gfx/screen.h" 27 28 #if defined(OS_ANDROID) 29 #include "content/browser/renderer_host/render_widget_host_view_android.h" 30 #endif 31 32 #if defined(USE_AURA) || (defined(OS_MACOSX) && !defined(OS_IOS)) 33 #include "content/browser/compositor/test/no_transport_image_transport_factory.h" 34 #endif 35 36 #if defined(USE_AURA) 37 #include "content/browser/renderer_host/render_widget_host_view_aura.h" 38 #include "content/browser/renderer_host/ui_events_helper.h" 39 #include "ui/aura/env.h" 40 #include "ui/aura/test/test_screen.h" 41 #include "ui/events/event.h" 42 #endif 43 44 using base::TimeDelta; 45 using blink::WebGestureDevice; 46 using blink::WebGestureEvent; 47 using blink::WebInputEvent; 48 using blink::WebKeyboardEvent; 49 using blink::WebMouseEvent; 50 using blink::WebMouseWheelEvent; 51 using blink::WebTouchEvent; 52 using blink::WebTouchPoint; 53 54 namespace content { 55 56 // MockInputRouter ------------------------------------------------------------- 57 58 class MockInputRouter : public InputRouter { 59 public: 60 explicit MockInputRouter(InputRouterClient* client) 61 : send_event_called_(false), 62 sent_mouse_event_(false), 63 sent_wheel_event_(false), 64 sent_keyboard_event_(false), 65 sent_gesture_event_(false), 66 send_touch_event_not_cancelled_(false), 67 message_received_(false), 68 client_(client) { 69 } 70 virtual ~MockInputRouter() {} 71 72 // InputRouter 73 virtual void Flush() OVERRIDE { 74 flush_called_ = true; 75 } 76 virtual bool SendInput(scoped_ptr<IPC::Message> message) OVERRIDE { 77 send_event_called_ = true; 78 return true; 79 } 80 virtual void SendMouseEvent( 81 const MouseEventWithLatencyInfo& mouse_event) OVERRIDE { 82 sent_mouse_event_ = true; 83 } 84 virtual void SendWheelEvent( 85 const MouseWheelEventWithLatencyInfo& wheel_event) OVERRIDE { 86 sent_wheel_event_ = true; 87 } 88 virtual void SendKeyboardEvent( 89 const NativeWebKeyboardEvent& key_event, 90 const ui::LatencyInfo& latency_info, 91 bool is_shortcut) OVERRIDE { 92 sent_keyboard_event_ = true; 93 } 94 virtual void SendGestureEvent( 95 const GestureEventWithLatencyInfo& gesture_event) OVERRIDE { 96 sent_gesture_event_ = true; 97 } 98 virtual void SendTouchEvent( 99 const TouchEventWithLatencyInfo& touch_event) OVERRIDE { 100 send_touch_event_not_cancelled_ = 101 client_->FilterInputEvent(touch_event.event, touch_event.latency) == 102 INPUT_EVENT_ACK_STATE_NOT_CONSUMED; 103 } 104 virtual const NativeWebKeyboardEvent* GetLastKeyboardEvent() const OVERRIDE { 105 NOTREACHED(); 106 return NULL; 107 } 108 virtual bool ShouldForwardTouchEvent() const OVERRIDE { return true; } 109 virtual void OnViewUpdated(int view_flags) OVERRIDE {} 110 virtual bool HasPendingEvents() const OVERRIDE { return false; } 111 112 // IPC::Listener 113 virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE { 114 message_received_ = true; 115 return false; 116 } 117 118 bool flush_called_; 119 bool send_event_called_; 120 bool sent_mouse_event_; 121 bool sent_wheel_event_; 122 bool sent_keyboard_event_; 123 bool sent_gesture_event_; 124 bool send_touch_event_not_cancelled_; 125 bool message_received_; 126 127 private: 128 InputRouterClient* client_; 129 130 DISALLOW_COPY_AND_ASSIGN(MockInputRouter); 131 }; 132 133 // MockRenderWidgetHost ---------------------------------------------------- 134 135 class MockRenderWidgetHost : public RenderWidgetHostImpl { 136 public: 137 MockRenderWidgetHost( 138 RenderWidgetHostDelegate* delegate, 139 RenderProcessHost* process, 140 int routing_id) 141 : RenderWidgetHostImpl(delegate, process, routing_id, false), 142 unresponsive_timer_fired_(false) { 143 acked_touch_event_type_ = blink::WebInputEvent::Undefined; 144 } 145 146 // Allow poking at a few private members. 147 using RenderWidgetHostImpl::GetResizeParams; 148 using RenderWidgetHostImpl::OnUpdateRect; 149 using RenderWidgetHostImpl::RendererExited; 150 using RenderWidgetHostImpl::SetInitialRenderSizeParams; 151 using RenderWidgetHostImpl::old_resize_params_; 152 using RenderWidgetHostImpl::is_hidden_; 153 using RenderWidgetHostImpl::resize_ack_pending_; 154 using RenderWidgetHostImpl::input_router_; 155 156 virtual void OnTouchEventAck( 157 const TouchEventWithLatencyInfo& event, 158 InputEventAckState ack_result) OVERRIDE { 159 // Sniff touch acks. 160 acked_touch_event_type_ = event.event.type; 161 RenderWidgetHostImpl::OnTouchEventAck(event, ack_result); 162 } 163 164 bool unresponsive_timer_fired() const { 165 return unresponsive_timer_fired_; 166 } 167 168 void set_hung_renderer_delay_ms(int delay_ms) { 169 hung_renderer_delay_ms_ = delay_ms; 170 } 171 172 void DisableGestureDebounce() { 173 input_router_.reset(new InputRouterImpl( 174 process_, this, this, routing_id_, InputRouterImpl::Config())); 175 } 176 177 WebInputEvent::Type acked_touch_event_type() const { 178 return acked_touch_event_type_; 179 } 180 181 void SetupForInputRouterTest() { 182 input_router_.reset(new MockInputRouter(this)); 183 } 184 185 MockInputRouter* mock_input_router() { 186 return static_cast<MockInputRouter*>(input_router_.get()); 187 } 188 189 protected: 190 virtual void NotifyRendererUnresponsive() OVERRIDE { 191 unresponsive_timer_fired_ = true; 192 } 193 194 bool unresponsive_timer_fired_; 195 WebInputEvent::Type acked_touch_event_type_; 196 197 DISALLOW_COPY_AND_ASSIGN(MockRenderWidgetHost); 198 }; 199 200 namespace { 201 202 // RenderWidgetHostProcess ----------------------------------------------------- 203 204 class RenderWidgetHostProcess : public MockRenderProcessHost { 205 public: 206 explicit RenderWidgetHostProcess(BrowserContext* browser_context) 207 : MockRenderProcessHost(browser_context), 208 update_msg_reply_flags_(0) { 209 } 210 virtual ~RenderWidgetHostProcess() { 211 } 212 213 void set_update_msg_reply_flags(int flags) { 214 update_msg_reply_flags_ = flags; 215 } 216 217 // Fills the given update parameters with resonable default values. 218 void InitUpdateRectParams(ViewHostMsg_UpdateRect_Params* params); 219 220 virtual bool HasConnection() const OVERRIDE { return true; } 221 222 protected: 223 // Indicates the flags that should be sent with a repaint request. This 224 // only has an effect when update_msg_should_reply_ is true. 225 int update_msg_reply_flags_; 226 227 DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostProcess); 228 }; 229 230 void RenderWidgetHostProcess::InitUpdateRectParams( 231 ViewHostMsg_UpdateRect_Params* params) { 232 const int w = 100, h = 100; 233 234 params->view_size = gfx::Size(w, h); 235 params->flags = update_msg_reply_flags_; 236 } 237 238 // TestView -------------------------------------------------------------------- 239 240 // This test view allows us to specify the size, and keep track of acked 241 // touch-events. 242 class TestView : public TestRenderWidgetHostView { 243 public: 244 explicit TestView(RenderWidgetHostImpl* rwh) 245 : TestRenderWidgetHostView(rwh), 246 unhandled_wheel_event_count_(0), 247 acked_event_count_(0), 248 gesture_event_type_(-1), 249 use_fake_physical_backing_size_(false), 250 ack_result_(INPUT_EVENT_ACK_STATE_UNKNOWN) { 251 } 252 253 // Sets the bounds returned by GetViewBounds. 254 void set_bounds(const gfx::Rect& bounds) { 255 bounds_ = bounds; 256 } 257 258 const WebTouchEvent& acked_event() const { return acked_event_; } 259 int acked_event_count() const { return acked_event_count_; } 260 void ClearAckedEvent() { 261 acked_event_.type = blink::WebInputEvent::Undefined; 262 acked_event_count_ = 0; 263 } 264 265 const WebMouseWheelEvent& unhandled_wheel_event() const { 266 return unhandled_wheel_event_; 267 } 268 int unhandled_wheel_event_count() const { 269 return unhandled_wheel_event_count_; 270 } 271 int gesture_event_type() const { return gesture_event_type_; } 272 InputEventAckState ack_result() const { return ack_result_; } 273 274 void SetMockPhysicalBackingSize(const gfx::Size& mock_physical_backing_size) { 275 use_fake_physical_backing_size_ = true; 276 mock_physical_backing_size_ = mock_physical_backing_size; 277 } 278 void ClearMockPhysicalBackingSize() { 279 use_fake_physical_backing_size_ = false; 280 } 281 282 // RenderWidgetHostView override. 283 virtual gfx::Rect GetViewBounds() const OVERRIDE { 284 return bounds_; 285 } 286 virtual void ProcessAckedTouchEvent(const TouchEventWithLatencyInfo& touch, 287 InputEventAckState ack_result) OVERRIDE { 288 acked_event_ = touch.event; 289 ++acked_event_count_; 290 } 291 virtual void WheelEventAck(const WebMouseWheelEvent& event, 292 InputEventAckState ack_result) OVERRIDE { 293 if (ack_result == INPUT_EVENT_ACK_STATE_CONSUMED) 294 return; 295 unhandled_wheel_event_count_++; 296 unhandled_wheel_event_ = event; 297 } 298 virtual void GestureEventAck(const WebGestureEvent& event, 299 InputEventAckState ack_result) OVERRIDE { 300 gesture_event_type_ = event.type; 301 ack_result_ = ack_result; 302 } 303 virtual gfx::Size GetPhysicalBackingSize() const OVERRIDE { 304 if (use_fake_physical_backing_size_) 305 return mock_physical_backing_size_; 306 return TestRenderWidgetHostView::GetPhysicalBackingSize(); 307 } 308 #if defined(USE_AURA) 309 virtual ~TestView() { 310 // Simulate the mouse exit event dispatched when an aura window is 311 // destroyed. (MakeWebMouseEventFromAuraEvent translates ET_MOUSE_EXITED 312 // into WebInputEvent::MouseMove.) 313 rwh_->input_router()->SendMouseEvent( 314 MouseEventWithLatencyInfo( 315 SyntheticWebMouseEventBuilder::Build(WebInputEvent::MouseMove), 316 ui::LatencyInfo())); 317 } 318 #endif 319 320 protected: 321 WebMouseWheelEvent unhandled_wheel_event_; 322 int unhandled_wheel_event_count_; 323 WebTouchEvent acked_event_; 324 int acked_event_count_; 325 int gesture_event_type_; 326 gfx::Rect bounds_; 327 bool use_fake_physical_backing_size_; 328 gfx::Size mock_physical_backing_size_; 329 InputEventAckState ack_result_; 330 331 DISALLOW_COPY_AND_ASSIGN(TestView); 332 }; 333 334 // MockRenderWidgetHostDelegate -------------------------------------------- 335 336 class MockRenderWidgetHostDelegate : public RenderWidgetHostDelegate { 337 public: 338 MockRenderWidgetHostDelegate() 339 : prehandle_keyboard_event_(false), 340 prehandle_keyboard_event_called_(false), 341 prehandle_keyboard_event_type_(WebInputEvent::Undefined), 342 unhandled_keyboard_event_called_(false), 343 unhandled_keyboard_event_type_(WebInputEvent::Undefined), 344 handle_wheel_event_(false), 345 handle_wheel_event_called_(false) { 346 } 347 virtual ~MockRenderWidgetHostDelegate() {} 348 349 // Tests that make sure we ignore keyboard event acknowledgments to events we 350 // didn't send work by making sure we didn't call UnhandledKeyboardEvent(). 351 bool unhandled_keyboard_event_called() const { 352 return unhandled_keyboard_event_called_; 353 } 354 355 WebInputEvent::Type unhandled_keyboard_event_type() const { 356 return unhandled_keyboard_event_type_; 357 } 358 359 bool prehandle_keyboard_event_called() const { 360 return prehandle_keyboard_event_called_; 361 } 362 363 WebInputEvent::Type prehandle_keyboard_event_type() const { 364 return prehandle_keyboard_event_type_; 365 } 366 367 void set_prehandle_keyboard_event(bool handle) { 368 prehandle_keyboard_event_ = handle; 369 } 370 371 void set_handle_wheel_event(bool handle) { 372 handle_wheel_event_ = handle; 373 } 374 375 bool handle_wheel_event_called() { 376 return handle_wheel_event_called_; 377 } 378 379 protected: 380 virtual bool PreHandleKeyboardEvent(const NativeWebKeyboardEvent& event, 381 bool* is_keyboard_shortcut) OVERRIDE { 382 prehandle_keyboard_event_type_ = event.type; 383 prehandle_keyboard_event_called_ = true; 384 return prehandle_keyboard_event_; 385 } 386 387 virtual void HandleKeyboardEvent( 388 const NativeWebKeyboardEvent& event) OVERRIDE { 389 unhandled_keyboard_event_type_ = event.type; 390 unhandled_keyboard_event_called_ = true; 391 } 392 393 virtual bool HandleWheelEvent( 394 const blink::WebMouseWheelEvent& event) OVERRIDE { 395 handle_wheel_event_called_ = true; 396 return handle_wheel_event_; 397 } 398 399 private: 400 bool prehandle_keyboard_event_; 401 bool prehandle_keyboard_event_called_; 402 WebInputEvent::Type prehandle_keyboard_event_type_; 403 404 bool unhandled_keyboard_event_called_; 405 WebInputEvent::Type unhandled_keyboard_event_type_; 406 407 bool handle_wheel_event_; 408 bool handle_wheel_event_called_; 409 }; 410 411 // RenderWidgetHostTest -------------------------------------------------------- 412 413 class RenderWidgetHostTest : public testing::Test { 414 public: 415 RenderWidgetHostTest() 416 : process_(NULL), 417 handle_key_press_event_(false), 418 handle_mouse_event_(false), 419 simulated_event_time_delta_seconds_(0) { 420 last_simulated_event_time_seconds_ = 421 (base::TimeTicks::Now() - base::TimeTicks()).InSecondsF(); 422 } 423 virtual ~RenderWidgetHostTest() { 424 } 425 426 bool KeyPressEventCallback(const NativeWebKeyboardEvent& /* event */) { 427 return handle_key_press_event_; 428 } 429 bool MouseEventCallback(const blink::WebMouseEvent& /* event */) { 430 return handle_mouse_event_; 431 } 432 433 protected: 434 // testing::Test 435 virtual void SetUp() { 436 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); 437 command_line->AppendSwitch(switches::kValidateInputEventStream); 438 439 browser_context_.reset(new TestBrowserContext()); 440 delegate_.reset(new MockRenderWidgetHostDelegate()); 441 process_ = new RenderWidgetHostProcess(browser_context_.get()); 442 #if defined(USE_AURA) || (defined(OS_MACOSX) && !defined(OS_IOS)) 443 if (IsDelegatedRendererEnabled()) { 444 ImageTransportFactory::InitializeForUnitTests( 445 scoped_ptr<ImageTransportFactory>( 446 new NoTransportImageTransportFactory)); 447 } 448 #endif 449 #if defined(USE_AURA) 450 aura::Env::CreateInstance(true); 451 screen_.reset(aura::TestScreen::Create(gfx::Size())); 452 gfx::Screen::SetScreenInstance(gfx::SCREEN_TYPE_NATIVE, screen_.get()); 453 #endif 454 host_.reset( 455 new MockRenderWidgetHost(delegate_.get(), process_, MSG_ROUTING_NONE)); 456 view_.reset(new TestView(host_.get())); 457 ConfigureView(view_.get()); 458 host_->SetView(view_.get()); 459 SetInitialRenderSizeParams(); 460 host_->Init(); 461 host_->DisableGestureDebounce(); 462 } 463 464 virtual void TearDown() { 465 view_.reset(); 466 host_.reset(); 467 delegate_.reset(); 468 process_ = NULL; 469 browser_context_.reset(); 470 471 #if defined(USE_AURA) 472 aura::Env::DeleteInstance(); 473 screen_.reset(); 474 #endif 475 #if defined(USE_AURA) || (defined(OS_MACOSX) && !defined(OS_IOS)) 476 if (IsDelegatedRendererEnabled()) 477 ImageTransportFactory::Terminate(); 478 #endif 479 480 // Process all pending tasks to avoid leaks. 481 base::MessageLoop::current()->RunUntilIdle(); 482 } 483 484 void SetInitialRenderSizeParams() { 485 ViewMsg_Resize_Params render_size_params; 486 host_->GetResizeParams(&render_size_params); 487 host_->SetInitialRenderSizeParams(render_size_params); 488 } 489 490 virtual void ConfigureView(TestView* view) { 491 } 492 493 int64 GetLatencyComponentId() { 494 return host_->GetLatencyComponentId(); 495 } 496 497 void SendInputEventACK(WebInputEvent::Type type, 498 InputEventAckState ack_result) { 499 InputHostMsg_HandleInputEvent_ACK_Params ack; 500 ack.type = type; 501 ack.state = ack_result; 502 host_->OnMessageReceived(InputHostMsg_HandleInputEvent_ACK(0, ack)); 503 } 504 505 double GetNextSimulatedEventTimeSeconds() { 506 last_simulated_event_time_seconds_ += simulated_event_time_delta_seconds_; 507 return last_simulated_event_time_seconds_; 508 } 509 510 void SimulateKeyboardEvent(WebInputEvent::Type type) { 511 SimulateKeyboardEvent(type, 0); 512 } 513 514 void SimulateKeyboardEvent(WebInputEvent::Type type, int modifiers) { 515 WebKeyboardEvent event = SyntheticWebKeyboardEventBuilder::Build(type); 516 event.modifiers = modifiers; 517 NativeWebKeyboardEvent native_event; 518 memcpy(&native_event, &event, sizeof(event)); 519 host_->ForwardKeyboardEvent(native_event); 520 } 521 522 void SimulateMouseEvent(WebInputEvent::Type type) { 523 host_->ForwardMouseEvent(SyntheticWebMouseEventBuilder::Build(type)); 524 } 525 526 void SimulateMouseEventWithLatencyInfo(WebInputEvent::Type type, 527 const ui::LatencyInfo& ui_latency) { 528 host_->ForwardMouseEventWithLatencyInfo( 529 SyntheticWebMouseEventBuilder::Build(type), 530 ui_latency); 531 } 532 533 void SimulateWheelEvent(float dX, float dY, int modifiers, bool precise) { 534 host_->ForwardWheelEvent( 535 SyntheticWebMouseWheelEventBuilder::Build(dX, dY, modifiers, precise)); 536 } 537 538 void SimulateWheelEventWithLatencyInfo(float dX, 539 float dY, 540 int modifiers, 541 bool precise, 542 const ui::LatencyInfo& ui_latency) { 543 host_->ForwardWheelEventWithLatencyInfo( 544 SyntheticWebMouseWheelEventBuilder::Build(dX, dY, modifiers, precise), 545 ui_latency); 546 } 547 548 void SimulateMouseMove(int x, int y, int modifiers) { 549 SimulateMouseEvent(WebInputEvent::MouseMove, x, y, modifiers, false); 550 } 551 552 void SimulateMouseEvent( 553 WebInputEvent::Type type, int x, int y, int modifiers, bool pressed) { 554 WebMouseEvent event = 555 SyntheticWebMouseEventBuilder::Build(type, x, y, modifiers); 556 if (pressed) 557 event.button = WebMouseEvent::ButtonLeft; 558 event.timeStampSeconds = GetNextSimulatedEventTimeSeconds(); 559 host_->ForwardMouseEvent(event); 560 } 561 562 // Inject simple synthetic WebGestureEvent instances. 563 void SimulateGestureEvent(WebInputEvent::Type type, 564 WebGestureDevice sourceDevice) { 565 host_->ForwardGestureEvent( 566 SyntheticWebGestureEventBuilder::Build(type, sourceDevice)); 567 } 568 569 void SimulateGestureEventWithLatencyInfo(WebInputEvent::Type type, 570 WebGestureDevice sourceDevice, 571 const ui::LatencyInfo& ui_latency) { 572 host_->ForwardGestureEventWithLatencyInfo( 573 SyntheticWebGestureEventBuilder::Build(type, sourceDevice), 574 ui_latency); 575 } 576 577 // Set the timestamp for the touch-event. 578 void SetTouchTimestamp(base::TimeDelta timestamp) { 579 touch_event_.SetTimestamp(timestamp); 580 } 581 582 // Sends a touch event (irrespective of whether the page has a touch-event 583 // handler or not). 584 void SendTouchEvent() { 585 host_->ForwardTouchEventWithLatencyInfo(touch_event_, ui::LatencyInfo()); 586 587 touch_event_.ResetPoints(); 588 } 589 590 int PressTouchPoint(int x, int y) { 591 return touch_event_.PressPoint(x, y); 592 } 593 594 void MoveTouchPoint(int index, int x, int y) { 595 touch_event_.MovePoint(index, x, y); 596 } 597 598 void ReleaseTouchPoint(int index) { 599 touch_event_.ReleasePoint(index); 600 } 601 602 const WebInputEvent* GetInputEventFromMessage(const IPC::Message& message) { 603 PickleIterator iter(message); 604 const char* data; 605 int data_length; 606 if (!message.ReadData(&iter, &data, &data_length)) 607 return NULL; 608 return reinterpret_cast<const WebInputEvent*>(data); 609 } 610 611 base::MessageLoopForUI message_loop_; 612 613 scoped_ptr<TestBrowserContext> browser_context_; 614 RenderWidgetHostProcess* process_; // Deleted automatically by the widget. 615 scoped_ptr<MockRenderWidgetHostDelegate> delegate_; 616 scoped_ptr<MockRenderWidgetHost> host_; 617 scoped_ptr<TestView> view_; 618 scoped_ptr<gfx::Screen> screen_; 619 bool handle_key_press_event_; 620 bool handle_mouse_event_; 621 double last_simulated_event_time_seconds_; 622 double simulated_event_time_delta_seconds_; 623 624 private: 625 SyntheticWebTouchEvent touch_event_; 626 627 DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostTest); 628 }; 629 630 #if GTEST_HAS_PARAM_TEST 631 // RenderWidgetHostWithSourceTest ---------------------------------------------- 632 633 // This is for tests that are to be run for all source devices. 634 class RenderWidgetHostWithSourceTest 635 : public RenderWidgetHostTest, 636 public testing::WithParamInterface<WebGestureDevice> {}; 637 #endif // GTEST_HAS_PARAM_TEST 638 639 } // namespace 640 641 // ----------------------------------------------------------------------------- 642 643 TEST_F(RenderWidgetHostTest, Resize) { 644 // The initial bounds is the empty rect, and the screen info hasn't been sent 645 // yet, so setting it to the same thing shouldn't send the resize message. 646 view_->set_bounds(gfx::Rect()); 647 host_->WasResized(); 648 EXPECT_FALSE(host_->resize_ack_pending_); 649 EXPECT_FALSE(process_->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID)); 650 651 // Setting the bounds to a "real" rect should send out the notification. 652 // but should not expect ack for empty physical backing size. 653 gfx::Rect original_size(0, 0, 100, 100); 654 process_->sink().ClearMessages(); 655 view_->set_bounds(original_size); 656 view_->SetMockPhysicalBackingSize(gfx::Size()); 657 host_->WasResized(); 658 EXPECT_FALSE(host_->resize_ack_pending_); 659 EXPECT_EQ(original_size.size(), host_->old_resize_params_->new_size); 660 EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID)); 661 662 // Setting the bounds to a "real" rect should send out the notification. 663 // but should not expect ack for only physical backing size change. 664 process_->sink().ClearMessages(); 665 view_->ClearMockPhysicalBackingSize(); 666 host_->WasResized(); 667 EXPECT_FALSE(host_->resize_ack_pending_); 668 EXPECT_EQ(original_size.size(), host_->old_resize_params_->new_size); 669 EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID)); 670 671 // Send out a update that's not a resize ack after setting resize ack pending 672 // flag. This should not clean the resize ack pending flag. 673 process_->sink().ClearMessages(); 674 gfx::Rect second_size(0, 0, 110, 110); 675 EXPECT_FALSE(host_->resize_ack_pending_); 676 view_->set_bounds(second_size); 677 host_->WasResized(); 678 EXPECT_TRUE(host_->resize_ack_pending_); 679 ViewHostMsg_UpdateRect_Params params; 680 process_->InitUpdateRectParams(¶ms); 681 host_->OnUpdateRect(params); 682 EXPECT_TRUE(host_->resize_ack_pending_); 683 EXPECT_EQ(second_size.size(), host_->old_resize_params_->new_size); 684 685 // Sending out a new notification should NOT send out a new IPC message since 686 // a resize ACK is pending. 687 gfx::Rect third_size(0, 0, 120, 120); 688 process_->sink().ClearMessages(); 689 view_->set_bounds(third_size); 690 host_->WasResized(); 691 EXPECT_TRUE(host_->resize_ack_pending_); 692 EXPECT_EQ(second_size.size(), host_->old_resize_params_->new_size); 693 EXPECT_FALSE(process_->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID)); 694 695 // Send a update that's a resize ack, but for the original_size we sent. Since 696 // this isn't the second_size, the message handler should immediately send 697 // a new resize message for the new size to the renderer. 698 process_->sink().ClearMessages(); 699 params.flags = ViewHostMsg_UpdateRect_Flags::IS_RESIZE_ACK; 700 params.view_size = original_size.size(); 701 host_->OnUpdateRect(params); 702 EXPECT_TRUE(host_->resize_ack_pending_); 703 EXPECT_EQ(third_size.size(), host_->old_resize_params_->new_size); 704 ASSERT_TRUE(process_->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID)); 705 706 // Send the resize ack for the latest size. 707 process_->sink().ClearMessages(); 708 params.view_size = third_size.size(); 709 host_->OnUpdateRect(params); 710 EXPECT_FALSE(host_->resize_ack_pending_); 711 EXPECT_EQ(third_size.size(), host_->old_resize_params_->new_size); 712 ASSERT_FALSE(process_->sink().GetFirstMessageMatching(ViewMsg_Resize::ID)); 713 714 // Now clearing the bounds should send out a notification but we shouldn't 715 // expect a resize ack (since the renderer won't ack empty sizes). The message 716 // should contain the new size (0x0) and not the previous one that we skipped 717 process_->sink().ClearMessages(); 718 view_->set_bounds(gfx::Rect()); 719 host_->WasResized(); 720 EXPECT_FALSE(host_->resize_ack_pending_); 721 EXPECT_EQ(gfx::Size(), host_->old_resize_params_->new_size); 722 EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID)); 723 724 // Send a rect that has no area but has either width or height set. 725 process_->sink().ClearMessages(); 726 view_->set_bounds(gfx::Rect(0, 0, 0, 30)); 727 host_->WasResized(); 728 EXPECT_FALSE(host_->resize_ack_pending_); 729 EXPECT_EQ(gfx::Size(0, 30), host_->old_resize_params_->new_size); 730 EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID)); 731 732 // Set the same size again. It should not be sent again. 733 process_->sink().ClearMessages(); 734 host_->WasResized(); 735 EXPECT_FALSE(host_->resize_ack_pending_); 736 EXPECT_EQ(gfx::Size(0, 30), host_->old_resize_params_->new_size); 737 EXPECT_FALSE(process_->sink().GetFirstMessageMatching(ViewMsg_Resize::ID)); 738 739 // A different size should be sent again, however. 740 view_->set_bounds(gfx::Rect(0, 0, 0, 31)); 741 host_->WasResized(); 742 EXPECT_FALSE(host_->resize_ack_pending_); 743 EXPECT_EQ(gfx::Size(0, 31), host_->old_resize_params_->new_size); 744 EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID)); 745 } 746 747 // Test for crbug.com/25097. If a renderer crashes between a resize and the 748 // corresponding update message, we must be sure to clear the resize ack logic. 749 TEST_F(RenderWidgetHostTest, ResizeThenCrash) { 750 // Clear the first Resize message that carried screen info. 751 process_->sink().ClearMessages(); 752 753 // Setting the bounds to a "real" rect should send out the notification. 754 gfx::Rect original_size(0, 0, 100, 100); 755 view_->set_bounds(original_size); 756 host_->WasResized(); 757 EXPECT_TRUE(host_->resize_ack_pending_); 758 EXPECT_EQ(original_size.size(), host_->old_resize_params_->new_size); 759 EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID)); 760 761 // Simulate a renderer crash before the update message. Ensure all the 762 // resize ack logic is cleared. Must clear the view first so it doesn't get 763 // deleted. 764 host_->SetView(NULL); 765 host_->RendererExited(base::TERMINATION_STATUS_PROCESS_CRASHED, -1); 766 EXPECT_FALSE(host_->resize_ack_pending_); 767 EXPECT_EQ(gfx::Size(), host_->old_resize_params_->new_size); 768 769 // Reset the view so we can exit the test cleanly. 770 host_->SetView(view_.get()); 771 } 772 773 // Unable to include render_widget_host_view_mac.h and compile. 774 #if !defined(OS_MACOSX) 775 // Tests setting background transparency. 776 TEST_F(RenderWidgetHostTest, Background) { 777 scoped_ptr<RenderWidgetHostViewBase> view; 778 #if defined(USE_AURA) 779 view.reset(new RenderWidgetHostViewAura(host_.get())); 780 // TODO(derat): Call this on all platforms: http://crbug.com/102450. 781 view->InitAsChild(NULL); 782 #elif defined(OS_ANDROID) 783 view.reset(new RenderWidgetHostViewAndroid(host_.get(), NULL)); 784 #endif 785 host_->SetView(view.get()); 786 787 EXPECT_TRUE(view->GetBackgroundOpaque()); 788 view->SetBackgroundOpaque(false); 789 EXPECT_FALSE(view->GetBackgroundOpaque()); 790 791 const IPC::Message* set_background = 792 process_->sink().GetUniqueMessageMatching( 793 ViewMsg_SetBackgroundOpaque::ID); 794 ASSERT_TRUE(set_background); 795 Tuple1<bool> sent_background; 796 ViewMsg_SetBackgroundOpaque::Read(set_background, &sent_background); 797 EXPECT_FALSE(sent_background.a); 798 799 #if defined(USE_AURA) 800 // See the comment above |InitAsChild(NULL)|. 801 host_->SetView(NULL); 802 static_cast<RenderWidgetHostViewBase*>(view.release())->Destroy(); 803 #endif 804 } 805 #endif 806 807 // Test that we don't paint when we're hidden, but we still send the ACK. Most 808 // of the rest of the painting is tested in the GetBackingStore* ones. 809 TEST_F(RenderWidgetHostTest, HiddenPaint) { 810 BrowserThreadImpl ui_thread(BrowserThread::UI, base::MessageLoop::current()); 811 // Hide the widget, it should have sent out a message to the renderer. 812 EXPECT_FALSE(host_->is_hidden_); 813 host_->WasHidden(); 814 EXPECT_TRUE(host_->is_hidden_); 815 EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(ViewMsg_WasHidden::ID)); 816 817 // Send it an update as from the renderer. 818 process_->sink().ClearMessages(); 819 ViewHostMsg_UpdateRect_Params params; 820 process_->InitUpdateRectParams(¶ms); 821 host_->OnUpdateRect(params); 822 823 // Now unhide. 824 process_->sink().ClearMessages(); 825 host_->WasShown(ui::LatencyInfo()); 826 EXPECT_FALSE(host_->is_hidden_); 827 828 // It should have sent out a restored message with a request to paint. 829 const IPC::Message* restored = process_->sink().GetUniqueMessageMatching( 830 ViewMsg_WasShown::ID); 831 ASSERT_TRUE(restored); 832 Tuple2<bool, ui::LatencyInfo> needs_repaint; 833 ViewMsg_WasShown::Read(restored, &needs_repaint); 834 EXPECT_TRUE(needs_repaint.a); 835 } 836 837 TEST_F(RenderWidgetHostTest, IgnoreKeyEventsHandledByRenderer) { 838 // Simulate a keyboard event. 839 SimulateKeyboardEvent(WebInputEvent::RawKeyDown); 840 841 // Make sure we sent the input event to the renderer. 842 EXPECT_TRUE(process_->sink().GetUniqueMessageMatching( 843 InputMsg_HandleInputEvent::ID)); 844 process_->sink().ClearMessages(); 845 846 // Send the simulated response from the renderer back. 847 SendInputEventACK(WebInputEvent::RawKeyDown, 848 INPUT_EVENT_ACK_STATE_CONSUMED); 849 EXPECT_FALSE(delegate_->unhandled_keyboard_event_called()); 850 } 851 852 TEST_F(RenderWidgetHostTest, PreHandleRawKeyDownEvent) { 853 // Simluate the situation that the browser handled the key down event during 854 // pre-handle phrase. 855 delegate_->set_prehandle_keyboard_event(true); 856 process_->sink().ClearMessages(); 857 858 // Simulate a keyboard event. 859 SimulateKeyboardEvent(WebInputEvent::RawKeyDown); 860 861 EXPECT_TRUE(delegate_->prehandle_keyboard_event_called()); 862 EXPECT_EQ(WebInputEvent::RawKeyDown, 863 delegate_->prehandle_keyboard_event_type()); 864 865 // Make sure the RawKeyDown event is not sent to the renderer. 866 EXPECT_EQ(0U, process_->sink().message_count()); 867 868 // The browser won't pre-handle a Char event. 869 delegate_->set_prehandle_keyboard_event(false); 870 871 // Forward the Char event. 872 SimulateKeyboardEvent(WebInputEvent::Char); 873 874 // Make sure the Char event is suppressed. 875 EXPECT_EQ(0U, process_->sink().message_count()); 876 877 // Forward the KeyUp event. 878 SimulateKeyboardEvent(WebInputEvent::KeyUp); 879 880 // Make sure only KeyUp was sent to the renderer. 881 EXPECT_EQ(1U, process_->sink().message_count()); 882 EXPECT_EQ(InputMsg_HandleInputEvent::ID, 883 process_->sink().GetMessageAt(0)->type()); 884 process_->sink().ClearMessages(); 885 886 // Send the simulated response from the renderer back. 887 SendInputEventACK(WebInputEvent::KeyUp, 888 INPUT_EVENT_ACK_STATE_NOT_CONSUMED); 889 890 EXPECT_TRUE(delegate_->unhandled_keyboard_event_called()); 891 EXPECT_EQ(WebInputEvent::KeyUp, delegate_->unhandled_keyboard_event_type()); 892 } 893 894 TEST_F(RenderWidgetHostTest, UnhandledWheelEvent) { 895 SimulateWheelEvent(-5, 0, 0, true); 896 897 // Make sure we sent the input event to the renderer. 898 EXPECT_TRUE(process_->sink().GetUniqueMessageMatching( 899 InputMsg_HandleInputEvent::ID)); 900 process_->sink().ClearMessages(); 901 902 // Send the simulated response from the renderer back. 903 SendInputEventACK(WebInputEvent::MouseWheel, 904 INPUT_EVENT_ACK_STATE_NOT_CONSUMED); 905 EXPECT_TRUE(delegate_->handle_wheel_event_called()); 906 EXPECT_EQ(1, view_->unhandled_wheel_event_count()); 907 EXPECT_EQ(-5, view_->unhandled_wheel_event().deltaX); 908 } 909 910 TEST_F(RenderWidgetHostTest, HandleWheelEvent) { 911 // Indicate that we're going to handle this wheel event 912 delegate_->set_handle_wheel_event(true); 913 914 SimulateWheelEvent(-5, 0, 0, true); 915 916 // Make sure we sent the input event to the renderer. 917 EXPECT_TRUE(process_->sink().GetUniqueMessageMatching( 918 InputMsg_HandleInputEvent::ID)); 919 process_->sink().ClearMessages(); 920 921 // Send the simulated response from the renderer back. 922 SendInputEventACK(WebInputEvent::MouseWheel, 923 INPUT_EVENT_ACK_STATE_NOT_CONSUMED); 924 925 // ensure the wheel event handler was invoked 926 EXPECT_TRUE(delegate_->handle_wheel_event_called()); 927 928 // and that it suppressed the unhandled wheel event handler. 929 EXPECT_EQ(0, view_->unhandled_wheel_event_count()); 930 } 931 932 TEST_F(RenderWidgetHostTest, UnhandledGestureEvent) { 933 SimulateGestureEvent(WebInputEvent::GestureTwoFingerTap, 934 blink::WebGestureDeviceTouchscreen); 935 936 // Make sure we sent the input event to the renderer. 937 EXPECT_TRUE(process_->sink().GetUniqueMessageMatching( 938 InputMsg_HandleInputEvent::ID)); 939 process_->sink().ClearMessages(); 940 941 // Send the simulated response from the renderer back. 942 SendInputEventACK(WebInputEvent::GestureTwoFingerTap, 943 INPUT_EVENT_ACK_STATE_NOT_CONSUMED); 944 EXPECT_EQ(WebInputEvent::GestureTwoFingerTap, view_->gesture_event_type()); 945 EXPECT_EQ(INPUT_EVENT_ACK_STATE_NOT_CONSUMED, view_->ack_result()); 946 } 947 948 // Test that the hang monitor timer expires properly if a new timer is started 949 // while one is in progress (see crbug.com/11007). 950 TEST_F(RenderWidgetHostTest, DontPostponeHangMonitorTimeout) { 951 // Start with a short timeout. 952 host_->StartHangMonitorTimeout(TimeDelta::FromMilliseconds(10)); 953 954 // Immediately try to add a long 30 second timeout. 955 EXPECT_FALSE(host_->unresponsive_timer_fired()); 956 host_->StartHangMonitorTimeout(TimeDelta::FromSeconds(30)); 957 958 // Wait long enough for first timeout and see if it fired. 959 base::MessageLoop::current()->PostDelayedTask( 960 FROM_HERE, 961 base::MessageLoop::QuitClosure(), 962 TimeDelta::FromMilliseconds(10)); 963 base::MessageLoop::current()->Run(); 964 EXPECT_TRUE(host_->unresponsive_timer_fired()); 965 } 966 967 // Test that the hang monitor timer expires properly if it is started, stopped, 968 // and then started again. 969 TEST_F(RenderWidgetHostTest, StopAndStartHangMonitorTimeout) { 970 // Start with a short timeout, then stop it. 971 host_->StartHangMonitorTimeout(TimeDelta::FromMilliseconds(10)); 972 host_->StopHangMonitorTimeout(); 973 974 // Start it again to ensure it still works. 975 EXPECT_FALSE(host_->unresponsive_timer_fired()); 976 host_->StartHangMonitorTimeout(TimeDelta::FromMilliseconds(10)); 977 978 // Wait long enough for first timeout and see if it fired. 979 base::MessageLoop::current()->PostDelayedTask( 980 FROM_HERE, 981 base::MessageLoop::QuitClosure(), 982 TimeDelta::FromMilliseconds(40)); 983 base::MessageLoop::current()->Run(); 984 EXPECT_TRUE(host_->unresponsive_timer_fired()); 985 } 986 987 // Test that the hang monitor timer expires properly if it is started, then 988 // updated to a shorter duration. 989 TEST_F(RenderWidgetHostTest, ShorterDelayHangMonitorTimeout) { 990 // Start with a timeout. 991 host_->StartHangMonitorTimeout(TimeDelta::FromMilliseconds(100)); 992 993 // Start it again with shorter delay. 994 EXPECT_FALSE(host_->unresponsive_timer_fired()); 995 host_->StartHangMonitorTimeout(TimeDelta::FromMilliseconds(20)); 996 997 // Wait long enough for the second timeout and see if it fired. 998 base::MessageLoop::current()->PostDelayedTask( 999 FROM_HERE, 1000 base::MessageLoop::QuitClosure(), 1001 TimeDelta::FromMilliseconds(25)); 1002 base::MessageLoop::current()->Run(); 1003 EXPECT_TRUE(host_->unresponsive_timer_fired()); 1004 } 1005 1006 // Test that the hang monitor catches two input events but only one ack. 1007 // This can happen if the second input event causes the renderer to hang. 1008 // This test will catch a regression of crbug.com/111185. 1009 TEST_F(RenderWidgetHostTest, MultipleInputEvents) { 1010 // Configure the host to wait 10ms before considering 1011 // the renderer hung. 1012 host_->set_hung_renderer_delay_ms(10); 1013 1014 // Send two events but only one ack. 1015 SimulateKeyboardEvent(WebInputEvent::RawKeyDown); 1016 SimulateKeyboardEvent(WebInputEvent::RawKeyDown); 1017 SendInputEventACK(WebInputEvent::RawKeyDown, 1018 INPUT_EVENT_ACK_STATE_CONSUMED); 1019 1020 // Wait long enough for first timeout and see if it fired. 1021 base::MessageLoop::current()->PostDelayedTask( 1022 FROM_HERE, 1023 base::MessageLoop::QuitClosure(), 1024 TimeDelta::FromMilliseconds(40)); 1025 base::MessageLoop::current()->Run(); 1026 EXPECT_TRUE(host_->unresponsive_timer_fired()); 1027 } 1028 1029 std::string GetInputMessageTypes(RenderWidgetHostProcess* process) { 1030 std::string result; 1031 for (size_t i = 0; i < process->sink().message_count(); ++i) { 1032 const IPC::Message *message = process->sink().GetMessageAt(i); 1033 EXPECT_EQ(InputMsg_HandleInputEvent::ID, message->type()); 1034 InputMsg_HandleInputEvent::Param params; 1035 EXPECT_TRUE(InputMsg_HandleInputEvent::Read(message, ¶ms)); 1036 const WebInputEvent* event = params.a; 1037 if (i != 0) 1038 result += " "; 1039 result += WebInputEventTraits::GetName(event->type); 1040 } 1041 process->sink().ClearMessages(); 1042 return result; 1043 } 1044 1045 TEST_F(RenderWidgetHostTest, TouchEmulator) { 1046 simulated_event_time_delta_seconds_ = 0.1; 1047 // Immediately ack all touches instead of sending them to the renderer. 1048 host_->OnMessageReceived(ViewHostMsg_HasTouchEventHandlers(0, false)); 1049 host_->SetTouchEventEmulationEnabled(true); 1050 process_->sink().ClearMessages(); 1051 view_->set_bounds(gfx::Rect(0, 0, 400, 200)); 1052 view_->Show(); 1053 1054 SimulateMouseEvent(WebInputEvent::MouseMove, 10, 10, 0, false); 1055 EXPECT_EQ(0U, process_->sink().message_count()); 1056 1057 // Mouse press becomes touch start which in turn becomes tap. 1058 SimulateMouseEvent(WebInputEvent::MouseDown, 10, 10, 0, true); 1059 EXPECT_EQ(WebInputEvent::TouchStart, host_->acked_touch_event_type()); 1060 EXPECT_EQ("GestureTapDown", GetInputMessageTypes(process_)); 1061 1062 // Mouse drag generates touch move, cancels tap and starts scroll. 1063 SimulateMouseEvent(WebInputEvent::MouseMove, 10, 30, 0, true); 1064 EXPECT_EQ(WebInputEvent::TouchMove, host_->acked_touch_event_type()); 1065 EXPECT_EQ( 1066 "GestureTapCancel GestureScrollBegin GestureScrollUpdate", 1067 GetInputMessageTypes(process_)); 1068 SendInputEventACK(WebInputEvent::GestureScrollUpdate, 1069 INPUT_EVENT_ACK_STATE_CONSUMED); 1070 EXPECT_EQ(0U, process_->sink().message_count()); 1071 1072 // Mouse drag with shift becomes pinch. 1073 SimulateMouseEvent( 1074 WebInputEvent::MouseMove, 10, 40, WebInputEvent::ShiftKey, true); 1075 EXPECT_EQ(WebInputEvent::TouchMove, host_->acked_touch_event_type()); 1076 EXPECT_EQ("GesturePinchBegin", 1077 GetInputMessageTypes(process_)); 1078 EXPECT_EQ(0U, process_->sink().message_count()); 1079 1080 SimulateMouseEvent( 1081 WebInputEvent::MouseMove, 10, 50, WebInputEvent::ShiftKey, true); 1082 EXPECT_EQ(WebInputEvent::TouchMove, host_->acked_touch_event_type()); 1083 EXPECT_EQ("GesturePinchUpdate", 1084 GetInputMessageTypes(process_)); 1085 SendInputEventACK(WebInputEvent::GesturePinchUpdate, 1086 INPUT_EVENT_ACK_STATE_CONSUMED); 1087 EXPECT_EQ(0U, process_->sink().message_count()); 1088 1089 // Mouse drag without shift becomes scroll again. 1090 SimulateMouseEvent(WebInputEvent::MouseMove, 10, 60, 0, true); 1091 EXPECT_EQ(WebInputEvent::TouchMove, host_->acked_touch_event_type()); 1092 EXPECT_EQ("GesturePinchEnd GestureScrollUpdate", 1093 GetInputMessageTypes(process_)); 1094 SendInputEventACK(WebInputEvent::GestureScrollUpdate, 1095 INPUT_EVENT_ACK_STATE_CONSUMED); 1096 EXPECT_EQ(0U, process_->sink().message_count()); 1097 1098 SimulateMouseEvent(WebInputEvent::MouseMove, 10, 70, 0, true); 1099 EXPECT_EQ(WebInputEvent::TouchMove, host_->acked_touch_event_type()); 1100 EXPECT_EQ("GestureScrollUpdate", 1101 GetInputMessageTypes(process_)); 1102 SendInputEventACK(WebInputEvent::GestureScrollUpdate, 1103 INPUT_EVENT_ACK_STATE_CONSUMED); 1104 EXPECT_EQ(0U, process_->sink().message_count()); 1105 1106 SimulateMouseEvent(WebInputEvent::MouseUp, 10, 70, 0, true); 1107 EXPECT_EQ(WebInputEvent::TouchEnd, host_->acked_touch_event_type()); 1108 EXPECT_EQ("GestureScrollEnd", GetInputMessageTypes(process_)); 1109 EXPECT_EQ(0U, process_->sink().message_count()); 1110 1111 // Mouse move does nothing. 1112 SimulateMouseEvent(WebInputEvent::MouseMove, 10, 80, 0, false); 1113 EXPECT_EQ(0U, process_->sink().message_count()); 1114 1115 // Another mouse down continues scroll. 1116 SimulateMouseEvent(WebInputEvent::MouseDown, 10, 80, 0, true); 1117 EXPECT_EQ(WebInputEvent::TouchStart, host_->acked_touch_event_type()); 1118 EXPECT_EQ("GestureTapDown", GetInputMessageTypes(process_)); 1119 EXPECT_EQ(0U, process_->sink().message_count()); 1120 1121 SimulateMouseEvent(WebInputEvent::MouseMove, 10, 100, 0, true); 1122 EXPECT_EQ(WebInputEvent::TouchMove, host_->acked_touch_event_type()); 1123 EXPECT_EQ( 1124 "GestureTapCancel GestureScrollBegin GestureScrollUpdate", 1125 GetInputMessageTypes(process_)); 1126 SendInputEventACK(WebInputEvent::GestureScrollUpdate, 1127 INPUT_EVENT_ACK_STATE_CONSUMED); 1128 EXPECT_EQ(0U, process_->sink().message_count()); 1129 1130 // Another pinch. 1131 SimulateMouseEvent( 1132 WebInputEvent::MouseMove, 10, 110, WebInputEvent::ShiftKey, true); 1133 EXPECT_EQ(WebInputEvent::TouchMove, host_->acked_touch_event_type()); 1134 EXPECT_EQ("GesturePinchBegin", 1135 GetInputMessageTypes(process_)); 1136 EXPECT_EQ(0U, process_->sink().message_count()); 1137 1138 SimulateMouseEvent( 1139 WebInputEvent::MouseMove, 10, 120, WebInputEvent::ShiftKey, true); 1140 EXPECT_EQ(WebInputEvent::TouchMove, host_->acked_touch_event_type()); 1141 EXPECT_EQ("GesturePinchUpdate", 1142 GetInputMessageTypes(process_)); 1143 SendInputEventACK(WebInputEvent::GesturePinchUpdate, 1144 INPUT_EVENT_ACK_STATE_CONSUMED); 1145 EXPECT_EQ(0U, process_->sink().message_count()); 1146 1147 // Turn off emulation during a pinch. 1148 host_->SetTouchEventEmulationEnabled(false); 1149 EXPECT_EQ(WebInputEvent::TouchCancel, host_->acked_touch_event_type()); 1150 EXPECT_EQ("GesturePinchEnd GestureScrollEnd", 1151 GetInputMessageTypes(process_)); 1152 EXPECT_EQ(0U, process_->sink().message_count()); 1153 1154 // Mouse event should pass untouched. 1155 SimulateMouseEvent( 1156 WebInputEvent::MouseMove, 10, 10, WebInputEvent::ShiftKey, true); 1157 EXPECT_EQ("MouseMove", GetInputMessageTypes(process_)); 1158 SendInputEventACK(WebInputEvent::MouseMove, 1159 INPUT_EVENT_ACK_STATE_CONSUMED); 1160 EXPECT_EQ(0U, process_->sink().message_count()); 1161 1162 // Turn on emulation. 1163 host_->SetTouchEventEmulationEnabled(true); 1164 EXPECT_EQ(0U, process_->sink().message_count()); 1165 1166 // Another touch. 1167 SimulateMouseEvent(WebInputEvent::MouseDown, 10, 10, 0, true); 1168 EXPECT_EQ(WebInputEvent::TouchStart, host_->acked_touch_event_type()); 1169 EXPECT_EQ("GestureTapDown", GetInputMessageTypes(process_)); 1170 EXPECT_EQ(0U, process_->sink().message_count()); 1171 1172 // Scroll. 1173 SimulateMouseEvent(WebInputEvent::MouseMove, 10, 30, 0, true); 1174 EXPECT_EQ(WebInputEvent::TouchMove, host_->acked_touch_event_type()); 1175 EXPECT_EQ( 1176 "GestureTapCancel GestureScrollBegin GestureScrollUpdate", 1177 GetInputMessageTypes(process_)); 1178 SendInputEventACK(WebInputEvent::GestureScrollUpdate, 1179 INPUT_EVENT_ACK_STATE_CONSUMED); 1180 1181 // Turn off emulation during a scroll. 1182 host_->SetTouchEventEmulationEnabled(false); 1183 EXPECT_EQ(WebInputEvent::TouchCancel, host_->acked_touch_event_type()); 1184 1185 EXPECT_EQ("GestureScrollEnd", GetInputMessageTypes(process_)); 1186 EXPECT_EQ(0U, process_->sink().message_count()); 1187 } 1188 1189 #define TEST_InputRouterRoutes_NOARGS(INPUTMSG) \ 1190 TEST_F(RenderWidgetHostTest, InputRouterRoutes##INPUTMSG) { \ 1191 host_->SetupForInputRouterTest(); \ 1192 host_->INPUTMSG(); \ 1193 EXPECT_TRUE(host_->mock_input_router()->send_event_called_); \ 1194 } 1195 1196 TEST_InputRouterRoutes_NOARGS(Focus); 1197 TEST_InputRouterRoutes_NOARGS(Blur); 1198 TEST_InputRouterRoutes_NOARGS(LostCapture); 1199 1200 #undef TEST_InputRouterRoutes_NOARGS 1201 1202 #define TEST_InputRouterRoutes_NOARGS_FromRFH(INPUTMSG) \ 1203 TEST_F(RenderWidgetHostTest, InputRouterRoutes##INPUTMSG) { \ 1204 host_->SetupForInputRouterTest(); \ 1205 host_->Send(new INPUTMSG(host_->GetRoutingID())); \ 1206 EXPECT_TRUE(host_->mock_input_router()->send_event_called_); \ 1207 } 1208 1209 TEST_InputRouterRoutes_NOARGS_FromRFH(InputMsg_Undo); 1210 TEST_InputRouterRoutes_NOARGS_FromRFH(InputMsg_Redo); 1211 TEST_InputRouterRoutes_NOARGS_FromRFH(InputMsg_Cut); 1212 TEST_InputRouterRoutes_NOARGS_FromRFH(InputMsg_Copy); 1213 #if defined(OS_MACOSX) 1214 TEST_InputRouterRoutes_NOARGS_FromRFH(InputMsg_CopyToFindPboard); 1215 #endif 1216 TEST_InputRouterRoutes_NOARGS_FromRFH(InputMsg_Paste); 1217 TEST_InputRouterRoutes_NOARGS_FromRFH(InputMsg_PasteAndMatchStyle); 1218 TEST_InputRouterRoutes_NOARGS_FromRFH(InputMsg_Delete); 1219 TEST_InputRouterRoutes_NOARGS_FromRFH(InputMsg_SelectAll); 1220 TEST_InputRouterRoutes_NOARGS_FromRFH(InputMsg_Unselect); 1221 1222 #undef TEST_InputRouterRoutes_NOARGS_FromRFH 1223 1224 TEST_F(RenderWidgetHostTest, InputRouterRoutesReplace) { 1225 host_->SetupForInputRouterTest(); 1226 host_->Send(new InputMsg_Replace(host_->GetRoutingID(), base::string16())); 1227 EXPECT_TRUE(host_->mock_input_router()->send_event_called_); 1228 } 1229 1230 TEST_F(RenderWidgetHostTest, InputRouterRoutesReplaceMisspelling) { 1231 host_->SetupForInputRouterTest(); 1232 host_->Send(new InputMsg_ReplaceMisspelling(host_->GetRoutingID(), 1233 base::string16())); 1234 EXPECT_TRUE(host_->mock_input_router()->send_event_called_); 1235 } 1236 1237 TEST_F(RenderWidgetHostTest, IgnoreInputEvent) { 1238 host_->SetupForInputRouterTest(); 1239 1240 host_->SetIgnoreInputEvents(true); 1241 1242 SimulateKeyboardEvent(WebInputEvent::RawKeyDown); 1243 EXPECT_FALSE(host_->mock_input_router()->sent_keyboard_event_); 1244 1245 SimulateMouseEvent(WebInputEvent::MouseMove); 1246 EXPECT_FALSE(host_->mock_input_router()->sent_mouse_event_); 1247 1248 SimulateWheelEvent(0, 100, 0, true); 1249 EXPECT_FALSE(host_->mock_input_router()->sent_wheel_event_); 1250 1251 SimulateGestureEvent(WebInputEvent::GestureScrollBegin, 1252 blink::WebGestureDeviceTouchpad); 1253 EXPECT_FALSE(host_->mock_input_router()->sent_gesture_event_); 1254 1255 PressTouchPoint(100, 100); 1256 SendTouchEvent(); 1257 EXPECT_FALSE(host_->mock_input_router()->send_touch_event_not_cancelled_); 1258 } 1259 1260 TEST_F(RenderWidgetHostTest, KeyboardListenerIgnoresEvent) { 1261 host_->SetupForInputRouterTest(); 1262 host_->AddKeyPressEventCallback( 1263 base::Bind(&RenderWidgetHostTest::KeyPressEventCallback, 1264 base::Unretained(this))); 1265 handle_key_press_event_ = false; 1266 SimulateKeyboardEvent(WebInputEvent::RawKeyDown); 1267 1268 EXPECT_TRUE(host_->mock_input_router()->sent_keyboard_event_); 1269 } 1270 1271 TEST_F(RenderWidgetHostTest, KeyboardListenerSuppressFollowingEvents) { 1272 host_->SetupForInputRouterTest(); 1273 1274 host_->AddKeyPressEventCallback( 1275 base::Bind(&RenderWidgetHostTest::KeyPressEventCallback, 1276 base::Unretained(this))); 1277 1278 // The callback handles the first event 1279 handle_key_press_event_ = true; 1280 SimulateKeyboardEvent(WebInputEvent::RawKeyDown); 1281 1282 EXPECT_FALSE(host_->mock_input_router()->sent_keyboard_event_); 1283 1284 // Following Char events should be suppressed 1285 handle_key_press_event_ = false; 1286 SimulateKeyboardEvent(WebInputEvent::Char); 1287 EXPECT_FALSE(host_->mock_input_router()->sent_keyboard_event_); 1288 SimulateKeyboardEvent(WebInputEvent::Char); 1289 EXPECT_FALSE(host_->mock_input_router()->sent_keyboard_event_); 1290 1291 // Sending RawKeyDown event should stop suppression 1292 SimulateKeyboardEvent(WebInputEvent::RawKeyDown); 1293 EXPECT_TRUE(host_->mock_input_router()->sent_keyboard_event_); 1294 1295 host_->mock_input_router()->sent_keyboard_event_ = false; 1296 SimulateKeyboardEvent(WebInputEvent::Char); 1297 EXPECT_TRUE(host_->mock_input_router()->sent_keyboard_event_); 1298 } 1299 1300 TEST_F(RenderWidgetHostTest, MouseEventCallbackCanHandleEvent) { 1301 host_->SetupForInputRouterTest(); 1302 1303 host_->AddMouseEventCallback( 1304 base::Bind(&RenderWidgetHostTest::MouseEventCallback, 1305 base::Unretained(this))); 1306 1307 handle_mouse_event_ = true; 1308 SimulateMouseEvent(WebInputEvent::MouseDown); 1309 1310 EXPECT_FALSE(host_->mock_input_router()->sent_mouse_event_); 1311 1312 handle_mouse_event_ = false; 1313 SimulateMouseEvent(WebInputEvent::MouseDown); 1314 1315 EXPECT_TRUE(host_->mock_input_router()->sent_mouse_event_); 1316 } 1317 1318 TEST_F(RenderWidgetHostTest, InputRouterReceivesHandleInputEvent_ACK) { 1319 host_->SetupForInputRouterTest(); 1320 1321 SendInputEventACK(WebInputEvent::RawKeyDown, 1322 INPUT_EVENT_ACK_STATE_CONSUMED); 1323 1324 EXPECT_TRUE(host_->mock_input_router()->message_received_); 1325 } 1326 1327 TEST_F(RenderWidgetHostTest, InputRouterReceivesMoveCaret_ACK) { 1328 host_->SetupForInputRouterTest(); 1329 1330 host_->OnMessageReceived(ViewHostMsg_MoveCaret_ACK(0)); 1331 1332 EXPECT_TRUE(host_->mock_input_router()->message_received_); 1333 } 1334 1335 TEST_F(RenderWidgetHostTest, InputRouterReceivesSelectRange_ACK) { 1336 host_->SetupForInputRouterTest(); 1337 1338 host_->OnMessageReceived(ViewHostMsg_SelectRange_ACK(0)); 1339 1340 EXPECT_TRUE(host_->mock_input_router()->message_received_); 1341 } 1342 1343 TEST_F(RenderWidgetHostTest, InputRouterReceivesHasTouchEventHandlers) { 1344 host_->SetupForInputRouterTest(); 1345 1346 host_->OnMessageReceived(ViewHostMsg_HasTouchEventHandlers(0, true)); 1347 1348 EXPECT_TRUE(host_->mock_input_router()->message_received_); 1349 } 1350 1351 ui::LatencyInfo GetLatencyInfoFromInputEvent(RenderWidgetHostProcess* process) { 1352 const IPC::Message* message = process->sink().GetUniqueMessageMatching( 1353 InputMsg_HandleInputEvent::ID); 1354 EXPECT_TRUE(message); 1355 InputMsg_HandleInputEvent::Param params; 1356 EXPECT_TRUE(InputMsg_HandleInputEvent::Read(message, ¶ms)); 1357 process->sink().ClearMessages(); 1358 return params.b; 1359 } 1360 1361 void CheckLatencyInfoComponentInMessage(RenderWidgetHostProcess* process, 1362 int64 component_id, 1363 WebInputEvent::Type input_type) { 1364 ui::LatencyInfo latency_info = GetLatencyInfoFromInputEvent(process); 1365 EXPECT_TRUE(latency_info.FindLatency( 1366 ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT, 1367 component_id, 1368 NULL)); 1369 } 1370 1371 // Tests that after input event passes through RWHI through ForwardXXXEvent() 1372 // or ForwardXXXEventWithLatencyInfo(), LatencyInfo component 1373 // ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT will always present in the 1374 // event's LatencyInfo. 1375 TEST_F(RenderWidgetHostTest, InputEventRWHLatencyComponent) { 1376 host_->OnMessageReceived(ViewHostMsg_HasTouchEventHandlers(0, true)); 1377 process_->sink().ClearMessages(); 1378 1379 // Tests RWHI::ForwardWheelEvent(). 1380 SimulateWheelEvent(-5, 0, 0, true); 1381 CheckLatencyInfoComponentInMessage( 1382 process_, GetLatencyComponentId(), WebInputEvent::MouseWheel); 1383 SendInputEventACK(WebInputEvent::MouseWheel, INPUT_EVENT_ACK_STATE_CONSUMED); 1384 1385 // Tests RWHI::ForwardWheelEventWithLatencyInfo(). 1386 SimulateWheelEventWithLatencyInfo(-5, 0, 0, true, ui::LatencyInfo()); 1387 CheckLatencyInfoComponentInMessage( 1388 process_, GetLatencyComponentId(), WebInputEvent::MouseWheel); 1389 SendInputEventACK(WebInputEvent::MouseWheel, INPUT_EVENT_ACK_STATE_CONSUMED); 1390 1391 // Tests RWHI::ForwardMouseEvent(). 1392 SimulateMouseEvent(WebInputEvent::MouseMove); 1393 CheckLatencyInfoComponentInMessage( 1394 process_, GetLatencyComponentId(), WebInputEvent::MouseMove); 1395 SendInputEventACK(WebInputEvent::MouseMove, INPUT_EVENT_ACK_STATE_CONSUMED); 1396 1397 // Tests RWHI::ForwardMouseEventWithLatencyInfo(). 1398 SimulateMouseEventWithLatencyInfo(WebInputEvent::MouseMove, 1399 ui::LatencyInfo()); 1400 CheckLatencyInfoComponentInMessage( 1401 process_, GetLatencyComponentId(), WebInputEvent::MouseMove); 1402 SendInputEventACK(WebInputEvent::MouseMove, INPUT_EVENT_ACK_STATE_CONSUMED); 1403 1404 // Tests RWHI::ForwardGestureEvent(). 1405 SimulateGestureEvent(WebInputEvent::GestureScrollBegin, 1406 blink::WebGestureDeviceTouchscreen); 1407 CheckLatencyInfoComponentInMessage( 1408 process_, GetLatencyComponentId(), WebInputEvent::GestureScrollBegin); 1409 1410 // Tests RWHI::ForwardGestureEventWithLatencyInfo(). 1411 SimulateGestureEventWithLatencyInfo(WebInputEvent::GestureScrollUpdate, 1412 blink::WebGestureDeviceTouchscreen, 1413 ui::LatencyInfo()); 1414 CheckLatencyInfoComponentInMessage( 1415 process_, GetLatencyComponentId(), WebInputEvent::GestureScrollUpdate); 1416 SendInputEventACK(WebInputEvent::GestureScrollUpdate, 1417 INPUT_EVENT_ACK_STATE_CONSUMED); 1418 1419 // Tests RWHI::ForwardTouchEventWithLatencyInfo(). 1420 PressTouchPoint(0, 1); 1421 SendTouchEvent(); 1422 CheckLatencyInfoComponentInMessage( 1423 process_, GetLatencyComponentId(), WebInputEvent::TouchStart); 1424 SendInputEventACK(WebInputEvent::TouchStart, INPUT_EVENT_ACK_STATE_CONSUMED); 1425 } 1426 1427 // Tests that after input event passes through RWHI through 1428 // ForwardXXXEventWithLatencyInfo(), input event coordinates will be present in 1429 // the latency info. 1430 TEST_F(RenderWidgetHostTest, InputEventRWHLatencyInfoCoordinates) { 1431 host_->OnMessageReceived(ViewHostMsg_HasTouchEventHandlers(0, true)); 1432 process_->sink().ClearMessages(); 1433 1434 { 1435 WebMouseWheelEvent event = 1436 SyntheticWebMouseWheelEventBuilder::Build(-5, 0, 0, true); 1437 event.x = 100; 1438 event.y = 200; 1439 host_->ForwardWheelEvent(event); 1440 ui::LatencyInfo latency_info = GetLatencyInfoFromInputEvent(process_); 1441 EXPECT_EQ(1u, latency_info.input_coordinates_size); 1442 EXPECT_EQ(100, latency_info.input_coordinates[0].x); 1443 EXPECT_EQ(200, latency_info.input_coordinates[0].y); 1444 SendInputEventACK(WebInputEvent::MouseWheel, 1445 INPUT_EVENT_ACK_STATE_CONSUMED); 1446 } 1447 1448 { 1449 WebMouseEvent event = 1450 SyntheticWebMouseEventBuilder::Build(WebInputEvent::MouseMove); 1451 event.x = 300; 1452 event.y = 400; 1453 host_->ForwardMouseEvent(event); 1454 ui::LatencyInfo latency_info = GetLatencyInfoFromInputEvent(process_); 1455 EXPECT_EQ(1u, latency_info.input_coordinates_size); 1456 EXPECT_EQ(300, latency_info.input_coordinates[0].x); 1457 EXPECT_EQ(400, latency_info.input_coordinates[0].y); 1458 SendInputEventACK(WebInputEvent::MouseMove, INPUT_EVENT_ACK_STATE_CONSUMED); 1459 } 1460 1461 { 1462 WebGestureEvent event = SyntheticWebGestureEventBuilder::Build( 1463 WebInputEvent::GestureScrollBegin, blink::WebGestureDeviceTouchscreen); 1464 event.x = 500; 1465 event.y = 600; 1466 host_->ForwardGestureEvent(event); 1467 ui::LatencyInfo latency_info = GetLatencyInfoFromInputEvent(process_); 1468 EXPECT_EQ(1u, latency_info.input_coordinates_size); 1469 EXPECT_EQ(500, latency_info.input_coordinates[0].x); 1470 EXPECT_EQ(600, latency_info.input_coordinates[0].y); 1471 SendInputEventACK(WebInputEvent::GestureScrollBegin, 1472 INPUT_EVENT_ACK_STATE_CONSUMED); 1473 } 1474 1475 { 1476 PressTouchPoint(700, 800); 1477 PressTouchPoint(900, 1000); 1478 PressTouchPoint(1100, 1200); // LatencyInfo only holds two coordinates. 1479 SendTouchEvent(); 1480 ui::LatencyInfo latency_info = GetLatencyInfoFromInputEvent(process_); 1481 EXPECT_EQ(2u, latency_info.input_coordinates_size); 1482 EXPECT_EQ(700, latency_info.input_coordinates[0].x); 1483 EXPECT_EQ(800, latency_info.input_coordinates[0].y); 1484 EXPECT_EQ(900, latency_info.input_coordinates[1].x); 1485 EXPECT_EQ(1000, latency_info.input_coordinates[1].y); 1486 SendInputEventACK(WebInputEvent::TouchStart, 1487 INPUT_EVENT_ACK_STATE_CONSUMED); 1488 } 1489 1490 { 1491 NativeWebKeyboardEvent event; 1492 event.type = WebKeyboardEvent::KeyDown; 1493 host_->ForwardKeyboardEvent(event); 1494 ui::LatencyInfo latency_info = GetLatencyInfoFromInputEvent(process_); 1495 EXPECT_EQ(0u, latency_info.input_coordinates_size); 1496 SendInputEventACK(WebInputEvent::KeyDown, INPUT_EVENT_ACK_STATE_CONSUMED); 1497 } 1498 } 1499 1500 TEST_F(RenderWidgetHostTest, RendererExitedResetsInputRouter) { 1501 // RendererExited will delete the view. 1502 host_->SetView(new TestView(host_.get())); 1503 host_->RendererExited(base::TERMINATION_STATUS_PROCESS_CRASHED, -1); 1504 1505 // Make sure the input router is in a fresh state. 1506 ASSERT_FALSE(host_->input_router()->HasPendingEvents()); 1507 } 1508 1509 // Regression test for http://crbug.com/401859. 1510 TEST_F(RenderWidgetHostTest, RendererExitedResetsIsHidden) { 1511 // RendererExited will delete the view. 1512 host_->SetView(new TestView(host_.get())); 1513 host_->WasHidden(); 1514 1515 ASSERT_TRUE(host_->is_hidden()); 1516 host_->RendererExited(base::TERMINATION_STATUS_PROCESS_CRASHED, -1); 1517 ASSERT_FALSE(host_->is_hidden()); 1518 1519 // Make sure the input router is in a fresh state. 1520 ASSERT_FALSE(host_->input_router()->HasPendingEvents()); 1521 } 1522 1523 TEST_F(RenderWidgetHostTest, ResizeParams) { 1524 gfx::Rect bounds(0, 0, 100, 100); 1525 gfx::Size physical_backing_size(40, 50); 1526 view_->set_bounds(bounds); 1527 view_->SetMockPhysicalBackingSize(physical_backing_size); 1528 1529 ViewMsg_Resize_Params resize_params; 1530 host_->GetResizeParams(&resize_params); 1531 EXPECT_EQ(bounds.size(), resize_params.new_size); 1532 EXPECT_EQ(physical_backing_size, resize_params.physical_backing_size); 1533 } 1534 1535 class RenderWidgetHostInitialSizeTest : public RenderWidgetHostTest { 1536 public: 1537 RenderWidgetHostInitialSizeTest() 1538 : RenderWidgetHostTest(), initial_size_(200, 100) {} 1539 1540 virtual void ConfigureView(TestView* view) override { 1541 view->set_bounds(gfx::Rect(initial_size_)); 1542 } 1543 1544 protected: 1545 gfx::Size initial_size_; 1546 }; 1547 1548 TEST_F(RenderWidgetHostInitialSizeTest, InitialSize) { 1549 // Having an initial size set means that the size information had been sent 1550 // with the reqiest to new up the RenderView and so subsequent WasResized 1551 // calls should not result in new IPC (unless the size has actually changed). 1552 host_->WasResized(); 1553 EXPECT_FALSE(process_->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID)); 1554 EXPECT_EQ(initial_size_, host_->old_resize_params_->new_size); 1555 EXPECT_TRUE(host_->resize_ack_pending_); 1556 } 1557 1558 } // namespace content 1559