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 "content/public/test/render_view_test.h" | 5 #include "content/public/test/render_view_test.h" |
6 | 6 |
| 7 #include <cctype> |
| 8 |
7 #include "base/run_loop.h" | 9 #include "base/run_loop.h" |
8 #include "content/common/dom_storage/dom_storage_types.h" | 10 #include "content/common/dom_storage/dom_storage_types.h" |
9 #include "content/common/frame_messages.h" | 11 #include "content/common/frame_messages.h" |
10 #include "content/common/input_messages.h" | 12 #include "content/common/input_messages.h" |
11 #include "content/common/view_messages.h" | 13 #include "content/common/view_messages.h" |
12 #include "content/public/browser/content_browser_client.h" | 14 #include "content/public/browser/content_browser_client.h" |
13 #include "content/public/browser/native_web_keyboard_event.h" | 15 #include "content/public/browser/native_web_keyboard_event.h" |
14 #include "content/public/common/content_client.h" | 16 #include "content/public/common/content_client.h" |
15 #include "content/public/common/renderer_preferences.h" | 17 #include "content/public/common/renderer_preferences.h" |
16 #include "content/public/renderer/content_renderer_client.h" | 18 #include "content/public/renderer/content_renderer_client.h" |
17 #include "content/public/test/frame_load_waiter.h" | 19 #include "content/public/test/frame_load_waiter.h" |
18 #include "content/renderer/history_controller.h" | 20 #include "content/renderer/history_controller.h" |
19 #include "content/renderer/history_serialization.h" | 21 #include "content/renderer/history_serialization.h" |
20 #include "content/renderer/render_thread_impl.h" | 22 #include "content/renderer/render_thread_impl.h" |
21 #include "content/renderer/render_view_impl.h" | 23 #include "content/renderer/render_view_impl.h" |
22 #include "content/renderer/renderer_blink_platform_impl.h" | 24 #include "content/renderer/renderer_blink_platform_impl.h" |
23 #include "content/renderer/renderer_main_platform_delegate.h" | 25 #include "content/renderer/renderer_main_platform_delegate.h" |
24 #include "content/renderer/scheduler/renderer_scheduler.h" | 26 #include "content/renderer/scheduler/renderer_scheduler.h" |
25 #include "content/test/fake_compositor_dependencies.h" | 27 #include "content/test/fake_compositor_dependencies.h" |
| 28 #include "content/test/mock_keyboard.h" |
26 #include "content/test/mock_render_process.h" | 29 #include "content/test/mock_render_process.h" |
27 #include "content/test/test_content_client.h" | 30 #include "content/test/test_content_client.h" |
28 #include "third_party/WebKit/public/platform/WebScreenInfo.h" | 31 #include "third_party/WebKit/public/platform/WebScreenInfo.h" |
29 #include "third_party/WebKit/public/platform/WebURLRequest.h" | 32 #include "third_party/WebKit/public/platform/WebURLRequest.h" |
| 33 #include "third_party/WebKit/public/web/WebDocument.h" |
30 #include "third_party/WebKit/public/web/WebHistoryItem.h" | 34 #include "third_party/WebKit/public/web/WebHistoryItem.h" |
31 #include "third_party/WebKit/public/web/WebInputEvent.h" | 35 #include "third_party/WebKit/public/web/WebInputEvent.h" |
32 #include "third_party/WebKit/public/web/WebKit.h" | 36 #include "third_party/WebKit/public/web/WebKit.h" |
33 #include "third_party/WebKit/public/web/WebLocalFrame.h" | 37 #include "third_party/WebKit/public/web/WebLocalFrame.h" |
34 #include "third_party/WebKit/public/web/WebScriptSource.h" | 38 #include "third_party/WebKit/public/web/WebScriptSource.h" |
35 #include "third_party/WebKit/public/web/WebView.h" | 39 #include "third_party/WebKit/public/web/WebView.h" |
36 #include "ui/base/resource/resource_bundle.h" | 40 #include "ui/base/resource/resource_bundle.h" |
| 41 #include "ui/events/event.h" |
| 42 #include "ui/events/keycodes/keyboard_codes.h" |
37 #include "v8/include/v8.h" | 43 #include "v8/include/v8.h" |
38 | 44 |
39 #if defined(OS_MACOSX) | 45 #if defined(OS_MACOSX) |
40 #include "base/mac/scoped_nsautorelease_pool.h" | 46 #include "base/mac/scoped_nsautorelease_pool.h" |
41 #endif | 47 #endif |
42 | 48 |
| 49 #if defined(USE_AURA) && defined(USE_X11) |
| 50 #include <X11/Xlib.h> |
| 51 #include "ui/events/event_constants.h" |
| 52 #include "ui/events/keycodes/keyboard_code_conversion.h" |
| 53 #include "ui/events/test/events_test_utils.h" |
| 54 #include "ui/events/test/events_test_utils_x11.h" |
| 55 #endif |
| 56 |
| 57 #if defined(USE_OZONE) |
| 58 #include "ui/events/keycodes/keyboard_code_conversion.h" |
| 59 #endif |
| 60 |
43 using blink::WebGestureEvent; | 61 using blink::WebGestureEvent; |
44 using blink::WebInputEvent; | 62 using blink::WebInputEvent; |
45 using blink::WebLocalFrame; | 63 using blink::WebLocalFrame; |
46 using blink::WebMouseEvent; | 64 using blink::WebMouseEvent; |
47 using blink::WebScriptSource; | 65 using blink::WebScriptSource; |
48 using blink::WebString; | 66 using blink::WebString; |
49 using blink::WebURLRequest; | 67 using blink::WebURLRequest; |
50 | 68 |
51 namespace { | 69 namespace { |
| 70 |
52 const int32 kOpenerId = -2; | 71 const int32 kOpenerId = -2; |
53 const int32 kRouteId = 5; | 72 const int32 kRouteId = 5; |
54 const int32 kMainFrameRouteId = 6; | 73 const int32 kMainFrameRouteId = 6; |
55 const int32 kNewWindowRouteId = 7; | 74 const int32 kNewWindowRouteId = 7; |
56 const int32 kNewFrameRouteId = 10; | 75 const int32 kNewFrameRouteId = 10; |
57 const int32 kSurfaceId = 42; | 76 const int32 kSurfaceId = 42; |
58 | 77 |
| 78 #if (defined(USE_AURA) && defined(USE_X11)) || defined(USE_OZONE) |
| 79 // Converts MockKeyboard::Modifiers to ui::EventFlags. |
| 80 int ConvertMockKeyboardModifier(content::MockKeyboard::Modifiers modifiers) { |
| 81 static struct ModifierMap { |
| 82 content::MockKeyboard::Modifiers src; |
| 83 int dst; |
| 84 } kModifierMap[] = { |
| 85 { content::MockKeyboard::LEFT_SHIFT, ui::EF_SHIFT_DOWN }, |
| 86 { content::MockKeyboard::RIGHT_SHIFT, ui::EF_SHIFT_DOWN }, |
| 87 { content::MockKeyboard::LEFT_CONTROL, ui::EF_CONTROL_DOWN }, |
| 88 { content::MockKeyboard::RIGHT_CONTROL, ui::EF_CONTROL_DOWN }, |
| 89 { content::MockKeyboard::LEFT_ALT, ui::EF_ALT_DOWN }, |
| 90 { content::MockKeyboard::RIGHT_ALT, ui::EF_ALT_DOWN }, |
| 91 }; |
| 92 int flags = 0; |
| 93 for (size_t i = 0; i < arraysize(kModifierMap); ++i) { |
| 94 if (kModifierMap[i].src & modifiers) { |
| 95 flags |= kModifierMap[i].dst; |
| 96 } |
| 97 } |
| 98 return flags; |
| 99 } |
| 100 #endif |
| 101 |
59 } // namespace | 102 } // namespace |
60 | 103 |
61 namespace content { | 104 namespace content { |
62 | 105 |
63 class RendererBlinkPlatformImplNoSandboxImpl | 106 class RendererBlinkPlatformImplNoSandboxImpl |
64 : public RendererBlinkPlatformImpl { | 107 : public RendererBlinkPlatformImpl { |
65 public: | 108 public: |
66 RendererBlinkPlatformImplNoSandboxImpl(RendererScheduler* scheduler) | 109 RendererBlinkPlatformImplNoSandboxImpl(RendererScheduler* scheduler) |
67 : RendererBlinkPlatformImpl(scheduler) {} | 110 : RendererBlinkPlatformImpl(scheduler) {} |
68 | 111 |
(...skipping 318 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
387 params.physical_backing_size = new_size; | 430 params.physical_backing_size = new_size; |
388 params.top_controls_height = 0.f; | 431 params.top_controls_height = 0.f; |
389 params.top_controls_shrink_blink_size = false; | 432 params.top_controls_shrink_blink_size = false; |
390 params.resizer_rect = resizer_rect; | 433 params.resizer_rect = resizer_rect; |
391 params.is_fullscreen_granted = is_fullscreen_granted; | 434 params.is_fullscreen_granted = is_fullscreen_granted; |
392 params.display_mode = blink::WebDisplayModeBrowser; | 435 params.display_mode = blink::WebDisplayModeBrowser; |
393 scoped_ptr<IPC::Message> resize_message(new ViewMsg_Resize(0, params)); | 436 scoped_ptr<IPC::Message> resize_message(new ViewMsg_Resize(0, params)); |
394 OnMessageReceived(*resize_message); | 437 OnMessageReceived(*resize_message); |
395 } | 438 } |
396 | 439 |
| 440 int RenderViewTest::SendKeyEvent(const MockKeyboard& keyboard, |
| 441 int key_code, |
| 442 base::string16* output) { |
| 443 #if defined(OS_WIN) |
| 444 // Retrieve the Unicode character for the given tuple (keyboard-layout, |
| 445 // key-code, and modifiers). |
| 446 // Exit when a keyboard-layout driver cannot assign a Unicode character to |
| 447 // the tuple to prevent sending an invalid key code to the RenderView |
| 448 // object. |
| 449 CHECK(output); |
| 450 int length = keyboard.GetCharacters(key_code, output); |
| 451 if (length != 1) |
| 452 return -1; |
| 453 |
| 454 // Create IPC messages from Windows messages and send them to our |
| 455 // back-end. |
| 456 // A keyboard event of Windows consists of three Windows messages: |
| 457 // WM_KEYDOWN, WM_CHAR, and WM_KEYUP. |
| 458 // WM_KEYDOWN and WM_KEYUP sends virtual-key codes. On the other hand, |
| 459 // WM_CHAR sends a composed Unicode character. |
| 460 MSG msg1 = {NULL, WM_KEYDOWN, key_code, 0}; |
| 461 ui::KeyEvent evt1(msg1); |
| 462 NativeWebKeyboardEvent keydown_event(evt1); |
| 463 SendNativeKeyEvent(keydown_event); |
| 464 |
| 465 MSG msg2 = {NULL, WM_CHAR, (*output)[0], 0}; |
| 466 ui::KeyEvent evt2(msg2); |
| 467 NativeWebKeyboardEvent char_event(evt2); |
| 468 SendNativeKeyEvent(char_event); |
| 469 |
| 470 MSG msg3 = {NULL, WM_KEYUP, key_code, 0}; |
| 471 ui::KeyEvent evt3(msg3); |
| 472 NativeWebKeyboardEvent keyup_event(evt3); |
| 473 SendNativeKeyEvent(keyup_event); |
| 474 |
| 475 return length; |
| 476 #elif defined(USE_AURA) && defined(USE_X11) |
| 477 // We ignore |layout|, which means we are only testing the layout of the |
| 478 // current locale. TODO(mazda): fix this to respect |layout|. |
| 479 CHECK(output); |
| 480 const int flags = ConvertMockKeyboardModifier(keyboard.modifiers()); |
| 481 |
| 482 ui::ScopedXI2Event xevent; |
| 483 xevent.InitKeyEvent(ui::ET_KEY_PRESSED, |
| 484 static_cast<ui::KeyboardCode>(key_code), flags); |
| 485 ui::KeyEvent event1(xevent); |
| 486 NativeWebKeyboardEvent keydown_event(event1); |
| 487 SendNativeKeyEvent(keydown_event); |
| 488 |
| 489 // X11 doesn't actually have native character events, but give the test |
| 490 // what it wants. |
| 491 xevent.InitKeyEvent(ui::ET_KEY_PRESSED, |
| 492 static_cast<ui::KeyboardCode>(key_code), flags); |
| 493 ui::KeyEvent event2(xevent); |
| 494 event2.set_character( |
| 495 GetCharacterFromKeyCode(event2.key_code(), event2.flags())); |
| 496 ui::KeyEventTestApi test_event2(&event2); |
| 497 test_event2.set_is_char(true); |
| 498 NativeWebKeyboardEvent char_event(event2); |
| 499 SendNativeKeyEvent(char_event); |
| 500 |
| 501 xevent.InitKeyEvent(ui::ET_KEY_RELEASED, |
| 502 static_cast<ui::KeyboardCode>(key_code), flags); |
| 503 ui::KeyEvent event3(xevent); |
| 504 NativeWebKeyboardEvent keyup_event(event3); |
| 505 SendNativeKeyEvent(keyup_event); |
| 506 |
| 507 long c = |
| 508 GetCharacterFromKeyCode(static_cast<ui::KeyboardCode>(key_code), flags); |
| 509 output->assign(1, static_cast<base::char16>(c)); |
| 510 return 1; |
| 511 #elif defined(USE_OZONE) |
| 512 const int flags = ConvertMockKeyboardModifier(keyboard.modifiers()); |
| 513 |
| 514 ui::KeyEvent keydown_event(ui::ET_KEY_PRESSED, |
| 515 static_cast<ui::KeyboardCode>(key_code), flags); |
| 516 NativeWebKeyboardEvent keydown_web_event(keydown_event); |
| 517 SendNativeKeyEvent(keydown_web_event); |
| 518 |
| 519 ui::KeyEvent char_event(keydown_event.GetCharacter(), |
| 520 static_cast<ui::KeyboardCode>(key_code), flags); |
| 521 NativeWebKeyboardEvent char_web_event(char_event); |
| 522 SendNativeKeyEvent(char_web_event); |
| 523 |
| 524 ui::KeyEvent keyup_event(ui::ET_KEY_RELEASED, |
| 525 static_cast<ui::KeyboardCode>(key_code), flags); |
| 526 NativeWebKeyboardEvent keyup_web_event(keyup_event); |
| 527 SendNativeKeyEvent(keyup_web_event); |
| 528 |
| 529 long c = |
| 530 GetCharacterFromKeyCode(static_cast<ui::KeyboardCode>(key_code), flags); |
| 531 output->assign(1, static_cast<base::char16>(c)); |
| 532 return 1; |
| 533 #else |
| 534 NOTIMPLEMENTED(); |
| 535 return L'\0'; |
| 536 #endif |
| 537 } |
| 538 |
| 539 void RenderViewTest::SimulateUserTypingASCIICharacter(char ascii_character) { |
| 540 int key_code = ascii_character; |
| 541 bool is_shift_pressed = false; |
| 542 |
| 543 if (isalnum(ascii_character)) { |
| 544 key_code = base::ToUpperASCII(ascii_character); |
| 545 is_shift_pressed = isupper(ascii_character); |
| 546 } else if (ascii_character == '@') { |
| 547 key_code = '2'; |
| 548 is_shift_pressed = true; |
| 549 } else if (ascii_character == '.') { |
| 550 key_code = ui::VKEY_OEM_PERIOD; |
| 551 } else if (ascii_character == '_') { |
| 552 key_code = ui::VKEY_OEM_MINUS; |
| 553 is_shift_pressed = true; |
| 554 } else { |
| 555 NOTREACHED(); |
| 556 } |
| 557 |
| 558 SimulateUserTypingKeyCodeWithShift(key_code, is_shift_pressed); |
| 559 } |
| 560 |
| 561 void RenderViewTest::SimulateUserTypingKeyCodeWithShift(int key_code, |
| 562 bool is_shift_pressed) { |
| 563 base::string16 unused_char_code; |
| 564 content::MockKeyboard keyboard; |
| 565 EXPECT_TRUE(keyboard.Update( |
| 566 content::MockKeyboard::LAYOUT_UNITED_STATES, |
| 567 is_shift_pressed ? content::MockKeyboard::LEFT_SHIFT |
| 568 : content::MockKeyboard::NONE)); |
| 569 SendKeyEvent(keyboard, key_code, &unused_char_code); |
| 570 } |
| 571 |
| 572 void RenderViewTest::SimulateUserInputChangeForElement( |
| 573 blink::WebInputElement* input, |
| 574 blink::WebFrame* input_frame, |
| 575 const std::string& new_value) { |
| 576 while (!input->focused()) |
| 577 input_frame->document().frame()->view()->advanceFocus(false); |
| 578 |
| 579 size_t previous_length = input->value().length(); |
| 580 for (size_t i = 0; i < previous_length; ++i) |
| 581 SimulateUserTypingKeyCodeWithShift(ui::VKEY_BACK, false); |
| 582 |
| 583 EXPECT_TRUE(input->value().utf8().empty()); |
| 584 ASSERT_TRUE(base::IsStringASCII(new_value)); |
| 585 for (size_t i = 0; i < new_value.size(); ++i) |
| 586 SimulateUserTypingASCIICharacter(new_value[i]); |
| 587 |
| 588 // Compare only beginning, because autocomplete may have filled out the |
| 589 // form. |
| 590 EXPECT_EQ(new_value, input->value().utf8().substr(0, new_value.length())); |
| 591 } |
| 592 |
397 bool RenderViewTest::OnMessageReceived(const IPC::Message& msg) { | 593 bool RenderViewTest::OnMessageReceived(const IPC::Message& msg) { |
398 RenderViewImpl* impl = static_cast<RenderViewImpl*>(view_); | 594 RenderViewImpl* impl = static_cast<RenderViewImpl*>(view_); |
399 return impl->OnMessageReceived(msg); | 595 return impl->OnMessageReceived(msg); |
400 } | 596 } |
401 | 597 |
402 void RenderViewTest::DidNavigateWithinPage(blink::WebLocalFrame* frame, | 598 void RenderViewTest::DidNavigateWithinPage(blink::WebLocalFrame* frame, |
403 bool is_new_navigation) { | 599 bool is_new_navigation) { |
404 RenderViewImpl* impl = static_cast<RenderViewImpl*>(view_); | 600 RenderViewImpl* impl = static_cast<RenderViewImpl*>(view_); |
405 blink::WebHistoryItem item; | 601 blink::WebHistoryItem item; |
406 item.initialize(); | 602 item.initialize(); |
407 impl->GetMainRenderFrame()->didNavigateWithinPage( | 603 impl->GetMainRenderFrame()->didNavigateWithinPage( |
408 frame, | 604 frame, |
409 item, | 605 item, |
410 is_new_navigation ? blink::WebStandardCommit | 606 is_new_navigation ? blink::WebStandardCommit |
411 : blink::WebHistoryInertCommit); | 607 : blink::WebHistoryInertCommit); |
412 } | 608 } |
413 | 609 |
414 void RenderViewTest::SendContentStateImmediately() { | 610 void RenderViewTest::SendContentStateImmediately() { |
415 RenderViewImpl* impl = static_cast<RenderViewImpl*>(view_); | 611 RenderViewImpl* impl = static_cast<RenderViewImpl*>(view_); |
416 impl->set_send_content_state_immediately(true); | 612 impl->set_send_content_state_immediately(true); |
417 } | 613 } |
418 | 614 |
419 blink::WebWidget* RenderViewTest::GetWebWidget() { | 615 blink::WebWidget* RenderViewTest::GetWebWidget() { |
420 RenderViewImpl* impl = static_cast<RenderViewImpl*>(view_); | 616 RenderViewImpl* impl = static_cast<RenderViewImpl*>(view_); |
421 return impl->webwidget(); | 617 return impl->webwidget(); |
422 } | 618 } |
423 | 619 |
424 | |
425 ContentClient* RenderViewTest::CreateContentClient() { | 620 ContentClient* RenderViewTest::CreateContentClient() { |
426 return new TestContentClient; | 621 return new TestContentClient; |
427 } | 622 } |
428 | 623 |
429 ContentBrowserClient* RenderViewTest::CreateContentBrowserClient() { | 624 ContentBrowserClient* RenderViewTest::CreateContentBrowserClient() { |
430 return new ContentBrowserClient; | 625 return new ContentBrowserClient; |
431 } | 626 } |
432 | 627 |
433 ContentRendererClient* RenderViewTest::CreateContentRendererClient() { | 628 ContentRendererClient* RenderViewTest::CreateContentRendererClient() { |
434 return new ContentRendererClient; | 629 return new ContentRendererClient; |
(...skipping 23 matching lines...) Expand all Loading... |
458 | 653 |
459 impl->GetMainRenderFrame()->OnNavigate(common_params, StartNavigationParams(), | 654 impl->GetMainRenderFrame()->OnNavigate(common_params, StartNavigationParams(), |
460 request_params); | 655 request_params); |
461 | 656 |
462 // The load actually happens asynchronously, so we pump messages to process | 657 // The load actually happens asynchronously, so we pump messages to process |
463 // the pending continuation. | 658 // the pending continuation. |
464 FrameLoadWaiter(view_->GetMainRenderFrame()).Wait(); | 659 FrameLoadWaiter(view_->GetMainRenderFrame()).Wait(); |
465 } | 660 } |
466 | 661 |
467 } // namespace content | 662 } // namespace content |
OLD | NEW |