Skip to content

Commit d522a7c

Browse files
author
Alex Moshchuk
committed
Add synthetic field trial for sign-in isolation. (Merge to M61)
This will allow filtering results for the sign-in process isolation trial to users that have actually browsed to accounts.google.com. [email protected] (cherry picked from commit 95e8906) Bug: 739418 Change-Id: I31c9b36614cbcf1440c692d29450a851a2e29aa3 Reviewed-on: https://chromium-review.googlesource.com/579629 Commit-Queue: Alex Moshchuk <[email protected]> Reviewed-by: Avi Drissman <[email protected]> Reviewed-by: Charlie Reis <[email protected]> Reviewed-by: Lukasz Anforowicz <[email protected]> Reviewed-by: Steven Holte <[email protected]> Cr-Original-Commit-Position: refs/heads/master@{#488532} Reviewed-on: https://chromium-review.googlesource.com/586075 Reviewed-by: Alex Moshchuk <[email protected]> Cr-Commit-Position: refs/branch-heads/3163@{#62} Cr-Branched-From: ff259ba-refs/heads/master@{#488528}
1 parent 58b7f63 commit d522a7c

File tree

4 files changed

+227
-4
lines changed

4 files changed

+227
-4
lines changed

chrome/browser/chrome_navigation_browsertest.cc

Lines changed: 174 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
#include "chrome/test/base/ui_test_utils.h"
1515
#include "components/network_session_configurator/common/network_switches.h"
1616
#include "components/url_formatter/url_formatter.h"
17+
#include "components/variations/active_field_trials.h"
18+
#include "components/variations/metrics_util.h"
1719
#include "content/public/browser/navigation_entry.h"
1820
#include "content/public/browser/navigation_handle.h"
1921
#include "content/public/browser/notification_service.h"
@@ -447,8 +449,12 @@ class SignInIsolationBrowserTest : public ChromeNavigationBrowserTest {
447449
: https_server_(net::EmbeddedTestServer::TYPE_HTTPS) {}
448450
~SignInIsolationBrowserTest() override {}
449451

450-
void SetUp() override {
452+
virtual void InitFeatureList() {
451453
feature_list_.InitAndEnableFeature(features::kSignInProcessIsolation);
454+
}
455+
456+
void SetUp() override {
457+
InitFeatureList();
452458
https_server_.ServeFilesFromSourceDirectory("chrome/test/data");
453459
ASSERT_TRUE(https_server_.InitializeAndListen());
454460
ChromeNavigationBrowserTest::SetUp();
@@ -477,8 +483,41 @@ class SignInIsolationBrowserTest : public ChromeNavigationBrowserTest {
477483

478484
net::EmbeddedTestServer* https_server() { return &https_server_; }
479485

480-
private:
486+
bool HasSyntheticTrial(const std::string& trial_name) {
487+
std::vector<std::string> synthetic_trials;
488+
variations::GetSyntheticTrialGroupIdsAsString(&synthetic_trials);
489+
std::string trial_hash =
490+
base::StringPrintf("%x", metrics::HashName(trial_name));
491+
492+
for (auto entry : synthetic_trials) {
493+
if (base::StartsWith(entry, trial_hash, base::CompareCase::SENSITIVE))
494+
return true;
495+
}
496+
497+
return false;
498+
}
499+
500+
bool IsInSyntheticTrialGroup(const std::string& trial_name,
501+
const std::string& trial_group) {
502+
std::vector<std::string> synthetic_trials;
503+
variations::GetSyntheticTrialGroupIdsAsString(&synthetic_trials);
504+
std::string expected_entry = base::StringPrintf(
505+
"%x-%x", metrics::HashName(trial_name), metrics::HashName(trial_group));
506+
507+
for (auto entry : synthetic_trials) {
508+
if (entry == expected_entry)
509+
return true;
510+
}
511+
512+
return false;
513+
}
514+
515+
const std::string kSyntheticTrialName = "SignInProcessIsolationActive";
516+
517+
protected:
481518
base::test::ScopedFeatureList feature_list_;
519+
520+
private:
482521
net::EmbeddedTestServer https_server_;
483522

484523
DISALLOW_COPY_AND_ASSIGN(SignInIsolationBrowserTest);
@@ -507,3 +546,136 @@ IN_PROC_BROWSER_TEST_F(SignInIsolationBrowserTest, NavigateToSignInPage) {
507546
manager.WaitForNavigationFinished();
508547
EXPECT_NE(web_contents->GetMainFrame()->GetSiteInstance(), first_instance);
509548
}
549+
550+
// The next four tests verify that the synthetic field trial is set correctly
551+
// for sign-in process isolation. The synthetic field trial should be created
552+
// when browsing to the sign-in URL for the first time, and it should reflect
553+
// whether or not the sign-in isolation base::Feature is enabled, and whether
554+
// or not it is force-enabled from the command line.
555+
IN_PROC_BROWSER_TEST_F(SignInIsolationBrowserTest, SyntheticTrial) {
556+
EXPECT_FALSE(HasSyntheticTrial(kSyntheticTrialName));
557+
558+
ui_test_utils::NavigateToURL(
559+
browser(), https_server()->GetURL("foo.com", "/title1.html"));
560+
EXPECT_FALSE(HasSyntheticTrial(kSyntheticTrialName));
561+
562+
GURL signin_url(
563+
https_server()->GetURL("accounts.google.com", "/title1.html"));
564+
565+
// This test class uses InitAndEnableFeature, which overrides the feature
566+
// settings as if it came from the command line, so by default, browsing to
567+
// the sign-in URL should create the synthetic trial with ForceEnabled.
568+
ui_test_utils::NavigateToURL(browser(), signin_url);
569+
EXPECT_TRUE(IsInSyntheticTrialGroup(kSyntheticTrialName, "ForceEnabled"));
570+
}
571+
572+
// This test class is used to check the synthetic sign-in trial for the Enabled
573+
// group. It creates a new field trial (with 100% probability of being in the
574+
// group), and initializes the test class's ScopedFeatureList using it, being
575+
// careful to not override it using the command line (which corresponds to
576+
// ForceEnabled).
577+
class EnabledSignInIsolationBrowserTest : public SignInIsolationBrowserTest {
578+
public:
579+
EnabledSignInIsolationBrowserTest() {}
580+
~EnabledSignInIsolationBrowserTest() override {}
581+
582+
void InitFeatureList() override {}
583+
584+
void SetUpOnMainThread() override {
585+
const std::string kTrialName = "SignInProcessIsolation";
586+
const std::string kGroupName = "FooGroup"; // unused
587+
scoped_refptr<base::FieldTrial> trial =
588+
base::FieldTrialList::CreateFieldTrial(kTrialName, kGroupName);
589+
590+
std::unique_ptr<base::FeatureList> feature_list(new base::FeatureList);
591+
feature_list->RegisterFieldTrialOverride(
592+
features::kSignInProcessIsolation.name,
593+
base::FeatureList::OverrideState::OVERRIDE_ENABLE_FEATURE, trial.get());
594+
595+
feature_list_.InitWithFeatureList(std::move(feature_list));
596+
SignInIsolationBrowserTest::SetUpOnMainThread();
597+
}
598+
599+
DISALLOW_COPY_AND_ASSIGN(EnabledSignInIsolationBrowserTest);
600+
};
601+
602+
IN_PROC_BROWSER_TEST_F(EnabledSignInIsolationBrowserTest, SyntheticTrial) {
603+
EXPECT_FALSE(HasSyntheticTrial(kSyntheticTrialName));
604+
EXPECT_FALSE(IsInSyntheticTrialGroup(kSyntheticTrialName, "Enabled"));
605+
606+
GURL signin_url =
607+
https_server()->GetURL("accounts.google.com", "/title1.html");
608+
ui_test_utils::NavigateToURL(browser(), signin_url);
609+
EXPECT_TRUE(IsInSyntheticTrialGroup(kSyntheticTrialName, "Enabled"));
610+
611+
// A repeat navigation shouldn't change the synthetic trial.
612+
ui_test_utils::NavigateToURL(
613+
browser(), https_server()->GetURL("accounts.google.com", "/title2.html"));
614+
EXPECT_TRUE(IsInSyntheticTrialGroup(kSyntheticTrialName, "Enabled"));
615+
}
616+
617+
// This test class is similar to EnabledSignInIsolationBrowserTest, but for the
618+
// Disabled group of the synthetic sign-in trial.
619+
class DisabledSignInIsolationBrowserTest : public SignInIsolationBrowserTest {
620+
public:
621+
DisabledSignInIsolationBrowserTest() {}
622+
~DisabledSignInIsolationBrowserTest() override {}
623+
624+
void InitFeatureList() override {}
625+
626+
void SetUpOnMainThread() override {
627+
const std::string kTrialName = "SignInProcessIsolation";
628+
const std::string kGroupName = "FooGroup"; // unused
629+
scoped_refptr<base::FieldTrial> trial =
630+
base::FieldTrialList::CreateFieldTrial(kTrialName, kGroupName);
631+
632+
std::unique_ptr<base::FeatureList> feature_list(new base::FeatureList);
633+
feature_list->RegisterFieldTrialOverride(
634+
features::kSignInProcessIsolation.name,
635+
base::FeatureList::OverrideState::OVERRIDE_DISABLE_FEATURE,
636+
trial.get());
637+
638+
feature_list_.InitWithFeatureList(std::move(feature_list));
639+
SignInIsolationBrowserTest::SetUpOnMainThread();
640+
}
641+
642+
DISALLOW_COPY_AND_ASSIGN(DisabledSignInIsolationBrowserTest);
643+
};
644+
645+
IN_PROC_BROWSER_TEST_F(DisabledSignInIsolationBrowserTest, SyntheticTrial) {
646+
EXPECT_FALSE(IsInSyntheticTrialGroup(kSyntheticTrialName, "Disabled"));
647+
GURL signin_url =
648+
https_server()->GetURL("accounts.google.com", "/title1.html");
649+
ui_test_utils::NavigateToURL(browser(), signin_url);
650+
EXPECT_TRUE(IsInSyntheticTrialGroup(kSyntheticTrialName, "Disabled"));
651+
}
652+
653+
// This test class is similar to EnabledSignInIsolationBrowserTest, but for the
654+
// ForceDisabled group of the synthetic sign-in trial.
655+
class ForceDisabledSignInIsolationBrowserTest
656+
: public SignInIsolationBrowserTest {
657+
public:
658+
ForceDisabledSignInIsolationBrowserTest() {}
659+
~ForceDisabledSignInIsolationBrowserTest() override {}
660+
661+
void InitFeatureList() override {
662+
feature_list_.InitAndDisableFeature(features::kSignInProcessIsolation);
663+
}
664+
665+
DISALLOW_COPY_AND_ASSIGN(ForceDisabledSignInIsolationBrowserTest);
666+
};
667+
668+
IN_PROC_BROWSER_TEST_F(ForceDisabledSignInIsolationBrowserTest,
669+
SyntheticTrial) {
670+
// Test subframe navigation in this case, since that should also trigger
671+
// synthetic trial creation.
672+
ui_test_utils::NavigateToURL(browser(),
673+
https_server()->GetURL("a.com", "/iframe.html"));
674+
content::WebContents* web_contents =
675+
browser()->tab_strip_model()->GetActiveWebContents();
676+
EXPECT_FALSE(IsInSyntheticTrialGroup(kSyntheticTrialName, "ForceDisabled"));
677+
GURL signin_url =
678+
https_server()->GetURL("accounts.google.com", "/title1.html");
679+
EXPECT_TRUE(NavigateIframeToURL(web_contents, "test", signin_url));
680+
EXPECT_TRUE(IsInSyntheticTrialGroup(kSyntheticTrialName, "ForceDisabled"));
681+
}

chrome/browser/metrics/chrome_metrics_service_accessor.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,10 @@
1515
#include "components/metrics/metrics_service_accessor.h"
1616

1717
class BrowserProcessImpl;
18-
class Profile;
1918
class ChromeMetricsServiceClient;
2019
class ChromePasswordManagerClient;
20+
class NavigationMetricsRecorder;
21+
class Profile;
2122

2223
namespace {
2324
class CrashesDOMHandler;
@@ -126,6 +127,7 @@ class ChromeMetricsServiceAccessor : public metrics::MetricsServiceAccessor {
126127
friend void SyzyASANRegisterExperiment(const char*, const char*);
127128
friend class ChromeMetricsServiceClient;
128129
friend class ChromePasswordManagerClient;
130+
friend class NavigationMetricsRecorder;
129131

130132
FRIEND_TEST_ALL_PREFIXES(ChromeMetricsServiceAccessorTest,
131133
MetricsReportingEnabled);

chrome/browser/tab_contents/navigation_metrics_recorder.cc

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,11 @@
44

55
#include "chrome/browser/tab_contents/navigation_metrics_recorder.h"
66

7+
#include "base/feature_list.h"
78
#include "base/metrics/histogram_macros.h"
89
#include "build/build_config.h"
910
#include "chrome/browser/browser_process.h"
11+
#include "chrome/browser/metrics/chrome_metrics_service_accessor.h"
1012
#include "components/navigation_metrics/navigation_metrics.h"
1113
#include "components/rappor/public/rappor_utils.h"
1214
#include "components/rappor/rappor_service_impl.h"
@@ -17,7 +19,9 @@
1719
#include "content/public/browser/render_view_host.h"
1820
#include "content/public/browser/render_widget_host.h"
1921
#include "content/public/browser/render_widget_host_view.h"
22+
#include "content/public/common/content_features.h"
2023
#include "content/public/common/frame_navigate_params.h"
24+
#include "google_apis/gaia/gaia_urls.h"
2125
#include "net/base/data_url.h"
2226
#include "url/gurl.h"
2327
#include "url/origin.h"
@@ -71,7 +75,20 @@ void NavigationMetricsRecorder::set_rappor_service_for_testing(
7175
void NavigationMetricsRecorder::DidFinishNavigation(
7276
content::NavigationHandle* navigation_handle) {
7377
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
74-
if (!navigation_handle->IsInMainFrame() || !navigation_handle->HasCommitted())
78+
if (!navigation_handle->HasCommitted())
79+
return;
80+
81+
// This needs to go before the IsInMainFrame() check, as we want to register
82+
// committed navigations to the sign-in URL from both main frames and
83+
// subframes.
84+
//
85+
// TODO(alexmos): See if there's a better place for this check.
86+
if (url::Origin(navigation_handle->GetURL()) ==
87+
url::Origin(GaiaUrls::GetInstance()->gaia_url())) {
88+
RegisterSyntheticSigninIsolationTrial();
89+
}
90+
91+
if (!navigation_handle->IsInMainFrame())
7592
return;
7693

7794
content::BrowserContext* context = web_contents()->GetBrowserContext();
@@ -104,3 +121,33 @@ void NavigationMetricsRecorder::DidFinishNavigation(
104121
}
105122
}
106123
}
124+
125+
void NavigationMetricsRecorder::RegisterSyntheticSigninIsolationTrial() {
126+
// For navigations to the sign-in URL, register a synthetic field trial for
127+
// this client. This will indicate whether the sign-in process isolation is
128+
// active, and whether or not it was activated manually via a command-line
129+
// flag.
130+
//
131+
// TODO(alexmos): Remove this after the field trial for sign-in isolation.
132+
if (base::FeatureList::IsEnabled(features::kSignInProcessIsolation)) {
133+
if (base::FeatureList::GetInstance()->IsFeatureOverriddenFromCommandLine(
134+
features::kSignInProcessIsolation.name,
135+
base::FeatureList::OVERRIDE_ENABLE_FEATURE)) {
136+
ChromeMetricsServiceAccessor::RegisterSyntheticFieldTrial(
137+
"SignInProcessIsolationActive", "ForceEnabled");
138+
} else {
139+
ChromeMetricsServiceAccessor::RegisterSyntheticFieldTrial(
140+
"SignInProcessIsolationActive", "Enabled");
141+
}
142+
} else {
143+
if (base::FeatureList::GetInstance()->IsFeatureOverriddenFromCommandLine(
144+
::features::kSignInProcessIsolation.name,
145+
base::FeatureList::OVERRIDE_DISABLE_FEATURE)) {
146+
ChromeMetricsServiceAccessor::RegisterSyntheticFieldTrial(
147+
"SignInProcessIsolationActive", "ForceDisabled");
148+
} else {
149+
ChromeMetricsServiceAccessor::RegisterSyntheticFieldTrial(
150+
"SignInProcessIsolationActive", "Disabled");
151+
}
152+
}
153+
}

chrome/browser/tab_contents/navigation_metrics_recorder.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ class NavigationMetricsRecorder
4141
void DidFinishNavigation(
4242
content::NavigationHandle* navigation_handle) override;
4343

44+
void RegisterSyntheticSigninIsolationTrial();
45+
4446
rappor::RapporServiceImpl* rappor_service_;
4547

4648
DISALLOW_COPY_AND_ASSIGN(NavigationMetricsRecorder);

0 commit comments

Comments
 (0)