OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "components/signin/core/browser/account_fetcher_service.h" | 5 #include "components/signin/core/browser/account_fetcher_service.h" |
6 | 6 |
7 #include "base/command_line.h" | 7 #include "base/command_line.h" |
8 #include "base/metrics/field_trial.h" | 8 #include "base/metrics/field_trial.h" |
9 #include "base/prefs/pref_service.h" | 9 #include "base/prefs/pref_service.h" |
10 #include "base/profiler/scoped_tracker.h" | 10 #include "base/profiler/scoped_tracker.h" |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
48 "account_tracker_service_last_update"; | 48 "account_tracker_service_last_update"; |
49 | 49 |
50 // AccountFetcherService implementation | 50 // AccountFetcherService implementation |
51 AccountFetcherService::AccountFetcherService() | 51 AccountFetcherService::AccountFetcherService() |
52 : account_tracker_service_(nullptr), | 52 : account_tracker_service_(nullptr), |
53 token_service_(nullptr), | 53 token_service_(nullptr), |
54 signin_client_(nullptr), | 54 signin_client_(nullptr), |
55 invalidation_service_(nullptr), | 55 invalidation_service_(nullptr), |
56 network_fetches_enabled_(false), | 56 network_fetches_enabled_(false), |
57 shutdown_called_(false), | 57 shutdown_called_(false), |
| 58 scheduled_refresh_enabled_(true), |
58 child_info_request_(nullptr) {} | 59 child_info_request_(nullptr) {} |
59 | 60 |
60 AccountFetcherService::~AccountFetcherService() { | 61 AccountFetcherService::~AccountFetcherService() { |
61 DCHECK(shutdown_called_); | 62 DCHECK(shutdown_called_); |
62 } | 63 } |
63 | 64 |
64 // static | 65 // static |
65 void AccountFetcherService::RegisterPrefs( | 66 void AccountFetcherService::RegisterPrefs( |
66 user_prefs::PrefRegistrySyncable* user_prefs) { | 67 user_prefs::PrefRegistrySyncable* user_prefs) { |
67 user_prefs->RegisterInt64Pref(kLastUpdatePref, 0); | 68 user_prefs->RegisterInt64Pref(kLastUpdatePref, 0); |
68 } | 69 } |
69 | 70 |
70 void AccountFetcherService::Initialize( | 71 void AccountFetcherService::Initialize( |
71 SigninClient* signin_client, | 72 SigninClient* signin_client, |
72 OAuth2TokenService* token_service, | 73 OAuth2TokenService* token_service, |
73 AccountTrackerService* account_tracker_service, | 74 AccountTrackerService* account_tracker_service) { |
74 invalidation::InvalidationService* invalidation_service) { | |
75 DCHECK(signin_client); | 75 DCHECK(signin_client); |
76 DCHECK(!signin_client_); | 76 DCHECK(!signin_client_); |
77 signin_client_ = signin_client; | 77 signin_client_ = signin_client; |
78 invalidation_service_ = invalidation_service; | |
79 DCHECK(account_tracker_service); | 78 DCHECK(account_tracker_service); |
80 DCHECK(!account_tracker_service_); | 79 DCHECK(!account_tracker_service_); |
81 account_tracker_service_ = account_tracker_service; | 80 account_tracker_service_ = account_tracker_service; |
82 DCHECK(token_service); | 81 DCHECK(token_service); |
83 DCHECK(!token_service_); | 82 DCHECK(!token_service_); |
84 token_service_ = token_service; | 83 token_service_ = token_service; |
85 token_service_->AddObserver(this); | 84 token_service_->AddObserver(this); |
86 | 85 |
87 last_updated_ = base::Time::FromInternalValue( | 86 last_updated_ = base::Time::FromInternalValue( |
88 signin_client_->GetPrefs()->GetInt64(kLastUpdatePref)); | 87 signin_client_->GetPrefs()->GetInt64(kLastUpdatePref)); |
89 | |
90 RefreshAllAccountInfo(true); | |
91 } | 88 } |
92 | 89 |
93 void AccountFetcherService::Shutdown() { | 90 void AccountFetcherService::Shutdown() { |
94 token_service_->RemoveObserver(this); | 91 token_service_->RemoveObserver(this); |
95 // child_info_request_ is an invalidation handler and needs to be | 92 // child_info_request_ is an invalidation handler and needs to be |
96 // unregistered during the lifetime of the invalidation service. | 93 // unregistered during the lifetime of the invalidation service. |
97 child_info_request_.reset(); | 94 child_info_request_.reset(); |
| 95 invalidation_service_ = nullptr; |
98 shutdown_called_ = true; | 96 shutdown_called_ = true; |
99 } | 97 } |
100 | 98 |
101 void AccountFetcherService::EnableNetworkFetches() { | |
102 DCHECK(CalledOnValidThread()); | |
103 DCHECK(!network_fetches_enabled_); | |
104 network_fetches_enabled_ = true; | |
105 // If there are accounts in |pending_user_info_fetches_|, they were deemed | |
106 // invalid after being loaded from prefs and need to be fetched now instead of | |
107 // waiting after the timer. | |
108 for (const std::string& account_id : pending_user_info_fetches_) | |
109 StartFetchingUserInfo(account_id); | |
110 pending_user_info_fetches_.clear(); | |
111 | |
112 // Now that network fetches are enabled, schedule the next refresh. | |
113 ScheduleNextRefresh(); | |
114 } | |
115 | |
116 bool AccountFetcherService::IsAllUserInfoFetched() const { | 99 bool AccountFetcherService::IsAllUserInfoFetched() const { |
117 return user_info_requests_.empty(); | 100 return user_info_requests_.empty(); |
118 } | 101 } |
119 | 102 |
120 void AccountFetcherService::FetchUserInfoBeforeSignin( | 103 void AccountFetcherService::FetchUserInfoBeforeSignin( |
121 const std::string& account_id) { | 104 const std::string& account_id) { |
| 105 DCHECK(network_fetches_enabled_); |
122 RefreshAccountInfo(account_id, false); | 106 RefreshAccountInfo(account_id, false); |
123 } | 107 } |
124 | 108 |
| 109 void AccountFetcherService::SetupInvalidations( |
| 110 invalidation::InvalidationService* invalidation_service) { |
| 111 DCHECK(!invalidation_service_); |
| 112 DCHECK(!child_info_request_); |
| 113 invalidation_service_ = invalidation_service; |
| 114 } |
| 115 |
| 116 void AccountFetcherService::DisableScheduledRefreshForTesting() { |
| 117 DCHECK(!timer_.IsRunning()); |
| 118 DCHECK(!network_fetches_enabled_); |
| 119 scheduled_refresh_enabled_ = false; |
| 120 } |
| 121 |
125 void AccountFetcherService::RefreshAllAccountInfo(bool only_fetch_if_invalid) { | 122 void AccountFetcherService::RefreshAllAccountInfo(bool only_fetch_if_invalid) { |
126 std::vector<std::string> accounts = token_service_->GetAccounts(); | 123 std::vector<std::string> accounts = token_service_->GetAccounts(); |
127 for (std::vector<std::string>::const_iterator it = accounts.begin(); | 124 for (std::vector<std::string>::const_iterator it = accounts.begin(); |
128 it != accounts.end(); ++it) { | 125 it != accounts.end(); ++it) { |
129 RefreshAccountInfo(*it, only_fetch_if_invalid); | 126 RefreshAccountInfo(*it, only_fetch_if_invalid); |
130 } | 127 } |
131 } | 128 } |
132 | 129 |
133 // Child account status is refreshed through invalidations which are only | 130 // Child account status is refreshed through invalidations which are only |
134 // available for the primary account. Finding the primary account requires a | 131 // available for the primary account. Finding the primary account requires a |
(...skipping 21 matching lines...) Expand all Loading... |
156 void AccountFetcherService::RefreshAllAccountsAndScheduleNext() { | 153 void AccountFetcherService::RefreshAllAccountsAndScheduleNext() { |
157 DCHECK(network_fetches_enabled_); | 154 DCHECK(network_fetches_enabled_); |
158 RefreshAllAccountInfo(false); | 155 RefreshAllAccountInfo(false); |
159 last_updated_ = base::Time::Now(); | 156 last_updated_ = base::Time::Now(); |
160 signin_client_->GetPrefs()->SetInt64(kLastUpdatePref, | 157 signin_client_->GetPrefs()->SetInt64(kLastUpdatePref, |
161 last_updated_.ToInternalValue()); | 158 last_updated_.ToInternalValue()); |
162 ScheduleNextRefresh(); | 159 ScheduleNextRefresh(); |
163 } | 160 } |
164 | 161 |
165 void AccountFetcherService::ScheduleNextRefresh() { | 162 void AccountFetcherService::ScheduleNextRefresh() { |
| 163 if (!scheduled_refresh_enabled_) |
| 164 return; |
166 DCHECK(!timer_.IsRunning()); | 165 DCHECK(!timer_.IsRunning()); |
167 DCHECK(network_fetches_enabled_); | 166 DCHECK(network_fetches_enabled_); |
168 | 167 |
169 const base::TimeDelta time_since_update = base::Time::Now() - last_updated_; | 168 const base::TimeDelta time_since_update = base::Time::Now() - last_updated_; |
170 if(time_since_update > kRefreshFromTokenServiceDelay) { | 169 if(time_since_update > kRefreshFromTokenServiceDelay) { |
171 RefreshAllAccountsAndScheduleNext(); | 170 RefreshAllAccountsAndScheduleNext(); |
172 } else { | 171 } else { |
173 timer_.Start(FROM_HERE, kRefreshFromTokenServiceDelay - time_since_update, | 172 timer_.Start(FROM_HERE, kRefreshFromTokenServiceDelay - time_since_update, |
174 this, | 173 this, |
175 &AccountFetcherService::RefreshAllAccountsAndScheduleNext); | 174 &AccountFetcherService::RefreshAllAccountsAndScheduleNext); |
176 } | 175 } |
177 } | 176 } |
178 | 177 |
179 // Starts fetching user information. This is called periodically to refresh. | 178 // Starts fetching user information. This is called periodically to refresh. |
180 void AccountFetcherService::StartFetchingUserInfo( | 179 void AccountFetcherService::StartFetchingUserInfo( |
181 const std::string& account_id) { | 180 const std::string& account_id) { |
182 DCHECK(CalledOnValidThread()); | 181 DCHECK(CalledOnValidThread()); |
183 if (!network_fetches_enabled_) { | 182 DCHECK(network_fetches_enabled_); |
184 pending_user_info_fetches_.push_back(account_id); | |
185 return; | |
186 } | |
187 | 183 |
188 if (!ContainsKey(user_info_requests_, account_id)) { | 184 if (!ContainsKey(user_info_requests_, account_id)) { |
189 DVLOG(1) << "StartFetching " << account_id; | 185 DVLOG(1) << "StartFetching " << account_id; |
190 scoped_ptr<AccountInfoFetcher> fetcher(new AccountInfoFetcher( | 186 scoped_ptr<AccountInfoFetcher> fetcher(new AccountInfoFetcher( |
191 token_service_, signin_client_->GetURLRequestContext(), this, | 187 token_service_, signin_client_->GetURLRequestContext(), this, |
192 account_id)); | 188 account_id)); |
193 user_info_requests_.set(account_id, fetcher.Pass()); | 189 user_info_requests_.set(account_id, fetcher.Pass()); |
194 user_info_requests_.get(account_id)->Start(); | 190 user_info_requests_.get(account_id)->Start(); |
195 } | 191 } |
196 } | 192 } |
197 | 193 |
198 // Starts fetching whether this is a child account. Handles refresh internally. | 194 // Starts fetching whether this is a child account. Handles refresh internally. |
199 void AccountFetcherService::StartFetchingChildInfo( | 195 void AccountFetcherService::StartFetchingChildInfo( |
200 const std::string& account_id) { | 196 const std::string& account_id) { |
201 child_info_request_.reset(ChildAccountInfoFetcher::CreateFrom( | 197 child_info_request_.reset(ChildAccountInfoFetcher::CreateFrom( |
202 child_request_account_id_, this, token_service_, | 198 child_request_account_id_, this, token_service_, |
203 signin_client_->GetURLRequestContext(), invalidation_service_)); | 199 signin_client_->GetURLRequestContext(), invalidation_service_)); |
204 } | 200 } |
205 | 201 |
206 void AccountFetcherService::ResetChildInfo() { | 202 void AccountFetcherService::ResetChildInfo() { |
207 if (!child_request_account_id_.empty()) | 203 if (!child_request_account_id_.empty()) |
208 SetIsChildAccount(child_request_account_id_, false); | 204 SetIsChildAccount(child_request_account_id_, false); |
209 child_request_account_id_.clear(); | 205 child_request_account_id_.clear(); |
210 child_info_request_.reset(); | 206 child_info_request_.reset(); |
211 } | 207 } |
212 | 208 |
213 void AccountFetcherService::RefreshAccountInfo(const std::string& account_id, | 209 void AccountFetcherService::RefreshAccountInfo(const std::string& account_id, |
214 bool only_fetch_if_invalid) { | 210 bool only_fetch_if_invalid) { |
| 211 DCHECK(network_fetches_enabled_); |
215 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/422460 is | 212 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/422460 is |
216 // fixed. | 213 // fixed. |
217 tracked_objects::ScopedTracker tracking_profile( | 214 tracked_objects::ScopedTracker tracking_profile( |
218 FROM_HERE_WITH_EXPLICIT_FUNCTION( | 215 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
219 "422460 AccountFetcherService::OnRefreshTokenAvailable")); | 216 "422460 AccountFetcherService::RefreshAccountInfo")); |
220 | |
221 TRACE_EVENT1("AccountFetcherService", | |
222 "AccountFetcherService::RefreshAccountInfo", | |
223 "account_id", | |
224 account_id); | |
225 DVLOG(1) << "AVAILABLE " << account_id; | |
226 | 217 |
227 account_tracker_service_->StartTrackingAccount(account_id); | 218 account_tracker_service_->StartTrackingAccount(account_id); |
228 const AccountInfo& info = | 219 const AccountInfo& info = |
229 account_tracker_service_->GetAccountInfo(account_id); | 220 account_tracker_service_->GetAccountInfo(account_id); |
230 if (!AccountSupportsUserInfo(account_id)) | 221 if (!AccountSupportsUserInfo(account_id)) |
231 return; | 222 return; |
232 | 223 |
233 // |only_fetch_if_invalid| is false when the service is due for a timed update. | 224 // |only_fetch_if_invalid| is false when the service is due for a timed update. |
234 #if defined(OS_ANDROID) | 225 #if defined(OS_ANDROID) |
235 // TODO(mlerman): Change this condition back to info.IsValid() and ensure the | 226 // TODO(mlerman): Change this condition back to info.IsValid() and ensure the |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
286 | 277 |
287 void AccountFetcherService::OnUserInfoFetchFailure( | 278 void AccountFetcherService::OnUserInfoFetchFailure( |
288 const std::string& account_id) { | 279 const std::string& account_id) { |
289 LOG(WARNING) << "Failed to get UserInfo for " << account_id; | 280 LOG(WARNING) << "Failed to get UserInfo for " << account_id; |
290 account_tracker_service_->NotifyAccountUpdateFailed(account_id); | 281 account_tracker_service_->NotifyAccountUpdateFailed(account_id); |
291 user_info_requests_.erase(account_id); | 282 user_info_requests_.erase(account_id); |
292 } | 283 } |
293 | 284 |
294 void AccountFetcherService::OnRefreshTokenAvailable( | 285 void AccountFetcherService::OnRefreshTokenAvailable( |
295 const std::string& account_id) { | 286 const std::string& account_id) { |
| 287 TRACE_EVENT1("AccountFetcherService", |
| 288 "AccountFetcherService::OnRefreshTokenAvailable", |
| 289 "account_id", |
| 290 account_id); |
| 291 DVLOG(1) << "AVAILABLE " << account_id; |
| 292 |
296 // The SigninClient needs a "final init" in order to perform some actions | 293 // The SigninClient needs a "final init" in order to perform some actions |
297 // (such as fetching the signin token "handle" in order to look for password | 294 // (such as fetching the signin token "handle" in order to look for password |
298 // changes) once everything is initialized and the refresh token is present. | 295 // changes) once everything is initialized and the refresh token is present. |
299 signin_client_->DoFinalInit(); | 296 signin_client_->DoFinalInit(); |
| 297 |
| 298 if (!network_fetches_enabled_) |
| 299 return; |
300 RefreshAccountInfo(account_id, true); | 300 RefreshAccountInfo(account_id, true); |
301 UpdateChildInfo(); | 301 UpdateChildInfo(); |
302 } | 302 } |
303 | 303 |
304 void AccountFetcherService::OnRefreshTokenRevoked( | 304 void AccountFetcherService::OnRefreshTokenRevoked( |
305 const std::string& account_id) { | 305 const std::string& account_id) { |
306 TRACE_EVENT1("AccountFetcherService", | 306 TRACE_EVENT1("AccountFetcherService", |
307 "AccountFetcherService::OnRefreshTokenRevoked", | 307 "AccountFetcherService::OnRefreshTokenRevoked", |
308 "account_id", | 308 "account_id", |
309 account_id); | 309 account_id); |
| 310 DVLOG(1) << "REVOKED " << account_id; |
310 | 311 |
311 DVLOG(1) << "REVOKED " << account_id; | 312 if (!network_fetches_enabled_) |
| 313 return; |
312 user_info_requests_.erase(account_id); | 314 user_info_requests_.erase(account_id); |
313 UpdateChildInfo(); | 315 UpdateChildInfo(); |
314 account_tracker_service_->StopTrackingAccount(account_id); | 316 account_tracker_service_->StopTrackingAccount(account_id); |
315 } | 317 } |
316 | 318 |
317 void AccountFetcherService::OnRefreshTokensLoaded() { | 319 void AccountFetcherService::OnRefreshTokensLoaded() { |
318 // OnRefreshTokenAvailable has been called for all accounts by this point. | 320 DCHECK(CalledOnValidThread()); |
319 // Maybe remove this after further investigation. | 321 if (!network_fetches_enabled_) { |
| 322 network_fetches_enabled_ = true; |
| 323 ScheduleNextRefresh(); |
| 324 } |
320 RefreshAllAccountInfo(true); | 325 RefreshAllAccountInfo(true); |
321 UpdateChildInfo(); | 326 UpdateChildInfo(); |
322 } | 327 } |
OLD | NEW |