1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/chrome_content_browser_client.h"
11 #include "base/bind.h"
12 #include "base/command_line.h"
13 #include "base/macros.h"
14 #include "base/metrics/field_trial.h"
15 #include "base/run_loop.h"
16 #include "base/strings/stringprintf.h"
17 #include "base/strings/utf_string_conversions.h"
18 #include "base/test/gtest_util.h"
19 #include "base/test/scoped_command_line.h"
20 #include "base/test/scoped_feature_list.h"
21 #include "build/build_config.h"
22 #include "chrome/browser/browsing_data/chrome_browsing_data_remover_delegate.h"
23 #include "chrome/browser/captive_portal/captive_portal_service_factory.h"
24 #include "chrome/browser/search_engines/template_url_service_factory.h"
25 #include "chrome/common/webui_url_constants.h"
26 #include "chrome/test/base/chrome_render_view_host_test_harness.h"
27 #include "chrome/test/base/testing_profile.h"
28 #include "components/browsing_data/content/browsing_data_helper.h"
29 #include "components/captive_portal/core/buildflags.h"
30 #include "components/content_settings/core/browser/host_content_settings_map.h"
31 #include "components/search_engines/template_url_service.h"
32 #include "components/variations/variations_associated_data.h"
33 #include "components/version_info/version_info.h"
34 #include "content/public/browser/browsing_data_filter_builder.h"
35 #include "content/public/browser/browsing_data_remover.h"
36 #include "content/public/browser/navigation_controller.h"
37 #include "content/public/browser/navigation_entry.h"
38 #include "content/public/browser/site_instance.h"
39 #include "content/public/browser/storage_partition.h"
40 #include "content/public/browser/web_contents.h"
41 #include "content/public/common/content_switches.h"
42 #include "content/public/common/user_agent.h"
43 #include "content/public/test/browser_task_environment.h"
44 #include "content/public/test/mock_render_process_host.h"
45 #include "media/media_buildflags.h"
46 #include "testing/gmock/include/gmock/gmock.h"
47 #include "testing/gtest/include/gtest/gtest.h"
48 #include "third_party/blink/public/common/features.h"
49 #include "third_party/blink/public/common/user_agent/user_agent_metadata.h"
52 #if defined(USE_X11) || defined(USE_OZONE)
53 #include <sys/utsname.h>
56 #if !defined(OS_ANDROID)
57 #include "chrome/browser/ui/browser.h"
58 #include "chrome/browser/ui/tabs/tab_strip_model.h"
59 #include "chrome/common/pref_names.h"
60 #include "chrome/test/base/browser_with_test_window_test.h"
61 #include "chrome/test/base/search_test_utils.h"
62 #include "ui/base/page_transition_types.h"
64 #include "base/system/sys_info.h"
67 #if BUILDFLAG(ENABLE_CAPTIVE_PORTAL_DETECTION)
68 #include "components/captive_portal/content/captive_portal_tab_helper.h"
71 #if defined(OS_CHROMEOS)
72 #include "chrome/browser/chromeos/policy/system_features_disable_list_policy_handler.h"
73 #include "chrome/test/base/scoped_testing_local_state.h"
74 #include "chrome/test/base/testing_browser_process.h"
75 #include "components/policy/core/common/policy_pref_names.h"
76 #endif // defined(OS_CHROMEOS)
78 using content::BrowsingDataFilterBuilder;
80 using ChromeContentBrowserClientTest = testing::Test;
84 void CheckUserAgentStringOrdering(bool mobile_device) {
85 std::vector<std::string> pieces;
87 // Check if the pieces of the user agent string come in the correct order.
88 ChromeContentBrowserClient content_browser_client;
89 std::string buffer = content_browser_client.GetUserAgent();
91 pieces = base::SplitStringUsingSubstr(
92 buffer, "Mozilla/5.0 (", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
93 ASSERT_EQ(2u, pieces.size());
95 EXPECT_EQ("", pieces[0]);
97 pieces = base::SplitStringUsingSubstr(
98 buffer, ") AppleWebKit/", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
99 ASSERT_EQ(2u, pieces.size());
101 std::string os_str = pieces[0];
104 base::SplitStringUsingSubstr(buffer, " (KHTML, like Gecko) ",
105 base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
106 ASSERT_EQ(2u, pieces.size());
108 std::string webkit_version_str = pieces[0];
110 pieces = base::SplitStringUsingSubstr(
111 buffer, " Safari/", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
112 ASSERT_EQ(2u, pieces.size());
113 std::string product_str = pieces[0];
114 std::string safari_version_str = pieces[1];
116 EXPECT_FALSE(os_str.empty());
118 pieces = base::SplitStringUsingSubstr(os_str, "; ", base::KEEP_WHITESPACE,
119 base::SPLIT_WANT_ALL);
121 // Windows NT 10.0; Win64; x64
122 // Windows NT 10.0; WOW64
124 std::string os_and_version = pieces[0];
125 for (unsigned int i = 1; i < pieces.size(); ++i) {
126 bool equals = ((pieces[i] == "WOW64") || (pieces[i] == "Win64") ||
130 pieces = base::SplitStringUsingSubstr(pieces[0], " ", base::KEEP_WHITESPACE,
131 base::SPLIT_WANT_ALL);
132 ASSERT_EQ(3u, pieces.size());
133 ASSERT_EQ("Windows", pieces[0]);
134 ASSERT_EQ("NT", pieces[1]);
136 ASSERT_TRUE(base::StringToDouble(pieces[2], &version));
137 ASSERT_LE(4.0, version);
138 ASSERT_GT(11.0, version);
139 #elif defined(OS_MACOSX)
140 // Macintosh; Intel Mac OS X 10_15_4
141 ASSERT_EQ(2u, pieces.size());
142 ASSERT_EQ("Macintosh", pieces[0]);
143 pieces = base::SplitStringUsingSubstr(pieces[1], " ", base::KEEP_WHITESPACE,
144 base::SPLIT_WANT_ALL);
145 ASSERT_EQ(5u, pieces.size());
146 ASSERT_EQ("Intel", pieces[0]);
147 ASSERT_EQ("Mac", pieces[1]);
148 ASSERT_EQ("OS", pieces[2]);
149 ASSERT_EQ("X", pieces[3]);
150 pieces = base::SplitStringUsingSubstr(pieces[4], "_", base::KEEP_WHITESPACE,
151 base::SPLIT_WANT_ALL);
152 ASSERT_EQ("10", pieces[0]);
154 ASSERT_TRUE(base::StringToInt(pieces[1], &value));
156 ASSERT_TRUE(base::StringToInt(pieces[2], &value));
158 #elif defined(USE_X11) || defined(USE_OZONE)
160 // X11; CrOS armv7l 4537.56.0
161 struct utsname unixinfo;
163 std::string machine = unixinfo.machine;
164 if (strcmp(unixinfo.machine, "x86_64") == 0 &&
165 sizeof(void*) == sizeof(int32_t)) {
166 machine = "i686 (x86_64)";
168 ASSERT_EQ(2u, pieces.size());
169 ASSERT_EQ("X11", pieces[0]);
170 pieces = base::SplitStringUsingSubstr(pieces[1], " ", base::KEEP_WHITESPACE,
171 base::SPLIT_WANT_ALL);
172 #if defined(OS_CHROMEOS)
173 // X11; CrOS armv7l 4537.56.0
175 ASSERT_EQ(3u, pieces.size());
176 ASSERT_EQ("CrOS", pieces[0]);
177 ASSERT_EQ(machine, pieces[1]);
178 pieces = base::SplitStringUsingSubstr(pieces[2], ".", base::KEEP_WHITESPACE,
179 base::SPLIT_WANT_ALL);
180 for (unsigned int i = 1; i < pieces.size(); ++i) {
182 ASSERT_TRUE(base::StringToInt(pieces[i], &value));
187 ASSERT_EQ(2u, pieces.size());
188 // This may not be Linux in all cases in the wild, but it is on the bots.
189 ASSERT_EQ("Linux", pieces[0]);
190 ASSERT_EQ(machine, pieces[1]);
192 #elif defined(OS_ANDROID)
193 // Linux; Android 7.1.1; Samsung Chromebook 3
194 ASSERT_GE(3u, pieces.size());
195 ASSERT_EQ("Linux", pieces[0]);
197 if (pieces.size() > 2)
200 pieces = base::SplitStringUsingSubstr(pieces[1], " ", base::KEEP_WHITESPACE,
201 base::SPLIT_WANT_ALL);
202 ASSERT_EQ(2u, pieces.size());
203 ASSERT_EQ("Android", pieces[0]);
204 pieces = base::SplitStringUsingSubstr(pieces[1], ".", base::KEEP_WHITESPACE,
205 base::SPLIT_WANT_ALL);
206 for (unsigned int i = 1; i < pieces.size(); ++i) {
208 ASSERT_TRUE(base::StringToInt(pieces[i], &value));
211 if (!model.empty()) {
212 if (base::SysInfo::GetAndroidBuildCodename() == "REL")
213 ASSERT_EQ(base::SysInfo::HardwareModelName(), model);
215 ASSERT_EQ("", model);
217 #elif defined(OS_FUCHSIA)
219 ASSERT_EQ(2u, pieces.size());
220 ASSERT_EQ("X11", pieces[0]);
221 ASSERT_EQ("Fuchsia", pieces[1]);
224 // Check that the version numbers match.
225 EXPECT_FALSE(webkit_version_str.empty());
226 EXPECT_FALSE(safari_version_str.empty());
227 EXPECT_EQ(webkit_version_str, safari_version_str);
230 base::StartsWith(product_str, "Chrome/", base::CompareCase::SENSITIVE));
232 // "Mobile" gets tacked on to the end for mobile devices, like phones.
234 base::EndsWith(product_str, " Mobile", base::CompareCase::SENSITIVE));
240 TEST_F(ChromeContentBrowserClientTest, ShouldAssignSiteForURL) {
241 ChromeContentBrowserClient client;
242 EXPECT_FALSE(client.ShouldAssignSiteForURL(GURL("chrome-native://test")));
243 EXPECT_TRUE(client.ShouldAssignSiteForURL(GURL("http://www.google.com")));
244 EXPECT_TRUE(client.ShouldAssignSiteForURL(GURL("https://www.google.com")));
247 // BrowserWithTestWindowTest doesn't work on Android.
248 #if !defined(OS_ANDROID)
250 using ChromeContentBrowserClientWindowTest = BrowserWithTestWindowTest;
252 static void DidOpenURLForWindowTest(content::WebContents** target_contents,
253 content::WebContents* opened_contents) {
254 DCHECK(target_contents);
256 *target_contents = opened_contents;
259 // This test opens two URLs using ContentBrowserClient::OpenURL. It expects the
260 // URLs to be opened in new tabs and activated, changing the active tabs after
261 // each call and increasing the tab count by 2.
262 TEST_F(ChromeContentBrowserClientWindowTest, OpenURL) {
263 ChromeContentBrowserClient client;
265 int previous_count = browser()->tab_strip_model()->count();
267 GURL urls[] = { GURL("https://www.google.com"),
268 GURL("https://www.chromium.org") };
270 for (const GURL& url : urls) {
271 content::OpenURLParams params(url, content::Referrer(),
272 WindowOpenDisposition::NEW_FOREGROUND_TAB,
273 ui::PAGE_TRANSITION_AUTO_TOPLEVEL, false);
274 // TODO(peter): We should have more in-depth browser tests for the window
275 // opening functionality, which also covers Android. This test can currently
276 // only be ran on platforms where OpenURL is implemented synchronously.
277 // See https://crbug.com/457667.
278 content::WebContents* web_contents = nullptr;
279 scoped_refptr<content::SiteInstance> site_instance =
280 content::SiteInstance::Create(browser()->profile());
281 client.OpenURL(site_instance.get(), params,
282 base::BindOnce(&DidOpenURLForWindowTest, &web_contents));
284 EXPECT_TRUE(web_contents);
286 content::WebContents* active_contents = browser()->tab_strip_model()->
287 GetActiveWebContents();
288 EXPECT_EQ(web_contents, active_contents);
289 EXPECT_EQ(url, active_contents->GetVisibleURL());
292 EXPECT_EQ(previous_count + 2, browser()->tab_strip_model()->count());
295 // TODO(crbug.com/566091): Remove the need for ShouldStayInParentProcessForNTP()
296 // and associated test.
297 TEST_F(ChromeContentBrowserClientWindowTest, ShouldStayInParentProcessForNTP) {
298 ChromeContentBrowserClient client;
299 scoped_refptr<content::SiteInstance> site_instance =
300 content::SiteInstance::CreateForURL(
301 browser()->profile(),
302 GURL("chrome-search://local-ntp/local-ntp.html"));
303 EXPECT_TRUE(client.ShouldStayInParentProcessForNTP(
304 GURL("chrome-search://local-ntp/local-ntp.html"), site_instance.get()));
306 site_instance = content::SiteInstance::CreateForURL(
307 browser()->profile(), GURL("chrome://new-tab-page"));
308 // chrome://new-tab-page is an NTP replacing local-ntp and supports OOPIFs.
309 // ShouldStayInParentProcessForNTP() should only return true for NTPs hosted
310 // under the chrome-search: scheme.
311 EXPECT_FALSE(client.ShouldStayInParentProcessForNTP(
312 GURL("chrome://new-tab-page"), site_instance.get()));
315 TEST_F(ChromeContentBrowserClientWindowTest, OverrideNavigationParams) {
316 ChromeContentBrowserClient client;
317 ui::PageTransition transition;
318 bool is_renderer_initiated;
319 content::Referrer referrer = content::Referrer();
320 base::Optional<url::Origin> initiator_origin = base::nullopt;
322 scoped_refptr<content::SiteInstance> site_instance =
323 content::SiteInstance::CreateForURL(
324 browser()->profile(),
325 GURL("chrome-search://local-ntp/local-ntp.html"));
326 transition = ui::PAGE_TRANSITION_LINK;
327 is_renderer_initiated = true;
328 // The origin is a placeholder to test that |initiator_origin| is set to
329 // base::nullopt and is not meant to represent what would happen in practice.
330 initiator_origin = url::Origin::Create(GURL("https://www.example.com"));
331 client.OverrideNavigationParams(site_instance.get(), &transition,
332 &is_renderer_initiated, &referrer,
334 EXPECT_TRUE(ui::PageTransitionCoreTypeIs(ui::PAGE_TRANSITION_AUTO_BOOKMARK,
336 EXPECT_FALSE(is_renderer_initiated);
337 EXPECT_EQ(base::nullopt, initiator_origin);
339 site_instance = content::SiteInstance::CreateForURL(
340 browser()->profile(), GURL("chrome://new-tab-page"));
341 transition = ui::PAGE_TRANSITION_LINK;
342 is_renderer_initiated = true;
343 initiator_origin = url::Origin::Create(GURL("https://www.example.com"));
344 client.OverrideNavigationParams(site_instance.get(), &transition,
345 &is_renderer_initiated, &referrer,
347 EXPECT_TRUE(ui::PageTransitionCoreTypeIs(ui::PAGE_TRANSITION_AUTO_BOOKMARK,
349 EXPECT_FALSE(is_renderer_initiated);
350 EXPECT_EQ(base::nullopt, initiator_origin);
352 // No change for transitions that are not PAGE_TRANSITION_LINK.
353 site_instance = content::SiteInstance::CreateForURL(
354 browser()->profile(), GURL("chrome://new-tab-page"));
355 transition = ui::PAGE_TRANSITION_TYPED;
356 client.OverrideNavigationParams(site_instance.get(), &transition,
357 &is_renderer_initiated, &referrer,
360 ui::PageTransitionCoreTypeIs(ui::PAGE_TRANSITION_TYPED, transition));
362 // No change for transitions on a non-NTP page.
363 site_instance = content::SiteInstance::CreateForURL(
364 browser()->profile(), GURL("https://www.example.com"));
365 transition = ui::PAGE_TRANSITION_LINK;
366 client.OverrideNavigationParams(site_instance.get(), &transition,
367 &is_renderer_initiated, &referrer,
370 ui::PageTransitionCoreTypeIs(ui::PAGE_TRANSITION_LINK, transition));
373 #endif // !defined(OS_ANDROID)
375 // NOTE: Any updates to the expectations in these tests should also be done in
376 // the browser test WebRtcDisableEncryptionFlagBrowserTest.
377 class DisableWebRtcEncryptionFlagTest : public testing::Test {
379 DisableWebRtcEncryptionFlagTest()
380 : from_command_line_(base::CommandLine::NO_PROGRAM),
381 to_command_line_(base::CommandLine::NO_PROGRAM) {}
384 void SetUp() override {
385 from_command_line_.AppendSwitch(switches::kDisableWebRtcEncryption);
388 void MaybeCopyDisableWebRtcEncryptionSwitch(version_info::Channel channel) {
389 ChromeContentBrowserClient::MaybeCopyDisableWebRtcEncryptionSwitch(
395 base::CommandLine from_command_line_;
396 base::CommandLine to_command_line_;
399 DISALLOW_COPY_AND_ASSIGN(DisableWebRtcEncryptionFlagTest);
402 TEST_F(DisableWebRtcEncryptionFlagTest, UnknownChannel) {
403 MaybeCopyDisableWebRtcEncryptionSwitch(version_info::Channel::UNKNOWN);
404 EXPECT_TRUE(to_command_line_.HasSwitch(switches::kDisableWebRtcEncryption));
407 TEST_F(DisableWebRtcEncryptionFlagTest, CanaryChannel) {
408 MaybeCopyDisableWebRtcEncryptionSwitch(version_info::Channel::CANARY);
409 EXPECT_TRUE(to_command_line_.HasSwitch(switches::kDisableWebRtcEncryption));
412 TEST_F(DisableWebRtcEncryptionFlagTest, DevChannel) {
413 MaybeCopyDisableWebRtcEncryptionSwitch(version_info::Channel::DEV);
414 EXPECT_TRUE(to_command_line_.HasSwitch(switches::kDisableWebRtcEncryption));
417 TEST_F(DisableWebRtcEncryptionFlagTest, BetaChannel) {
418 MaybeCopyDisableWebRtcEncryptionSwitch(version_info::Channel::BETA);
419 #if defined(OS_ANDROID)
420 EXPECT_TRUE(to_command_line_.HasSwitch(switches::kDisableWebRtcEncryption));
422 EXPECT_FALSE(to_command_line_.HasSwitch(switches::kDisableWebRtcEncryption));
426 TEST_F(DisableWebRtcEncryptionFlagTest, StableChannel) {
427 MaybeCopyDisableWebRtcEncryptionSwitch(version_info::Channel::STABLE);
428 EXPECT_FALSE(to_command_line_.HasSwitch(switches::kDisableWebRtcEncryption));
431 class BlinkSettingsFieldTrialTest : public testing::Test {
433 static const char kDisallowFetchFieldTrialName[];
434 static const char kFakeGroupName[];
436 BlinkSettingsFieldTrialTest()
437 : command_line_(base::CommandLine::NO_PROGRAM) {}
439 void SetUp() override {
440 command_line_.AppendSwitchASCII(
441 switches::kProcessType, switches::kRendererProcess);
444 void TearDown() override {
445 variations::testing::ClearAllVariationParams();
448 void CreateFieldTrial(const char* trial_name, const char* group_name) {
449 base::FieldTrialList::CreateFieldTrial(trial_name, group_name);
452 void CreateFieldTrialWithParams(
453 const char* trial_name,
454 const char* group_name,
455 const char* key1, const char* value1,
456 const char* key2, const char* value2) {
457 std::map<std::string, std::string> params;
458 params.insert(std::make_pair(key1, value1));
459 params.insert(std::make_pair(key2, value2));
460 CreateFieldTrial(trial_name, kFakeGroupName);
461 variations::AssociateVariationParams(trial_name, kFakeGroupName, params);
464 void AppendContentBrowserClientSwitches() {
465 client_.AppendExtraCommandLineSwitches(&command_line_, kFakeChildProcessId);
468 const base::CommandLine& command_line() const {
469 return command_line_;
472 void AppendBlinkSettingsSwitch(const char* value) {
473 command_line_.AppendSwitchASCII(switches::kBlinkSettings, value);
477 static const int kFakeChildProcessId = 1;
479 ChromeContentBrowserClient client_;
480 base::CommandLine command_line_;
482 content::BrowserTaskEnvironment task_environment_;
485 const char BlinkSettingsFieldTrialTest::kDisallowFetchFieldTrialName[] =
486 "DisallowFetchForDocWrittenScriptsInMainFrame";
487 const char BlinkSettingsFieldTrialTest::kFakeGroupName[] = "FakeGroup";
489 TEST_F(BlinkSettingsFieldTrialTest, NoFieldTrial) {
490 AppendContentBrowserClientSwitches();
491 EXPECT_FALSE(command_line().HasSwitch(switches::kBlinkSettings));
494 TEST_F(BlinkSettingsFieldTrialTest, FieldTrialWithoutParams) {
495 CreateFieldTrial(kDisallowFetchFieldTrialName, kFakeGroupName);
496 AppendContentBrowserClientSwitches();
497 EXPECT_FALSE(command_line().HasSwitch(switches::kBlinkSettings));
500 TEST_F(BlinkSettingsFieldTrialTest, BlinkSettingsSwitchAlreadySpecified) {
501 AppendBlinkSettingsSwitch("foo");
502 CreateFieldTrialWithParams(kDisallowFetchFieldTrialName, kFakeGroupName,
503 "key1", "value1", "key2", "value2");
504 AppendContentBrowserClientSwitches();
505 EXPECT_TRUE(command_line().HasSwitch(switches::kBlinkSettings));
507 command_line().GetSwitchValueASCII(switches::kBlinkSettings));
510 TEST_F(BlinkSettingsFieldTrialTest, FieldTrialEnabled) {
511 CreateFieldTrialWithParams(kDisallowFetchFieldTrialName, kFakeGroupName,
512 "key1", "value1", "key2", "value2");
513 AppendContentBrowserClientSwitches();
514 EXPECT_TRUE(command_line().HasSwitch(switches::kBlinkSettings));
515 EXPECT_EQ("key1=value1,key2=value2",
516 command_line().GetSwitchValueASCII(switches::kBlinkSettings));
519 #if !defined(OS_ANDROID)
522 class InstantNTPURLRewriteTest : public BrowserWithTestWindowTest {
524 void InstallTemplateURLWithNewTabPage(GURL new_tab_page_url) {
525 TemplateURLServiceFactory::GetInstance()->SetTestingFactoryAndUse(
527 base::BindRepeating(&TemplateURLServiceFactory::BuildInstanceFor));
528 TemplateURLService* template_url_service =
529 TemplateURLServiceFactory::GetForProfile(browser()->profile());
530 search_test_utils::WaitForTemplateURLServiceToLoad(template_url_service);
532 TemplateURLData data;
533 data.SetShortName(base::ASCIIToUTF16("foo.com"));
534 data.SetURL("http://foo.com/url?bar={searchTerms}");
535 data.new_tab_url = new_tab_page_url.spec();
536 TemplateURL* template_url =
537 template_url_service->Add(std::make_unique<TemplateURL>(data));
538 template_url_service->SetUserSelectedDefaultSearchProvider(template_url);
542 TEST_F(InstantNTPURLRewriteTest, UberURLHandler_InstantExtendedNewTabPage) {
543 const GURL url_original(chrome::kChromeUINewTabURL);
544 const GURL url_rewritten("https://www.example.com/newtab");
545 InstallTemplateURLWithNewTabPage(url_rewritten);
546 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial("InstantExtended",
547 "Group1 use_cacheable_ntp:1"));
549 AddTab(browser(), GURL(url::kAboutBlankURL));
550 NavigateAndCommitActiveTab(url_original);
552 NavigationEntry* entry = browser()->tab_strip_model()->
553 GetActiveWebContents()->GetController().GetLastCommittedEntry();
554 ASSERT_TRUE(entry != NULL);
555 EXPECT_EQ(url_rewritten, entry->GetURL());
556 EXPECT_EQ(url_original, entry->GetVirtualURL());
559 } // namespace content
560 #endif // !defined(OS_ANDROID)
562 class ChromeContentBrowserClientGetLoggingFileTest : public testing::Test {};
564 TEST_F(ChromeContentBrowserClientGetLoggingFileTest, GetLoggingFile) {
565 base::CommandLine cmd_line(base::CommandLine::NO_PROGRAM);
566 ChromeContentBrowserClient client;
567 base::FilePath log_file_name;
568 EXPECT_FALSE(client.GetLoggingFileName(cmd_line).empty());
571 TEST_F(ChromeContentBrowserClientGetLoggingFileTest,
572 GetLoggingFileFromCommandLine) {
573 base::CommandLine cmd_line(base::CommandLine::NO_PROGRAM);
574 cmd_line.AppendSwitchASCII(switches::kLogFile, "test_log.txt");
575 ChromeContentBrowserClient client;
576 base::FilePath log_file_name;
577 EXPECT_EQ(base::FilePath(FILE_PATH_LITERAL("test_log.txt")).value(),
578 client.GetLoggingFileName(cmd_line).value());
581 class TestChromeContentBrowserClient : public ChromeContentBrowserClient {
583 using ChromeContentBrowserClient::HandleWebUI;
584 using ChromeContentBrowserClient::HandleWebUIReverse;
587 TEST(ChromeContentBrowserClientTest, HandleWebUI) {
588 TestChromeContentBrowserClient test_content_browser_client;
589 const GURL http_help("http://help/");
590 GURL should_not_redirect = http_help;
591 test_content_browser_client.HandleWebUI(&should_not_redirect, nullptr);
592 EXPECT_EQ(http_help, should_not_redirect);
594 const GURL chrome_help(chrome::kChromeUIHelpURL);
595 GURL should_redirect = chrome_help;
596 test_content_browser_client.HandleWebUI(&should_redirect, nullptr);
597 EXPECT_NE(chrome_help, should_redirect);
600 TEST(ChromeContentBrowserClientTest, HandleWebUIReverse) {
601 TestChromeContentBrowserClient test_content_browser_client;
602 GURL http_settings("http://settings/");
604 test_content_browser_client.HandleWebUIReverse(&http_settings, nullptr));
605 GURL chrome_settings(chrome::kChromeUISettingsURL);
606 EXPECT_TRUE(test_content_browser_client.HandleWebUIReverse(&chrome_settings,
610 TEST(ChromeContentBrowserClientTest, UserAgentStringFrozen) {
611 base::test::ScopedFeatureList scoped_feature_list;
612 scoped_feature_list.InitAndEnableFeature(blink::features::kFreezeUserAgent);
614 #if defined(OS_ANDROID)
615 // Verify the correct user agent is returned when the UseMobileUserAgent
616 // command line flag is present.
617 const char* const kArguments[] = {"chrome"};
618 base::test::ScopedCommandLine scoped_command_line;
619 base::CommandLine* command_line = scoped_command_line.GetProcessCommandLine();
620 command_line->InitFromArgv(1, kArguments);
622 // Verify the mobile user agent string is not returned when not using a mobile
624 ASSERT_FALSE(command_line->HasSwitch(switches::kUseMobileUserAgent));
626 ChromeContentBrowserClient content_browser_client;
627 std::string buffer = content_browser_client.GetUserAgent();
628 EXPECT_EQ(buffer, base::StringPrintf(
629 content::frozen_user_agent_strings::kAndroid,
630 version_info::GetMajorVersionNumber().c_str()));
633 // Verify the mobile user agent string is returned when using a mobile user
635 command_line->AppendSwitch(switches::kUseMobileUserAgent);
636 ASSERT_TRUE(command_line->HasSwitch(switches::kUseMobileUserAgent));
638 ChromeContentBrowserClient content_browser_client;
639 std::string buffer = content_browser_client.GetUserAgent();
640 EXPECT_EQ(buffer, base::StringPrintf(
641 content::frozen_user_agent_strings::kAndroidMobile,
642 version_info::GetMajorVersionNumber().c_str()));
646 ChromeContentBrowserClient content_browser_client;
647 std::string buffer = content_browser_client.GetUserAgent();
648 EXPECT_EQ(buffer, base::StringPrintf(
649 content::frozen_user_agent_strings::kDesktop,
650 version_info::GetMajorVersionNumber().c_str()));
655 TEST(ChromeContentBrowserClientTest, UserAgentStringOrdering) {
656 #if defined(OS_ANDROID)
657 const char* const kArguments[] = {"chrome"};
658 base::test::ScopedCommandLine scoped_command_line;
659 base::CommandLine* command_line = scoped_command_line.GetProcessCommandLine();
660 command_line->InitFromArgv(1, kArguments);
662 // Do it for regular devices.
663 ASSERT_FALSE(command_line->HasSwitch(switches::kUseMobileUserAgent));
664 CheckUserAgentStringOrdering(false);
666 // Do it for mobile devices.
667 command_line->AppendSwitch(switches::kUseMobileUserAgent);
668 ASSERT_TRUE(command_line->HasSwitch(switches::kUseMobileUserAgent));
669 CheckUserAgentStringOrdering(true);
671 CheckUserAgentStringOrdering(false);
675 TEST(ChromeContentBrowserClientTest, UserAgentMetadata) {
676 ChromeContentBrowserClient content_browser_client;
677 auto metadata = content_browser_client.GetUserAgentMetadata();
679 std::string major_version = version_info::GetMajorVersionNumber();
681 // According to spec, Sec-CH-UA should contain what project the browser is
682 // based on (i.e. Chromium in this case) as well as the actual product.
683 // In CHROMIUM_BRANDING builds this will check chromium twice. That should be
686 const blink::UserAgentBrandVersion chromium_brand_version = {"Chromium",
688 const blink::UserAgentBrandVersion product_brand_version = {
689 version_info::GetProductName(), version_info::GetMajorVersionNumber()};
690 bool contains_chromium_brand_version = false;
691 bool contains_product_brand_version = false;
693 for (const auto& brand_version : metadata.brand_version_list) {
694 if (brand_version == chromium_brand_version) {
695 contains_chromium_brand_version = true;
697 if (brand_version == product_brand_version) {
698 contains_product_brand_version = true;
702 EXPECT_TRUE(contains_chromium_brand_version);
703 EXPECT_TRUE(contains_product_brand_version);
705 EXPECT_EQ(metadata.full_version, version_info::GetVersionNumber());
706 EXPECT_EQ(metadata.platform_version,
707 content::GetOSVersion(content::IncludeAndroidBuildNumber::Exclude,
708 content::IncludeAndroidModel::Exclude));
709 // This makes sure no extra information is added to the platform version.
710 EXPECT_EQ(metadata.platform_version.find(";"), std::string::npos);
711 EXPECT_EQ(metadata.platform, version_info::GetOSType());
712 EXPECT_EQ(metadata.architecture, content::GetLowEntropyCpuArchitecture());
713 EXPECT_EQ(metadata.model, content::BuildModelInfo());
716 TEST(ChromeContentBrowserClientTest, GenerateBrandVersionList) {
717 blink::UserAgentMetadata metadata;
719 metadata.brand_version_list =
720 GenerateBrandVersionList(84, base::nullopt, "84");
721 std::string brand_list = metadata.SerializeBrandVersionList();
722 EXPECT_EQ(R"("\\Not\"A;Brand";v="99", "Chromium";v="84")", brand_list);
724 metadata.brand_version_list =
725 GenerateBrandVersionList(85, base::nullopt, "85");
726 std::string brand_list_diff = metadata.SerializeBrandVersionList();
727 // Make sure the lists are different for different seeds
728 EXPECT_EQ(R"("Chromium";v="85", "\\Not;A\"Brand";v="99")", brand_list_diff);
729 EXPECT_NE(brand_list, brand_list_diff);
731 metadata.brand_version_list =
732 GenerateBrandVersionList(84, "Totally A Brand", "84");
733 std::string brand_list_w_brand = metadata.SerializeBrandVersionList();
735 R"("\\Not\"A;Brand";v="99", "Chromium";v="84", "Totally A Brand";v="84")",
738 // Should DCHECK on negative numbers
739 EXPECT_DCHECK_DEATH(GenerateBrandVersionList(-1, base::nullopt, "99"));
742 TEST(ChromeContentBrowserClientTest, LowEntropyCpuArchitecture) {
743 std::string arch = content::GetLowEntropyCpuArchitecture();
745 #if (!defined(OS_POSIX) && !defined(OS_WIN)) || defined(OS_MACOSX) || \
748 #elif (defined(OS_POSIX) && !defined(OS_MACOSX)) || defined(OS_WIN)
749 EXPECT_TRUE("arm" == arch || "x86" == arch);
753 #if defined(OS_CHROMEOS)
754 class ChromeContentSettingsRedirectTest
755 : public ChromeContentBrowserClientTest {
757 ChromeContentSettingsRedirectTest()
758 : testing_local_state_(TestingBrowserProcess::GetGlobal()) {}
761 content::BrowserTaskEnvironment task_environment_;
762 ScopedTestingLocalState testing_local_state_;
763 TestingProfile profile_;
766 TEST_F(ChromeContentSettingsRedirectTest, RedirectOSSettingsURL) {
767 TestChromeContentBrowserClient test_content_browser_client;
768 const GURL os_settings_url(chrome::kChromeUIOSSettingsURL);
769 GURL dest_url = os_settings_url;
770 test_content_browser_client.HandleWebUI(&dest_url, &profile_);
771 EXPECT_EQ(os_settings_url, dest_url);
773 base::Value list(base::Value::Type::LIST);
774 list.Append(policy::SystemFeature::OS_SETTINGS);
775 testing_local_state_.Get()->Set(
776 policy::policy_prefs::kSystemFeaturesDisableList, std::move(list));
778 dest_url = os_settings_url;
779 test_content_browser_client.HandleWebUI(&dest_url, &profile_);
780 EXPECT_EQ(GURL(chrome::kChromeUIAppDisabledURL), dest_url);
782 GURL os_settings_pwa_url =
783 GURL(chrome::kChromeUIOSSettingsURL).Resolve("pwa.html");
784 dest_url = os_settings_pwa_url;
785 test_content_browser_client.HandleWebUI(&dest_url, &profile_);
786 EXPECT_EQ(os_settings_pwa_url, dest_url);
789 TEST_F(ChromeContentSettingsRedirectTest, RedirectSettingsURL) {
790 TestChromeContentBrowserClient test_content_browser_client;
791 const GURL settings_url(chrome::kChromeUISettingsURL);
792 GURL dest_url = settings_url;
793 test_content_browser_client.HandleWebUI(&dest_url, &profile_);
794 EXPECT_EQ(settings_url, dest_url);
796 base::Value list(base::Value::Type::LIST);
797 list.Append(policy::SystemFeature::BROWSER_SETTINGS);
798 testing_local_state_.Get()->Set(
799 policy::policy_prefs::kSystemFeaturesDisableList, std::move(list));
801 dest_url = settings_url;
802 test_content_browser_client.HandleWebUI(&dest_url, &profile_);
803 EXPECT_EQ(GURL(chrome::kChromeUIAppDisabledURL), dest_url);
805 #endif // defined(OS_CHROMEOS)
807 class CaptivePortalCheckProcessHost : public content::MockRenderProcessHost {
809 explicit CaptivePortalCheckProcessHost(
810 content::BrowserContext* browser_context)
811 : MockRenderProcessHost(browser_context) {}
813 void CreateURLLoaderFactory(
814 mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver,
815 network::mojom::URLLoaderFactoryParamsPtr params) override {
816 *invoked_url_factory_ = true;
817 DCHECK_EQ(expected_disable_secure_dns_, params->disable_secure_dns);
820 void SetupForTracking(bool* invoked_url_factory,
821 bool expected_disable_secure_dns) {
822 invoked_url_factory_ = invoked_url_factory;
823 expected_disable_secure_dns_ = expected_disable_secure_dns;
827 bool* invoked_url_factory_ = nullptr;
828 bool expected_disable_secure_dns_ = false;
830 DISALLOW_COPY_AND_ASSIGN(CaptivePortalCheckProcessHost);
833 class CaptivePortalCheckRenderProcessHostFactory
834 : public content::RenderProcessHostFactory {
836 CaptivePortalCheckRenderProcessHostFactory() = default;
838 content::RenderProcessHost* CreateRenderProcessHost(
839 content::BrowserContext* browser_context,
840 content::SiteInstance* site_instance) override {
841 rph_ = new CaptivePortalCheckProcessHost(browser_context);
845 void SetupForTracking(bool* invoked_url_factory,
846 bool expected_disable_secure_dns) {
847 rph_->SetupForTracking(invoked_url_factory, expected_disable_secure_dns);
851 CaptivePortalCheckProcessHost* rph_ = nullptr;
853 DISALLOW_COPY_AND_ASSIGN(CaptivePortalCheckRenderProcessHostFactory);
856 class ChromeContentBrowserClientCaptivePortalBrowserTest
857 : public ChromeRenderViewHostTestHarness {
860 void SetUp() override {
861 SetRenderProcessHostFactory(&cp_rph_factory_);
862 ChromeRenderViewHostTestHarness::SetUp();
865 CaptivePortalCheckRenderProcessHostFactory cp_rph_factory_;
868 TEST_F(ChromeContentBrowserClientCaptivePortalBrowserTest,
869 NotCaptivePortalWindow) {
870 bool invoked_url_factory = false;
871 cp_rph_factory_.SetupForTracking(&invoked_url_factory,
872 false /* expected_disable_secure_dns */);
873 NavigateAndCommit(GURL("https://www.google.com"), ui::PAGE_TRANSITION_LINK);
874 EXPECT_TRUE(invoked_url_factory);
877 #if BUILDFLAG(ENABLE_CAPTIVE_PORTAL_DETECTION)
878 TEST_F(ChromeContentBrowserClientCaptivePortalBrowserTest,
879 CaptivePortalWindow) {
880 bool invoked_url_factory = false;
881 cp_rph_factory_.SetupForTracking(&invoked_url_factory,
882 true /* expected_disable_secure_dns */);
883 captive_portal::CaptivePortalTabHelper::CreateForWebContents(
884 web_contents(), CaptivePortalServiceFactory::GetForProfile(profile()),
885 base::Callback<void(void)>());
886 captive_portal::CaptivePortalTabHelper::FromWebContents(web_contents())
887 ->set_is_captive_portal_window();
888 NavigateAndCommit(GURL("https://www.google.com"), ui::PAGE_TRANSITION_LINK);
889 EXPECT_TRUE(invoked_url_factory);