OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "base/basictypes.h" | 5 #include "base/basictypes.h" |
6 #include "base/memory/scoped_ptr.h" | 6 #include "base/memory/scoped_ptr.h" |
7 #include "base/shared_memory.h" | 7 #include "base/shared_memory.h" |
8 #include "base/timer.h" | 8 #include "base/timer.h" |
9 #include "content/browser/browser_thread_impl.h" | 9 #include "content/browser/browser_thread_impl.h" |
10 #include "content/browser/renderer_host/backing_store.h" | 10 #include "content/browser/renderer_host/backing_store.h" |
| 11 #include "content/browser/renderer_host/render_widget_host_delegate.h" |
11 #include "content/browser/renderer_host/test_render_view_host.h" | 12 #include "content/browser/renderer_host/test_render_view_host.h" |
12 #include "content/common/view_messages.h" | 13 #include "content/common/view_messages.h" |
13 #include "content/port/browser/render_widget_host_view_port.h" | 14 #include "content/port/browser/render_widget_host_view_port.h" |
14 #include "content/public/browser/notification_details.h" | 15 #include "content/public/browser/notification_details.h" |
15 #include "content/public/browser/notification_observer.h" | 16 #include "content/public/browser/notification_observer.h" |
16 #include "content/public/browser/notification_registrar.h" | 17 #include "content/public/browser/notification_registrar.h" |
17 #include "content/public/browser/notification_source.h" | 18 #include "content/public/browser/notification_source.h" |
18 #include "content/public/browser/notification_types.h" | 19 #include "content/public/browser/notification_types.h" |
19 #include "content/test/mock_render_process_host.h" | 20 #include "content/test/mock_render_process_host.h" |
20 #include "content/test/test_browser_context.h" | 21 #include "content/test/test_browser_context.h" |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
140 virtual gfx::Rect GetViewCocoaBounds() const { | 141 virtual gfx::Rect GetViewCocoaBounds() const { |
141 return bounds_; | 142 return bounds_; |
142 } | 143 } |
143 #endif | 144 #endif |
144 | 145 |
145 protected: | 146 protected: |
146 gfx::Rect bounds_; | 147 gfx::Rect bounds_; |
147 DISALLOW_COPY_AND_ASSIGN(TestView); | 148 DISALLOW_COPY_AND_ASSIGN(TestView); |
148 }; | 149 }; |
149 | 150 |
150 // MockRenderWidgetHost ---------------------------------------------------- | 151 // MockRenderWidgetHostDelegate -------------------------------------------- |
151 | 152 |
152 class MockRenderWidgetHost : public RenderWidgetHostImpl { | 153 class MockRenderWidgetHostDelegate : public content::RenderWidgetHostDelegate { |
153 public: | 154 public: |
154 MockRenderWidgetHost(content::RenderProcessHost* process, int routing_id) | 155 MockRenderWidgetHostDelegate() |
155 : RenderWidgetHostImpl(process, routing_id), | 156 : prehandle_keyboard_event_(false), |
156 prehandle_keyboard_event_(false), | |
157 prehandle_keyboard_event_called_(false), | 157 prehandle_keyboard_event_called_(false), |
158 prehandle_keyboard_event_type_(WebInputEvent::Undefined), | 158 prehandle_keyboard_event_type_(WebInputEvent::Undefined), |
159 unhandled_keyboard_event_called_(false), | 159 unhandled_keyboard_event_called_(false), |
160 unhandled_keyboard_event_type_(WebInputEvent::Undefined), | 160 unhandled_keyboard_event_type_(WebInputEvent::Undefined) { |
161 unresponsive_timer_fired_(false) { | |
162 } | 161 } |
163 | 162 virtual ~MockRenderWidgetHostDelegate() {} |
164 // Allow poking at a few private members. | |
165 using RenderWidgetHostImpl::OnMsgPaintAtSizeAck; | |
166 using RenderWidgetHostImpl::OnMsgUpdateRect; | |
167 using RenderWidgetHostImpl::RendererExited; | |
168 using RenderWidgetHostImpl::in_flight_size_; | |
169 using RenderWidgetHostImpl::is_hidden_; | |
170 using RenderWidgetHostImpl::resize_ack_pending_; | |
171 | 163 |
172 // Tests that make sure we ignore keyboard event acknowledgments to events we | 164 // Tests that make sure we ignore keyboard event acknowledgments to events we |
173 // didn't send work by making sure we didn't call UnhandledKeyboardEvent(). | 165 // didn't send work by making sure we didn't call UnhandledKeyboardEvent(). |
174 bool unhandled_keyboard_event_called() const { | 166 bool unhandled_keyboard_event_called() const { |
175 return unhandled_keyboard_event_called_; | 167 return unhandled_keyboard_event_called_; |
176 } | 168 } |
177 | 169 |
178 WebInputEvent::Type unhandled_keyboard_event_type() const { | 170 WebInputEvent::Type unhandled_keyboard_event_type() const { |
179 return unhandled_keyboard_event_type_; | 171 return unhandled_keyboard_event_type_; |
180 } | 172 } |
181 | 173 |
182 bool prehandle_keyboard_event_called() const { | 174 bool prehandle_keyboard_event_called() const { |
183 return prehandle_keyboard_event_called_; | 175 return prehandle_keyboard_event_called_; |
184 } | 176 } |
185 | 177 |
186 WebInputEvent::Type prehandle_keyboard_event_type() const { | 178 WebInputEvent::Type prehandle_keyboard_event_type() const { |
187 return prehandle_keyboard_event_type_; | 179 return prehandle_keyboard_event_type_; |
188 } | 180 } |
189 | 181 |
190 void set_prehandle_keyboard_event(bool handle) { | 182 void set_prehandle_keyboard_event(bool handle) { |
191 prehandle_keyboard_event_ = handle; | 183 prehandle_keyboard_event_ = handle; |
192 } | 184 } |
193 | 185 |
194 bool unresponsive_timer_fired() const { | |
195 return unresponsive_timer_fired_; | |
196 } | |
197 | |
198 void set_hung_renderer_delay_ms(int delay_ms) { | |
199 hung_renderer_delay_ms_ = delay_ms; | |
200 } | |
201 | |
202 protected: | 186 protected: |
203 virtual bool PreHandleKeyboardEvent(const NativeWebKeyboardEvent& event, | 187 virtual bool PreHandleKeyboardEvent(const NativeWebKeyboardEvent& event, |
204 bool* is_keyboard_shortcut) { | 188 bool* is_keyboard_shortcut) OVERRIDE { |
205 prehandle_keyboard_event_type_ = event.type; | 189 prehandle_keyboard_event_type_ = event.type; |
206 prehandle_keyboard_event_called_ = true; | 190 prehandle_keyboard_event_called_ = true; |
207 return prehandle_keyboard_event_; | 191 return prehandle_keyboard_event_; |
208 } | 192 } |
209 | 193 |
210 virtual void UnhandledKeyboardEvent(const NativeWebKeyboardEvent& event) { | 194 virtual void HandleKeyboardEvent( |
| 195 const NativeWebKeyboardEvent& event) OVERRIDE { |
211 unhandled_keyboard_event_type_ = event.type; | 196 unhandled_keyboard_event_type_ = event.type; |
212 unhandled_keyboard_event_called_ = true; | 197 unhandled_keyboard_event_called_ = true; |
213 } | 198 } |
214 | 199 |
215 virtual void NotifyRendererUnresponsive() { | |
216 unresponsive_timer_fired_ = true; | |
217 } | |
218 | |
219 private: | 200 private: |
220 bool prehandle_keyboard_event_; | 201 bool prehandle_keyboard_event_; |
221 bool prehandle_keyboard_event_called_; | 202 bool prehandle_keyboard_event_called_; |
222 WebInputEvent::Type prehandle_keyboard_event_type_; | 203 WebInputEvent::Type prehandle_keyboard_event_type_; |
223 | 204 |
224 bool unhandled_keyboard_event_called_; | 205 bool unhandled_keyboard_event_called_; |
225 WebInputEvent::Type unhandled_keyboard_event_type_; | 206 WebInputEvent::Type unhandled_keyboard_event_type_; |
| 207 }; |
226 | 208 |
| 209 // MockRenderWidgetHost ---------------------------------------------------- |
| 210 |
| 211 class MockRenderWidgetHost : public RenderWidgetHostImpl { |
| 212 public: |
| 213 MockRenderWidgetHost( |
| 214 content::RenderWidgetHostDelegate* delegate, |
| 215 content::RenderProcessHost* process, |
| 216 int routing_id) |
| 217 : RenderWidgetHostImpl(delegate, process, routing_id), |
| 218 unresponsive_timer_fired_(false) { |
| 219 } |
| 220 |
| 221 // Allow poking at a few private members. |
| 222 using RenderWidgetHostImpl::OnMsgPaintAtSizeAck; |
| 223 using RenderWidgetHostImpl::OnMsgUpdateRect; |
| 224 using RenderWidgetHostImpl::RendererExited; |
| 225 using RenderWidgetHostImpl::in_flight_size_; |
| 226 using RenderWidgetHostImpl::is_hidden_; |
| 227 using RenderWidgetHostImpl::resize_ack_pending_; |
| 228 |
| 229 bool unresponsive_timer_fired() const { |
| 230 return unresponsive_timer_fired_; |
| 231 } |
| 232 |
| 233 void set_hung_renderer_delay_ms(int delay_ms) { |
| 234 hung_renderer_delay_ms_ = delay_ms; |
| 235 } |
| 236 |
| 237 protected: |
| 238 virtual void NotifyRendererUnresponsive() OVERRIDE { |
| 239 unresponsive_timer_fired_ = true; |
| 240 } |
| 241 |
| 242 private: |
227 bool unresponsive_timer_fired_; | 243 bool unresponsive_timer_fired_; |
228 }; | 244 }; |
229 | 245 |
230 // MockPaintingObserver -------------------------------------------------------- | 246 // MockPaintingObserver -------------------------------------------------------- |
231 | 247 |
232 class MockPaintingObserver : public content::NotificationObserver { | 248 class MockPaintingObserver : public content::NotificationObserver { |
233 public: | 249 public: |
234 void WidgetDidReceivePaintAtSizeAck(RenderWidgetHostImpl* host, | 250 void WidgetDidReceivePaintAtSizeAck(RenderWidgetHostImpl* host, |
235 int tag, | 251 int tag, |
236 const gfx::Size& size) { | 252 const gfx::Size& size) { |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
271 public: | 287 public: |
272 RenderWidgetHostTest() : process_(NULL) { | 288 RenderWidgetHostTest() : process_(NULL) { |
273 } | 289 } |
274 ~RenderWidgetHostTest() { | 290 ~RenderWidgetHostTest() { |
275 } | 291 } |
276 | 292 |
277 protected: | 293 protected: |
278 // testing::Test | 294 // testing::Test |
279 void SetUp() { | 295 void SetUp() { |
280 browser_context_.reset(new TestBrowserContext()); | 296 browser_context_.reset(new TestBrowserContext()); |
| 297 delegate_.reset(new MockRenderWidgetHostDelegate()); |
281 process_ = new RenderWidgetHostProcess(browser_context_.get()); | 298 process_ = new RenderWidgetHostProcess(browser_context_.get()); |
282 host_.reset(new MockRenderWidgetHost(process_, MSG_ROUTING_NONE)); | 299 host_.reset( |
| 300 new MockRenderWidgetHost(delegate_.get(), process_, MSG_ROUTING_NONE)); |
283 view_.reset(new TestView(host_.get())); | 301 view_.reset(new TestView(host_.get())); |
284 host_->SetView(view_.get()); | 302 host_->SetView(view_.get()); |
285 host_->Init(); | 303 host_->Init(); |
286 } | 304 } |
287 void TearDown() { | 305 void TearDown() { |
288 view_.reset(); | 306 view_.reset(); |
289 host_.reset(); | 307 host_.reset(); |
| 308 delegate_.reset(); |
290 process_ = NULL; | 309 process_ = NULL; |
291 browser_context_.reset(); | 310 browser_context_.reset(); |
292 | 311 |
293 // Process all pending tasks to avoid leaks. | 312 // Process all pending tasks to avoid leaks. |
294 MessageLoop::current()->RunAllPending(); | 313 MessageLoop::current()->RunAllPending(); |
295 } | 314 } |
296 | 315 |
297 void SendInputEventACK(WebInputEvent::Type type, bool processed) { | 316 void SendInputEventACK(WebInputEvent::Type type, bool processed) { |
298 scoped_ptr<IPC::Message> response( | 317 scoped_ptr<IPC::Message> response( |
299 new ViewHostMsg_HandleInputEvent_ACK(0, type, processed)); | 318 new ViewHostMsg_HandleInputEvent_ACK(0, type, processed)); |
(...skipping 13 matching lines...) Expand all Loading... |
313 wheel_event.deltaX = dX; | 332 wheel_event.deltaX = dX; |
314 wheel_event.deltaY = dY; | 333 wheel_event.deltaY = dY; |
315 wheel_event.modifiers = modifiers; | 334 wheel_event.modifiers = modifiers; |
316 host_->ForwardWheelEvent(wheel_event); | 335 host_->ForwardWheelEvent(wheel_event); |
317 } | 336 } |
318 | 337 |
319 MessageLoopForUI message_loop_; | 338 MessageLoopForUI message_loop_; |
320 | 339 |
321 scoped_ptr<TestBrowserContext> browser_context_; | 340 scoped_ptr<TestBrowserContext> browser_context_; |
322 RenderWidgetHostProcess* process_; // Deleted automatically by the widget. | 341 RenderWidgetHostProcess* process_; // Deleted automatically by the widget. |
| 342 scoped_ptr<MockRenderWidgetHostDelegate> delegate_; |
323 scoped_ptr<MockRenderWidgetHost> host_; | 343 scoped_ptr<MockRenderWidgetHost> host_; |
324 scoped_ptr<TestView> view_; | 344 scoped_ptr<TestView> view_; |
325 | 345 |
326 DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostTest); | 346 DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostTest); |
327 }; | 347 }; |
328 | 348 |
329 // ----------------------------------------------------------------------------- | 349 // ----------------------------------------------------------------------------- |
330 | 350 |
331 TEST_F(RenderWidgetHostTest, Resize) { | 351 TEST_F(RenderWidgetHostTest, Resize) { |
332 // The initial bounds is the empty rect, so setting it to the same thing | 352 // The initial bounds is the empty rect, so setting it to the same thing |
(...skipping 301 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
634 SimulateKeyboardEvent(WebInputEvent::RawKeyDown); | 654 SimulateKeyboardEvent(WebInputEvent::RawKeyDown); |
635 | 655 |
636 // Make sure we sent the input event to the renderer. | 656 // Make sure we sent the input event to the renderer. |
637 EXPECT_TRUE(process_->sink().GetUniqueMessageMatching( | 657 EXPECT_TRUE(process_->sink().GetUniqueMessageMatching( |
638 ViewMsg_HandleInputEvent::ID)); | 658 ViewMsg_HandleInputEvent::ID)); |
639 process_->sink().ClearMessages(); | 659 process_->sink().ClearMessages(); |
640 | 660 |
641 // Send the simulated response from the renderer back. | 661 // Send the simulated response from the renderer back. |
642 SendInputEventACK(WebInputEvent::RawKeyDown, false); | 662 SendInputEventACK(WebInputEvent::RawKeyDown, false); |
643 | 663 |
644 EXPECT_TRUE(host_->unhandled_keyboard_event_called()); | 664 EXPECT_TRUE(delegate_->unhandled_keyboard_event_called()); |
645 EXPECT_EQ(WebInputEvent::RawKeyDown, host_->unhandled_keyboard_event_type()); | 665 EXPECT_EQ(WebInputEvent::RawKeyDown, |
| 666 delegate_->unhandled_keyboard_event_type()); |
646 } | 667 } |
647 | 668 |
648 TEST_F(RenderWidgetHostTest, IgnoreKeyEventsWeDidntSend) { | 669 TEST_F(RenderWidgetHostTest, IgnoreKeyEventsWeDidntSend) { |
649 // Send a simulated, unrequested key response. We should ignore this. | 670 // Send a simulated, unrequested key response. We should ignore this. |
650 SendInputEventACK(WebInputEvent::RawKeyDown, false); | 671 SendInputEventACK(WebInputEvent::RawKeyDown, false); |
651 | 672 |
652 EXPECT_FALSE(host_->unhandled_keyboard_event_called()); | 673 EXPECT_FALSE(delegate_->unhandled_keyboard_event_called()); |
653 } | 674 } |
654 | 675 |
655 TEST_F(RenderWidgetHostTest, IgnoreKeyEventsHandledByRenderer) { | 676 TEST_F(RenderWidgetHostTest, IgnoreKeyEventsHandledByRenderer) { |
656 // Simulate a keyboard event. | 677 // Simulate a keyboard event. |
657 SimulateKeyboardEvent(WebInputEvent::RawKeyDown); | 678 SimulateKeyboardEvent(WebInputEvent::RawKeyDown); |
658 | 679 |
659 // Make sure we sent the input event to the renderer. | 680 // Make sure we sent the input event to the renderer. |
660 EXPECT_TRUE(process_->sink().GetUniqueMessageMatching( | 681 EXPECT_TRUE(process_->sink().GetUniqueMessageMatching( |
661 ViewMsg_HandleInputEvent::ID)); | 682 ViewMsg_HandleInputEvent::ID)); |
662 process_->sink().ClearMessages(); | 683 process_->sink().ClearMessages(); |
663 | 684 |
664 // Send the simulated response from the renderer back. | 685 // Send the simulated response from the renderer back. |
665 SendInputEventACK(WebInputEvent::RawKeyDown, true); | 686 SendInputEventACK(WebInputEvent::RawKeyDown, true); |
666 EXPECT_FALSE(host_->unhandled_keyboard_event_called()); | 687 EXPECT_FALSE(delegate_->unhandled_keyboard_event_called()); |
667 } | 688 } |
668 | 689 |
669 TEST_F(RenderWidgetHostTest, PreHandleRawKeyDownEvent) { | 690 TEST_F(RenderWidgetHostTest, PreHandleRawKeyDownEvent) { |
670 // Simluate the situation that the browser handled the key down event during | 691 // Simluate the situation that the browser handled the key down event during |
671 // pre-handle phrase. | 692 // pre-handle phrase. |
672 host_->set_prehandle_keyboard_event(true); | 693 delegate_->set_prehandle_keyboard_event(true); |
673 process_->sink().ClearMessages(); | 694 process_->sink().ClearMessages(); |
674 | 695 |
675 // Simulate a keyboard event. | 696 // Simulate a keyboard event. |
676 SimulateKeyboardEvent(WebInputEvent::RawKeyDown); | 697 SimulateKeyboardEvent(WebInputEvent::RawKeyDown); |
677 | 698 |
678 EXPECT_TRUE(host_->prehandle_keyboard_event_called()); | 699 EXPECT_TRUE(delegate_->prehandle_keyboard_event_called()); |
679 EXPECT_EQ(WebInputEvent::RawKeyDown, host_->prehandle_keyboard_event_type()); | 700 EXPECT_EQ(WebInputEvent::RawKeyDown, |
| 701 delegate_->prehandle_keyboard_event_type()); |
680 | 702 |
681 // Make sure the RawKeyDown event is not sent to the renderer. | 703 // Make sure the RawKeyDown event is not sent to the renderer. |
682 EXPECT_EQ(0U, process_->sink().message_count()); | 704 EXPECT_EQ(0U, process_->sink().message_count()); |
683 | 705 |
684 // The browser won't pre-handle a Char event. | 706 // The browser won't pre-handle a Char event. |
685 host_->set_prehandle_keyboard_event(false); | 707 delegate_->set_prehandle_keyboard_event(false); |
686 | 708 |
687 // Forward the Char event. | 709 // Forward the Char event. |
688 SimulateKeyboardEvent(WebInputEvent::Char); | 710 SimulateKeyboardEvent(WebInputEvent::Char); |
689 | 711 |
690 // Make sure the Char event is suppressed. | 712 // Make sure the Char event is suppressed. |
691 EXPECT_EQ(0U, process_->sink().message_count()); | 713 EXPECT_EQ(0U, process_->sink().message_count()); |
692 | 714 |
693 // Forward the KeyUp event. | 715 // Forward the KeyUp event. |
694 SimulateKeyboardEvent(WebInputEvent::KeyUp); | 716 SimulateKeyboardEvent(WebInputEvent::KeyUp); |
695 | 717 |
696 // Make sure only KeyUp was sent to the renderer. | 718 // Make sure only KeyUp was sent to the renderer. |
697 EXPECT_EQ(1U, process_->sink().message_count()); | 719 EXPECT_EQ(1U, process_->sink().message_count()); |
698 EXPECT_EQ(ViewMsg_HandleInputEvent::ID, | 720 EXPECT_EQ(ViewMsg_HandleInputEvent::ID, |
699 process_->sink().GetMessageAt(0)->type()); | 721 process_->sink().GetMessageAt(0)->type()); |
700 process_->sink().ClearMessages(); | 722 process_->sink().ClearMessages(); |
701 | 723 |
702 // Send the simulated response from the renderer back. | 724 // Send the simulated response from the renderer back. |
703 SendInputEventACK(WebInputEvent::KeyUp, false); | 725 SendInputEventACK(WebInputEvent::KeyUp, false); |
704 | 726 |
705 EXPECT_TRUE(host_->unhandled_keyboard_event_called()); | 727 EXPECT_TRUE(delegate_->unhandled_keyboard_event_called()); |
706 EXPECT_EQ(WebInputEvent::KeyUp, host_->unhandled_keyboard_event_type()); | 728 EXPECT_EQ(WebInputEvent::KeyUp, delegate_->unhandled_keyboard_event_type()); |
707 } | 729 } |
708 | 730 |
709 TEST_F(RenderWidgetHostTest, CoalescesWheelEvents) { | 731 TEST_F(RenderWidgetHostTest, CoalescesWheelEvents) { |
710 process_->sink().ClearMessages(); | 732 process_->sink().ClearMessages(); |
711 | 733 |
712 // Simulate wheel events. | 734 // Simulate wheel events. |
713 SimulateWheelEvent(0, -5, 0); // sent directly | 735 SimulateWheelEvent(0, -5, 0); // sent directly |
714 SimulateWheelEvent(0, -10, 0); // enqueued | 736 SimulateWheelEvent(0, -10, 0); // enqueued |
715 SimulateWheelEvent(8, -6, 0); // coalesced into previous event | 737 SimulateWheelEvent(8, -6, 0); // coalesced into previous event |
716 SimulateWheelEvent(9, -7, 1); // enqueued, different modifiers | 738 SimulateWheelEvent(9, -7, 1); // enqueued, different modifiers |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
793 SimulateKeyboardEvent(WebInputEvent::RawKeyDown); | 815 SimulateKeyboardEvent(WebInputEvent::RawKeyDown); |
794 SimulateKeyboardEvent(WebInputEvent::RawKeyDown); | 816 SimulateKeyboardEvent(WebInputEvent::RawKeyDown); |
795 SendInputEventACK(WebInputEvent::RawKeyDown, true); | 817 SendInputEventACK(WebInputEvent::RawKeyDown, true); |
796 | 818 |
797 // Wait long enough for first timeout and see if it fired. | 819 // Wait long enough for first timeout and see if it fired. |
798 MessageLoop::current()->PostDelayedTask( | 820 MessageLoop::current()->PostDelayedTask( |
799 FROM_HERE, MessageLoop::QuitClosure(), TimeDelta::FromMilliseconds(40)); | 821 FROM_HERE, MessageLoop::QuitClosure(), TimeDelta::FromMilliseconds(40)); |
800 MessageLoop::current()->Run(); | 822 MessageLoop::current()->Run(); |
801 EXPECT_TRUE(host_->unresponsive_timer_fired()); | 823 EXPECT_TRUE(host_->unresponsive_timer_fired()); |
802 } | 824 } |
OLD | NEW |