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

#include "chrome/browser/chrome_content_browser_client.h"

#include <memory>
#include <string_view>
#include <vector>

#include "base/command_line.h"
#include "base/containers/fixed_flat_map.h"
#include "base/functional/bind.h"
#include "base/memory/raw_ptr.h"
#include "base/path_service.h"
#include "base/strings/strcat.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/test_future.h"
#include "build/build_config.h"
#include "chrome/browser/accessibility/page_colors_controller.h"
#include "chrome/browser/accessibility/page_colors_controller_factory.h"
#include "chrome/browser/browser_features.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/custom_handlers/protocol_handler_registry_factory.h"
#include "chrome/browser/enterprise/connectors/analysis/clipboard_request_handler.h"
#include "chrome/browser/enterprise/connectors/test/fake_clipboard_request_handler.h"
#include "chrome/browser/external_protocol/external_protocol_handler.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/search/instant_service.h"
#include "chrome/browser/search/instant_service_factory.h"
#include "chrome/browser/search/search.h"
#include "chrome/browser/themes/theme_service.h"
#include "chrome/browser/themes/theme_service_factory.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/search/instant_test_base.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/browser/ui/ui_features.h"
#include "chrome/common/chrome_features.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/url_constants.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/ui_test_utils.h"
#include "components/content_settings/core/browser/cookie_settings.h"
#include "components/content_settings/core/common/features.h"
#include "components/content_settings/core/common/pref_names.h"
#include "components/custom_handlers/protocol_handler.h"
#include "components/custom_handlers/protocol_handler_registry.h"
#include "components/enterprise/buildflags/buildflags.h"
#include "components/enterprise/data_controls/core/browser/test_utils.h"
#include "components/guest_view/browser/guest_view_base.h"
#include "components/guest_view/browser/guest_view_manager.h"
#include "components/guest_view/browser/guest_view_manager_delegate.h"
#include "components/guest_view/browser/test_guest_view_manager.h"
#include "components/network_session_configurator/common/network_switches.h"
#include "components/policy/core/common/cloud/cloud_policy_constants.h"
#include "components/policy/core/common/policy_pref_names.h"
#include "components/prefs/pref_service.h"
#include "components/privacy_sandbox/privacy_sandbox_attestations/privacy_sandbox_attestations.h"
#include "components/privacy_sandbox/privacy_sandbox_attestations/scoped_privacy_sandbox_attestations.h"
#include "components/privacy_sandbox/privacy_sandbox_features.h"
#include "components/safe_browsing/buildflags.h"
#include "components/site_isolation/site_isolation_policy.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/browser/navigation_controller.h"
#include "content/public/browser/navigation_entry.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/web_contents.h"
#include "content/public/common/content_client.h"
#include "content/public/common/content_features.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/url_utils.h"
#include "content/public/test/browser_test.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/fenced_frame_test_util.h"
#include "content/public/test/frame_test_utils.h"
#include "content/public/test/test_devtools_protocol_client.h"
#include "content/public/test/test_frame_navigation_observer.h"
#include "content/public/test/test_navigation_observer.h"
#include "content/public/test/url_loader_interceptor.h"
#include "extensions/browser/api/extensions_api_client.h"
#include "net/dns/mock_host_resolver.h"
#include "net/http/http_status_code.h"
#include "net/test/embedded_test_server/controllable_http_response.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
#include "net/test/embedded_test_server/http_request.h"
#include "net/test/embedded_test_server/http_response.h"
#include "services/network/public/cpp/url_loader_factory_builder.h"
#include "third_party/blink/public/mojom/webpreferences/web_preferences.mojom.h"
#include "ui/base/clipboard/clipboard_monitor.h"
#include "ui/base/data_transfer_policy/data_transfer_endpoint.h"
#include "ui/color/color_provider.h"
#include "ui/color/color_provider_key.h"
#include "ui/color/color_provider_manager.h"
#include "ui/color/color_provider_source.h"
#include "ui/color/color_provider_utils.h"
#include "ui/native_theme/native_theme.h"
#include "ui/native_theme/test_native_theme.h"
#include "url/gurl.h"
#include "url/origin.h"

#if BUILDFLAG(ENABLE_EXTENSIONS)
#include "extensions/common/constants.h"
#include "extensions/common/extension_urls.h"
#include "url/url_constants.h"
#endif

#if BUILDFLAG(ENABLE_EXTENSIONS_CORE)
#include "extensions/common/extension_features.h"
#endif

#if BUILDFLAG(IS_MAC)
#include "chrome/test/base/launchservices_utils_mac.h"
#endif

#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_WIN)
#include "third_party/blink/public/common/features.h"
#endif  //  BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_WIN)

#if BUILDFLAG(ENTERPRISE_CONTENT_ANALYSIS)
#include "base/files/scoped_temp_dir.h"
#include "base/test/bind.h"
#include "base/threading/scoped_blocking_call.h"
#include "chrome/browser/enterprise/connectors/connectors_service.h"
#include "chrome/browser/enterprise/connectors/test/deep_scanning_test_utils.h"  // nogncheck
#include "chrome/browser/enterprise/connectors/test/fake_content_analysis_delegate.h"  // nogncheck
#include "ui/base/clipboard/clipboard_format_type.h"

#if BUILDFLAG(ENTERPRISE_LOCAL_CONTENT_ANALYSIS)
#include "chrome/browser/enterprise/connectors/test/fake_content_analysis_sdk_manager.h"  // nogncheck
#endif  // BUILDFLAG(ENTERPRISE_LOCAL_CONTENT_ANALYSIS)

#endif  // BUILDFLAG(ENTERPRISE_CONTENT_ANALYSIS)

#if BUILDFLAG(ENABLE_GLIC)
#include "chrome/browser/glic/test_support/glic_test_environment.h"
#include "chrome/browser/glic/test_support/glic_test_util.h"
#endif

namespace {

std::vector<uint8_t> StringToVector(const std::string& str) {
  return std::vector<uint8_t>(str.begin(), str.end());
}

// Use a test class with SetUpCommandLine to ensure the flag is sent to the
// first renderer process.
class ChromeContentBrowserClientBrowserTest : public InProcessBrowserTest {
 public:
  void SetUpCommandLine(base::CommandLine* command_line) override {
    content::IsolateAllSitesForTesting(command_line);
  }
};

// Test that a basic navigation works in --site-per-process mode.  This prevents
// regressions when that mode calls out into the ChromeContentBrowserClient,
// such as http://crbug.com/164223.
IN_PROC_BROWSER_TEST_F(ChromeContentBrowserClientBrowserTest,
                       SitePerProcessNavigation) {
  ASSERT_TRUE(embedded_test_server()->Start());
  const GURL url(embedded_test_server()->GetURL("/title1.html"));

  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));
  content::NavigationEntry* entry = browser()
                                        ->tab_strip_model()
                                        ->GetWebContentsAt(0)
                                        ->GetController()
                                        .GetLastCommittedEntry();

  ASSERT_TRUE(entry != nullptr);
  EXPECT_EQ(url, entry->GetURL());
  EXPECT_EQ(url, entry->GetVirtualURL());
}

// Helper class to mark "https://ntp.com/" as an isolated origin.
class IsolatedOriginNTPBrowserTest : public InProcessBrowserTest,
                                     public InstantTestBase {
 public:
  void SetUpCommandLine(base::CommandLine* command_line) override {
    ASSERT_TRUE(https_test_server().InitializeAndListen());

    // Mark ntp.com (with an appropriate port from the test server) as an
    // isolated origin.
    GURL isolated_url(https_test_server().GetURL("ntp.com", "/"));
    command_line->AppendSwitchASCII(switches::kIsolateOrigins,
                                    isolated_url.spec());
    command_line->AppendSwitch(switches::kIgnoreCertificateErrors);
  }

  void SetUpOnMainThread() override {
    InProcessBrowserTest::SetUpOnMainThread();
    host_resolver()->AddRule("*", "127.0.0.1");
    https_test_server().StartAcceptingConnections();
  }
};

// Verifies that when the remote NTP URL has an origin which is also marked as
// an isolated origin (i.e., requiring a dedicated process), the NTP URL
// still loads successfully, and the resulting process is marked as an Instant
// process.  See https://crbug.com/755595.
IN_PROC_BROWSER_TEST_F(IsolatedOriginNTPBrowserTest,
                       IsolatedOriginDoesNotInterfereWithNTP) {
  GURL base_url =
      https_test_server().GetURL("ntp.com", "/instant_extended.html");
  GURL ntp_url =
      https_test_server().GetURL("ntp.com", "/instant_extended_ntp.html");
  SetupInstant(browser()->profile(), base_url, ntp_url);

  // Sanity check that a SiteInstance for a generic ntp.com URL requires a
  // dedicated process.
  content::BrowserContext* context = browser()->profile();
  GURL isolated_url(https_test_server().GetURL("ntp.com", "/title1.html"));
  scoped_refptr<content::SiteInstance> site_instance =
      content::SiteInstance::CreateForURL(context, isolated_url);
  EXPECT_TRUE(site_instance->RequiresDedicatedProcess());
  // Verify the isolated origin does not receive an NTP site URL scheme.
  EXPECT_FALSE(
      site_instance->GetSiteURL().SchemeIs(chrome::kChromeSearchScheme));

  // The site URL for the NTP URL should resolve to a chrome-search:// URL via
  // GetEffectiveURL(), even if the NTP URL matches an isolated origin.
  scoped_refptr<content::SiteInstance> ntp_site_instance =
      content::SiteInstance::CreateForURL(context, ntp_url);
  EXPECT_TRUE(
      ntp_site_instance->GetSiteURL().SchemeIs(chrome::kChromeSearchScheme));

  // Navigate to the NTP URL and verify that the resulting process is marked as
  // an Instant process.
  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), ntp_url));
  content::WebContents* contents =
      browser()->tab_strip_model()->GetActiveWebContents();
  InstantService* instant_service =
      InstantServiceFactory::GetForProfile(browser()->profile());
  EXPECT_TRUE(instant_service->IsInstantProcess(
      contents->GetPrimaryMainFrame()->GetProcess()->GetDeprecatedID()));
  EXPECT_EQ(contents->GetPrimaryMainFrame()->GetSiteInstance()->GetSiteURL(),
            ntp_site_instance->GetSiteURL());

  // Navigating to a non-NTP URL on ntp.com should not result in an Instant
  // process.
  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), isolated_url));
  EXPECT_FALSE(instant_service->IsInstantProcess(
      contents->GetPrimaryMainFrame()->GetProcess()->GetDeprecatedID()));
  EXPECT_EQ(contents->GetPrimaryMainFrame()->GetSiteInstance()->GetSiteURL(),
            site_instance->GetSiteURL());
}

// Helper class to test window creation from NTP.
class OpenWindowFromNTPBrowserTest : public InProcessBrowserTest,
                                     public InstantTestBase {
 public:
  void SetUpCommandLine(base::CommandLine* command_line) override {
    command_line->AppendSwitch(switches::kIgnoreCertificateErrors);
  }

  void SetUpOnMainThread() override {
    InProcessBrowserTest::SetUpOnMainThread();
    host_resolver()->AddRule("*", "127.0.0.1");
    ASSERT_TRUE(https_test_server().InitializeAndListen());
    https_test_server().StartAcceptingConnections();
  }
};

// Test checks that navigations from NTP tab to URLs with same host as NTP but
// different path do not reuse NTP SiteInstance. See https://crbug.com/859062
// for details.
IN_PROC_BROWSER_TEST_F(OpenWindowFromNTPBrowserTest,
                       TransferFromNTPCreateNewTab) {
  GURL search_url =
      https_test_server().GetURL("ntp.com", "/instant_extended.html");
  GURL ntp_url =
      https_test_server().GetURL("ntp.com", "/instant_extended_ntp.html");
  SetupInstant(browser()->profile(), search_url, ntp_url);

  // Navigate to the NTP URL and verify that the resulting process is marked as
  // an Instant process.
  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), ntp_url));
  content::WebContents* ntp_tab =
      browser()->tab_strip_model()->GetActiveWebContents();
  InstantService* instant_service =
      InstantServiceFactory::GetForProfile(browser()->profile());
  EXPECT_TRUE(instant_service->IsInstantProcess(
      ntp_tab->GetPrimaryMainFrame()->GetProcess()->GetDeprecatedID()));

  // Execute script that creates new window from ntp tab with
  // ntp.com/title1.html as target url. Host is same as remote-ntp host, yet
  // path is different.
  GURL generic_url(https_test_server().GetURL("ntp.com", "/title1.html"));
  content::TestNavigationObserver opened_tab_observer(nullptr);
  opened_tab_observer.StartWatchingNewWebContents();
  EXPECT_TRUE(ExecJs(ntp_tab, "window.open('" + generic_url.spec() + "');"));
  opened_tab_observer.Wait();
  ASSERT_EQ(2, browser()->tab_strip_model()->count());

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

  // Wait until newly opened tab is fully loaded.
  EXPECT_TRUE(WaitForLoadStop(opened_tab));

  EXPECT_NE(opened_tab, ntp_tab);
  EXPECT_EQ(generic_url, opened_tab->GetLastCommittedURL());
  // New created tab should not reside in an Instant process.
  EXPECT_FALSE(instant_service->IsInstantProcess(
      opened_tab->GetPrimaryMainFrame()->GetProcess()->GetDeprecatedID()));
}

// Test for the state of Forced Colors Mode for a given WebContents across
// various scenarios.
class ForcedColorsTest : public testing::WithParamInterface<bool>,
                         public InProcessBrowserTest {
 protected:
  ForcedColorsTest() : theme_client_(&test_theme_) {}

  ~ForcedColorsTest() override {
    CHECK_EQ(&theme_client_, SetBrowserClientForTesting(original_client_));
  }

  static bool ForcedColorsActive() { return GetParam(); }

  void SetUpCommandLine(base::CommandLine* command_line) override {
    command_line->AppendSwitchASCII(switches::kEnableBlinkFeatures,
                                    "ForcedColors");
  }

  void SetUpOnMainThread() override {
    InProcessBrowserTest::SetUpOnMainThread();
    original_client_ = SetBrowserClientForTesting(&theme_client_);
  }

 protected:
  ui::TestNativeTheme test_theme_;

 private:
  raw_ptr<content::ContentBrowserClient> original_client_ = nullptr;

  class ChromeContentBrowserClientWithWebTheme
      : public ChromeContentBrowserClient {
   public:
    explicit ChromeContentBrowserClientWithWebTheme(
        const ui::NativeTheme* theme)
        : theme_(theme) {}

   protected:
    const ui::NativeTheme* GetWebTheme() const override { return theme_; }

   private:
    const raw_ptr<const ui::NativeTheme> theme_;
  };

  ChromeContentBrowserClientWithWebTheme theme_client_;
};

IN_PROC_BROWSER_TEST_P(ForcedColorsTest, ForcedColors) {
  test_theme_.set_forced_colors(ForcedColorsActive());
  browser()
      ->tab_strip_model()
      ->GetActiveWebContents()
      ->OnWebPreferencesChanged();
  ASSERT_TRUE(ui_test_utils::NavigateToURL(
      browser(), ui_test_utils::GetTestUrl(
                     base::FilePath(base::FilePath::kCurrentDirectory),
                     base::FilePath(FILE_PATH_LITERAL("forced-colors.html")))));
  std::u16string tab_title;
  const char* expected = ForcedColorsActive() ? "active" : "none";
  ASSERT_TRUE(ui_test_utils::GetCurrentTabTitle(browser(), &tab_title));
  EXPECT_EQ(base::ASCIIToUTF16(expected), tab_title);
}

IN_PROC_BROWSER_TEST_P(ForcedColorsTest, ForcedColorsWithBlockList) {
  test_theme_.set_forced_colors(ForcedColorsActive());

  const char* url = "https://foo.com";
  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), GURL(url)));

  // Add url to the page colors block list.
  base::Value::List list;
  list.Append(url);
  Profile* profile = browser()->profile();
  profile->GetPrefs()->SetList(prefs::kPageColorsBlockList, list.Clone());
  browser()
      ->tab_strip_model()
      ->GetActiveWebContents()
      ->OnWebPreferencesChanged();

  // Forced colors should be `none` when a site is added to the block list.
  EXPECT_EQ(true, EvalJs(browser()->tab_strip_model()->GetActiveWebContents(),
                         base::StringPrintf(
                             "window.matchMedia('(forced-colors: %s)').matches",
                             "none")));

  // Remove url from the page colors block list.
  list.EraseValue(base::Value(url));
  profile->GetPrefs()->SetList(prefs::kPageColorsBlockList, list.Clone());
  browser()
      ->tab_strip_model()
      ->GetActiveWebContents()
      ->OnWebPreferencesChanged();

  // Forced colors should respect the OS when a site is removed from the block
  // list.
  const char* expected = ForcedColorsActive() ? "active" : "none";
  EXPECT_EQ(true, EvalJs(browser()->tab_strip_model()->GetActiveWebContents(),
                         base::StringPrintf(
                             "window.matchMedia('(forced-colors: %s)').matches",
                             expected)));
}

INSTANTIATE_TEST_SUITE_P(
    All,
    ForcedColorsTest,
    testing::Bool(),
    [](const ::testing::TestParamInfo<ForcedColorsTest::ParamType>& info) {
      return base::StrCat({"ForcedColors", info.param ? "Active" : "Inactive"});
    });

// Helper class to test the Page colors feature. Page colors is a feature that
// simulates Forced colors mode via a browser setting.
using PageColorsBrowserClientTest = InProcessBrowserTest;

IN_PROC_BROWSER_TEST_F(PageColorsBrowserClientTest,
                       PageColorsAffectsWebContents) {
  PageColorsControllerFactory::GetForProfile(browser()->profile())
      ->SetRequestedPageColors(PageColors::kDusk);

  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), GURL("http://foo.com")));

  // Check that the page colors are applied when Forced Colors is enabled. For
  // the Dusk theme, the color value for Window is 0x2D3236 which corresponds to
  // rgb(45, 50, 54).
  std::string expected_bg_color = "rgb(45, 50, 54)";
  EXPECT_EQ(expected_bg_color,
            EvalJs(browser()->tab_strip_model()->GetActiveWebContents(),
                   "window.getComputedStyle(document.body).getPropertyValue('"
                   "background-color').toString()"));
}

IN_PROC_BROWSER_TEST_F(PageColorsBrowserClientTest,
                       PageColorsAffectsCssPseudoElements) {
  PageColorsControllerFactory::GetForProfile(browser()->profile())
      ->SetRequestedPageColors(PageColors::kDesert);

  ASSERT_TRUE(ui_test_utils::NavigateToURL(
      browser(), ui_test_utils::GetTestUrl(
                     base::FilePath(base::FilePath::kCurrentDirectory),
                     base::FilePath(FILE_PATH_LITERAL("system-colors.html")))));

  // Check that the right system color is applied for Pseudo elements when
  // Forced Colors is enabled. For the Desert theme, the color value for
  // WindowText is 0x3D3D3D which corresponds to rgb(61, 61, 61).
  std::string expected_element_color = "rgb(61, 61, 61)";
  EXPECT_EQ(expected_element_color,
            EvalJs(browser()->tab_strip_model()->GetActiveWebContents(),
                   "window.getComputedStyle(document.getElementById('icon'), "
                   "'::before')."
                   "getPropertyValue('color').toString()"));
}

// Tests for the preferred color scheme for a given WebContents. The first param
// controls whether the web NativeTheme is light or dark the second controls
// whether the color mode on the associated color provider is light or dark.
class PrefersColorSchemeTest
    : public testing::WithParamInterface<std::tuple<bool, bool>>,
      public InProcessBrowserTest {
 public:
  ~PrefersColorSchemeTest() override {
    CHECK_EQ(&theme_client_, SetBrowserClientForTesting(original_client_));
  }

  void SetUpOnMainThread() override {
    InProcessBrowserTest::SetUpOnMainThread();

    original_client_ = SetBrowserClientForTesting(&theme_client_);
    test_theme_.SetPreferredColorScheme(
        DarkOs() ? ui::NativeTheme::PreferredColorScheme::kDark
                 : ui::NativeTheme::PreferredColorScheme::kLight);

#if BUILDFLAG(ENABLE_GLIC)
    embedded_test_server()->ServeFilesFromDirectory(
        base::PathService::CheckedGet(base::DIR_ASSETS)
            .AppendASCII("gen/chrome/test/data/webui/glic/"));
    ASSERT_TRUE(embedded_test_server()->Start());
    auto* command_line = base::CommandLine::ForCurrentProcess();
    command_line->AppendSwitchASCII(
        ::switches::kGlicGuestURL,
        embedded_test_server()->GetURL("/glic/test_client/index.html").spec());
#endif

    guest_view_manager_ =
        guest_view_manager_factory_.GetOrCreateTestGuestViewManager(
            browser()->profile(), extensions::ExtensionsAPIClient::Get()
                                      ->CreateGuestViewManagerDelegate());

    auto* const web_contents =
        browser()->tab_strip_model()->GetActiveWebContents();
    web_contents->SetColorProviderSource(&color_provider_source_);
    web_contents->OnWebPreferencesChanged();
  }

  void TearDownOnMainThread() override {
    guest_view_manager_ = nullptr;
    InProcessBrowserTest::TearDownOnMainThread();
  }

 protected:
  std::string_view ExpectedColorScheme() const {
    // Most web content should follow the browser theme, with the exception of
    // non-WebUI incognito pages, which follow the device theme directly.
    const auto* const web_contents =
        browser()->tab_strip_model()->GetActiveWebContents();
    const bool use_os_theme =
        browser()->profile()->IsIncognitoProfile() &&
        !web_contents->GetLastCommittedURL().SchemeIs(content::kChromeUIScheme);
    const bool dark_mode = use_os_theme ? DarkOs() : DarkColorProvider();
    return dark_mode ? "dark" : "light";
  }

  guest_view::TestGuestViewManager* guest_view_manager() const {
    return guest_view_manager_;
  }

  ui::TestNativeTheme test_theme_;

 private:
  class ChromeContentBrowserClientWithWebTheme
      : public ChromeContentBrowserClient {
   public:
    explicit ChromeContentBrowserClientWithWebTheme(
        const ui::NativeTheme* theme)
        : theme_(theme) {}

   protected:
    const ui::NativeTheme* GetWebTheme() const override { return theme_; }

   private:
    const raw_ptr<const ui::NativeTheme> theme_;
  };

  class MockColorProviderSource : public ui::ColorProviderSource {
   public:
    explicit MockColorProviderSource(bool is_dark) {
      key_.color_mode = is_dark ? ui::ColorProviderKey::ColorMode::kDark
                                : ui::ColorProviderKey::ColorMode::kLight;
    }
    MockColorProviderSource(const MockColorProviderSource&) = delete;
    MockColorProviderSource& operator=(const MockColorProviderSource&) = delete;
    ~MockColorProviderSource() override = default;

    // ui::ColorProviderSource:
    const ui::ColorProvider* GetColorProvider() const override {
      return &provider_;
    }

    ui::RendererColorMap GetRendererColorMap(
        ui::ColorProviderKey::ColorMode color_mode,
        ui::ColorProviderKey::ForcedColors forced_colors) const override {
      ui::ColorProviderKey key = GetColorProviderKey();
      key.color_mode = color_mode;
      key.forced_colors = forced_colors;
      return ui::CreateRendererColorMap(
          *ui::ColorProviderManager::Get().GetColorProviderFor(key));
    }

    ui::ColorProviderKey GetColorProviderKey() const override { return key_; }

   private:
    ui::ColorProvider provider_;
    ui::ColorProviderKey key_;
  };

  static bool DarkOs() { return std::get<0>(GetParam()); }
  static bool DarkColorProvider() { return std::get<1>(GetParam()); }

  raw_ptr<content::ContentBrowserClient> original_client_ = nullptr;
  ChromeContentBrowserClientWithWebTheme theme_client_{&test_theme_};
  MockColorProviderSource color_provider_source_{DarkColorProvider()};
#if BUILDFLAG(ENABLE_GLIC)
  glic::GlicTestEnvironment glic_test_environment_;
#endif
  guest_view::TestGuestViewManagerFactory guest_view_manager_factory_;
  raw_ptr<guest_view::TestGuestViewManager> guest_view_manager_ = nullptr;
};

IN_PROC_BROWSER_TEST_P(PrefersColorSchemeTest, PrefersColorScheme) {
  ASSERT_TRUE(ui_test_utils::NavigateToURL(
      browser(),
      ui_test_utils::GetTestUrl(
          base::FilePath(base::FilePath::kCurrentDirectory),
          base::FilePath(FILE_PATH_LITERAL("prefers-color-scheme.html")))));
  std::u16string tab_title;
  ASSERT_TRUE(ui_test_utils::GetCurrentTabTitle(browser(), &tab_title));
  EXPECT_EQ(base::ASCIIToUTF16(ExpectedColorScheme()), tab_title);
}

IN_PROC_BROWSER_TEST_P(PrefersColorSchemeTest, FeatureOverridesChromeSchemes) {
  ASSERT_TRUE(ui_test_utils::NavigateToURL(
      browser(), GURL(chrome::kChromeUIDownloadsURL)));

  EXPECT_EQ(
      true,
      EvalJs(browser()->tab_strip_model()->GetActiveWebContents(),
             base::StringPrintf(
                 "window.matchMedia('(prefers-color-scheme: %s)').matches",
                 ExpectedColorScheme())));
}

#if BUILDFLAG(ENABLE_GLIC)
IN_PROC_BROWSER_TEST_P(PrefersColorSchemeTest, PrefersColorSchemeGlic) {
  ASSERT_TRUE(
      ui_test_utils::NavigateToURL(browser(), GURL(chrome::kChromeUIGlicURL)));

  guest_view::GuestViewBase* guest_view =
      guest_view_manager()->WaitForSingleGuestViewCreated();
  // Intentionally ignore the return value. It seems that on Windows and Linux
  // the guest contents could have already been loaded by the time we get here.
  std::ignore = guest_view_manager()->WaitUntilAttachedAndLoaded(guest_view);

  EXPECT_EQ(
      true,
      EvalJs(guest_view->GetGuestMainFrame(),
             base::StringPrintf(
                 "window.matchMedia('(prefers-color-scheme: %s)').matches",
                 ExpectedColorScheme())));
}
#endif

#if BUILDFLAG(ENABLE_EXTENSIONS)
IN_PROC_BROWSER_TEST_P(PrefersColorSchemeTest, FeatureOverridesPdfUI) {
  std::string pdf_extension_url(extensions::kExtensionScheme);
  pdf_extension_url.append(url::kStandardSchemeSeparator);
  pdf_extension_url.append(extension_misc::kPdfExtensionId);
  GURL pdf_index = GURL(pdf_extension_url).Resolve("/index.html");
  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), pdf_index));

  EXPECT_EQ(
      true,
      EvalJs(browser()->tab_strip_model()->GetActiveWebContents(),
             base::StringPrintf(
                 "window.matchMedia('(prefers-color-scheme: %s)').matches",
                 ExpectedColorScheme())));
}
#endif

INSTANTIATE_TEST_SUITE_P(
    All,
    PrefersColorSchemeTest,
    testing::Combine(testing::Bool(), testing::Bool()),
    [](const ::testing::TestParamInfo<PrefersColorSchemeTest::ParamType>&
           info) {
      return base::StrCat({std::get<0>(info.param) ? "Dark" : "Light", "OS_",
                           std::get<1>(info.param) ? "Dark" : "Light",
                           "ColorProvider"});
    });

class PreferredRootScrollbarColorSchemeChromeClientTest
    : public testing::WithParamInterface<std::tuple<bool, bool>>,
      public InProcessBrowserTest {
 public:
  PreferredRootScrollbarColorSchemeChromeClientTest()
      : theme_color_(DarkMode() ? SK_ColorDKGRAY : SK_ColorLTGRAY) {
#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_WIN)
    feature_list_.InitAndEnableFeature(
        blink::features::kRootScrollbarFollowsBrowserTheme);
#endif  //  BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_WIN)
  }

  void SetUpOnMainThread() override {
    InProcessBrowserTest::SetUpOnMainThread();
    original_client_ = SetBrowserClientForTesting(&theme_client_);
    const auto color_scheme =
        DarkMode() ? ui::NativeTheme::PreferredColorScheme::kDark
                   : ui::NativeTheme::PreferredColorScheme::kLight;
    test_theme_.SetPreferredColorScheme(color_scheme);
    ui::NativeTheme::GetInstanceForNativeUi()->set_preferred_color_scheme(
        color_scheme);
    ThemeService* const theme_service =
        ThemeServiceFactory::GetForProfile(browser()->profile());
    if (UsesCustomTheme()) {
      // Browser themes adapt their hue to match the used color scheme (light
      // or dark), however autogenerated themes don't take color schemes into
      // consideration. So we select which color to use based on the color
      // scheme to simulate this behavior.
      theme_service->BuildAutogeneratedThemeFromColor(theme_color_);
    } else {
      theme_service->UseDefaultTheme();
    }
  }

  ~PreferredRootScrollbarColorSchemeChromeClientTest() override {
    CHECK_EQ(&theme_client_, SetBrowserClientForTesting(original_client_));
  }

 protected:
  blink::mojom::PreferredColorScheme ExpectedColorScheme() const {
    return DarkMode() ? blink::mojom::PreferredColorScheme::kDark
                      : blink::mojom::PreferredColorScheme::kLight;
  }

  bool ThemeColorMatches() const {
    const std::optional<SkColor> root_scrollbar_pref =
        browser()
            ->tab_strip_model()
            ->GetActiveWebContents()
            ->GetOrCreateWebPreferences()
            .root_scrollbar_theme_color;
    // If not using a custom theme, `root_scrollbar_theme_color` shouldn't be
    // set.
    if (!UsesCustomTheme()) {
      return !root_scrollbar_pref.has_value();
    }
    EXPECT_TRUE(root_scrollbar_pref.has_value());
    const SkColor root_scrollbar_color = root_scrollbar_pref.value();
    // `root_scrollbar_theme_color` is set based off the toolbar color, which is
    // generated using the theme's color. Because of this, we can't directly
    // compare equality between the two colors and we check that they are
    // similar enough.
    const double r_diff =
        std::abs(SkColorGetR(root_scrollbar_color) -
                 static_cast<double>(SkColorGetR(theme_color_)));
    const double g_diff =
        std::abs(SkColorGetG(root_scrollbar_color) -
                 static_cast<double>(SkColorGetG(theme_color_)));
    const double b_diff =
        std::abs(SkColorGetB(root_scrollbar_color) -
                 static_cast<double>(SkColorGetB(theme_color_)));

    const int kMaxDiff = 20;
    return r_diff < kMaxDiff && b_diff < kMaxDiff && g_diff < kMaxDiff;
  }

 private:
  class ChromeContentBrowserClientWithWebTheme
      : public ChromeContentBrowserClient {
   public:
    explicit ChromeContentBrowserClientWithWebTheme(
        const ui::NativeTheme* theme)
        : theme_(theme) {}

   protected:
    const ui::NativeTheme* GetWebTheme() const override { return theme_; }

   private:
    const raw_ptr<const ui::NativeTheme> theme_;
  };

  static bool DarkMode() { return std::get<0>(GetParam()); }
  static bool UsesCustomTheme() { return std::get<1>(GetParam()); }

  raw_ptr<content::ContentBrowserClient> original_client_ = nullptr;
  ui::TestNativeTheme test_theme_;
  ChromeContentBrowserClientWithWebTheme theme_client_{&test_theme_};
  const SkColor theme_color_;
  base::test::ScopedFeatureList feature_list_;
};

// This test verifies that the preferred color scheme for root scrollbars is set
// appropriately following the web content's color scheme and the presence of
// a custom theme.
IN_PROC_BROWSER_TEST_P(PreferredRootScrollbarColorSchemeChromeClientTest,
                       ScrollbarFollowsPreferredColorScheme) {
  auto* const web_contents =
      browser()->tab_strip_model()->GetActiveWebContents();
  EXPECT_EQ(web_contents->GetOrCreateWebPreferences()
                .preferred_root_scrollbar_color_scheme,
            ExpectedColorScheme());
}

#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_WIN)
// This test verifies that the root scrollbar color theme is set correctly only
// when using a custom theme.
IN_PROC_BROWSER_TEST_P(PreferredRootScrollbarColorSchemeChromeClientTest,
                       VerifyRootScrollbarColorTheme) {
  EXPECT_TRUE(ThemeColorMatches());
}
#endif  //  BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_WIN)

INSTANTIATE_TEST_SUITE_P(
    All,
    PreferredRootScrollbarColorSchemeChromeClientTest,
    testing::Combine(testing::Bool(), testing::Bool()),
    [](const ::testing::TestParamInfo<
        PreferredRootScrollbarColorSchemeChromeClientTest::ParamType>& info) {
      return base::StrCat({std::get<0>(info.param) ? "Dark" : "Light", "Mode_",
                           std::get<1>(info.param) ? "Custom" : "Default",
                           "Theme"});
    });

class PrefersContrastTest
    : public testing::WithParamInterface<ui::NativeTheme::PreferredContrast>,
      public InProcessBrowserTest {
 public:
  ~PrefersContrastTest() override {
    CHECK_EQ(&theme_client_, SetBrowserClientForTesting(original_client_));
  }

  void SetUpCommandLine(base::CommandLine* command_line) override {
    command_line->AppendSwitchASCII(switches::kEnableBlinkFeatures,
                                    "PrefersContrast");
    command_line->AppendSwitchASCII(switches::kEnableBlinkFeatures,
                                    "ForcedColors");
  }

  void SetUpOnMainThread() override {
    InProcessBrowserTest::SetUpOnMainThread();
    original_client_ = SetBrowserClientForTesting(&theme_client_);
    test_theme_.SetPreferredContrast(PreferredContrast());
    browser()
        ->tab_strip_model()
        ->GetActiveWebContents()
        ->OnWebPreferencesChanged();
  }

 protected:
  std::string_view ExpectedPrefersContrast() const {
    switch (PreferredContrast()) {
      case ui::NativeTheme::PreferredContrast::kNoPreference:
        return "no-preference";
      case ui::NativeTheme::PreferredContrast::kMore:
        return "more";
      case ui::NativeTheme::PreferredContrast::kLess:
        return "less";
      case ui::NativeTheme::PreferredContrast::kCustom:
        return "custom";
    }
  }

  ui::TestNativeTheme test_theme_;

 private:
  class ChromeContentBrowserClientWithWebTheme
      : public ChromeContentBrowserClient {
   public:
    explicit ChromeContentBrowserClientWithWebTheme(
        const ui::NativeTheme* theme)
        : theme_(theme) {}

   protected:
    const ui::NativeTheme* GetWebTheme() const override { return theme_; }

   private:
    const raw_ptr<const ui::NativeTheme> theme_;
  };

  static ui::NativeTheme::PreferredContrast PreferredContrast() {
    return GetParam();
  }

  raw_ptr<content::ContentBrowserClient> original_client_ = nullptr;
  ChromeContentBrowserClientWithWebTheme theme_client_{&test_theme_};
};

IN_PROC_BROWSER_TEST_P(PrefersContrastTest, PrefersContrast) {
  ASSERT_TRUE(ui_test_utils::NavigateToURL(
      browser(),
      ui_test_utils::GetTestUrl(
          base::FilePath(base::FilePath::kCurrentDirectory),
          base::FilePath(FILE_PATH_LITERAL("prefers-contrast.html")))));
  std::u16string tab_title;
  ASSERT_TRUE(ui_test_utils::GetCurrentTabTitle(browser(), &tab_title));
  EXPECT_EQ(base::ASCIIToUTF16(ExpectedPrefersContrast()), tab_title);
}

INSTANTIATE_TEST_SUITE_P(
    All,
    PrefersContrastTest,
    testing::Values(ui::NativeTheme::PreferredContrast::kNoPreference,
                    ui::NativeTheme::PreferredContrast::kMore,
                    ui::NativeTheme::PreferredContrast::kLess,
                    ui::NativeTheme::PreferredContrast::kCustom),
    ([](const ::testing::TestParamInfo<PrefersContrastTest::ParamType>& info) {
      using enum ui::NativeTheme::PreferredContrast;
      static constexpr auto kContrastValues =
          base::MakeFixedFlatMap<ui::NativeTheme::PreferredContrast,
                                 std::string_view>({{kNoPreference, "Default"},
                                                    {kMore, "More"},
                                                    {kLess, "Less"},
                                                    {kCustom, "Custom"}});
      return base::StrCat({kContrastValues.at(info.param), "Contrast"});
    }));

class ProtocolHandlerTest : public InProcessBrowserTest {
 public:
  void SetUpOnMainThread() override {
    InProcessBrowserTest::SetUpOnMainThread();
    host_resolver()->AddRule("*", "127.0.0.1");
    ASSERT_TRUE(embedded_test_server()->Start());
  }

 protected:
  void AddProtocolHandler(const std::string& scheme,
                          const std::string& redirect_template) {
    protocol_handler_registry()->OnAcceptRegisterProtocolHandler(
        custom_handlers::ProtocolHandler::CreateProtocolHandler(
            scheme, GURL(redirect_template)));
  }

  custom_handlers::ProtocolHandlerRegistry* protocol_handler_registry() {
    return ProtocolHandlerRegistryFactory::GetInstance()->GetForBrowserContext(
        browser()->profile());
  }
};

// TODO(crbug.com/40917055): Enable test when MacOS flake is fixed.
#if BUILDFLAG(IS_MAC)
#define MAYBE_CustomHandler DISABLED_CustomHandler
#else
#define MAYBE_CustomHandler CustomHandler
#endif
IN_PROC_BROWSER_TEST_F(ProtocolHandlerTest, MAYBE_CustomHandler) {
#if BUILDFLAG(IS_MAC)
  ASSERT_TRUE(test::RegisterAppWithLaunchServices());
#endif
  AddProtocolHandler("news", "https://abc.xyz/?url=%s");

  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), GURL("news:something")));

  std::u16string expected_title = u"abc.xyz";
  content::TitleWatcher title_watcher(
      browser()->tab_strip_model()->GetActiveWebContents(), expected_title);
  EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle());
}

// This is a regression test for crbug.com/969177.
IN_PROC_BROWSER_TEST_F(ProtocolHandlerTest, HandlersIgnoredWhenDisabled) {
  AddProtocolHandler("bitcoin", "https://abc.xyz/?url=%s");
  protocol_handler_registry()->Disable();

  ASSERT_TRUE(
      ui_test_utils::NavigateToURL(browser(), GURL("bitcoin:something")));

  std::u16string tab_title;
  ASSERT_TRUE(ui_test_utils::GetCurrentTabTitle(browser(), &tab_title));
  EXPECT_EQ(u"about:blank", tab_title);
}

#if BUILDFLAG(IS_CHROMEOS)
// Tests that if a protocol handler is registered for a scheme, an external
// program (another Chrome tab in this case) is not launched to handle the
// navigation. This is a regression test for crbug.com/963133.
IN_PROC_BROWSER_TEST_F(ProtocolHandlerTest, ExternalProgramNotLaunched) {
  ASSERT_TRUE(
      ui_test_utils::NavigateToURL(browser(), GURL("mailto:bob@example.com")));

  // If an external program (Chrome) was launched, it will result in a second
  // tab being opened.
  EXPECT_EQ(1, browser()->tab_strip_model()->count());
  // Make sure the protocol handler redirected the navigation.
  std::u16string expected_title = u"mail.google.com";
  content::TitleWatcher title_watcher(
      browser()->tab_strip_model()->GetActiveWebContents(), expected_title);
  EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle());
}

namespace {
class FakeExternalProtocolHandlerWorker
    : public shell_integration::DefaultSchemeClientWorker {
 public:
  FakeExternalProtocolHandlerWorker(
      const GURL& url,
      shell_integration::DefaultWebClientState os_state,
      const std::u16string& program_name)
      : shell_integration::DefaultSchemeClientWorker(url),
        os_state_(os_state),
        program_name_(program_name) {}

 protected:
  ~FakeExternalProtocolHandlerWorker() override = default;

 private:
  shell_integration::DefaultWebClientState CheckIsDefaultImpl() override {
    return os_state_;
  }

  std::u16string GetDefaultClientNameImpl() override { return program_name_; }

  void SetAsDefaultImpl(base::OnceClosure on_finished_callback) override {
    std::move(on_finished_callback).Run();
  }

  shell_integration::DefaultWebClientState os_state_;
  std::u16string program_name_;
};

class ScopedFakeExternalProtocolHandlerDelegate
    : public ExternalProtocolHandler::Delegate {
 public:
  ScopedFakeExternalProtocolHandlerDelegate() {
    ExternalProtocolHandler::SetDelegateForTesting(this);
  }
  ~ScopedFakeExternalProtocolHandlerDelegate() override {
    ExternalProtocolHandler::SetDelegateForTesting(nullptr);
  }

  scoped_refptr<shell_integration::DefaultSchemeClientWorker> CreateShellWorker(
      const GURL& url) override {
    return new FakeExternalProtocolHandlerWorker(
        url, shell_integration::UNKNOWN_DEFAULT, program_name_);
  }

  ExternalProtocolHandler::BlockState GetBlockState(const std::string& scheme,
                                                    Profile* profile) override {
    return ExternalProtocolHandler::UNKNOWN;
  }

  void BlockRequest() override {
    FAIL() << "Unexpected BlockRequest call received";
  }

  void RunExternalProtocolDialog(
      const GURL& url,
      content::WebContents* web_contents,
      ui::PageTransition page_transition,
      bool has_user_gesture,
      const std::optional<url::Origin>& initiating_origin,
      const std::u16string& program_name) override {
    EXPECT_EQ(program_name_, program_name);
    external_protocol_dialog_called_ = true;
    launched_url_with_security_check_ = url.spec();
  }

  void LaunchUrlWithoutSecurityCheck(
      const GURL& url,
      content::WebContents* web_contents) override {
    launched_url_without_security_check_ = url.spec();
    launch_url_run_loop_.Quit();
  }

  void FinishedProcessingCheck() override { launch_url_run_loop_.Quit(); }

  void WaitExternalUrlLaunchCompleted() { launch_url_run_loop_.Run(); }

  bool external_protocol_dialog_called() const {
    return external_protocol_dialog_called_;
  }
  std::string_view launched_url_without_security_check() const {
    return launched_url_without_security_check_;
  }
  std::string_view launched_url_with_security_check() const {
    return launched_url_with_security_check_;
  }

 private:
  base::RunLoop launch_url_run_loop_;
  const std::u16string program_name_ = u"custom";
  bool external_protocol_dialog_called_ = false;
  std::string launched_url_without_security_check_;
  std::string launched_url_with_security_check_;
};

}  // namespace

// URLs which are explicitly allowlisted by policy can bypass security checks.
// TODO: https://crbug.com/434758587 - Re-enable this test.
IN_PROC_BROWSER_TEST_F(ProtocolHandlerTest,
                       DISABLED_SecurityCheckExceptionForAllowlistedUrls) {
  ProtocolHandlerRegistryFactory::GetInstance()
      ->GetForBrowserContext(browser()->profile())
      ->OnAcceptRegisterProtocolHandler(
          custom_handlers::ProtocolHandler::CreateProtocolHandler(
              "map", GURL("geo://%s")));

  ScopedFakeExternalProtocolHandlerDelegate delegate;

  base::Value::List allowlist;
  allowlist.Append("geo://*");
  browser()->profile()->GetPrefs()->SetList(policy::policy_prefs::kUrlAllowlist,
                                            std::move(allowlist));
  // The call to update the internal allowlist value is async.
  base::RunLoop().RunUntilIdle();

  const char kGeoUrl[] = "geo:48.2082,16.3738";

  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), GURL(kGeoUrl)));
  delegate.WaitExternalUrlLaunchCompleted();

  EXPECT_FALSE(delegate.external_protocol_dialog_called());
  EXPECT_EQ(delegate.launched_url_without_security_check(), kGeoUrl);
  EXPECT_EQ(delegate.launched_url_with_security_check(), "");
}

// Regardless of the value of the UrlAllowlist policy, intent:// URLs should
// always be deferred to the external protocol dialog (which currently defers
// the call to ARC).
IN_PROC_BROWSER_TEST_F(ProtocolHandlerTest,
                       IntentSchemeBypassSecurityExceptions) {
  ProtocolHandlerRegistryFactory::GetInstance()
      ->GetForBrowserContext(browser()->profile())
      ->OnAcceptRegisterProtocolHandler(
          custom_handlers::ProtocolHandler::CreateProtocolHandler(
              "search", GURL("intent://%s")));

  ScopedFakeExternalProtocolHandlerDelegate delegate;

  base::Value::List allowlist;
  allowlist.Append("intent://*");
  browser()->profile()->GetPrefs()->SetList(policy::policy_prefs::kUrlAllowlist,
                                            std::move(allowlist));
  // The call to update the internal allowlist value is async.
  base::RunLoop().RunUntilIdle();

  const char kIntentUrl[] =
      "intent://www.google.com/"
      "#Intent;scheme=http;package=com.android.chrome;end";

  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), GURL(kIntentUrl)));
  delegate.WaitExternalUrlLaunchCompleted();

  EXPECT_TRUE(delegate.external_protocol_dialog_called());
  // intent:// URLs should not skip security checks.
  EXPECT_EQ(delegate.launched_url_without_security_check(), "");
  EXPECT_EQ(delegate.launched_url_with_security_check(), kIntentUrl);
}
#endif

#if !BUILDFLAG(IS_ANDROID)
class KeepaliveDurationOnShutdownTest : public InProcessBrowserTest,
                                        public InstantTestBase {
 public:
  void SetUpOnMainThread() override {
    InProcessBrowserTest::SetUpOnMainThread();
    client_ = static_cast<ChromeContentBrowserClient*>(
        content::GetContentClientForTesting()->browser());
  }

  void TearDownOnMainThread() override {
    client_ = nullptr;
    InProcessBrowserTest::TearDownOnMainThread();
  }

 protected:
  const ChromeContentBrowserClient* client() const { return client_; }

 private:
  raw_ptr<ChromeContentBrowserClient> client_ = nullptr;
};

IN_PROC_BROWSER_TEST_F(KeepaliveDurationOnShutdownTest, DefaultValue) {
  Profile* profile = browser()->profile();
  EXPECT_EQ(client()->GetKeepaliveTimerTimeout(profile), base::TimeDelta());
}

IN_PROC_BROWSER_TEST_F(KeepaliveDurationOnShutdownTest, PolicySettings) {
  Profile* profile = browser()->profile();
  profile->GetPrefs()->SetInteger(prefs::kFetchKeepaliveDurationOnShutdown, 2);

  EXPECT_EQ(client()->GetKeepaliveTimerTimeout(profile), base::Seconds(2));
}

IN_PROC_BROWSER_TEST_F(KeepaliveDurationOnShutdownTest, DynamicUpdate) {
  Profile* profile = browser()->profile();
  profile->GetPrefs()->SetInteger(prefs::kFetchKeepaliveDurationOnShutdown, 2);

  EXPECT_EQ(client()->GetKeepaliveTimerTimeout(profile), base::Seconds(2));

  profile->GetPrefs()->SetInteger(prefs::kFetchKeepaliveDurationOnShutdown, 3);

  EXPECT_EQ(client()->GetKeepaliveTimerTimeout(profile), base::Seconds(3));
}

#endif  // !BUILDFLAG(IS_ANDROID)

#if BUILDFLAG(ENTERPRISE_CONTENT_ANALYSIS)

class ClipboardTestContentAnalysisDelegate
    : public enterprise_connectors::test::FakeContentAnalysisDelegate {
 public:
  static std::unique_ptr<ContentAnalysisDelegate> Create(
      base::RepeatingClosure delete_closure,
      StatusCallback status_callback,
      std::string dm_token,
      content::WebContents* web_contents,
      Data data,
      CompletionCallback callback) {
    auto ret = std::make_unique<ClipboardTestContentAnalysisDelegate>(
        delete_closure, std::move(status_callback), std::move(dm_token),
        web_contents, std::move(data), std::move(callback));
    enterprise_connectors::FilesRequestHandler::SetFactoryForTesting(
        base::BindRepeating(
            &enterprise_connectors::test::FakeFilesRequestHandler::Create,
            base::BindRepeating(&ClipboardTestContentAnalysisDelegate::
                                    FakeUploadFileForDeepScanning,
                                base::Unretained(ret.get()))));
    enterprise_connectors::ClipboardRequestHandler::SetFactoryForTesting(
        base::BindRepeating(
            &enterprise_connectors::test::FakeClipboardRequestHandler::Create,
            base::Unretained(ret.get())));
    return ret;
  }

  using FakeContentAnalysisDelegate::FakeContentAnalysisDelegate;

 protected:
  void FakeUploadFileForDeepScanning(
      safe_browsing::BinaryUploadService::Result result,
      const base::FilePath& path,
      std::unique_ptr<safe_browsing::BinaryUploadService::Request> request,
      enterprise_connectors::test::FakeFilesRequestHandler::
          FakeFileRequestCallback callback) override {
    ASSERT_EQ(request->reason(),
              enterprise_connectors::ContentAnalysisRequest::CLIPBOARD_PASTE);

    enterprise_connectors::test::FakeContentAnalysisDelegate::
        FakeUploadFileForDeepScanning(result, path, std::move(request),
                                      std::move(callback));
  }
};

class IsClipboardPasteAllowedTest : public InProcessBrowserTest {
 public:
  IsClipboardPasteAllowedTest() {
    EXPECT_TRUE(temp_dir_.CreateUniqueTempDir());
  }

  void SetUpOnMainThread() override {
    InProcessBrowserTest::SetUpOnMainThread();

    // Make sure enterprise policies are set to turn on content analysis.
    enterprise_connectors::test::SetAnalysisConnector(
        browser()->profile()->GetPrefs(),
        enterprise_connectors::BULK_DATA_ENTRY, kBulkDataEntryPolicyValue);
    enterprise_connectors::test::SetAnalysisConnector(
        browser()->profile()->GetPrefs(), enterprise_connectors::FILE_ATTACHED,
        kFileAttachedPolicyValue);

    enterprise_connectors::ContentAnalysisDelegate::SetFactoryForTesting(
        base::BindRepeating(
            &ClipboardTestContentAnalysisDelegate::Create, base::DoNothing(),
            base::BindRepeating([](const std::string& contents,
                                   const base::FilePath& path) {
              bool success = false;
              if (!contents.empty()) {
                success = contents.substr(0, 5) == "allow";
              } else {
                success =
                    path.BaseName().AsUTF8Unsafe().substr(0, 5) == "allow";
              }
              return success
                         ? enterprise_connectors::test::
                               FakeContentAnalysisDelegate::SuccessfulResponse(
                                   {"dlp"})
                         : enterprise_connectors::test::
                               FakeContentAnalysisDelegate::DlpResponse(
                                   enterprise_connectors::
                                       ContentAnalysisResponse::Result::SUCCESS,
                                   "rule-name",
                                   enterprise_connectors::
                                       ContentAnalysisResponse::Result::
                                           TriggeredRule::BLOCK);
            }),
            /*dm_token=*/std::string()));

    client_ = static_cast<ChromeContentBrowserClient*>(
        content::GetContentClientForTesting()->browser());
  }

  void TearDownOnMainThread() override {
    client_ = nullptr;
    InProcessBrowserTest::TearDownOnMainThread();
  }

 protected:
  ChromeContentBrowserClient* client() { return client_; }

  base::FilePath CreateTestFile(const base::FilePath::StringType& filename,
                                const std::string& content) {
    base::ScopedAllowBlockingForTesting allow_blocking;
    base::FilePath path = temp_dir_.GetPath().Append(filename);
    base::File file(path, base::File::FLAG_CREATE | base::File::FLAG_WRITE);
    file.WriteAtCurrentPos(base::as_byte_span(content));
    return path;
  }

 private:
  static constexpr char kBulkDataEntryPolicyValue[] = R"(
  {
    "service_provider": "local_system_agent",
    "enable": [
      {
        "url_list": ["*"],
        "tags": ["dlp"]
      }
    ],
    "block_until_verdict": 1,
    "minimum_data_size": 1
  })";

  static constexpr char kFileAttachedPolicyValue[] = R"(
  {
    "service_provider": "local_system_agent",
    "enable": [
      {
        "url_list": ["*"],
        "tags": ["dlp"]
      }
    ],
    "block_until_verdict": 1
  })";

  base::ScopedTempDir temp_dir_;
  raw_ptr<ChromeContentBrowserClient> client_ = nullptr;
#if BUILDFLAG(ENTERPRISE_LOCAL_CONTENT_ANALYSIS)
  // This installs a fake SDK manager that creates fake SDK clients when
  // its GetClient() method is called. This is needed so that calls to
  // ContentAnalysisSdkManager::Get()->GetClient() do not fail.
  enterprise_connectors::FakeContentAnalysisSdkManager sdk_manager_;
#endif
};

IN_PROC_BROWSER_TEST_F(IsClipboardPasteAllowedTest, BitmapAllowed) {
  content::WebContents* contents =
      browser()->tab_strip_model()->GetWebContentsAt(0);
  ChromeContentBrowserClient::ClipboardPasteData clipboard_paste_data;
  clipboard_paste_data.png = StringToVector("allowed");

  client()->IsClipboardPasteAllowedByPolicy(
      content::ClipboardEndpoint(
          ui::DataTransferEndpoint(GURL("https://google.com"))),
      content::ClipboardEndpoint(
          ui::DataTransferEndpoint(GURL("https://google.com")),
          base::BindLambdaForTesting(
              [contents] { return contents->GetBrowserContext(); }),
          *contents->GetPrimaryMainFrame()),
      {
          .size = clipboard_paste_data.png.size(),
          .format_type = ui::ClipboardFormatType::BitmapType(),
      },
      clipboard_paste_data,
      base::BindOnce(
          [](std::optional<ChromeContentBrowserClient::ClipboardPasteData>
                 clipboard_paste_data) {
            EXPECT_TRUE(clipboard_paste_data.has_value());
            EXPECT_EQ(clipboard_paste_data->png, StringToVector("allowed"));
          }));
}

IN_PROC_BROWSER_TEST_F(IsClipboardPasteAllowedTest, BitmapBlocked) {
  content::WebContents* contents =
      browser()->tab_strip_model()->GetWebContentsAt(0);
  ChromeContentBrowserClient::ClipboardPasteData clipboard_paste_data;
  clipboard_paste_data.png = StringToVector("blocked");

  client()->IsClipboardPasteAllowedByPolicy(
      content::ClipboardEndpoint(
          ui::DataTransferEndpoint(GURL("https://google.com"))),
      content::ClipboardEndpoint(
          ui::DataTransferEndpoint(GURL("https://google.com")),
          base::BindLambdaForTesting(
              [contents] { return contents->GetBrowserContext(); }),
          *contents->GetPrimaryMainFrame()),
      {
          .size = clipboard_paste_data.png.size(),
          .format_type = ui::ClipboardFormatType::BitmapType(),
      },
      clipboard_paste_data,
      base::BindOnce(
          [](std::optional<ChromeContentBrowserClient::ClipboardPasteData>
                 clipboard_paste_data) {
#if BUILDFLAG(ENTERPRISE_LOCAL_CONTENT_ANALYSIS)
            EXPECT_FALSE(clipboard_paste_data.has_value());
#else
            // Platforms that don't support local content analysis shouldn't
            // block anything, even when the policy is set to a local service
            // provider value.
            EXPECT_TRUE(clipboard_paste_data.has_value());
            EXPECT_EQ(clipboard_paste_data->png, StringToVector("blocked"));
#endif
          }));
}

IN_PROC_BROWSER_TEST_F(IsClipboardPasteAllowedTest, TextAllowed) {
  content::WebContents* contents =
      browser()->tab_strip_model()->GetWebContentsAt(0);
  ChromeContentBrowserClient::ClipboardPasteData clipboard_paste_data;
  clipboard_paste_data.text = u"allowed";

  client()->IsClipboardPasteAllowedByPolicy(
      content::ClipboardEndpoint(
          ui::DataTransferEndpoint(GURL("https://google.com"))),
      content::ClipboardEndpoint(
          ui::DataTransferEndpoint(GURL("https://google.com")),
          base::BindLambdaForTesting(
              [contents] { return contents->GetBrowserContext(); }),
          *contents->GetPrimaryMainFrame()),
      {
          .size = clipboard_paste_data.text.size(),
          .format_type = ui::ClipboardFormatType::PlainTextType(),
      },
      clipboard_paste_data,
      base::BindOnce(
          [](std::optional<ChromeContentBrowserClient::ClipboardPasteData>
                 clipboard_paste_data) {
            EXPECT_TRUE(clipboard_paste_data.has_value());
            EXPECT_EQ(clipboard_paste_data->text, u"allowed");
          }));
}

IN_PROC_BROWSER_TEST_F(IsClipboardPasteAllowedTest, TextBlocked) {
  content::WebContents* contents =
      browser()->tab_strip_model()->GetWebContentsAt(0);
  ChromeContentBrowserClient::ClipboardPasteData clipboard_paste_data;
  clipboard_paste_data.text = u"blocked";

  client()->IsClipboardPasteAllowedByPolicy(
      content::ClipboardEndpoint(
          ui::DataTransferEndpoint(GURL("https://google.com"))),
      content::ClipboardEndpoint(
          ui::DataTransferEndpoint(GURL("https://google.com")),
          base::BindLambdaForTesting(
              [contents] { return contents->GetBrowserContext(); }),
          *contents->GetPrimaryMainFrame()),
      {
          .size = clipboard_paste_data.text.size(),
          .format_type = ui::ClipboardFormatType::PlainTextType(),
      },
      clipboard_paste_data,
      base::BindOnce(
          [](std::optional<ChromeContentBrowserClient::ClipboardPasteData>
                 clipboard_paste_data) {
#if BUILDFLAG(ENTERPRISE_LOCAL_CONTENT_ANALYSIS)
            EXPECT_FALSE(clipboard_paste_data.has_value());
#else
            // Platforms that don't support local content analysis shouldn't
            // block anything, even when the policy is set to a local service
            // provider value.
            EXPECT_TRUE(clipboard_paste_data.has_value());
            EXPECT_EQ(clipboard_paste_data->text, u"blocked");
#endif
          }));
}

IN_PROC_BROWSER_TEST_F(IsClipboardPasteAllowedTest, HtmlAllowed) {
  content::WebContents* contents =
      browser()->tab_strip_model()->GetWebContentsAt(0);
  ChromeContentBrowserClient::ClipboardPasteData clipboard_paste_data;
  clipboard_paste_data.html = u"allowed";

  client()->IsClipboardPasteAllowedByPolicy(
      content::ClipboardEndpoint(
          ui::DataTransferEndpoint(GURL("https://google.com"))),
      content::ClipboardEndpoint(
          ui::DataTransferEndpoint(GURL("https://google.com")),
          base::BindLambdaForTesting(
              [contents] { return contents->GetBrowserContext(); }),
          *contents->GetPrimaryMainFrame()),
      {
          .size = clipboard_paste_data.html.size(),
          .format_type = ui::ClipboardFormatType::HtmlType(),
      },
      clipboard_paste_data,
      base::BindOnce(
          [](std::optional<ChromeContentBrowserClient::ClipboardPasteData>
                 clipboard_paste_data) {
            EXPECT_TRUE(clipboard_paste_data.has_value());
            EXPECT_EQ(clipboard_paste_data->html, u"allowed");
          }));
}

IN_PROC_BROWSER_TEST_F(IsClipboardPasteAllowedTest, HtmlBlocked) {
  content::WebContents* contents =
      browser()->tab_strip_model()->GetWebContentsAt(0);
  ChromeContentBrowserClient::ClipboardPasteData clipboard_paste_data;
  clipboard_paste_data.html = u"blocked";

  client()->IsClipboardPasteAllowedByPolicy(
      content::ClipboardEndpoint(
          ui::DataTransferEndpoint(GURL("https://google.com"))),
      content::ClipboardEndpoint(
          ui::DataTransferEndpoint(GURL("https://google.com")),
          base::BindLambdaForTesting(
              [contents] { return contents->GetBrowserContext(); }),
          *contents->GetPrimaryMainFrame()),
      {
          .size = clipboard_paste_data.html.size(),
          .format_type = ui::ClipboardFormatType::HtmlType(),
      },
      clipboard_paste_data,
      base::BindOnce(
          [](std::optional<ChromeContentBrowserClient::ClipboardPasteData>
                 clipboard_paste_data) {
#if BUILDFLAG(ENTERPRISE_LOCAL_CONTENT_ANALYSIS)
            EXPECT_FALSE(clipboard_paste_data.has_value());
#else
            // Platforms that don't support local content analysis shouldn't
            // block anything, even when the policy is set to a local service
            // provider value.
            EXPECT_TRUE(clipboard_paste_data.has_value());
            EXPECT_EQ(clipboard_paste_data->html, u"blocked");
#endif
          }));
}

IN_PROC_BROWSER_TEST_F(IsClipboardPasteAllowedTest, SvgAllowed) {
  content::WebContents* contents =
      browser()->tab_strip_model()->GetWebContentsAt(0);
  ChromeContentBrowserClient::ClipboardPasteData clipboard_paste_data;
  clipboard_paste_data.svg = u"allowed";

  client()->IsClipboardPasteAllowedByPolicy(
      content::ClipboardEndpoint(
          ui::DataTransferEndpoint(GURL("https://google.com"))),
      content::ClipboardEndpoint(
          ui::DataTransferEndpoint(GURL("https://google.com")),
          base::BindLambdaForTesting(
              [contents] { return contents->GetBrowserContext(); }),
          *contents->GetPrimaryMainFrame()),
      {
          .size = clipboard_paste_data.svg.size(),
          .format_type = ui::ClipboardFormatType::SvgType(),
      },
      clipboard_paste_data,
      base::BindOnce(
          [](std::optional<ChromeContentBrowserClient::ClipboardPasteData>
                 clipboard_paste_data) {
            EXPECT_TRUE(clipboard_paste_data.has_value());
            EXPECT_EQ(clipboard_paste_data->svg, u"allowed");
          }));
}

IN_PROC_BROWSER_TEST_F(IsClipboardPasteAllowedTest, SvgBlocked) {
  content::WebContents* contents =
      browser()->tab_strip_model()->GetWebContentsAt(0);
  ChromeContentBrowserClient::ClipboardPasteData clipboard_paste_data;
  clipboard_paste_data.svg = u"blocked";

  client()->IsClipboardPasteAllowedByPolicy(
      content::ClipboardEndpoint(
          ui::DataTransferEndpoint(GURL("https://google.com"))),
      content::ClipboardEndpoint(
          ui::DataTransferEndpoint(GURL("https://google.com")),
          base::BindLambdaForTesting(
              [contents] { return contents->GetBrowserContext(); }),
          *contents->GetPrimaryMainFrame()),
      {
          .size = clipboard_paste_data.svg.size(),
          .format_type = ui::ClipboardFormatType::SvgType(),
      },
      clipboard_paste_data,
      base::BindOnce(
          [](std::optional<ChromeContentBrowserClient::ClipboardPasteData>
                 clipboard_paste_data) {
#if BUILDFLAG(ENTERPRISE_LOCAL_CONTENT_ANALYSIS)
            EXPECT_FALSE(clipboard_paste_data.has_value());
#else
            // Platforms that don't support local content analysis shouldn't
            // block anything, even when the policy is set to a local service
            // provider value.
            EXPECT_TRUE(clipboard_paste_data.has_value());
            EXPECT_EQ(clipboard_paste_data->svg, u"blocked");
#endif
          }));
}
IN_PROC_BROWSER_TEST_F(IsClipboardPasteAllowedTest, RtfAllowed) {
  content::WebContents* contents =
      browser()->tab_strip_model()->GetWebContentsAt(0);
  ChromeContentBrowserClient::ClipboardPasteData clipboard_paste_data;
  clipboard_paste_data.rtf = "allowed";

  client()->IsClipboardPasteAllowedByPolicy(
      content::ClipboardEndpoint(
          ui::DataTransferEndpoint(GURL("https://google.com"))),
      content::ClipboardEndpoint(
          ui::DataTransferEndpoint(GURL("https://google.com")),
          base::BindLambdaForTesting(
              [contents] { return contents->GetBrowserContext(); }),
          *contents->GetPrimaryMainFrame()),
      {
          .size = clipboard_paste_data.rtf.size(),
          .format_type = ui::ClipboardFormatType::RtfType(),
      },
      clipboard_paste_data,
      base::BindOnce(
          [](std::optional<ChromeContentBrowserClient::ClipboardPasteData>
                 clipboard_paste_data) {
            EXPECT_TRUE(clipboard_paste_data.has_value());
            EXPECT_EQ(clipboard_paste_data->rtf, "allowed");
          }));
}

IN_PROC_BROWSER_TEST_F(IsClipboardPasteAllowedTest, RtfBlocked) {
  content::WebContents* contents =
      browser()->tab_strip_model()->GetWebContentsAt(0);
  ChromeContentBrowserClient::ClipboardPasteData clipboard_paste_data;
  clipboard_paste_data.rtf = "blocked";

  client()->IsClipboardPasteAllowedByPolicy(
      content::ClipboardEndpoint(
          ui::DataTransferEndpoint(GURL("https://google.com"))),
      content::ClipboardEndpoint(
          ui::DataTransferEndpoint(GURL("https://google.com")),
          base::BindLambdaForTesting(
              [contents] { return contents->GetBrowserContext(); }),
          *contents->GetPrimaryMainFrame()),
      {
          .size = clipboard_paste_data.rtf.size(),
          .format_type = ui::ClipboardFormatType::RtfType(),
      },
      clipboard_paste_data,
      base::BindOnce(
          [](std::optional<ChromeContentBrowserClient::ClipboardPasteData>
                 clipboard_paste_data) {
#if BUILDFLAG(ENTERPRISE_LOCAL_CONTENT_ANALYSIS)
            EXPECT_FALSE(clipboard_paste_data.has_value());
#else
            // Platforms that don't support local content analysis shouldn't
            // block anything, even when the policy is set to a local service
            // provider value.
            EXPECT_TRUE(clipboard_paste_data.has_value());
            EXPECT_EQ(clipboard_paste_data->rtf, "blocked");
#endif
          }));
}

IN_PROC_BROWSER_TEST_F(IsClipboardPasteAllowedTest, CustomDataAllowed) {
  content::WebContents* contents =
      browser()->tab_strip_model()->GetWebContentsAt(0);
  ChromeContentBrowserClient::ClipboardPasteData clipboard_paste_data;
  clipboard_paste_data.custom_data[u"custom/data"] = u"allowed";

  client()->IsClipboardPasteAllowedByPolicy(
      content::ClipboardEndpoint(
          ui::DataTransferEndpoint(GURL("https://google.com"))),
      content::ClipboardEndpoint(
          ui::DataTransferEndpoint(GURL("https://google.com")),
          base::BindLambdaForTesting(
              [contents] { return contents->GetBrowserContext(); }),
          *contents->GetPrimaryMainFrame()),
      {
          .size = clipboard_paste_data.custom_data[u"custom/data"].size(),
          .format_type = ui::ClipboardFormatType::DataTransferCustomType(),
      },
      clipboard_paste_data,
      base::BindOnce(
          [](std::optional<ChromeContentBrowserClient::ClipboardPasteData>
                 clipboard_paste_data) {
            EXPECT_TRUE(clipboard_paste_data.has_value());
            EXPECT_EQ(clipboard_paste_data->custom_data.size(), 1u);
            EXPECT_TRUE(
                clipboard_paste_data->custom_data.count(u"custom/data"));
            EXPECT_EQ(clipboard_paste_data->custom_data[u"custom/data"],
                      u"allowed");
          }));
}

IN_PROC_BROWSER_TEST_F(IsClipboardPasteAllowedTest, CustomDataBlocked) {
  content::WebContents* contents =
      browser()->tab_strip_model()->GetWebContentsAt(0);
  ChromeContentBrowserClient::ClipboardPasteData clipboard_paste_data;
  clipboard_paste_data.custom_data[u"custom/data"] = u"blocked";

  client()->IsClipboardPasteAllowedByPolicy(
      content::ClipboardEndpoint(
          ui::DataTransferEndpoint(GURL("https://google.com"))),
      content::ClipboardEndpoint(
          ui::DataTransferEndpoint(GURL("https://google.com")),
          base::BindLambdaForTesting(
              [contents] { return contents->GetBrowserContext(); }),
          *contents->GetPrimaryMainFrame()),
      {
          .size = clipboard_paste_data.custom_data[u"custom/data"].size(),
          .format_type = ui::ClipboardFormatType::DataTransferCustomType(),
      },
      clipboard_paste_data,
      base::BindOnce(
          [](std::optional<ChromeContentBrowserClient::ClipboardPasteData>
                 clipboard_paste_data) {
#if BUILDFLAG(ENTERPRISE_LOCAL_CONTENT_ANALYSIS)
            EXPECT_FALSE(clipboard_paste_data.has_value());
#else
            // Platforms that don't support local content analysis shouldn't
            // block anything, even when the policy is set to a local service
            // provider value.
            EXPECT_TRUE(clipboard_paste_data.has_value());
            EXPECT_EQ(clipboard_paste_data->custom_data.size(), 1u);
            EXPECT_TRUE(
                clipboard_paste_data->custom_data.count(u"custom/data"));
            EXPECT_EQ(clipboard_paste_data->custom_data[u"custom/data"],
                      u"blocked");
#endif
          }));
}

// TODO(crbug.com/391682998): Enable.
IN_PROC_BROWSER_TEST_F(IsClipboardPasteAllowedTest, DISABLED_AllFilesAllowed) {
  std::vector<base::FilePath> paths;
  paths.push_back(CreateTestFile(FILE_PATH_LITERAL("allow0"), "data"));
  paths.push_back(CreateTestFile(FILE_PATH_LITERAL("allow1"), "data"));
  ChromeContentBrowserClient::ClipboardPasteData clipboard_paste_data;
  clipboard_paste_data.file_paths = paths;

  content::WebContents* contents =
      browser()->tab_strip_model()->GetWebContentsAt(0);
  client()->IsClipboardPasteAllowedByPolicy(
      content::ClipboardEndpoint(
          ui::DataTransferEndpoint(GURL("https://google.com"))),
      content::ClipboardEndpoint(
          ui::DataTransferEndpoint(GURL("https://google.com")),
          base::BindLambdaForTesting(
              [contents] { return contents->GetBrowserContext(); }),
          *contents->GetPrimaryMainFrame()),
      {
          .format_type = ui::ClipboardFormatType::FilenamesType(),
      },
      clipboard_paste_data,
      base::BindLambdaForTesting(
          [paths](std::optional<ChromeContentBrowserClient::ClipboardPasteData>
                      clipboard_paste_data) {
            EXPECT_TRUE(clipboard_paste_data.has_value());
            EXPECT_EQ(paths[0], clipboard_paste_data->file_paths[0]);
            EXPECT_EQ(paths[1], clipboard_paste_data->file_paths[1]);
          }));
}

// TODO(crbug.com/391682998): Enable.
IN_PROC_BROWSER_TEST_F(IsClipboardPasteAllowedTest, DISABLED_AllFilesBlocked) {
  std::vector<base::FilePath> paths;
  paths.push_back(CreateTestFile(FILE_PATH_LITERAL("block0"), "data"));
  paths.push_back(CreateTestFile(FILE_PATH_LITERAL("block1"), "data"));

  ChromeContentBrowserClient::ClipboardPasteData clipboard_paste_data;
  clipboard_paste_data.file_paths = paths;

  content::WebContents* contents =
      browser()->tab_strip_model()->GetWebContentsAt(0);
  client()->IsClipboardPasteAllowedByPolicy(
      content::ClipboardEndpoint(
          ui::DataTransferEndpoint(GURL("https://google.com"))),
      content::ClipboardEndpoint(
          ui::DataTransferEndpoint(GURL("https://google.com")),
          base::BindLambdaForTesting(
              [contents] { return contents->GetBrowserContext(); }),
          *contents->GetPrimaryMainFrame()),
      {
          .format_type = ui::ClipboardFormatType::FilenamesType(),
      },
      clipboard_paste_data,
      base::BindLambdaForTesting(
          [paths](std::optional<ChromeContentBrowserClient::ClipboardPasteData>
                      clipboard_paste_data) {
#if BUILDFLAG(ENTERPRISE_LOCAL_CONTENT_ANALYSIS)
            EXPECT_FALSE(clipboard_paste_data.has_value());
#else
            // Platforms that don't support local content analysis shouldn't
            // block anything, even when the policy is set to a local service
            // provider value.
            EXPECT_TRUE(clipboard_paste_data.has_value());
            EXPECT_EQ(clipboard_paste_data->file_paths[0], paths[0]);
            EXPECT_EQ(clipboard_paste_data->file_paths[1], paths[1]);
#endif
          }));
}

// TODO(crbug.com/391682998): Re-enable this test
IN_PROC_BROWSER_TEST_F(IsClipboardPasteAllowedTest, DISABLED_SomeFilesBlocked) {
  std::vector<base::FilePath> paths;
  paths.push_back(CreateTestFile(FILE_PATH_LITERAL("allow0"), "data"));
  paths.push_back(CreateTestFile(FILE_PATH_LITERAL("block1"), "data"));
  ChromeContentBrowserClient::ClipboardPasteData clipboard_paste_data;
  clipboard_paste_data.file_paths = paths;

  content::WebContents* contents =
      browser()->tab_strip_model()->GetWebContentsAt(0);
  client()->IsClipboardPasteAllowedByPolicy(
      content::ClipboardEndpoint(
          ui::DataTransferEndpoint(GURL("https://google.com"))),
      content::ClipboardEndpoint(
          ui::DataTransferEndpoint(GURL("https://google.com")),
          base::BindLambdaForTesting(
              [contents] { return contents->GetBrowserContext(); }),
          *contents->GetPrimaryMainFrame()),
      {
          .format_type = ui::ClipboardFormatType::FilenamesType(),
      },
      clipboard_paste_data,
      base::BindLambdaForTesting(
          [paths](std::optional<ChromeContentBrowserClient::ClipboardPasteData>
                      clipboard_paste_data) {
            EXPECT_TRUE(clipboard_paste_data.has_value());
            EXPECT_EQ(clipboard_paste_data->file_paths[0], paths[0]);
          }));
}

// Verifies that the available clipboard types are correctly reported when
// clipboard data is replaced by a Data Controls policy.
IN_PROC_BROWSER_TEST_F(IsClipboardPasteAllowedTest,
                       GetClipboardTypesIfPolicyApplied) {
  content::WebContents* contents =
      browser()->tab_strip_model()->GetWebContentsAt(0);

  // Set policy that blocks copying to the OS clipboard for a specific source.
  data_controls::SetDataControls(browser()->profile()->GetPrefs(), {R"({
      "name": "test rule",
      "sources": {
        "urls": ["https://google.com"]
      },
      "destinations": {
        "os_clipboard": true
      },
      "restrictions": [
        {"class": "CLIPBOARD", "level": "BLOCK"}
      ]
    })"});

  content::ClipboardPasteData clipboard_paste_data;
  clipboard_paste_data.text = u"foo";
  clipboard_paste_data.custom_data[u"custom/data"] = u"custom data";

  base::test::TestFuture<const ui::ClipboardFormatType&,
                         const content::ClipboardPasteData&,
                         std::optional<std::u16string>>
      future;

  // Initiates a copy request and verify that replacement is written as per the
  // policy.
  client()->IsClipboardCopyAllowedByPolicy(
      /*source=*/content::ClipboardEndpoint(
          ui::DataTransferEndpoint(GURL("https://google.com")),
          base::BindLambdaForTesting(
              [&contents]() { return contents->GetBrowserContext(); }),
          *contents->GetPrimaryMainFrame()),
      /*metadata=*/{.size = 1234}, clipboard_paste_data,
      future.GetCallback());
  auto replacement = future.Get<std::optional<std::u16string>>();
  EXPECT_TRUE(replacement.has_value());

  // Triggers the clipboard observer started by `IsClipboardCopyAllowedByPolicy`
  // so that it's aware of the new seqno.
  ui::ClipboardMonitor::GetInstance()->NotifyClipboardDataChanged();

  // Verifies that the last replaced clipboard types are retrieved correctly.
  auto types = client()->GetClipboardTypesIfPolicyApplied(
      ui::Clipboard::GetForCurrentThread()->GetSequenceNumber(
          ui::ClipboardBuffer::kCopyPaste));

  ASSERT_TRUE(types.has_value());
  ASSERT_EQ(types->size(), 2u);
  EXPECT_EQ((*types)[0], u"text/plain");
  EXPECT_EQ((*types)[1], u"custom/data");
}

#endif  // BUILDFLAG(ENTERPRISE_CONTENT_ANALYSIS)

class AutomaticBeaconCredentialsBrowserTest : public InProcessBrowserTest,
                                              public InstantTestBase {
 public:
  AutomaticBeaconCredentialsBrowserTest() {
    scoped_feature_list_.InitWithFeatures(
        /*enabled_features=*/{privacy_sandbox::
                                  kOverridePrivacySandboxSettingsLocalTesting},
        /*disabled_features=*/{
            content_settings::features::kTrackingProtection3pcd});
  }

  void SetUpCommandLine(base::CommandLine* command_line) override {
    command_line->AppendSwitch(switches::kIgnoreCertificateErrors);
  }

  void SetUpOnMainThread() override {
    InProcessBrowserTest::SetUpOnMainThread();
    host_resolver()->AddRule("*", "127.0.0.1");
  }

 protected:
  content::RenderFrameHost* primary_main_frame_host() {
    auto* const web_contents =
        browser()->tab_strip_model()->GetActiveWebContents();
    return web_contents->GetPrimaryMainFrame();
  }

  content::test::FencedFrameTestHelper& fenced_frame_test_helper() {
    return fenced_frame_test_helper_;
  }

 private:
  content::test::FencedFrameTestHelper fenced_frame_test_helper_;
  base::test::ScopedFeatureList scoped_feature_list_;
};

IN_PROC_BROWSER_TEST_F(AutomaticBeaconCredentialsBrowserTest,
                       3PCEnabledAndDisabled) {
  privacy_sandbox::ScopedPrivacySandboxAttestations scoped_attestations(
      privacy_sandbox::PrivacySandboxAttestations::CreateForTesting());
  // Mark all Privacy Sandbox APIs as attested since the test case is testing
  // behaviors not related to attestations.
  privacy_sandbox::PrivacySandboxAttestations::GetInstance()
      ->SetAllPrivacySandboxAttestedForTesting(true);

  static constexpr char kReportingURL[] = "/_report_event_server.html";
  static constexpr char kBeaconMessage[] = "this is the message";

  net::test_server::ControllableHttpResponse first_response(
      &https_test_server(), kReportingURL);
  net::test_server::ControllableHttpResponse second_response(
      &https_test_server(), kReportingURL);

  ASSERT_TRUE(https_test_server().Start());

  // Set up the document.cookie for credentialed automatic beacons. Automatic
  // beacons are set up in chrome/test/data/interest_group/bidding_logic.js to
  // send to "d.test/_report_event_server.html".
  auto cookie_url = https_test_server().GetURL("d.test", "/empty.html");
  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), cookie_url));
  EXPECT_TRUE(
      ExecJs(primary_main_frame_host(),
             "document.cookie = 'name=foobarbaz; SameSite=None; Secure';"));

  auto initial_url = https_test_server().GetURL("a.test", "/empty.html");
  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), initial_url));

  // Load a fenced frame.
  GURL fenced_frame_url(
      https_test_server().GetURL("a.test", "/fenced_frames/title1.html"));
  GURL new_tab_url(https_test_server().GetURL("a.test", "/title2.html"));
  EXPECT_TRUE(ExecJs(primary_main_frame_host(),
                     "var fenced_frame = document.createElement('fencedframe');"
                     "fenced_frame.id = 'fenced_frame';"
                     "document.body.appendChild(fenced_frame);"));
  auto* fenced_frame_host =
      fenced_frame_test_helper().GetMostRecentlyAddedFencedFrame(
          primary_main_frame_host());
  content::TestFrameNavigationObserver observer(fenced_frame_host);
  fenced_frame_test_helper().NavigateFencedFrameUsingFledge(
      primary_main_frame_host(), fenced_frame_url, "fenced_frame");
  observer.Wait();

  // The navigation will change the fenced frame node. Get the handle to the new
  // node.
  fenced_frame_host =
      fenced_frame_test_helper().GetMostRecentlyAddedFencedFrame(
          primary_main_frame_host());

  // Set the automatic beacon
  EXPECT_TRUE(
      ExecJs(fenced_frame_host,
             content::JsReplace(R"(
      window.fence.setReportEventDataForAutomaticBeacons({
        eventType: $1,
        eventData: $2,
        destination: ['seller', 'buyer']
      });
    )",
                                "reserved.top_navigation", kBeaconMessage)));

  // Trigger the first automatic beacon and verify it was sent with cookie data.
  auto top_nav_url = https_test_server().GetURL("a.test", "/empty.html");
  EXPECT_TRUE(
      ExecJs(fenced_frame_host,
             content::JsReplace("window.open($1, '_blank');", top_nav_url)));
  first_response.WaitForRequest();
  EXPECT_EQ(1U, first_response.http_request()->headers.count("Cookie"));
  EXPECT_EQ("name=foobarbaz",
            first_response.http_request()->headers.at("Cookie"));

  // Disable 3rd party cookies.
  browser()->profile()->GetPrefs()->SetBoolean(
      prefs::kTrackingProtection3pcdEnabled, true);

  // Verify automatic beacons no longer are sent with cookie data.
  EXPECT_TRUE(
      ExecJs(fenced_frame_host,
             content::JsReplace("window.open($1, '_blank');", top_nav_url)));
  second_response.WaitForRequest();
  EXPECT_EQ(0U, second_response.http_request()->headers.count("Cookie"));
}

class TopChromeChromeContentBrowserClientTest
    : public ChromeContentBrowserClientBrowserTest {
 public:
  // ChromeContentBrowserClientBrowserTest:
  void SetUpOnMainThread() override {
    ChromeContentBrowserClientBrowserTest::SetUpOnMainThread();
    client_ = static_cast<ChromeContentBrowserClient*>(
        content::GetContentClientForTesting()->browser());
  }

  ChromeContentBrowserClient* client() { return client_; }

 private:
  raw_ptr<ChromeContentBrowserClient> client_ = nullptr;
  base::test::ScopedFeatureList feature_list_;
};

IN_PROC_BROWSER_TEST_F(TopChromeChromeContentBrowserClientTest,
                       UnboundRequestDoesNothing) {
#if BUILDFLAG(IS_ANDROID)
  network::URLLoaderFactoryBuilder factory_builder;
  client()->MaybeProxyNetworkBoundRequest(browser()->profile(),
                                          net::handles::kInvalidNetworkHandle,
                                          factory_builder, nullptr);
  EXPECT_EQ(
      client()
          ->get_target_network_for_network_bound_network_context_for_testing(),
      net::handles::kInvalidNetworkHandle);
  EXPECT_FALSE(
      client()->get_network_bound_network_context_for_testing().is_bound());
#else   // !BUILDFLAG(IS_ANDROID)
  GTEST_SKIP() << "proxying bound requests is supported only on Android";
#endif  // BUILDFLAG(IS_ANDROID)
}

IN_PROC_BROWSER_TEST_F(TopChromeChromeContentBrowserClientTest,
                       BoundRequestCreatesNetworkContext) {
#if BUILDFLAG(IS_ANDROID)
  constexpr net::handles::NetworkHandle network = 1;
  network::URLLoaderFactoryBuilder factory_builder;
  client()->MaybeProxyNetworkBoundRequest(browser()->profile(), network,
                                          factory_builder, nullptr);
  EXPECT_EQ(
      client()
          ->get_target_network_for_network_bound_network_context_for_testing(),
      network);
  EXPECT_TRUE(
      client()->get_network_bound_network_context_for_testing().is_bound());
  EXPECT_TRUE(
      client()->get_network_bound_network_context_for_testing().is_connected());
  {
    base::RunLoop run_loop;
    client()
        ->get_network_bound_network_context_for_testing()
        ->GetBoundNetworkForTesting(base::BindOnce(
            [](base::OnceClosure callback,
               net::handles::NetworkHandle bound_network) {
              EXPECT_EQ(bound_network, network);
              std::move(callback).Run();
            },
            run_loop.QuitClosure()));
    run_loop.Run();
  }
#else   // !BUILDFLAG(IS_ANDROID)
  GTEST_SKIP() << "proxying bound requests is supported only on Android";
#endif  // BUILDFLAG(IS_ANDROID)
}

IN_PROC_BROWSER_TEST_F(TopChromeChromeContentBrowserClientTest,
                       BoundRequestWithOverrideCreatesNetworkContext) {
#if BUILDFLAG(IS_ANDROID)
  constexpr net::handles::NetworkHandle network = 1;
  network::URLLoaderFactoryBuilder factory_builder;
  network::mojom::URLLoaderFactoryOverridePtr factory_override;
  EXPECT_FALSE(factory_override);
  client()->MaybeProxyNetworkBoundRequest(browser()->profile(), network,
                                          factory_builder, &factory_override);
  EXPECT_EQ(
      client()
          ->get_target_network_for_network_bound_network_context_for_testing(),
      network);
  EXPECT_TRUE(
      client()->get_network_bound_network_context_for_testing().is_bound());
  EXPECT_TRUE(
      client()->get_network_bound_network_context_for_testing().is_connected());
  EXPECT_TRUE(factory_override->overriding_factory);
  mojo::Remote<network::mojom::URLLoaderFactory> overridden_factory;
  overridden_factory.Bind(std::move(factory_override->overriding_factory));
  {
    base::RunLoop run_loop;
    client()
        ->get_network_bound_network_context_for_testing()
        ->GetBoundNetworkForTesting(base::BindOnce(
            [](base::OnceClosure callback,
               net::handles::NetworkHandle bound_network) {
              EXPECT_EQ(bound_network, network);
              std::move(callback).Run();
            },
            run_loop.QuitClosure()));
    run_loop.Run();
  }
#else   // !BUILDFLAG(IS_ANDROID)
  GTEST_SKIP() << "proxying bound requests is supported only on Android";
#endif  // BUILDFLAG(IS_ANDROID)
}

IN_PROC_BROWSER_TEST_F(TopChromeChromeContentBrowserClientTest,
                       ShouldReuseRendererWhenTopChromePagesPresent) {
  const GURL top_chrome_url(chrome::kChromeUITabSearchURL);
  const GURL top_chrome_url2(chrome::kChromeUIReadLaterURL);
  const GURL random_url(GURL("www.google.com"));

  const auto navigate_browser = [&](const GURL& url, int index) {
    ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));
    content::NavigationEntry* entry = browser()
                                          ->tab_strip_model()
                                          ->GetWebContentsAt(index)
                                          ->GetController()
                                          .GetLastCommittedEntry();
    ASSERT_NE(nullptr, entry);
    EXPECT_EQ(url, entry->GetURL());
    EXPECT_EQ(url, entry->GetVirtualURL());
  };

  // Navigate to a top chrome URL.
  navigate_browser(top_chrome_url, 0);

  // The browser now hosts a top chrome page and the client should return true
  // to reuse the current renderer Host for the other Top Chrome UI pages.
  EXPECT_TRUE(client()->ShouldTryToUseExistingProcessHost(browser()->profile(),
                                                          top_chrome_url2));

  // Should not reuse existing process host for pages that are not Top Chrome
  // UI.
  EXPECT_FALSE(client()->ShouldTryToUseExistingProcessHost(browser()->profile(),
                                                           random_url));
}

class BundledCodeCacheChromeContentBrowserClientTest
    : public InProcessBrowserTest,
      public testing::WithParamInterface<bool> {
 public:
  BundledCodeCacheChromeContentBrowserClientTest() {
    feature_list_.InitWithFeatureState(features::kWebUIBundledCodeCache,
                                       IsBundledCodeCacheEnabled());
  }

  bool IsBundledCodeCacheEnabled() const { return GetParam(); }

 private:
  base::test::ScopedFeatureList feature_list_;
};

// Assert top-chrome webui renderers disallow v8 feature flag overrides only
// when the bundled webui code cache is enabled.
IN_PROC_BROWSER_TEST_P(BundledCodeCacheChromeContentBrowserClientTest,
                       ConfiguresRendererForDisallowV8FeatureOverrides) {
  ASSERT_TRUE(embedded_test_server()->Start());
  const GURL top_chrome_url1(chrome::kChromeUITabSearchURL);
  const GURL top_chrome_url2(chrome::kChromeUIReadLaterURL);
  const GURL non_top_chrome_url1(chrome::kChromeUINewTabPageURL);
  const GURL non_top_chrome_url2(
      embedded_test_server()->GetURL("/title1.html"));
  EXPECT_TRUE(top_chrome_url1.DomainIs(chrome::kChromeUITopChromeDomain));
  EXPECT_TRUE(top_chrome_url2.DomainIs(chrome::kChromeUITopChromeDomain));
  EXPECT_FALSE(non_top_chrome_url1.DomainIs(chrome::kChromeUITopChromeDomain));
  EXPECT_FALSE(non_top_chrome_url1.DomainIs(chrome::kChromeUITopChromeDomain));

  // Disallow V8 feature flag overrides should only apply to top-chrome URLs
  // when bundled code caching is enabled.
  auto navigate_and_expect_policy_result = [this](const GURL& url,
                                                  bool expectation) {
    content::RenderFrameHost* rfh =
        ui_test_utils::NavigateToURL(browser(), url);
    EXPECT_EQ(expectation, rfh->GetProcess()->DisallowV8FeatureFlagOverrides());
  };
  navigate_and_expect_policy_result(top_chrome_url1,
                                    IsBundledCodeCacheEnabled());
  navigate_and_expect_policy_result(top_chrome_url2,
                                    IsBundledCodeCacheEnabled());
  navigate_and_expect_policy_result(non_top_chrome_url1, false);
  navigate_and_expect_policy_result(non_top_chrome_url1, false);
}

INSTANTIATE_TEST_SUITE_P(
    ,
    BundledCodeCacheChromeContentBrowserClientTest,
    ::testing::Bool(),
    [](const ::testing::TestParamInfo<
        BundledCodeCacheChromeContentBrowserClientTest::ParamType>& info) {
      return base::StrCat(
          {"BundledCodeCache", info.param ? "Enabled" : "Disabled"});
    });

class DevToolsOverridesThirdPartyCookiesBrowserTest
    : public InProcessBrowserTest,
      public content::TestDevToolsProtocolClient {
 public:
  DevToolsOverridesThirdPartyCookiesBrowserTest()
      : https_server_(net::EmbeddedTestServer::TYPE_HTTPS) {
    std::vector<base::test::FeatureRefAndParams> enabled_features;
    std::vector<base::test::FeatureRef> disabled_features;
    // The 3PCD tracking protection feature must be disabled so that we can
    // disable third-party cookies by changing the devtools overrides.
    disabled_features.push_back(
        content_settings::features::kTrackingProtection3pcd);

#if BUILDFLAG(ENABLE_EXTENSIONS_CORE)
    // This feature must be enabled to align the behavior in the test with the
    // actual behavior in the branded-build. Related bug: crbug.com/385032014.
    enabled_features.push_back(
        {extensions_features::kForceWebRequestProxyForTest, {}});

#endif

    feature_list_.InitWithFeaturesAndParameters(enabled_features,
                                                disabled_features);
  }

  void SetUpOnMainThread() override {
    host_resolver()->AddRule("*", "127.0.0.1");
    https_server_.SetSSLConfig(net::EmbeddedTestServer::CERT_TEST_NAMES);
    https_server_.AddDefaultHandlers(GetChromeTestDataDir());
    ASSERT_TRUE(https_server_.Start());

    // Open DevTools and enable network agent.
    AttachToWebContents(web_contents());
    SendCommandAsync("Network.enable");
  }

  void TearDownOnMainThread() override {
    DetachProtocolClient();
    InProcessBrowserTest::TearDownOnMainThread();
  }

  content::WebContents* web_contents() const {
    return browser()->tab_strip_model()->GetActiveWebContents();
  }

  GURL GetURL(std::string_view host) { return https_server_.GetURL(host, "/"); }

  void NavigateToPageWithFrame(std::string_view host,
                               Browser* browser_ptr = nullptr) {
    GURL main_url(https_server_.GetURL(host, "/iframe.html"));
    ASSERT_TRUE(ui_test_utils::NavigateToURL(
        browser_ptr ? browser_ptr : browser(), main_url));
  }

  void NavigateFrameTo(std::string_view host, std::string_view path) {
    GURL page = https_server_.GetURL(host, path);
    EXPECT_TRUE(NavigateIframeToURL(web_contents(), "test", page));
  }

 private:
  base::test::ScopedFeatureList feature_list_;
  net::EmbeddedTestServer https_server_;
};

IN_PROC_BROWSER_TEST_F(DevToolsOverridesThirdPartyCookiesBrowserTest,
                       DevToolsForceDisableTPC) {
  const std::string_view kHostA = "a.test";
  const std::string_view kHostB = "b.test";
  // Apply devtools overrides to enable 3pc restriction.
  base::Value::Dict command_params;
  command_params.Set("enableThirdPartyCookieRestriction", true);
  command_params.Set("disableThirdPartyCookieMetadata", false);
  command_params.Set("disableThirdPartyCookieHeuristics", false);
  SendCommandSync("Network.setCookieControls", std::move(command_params));

  NavigateToPageWithFrame(kHostA);
  // Navigate iframe to a cross-site, cookie-setting endpoint, and verify that
  // setting 3pc should be blocked due to devtools overrides.
  NavigateFrameTo(kHostB, "/set-cookie?thirdparty=1;SameSite=None;Secure");
  EXPECT_EQ(content::GetCookies(browser()->profile(), GetURL(kHostB)), "");

  SendCommandAsync("Network.disable");
  // The override should stop working and setting 3pc is re-allowed after
  // devtools is disabled.
  NavigateToPageWithFrame(kHostA);
  NavigateFrameTo(kHostB, "/set-cookie?thirdparty=1;SameSite=None;Secure");
  EXPECT_EQ(content::GetCookies(browser()->profile(), GetURL(kHostB)),
            "thirdparty=1");
}
}  // namespace
