518 lines
20 KiB
C++
518 lines
20 KiB
C++
/* Copyright (c) 2019 The Brave Authors. All rights reserved.
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
|
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
#include "brave/browser/brave_content_browser_client.h"
|
|
|
|
#include <memory>
|
|
#include <vector>
|
|
|
|
#include "base/path_service.h"
|
|
#include "base/strings/strcat.h"
|
|
#include "base/strings/utf_string_conversions.h"
|
|
#include "base/test/bind.h"
|
|
#include "brave/components/brave_shields/core/common/brave_shield_constants.h"
|
|
#include "brave/components/constants/brave_paths.h"
|
|
#include "brave/components/constants/pref_names.h"
|
|
#include "brave/components/constants/webui_url_constants.h"
|
|
#include "brave/components/tor/buildflags/buildflags.h"
|
|
#include "chrome/browser/browser_process.h"
|
|
#include "chrome/browser/content_settings/host_content_settings_map_factory.h"
|
|
#include "chrome/browser/extensions/component_loader.h"
|
|
#include "chrome/browser/extensions/extension_service.h"
|
|
#include "chrome/browser/profiles/profile.h"
|
|
#include "chrome/browser/ui/browser.h"
|
|
#include "chrome/browser/ui/browser_window.h"
|
|
#include "chrome/browser/ui/browser_window/public/browser_window_features.h"
|
|
#include "chrome/common/buildflags.h"
|
|
#include "chrome/common/webui_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/host_content_settings_map.h"
|
|
#include "components/content_settings/core/common/content_settings_types.h"
|
|
#include "components/omnibox/browser/location_bar_model.h"
|
|
#include "components/prefs/pref_service.h"
|
|
#include "content/public/browser/navigation_entry.h"
|
|
#include "content/public/common/content_client.h"
|
|
#include "content/public/test/browser_test.h"
|
|
#include "content/public/test/browser_test_utils.h"
|
|
#include "extensions/browser/extension_registry.h"
|
|
#include "extensions/browser/extension_system.h"
|
|
#include "extensions/common/constants.h"
|
|
#include "extensions/common/manifest_handlers/background_info.h"
|
|
#include "net/dns/mock_host_resolver.h"
|
|
#include "url/origin.h"
|
|
|
|
#if BUILDFLAG(ENABLE_TOR)
|
|
#include "brave/browser/tor/tor_profile_manager.h"
|
|
#include "brave/components/tor/tor_navigation_throttle.h"
|
|
#include "brave/net/proxy_resolution/proxy_config_service_tor.h"
|
|
#endif
|
|
|
|
#if BUILDFLAG(IS_WIN)
|
|
#include "base/test/scoped_os_info_override_win.h"
|
|
#include "base/win/windows_version.h"
|
|
#include "brave/components/windows_recall/windows_recall.h"
|
|
#endif
|
|
|
|
class BraveContentBrowserClientTest : public InProcessBrowserTest {
|
|
public:
|
|
void SetUp() override {
|
|
// This is needed because component extensions are not added by default
|
|
// without it. Theyu are found to interfere with tests otherwise. It's
|
|
// needed for loading the hangouts extension of which there are tests for
|
|
// below.
|
|
extensions::ComponentLoader::EnableBackgroundExtensionsForTesting();
|
|
InProcessBrowserTest::SetUp();
|
|
}
|
|
|
|
void SetUpOnMainThread() override {
|
|
InProcessBrowserTest::SetUpOnMainThread();
|
|
|
|
browser_content_client_ = std::make_unique<BraveContentBrowserClient>();
|
|
content::SetBrowserClientForTesting(browser_content_client_.get());
|
|
|
|
host_resolver()->AddRule("*", "127.0.0.1");
|
|
content::SetupCrossSiteRedirector(embedded_test_server());
|
|
|
|
base::FilePath test_data_dir;
|
|
base::PathService::Get(brave::DIR_TEST_DATA, &test_data_dir);
|
|
embedded_test_server()->ServeFilesFromDirectory(test_data_dir);
|
|
|
|
ASSERT_TRUE(embedded_test_server()->Start());
|
|
}
|
|
|
|
void TearDown() override { browser_content_client_.reset(); }
|
|
|
|
void NavigateToURLAndWaitForRewrites(content::WebContents* contents,
|
|
const GURL& original_url,
|
|
const GURL& final_url) {
|
|
ui_test_utils::UrlLoadObserver load_complete(final_url);
|
|
browser()->OpenURL(
|
|
content::OpenURLParams(original_url, content::Referrer(),
|
|
WindowOpenDisposition::CURRENT_TAB,
|
|
ui::PAGE_TRANSITION_TYPED, false),
|
|
/*navigation_handle_callback=*/{});
|
|
load_complete.Wait();
|
|
EXPECT_EQ(contents->GetLastCommittedURL(), final_url);
|
|
}
|
|
|
|
content::ContentBrowserClient* client() {
|
|
return browser_content_client_.get();
|
|
}
|
|
|
|
private:
|
|
std::unique_ptr<BraveContentBrowserClient> browser_content_client_;
|
|
};
|
|
|
|
IN_PROC_BROWSER_TEST_F(BraveContentBrowserClientTest, CanLoadChromeURL) {
|
|
std::vector<std::string> pages{
|
|
kWelcomeHost,
|
|
};
|
|
|
|
std::vector<std::string> schemes{
|
|
"brave://",
|
|
"chrome://",
|
|
};
|
|
|
|
for (const std::string& page : pages) {
|
|
for (const std::string& scheme : schemes) {
|
|
content::WebContents* contents =
|
|
browser()->tab_strip_model()->GetActiveWebContents();
|
|
ASSERT_TRUE(
|
|
ui_test_utils::NavigateToURL(browser(), GURL(scheme + page + "/")));
|
|
ASSERT_TRUE(WaitForLoadStop(contents));
|
|
|
|
EXPECT_EQ(base::UTF16ToUTF8(browser()
|
|
->GetFeatures()
|
|
.location_bar_model()
|
|
->GetFormattedFullURL()),
|
|
("brave://" + page));
|
|
EXPECT_EQ(contents->GetController()
|
|
.GetLastCommittedEntry()
|
|
->GetVirtualURL()
|
|
.spec(),
|
|
("chrome://" + page + "/"));
|
|
EXPECT_EQ(
|
|
contents->GetController().GetLastCommittedEntry()->GetURL().spec(),
|
|
("chrome://" + page + "/"));
|
|
}
|
|
}
|
|
}
|
|
|
|
IN_PROC_BROWSER_TEST_F(BraveContentBrowserClientTest, CanLoadCustomBravePages) {
|
|
std::vector<std::string> pages{
|
|
"welcome",
|
|
};
|
|
|
|
std::vector<std::string> schemes{
|
|
"brave://",
|
|
"chrome://",
|
|
};
|
|
|
|
for (const std::string& page : pages) {
|
|
for (const std::string& scheme : schemes) {
|
|
content::WebContents* contents =
|
|
browser()->tab_strip_model()->GetActiveWebContents();
|
|
ASSERT_TRUE(
|
|
ui_test_utils::NavigateToURL(browser(), GURL(scheme + page + "/")));
|
|
ASSERT_TRUE(WaitForLoadStop(contents));
|
|
|
|
EXPECT_EQ(base::UTF16ToUTF8(browser()
|
|
->GetFeatures()
|
|
.location_bar_model()
|
|
->GetFormattedFullURL()),
|
|
("brave://" + page));
|
|
EXPECT_EQ(contents->GetController()
|
|
.GetLastCommittedEntry()
|
|
->GetVirtualURL()
|
|
.spec(),
|
|
("chrome://" + page + "/"));
|
|
EXPECT_EQ(
|
|
contents->GetController().GetLastCommittedEntry()->GetURL().spec(),
|
|
("chrome://" + page + "/"));
|
|
}
|
|
}
|
|
}
|
|
|
|
IN_PROC_BROWSER_TEST_F(BraveContentBrowserClientTest, CanLoadAboutHost) {
|
|
std::vector<std::string> schemes{
|
|
"chrome://",
|
|
"brave://",
|
|
};
|
|
|
|
for (const std::string& scheme : schemes) {
|
|
content::WebContents* contents =
|
|
browser()->tab_strip_model()->GetActiveWebContents();
|
|
ASSERT_TRUE(
|
|
ui_test_utils::NavigateToURL(browser(), GURL(scheme + "about/")));
|
|
ASSERT_TRUE(WaitForLoadStop(contents));
|
|
|
|
EXPECT_EQ(base::UTF16ToUTF8(browser()
|
|
->GetFeatures()
|
|
.location_bar_model()
|
|
->GetFormattedFullURL()),
|
|
"brave://about");
|
|
EXPECT_EQ(contents->GetController()
|
|
.GetLastCommittedEntry()
|
|
->GetVirtualURL()
|
|
.spec(),
|
|
"chrome://about/");
|
|
EXPECT_EQ(
|
|
contents->GetController().GetLastCommittedEntry()->GetURL().spec(),
|
|
"chrome://chrome-urls/");
|
|
}
|
|
}
|
|
IN_PROC_BROWSER_TEST_F(BraveContentBrowserClientTest, RewriteChromeSync) {
|
|
std::vector<std::string> schemes{
|
|
"brave://",
|
|
"chrome://",
|
|
};
|
|
|
|
for (const std::string& scheme : schemes) {
|
|
content::WebContents* contents =
|
|
browser()->tab_strip_model()->GetActiveWebContents();
|
|
NavigateToURLAndWaitForRewrites(contents,
|
|
GURL(scheme + chrome::kBraveUISyncHost),
|
|
GURL("chrome://sync"));
|
|
|
|
EXPECT_EQ(base::UTF16ToUTF8(browser()
|
|
->GetFeatures()
|
|
.location_bar_model()
|
|
->GetFormattedFullURL()),
|
|
"brave://sync");
|
|
EXPECT_EQ(
|
|
contents->GetController().GetLastCommittedEntry()->GetVirtualURL(),
|
|
GURL("chrome://sync"));
|
|
EXPECT_EQ(contents->GetController().GetLastCommittedEntry()->GetURL(),
|
|
GURL("chrome://settings/braveSync"));
|
|
}
|
|
}
|
|
|
|
IN_PROC_BROWSER_TEST_F(BraveContentBrowserClientTest, RewriteAdblock) {
|
|
std::vector<std::string> schemes{
|
|
"brave://",
|
|
"chrome://",
|
|
};
|
|
|
|
for (const std::string& scheme : schemes) {
|
|
content::WebContents* contents =
|
|
browser()->tab_strip_model()->GetActiveWebContents();
|
|
NavigateToURLAndWaitForRewrites(contents, GURL(scheme + "adblock"),
|
|
GURL("chrome://settings/shields/filters"));
|
|
EXPECT_EQ(base::UTF16ToUTF8(browser()
|
|
->GetFeatures()
|
|
.location_bar_model()
|
|
->GetFormattedFullURL()),
|
|
"brave://settings/shields/filters");
|
|
EXPECT_EQ(browser()->GetFeatures().location_bar_model()->GetURL(),
|
|
GURL("chrome://settings/shields/filters"));
|
|
EXPECT_EQ(
|
|
contents->GetController().GetLastCommittedEntry()->GetVirtualURL(),
|
|
GURL("chrome://settings/shields/filters"));
|
|
}
|
|
}
|
|
|
|
#if BUILDFLAG(ENABLE_TOR)
|
|
IN_PROC_BROWSER_TEST_F(BraveContentBrowserClientTest, MixedContentForOnion) {
|
|
net::ProxyConfigServiceTor::SetBypassTorProxyConfigForTesting(true);
|
|
tor::TorNavigationThrottle::SetSkipWaitForTorConnectedForTesting(true);
|
|
Browser* tor_browser =
|
|
TorProfileManager::SwitchToTorProfile(browser()->profile());
|
|
|
|
const GURL onion_url =
|
|
embedded_test_server()->GetURL("test.onion", "/onion.html");
|
|
const GURL onion_upgradable_url =
|
|
embedded_test_server()->GetURL("test.onion", "/onion_upgradable.html");
|
|
|
|
ASSERT_EQ("http", onion_url.scheme());
|
|
content::WebContents* contents =
|
|
tor_browser->tab_strip_model()->GetActiveWebContents();
|
|
{
|
|
content::WebContentsConsoleObserver console_observer(contents);
|
|
// filter out noises like "crbug/1173575, non-JS module files deprecated"
|
|
// since we are only interested in mix content error
|
|
console_observer.SetFilter(base::BindLambdaForTesting(
|
|
[](const content::WebContentsConsoleObserver::Message& message) {
|
|
return message.log_level == blink::mojom::ConsoleMessageLevel::kError;
|
|
}));
|
|
ASSERT_TRUE(
|
|
ui_test_utils::NavigateToURL(tor_browser, onion_upgradable_url));
|
|
EXPECT_TRUE(console_observer.messages().empty());
|
|
}
|
|
{
|
|
content::WebContentsConsoleObserver console_observer(contents);
|
|
console_observer.SetPattern(
|
|
"Mixed Content: The page at 'http://test.onion*/onion.html' was loaded "
|
|
"over HTTPS, but requested an insecure element "
|
|
"'http://auto_upgradable_to_https.com/image.jpg'. This request was "
|
|
"automatically upgraded to HTTPS*");
|
|
ASSERT_TRUE(ui_test_utils::NavigateToURL(tor_browser, onion_url));
|
|
ASSERT_TRUE(console_observer.Wait());
|
|
}
|
|
auto fetch = [](const std::string& resource) {
|
|
return "fetch('" + resource + "').then((response) => { console.log('" +
|
|
resource + "' + ' ' + response.statusText) })";
|
|
};
|
|
{
|
|
content::WebContentsConsoleObserver console_observer(contents);
|
|
console_observer.SetPattern(
|
|
"Mixed Content: The page at 'http://test.onion*/onion.html' was "
|
|
"loaded over HTTPS, but requested an insecure resource "
|
|
"'http://example.com*'. This request has been blocked; the content "
|
|
"must be served over HTTPS.");
|
|
const GURL resource_url =
|
|
embedded_test_server()->GetURL("example.com", "/logo-referrer.png");
|
|
const std::string kFetchScript = fetch(resource_url.spec());
|
|
ASSERT_FALSE(content::ExecJs(contents, kFetchScript));
|
|
ASSERT_TRUE(console_observer.Wait());
|
|
}
|
|
{
|
|
auto https_server = std::make_unique<net::EmbeddedTestServer>(
|
|
net::test_server::EmbeddedTestServer::TYPE_HTTPS);
|
|
https_server->SetSSLConfig(net::EmbeddedTestServer::CERT_TEST_NAMES);
|
|
https_server->AddDefaultHandlers();
|
|
ASSERT_TRUE(https_server->Start());
|
|
|
|
content::WebContentsConsoleObserver console_observer(contents);
|
|
const auto resource_url =
|
|
https_server->GetURL("example.a.test", "/echoheader").spec();
|
|
console_observer.SetPattern(resource_url + " OK");
|
|
const std::string kFetchScript = fetch(resource_url);
|
|
ASSERT_TRUE(content::ExecJs(contents, kFetchScript));
|
|
ASSERT_TRUE(console_observer.Wait());
|
|
}
|
|
{
|
|
content::WebContentsConsoleObserver console_observer(contents);
|
|
// logo-referrer.png sets "access-control-allow-origin: *"
|
|
const auto resource_url =
|
|
embedded_test_server()
|
|
->GetURL("example.onion", "/logo-referrer.png")
|
|
.spec();
|
|
console_observer.SetPattern(resource_url + " OK");
|
|
const std::string kFetchScript = fetch(resource_url);
|
|
ASSERT_TRUE(content::ExecJs(contents, kFetchScript));
|
|
ASSERT_TRUE(console_observer.Wait());
|
|
}
|
|
}
|
|
#endif
|
|
|
|
class BraveContentBrowserClientReferrerTest
|
|
: public BraveContentBrowserClientTest {
|
|
public:
|
|
HostContentSettingsMap* content_settings() {
|
|
return HostContentSettingsMapFactory::GetForProfile(browser()->profile());
|
|
}
|
|
};
|
|
|
|
IN_PROC_BROWSER_TEST_F(BraveContentBrowserClientReferrerTest,
|
|
DefaultBehaviour) {
|
|
const GURL kRequestUrl("http://request.com/path?query");
|
|
const GURL kDocumentUrl("http://document.com/path?query");
|
|
const GURL kSameSiteRequestUrl("http://sub.document.com/sub/path");
|
|
const GURL kSameOriginRequestUrl("http://document.com/different/path");
|
|
|
|
blink::mojom::ReferrerPtr kReferrer = blink::mojom::Referrer::New(
|
|
kDocumentUrl, network::mojom::ReferrerPolicy::kDefault);
|
|
|
|
// Cross-origin navigations get an origin.
|
|
blink::mojom::ReferrerPtr referrer = kReferrer.Clone();
|
|
client()->MaybeHideReferrer(browser()->profile(), kRequestUrl, kDocumentUrl,
|
|
&referrer);
|
|
|
|
// Creating an Origin off a GURL should generally be avoided, but it's ok in
|
|
// this particular case where we're just testing and using the http protocol.
|
|
GURL document_url_origin = url::Origin::Create(kDocumentUrl).GetURL();
|
|
EXPECT_EQ(referrer->url, document_url_origin);
|
|
|
|
// Same-origin navigations get full referrers.
|
|
referrer = kReferrer.Clone();
|
|
client()->MaybeHideReferrer(browser()->profile(), kSameOriginRequestUrl,
|
|
kDocumentUrl, &referrer);
|
|
EXPECT_EQ(referrer->url, kDocumentUrl);
|
|
|
|
// Same-site navigations get truncated referrers.
|
|
referrer = kReferrer.Clone();
|
|
client()->MaybeHideReferrer(browser()->profile(), kSameSiteRequestUrl,
|
|
kDocumentUrl, &referrer);
|
|
EXPECT_EQ(referrer->url, document_url_origin);
|
|
|
|
// Cross-origin iframe navigations get origins.
|
|
referrer = kReferrer.Clone();
|
|
client()->MaybeHideReferrer(browser()->profile(), kRequestUrl, kDocumentUrl,
|
|
&referrer);
|
|
EXPECT_EQ(referrer->url, document_url_origin);
|
|
|
|
// Same-origin iframe navigations get full referrers.
|
|
referrer = kReferrer.Clone();
|
|
client()->MaybeHideReferrer(browser()->profile(), kSameOriginRequestUrl,
|
|
kDocumentUrl, &referrer);
|
|
EXPECT_EQ(referrer->url, kDocumentUrl);
|
|
|
|
// Special rule for extensions.
|
|
const GURL kExtensionUrl("chrome-extension://abc/path?query");
|
|
referrer = kReferrer.Clone();
|
|
referrer->url = kExtensionUrl;
|
|
client()->MaybeHideReferrer(browser()->profile(), kRequestUrl, kExtensionUrl,
|
|
&referrer);
|
|
EXPECT_EQ(referrer->url, kExtensionUrl);
|
|
|
|
// Special rule for Onion services.
|
|
const GURL kOnionUrl("http://lwkjglkejslkgjel.onion/index.html");
|
|
referrer = kReferrer.Clone();
|
|
referrer->url = kOnionUrl;
|
|
client()->MaybeHideReferrer(browser()->profile(), kRequestUrl, kOnionUrl,
|
|
&referrer);
|
|
EXPECT_EQ(referrer->url, GURL()); // .onion -> normal
|
|
referrer = kReferrer.Clone();
|
|
client()->MaybeHideReferrer(browser()->profile(), kOnionUrl, kDocumentUrl,
|
|
&referrer);
|
|
EXPECT_EQ(referrer->url, document_url_origin); // normal -> .onion
|
|
|
|
// Allow referrers for certain URL.
|
|
content_settings()->SetContentSettingCustomScope(
|
|
ContentSettingsPattern::FromString(document_url_origin.spec() + "*"),
|
|
ContentSettingsPattern::Wildcard(), ContentSettingsType::BRAVE_REFERRERS,
|
|
CONTENT_SETTING_ALLOW);
|
|
referrer = kReferrer.Clone();
|
|
client()->MaybeHideReferrer(browser()->profile(), kRequestUrl, kDocumentUrl,
|
|
&referrer);
|
|
EXPECT_EQ(referrer->url, kDocumentUrl);
|
|
}
|
|
|
|
// Confirm only expected extension has been installed.
|
|
IN_PROC_BROWSER_TEST_F(BraveContentBrowserClientTest, CheckExpectedExtensions) {
|
|
// Info: This checkup will not cover on-demand component extension
|
|
// installation.
|
|
std::set<std::string> expected_extensions = {
|
|
brave_extension_id,
|
|
extensions::kWebStoreAppId,
|
|
extension_misc::kPdfExtensionId,
|
|
};
|
|
|
|
extensions::ExtensionRegistry* registry =
|
|
extensions::ExtensionRegistry::Get(browser()->profile());
|
|
std::set<std::string> installed_extensions =
|
|
registry->GenerateInstalledExtensionsSet().GetIDs();
|
|
|
|
EXPECT_EQ(expected_extensions, installed_extensions);
|
|
|
|
const auto* brave_extension =
|
|
registry->GetInstalledExtension(brave_extension_id);
|
|
|
|
// Brave Extension background page should be disabled by default.
|
|
EXPECT_FALSE(extensions::BackgroundInfo::HasBackgroundPage(brave_extension));
|
|
}
|
|
|
|
#if BUILDFLAG(IS_WIN)
|
|
|
|
class WinBraveContentBrowserClientTest
|
|
: public BraveContentBrowserClientTest,
|
|
public ::testing::WithParamInterface<
|
|
base::test::ScopedOSInfoOverride::Type> {
|
|
public:
|
|
WinBraveContentBrowserClientTest() = default;
|
|
~WinBraveContentBrowserClientTest() override = default;
|
|
|
|
bool GetShouldDoLearning(Browser* browser) {
|
|
return browser->tab_strip_model()
|
|
->GetActiveWebContents()
|
|
->GetShouldDoLearningForTesting();
|
|
}
|
|
|
|
bool IsWin11() const {
|
|
return base::win::GetVersion() >= base::win::Version::WIN11;
|
|
}
|
|
|
|
private:
|
|
base::test::ScopedOSInfoOverride win_version_{GetParam()};
|
|
};
|
|
|
|
INSTANTIATE_TEST_SUITE_P(
|
|
,
|
|
WinBraveContentBrowserClientTest,
|
|
::testing::Values(base::test::ScopedOSInfoOverride::Type::kWin11Home,
|
|
base::test::ScopedOSInfoOverride::Type::kWin10Home));
|
|
|
|
IN_PROC_BROWSER_TEST_P(WinBraveContentBrowserClientTest, PRE_WindowsRecall) {
|
|
auto* local_state = g_browser_process->local_state();
|
|
|
|
if (IsWin11()) {
|
|
// ensure previous state is already cached before the first check is made
|
|
local_state->SetBoolean(windows_recall::prefs::kWindowsRecallDisabled,
|
|
false);
|
|
// Not changed until restart.
|
|
EXPECT_TRUE(client()->IsWindowsRecallDisabled());
|
|
EXPECT_FALSE(GetShouldDoLearning(browser()));
|
|
} else {
|
|
EXPECT_FALSE(client()->IsWindowsRecallDisabled());
|
|
EXPECT_TRUE(GetShouldDoLearning(browser()));
|
|
}
|
|
|
|
// incognito behavior is unchanged from upstream (always false)
|
|
Browser* incognito = CreateIncognitoBrowser(browser()->profile());
|
|
EXPECT_FALSE(GetShouldDoLearning(incognito));
|
|
}
|
|
|
|
IN_PROC_BROWSER_TEST_P(WinBraveContentBrowserClientTest, WindowsRecall) {
|
|
auto* local_state = g_browser_process->local_state();
|
|
|
|
if (IsWin11()) {
|
|
// ensure previous state is already cached before the first check is made
|
|
local_state->SetBoolean(windows_recall::prefs::kWindowsRecallDisabled,
|
|
true);
|
|
EXPECT_FALSE(client()->IsWindowsRecallDisabled());
|
|
EXPECT_TRUE(GetShouldDoLearning(browser()));
|
|
} else {
|
|
EXPECT_FALSE(client()->IsWindowsRecallDisabled());
|
|
EXPECT_TRUE(GetShouldDoLearning(browser()));
|
|
}
|
|
|
|
// incognito behavior is unchanged from upstream (always false)
|
|
Browser* incognito = CreateIncognitoBrowser(browser()->profile());
|
|
EXPECT_FALSE(GetShouldDoLearning(incognito));
|
|
}
|
|
|
|
#endif // BUILDFLAG(IS_WIN)
|