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