Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(968)

Side by Side Diff: chrome/browser/services/gcm/gcm_account_tracker.cc

Issue 710903002: Revert of [GCM] Fetching OAuth2 tokens periodically in account tracker (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@mapper-in-driver
Patch Set: Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 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 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 "chrome/browser/services/gcm/gcm_account_tracker.h" 5 #include "chrome/browser/services/gcm/gcm_account_tracker.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <vector> 8 #include <vector>
9 9
10 #include "base/time/time.h" 10 #include "base/time/time.h"
11 #include "components/gcm_driver/gcm_driver.h" 11 #include "components/gcm_driver/gcm_driver.h"
12 #include "google_apis/gaia/google_service_auth_error.h" 12 #include "google_apis/gaia/google_service_auth_error.h"
13 #include "net/base/ip_endpoint.h" 13 #include "net/base/ip_endpoint.h"
14 14
15 namespace gcm { 15 namespace gcm {
16 16
17 namespace { 17 namespace {
18
19 // Scopes needed by the OAuth2 access tokens.
20 const char kGCMGroupServerScope[] = "https://www.googleapis.com/auth/gcm"; 18 const char kGCMGroupServerScope[] = "https://www.googleapis.com/auth/gcm";
21 const char kGCMCheckinServerScope[] = 19 const char kGCMCheckinServerScope[] =
22 "https://www.googleapis.com/auth/android_checkin"; 20 "https://www.googleapis.com/auth/android_checkin";
23 // Name of the GCM account tracker for the OAuth2TokenService.
24 const char kGCMAccountTrackerName[] = "gcm_account_tracker"; 21 const char kGCMAccountTrackerName[] = "gcm_account_tracker";
25 // Minimum token validity when sending to GCM groups server.
26 const int64 kMinimumTokenValidityMs = 500; 22 const int64 kMinimumTokenValidityMs = 500;
27 // Token reporting interval, when no account changes are detected.
28 const int64 kTokenReportingIntervalMs = 12 * 60 * 60 * 1000; // 12 hours in ms.
29
30 } // namespace 23 } // namespace
31 24
32 GCMAccountTracker::AccountInfo::AccountInfo(const std::string& email, 25 GCMAccountTracker::AccountInfo::AccountInfo(const std::string& email,
33 AccountState state) 26 AccountState state)
34 : email(email), state(state) { 27 : email(email), state(state) {
35 } 28 }
36 29
37 GCMAccountTracker::AccountInfo::~AccountInfo() { 30 GCMAccountTracker::AccountInfo::~AccountInfo() {
38 } 31 }
39 32
40 GCMAccountTracker::GCMAccountTracker( 33 GCMAccountTracker::GCMAccountTracker(
41 scoped_ptr<gaia::AccountTracker> account_tracker, 34 scoped_ptr<gaia::AccountTracker> account_tracker,
42 GCMDriver* driver) 35 GCMDriver* driver)
43 : OAuth2TokenService::Consumer(kGCMAccountTrackerName), 36 : OAuth2TokenService::Consumer(kGCMAccountTrackerName),
44 account_tracker_(account_tracker.release()), 37 account_tracker_(account_tracker.release()),
45 driver_(driver), 38 driver_(driver),
46 shutdown_called_(false), 39 shutdown_called_(false) {
47 reporting_weak_ptr_factory_(this) {
48 } 40 }
49 41
50 GCMAccountTracker::~GCMAccountTracker() { 42 GCMAccountTracker::~GCMAccountTracker() {
51 DCHECK(shutdown_called_); 43 DCHECK(shutdown_called_);
52 } 44 }
53 45
54 void GCMAccountTracker::Shutdown() { 46 void GCMAccountTracker::Shutdown() {
55 shutdown_called_ = true; 47 shutdown_called_ = true;
56 driver_->RemoveConnectionObserver(this); 48 driver_->RemoveConnectionObserver(this);
57 account_tracker_->RemoveObserver(this); 49 account_tracker_->RemoveObserver(this);
58 account_tracker_->Shutdown(); 50 account_tracker_->Shutdown();
59 } 51 }
60 52
61 void GCMAccountTracker::Start() { 53 void GCMAccountTracker::Start() {
62 DCHECK(!shutdown_called_); 54 DCHECK(!shutdown_called_);
63 account_tracker_->AddObserver(this); 55 account_tracker_->AddObserver(this);
64 driver_->AddConnectionObserver(this); 56 driver_->AddConnectionObserver(this);
65 57
66 std::vector<gaia::AccountIds> accounts = account_tracker_->GetAccounts(); 58 std::vector<gaia::AccountIds> accounts = account_tracker_->GetAccounts();
59 if (accounts.empty()) {
60 CompleteCollectingTokens();
61 return;
62 }
63
67 for (std::vector<gaia::AccountIds>::const_iterator iter = accounts.begin(); 64 for (std::vector<gaia::AccountIds>::const_iterator iter = accounts.begin();
68 iter != accounts.end(); 65 iter != accounts.end();
69 ++iter) { 66 ++iter) {
70 if (!iter->email.empty()) { 67 if (!iter->email.empty()) {
71 account_infos_.insert(std::make_pair( 68 account_infos_.insert(std::make_pair(
72 iter->account_key, AccountInfo(iter->email, TOKEN_NEEDED))); 69 iter->account_key, AccountInfo(iter->email, TOKEN_NEEDED)));
73 } 70 }
74 } 71 }
75 72
76 if (IsTokenReportingRequired()) 73 GetAllNeededTokens();
77 ReportTokens();
78 else
79 ScheduleReportTokens();
80 }
81
82 void GCMAccountTracker::ScheduleReportTokens() {
83 DVLOG(1) << "Deferring the token reporting for: "
84 << GetTimeToNextTokenReporting().InSeconds() << " seconds.";
85
86 reporting_weak_ptr_factory_.InvalidateWeakPtrs();
87 base::MessageLoop::current()->PostDelayedTask(
88 FROM_HERE,
89 base::Bind(&GCMAccountTracker::ReportTokens,
90 reporting_weak_ptr_factory_.GetWeakPtr()),
91 GetTimeToNextTokenReporting());
92 } 74 }
93 75
94 void GCMAccountTracker::OnAccountAdded(const gaia::AccountIds& ids) { 76 void GCMAccountTracker::OnAccountAdded(const gaia::AccountIds& ids) {
95 DVLOG(1) << "Account added: " << ids.email; 77 DVLOG(1) << "Account added: " << ids.email;
96 // We listen for the account signing in, which happens after account is added. 78 // We listen for the account signing in, which happens after account is added.
97 } 79 }
98 80
99 void GCMAccountTracker::OnAccountRemoved(const gaia::AccountIds& ids) { 81 void GCMAccountTracker::OnAccountRemoved(const gaia::AccountIds& ids) {
100 DVLOG(1) << "Account removed: " << ids.email; 82 DVLOG(1) << "Account removed: " << ids.email;
101 // We listen for the account signing out, which happens before account is 83 // We listen for the account signing out, which happens before account is
(...skipping 24 matching lines...) Expand all
126 // If OnAccountSignedOut(..) was called most recently, account is kept in 108 // If OnAccountSignedOut(..) was called most recently, account is kept in
127 // ACCOUNT_REMOVED state. 109 // ACCOUNT_REMOVED state.
128 if (iter->second.state == GETTING_TOKEN) { 110 if (iter->second.state == GETTING_TOKEN) {
129 iter->second.state = TOKEN_PRESENT; 111 iter->second.state = TOKEN_PRESENT;
130 iter->second.access_token = access_token; 112 iter->second.access_token = access_token;
131 iter->second.expiration_time = expiration_time; 113 iter->second.expiration_time = expiration_time;
132 } 114 }
133 } 115 }
134 116
135 DeleteTokenRequest(request); 117 DeleteTokenRequest(request);
136 ReportTokens(); 118 CompleteCollectingTokens();
137 } 119 }
138 120
139 void GCMAccountTracker::OnGetTokenFailure( 121 void GCMAccountTracker::OnGetTokenFailure(
140 const OAuth2TokenService::Request* request, 122 const OAuth2TokenService::Request* request,
141 const GoogleServiceAuthError& error) { 123 const GoogleServiceAuthError& error) {
142 DCHECK(request); 124 DCHECK(request);
143 DCHECK(!request->GetAccountId().empty()); 125 DCHECK(!request->GetAccountId().empty());
144 DVLOG(1) << "Get token failure: " << request->GetAccountId(); 126 DVLOG(1) << "Get token failure: " << request->GetAccountId();
145 127
146 AccountInfos::iterator iter = account_infos_.find(request->GetAccountId()); 128 AccountInfos::iterator iter = account_infos_.find(request->GetAccountId());
147 DCHECK(iter != account_infos_.end()); 129 DCHECK(iter != account_infos_.end());
148 if (iter != account_infos_.end()) { 130 if (iter != account_infos_.end()) {
149 DCHECK(iter->second.state == GETTING_TOKEN || 131 DCHECK(iter->second.state == GETTING_TOKEN ||
150 iter->second.state == ACCOUNT_REMOVED); 132 iter->second.state == ACCOUNT_REMOVED);
151 // If OnAccountSignedOut(..) was called most recently, account is kept in 133 // If OnAccountSignedOut(..) was called most recently, account is kept in
152 // ACCOUNT_REMOVED state. 134 // ACCOUNT_REMOVED state.
153 if (iter->second.state == GETTING_TOKEN) 135 if (iter->second.state == GETTING_TOKEN)
154 iter->second.state = TOKEN_NEEDED; 136 iter->second.state = TOKEN_NEEDED;
155 } 137 }
156 138
157 DeleteTokenRequest(request); 139 DeleteTokenRequest(request);
158 ReportTokens(); 140 CompleteCollectingTokens();
159 } 141 }
160 142
161 void GCMAccountTracker::OnConnected(const net::IPEndPoint& ip_endpoint) { 143 void GCMAccountTracker::OnConnected(const net::IPEndPoint& ip_endpoint) {
162 if (IsTokenReportingRequired()) 144 if (SanitizeTokens())
163 ReportTokens(); 145 GetAllNeededTokens();
164 } 146 }
165 147
166 void GCMAccountTracker::OnDisconnected() { 148 void GCMAccountTracker::OnDisconnected() {
167 // We are disconnected, so no point in trying to work with tokens. 149 // We are disconnected, so no point in trying to work with tokens.
168 } 150 }
169 151
170 void GCMAccountTracker::ReportTokens() { 152 void GCMAccountTracker::CompleteCollectingTokens() {
171 SanitizeTokens();
172 // Make sure all tokens are valid. 153 // Make sure all tokens are valid.
173 if (IsTokenFetchingRequired()) { 154 if (SanitizeTokens()) {
174 GetAllNeededTokens(); 155 GetAllNeededTokens();
175 return; 156 return;
176 } 157 }
177 158
178 // Wait for gaia::AccountTracker to be done with fetching the user info, as 159 // Wait for gaia::AccountTracker to be done with fetching the user info, as
179 // well as all of the pending token requests from GCMAccountTracker to be done 160 // well as all of the pending token requests from GCMAccountTracker to be done
180 // before you report the results. 161 // before you report the results.
181 if (!account_tracker_->IsAllUserInfoFetched() || 162 if (!account_tracker_->IsAllUserInfoFetched() ||
182 !pending_token_requests_.empty()) { 163 !pending_token_requests_.empty()) {
183 return; 164 return;
(...skipping 26 matching lines...) Expand all
210 // pending requests above, stopping tracking of removed accounts, or start 191 // pending requests above, stopping tracking of removed accounts, or start
211 // fetching tokens. 192 // fetching tokens.
212 NOTREACHED(); 193 NOTREACHED();
213 } 194 }
214 } 195 }
215 196
216 // Make sure that there is something to report, otherwise bail out. 197 // Make sure that there is something to report, otherwise bail out.
217 if (!account_tokens.empty() || account_removed) { 198 if (!account_tokens.empty() || account_removed) {
218 DVLOG(1) << "Reporting the tokens to driver: " << account_tokens.size(); 199 DVLOG(1) << "Reporting the tokens to driver: " << account_tokens.size();
219 driver_->SetAccountTokens(account_tokens); 200 driver_->SetAccountTokens(account_tokens);
220 driver_->SetLastTokenFetchTime(base::Time::Now());
221 ScheduleReportTokens();
222 } else { 201 } else {
223 DVLOG(1) << "No tokens and nothing removed. Skipping callback."; 202 DVLOG(1) << "No tokens and nothing removed. Skipping callback.";
224 } 203 }
225 } 204 }
226 205
227 void GCMAccountTracker::SanitizeTokens() { 206 bool GCMAccountTracker::SanitizeTokens() {
207 bool tokens_needed = false;
228 for (AccountInfos::iterator iter = account_infos_.begin(); 208 for (AccountInfos::iterator iter = account_infos_.begin();
229 iter != account_infos_.end(); 209 iter != account_infos_.end();
230 ++iter) { 210 ++iter) {
231 if (iter->second.state == TOKEN_PRESENT && 211 if (iter->second.state == TOKEN_PRESENT &&
232 iter->second.expiration_time < 212 iter->second.expiration_time <
233 base::Time::Now() + 213 base::Time::Now() +
234 base::TimeDelta::FromMilliseconds(kMinimumTokenValidityMs)) { 214 base::TimeDelta::FromMilliseconds(kMinimumTokenValidityMs)) {
235 iter->second.access_token.clear(); 215 iter->second.access_token.clear();
236 iter->second.state = TOKEN_NEEDED; 216 iter->second.state = TOKEN_NEEDED;
237 iter->second.expiration_time = base::Time(); 217 iter->second.expiration_time = base::Time();
238 } 218 }
239 }
240 }
241 219
242 bool GCMAccountTracker::IsTokenReportingRequired() const { 220 if (iter->second.state == TOKEN_NEEDED)
243 if (GetTimeToNextTokenReporting() == base::TimeDelta()) 221 tokens_needed = true;
244 return true;
245
246 bool reporting_required = false;
247 for (AccountInfos::const_iterator iter = account_infos_.begin();
248 iter != account_infos_.end();
249 ++iter) {
250 if (iter->second.state == ACCOUNT_REMOVED)
251 reporting_required = true;
252 } 222 }
253 223
254 return reporting_required; 224 return tokens_needed;
255 }
256
257 bool GCMAccountTracker::IsTokenFetchingRequired() const {
258 bool token_needed = false;
259 for (AccountInfos::const_iterator iter = account_infos_.begin();
260 iter != account_infos_.end();
261 ++iter) {
262 if (iter->second.state == TOKEN_NEEDED)
263 token_needed = true;
264 }
265
266 return token_needed;
267 }
268
269 base::TimeDelta GCMAccountTracker::GetTimeToNextTokenReporting() const {
270 base::TimeDelta time_till_next_reporting =
271 driver_->GetLastTokenFetchTime() +
272 base::TimeDelta::FromMilliseconds(kTokenReportingIntervalMs) -
273 base::Time::Now();
274 return time_till_next_reporting < base::TimeDelta() ?
275 base::TimeDelta() : time_till_next_reporting;
276 } 225 }
277 226
278 void GCMAccountTracker::DeleteTokenRequest( 227 void GCMAccountTracker::DeleteTokenRequest(
279 const OAuth2TokenService::Request* request) { 228 const OAuth2TokenService::Request* request) {
280 ScopedVector<OAuth2TokenService::Request>::iterator iter = std::find( 229 ScopedVector<OAuth2TokenService::Request>::iterator iter = std::find(
281 pending_token_requests_.begin(), pending_token_requests_.end(), request); 230 pending_token_requests_.begin(), pending_token_requests_.end(), request);
282 if (iter != pending_token_requests_.end()) 231 if (iter != pending_token_requests_.end())
283 pending_token_requests_.erase(iter); 232 pending_token_requests_.erase(iter);
284 } 233 }
285 234
286 void GCMAccountTracker::GetAllNeededTokens() { 235 void GCMAccountTracker::GetAllNeededTokens() {
287 // Only start fetching tokens if driver is running, they have a limited 236 // Only start fetching tokens if driver is running, they have a limited
288 // validity time and GCM connection is a good indication of network running. 237 // validity time and GCM connection is a good indication of network running.
289 // If the GetAllNeededTokens was called as part of periodic schedule, it may
290 // not have network. In that case the next network change will trigger token
291 // fetching.
292 if (!driver_->IsConnected()) 238 if (!driver_->IsConnected())
293 return; 239 return;
294 240
295 for (AccountInfos::iterator iter = account_infos_.begin(); 241 for (AccountInfos::iterator iter = account_infos_.begin();
296 iter != account_infos_.end(); 242 iter != account_infos_.end();
297 ++iter) { 243 ++iter) {
298 if (iter->second.state == TOKEN_NEEDED) 244 if (iter->second.state == TOKEN_NEEDED)
299 GetToken(iter); 245 GetToken(iter);
300 } 246 }
301 } 247 }
(...skipping 27 matching lines...) Expand all
329 } 275 }
330 276
331 void GCMAccountTracker::OnAccountSignedOut(const gaia::AccountIds& ids) { 277 void GCMAccountTracker::OnAccountSignedOut(const gaia::AccountIds& ids) {
332 DVLOG(1) << "Account signed out: " << ids.email; 278 DVLOG(1) << "Account signed out: " << ids.email;
333 AccountInfos::iterator iter = account_infos_.find(ids.account_key); 279 AccountInfos::iterator iter = account_infos_.find(ids.account_key);
334 if (iter == account_infos_.end()) 280 if (iter == account_infos_.end())
335 return; 281 return;
336 282
337 iter->second.access_token.clear(); 283 iter->second.access_token.clear();
338 iter->second.state = ACCOUNT_REMOVED; 284 iter->second.state = ACCOUNT_REMOVED;
339 ReportTokens(); 285 CompleteCollectingTokens();
340 } 286 }
341 287
342 OAuth2TokenService* GCMAccountTracker::GetTokenService() { 288 OAuth2TokenService* GCMAccountTracker::GetTokenService() {
343 DCHECK(account_tracker_->identity_provider()); 289 DCHECK(account_tracker_->identity_provider());
344 return account_tracker_->identity_provider()->GetTokenService(); 290 return account_tracker_->identity_provider()->GetTokenService();
345 } 291 }
346 292
347 } // namespace gcm 293 } // namespace gcm
OLDNEW
« no previous file with comments | « chrome/browser/services/gcm/gcm_account_tracker.h ('k') | chrome/browser/services/gcm/gcm_account_tracker_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698