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 <string> | 7 #include <string> |
| 8 #include <vector> | 8 #include <vector> |
| 9 | 9 |
| 10 #include "base/base64.h" | 10 #include "base/base64.h" |
| (...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 229 for (size_t i = 0; i < task_queue->tasks.size(); ++i) | 229 for (size_t i = 0; i < task_queue->tasks.size(); ++i) |
| 230 task_queue->tasks[i].Run(); | 230 task_queue->tasks[i].Run(); |
| 231 task_queue->tasks.clear(); | 231 task_queue->tasks.clear(); |
| 232 } | 232 } |
| 233 | 233 |
| 234 class GCMProfileService::IOWorker | 234 class GCMProfileService::IOWorker |
| 235 : public GCMClient::Delegate, | 235 : public GCMClient::Delegate, |
| 236 public base::RefCountedThreadSafe<GCMProfileService::IOWorker>{ | 236 public base::RefCountedThreadSafe<GCMProfileService::IOWorker>{ |
| 237 public: | 237 public: |
| 238 // Called on UI thread. | 238 // Called on UI thread. |
| 239 explicit IOWorker(const base::WeakPtr<GCMProfileService>& service); | 239 explicit IOWorker(const base::WeakPtr<GCMProfileService>& service); |
|
Nicolas Zea
2014/02/26 02:26:37
is |service| here still necessary?
jianli
2014/02/26 19:04:25
Yes, it is not needed. Removed.
| |
| 240 | 240 |
| 241 // Overridden from GCMClient::Delegate: | 241 // Overridden from GCMClient::Delegate: |
| 242 // Called on IO thread. | 242 // Called on IO thread. |
| 243 virtual void OnRegisterFinished(const std::string& app_id, | 243 virtual void OnRegisterFinished(const std::string& app_id, |
| 244 const std::string& registration_id, | 244 const std::string& registration_id, |
| 245 GCMClient::Result result) OVERRIDE; | 245 GCMClient::Result result) OVERRIDE; |
| 246 virtual void OnUnregisterFinished(const std::string& app_id, | 246 virtual void OnUnregisterFinished(const std::string& app_id, |
| 247 bool success) OVERRIDE; | 247 bool success) OVERRIDE; |
| 248 virtual void OnSendFinished(const std::string& app_id, | 248 virtual void OnSendFinished(const std::string& app_id, |
| 249 const std::string& message_id, | 249 const std::string& message_id, |
| 250 GCMClient::Result result) OVERRIDE; | 250 GCMClient::Result result) OVERRIDE; |
| 251 virtual void OnMessageReceived( | 251 virtual void OnMessageReceived( |
| 252 const std::string& app_id, | 252 const std::string& app_id, |
| 253 const GCMClient::IncomingMessage& message) OVERRIDE; | 253 const GCMClient::IncomingMessage& message) OVERRIDE; |
| 254 virtual void OnMessagesDeleted(const std::string& app_id) OVERRIDE; | 254 virtual void OnMessagesDeleted(const std::string& app_id) OVERRIDE; |
| 255 virtual void OnMessageSendError(const std::string& app_id, | 255 virtual void OnMessageSendError(const std::string& app_id, |
| 256 const std::string& message_id, | 256 const std::string& message_id, |
| 257 GCMClient::Result result) OVERRIDE; | 257 GCMClient::Result result) OVERRIDE; |
| 258 virtual void OnGCMReady() OVERRIDE; | 258 virtual void OnGCMReady() OVERRIDE; |
| 259 | 259 |
| 260 // Called on IO thread. | 260 // Called on IO thread. |
| 261 void Initialize(GCMClientFactory* gcm_client_factory, | 261 void Initialize(scoped_ptr<GCMClientFactory> gcm_client_factory, |
| 262 const base::FilePath& store_path, | 262 const base::FilePath& store_path, |
| 263 const std::vector<std::string>& account_ids, | 263 const std::vector<std::string>& account_ids, |
| 264 const scoped_refptr<net::URLRequestContextGetter>& | 264 const scoped_refptr<net::URLRequestContextGetter>& |
| 265 url_request_context_getter); | 265 url_request_context_getter); |
| 266 void Reset(); | 266 void Reset(); |
| 267 void Load(const base::WeakPtr<GCMProfileService>& service); | |
| 267 void CheckOut(); | 268 void CheckOut(); |
| 268 void Register(const std::string& app_id, | 269 void Register(const std::string& app_id, |
| 269 const std::vector<std::string>& sender_ids, | 270 const std::vector<std::string>& sender_ids, |
| 270 const std::string& cert); | 271 const std::string& cert); |
| 271 void Unregister(const std::string& app_id); | 272 void Unregister(const std::string& app_id); |
| 272 void Send(const std::string& app_id, | 273 void Send(const std::string& app_id, |
| 273 const std::string& receiver_id, | 274 const std::string& receiver_id, |
| 274 const GCMClient::OutgoingMessage& message); | 275 const GCMClient::OutgoingMessage& message); |
| 275 | 276 |
| 277 // For testing purpose. Can be called from UI thread. Use with care. | |
| 278 GCMClient* gcm_client_for_testing() const { return gcm_client_.get(); } | |
| 279 | |
| 276 private: | 280 private: |
| 277 friend class base::RefCountedThreadSafe<IOWorker>; | 281 friend class base::RefCountedThreadSafe<IOWorker>; |
| 278 virtual ~IOWorker(); | 282 virtual ~IOWorker(); |
| 279 | 283 |
| 280 const base::WeakPtr<GCMProfileService> service_; | 284 base::WeakPtr<GCMProfileService> service_; |
| 281 | 285 |
| 282 scoped_ptr<GCMClient> gcm_client_; | 286 scoped_ptr<GCMClient> gcm_client_; |
| 283 }; | 287 }; |
| 284 | 288 |
| 285 GCMProfileService::IOWorker::IOWorker( | 289 GCMProfileService::IOWorker::IOWorker( |
| 286 const base::WeakPtr<GCMProfileService>& service) | 290 const base::WeakPtr<GCMProfileService>& service) |
| 287 : service_(service) { | 291 : service_(service) { |
| 288 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | 292 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
| 289 } | 293 } |
| 290 | 294 |
| 291 GCMProfileService::IOWorker::~IOWorker() { | 295 GCMProfileService::IOWorker::~IOWorker() { |
| 292 } | 296 } |
| 293 | 297 |
| 294 void GCMProfileService::IOWorker::Initialize( | 298 void GCMProfileService::IOWorker::Initialize( |
| 295 GCMClientFactory* gcm_client_factory, | 299 scoped_ptr<GCMClientFactory> gcm_client_factory, |
| 296 const base::FilePath& store_path, | 300 const base::FilePath& store_path, |
| 297 const std::vector<std::string>& account_ids, | 301 const std::vector<std::string>& account_ids, |
| 298 const scoped_refptr<net::URLRequestContextGetter>& | 302 const scoped_refptr<net::URLRequestContextGetter>& |
| 299 url_request_context_getter) { | 303 url_request_context_getter) { |
| 300 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); | 304 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); |
| 301 | 305 |
| 302 gcm_client_ = gcm_client_factory->BuildInstance().Pass(); | 306 gcm_client_ = gcm_client_factory->BuildInstance().Pass(); |
| 303 | 307 |
| 304 checkin_proto::ChromeBuildProto chrome_build_proto; | 308 checkin_proto::ChromeBuildProto chrome_build_proto; |
| 305 chrome_build_proto.set_platform(GetPlatform()); | 309 chrome_build_proto.set_platform(GetPlatform()); |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 316 gcm_client_->Initialize(chrome_build_proto, | 320 gcm_client_->Initialize(chrome_build_proto, |
| 317 store_path, | 321 store_path, |
| 318 account_ids, | 322 account_ids, |
| 319 blocking_task_runner, | 323 blocking_task_runner, |
| 320 url_request_context_getter, | 324 url_request_context_getter, |
| 321 this); | 325 this); |
| 322 | 326 |
| 323 content::BrowserThread::PostTask( | 327 content::BrowserThread::PostTask( |
| 324 content::BrowserThread::UI, | 328 content::BrowserThread::UI, |
| 325 FROM_HERE, | 329 FROM_HERE, |
| 326 base::Bind(&GCMProfileService::FinishInitializationOnUI, | 330 base::Bind(&GCMProfileService::FinishInitializationOnUI, service_)); |
| 327 service_, | |
| 328 gcm_client_->IsReady())); | |
| 329 } | 331 } |
| 330 | 332 |
| 331 void GCMProfileService::IOWorker::Reset() { | 333 void GCMProfileService::IOWorker::Reset() { |
| 332 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); | 334 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); |
| 333 | 335 |
| 334 // GCMClient instance must be destroyed from the same thread where it was | 336 // GCMClient instance must be destroyed from the same thread where it was |
| 335 // created. | 337 // created. |
| 336 gcm_client_.reset(); | 338 gcm_client_.reset(); |
| 337 } | 339 } |
| 338 | 340 |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 416 } | 418 } |
| 417 | 419 |
| 418 void GCMProfileService::IOWorker::OnGCMReady() { | 420 void GCMProfileService::IOWorker::OnGCMReady() { |
| 419 content::BrowserThread::PostTask( | 421 content::BrowserThread::PostTask( |
| 420 content::BrowserThread::UI, | 422 content::BrowserThread::UI, |
| 421 FROM_HERE, | 423 FROM_HERE, |
| 422 base::Bind(&GCMProfileService::GCMClientReady, | 424 base::Bind(&GCMProfileService::GCMClientReady, |
| 423 service_)); | 425 service_)); |
| 424 } | 426 } |
| 425 | 427 |
| 428 void GCMProfileService::IOWorker::Load( | |
| 429 const base::WeakPtr<GCMProfileService>& service) { | |
| 430 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); | |
| 431 | |
| 432 service_ = service; | |
| 433 gcm_client_->Load(); | |
| 434 } | |
| 435 | |
| 426 void GCMProfileService::IOWorker::CheckOut() { | 436 void GCMProfileService::IOWorker::CheckOut() { |
| 427 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); | 437 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); |
| 428 | 438 |
| 429 gcm_client_->CheckOut(); | 439 gcm_client_->CheckOut(); |
| 430 gcm_client_.reset(); | 440 |
| 441 // Note that we still need to keep GCMClient instance alive since the profile | |
| 442 // might be signed in again. | |
| 431 } | 443 } |
| 432 | 444 |
| 433 void GCMProfileService::IOWorker::Register( | 445 void GCMProfileService::IOWorker::Register( |
| 434 const std::string& app_id, | 446 const std::string& app_id, |
| 435 const std::vector<std::string>& sender_ids, | 447 const std::vector<std::string>& sender_ids, |
| 436 const std::string& cert) { | 448 const std::string& cert) { |
| 437 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); | 449 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); |
| 438 | 450 |
| 439 gcm_client_->Register(app_id, cert, sender_ids); | 451 gcm_client_->Register(app_id, cert, sender_ids); |
| 440 } | 452 } |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 457 GCMProfileService::RegistrationInfo::RegistrationInfo() { | 469 GCMProfileService::RegistrationInfo::RegistrationInfo() { |
| 458 } | 470 } |
| 459 | 471 |
| 460 GCMProfileService::RegistrationInfo::~RegistrationInfo() { | 472 GCMProfileService::RegistrationInfo::~RegistrationInfo() { |
| 461 } | 473 } |
| 462 | 474 |
| 463 bool GCMProfileService::RegistrationInfo::IsValid() const { | 475 bool GCMProfileService::RegistrationInfo::IsValid() const { |
| 464 return !sender_ids.empty() && !registration_id.empty(); | 476 return !sender_ids.empty() && !registration_id.empty(); |
| 465 } | 477 } |
| 466 | 478 |
| 467 bool GCMProfileService::enable_gcm_for_testing_ = false; | 479 // static |
| 480 GCMProfileService::GCMEnabledState GCMProfileService::GetGCMEnabledState( | |
| 481 Profile* profile) { | |
| 482 const base::Value* gcm_enabled_value = | |
| 483 profile->GetPrefs()->GetUserPrefValue(prefs::kGCMChannelEnabled); | |
| 484 if (!gcm_enabled_value) | |
| 485 return ENABLED_FOR_APPS; | |
| 468 | 486 |
| 469 // static | 487 bool gcm_enabled = false; |
| 470 bool GCMProfileService::IsGCMEnabled(Profile* profile) { | 488 if (!gcm_enabled_value->GetAsBoolean(&gcm_enabled)) |
| 471 // GCM is not enabled in incognito mode. | 489 return ENABLED_FOR_APPS; |
| 472 if (profile->IsOffTheRecord()) | |
| 473 return false; | |
| 474 | 490 |
| 475 if (enable_gcm_for_testing_) | 491 return gcm_enabled ? ALWAYS_ENABLED : ALWAYS_DISABLED; |
| 476 return true; | |
| 477 | |
| 478 return profile->GetPrefs()->GetBoolean(prefs::kGCMChannelEnabled); | |
| 479 } | 492 } |
| 480 | 493 |
| 481 // static | 494 // static |
| 482 void GCMProfileService::RegisterProfilePrefs( | 495 void GCMProfileService::RegisterProfilePrefs( |
| 483 user_prefs::PrefRegistrySyncable* registry) { | 496 user_prefs::PrefRegistrySyncable* registry) { |
| 484 // GCM support is only enabled by default for Canary/Dev/Custom builds. | 497 // GCM support is only enabled by default for Canary/Dev/Custom builds. |
| 485 chrome::VersionInfo::Channel channel = chrome::VersionInfo::GetChannel(); | 498 chrome::VersionInfo::Channel channel = chrome::VersionInfo::GetChannel(); |
| 486 bool on_by_default = false; | 499 bool on_by_default = false; |
| 487 if (channel == chrome::VersionInfo::CHANNEL_UNKNOWN || | 500 if (channel == chrome::VersionInfo::CHANNEL_UNKNOWN || |
| 488 channel == chrome::VersionInfo::CHANNEL_CANARY || | 501 channel == chrome::VersionInfo::CHANNEL_CANARY || |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 504 testing_delegate_(NULL), | 517 testing_delegate_(NULL), |
| 505 weak_ptr_factory_(this) { | 518 weak_ptr_factory_(this) { |
| 506 DCHECK(!profile->IsOffTheRecord()); | 519 DCHECK(!profile->IsOffTheRecord()); |
| 507 } | 520 } |
| 508 | 521 |
| 509 GCMProfileService::~GCMProfileService() { | 522 GCMProfileService::~GCMProfileService() { |
| 510 } | 523 } |
| 511 | 524 |
| 512 void GCMProfileService::Initialize( | 525 void GCMProfileService::Initialize( |
| 513 scoped_ptr<GCMClientFactory> gcm_client_factory) { | 526 scoped_ptr<GCMClientFactory> gcm_client_factory) { |
| 514 gcm_client_factory_ = gcm_client_factory.Pass(); | |
| 515 | |
| 516 // This has to be done first since CheckIn depends on it. | |
| 517 io_worker_ = new IOWorker(weak_ptr_factory_.GetWeakPtr()); | |
| 518 | |
| 519 #if !defined(OS_ANDROID) | |
| 520 js_event_router_.reset(new extensions::GcmJsEventRouter(profile_)); | |
| 521 #endif | |
| 522 | |
| 523 registrar_.Add(this, | 527 registrar_.Add(this, |
| 524 chrome::NOTIFICATION_GOOGLE_SIGNIN_SUCCESSFUL, | 528 chrome::NOTIFICATION_GOOGLE_SIGNIN_SUCCESSFUL, |
| 525 content::Source<Profile>(profile_)); | 529 content::Source<Profile>(profile_)); |
| 526 registrar_.Add(this, | 530 registrar_.Add(this, |
| 527 chrome::NOTIFICATION_GOOGLE_SIGNED_OUT, | 531 chrome::NOTIFICATION_GOOGLE_SIGNED_OUT, |
| 528 content::Source<Profile>(profile_)); | 532 content::Source<Profile>(profile_)); |
| 529 registrar_.Add(this, | 533 registrar_.Add(this, |
| 530 chrome::NOTIFICATION_PROFILE_DESTROYED, | 534 chrome::NOTIFICATION_PROFILE_DESTROYED, |
| 531 content::Source<Profile>(profile_)); | 535 content::Source<Profile>(profile_)); |
| 532 // TODO(jianli): move extension specific logic out of GCMProfileService. | 536 // TODO(jianli): move extension specific logic out of GCMProfileService. |
| 533 registrar_.Add(this, | 537 registrar_.Add(this, |
| 534 chrome:: NOTIFICATION_EXTENSION_UNINSTALLED, | 538 chrome:: NOTIFICATION_EXTENSION_UNINSTALLED, |
| 535 content::Source<Profile>(profile_)); | 539 content::Source<Profile>(profile_)); |
| 536 | 540 |
| 537 // In case that the profile has been signed in before GCMProfileService is | 541 // Get the list of available accounts. |
| 538 // created. | 542 std::vector<std::string> account_ids; |
| 539 SigninManagerBase* manager = SigninManagerFactory::GetForProfile(profile_); | 543 #if !defined(OS_ANDROID) |
| 540 if (manager) { | 544 account_ids = |
| 541 std::string username = manager->GetAuthenticatedUsername(); | 545 ProfileOAuth2TokenServiceFactory::GetForProfile(profile_)->GetAccounts(); |
| 542 if (!username.empty()) | 546 #endif |
| 543 CheckIn(username); | 547 |
| 544 } | 548 // Create and initialize the GCMClient. Note that this does not initiate the |
| 549 // GCM check-in. | |
| 550 io_worker_ = new IOWorker(weak_ptr_factory_.GetWeakPtr()); | |
| 551 scoped_refptr<net::URLRequestContextGetter> url_request_context_getter = | |
| 552 profile_->GetRequestContext(); | |
| 553 content::BrowserThread::PostTask( | |
| 554 content::BrowserThread::IO, | |
| 555 FROM_HERE, | |
| 556 base::Bind(&GCMProfileService::IOWorker::Initialize, | |
| 557 io_worker_, | |
| 558 base::Passed(&gcm_client_factory), | |
| 559 profile_->GetPath().Append(chrome::kGCMStoreDirname), | |
| 560 account_ids, | |
| 561 url_request_context_getter)); | |
| 545 } | 562 } |
| 546 | 563 |
| 547 void GCMProfileService::Register(const std::string& app_id, | 564 void GCMProfileService::Register(const std::string& app_id, |
| 548 const std::vector<std::string>& sender_ids, | 565 const std::vector<std::string>& sender_ids, |
| 549 const std::string& cert, | 566 const std::string& cert, |
| 550 RegisterCallback callback) { | 567 RegisterCallback callback) { |
| 551 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | 568 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
| 552 DCHECK(!app_id.empty() && !sender_ids.empty() && !callback.is_null()); | 569 DCHECK(!app_id.empty() && !sender_ids.empty() && !callback.is_null()); |
| 553 | 570 |
| 571 // Ensure that check-in has been done. | |
| 572 EnsureLoaded(); | |
| 573 | |
| 554 // If the profile was not signed in, bail out. | 574 // If the profile was not signed in, bail out. |
| 555 if (username_.empty()) { | 575 if (username_.empty()) { |
| 556 callback.Run(std::string(), GCMClient::NOT_SIGNED_IN); | 576 callback.Run(std::string(), GCMClient::NOT_SIGNED_IN); |
| 557 return; | 577 return; |
| 558 } | 578 } |
| 559 | 579 |
| 560 // If previous register operation is still in progress, bail out. | 580 // If previous register operation is still in progress, bail out. |
| 561 if (register_callbacks_.find(app_id) != register_callbacks_.end()) { | 581 if (register_callbacks_.find(app_id) != register_callbacks_.end()) { |
| 562 callback.Run(std::string(), GCMClient::ASYNC_OPERATION_PENDING); | 582 callback.Run(std::string(), GCMClient::ASYNC_OPERATION_PENDING); |
| 563 return; | 583 return; |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 629 cert)); | 649 cert)); |
| 630 } | 650 } |
| 631 | 651 |
| 632 void GCMProfileService::Send(const std::string& app_id, | 652 void GCMProfileService::Send(const std::string& app_id, |
| 633 const std::string& receiver_id, | 653 const std::string& receiver_id, |
| 634 const GCMClient::OutgoingMessage& message, | 654 const GCMClient::OutgoingMessage& message, |
| 635 SendCallback callback) { | 655 SendCallback callback) { |
| 636 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | 656 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
| 637 DCHECK(!app_id.empty() && !receiver_id.empty() && !callback.is_null()); | 657 DCHECK(!app_id.empty() && !receiver_id.empty() && !callback.is_null()); |
| 638 | 658 |
| 659 // Ensure that check-in has been done. | |
| 660 EnsureLoaded(); | |
| 661 | |
| 639 // If the profile was not signed in, bail out. | 662 // If the profile was not signed in, bail out. |
| 640 if (username_.empty()) { | 663 if (username_.empty()) { |
| 641 callback.Run(std::string(), GCMClient::NOT_SIGNED_IN); | 664 callback.Run(std::string(), GCMClient::NOT_SIGNED_IN); |
| 642 return; | 665 return; |
| 643 } | 666 } |
| 644 | 667 |
| 645 // If the message with send ID is still in progress, bail out. | 668 // If the message with send ID is still in progress, bail out. |
| 646 std::pair<std::string, std::string> key(app_id, message.id); | 669 std::pair<std::string, std::string> key(app_id, message.id); |
| 647 if (send_callbacks_.find(key) != send_callbacks_.end()) { | 670 if (send_callbacks_.find(key) != send_callbacks_.end()) { |
| 648 callback.Run(message.id, GCMClient::INVALID_PARAMETER); | 671 callback.Run(message.id, GCMClient::INVALID_PARAMETER); |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 673 content::BrowserThread::PostTask( | 696 content::BrowserThread::PostTask( |
| 674 content::BrowserThread::IO, | 697 content::BrowserThread::IO, |
| 675 FROM_HERE, | 698 FROM_HERE, |
| 676 base::Bind(&GCMProfileService::IOWorker::Send, | 699 base::Bind(&GCMProfileService::IOWorker::Send, |
| 677 io_worker_, | 700 io_worker_, |
| 678 app_id, | 701 app_id, |
| 679 receiver_id, | 702 receiver_id, |
| 680 message)); | 703 message)); |
| 681 } | 704 } |
| 682 | 705 |
| 706 GCMClient* GCMProfileService::GetGCMClientForTesting() const { | |
| 707 return io_worker_ ? io_worker_->gcm_client_for_testing() : NULL; | |
| 708 } | |
| 709 | |
| 683 void GCMProfileService::Observe(int type, | 710 void GCMProfileService::Observe(int type, |
| 684 const content::NotificationSource& source, | 711 const content::NotificationSource& source, |
| 685 const content::NotificationDetails& details) { | 712 const content::NotificationDetails& details) { |
| 686 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | 713 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
| 687 | 714 |
| 688 switch (type) { | 715 switch (type) { |
| 689 case chrome::NOTIFICATION_GOOGLE_SIGNIN_SUCCESSFUL: { | 716 case chrome::NOTIFICATION_GOOGLE_SIGNIN_SUCCESSFUL: { |
| 690 const GoogleServiceSigninSuccessDetails* signin_details = | 717 if (GetGCMEnabledState(profile_) == ALWAYS_ENABLED) |
| 691 content::Details<GoogleServiceSigninSuccessDetails>(details).ptr(); | 718 EnsureLoaded(); |
| 692 // This could be called multiple times when the password changed. | |
| 693 if (username_ != signin_details->username) | |
| 694 CheckIn(signin_details->username); | |
| 695 break; | 719 break; |
| 696 } | 720 } |
| 697 case chrome::NOTIFICATION_GOOGLE_SIGNED_OUT: | 721 case chrome::NOTIFICATION_GOOGLE_SIGNED_OUT: |
| 698 CheckOut(); | 722 CheckOut(); |
| 699 break; | 723 break; |
| 700 case chrome::NOTIFICATION_PROFILE_DESTROYED: | 724 case chrome::NOTIFICATION_PROFILE_DESTROYED: |
| 701 ResetGCMClient(); | 725 ResetGCMClient(); |
| 702 break; | 726 break; |
| 703 case chrome:: NOTIFICATION_EXTENSION_UNINSTALLED: { | 727 case chrome:: NOTIFICATION_EXTENSION_UNINSTALLED: |
| 704 extensions::Extension* extension = | 728 if (!username_.empty()) { |
| 705 content::Details<extensions::Extension>(details).ptr(); | 729 extensions::Extension* extension = |
| 706 Unregister(extension->id()); | 730 content::Details<extensions::Extension>(details).ptr(); |
| 731 Unregister(extension->id()); | |
| 732 } | |
| 707 break; | 733 break; |
| 708 } | |
| 709 default: | 734 default: |
| 710 NOTREACHED(); | 735 NOTREACHED(); |
| 711 } | 736 } |
| 712 } | 737 } |
| 713 | 738 |
| 714 void GCMProfileService::CheckIn(const std::string& username) { | 739 void GCMProfileService::EnsureLoaded() { |
| 715 DCHECK(!username.empty() && username_.empty()); | 740 SigninManagerBase* manager = SigninManagerFactory::GetForProfile(profile_); |
| 741 if (!manager) | |
| 742 return; | |
| 743 std::string username = manager->GetAuthenticatedUsername(); | |
| 744 if (username.empty()) | |
| 745 return; | |
| 746 | |
| 747 // CheckIn could be called more than once when: | |
| 748 // 1) The password changes. | |
| 749 // 2) Register/send function calls it to ensure CheckIn is done. | |
| 750 if (username_ == username) | |
| 751 return; | |
| 716 username_ = username; | 752 username_ = username; |
| 717 | 753 |
| 754 #if !defined(OS_ANDROID) | |
| 755 if (!js_event_router_) | |
| 756 js_event_router_.reset(new extensions::GcmJsEventRouter(profile_)); | |
| 757 #endif | |
| 758 | |
| 718 DCHECK(!delayed_task_controller_); | 759 DCHECK(!delayed_task_controller_); |
| 719 delayed_task_controller_.reset(new DelayedTaskController); | 760 delayed_task_controller_.reset(new DelayedTaskController); |
| 720 | 761 |
| 721 // Load all register apps. | 762 // Load all the registered apps. |
| 722 ReadRegisteredAppIDs(); | 763 ReadRegisteredAppIDs(); |
| 723 | 764 |
| 724 // Get the list of available accounts. | 765 // This will load the data from the gcm store and trigger the check-in if |
| 725 std::vector<std::string> account_ids; | 766 // the persisted check-in info is not found. |
| 726 #if !defined(OS_ANDROID) | 767 // Note that we need to pass weak pointer again since the existing weak |
| 727 account_ids = | 768 // pointer in IOWorker might have been invalidated when check-out occurs. |
| 728 ProfileOAuth2TokenServiceFactory::GetForProfile(profile_)->GetAccounts(); | |
| 729 #endif | |
| 730 | |
| 731 // Let the IO thread create and initialize GCMClient. | |
| 732 scoped_refptr<net::URLRequestContextGetter> url_request_context_getter = | |
| 733 profile_->GetRequestContext(); | |
| 734 content::BrowserThread::PostTask( | 769 content::BrowserThread::PostTask( |
| 735 content::BrowserThread::IO, | 770 content::BrowserThread::IO, |
| 736 FROM_HERE, | 771 FROM_HERE, |
| 737 base::Bind(&GCMProfileService::IOWorker::Initialize, | 772 base::Bind(&GCMProfileService::IOWorker::Load, |
| 738 io_worker_, | 773 io_worker_, |
| 739 gcm_client_factory_.get(), | 774 weak_ptr_factory_.GetWeakPtr())); |
| 740 profile_->GetPath().Append(chrome::kGCMStoreDirname), | |
| 741 account_ids, | |
| 742 url_request_context_getter)); | |
| 743 } | 775 } |
| 744 | 776 |
| 745 void GCMProfileService::CheckOut() { | 777 void GCMProfileService::CheckOut() { |
| 746 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | 778 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
| 747 | 779 |
| 748 DCHECK(!username_.empty()); | 780 // We still proceed with the check-out logic even if the check-in is not |
| 781 // initiated in the current session. This will make sure that all the | |
| 782 // persisted data written previously will get purged. | |
| 749 username_.clear(); | 783 username_.clear(); |
| 750 | 784 |
| 785 // Remove all the queued tasks since they no longer make sense after | |
| 786 // check-out. | |
| 787 weak_ptr_factory_.InvalidateWeakPtrs(); | |
| 788 | |
| 751 // Remove persisted data from app's state store. | 789 // Remove persisted data from app's state store. |
| 752 for (RegistrationInfoMap::const_iterator iter = | 790 for (RegistrationInfoMap::const_iterator iter = |
| 753 registration_info_map_.begin(); | 791 registration_info_map_.begin(); |
| 754 iter != registration_info_map_.end(); ++iter) { | 792 iter != registration_info_map_.end(); ++iter) { |
| 755 DeleteRegistrationInfo(iter->first); | 793 DeleteRegistrationInfo(iter->first); |
| 756 } | 794 } |
| 757 | 795 |
| 758 // Remove persisted data from prefs store. | 796 // Remove persisted data from prefs store. |
| 759 profile_->GetPrefs()->ClearPref(prefs::kGCMChannelEnabled); | |
| 760 profile_->GetPrefs()->ClearPref(prefs::kGCMRegisteredAppIDs); | 797 profile_->GetPrefs()->ClearPref(prefs::kGCMRegisteredAppIDs); |
| 761 | 798 |
| 762 gcm_client_ready_ = false; | 799 gcm_client_ready_ = false; |
| 763 delayed_task_controller_.reset(); | 800 delayed_task_controller_.reset(); |
| 764 register_callbacks_.clear(); | 801 register_callbacks_.clear(); |
| 765 send_callbacks_.clear(); | 802 send_callbacks_.clear(); |
| 766 registration_info_map_.clear(); | 803 registration_info_map_.clear(); |
| 767 | 804 |
| 768 content::BrowserThread::PostTask( | 805 content::BrowserThread::PostTask( |
| 769 content::BrowserThread::IO, | 806 content::BrowserThread::IO, |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 895 GCMClient::Result result) { | 932 GCMClient::Result result) { |
| 896 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | 933 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
| 897 | 934 |
| 898 // Drop the event if signed out. | 935 // Drop the event if signed out. |
| 899 if (username_.empty()) | 936 if (username_.empty()) |
| 900 return; | 937 return; |
| 901 | 938 |
| 902 GetEventRouter(app_id)->OnSendError(app_id, message_id, result); | 939 GetEventRouter(app_id)->OnSendError(app_id, message_id, result); |
| 903 } | 940 } |
| 904 | 941 |
| 905 void GCMProfileService::FinishInitializationOnUI(bool ready) { | 942 void GCMProfileService::FinishInitializationOnUI() { |
| 906 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | 943 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
| 907 | 944 |
| 908 gcm_client_ready_ = ready; | 945 // Initiates the check-in if the rollout signal indicates yes. |
| 909 if (gcm_client_ready_) | 946 if (GetGCMEnabledState(profile_) == ALWAYS_ENABLED) |
| 910 delayed_task_controller_->SetGCMReady(); | 947 EnsureLoaded(); |
| 911 } | 948 } |
| 912 | 949 |
| 913 void GCMProfileService::GCMClientReady() { | 950 void GCMProfileService::GCMClientReady() { |
| 914 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | 951 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
| 915 | 952 |
| 916 if (gcm_client_ready_) | 953 if (gcm_client_ready_) |
| 917 return; | 954 return; |
| 918 gcm_client_ready_ = true; | 955 gcm_client_ready_ = true; |
| 919 | 956 |
| 920 delayed_task_controller_->SetGCMReady(); | 957 delayed_task_controller_->SetGCMReady(); |
| (...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1042 | 1079 |
| 1043 return true; | 1080 return true; |
| 1044 } | 1081 } |
| 1045 | 1082 |
| 1046 // static | 1083 // static |
| 1047 const char* GCMProfileService::GetPersistentRegisterKeyForTesting() { | 1084 const char* GCMProfileService::GetPersistentRegisterKeyForTesting() { |
| 1048 return kRegistrationKey; | 1085 return kRegistrationKey; |
| 1049 } | 1086 } |
| 1050 | 1087 |
| 1051 } // namespace gcm | 1088 } // namespace gcm |
| OLD | NEW |