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