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