summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
authorpetewil@chromium.org <petewil@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-10-01 22:49:43 +0000
committerpetewil@chromium.org <petewil@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-10-01 22:49:43 +0000
commit18b82392e590540cec2a2fe19bf03b8231ded49e (patch)
tree8b20abbce0aca7f5a9059941ef63656d1db4359c /chrome
parentee62ae2d075c19e0c327dbc0e3a4e1d78413786d (diff)
downloadchromium_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')
-rw-r--r--chrome/browser/extensions/api/push_messaging/push_messaging_api.cc42
-rw-r--r--chrome/browser/extensions/api/push_messaging/push_messaging_api.h3
-rw-r--r--chrome/browser/extensions/api/push_messaging/push_messaging_apitest.cc4
-rw-r--r--chrome/browser/signin/token_service.cc50
-rw-r--r--chrome/browser/signin/token_service.h16
-rw-r--r--chrome/browser/sync/glue/sync_backend_host.cc9
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(