| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/extensions/api/push_messaging/push_messaging_api.h" | 5 #include "chrome/browser/extensions/api/push_messaging/push_messaging_api.h" |
| 6 | 6 |
| 7 #include <set> | 7 #include <set> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/lazy_instance.h" | 10 #include "base/lazy_instance.h" |
| 11 #include "base/logging.h" | 11 #include "base/logging.h" |
| 12 #include "base/strings/string_number_conversions.h" | 12 #include "base/strings/string_number_conversions.h" |
| 13 #include "base/values.h" | 13 #include "base/values.h" |
| 14 #include "chrome/browser/browser_process.h" |
| 14 #include "chrome/browser/chrome_notification_types.h" | 15 #include "chrome/browser/chrome_notification_types.h" |
| 15 #include "chrome/browser/extensions/api/push_messaging/push_messaging_invalidati
on_handler.h" | 16 #include "chrome/browser/extensions/api/push_messaging/push_messaging_invalidati
on_handler.h" |
| 16 #include "chrome/browser/extensions/extension_service.h" | 17 #include "chrome/browser/extensions/extension_service.h" |
| 17 #include "chrome/browser/extensions/token_cache/token_cache_service.h" | 18 #include "chrome/browser/extensions/token_cache/token_cache_service.h" |
| 18 #include "chrome/browser/extensions/token_cache/token_cache_service_factory.h" | 19 #include "chrome/browser/extensions/token_cache/token_cache_service_factory.h" |
| 20 #include "chrome/browser/invalidation/invalidation_auth_provider.h" |
| 19 #include "chrome/browser/invalidation/invalidation_service.h" | 21 #include "chrome/browser/invalidation/invalidation_service.h" |
| 20 #include "chrome/browser/invalidation/invalidation_service_factory.h" | 22 #include "chrome/browser/invalidation/invalidation_service_factory.h" |
| 21 #include "chrome/browser/profiles/profile.h" | 23 #include "chrome/browser/profiles/profile.h" |
| 22 #include "chrome/browser/signin/profile_oauth2_token_service.h" | 24 #include "chrome/browser/signin/profile_oauth2_token_service.h" |
| 23 #include "chrome/browser/signin/profile_oauth2_token_service_factory.h" | 25 #include "chrome/browser/signin/profile_oauth2_token_service_factory.h" |
| 24 #include "chrome/browser/signin/signin_manager.h" | 26 #include "chrome/browser/signin/signin_manager.h" |
| 25 #include "chrome/browser/signin/signin_manager_factory.h" | 27 #include "chrome/browser/signin/signin_manager_factory.h" |
| 26 #include "chrome/browser/ui/webui/signin/login_ui_service_factory.h" | |
| 27 #include "chrome/common/extensions/api/push_messaging.h" | 28 #include "chrome/common/extensions/api/push_messaging.h" |
| 28 #include "content/public/browser/browser_thread.h" | 29 #include "content/public/browser/browser_thread.h" |
| 29 #include "content/public/browser/notification_details.h" | 30 #include "content/public/browser/notification_details.h" |
| 30 #include "content/public/browser/notification_source.h" | 31 #include "content/public/browser/notification_source.h" |
| 31 #include "extensions/browser/event_router.h" | 32 #include "extensions/browser/event_router.h" |
| 32 #include "extensions/browser/extension_system.h" | 33 #include "extensions/browser/extension_system.h" |
| 33 #include "extensions/browser/extension_system_provider.h" | 34 #include "extensions/browser/extension_system_provider.h" |
| 34 #include "extensions/browser/extensions_browser_client.h" | 35 #include "extensions/browser/extensions_browser_client.h" |
| 35 #include "extensions/common/extension.h" | 36 #include "extensions/common/extension.h" |
| 36 #include "extensions/common/permissions/api_permission.h" | 37 #include "extensions/common/permissions/api_permission.h" |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 96 EXTENSION_FUNCTION_VALIDATE(params.get()); | 97 EXTENSION_FUNCTION_VALIDATE(params.get()); |
| 97 | 98 |
| 98 if (params && params->interactive) { | 99 if (params && params->interactive) { |
| 99 interactive_ = *params->interactive; | 100 interactive_ = *params->interactive; |
| 100 } | 101 } |
| 101 | 102 |
| 102 // Balanced in ReportResult() | 103 // Balanced in ReportResult() |
| 103 AddRef(); | 104 AddRef(); |
| 104 | 105 |
| 105 if (!IsUserLoggedIn()) { | 106 if (!IsUserLoggedIn()) { |
| 106 if (interactive_) { | 107 invalidation::InvalidationAuthProvider* auth_provider = |
| 107 ProfileOAuth2TokenServiceFactory::GetForProfile(GetProfile()) | 108 GetInvalidationAuthProvider(); |
| 108 ->AddObserver(this); | 109 if (interactive_ && auth_provider->ShowLoginUI()) { |
| 109 LoginUIServiceFactory::GetForProfile(GetProfile())->ShowLoginPopup(); | 110 auth_provider->GetTokenService()->AddObserver(this); |
| 110 return true; | 111 return true; |
| 111 } else { | 112 } else { |
| 112 error_ = kUserNotSignedIn; | 113 error_ = kUserNotSignedIn; |
| 113 ReportResult(std::string(), error_); | 114 ReportResult(std::string(), error_); |
| 114 return false; | 115 return false; |
| 115 } | 116 } |
| 116 } | 117 } |
| 117 | 118 |
| 118 DVLOG(2) << "Logged in profile name: " << GetProfile()->GetProfileName(); | 119 DVLOG(2) << "Logged in profile name: " << GetProfile()->GetProfileName(); |
| 119 | 120 |
| 120 StartAccessTokenFetch(); | 121 StartAccessTokenFetch(); |
| 121 return true; | 122 return true; |
| 122 } | 123 } |
| 123 | 124 |
| 124 void PushMessagingGetChannelIdFunction::StartAccessTokenFetch() { | 125 void PushMessagingGetChannelIdFunction::StartAccessTokenFetch() { |
| 125 std::vector<std::string> scope_vector = | 126 std::vector<std::string> scope_vector = |
| 126 extensions::ObfuscatedGaiaIdFetcher::GetScopes(); | 127 extensions::ObfuscatedGaiaIdFetcher::GetScopes(); |
| 127 OAuth2TokenService::ScopeSet scopes(scope_vector.begin(), scope_vector.end()); | 128 OAuth2TokenService::ScopeSet scopes(scope_vector.begin(), scope_vector.end()); |
| 128 ProfileOAuth2TokenService* token_service = | 129 invalidation::InvalidationAuthProvider* auth_provider = |
| 129 ProfileOAuth2TokenServiceFactory::GetForProfile(GetProfile()); | 130 GetInvalidationAuthProvider(); |
| 130 SigninManagerBase* signin_manager = | 131 fetcher_access_token_request_ = |
| 131 SigninManagerFactory::GetForProfile(GetProfile()); | 132 auth_provider->GetTokenService()->StartRequest( |
| 132 fetcher_access_token_request_ = token_service->StartRequest( | 133 auth_provider->GetAccountId(), scopes, this); |
| 133 signin_manager->GetAuthenticatedAccountId(), scopes, this); | |
| 134 } | 134 } |
| 135 | 135 |
| 136 void PushMessagingGetChannelIdFunction::OnRefreshTokenAvailable( | 136 void PushMessagingGetChannelIdFunction::OnRefreshTokenAvailable( |
| 137 const std::string& account_id) { | 137 const std::string& account_id) { |
| 138 ProfileOAuth2TokenServiceFactory::GetForProfile(GetProfile()) | 138 GetInvalidationAuthProvider()->GetTokenService()->RemoveObserver(this); |
| 139 ->RemoveObserver(this); | |
| 140 DVLOG(2) << "Newly logged in: " << GetProfile()->GetProfileName(); | 139 DVLOG(2) << "Newly logged in: " << GetProfile()->GetProfileName(); |
| 141 StartAccessTokenFetch(); | 140 StartAccessTokenFetch(); |
| 142 } | 141 } |
| 143 | 142 |
| 144 void PushMessagingGetChannelIdFunction::OnGetTokenSuccess( | 143 void PushMessagingGetChannelIdFunction::OnGetTokenSuccess( |
| 145 const OAuth2TokenService::Request* request, | 144 const OAuth2TokenService::Request* request, |
| 146 const std::string& access_token, | 145 const std::string& access_token, |
| 147 const base::Time& expiration_time) { | 146 const base::Time& expiration_time) { |
| 148 DCHECK_EQ(fetcher_access_token_request_.get(), request); | 147 DCHECK_EQ(fetcher_access_token_request_.get(), request); |
| 149 fetcher_access_token_request_.reset(); | 148 fetcher_access_token_request_.reset(); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 183 token_cache->RetrieveToken(GaiaConstants::kObfuscatedGaiaId); | 182 token_cache->RetrieveToken(GaiaConstants::kObfuscatedGaiaId); |
| 184 if (!gaia_id.empty()) { | 183 if (!gaia_id.empty()) { |
| 185 ReportResult(gaia_id, std::string()); | 184 ReportResult(gaia_id, std::string()); |
| 186 return; | 185 return; |
| 187 } | 186 } |
| 188 | 187 |
| 189 fetcher_->Start(); | 188 fetcher_->Start(); |
| 190 } | 189 } |
| 191 | 190 |
| 192 // Check if the user is logged in. | 191 // Check if the user is logged in. |
| 193 bool PushMessagingGetChannelIdFunction::IsUserLoggedIn() const { | 192 bool PushMessagingGetChannelIdFunction::IsUserLoggedIn() { |
| 194 ProfileOAuth2TokenService* token_service = | 193 invalidation::InvalidationAuthProvider* auth_provider = |
| 195 ProfileOAuth2TokenServiceFactory::GetForProfile(GetProfile()); | 194 GetInvalidationAuthProvider(); |
| 196 SigninManagerBase* signin_manager = | 195 return auth_provider->GetTokenService()->RefreshTokenIsAvailable( |
| 197 SigninManagerFactory::GetForProfile(GetProfile()); | 196 auth_provider->GetAccountId()); |
| 198 return token_service->RefreshTokenIsAvailable( | |
| 199 signin_manager->GetAuthenticatedAccountId()); | |
| 200 } | 197 } |
| 201 | 198 |
| 202 void PushMessagingGetChannelIdFunction::ReportResult( | 199 void PushMessagingGetChannelIdFunction::ReportResult( |
| 203 const std::string& gaia_id, const std::string& error_string) { | 200 const std::string& gaia_id, const std::string& error_string) { |
| 204 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 201 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 205 | 202 |
| 206 BuildAndSendResult(gaia_id, error_string); | 203 BuildAndSendResult(gaia_id, error_string); |
| 207 | 204 |
| 208 // Cache the obfuscated ID locally. It never changes for this user, | 205 // Cache the obfuscated ID locally. It never changes for this user, |
| 209 // and if we call the web API too often, we get errors due to rate limiting. | 206 // and if we call the web API too often, we get errors due to rate limiting. |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 257 error_text = base::IntToString(error.state()); | 254 error_text = base::IntToString(error.state()); |
| 258 } | 255 } |
| 259 | 256 |
| 260 DVLOG(1) << "GetChannelId status: '" << error_text << "'"; | 257 DVLOG(1) << "GetChannelId status: '" << error_text << "'"; |
| 261 | 258 |
| 262 // If we had bad credentials, try the logon again. | 259 // If we had bad credentials, try the logon again. |
| 263 switch (error.state()) { | 260 switch (error.state()) { |
| 264 case GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS: | 261 case GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS: |
| 265 case GoogleServiceAuthError::ACCOUNT_DELETED: | 262 case GoogleServiceAuthError::ACCOUNT_DELETED: |
| 266 case GoogleServiceAuthError::ACCOUNT_DISABLED: { | 263 case GoogleServiceAuthError::ACCOUNT_DISABLED: { |
| 267 if (interactive_) { | 264 if (!interactive_ || !GetInvalidationAuthProvider()->ShowLoginUI()) { |
| 268 LoginUIService* login_ui_service = | |
| 269 LoginUIServiceFactory::GetForProfile(GetProfile()); | |
| 270 // content::NotificationObserver will be called if token is issued. | |
| 271 login_ui_service->ShowLoginPopup(); | |
| 272 } else { | |
| 273 ReportResult(std::string(), error_text); | 265 ReportResult(std::string(), error_text); |
| 274 } | 266 } |
| 275 return; | 267 return; |
| 276 } | 268 } |
| 277 default: | 269 default: |
| 278 // Return error to caller. | 270 // Return error to caller. |
| 279 ReportResult(std::string(), error_text); | 271 ReportResult(std::string(), error_text); |
| 280 return; | 272 return; |
| 281 } | 273 } |
| 282 } | 274 } |
| 283 | 275 |
| 276 invalidation::InvalidationAuthProvider* |
| 277 PushMessagingGetChannelIdFunction::GetInvalidationAuthProvider() { |
| 278 return invalidation::InvalidationServiceFactory::GetForProfile(GetProfile()) |
| 279 ->GetInvalidationAuthProvider(); |
| 280 } |
| 281 |
| 284 PushMessagingAPI::PushMessagingAPI(Profile* profile) : profile_(profile) { | 282 PushMessagingAPI::PushMessagingAPI(Profile* profile) : profile_(profile) { |
| 285 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_INSTALLED, | 283 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_INSTALLED, |
| 286 content::Source<Profile>(profile_->GetOriginalProfile())); | 284 content::Source<Profile>(profile_->GetOriginalProfile())); |
| 287 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_LOADED, | 285 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_LOADED, |
| 288 content::Source<Profile>(profile_->GetOriginalProfile())); | 286 content::Source<Profile>(profile_->GetOriginalProfile())); |
| 289 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED, | 287 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED, |
| 290 content::Source<Profile>(profile_->GetOriginalProfile())); | 288 content::Source<Profile>(profile_->GetOriginalProfile())); |
| 291 } | 289 } |
| 292 | 290 |
| 293 PushMessagingAPI::~PushMessagingAPI() { | 291 PushMessagingAPI::~PushMessagingAPI() { |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 362 handler_ = mapper.Pass(); | 360 handler_ = mapper.Pass(); |
| 363 } | 361 } |
| 364 | 362 |
| 365 template <> | 363 template <> |
| 366 void ProfileKeyedAPIFactory<PushMessagingAPI>::DeclareFactoryDependencies() { | 364 void ProfileKeyedAPIFactory<PushMessagingAPI>::DeclareFactoryDependencies() { |
| 367 DependsOn(ExtensionsBrowserClient::Get()->GetExtensionSystemFactory()); | 365 DependsOn(ExtensionsBrowserClient::Get()->GetExtensionSystemFactory()); |
| 368 DependsOn(invalidation::InvalidationServiceFactory::GetInstance()); | 366 DependsOn(invalidation::InvalidationServiceFactory::GetInstance()); |
| 369 } | 367 } |
| 370 | 368 |
| 371 } // namespace extensions | 369 } // namespace extensions |
| OLD | NEW |