// Copyright (c) 2011 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.

#include "build/build_config.h"

#include "base/file_util.h"
#include "base/format_macros.h"
#include "base/message_loop.h"
#include "base/path_service.h"
#include "base/string_number_conversions.h"
#include "base/string_util.h"
#include "base/utf_string_conversions.h"
#include "chrome/browser/tabs/tab_strip_model.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_window.h"
#include "chrome/browser/ui/view_ids.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/url_constants.h"
#include "chrome/test/in_process_browser_test.h"
#include "chrome/test/ui_test_utils.h"
#include "content/browser/renderer_host/render_view_host.h"
#include "content/browser/renderer_host/render_widget_host_view.h"
#include "content/browser/tab_contents/interstitial_page.h"
#include "content/browser/tab_contents/tab_contents.h"
#include "content/browser/tab_contents/tab_contents_view.h"
#include "net/test/test_server.h"

#if defined(TOOLKIT_VIEWS) || defined(OS_WIN)
#include "views/focus/focus_manager.h"
#include "views/view.h"
#include "views/window/window.h"
#endif

#if defined(TOOLKIT_VIEWS)
#include "chrome/browser/ui/views/frame/browser_view.h"
#include "chrome/browser/ui/views/location_bar/location_bar_view.h"
#include "chrome/browser/ui/views/tab_contents/tab_contents_container.h"
#endif

#if defined(TOOLKIT_USES_GTK)
#include "chrome/browser/ui/gtk/view_id_util.h"
#endif

#if defined(OS_WIN)
#include <Psapi.h>
#include <windows.h>
#endif

#if defined(OS_LINUX)
#define MAYBE_FocusTraversal FocusTraversal
#define MAYBE_FocusTraversalOnInterstitial FocusTraversalOnInterstitial
// TODO(jcampan): http://crbug.com/23683
#define MAYBE_TabsRememberFocusFindInPage FAILS_TabsRememberFocusFindInPage
#elif defined(OS_MACOSX)
// TODO(suzhe): http://crbug.com/60973 (following two tests)
#define MAYBE_FocusTraversal DISABLED_FocusTraversal
#define MAYBE_FocusTraversalOnInterstitial DISABLED_FocusTraversalOnInterstitial
// TODO(suzhe): http://crbug.com/49737
#define MAYBE_TabsRememberFocusFindInPage FAILS_TabsRememberFocusFindInPage
#elif defined(OS_WIN)
// Disabled, http://crbug.com/62543.
#define MAYBE_FocusTraversal DISABLED_FocusTraversal
// Disabled, http://crbug.com/62544.
#define MAYBE_FocusTraversalOnInterstitial DISABLED_FocusTraversalOnInterstitial
// Flaky, http://crbug.com/62537.
#define MAYBE_TabsRememberFocusFindInPage FLAKY_TabsRememberFocusFindInPage
#endif

namespace {

// The delay waited in some cases where we don't have a notifications for an
// action we take.
const int kActionDelayMs = 500;

const char kSimplePage[] = "files/focus/page_with_focus.html";
const char kStealFocusPage[] = "files/focus/page_steals_focus.html";
const char kTypicalPage[] = "files/focus/typical_page.html";
const char kTypicalPageName[] = "typical_page.html";

// Test to make sure Chrome is in the foreground as we start testing. This is
// required for tests that synthesize input to the Chrome window.
bool ChromeInForeground() {
#if defined(OS_WIN)
  HWND window = ::GetForegroundWindow();
  std::wstring caption;
  std::wstring filename;
  int len = ::GetWindowTextLength(window) + 1;
  ::GetWindowText(window, WriteInto(&caption, len), len);
  bool chrome_window_in_foreground =
      EndsWith(caption, L" - Google Chrome", true) ||
      EndsWith(caption, L" - Chromium", true);
  if (!chrome_window_in_foreground) {
    DWORD process_id;
    int thread_id = ::GetWindowThreadProcessId(window, &process_id);

    base::ProcessHandle process;
    if (base::OpenProcessHandleWithAccess(process_id,
                                          PROCESS_QUERY_LIMITED_INFORMATION,
                                          &process)) {
      len = MAX_PATH;
      if (!GetProcessImageFileName(process, WriteInto(&filename, len), len)) {
        int error = GetLastError();
        filename = std::wstring(L"Unable to read filename for process id '" +
                                base::IntToString16(process_id) +
                                L"' (error ") +
                                base::IntToString16(error) + L")";
      }
      base::CloseProcessHandle(process);
    }
  }
  EXPECT_TRUE(chrome_window_in_foreground)
      << "Chrome must be in the foreground when running interactive tests\n"
      << "Process in foreground: " << filename.c_str() << "\n"
      << "Window: " << window << "\n"
      << "Caption: " << caption.c_str();
  return chrome_window_in_foreground;
#else
  // Windows only at the moment.
  return true;
#endif
}

class BrowserFocusTest : public InProcessBrowserTest {
 public:
  BrowserFocusTest() {
    set_show_window(true);
    EnableDOMAutomation();
  }

  bool IsViewFocused(ViewID vid) {
    return ui_test_utils::IsViewFocused(browser(), vid);
  }

  void ClickOnView(ViewID vid) {
    ui_test_utils::ClickOnView(browser(), vid);
  }
};

class TestInterstitialPage : public InterstitialPage {
 public:
  TestInterstitialPage(TabContents* tab, bool new_navigation, const GURL& url)
      : InterstitialPage(tab, new_navigation, url) {
    FilePath file_path;
    bool r = PathService::Get(chrome::DIR_TEST_DATA, &file_path);
    EXPECT_TRUE(r);
    file_path = file_path.AppendASCII("focus");
    file_path = file_path.AppendASCII(kTypicalPageName);
    r = file_util::ReadFileToString(file_path, &html_contents_);
    EXPECT_TRUE(r);
  }

  virtual std::string GetHTMLContents() {
    return html_contents_;
  }

  // Exposing render_view_host() and tab() to be public; they are declared as
  // protected in the superclass.
  virtual RenderViewHost* render_view_host() {
    return InterstitialPage::render_view_host();
  }

  virtual TabContents* tab() {
    return InterstitialPage::tab();
  }

  bool HasFocus() {
    return render_view_host()->view()->HasFocus();
  }

 protected:
  virtual void FocusedNodeChanged(bool is_editable_node) {
    NotificationService::current()->Notify(
        NotificationType::FOCUS_CHANGED_IN_PAGE,
        Source<TabContents>(tab()),
        Details<const bool>(&is_editable_node));
  }

 private:
  std::string html_contents_;
};

IN_PROC_BROWSER_TEST_F(BrowserFocusTest, ClickingMovesFocus) {
  ASSERT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser()));
#if defined(OS_POSIX)
  // It seems we have to wait a little bit for the widgets to spin up before
  // we can start clicking on them.
  MessageLoop::current()->PostDelayedTask(FROM_HERE,
                                          new MessageLoop::QuitTask(),
                                          kActionDelayMs);
  ui_test_utils::RunMessageLoop();
#endif  // defined(OS_POSIX)

  ASSERT_TRUE(IsViewFocused(VIEW_ID_LOCATION_BAR));

  ClickOnView(VIEW_ID_TAB_CONTAINER);
  ASSERT_TRUE(IsViewFocused(VIEW_ID_TAB_CONTAINER_FOCUS_VIEW));

  ClickOnView(VIEW_ID_LOCATION_BAR);
  ASSERT_TRUE(IsViewFocused(VIEW_ID_LOCATION_BAR));
}

// Flaky, http://crbug.com/69034.
IN_PROC_BROWSER_TEST_F(BrowserFocusTest, FLAKY_BrowsersRememberFocus) {
  ASSERT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser()));
  ASSERT_TRUE(test_server()->Start());

  // First we navigate to our test page.
  GURL url = test_server()->GetURL(kSimplePage);
  ui_test_utils::NavigateToURL(browser(), url);

  gfx::NativeWindow window = browser()->window()->GetNativeHandle();

  // The focus should be on the Tab contents.
  ASSERT_TRUE(IsViewFocused(VIEW_ID_TAB_CONTAINER_FOCUS_VIEW));
  // Now hide the window, show it again, the focus should not have changed.
  ui_test_utils::HideNativeWindow(window);
  ui_test_utils::ShowAndFocusNativeWindow(window);
  ASSERT_TRUE(IsViewFocused(VIEW_ID_TAB_CONTAINER_FOCUS_VIEW));

  browser()->FocusLocationBar();
  ASSERT_TRUE(IsViewFocused(VIEW_ID_LOCATION_BAR));
  // Hide the window, show it again, the focus should not have changed.
  ui_test_utils::HideNativeWindow(window);
  ui_test_utils::ShowAndFocusNativeWindow(window);
  ASSERT_TRUE(IsViewFocused(VIEW_ID_LOCATION_BAR));

  // The rest of this test does not make sense on Linux because the behavior
  // of Activate() is not well defined and can vary by window manager.
#if defined(OS_WIN)
  // Open a new browser window.
  Browser* browser2 = Browser::Create(browser()->profile());
  ASSERT_TRUE(browser2);
  browser2->tabstrip_model()->delegate()->AddBlankTab(true);
  browser2->window()->Show();
  ui_test_utils::NavigateToURL(browser2, url);

  HWND hwnd2 = reinterpret_cast<HWND>(browser2->window()->GetNativeHandle());
  BrowserView* browser_view2 =
      BrowserView::GetBrowserViewForNativeWindow(hwnd2);
  ASSERT_TRUE(browser_view2);
  views::FocusManager* focus_manager2 =
      views::FocusManager::GetFocusManagerForNativeView(hwnd2);
  ASSERT_TRUE(focus_manager2);
  EXPECT_EQ(browser_view2->GetTabContentsContainerView(),
            focus_manager2->GetFocusedView());

  // Switch to the 1st browser window, focus should still be on the location
  // bar and the second browser should have nothing focused.
  browser()->window()->Activate();
  ASSERT_TRUE(IsViewFocused(VIEW_ID_LOCATION_BAR));
  EXPECT_EQ(NULL, focus_manager2->GetFocusedView());

  // Switch back to the second browser, focus should still be on the page.
  browser2->window()->Activate();
  EXPECT_EQ(NULL,
            views::FocusManager::GetFocusManagerForNativeView(
                browser()->window()->GetNativeHandle())->GetFocusedView());
  EXPECT_EQ(browser_view2->GetTabContentsContainerView(),
            focus_manager2->GetFocusedView());

  // Close the 2nd browser to avoid a DCHECK().
  browser_view2->Close();
#endif
}

// Tabs remember focus.
// Disabled, http://crbug.com/62542.
IN_PROC_BROWSER_TEST_F(BrowserFocusTest, DISABLED_TabsRememberFocus) {
  ASSERT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser()));
  ASSERT_TRUE(test_server()->Start());

  // First we navigate to our test page.
  GURL url = test_server()->GetURL(kSimplePage);
  ui_test_utils::NavigateToURL(browser(), url);

  // Create several tabs.
  for (int i = 0; i < 4; ++i)
    browser()->AddSelectedTabWithURL(url, PageTransition::TYPED);

  // Alternate focus for the tab.
  const bool kFocusPage[3][5] = {
    { true, true, true, true, false },
    { false, false, false, false, false },
    { false, true, false, true, false }
  };

  for (int i = 1; i < 3; i++) {
    for (int j = 0; j < 5; j++) {
      // Activate the tab.
      browser()->ActivateTabAt(j, true);

      // Activate the location bar or the page.
      if (kFocusPage[i][j]) {
        browser()->GetTabContentsAt(j)->view()->Focus();
      } else {
        browser()->FocusLocationBar();
      }
    }

    // Now come back to the tab and check the right view is focused.
    for (int j = 0; j < 5; j++) {
      // Activate the tab.
      browser()->ActivateTabAt(j, true);

      ViewID vid = kFocusPage[i][j] ? VIEW_ID_TAB_CONTAINER_FOCUS_VIEW :
                                      VIEW_ID_LOCATION_BAR;
      ASSERT_TRUE(IsViewFocused(vid));
    }

    browser()->ActivateTabAt(0, true);
    // Try the above, but with ctrl+tab. Since tab normally changes focus,
    // this has regressed in the past. Loop through several times to be sure.
    for (int j = 0; j < 15; j++) {
      ViewID vid = kFocusPage[i][j % 5] ? VIEW_ID_TAB_CONTAINER_FOCUS_VIEW :
                                          VIEW_ID_LOCATION_BAR;
      ASSERT_TRUE(IsViewFocused(vid));

      ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
          browser(), ui::VKEY_TAB, true, false, false, false));
    }

    // As above, but with ctrl+shift+tab.
    browser()->ActivateTabAt(4, true);
    for (int j = 14; j >= 0; --j) {
      ViewID vid = kFocusPage[i][j % 5] ? VIEW_ID_TAB_CONTAINER_FOCUS_VIEW :
                                          VIEW_ID_LOCATION_BAR;
      ASSERT_TRUE(IsViewFocused(vid));

      ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
          browser(), ui::VKEY_TAB, true, true, false, false));
    }
  }
}

// Tabs remember focus with find-in-page box.
IN_PROC_BROWSER_TEST_F(BrowserFocusTest, MAYBE_TabsRememberFocusFindInPage) {
  ASSERT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser()));
  ASSERT_TRUE(test_server()->Start());

  // First we navigate to our test page.
  GURL url = test_server()->GetURL(kSimplePage);
  ui_test_utils::NavigateToURL(browser(), url);

  browser()->Find();
  ui_test_utils::FindInPage(browser()->GetSelectedTabContentsWrapper(),
                            ASCIIToUTF16("a"), true, false, NULL);
  ASSERT_TRUE(IsViewFocused(VIEW_ID_FIND_IN_PAGE_TEXT_FIELD));

  // Focus the location bar.
  browser()->FocusLocationBar();

  // Create a 2nd tab.
  browser()->AddSelectedTabWithURL(url, PageTransition::TYPED);

  // Focus should be on the recently opened tab page.
  ASSERT_TRUE(IsViewFocused(VIEW_ID_TAB_CONTAINER_FOCUS_VIEW));

  // Select 1st tab, focus should still be on the location-bar.
  // (bug http://crbug.com/23296)
  browser()->ActivateTabAt(0, true);
  ASSERT_TRUE(IsViewFocused(VIEW_ID_LOCATION_BAR));

  // Now open the find box again, switch to another tab and come back, the focus
  // should return to the find box.
  browser()->Find();
  ASSERT_TRUE(IsViewFocused(VIEW_ID_FIND_IN_PAGE_TEXT_FIELD));
  browser()->ActivateTabAt(1, true);
  ASSERT_TRUE(IsViewFocused(VIEW_ID_TAB_CONTAINER_FOCUS_VIEW));
  browser()->ActivateTabAt(0, true);
  ASSERT_TRUE(IsViewFocused(VIEW_ID_FIND_IN_PAGE_TEXT_FIELD));
}

// Background window does not steal focus.
// Flaky, http://crbug.com/62538.
IN_PROC_BROWSER_TEST_F(BrowserFocusTest,
                       FLAKY_BackgroundBrowserDontStealFocus) {
  ASSERT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser()));
  ASSERT_TRUE(test_server()->Start());

  // Open a new browser window.
  Browser* browser2 = Browser::Create(browser()->profile());
  ASSERT_TRUE(browser2);
  browser2->tabstrip_model()->delegate()->AddBlankTab(true);
  browser2->window()->Show();

  Browser* focused_browser = NULL;
  Browser* unfocused_browser = NULL;
#if defined(USE_X11)
  // On X11, calling Activate() is not guaranteed to move focus, so we have
  // to figure out which browser does have focus.
  if (browser2->window()->IsActive()) {
    focused_browser = browser2;
    unfocused_browser = browser();
  } else if (browser()->window()->IsActive()) {
    focused_browser = browser();
    unfocused_browser = browser2;
  } else {
    FAIL() << "Could not determine which browser has focus";
  }
#elif defined(OS_WIN)
  focused_browser = browser();
  unfocused_browser = browser2;
#elif defined(OS_MACOSX)
  // On Mac, the newly created window always gets the focus.
  focused_browser = browser2;
  unfocused_browser = browser();
#endif

  GURL steal_focus_url = test_server()->GetURL(kStealFocusPage);
  ui_test_utils::NavigateToURL(unfocused_browser, steal_focus_url);

  // Activate the first browser.
  focused_browser->window()->Activate();

  ASSERT_TRUE(ui_test_utils::ExecuteJavaScript(
      unfocused_browser->GetSelectedTabContents()->render_view_host(), L"",
      L"stealFocus();"));

  // Make sure the first browser is still active.
  EXPECT_TRUE(focused_browser->window()->IsActive());
}

// Page cannot steal focus when focus is on location bar.
IN_PROC_BROWSER_TEST_F(BrowserFocusTest, LocationBarLockFocus) {
  ASSERT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser()));
  ASSERT_TRUE(test_server()->Start());

  // Open the page that steals focus.
  GURL url = test_server()->GetURL(kStealFocusPage);
  ui_test_utils::NavigateToURL(browser(), url);

  browser()->FocusLocationBar();

  ASSERT_TRUE(ui_test_utils::ExecuteJavaScript(
      browser()->GetSelectedTabContents()->render_view_host(), L"",
      L"stealFocus();"));

  // Make sure the location bar is still focused.
  ASSERT_TRUE(IsViewFocused(VIEW_ID_LOCATION_BAR));
}

// Focus traversal on a regular page.
// Note that this test relies on a notification from the renderer that the
// focus has changed in the page.  The notification in the renderer may change
// at which point this test would fail (see comment in
// RenderWidget::didFocus()).
IN_PROC_BROWSER_TEST_F(BrowserFocusTest, MAYBE_FocusTraversal) {
  ASSERT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser()));
  ASSERT_TRUE(test_server()->Start());

  // First we navigate to our test page.
  GURL url = test_server()->GetURL(kTypicalPage);
  ui_test_utils::NavigateToURL(browser(), url);

  browser()->FocusLocationBar();

  const char* kTextElementID = "textEdit";
  const char* kExpElementIDs[] = {
    "",  // Initially no element in the page should be focused
         // (the location bar is focused).
    kTextElementID, "searchButton", "luckyButton", "googleLink", "gmailLink",
    "gmapLink"
  };

  // Test forward focus traversal.
  for (int i = 0; i < 3; ++i) {
    SCOPED_TRACE(StringPrintf("outer loop: %d", i));
    // Location bar should be focused.
    ASSERT_TRUE(IsViewFocused(VIEW_ID_LOCATION_BAR));

    // Move the caret to the end, otherwise the next Tab key may not move focus.
    ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
        browser(), ui::VKEY_END, false, false, false, false));

    // Now let's press tab to move the focus.
    for (size_t j = 0; j < arraysize(kExpElementIDs); ++j) {
      SCOPED_TRACE(StringPrintf("inner loop %" PRIuS, j));
      // Let's make sure the focus is on the expected element in the page.
      std::string actual;
      ASSERT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractString(
          browser()->GetSelectedTabContents()->render_view_host(),
          L"",
          L"window.domAutomationController.send(getFocusedElement());",
          &actual));
      ASSERT_STREQ(kExpElementIDs[j], actual.c_str());

      if (j < arraysize(kExpElementIDs) - 1) {
        // If the next element is the kTextElementID, we expect to be
        // notified we have switched to an editable node.
        bool is_editable_node =
            (strcmp(kTextElementID, kExpElementIDs[j + 1]) == 0);
        Details<bool> details(&is_editable_node);

        ASSERT_TRUE(ui_test_utils::SendKeyPressAndWaitWithDetails(
            browser(), ui::VKEY_TAB, false, false, false, false,
            NotificationType::FOCUS_CHANGED_IN_PAGE,
            NotificationSource(Source<TabContents>(
                browser()->GetSelectedTabContents())),
            details));
      } else {
        // On the last tab key press, the focus returns to the browser.
        ASSERT_TRUE(ui_test_utils::SendKeyPressAndWait(
            browser(), ui::VKEY_TAB, false, false, false, false,
            NotificationType::FOCUS_RETURNED_TO_BROWSER,
            NotificationSource(Source<Browser>(browser()))));
      }
    }

    // At this point the renderer has sent us a message asking to advance the
    // focus (as the end of the focus loop was reached in the renderer).
    // We need to run the message loop to process it.
    ui_test_utils::RunAllPendingInMessageLoop();
  }

  // Now let's try reverse focus traversal.
  for (int i = 0; i < 3; ++i) {
    SCOPED_TRACE(StringPrintf("outer loop: %d", i));
    // Location bar should be focused.
    ASSERT_TRUE(IsViewFocused(VIEW_ID_LOCATION_BAR));

    // Move the caret to the end, otherwise the next Tab key may not move focus.
    ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
        browser(), ui::VKEY_END, false, false, false, false));

    // Now let's press shift-tab to move the focus in reverse.
    for (size_t j = 0; j < arraysize(kExpElementIDs); ++j) {
      SCOPED_TRACE(StringPrintf("inner loop: %" PRIuS, j));
      const char* next_element =
          kExpElementIDs[arraysize(kExpElementIDs) - 1 - j];

      if (j < arraysize(kExpElementIDs) - 1) {
        // If the next element is the kTextElementID, we expect to be
        // notified we have switched to an editable node.
        bool is_editable_node = (strcmp(kTextElementID, next_element) == 0);
        Details<bool> details(&is_editable_node);

        ASSERT_TRUE(ui_test_utils::SendKeyPressAndWaitWithDetails(
            browser(), ui::VKEY_TAB, false, true, false, false,
            NotificationType::FOCUS_CHANGED_IN_PAGE,
            NotificationSource(Source<TabContents>(
                browser()->GetSelectedTabContents())),
            details));
      } else {
        // On the last tab key press, the focus returns to the browser.
        ASSERT_TRUE(ui_test_utils::SendKeyPressAndWait(
            browser(), ui::VKEY_TAB, false, true, false, false,
            NotificationType::FOCUS_RETURNED_TO_BROWSER,
            NotificationSource(Source<Browser>(browser()))));
      }

      // Let's make sure the focus is on the expected element in the page.
      std::string actual;
      ASSERT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractString(
          browser()->GetSelectedTabContents()->render_view_host(),
          L"",
          L"window.domAutomationController.send(getFocusedElement());",
          &actual));
      ASSERT_STREQ(next_element, actual.c_str());
    }

    // At this point the renderer has sent us a message asking to advance the
    // focus (as the end of the focus loop was reached in the renderer).
    // We need to run the message loop to process it.
    ui_test_utils::RunAllPendingInMessageLoop();
  }
}

// Focus traversal while an interstitial is showing.
IN_PROC_BROWSER_TEST_F(BrowserFocusTest, MAYBE_FocusTraversalOnInterstitial) {
  ASSERT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser()));
  ASSERT_TRUE(test_server()->Start());

  // First we navigate to our test page.
  GURL url = test_server()->GetURL(kSimplePage);
  ui_test_utils::NavigateToURL(browser(), url);

  // Focus should be on the page.
  ASSERT_TRUE(IsViewFocused(VIEW_ID_TAB_CONTAINER_FOCUS_VIEW));

  // Let's show an interstitial.
  TestInterstitialPage* interstitial_page =
      new TestInterstitialPage(browser()->GetSelectedTabContents(),
                               true, GURL("http://interstitial.com"));
  interstitial_page->Show();
  // Give some time for the interstitial to show.
  MessageLoop::current()->PostDelayedTask(FROM_HERE,
                                          new MessageLoop::QuitTask(),
                                          1000);
  ui_test_utils::RunMessageLoop();

  browser()->FocusLocationBar();

  const char* kExpElementIDs[] = {
    "",  // Initially no element in the page should be focused
         // (the location bar is focused).
    "textEdit", "searchButton", "luckyButton", "googleLink", "gmailLink",
    "gmapLink"
  };

  // Test forward focus traversal.
  for (int i = 0; i < 2; ++i) {
    // Location bar should be focused.
    ASSERT_TRUE(IsViewFocused(VIEW_ID_LOCATION_BAR));

    // Move the caret to the end, otherwise the next Tab key may not move focus.
    ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
        browser(), ui::VKEY_END, false, false, false, false));

    // Now let's press tab to move the focus.
    for (size_t j = 0; j < 7; ++j) {
      // Let's make sure the focus is on the expected element in the page.
      std::string actual;
      ASSERT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractString(
          interstitial_page->render_view_host(), L"",
          L"window.domAutomationController.send(getFocusedElement());",
          &actual));
      ASSERT_STREQ(kExpElementIDs[j], actual.c_str());

      NotificationType::Type notification_type;
      NotificationSource notification_source =
          NotificationService::AllSources();
      if (j < arraysize(kExpElementIDs) - 1) {
        notification_type = NotificationType::FOCUS_CHANGED_IN_PAGE;
        notification_source = Source<TabContents>(
            interstitial_page->tab());
      } else {
        // On the last tab key press, the focus returns to the browser.
        notification_type = NotificationType::FOCUS_RETURNED_TO_BROWSER;
        notification_source = Source<Browser>(browser());
      }

      ASSERT_TRUE(ui_test_utils::SendKeyPressAndWait(
          browser(), ui::VKEY_TAB, false, false, false, false,
          notification_type, notification_source));
    }

    // At this point the renderer has sent us a message asking to advance the
    // focus (as the end of the focus loop was reached in the renderer).
    // We need to run the message loop to process it.
    ui_test_utils::RunAllPendingInMessageLoop();
  }

  // Now let's try reverse focus traversal.
  for (int i = 0; i < 2; ++i) {
    // Location bar should be focused.
    ASSERT_TRUE(IsViewFocused(VIEW_ID_LOCATION_BAR));

    // Move the caret to the end, otherwise the next Tab key may not move focus.
    ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
        browser(), ui::VKEY_END, false, false, false, false));

    // Now let's press shift-tab to move the focus in reverse.
    for (size_t j = 0; j < 7; ++j) {
      NotificationType::Type notification_type;
      NotificationSource notification_source =
          NotificationService::AllSources();
      if (j < arraysize(kExpElementIDs) - 1) {
        notification_type = NotificationType::FOCUS_CHANGED_IN_PAGE;
        notification_source = Source<TabContents>(
            interstitial_page->tab());
      } else {
        // On the last tab key press, the focus returns to the browser.
        notification_type = NotificationType::FOCUS_RETURNED_TO_BROWSER;
        notification_source = Source<Browser>(browser());
      }

      ASSERT_TRUE(ui_test_utils::SendKeyPressAndWait(
          browser(), ui::VKEY_TAB, false, true, false, false,
          notification_type, notification_source));

      // Let's make sure the focus is on the expected element in the page.
      std::string actual;
      ASSERT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractString(
          interstitial_page->render_view_host(), L"",
          L"window.domAutomationController.send(getFocusedElement());",
          &actual));
      ASSERT_STREQ(kExpElementIDs[6 - j], actual.c_str());
    }

    // At this point the renderer has sent us a message asking to advance the
    // focus (as the end of the focus loop was reached in the renderer).
    // We need to run the message loop to process it.
    ui_test_utils::RunAllPendingInMessageLoop();
  }
}

// Focus stays on page with interstitials.
IN_PROC_BROWSER_TEST_F(BrowserFocusTest, InterstitialFocus) {
  ASSERT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser()));
  ASSERT_TRUE(test_server()->Start());

  // First we navigate to our test page.
  GURL url = test_server()->GetURL(kSimplePage);
  ui_test_utils::NavigateToURL(browser(), url);

  // Page should have focus.
  ASSERT_TRUE(IsViewFocused(VIEW_ID_TAB_CONTAINER_FOCUS_VIEW));
  EXPECT_TRUE(browser()->GetSelectedTabContents()->render_view_host()->view()->
      HasFocus());

  // Let's show an interstitial.
  TestInterstitialPage* interstitial_page =
      new TestInterstitialPage(browser()->GetSelectedTabContents(),
                               true, GURL("http://interstitial.com"));
  interstitial_page->Show();
  // Give some time for the interstitial to show.
  MessageLoop::current()->PostDelayedTask(FROM_HERE,
                                          new MessageLoop::QuitTask(),
                                          1000);
  ui_test_utils::RunMessageLoop();

  // The interstitial should have focus now.
  ASSERT_TRUE(IsViewFocused(VIEW_ID_TAB_CONTAINER_FOCUS_VIEW));
  EXPECT_TRUE(interstitial_page->HasFocus());

  // Hide the interstitial.
  interstitial_page->DontProceed();

  // Focus should be back on the original page.
  ASSERT_TRUE(IsViewFocused(VIEW_ID_TAB_CONTAINER_FOCUS_VIEW));
}

// Make sure Find box can request focus, even when it is already open.
IN_PROC_BROWSER_TEST_F(BrowserFocusTest, FindFocusTest) {
  ASSERT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser()));
  ASSERT_TRUE(test_server()->Start());

  // Open some page (any page that doesn't steal focus).
  GURL url = test_server()->GetURL(kTypicalPage);
  ui_test_utils::NavigateToURL(browser(), url);

  EXPECT_TRUE(ChromeInForeground());

#if defined(OS_MACOSX)
  // Press Cmd+F, which will make the Find box open and request focus.
  ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
      browser(), ui::VKEY_F, false, false, false, true));
#else
  // Press Ctrl+F, which will make the Find box open and request focus.
  ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
      browser(), ui::VKEY_F, true, false, false, false));
#endif

  // Ideally, we wouldn't sleep here and instead would intercept the
  // RenderViewHostDelegate::HandleKeyboardEvent() callback.  To do that, we
  // could create a RenderViewHostDelegate wrapper and hook-it up by either:
  // - creating a factory used to create the delegate
  // - making the test a private and overwriting the delegate member directly.
  MessageLoop::current()->PostDelayedTask(
      FROM_HERE, new MessageLoop::QuitTask(), kActionDelayMs);
  ui_test_utils::RunMessageLoop();

  ASSERT_TRUE(IsViewFocused(VIEW_ID_FIND_IN_PAGE_TEXT_FIELD));

  browser()->FocusLocationBar();
  ASSERT_TRUE(IsViewFocused(VIEW_ID_LOCATION_BAR));

  // Now press Ctrl+F again and focus should move to the Find box.
#if defined(OS_MACOSX)
  ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
      browser(), ui::VKEY_F, false, false, false, true));
#else
  ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
      browser(), ui::VKEY_F, true, false, false, false));
#endif
  ASSERT_TRUE(IsViewFocused(VIEW_ID_FIND_IN_PAGE_TEXT_FIELD));

  // Set focus to the page.
  ClickOnView(VIEW_ID_TAB_CONTAINER);
  ASSERT_TRUE(IsViewFocused(VIEW_ID_TAB_CONTAINER_FOCUS_VIEW));

  // Now press Ctrl+F again and focus should move to the Find box.
#if defined(OS_MACOSX)
  ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
      browser(), ui::VKEY_F, false, false, false, true));
#else
  ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
      browser(), ui::VKEY_F, true, false, false, false));
#endif

  // See remark above on why we wait.
  MessageLoop::current()->PostDelayedTask(
      FROM_HERE, new MessageLoop::QuitTask(), kActionDelayMs);
  ui_test_utils::RunMessageLoop();
  ASSERT_TRUE(IsViewFocused(VIEW_ID_FIND_IN_PAGE_TEXT_FIELD));
}

// Makes sure the focus is in the right location when opening the different
// types of tabs.
// Flaky, http://crbug.com/62539.
IN_PROC_BROWSER_TEST_F(BrowserFocusTest, FLAKY_TabInitialFocus) {
  ASSERT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser()));

  // Open the history tab, focus should be on the tab contents.
  browser()->ShowHistoryTab();
  ASSERT_NO_FATAL_FAILURE(ui_test_utils::WaitForLoadStop(
      browser()->GetSelectedTabContents()));
  EXPECT_TRUE(IsViewFocused(VIEW_ID_TAB_CONTAINER_FOCUS_VIEW));

  // Open the new tab, focus should be on the location bar.
  browser()->NewTab();
  ASSERT_NO_FATAL_FAILURE(ui_test_utils::WaitForLoadStop(
      browser()->GetSelectedTabContents()));
  EXPECT_TRUE(IsViewFocused(VIEW_ID_LOCATION_BAR));

  // Open the download tab, focus should be on the tab contents.
  browser()->ShowDownloadsTab();
  ASSERT_NO_FATAL_FAILURE(ui_test_utils::WaitForLoadStop(
      browser()->GetSelectedTabContents()));
  EXPECT_TRUE(IsViewFocused(VIEW_ID_TAB_CONTAINER_FOCUS_VIEW));

  // Open about:blank, focus should be on the location bar.
  browser()->AddSelectedTabWithURL(GURL(chrome::kAboutBlankURL),
                                   PageTransition::LINK);
  ASSERT_NO_FATAL_FAILURE(ui_test_utils::WaitForLoadStop(
      browser()->GetSelectedTabContents()));
  EXPECT_TRUE(IsViewFocused(VIEW_ID_LOCATION_BAR));
}

// Tests that focus goes where expected when using reload.
IN_PROC_BROWSER_TEST_F(BrowserFocusTest, FocusOnReload) {
  ASSERT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser()));
  ASSERT_TRUE(test_server()->Start());

  // Open the new tab, reload.
  browser()->NewTab();
  ui_test_utils::RunAllPendingInMessageLoop();

  browser()->Reload(CURRENT_TAB);
  ASSERT_TRUE(ui_test_utils::WaitForNavigationInCurrentTab(browser()));
  // Focus should stay on the location bar.
  ASSERT_TRUE(IsViewFocused(VIEW_ID_LOCATION_BAR));

  // Open a regular page, focus the location bar, reload.
  ui_test_utils::NavigateToURL(browser(), test_server()->GetURL(kSimplePage));
  browser()->FocusLocationBar();
  ASSERT_TRUE(IsViewFocused(VIEW_ID_LOCATION_BAR));
  browser()->Reload(CURRENT_TAB);
  ASSERT_TRUE(ui_test_utils::WaitForNavigationInCurrentTab(browser()));

  // Focus should now be on the tab contents.
  browser()->ShowDownloadsTab();
  ASSERT_TRUE(IsViewFocused(VIEW_ID_TAB_CONTAINER_FOCUS_VIEW));
}

// Tests that focus goes where expected when using reload on a crashed tab.
IN_PROC_BROWSER_TEST_F(BrowserFocusTest, DISABLED_FocusOnReloadCrashedTab) {
  ASSERT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser()));
  ASSERT_TRUE(test_server()->Start());

  // Open a regular page, crash, reload.
  ui_test_utils::NavigateToURL(browser(), test_server()->GetURL(kSimplePage));
  ui_test_utils::CrashTab(browser()->GetSelectedTabContents());
  browser()->Reload(CURRENT_TAB);
  ASSERT_TRUE(ui_test_utils::WaitForNavigationInCurrentTab(browser()));

  // Focus should now be on the tab contents.
  browser()->ShowDownloadsTab();
  ASSERT_TRUE(IsViewFocused(VIEW_ID_TAB_CONTAINER_FOCUS_VIEW));
}

}  // namespace
