// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// This functionality currently works on Windows and on Linux when
// toolkit_views is defined (i.e. for Chrome OS). It's not needed
// on the Mac, and it's not yet implemented on Linux.

#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 {

// An async version of SendKeyPressSync since we don't get notified when a
// menu is showing.
void SendKeyPress(Browser* browser, ui::KeyboardCode key) {
  ASSERT_TRUE(ui_controls::SendKeyPress(
      browser->window()->GetNativeWindow(), key, false, false, false, false));
}

// Helper class that waits until the focus has changed to a view other
// than the one with the provided view id.
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);
    // Call the focus change notification once in case the focus has
    // already changed.
    OnWillChangeFocus(NULL, focus_manager_->GetFocusedView());
  }

  virtual ~ViewFocusChangeWaiter() {
    focus_manager_->RemoveFocusChangeListener(this);
  }

  void Wait() {
    content::RunMessageLoop();
  }

 private:
  // Inherited from FocusChangeListener
  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:
  // Overridden from views::MenuListener:
  virtual void OnMenuOpened() OVERRIDE {
    menu_open_count_++;
    if (!test_dismiss_menu_) {
      toolbar_view_->RemoveMenuListener(this);
      // Press DOWN to select the first item, then RETURN to select it.
      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_;
  // Keeps track of the number of times the menu was opened.
  int menu_open_count_;
  // If this is set then on receiving a notification that the menu was opened
  // we dismiss it by sending the ESC key.
  bool test_dismiss_menu_;

  DISALLOW_COPY_AND_ASSIGN(SendKeysMenuListener);
};

class KeyboardAccessTest : public InProcessBrowserTest {
 public:
  KeyboardAccessTest() {}

  // Use the keyboard to select "New Tab" from the app menu.
  // This test depends on the fact that there is one menu and that
  // New Tab is the first item in the menu. If the menus change,
  // this test will need to be changed to reflect that.
  //
  // If alternate_key_sequence is true, use "Alt" instead of "F10" to
  // open the menu bar, and "Down" instead of "Enter" to open a menu.
  // If focus_omnibox is true then the test on startup sets focus to the
  // omnibox.
  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)
  // Opens the system menu on Windows with the Alt Space combination and selects
  // the New Tab option from the menu.
  void TestSystemMenuWithKeyboard();
#endif

#if defined(USE_AURA)
  // Uses the keyboard to select the wrench menu i.e. with the F10 key.
  // It verifies that the menu when dismissed by sending the ESC key it does
  // not display twice.
  void TestMenuKeyboardAccessAndDismiss();
#endif

  DISALLOW_COPY_AND_ASSIGN(KeyboardAccessTest);
};

void KeyboardAccessTest::TestMenuKeyboardAccess(bool alternate_key_sequence,
                                                bool shift,
                                                bool focus_omnibox) {
  // Navigate to a page in the first tab, which makes sure that focus is
  // set to the browser window.
  ui_test_utils::NavigateToURL(browser(), GURL("about:"));

  // The initial tab index should be 0.
  ASSERT_EQ(0, browser()->tab_strip_model()->active_index());

  ASSERT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser()));

  // Get the focused view ID, then press a key to activate the
  // page menu, then wait until the focused view changes.
  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)
  // Chrome OS doesn't have a way to just focus the wrench menu, so we use Alt+F
  // to bring up the menu.
  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) {
    // Verify Chrome does not move the view focus. We should not move the view
    // focus when typing a menu key with modifier keys, such as shift keys or
    // control keys.
    int new_view_id = GetFocusedViewID();
    ASSERT_EQ(original_view_id, new_view_id);
    return;
  }

  WaitForFocusedViewIDToChange(original_view_id);

  // See above comment. Since we already brought up the menu, no need to do this
  // on ChromeOS.
#if !defined(OS_CHROMEOS)
  if (alternate_key_sequence)
    SendKeyPress(browser(), ui::VKEY_DOWN);
  else
    SendKeyPress(browser(), ui::VKEY_RETURN);
#endif

  // Wait for the new tab to appear.
  new_tab_observer.Wait();

  // Make sure that the new tab index is 1.
  ASSERT_EQ(1, browser()->tab_strip_model()->active_index());
}

#if defined(OS_WIN)

// This CBT hook is set for the duration of the TestSystemMenuWithKeyboard test
LRESULT CALLBACK SystemMenuTestCBTHook(int n_code,
                                       WPARAM w_param,
                                       LPARAM l_param) {
  // Look for the system menu window getting created or becoming visible and
  // then select the New Tab option from the menu.
  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")) {
      // Select the New Tab option and then send the enter key to execute it.
      ::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() {
  // Navigate to a page in the first tab, which makes sure that focus is
  // set to the browser window.
  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()));
  // Sending the Alt space keys to the browser will bring up the system menu
  // which runs a model loop. We set a CBT hook to look for the menu and send
  // keystrokes to it.
  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) {
    // Wait for the new tab to appear.
    new_tab_observer.Wait();
    // Make sure that the new tab index is 1.
    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

// http://crbug.com/62310.
#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);
}

// http://crbug.com/62310.
#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 this flakes, use http://crbug.com/62311.
#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) && !defined(USE_AURA)
IN_PROC_BROWSER_TEST_F(KeyboardAccessTest,
                       TestAltMenuKeyboardAccessFocusOmnibox) {
  TestMenuKeyboardAccess(true, false, true);
}

IN_PROC_BROWSER_TEST_F(KeyboardAccessTest, TestSystemMenuWithKeyboard) {
  TestSystemMenuWithKeyboard();
}
#endif

#if !defined(OS_WIN) && defined(USE_AURA)
IN_PROC_BROWSER_TEST_F(KeyboardAccessTest, TestMenuKeyboardOpenDismiss) {
  TestMenuKeyboardAccessAndDismiss();
}
#endif

// Test that JavaScript cannot intercept reserved keyboard accelerators like
// ctrl-t to open a new tab or ctrl-f4 to close a tab.
// TODO(isherman): This test times out on ChromeOS.  We should merge it with
// BrowserKeyEventsTest.ReservedAccelerators, but just disable for now.
// If this flakes, use http://crbug.com/62311.
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)  // These keys are Windows-only.
IN_PROC_BROWSER_TEST_F(KeyboardAccessTest, BackForwardKeys) {
  // Navigate to create some history.
  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));

  // Navigate 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);

  // And then forward.
  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

}  // namespace
