| 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 |