OLD | NEW |
---|---|
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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_driver.h" | 5 #include "chrome/browser/services/gcm/gcm_driver.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <utility> | 8 #include <utility> |
9 | 9 |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
(...skipping 364 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
375 stats = gcm_client_->GetStatistics(); | 375 stats = gcm_client_->GetStatistics(); |
376 stats.gcm_client_created = true; | 376 stats.gcm_client_created = true; |
377 } | 377 } |
378 | 378 |
379 content::BrowserThread::PostTask( | 379 content::BrowserThread::PostTask( |
380 content::BrowserThread::UI, | 380 content::BrowserThread::UI, |
381 FROM_HERE, | 381 FROM_HERE, |
382 base::Bind(&GCMDriver::GetGCMStatisticsFinished, service_, stats)); | 382 base::Bind(&GCMDriver::GetGCMStatisticsFinished, service_, stats)); |
383 } | 383 } |
384 | 384 |
385 GCMDriver::GCMDriver(scoped_ptr<IdentityProvider> identity_provider) | 385 GCMDriver::GCMDriver( |
386 : identity_provider_(identity_provider.Pass()), | 386 scoped_ptr<GCMClientFactory> gcm_client_factory, |
387 scoped_ptr<IdentityProvider> identity_provider, | |
388 const base::FilePath& store_path, | |
389 const scoped_refptr<net::URLRequestContextGetter>& request_context) | |
390 : gcm_enabled_(true), | |
387 gcm_client_ready_(false), | 391 gcm_client_ready_(false), |
392 identity_provider_(identity_provider.Pass()), | |
388 weak_ptr_factory_(this) { | 393 weak_ptr_factory_(this) { |
389 } | |
390 | |
391 GCMDriver::~GCMDriver() { | |
392 } | |
393 | |
394 void GCMDriver::Initialize(scoped_ptr<GCMClientFactory> gcm_client_factory) { | |
395 // Get the list of available accounts. | 394 // Get the list of available accounts. |
396 std::vector<std::string> account_ids; | 395 std::vector<std::string> account_ids; |
397 #if !defined(OS_ANDROID) | 396 #if !defined(OS_ANDROID) |
398 account_ids = identity_provider_->GetTokenService()->GetAccounts(); | 397 account_ids = identity_provider_->GetTokenService()->GetAccounts(); |
399 #endif | 398 #endif |
400 | 399 |
401 // Create and initialize the GCMClient. Note that this does not initiate the | 400 // Create and initialize the GCMClient. Note that this does not initiate the |
402 // GCM check-in. | 401 // GCM check-in. |
403 DCHECK(!io_worker_); | 402 DCHECK(!io_worker_); |
404 io_worker_.reset(new IOWorker()); | 403 io_worker_.reset(new IOWorker()); |
405 content::BrowserThread::PostTask( | 404 content::BrowserThread::PostTask( |
406 content::BrowserThread::IO, | 405 content::BrowserThread::IO, |
407 FROM_HERE, | 406 FROM_HERE, |
408 base::Bind(&GCMDriver::IOWorker::Initialize, | 407 base::Bind(&GCMDriver::IOWorker::Initialize, |
409 base::Unretained(io_worker_.get()), | 408 base::Unretained(io_worker_.get()), |
410 base::Passed(&gcm_client_factory), | 409 base::Passed(&gcm_client_factory), |
411 GetStorePath(), | 410 store_path, |
412 account_ids, | 411 account_ids, |
413 GetURLRequestContextGetter())); | 412 request_context)); |
414 | |
415 // Start the GCM service if the rollout signal indicates yes. | |
416 if (ShouldStartAutomatically()) | |
417 EnsureStarted(); | |
418 | 413 |
419 identity_provider_->AddObserver(this); | 414 identity_provider_->AddObserver(this); |
420 } | 415 } |
421 | 416 |
422 void GCMDriver::Start() { | 417 GCMDriver::GCMDriver() |
418 : gcm_enabled_(true), | |
419 gcm_client_ready_(false), | |
420 weak_ptr_factory_(this) { | |
421 } | |
422 | |
423 GCMDriver::~GCMDriver() { | |
424 } | |
425 | |
426 void GCMDriver::Enable() { | |
423 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | 427 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
424 | 428 |
429 if (gcm_enabled_) | |
430 return; | |
431 gcm_enabled_ = true; | |
432 | |
425 EnsureStarted(); | 433 EnsureStarted(); |
426 } | 434 } |
427 | 435 |
436 void GCMDriver::Disable() { | |
437 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | |
438 | |
439 if (!gcm_enabled_) | |
440 return; | |
441 gcm_enabled_ = false; | |
442 | |
443 Stop(); | |
444 } | |
445 | |
428 void GCMDriver::Stop() { | 446 void GCMDriver::Stop() { |
429 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | 447 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
430 | 448 |
431 // No need to stop GCM service if not started yet. | 449 // No need to stop GCM service if not started yet. |
432 if (account_id_.empty()) | 450 if (account_id_.empty()) |
433 return; | 451 return; |
434 | 452 |
435 RemoveCachedData(); | 453 RemoveCachedData(); |
436 | 454 |
437 content::BrowserThread::PostTask( | 455 content::BrowserThread::PostTask( |
438 content::BrowserThread::IO, | 456 content::BrowserThread::IO, |
439 FROM_HERE, | 457 FROM_HERE, |
440 base::Bind(&GCMDriver::IOWorker::Stop, | 458 base::Bind(&GCMDriver::IOWorker::Stop, |
441 base::Unretained(io_worker_.get()))); | 459 base::Unretained(io_worker_.get()))); |
442 } | 460 } |
443 | 461 |
444 void GCMDriver::ShutdownService() { | 462 void GCMDriver::Shutdown() { |
445 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | 463 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
446 identity_provider_->RemoveObserver(this); | 464 identity_provider_->RemoveObserver(this); |
447 for (GCMAppHandlerMap::const_iterator iter = app_handlers_.begin(); | 465 for (GCMAppHandlerMap::const_iterator iter = app_handlers_.begin(); |
448 iter != app_handlers_.end(); ++iter) { | 466 iter != app_handlers_.end(); ++iter) { |
449 iter->second->ShutdownHandler(); | 467 iter->second->ShutdownHandler(); |
450 } | 468 } |
451 app_handlers_.clear(); | 469 app_handlers_.clear(); |
452 content::BrowserThread::DeleteSoon(content::BrowserThread::IO, | 470 content::BrowserThread::DeleteSoon(content::BrowserThread::IO, |
453 FROM_HERE, | 471 FROM_HERE, |
454 io_worker_.release()); | 472 io_worker_.release()); |
455 } | 473 } |
456 | 474 |
457 void GCMDriver::AddAppHandler(const std::string& app_id, | 475 void GCMDriver::AddAppHandler(const std::string& app_id, |
458 GCMAppHandler* handler) { | 476 GCMAppHandler* handler) { |
459 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | 477 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
460 DCHECK(!app_id.empty()); | 478 DCHECK(!app_id.empty()); |
461 DCHECK(handler); | 479 DCHECK(handler); |
462 DCHECK(app_handlers_.find(app_id) == app_handlers_.end()); | 480 DCHECK(app_handlers_.find(app_id) == app_handlers_.end()); |
463 | 481 |
464 app_handlers_[app_id] = handler; | 482 app_handlers_[app_id] = handler; |
483 | |
484 // Ensures that the GCM service is started when there is an interest. | |
485 EnsureStarted(); | |
465 } | 486 } |
466 | 487 |
467 void GCMDriver::RemoveAppHandler(const std::string& app_id) { | 488 void GCMDriver::RemoveAppHandler(const std::string& app_id) { |
468 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | 489 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
469 DCHECK(!app_id.empty()); | 490 DCHECK(!app_id.empty()); |
470 | 491 |
471 app_handlers_.erase(app_id); | 492 app_handlers_.erase(app_id); |
472 } | 493 } |
473 | 494 |
474 void GCMDriver::Register(const std::string& app_id, | 495 void GCMDriver::Register(const std::string& app_id, |
475 const std::vector<std::string>& sender_ids, | 496 const std::vector<std::string>& sender_ids, |
476 const RegisterCallback& callback) { | 497 const RegisterCallback& callback) { |
477 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | 498 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
478 DCHECK(!app_id.empty()); | 499 DCHECK(!app_id.empty()); |
479 DCHECK(!sender_ids.empty()); | 500 DCHECK(!sender_ids.empty()); |
480 DCHECK(!callback.is_null()); | 501 DCHECK(!callback.is_null()); |
481 | 502 |
482 GCMClient::Result result = EnsureAppReady(app_id); | 503 GCMClient::Result result = EnsureStarted(); |
483 if (result != GCMClient::SUCCESS) { | 504 if (result != GCMClient::SUCCESS) { |
484 callback.Run(std::string(), result); | 505 callback.Run(std::string(), result); |
485 return; | 506 return; |
486 } | 507 } |
487 | 508 |
488 // If previous un/register operation is still in progress, bail out. | 509 // If previous un/register operation is still in progress, bail out. |
489 if (IsAsyncOperationPending(app_id)) { | 510 if (IsAsyncOperationPending(app_id)) { |
490 callback.Run(std::string(), GCMClient::ASYNC_OPERATION_PENDING); | 511 callback.Run(std::string(), GCMClient::ASYNC_OPERATION_PENDING); |
491 return; | 512 return; |
492 } | 513 } |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
527 app_id, | 548 app_id, |
528 normalized_sender_ids)); | 549 normalized_sender_ids)); |
529 } | 550 } |
530 | 551 |
531 void GCMDriver::Unregister(const std::string& app_id, | 552 void GCMDriver::Unregister(const std::string& app_id, |
532 const UnregisterCallback& callback) { | 553 const UnregisterCallback& callback) { |
533 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | 554 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
534 DCHECK(!app_id.empty()); | 555 DCHECK(!app_id.empty()); |
535 DCHECK(!callback.is_null()); | 556 DCHECK(!callback.is_null()); |
536 | 557 |
537 GCMClient::Result result = EnsureAppReady(app_id); | 558 GCMClient::Result result = EnsureStarted(); |
538 if (result != GCMClient::SUCCESS) { | 559 if (result != GCMClient::SUCCESS) { |
539 callback.Run(result); | 560 callback.Run(result); |
540 return; | 561 return; |
541 } | 562 } |
542 | 563 |
543 // If previous un/register operation is still in progress, bail out. | 564 // If previous un/register operation is still in progress, bail out. |
544 if (IsAsyncOperationPending(app_id)) { | 565 if (IsAsyncOperationPending(app_id)) { |
545 callback.Run(GCMClient::ASYNC_OPERATION_PENDING); | 566 callback.Run(GCMClient::ASYNC_OPERATION_PENDING); |
546 return; | 567 return; |
547 } | 568 } |
(...skipping 27 matching lines...) Expand all Loading... | |
575 | 596 |
576 void GCMDriver::Send(const std::string& app_id, | 597 void GCMDriver::Send(const std::string& app_id, |
577 const std::string& receiver_id, | 598 const std::string& receiver_id, |
578 const GCMClient::OutgoingMessage& message, | 599 const GCMClient::OutgoingMessage& message, |
579 const SendCallback& callback) { | 600 const SendCallback& callback) { |
580 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | 601 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
581 DCHECK(!app_id.empty()); | 602 DCHECK(!app_id.empty()); |
582 DCHECK(!receiver_id.empty()); | 603 DCHECK(!receiver_id.empty()); |
583 DCHECK(!callback.is_null()); | 604 DCHECK(!callback.is_null()); |
584 | 605 |
585 GCMClient::Result result = EnsureAppReady(app_id); | 606 GCMClient::Result result = EnsureStarted(); |
586 if (result != GCMClient::SUCCESS) { | 607 if (result != GCMClient::SUCCESS) { |
587 callback.Run(std::string(), result); | 608 callback.Run(std::string(), result); |
588 return; | 609 return; |
589 } | 610 } |
590 | 611 |
591 // If the message with send ID is still in progress, bail out. | 612 // If the message with send ID is still in progress, bail out. |
592 std::pair<std::string, std::string> key(app_id, message.id); | 613 std::pair<std::string, std::string> key(app_id, message.id); |
593 if (send_callbacks_.find(key) != send_callbacks_.end()) { | 614 if (send_callbacks_.find(key) != send_callbacks_.end()) { |
594 callback.Run(message.id, GCMClient::INVALID_PARAMETER); | 615 callback.Run(message.id, GCMClient::INVALID_PARAMETER); |
595 return; | 616 return; |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
660 request_gcm_statistics_callback_ = callback; | 681 request_gcm_statistics_callback_ = callback; |
661 content::BrowserThread::PostTask( | 682 content::BrowserThread::PostTask( |
662 content::BrowserThread::IO, | 683 content::BrowserThread::IO, |
663 FROM_HERE, | 684 FROM_HERE, |
664 base::Bind(&GCMDriver::IOWorker::SetGCMRecording, | 685 base::Bind(&GCMDriver::IOWorker::SetGCMRecording, |
665 base::Unretained(io_worker_.get()), | 686 base::Unretained(io_worker_.get()), |
666 recording)); | 687 recording)); |
667 } | 688 } |
668 | 689 |
669 void GCMDriver::OnActiveAccountLogin() { | 690 void GCMDriver::OnActiveAccountLogin() { |
670 if (ShouldStartAutomatically()) | 691 EnsureStarted(); |
671 EnsureStarted(); | |
672 } | 692 } |
673 | 693 |
674 void GCMDriver::OnActiveAccountLogout() { | 694 void GCMDriver::OnActiveAccountLogout() { |
675 CheckOut(); | 695 CheckOut(); |
676 } | 696 } |
677 | 697 |
678 void GCMDriver::EnsureStarted() { | 698 GCMClient::Result GCMDriver::EnsureStarted() { |
679 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | 699 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
700 | |
701 // Is GCM enabled? | |
fgorski
2014/05/19 20:37:09
nit: comment is redundant
jianli
2014/05/19 23:03:48
Done.
| |
702 if (!gcm_enabled_) | |
703 return GCMClient::GCM_DISABLED; | |
704 | |
705 // Can we get an account ID from the identity provider? | |
fgorski
2014/05/19 20:37:09
nit: Comment should be:
Is the user signed in?
jianli
2014/05/19 23:03:48
Done.
| |
680 const std::string account_id = identity_provider_->GetActiveAccountId(); | 706 const std::string account_id = identity_provider_->GetActiveAccountId(); |
681 if (account_id.empty()) | 707 if (account_id.empty()) |
682 return; | 708 return GCMClient::NOT_SIGNED_IN; |
683 | 709 |
684 // CheckIn could be called more than once when: | 710 // CheckIn could be called more than once when: |
685 // 1) The password changes. | 711 // 1) The password changes. |
686 // 2) Register/send function calls it to ensure CheckIn is done. | 712 // 2) Register/send function calls it to ensure CheckIn is done. |
687 if (account_id_ == account_id) | 713 if (account_id_ == account_id) |
688 return; | 714 return GCMClient::SUCCESS; |
689 account_id_ = account_id; | 715 account_id_ = account_id; |
690 | 716 |
691 DCHECK(!delayed_task_controller_); | 717 DCHECK(!delayed_task_controller_); |
692 delayed_task_controller_.reset(new DelayedTaskController); | 718 delayed_task_controller_.reset(new DelayedTaskController); |
693 | 719 |
694 // Note that we need to pass weak pointer again since the existing weak | 720 // Note that we need to pass weak pointer again since the existing weak |
695 // pointer in IOWorker might have been invalidated when check-out occurs. | 721 // pointer in IOWorker might have been invalidated when check-out occurs. |
696 content::BrowserThread::PostTask( | 722 content::BrowserThread::PostTask( |
697 content::BrowserThread::IO, | 723 content::BrowserThread::IO, |
698 FROM_HERE, | 724 FROM_HERE, |
699 base::Bind(&GCMDriver::IOWorker::Start, | 725 base::Bind(&GCMDriver::IOWorker::Start, |
700 base::Unretained(io_worker_.get()), | 726 base::Unretained(io_worker_.get()), |
701 weak_ptr_factory_.GetWeakPtr())); | 727 weak_ptr_factory_.GetWeakPtr())); |
728 | |
729 return GCMClient::SUCCESS; | |
702 } | 730 } |
703 | 731 |
704 void GCMDriver::RemoveCachedData() { | 732 void GCMDriver::RemoveCachedData() { |
705 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | 733 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
706 // Remove all the queued tasks since they no longer make sense after | 734 // Remove all the queued tasks since they no longer make sense after |
707 // GCM service is stopped. | 735 // GCM service is stopped. |
708 weak_ptr_factory_.InvalidateWeakPtrs(); | 736 weak_ptr_factory_.InvalidateWeakPtrs(); |
709 | 737 |
710 account_id_.clear(); | 738 account_id_.clear(); |
711 gcm_client_ready_ = false; | 739 gcm_client_ready_ = false; |
(...skipping 11 matching lines...) Expand all Loading... | |
723 | 751 |
724 RemoveCachedData(); | 752 RemoveCachedData(); |
725 | 753 |
726 content::BrowserThread::PostTask( | 754 content::BrowserThread::PostTask( |
727 content::BrowserThread::IO, | 755 content::BrowserThread::IO, |
728 FROM_HERE, | 756 FROM_HERE, |
729 base::Bind(&GCMDriver::IOWorker::CheckOut, | 757 base::Bind(&GCMDriver::IOWorker::CheckOut, |
730 base::Unretained(io_worker_.get()))); | 758 base::Unretained(io_worker_.get()))); |
731 } | 759 } |
732 | 760 |
733 GCMClient::Result GCMDriver::EnsureAppReady(const std::string& app_id) { | |
734 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | |
735 | |
736 // Starts the service if not yet. | |
737 EnsureStarted(); | |
738 | |
739 // If the service cannot be started, bail out. | |
740 if (account_id_.empty()) | |
741 return GCMClient::NOT_SIGNED_IN; | |
742 | |
743 return GCMClient::SUCCESS; | |
744 } | |
745 | |
746 bool GCMDriver::IsAsyncOperationPending(const std::string& app_id) const { | 761 bool GCMDriver::IsAsyncOperationPending(const std::string& app_id) const { |
747 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | 762 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
748 return register_callbacks_.find(app_id) != register_callbacks_.end() || | 763 return register_callbacks_.find(app_id) != register_callbacks_.end() || |
749 unregister_callbacks_.find(app_id) != unregister_callbacks_.end(); | 764 unregister_callbacks_.find(app_id) != unregister_callbacks_.end(); |
750 } | 765 } |
751 | 766 |
752 void GCMDriver::RegisterFinished(const std::string& app_id, | 767 void GCMDriver::RegisterFinished(const std::string& app_id, |
753 const std::string& registration_id, | 768 const std::string& registration_id, |
754 GCMClient::Result result) { | 769 GCMClient::Result result) { |
755 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | 770 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
852 void GCMDriver::GetGCMStatisticsFinished(GCMClient::GCMStatistics stats) { | 867 void GCMDriver::GetGCMStatisticsFinished(GCMClient::GCMStatistics stats) { |
853 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | 868 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
854 | 869 |
855 // Normally request_gcm_statistics_callback_ would not be null. | 870 // Normally request_gcm_statistics_callback_ would not be null. |
856 if (!request_gcm_statistics_callback_.is_null()) | 871 if (!request_gcm_statistics_callback_.is_null()) |
857 request_gcm_statistics_callback_.Run(stats); | 872 request_gcm_statistics_callback_.Run(stats); |
858 else | 873 else |
859 LOG(WARNING) << "request_gcm_statistics_callback_ is NULL."; | 874 LOG(WARNING) << "request_gcm_statistics_callback_ is NULL."; |
860 } | 875 } |
861 | 876 |
877 std::string GCMDriver::SignedInUserName() const { | |
878 if (IsStarted()) | |
879 return identity_provider_->GetActiveUsername(); | |
880 return std::string(); | |
881 } | |
882 | |
862 } // namespace gcm | 883 } // namespace gcm |
OLD | NEW |