Chromium Code Reviews| Index: chrome/browser/extensions/app_notify_channel_setup.cc |
| =================================================================== |
| --- chrome/browser/extensions/app_notify_channel_setup.cc (revision 108838) |
| +++ chrome/browser/extensions/app_notify_channel_setup.cc (working copy) |
| @@ -11,11 +11,14 @@ |
| #include "chrome/browser/net/gaia/token_service.h" |
| #include "chrome/browser/prefs/pref_service.h" |
| #include "chrome/browser/profiles/profile.h" |
| +#include "chrome/common/chrome_notification_types.h" |
| #include "chrome/common/chrome_switches.h" |
| #include "chrome/common/net/gaia/gaia_constants.h" |
| #include "chrome/common/net/http_return.h" |
| #include "chrome/common/pref_names.h" |
| #include "content/public/browser/browser_thread.h" |
| +#include "content/public/browser/notification_details.h" |
| +#include "content/public/browser/notification_service.h" |
| #include "content/public/common/url_fetcher.h" |
| #include "net/base/escape.h" |
| #include "net/base/load_flags.h" |
| @@ -65,43 +68,59 @@ |
| callback_id_(callback_id), |
| delegate_(delegate), |
| ui_(ui), |
| - state_(INITIAL) {} |
| + state_(INITIAL), |
| + fetch_token_success_count_(0), |
| + fetch_token_fail_count_(0) {} |
| AppNotifyChannelSetup::~AppNotifyChannelSetup() {} |
| void AppNotifyChannelSetup::Start() { |
| - AddRef(); // Balanced in ReportResult. |
| + AddRef(); // Balanced in ReportResult. |
| + BeginLogin(); |
| +} |
| - CHECK_EQ(INITIAL, state_); |
| +void AppNotifyChannelSetup::Observe( |
| + int type, |
| + const content::NotificationSource& source, |
| + const content::NotificationDetails& details) { |
| + if (type == chrome::NOTIFICATION_TOKEN_AVAILABLE) { |
| + TokenService::TokenAvailableDetails* tok_details = |
| + content::Details<TokenService::TokenAvailableDetails>(details).ptr(); |
| + if (IsGaiaServiceRelevant(tok_details->service())) |
| + ++fetch_token_success_count_; |
| + } else if (type == chrome::NOTIFICATION_TOKEN_REQUEST_FAILED) { |
| + TokenService::TokenRequestFailedDetails* error_details = |
| + content::Details<TokenService::TokenRequestFailedDetails>( |
| + details).ptr(); |
| + if (IsGaiaServiceRelevant(error_details->service())) |
| + ++fetch_token_fail_count_; |
| + } else { |
| + CHECK(false) << "Received a notification not registered for."; |
| + } |
| - // Check if the user is logged in to the browser. |
| - std::string username = profile_->GetPrefs()->GetString( |
| - prefs::kGoogleServicesUsername); |
| - |
| - if (username.empty()) { |
| - state_ = LOGIN_STARTED; |
| - ui_->PromptSyncSetup(this); |
| - return; // We'll get called back in OnSyncSetupResult |
| + // If we already got fetch results (success + failure) for all services |
| + // we care about, we are done with fetching tokens. |
| + if (fetch_token_success_count_ + fetch_token_fail_count_ == 2) { |
|
Rick Campbell
2011/11/11 21:18:58
I'll defer to others' judgement here, but I'm unco
Munjal (Google)
2011/11/14 23:03:15
Done.
|
| + UnregisterForTokenServiceNotifications(); |
| + // We successfully fetched tokens if success count is equal to the |
| + // number of services we care about. |
| + bool success = (fetch_token_success_count_ == 2); |
| + EndFetchTokens(success); |
| } |
| +} |
| - state_ = LOGIN_DONE; |
| - BeginRecordGrant(); |
| +bool AppNotifyChannelSetup::ShouldFetchServiceTokens() const { |
| + TokenService* token_service = profile_->GetTokenService(); |
| + return !token_service->HasTokenForService(GaiaConstants::kLSOService) || |
|
Rick Campbell
2011/11/11 21:18:58
Similarly here -- clearly related to the literal 2
Munjal (Google)
2011/11/14 23:03:15
Done.
|
| + !token_service->HasTokenForService(GaiaConstants::kCWSService); |
| } |
| void AppNotifyChannelSetup::OnSyncSetupResult(bool enabled) { |
| - CHECK_EQ(LOGIN_STARTED, state_); |
| - if (enabled) { |
| - state_ = LOGIN_DONE; |
| - BeginRecordGrant(); |
| - } else { |
| - state_ = ERROR_STATE; |
| - ReportResult("", kChannelSetupCanceledByUser); |
| - } |
| + EndLogin(enabled); |
| } |
| void AppNotifyChannelSetup::OnURLFetchComplete(const URLFetcher* source) { |
| CHECK(source); |
| - |
| switch (state_) { |
| case RECORD_GRANT_STARTED: |
| EndRecordGrant(source); |
| @@ -133,8 +152,82 @@ |
| return fetcher; |
| } |
| +// static |
|
Rick Campbell
2011/11/11 21:18:58
Similarly here -- clearly related to the literal 2
Munjal (Google)
2011/11/14 23:03:15
Done.
|
| +bool AppNotifyChannelSetup::IsGaiaServiceRelevant(const std::string& service) { |
| + return service == GaiaConstants::kLSOService || |
| + service == GaiaConstants::kCWSService; |
| +} |
| + |
| +void AppNotifyChannelSetup::RegisterForTokenServiceNotifications() { |
| + content::Source<TokenService> token_service(profile_->GetTokenService()); |
| + registrar_.Add(this, |
| + chrome::NOTIFICATION_TOKEN_AVAILABLE, |
| + token_service); |
| + registrar_.Add(this, |
| + chrome::NOTIFICATION_TOKEN_REQUEST_FAILED, |
| + token_service); |
| +} |
| + |
| +void AppNotifyChannelSetup::UnregisterForTokenServiceNotifications() { |
| + registrar_.RemoveAll(); |
| +} |
| + |
| +bool AppNotifyChannelSetup::ShouldPromptForLogin() const { |
| + std::string username = profile_->GetPrefs()->GetString( |
| + prefs::kGoogleServicesUsername); |
| + return username.empty(); |
| +} |
| + |
| +void AppNotifyChannelSetup::BeginLogin() { |
| + CHECK_EQ(INITIAL, state_); |
| + if (ShouldPromptForLogin()) { |
| + state_ = LOGIN_STARTED; |
| + ui_->PromptSyncSetup(this); |
| + // We'll get called back in OnSyncSetupResult |
| + } else { |
| + EndLogin(true); |
| + } |
| +} |
| + |
| +void AppNotifyChannelSetup::EndLogin(bool success) { |
| + CHECK_EQ(LOGIN_STARTED, state_); |
| + if (success) { |
| + state_ = LOGIN_DONE; |
| + BeginFetchTokens(); |
| + } else { |
| + state_ = ERROR_STATE; |
| + ReportResult("", kChannelSetupCanceledByUser); |
| + } |
| +} |
| + |
| +void AppNotifyChannelSetup::BeginFetchTokens() { |
| + CHECK_EQ(LOGIN_DONE, state_); |
| + if (ShouldFetchServiceTokens()) { |
| + // If a user is logged in already, and a new version of Chrome is released |
| + // with new services added to Tokenservice, TokenService will not have |
| + // tokens for the new services. |
| + state_ = FETCH_TOKEN_STARTED; |
| + RegisterForTokenServiceNotifications(); |
| + profile_->GetTokenService()->StartFetchingMissingTokens(); |
| + // Observe will get called with notifications from TokenService. |
| + } else { |
| + EndFetchTokens(true); |
| + } |
| +} |
| + |
| +void AppNotifyChannelSetup::EndFetchTokens(bool success) { |
| + CHECK_EQ(FETCH_TOKEN_STARTED, state_); |
| + if (success) { |
| + state_ = FETCH_TOKEN_DONE; |
| + BeginRecordGrant(); |
| + } else { |
| + state_ = ERROR_STATE; |
| + ReportResult("", kChannelSetupInternalError); |
| + } |
| +} |
| + |
| void AppNotifyChannelSetup::BeginRecordGrant() { |
| - CHECK_EQ(LOGIN_DONE, state_); |
| + CHECK(FETCH_TOKEN_DONE == state_); |
| state_ = RECORD_GRANT_STARTED; |
| GURL url = GetOAuth2IssueTokenURL(); |