This source file includes following definitions.
- SendKeyPress
- weak_factory_
- Wait
- OnWillChangeFocus
- OnDidChangeFocus
- test_dismiss_menu_
- menu_open_count
- OnMenuOpened
- GetFocusedViewID
- WaitForFocusedViewIDToChange
- TestMenuKeyboardAccess
- SystemMenuTestCBTHook
- TestSystemMenuWithKeyboard
- TestMenuKeyboardAccessAndDismiss
- IN_PROC_BROWSER_TEST_F
- IN_PROC_BROWSER_TEST_F
- IN_PROC_BROWSER_TEST_F
- IN_PROC_BROWSER_TEST_F
- IN_PROC_BROWSER_TEST_F
- IN_PROC_BROWSER_TEST_F
- IN_PROC_BROWSER_TEST_F
- IN_PROC_BROWSER_TEST_F
#include "base/memory/weak_ptr.h"
#include "base/message_loop/message_loop.h"
#include "base/strings/string_util.h"
#include "base/time/time.h"
#include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_window.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/browser/ui/views/frame/browser_view.h"
#include "chrome/browser/ui/views/toolbar/toolbar_view.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/interactive_test_utils.h"
#include "chrome/test/base/ui_test_utils.h"
#include "ui/base/test/ui_controls.h"
#include "ui/events/event_constants.h"
#include "ui/events/keycodes/keyboard_codes.h"
#include "ui/views/controls/menu/menu_listener.h"
#include "ui/views/focus/focus_manager.h"
#include "ui/views/view.h"
#include "ui/views/widget/widget.h"
namespace {
void SendKeyPress(Browser* browser, ui::KeyboardCode key) {
ASSERT_TRUE(ui_controls::SendKeyPress(
browser->window()->GetNativeWindow(), key, false, false, false, false));
}
class ViewFocusChangeWaiter : public views::FocusChangeListener {
public:
ViewFocusChangeWaiter(views::FocusManager* focus_manager,
int previous_view_id)
: focus_manager_(focus_manager),
previous_view_id_(previous_view_id),
weak_factory_(this) {
focus_manager_->AddFocusChangeListener(this);
OnWillChangeFocus(NULL, focus_manager_->GetFocusedView());
}
virtual ~ViewFocusChangeWaiter() {
focus_manager_->RemoveFocusChangeListener(this);
}
void Wait() {
content::RunMessageLoop();
}
private:
virtual void OnWillChangeFocus(views::View* focused_before,
views::View* focused_now) OVERRIDE {
}
virtual void OnDidChangeFocus(views::View* focused_before,
views::View* focused_now) OVERRIDE {
if (focused_now && focused_now->id() != previous_view_id_) {
base::MessageLoop::current()->PostTask(FROM_HERE,
base::MessageLoop::QuitClosure());
}
}
views::FocusManager* focus_manager_;
int previous_view_id_;
base::WeakPtrFactory<ViewFocusChangeWaiter> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(ViewFocusChangeWaiter);
};
class SendKeysMenuListener : public views::MenuListener {
public:
SendKeysMenuListener(ToolbarView* toolbar_view,
Browser* browser,
bool test_dismiss_menu)
: toolbar_view_(toolbar_view), browser_(browser), menu_open_count_(0),
test_dismiss_menu_(test_dismiss_menu) {
toolbar_view_->AddMenuListener(this);
}
virtual ~SendKeysMenuListener() {
if (test_dismiss_menu_)
toolbar_view_->RemoveMenuListener(this);
}
int menu_open_count() const {
return menu_open_count_;
}
private:
virtual void OnMenuOpened() OVERRIDE {
menu_open_count_++;
if (!test_dismiss_menu_) {
toolbar_view_->RemoveMenuListener(this);
SendKeyPress(browser_, ui::VKEY_DOWN);
SendKeyPress(browser_, ui::VKEY_RETURN);
} else {
SendKeyPress(browser_, ui::VKEY_ESCAPE);
base::MessageLoop::current()->PostDelayedTask(
FROM_HERE,
base::MessageLoop::QuitClosure(),
base::TimeDelta::FromMilliseconds(200));
}
}
ToolbarView* toolbar_view_;
Browser* browser_;
int menu_open_count_;
bool test_dismiss_menu_;
DISALLOW_COPY_AND_ASSIGN(SendKeysMenuListener);
};
class KeyboardAccessTest : public InProcessBrowserTest {
public:
KeyboardAccessTest() {}
void TestMenuKeyboardAccess(bool alternate_key_sequence,
bool shift,
bool focus_omnibox);
int GetFocusedViewID() {
gfx::NativeWindow window = browser()->window()->GetNativeWindow();
views::Widget* widget = views::Widget::GetWidgetForNativeWindow(window);
const views::FocusManager* focus_manager = widget->GetFocusManager();
const views::View* focused_view = focus_manager->GetFocusedView();
return focused_view ? focused_view->id() : -1;
}
void WaitForFocusedViewIDToChange(int original_view_id) {
if (GetFocusedViewID() != original_view_id)
return;
gfx::NativeWindow window = browser()->window()->GetNativeWindow();
views::Widget* widget = views::Widget::GetWidgetForNativeWindow(window);
views::FocusManager* focus_manager = widget->GetFocusManager();
ViewFocusChangeWaiter waiter(focus_manager, original_view_id);
waiter.Wait();
}
#if defined(OS_WIN)
void TestSystemMenuWithKeyboard();
#endif
#if defined(USE_AURA)
void TestMenuKeyboardAccessAndDismiss();
#endif
DISALLOW_COPY_AND_ASSIGN(KeyboardAccessTest);
};
void KeyboardAccessTest::TestMenuKeyboardAccess(bool alternate_key_sequence,
bool shift,
bool focus_omnibox) {
ui_test_utils::NavigateToURL(browser(), GURL("about:"));
ASSERT_EQ(0, browser()->tab_strip_model()->active_index());
ASSERT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser()));
int original_view_id = GetFocusedViewID();
content::WindowedNotificationObserver new_tab_observer(
chrome::NOTIFICATION_TAB_ADDED,
content::Source<content::WebContentsDelegate>(browser()));
BrowserView* browser_view = reinterpret_cast<BrowserView*>(
browser()->window());
ToolbarView* toolbar_view = browser_view->GetToolbarView();
SendKeysMenuListener menu_listener(toolbar_view, browser(), false);
if (focus_omnibox)
browser()->window()->GetLocationBar()->FocusLocation(false);
#if defined(OS_CHROMEOS)
ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
browser(), ui::VKEY_F, false, shift, true, false));
#else
ui::KeyboardCode menu_key =
alternate_key_sequence ? ui::VKEY_MENU : ui::VKEY_F10;
ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
browser(), menu_key, false, shift, false, false));
#endif
if (shift) {
int new_view_id = GetFocusedViewID();
ASSERT_EQ(original_view_id, new_view_id);
return;
}
WaitForFocusedViewIDToChange(original_view_id);
#if !defined(OS_CHROMEOS)
if (alternate_key_sequence)
SendKeyPress(browser(), ui::VKEY_DOWN);
else
SendKeyPress(browser(), ui::VKEY_RETURN);
#endif
new_tab_observer.Wait();
ASSERT_EQ(1, browser()->tab_strip_model()->active_index());
}
#if defined(OS_WIN)
LRESULT CALLBACK SystemMenuTestCBTHook(int n_code,
WPARAM w_param,
LPARAM l_param) {
if (n_code == HCBT_ACTIVATE || n_code == HCBT_CREATEWND) {
wchar_t class_name[MAX_PATH] = {0};
GetClassName(reinterpret_cast<HWND>(w_param),
class_name,
arraysize(class_name));
if (LowerCaseEqualsASCII(class_name, "#32768")) {
::PostMessage(reinterpret_cast<HWND>(w_param), WM_CHAR, 'T', 0);
::PostMessage(reinterpret_cast<HWND>(w_param), WM_KEYDOWN, VK_RETURN, 0);
::PostMessage(reinterpret_cast<HWND>(w_param), WM_KEYUP, VK_RETURN, 0);
}
}
return ::CallNextHookEx(0, n_code, w_param, l_param);
}
void KeyboardAccessTest::TestSystemMenuWithKeyboard() {
ui_test_utils::NavigateToURL(browser(), GURL("about:"));
ASSERT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser()));
content::WindowedNotificationObserver new_tab_observer(
chrome::NOTIFICATION_TAB_ADDED,
content::Source<content::WebContentsDelegate>(browser()));
HHOOK cbt_hook = ::SetWindowsHookEx(WH_CBT,
SystemMenuTestCBTHook,
NULL,
::GetCurrentThreadId());
ASSERT_TRUE(cbt_hook != NULL);
bool ret = ui_test_utils::SendKeyPressSync(
browser(), ui::VKEY_SPACE, false, false, true, false);
EXPECT_TRUE(ret);
if (ret) {
new_tab_observer.Wait();
ASSERT_EQ(1, browser()->tab_strip_model()->active_index());
}
::UnhookWindowsHookEx(cbt_hook);
}
#endif
#if defined(USE_AURA)
void KeyboardAccessTest::TestMenuKeyboardAccessAndDismiss() {
ui_test_utils::NavigateToURL(browser(), GURL("about:"));
ASSERT_EQ(0, browser()->tab_strip_model()->active_index());
ASSERT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser()));
int original_view_id = GetFocusedViewID();
BrowserView* browser_view = reinterpret_cast<BrowserView*>(
browser()->window());
ToolbarView* toolbar_view = browser_view->GetToolbarView();
SendKeysMenuListener menu_listener(toolbar_view, browser(), true);
browser()->window()->GetLocationBar()->FocusLocation(false);
ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
browser(), ui::VKEY_F10, false, false, false, false));
WaitForFocusedViewIDToChange(original_view_id);
SendKeyPress(browser(), ui::VKEY_DOWN);
content::RunMessageLoop();
ASSERT_EQ(1, menu_listener.menu_open_count());
}
#endif
#if defined(OS_CHROMEOS)
#define MAYBE_TestMenuKeyboardAccess DISABLED_TestMenuKeyboardAccess
#else
#define MAYBE_TestMenuKeyboardAccess TestMenuKeyboardAccess
#endif
IN_PROC_BROWSER_TEST_F(KeyboardAccessTest, MAYBE_TestMenuKeyboardAccess) {
TestMenuKeyboardAccess(false, false, false);
}
#if defined(OS_CHROMEOS)
#define MAYBE_TestAltMenuKeyboardAccess DISABLED_TestAltMenuKeyboardAccess
#else
#define MAYBE_TestAltMenuKeyboardAccess TestAltMenuKeyboardAccess
#endif
IN_PROC_BROWSER_TEST_F(KeyboardAccessTest, MAYBE_TestAltMenuKeyboardAccess) {
TestMenuKeyboardAccess(true, false, false);
}
#if defined(OS_WIN)
#define MAYBE_TestShiftAltMenuKeyboardAccess DISABLED_TestShiftAltMenuKeyboardAccess
#else
#define MAYBE_TestShiftAltMenuKeyboardAccess TestShiftAltMenuKeyboardAccess
#endif
IN_PROC_BROWSER_TEST_F(KeyboardAccessTest,
MAYBE_TestShiftAltMenuKeyboardAccess) {
TestMenuKeyboardAccess(true, true, false);
}
#if defined(OS_WIN)
IN_PROC_BROWSER_TEST_F(KeyboardAccessTest,
DISABLED_TestAltMenuKeyboardAccessFocusOmnibox) {
TestMenuKeyboardAccess(true, false, true);
}
IN_PROC_BROWSER_TEST_F(KeyboardAccessTest,
DISABLED_TestSystemMenuWithKeyboard) {
TestSystemMenuWithKeyboard();
}
#endif
#if !defined(OS_WIN) && defined(USE_AURA)
IN_PROC_BROWSER_TEST_F(KeyboardAccessTest, TestMenuKeyboardOpenDismiss) {
TestMenuKeyboardAccessAndDismiss();
}
#endif
IN_PROC_BROWSER_TEST_F(KeyboardAccessTest, ReserveKeyboardAccelerators) {
const std::string kBadPage =
"<html><script>"
"document.onkeydown = function() {"
" event.preventDefault();"
" return false;"
"}"
"</script></html>";
GURL url("data:text/html," + kBadPage);
ui_test_utils::NavigateToURLWithDisposition(
browser(), url, NEW_FOREGROUND_TAB,
ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
browser(), ui::VKEY_TAB, true, false, false, false));
ASSERT_EQ(0, browser()->tab_strip_model()->active_index());
ui_test_utils::NavigateToURLWithDisposition(
browser(), url, NEW_FOREGROUND_TAB,
ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
ASSERT_EQ(2, browser()->tab_strip_model()->active_index());
ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
browser(), ui::VKEY_W, true, false, false, false));
ASSERT_EQ(0, browser()->tab_strip_model()->active_index());
}
#if defined(OS_WIN)
IN_PROC_BROWSER_TEST_F(KeyboardAccessTest, BackForwardKeys) {
ui_test_utils::NavigateToURL(browser(), GURL("chrome://version/"));
ui_test_utils::NavigateToURL(browser(), GURL("chrome://about/"));
base::string16 before_back;
ASSERT_TRUE(ui_test_utils::GetCurrentTabTitle(browser(), &before_back));
ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
browser(), ui::VKEY_BROWSER_BACK, false, false, false, false));
base::string16 after_back;
ASSERT_TRUE(ui_test_utils::GetCurrentTabTitle(browser(), &after_back));
EXPECT_NE(before_back, after_back);
ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
browser(), ui::VKEY_BROWSER_FORWARD, false, false, false, false));
base::string16 after_forward;
ASSERT_TRUE(ui_test_utils::GetCurrentTabTitle(browser(), &after_forward));
EXPECT_EQ(before_back, after_forward);
}
#endif
}