Add new certificateProvider extension API.
[chromium-blink-merge.git] / chrome / browser / ui / sync / one_click_signin_sync_starter.cc
bloba87c44c294417004894363ef1912794d14871c0f
1 // Copyright (c) 2012 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/ui/sync/one_click_signin_sync_starter.h"
7 #include "base/metrics/histogram.h"
8 #include "base/prefs/pref_service.h"
9 #include "base/strings/utf_string_conversions.h"
10 #include "chrome/browser/browser_process.h"
12 #if defined(ENABLE_CONFIGURATION_POLICY)
13 #include "chrome/browser/policy/cloud/user_policy_signin_service.h"
14 #include "chrome/browser/policy/cloud/user_policy_signin_service_factory.h"
15 #endif
17 #include "chrome/browser/profiles/profile.h"
18 #include "chrome/browser/profiles/profile_avatar_icon_util.h"
19 #include "chrome/browser/profiles/profile_info_cache.h"
20 #include "chrome/browser/profiles/profile_io_data.h"
21 #include "chrome/browser/profiles/profile_manager.h"
22 #include "chrome/browser/profiles/profile_window.h"
23 #include "chrome/browser/signin/signin_manager_factory.h"
24 #include "chrome/browser/signin/signin_tracker_factory.h"
25 #include "chrome/browser/sync/profile_sync_service.h"
26 #include "chrome/browser/sync/profile_sync_service_factory.h"
27 #include "chrome/browser/ui/browser.h"
28 #include "chrome/browser/ui/browser_finder.h"
29 #include "chrome/browser/ui/browser_list.h"
30 #include "chrome/browser/ui/browser_navigator.h"
31 #include "chrome/browser/ui/browser_tabstrip.h"
32 #include "chrome/browser/ui/browser_window.h"
33 #include "chrome/browser/ui/chrome_pages.h"
34 #include "chrome/browser/ui/sync/one_click_signin_sync_observer.h"
35 #include "chrome/browser/ui/tab_dialogs.h"
36 #include "chrome/browser/ui/tabs/tab_strip_model.h"
37 #include "chrome/browser/ui/webui/signin/login_ui_service_factory.h"
38 #include "chrome/common/url_constants.h"
39 #include "chrome/grit/chromium_strings.h"
40 #include "chrome/grit/generated_resources.h"
41 #include "components/signin/core/browser/signin_manager.h"
42 #include "components/signin/core/browser/signin_metrics.h"
43 #include "components/sync_driver/sync_prefs.h"
44 #include "net/url_request/url_request_context_getter.h"
45 #include "ui/base/l10n/l10n_util.h"
47 namespace {
49 // UMA histogram for tracking what users do when presented with the signin
50 // screen.
51 // Hence,
52 // (a) existing enumerated constants should never be deleted or reordered, and
53 // (b) new constants should only be appended at the end of the enumeration.
55 // Keep this in sync with SigninChoice in histograms.xml.
56 enum SigninChoice {
57 SIGNIN_CHOICE_CANCEL = 0,
58 SIGNIN_CHOICE_CONTINUE = 1,
59 SIGNIN_CHOICE_NEW_PROFILE = 2,
60 // SIGNIN_CHOICE_SIZE should always be last - this is a count of the number
61 // of items in this enum.
62 SIGNIN_CHOICE_SIZE,
65 void SetUserChoiceHistogram(SigninChoice choice) {
66 UMA_HISTOGRAM_ENUMERATION("Enterprise.UserSigninChoice",
67 choice,
68 SIGNIN_CHOICE_SIZE);
71 } // namespace
73 OneClickSigninSyncStarter::OneClickSigninSyncStarter(
74 Profile* profile,
75 Browser* browser,
76 const std::string& gaia_id,
77 const std::string& email,
78 const std::string& password,
79 const std::string& refresh_token,
80 StartSyncMode start_mode,
81 content::WebContents* web_contents,
82 ConfirmationRequired confirmation_required,
83 const GURL& continue_url,
84 Callback sync_setup_completed_callback)
85 : content::WebContentsObserver(web_contents),
86 profile_(NULL),
87 start_mode_(start_mode),
88 desktop_type_(chrome::HOST_DESKTOP_TYPE_NATIVE),
89 confirmation_required_(confirmation_required),
90 continue_url_(continue_url),
91 sync_setup_completed_callback_(sync_setup_completed_callback),
92 weak_pointer_factory_(this) {
93 DCHECK(profile);
94 DCHECK(web_contents || continue_url.is_empty());
95 BrowserList::AddObserver(this);
96 Initialize(profile, browser);
98 // Policy is enabled, so pass in a callback to do extra policy-related UI
99 // before signin completes.
100 SigninManagerFactory::GetForProfile(profile_)->
101 StartSignInWithRefreshToken(
102 refresh_token, gaia_id, email, password,
103 base::Bind(&OneClickSigninSyncStarter::ConfirmSignin,
104 weak_pointer_factory_.GetWeakPtr()));
107 void OneClickSigninSyncStarter::OnBrowserRemoved(Browser* browser) {
108 if (browser == browser_)
109 browser_ = NULL;
112 OneClickSigninSyncStarter::~OneClickSigninSyncStarter() {
113 BrowserList::RemoveObserver(this);
114 LoginUIServiceFactory::GetForProfile(profile_)->RemoveObserver(this);
117 void OneClickSigninSyncStarter::Initialize(Profile* profile, Browser* browser) {
118 DCHECK(profile);
120 if (profile_)
121 LoginUIServiceFactory::GetForProfile(profile_)->RemoveObserver(this);
123 profile_ = profile;
124 browser_ = browser;
126 LoginUIServiceFactory::GetForProfile(profile_)->AddObserver(this);
128 // Cache the parent desktop for the browser, so we can reuse that same
129 // desktop for any UI we want to display.
130 if (browser) {
131 desktop_type_ = browser->host_desktop_type();
132 } else {
133 desktop_type_ = chrome::GetActiveDesktop();
136 signin_tracker_ = SigninTrackerFactory::CreateForProfile(profile_, this);
138 // Let the sync service know that setup is in progress so it doesn't start
139 // syncing until the user has finished any configuration.
140 ProfileSyncService* profile_sync_service = GetProfileSyncService();
141 if (profile_sync_service)
142 profile_sync_service->SetSetupInProgress(true);
144 // Make sure the syncing is requested, otherwise the SigninManager
145 // will not be able to complete sucessfully.
146 sync_driver::SyncPrefs sync_prefs(profile_->GetPrefs());
147 sync_prefs.SetSyncRequested(true);
150 void OneClickSigninSyncStarter::ConfirmSignin(const std::string& oauth_token) {
151 DCHECK(!oauth_token.empty());
152 SigninManager* signin = SigninManagerFactory::GetForProfile(profile_);
153 // If this is a new signin (no account authenticated yet) try loading
154 // policy for this user now, before any signed in services are initialized.
155 if (!signin->IsAuthenticated()) {
156 #if defined(ENABLE_CONFIGURATION_POLICY)
157 policy::UserPolicySigninService* policy_service =
158 policy::UserPolicySigninServiceFactory::GetForProfile(profile_);
159 policy_service->RegisterForPolicy(
160 signin->GetUsernameForAuthInProgress(),
161 oauth_token,
162 base::Bind(&OneClickSigninSyncStarter::OnRegisteredForPolicy,
163 weak_pointer_factory_.GetWeakPtr()));
164 return;
165 #else
166 ConfirmAndSignin();
167 #endif
168 } else {
169 // The user is already signed in - just tell SigninManager to continue
170 // with its re-auth flow.
171 signin->CompletePendingSignin();
175 #if defined(ENABLE_CONFIGURATION_POLICY)
176 OneClickSigninSyncStarter::SigninDialogDelegate::SigninDialogDelegate(
177 base::WeakPtr<OneClickSigninSyncStarter> sync_starter)
178 : sync_starter_(sync_starter) {
181 OneClickSigninSyncStarter::SigninDialogDelegate::~SigninDialogDelegate() {
184 void OneClickSigninSyncStarter::SigninDialogDelegate::OnCancelSignin() {
185 SetUserChoiceHistogram(SIGNIN_CHOICE_CANCEL);
186 if (sync_starter_ != NULL)
187 sync_starter_->CancelSigninAndDelete();
190 void OneClickSigninSyncStarter::SigninDialogDelegate::OnContinueSignin() {
191 SetUserChoiceHistogram(SIGNIN_CHOICE_CONTINUE);
193 if (sync_starter_ != NULL)
194 sync_starter_->LoadPolicyWithCachedCredentials();
197 void OneClickSigninSyncStarter::SigninDialogDelegate::OnSigninWithNewProfile() {
198 SetUserChoiceHistogram(SIGNIN_CHOICE_NEW_PROFILE);
200 if (sync_starter_ != NULL)
201 sync_starter_->CreateNewSignedInProfile();
204 void OneClickSigninSyncStarter::OnRegisteredForPolicy(
205 const std::string& dm_token, const std::string& client_id) {
206 SigninManager* signin = SigninManagerFactory::GetForProfile(profile_);
207 // If there's no token for the user (policy registration did not succeed) just
208 // finish signing in.
209 if (dm_token.empty()) {
210 DVLOG(1) << "Policy registration failed";
211 ConfirmAndSignin();
212 return;
215 DVLOG(1) << "Policy registration succeeded: dm_token=" << dm_token;
217 // Stash away a copy of our CloudPolicyClient (should not already have one).
218 DCHECK(dm_token_.empty());
219 DCHECK(client_id_.empty());
220 dm_token_ = dm_token;
221 client_id_ = client_id;
223 // Allow user to create a new profile before continuing with sign-in.
224 browser_ = EnsureBrowser(browser_, profile_, desktop_type_);
225 content::WebContents* web_contents =
226 browser_->tab_strip_model()->GetActiveWebContents();
227 if (!web_contents) {
228 CancelSigninAndDelete();
229 return;
231 TabDialogs::FromWebContents(web_contents)->ShowProfileSigninConfirmation(
232 browser_,
233 profile_,
234 signin->GetUsernameForAuthInProgress(),
235 new SigninDialogDelegate(weak_pointer_factory_.GetWeakPtr()));
238 void OneClickSigninSyncStarter::LoadPolicyWithCachedCredentials() {
239 DCHECK(!dm_token_.empty());
240 DCHECK(!client_id_.empty());
241 SigninManager* signin = SigninManagerFactory::GetForProfile(profile_);
242 policy::UserPolicySigninService* policy_service =
243 policy::UserPolicySigninServiceFactory::GetForProfile(profile_);
244 policy_service->FetchPolicyForSignedInUser(
245 signin->GetUsernameForAuthInProgress(),
246 dm_token_,
247 client_id_,
248 profile_->GetRequestContext(),
249 base::Bind(&OneClickSigninSyncStarter::OnPolicyFetchComplete,
250 weak_pointer_factory_.GetWeakPtr()));
253 void OneClickSigninSyncStarter::OnPolicyFetchComplete(bool success) {
254 // For now, we allow signin to complete even if the policy fetch fails. If
255 // we ever want to change this behavior, we could call
256 // SigninManager::SignOut() here instead.
257 DLOG_IF(ERROR, !success) << "Error fetching policy for user";
258 DVLOG_IF(1, success) << "Policy fetch successful - completing signin";
259 SigninManagerFactory::GetForProfile(profile_)->CompletePendingSignin();
262 void OneClickSigninSyncStarter::CreateNewSignedInProfile() {
263 SigninManager* signin = SigninManagerFactory::GetForProfile(profile_);
264 DCHECK(!signin->GetUsernameForAuthInProgress().empty());
265 DCHECK(!dm_token_.empty());
266 DCHECK(!client_id_.empty());
267 // Create a new profile and have it call back when done so we can inject our
268 // signin credentials.
269 size_t icon_index = g_browser_process->profile_manager()->
270 GetProfileInfoCache().ChooseAvatarIconIndexForNewProfile();
271 ProfileManager::CreateMultiProfileAsync(
272 base::UTF8ToUTF16(signin->GetUsernameForAuthInProgress()),
273 base::UTF8ToUTF16(profiles::GetDefaultAvatarIconUrl(icon_index)),
274 base::Bind(&OneClickSigninSyncStarter::CompleteInitForNewProfile,
275 weak_pointer_factory_.GetWeakPtr(), desktop_type_),
276 std::string());
279 void OneClickSigninSyncStarter::CompleteInitForNewProfile(
280 chrome::HostDesktopType desktop_type,
281 Profile* new_profile,
282 Profile::CreateStatus status) {
283 DCHECK_NE(profile_, new_profile);
285 // TODO(atwilson): On error, unregister the client to release the DMToken
286 // and surface a better error for the user.
287 switch (status) {
288 case Profile::CREATE_STATUS_LOCAL_FAIL: {
289 NOTREACHED() << "Error creating new profile";
290 CancelSigninAndDelete();
291 return;
293 case Profile::CREATE_STATUS_CREATED: {
294 break;
296 case Profile::CREATE_STATUS_INITIALIZED: {
297 // Wait until the profile is initialized before we transfer credentials.
298 SigninManager* old_signin_manager =
299 SigninManagerFactory::GetForProfile(profile_);
300 SigninManager* new_signin_manager =
301 SigninManagerFactory::GetForProfile(new_profile);
302 DCHECK(!old_signin_manager->GetUsernameForAuthInProgress().empty());
303 DCHECK(!old_signin_manager->IsAuthenticated());
304 DCHECK(!new_signin_manager->IsAuthenticated());
305 DCHECK(!dm_token_.empty());
306 DCHECK(!client_id_.empty());
308 // Copy credentials from the old profile to the just-created profile,
309 // and switch over to tracking that profile.
310 new_signin_manager->CopyCredentialsFrom(*old_signin_manager);
311 FinishProfileSyncServiceSetup();
312 Initialize(new_profile, NULL);
313 DCHECK_EQ(profile_, new_profile);
315 // We've transferred our credentials to the new profile - notify that
316 // the signin for the original profile was cancelled (must do this after
317 // we have called Initialize() with the new profile, as otherwise this
318 // object will get freed when the signin on the old profile is cancelled.
319 old_signin_manager->SignOut(signin_metrics::TRANSFER_CREDENTIALS);
321 // Load policy for the just-created profile - once policy has finished
322 // loading the signin process will complete.
323 LoadPolicyWithCachedCredentials();
325 // Open the profile's first window, after all initialization.
326 profiles::FindOrCreateNewWindowForProfile(
327 new_profile,
328 chrome::startup::IS_PROCESS_STARTUP,
329 chrome::startup::IS_FIRST_RUN,
330 desktop_type,
331 false);
332 break;
334 case Profile::CREATE_STATUS_REMOTE_FAIL:
335 case Profile::CREATE_STATUS_CANCELED:
336 case Profile::MAX_CREATE_STATUS: {
337 NOTREACHED() << "Invalid profile creation status";
338 CancelSigninAndDelete();
339 return;
343 #endif
345 void OneClickSigninSyncStarter::CancelSigninAndDelete() {
346 SigninManagerFactory::GetForProfile(profile_)->SignOut(
347 signin_metrics::ABORT_SIGNIN);
348 // The statement above results in a call to SigninFailed() which will free
349 // this object, so do not refer to the OneClickSigninSyncStarter object
350 // after this point.
353 void OneClickSigninSyncStarter::ConfirmAndSignin() {
354 SigninManager* signin = SigninManagerFactory::GetForProfile(profile_);
355 if (confirmation_required_ == CONFIRM_UNTRUSTED_SIGNIN) {
356 browser_ = EnsureBrowser(browser_, profile_, desktop_type_);
357 // Display a confirmation dialog to the user.
358 browser_->window()->ShowOneClickSigninBubble(
359 BrowserWindow::ONE_CLICK_SIGNIN_BUBBLE_TYPE_SAML_MODAL_DIALOG,
360 base::UTF8ToUTF16(signin->GetUsernameForAuthInProgress()),
361 base::string16(), // No error message to display.
362 base::Bind(&OneClickSigninSyncStarter::UntrustedSigninConfirmed,
363 weak_pointer_factory_.GetWeakPtr()));
364 LoginUIServiceFactory::GetForProfile(profile_)->UntrustedLoginUIShown();
365 } else {
366 // No confirmation required - just sign in the user.
367 signin->CompletePendingSignin();
371 void OneClickSigninSyncStarter::UntrustedSigninConfirmed(
372 StartSyncMode response) {
373 if (response == UNDO_SYNC) {
374 CancelSigninAndDelete(); // This statement frees this object.
375 } else {
376 // If the user clicked the "Advanced" link in the confirmation dialog, then
377 // override the current start_mode_ to bring up the advanced sync settings.
379 // If the user signs in from the new avatar bubble, the untrusted dialog
380 // would dismiss the avatar bubble, thus it won't show any confirmation upon
381 // sign in completes. This dialog already has a settings link, thus we just
382 // start sync immediately .
384 if (response == CONFIGURE_SYNC_FIRST)
385 start_mode_ = response;
386 else if (start_mode_ == CONFIRM_SYNC_SETTINGS_FIRST)
387 start_mode_ = SYNC_WITH_DEFAULT_SETTINGS;
389 SigninManager* signin = SigninManagerFactory::GetForProfile(profile_);
390 signin->CompletePendingSignin();
394 void OneClickSigninSyncStarter::OnSyncConfirmationUIClosed(
395 bool configure_sync_first) {
396 if (configure_sync_first) {
397 chrome::ShowSettingsSubPage(browser_, chrome::kSyncSetupSubPage);
398 } else {
399 ProfileSyncService* profile_sync_service = GetProfileSyncService();
400 if (profile_sync_service)
401 profile_sync_service->SetSyncSetupCompleted();
402 FinishProfileSyncServiceSetup();
405 delete this;
408 void OneClickSigninSyncStarter::SigninFailed(
409 const GoogleServiceAuthError& error) {
410 if (!sync_setup_completed_callback_.is_null())
411 sync_setup_completed_callback_.Run(SYNC_SETUP_FAILURE);
413 FinishProfileSyncServiceSetup();
414 if (confirmation_required_ == CONFIRM_AFTER_SIGNIN) {
415 switch (error.state()) {
416 case GoogleServiceAuthError::SERVICE_UNAVAILABLE:
417 DisplayFinalConfirmationBubble(l10n_util::GetStringUTF16(
418 IDS_SYNC_UNRECOVERABLE_ERROR));
419 break;
420 case GoogleServiceAuthError::REQUEST_CANCELED:
421 // No error notification needed if the user manually cancelled signin.
422 break;
423 default:
424 DisplayFinalConfirmationBubble(l10n_util::GetStringUTF16(
425 IDS_SYNC_ERROR_SIGNING_IN));
426 break;
429 delete this;
432 void OneClickSigninSyncStarter::SigninSuccess() {
435 void OneClickSigninSyncStarter::AccountAddedToCookie(
436 const GoogleServiceAuthError& error) {
437 // Regardless of whether the account was successfully added or not,
438 // continue with sync starting.
440 if (!sync_setup_completed_callback_.is_null())
441 sync_setup_completed_callback_.Run(SYNC_SETUP_SUCCESS);
443 switch (start_mode_) {
444 case SYNC_WITH_DEFAULT_SETTINGS: {
445 // Just kick off the sync machine, no need to configure it first.
446 ProfileSyncService* profile_sync_service = GetProfileSyncService();
447 if (profile_sync_service)
448 profile_sync_service->SetSyncSetupCompleted();
449 FinishProfileSyncServiceSetup();
450 if (confirmation_required_ == CONFIRM_AFTER_SIGNIN) {
451 base::string16 message;
452 if (!profile_sync_service) {
453 // Sync is disabled by policy.
454 message = l10n_util::GetStringUTF16(
455 IDS_ONE_CLICK_SIGNIN_BUBBLE_SYNC_DISABLED_MESSAGE);
457 DisplayFinalConfirmationBubble(message);
459 break;
461 case CONFIRM_SYNC_SETTINGS_FIRST:
462 // Blocks sync until the sync settings confirmation UI is closed.
463 DisplayFinalConfirmationBubble(base::string16());
464 return;
465 case CONFIGURE_SYNC_FIRST:
466 ShowSettingsPage(true); // Show sync config UI.
467 break;
468 case SHOW_SETTINGS_WITHOUT_CONFIGURE:
469 ShowSettingsPage(false); // Don't show sync config UI.
470 break;
471 case UNDO_SYNC:
472 NOTREACHED();
475 // Navigate to the |continue_url_| if one is set, unless the user first needs
476 // to configure Sync.
477 if (web_contents() && !continue_url_.is_empty() &&
478 start_mode_ != CONFIGURE_SYNC_FIRST) {
479 LoadContinueUrl();
482 delete this;
485 void OneClickSigninSyncStarter::DisplayFinalConfirmationBubble(
486 const base::string16& custom_message) {
487 browser_ = EnsureBrowser(browser_, profile_, desktop_type_);
488 LoginUIServiceFactory::GetForProfile(browser_->profile())->
489 DisplayLoginResult(browser_, custom_message);
492 // static
493 Browser* OneClickSigninSyncStarter::EnsureBrowser(
494 Browser* browser,
495 Profile* profile,
496 chrome::HostDesktopType desktop_type) {
497 if (!browser) {
498 // The user just created a new profile or has closed the browser that
499 // we used previously. Grab the most recently active browser or else
500 // create a new one.
501 browser = chrome::FindLastActiveWithProfile(profile, desktop_type);
502 if (!browser) {
503 browser = new Browser(Browser::CreateParams(profile,
504 desktop_type));
505 chrome::AddTabAt(browser, GURL(), -1, true);
507 browser->window()->Show();
509 return browser;
512 void OneClickSigninSyncStarter::ShowSettingsPage(bool configure_sync) {
513 // Give the user a chance to configure things. We don't clear the
514 // ProfileSyncService::setup_in_progress flag because we don't want sync
515 // to start up until after the configure UI is displayed (the configure UI
516 // will clear the flag when the user is done setting up sync).
517 ProfileSyncService* profile_sync_service = GetProfileSyncService();
518 LoginUIService* login_ui = LoginUIServiceFactory::GetForProfile(profile_);
519 if (login_ui->current_login_ui()) {
520 login_ui->current_login_ui()->FocusUI();
521 } else {
522 browser_ = EnsureBrowser(browser_, profile_, desktop_type_);
524 // If the sign in tab is showing the native signin page or the blank page
525 // for web-based flow, and is not about to be closed, use it to show the
526 // settings UI.
527 bool use_same_tab = false;
528 if (web_contents()) {
529 GURL current_url = web_contents()->GetLastCommittedURL();
530 bool is_chrome_signin_url =
531 current_url.GetOrigin().spec() == chrome::kChromeUIChromeSigninURL;
532 bool is_same_profile =
533 Profile::FromBrowserContext(web_contents()->GetBrowserContext()) ==
534 profile_;
535 use_same_tab =
536 is_chrome_signin_url &&
537 !signin::IsAutoCloseEnabledInURL(current_url) &&
538 is_same_profile;
540 if (profile_sync_service) {
541 // Need to navigate to the settings page and display the sync UI.
542 if (use_same_tab) {
543 ShowSettingsPageInWebContents(web_contents(),
544 chrome::kSyncSetupSubPage);
545 } else {
546 // If the user is setting up sync for the first time, let them configure
547 // advanced sync settings. However, in the case of re-authentication,
548 // return the user to the settings page without showing any config UI.
549 if (configure_sync) {
550 chrome::ShowSettingsSubPage(browser_, chrome::kSyncSetupSubPage);
551 } else {
552 FinishProfileSyncServiceSetup();
553 chrome::ShowSettings(browser_);
556 } else {
557 // Sync is disabled - just display the settings page or redirect to the
558 // |continue_url_|.
559 FinishProfileSyncServiceSetup();
560 if (!use_same_tab)
561 chrome::ShowSettings(browser_);
562 else if (!continue_url_.is_empty())
563 LoadContinueUrl();
564 else
565 ShowSettingsPageInWebContents(web_contents(), std::string());
570 ProfileSyncService* OneClickSigninSyncStarter::GetProfileSyncService() {
571 ProfileSyncService* service = NULL;
572 if (profile_->IsSyncAllowed())
573 service = ProfileSyncServiceFactory::GetForProfile(profile_);
574 return service;
577 void OneClickSigninSyncStarter::FinishProfileSyncServiceSetup() {
578 ProfileSyncService* service =
579 ProfileSyncServiceFactory::GetForProfile(profile_);
580 if (service)
581 service->SetSetupInProgress(false);
584 void OneClickSigninSyncStarter::ShowSettingsPageInWebContents(
585 content::WebContents* contents,
586 const std::string& sub_page) {
587 if (!continue_url_.is_empty()) {
588 // The observer deletes itself once it's done.
589 DCHECK(!sub_page.empty());
590 new OneClickSigninSyncObserver(contents, continue_url_);
593 GURL url = chrome::GetSettingsUrl(sub_page);
594 content::OpenURLParams params(url,
595 content::Referrer(),
596 CURRENT_TAB,
597 ui::PAGE_TRANSITION_AUTO_TOPLEVEL,
598 false);
599 contents->OpenURL(params);
601 // Activate the tab.
602 Browser* browser = chrome::FindBrowserWithWebContents(contents);
603 int content_index =
604 browser->tab_strip_model()->GetIndexOfWebContents(contents);
605 browser->tab_strip_model()->ActivateTabAt(content_index,
606 false /* user_gesture */);
609 void OneClickSigninSyncStarter::LoadContinueUrl() {
610 web_contents()->GetController().LoadURL(
611 continue_url_,
612 content::Referrer(),
613 ui::PAGE_TRANSITION_AUTO_TOPLEVEL,
614 std::string());