15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/sync/one_click_signin_sync_starter.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/prefs/pref_service.h"
8868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
9c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/browser_process.h"
10c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
11c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#if defined(ENABLE_CONFIGURATION_POLICY)
12c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/policy/cloud/user_policy_signin_service.h"
13c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/policy/cloud/user_policy_signin_service_factory.h"
14c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#endif
15c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile.h"
17c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "chrome/browser/profiles/profile_avatar_icon_util.h"
18c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/profiles/profile_info_cache.h"
19c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/profiles/profile_io_data.h"
20c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/profiles/profile_manager.h"
219ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "chrome/browser/profiles/profile_window.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/signin/signin_manager_factory.h"
23e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include "chrome/browser/signin/signin_tracker_factory.h"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/sync/profile_sync_service.h"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/sync/profile_sync_service_factory.h"
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/browser.h"
27868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/browser/ui/browser_dialogs.h"
28c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/ui/browser_finder.h"
29868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/browser/ui/browser_list.h"
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/browser_navigator.h"
31868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/browser/ui/browser_tabstrip.h"
32c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/ui/browser_window.h"
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/chrome_pages.h"
34010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "chrome/browser/ui/sync/one_click_signin_sync_observer.h"
35868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/browser/ui/tabs/tab_strip_model.h"
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/webui/signin/login_ui_service.h"
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/webui/signin/login_ui_service_factory.h"
38c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/ui/webui/signin/profile_signin_confirmation_dialog.h"
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/common/url_constants.h"
40e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include "components/signin/core/browser/signin_manager.h"
4108fd22434aed8d58d4e04bbbc0df2a942440bcc5Bo Liu#include "components/signin/core/browser/signin_metrics.h"
420529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "components/signin/core/common/profile_management_switches.h"
4323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "components/sync_driver/sync_prefs.h"
44b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#include "grit/chromium_strings.h"
45b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#include "grit/generated_resources.h"
46b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#include "ui/base/l10n/l10n_util.h"
47b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#include "ui/base/resource/resource_bundle.h"
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)OneClickSigninSyncStarter::OneClickSigninSyncStarter(
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Profile* profile,
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Browser* browser,
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& email,
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& password,
54a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const std::string& refresh_token,
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    StartSyncMode start_mode,
56ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    content::WebContents* web_contents,
57eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    ConfirmationRequired confirmation_required,
58010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    const GURL& continue_url,
59a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    Callback sync_setup_completed_callback)
60ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    : content::WebContentsObserver(web_contents),
61ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      start_mode_(start_mode),
6258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      desktop_type_(chrome::HOST_DESKTOP_TYPE_NATIVE),
63c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      confirmation_required_(confirmation_required),
64010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      continue_url_(continue_url),
65a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      sync_setup_completed_callback_(sync_setup_completed_callback),
66c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      weak_pointer_factory_(this) {
67c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(profile);
68010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  DCHECK(web_contents || continue_url.is_empty());
69868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  BrowserList::AddObserver(this);
70868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  Initialize(profile, browser);
72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
73c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Policy is enabled, so pass in a callback to do extra policy-related UI
74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // before signin completes.
75a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  SigninManagerFactory::GetForProfile(profile_)->
76a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      StartSignInWithRefreshToken(
77a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          refresh_token, email, password,
78a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          base::Bind(&OneClickSigninSyncStarter::ConfirmSignin,
79a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                     weak_pointer_factory_.GetWeakPtr()));
80c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
81c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
82868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void OneClickSigninSyncStarter::OnBrowserRemoved(Browser* browser) {
83868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (browser == browser_)
84868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    browser_ = NULL;
85868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
86868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
87c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)OneClickSigninSyncStarter::~OneClickSigninSyncStarter() {
88868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  BrowserList::RemoveObserver(this);
89c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
90c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
91c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void OneClickSigninSyncStarter::Initialize(Profile* profile, Browser* browser) {
92c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(profile);
93c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  profile_ = profile;
94c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  browser_ = browser;
95c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
96c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Cache the parent desktop for the browser, so we can reuse that same
97c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // desktop for any UI we want to display.
98a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (browser) {
99c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    desktop_type_ = browser->host_desktop_type();
100a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  } else {
101a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    desktop_type_ = chrome::GetActiveDesktop();
102a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
103c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
104e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  signin_tracker_ = SigninTrackerFactory::CreateForProfile(profile_, this);
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Let the sync service know that setup is in progress so it doesn't start
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // syncing until the user has finished any configuration.
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ProfileSyncService* profile_sync_service = GetProfileSyncService();
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (profile_sync_service)
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    profile_sync_service->SetSetupInProgress(true);
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make sure the syncing is not suppressed, otherwise the SigninManager
113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // will not be able to complete sucessfully.
11423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  sync_driver::SyncPrefs sync_prefs(profile_->GetPrefs());
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sync_prefs.SetStartSuppressed(false);
116c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
118c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void OneClickSigninSyncStarter::ConfirmSignin(const std::string& oauth_token) {
119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(!oauth_token.empty());
120c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  SigninManager* signin = SigninManagerFactory::GetForProfile(profile_);
121c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // If this is a new signin (no authenticated username yet) try loading
122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // policy for this user now, before any signed in services are initialized.
123c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (signin->GetAuthenticatedUsername().empty()) {
124c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#if defined(ENABLE_CONFIGURATION_POLICY)
125c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    policy::UserPolicySigninService* policy_service =
126c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        policy::UserPolicySigninServiceFactory::GetForProfile(profile_);
127f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    policy_service->RegisterForPolicy(
128c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        signin->GetUsernameForAuthInProgress(),
129c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        oauth_token,
130c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        base::Bind(&OneClickSigninSyncStarter::OnRegisteredForPolicy,
131c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                   weak_pointer_factory_.GetWeakPtr()));
132c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return;
133c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#else
134b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    ConfirmAndSignin();
135c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#endif
136c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  } else {
137c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // The user is already signed in - just tell SigninManager to continue
138c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // with its re-auth flow.
139c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    signin->CompletePendingSignin();
140c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
143c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#if defined(ENABLE_CONFIGURATION_POLICY)
144868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)OneClickSigninSyncStarter::SigninDialogDelegate::SigninDialogDelegate(
145868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    base::WeakPtr<OneClickSigninSyncStarter> sync_starter)
146868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  : sync_starter_(sync_starter) {
147868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
148868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
149868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)OneClickSigninSyncStarter::SigninDialogDelegate::~SigninDialogDelegate() {
150868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
151868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
152868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void OneClickSigninSyncStarter::SigninDialogDelegate::OnCancelSignin() {
1531e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (sync_starter_ != NULL)
1541e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    sync_starter_->CancelSigninAndDelete();
155868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
156868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
157868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void OneClickSigninSyncStarter::SigninDialogDelegate::OnContinueSignin() {
1581e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (sync_starter_ != NULL)
159f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    sync_starter_->LoadPolicyWithCachedCredentials();
160868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
161868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
162868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void OneClickSigninSyncStarter::SigninDialogDelegate::OnSigninWithNewProfile() {
1631e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (sync_starter_ != NULL)
1641e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    sync_starter_->CreateNewSignedInProfile();
165868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
166868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
167c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void OneClickSigninSyncStarter::OnRegisteredForPolicy(
168f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const std::string& dm_token, const std::string& client_id) {
169c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  SigninManager* signin = SigninManagerFactory::GetForProfile(profile_);
170c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // If there's no token for the user (policy registration did not succeed) just
171c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // finish signing in.
172f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (dm_token.empty()) {
173c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    DVLOG(1) << "Policy registration failed";
174b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    ConfirmAndSignin();
175c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return;
176c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
177c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
178f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DVLOG(1) << "Policy registration succeeded: dm_token=" << dm_token;
179c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
180c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Stash away a copy of our CloudPolicyClient (should not already have one).
181f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK(dm_token_.empty());
182f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK(client_id_.empty());
183f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  dm_token_ = dm_token;
184f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  client_id_ = client_id;
185c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
186c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Allow user to create a new profile before continuing with sign-in.
187a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  browser_ = EnsureBrowser(browser_, profile_, desktop_type_);
188868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  content::WebContents* web_contents =
1897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      browser_->tab_strip_model()->GetActiveWebContents();
190868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!web_contents) {
191868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    CancelSigninAndDelete();
192868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return;
193868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
194868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  chrome::ShowProfileSigninConfirmationDialog(
1957d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      browser_,
196868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      web_contents,
197c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      profile_,
198c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      signin->GetUsernameForAuthInProgress(),
199868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new SigninDialogDelegate(weak_pointer_factory_.GetWeakPtr()));
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
202f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void OneClickSigninSyncStarter::LoadPolicyWithCachedCredentials() {
203f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK(!dm_token_.empty());
204f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK(!client_id_.empty());
205f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  SigninManager* signin = SigninManagerFactory::GetForProfile(profile_);
206c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  policy::UserPolicySigninService* policy_service =
207c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      policy::UserPolicySigninServiceFactory::GetForProfile(profile_);
208c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  policy_service->FetchPolicyForSignedInUser(
209f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      signin->GetUsernameForAuthInProgress(),
210f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      dm_token_,
211f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      client_id_,
2125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      profile_->GetRequestContext(),
213c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      base::Bind(&OneClickSigninSyncStarter::OnPolicyFetchComplete,
214c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 weak_pointer_factory_.GetWeakPtr()));
215c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
216c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
217c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void OneClickSigninSyncStarter::OnPolicyFetchComplete(bool success) {
218c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // For now, we allow signin to complete even if the policy fetch fails. If
219c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // we ever want to change this behavior, we could call
220c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // SigninManager::SignOut() here instead.
221c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DLOG_IF(ERROR, !success) << "Error fetching policy for user";
222c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DVLOG_IF(1, success) << "Policy fetch successful - completing signin";
223c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  SigninManagerFactory::GetForProfile(profile_)->CompletePendingSignin();
224c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
225c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
226c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void OneClickSigninSyncStarter::CreateNewSignedInProfile() {
227c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  SigninManager* signin = SigninManagerFactory::GetForProfile(profile_);
228c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(!signin->GetUsernameForAuthInProgress().empty());
229f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK(!dm_token_.empty());
230f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK(!client_id_.empty());
231c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Create a new profile and have it call back when done so we can inject our
232c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // signin credentials.
233c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  size_t icon_index = g_browser_process->profile_manager()->
234c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      GetProfileInfoCache().ChooseAvatarIconIndexForNewProfile();
235c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ProfileManager::CreateMultiProfileAsync(
2365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::UTF8ToUTF16(signin->GetUsernameForAuthInProgress()),
237c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      base::UTF8ToUTF16(profiles::GetDefaultAvatarIconUrl(icon_index)),
238868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      base::Bind(&OneClickSigninSyncStarter::CompleteInitForNewProfile,
239868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                 weak_pointer_factory_.GetWeakPtr(), desktop_type_),
2402385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      std::string());
241c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
242c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
243868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void OneClickSigninSyncStarter::CompleteInitForNewProfile(
244868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    chrome::HostDesktopType desktop_type,
245c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    Profile* new_profile,
246c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    Profile::CreateStatus status) {
247c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK_NE(profile_, new_profile);
248c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
249868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // TODO(atwilson): On error, unregister the client to release the DMToken
250868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // and surface a better error for the user.
251868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  switch (status) {
252868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    case Profile::CREATE_STATUS_LOCAL_FAIL: {
253868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      NOTREACHED() << "Error creating new profile";
254868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      CancelSigninAndDelete();
255868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      return;
256868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    }
257868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    case Profile::CREATE_STATUS_CREATED: {
258868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      break;
259868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    }
260868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    case Profile::CREATE_STATUS_INITIALIZED: {
261868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      // Wait until the profile is initialized before we transfer credentials.
262868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      SigninManager* old_signin_manager =
263868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          SigninManagerFactory::GetForProfile(profile_);
264868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      SigninManager* new_signin_manager =
265868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          SigninManagerFactory::GetForProfile(new_profile);
266868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      DCHECK(!old_signin_manager->GetUsernameForAuthInProgress().empty());
267868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      DCHECK(old_signin_manager->GetAuthenticatedUsername().empty());
268868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      DCHECK(new_signin_manager->GetAuthenticatedUsername().empty());
269f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      DCHECK(!dm_token_.empty());
270f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      DCHECK(!client_id_.empty());
271868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
272868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      // Copy credentials from the old profile to the just-created profile,
273868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      // and switch over to tracking that profile.
274868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new_signin_manager->CopyCredentialsFrom(*old_signin_manager);
275868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      FinishProfileSyncServiceSetup();
276868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      Initialize(new_profile, NULL);
277868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      DCHECK_EQ(profile_, new_profile);
278868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
279868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      // We've transferred our credentials to the new profile - notify that
280868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      // the signin for the original profile was cancelled (must do this after
281868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      // we have called Initialize() with the new profile, as otherwise this
282868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      // object will get freed when the signin on the old profile is cancelled.
28308fd22434aed8d58d4e04bbbc0df2a942440bcc5Bo Liu      old_signin_manager->SignOut(signin_metrics::TRANSFER_CREDENTIALS);
284868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
285868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      // Load policy for the just-created profile - once policy has finished
286868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      // loading the signin process will complete.
287f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      LoadPolicyWithCachedCredentials();
288868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
289868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      // Open the profile's first window, after all initialization.
2909ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch      profiles::FindOrCreateNewWindowForProfile(
291868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        new_profile,
292868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        chrome::startup::IS_PROCESS_STARTUP,
293868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        chrome::startup::IS_FIRST_RUN,
294868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        desktop_type,
295868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        false);
296868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      break;
297868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    }
298868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    case Profile::CREATE_STATUS_REMOTE_FAIL:
299868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    case Profile::CREATE_STATUS_CANCELED:
300868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    case Profile::MAX_CREATE_STATUS: {
301868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      NOTREACHED() << "Invalid profile creation status";
302868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      CancelSigninAndDelete();
303868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      return;
304868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    }
305c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
306c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
307c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#endif
308c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
3090f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)void OneClickSigninSyncStarter::CancelSigninAndDelete() {
31008fd22434aed8d58d4e04bbbc0df2a942440bcc5Bo Liu  SigninManagerFactory::GetForProfile(profile_)->SignOut(
31108fd22434aed8d58d4e04bbbc0df2a942440bcc5Bo Liu      signin_metrics::ABORT_SIGNIN);
3120f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // The statement above results in a call to SigninFailed() which will free
3130f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // this object, so do not refer to the OneClickSigninSyncStarter object
3140f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // after this point.
3150f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)}
3160f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
317b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)void OneClickSigninSyncStarter::ConfirmAndSignin() {
318c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  SigninManager* signin = SigninManagerFactory::GetForProfile(profile_);
319868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (confirmation_required_ == CONFIRM_UNTRUSTED_SIGNIN) {
320a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    browser_ = EnsureBrowser(browser_, profile_, desktop_type_);
321c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // Display a confirmation dialog to the user.
322c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    browser_->window()->ShowOneClickSigninBubble(
323c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        BrowserWindow::ONE_CLICK_SIGNIN_BUBBLE_TYPE_SAML_MODAL_DIALOG,
3245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        base::UTF8ToUTF16(signin->GetUsernameForAuthInProgress()),
325a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        base::string16(),  // No error message to display.
326b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        base::Bind(&OneClickSigninSyncStarter::UntrustedSigninConfirmed,
327c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                   weak_pointer_factory_.GetWeakPtr()));
328b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  } else {
329b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    // No confirmation required - just sign in the user.
330b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    signin->CompletePendingSignin();
331c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
332c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
333c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
334b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)void OneClickSigninSyncStarter::UntrustedSigninConfirmed(
335c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    StartSyncMode response) {
336c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (response == UNDO_SYNC) {
3377dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    CancelSigninAndDelete();  // This statement frees this object.
338c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  } else {
339c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // If the user clicked the "Advanced" link in the confirmation dialog, then
340c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // override the current start_mode_ to bring up the advanced sync settings.
341c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (response == CONFIGURE_SYNC_FIRST)
342c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      start_mode_ = response;
343c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    SigninManager* signin = SigninManagerFactory::GetForProfile(profile_);
344c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    signin->CompletePendingSignin();
345c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
346c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
347c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void OneClickSigninSyncStarter::SigninFailed(
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GoogleServiceAuthError& error) {
350a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  if (!sync_setup_completed_callback_.is_null())
351a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    sync_setup_completed_callback_.Run(SYNC_SETUP_FAILURE);
352a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
353868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  FinishProfileSyncServiceSetup();
354b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  if (confirmation_required_ == CONFIRM_AFTER_SIGNIN) {
355b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    switch (error.state()) {
356b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      case GoogleServiceAuthError::SERVICE_UNAVAILABLE:
357b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        DisplayFinalConfirmationBubble(l10n_util::GetStringUTF16(
358b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)            IDS_SYNC_UNRECOVERABLE_ERROR));
359b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        break;
360b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      case GoogleServiceAuthError::REQUEST_CANCELED:
361b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        // No error notification needed if the user manually cancelled signin.
362b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        break;
363b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      default:
364b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        DisplayFinalConfirmationBubble(l10n_util::GetStringUTF16(
365b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)            IDS_SYNC_ERROR_SIGNING_IN));
366b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        break;
367b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    }
368b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  }
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  delete this;
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void OneClickSigninSyncStarter::SigninSuccess() {
3735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (switches::IsEnableWebBasedSignin())
3745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    MergeSessionComplete(GoogleServiceAuthError(GoogleServiceAuthError::NONE));
3755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
3765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void OneClickSigninSyncStarter::MergeSessionComplete(
3785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const GoogleServiceAuthError& error) {
3795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Regardless of whether the merge session completed sucessfully or not,
3805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // continue with sync starting.
3815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
382a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  if (!sync_setup_completed_callback_.is_null())
383a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    sync_setup_completed_callback_.Run(SYNC_SETUP_SUCCESS);
384a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
3857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  switch (start_mode_) {
3867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    case SYNC_WITH_DEFAULT_SETTINGS: {
387868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      // Just kick off the sync machine, no need to configure it first.
388bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch      ProfileSyncService* profile_sync_service = GetProfileSyncService();
3897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      if (profile_sync_service)
3907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        profile_sync_service->SetSyncSetupCompleted();
3917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      FinishProfileSyncServiceSetup();
3927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      if (confirmation_required_ == CONFIRM_AFTER_SIGNIN) {
393a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        base::string16 message;
3947d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        if (!profile_sync_service) {
3957d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)          // Sync is disabled by policy.
3967d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)          message = l10n_util::GetStringUTF16(
3977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)              IDS_ONE_CLICK_SIGNIN_BUBBLE_SYNC_DISABLED_MESSAGE);
3987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        }
3997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        DisplayFinalConfirmationBubble(message);
400b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      }
4017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      break;
402868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    }
4037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    case CONFIGURE_SYNC_FIRST:
4043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      ShowSettingsPage(true);  // Show sync config UI.
405ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      break;
406ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    case SHOW_SETTINGS_WITHOUT_CONFIGURE:
4073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      ShowSettingsPage(false);  // Don't show sync config UI.
4087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      break;
409010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    case UNDO_SYNC:
4107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      NOTREACHED();
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
412010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
413010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // Navigate to the |continue_url_| if one is set, unless the user first needs
414010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // to configure Sync.
415010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  if (web_contents() && !continue_url_.is_empty() &&
416010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      start_mode_ != CONFIGURE_SYNC_FIRST) {
417010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    LoadContinueUrl();
418010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
419010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  delete this;
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
423b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)void OneClickSigninSyncStarter::DisplayFinalConfirmationBubble(
424a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    const base::string16& custom_message) {
425a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  browser_ = EnsureBrowser(browser_, profile_, desktop_type_);
426b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  browser_->window()->ShowOneClickSigninBubble(
427b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      BrowserWindow::ONE_CLICK_SIGNIN_BUBBLE_TYPE_BUBBLE,
428a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      base::string16(),  // No email required - this is not a SAML confirmation.
429b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      custom_message,
430b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      // Callback is ignored.
431b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      BrowserWindow::StartSyncCallback());
432b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)}
433b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
434a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// static
435a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)Browser* OneClickSigninSyncStarter::EnsureBrowser(
436a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    Browser* browser,
437a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    Profile* profile,
438a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    chrome::HostDesktopType desktop_type) {
439a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (!browser) {
440868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    // The user just created a new profile or has closed the browser that
441868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    // we used previously. Grab the most recently active browser or else
442868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    // create a new one.
443a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    browser = chrome::FindLastActiveWithProfile(profile, desktop_type);
444a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    if (!browser) {
445a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      browser = new Browser(Browser::CreateParams(profile,
446a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                                   desktop_type));
447a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      chrome::AddTabAt(browser, GURL(), -1, true);
448b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    }
449a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    browser->window()->Show();
450b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  }
451a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return browser;
452b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)}
453b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
4543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void OneClickSigninSyncStarter::ShowSettingsPage(bool configure_sync) {
455c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Give the user a chance to configure things. We don't clear the
456c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // ProfileSyncService::setup_in_progress flag because we don't want sync
457c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // to start up until after the configure UI is displayed (the configure UI
458c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // will clear the flag when the user is done setting up sync).
459c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ProfileSyncService* profile_sync_service = GetProfileSyncService();
460c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  LoginUIService* login_ui = LoginUIServiceFactory::GetForProfile(profile_);
461c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (login_ui->current_login_ui()) {
462c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    login_ui->current_login_ui()->FocusUI();
463c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  } else {
464a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    browser_ = EnsureBrowser(browser_, profile_, desktop_type_);
4653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
4665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // If the sign in tab is showing the native signin page or the blank page
4675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // for web-based flow, and is not about to be closed, use it to show the
4685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // settings UI.
4693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    bool use_same_tab = false;
4703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    if (web_contents()) {
4713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      GURL current_url = web_contents()->GetLastCommittedURL();
4725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      bool is_chrome_signin_url =
4735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          current_url.GetOrigin().spec() == chrome::kChromeUIChromeSigninURL;
474a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      bool is_same_profile =
475a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          Profile::FromBrowserContext(web_contents()->GetBrowserContext()) ==
476a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          profile_;
4775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      use_same_tab =
4785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          (is_chrome_signin_url ||
4795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)           signin::IsContinueUrlForWebBasedSigninFlow(current_url)) &&
480a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          !signin::IsAutoCloseEnabledInURL(current_url) &&
481a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          is_same_profile;
4823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    }
483c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (profile_sync_service) {
484c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      // Need to navigate to the settings page and display the sync UI.
4853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      if (use_same_tab) {
4863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        ShowSettingsPageInWebContents(web_contents(),
4873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                      chrome::kSyncSetupSubPage);
488c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      } else {
489ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch        // If the user is setting up sync for the first time, let them configure
490ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch        // advanced sync settings. However, in the case of re-authentication,
491ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch        // return the user to the settings page without showing any config UI.
492ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch        if (configure_sync) {
493ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch          chrome::ShowSettingsSubPage(browser_, chrome::kSyncSetupSubPage);
494ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch        } else {
495ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch          FinishProfileSyncServiceSetup();
496ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch          chrome::ShowSettings(browser_);
497ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch        }
498c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      }
499c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    } else {
500010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      // Sync is disabled - just display the settings page or redirect to the
501010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      // |continue_url_|.
502868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      FinishProfileSyncServiceSetup();
503010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      if (!use_same_tab)
5043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        chrome::ShowSettings(browser_);
505010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      else if (!continue_url_.is_empty())
506010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)        LoadContinueUrl();
507010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      else
508010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)        ShowSettingsPageInWebContents(web_contents(), std::string());
509c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
510c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
511c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
512c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
5132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ProfileSyncService* OneClickSigninSyncStarter::GetProfileSyncService() {
5142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ProfileSyncService* service = NULL;
5152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (profile_->IsSyncAccessible())
5162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    service = ProfileSyncServiceFactory::GetForProfile(profile_);
5172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return service;
5182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
520868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void OneClickSigninSyncStarter::FinishProfileSyncServiceSetup() {
521868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ProfileSyncService* service =
522868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      ProfileSyncServiceFactory::GetForProfile(profile_);
523868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (service)
524868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    service->SetSetupInProgress(false);
525868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
526868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
5273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void OneClickSigninSyncStarter::ShowSettingsPageInWebContents(
5283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    content::WebContents* contents,
5293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    const std::string& sub_page) {
530010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  if (!continue_url_.is_empty()) {
531010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    // The observer deletes itself once it's done.
532010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    DCHECK(!sub_page.empty());
533010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    new OneClickSigninSyncObserver(contents, continue_url_);
534010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
535010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
536effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  GURL url = chrome::GetSettingsUrl(sub_page);
537effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  content::OpenURLParams params(url,
538ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch                                content::Referrer(),
539ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch                                CURRENT_TAB,
540ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch                                content::PAGE_TRANSITION_AUTO_TOPLEVEL,
541ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch                                false);
542ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  contents->OpenURL(params);
543ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
544ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // Activate the tab.
545ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  Browser* browser = chrome::FindBrowserWithWebContents(contents);
546ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  int content_index =
547ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      browser->tab_strip_model()->GetIndexOfWebContents(contents);
548ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  browser->tab_strip_model()->ActivateTabAt(content_index,
549ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch                                            false /* user_gesture */);
5502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
551010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
552010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void OneClickSigninSyncStarter::LoadContinueUrl() {
553010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  web_contents()->GetController().LoadURL(
554010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      continue_url_,
555010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      content::Referrer(),
556010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      content::PAGE_TRANSITION_AUTO_TOPLEVEL,
557010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      std::string());
558010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
559