diff options
author | petewil@chromium.org <petewil@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-10-01 22:49:43 +0000 |
---|---|---|
committer | petewil@chromium.org <petewil@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-10-01 22:49:43 +0000 |
commit | 18b82392e590540cec2a2fe19bf03b8231ded49e (patch) | |
tree | 8b20abbce0aca7f5a9059941ef63656d1db4359c /chrome | |
parent | ee62ae2d075c19e0c327dbc0e3a4e1d78413786d (diff) | |
download | chromium_src-18b82392e590540cec2a2fe19bf03b8231ded49e.zip chromium_src-18b82392e590540cec2a2fe19bf03b8231ded49e.tar.gz chromium_src-18b82392e590540cec2a2fe19bf03b8231ded49e.tar.bz2 |
Cache the channel ID
To prevent hitting rate limits on how fast we can access the server to get an
auth token to get a channel Id, we cache the channel Id when we get one.
Note that a channel Id is per profile, so we store them by profile login name.
BUG=149733
Review URL: https://chromiumcodereview.appspot.com/10951022
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@159576 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
6 files changed, 78 insertions, 46 deletions
diff --git a/chrome/browser/extensions/api/push_messaging/push_messaging_api.cc b/chrome/browser/extensions/api/push_messaging/push_messaging_api.cc index 0d69b4c..04f356f 100644 --- a/chrome/browser/extensions/api/push_messaging/push_messaging_api.cc +++ b/chrome/browser/extensions/api/push_messaging/push_messaging_api.cc @@ -6,6 +6,7 @@ #include <set> +#include "base/basictypes.h" #include "base/bind.h" #include "base/logging.h" #include "base/values.h" @@ -29,6 +30,7 @@ #include "chrome/browser/signin/token_service_factory.h" #include "chrome/common/extensions/api/experimental_push_messaging.h" #include "content/public/browser/browser_thread.h" +#include "google_apis/gaia/gaia_constants.h" #include "googleurl/src/gurl.h" #include "chrome/browser/extensions/api/push_messaging/obfuscated_gaia_id_fetcher.h" @@ -149,10 +151,21 @@ bool PushMessagingGetChannelIdFunction::RunImpl() { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); net::URLRequestContextGetter* context = profile()->GetRequestContext(); TokenService* token_service = TokenServiceFactory::GetForProfile(profile()); + if (!token_service) + return false; const std::string& refresh_token = token_service->GetOAuth2LoginRefreshToken(); fetcher_.reset(new ObfuscatedGaiaIdFetcher(context, this, refresh_token)); + // Check the cache, if we already have a gaia ID, use it instead of + // fetching the ID over the network. + const std::string& gaia_id = + token_service->GetTokenForService(GaiaConstants::kObfuscatedGaiaId); + if (!gaia_id.empty()) { + BuildAndSendResult(gaia_id, std::string()); + return true; + } + // Balanced in ReportResult() AddRef(); @@ -168,7 +181,28 @@ void PushMessagingGetChannelIdFunction::ReportResult( // Unpack the status and GaiaId parameters, and use it to build the // channel ID here. std::string channel_id(gaia_id); + + BuildAndSendResult(gaia_id, error_string); + + // Cache the obfuscated ID locally. It never changes for this user, + // and if we call the web API too often, we get errors due to rate limiting. + if (!gaia_id.empty()) { + TokenService* token_service = TokenServiceFactory::GetForProfile(profile()); + if (token_service) { + token_service->AddAuthTokenManually(GaiaConstants::kObfuscatedGaiaId, + gaia_id); + } + } + + // Balanced in RunImpl + Release(); +} + +void PushMessagingGetChannelIdFunction::BuildAndSendResult( + const std::string& gaia_id, const std::string& error_message) { + std::string channel_id; if (!gaia_id.empty()) { + channel_id = gaia_id; channel_id += kChannelIdSeparator; channel_id += extension_id(); } @@ -180,12 +214,10 @@ void PushMessagingGetChannelIdFunction::ReportResult( // Create a ChannelId results object and set the fields. glue::ChannelIdResult result; result.channel_id = channel_id; - SetError(error_string); + SetError(error_message); results_ = glue::GetChannelId::Results::Create(result); - SendResponse(true); - - // Balanced in RunImpl - Release(); + bool success = error_message.empty() && !gaia_id.empty(); + SendResponse(success); } void PushMessagingGetChannelIdFunction::OnObfuscatedGaiaIdFetchSuccess( diff --git a/chrome/browser/extensions/api/push_messaging/push_messaging_api.h b/chrome/browser/extensions/api/push_messaging/push_messaging_api.h index 992c898..c14820b 100644 --- a/chrome/browser/extensions/api/push_messaging/push_messaging_api.h +++ b/chrome/browser/extensions/api/push_messaging/push_messaging_api.h @@ -78,6 +78,9 @@ class PushMessagingGetChannelIdFunction void ReportResult(const std::string& gaia_id, const std::string& error_message); + void BuildAndSendResult(const std::string& gaia_id, + const std::string& error_message); + // ObfuscatedGiaiaIdFetcher::Delegate implementation. virtual void OnObfuscatedGaiaIdFetchSuccess(const std::string& gaia_id) OVERRIDE; diff --git a/chrome/browser/extensions/api/push_messaging/push_messaging_apitest.cc b/chrome/browser/extensions/api/push_messaging/push_messaging_apitest.cc index d5d48fd..eeb7677 100644 --- a/chrome/browser/extensions/api/push_messaging/push_messaging_apitest.cc +++ b/chrome/browser/extensions/api/push_messaging/push_messaging_apitest.cc @@ -88,7 +88,9 @@ IN_PROC_BROWSER_TEST_F(PushMessagingApiTest, ReceivesPush) { ASSERT_TRUE(pss); // Construct a sync id for the object "U/<extension-id>/1". - std::string id = "U/" + extension->id() + "/1"; + std::string id = "U/"; + id += extension->id(); + id += "/1"; invalidation::ObjectId object_id(kSourceId, id); diff --git a/chrome/browser/signin/token_service.cc b/chrome/browser/signin/token_service.cc index a3e4fe9..fe2e394 100644 --- a/chrome/browser/signin/token_service.cc +++ b/chrome/browser/signin/token_service.cc @@ -86,12 +86,29 @@ void TokenService::Initialize(const char* const source, token_map_[service] = token; SaveAuthTokenToDB(service, token); } +} + +// TODO(petewil) We should refactor the token_service so it does not both +// store tokens and fetch them. Move the key-value storage out of +// token_service, and leave the token fetching in token_service. - registrar_.Add(this, - chrome::NOTIFICATION_TOKEN_UPDATED, - content::Source<Profile>(profile)); +void TokenService::AddAuthTokenManually(const std::string& service, + const std::string& auth_token) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + VLOG(1) << "Got an authorization token for " << service; + token_map_[service] = auth_token; + FireTokenAvailableNotification(service, auth_token); + SaveAuthTokenToDB(service, auth_token); + // If we got ClientLogin token for "lso" service, then start fetching OAuth2 + // login scoped token pair. + if (service == GaiaConstants::kLSOService) { + int index = GetServiceIndex(service); + CHECK_GE(index, 0); + fetchers_[index]->StartLsoForOAuthLoginTokenExchange(auth_token); + } } + void TokenService::ResetCredentialsInMemory() { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); @@ -135,7 +152,6 @@ void TokenService::UpdateCredentialsWithOAuth2( NOTREACHED(); } - void TokenService::LoadTokensFromDB() { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); if (web_data_service_.get()) @@ -274,18 +290,7 @@ void TokenService::IssueAuthTokenForTest(const std::string& service, void TokenService::OnIssueAuthTokenSuccess(const std::string& service, const std::string& auth_token) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - VLOG(1) << "Got an authorization token for " << service; - token_map_[service] = auth_token; - FireTokenAvailableNotification(service, auth_token); - SaveAuthTokenToDB(service, auth_token); - // If we got ClientLogin token for "lso" service, then start fetching OAuth2 - // login scoped token pair. - if (service == GaiaConstants::kLSOService) { - int index = GetServiceIndex(service); - CHECK_GE(index, 0); - fetchers_[index]->StartLsoForOAuthLoginTokenExchange(auth_token); - } + AddAuthTokenManually(service, auth_token); } void TokenService::OnIssueAuthTokenFailure(const std::string& service, @@ -360,6 +365,10 @@ void TokenService::LoadTokensIntoMemory( GaiaConstants::kGaiaOAuth2LoginRefreshToken); LoadSingleTokenIntoMemory(db_tokens, in_memory_tokens, GaiaConstants::kGaiaOAuth2LoginAccessToken); + // TODO(petewil): Remove next line when we refactor key-value + // storage out of token_service. + LoadSingleTokenIntoMemory(db_tokens, in_memory_tokens, + GaiaConstants::kObfuscatedGaiaId); if (credentials_.lsid.empty() && credentials_.sid.empty()) { // Look for GAIA SID and LSID tokens. If we have both, and the current @@ -404,12 +413,3 @@ void TokenService::LoadSingleTokenIntoMemory( } } } - -void TokenService::Observe(int type, - const content::NotificationSource& source, - const content::NotificationDetails& details) { - DCHECK_EQ(type, chrome::NOTIFICATION_TOKEN_UPDATED); - TokenAvailableDetails* tok_details = - content::Details<TokenAvailableDetails>(details).ptr(); - OnIssueAuthTokenSuccess(tok_details->service(), tok_details->token()); -} diff --git a/chrome/browser/signin/token_service.h b/chrome/browser/signin/token_service.h index d7a2175..2374317 100644 --- a/chrome/browser/signin/token_service.h +++ b/chrome/browser/signin/token_service.h @@ -52,8 +52,6 @@ #include "base/memory/scoped_ptr.h" #include "chrome/browser/profiles/profile_keyed_service.h" #include "chrome/browser/webdata/web_data_service.h" -#include "content/public/browser/notification_observer.h" -#include "content/public/browser/notification_registrar.h" #include "google_apis/gaia/gaia_auth_consumer.h" #include "google_apis/gaia/gaia_auth_fetcher.h" #include "google_apis/gaia/google_service_auth_error.h" @@ -69,8 +67,7 @@ class URLRequestContextGetter; // from the UI thread. class TokenService : public GaiaAuthConsumer, public ProfileKeyedService, - public WebDataServiceConsumer, - public content::NotificationObserver { + public WebDataServiceConsumer { public: TokenService(); virtual ~TokenService(); @@ -123,6 +120,10 @@ class TokenService : public GaiaAuthConsumer, // Used to determine whether Initialize() has been called. bool Initialized() const { return !source_.empty(); } + // Add a token not supported by a fetcher. + void AddAuthTokenManually(const std::string& service, + const std::string& auth_token); + // Update ClientLogin credentials in the token service. // Afterwards you can StartFetchingTokens. void UpdateCredentials( @@ -196,11 +197,6 @@ class TokenService : public GaiaAuthConsumer, WebDataService::Handle h, const WDTypedResult* result) OVERRIDE; - // content::NotificationObserver implementation. - virtual void Observe(int type, - const content::NotificationSource& source, - const content::NotificationDetails& details) OVERRIDE; - private: // Gets the list of all service names for which tokens will be retrieved. @@ -257,8 +253,6 @@ class TokenService : public GaiaAuthConsumer, // Map from service to token. std::map<std::string, std::string> token_map_; - content::NotificationRegistrar registrar_; - friend class TokenServiceTest; FRIEND_TEST_ALL_PREFIXES(TokenServiceTest, LoadTokensIntoMemoryBasic); FRIEND_TEST_ALL_PREFIXES(TokenServiceTest, LoadTokensIntoMemoryAdvanced); diff --git a/chrome/browser/sync/glue/sync_backend_host.cc b/chrome/browser/sync/glue/sync_backend_host.cc index a8a50ff..e235cf7 100644 --- a/chrome/browser/sync/glue/sync_backend_host.cc +++ b/chrome/browser/sync/glue/sync_backend_host.cc @@ -24,6 +24,7 @@ #include "build/build_config.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/signin/token_service.h" +#include "chrome/browser/signin/token_service_factory.h" #include "chrome/browser/sync/glue/bridged_invalidator.h" #include "chrome/browser/sync/glue/change_processor.h" #include "chrome/browser/sync/glue/chrome_encryptor.h" @@ -1491,10 +1492,10 @@ void SyncBackendHost::NotifyPassphraseAccepted() { void SyncBackendHost::NotifyUpdatedToken(const std::string& token) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); TokenAvailableDetails details(GaiaConstants::kSyncService, token); - content::NotificationService::current()->Notify( - chrome::NOTIFICATION_TOKEN_UPDATED, - content::Source<Profile>(profile_), - content::Details<const TokenAvailableDetails>(&details)); + + TokenService* token_service = TokenServiceFactory::GetForProfile(profile_); + CHECK(token_service); + token_service->AddAuthTokenManually(details.service(), details.token()); } void SyncBackendHost::NotifyEncryptedTypesChanged( |