• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2014 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.
4 
5 #include "chrome/browser/password_manager/chrome_password_manager_client.h"
6 
7 #include "base/bind_helpers.h"
8 #include "base/command_line.h"
9 #include "base/memory/singleton.h"
10 #include "base/metrics/histogram.h"
11 #include "base/strings/string16.h"
12 #include "base/strings/utf_string_conversions.h"
13 #include "chrome/browser/browsing_data/browsing_data_helper.h"
14 #include "chrome/browser/password_manager/password_manager_util.h"
15 #include "chrome/browser/password_manager/password_store_factory.h"
16 #include "chrome/browser/password_manager/save_password_infobar_delegate.h"
17 #include "chrome/browser/password_manager/sync_metrics.h"
18 #include "chrome/browser/profiles/profile.h"
19 #include "chrome/browser/sync/profile_sync_service.h"
20 #include "chrome/browser/sync/profile_sync_service_factory.h"
21 #include "chrome/browser/ui/autofill/password_generation_popup_controller_impl.h"
22 #include "chrome/browser/ui/passwords/manage_passwords_ui_controller.h"
23 #include "chrome/common/chrome_switches.h"
24 #include "chrome/common/chrome_version_info.h"
25 #include "chrome/common/url_constants.h"
26 #include "components/autofill/content/common/autofill_messages.h"
27 #include "components/autofill/core/browser/password_generator.h"
28 #include "components/autofill/core/common/password_form.h"
29 #include "components/password_manager/content/browser/password_manager_internals_service_factory.h"
30 #include "components/password_manager/content/common/credential_manager_messages.h"
31 #include "components/password_manager/content/common/credential_manager_types.h"
32 #include "components/password_manager/core/browser/log_receiver.h"
33 #include "components/password_manager/core/browser/password_form_manager.h"
34 #include "components/password_manager/core/browser/password_manager.h"
35 #include "components/password_manager/core/browser/password_manager_internals_service.h"
36 #include "components/password_manager/core/browser/password_manager_metrics_util.h"
37 #include "components/password_manager/core/common/password_manager_switches.h"
38 #include "content/public/browser/navigation_entry.h"
39 #include "content/public/browser/render_view_host.h"
40 #include "content/public/browser/web_contents.h"
41 #include "google_apis/gaia/gaia_urls.h"
42 #include "net/base/url_util.h"
43 #include "third_party/re2/re2/re2.h"
44 
45 #if defined(OS_ANDROID)
46 #include "chrome/browser/android/password_authentication_manager.h"
47 #endif  // OS_ANDROID
48 
49 using password_manager::PasswordManagerInternalsService;
50 using password_manager::PasswordManagerInternalsServiceFactory;
51 
52 DEFINE_WEB_CONTENTS_USER_DATA_KEY(ChromePasswordManagerClient);
53 
54 // static
CreateForWebContentsWithAutofillClient(content::WebContents * contents,autofill::AutofillClient * autofill_client)55 void ChromePasswordManagerClient::CreateForWebContentsWithAutofillClient(
56     content::WebContents* contents,
57     autofill::AutofillClient* autofill_client) {
58   if (FromWebContents(contents))
59     return;
60 
61   contents->SetUserData(
62       UserDataKey(),
63       new ChromePasswordManagerClient(contents, autofill_client));
64 }
65 
ChromePasswordManagerClient(content::WebContents * web_contents,autofill::AutofillClient * autofill_client)66 ChromePasswordManagerClient::ChromePasswordManagerClient(
67     content::WebContents* web_contents,
68     autofill::AutofillClient* autofill_client)
69     : content::WebContentsObserver(web_contents),
70       profile_(Profile::FromBrowserContext(web_contents->GetBrowserContext())),
71       driver_(web_contents, this, autofill_client),
72       observer_(NULL),
73       can_use_log_router_(false),
74       autofill_sync_state_(ALLOW_SYNC_CREDENTIALS),
75       sync_credential_was_filtered_(false),
76       weak_factory_(this) {
77   PasswordManagerInternalsService* service =
78       PasswordManagerInternalsServiceFactory::GetForBrowserContext(profile_);
79   if (service)
80     can_use_log_router_ = service->RegisterClient(this);
81   SetUpAutofillSyncState();
82 }
83 
~ChromePasswordManagerClient()84 ChromePasswordManagerClient::~ChromePasswordManagerClient() {
85   PasswordManagerInternalsService* service =
86       PasswordManagerInternalsServiceFactory::GetForBrowserContext(profile_);
87   if (service)
88     service->UnregisterClient(this);
89 }
90 
IsAutomaticPasswordSavingEnabled() const91 bool ChromePasswordManagerClient::IsAutomaticPasswordSavingEnabled() const {
92   return CommandLine::ForCurrentProcess()->HasSwitch(
93       password_manager::switches::kEnableAutomaticPasswordSaving) &&
94          chrome::VersionInfo::GetChannel() ==
95              chrome::VersionInfo::CHANNEL_UNKNOWN;
96 }
97 
IsPasswordManagerEnabledForCurrentPage() const98 bool ChromePasswordManagerClient::IsPasswordManagerEnabledForCurrentPage()
99     const {
100   DCHECK(web_contents());
101   content::NavigationEntry* entry =
102       web_contents()->GetController().GetLastCommittedEntry();
103   if (!entry) {
104     // TODO(gcasto): Determine if fix for crbug.com/388246 is relevant here.
105     return true;
106   }
107 
108   // Disable the password manager for online password management.
109   if (IsURLPasswordWebsiteReauth(entry->GetURL()))
110     return false;
111 
112   if (EnabledForSyncSignin())
113     return true;
114 
115   // Do not fill nor save password when a user is signing in for sync. This
116   // is because users need to remember their password if they are syncing as
117   // this is effectively their master password.
118   return entry->GetURL().host() != chrome::kChromeUIChromeSigninHost;
119 }
120 
ShouldFilterAutofillResult(const autofill::PasswordForm & form)121 bool ChromePasswordManagerClient::ShouldFilterAutofillResult(
122     const autofill::PasswordForm& form) {
123   if (!IsSyncAccountCredential(base::UTF16ToUTF8(form.username_value),
124                                form.signon_realm))
125     return false;
126 
127   if (autofill_sync_state_ == DISALLOW_SYNC_CREDENTIALS) {
128     sync_credential_was_filtered_ = true;
129     return true;
130   }
131 
132   if (autofill_sync_state_ == DISALLOW_SYNC_CREDENTIALS_FOR_REAUTH &&
133       LastLoadWasTransactionalReauthPage()) {
134     sync_credential_was_filtered_ = true;
135     return true;
136   }
137 
138   return false;
139 }
140 
IsSyncAccountCredential(const std::string & username,const std::string & origin) const141 bool ChromePasswordManagerClient::IsSyncAccountCredential(
142     const std::string& username, const std::string& origin) const {
143   return password_manager_sync_metrics::IsSyncAccountCredential(
144       profile_, username, origin);
145 }
146 
AutofillResultsComputed()147 void ChromePasswordManagerClient::AutofillResultsComputed() {
148   UMA_HISTOGRAM_BOOLEAN("PasswordManager.SyncCredentialFiltered",
149                         sync_credential_was_filtered_);
150   sync_credential_was_filtered_ = false;
151 }
152 
PromptUserToSavePassword(scoped_ptr<password_manager::PasswordFormManager> form_to_save)153 bool ChromePasswordManagerClient::PromptUserToSavePassword(
154     scoped_ptr<password_manager::PasswordFormManager> form_to_save) {
155   // Save password infobar and the password bubble prompts in case of
156   // "webby" URLs and do not prompt in case of "non-webby" URLS (e.g. file://).
157   if (!BrowsingDataHelper::IsWebScheme(
158       web_contents()->GetLastCommittedURL().scheme())) {
159     return false;
160   }
161 
162   if (IsTheHotNewBubbleUIEnabled()) {
163     ManagePasswordsUIController* manage_passwords_ui_controller =
164         ManagePasswordsUIController::FromWebContents(web_contents());
165     manage_passwords_ui_controller->OnPasswordSubmitted(form_to_save.Pass());
166   } else {
167     std::string uma_histogram_suffix(
168         password_manager::metrics_util::GroupIdToString(
169             password_manager::metrics_util::MonitoredDomainGroupId(
170                 form_to_save->realm(), GetPrefs())));
171     SavePasswordInfoBarDelegate::Create(
172         web_contents(), form_to_save.Pass(), uma_histogram_suffix);
173   }
174   return true;
175 }
176 
AutomaticPasswordSave(scoped_ptr<password_manager::PasswordFormManager> saved_form)177 void ChromePasswordManagerClient::AutomaticPasswordSave(
178     scoped_ptr<password_manager::PasswordFormManager> saved_form) {
179   if (IsTheHotNewBubbleUIEnabled()) {
180     ManagePasswordsUIController* manage_passwords_ui_controller =
181         ManagePasswordsUIController::FromWebContents(web_contents());
182     manage_passwords_ui_controller->OnAutomaticPasswordSave(
183         saved_form.Pass());
184   }
185 }
186 
PasswordWasAutofilled(const autofill::PasswordFormMap & best_matches) const187 void ChromePasswordManagerClient::PasswordWasAutofilled(
188     const autofill::PasswordFormMap& best_matches) const {
189   ManagePasswordsUIController* manage_passwords_ui_controller =
190       ManagePasswordsUIController::FromWebContents(web_contents());
191   if (manage_passwords_ui_controller && IsTheHotNewBubbleUIEnabled())
192     manage_passwords_ui_controller->OnPasswordAutofilled(best_matches);
193 }
194 
PasswordAutofillWasBlocked(const autofill::PasswordFormMap & best_matches) const195 void ChromePasswordManagerClient::PasswordAutofillWasBlocked(
196     const autofill::PasswordFormMap& best_matches) const {
197   ManagePasswordsUIController* controller =
198       ManagePasswordsUIController::FromWebContents(web_contents());
199   if (controller && IsTheHotNewBubbleUIEnabled())
200     controller->OnBlacklistBlockedAutofill(best_matches);
201 }
202 
AuthenticateAutofillAndFillForm(scoped_ptr<autofill::PasswordFormFillData> fill_data)203 void ChromePasswordManagerClient::AuthenticateAutofillAndFillForm(
204       scoped_ptr<autofill::PasswordFormFillData> fill_data) {
205 #if defined(OS_ANDROID)
206   PasswordAuthenticationManager::AuthenticatePasswordAutofill(
207       web_contents(),
208       base::Bind(&ChromePasswordManagerClient::CommitFillPasswordForm,
209                  weak_factory_.GetWeakPtr(),
210                  base::Owned(fill_data.release())));
211 #else
212   // Additional authentication is currently only available for Android, so all
213   // other plaftorms should just fill the password form directly.
214   CommitFillPasswordForm(fill_data.get());
215 #endif  // OS_ANDROID
216 }
217 
HidePasswordGenerationPopup()218 void ChromePasswordManagerClient::HidePasswordGenerationPopup() {
219   if (popup_controller_)
220     popup_controller_->HideAndDestroy();
221 }
222 
GetPrefs()223 PrefService* ChromePasswordManagerClient::GetPrefs() {
224   return profile_->GetPrefs();
225 }
226 
227 password_manager::PasswordStore*
GetPasswordStore()228 ChromePasswordManagerClient::GetPasswordStore() {
229   // Always use EXPLICIT_ACCESS as the password manager checks IsOffTheRecord
230   // itself when it shouldn't access the PasswordStore.
231   // TODO(gcasto): Is is safe to change this to Profile::IMPLICIT_ACCESS?
232   return PasswordStoreFactory::GetForProfile(profile_, Profile::EXPLICIT_ACCESS)
233       .get();
234 }
235 
236 password_manager::PasswordManagerDriver*
GetDriver()237 ChromePasswordManagerClient::GetDriver() {
238   return &driver_;
239 }
240 
241 base::FieldTrial::Probability
GetProbabilityForExperiment(const std::string & experiment_name)242 ChromePasswordManagerClient::GetProbabilityForExperiment(
243     const std::string& experiment_name) {
244   base::FieldTrial::Probability enabled_probability = 0;
245   if (experiment_name ==
246       password_manager::PasswordManager::kOtherPossibleUsernamesExperiment) {
247     switch (chrome::VersionInfo::GetChannel()) {
248       case chrome::VersionInfo::CHANNEL_DEV:
249       case chrome::VersionInfo::CHANNEL_BETA:
250         enabled_probability = 50;
251         break;
252       default:
253         break;
254     }
255   }
256   return enabled_probability;
257 }
258 
IsPasswordSyncEnabled()259 bool ChromePasswordManagerClient::IsPasswordSyncEnabled() {
260   ProfileSyncService* sync_service =
261       ProfileSyncServiceFactory::GetForProfile(profile_);
262   // Don't consider sync enabled if the user has a custom passphrase. See
263   // crbug.com/358998 for more details.
264   if (sync_service &&
265       sync_service->HasSyncSetupCompleted() &&
266       sync_service->sync_initialized() &&
267       !sync_service->IsUsingSecondaryPassphrase()) {
268     return sync_service->GetActiveDataTypes().Has(syncer::PASSWORDS);
269   }
270   return false;
271 }
272 
OnLogRouterAvailabilityChanged(bool router_can_be_used)273 void ChromePasswordManagerClient::OnLogRouterAvailabilityChanged(
274     bool router_can_be_used) {
275   if (can_use_log_router_ == router_can_be_used)
276     return;
277   can_use_log_router_ = router_can_be_used;
278 
279   NotifyRendererOfLoggingAvailability();
280 }
281 
LogSavePasswordProgress(const std::string & text)282 void ChromePasswordManagerClient::LogSavePasswordProgress(
283     const std::string& text) {
284   if (!IsLoggingActive())
285     return;
286   PasswordManagerInternalsService* service =
287       PasswordManagerInternalsServiceFactory::GetForBrowserContext(profile_);
288   if (service)
289     service->ProcessLog(text);
290 }
291 
IsLoggingActive() const292 bool ChromePasswordManagerClient::IsLoggingActive() const {
293   // WebUI tabs do not need to log password saving progress. In particular, the
294   // internals page itself should not send any logs.
295   return can_use_log_router_ && !web_contents()->GetWebUI();
296 }
297 
OnNotifyFailedSignIn(int request_id,const password_manager::CredentialInfo &)298 void ChromePasswordManagerClient::OnNotifyFailedSignIn(
299     int request_id,
300     const password_manager::CredentialInfo&) {
301   // TODO(mkwst): This is a stub.
302   web_contents()->GetRenderViewHost()->Send(
303       new CredentialManagerMsg_AcknowledgeFailedSignIn(
304           web_contents()->GetRenderViewHost()->GetRoutingID(), request_id));
305 }
306 
OnNotifySignedIn(int request_id,const password_manager::CredentialInfo &)307 void ChromePasswordManagerClient::OnNotifySignedIn(
308     int request_id,
309     const password_manager::CredentialInfo&) {
310   // TODO(mkwst): This is a stub.
311   web_contents()->GetRenderViewHost()->Send(
312       new CredentialManagerMsg_AcknowledgeSignedIn(
313           web_contents()->GetRenderViewHost()->GetRoutingID(), request_id));
314 }
315 
OnNotifySignedOut(int request_id)316 void ChromePasswordManagerClient::OnNotifySignedOut(int request_id) {
317   // TODO(mkwst): This is a stub.
318   web_contents()->GetRenderViewHost()->Send(
319       new CredentialManagerMsg_AcknowledgeSignedOut(
320           web_contents()->GetRenderViewHost()->GetRoutingID(), request_id));
321 }
322 
OnRequestCredential(int request_id,bool zero_click_only,const std::vector<GURL> & federations)323 void ChromePasswordManagerClient::OnRequestCredential(
324     int request_id,
325     bool zero_click_only,
326     const std::vector<GURL>& federations) {
327   // TODO(mkwst): This is a stub.
328   password_manager::CredentialInfo info(base::ASCIIToUTF16("id"),
329                                         base::ASCIIToUTF16("name"),
330                                         GURL("https://example.com/image.png"));
331   web_contents()->GetRenderViewHost()->Send(
332       new CredentialManagerMsg_SendCredential(
333           web_contents()->GetRenderViewHost()->GetRoutingID(),
334           request_id,
335           info));
336 }
337 
338 // static
339 password_manager::PasswordGenerationManager*
GetGenerationManagerFromWebContents(content::WebContents * contents)340 ChromePasswordManagerClient::GetGenerationManagerFromWebContents(
341     content::WebContents* contents) {
342   ChromePasswordManagerClient* client =
343       ChromePasswordManagerClient::FromWebContents(contents);
344   if (!client)
345     return NULL;
346   return client->GetDriver()->GetPasswordGenerationManager();
347 }
348 
349 // static
350 password_manager::PasswordManager*
GetManagerFromWebContents(content::WebContents * contents)351 ChromePasswordManagerClient::GetManagerFromWebContents(
352     content::WebContents* contents) {
353   ChromePasswordManagerClient* client =
354       ChromePasswordManagerClient::FromWebContents(contents);
355   if (!client)
356     return NULL;
357   return client->GetDriver()->GetPasswordManager();
358 }
359 
SetTestObserver(autofill::PasswordGenerationPopupObserver * observer)360 void ChromePasswordManagerClient::SetTestObserver(
361     autofill::PasswordGenerationPopupObserver* observer) {
362   observer_ = observer;
363 }
364 
OnMessageReceived(const IPC::Message & message)365 bool ChromePasswordManagerClient::OnMessageReceived(
366     const IPC::Message& message) {
367   bool handled = true;
368   IPC_BEGIN_MESSAGE_MAP(ChromePasswordManagerClient, message)
369     // Autofill messages:
370     IPC_MESSAGE_HANDLER(AutofillHostMsg_ShowPasswordGenerationPopup,
371                         ShowPasswordGenerationPopup)
372     IPC_MESSAGE_HANDLER(AutofillHostMsg_ShowPasswordEditingPopup,
373                         ShowPasswordEditingPopup)
374     IPC_MESSAGE_HANDLER(AutofillHostMsg_HidePasswordGenerationPopup,
375                         HidePasswordGenerationPopup)
376     IPC_MESSAGE_HANDLER(AutofillHostMsg_PasswordAutofillAgentConstructed,
377                         NotifyRendererOfLoggingAvailability)
378 
379     // Credential Manager messages:
380     IPC_MESSAGE_HANDLER(CredentialManagerHostMsg_NotifyFailedSignIn,
381                         OnNotifyFailedSignIn);
382     IPC_MESSAGE_HANDLER(CredentialManagerHostMsg_NotifySignedIn,
383                         OnNotifySignedIn);
384     IPC_MESSAGE_HANDLER(CredentialManagerHostMsg_NotifySignedOut,
385                         OnNotifySignedOut);
386     IPC_MESSAGE_HANDLER(CredentialManagerHostMsg_RequestCredential,
387                         OnRequestCredential);
388 
389     // Default:
390     IPC_MESSAGE_UNHANDLED(handled = false)
391   IPC_END_MESSAGE_MAP()
392   return handled;
393 }
394 
GetBoundsInScreenSpace(const gfx::RectF & bounds)395 gfx::RectF ChromePasswordManagerClient::GetBoundsInScreenSpace(
396     const gfx::RectF& bounds) {
397   gfx::Rect client_area = web_contents()->GetContainerBounds();
398   return bounds + client_area.OffsetFromOrigin();
399 }
400 
ShowPasswordGenerationPopup(const gfx::RectF & bounds,int max_length,const autofill::PasswordForm & form)401 void ChromePasswordManagerClient::ShowPasswordGenerationPopup(
402     const gfx::RectF& bounds,
403     int max_length,
404     const autofill::PasswordForm& form) {
405   // TODO(gcasto): Validate data in PasswordForm.
406 
407   // Not yet implemented on other platforms.
408 #if defined(USE_AURA) || defined(OS_MACOSX)
409   gfx::RectF element_bounds_in_screen_space = GetBoundsInScreenSpace(bounds);
410 
411   popup_controller_ =
412       autofill::PasswordGenerationPopupControllerImpl::GetOrCreate(
413           popup_controller_,
414           element_bounds_in_screen_space,
415           form,
416           max_length,
417           driver_.GetPasswordManager(),
418           observer_,
419           web_contents(),
420           web_contents()->GetNativeView());
421   popup_controller_->Show(true /* display_password */);
422 #endif  // defined(USE_AURA) || defined(OS_MACOSX)
423 }
424 
ShowPasswordEditingPopup(const gfx::RectF & bounds,const autofill::PasswordForm & form)425 void ChromePasswordManagerClient::ShowPasswordEditingPopup(
426     const gfx::RectF& bounds,
427     const autofill::PasswordForm& form) {
428   gfx::RectF element_bounds_in_screen_space = GetBoundsInScreenSpace(bounds);
429   // Not yet implemented on other platforms.
430 #if defined(USE_AURA) || defined(OS_MACOSX)
431   popup_controller_ =
432       autofill::PasswordGenerationPopupControllerImpl::GetOrCreate(
433           popup_controller_,
434           element_bounds_in_screen_space,
435           form,
436           0,  // Unspecified max length.
437           driver_.GetPasswordManager(),
438           observer_,
439           web_contents(),
440           web_contents()->GetNativeView());
441   popup_controller_->Show(false /* display_password */);
442 #endif  // defined(USE_AURA) || defined(OS_MACOSX)
443 }
444 
NotifyRendererOfLoggingAvailability()445 void ChromePasswordManagerClient::NotifyRendererOfLoggingAvailability() {
446   if (!web_contents())
447     return;
448 
449   web_contents()->GetRenderViewHost()->Send(new AutofillMsg_SetLoggingState(
450       web_contents()->GetRenderViewHost()->GetRoutingID(),
451       can_use_log_router_));
452 }
453 
CommitFillPasswordForm(autofill::PasswordFormFillData * data)454 void ChromePasswordManagerClient::CommitFillPasswordForm(
455     autofill::PasswordFormFillData* data) {
456   driver_.FillPasswordForm(*data);
457 }
458 
LastLoadWasTransactionalReauthPage() const459 bool ChromePasswordManagerClient::LastLoadWasTransactionalReauthPage() const {
460   DCHECK(web_contents());
461   content::NavigationEntry* entry =
462       web_contents()->GetController().GetLastCommittedEntry();
463   if (!entry)
464     return false;
465 
466   if (entry->GetURL().GetOrigin() !=
467       GaiaUrls::GetInstance()->gaia_url().GetOrigin())
468     return false;
469 
470   // "rart" is the transactional reauth paramter.
471   std::string ignored_value;
472   return net::GetValueForKeyInQuery(entry->GetURL(),
473                                     "rart",
474                                     &ignored_value);
475 }
476 
IsURLPasswordWebsiteReauth(const GURL & url) const477 bool ChromePasswordManagerClient::IsURLPasswordWebsiteReauth(
478     const GURL& url) const {
479   if (url.GetOrigin() != GaiaUrls::GetInstance()->gaia_url().GetOrigin())
480     return false;
481 
482   // "rart" param signals this page is for transactional reauth.
483   std::string param_value;
484   if (!net::GetValueForKeyInQuery(url, "rart", &param_value))
485     return false;
486 
487   // Check the "continue" param to see if this reauth page is for the passwords
488   // website.
489   param_value.clear();
490   if (!net::GetValueForKeyInQuery(url, "continue", &param_value))
491     return false;
492 
493   // All password sites, including test sites, have autofilling disabled.
494   CR_DEFINE_STATIC_LOCAL(RE2, account_dashboard_pattern,
495                          ("passwords(-([a-z-]+\\.corp))?\\.google\\.com"));
496 
497   return RE2::FullMatch(GURL(param_value).host(), account_dashboard_pattern);
498 }
499 
IsTheHotNewBubbleUIEnabled()500 bool ChromePasswordManagerClient::IsTheHotNewBubbleUIEnabled() {
501 #if !defined(USE_AURA) && !defined(OS_MACOSX)
502   return false;
503 #endif
504   CommandLine* command_line = CommandLine::ForCurrentProcess();
505   if (command_line->HasSwitch(switches::kDisableSavePasswordBubble))
506     return false;
507 
508   if (command_line->HasSwitch(switches::kEnableSavePasswordBubble))
509     return true;
510 
511   std::string group_name =
512       base::FieldTrialList::FindFullName("PasswordManagerUI");
513 
514   // The bubble should be the default case that runs on the bots.
515   return group_name != "Infobar";
516 }
517 
EnabledForSyncSignin()518 bool ChromePasswordManagerClient::EnabledForSyncSignin() {
519   CommandLine* command_line = CommandLine::ForCurrentProcess();
520   if (command_line->HasSwitch(
521           password_manager::switches::kDisableManagerForSyncSignin))
522     return false;
523 
524   if (command_line->HasSwitch(
525           password_manager::switches::kEnableManagerForSyncSignin))
526     return true;
527 
528   // Default is enabled.
529   std::string group_name =
530       base::FieldTrialList::FindFullName("PasswordManagerStateForSyncSignin");
531   return group_name != "Disabled";
532 }
533 
SetUpAutofillSyncState()534 void ChromePasswordManagerClient::SetUpAutofillSyncState() {
535   std::string group_name =
536       base::FieldTrialList::FindFullName("AutofillSyncCredential");
537 
538   CommandLine* command_line = CommandLine::ForCurrentProcess();
539   if (command_line->HasSwitch(
540           password_manager::switches::kAllowAutofillSyncCredential)) {
541     autofill_sync_state_ = ALLOW_SYNC_CREDENTIALS;
542     return;
543   }
544   if (command_line->HasSwitch(
545           password_manager::switches::
546           kDisallowAutofillSyncCredentialForReauth)) {
547     autofill_sync_state_ = DISALLOW_SYNC_CREDENTIALS_FOR_REAUTH;
548     return;
549   }
550   if (command_line->HasSwitch(
551           password_manager::switches::kDisallowAutofillSyncCredential)) {
552     autofill_sync_state_ = DISALLOW_SYNC_CREDENTIALS;
553     return;
554   }
555 
556   if (group_name == "DisallowSyncCredentialsForReauth") {
557     autofill_sync_state_ = DISALLOW_SYNC_CREDENTIALS_FOR_REAUTH;
558   } else if (group_name == "DisallowSyncCredentials") {
559       autofill_sync_state_ = DISALLOW_SYNC_CREDENTIALS;
560   } else {
561     // Allow by default.
562     autofill_sync_state_ = ALLOW_SYNC_CREDENTIALS;
563   }
564 }
565