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 "components/gcm_driver/gcm_driver_desktop.h" | 5 #include "components/gcm_driver/gcm_driver_desktop.h" |
6 | 6 |
7 #include <utility> | 7 #include <utility> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/bind_helpers.h" | 10 #include "base/bind_helpers.h" |
11 #include "base/files/file_path.h" | 11 #include "base/files/file_path.h" |
12 #include "base/location.h" | 12 #include "base/location.h" |
13 #include "base/logging.h" | 13 #include "base/logging.h" |
14 #include "base/sequenced_task_runner.h" | 14 #include "base/sequenced_task_runner.h" |
15 #include "base/threading/sequenced_worker_pool.h" | 15 #include "base/threading/sequenced_worker_pool.h" |
16 #include "components/gcm_driver/gcm_app_handler.h" | 16 #include "components/gcm_driver/gcm_app_handler.h" |
17 #include "components/gcm_driver/gcm_client_factory.h" | 17 #include "components/gcm_driver/gcm_client_factory.h" |
18 #include "components/gcm_driver/system_encryptor.h" | 18 #include "components/gcm_driver/system_encryptor.h" |
19 #include "google_apis/gaia/oauth2_token_service.h" | |
20 #include "net/url_request/url_request_context_getter.h" | 19 #include "net/url_request/url_request_context_getter.h" |
21 | 20 |
22 namespace gcm { | 21 namespace gcm { |
23 | 22 |
24 // Helper class to save tasks to run until we're ready to execute them. | 23 // Helper class to save tasks to run until we're ready to execute them. |
25 class GCMDriverDesktop::DelayedTaskController { | 24 class GCMDriverDesktop::DelayedTaskController { |
26 public: | 25 public: |
27 DelayedTaskController(); | 26 DelayedTaskController(); |
28 ~DelayedTaskController(); | 27 ~DelayedTaskController(); |
29 | 28 |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
102 const std::string& app_id, | 101 const std::string& app_id, |
103 const GCMClient::SendErrorDetails& send_error_details) OVERRIDE; | 102 const GCMClient::SendErrorDetails& send_error_details) OVERRIDE; |
104 virtual void OnGCMReady() OVERRIDE; | 103 virtual void OnGCMReady() OVERRIDE; |
105 virtual void OnActivityRecorded() OVERRIDE; | 104 virtual void OnActivityRecorded() OVERRIDE; |
106 | 105 |
107 // Called on IO thread. | 106 // Called on IO thread. |
108 void Initialize( | 107 void Initialize( |
109 scoped_ptr<GCMClientFactory> gcm_client_factory, | 108 scoped_ptr<GCMClientFactory> gcm_client_factory, |
110 const GCMClient::ChromeBuildInfo& chrome_build_info, | 109 const GCMClient::ChromeBuildInfo& chrome_build_info, |
111 const base::FilePath& store_path, | 110 const base::FilePath& store_path, |
112 const std::vector<std::string>& account_ids, | |
113 const scoped_refptr<net::URLRequestContextGetter>& request_context, | 111 const scoped_refptr<net::URLRequestContextGetter>& request_context, |
114 const scoped_refptr<base::SequencedTaskRunner> blocking_task_runner); | 112 const scoped_refptr<base::SequencedTaskRunner> blocking_task_runner); |
115 void Start(const base::WeakPtr<GCMDriverDesktop>& service); | 113 void Start(const base::WeakPtr<GCMDriverDesktop>& service); |
116 void Stop(); | 114 void Stop(); |
117 void CheckOut(); | 115 void CheckOut(); |
118 void Register(const std::string& app_id, | 116 void Register(const std::string& app_id, |
119 const std::vector<std::string>& sender_ids); | 117 const std::vector<std::string>& sender_ids); |
120 void Unregister(const std::string& app_id); | 118 void Unregister(const std::string& app_id); |
121 void Send(const std::string& app_id, | 119 void Send(const std::string& app_id, |
122 const std::string& receiver_id, | 120 const std::string& receiver_id, |
(...skipping 24 matching lines...) Expand all Loading... |
147 } | 145 } |
148 | 146 |
149 GCMDriverDesktop::IOWorker::~IOWorker() { | 147 GCMDriverDesktop::IOWorker::~IOWorker() { |
150 DCHECK(io_thread_->RunsTasksOnCurrentThread()); | 148 DCHECK(io_thread_->RunsTasksOnCurrentThread()); |
151 } | 149 } |
152 | 150 |
153 void GCMDriverDesktop::IOWorker::Initialize( | 151 void GCMDriverDesktop::IOWorker::Initialize( |
154 scoped_ptr<GCMClientFactory> gcm_client_factory, | 152 scoped_ptr<GCMClientFactory> gcm_client_factory, |
155 const GCMClient::ChromeBuildInfo& chrome_build_info, | 153 const GCMClient::ChromeBuildInfo& chrome_build_info, |
156 const base::FilePath& store_path, | 154 const base::FilePath& store_path, |
157 const std::vector<std::string>& account_ids, | |
158 const scoped_refptr<net::URLRequestContextGetter>& request_context, | 155 const scoped_refptr<net::URLRequestContextGetter>& request_context, |
159 const scoped_refptr<base::SequencedTaskRunner> blocking_task_runner) { | 156 const scoped_refptr<base::SequencedTaskRunner> blocking_task_runner) { |
160 DCHECK(io_thread_->RunsTasksOnCurrentThread()); | 157 DCHECK(io_thread_->RunsTasksOnCurrentThread()); |
161 | 158 |
162 gcm_client_ = gcm_client_factory->BuildInstance(); | 159 gcm_client_ = gcm_client_factory->BuildInstance(); |
163 | 160 |
164 gcm_client_->Initialize(chrome_build_info, | 161 gcm_client_->Initialize(chrome_build_info, |
165 store_path, | 162 store_path, |
166 account_ids, | |
167 blocking_task_runner, | 163 blocking_task_runner, |
168 request_context, | 164 request_context, |
169 make_scoped_ptr<Encryptor>(new SystemEncryptor), | 165 make_scoped_ptr<Encryptor>(new SystemEncryptor), |
170 this); | 166 this); |
171 } | 167 } |
172 | 168 |
173 void GCMDriverDesktop::IOWorker::OnRegisterFinished( | 169 void GCMDriverDesktop::IOWorker::OnRegisterFinished( |
174 const std::string& app_id, | 170 const std::string& app_id, |
175 const std::string& registration_id, | 171 const std::string& registration_id, |
176 GCMClient::Result result) { | 172 GCMClient::Result result) { |
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
321 stats.gcm_client_created = true; | 317 stats.gcm_client_created = true; |
322 } | 318 } |
323 | 319 |
324 ui_thread_->PostTask( | 320 ui_thread_->PostTask( |
325 FROM_HERE, | 321 FROM_HERE, |
326 base::Bind(&GCMDriverDesktop::GetGCMStatisticsFinished, service_, stats)); | 322 base::Bind(&GCMDriverDesktop::GetGCMStatisticsFinished, service_, stats)); |
327 } | 323 } |
328 | 324 |
329 GCMDriverDesktop::GCMDriverDesktop( | 325 GCMDriverDesktop::GCMDriverDesktop( |
330 scoped_ptr<GCMClientFactory> gcm_client_factory, | 326 scoped_ptr<GCMClientFactory> gcm_client_factory, |
331 scoped_ptr<IdentityProvider> identity_provider, | |
332 const GCMClient::ChromeBuildInfo& chrome_build_info, | 327 const GCMClient::ChromeBuildInfo& chrome_build_info, |
333 const base::FilePath& store_path, | 328 const base::FilePath& store_path, |
334 const scoped_refptr<net::URLRequestContextGetter>& request_context, | 329 const scoped_refptr<net::URLRequestContextGetter>& request_context, |
335 const scoped_refptr<base::SequencedTaskRunner>& ui_thread, | 330 const scoped_refptr<base::SequencedTaskRunner>& ui_thread, |
336 const scoped_refptr<base::SequencedTaskRunner>& io_thread, | 331 const scoped_refptr<base::SequencedTaskRunner>& io_thread, |
337 const scoped_refptr<base::SequencedTaskRunner>& blocking_task_runner) | 332 const scoped_refptr<base::SequencedTaskRunner>& blocking_task_runner) |
338 : gcm_enabled_(true), | 333 : signed_in_(false), |
| 334 gcm_started_(false), |
| 335 gcm_enabled_(true), |
339 gcm_client_ready_(false), | 336 gcm_client_ready_(false), |
340 identity_provider_(identity_provider.Pass()), | |
341 ui_thread_(ui_thread), | 337 ui_thread_(ui_thread), |
342 io_thread_(io_thread), | 338 io_thread_(io_thread), |
343 weak_ptr_factory_(this) { | 339 weak_ptr_factory_(this) { |
344 // Get the list of available accounts. | |
345 std::vector<std::string> account_ids; | |
346 account_ids = identity_provider_->GetTokenService()->GetAccounts(); | |
347 | |
348 // Create and initialize the GCMClient. Note that this does not initiate the | 340 // Create and initialize the GCMClient. Note that this does not initiate the |
349 // GCM check-in. | 341 // GCM check-in. |
350 io_worker_.reset(new IOWorker(ui_thread, io_thread)); | 342 io_worker_.reset(new IOWorker(ui_thread, io_thread)); |
351 io_thread_->PostTask( | 343 io_thread_->PostTask( |
352 FROM_HERE, | 344 FROM_HERE, |
353 base::Bind(&GCMDriverDesktop::IOWorker::Initialize, | 345 base::Bind(&GCMDriverDesktop::IOWorker::Initialize, |
354 base::Unretained(io_worker_.get()), | 346 base::Unretained(io_worker_.get()), |
355 base::Passed(&gcm_client_factory), | 347 base::Passed(&gcm_client_factory), |
356 chrome_build_info, | 348 chrome_build_info, |
357 store_path, | 349 store_path, |
358 account_ids, | |
359 request_context, | 350 request_context, |
360 blocking_task_runner)); | 351 blocking_task_runner)); |
361 | |
362 identity_provider_->AddObserver(this); | |
363 } | 352 } |
364 | 353 |
365 GCMDriverDesktop::~GCMDriverDesktop() { | 354 GCMDriverDesktop::~GCMDriverDesktop() { |
366 } | 355 } |
367 | 356 |
368 void GCMDriverDesktop::OnActiveAccountLogin() { | |
369 EnsureStarted(); | |
370 } | |
371 | |
372 void GCMDriverDesktop::OnActiveAccountLogout() { | |
373 CheckOut(); | |
374 } | |
375 | |
376 void GCMDriverDesktop::Shutdown() { | 357 void GCMDriverDesktop::Shutdown() { |
377 DCHECK(ui_thread_->RunsTasksOnCurrentThread()); | 358 DCHECK(ui_thread_->RunsTasksOnCurrentThread()); |
378 identity_provider_->RemoveObserver(this); | |
379 GCMDriver::Shutdown(); | 359 GCMDriver::Shutdown(); |
380 io_thread_->DeleteSoon(FROM_HERE, io_worker_.release()); | 360 io_thread_->DeleteSoon(FROM_HERE, io_worker_.release()); |
381 } | 361 } |
382 | 362 |
| 363 void GCMDriverDesktop::SignIn() { |
| 364 signed_in_ = true; |
| 365 EnsureStarted(); |
| 366 } |
| 367 |
| 368 void GCMDriverDesktop::Purge() { |
| 369 DCHECK(ui_thread_->RunsTasksOnCurrentThread()); |
| 370 |
| 371 // We still proceed with the check-out logic even if the check-in is not |
| 372 // initiated in the current session. This will make sure that all the |
| 373 // persisted data written previously will get purged. |
| 374 signed_in_ = false; |
| 375 RemoveCachedData(); |
| 376 |
| 377 io_thread_->PostTask(FROM_HERE, |
| 378 base::Bind(&GCMDriverDesktop::IOWorker::CheckOut, |
| 379 base::Unretained(io_worker_.get()))); |
| 380 } |
| 381 |
383 void GCMDriverDesktop::AddAppHandler(const std::string& app_id, | 382 void GCMDriverDesktop::AddAppHandler(const std::string& app_id, |
384 GCMAppHandler* handler) { | 383 GCMAppHandler* handler) { |
385 DCHECK(ui_thread_->RunsTasksOnCurrentThread()); | 384 DCHECK(ui_thread_->RunsTasksOnCurrentThread()); |
386 GCMDriver::AddAppHandler(app_id, handler); | 385 GCMDriver::AddAppHandler(app_id, handler); |
387 | 386 |
388 // Ensures that the GCM service is started when there is an interest. | 387 // Ensures that the GCM service is started when there is an interest. |
389 EnsureStarted(); | 388 EnsureStarted(); |
390 } | 389 } |
391 | 390 |
392 void GCMDriverDesktop::RemoveAppHandler(const std::string& app_id) { | 391 void GCMDriverDesktop::RemoveAppHandler(const std::string& app_id) { |
(...skipping 22 matching lines...) Expand all Loading... |
415 return; | 414 return; |
416 gcm_enabled_ = false; | 415 gcm_enabled_ = false; |
417 | 416 |
418 Stop(); | 417 Stop(); |
419 } | 418 } |
420 | 419 |
421 void GCMDriverDesktop::Stop() { | 420 void GCMDriverDesktop::Stop() { |
422 DCHECK(ui_thread_->RunsTasksOnCurrentThread()); | 421 DCHECK(ui_thread_->RunsTasksOnCurrentThread()); |
423 | 422 |
424 // No need to stop GCM service if not started yet. | 423 // No need to stop GCM service if not started yet. |
425 if (account_id_.empty()) | 424 if (!gcm_started_) |
426 return; | 425 return; |
427 | 426 |
428 RemoveCachedData(); | 427 RemoveCachedData(); |
429 | 428 |
430 io_thread_->PostTask( | 429 io_thread_->PostTask( |
431 FROM_HERE, | 430 FROM_HERE, |
432 base::Bind(&GCMDriverDesktop::IOWorker::Stop, | 431 base::Bind(&GCMDriverDesktop::IOWorker::Stop, |
433 base::Unretained(io_worker_.get()))); | 432 base::Unretained(io_worker_.get()))); |
434 } | 433 } |
435 | 434 |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
519 message)); | 518 message)); |
520 } | 519 } |
521 | 520 |
522 GCMClient* GCMDriverDesktop::GetGCMClientForTesting() const { | 521 GCMClient* GCMDriverDesktop::GetGCMClientForTesting() const { |
523 DCHECK(ui_thread_->RunsTasksOnCurrentThread()); | 522 DCHECK(ui_thread_->RunsTasksOnCurrentThread()); |
524 return io_worker_ ? io_worker_->gcm_client_for_testing() : NULL; | 523 return io_worker_ ? io_worker_->gcm_client_for_testing() : NULL; |
525 } | 524 } |
526 | 525 |
527 bool GCMDriverDesktop::IsStarted() const { | 526 bool GCMDriverDesktop::IsStarted() const { |
528 DCHECK(ui_thread_->RunsTasksOnCurrentThread()); | 527 DCHECK(ui_thread_->RunsTasksOnCurrentThread()); |
529 return !account_id_.empty(); | 528 return gcm_started_; |
530 } | 529 } |
531 | 530 |
532 bool GCMDriverDesktop::IsGCMClientReady() const { | 531 bool GCMDriverDesktop::IsGCMClientReady() const { |
533 DCHECK(ui_thread_->RunsTasksOnCurrentThread()); | 532 DCHECK(ui_thread_->RunsTasksOnCurrentThread()); |
534 return gcm_client_ready_; | 533 return gcm_client_ready_; |
535 } | 534 } |
536 | 535 |
537 void GCMDriverDesktop::GetGCMStatistics( | 536 void GCMDriverDesktop::GetGCMStatistics( |
538 const GetGCMStatisticsCallback& callback, | 537 const GetGCMStatisticsCallback& callback, |
539 bool clear_logs) { | 538 bool clear_logs) { |
(...skipping 16 matching lines...) Expand all Loading... |
556 io_thread_->PostTask( | 555 io_thread_->PostTask( |
557 FROM_HERE, | 556 FROM_HERE, |
558 base::Bind(&GCMDriverDesktop::IOWorker::SetGCMRecording, | 557 base::Bind(&GCMDriverDesktop::IOWorker::SetGCMRecording, |
559 base::Unretained(io_worker_.get()), | 558 base::Unretained(io_worker_.get()), |
560 recording)); | 559 recording)); |
561 } | 560 } |
562 | 561 |
563 GCMClient::Result GCMDriverDesktop::EnsureStarted() { | 562 GCMClient::Result GCMDriverDesktop::EnsureStarted() { |
564 DCHECK(ui_thread_->RunsTasksOnCurrentThread()); | 563 DCHECK(ui_thread_->RunsTasksOnCurrentThread()); |
565 | 564 |
| 565 if (gcm_started_) |
| 566 return GCMClient::SUCCESS; |
| 567 |
566 if (!gcm_enabled_) | 568 if (!gcm_enabled_) |
567 return GCMClient::GCM_DISABLED; | 569 return GCMClient::GCM_DISABLED; |
568 | 570 |
569 // Have any app requested the service? | 571 // Have any app requested the service? |
570 if (app_handlers().empty()) | 572 if (app_handlers().empty()) |
571 return GCMClient::UNKNOWN_ERROR; | 573 return GCMClient::UNKNOWN_ERROR; |
572 | 574 |
573 // Is the user signed in? | 575 // TODO(jianli): To be removed when sign-in enforcement is dropped. |
574 const std::string account_id = identity_provider_->GetActiveAccountId(); | 576 if (!signed_in_) |
575 if (account_id.empty()) | |
576 return GCMClient::NOT_SIGNED_IN; | 577 return GCMClient::NOT_SIGNED_IN; |
577 | 578 |
578 // CheckIn could be called more than once when: | |
579 // 1) The password changes. | |
580 // 2) Register/send function calls it to ensure CheckIn is done. | |
581 if (account_id_ == account_id) | |
582 return GCMClient::SUCCESS; | |
583 account_id_ = account_id; | |
584 | |
585 DCHECK(!delayed_task_controller_); | 579 DCHECK(!delayed_task_controller_); |
586 delayed_task_controller_.reset(new DelayedTaskController); | 580 delayed_task_controller_.reset(new DelayedTaskController); |
587 | 581 |
588 // Note that we need to pass weak pointer again since the existing weak | 582 // Note that we need to pass weak pointer again since the existing weak |
589 // pointer in IOWorker might have been invalidated when check-out occurs. | 583 // pointer in IOWorker might have been invalidated when check-out occurs. |
590 io_thread_->PostTask( | 584 io_thread_->PostTask( |
591 FROM_HERE, | 585 FROM_HERE, |
592 base::Bind(&GCMDriverDesktop::IOWorker::Start, | 586 base::Bind(&GCMDriverDesktop::IOWorker::Start, |
593 base::Unretained(io_worker_.get()), | 587 base::Unretained(io_worker_.get()), |
594 weak_ptr_factory_.GetWeakPtr())); | 588 weak_ptr_factory_.GetWeakPtr())); |
595 | 589 |
| 590 gcm_started_ = true; |
596 return GCMClient::SUCCESS; | 591 return GCMClient::SUCCESS; |
597 } | 592 } |
598 | 593 |
599 void GCMDriverDesktop::RemoveCachedData() { | 594 void GCMDriverDesktop::RemoveCachedData() { |
600 DCHECK(ui_thread_->RunsTasksOnCurrentThread()); | 595 DCHECK(ui_thread_->RunsTasksOnCurrentThread()); |
601 // Remove all the queued tasks since they no longer make sense after | 596 // Remove all the queued tasks since they no longer make sense after |
602 // GCM service is stopped. | 597 // GCM service is stopped. |
603 weak_ptr_factory_.InvalidateWeakPtrs(); | 598 weak_ptr_factory_.InvalidateWeakPtrs(); |
604 | 599 |
605 account_id_.clear(); | 600 gcm_started_ = false; |
606 gcm_client_ready_ = false; | 601 gcm_client_ready_ = false; |
607 delayed_task_controller_.reset(); | 602 delayed_task_controller_.reset(); |
608 ClearCallbacks(); | 603 ClearCallbacks(); |
609 } | 604 } |
610 | 605 |
611 void GCMDriverDesktop::CheckOut() { | |
612 DCHECK(ui_thread_->RunsTasksOnCurrentThread()); | |
613 | |
614 // We still proceed with the check-out logic even if the check-in is not | |
615 // initiated in the current session. This will make sure that all the | |
616 // persisted data written previously will get purged. | |
617 | |
618 RemoveCachedData(); | |
619 | |
620 io_thread_->PostTask( | |
621 FROM_HERE, | |
622 base::Bind(&GCMDriverDesktop::IOWorker::CheckOut, | |
623 base::Unretained(io_worker_.get()))); | |
624 } | |
625 | |
626 void GCMDriverDesktop::MessageReceived( | 606 void GCMDriverDesktop::MessageReceived( |
627 const std::string& app_id, | 607 const std::string& app_id, |
628 const GCMClient::IncomingMessage& message) { | 608 const GCMClient::IncomingMessage& message) { |
629 DCHECK(ui_thread_->RunsTasksOnCurrentThread()); | 609 DCHECK(ui_thread_->RunsTasksOnCurrentThread()); |
630 | 610 |
631 // Drop the event if signed out. | 611 // Drop the event if the service has been stopped. |
632 if (account_id_.empty()) | 612 if (!gcm_started_) |
633 return; | 613 return; |
634 | 614 |
635 GetAppHandler(app_id)->OnMessage(app_id, message); | 615 GetAppHandler(app_id)->OnMessage(app_id, message); |
636 } | 616 } |
637 | 617 |
638 void GCMDriverDesktop::MessagesDeleted(const std::string& app_id) { | 618 void GCMDriverDesktop::MessagesDeleted(const std::string& app_id) { |
639 DCHECK(ui_thread_->RunsTasksOnCurrentThread()); | 619 DCHECK(ui_thread_->RunsTasksOnCurrentThread()); |
640 | 620 |
641 // Drop the event if signed out. | 621 // Drop the event if the service has been stopped. |
642 if (account_id_.empty()) | 622 if (!gcm_started_) |
643 return; | 623 return; |
644 | 624 |
645 GetAppHandler(app_id)->OnMessagesDeleted(app_id); | 625 GetAppHandler(app_id)->OnMessagesDeleted(app_id); |
646 } | 626 } |
647 | 627 |
648 void GCMDriverDesktop::MessageSendError( | 628 void GCMDriverDesktop::MessageSendError( |
649 const std::string& app_id, | 629 const std::string& app_id, |
650 const GCMClient::SendErrorDetails& send_error_details) { | 630 const GCMClient::SendErrorDetails& send_error_details) { |
651 DCHECK(ui_thread_->RunsTasksOnCurrentThread()); | 631 DCHECK(ui_thread_->RunsTasksOnCurrentThread()); |
652 | 632 |
653 // Drop the event if signed out. | 633 // Drop the event if the service has been stopped. |
654 if (account_id_.empty()) | 634 if (!gcm_started_) |
655 return; | 635 return; |
656 | 636 |
657 GetAppHandler(app_id)->OnSendError(app_id, send_error_details); | 637 GetAppHandler(app_id)->OnSendError(app_id, send_error_details); |
658 } | 638 } |
659 | 639 |
660 void GCMDriverDesktop::GCMClientReady() { | 640 void GCMDriverDesktop::GCMClientReady() { |
661 DCHECK(ui_thread_->RunsTasksOnCurrentThread()); | 641 DCHECK(ui_thread_->RunsTasksOnCurrentThread()); |
662 | 642 |
663 if (gcm_client_ready_) | 643 if (gcm_client_ready_) |
664 return; | 644 return; |
665 gcm_client_ready_ = true; | 645 gcm_client_ready_ = true; |
666 | 646 |
667 delayed_task_controller_->SetReady(); | 647 delayed_task_controller_->SetReady(); |
668 } | 648 } |
669 | 649 |
670 void GCMDriverDesktop::GetGCMStatisticsFinished( | 650 void GCMDriverDesktop::GetGCMStatisticsFinished( |
671 const GCMClient::GCMStatistics& stats) { | 651 const GCMClient::GCMStatistics& stats) { |
672 DCHECK(ui_thread_->RunsTasksOnCurrentThread()); | 652 DCHECK(ui_thread_->RunsTasksOnCurrentThread()); |
673 | 653 |
674 // Normally request_gcm_statistics_callback_ would not be null. | 654 // Normally request_gcm_statistics_callback_ would not be null. |
675 if (!request_gcm_statistics_callback_.is_null()) | 655 if (!request_gcm_statistics_callback_.is_null()) |
676 request_gcm_statistics_callback_.Run(stats); | 656 request_gcm_statistics_callback_.Run(stats); |
677 else | 657 else |
678 LOG(WARNING) << "request_gcm_statistics_callback_ is NULL."; | 658 LOG(WARNING) << "request_gcm_statistics_callback_ is NULL."; |
679 } | 659 } |
680 | 660 |
681 std::string GCMDriverDesktop::SignedInUserName() const { | |
682 if (IsStarted()) | |
683 return identity_provider_->GetActiveUsername(); | |
684 return std::string(); | |
685 } | |
686 | |
687 } // namespace gcm | 661 } // namespace gcm |
OLD | NEW |