// 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.

#include <stddef.h>

#include "base/path_service.h"
#include "base/stl_util.h"
#include "base/strings/stringprintf.h"
#include "base/test/metrics/histogram_tester.h"
#include "build/build_config.h"
#include "chrome/browser/extensions/extension_apitest.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_finder.h"
#include "chrome/browser/ui/browser_list.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/url_constants.h"
#include "chrome/test/base/ui_test_utils.h"
#include "content/public/browser/navigation_entry.h"
#include "content/public/browser/notification_service.h"
#include "content/public/browser/notification_types.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/web_contents.h"
#include "content/public/common/result_codes.h"
#include "content/public/common/url_constants.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/test_navigation_observer.h"
#include "extensions/browser/extension_host.h"
#include "extensions/browser/process_manager.h"
#include "extensions/common/constants.h"
#include "extensions/common/extension.h"
#include "extensions/test/extension_test_message_listener.h"
#include "extensions/test/result_catcher.h"
#include "net/dns/mock_host_resolver.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/base/base_window.h"

#if defined(OS_CHROMEOS)
#include "ash/public/cpp/window_pin_type.h"
#include "ash/public/cpp/window_properties.h"
#include "chrome/app/chrome_command_ids.h"
#include "chrome/browser/extensions/window_controller.h"
#include "chrome/browser/extensions/window_controller_list.h"
#include "chrome/browser/ui/browser_command_controller.h"
#include "ui/aura/window.h"
#endif

using content::OpenURLParams;
using content::Referrer;
using content::WebContents;

namespace aura {
class Window;
}

namespace extensions {

class WindowOpenApiTest : public ExtensionApiTest {
  void SetUpOnMainThread() override {
    ExtensionApiTest::SetUpOnMainThread();
    host_resolver()->AddRule("*", "127.0.0.1");
  }
};

// The test uses the chrome.browserAction.openPopup API, which requires that the
// window can automatically be activated.
// See comments at BrowserActionInteractiveTest::ShouldRunPopupTest
// Fails flakily on all platforms. https://crbug.com/477691
IN_PROC_BROWSER_TEST_F(WindowOpenApiTest, DISABLED_WindowOpen) {
  extensions::ResultCatcher catcher;
  ASSERT_TRUE(LoadExtensionIncognito(test_data_dir_
      .AppendASCII("window_open").AppendASCII("spanning")));
  EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
}

bool WaitForTabsAndPopups(Browser* browser,
                          int num_tabs,
                          int num_popups) {
  SCOPED_TRACE(
      base::StringPrintf("WaitForTabsAndPopups tabs:%d, popups:%d",
                         num_tabs, num_popups));
  // We start with one tab and one browser already open.
  ++num_tabs;
  size_t num_browsers = static_cast<size_t>(num_popups) + 1;

  const base::TimeDelta kWaitTime = base::TimeDelta::FromSeconds(10);
  base::TimeTicks end_time = base::TimeTicks::Now() + kWaitTime;
  while (base::TimeTicks::Now() < end_time) {
    if (chrome::GetBrowserCount(browser->profile()) == num_browsers &&
        browser->tab_strip_model()->count() == num_tabs)
      break;

    content::RunAllPendingInMessageLoop();
  }

  EXPECT_EQ(num_browsers, chrome::GetBrowserCount(browser->profile()));
  EXPECT_EQ(num_tabs, browser->tab_strip_model()->count());

  int num_popups_seen = 0;
  for (auto* b : *BrowserList::GetInstance()) {
    if (b == browser)
      continue;

    EXPECT_TRUE(b->is_type_popup());
    ++num_popups_seen;
  }
  EXPECT_EQ(num_popups, num_popups_seen);

  return ((num_browsers == chrome::GetBrowserCount(browser->profile())) &&
          (num_tabs == browser->tab_strip_model()->count()) &&
          (num_popups == num_popups_seen));
}

IN_PROC_BROWSER_TEST_F(WindowOpenApiTest, BrowserIsApp) {
  ASSERT_TRUE(StartEmbeddedTestServer());
  ASSERT_TRUE(LoadExtension(
      test_data_dir_.AppendASCII("window_open").AppendASCII("browser_is_app")));

  EXPECT_TRUE(WaitForTabsAndPopups(browser(), 0, 2));

  for (auto* b : *BrowserList::GetInstance()) {
    if (b == browser())
      ASSERT_FALSE(b->is_app());
    else
      ASSERT_TRUE(b->is_app());
  }
}

IN_PROC_BROWSER_TEST_F(WindowOpenApiTest, WindowOpenPopupDefault) {
  ASSERT_TRUE(StartEmbeddedTestServer());
  ASSERT_TRUE(LoadExtension(
      test_data_dir_.AppendASCII("window_open").AppendASCII("popup")));

  const int num_tabs = 1;
  const int num_popups = 0;
  EXPECT_TRUE(WaitForTabsAndPopups(browser(), num_tabs, num_popups));
}

IN_PROC_BROWSER_TEST_F(WindowOpenApiTest, WindowOpenPopupIframe) {
  base::FilePath test_data_dir;
  base::PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir);
  embedded_test_server()->ServeFilesFromDirectory(test_data_dir);
  ASSERT_TRUE(StartEmbeddedTestServer());
  ASSERT_TRUE(LoadExtension(
      test_data_dir_.AppendASCII("window_open").AppendASCII("popup_iframe")));

  const int num_tabs = 1;
  const int num_popups = 0;
  EXPECT_TRUE(WaitForTabsAndPopups(browser(), num_tabs, num_popups));
}

IN_PROC_BROWSER_TEST_F(WindowOpenApiTest, WindowOpenPopupLarge) {
  ASSERT_TRUE(StartEmbeddedTestServer());
  ASSERT_TRUE(LoadExtension(
      test_data_dir_.AppendASCII("window_open").AppendASCII("popup_large")));

  // On other systems this should open a new popup window.
  const int num_tabs = 0;
  const int num_popups = 1;
  EXPECT_TRUE(WaitForTabsAndPopups(browser(), num_tabs, num_popups));
}

IN_PROC_BROWSER_TEST_F(WindowOpenApiTest, WindowOpenPopupSmall) {
  ASSERT_TRUE(StartEmbeddedTestServer());
  ASSERT_TRUE(LoadExtension(
      test_data_dir_.AppendASCII("window_open").AppendASCII("popup_small")));

  // On ChromeOS this should open a new panel (acts like a new popup window).
  // On other systems this should open a new popup window.
  const int num_tabs = 0;
  const int num_popups = 1;
  EXPECT_TRUE(WaitForTabsAndPopups(browser(), num_tabs, num_popups));
}

// Disabled on Windows. Often times out or fails: crbug.com/177530
#if defined(OS_WIN)
#define MAYBE_PopupBlockingExtension DISABLED_PopupBlockingExtension
#else
#define MAYBE_PopupBlockingExtension PopupBlockingExtension
#endif
IN_PROC_BROWSER_TEST_F(WindowOpenApiTest, MAYBE_PopupBlockingExtension) {
  ASSERT_TRUE(StartEmbeddedTestServer());

  ASSERT_TRUE(LoadExtension(
      test_data_dir_.AppendASCII("window_open").AppendASCII("popup_blocking")
      .AppendASCII("extension")));

  EXPECT_TRUE(WaitForTabsAndPopups(browser(), 5, 3));
}

IN_PROC_BROWSER_TEST_F(WindowOpenApiTest, PopupBlockingHostedApp) {
  ASSERT_TRUE(embedded_test_server()->Start());

  ASSERT_TRUE(LoadExtension(
      test_data_dir_.AppendASCII("window_open").AppendASCII("popup_blocking")
      .AppendASCII("hosted_app")));

  // The app being tested owns the domain a.com .  The test URLs we navigate
  // to below must be within that domain, so that they fall within the app's
  // web extent.
  GURL::Replacements replace_host;
  replace_host.SetHostStr("a.com");

  const std::string popup_app_contents_path(
      "/extensions/api_test/window_open/popup_blocking/hosted_app/");

  GURL open_tab = embedded_test_server()
                      ->GetURL(popup_app_contents_path + "open_tab.html")
                      .ReplaceComponents(replace_host);
  GURL open_popup = embedded_test_server()
                        ->GetURL(popup_app_contents_path + "open_popup.html")
                        .ReplaceComponents(replace_host);

  browser()->OpenURL(OpenURLParams(open_tab, Referrer(),
                                   WindowOpenDisposition::NEW_FOREGROUND_TAB,
                                   ui::PAGE_TRANSITION_TYPED, false));
  browser()->OpenURL(OpenURLParams(open_popup, Referrer(),
                                   WindowOpenDisposition::NEW_FOREGROUND_TAB,
                                   ui::PAGE_TRANSITION_TYPED, false));

  EXPECT_TRUE(WaitForTabsAndPopups(browser(), 3, 1));
}

IN_PROC_BROWSER_TEST_F(WindowOpenApiTest, WindowArgumentsOverflow) {
  ASSERT_TRUE(RunExtensionTest("window_open/argument_overflow")) << message_;
}

IN_PROC_BROWSER_TEST_F(WindowOpenApiTest, DISABLED_WindowOpener) {
  ASSERT_TRUE(RunExtensionTest("window_open/opener")) << message_;
}

#if defined(OS_MACOSX)
// Extension popup windows are incorrectly sized on OSX, crbug.com/225601
#define MAYBE_WindowOpenSized DISABLED_WindowOpenSized
#else
#define MAYBE_WindowOpenSized WindowOpenSized
#endif
// Ensure that the width and height properties of a window opened with
// chrome.windows.create match the creation parameters. See crbug.com/173831.
IN_PROC_BROWSER_TEST_F(WindowOpenApiTest, MAYBE_WindowOpenSized) {
  ASSERT_TRUE(RunExtensionTest("window_open/window_size")) << message_;
  EXPECT_TRUE(WaitForTabsAndPopups(browser(), 0, 1));
}

// Tests that an extension page can call window.open to an extension URL and
// the new window has extension privileges.
IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, WindowOpenExtension) {
  ASSERT_TRUE(LoadExtension(
      test_data_dir_.AppendASCII("uitest").AppendASCII("window_open")));

  GURL start_url(std::string(extensions::kExtensionScheme) +
                     url::kStandardSchemeSeparator +
                     last_loaded_extension_id() + "/test.html");
  ui_test_utils::NavigateToURL(browser(), start_url);
  WebContents* newtab = NULL;
  ASSERT_NO_FATAL_FAILURE(
      OpenWindow(browser()->tab_strip_model()->GetActiveWebContents(),
                 start_url.Resolve("newtab.html"), true, true, &newtab));

  bool result = false;
  ASSERT_TRUE(content::ExecuteScriptAndExtractBool(newtab, "testExtensionApi()",
                                                   &result));
  EXPECT_TRUE(result);
}

// Tests that if an extension page calls window.open to an invalid extension
// URL, the browser doesn't crash.
IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, WindowOpenInvalidExtension) {
  const extensions::Extension* extension = LoadExtension(
      test_data_dir_.AppendASCII("uitest").AppendASCII("window_open"));
  ASSERT_TRUE(extension);

  GURL start_url = extension->GetResourceURL("/test.html");
  ui_test_utils::NavigateToURL(browser(), start_url);
  WebContents* newtab = nullptr;
  bool new_page_in_same_process = true;
  bool expect_success = false;
  ASSERT_NO_FATAL_FAILURE(OpenWindow(
      browser()->tab_strip_model()->GetActiveWebContents(),
      GURL("chrome-extension://thisissurelynotavalidextensionid/newtab.html"),
      new_page_in_same_process, expect_success, &newtab));

  // This is expected to redirect to about:blank.
  EXPECT_EQ(GURL(url::kAboutBlankURL), newtab->GetLastCommittedURL());
}

// Tests that calling window.open from the newtab page to an extension URL
// gives the new window extension privileges - even though the opening page
// does not have extension privileges, we break the script connection, so
// there is no privilege leak.
IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, WindowOpenNoPrivileges) {
  ASSERT_TRUE(LoadExtension(
      test_data_dir_.AppendASCII("uitest").AppendASCII("window_open")));

  ui_test_utils::NavigateToURL(browser(), GURL("about:blank"));
  WebContents* newtab = NULL;
  ASSERT_NO_FATAL_FAILURE(
      OpenWindow(browser()->tab_strip_model()->GetActiveWebContents(),
                 GURL(std::string(extensions::kExtensionScheme) +
                      url::kStandardSchemeSeparator +
                      last_loaded_extension_id() + "/newtab.html"),
                 false, true, &newtab));

  // Extension API should succeed.
  bool result = false;
  ASSERT_TRUE(content::ExecuteScriptAndExtractBool(newtab, "testExtensionApi()",
                                                   &result));
  EXPECT_TRUE(result);
}

// Tests that calling window.open for an extension URL from a non-HTTP or HTTPS
// URL on a new tab cannot access non-web-accessible resources.
IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest,
                       WindowOpenInaccessibleResourceFromDataURL) {
  base::HistogramTester uma;
  const extensions::Extension* extension = LoadExtension(
      test_data_dir_.AppendASCII("uitest").AppendASCII("window_open"));
  ASSERT_TRUE(extension);

  ui_test_utils::NavigateToURL(browser(), GURL("data:text/html,foo"));

  // test.html is not web-accessible and should not be loaded.
  GURL extension_url(extension->GetResourceURL("test.html"));
  content::WindowedNotificationObserver windowed_observer(
      content::NOTIFICATION_LOAD_STOP,
      content::NotificationService::AllSources());
  ASSERT_TRUE(content::ExecuteScript(
      browser()->tab_strip_model()->GetActiveWebContents(),
      "window.open('" + extension_url.spec() + "');"));
  windowed_observer.Wait();
  content::NavigationController* controller =
      content::Source<content::NavigationController>(windowed_observer.source())
          .ptr();
  content::WebContents* newtab = controller->GetWebContents();
  ASSERT_TRUE(newtab);

  EXPECT_NE(extension_url, newtab->GetMainFrame()->GetLastCommittedURL());
  EXPECT_FALSE(newtab->GetMainFrame()->GetSiteInstance()->GetSiteURL().SchemeIs(
      extensions::kExtensionScheme));

  // Verify that the blocking was recorded correctly in UMA. ShouldAllowOpenURL
  // is called twice by the content layer, once when creating the window, and
  // again when attempting to navigate the newly-created window.
  uma.ExpectUniqueSample("Extensions.ShouldAllowOpenURL.Failure",
                         2, /* FAILURE_SCHEME_NOT_HTTP_OR_HTTPS_OR_EXTENSION */
                         2);
  uma.ExpectUniqueSample("Extensions.ShouldAllowOpenURL.Failure.Scheme",
                         6 /* SCHEME_DATA */, 2);
}

// Test that navigating to an extension URL is allowed on chrome:// and
// chrome-search:// pages, even for URLs that are not web-accessible.
// See https://crbug.com/662602.
IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest,
                       NavigateToInaccessibleResourceFromChromeURL) {
  // Mint an extension URL which is not web-accessible.
  const extensions::Extension* extension = LoadExtension(
      test_data_dir_.AppendASCII("uitest").AppendASCII("window_open"));
  ASSERT_TRUE(extension);
  GURL extension_url(extension->GetResourceURL("test.html"));

  content::WebContents* tab =
      browser()->tab_strip_model()->GetActiveWebContents();

  // Navigate to the non-web-accessible URL from chrome:// and
  // chrome-search:// pages.  Verify that the page loads correctly.
  GURL history_url(chrome::kChromeUIHistoryURL);
  GURL ntp_url(chrome::kChromeSearchLocalNtpUrl);
  ASSERT_TRUE(history_url.SchemeIs(content::kChromeUIScheme));
  ASSERT_TRUE(ntp_url.SchemeIs(chrome::kChromeSearchScheme));
  GURL start_urls[] = {history_url, ntp_url};
  for (size_t i = 0; i < base::size(start_urls); i++) {
    ui_test_utils::NavigateToURL(browser(), start_urls[i]);
    EXPECT_EQ(start_urls[i], tab->GetMainFrame()->GetLastCommittedURL());

    content::TestNavigationObserver observer(tab);
    ASSERT_TRUE(content::ExecuteScript(
        tab, "location.href = '" + extension_url.spec() + "';"));
    observer.Wait();
    EXPECT_EQ(extension_url, tab->GetMainFrame()->GetLastCommittedURL());
    std::string result;
    ASSERT_TRUE(content::ExecuteScriptAndExtractString(
        tab, "domAutomationController.send(document.body.innerText)", &result));
    EXPECT_EQ("HOWDIE!!!", result);
  }
}

#if defined(OS_CHROMEOS)

namespace {

aura::Window* GetCurrentWindow() {
  extensions::WindowController* controller = nullptr;
  for (auto* iter :
       extensions::WindowControllerList::GetInstance()->windows()) {
    if (iter->window()->IsActive()) {
      controller = iter;
      break;
    }
  }
  EXPECT_TRUE(controller);
  return controller->window()->GetNativeWindow();
}

ash::WindowPinType GetCurrentWindowPinType() {
  ash::WindowPinType type =
      GetCurrentWindow()->GetProperty(ash::kWindowPinTypeKey);
  return type;
}

void SetCurrentWindowPinType(ash::WindowPinType type) {
  GetCurrentWindow()->SetProperty(ash::kWindowPinTypeKey, type);
}

}  // namespace

IN_PROC_BROWSER_TEST_F(WindowOpenApiTest, OpenLockedFullscreenWindow) {
  ASSERT_TRUE(RunExtensionTestWithArg("locked_fullscreen/with_permission",
                                      "openLockedFullscreenWindow"))
      << message_;

  // Make sure the newly created window is "trusted pinned" (which means that
  // it's in locked fullscreen mode).
  EXPECT_EQ(ash::WindowPinType::kTrustedPinned, GetCurrentWindowPinType());
}

IN_PROC_BROWSER_TEST_F(WindowOpenApiTest, UpdateWindowToLockedFullscreen) {
  ASSERT_TRUE(RunExtensionTestWithArg("locked_fullscreen/with_permission",
                                      "updateWindowToLockedFullscreen"))
      << message_;

  // Make sure the current window is put into the "trusted pinned" state.
  EXPECT_EQ(ash::WindowPinType::kTrustedPinned, GetCurrentWindowPinType());
}

IN_PROC_BROWSER_TEST_F(WindowOpenApiTest, RemoveLockedFullscreenFromWindow) {
  // After locking the window, do a LockedFullscreenStateChanged so the
  // command_controller state catches up as well.
  SetCurrentWindowPinType(ash::WindowPinType::kTrustedPinned);
  browser()->command_controller()->LockedFullscreenStateChanged();

  ASSERT_TRUE(RunExtensionTestWithArg("locked_fullscreen/with_permission",
                                      "removeLockedFullscreenFromWindow"))
      << message_;

  // Make sure the current window is removed from locked-fullscreen state.
  EXPECT_EQ(ash::WindowPinType::kNone, GetCurrentWindowPinType());
}

// Make sure that commands disabling code works in locked fullscreen mode.
IN_PROC_BROWSER_TEST_F(WindowOpenApiTest, VerifyCommandsInLockedFullscreen) {
  // IDC_EXIT is always enabled in regular mode so it's a perfect candidate for
  // testing.
  EXPECT_TRUE(browser()->command_controller()->IsCommandEnabled(IDC_EXIT));
  ASSERT_TRUE(RunExtensionTestWithArg("locked_fullscreen/with_permission",
                                      "updateWindowToLockedFullscreen"))
      << message_;

  // IDC_EXIT should always be disabled in locked fullscreen.
  EXPECT_FALSE(browser()->command_controller()->IsCommandEnabled(IDC_EXIT));

  // Some other disabled commands.
  EXPECT_FALSE(browser()->command_controller()->IsCommandEnabled(IDC_FIND));
  EXPECT_FALSE(
      browser()->command_controller()->IsCommandEnabled(IDC_ZOOM_PLUS));

  // Verify some whitelisted commands.
  EXPECT_TRUE(browser()->command_controller()->IsCommandEnabled(IDC_COPY));
  EXPECT_TRUE(browser()->command_controller()->IsCommandEnabled(IDC_PASTE));
}

IN_PROC_BROWSER_TEST_F(WindowOpenApiTest,
                       OpenLockedFullscreenWindowWithoutPermission) {
  ASSERT_TRUE(RunExtensionTestWithArg("locked_fullscreen/without_permission",
                                      "openLockedFullscreenWindow"))
      << message_;

  // Make sure no new windows get created (so only the one created by default
  // exists) since the call to chrome.windows.create fails on the javascript
  // side.
  EXPECT_EQ(1u,
            extensions::WindowControllerList::GetInstance()->windows().size());
}

IN_PROC_BROWSER_TEST_F(WindowOpenApiTest,
                       UpdateWindowToLockedFullscreenWithoutPermission) {
  ASSERT_TRUE(RunExtensionTestWithArg("locked_fullscreen/without_permission",
                                      "updateWindowToLockedFullscreen"))
      << message_;

  // chrome.windows.update call fails since this extension doesn't have the
  // correct permission and hence the current window has NONE as WindowPinType.
  EXPECT_EQ(ash::WindowPinType::kNone, GetCurrentWindowPinType());
}

IN_PROC_BROWSER_TEST_F(WindowOpenApiTest,
                       RemoveLockedFullscreenFromWindowWithoutPermission) {
  SetCurrentWindowPinType(ash::WindowPinType::kTrustedPinned);
  browser()->command_controller()->LockedFullscreenStateChanged();

  ASSERT_TRUE(RunExtensionTestWithArg("locked_fullscreen/without_permission",
                                      "removeLockedFullscreenFromWindow"))
      << message_;

  // The current window is still locked-fullscreen.
  EXPECT_EQ(ash::WindowPinType::kTrustedPinned, GetCurrentWindowPinType());
}
#endif  // defined(OS_CHROMEOS)

#if !defined(OS_CHROMEOS)
// Loading an extension requiring the 'lockWindowFullscreenPrivate' permission
// on non Chrome OS platforms should always fail since the API is available only
// on Chrome OS.
IN_PROC_BROWSER_TEST_F(WindowOpenApiTest,
                       OpenLockedFullscreenWindowNonChromeOS) {
  const extensions::Extension* extension = LoadExtensionWithFlags(
      test_data_dir_.AppendASCII("locked_fullscreen/with_permission"),
      ExtensionBrowserTest::kFlagIgnoreManifestWarnings);
  ASSERT_TRUE(extension);
  EXPECT_EQ(1u, extension->install_warnings().size());
  EXPECT_EQ(std::string("'lockWindowFullscreenPrivate' "
                        "is not allowed for specified platform."),
            extension->install_warnings().front().message);
}
#endif

}  // namespace extensions
