| 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" |
| (...skipping 24 matching lines...) Expand all Loading... |
| 35 #include "extensions/common/extension.h" | 35 #include "extensions/common/extension.h" |
| 36 #include "extensions/common/permissions/api_permission.h" | 36 #include "extensions/common/permissions/api_permission.h" |
| 37 #include "google_apis/gaia/gaia_constants.h" | 37 #include "google_apis/gaia/gaia_constants.h" |
| 38 | 38 |
| 39 using content::BrowserThread; | 39 using content::BrowserThread; |
| 40 | 40 |
| 41 const char kChannelIdSeparator[] = "/"; | 41 const char kChannelIdSeparator[] = "/"; |
| 42 const char kUserNotSignedIn[] = "The user is not signed in."; | 42 const char kUserNotSignedIn[] = "The user is not signed in."; |
| 43 const char kUserAccessTokenFailure[] = | 43 const char kUserAccessTokenFailure[] = |
| 44 "Cannot obtain access token for the user."; | 44 "Cannot obtain access token for the user."; |
| 45 const char kAPINotAvailableForUser[] = |
| 46 "The API is not available for this user."; |
| 45 const int kObfuscatedGaiaIdTimeoutInDays = 30; | 47 const int kObfuscatedGaiaIdTimeoutInDays = 30; |
| 46 | 48 |
| 47 namespace extensions { | 49 namespace extensions { |
| 48 | 50 |
| 49 namespace glue = api::push_messaging; | 51 namespace glue = api::push_messaging; |
| 50 | 52 |
| 51 PushMessagingEventRouter::PushMessagingEventRouter(Profile* profile) | 53 PushMessagingEventRouter::PushMessagingEventRouter(Profile* profile) |
| 52 : profile_(profile) { | 54 : profile_(profile) { |
| 53 } | 55 } |
| 54 | 56 |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 95 glue::GetChannelId::Params::Create(*args_)); | 97 glue::GetChannelId::Params::Create(*args_)); |
| 96 EXTENSION_FUNCTION_VALIDATE(params.get()); | 98 EXTENSION_FUNCTION_VALIDATE(params.get()); |
| 97 | 99 |
| 98 if (params && params->interactive) { | 100 if (params && params->interactive) { |
| 99 interactive_ = *params->interactive; | 101 interactive_ = *params->interactive; |
| 100 } | 102 } |
| 101 | 103 |
| 102 // Balanced in ReportResult() | 104 // Balanced in ReportResult() |
| 103 AddRef(); | 105 AddRef(); |
| 104 | 106 |
| 105 if (!IsUserLoggedIn()) { | 107 invalidation::InvalidationService* invalidation_service = |
| 106 invalidation::InvalidationAuthProvider* auth_provider = | 108 invalidation::InvalidationServiceFactory::GetForProfile(GetProfile()); |
| 107 GetInvalidationAuthProvider(); | 109 if (!invalidation_service) { |
| 110 error_ = kAPINotAvailableForUser; |
| 111 ReportResult(std::string(), error_); |
| 112 return false; |
| 113 } |
| 114 |
| 115 invalidation::InvalidationAuthProvider* auth_provider = |
| 116 invalidation_service->GetInvalidationAuthProvider(); |
| 117 if (!auth_provider->GetTokenService()->RefreshTokenIsAvailable( |
| 118 auth_provider->GetAccountId())) { |
| 108 if (interactive_ && auth_provider->ShowLoginUI()) { | 119 if (interactive_ && auth_provider->ShowLoginUI()) { |
| 109 auth_provider->GetTokenService()->AddObserver(this); | 120 auth_provider->GetTokenService()->AddObserver(this); |
| 110 return true; | 121 return true; |
| 111 } else { | 122 } else { |
| 112 error_ = kUserNotSignedIn; | 123 error_ = kUserNotSignedIn; |
| 113 ReportResult(std::string(), error_); | 124 ReportResult(std::string(), error_); |
| 114 return false; | 125 return false; |
| 115 } | 126 } |
| 116 } | 127 } |
| 117 | 128 |
| 118 DVLOG(2) << "Logged in profile name: " << GetProfile()->GetProfileName(); | 129 DVLOG(2) << "Logged in profile name: " << GetProfile()->GetProfileName(); |
| 119 | 130 |
| 120 StartAccessTokenFetch(); | 131 StartAccessTokenFetch(); |
| 121 return true; | 132 return true; |
| 122 } | 133 } |
| 123 | 134 |
| 124 void PushMessagingGetChannelIdFunction::StartAccessTokenFetch() { | 135 void PushMessagingGetChannelIdFunction::StartAccessTokenFetch() { |
| 136 invalidation::InvalidationService* invalidation_service = |
| 137 invalidation::InvalidationServiceFactory::GetForProfile(GetProfile()); |
| 138 CHECK(invalidation_service); |
| 139 invalidation::InvalidationAuthProvider* auth_provider = |
| 140 invalidation_service->GetInvalidationAuthProvider(); |
| 141 |
| 125 std::vector<std::string> scope_vector = | 142 std::vector<std::string> scope_vector = |
| 126 extensions::ObfuscatedGaiaIdFetcher::GetScopes(); | 143 extensions::ObfuscatedGaiaIdFetcher::GetScopes(); |
| 127 OAuth2TokenService::ScopeSet scopes(scope_vector.begin(), scope_vector.end()); | 144 OAuth2TokenService::ScopeSet scopes(scope_vector.begin(), scope_vector.end()); |
| 128 invalidation::InvalidationAuthProvider* auth_provider = | |
| 129 GetInvalidationAuthProvider(); | |
| 130 fetcher_access_token_request_ = | 145 fetcher_access_token_request_ = |
| 131 auth_provider->GetTokenService()->StartRequest( | 146 auth_provider->GetTokenService()->StartRequest( |
| 132 auth_provider->GetAccountId(), scopes, this); | 147 auth_provider->GetAccountId(), scopes, this); |
| 133 } | 148 } |
| 134 | 149 |
| 135 void PushMessagingGetChannelIdFunction::OnRefreshTokenAvailable( | 150 void PushMessagingGetChannelIdFunction::OnRefreshTokenAvailable( |
| 136 const std::string& account_id) { | 151 const std::string& account_id) { |
| 137 GetInvalidationAuthProvider()->GetTokenService()->RemoveObserver(this); | 152 invalidation::InvalidationService* invalidation_service = |
| 153 invalidation::InvalidationServiceFactory::GetForProfile(GetProfile()); |
| 154 CHECK(invalidation_service); |
| 155 invalidation_service->GetInvalidationAuthProvider()->GetTokenService()-> |
| 156 RemoveObserver(this); |
| 138 DVLOG(2) << "Newly logged in: " << GetProfile()->GetProfileName(); | 157 DVLOG(2) << "Newly logged in: " << GetProfile()->GetProfileName(); |
| 139 StartAccessTokenFetch(); | 158 StartAccessTokenFetch(); |
| 140 } | 159 } |
| 141 | 160 |
| 142 void PushMessagingGetChannelIdFunction::OnGetTokenSuccess( | 161 void PushMessagingGetChannelIdFunction::OnGetTokenSuccess( |
| 143 const OAuth2TokenService::Request* request, | 162 const OAuth2TokenService::Request* request, |
| 144 const std::string& access_token, | 163 const std::string& access_token, |
| 145 const base::Time& expiration_time) { | 164 const base::Time& expiration_time) { |
| 146 DCHECK_EQ(fetcher_access_token_request_.get(), request); | 165 DCHECK_EQ(fetcher_access_token_request_.get(), request); |
| 147 fetcher_access_token_request_.reset(); | 166 fetcher_access_token_request_.reset(); |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 180 const std::string& gaia_id = | 199 const std::string& gaia_id = |
| 181 token_cache->RetrieveToken(GaiaConstants::kObfuscatedGaiaId); | 200 token_cache->RetrieveToken(GaiaConstants::kObfuscatedGaiaId); |
| 182 if (!gaia_id.empty()) { | 201 if (!gaia_id.empty()) { |
| 183 ReportResult(gaia_id, std::string()); | 202 ReportResult(gaia_id, std::string()); |
| 184 return; | 203 return; |
| 185 } | 204 } |
| 186 | 205 |
| 187 fetcher_->Start(); | 206 fetcher_->Start(); |
| 188 } | 207 } |
| 189 | 208 |
| 190 // Check if the user is logged in. | |
| 191 bool PushMessagingGetChannelIdFunction::IsUserLoggedIn() { | |
| 192 invalidation::InvalidationAuthProvider* auth_provider = | |
| 193 GetInvalidationAuthProvider(); | |
| 194 return auth_provider->GetTokenService()->RefreshTokenIsAvailable( | |
| 195 auth_provider->GetAccountId()); | |
| 196 } | |
| 197 | |
| 198 void PushMessagingGetChannelIdFunction::ReportResult( | 209 void PushMessagingGetChannelIdFunction::ReportResult( |
| 199 const std::string& gaia_id, const std::string& error_string) { | 210 const std::string& gaia_id, const std::string& error_string) { |
| 200 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 211 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 201 | 212 |
| 202 BuildAndSendResult(gaia_id, error_string); | 213 BuildAndSendResult(gaia_id, error_string); |
| 203 | 214 |
| 204 // Cache the obfuscated ID locally. It never changes for this user, | 215 // Cache the obfuscated ID locally. It never changes for this user, |
| 205 // and if we call the web API too often, we get errors due to rate limiting. | 216 // and if we call the web API too often, we get errors due to rate limiting. |
| 206 if (!gaia_id.empty()) { | 217 if (!gaia_id.empty()) { |
| 207 base::TimeDelta timeout = | 218 base::TimeDelta timeout = |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 253 error_text = base::IntToString(error.state()); | 264 error_text = base::IntToString(error.state()); |
| 254 } | 265 } |
| 255 | 266 |
| 256 DVLOG(1) << "GetChannelId status: '" << error_text << "'"; | 267 DVLOG(1) << "GetChannelId status: '" << error_text << "'"; |
| 257 | 268 |
| 258 // If we had bad credentials, try the logon again. | 269 // If we had bad credentials, try the logon again. |
| 259 switch (error.state()) { | 270 switch (error.state()) { |
| 260 case GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS: | 271 case GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS: |
| 261 case GoogleServiceAuthError::ACCOUNT_DELETED: | 272 case GoogleServiceAuthError::ACCOUNT_DELETED: |
| 262 case GoogleServiceAuthError::ACCOUNT_DISABLED: { | 273 case GoogleServiceAuthError::ACCOUNT_DISABLED: { |
| 263 if (!interactive_ || !GetInvalidationAuthProvider()->ShowLoginUI()) { | 274 invalidation::InvalidationService* invalidation_service = |
| 275 invalidation::InvalidationServiceFactory::GetForProfile(GetProfile()); |
| 276 CHECK(invalidation_service); |
| 277 if (!interactive_ || |
| 278 !invalidation_service->GetInvalidationAuthProvider()->ShowLoginUI()) { |
| 264 ReportResult(std::string(), error_text); | 279 ReportResult(std::string(), error_text); |
| 265 } | 280 } |
| 266 return; | 281 return; |
| 267 } | 282 } |
| 268 default: | 283 default: |
| 269 // Return error to caller. | 284 // Return error to caller. |
| 270 ReportResult(std::string(), error_text); | 285 ReportResult(std::string(), error_text); |
| 271 return; | 286 return; |
| 272 } | 287 } |
| 273 } | 288 } |
| 274 | 289 |
| 275 invalidation::InvalidationAuthProvider* | |
| 276 PushMessagingGetChannelIdFunction::GetInvalidationAuthProvider() { | |
| 277 return invalidation::InvalidationServiceFactory::GetForProfile(GetProfile()) | |
| 278 ->GetInvalidationAuthProvider(); | |
| 279 } | |
| 280 | |
| 281 PushMessagingAPI::PushMessagingAPI(content::BrowserContext* context) | 290 PushMessagingAPI::PushMessagingAPI(content::BrowserContext* context) |
| 282 : profile_(Profile::FromBrowserContext(context)) { | 291 : profile_(Profile::FromBrowserContext(context)) { |
| 283 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_INSTALLED, | 292 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_INSTALLED, |
| 284 content::Source<Profile>(profile_->GetOriginalProfile())); | 293 content::Source<Profile>(profile_->GetOriginalProfile())); |
| 285 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_LOADED, | 294 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_LOADED, |
| 286 content::Source<Profile>(profile_->GetOriginalProfile())); | 295 content::Source<Profile>(profile_->GetOriginalProfile())); |
| 287 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED_DEPRECATED, | 296 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED_DEPRECATED, |
| 288 content::Source<Profile>(profile_->GetOriginalProfile())); | 297 content::Source<Profile>(profile_->GetOriginalProfile())); |
| 289 } | 298 } |
| 290 | 299 |
| (...skipping 17 matching lines...) Expand all Loading... |
| 308 BrowserContextKeyedAPIFactory<PushMessagingAPI>* | 317 BrowserContextKeyedAPIFactory<PushMessagingAPI>* |
| 309 PushMessagingAPI::GetFactoryInstance() { | 318 PushMessagingAPI::GetFactoryInstance() { |
| 310 return g_factory.Pointer(); | 319 return g_factory.Pointer(); |
| 311 } | 320 } |
| 312 | 321 |
| 313 void PushMessagingAPI::Observe(int type, | 322 void PushMessagingAPI::Observe(int type, |
| 314 const content::NotificationSource& source, | 323 const content::NotificationSource& source, |
| 315 const content::NotificationDetails& details) { | 324 const content::NotificationDetails& details) { |
| 316 invalidation::InvalidationService* invalidation_service = | 325 invalidation::InvalidationService* invalidation_service = |
| 317 invalidation::InvalidationServiceFactory::GetForProfile(profile_); | 326 invalidation::InvalidationServiceFactory::GetForProfile(profile_); |
| 318 // This may be NULL; for example, for the ChromeOS guest user. In these cases, | |
| 319 // just return without setting up anything, since it won't work anyway. | |
| 320 if (!invalidation_service) | 327 if (!invalidation_service) |
| 321 return; | 328 return; |
| 322 | 329 |
| 323 if (!event_router_) | 330 if (!event_router_) |
| 324 event_router_.reset(new PushMessagingEventRouter(profile_)); | 331 event_router_.reset(new PushMessagingEventRouter(profile_)); |
| 325 if (!handler_) { | 332 if (!handler_) { |
| 326 handler_.reset(new PushMessagingInvalidationHandler( | 333 handler_.reset(new PushMessagingInvalidationHandler( |
| 327 invalidation_service, event_router_.get())); | 334 invalidation_service, event_router_.get())); |
| 328 } | 335 } |
| 329 switch (type) { | 336 switch (type) { |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 361 } | 368 } |
| 362 | 369 |
| 363 template <> | 370 template <> |
| 364 void | 371 void |
| 365 BrowserContextKeyedAPIFactory<PushMessagingAPI>::DeclareFactoryDependencies() { | 372 BrowserContextKeyedAPIFactory<PushMessagingAPI>::DeclareFactoryDependencies() { |
| 366 DependsOn(ExtensionsBrowserClient::Get()->GetExtensionSystemFactory()); | 373 DependsOn(ExtensionsBrowserClient::Get()->GetExtensionSystemFactory()); |
| 367 DependsOn(invalidation::InvalidationServiceFactory::GetInstance()); | 374 DependsOn(invalidation::InvalidationServiceFactory::GetInstance()); |
| 368 } | 375 } |
| 369 | 376 |
| 370 } // namespace extensions | 377 } // namespace extensions |
| OLD | NEW |