Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(33)

Side by Side Diff: chrome/browser/services/gcm/gcm_profile_service.cc

Issue 165993005: [GCM] Make sure GCM checkout logic is invoked when the profile is signed out (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix test Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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 IOWorker();
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)
287 : service_(service) {
288 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 290 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
289 } 291 }
290 292
291 GCMProfileService::IOWorker::~IOWorker() { 293 GCMProfileService::IOWorker::~IOWorker() {
292 } 294 }
293 295
294 void GCMProfileService::IOWorker::Initialize( 296 void GCMProfileService::IOWorker::Initialize(
295 GCMClientFactory* gcm_client_factory, 297 scoped_ptr<GCMClientFactory> gcm_client_factory,
296 const base::FilePath& store_path, 298 const base::FilePath& store_path,
297 const std::vector<std::string>& account_ids, 299 const std::vector<std::string>& account_ids,
298 const scoped_refptr<net::URLRequestContextGetter>& 300 const scoped_refptr<net::URLRequestContextGetter>&
299 url_request_context_getter) { 301 url_request_context_getter) {
300 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); 302 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
301 303
302 gcm_client_ = gcm_client_factory->BuildInstance().Pass(); 304 gcm_client_ = gcm_client_factory->BuildInstance().Pass();
303 305
304 checkin_proto::ChromeBuildProto chrome_build_proto; 306 checkin_proto::ChromeBuildProto chrome_build_proto;
305 chrome_build_proto.set_platform(GetPlatform()); 307 chrome_build_proto.set_platform(GetPlatform());
306 chrome_build_proto.set_chrome_version(GetVersion()); 308 chrome_build_proto.set_chrome_version(GetVersion());
307 chrome_build_proto.set_channel(GetChannel()); 309 chrome_build_proto.set_channel(GetChannel());
308 310
309 scoped_refptr<base::SequencedWorkerPool> worker_pool( 311 scoped_refptr<base::SequencedWorkerPool> worker_pool(
310 content::BrowserThread::GetBlockingPool()); 312 content::BrowserThread::GetBlockingPool());
311 scoped_refptr<base::SequencedTaskRunner> blocking_task_runner( 313 scoped_refptr<base::SequencedTaskRunner> blocking_task_runner(
312 worker_pool->GetSequencedTaskRunnerWithShutdownBehavior( 314 worker_pool->GetSequencedTaskRunnerWithShutdownBehavior(
313 worker_pool->GetSequenceToken(), 315 worker_pool->GetSequenceToken(),
314 base::SequencedWorkerPool::SKIP_ON_SHUTDOWN)); 316 base::SequencedWorkerPool::SKIP_ON_SHUTDOWN));
315 317
316 gcm_client_->Initialize(chrome_build_proto, 318 gcm_client_->Initialize(chrome_build_proto,
317 store_path, 319 store_path,
318 account_ids, 320 account_ids,
319 blocking_task_runner, 321 blocking_task_runner,
320 url_request_context_getter, 322 url_request_context_getter,
321 this); 323 this);
322
323 content::BrowserThread::PostTask(
324 content::BrowserThread::UI,
325 FROM_HERE,
326 base::Bind(&GCMProfileService::FinishInitializationOnUI,
327 service_,
328 gcm_client_->IsReady()));
329 } 324 }
330 325
331 void GCMProfileService::IOWorker::Reset() { 326 void GCMProfileService::IOWorker::Reset() {
332 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); 327 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
333 328
334 // 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
335 // created. 330 // created.
336 gcm_client_.reset(); 331 gcm_client_.reset();
337 } 332 }
338 333
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
416 } 411 }
417 412
418 void GCMProfileService::IOWorker::OnGCMReady() { 413 void GCMProfileService::IOWorker::OnGCMReady() {
419 content::BrowserThread::PostTask( 414 content::BrowserThread::PostTask(
420 content::BrowserThread::UI, 415 content::BrowserThread::UI,
421 FROM_HERE, 416 FROM_HERE,
422 base::Bind(&GCMProfileService::GCMClientReady, 417 base::Bind(&GCMProfileService::GCMClientReady,
423 service_)); 418 service_));
424 } 419 }
425 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
426 void GCMProfileService::IOWorker::CheckOut() { 429 void GCMProfileService::IOWorker::CheckOut() {
427 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); 430 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
428 431
429 gcm_client_->CheckOut(); 432 gcm_client_->CheckOut();
430 gcm_client_.reset(); 433
434 // Note that we still need to keep GCMClient instance alive since the profile
435 // might be signed in again.
431 } 436 }
432 437
433 void GCMProfileService::IOWorker::Register( 438 void GCMProfileService::IOWorker::Register(
434 const std::string& app_id, 439 const std::string& app_id,
435 const std::vector<std::string>& sender_ids, 440 const std::vector<std::string>& sender_ids,
436 const std::string& cert) { 441 const std::string& cert) {
437 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); 442 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
438 443
439 gcm_client_->Register(app_id, cert, sender_ids); 444 gcm_client_->Register(app_id, cert, sender_ids);
440 } 445 }
(...skipping 16 matching lines...) Expand all
457 GCMProfileService::RegistrationInfo::RegistrationInfo() { 462 GCMProfileService::RegistrationInfo::RegistrationInfo() {
458 } 463 }
459 464
460 GCMProfileService::RegistrationInfo::~RegistrationInfo() { 465 GCMProfileService::RegistrationInfo::~RegistrationInfo() {
461 } 466 }
462 467
463 bool GCMProfileService::RegistrationInfo::IsValid() const { 468 bool GCMProfileService::RegistrationInfo::IsValid() const {
464 return !sender_ids.empty() && !registration_id.empty(); 469 return !sender_ids.empty() && !registration_id.empty();
465 } 470 }
466 471
467 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;
468 479
469 // static 480 bool gcm_enabled = false;
470 bool GCMProfileService::IsGCMEnabled(Profile* profile) { 481 if (!gcm_enabled_value->GetAsBoolean(&gcm_enabled))
471 // GCM is not enabled in incognito mode. 482 return ENABLED_FOR_APPS;
472 if (profile->IsOffTheRecord())
473 return false;
474 483
475 if (enable_gcm_for_testing_) 484 return gcm_enabled ? ALWAYS_ENABLED : ALWAYS_DISABLED;
476 return true;
477
478 return profile->GetPrefs()->GetBoolean(prefs::kGCMChannelEnabled);
479 } 485 }
480 486
481 // static 487 // static
482 void GCMProfileService::RegisterProfilePrefs( 488 void GCMProfileService::RegisterProfilePrefs(
483 user_prefs::PrefRegistrySyncable* registry) { 489 user_prefs::PrefRegistrySyncable* registry) {
484 // 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.
485 chrome::VersionInfo::Channel channel = chrome::VersionInfo::GetChannel(); 491 chrome::VersionInfo::Channel channel = chrome::VersionInfo::GetChannel();
486 bool on_by_default = false; 492 bool on_by_default = false;
487 if (channel == chrome::VersionInfo::CHANNEL_UNKNOWN || 493 if (channel == chrome::VersionInfo::CHANNEL_UNKNOWN ||
488 channel == chrome::VersionInfo::CHANNEL_CANARY || 494 channel == chrome::VersionInfo::CHANNEL_CANARY ||
(...skipping 15 matching lines...) Expand all
504 testing_delegate_(NULL), 510 testing_delegate_(NULL),
505 weak_ptr_factory_(this) { 511 weak_ptr_factory_(this) {
506 DCHECK(!profile->IsOffTheRecord()); 512 DCHECK(!profile->IsOffTheRecord());
507 } 513 }
508 514
509 GCMProfileService::~GCMProfileService() { 515 GCMProfileService::~GCMProfileService() {
510 } 516 }
511 517
512 void GCMProfileService::Initialize( 518 void GCMProfileService::Initialize(
513 scoped_ptr<GCMClientFactory> gcm_client_factory) { 519 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, 520 registrar_.Add(this,
524 chrome::NOTIFICATION_GOOGLE_SIGNIN_SUCCESSFUL, 521 chrome::NOTIFICATION_GOOGLE_SIGNIN_SUCCESSFUL,
525 content::Source<Profile>(profile_)); 522 content::Source<Profile>(profile_));
526 registrar_.Add(this, 523 registrar_.Add(this,
527 chrome::NOTIFICATION_GOOGLE_SIGNED_OUT, 524 chrome::NOTIFICATION_GOOGLE_SIGNED_OUT,
528 content::Source<Profile>(profile_)); 525 content::Source<Profile>(profile_));
529 registrar_.Add(this, 526 registrar_.Add(this,
530 chrome::NOTIFICATION_PROFILE_DESTROYED, 527 chrome::NOTIFICATION_PROFILE_DESTROYED,
531 content::Source<Profile>(profile_)); 528 content::Source<Profile>(profile_));
532 // TODO(jianli): move extension specific logic out of GCMProfileService. 529 // TODO(jianli): move extension specific logic out of GCMProfileService.
533 registrar_.Add(this, 530 registrar_.Add(this,
534 chrome:: NOTIFICATION_EXTENSION_UNINSTALLED, 531 chrome:: NOTIFICATION_EXTENSION_UNINSTALLED,
535 content::Source<Profile>(profile_)); 532 content::Source<Profile>(profile_));
536 533
537 // In case that the profile has been signed in before GCMProfileService is 534 // Get the list of available accounts.
538 // created. 535 std::vector<std::string> account_ids;
539 SigninManagerBase* manager = SigninManagerFactory::GetForProfile(profile_); 536 #if !defined(OS_ANDROID)
540 if (manager) { 537 account_ids =
541 std::string username = manager->GetAuthenticatedUsername(); 538 ProfileOAuth2TokenServiceFactory::GetForProfile(profile_)->GetAccounts();
542 if (!username.empty()) 539 #endif
543 CheckIn(username); 540
544 } 541 // Create and initialize the GCMClient. Note that this does not initiate the
542 // GCM check-in.
543 io_worker_ = new IOWorker();
544 scoped_refptr<net::URLRequestContextGetter> url_request_context_getter =
SeRya 2014/03/04 08:35:26 I tried to use ProfileSyncService on startup and g
jianli 2014/03/05 01:37:34 I can't repro this. Could you please share how you
545 profile_->GetRequestContext();
546 content::BrowserThread::PostTask(
547 content::BrowserThread::IO,
548 FROM_HERE,
549 base::Bind(&GCMProfileService::IOWorker::Initialize,
550 io_worker_,
551 base::Passed(&gcm_client_factory),
552 profile_->GetPath().Append(chrome::kGCMStoreDirname),
553 account_ids,
554 url_request_context_getter));
555
556 // Load from the GCM store and initiate the GCM check-in if the rollout signal
557 // indicates yes.
558 if (GetGCMEnabledState(profile_) == ALWAYS_ENABLED)
559 EnsureLoaded();
545 } 560 }
546 561
547 void GCMProfileService::Register(const std::string& app_id, 562 void GCMProfileService::Register(const std::string& app_id,
548 const std::vector<std::string>& sender_ids, 563 const std::vector<std::string>& sender_ids,
549 const std::string& cert, 564 const std::string& cert,
550 RegisterCallback callback) { 565 RegisterCallback callback) {
551 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 566 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
552 DCHECK(!app_id.empty() && !sender_ids.empty() && !callback.is_null()); 567 DCHECK(!app_id.empty() && !sender_ids.empty() && !callback.is_null());
553 568
569 // Ensure that check-in has been done.
570 EnsureLoaded();
571
554 // If the profile was not signed in, bail out. 572 // If the profile was not signed in, bail out.
555 if (username_.empty()) { 573 if (username_.empty()) {
556 callback.Run(std::string(), GCMClient::NOT_SIGNED_IN); 574 callback.Run(std::string(), GCMClient::NOT_SIGNED_IN);
557 return; 575 return;
558 } 576 }
559 577
560 // If previous register operation is still in progress, bail out. 578 // If previous register operation is still in progress, bail out.
561 if (register_callbacks_.find(app_id) != register_callbacks_.end()) { 579 if (register_callbacks_.find(app_id) != register_callbacks_.end()) {
562 callback.Run(std::string(), GCMClient::ASYNC_OPERATION_PENDING); 580 callback.Run(std::string(), GCMClient::ASYNC_OPERATION_PENDING);
563 return; 581 return;
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
629 cert)); 647 cert));
630 } 648 }
631 649
632 void GCMProfileService::Send(const std::string& app_id, 650 void GCMProfileService::Send(const std::string& app_id,
633 const std::string& receiver_id, 651 const std::string& receiver_id,
634 const GCMClient::OutgoingMessage& message, 652 const GCMClient::OutgoingMessage& message,
635 SendCallback callback) { 653 SendCallback callback) {
636 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 654 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
637 DCHECK(!app_id.empty() && !receiver_id.empty() && !callback.is_null()); 655 DCHECK(!app_id.empty() && !receiver_id.empty() && !callback.is_null());
638 656
657 // Ensure that check-in has been done.
658 EnsureLoaded();
659
639 // If the profile was not signed in, bail out. 660 // If the profile was not signed in, bail out.
640 if (username_.empty()) { 661 if (username_.empty()) {
641 callback.Run(std::string(), GCMClient::NOT_SIGNED_IN); 662 callback.Run(std::string(), GCMClient::NOT_SIGNED_IN);
642 return; 663 return;
643 } 664 }
644 665
645 // If the message with send ID is still in progress, bail out. 666 // If the message with send ID is still in progress, bail out.
646 std::pair<std::string, std::string> key(app_id, message.id); 667 std::pair<std::string, std::string> key(app_id, message.id);
647 if (send_callbacks_.find(key) != send_callbacks_.end()) { 668 if (send_callbacks_.find(key) != send_callbacks_.end()) {
648 callback.Run(message.id, GCMClient::INVALID_PARAMETER); 669 callback.Run(message.id, GCMClient::INVALID_PARAMETER);
(...skipping 24 matching lines...) Expand all
673 content::BrowserThread::PostTask( 694 content::BrowserThread::PostTask(
674 content::BrowserThread::IO, 695 content::BrowserThread::IO,
675 FROM_HERE, 696 FROM_HERE,
676 base::Bind(&GCMProfileService::IOWorker::Send, 697 base::Bind(&GCMProfileService::IOWorker::Send,
677 io_worker_, 698 io_worker_,
678 app_id, 699 app_id,
679 receiver_id, 700 receiver_id,
680 message)); 701 message));
681 } 702 }
682 703
704 GCMClient* GCMProfileService::GetGCMClientForTesting() const {
705 return io_worker_ ? io_worker_->gcm_client_for_testing() : NULL;
706 }
707
683 void GCMProfileService::Observe(int type, 708 void GCMProfileService::Observe(int type,
684 const content::NotificationSource& source, 709 const content::NotificationSource& source,
685 const content::NotificationDetails& details) { 710 const content::NotificationDetails& details) {
686 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 711 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
687 712
688 switch (type) { 713 switch (type) {
689 case chrome::NOTIFICATION_GOOGLE_SIGNIN_SUCCESSFUL: { 714 case chrome::NOTIFICATION_GOOGLE_SIGNIN_SUCCESSFUL: {
690 const GoogleServiceSigninSuccessDetails* signin_details = 715 if (GetGCMEnabledState(profile_) == ALWAYS_ENABLED)
691 content::Details<GoogleServiceSigninSuccessDetails>(details).ptr(); 716 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; 717 break;
696 } 718 }
697 case chrome::NOTIFICATION_GOOGLE_SIGNED_OUT: 719 case chrome::NOTIFICATION_GOOGLE_SIGNED_OUT:
698 CheckOut(); 720 CheckOut();
699 break; 721 break;
700 case chrome::NOTIFICATION_PROFILE_DESTROYED: 722 case chrome::NOTIFICATION_PROFILE_DESTROYED:
701 ResetGCMClient(); 723 ResetGCMClient();
702 break; 724 break;
703 case chrome:: NOTIFICATION_EXTENSION_UNINSTALLED: { 725 case chrome:: NOTIFICATION_EXTENSION_UNINSTALLED:
704 extensions::Extension* extension = 726 if (!username_.empty()) {
705 content::Details<extensions::Extension>(details).ptr(); 727 extensions::Extension* extension =
706 Unregister(extension->id()); 728 content::Details<extensions::Extension>(details).ptr();
729 Unregister(extension->id());
730 }
707 break; 731 break;
708 }
709 default: 732 default:
710 NOTREACHED(); 733 NOTREACHED();
711 } 734 }
712 } 735 }
713 736
714 void GCMProfileService::CheckIn(const std::string& username) { 737 void GCMProfileService::EnsureLoaded() {
715 DCHECK(!username.empty() && username_.empty()); 738 SigninManagerBase* manager = SigninManagerFactory::GetForProfile(profile_);
739 if (!manager)
740 return;
741 std::string username = manager->GetAuthenticatedUsername();
742 if (username.empty())
743 return;
744
745 // CheckIn could be called more than once when:
746 // 1) The password changes.
747 // 2) Register/send function calls it to ensure CheckIn is done.
748 if (username_ == username)
749 return;
716 username_ = username; 750 username_ = username;
717 751
752 #if !defined(OS_ANDROID)
753 if (!js_event_router_)
754 js_event_router_.reset(new extensions::GcmJsEventRouter(profile_));
755 #endif
756
718 DCHECK(!delayed_task_controller_); 757 DCHECK(!delayed_task_controller_);
719 delayed_task_controller_.reset(new DelayedTaskController); 758 delayed_task_controller_.reset(new DelayedTaskController);
720 759
721 // Load all register apps. 760 // Load all the registered apps.
722 ReadRegisteredAppIDs(); 761 ReadRegisteredAppIDs();
723 762
724 // Get the list of available accounts. 763 // This will load the data from the gcm store and trigger the check-in if
725 std::vector<std::string> account_ids; 764 // the persisted check-in info is not found.
726 #if !defined(OS_ANDROID) 765 // Note that we need to pass weak pointer again since the existing weak
727 account_ids = 766 // 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( 767 content::BrowserThread::PostTask(
735 content::BrowserThread::IO, 768 content::BrowserThread::IO,
736 FROM_HERE, 769 FROM_HERE,
737 base::Bind(&GCMProfileService::IOWorker::Initialize, 770 base::Bind(&GCMProfileService::IOWorker::Load,
738 io_worker_, 771 io_worker_,
739 gcm_client_factory_.get(), 772 weak_ptr_factory_.GetWeakPtr()));
740 profile_->GetPath().Append(chrome::kGCMStoreDirname),
741 account_ids,
742 url_request_context_getter));
743 } 773 }
744 774
745 void GCMProfileService::CheckOut() { 775 void GCMProfileService::CheckOut() {
746 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 776 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
747 777
748 DCHECK(!username_.empty()); 778 // We still proceed with the check-out logic even if the check-in is not
779 // initiated in the current session. This will make sure that all the
780 // persisted data written previously will get purged.
749 username_.clear(); 781 username_.clear();
750 782
783 // Remove all the queued tasks since they no longer make sense after
784 // check-out.
785 weak_ptr_factory_.InvalidateWeakPtrs();
786
751 // Remove persisted data from app's state store. 787 // Remove persisted data from app's state store.
752 for (RegistrationInfoMap::const_iterator iter = 788 for (RegistrationInfoMap::const_iterator iter =
753 registration_info_map_.begin(); 789 registration_info_map_.begin();
754 iter != registration_info_map_.end(); ++iter) { 790 iter != registration_info_map_.end(); ++iter) {
755 DeleteRegistrationInfo(iter->first); 791 DeleteRegistrationInfo(iter->first);
756 } 792 }
757 793
758 // Remove persisted data from prefs store. 794 // Remove persisted data from prefs store.
759 profile_->GetPrefs()->ClearPref(prefs::kGCMChannelEnabled);
760 profile_->GetPrefs()->ClearPref(prefs::kGCMRegisteredAppIDs); 795 profile_->GetPrefs()->ClearPref(prefs::kGCMRegisteredAppIDs);
761 796
762 gcm_client_ready_ = false; 797 gcm_client_ready_ = false;
763 delayed_task_controller_.reset(); 798 delayed_task_controller_.reset();
764 register_callbacks_.clear(); 799 register_callbacks_.clear();
765 send_callbacks_.clear(); 800 send_callbacks_.clear();
766 registration_info_map_.clear(); 801 registration_info_map_.clear();
767 802
768 content::BrowserThread::PostTask( 803 content::BrowserThread::PostTask(
769 content::BrowserThread::IO, 804 content::BrowserThread::IO,
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
895 GCMClient::Result result) { 930 GCMClient::Result result) {
896 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 931 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
897 932
898 // Drop the event if signed out. 933 // Drop the event if signed out.
899 if (username_.empty()) 934 if (username_.empty())
900 return; 935 return;
901 936
902 GetEventRouter(app_id)->OnSendError(app_id, message_id, result); 937 GetEventRouter(app_id)->OnSendError(app_id, message_id, result);
903 } 938 }
904 939
905 void GCMProfileService::FinishInitializationOnUI(bool ready) {
906 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
907
908 gcm_client_ready_ = ready;
909 if (gcm_client_ready_)
910 delayed_task_controller_->SetGCMReady();
911 }
912
913 void GCMProfileService::GCMClientReady() { 940 void GCMProfileService::GCMClientReady() {
914 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 941 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
915 942
916 if (gcm_client_ready_) 943 if (gcm_client_ready_)
917 return; 944 return;
918 gcm_client_ready_ = true; 945 gcm_client_ready_ = true;
919 946
920 delayed_task_controller_->SetGCMReady(); 947 delayed_task_controller_->SetGCMReady();
921 } 948 }
922 949
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
1042 1069
1043 return true; 1070 return true;
1044 } 1071 }
1045 1072
1046 // static 1073 // static
1047 const char* GCMProfileService::GetPersistentRegisterKeyForTesting() { 1074 const char* GCMProfileService::GetPersistentRegisterKeyForTesting() {
1048 return kRegistrationKey; 1075 return kRegistrationKey;
1049 } 1076 }
1050 1077
1051 } // namespace gcm 1078 } // namespace gcm
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698