Commit 524dd70e authored by gcasto@chromium.org's avatar gcasto@chromium.org

[Password Manager] Setup experiment to restrict autofilling of sync credential

By default there is no change in behavior, but autofilling can now be disabled
for the sync credential entirely or just disabled for reauth pages that support
transactional reauth.

Note that this also changes GetSyncUsername() to not return the username if
password sync is disabled if it is possible to determine. This makes GetSyncUsername() a little inconsistent depending on the state of sync setup, but it's important to be as specific as possible when disabling autofilling, since it's a
usability hit.

BUG=386692
R=isherman@chromium.org

Committed: https://src.chromium.org/viewvc/chrome?view=rev&revision=290030

Review URL: https://codereview.chromium.org/451853003

Cr-Commit-Position: refs/heads/master@{#290057}
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@290057 0039d316-1c4b-4281-b951-d872f2087c98
parent 42504179
......@@ -6127,6 +6127,12 @@ Keep your key file in a safe place. You will need it to create new versions of y
<message name="IDS_FLAGS_PASSWORD_MANAGER_ANDROID_LINK_DESCRIPTION" desc="Description of the flag to enable showing a link to account central on Android password settings page">
Show a link in the password manager settings page to manage your synced passwords online.
</message>
<message name="IDS_FLAGS_AUTOFILL_SYNC_CREDENTIAL_NAME" desc="Name of the flag specifying how the browser will handle autofilling the users sync credential.">
Autofill sync credential
</message>
<message name="IDS_FLAGS_AUTOFILL_SYNC_CREDENTIAL_DESCRIPTION" desc="Description of the flag specifying how the browser will handle autofilling the users sync credential.">
How the password manager handles autofill for the sync credential.
</message>
<message name="IDS_FLAGS_PERFORMANCE_MONITOR_GATHERING_NAME" desc="Name for the flag to enable Performance Monitor.">
Enable performance monitoring
</message>
......@@ -12957,6 +12963,16 @@ Some features may be unavailable. Please check that the profile exists and you
Undo
</message>
<message name="IDS_ALLOW_AUTOFILL_SYNC_CREDENTIAL" desc="The text for the choice to allow autofilling in about:flags">
Allow
</message>
<message name="IDS_DISALLOW_AUTOFILL_SYNC_CREDENTIAL" desc="The text for the choice to not allow autofilling in about:flags">
Disallow
</message>
<message name="IDS_DISALLOW_AUTOFILL_SYNC_CREDENTIAL_FOR_REAUTH" desc="The text for the choice to not allow autofilling for reauth pages in about:flags">
Disallow for reauth
</message>
<!-- Update Recommended dialog -->
<if expr="not chromeos">
<message name="IDS_UPDATE_RECOMMENDED" desc="The main text of the Update Recommended dialog.">
......
......@@ -503,6 +503,16 @@ const Experiment::Choice kEnableAVFoundationChoices[] = {
};
#endif
const Experiment::Choice kAutofillSyncCredentialChoices[] = {
{ IDS_GENERIC_EXPERIMENT_CHOICE_DEFAULT, "", ""},
{ IDS_ALLOW_AUTOFILL_SYNC_CREDENTIAL,
password_manager::switches::kAllowAutofillSyncCredential, ""},
{ IDS_DISALLOW_AUTOFILL_SYNC_CREDENTIAL_FOR_REAUTH,
password_manager::switches::kDisallowAutofillSyncCredentialForReauth, ""},
{ IDS_DISALLOW_AUTOFILL_SYNC_CREDENTIAL,
password_manager::switches::kDisallowAutofillSyncCredential, ""},
};
// RECORDING USER METRICS FOR FLAGS:
// -----------------------------------------------------------------------------
// The first line of the experiment is the internal name. If you'd like to
......@@ -1939,6 +1949,13 @@ const Experiment kExperiments[] = {
kOsWin | kOsLinux | kOsCrOS,
SINGLE_VALUE_TYPE(extensions::switches::kEnableExtensionActionRedesign)
},
{
"autofill-sync-credential",
IDS_FLAGS_AUTOFILL_SYNC_CREDENTIAL_NAME,
IDS_FLAGS_AUTOFILL_SYNC_CREDENTIAL_DESCRIPTION,
kOsAll,
MULTI_VALUE_TYPE(kAutofillSyncCredentialChoices)
},
// NOTE: Adding new command-line switches requires adding corresponding
// entries to enum "LoginCustomFlags" in histograms.xml. See note in
// histograms.xml and don't forget to run AboutFlagsHistogramTest unit test.
......
......@@ -8,6 +8,7 @@
#include "base/command_line.h"
#include "base/memory/singleton.h"
#include "base/metrics/histogram.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/password_manager/password_manager_util.h"
#include "chrome/browser/password_manager/password_store_factory.h"
#include "chrome/browser/password_manager/save_password_infobar_delegate.h"
......@@ -33,6 +34,8 @@
#include "content/public/browser/navigation_entry.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/web_contents.h"
#include "google_apis/gaia/gaia_urls.h"
#include "net/base/url_util.h"
#if defined(OS_ANDROID)
#include "chrome/browser/android/password_authentication_manager.h"
......@@ -63,11 +66,14 @@ ChromePasswordManagerClient::ChromePasswordManagerClient(
driver_(web_contents, this, autofill_client),
observer_(NULL),
weak_factory_(this),
can_use_log_router_(false) {
can_use_log_router_(false),
autofill_sync_state_(ALLOW_SYNC_CREDENTIALS),
sync_credential_was_filtered_(false) {
PasswordManagerInternalsService* service =
PasswordManagerInternalsServiceFactory::GetForBrowserContext(profile_);
if (service)
can_use_log_router_ = service->RegisterClient(this);
SetUpAutofillSyncState();
}
ChromePasswordManagerClient::~ChromePasswordManagerClient() {
......@@ -79,7 +85,7 @@ ChromePasswordManagerClient::~ChromePasswordManagerClient() {
bool ChromePasswordManagerClient::IsAutomaticPasswordSavingEnabled() const {
return CommandLine::ForCurrentProcess()->HasSwitch(
password_manager::switches::kEnableAutomaticPasswordSaving) &&
password_manager::switches::kEnableAutomaticPasswordSaving) &&
chrome::VersionInfo::GetChannel() ==
chrome::VersionInfo::CHANNEL_UNKNOWN;
}
......@@ -102,12 +108,38 @@ bool ChromePasswordManagerClient::IsPasswordManagerEnabledForCurrentPage()
return entry->GetURL().host() != chrome::kChromeUIChromeSigninHost;
}
bool ChromePasswordManagerClient::ShouldFilterAutofillResult(
const autofill::PasswordForm& form) {
if (!IsSyncAccountCredential(base::UTF16ToUTF8(form.username_value),
form.signon_realm))
return false;
if (autofill_sync_state_ == DISALLOW_SYNC_CREDENTIALS) {
sync_credential_was_filtered_ = true;
return true;
}
if (autofill_sync_state_ == DISALLOW_SYNC_CREDENTIALS_FOR_REAUTH &&
LastLoadWasTransactionalReauthPage()) {
sync_credential_was_filtered_ = true;
return true;
}
return false;
}
bool ChromePasswordManagerClient::IsSyncAccountCredential(
const std::string& username, const std::string& origin) const {
return password_manager_sync_metrics::IsSyncAccountCredential(
profile_, username, origin);
}
void ChromePasswordManagerClient::AutofillResultsComputed() {
UMA_HISTOGRAM_BOOLEAN("PasswordManager.SyncCredentialFiltered",
sync_credential_was_filtered_);
sync_credential_was_filtered_ = false;
}
void ChromePasswordManagerClient::PromptUserToSavePassword(
scoped_ptr<password_manager::PasswordFormManager> form_to_save) {
if (IsTheHotNewBubbleUIEnabled()) {
......@@ -353,6 +385,24 @@ void ChromePasswordManagerClient::CommitFillPasswordForm(
driver_.FillPasswordForm(*data);
}
bool ChromePasswordManagerClient::LastLoadWasTransactionalReauthPage() const {
DCHECK(web_contents());
content::NavigationEntry* entry =
web_contents()->GetController().GetLastCommittedEntry();
if (!entry)
return false;
if (entry->GetURL().GetOrigin() !=
GaiaUrls::GetInstance()->gaia_url().GetOrigin())
return false;
// "rart" is the transactional reauth paramter.
std::string ignored_value;
return net::GetValueForKeyInQuery(entry->GetURL(),
"rart",
&ignored_value);
}
bool ChromePasswordManagerClient::IsTheHotNewBubbleUIEnabled() {
#if !defined(USE_AURA)
return false;
......@@ -386,3 +436,35 @@ bool ChromePasswordManagerClient::EnabledForSyncSignin() {
base::FieldTrialList::FindFullName("PasswordManagerStateForSyncSignin");
return group_name != "Disabled";
}
void ChromePasswordManagerClient::SetUpAutofillSyncState() {
std::string group_name =
base::FieldTrialList::FindFullName("AutofillSyncCredential");
CommandLine* command_line = CommandLine::ForCurrentProcess();
if (command_line->HasSwitch(
password_manager::switches::kAllowAutofillSyncCredential)) {
autofill_sync_state_ = ALLOW_SYNC_CREDENTIALS;
return;
}
if (command_line->HasSwitch(
password_manager::switches::
kDisallowAutofillSyncCredentialForReauth)) {
autofill_sync_state_ = DISALLOW_SYNC_CREDENTIALS_FOR_REAUTH;
return;
}
if (command_line->HasSwitch(
password_manager::switches::kDisallowAutofillSyncCredential)) {
autofill_sync_state_ = DISALLOW_SYNC_CREDENTIALS;
return;
}
if (group_name == "DisallowSyncCredentialsForReauth") {
autofill_sync_state_ = DISALLOW_SYNC_CREDENTIALS_FOR_REAUTH;
} else if (group_name == "DisallowSyncCredentials") {
autofill_sync_state_ = DISALLOW_SYNC_CREDENTIALS;
} else {
// Allow by default.
autofill_sync_state_ = ALLOW_SYNC_CREDENTIALS;
}
}
......@@ -40,8 +40,11 @@ class ChromePasswordManagerClient
// PasswordManagerClient implementation.
virtual bool IsAutomaticPasswordSavingEnabled() const OVERRIDE;
virtual bool IsPasswordManagerEnabledForCurrentPage() const OVERRIDE;
virtual bool ShouldFilterAutofillResult(
const autofill::PasswordForm& form) OVERRIDE;
virtual bool IsSyncAccountCredential(
const std::string& username, const std::string& origin) const OVERRIDE;
virtual void AutofillResultsComputed() OVERRIDE;
virtual void PromptUserToSavePassword(
scoped_ptr<password_manager::PasswordFormManager> form_to_save) OVERRIDE;
virtual void AutomaticPasswordSave(
......@@ -90,9 +93,18 @@ class ChromePasswordManagerClient
// Returns true if the password manager should be enabled during sync signin.
static bool EnabledForSyncSignin();
private:
protected:
// Callable for tests.
ChromePasswordManagerClient(content::WebContents* web_contents,
autofill::AutofillClient* autofill_client);
private:
enum AutofillForSyncCredentialsState {
ALLOW_SYNC_CREDENTIALS,
DISALLOW_SYNC_CREDENTIALS_FOR_REAUTH,
DISALLOW_SYNC_CREDENTIALS,
};
friend class content::WebContentsUserData<ChromePasswordManagerClient>;
// content::WebContentsObserver overrides.
......@@ -122,6 +134,13 @@ class ChromePasswordManagerClient
// |can_use_log_router_|.
void NotifyRendererOfLoggingAvailability();
// Returns true if the last loaded page was for transactional re-auth on a
// Google property.
bool LastLoadWasTransactionalReauthPage() const;
// Sets |autofill_state_| based on experiment and flag values.
void SetUpAutofillSyncState();
Profile* const profile_;
password_manager::ContentPasswordManagerDriver driver_;
......@@ -139,6 +158,13 @@ class ChromePasswordManagerClient
// True if |this| is registered with some LogRouter which can accept logs.
bool can_use_log_router_;
// How to handle the sync credential in ShouldFilterAutofillResult().
AutofillForSyncCredentialsState autofill_sync_state_;
// If the sync credential was filtered during autofill. Used for statistics
// reporting.
bool sync_credential_was_filtered_;
DISALLOW_COPY_AND_ASSIGN(ChromePasswordManagerClient);
};
......
......@@ -32,6 +32,29 @@ class MockLogReceiver : public password_manager::LogReceiver {
MOCK_METHOD1(LogSavePasswordProgress, void(const std::string&));
};
class TestChromePasswordManagerClient : public ChromePasswordManagerClient {
public:
explicit TestChromePasswordManagerClient(content::WebContents* web_contents)
: ChromePasswordManagerClient(web_contents, NULL),
is_sync_account_credential_(false) {}
virtual ~TestChromePasswordManagerClient() {}
virtual bool IsSyncAccountCredential(
const std::string& username,
const std::string& origin) const OVERRIDE {
return is_sync_account_credential_;
}
void set_is_sync_account_credential(bool is_sync_account_credential) {
is_sync_account_credential_ = is_sync_account_credential;
}
private:
bool is_sync_account_credential_;
DISALLOW_COPY_AND_ASSIGN(TestChromePasswordManagerClient);
};
} // namespace
class ChromePasswordManagerClientTest : public ChromeRenderViewHostTestHarness {
......@@ -192,3 +215,54 @@ TEST_F(ChromePasswordManagerClientTest, LogToAReceiver) {
service_->UnregisterReceiver(&receiver_);
EXPECT_FALSE(client->IsLoggingActive());
}
TEST_F(ChromePasswordManagerClientTest, ShouldFilterAutofillResult_Reauth) {
// Make client disallow only reauth requests.
CommandLine* command_line = CommandLine::ForCurrentProcess();
command_line->AppendSwitch(
password_manager::switches::kDisallowAutofillSyncCredentialForReauth);
scoped_ptr<TestChromePasswordManagerClient> client(
new TestChromePasswordManagerClient(web_contents()));
autofill::PasswordForm form;
client->set_is_sync_account_credential(false);
NavigateAndCommit(
GURL("https://accounts.google.com/login?rart=123&continue=blah"));
EXPECT_FALSE(client->ShouldFilterAutofillResult(form));
client->set_is_sync_account_credential(true);
NavigateAndCommit(
GURL("https://accounts.google.com/login?rart=123&continue=blah"));
EXPECT_TRUE(client->ShouldFilterAutofillResult(form));
// This counts as a reauth url, though a valid URL should have a value for
// "rart"
NavigateAndCommit(GURL("https://accounts.google.com/addlogin?rart"));
EXPECT_TRUE(client->ShouldFilterAutofillResult(form));
NavigateAndCommit(GURL("https://accounts.google.com/login?param=123"));
EXPECT_FALSE(client->ShouldFilterAutofillResult(form));
NavigateAndCommit(GURL("https://site.com/login?rart=678"));
EXPECT_FALSE(client->ShouldFilterAutofillResult(form));
}
TEST_F(ChromePasswordManagerClientTest, ShouldFilterAutofillResult) {
// Normally the client should allow any credentials through, even if they
// are the sync credential.
scoped_ptr<TestChromePasswordManagerClient> client(
new TestChromePasswordManagerClient(web_contents()));
autofill::PasswordForm form;
client->set_is_sync_account_credential(true);
NavigateAndCommit(GURL("https://accounts.google.com/Login"));
EXPECT_FALSE(client->ShouldFilterAutofillResult(form));
// Adding disallow switch should cause sync credential to be filtered.
CommandLine* command_line = CommandLine::ForCurrentProcess();
command_line->AppendSwitch(
password_manager::switches::kDisallowAutofillSyncCredential);
client.reset(new TestChromePasswordManagerClient(web_contents()));
client->set_is_sync_account_credential(true);
NavigateAndCommit(GURL("https://accounts.google.com/Login"));
EXPECT_TRUE(client->ShouldFilterAutofillResult(form));
}
......@@ -14,10 +14,19 @@
namespace password_manager_sync_metrics {
std::string GetSyncUsername(Profile* profile) {
// If sync is set up, return early if we aren't syncing passwords.
if (ProfileSyncServiceFactory::HasProfileSyncService(profile)) {
ProfileSyncService* sync_service =
ProfileSyncServiceFactory::GetForProfile(profile);
if (!sync_service->GetPreferredDataTypes().Has(syncer::PASSWORDS))
return std::string();
}
SigninManagerBase* signin_manager =
SigninManagerFactory::GetForProfile(profile);
if (!signin_manager)
return "";
return std::string();
return signin_manager->GetAuthenticatedUsername();
}
......
......@@ -12,9 +12,9 @@ class Profile;
namespace password_manager_sync_metrics {
// Returns the sync username for |profile|. Returns an empty string if the
// |profile| isn't syncing. It would be preferable to only return the username
// if the user is syncing passwords, but that is not currently possible since
// this function can be called during sync setup (http://crbug.com/393626).
// |profile| isn't syncing. This function tries to return an empty string if
// the user isn't syncing passwords, but it is not always possibly to determine
// since this code can be called during sync setup (http://crbug.com/393626).
std::string GetSyncUsername(Profile* profile);
// Returns true if |username| and |origin| correspond to the account which is
......
......@@ -379,7 +379,7 @@ void PasswordFormManager::OnRequestDone(
// These credentials will be in the final result regardless of score.
std::vector<PasswordForm> credentials_to_keep;
for (size_t i = 0; i < logins_result.size(); i++) {
if (IgnoreResult(*logins_result[i])) {
if (ShouldIgnoreResult(*logins_result[i])) {
delete logins_result[i];
continue;
}
......@@ -439,6 +439,8 @@ void PasswordFormManager::OnRequestDone(
// We're done matching now.
state_ = POST_MATCHING_PHASE;
client_->AutofillResultsComputed();
if (best_score <= 0) {
return;
}
......@@ -507,7 +509,7 @@ void PasswordFormManager::OnGetPasswordStoreResults(
OnRequestDone(results);
}
bool PasswordFormManager::IgnoreResult(const PasswordForm& form) const {
bool PasswordFormManager::ShouldIgnoreResult(const PasswordForm& form) const {
// Do not autofill on sign-up or change password forms (until we have some
// working change password functionality).
if (!observed_form_.new_password_element.empty())
......@@ -515,6 +517,10 @@ bool PasswordFormManager::IgnoreResult(const PasswordForm& form) const {
// Don't match an invalid SSL form with one saved under secure circumstances.
if (form.ssl_valid && !observed_form_.ssl_valid)
return true;
if (client_->ShouldFilterAutofillResult(form))
return true;
return false;
}
......
......@@ -219,7 +219,7 @@ class PasswordFormManager : public PasswordStoreConsumer {
// Helper for OnGetPasswordStoreResults to determine whether or not
// the given result form is worth scoring.
bool IgnoreResult(const autofill::PasswordForm& form) const;
bool ShouldIgnoreResult(const autofill::PasswordForm& form) const;
// Helper for Save in the case that best_matches.size() == 0, meaning
// we have no prior record of this form/username/password and the user
......
......@@ -60,6 +60,13 @@ class TestPasswordManagerClient : public StubPasswordManagerClient {
true);
}
virtual bool ShouldFilterAutofillResult(
const autofill::PasswordForm& form) OVERRIDE {
if (form == form_to_filter_)
return true;
return false;
}
virtual void PromptUserToSavePassword(
scoped_ptr<PasswordFormManager> form_to_save) OVERRIDE {}
virtual PrefService* GetPrefs() OVERRIDE { return &prefs_; }
......@@ -70,9 +77,15 @@ class TestPasswordManagerClient : public StubPasswordManagerClient {
driver_.FillPasswordForm(*fill_data.get());
}
void SetFormToFilter(const autofill::PasswordForm& form) {
form_to_filter_ = form;
}
MockPasswordManagerDriver* GetMockDriver() { return &driver_; }
private:
autofill::PasswordForm form_to_filter_;
TestingPrefServiceSimple prefs_;
PasswordStore* password_store_;
MockPasswordManagerDriver driver_;
......@@ -177,7 +190,7 @@ class PasswordFormManagerTest : public testing::Test {
}
bool IgnoredResult(PasswordFormManager* p, PasswordForm* form) {
return p->IgnoreResult(*form);
return p->ShouldIgnoreResult(*form);
}
PasswordForm* observed_form() { return &observed_form_; }
......@@ -427,6 +440,10 @@ TEST_F(PasswordFormManagerTest, TestIgnoreResult) {
saved_match()->action = GURL("http://www.google.com/b/Login");
saved_match()->origin = GURL("http://www.google.com/foo");
EXPECT_FALSE(IgnoredResult(&manager, saved_match()));
// Results should be ignored if the client requests it.
client()->SetFormToFilter(*saved_match());
EXPECT_TRUE(IgnoredResult(&manager, saved_match()));
}
TEST_F(PasswordFormManagerTest, TestEmptyAction) {
......
......@@ -35,11 +35,19 @@ class PasswordManagerClient {
// always returns true.
virtual bool IsPasswordManagerEnabledForCurrentPage() const;
// Return true if |form| should not be available for autofill.
virtual bool ShouldFilterAutofillResult(
const autofill::PasswordForm& form) = 0;
// Returns true if |username| and |origin| correspond to the account which is
// syncing.
virtual bool IsSyncAccountCredential(
const std::string& username, const std::string& origin) const = 0;
// Called when all autofill results have been computed. Client can use
// this signal to report statistics. Default implementation is a noop.
virtual void AutofillResultsComputed() {}
// Informs the embedder of a password form that can be saved if the user
// allows it. The embedder is not required to prompt the user if it decides
// that this form doesn't need to be saved.
......
......@@ -17,6 +17,11 @@ bool StubPasswordManagerClient::IsSyncAccountCredential(
return false;
}
bool StubPasswordManagerClient::ShouldFilterAutofillResult(
const autofill::PasswordForm& form) {
return false;
}
void StubPasswordManagerClient::PromptUserToSavePassword(
scoped_ptr<PasswordFormManager> form_to_save) {}
......
......@@ -20,6 +20,8 @@ class StubPasswordManagerClient : public PasswordManagerClient {
// PasswordManagerClient:
virtual bool IsSyncAccountCredential(
const std::string& username, const std::string& origin) const OVERRIDE;
virtual bool ShouldFilterAutofillResult(
const autofill::PasswordForm& form) OVERRIDE;
virtual void PromptUserToSavePassword(
scoped_ptr<PasswordFormManager> form_to_save) OVERRIDE;
virtual void AutomaticPasswordSave(
......
......@@ -8,6 +8,10 @@ namespace password_manager {
namespace switches {
// Force the password manager to allow sync credentials to be autofilled.
const char kAllowAutofillSyncCredential[] =
"allow-autofill-sync-credential";
// Disable the link in the password manager settings page that points to account
// central.
const char kDisableAndroidPasswordLink[] = "disable-android-password-link";
......@@ -20,6 +24,15 @@ const char kDisableDropSyncCredential[] =
const char kDisableManagerForSyncSignin[] =
"disable-manager-for-sync-signin";
// Disallow autofilling of the sync credential.
const char kDisallowAutofillSyncCredential[] =
"disallow-autofill-sync-credential";
// Disallow autofilling of the sync credential only for transactional reauth
// pages.
const char kDisallowAutofillSyncCredentialForReauth[] =
"disallow-autofill-sync-credential-for-reauth";
// Enable the link in the password manager settings page that points to account
// central.
const char kEnableAndroidPasswordLink[] = "enable-android-password-link";
......
......@@ -12,9 +12,12 @@ namespace switches {
// All switches in alphabetical order. The switches should be documented
// alongside the definition of their values in the .cc file.
extern const char kAllowAutofillSyncCredential[];
extern const char kDisableAndroidPasswordLink[];
extern const char kDisableDropSyncCredential[];
extern const char kDisableManagerForSyncSignin[];
extern const char kDisallowAutofillSyncCredential[];
extern const char kDisallowAutofillSyncCredentialForReauth[];
extern const char kEnableAndroidPasswordLink[];
extern const char kEnableDropSyncCredential[];
extern const char kEnableManagerForSyncSignin[];
......
......@@ -20592,6 +20592,14 @@ Therefore, the affected-histogram name has to have at least one dot in it.
</summary>
</histogram>
<histogram name="PasswordManager.SyncCredentialFiltered" enum="Boolean">
<owner>gcasto@chromium.org</owner>
<owner>vabr@chromium.org</owner>
<summary>
If the sync credential was removed from autofill consideration.
</summary>
</histogram>
<histogram name="PasswordManager.SyncingAccountState"
enum="PasswordManagerSyncingAccountState">
<owner>gcasto@chromium.org</owner>
......@@ -43737,6 +43745,7 @@ To add a new entry, add it with any value and run test to compute valid value.
<int value="1747279677" label="disable-delegated-renderer"/>
<int value="1775475563" label="malware-interstitial-v3"/>
<int value="1776475705" label="show-composited-layer-borders"/>
<int value="1783293530" label="disallow-autofill-sync-credential"/>
<int value="1803465156" label="enable-zero-suggest-most-visited"/>
<int value="1814671708" label="disable-password-manager-reauthentication"/>
<int value="1817312143" label="num-raster-threads"/>
......@@ -43815,6 +43824,7 @@ To add a new entry, add it with any value and run test to compute valid value.
<int value="2895547724" label="enable-app-list"/>
<int value="2902404798" label="disable-origin-chip"/>
<int value="2919856272" label="enable-fixed-position-compositing"/>
<int value="2945094390" label="disallow-autofill-sync-credential-for-reauth"/>
<int value="2953874362" label="enable-accelerated-overflow-scroll"/>
<int value="2954911336" label="enable-streamlined-hosted-apps"/>
<int value="2960639886" label="ash-enable-touch-view-testing"/>
......@@ -43889,6 +43899,7 @@ To add a new entry, add it with any value and run test to compute valid value.
<int value="4136418019" label="enable-embeddedsearch-api"/>
<int value="4147683810" label="enable-network-portal-notification"/>
<int value="4192430026" label="extension-content-verification"/>
<int value="4208178709" label="allow-autofill-sync-credential"/>
<int value="4214614109" label="disable-display-color-calibration"/>
<int value="4218336248" label="disable-offline-auto-reload-visible-only"/>
<int value="4226741844" label="enable-translate-new-ux"/>
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment