Stack sampling profiler: add fire-and-forget interface
[chromium-blink-merge.git] / components / signin / core / browser / signin_manager_base.cc
blob7f581796eb0642a826664ea4c5fd3fb379d7d531
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "components/signin/core/browser/signin_manager_base.h"
7 #include <string>
8 #include <vector>
10 #include "base/command_line.h"
11 #include "base/memory/ref_counted.h"
12 #include "base/prefs/pref_service.h"
13 #include "base/strings/string_split.h"
14 #include "base/strings/string_util.h"
15 #include "base/strings/utf_string_conversions.h"
16 #include "components/pref_registry/pref_registry_syncable.h"
17 #include "components/signin/core/browser/account_tracker_service.h"
18 #include "components/signin/core/browser/signin_client.h"
19 #include "components/signin/core/common/signin_pref_names.h"
20 #include "components/signin/core/common/signin_switches.h"
21 #include "google_apis/gaia/gaia_auth_util.h"
22 #include "google_apis/gaia/gaia_constants.h"
23 #include "google_apis/gaia/gaia_urls.h"
25 using namespace signin_internals_util;
27 SigninManagerBase::SigninManagerBase(
28 SigninClient* client,
29 AccountTrackerService* account_tracker_service)
30 : client_(client),
31 account_tracker_service_(account_tracker_service),
32 initialized_(false),
33 weak_pointer_factory_(this) {
34 DCHECK(client_);
35 DCHECK(account_tracker_service_);
38 SigninManagerBase::~SigninManagerBase() {}
40 // static
41 void SigninManagerBase::RegisterProfilePrefs(
42 user_prefs::PrefRegistrySyncable* registry) {
43 registry->RegisterStringPref(prefs::kGoogleServicesHostedDomain,
44 std::string());
45 registry->RegisterStringPref(prefs::kGoogleServicesLastUsername,
46 std::string());
47 registry->RegisterInt64Pref(
48 prefs::kGoogleServicesRefreshTokenAnnotateScheduledTime,
49 base::Time().ToInternalValue());
50 registry->RegisterStringPref(prefs::kGoogleServicesSigninScopedDeviceId,
51 std::string());
52 registry->RegisterStringPref(prefs::kGoogleServicesAccountId, std::string());
53 registry->RegisterStringPref(prefs::kGoogleServicesUserAccountId,
54 std::string());
55 registry->RegisterBooleanPref(prefs::kAutologinEnabled, true);
56 registry->RegisterBooleanPref(prefs::kReverseAutologinEnabled, true);
57 registry->RegisterListPref(prefs::kReverseAutologinRejectedEmailList,
58 new base::ListValue);
59 registry->RegisterInt64Pref(prefs::kSignedInTime,
60 base::Time().ToInternalValue());
62 // Deprecated prefs: will be removed in a future release.
63 registry->RegisterStringPref(prefs::kGoogleServicesUsername, std::string());
66 // static
67 void SigninManagerBase::RegisterPrefs(PrefRegistrySimple* registry) {
68 registry->RegisterStringPref(prefs::kGoogleServicesUsernamePattern,
69 std::string());
72 void SigninManagerBase::Initialize(PrefService* local_state) {
73 // Should never call Initialize() twice.
74 DCHECK(!IsInitialized());
75 initialized_ = true;
77 // If the user is clearing the token service from the command line, then
78 // clear their login info also (not valid to be logged in without any
79 // tokens).
80 base::CommandLine* cmd_line = base::CommandLine::ForCurrentProcess();
81 if (cmd_line->HasSwitch(switches::kClearTokenService)) {
82 client_->GetPrefs()->ClearPref(prefs::kGoogleServicesAccountId);
83 client_->GetPrefs()->ClearPref(prefs::kGoogleServicesUsername);
84 client_->GetPrefs()->ClearPref(prefs::kGoogleServicesUserAccountId);
87 std::string account_id =
88 client_->GetPrefs()->GetString(prefs::kGoogleServicesAccountId);
90 // Handle backward compatibility: if kGoogleServicesAccountId is empty, but
91 // kGoogleServicesUsername is not, then this is an old profile that needs to
92 // be updated. kGoogleServicesUserAccountId should not be empty, and contains
93 // the gaia_id. Use both properties to prime the account tracker before
94 // proceeding.
95 if (account_id.empty()) {
96 std::string pref_account_username =
97 client_->GetPrefs()->GetString(prefs::kGoogleServicesUsername);
98 if (!pref_account_username.empty()) {
99 // This is an old profile connected to a google account. Migrate from
100 // kGoogleServicesUsername to kGoogleServicesAccountId.
101 std::string pref_gaia_id =
102 client_->GetPrefs()->GetString(prefs::kGoogleServicesUserAccountId);
104 // If kGoogleServicesUserAccountId is empty, then this is either a cros
105 // machine or a really old profile on one of the other platforms. However
106 // in this case the account tracker should have the gaia_id so fetch it
107 // from there.
108 if (pref_gaia_id.empty()) {
109 AccountTrackerService::AccountInfo info =
110 account_tracker_service_->FindAccountInfoByEmail(
111 pref_account_username);
112 pref_gaia_id = info.gaia;
115 // If |pref_gaia_id| is still empty, this means the profile has been in
116 // an auth error state for some time (since M39). It could also mean
117 // a profile that has not been used since M33. Before migration to gaia
118 // id is complete, the returned value will be the normalized email, which
119 // is correct. After the migration, the returned value will be empty,
120 // which means the user is essentially signed out.
121 // TODO(rogerta): may want to show a toast or something.
122 account_id = account_tracker_service_->SeedAccountInfo(
123 pref_gaia_id, pref_account_username);
125 // Set account id before removing obsolete user name in case crash in the
126 // middle.
127 client_->GetPrefs()->SetString(prefs::kGoogleServicesAccountId,
128 account_id);
130 // Now remove obsolete preferences.
131 client_->GetPrefs()->ClearPref(prefs::kGoogleServicesUsername);
134 // TODO(rogerta): once migration to gaia id is complete, remove
135 // kGoogleServicesUserAccountId and change all uses of that pref to
136 // kGoogleServicesAccountId.
139 if (!account_id.empty()) {
140 if (account_tracker_service_->GetMigrationState() ==
141 AccountTrackerService::MIGRATION_IN_PROGRESS) {
142 AccountTrackerService::AccountInfo account_info =
143 account_tracker_service_->FindAccountInfoByEmail(account_id);
144 // |account_info.gaia| could be empty if |account_id| is already gaia id.
145 if (!account_info.gaia.empty()) {
146 account_id = account_info.gaia;
147 client_->GetPrefs()->SetString(prefs::kGoogleServicesAccountId,
148 account_id);
151 SetAuthenticatedAccountId(account_id);
155 bool SigninManagerBase::IsInitialized() const { return initialized_; }
157 bool SigninManagerBase::IsSigninAllowed() const {
158 return client_->GetPrefs()->GetBoolean(prefs::kSigninAllowed);
161 std::string SigninManagerBase::GetAuthenticatedUsername() const {
162 return account_tracker_service_->GetAccountInfo(
163 GetAuthenticatedAccountId()).email;
166 const std::string& SigninManagerBase::GetAuthenticatedAccountId() const {
167 return authenticated_account_id_;
170 void SigninManagerBase::SetAuthenticatedAccountInfo(const std::string& gaia_id,
171 const std::string& email) {
172 DCHECK(!gaia_id.empty());
173 DCHECK(!email.empty());
175 std::string account_id =
176 account_tracker_service_->SeedAccountInfo(gaia_id, email);
177 SetAuthenticatedAccountId(account_id);
180 void SigninManagerBase::SetAuthenticatedAccountId(
181 const std::string& account_id) {
182 DCHECK(!account_id.empty());
183 if (!authenticated_account_id_.empty()) {
184 DLOG_IF(ERROR, account_id != authenticated_account_id_)
185 << "Tried to change the authenticated id to something different: "
186 << "Current: " << authenticated_account_id_ << ", New: " << account_id;
187 return;
190 std::string pref_account_id =
191 client_->GetPrefs()->GetString(prefs::kGoogleServicesAccountId);
193 DCHECK(pref_account_id.empty() || pref_account_id == account_id)
194 << "account_id=" << account_id
195 << " pref_account_id=" << pref_account_id;
196 authenticated_account_id_ = account_id;
197 client_->GetPrefs()->SetString(prefs::kGoogleServicesAccountId, account_id);
199 // This preference is set so that code on I/O thread has access to the
200 // Gaia id of the signed in user.
201 AccountTrackerService::AccountInfo info =
202 account_tracker_service_->GetAccountInfo(account_id);
204 // When this function is called from Initialize(), it's possible for
205 // |info.gaia| to be empty when migrating from a really old profile.
206 if (!info.gaia.empty()) {
207 client_->GetPrefs()->SetString(prefs::kGoogleServicesUserAccountId,
208 info.gaia);
211 // Go ahead and update the last signed in account info here as well. Once a
212 // user is signed in the two preferences should match. Doing it here as
213 // opposed to on signin allows us to catch the upgrade scenario.
214 client_->GetPrefs()->SetString(prefs::kGoogleServicesLastUsername,
215 info.email);
218 bool SigninManagerBase::IsAuthenticated() const {
219 return !authenticated_account_id_.empty();
222 bool SigninManagerBase::AuthInProgress() const {
223 // SigninManagerBase never kicks off auth processes itself.
224 return false;
227 void SigninManagerBase::Shutdown() {}
229 void SigninManagerBase::AddObserver(Observer* observer) {
230 observer_list_.AddObserver(observer);
233 void SigninManagerBase::RemoveObserver(Observer* observer) {
234 observer_list_.RemoveObserver(observer);
237 void SigninManagerBase::AddSigninDiagnosticsObserver(
238 SigninDiagnosticsObserver* observer) {
239 signin_diagnostics_observers_.AddObserver(observer);
242 void SigninManagerBase::RemoveSigninDiagnosticsObserver(
243 SigninDiagnosticsObserver* observer) {
244 signin_diagnostics_observers_.RemoveObserver(observer);
247 void SigninManagerBase::NotifyDiagnosticsObservers(
248 const TimedSigninStatusField& field,
249 const std::string& value) {
250 FOR_EACH_OBSERVER(SigninDiagnosticsObserver,
251 signin_diagnostics_observers_,
252 NotifySigninValueChanged(field, value));