Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 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/services/gcm/gcm_profile_service.h" | 5 #include "chrome/browser/services/gcm/gcm_profile_service.h" |
| 6 | 6 |
| 7 #include "base/base64.h" | 7 #include "base/base64.h" |
| 8 #include "base/files/file_path.h" | 8 #include "base/files/file_path.h" |
| 9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "base/path_service.h" | 10 #include "base/path_service.h" |
| (...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 248 const std::string& app_id, | 248 const std::string& app_id, |
| 249 const GCMClient::IncomingMessage& message) OVERRIDE; | 249 const GCMClient::IncomingMessage& message) OVERRIDE; |
| 250 virtual void OnMessagesDeleted(const std::string& app_id) OVERRIDE; | 250 virtual void OnMessagesDeleted(const std::string& app_id) OVERRIDE; |
| 251 virtual void OnMessageSendError(const std::string& app_id, | 251 virtual void OnMessageSendError(const std::string& app_id, |
| 252 const std::string& message_id, | 252 const std::string& message_id, |
| 253 GCMClient::Result result) OVERRIDE; | 253 GCMClient::Result result) OVERRIDE; |
| 254 virtual void OnGCMReady() OVERRIDE; | 254 virtual void OnGCMReady() OVERRIDE; |
| 255 | 255 |
| 256 // Called on IO thread. | 256 // Called on IO thread. |
| 257 void Initialize( | 257 void Initialize( |
| 258 GCMClientFactory* gcm_client_factory, | 258 scoped_ptr<GCMClientFactory> gcm_client_factory, |
| 259 const base::FilePath& store_path, | 259 const base::FilePath& store_path, |
| 260 const scoped_refptr<net::URLRequestContextGetter>& | 260 const scoped_refptr<net::URLRequestContextGetter>& |
| 261 url_request_context_getter); | 261 url_request_context_getter); |
| 262 void Reset(); | 262 void Reset(); |
| 263 void Load(); | |
| 263 void CheckOut(); | 264 void CheckOut(); |
| 264 void Register(const std::string& app_id, | 265 void Register(const std::string& app_id, |
| 265 const std::vector<std::string>& sender_ids, | 266 const std::vector<std::string>& sender_ids, |
| 266 const std::string& cert); | 267 const std::string& cert); |
| 267 void Unregister(const std::string& app_id); | 268 void Unregister(const std::string& app_id); |
| 268 void Send(const std::string& app_id, | 269 void Send(const std::string& app_id, |
| 269 const std::string& receiver_id, | 270 const std::string& receiver_id, |
| 270 const GCMClient::OutgoingMessage& message); | 271 const GCMClient::OutgoingMessage& message); |
| 271 | 272 |
| 273 // For testing purpose. Can be called from UI thread. Use with care. | |
| 274 GCMClient* gcm_client_for_testing() const { return gcm_client_.get(); } | |
| 275 | |
| 272 private: | 276 private: |
| 273 friend class base::RefCountedThreadSafe<IOWorker>; | 277 friend class base::RefCountedThreadSafe<IOWorker>; |
| 274 virtual ~IOWorker(); | 278 virtual ~IOWorker(); |
| 275 | 279 |
| 276 const base::WeakPtr<GCMProfileService> service_; | 280 const base::WeakPtr<GCMProfileService> service_; |
| 277 | 281 |
| 278 scoped_ptr<GCMClient> gcm_client_; | 282 scoped_ptr<GCMClient> gcm_client_; |
| 279 }; | 283 }; |
| 280 | 284 |
| 281 GCMProfileService::IOWorker::IOWorker( | 285 GCMProfileService::IOWorker::IOWorker( |
| 282 const base::WeakPtr<GCMProfileService>& service) | 286 const base::WeakPtr<GCMProfileService>& service) |
| 283 : service_(service) { | 287 : service_(service) { |
| 284 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | 288 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
| 285 } | 289 } |
| 286 | 290 |
| 287 GCMProfileService::IOWorker::~IOWorker() { | 291 GCMProfileService::IOWorker::~IOWorker() { |
| 288 } | 292 } |
| 289 | 293 |
| 290 void GCMProfileService::IOWorker::Initialize( | 294 void GCMProfileService::IOWorker::Initialize( |
| 291 GCMClientFactory* gcm_client_factory, | 295 scoped_ptr<GCMClientFactory> gcm_client_factory, |
| 292 const base::FilePath& store_path, | 296 const base::FilePath& store_path, |
| 293 const scoped_refptr<net::URLRequestContextGetter>& | 297 const scoped_refptr<net::URLRequestContextGetter>& |
| 294 url_request_context_getter) { | 298 url_request_context_getter) { |
| 295 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); | 299 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); |
| 296 | 300 |
| 297 gcm_client_ = gcm_client_factory->BuildInstance().Pass(); | 301 gcm_client_ = gcm_client_factory->BuildInstance().Pass(); |
| 298 | 302 |
| 299 checkin_proto::ChromeBuildProto chrome_build_proto; | 303 checkin_proto::ChromeBuildProto chrome_build_proto; |
| 300 chrome_build_proto.set_platform(GetPlatform()); | 304 chrome_build_proto.set_platform(GetPlatform()); |
| 301 chrome_build_proto.set_chrome_version(GetVersion()); | 305 chrome_build_proto.set_chrome_version(GetVersion()); |
| 302 chrome_build_proto.set_channel(GetChannel()); | 306 chrome_build_proto.set_channel(GetChannel()); |
| 303 | 307 |
| 304 scoped_refptr<base::SequencedWorkerPool> worker_pool( | 308 scoped_refptr<base::SequencedWorkerPool> worker_pool( |
| 305 content::BrowserThread::GetBlockingPool()); | 309 content::BrowserThread::GetBlockingPool()); |
| 306 scoped_refptr<base::SequencedTaskRunner> blocking_task_runner( | 310 scoped_refptr<base::SequencedTaskRunner> blocking_task_runner( |
| 307 worker_pool->GetSequencedTaskRunnerWithShutdownBehavior( | 311 worker_pool->GetSequencedTaskRunnerWithShutdownBehavior( |
| 308 worker_pool->GetSequenceToken(), | 312 worker_pool->GetSequenceToken(), |
| 309 base::SequencedWorkerPool::SKIP_ON_SHUTDOWN)); | 313 base::SequencedWorkerPool::SKIP_ON_SHUTDOWN)); |
| 310 | 314 |
| 311 gcm_client_->Initialize(chrome_build_proto, | 315 gcm_client_->Initialize(chrome_build_proto, |
| 312 store_path, | 316 store_path, |
| 313 blocking_task_runner, | 317 blocking_task_runner, |
| 314 url_request_context_getter, | 318 url_request_context_getter, |
| 315 this); | 319 this); |
| 316 | 320 |
| 317 content::BrowserThread::PostTask( | 321 content::BrowserThread::PostTask( |
| 318 content::BrowserThread::UI, | 322 content::BrowserThread::UI, |
| 319 FROM_HERE, | 323 FROM_HERE, |
| 320 base::Bind(&GCMProfileService::FinishInitializationOnUI, | 324 base::Bind(&GCMProfileService::FinishInitializationOnUI, service_)); |
| 321 service_, | |
| 322 gcm_client_->IsReady())); | |
| 323 } | 325 } |
| 324 | 326 |
| 325 void GCMProfileService::IOWorker::Reset() { | 327 void GCMProfileService::IOWorker::Reset() { |
| 326 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); | 328 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); |
| 327 | 329 |
| 328 // GCMClient instance must be destroyed from the same thread where it was | 330 // GCMClient instance must be destroyed from the same thread where it was |
| 329 // created. | 331 // created. |
| 330 gcm_client_.reset(); | 332 gcm_client_.reset(); |
| 331 } | 333 } |
| 332 | 334 |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 410 } | 412 } |
| 411 | 413 |
| 412 void GCMProfileService::IOWorker::OnGCMReady() { | 414 void GCMProfileService::IOWorker::OnGCMReady() { |
| 413 content::BrowserThread::PostTask( | 415 content::BrowserThread::PostTask( |
| 414 content::BrowserThread::UI, | 416 content::BrowserThread::UI, |
| 415 FROM_HERE, | 417 FROM_HERE, |
| 416 base::Bind(&GCMProfileService::GCMClientReady, | 418 base::Bind(&GCMProfileService::GCMClientReady, |
| 417 service_)); | 419 service_)); |
| 418 } | 420 } |
| 419 | 421 |
| 422 void GCMProfileService::IOWorker::Load() { | |
| 423 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); | |
| 424 | |
| 425 gcm_client_->Load(); | |
| 426 } | |
| 427 | |
| 420 void GCMProfileService::IOWorker::CheckOut() { | 428 void GCMProfileService::IOWorker::CheckOut() { |
| 421 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); | 429 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); |
| 422 | 430 |
| 423 gcm_client_->CheckOut(); | 431 gcm_client_->CheckOut(); |
| 424 gcm_client_.reset(); | 432 |
| 433 // Note that we still need to keep GCMClient instance alive since the profile | |
| 434 // might have been signed in again. | |
|
Nicolas Zea
2014/02/22 00:20:47
nit: might have been -> might be
| |
| 425 } | 435 } |
| 426 | 436 |
| 427 void GCMProfileService::IOWorker::Register( | 437 void GCMProfileService::IOWorker::Register( |
| 428 const std::string& app_id, | 438 const std::string& app_id, |
| 429 const std::vector<std::string>& sender_ids, | 439 const std::vector<std::string>& sender_ids, |
| 430 const std::string& cert) { | 440 const std::string& cert) { |
| 431 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); | 441 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); |
| 432 | 442 |
| 433 gcm_client_->Register(app_id, cert, sender_ids); | 443 gcm_client_->Register(app_id, cert, sender_ids); |
| 434 } | 444 } |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 451 GCMProfileService::RegistrationInfo::RegistrationInfo() { | 461 GCMProfileService::RegistrationInfo::RegistrationInfo() { |
| 452 } | 462 } |
| 453 | 463 |
| 454 GCMProfileService::RegistrationInfo::~RegistrationInfo() { | 464 GCMProfileService::RegistrationInfo::~RegistrationInfo() { |
| 455 } | 465 } |
| 456 | 466 |
| 457 bool GCMProfileService::RegistrationInfo::IsValid() const { | 467 bool GCMProfileService::RegistrationInfo::IsValid() const { |
| 458 return !sender_ids.empty() && !registration_id.empty(); | 468 return !sender_ids.empty() && !registration_id.empty(); |
| 459 } | 469 } |
| 460 | 470 |
| 461 bool GCMProfileService::enable_gcm_for_testing_ = false; | 471 // static |
| 472 GCMProfileService::GCMEnabledState GCMProfileService::GetGCMEnabledState( | |
| 473 Profile* profile) { | |
| 474 const base::Value* gcm_enabled_value = | |
| 475 profile->GetPrefs()->GetUserPrefValue(prefs::kGCMChannelEnabled); | |
| 476 if (!gcm_enabled_value) | |
| 477 return ENABLED_FOR_APPS; | |
| 462 | 478 |
| 463 // static | 479 bool gcm_enabled = false; |
| 464 bool GCMProfileService::IsGCMEnabled(Profile* profile) { | 480 if (!gcm_enabled_value->GetAsBoolean(&gcm_enabled)) |
| 465 // GCM is not enabled in incognito mode. | 481 return ENABLED_FOR_APPS; |
| 466 if (profile->IsOffTheRecord()) | |
| 467 return false; | |
| 468 | 482 |
| 469 if (enable_gcm_for_testing_) | 483 return gcm_enabled ? ALWAYS_ENABLED : ALWAYS_DISABLED; |
| 470 return true; | |
| 471 | |
| 472 return profile->GetPrefs()->GetBoolean(prefs::kGCMChannelEnabled); | |
| 473 } | 484 } |
| 474 | 485 |
| 475 // static | 486 // static |
| 476 void GCMProfileService::RegisterProfilePrefs( | 487 void GCMProfileService::RegisterProfilePrefs( |
| 477 user_prefs::PrefRegistrySyncable* registry) { | 488 user_prefs::PrefRegistrySyncable* registry) { |
| 478 // GCM support is only enabled by default for Canary/Dev/Custom builds. | 489 // GCM support is only enabled by default for Canary/Dev/Custom builds. |
| 479 chrome::VersionInfo::Channel channel = chrome::VersionInfo::GetChannel(); | 490 chrome::VersionInfo::Channel channel = chrome::VersionInfo::GetChannel(); |
| 480 bool on_by_default = false; | 491 bool on_by_default = false; |
| 481 if (channel == chrome::VersionInfo::CHANNEL_UNKNOWN || | 492 if (channel == chrome::VersionInfo::CHANNEL_UNKNOWN || |
| 482 channel == chrome::VersionInfo::CHANNEL_CANARY || | 493 channel == chrome::VersionInfo::CHANNEL_CANARY || |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 498 testing_delegate_(NULL), | 509 testing_delegate_(NULL), |
| 499 weak_ptr_factory_(this) { | 510 weak_ptr_factory_(this) { |
| 500 DCHECK(!profile->IsOffTheRecord()); | 511 DCHECK(!profile->IsOffTheRecord()); |
| 501 } | 512 } |
| 502 | 513 |
| 503 GCMProfileService::~GCMProfileService() { | 514 GCMProfileService::~GCMProfileService() { |
| 504 } | 515 } |
| 505 | 516 |
| 506 void GCMProfileService::Initialize( | 517 void GCMProfileService::Initialize( |
| 507 scoped_ptr<GCMClientFactory> gcm_client_factory) { | 518 scoped_ptr<GCMClientFactory> gcm_client_factory) { |
| 508 gcm_client_factory_ = gcm_client_factory.Pass(); | |
| 509 | |
| 510 // This has to be done first since CheckIn depends on it. | |
| 511 io_worker_ = new IOWorker(weak_ptr_factory_.GetWeakPtr()); | |
| 512 | |
| 513 #if !defined(OS_ANDROID) | |
| 514 js_event_router_.reset(new extensions::GcmJsEventRouter(profile_)); | |
| 515 #endif | |
| 516 | |
| 517 registrar_.Add(this, | 519 registrar_.Add(this, |
| 518 chrome::NOTIFICATION_GOOGLE_SIGNIN_SUCCESSFUL, | 520 chrome::NOTIFICATION_GOOGLE_SIGNIN_SUCCESSFUL, |
| 519 content::Source<Profile>(profile_)); | 521 content::Source<Profile>(profile_)); |
| 520 registrar_.Add(this, | 522 registrar_.Add(this, |
| 521 chrome::NOTIFICATION_GOOGLE_SIGNED_OUT, | 523 chrome::NOTIFICATION_GOOGLE_SIGNED_OUT, |
| 522 content::Source<Profile>(profile_)); | 524 content::Source<Profile>(profile_)); |
| 523 registrar_.Add(this, | 525 registrar_.Add(this, |
| 524 chrome::NOTIFICATION_PROFILE_DESTROYED, | 526 chrome::NOTIFICATION_PROFILE_DESTROYED, |
| 525 content::Source<Profile>(profile_)); | 527 content::Source<Profile>(profile_)); |
| 526 // TODO(jianli): move extension specific logic out of GCMProfileService. | 528 // TODO(jianli): move extension specific logic out of GCMProfileService. |
| 527 registrar_.Add(this, | 529 registrar_.Add(this, |
| 528 chrome:: NOTIFICATION_EXTENSION_UNINSTALLED, | 530 chrome:: NOTIFICATION_EXTENSION_UNINSTALLED, |
| 529 content::Source<Profile>(profile_)); | 531 content::Source<Profile>(profile_)); |
| 530 | 532 |
| 531 // In case that the profile has been signed in before GCMProfileService is | 533 // Create and initialize the GCMClient. Note that this does not initiate the |
| 532 // created. | 534 // GCM check-in. |
| 533 SigninManagerBase* manager = SigninManagerFactory::GetForProfile(profile_); | 535 io_worker_ = new IOWorker(weak_ptr_factory_.GetWeakPtr()); |
| 534 if (manager) { | 536 scoped_refptr<net::URLRequestContextGetter> url_request_context_getter = |
| 535 std::string username = manager->GetAuthenticatedUsername(); | 537 profile_->GetRequestContext(); |
| 536 if (!username.empty()) | 538 content::BrowserThread::PostTask( |
| 537 CheckIn(username); | 539 content::BrowserThread::IO, |
| 538 } | 540 FROM_HERE, |
| 541 base::Bind(&GCMProfileService::IOWorker::Initialize, | |
| 542 io_worker_, | |
| 543 base::Passed(&gcm_client_factory), | |
| 544 profile_->GetPath().Append(chrome::kGCMStoreDirname), | |
| 545 url_request_context_getter)); | |
| 539 } | 546 } |
| 540 | 547 |
| 541 void GCMProfileService::Register(const std::string& app_id, | 548 void GCMProfileService::Register(const std::string& app_id, |
| 542 const std::vector<std::string>& sender_ids, | 549 const std::vector<std::string>& sender_ids, |
| 543 const std::string& cert, | 550 const std::string& cert, |
| 544 RegisterCallback callback) { | 551 RegisterCallback callback) { |
| 545 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | 552 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
| 546 DCHECK(!app_id.empty() && !sender_ids.empty() && !callback.is_null()); | 553 DCHECK(!app_id.empty() && !sender_ids.empty() && !callback.is_null()); |
| 547 | 554 |
| 555 // Ensure that check-in has been done. | |
| 556 EnsureLoaded(); | |
| 557 | |
| 548 // If the profile was not signed in, bail out. | 558 // If the profile was not signed in, bail out. |
| 549 if (username_.empty()) { | 559 if (username_.empty()) { |
| 550 callback.Run(std::string(), GCMClient::NOT_SIGNED_IN); | 560 callback.Run(std::string(), GCMClient::NOT_SIGNED_IN); |
| 551 return; | 561 return; |
| 552 } | 562 } |
| 553 | 563 |
| 554 // If previous register operation is still in progress, bail out. | 564 // If previous register operation is still in progress, bail out. |
| 555 if (register_callbacks_.find(app_id) != register_callbacks_.end()) { | 565 if (register_callbacks_.find(app_id) != register_callbacks_.end()) { |
| 556 callback.Run(std::string(), GCMClient::ASYNC_OPERATION_PENDING); | 566 callback.Run(std::string(), GCMClient::ASYNC_OPERATION_PENDING); |
| 557 return; | 567 return; |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 623 cert)); | 633 cert)); |
| 624 } | 634 } |
| 625 | 635 |
| 626 void GCMProfileService::Send(const std::string& app_id, | 636 void GCMProfileService::Send(const std::string& app_id, |
| 627 const std::string& receiver_id, | 637 const std::string& receiver_id, |
| 628 const GCMClient::OutgoingMessage& message, | 638 const GCMClient::OutgoingMessage& message, |
| 629 SendCallback callback) { | 639 SendCallback callback) { |
| 630 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | 640 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
| 631 DCHECK(!app_id.empty() && !receiver_id.empty() && !callback.is_null()); | 641 DCHECK(!app_id.empty() && !receiver_id.empty() && !callback.is_null()); |
| 632 | 642 |
| 643 // Ensure that check-in has been done. | |
| 644 EnsureLoaded(); | |
| 645 | |
| 633 // If the profile was not signed in, bail out. | 646 // If the profile was not signed in, bail out. |
| 634 if (username_.empty()) { | 647 if (username_.empty()) { |
| 635 callback.Run(std::string(), GCMClient::NOT_SIGNED_IN); | 648 callback.Run(std::string(), GCMClient::NOT_SIGNED_IN); |
| 636 return; | 649 return; |
| 637 } | 650 } |
| 638 | 651 |
| 639 // If the message with send ID is still in progress, bail out. | 652 // If the message with send ID is still in progress, bail out. |
| 640 std::pair<std::string, std::string> key(app_id, message.id); | 653 std::pair<std::string, std::string> key(app_id, message.id); |
| 641 if (send_callbacks_.find(key) != send_callbacks_.end()) { | 654 if (send_callbacks_.find(key) != send_callbacks_.end()) { |
| 642 callback.Run(message.id, GCMClient::INVALID_PARAMETER); | 655 callback.Run(message.id, GCMClient::INVALID_PARAMETER); |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 667 content::BrowserThread::PostTask( | 680 content::BrowserThread::PostTask( |
| 668 content::BrowserThread::IO, | 681 content::BrowserThread::IO, |
| 669 FROM_HERE, | 682 FROM_HERE, |
| 670 base::Bind(&GCMProfileService::IOWorker::Send, | 683 base::Bind(&GCMProfileService::IOWorker::Send, |
| 671 io_worker_, | 684 io_worker_, |
| 672 app_id, | 685 app_id, |
| 673 receiver_id, | 686 receiver_id, |
| 674 message)); | 687 message)); |
| 675 } | 688 } |
| 676 | 689 |
| 690 GCMClient* GCMProfileService::GetGCMClientForTesting() const { | |
| 691 return io_worker_ ? io_worker_->gcm_client_for_testing() : NULL; | |
| 692 } | |
| 693 | |
| 677 void GCMProfileService::Observe(int type, | 694 void GCMProfileService::Observe(int type, |
| 678 const content::NotificationSource& source, | 695 const content::NotificationSource& source, |
| 679 const content::NotificationDetails& details) { | 696 const content::NotificationDetails& details) { |
| 680 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | 697 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
| 681 | 698 |
| 682 switch (type) { | 699 switch (type) { |
| 683 case chrome::NOTIFICATION_GOOGLE_SIGNIN_SUCCESSFUL: { | 700 case chrome::NOTIFICATION_GOOGLE_SIGNIN_SUCCESSFUL: { |
| 684 const GoogleServiceSigninSuccessDetails* signin_details = | 701 if (GetGCMEnabledState(profile_) == ALWAYS_ENABLED) |
| 685 content::Details<GoogleServiceSigninSuccessDetails>(details).ptr(); | 702 EnsureLoaded(); |
| 686 // This could be called multiple times when the password changed. | |
| 687 if (username_ != signin_details->username) | |
| 688 CheckIn(signin_details->username); | |
| 689 break; | 703 break; |
| 690 } | 704 } |
| 691 case chrome::NOTIFICATION_GOOGLE_SIGNED_OUT: | 705 case chrome::NOTIFICATION_GOOGLE_SIGNED_OUT: |
| 692 CheckOut(); | 706 CheckOut(); |
| 693 break; | 707 break; |
| 694 case chrome::NOTIFICATION_PROFILE_DESTROYED: | 708 case chrome::NOTIFICATION_PROFILE_DESTROYED: |
| 695 ResetGCMClient(); | 709 ResetGCMClient(); |
| 696 break; | 710 break; |
| 697 case chrome:: NOTIFICATION_EXTENSION_UNINSTALLED: { | 711 case chrome:: NOTIFICATION_EXTENSION_UNINSTALLED: |
| 698 extensions::Extension* extension = | 712 if (!username_.empty()) { |
| 699 content::Details<extensions::Extension>(details).ptr(); | 713 extensions::Extension* extension = |
| 700 Unregister(extension->id()); | 714 content::Details<extensions::Extension>(details).ptr(); |
| 715 Unregister(extension->id()); | |
| 716 } | |
| 701 break; | 717 break; |
| 702 } | |
| 703 default: | 718 default: |
| 704 NOTREACHED(); | 719 NOTREACHED(); |
| 705 } | 720 } |
| 706 } | 721 } |
| 707 | 722 |
| 708 void GCMProfileService::CheckIn(const std::string& username) { | 723 void GCMProfileService::EnsureLoaded() { |
| 709 DCHECK(!username.empty() && username_.empty()); | 724 SigninManagerBase* manager = SigninManagerFactory::GetForProfile(profile_); |
| 725 if (!manager) | |
| 726 return; | |
| 727 std::string username = manager->GetAuthenticatedUsername(); | |
| 728 if (username.empty()) | |
| 729 return; | |
| 730 | |
| 731 // CheckIn could be called more than once when: | |
| 732 // 1) The password changes. | |
| 733 // 2) Register/send function calls it to ensure CheckIn is done. | |
| 734 if (username_ == username) | |
| 735 return; | |
| 710 username_ = username; | 736 username_ = username; |
| 711 | 737 |
| 738 #if !defined(OS_ANDROID) | |
| 739 if (!js_event_router_) | |
| 740 js_event_router_.reset(new extensions::GcmJsEventRouter(profile_)); | |
| 741 #endif | |
| 742 | |
| 712 DCHECK(!delayed_task_controller_); | 743 DCHECK(!delayed_task_controller_); |
| 713 delayed_task_controller_.reset(new DelayedTaskController); | 744 delayed_task_controller_.reset(new DelayedTaskController); |
| 714 | 745 |
| 715 // Load all register apps. | 746 // Load all the registered apps. |
| 716 ReadRegisteredAppIDs(); | 747 ReadRegisteredAppIDs(); |
| 717 | 748 |
| 718 // Let the IO thread create and initialize GCMClient. | 749 // This will load the data from the gcm store and trigger the check-in if |
| 719 scoped_refptr<net::URLRequestContextGetter> url_request_context_getter = | 750 // the persisted check-in info is not found. |
| 720 profile_->GetRequestContext(); | |
| 721 content::BrowserThread::PostTask( | 751 content::BrowserThread::PostTask( |
| 722 content::BrowserThread::IO, | 752 content::BrowserThread::IO, |
| 723 FROM_HERE, | 753 FROM_HERE, |
| 724 base::Bind(&GCMProfileService::IOWorker::Initialize, | 754 base::Bind(&GCMProfileService::IOWorker::Load, io_worker_)); |
| 725 io_worker_, | |
| 726 gcm_client_factory_.get(), | |
| 727 profile_->GetPath().Append(chrome::kGCMStoreDirname), | |
| 728 url_request_context_getter)); | |
| 729 } | 755 } |
| 730 | 756 |
| 731 void GCMProfileService::CheckOut() { | 757 void GCMProfileService::CheckOut() { |
| 732 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | 758 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
| 733 | 759 |
| 734 DCHECK(!username_.empty()); | 760 // We still proceed with the check-out logic even if the check-in is not |
| 761 // initiated in the current session. This will make sure that all the | |
| 762 // persisted data written previously will get purged. | |
| 735 username_.clear(); | 763 username_.clear(); |
| 736 | 764 |
| 737 // Remove persisted data from app's state store. | 765 // Remove persisted data from app's state store. |
| 738 for (RegistrationInfoMap::const_iterator iter = | 766 for (RegistrationInfoMap::const_iterator iter = |
| 739 registration_info_map_.begin(); | 767 registration_info_map_.begin(); |
| 740 iter != registration_info_map_.end(); ++iter) { | 768 iter != registration_info_map_.end(); ++iter) { |
| 741 DeleteRegistrationInfo(iter->first); | 769 DeleteRegistrationInfo(iter->first); |
| 742 } | 770 } |
| 743 | 771 |
| 744 // Remove persisted data from prefs store. | 772 // Remove persisted data from prefs store. |
| 745 profile_->GetPrefs()->ClearPref(prefs::kGCMChannelEnabled); | |
| 746 profile_->GetPrefs()->ClearPref(prefs::kGCMRegisteredAppIDs); | 773 profile_->GetPrefs()->ClearPref(prefs::kGCMRegisteredAppIDs); |
| 747 | 774 |
| 748 gcm_client_ready_ = false; | 775 gcm_client_ready_ = false; |
| 749 delayed_task_controller_.reset(); | 776 delayed_task_controller_.reset(); |
| 750 register_callbacks_.clear(); | 777 register_callbacks_.clear(); |
| 751 send_callbacks_.clear(); | 778 send_callbacks_.clear(); |
| 752 registration_info_map_.clear(); | 779 registration_info_map_.clear(); |
| 753 | 780 |
| 754 content::BrowserThread::PostTask( | 781 content::BrowserThread::PostTask( |
| 755 content::BrowserThread::IO, | 782 content::BrowserThread::IO, |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 881 GCMClient::Result result) { | 908 GCMClient::Result result) { |
| 882 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | 909 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
| 883 | 910 |
| 884 // Drop the event if signed out. | 911 // Drop the event if signed out. |
| 885 if (username_.empty()) | 912 if (username_.empty()) |
| 886 return; | 913 return; |
| 887 | 914 |
| 888 GetEventRouter(app_id)->OnSendError(app_id, message_id, result); | 915 GetEventRouter(app_id)->OnSendError(app_id, message_id, result); |
| 889 } | 916 } |
| 890 | 917 |
| 891 void GCMProfileService::FinishInitializationOnUI(bool ready) { | 918 void GCMProfileService::FinishInitializationOnUI() { |
| 892 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | 919 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
| 893 | 920 |
| 894 gcm_client_ready_ = ready; | 921 // Initiates the check-in if the rollout signal indicates yes. |
| 895 if (gcm_client_ready_) | 922 if (GetGCMEnabledState(profile_) == ALWAYS_ENABLED) |
| 896 delayed_task_controller_->SetGCMReady(); | 923 EnsureLoaded(); |
| 897 } | 924 } |
| 898 | 925 |
| 899 void GCMProfileService::GCMClientReady() { | 926 void GCMProfileService::GCMClientReady() { |
| 900 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | 927 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
| 901 | 928 |
| 902 if (gcm_client_ready_) | 929 if (gcm_client_ready_) |
| 903 return; | 930 return; |
| 904 gcm_client_ready_ = true; | 931 gcm_client_ready_ = true; |
| 905 | 932 |
| 906 delayed_task_controller_->SetGCMReady(); | 933 delayed_task_controller_->SetGCMReady(); |
| (...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1028 | 1055 |
| 1029 return true; | 1056 return true; |
| 1030 } | 1057 } |
| 1031 | 1058 |
| 1032 // static | 1059 // static |
| 1033 const char* GCMProfileService::GetPersistentRegisterKeyForTesting() { | 1060 const char* GCMProfileService::GetPersistentRegisterKeyForTesting() { |
| 1034 return kRegistrationKey; | 1061 return kRegistrationKey; |
| 1035 } | 1062 } |
| 1036 | 1063 |
| 1037 } // namespace gcm | 1064 } // namespace gcm |
| OLD | NEW |