Loading the account mappings from store to the driver.
[chromium-blink-merge.git] / components / gcm_driver / gcm_driver_desktop.cc
blobb2d2e558c32c207b63bbd799f9d1fa1a4eb0d680
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
3 // found in the LICENSE file.
5 #include "components/gcm_driver/gcm_driver_desktop.h"
7 #include <utility>
9 #include "base/bind.h"
10 #include "base/bind_helpers.h"
11 #include "base/files/file_path.h"
12 #include "base/location.h"
13 #include "base/logging.h"
14 #include "base/sequenced_task_runner.h"
15 #include "base/threading/sequenced_worker_pool.h"
16 #include "components/gcm_driver/gcm_app_handler.h"
17 #include "components/gcm_driver/gcm_channel_status_syncer.h"
18 #include "components/gcm_driver/gcm_client_factory.h"
19 #include "components/gcm_driver/gcm_delayed_task_controller.h"
20 #include "components/gcm_driver/system_encryptor.h"
21 #include "google_apis/gcm/engine/account_mapping.h"
22 #include "net/base/ip_endpoint.h"
23 #include "net/url_request/url_request_context_getter.h"
25 namespace gcm {
27 class GCMDriverDesktop::IOWorker : public GCMClient::Delegate {
28 public:
29 // Called on UI thread.
30 IOWorker(const scoped_refptr<base::SequencedTaskRunner>& ui_thread,
31 const scoped_refptr<base::SequencedTaskRunner>& io_thread);
32 virtual ~IOWorker();
34 // Overridden from GCMClient::Delegate:
35 // Called on IO thread.
36 virtual void OnRegisterFinished(const std::string& app_id,
37 const std::string& registration_id,
38 GCMClient::Result result) OVERRIDE;
39 virtual void OnUnregisterFinished(const std::string& app_id,
40 GCMClient::Result result) OVERRIDE;
41 virtual void OnSendFinished(const std::string& app_id,
42 const std::string& message_id,
43 GCMClient::Result result) OVERRIDE;
44 virtual void OnMessageReceived(
45 const std::string& app_id,
46 const GCMClient::IncomingMessage& message) OVERRIDE;
47 virtual void OnMessagesDeleted(const std::string& app_id) OVERRIDE;
48 virtual void OnMessageSendError(
49 const std::string& app_id,
50 const GCMClient::SendErrorDetails& send_error_details) OVERRIDE;
51 virtual void OnSendAcknowledged(const std::string& app_id,
52 const std::string& message_id) OVERRIDE;
53 virtual void OnGCMReady(
54 const std::vector<AccountMapping>& account_mappings) OVERRIDE;
55 virtual void OnActivityRecorded() OVERRIDE;
56 virtual void OnConnected(const net::IPEndPoint& ip_endpoint) OVERRIDE;
57 virtual void OnDisconnected() OVERRIDE;
59 // Called on IO thread.
60 void Initialize(
61 scoped_ptr<GCMClientFactory> gcm_client_factory,
62 const GCMClient::ChromeBuildInfo& chrome_build_info,
63 const base::FilePath& store_path,
64 const scoped_refptr<net::URLRequestContextGetter>& request_context,
65 const scoped_refptr<base::SequencedTaskRunner> blocking_task_runner);
66 void Start(const base::WeakPtr<GCMDriverDesktop>& service);
67 void Stop();
68 void CheckOut();
69 void Register(const std::string& app_id,
70 const std::vector<std::string>& sender_ids);
71 void Unregister(const std::string& app_id);
72 void Send(const std::string& app_id,
73 const std::string& receiver_id,
74 const GCMClient::OutgoingMessage& message);
75 void GetGCMStatistics(bool clear_logs);
76 void SetGCMRecording(bool recording);
78 void SetAccountsForCheckin(
79 const std::map<std::string, std::string>& account_tokens);
80 void UpdateAccountMapping(const AccountMapping& account_mapping);
81 void RemoveAccountMapping(const std::string& account_id);
83 // For testing purpose. Can be called from UI thread. Use with care.
84 GCMClient* gcm_client_for_testing() const { return gcm_client_.get(); }
86 private:
87 scoped_refptr<base::SequencedTaskRunner> ui_thread_;
88 scoped_refptr<base::SequencedTaskRunner> io_thread_;
90 base::WeakPtr<GCMDriverDesktop> service_;
92 scoped_ptr<GCMClient> gcm_client_;
94 DISALLOW_COPY_AND_ASSIGN(IOWorker);
97 GCMDriverDesktop::IOWorker::IOWorker(
98 const scoped_refptr<base::SequencedTaskRunner>& ui_thread,
99 const scoped_refptr<base::SequencedTaskRunner>& io_thread)
100 : ui_thread_(ui_thread),
101 io_thread_(io_thread) {
102 DCHECK(ui_thread_->RunsTasksOnCurrentThread());
105 GCMDriverDesktop::IOWorker::~IOWorker() {
106 DCHECK(io_thread_->RunsTasksOnCurrentThread());
109 void GCMDriverDesktop::IOWorker::Initialize(
110 scoped_ptr<GCMClientFactory> gcm_client_factory,
111 const GCMClient::ChromeBuildInfo& chrome_build_info,
112 const base::FilePath& store_path,
113 const scoped_refptr<net::URLRequestContextGetter>& request_context,
114 const scoped_refptr<base::SequencedTaskRunner> blocking_task_runner) {
115 DCHECK(io_thread_->RunsTasksOnCurrentThread());
117 gcm_client_ = gcm_client_factory->BuildInstance();
119 gcm_client_->Initialize(chrome_build_info,
120 store_path,
121 blocking_task_runner,
122 request_context,
123 make_scoped_ptr<Encryptor>(new SystemEncryptor),
124 this);
127 void GCMDriverDesktop::IOWorker::OnRegisterFinished(
128 const std::string& app_id,
129 const std::string& registration_id,
130 GCMClient::Result result) {
131 DCHECK(io_thread_->RunsTasksOnCurrentThread());
133 ui_thread_->PostTask(
134 FROM_HERE,
135 base::Bind(&GCMDriverDesktop::RegisterFinished, service_, app_id,
136 registration_id, result));
139 void GCMDriverDesktop::IOWorker::OnUnregisterFinished(
140 const std::string& app_id,
141 GCMClient::Result result) {
142 DCHECK(io_thread_->RunsTasksOnCurrentThread());
144 ui_thread_->PostTask(FROM_HERE,
145 base::Bind(&GCMDriverDesktop::UnregisterFinished,
146 service_,
147 app_id,
148 result));
151 void GCMDriverDesktop::IOWorker::OnSendFinished(const std::string& app_id,
152 const std::string& message_id,
153 GCMClient::Result result) {
154 DCHECK(io_thread_->RunsTasksOnCurrentThread());
156 ui_thread_->PostTask(
157 FROM_HERE,
158 base::Bind(&GCMDriverDesktop::SendFinished, service_, app_id, message_id,
159 result));
162 void GCMDriverDesktop::IOWorker::OnMessageReceived(
163 const std::string& app_id,
164 const GCMClient::IncomingMessage& message) {
165 DCHECK(io_thread_->RunsTasksOnCurrentThread());
167 ui_thread_->PostTask(
168 FROM_HERE,
169 base::Bind(&GCMDriverDesktop::MessageReceived,
170 service_,
171 app_id,
172 message));
175 void GCMDriverDesktop::IOWorker::OnMessagesDeleted(const std::string& app_id) {
176 DCHECK(io_thread_->RunsTasksOnCurrentThread());
178 ui_thread_->PostTask(
179 FROM_HERE,
180 base::Bind(&GCMDriverDesktop::MessagesDeleted, service_, app_id));
183 void GCMDriverDesktop::IOWorker::OnMessageSendError(
184 const std::string& app_id,
185 const GCMClient::SendErrorDetails& send_error_details) {
186 DCHECK(io_thread_->RunsTasksOnCurrentThread());
188 ui_thread_->PostTask(
189 FROM_HERE,
190 base::Bind(&GCMDriverDesktop::MessageSendError, service_, app_id,
191 send_error_details));
194 void GCMDriverDesktop::IOWorker::OnSendAcknowledged(
195 const std::string& app_id,
196 const std::string& message_id) {
197 DCHECK(io_thread_->RunsTasksOnCurrentThread());
199 ui_thread_->PostTask(
200 FROM_HERE,
201 base::Bind(
202 &GCMDriverDesktop::SendAcknowledged, service_, app_id, message_id));
205 void GCMDriverDesktop::IOWorker::OnGCMReady(
206 const std::vector<AccountMapping>& account_mappings) {
207 ui_thread_->PostTask(
208 FROM_HERE,
209 base::Bind(
210 &GCMDriverDesktop::GCMClientReady, service_, account_mappings));
213 void GCMDriverDesktop::IOWorker::OnActivityRecorded() {
214 DCHECK(io_thread_->RunsTasksOnCurrentThread());
215 // When an activity is recorded, get all the stats and refresh the UI of
216 // gcm-internals page.
217 GetGCMStatistics(false);
220 void GCMDriverDesktop::IOWorker::OnConnected(
221 const net::IPEndPoint& ip_endpoint) {
222 ui_thread_->PostTask(FROM_HERE,
223 base::Bind(&GCMDriverDesktop::OnConnected,
224 service_,
225 ip_endpoint));
228 void GCMDriverDesktop::IOWorker::OnDisconnected() {
229 ui_thread_->PostTask(FROM_HERE,
230 base::Bind(&GCMDriverDesktop::OnDisconnected, service_));
233 void GCMDriverDesktop::IOWorker::Start(
234 const base::WeakPtr<GCMDriverDesktop>& service) {
235 DCHECK(io_thread_->RunsTasksOnCurrentThread());
237 service_ = service;
238 gcm_client_->Start();
241 void GCMDriverDesktop::IOWorker::Stop() {
242 DCHECK(io_thread_->RunsTasksOnCurrentThread());
244 gcm_client_->Stop();
247 void GCMDriverDesktop::IOWorker::CheckOut() {
248 DCHECK(io_thread_->RunsTasksOnCurrentThread());
250 gcm_client_->CheckOut();
252 // Note that we still need to keep GCMClient instance alive since the
253 // GCMDriverDesktop may check in again.
256 void GCMDriverDesktop::IOWorker::Register(
257 const std::string& app_id,
258 const std::vector<std::string>& sender_ids) {
259 DCHECK(io_thread_->RunsTasksOnCurrentThread());
261 gcm_client_->Register(app_id, sender_ids);
264 void GCMDriverDesktop::IOWorker::Unregister(const std::string& app_id) {
265 DCHECK(io_thread_->RunsTasksOnCurrentThread());
267 gcm_client_->Unregister(app_id);
270 void GCMDriverDesktop::IOWorker::Send(
271 const std::string& app_id,
272 const std::string& receiver_id,
273 const GCMClient::OutgoingMessage& message) {
274 DCHECK(io_thread_->RunsTasksOnCurrentThread());
276 gcm_client_->Send(app_id, receiver_id, message);
279 void GCMDriverDesktop::IOWorker::GetGCMStatistics(bool clear_logs) {
280 DCHECK(io_thread_->RunsTasksOnCurrentThread());
281 gcm::GCMClient::GCMStatistics stats;
283 if (gcm_client_.get()) {
284 if (clear_logs)
285 gcm_client_->ClearActivityLogs();
286 stats = gcm_client_->GetStatistics();
289 ui_thread_->PostTask(
290 FROM_HERE,
291 base::Bind(&GCMDriverDesktop::GetGCMStatisticsFinished, service_, stats));
294 void GCMDriverDesktop::IOWorker::SetGCMRecording(bool recording) {
295 DCHECK(io_thread_->RunsTasksOnCurrentThread());
296 gcm::GCMClient::GCMStatistics stats;
298 if (gcm_client_.get()) {
299 gcm_client_->SetRecording(recording);
300 stats = gcm_client_->GetStatistics();
301 stats.gcm_client_created = true;
304 ui_thread_->PostTask(
305 FROM_HERE,
306 base::Bind(&GCMDriverDesktop::GetGCMStatisticsFinished, service_, stats));
309 void GCMDriverDesktop::IOWorker::SetAccountsForCheckin(
310 const std::map<std::string, std::string>& account_tokens) {
311 DCHECK(io_thread_->RunsTasksOnCurrentThread());
313 if (gcm_client_.get())
314 gcm_client_->SetAccountsForCheckin(account_tokens);
317 void GCMDriverDesktop::IOWorker::UpdateAccountMapping(
318 const AccountMapping& account_mapping) {
319 DCHECK(io_thread_->RunsTasksOnCurrentThread());
321 if (gcm_client_.get())
322 gcm_client_->UpdateAccountMapping(account_mapping);
325 void GCMDriverDesktop::IOWorker::RemoveAccountMapping(
326 const std::string& account_id) {
327 DCHECK(io_thread_->RunsTasksOnCurrentThread());
329 if (gcm_client_.get())
330 gcm_client_->RemoveAccountMapping(account_id);
333 GCMDriverDesktop::GCMDriverDesktop(
334 scoped_ptr<GCMClientFactory> gcm_client_factory,
335 const GCMClient::ChromeBuildInfo& chrome_build_info,
336 PrefService* prefs,
337 const base::FilePath& store_path,
338 const scoped_refptr<net::URLRequestContextGetter>& request_context,
339 const scoped_refptr<base::SequencedTaskRunner>& ui_thread,
340 const scoped_refptr<base::SequencedTaskRunner>& io_thread,
341 const scoped_refptr<base::SequencedTaskRunner>& blocking_task_runner)
342 : gcm_channel_status_syncer_(
343 new GCMChannelStatusSyncer(this, prefs, request_context)),
344 signed_in_(false),
345 gcm_started_(false),
346 gcm_enabled_(true),
347 connected_(false),
348 ui_thread_(ui_thread),
349 io_thread_(io_thread),
350 weak_ptr_factory_(this) {
351 gcm_enabled_ = gcm_channel_status_syncer_->gcm_enabled();
353 // Create and initialize the GCMClient. Note that this does not initiate the
354 // GCM check-in.
355 io_worker_.reset(new IOWorker(ui_thread, io_thread));
356 io_thread_->PostTask(
357 FROM_HERE,
358 base::Bind(&GCMDriverDesktop::IOWorker::Initialize,
359 base::Unretained(io_worker_.get()),
360 base::Passed(&gcm_client_factory),
361 chrome_build_info,
362 store_path,
363 request_context,
364 blocking_task_runner));
367 GCMDriverDesktop::~GCMDriverDesktop() {
370 void GCMDriverDesktop::Shutdown() {
371 DCHECK(ui_thread_->RunsTasksOnCurrentThread());
372 GCMDriver::Shutdown();
374 // Dispose the syncer in order to release the reference to
375 // URLRequestContextGetter that needs to be done before IOThread gets
376 // deleted.
377 gcm_channel_status_syncer_.reset();
379 io_thread_->DeleteSoon(FROM_HERE, io_worker_.release());
382 void GCMDriverDesktop::OnSignedIn() {
383 signed_in_ = true;
384 EnsureStarted();
387 void GCMDriverDesktop::OnSignedOut() {
388 signed_in_ = false;
390 // When sign-in enforcement is dropped, we will no longer wipe out the GCM
391 // data when the user signs out.
392 if (!GCMDriver::IsAllowedForAllUsers())
393 Purge();
396 void GCMDriverDesktop::Purge() {
397 DCHECK(ui_thread_->RunsTasksOnCurrentThread());
399 RemoveCachedData();
401 io_thread_->PostTask(FROM_HERE,
402 base::Bind(&GCMDriverDesktop::IOWorker::CheckOut,
403 base::Unretained(io_worker_.get())));
406 void GCMDriverDesktop::AddAppHandler(const std::string& app_id,
407 GCMAppHandler* handler) {
408 DCHECK(ui_thread_->RunsTasksOnCurrentThread());
409 GCMDriver::AddAppHandler(app_id, handler);
411 // Ensures that the GCM service is started when there is an interest.
412 EnsureStarted();
415 void GCMDriverDesktop::RemoveAppHandler(const std::string& app_id) {
416 DCHECK(ui_thread_->RunsTasksOnCurrentThread());
417 GCMDriver::RemoveAppHandler(app_id);
419 // Stops the GCM service when no app intends to consume it.
420 if (app_handlers().empty())
421 Stop();
424 void GCMDriverDesktop::AddConnectionObserver(GCMConnectionObserver* observer) {
425 connection_observer_list_.AddObserver(observer);
428 void GCMDriverDesktop::RemoveConnectionObserver(
429 GCMConnectionObserver* observer) {
430 connection_observer_list_.RemoveObserver(observer);
433 void GCMDriverDesktop::Enable() {
434 DCHECK(ui_thread_->RunsTasksOnCurrentThread());
436 if (gcm_enabled_)
437 return;
438 gcm_enabled_ = true;
440 EnsureStarted();
443 void GCMDriverDesktop::Disable() {
444 DCHECK(ui_thread_->RunsTasksOnCurrentThread());
446 if (!gcm_enabled_)
447 return;
448 gcm_enabled_ = false;
450 Stop();
453 void GCMDriverDesktop::Stop() {
454 DCHECK(ui_thread_->RunsTasksOnCurrentThread());
456 // No need to stop GCM service if not started yet.
457 if (!gcm_started_)
458 return;
460 gcm_channel_status_syncer_->Stop();
462 RemoveCachedData();
464 io_thread_->PostTask(
465 FROM_HERE,
466 base::Bind(&GCMDriverDesktop::IOWorker::Stop,
467 base::Unretained(io_worker_.get())));
470 void GCMDriverDesktop::RegisterImpl(
471 const std::string& app_id,
472 const std::vector<std::string>& sender_ids) {
473 // Delay the register operation until GCMClient is ready.
474 if (!delayed_task_controller_->CanRunTaskWithoutDelay()) {
475 delayed_task_controller_->AddTask(base::Bind(&GCMDriverDesktop::DoRegister,
476 weak_ptr_factory_.GetWeakPtr(),
477 app_id,
478 sender_ids));
479 return;
482 DoRegister(app_id, sender_ids);
485 void GCMDriverDesktop::DoRegister(const std::string& app_id,
486 const std::vector<std::string>& sender_ids) {
487 DCHECK(ui_thread_->RunsTasksOnCurrentThread());
488 if (!HasRegisterCallback(app_id)) {
489 // The callback could have been removed when the app is uninstalled.
490 return;
493 io_thread_->PostTask(
494 FROM_HERE,
495 base::Bind(&GCMDriverDesktop::IOWorker::Register,
496 base::Unretained(io_worker_.get()),
497 app_id,
498 sender_ids));
501 void GCMDriverDesktop::UnregisterImpl(const std::string& app_id) {
502 // Delay the unregister operation until GCMClient is ready.
503 if (!delayed_task_controller_->CanRunTaskWithoutDelay()) {
504 delayed_task_controller_->AddTask(
505 base::Bind(&GCMDriverDesktop::DoUnregister,
506 weak_ptr_factory_.GetWeakPtr(),
507 app_id));
508 return;
511 DoUnregister(app_id);
514 void GCMDriverDesktop::DoUnregister(const std::string& app_id) {
515 DCHECK(ui_thread_->RunsTasksOnCurrentThread());
517 // Ask the server to unregister it. There could be a small chance that the
518 // unregister request fails. If this occurs, it does not bring any harm since
519 // we simply reject the messages/events received from the server.
520 io_thread_->PostTask(
521 FROM_HERE,
522 base::Bind(&GCMDriverDesktop::IOWorker::Unregister,
523 base::Unretained(io_worker_.get()),
524 app_id));
527 void GCMDriverDesktop::SendImpl(const std::string& app_id,
528 const std::string& receiver_id,
529 const GCMClient::OutgoingMessage& message) {
530 // Delay the send operation until all GCMClient is ready.
531 if (!delayed_task_controller_->CanRunTaskWithoutDelay()) {
532 delayed_task_controller_->AddTask(base::Bind(&GCMDriverDesktop::DoSend,
533 weak_ptr_factory_.GetWeakPtr(),
534 app_id,
535 receiver_id,
536 message));
537 return;
540 DoSend(app_id, receiver_id, message);
543 void GCMDriverDesktop::DoSend(const std::string& app_id,
544 const std::string& receiver_id,
545 const GCMClient::OutgoingMessage& message) {
546 DCHECK(ui_thread_->RunsTasksOnCurrentThread());
547 io_thread_->PostTask(
548 FROM_HERE,
549 base::Bind(&GCMDriverDesktop::IOWorker::Send,
550 base::Unretained(io_worker_.get()),
551 app_id,
552 receiver_id,
553 message));
556 GCMClient* GCMDriverDesktop::GetGCMClientForTesting() const {
557 DCHECK(ui_thread_->RunsTasksOnCurrentThread());
558 return io_worker_ ? io_worker_->gcm_client_for_testing() : NULL;
561 bool GCMDriverDesktop::IsStarted() const {
562 DCHECK(ui_thread_->RunsTasksOnCurrentThread());
563 return gcm_started_;
566 bool GCMDriverDesktop::IsConnected() const {
567 return connected_;
570 void GCMDriverDesktop::GetGCMStatistics(
571 const GetGCMStatisticsCallback& callback,
572 bool clear_logs) {
573 DCHECK(ui_thread_->RunsTasksOnCurrentThread());
574 DCHECK(!callback.is_null());
576 request_gcm_statistics_callback_ = callback;
577 io_thread_->PostTask(
578 FROM_HERE,
579 base::Bind(&GCMDriverDesktop::IOWorker::GetGCMStatistics,
580 base::Unretained(io_worker_.get()),
581 clear_logs));
584 void GCMDriverDesktop::SetGCMRecording(const GetGCMStatisticsCallback& callback,
585 bool recording) {
586 DCHECK(ui_thread_->RunsTasksOnCurrentThread());
588 request_gcm_statistics_callback_ = callback;
589 io_thread_->PostTask(
590 FROM_HERE,
591 base::Bind(&GCMDriverDesktop::IOWorker::SetGCMRecording,
592 base::Unretained(io_worker_.get()),
593 recording));
596 void GCMDriverDesktop::UpdateAccountMapping(
597 const AccountMapping& account_mapping) {
598 DCHECK(ui_thread_->RunsTasksOnCurrentThread());
600 io_thread_->PostTask(
601 FROM_HERE,
602 base::Bind(&GCMDriverDesktop::IOWorker::UpdateAccountMapping,
603 base::Unretained(io_worker_.get()),
604 account_mapping));
607 void GCMDriverDesktop::RemoveAccountMapping(const std::string& account_id) {
608 DCHECK(ui_thread_->RunsTasksOnCurrentThread());
610 io_thread_->PostTask(
611 FROM_HERE,
612 base::Bind(&GCMDriverDesktop::IOWorker::RemoveAccountMapping,
613 base::Unretained(io_worker_.get()),
614 account_id));
617 void GCMDriverDesktop::SetAccountsForCheckin(
618 const std::map<std::string, std::string>& account_tokens) {
619 DCHECK(ui_thread_->RunsTasksOnCurrentThread());
621 io_thread_->PostTask(
622 FROM_HERE,
623 base::Bind(&GCMDriverDesktop::IOWorker::SetAccountsForCheckin,
624 base::Unretained(io_worker_.get()),
625 account_tokens));
628 GCMClient::Result GCMDriverDesktop::EnsureStarted() {
629 DCHECK(ui_thread_->RunsTasksOnCurrentThread());
631 if (gcm_started_)
632 return GCMClient::SUCCESS;
634 if (!gcm_enabled_)
635 return GCMClient::GCM_DISABLED;
637 // Have any app requested the service?
638 if (app_handlers().empty())
639 return GCMClient::UNKNOWN_ERROR;
641 if (!signed_in_ && !GCMDriver::IsAllowedForAllUsers())
642 return GCMClient::NOT_SIGNED_IN;
644 DCHECK(!delayed_task_controller_);
645 delayed_task_controller_.reset(new GCMDelayedTaskController);
647 // Polling for channel status is only needed when GCM is supported for all
648 // users.
649 if (GCMDriver::IsAllowedForAllUsers())
650 gcm_channel_status_syncer_->EnsureStarted();
652 // Note that we need to pass weak pointer again since the existing weak
653 // pointer in IOWorker might have been invalidated when check-out occurs.
654 io_thread_->PostTask(
655 FROM_HERE,
656 base::Bind(&GCMDriverDesktop::IOWorker::Start,
657 base::Unretained(io_worker_.get()),
658 weak_ptr_factory_.GetWeakPtr()));
660 gcm_started_ = true;
661 return GCMClient::SUCCESS;
664 void GCMDriverDesktop::RemoveCachedData() {
665 DCHECK(ui_thread_->RunsTasksOnCurrentThread());
666 // Remove all the queued tasks since they no longer make sense after
667 // GCM service is stopped.
668 weak_ptr_factory_.InvalidateWeakPtrs();
670 gcm_started_ = false;
671 delayed_task_controller_.reset();
672 ClearCallbacks();
675 void GCMDriverDesktop::MessageReceived(
676 const std::string& app_id,
677 const GCMClient::IncomingMessage& message) {
678 DCHECK(ui_thread_->RunsTasksOnCurrentThread());
680 // Drop the event if the service has been stopped.
681 if (!gcm_started_)
682 return;
684 GetAppHandler(app_id)->OnMessage(app_id, message);
687 void GCMDriverDesktop::MessagesDeleted(const std::string& app_id) {
688 DCHECK(ui_thread_->RunsTasksOnCurrentThread());
690 // Drop the event if the service has been stopped.
691 if (!gcm_started_)
692 return;
694 GetAppHandler(app_id)->OnMessagesDeleted(app_id);
697 void GCMDriverDesktop::MessageSendError(
698 const std::string& app_id,
699 const GCMClient::SendErrorDetails& send_error_details) {
700 DCHECK(ui_thread_->RunsTasksOnCurrentThread());
702 // Drop the event if the service has been stopped.
703 if (!gcm_started_)
704 return;
706 GetAppHandler(app_id)->OnSendError(app_id, send_error_details);
709 void GCMDriverDesktop::SendAcknowledged(const std::string& app_id,
710 const std::string& message_id) {
711 DCHECK(ui_thread_->RunsTasksOnCurrentThread());
713 // Drop the event if the service has been stopped.
714 if (!gcm_started_)
715 return;
717 GetAppHandler(app_id)->OnSendAcknowledged(app_id, message_id);
720 void GCMDriverDesktop::GCMClientReady(
721 const std::vector<AccountMapping>& account_mappings) {
722 DCHECK(ui_thread_->RunsTasksOnCurrentThread());
724 delayed_task_controller_->SetReady();
727 void GCMDriverDesktop::OnConnected(const net::IPEndPoint& ip_endpoint) {
728 DCHECK(ui_thread_->RunsTasksOnCurrentThread());
730 connected_ = true;
732 // Drop the event if the service has been stopped.
733 if (!gcm_started_)
734 return;
736 FOR_EACH_OBSERVER(GCMConnectionObserver,
737 connection_observer_list_,
738 OnConnected(ip_endpoint));
741 void GCMDriverDesktop::OnDisconnected() {
742 DCHECK(ui_thread_->RunsTasksOnCurrentThread());
744 connected_ = false;
746 // Drop the event if the service has been stopped.
747 if (!gcm_started_)
748 return;
750 FOR_EACH_OBSERVER(
751 GCMConnectionObserver, connection_observer_list_, OnDisconnected());
754 void GCMDriverDesktop::GetGCMStatisticsFinished(
755 const GCMClient::GCMStatistics& stats) {
756 DCHECK(ui_thread_->RunsTasksOnCurrentThread());
758 // Normally request_gcm_statistics_callback_ would not be null.
759 if (!request_gcm_statistics_callback_.is_null())
760 request_gcm_statistics_callback_.Run(stats);
761 else
762 LOG(WARNING) << "request_gcm_statistics_callback_ is NULL.";
765 } // namespace gcm