OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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/net/gaia/token_service.h" | 5 #include "chrome/browser/net/gaia/token_service.h" |
6 | 6 |
7 #include "base/string_util.h" | 7 #include "base/string_util.h" |
8 #include "chrome/browser/chrome_thread.h" | 8 #include "chrome/browser/chrome_thread.h" |
9 #include "chrome/browser/profile.h" | 9 #include "chrome/browser/profile.h" |
10 #include "chrome/common/net/gaia/gaia_authenticator2.h" | 10 #include "chrome/common/net/gaia/gaia_authenticator2.h" |
11 #include "chrome/common/net/gaia/gaia_constants.h" | 11 #include "chrome/common/net/gaia/gaia_constants.h" |
12 #include "chrome/common/net/url_request_context_getter.h" | 12 #include "chrome/common/net/url_request_context_getter.h" |
13 #include "chrome/common/notification_service.h" | 13 #include "chrome/common/notification_service.h" |
14 | 14 |
15 // Unfortunately kNumServices must be defined in the .h. | 15 // Unfortunately kNumServices must be defined in the .h. |
| 16 // TODO(chron): Sync doesn't use the TalkToken anymore so we can stop |
| 17 // requesting it. |
16 const char* TokenService::kServices[] = {GaiaConstants::kSyncService, | 18 const char* TokenService::kServices[] = {GaiaConstants::kSyncService, |
17 GaiaConstants::kTalkService}; | 19 GaiaConstants::kTalkService}; |
18 TokenService::TokenService() | 20 TokenService::TokenService() |
19 : token_loading_query_(NULL) { | 21 : token_loading_query_(NULL) { |
20 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); | 22 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); |
21 } | 23 } |
22 | 24 |
23 TokenService::~TokenService() { | 25 TokenService::~TokenService() { |
24 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); | 26 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); |
25 ResetCredentialsInMemory(); | 27 ResetCredentialsInMemory(); |
26 } | 28 } |
27 | 29 |
28 void TokenService::Initialize(const char* const source, | 30 void TokenService::Initialize(const char* const source, |
29 Profile* profile) { | 31 Profile* profile) { |
30 | 32 |
31 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); | 33 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); |
32 | 34 if (!source_.empty()) { |
| 35 // Already initialized. |
| 36 return; |
| 37 } |
33 getter_ = profile->GetRequestContext(); | 38 getter_ = profile->GetRequestContext(); |
34 // Since the user can create a bookmark in incognito, sync may be running. | 39 // Since the user can create a bookmark in incognito, sync may be running. |
35 // Thus we have to go for explicit access. | 40 // Thus we have to go for explicit access. |
36 web_data_service_ = profile->GetWebDataService(Profile::EXPLICIT_ACCESS); | 41 web_data_service_ = profile->GetWebDataService(Profile::EXPLICIT_ACCESS); |
37 source_ = std::string(source); | 42 source_ = std::string(source); |
| 43 registrar_.Add(this, |
| 44 NotificationType::TOKEN_UPDATED, |
| 45 NotificationService::AllSources()); |
38 } | 46 } |
39 | 47 |
40 void TokenService::ResetCredentialsInMemory() { | 48 void TokenService::ResetCredentialsInMemory() { |
41 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); | 49 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); |
42 | 50 |
43 // Terminate any running fetchers. Callbacks will not return. | 51 // Terminate any running fetchers. Callbacks will not return. |
44 for (int i = 0; i < kNumServices; i++) { | 52 for (int i = 0; i < kNumServices; i++) { |
45 fetchers_[i].reset(); | 53 fetchers_[i].reset(); |
46 } | 54 } |
47 | 55 |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
140 const std::string& service, | 148 const std::string& service, |
141 const GoogleServiceAuthError& error) { | 149 const GoogleServiceAuthError& error) { |
142 | 150 |
143 TokenRequestFailedDetails details(service, error); | 151 TokenRequestFailedDetails details(service, error); |
144 NotificationService::current()->Notify( | 152 NotificationService::current()->Notify( |
145 NotificationType::TOKEN_REQUEST_FAILED, | 153 NotificationType::TOKEN_REQUEST_FAILED, |
146 Source<TokenService>(this), | 154 Source<TokenService>(this), |
147 Details<const TokenRequestFailedDetails>(&details)); | 155 Details<const TokenRequestFailedDetails>(&details)); |
148 } | 156 } |
149 | 157 |
| 158 void TokenService::IssueAuthTokenForTest(const std::string& service, |
| 159 const std::string& auth_token) { |
| 160 token_map_[service] = auth_token; |
| 161 FireTokenAvailableNotification(service, auth_token); |
| 162 } |
| 163 |
150 void TokenService::OnIssueAuthTokenSuccess(const std::string& service, | 164 void TokenService::OnIssueAuthTokenSuccess(const std::string& service, |
151 const std::string& auth_token) { | 165 const std::string& auth_token) { |
152 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); | 166 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); |
153 LOG(INFO) << "Got an authorization token for " << service; | 167 LOG(INFO) << "Got an authorization token for " << service; |
154 token_map_[service] = auth_token; | 168 token_map_[service] = auth_token; |
155 FireTokenAvailableNotification(service, auth_token); | 169 FireTokenAvailableNotification(service, auth_token); |
156 SaveAuthTokenToDB(service, auth_token); | 170 SaveAuthTokenToDB(service, auth_token); |
157 } | 171 } |
158 | 172 |
159 void TokenService::OnIssueAuthTokenFailure(const std::string& service, | 173 void TokenService::OnIssueAuthTokenFailure(const std::string& service, |
(...skipping 11 matching lines...) Expand all Loading... |
171 | 185 |
172 // If the fetch failed, there will be no result. In that case, we just don't | 186 // If the fetch failed, there will be no result. In that case, we just don't |
173 // load any tokens at all from the DB. | 187 // load any tokens at all from the DB. |
174 if (result) { | 188 if (result) { |
175 DCHECK(result->GetType() == TOKEN_RESULT); | 189 DCHECK(result->GetType() == TOKEN_RESULT); |
176 const WDResult<std::map<std::string, std::string> > * token_result = | 190 const WDResult<std::map<std::string, std::string> > * token_result = |
177 static_cast<const WDResult<std::map<std::string, std::string> > * > ( | 191 static_cast<const WDResult<std::map<std::string, std::string> > * > ( |
178 result); | 192 result); |
179 LoadTokensIntoMemory(token_result->GetValue(), &token_map_); | 193 LoadTokensIntoMemory(token_result->GetValue(), &token_map_); |
180 } | 194 } |
| 195 |
| 196 NotificationService::current()->Notify( |
| 197 NotificationType::TOKEN_LOADING_FINISHED, |
| 198 Source<TokenService>(this), |
| 199 NotificationService::NoDetails()); |
181 } | 200 } |
182 | 201 |
183 // Load tokens from the db_token map into the in memory token map. | 202 // Load tokens from the db_token map into the in memory token map. |
184 void TokenService::LoadTokensIntoMemory( | 203 void TokenService::LoadTokensIntoMemory( |
185 const std::map<std::string, std::string>& db_tokens, | 204 const std::map<std::string, std::string>& db_tokens, |
186 std::map<std::string, std::string>* in_memory_tokens) { | 205 std::map<std::string, std::string>* in_memory_tokens) { |
187 | 206 |
188 for (int i = 0; i < kNumServices; i++) { | 207 for (int i = 0; i < kNumServices; i++) { |
189 // OnIssueAuthTokenSuccess should come from the same thread. | 208 // OnIssueAuthTokenSuccess should come from the same thread. |
190 // If a token is already present in the map, it could only have | 209 // If a token is already present in the map, it could only have |
191 // come from a DB read or from IssueAuthToken. Since we should never | 210 // come from a DB read or from IssueAuthToken. Since we should never |
192 // fetch from the DB twice in a browser session, it must be from | 211 // fetch from the DB twice in a browser session, it must be from |
193 // OnIssueAuthTokenSuccess, which is a live fetcher. | 212 // OnIssueAuthTokenSuccess, which is a live fetcher. |
194 // | 213 // |
195 // Network fetched tokens take priority over DB tokens, so exclude tokens | 214 // Network fetched tokens take priority over DB tokens, so exclude tokens |
196 // which have already been loaded by the fetcher. | 215 // which have already been loaded by the fetcher. |
197 if (!in_memory_tokens->count(kServices[i]) && | 216 if (!in_memory_tokens->count(kServices[i]) && |
198 db_tokens.count(kServices[i])) { | 217 db_tokens.count(kServices[i])) { |
199 std::string db_token = db_tokens.find(kServices[i])->second; | 218 std::string db_token = db_tokens.find(kServices[i])->second; |
200 if (!db_token.empty()) { | 219 if (!db_token.empty()) { |
201 LOG(INFO) << "Loading " << kServices[i] << "token from DB:" | 220 LOG(INFO) << "Loading " << kServices[i] << "token from DB:" |
202 << db_token; | 221 << db_token; |
203 (*in_memory_tokens)[kServices[i]] = db_token; | 222 (*in_memory_tokens)[kServices[i]] = db_token; |
204 FireTokenAvailableNotification(kServices[i], db_token); | 223 FireTokenAvailableNotification(kServices[i], db_token); |
205 // Failures are only for network errors. | 224 // Failures are only for network errors. |
206 } | 225 } |
207 } | 226 } |
208 } | 227 } |
209 } | 228 } |
| 229 |
| 230 void TokenService::Observe(NotificationType type, |
| 231 const NotificationSource& source, |
| 232 const NotificationDetails& details) { |
| 233 DCHECK(type == NotificationType::TOKEN_UPDATED); |
| 234 TokenAvailableDetails* tok_details = |
| 235 Details<TokenAvailableDetails>(details).ptr(); |
| 236 OnIssueAuthTokenSuccess(tok_details->service(), tok_details->token()); |
| 237 } |
OLD | NEW |