gcm_driver_desktop.cc revision 1320f92c476a1ad9d19dba2a48c72b75566198e9
146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// found in the LICENSE file.
446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "components/gcm_driver/gcm_driver_desktop.h"
646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include <utility>
846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "base/bind.h"
1046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "base/bind_helpers.h"
1146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "base/files/file_path.h"
1246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "base/location.h"
1346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "base/logging.h"
141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/metrics/histogram.h"
1546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "base/sequenced_task_runner.h"
1646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "base/threading/sequenced_worker_pool.h"
1746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "components/gcm_driver/gcm_app_handler.h"
181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "components/gcm_driver/gcm_channel_status_syncer.h"
1946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "components/gcm_driver/gcm_client_factory.h"
201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "components/gcm_driver/gcm_delayed_task_controller.h"
2146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "components/gcm_driver/system_encryptor.h"
2203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "google_apis/gcm/engine/account_mapping.h"
23f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "net/base/ip_endpoint.h"
2446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "net/url_request/url_request_context_getter.h"
2546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
2646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)namespace gcm {
2746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
2846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)class GCMDriverDesktop::IOWorker : public GCMClient::Delegate {
2946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) public:
3046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Called on UI thread.
3146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  IOWorker(const scoped_refptr<base::SequencedTaskRunner>& ui_thread,
3246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)           const scoped_refptr<base::SequencedTaskRunner>& io_thread);
3346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  virtual ~IOWorker();
3446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
3546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Overridden from GCMClient::Delegate:
3646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Called on IO thread.
3746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  virtual void OnRegisterFinished(const std::string& app_id,
3846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                  const std::string& registration_id,
3946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                  GCMClient::Result result) OVERRIDE;
4046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  virtual void OnUnregisterFinished(const std::string& app_id,
4146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                    GCMClient::Result result) OVERRIDE;
4246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  virtual void OnSendFinished(const std::string& app_id,
4346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                              const std::string& message_id,
4446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                              GCMClient::Result result) OVERRIDE;
4546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  virtual void OnMessageReceived(
4646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      const std::string& app_id,
4746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      const GCMClient::IncomingMessage& message) OVERRIDE;
4846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  virtual void OnMessagesDeleted(const std::string& app_id) OVERRIDE;
4946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  virtual void OnMessageSendError(
5046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      const std::string& app_id,
5146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      const GCMClient::SendErrorDetails& send_error_details) OVERRIDE;
525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  virtual void OnSendAcknowledged(const std::string& app_id,
535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                  const std::string& message_id) OVERRIDE;
541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  virtual void OnGCMReady(
551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      const std::vector<AccountMapping>& account_mappings) OVERRIDE;
5646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  virtual void OnActivityRecorded() OVERRIDE;
57f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  virtual void OnConnected(const net::IPEndPoint& ip_endpoint) OVERRIDE;
58f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  virtual void OnDisconnected() OVERRIDE;
5946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
6046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Called on IO thread.
6146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  void Initialize(
6246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      scoped_ptr<GCMClientFactory> gcm_client_factory,
6346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      const GCMClient::ChromeBuildInfo& chrome_build_info,
6446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      const base::FilePath& store_path,
6546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      const scoped_refptr<net::URLRequestContextGetter>& request_context,
6646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      const scoped_refptr<base::SequencedTaskRunner> blocking_task_runner);
6746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  void Start(const base::WeakPtr<GCMDriverDesktop>& service);
6846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  void Stop();
6946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  void CheckOut();
7046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  void Register(const std::string& app_id,
7146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                const std::vector<std::string>& sender_ids);
7246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  void Unregister(const std::string& app_id);
7346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  void Send(const std::string& app_id,
7446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)            const std::string& receiver_id,
7546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)            const GCMClient::OutgoingMessage& message);
7646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  void GetGCMStatistics(bool clear_logs);
7746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  void SetGCMRecording(bool recording);
7846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
79116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  void SetAccountsForCheckin(
80116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      const std::map<std::string, std::string>& account_tokens);
8103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  void UpdateAccountMapping(const AccountMapping& account_mapping);
8203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  void RemoveAccountMapping(const std::string& account_id);
83116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
8446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // For testing purpose. Can be called from UI thread. Use with care.
8546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  GCMClient* gcm_client_for_testing() const { return gcm_client_.get(); }
8646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
8746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) private:
8846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  scoped_refptr<base::SequencedTaskRunner> ui_thread_;
8946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  scoped_refptr<base::SequencedTaskRunner> io_thread_;
9046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
9146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  base::WeakPtr<GCMDriverDesktop> service_;
9246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
9346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  scoped_ptr<GCMClient> gcm_client_;
9446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
9546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(IOWorker);
9646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)};
9746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
9846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)GCMDriverDesktop::IOWorker::IOWorker(
9946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    const scoped_refptr<base::SequencedTaskRunner>& ui_thread,
10046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    const scoped_refptr<base::SequencedTaskRunner>& io_thread)
10146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    : ui_thread_(ui_thread),
10246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      io_thread_(io_thread) {
10346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  DCHECK(ui_thread_->RunsTasksOnCurrentThread());
10446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
10546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
10646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)GCMDriverDesktop::IOWorker::~IOWorker() {
10746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  DCHECK(io_thread_->RunsTasksOnCurrentThread());
10846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
10946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
11046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void GCMDriverDesktop::IOWorker::Initialize(
11146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    scoped_ptr<GCMClientFactory> gcm_client_factory,
11246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    const GCMClient::ChromeBuildInfo& chrome_build_info,
11346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    const base::FilePath& store_path,
11446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    const scoped_refptr<net::URLRequestContextGetter>& request_context,
11546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    const scoped_refptr<base::SequencedTaskRunner> blocking_task_runner) {
11646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  DCHECK(io_thread_->RunsTasksOnCurrentThread());
11746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
11846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  gcm_client_ = gcm_client_factory->BuildInstance();
11946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
12046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  gcm_client_->Initialize(chrome_build_info,
12146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                          store_path,
12246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                          blocking_task_runner,
12346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                          request_context,
12446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                          make_scoped_ptr<Encryptor>(new SystemEncryptor),
12546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                          this);
12646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
12746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
12846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void GCMDriverDesktop::IOWorker::OnRegisterFinished(
12946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    const std::string& app_id,
13046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    const std::string& registration_id,
13146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    GCMClient::Result result) {
13246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  DCHECK(io_thread_->RunsTasksOnCurrentThread());
13346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
13446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ui_thread_->PostTask(
13546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      FROM_HERE,
13646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      base::Bind(&GCMDriverDesktop::RegisterFinished, service_, app_id,
13746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                 registration_id, result));
13846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
13946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
14046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void GCMDriverDesktop::IOWorker::OnUnregisterFinished(
14146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    const std::string& app_id,
14246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    GCMClient::Result result) {
14346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  DCHECK(io_thread_->RunsTasksOnCurrentThread());
14446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
14546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ui_thread_->PostTask(FROM_HERE,
14646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                       base::Bind(&GCMDriverDesktop::UnregisterFinished,
14746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                  service_,
14846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                  app_id,
14946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                  result));
15046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
15146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
15246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void GCMDriverDesktop::IOWorker::OnSendFinished(const std::string& app_id,
15346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                                const std::string& message_id,
15446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                                GCMClient::Result result) {
15546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  DCHECK(io_thread_->RunsTasksOnCurrentThread());
15646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
15746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ui_thread_->PostTask(
15846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      FROM_HERE,
15946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      base::Bind(&GCMDriverDesktop::SendFinished, service_, app_id, message_id,
16046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                 result));
16146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
16246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
16346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void GCMDriverDesktop::IOWorker::OnMessageReceived(
16446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    const std::string& app_id,
16546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    const GCMClient::IncomingMessage& message) {
16646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  DCHECK(io_thread_->RunsTasksOnCurrentThread());
16746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
16846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ui_thread_->PostTask(
16946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      FROM_HERE,
17046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      base::Bind(&GCMDriverDesktop::MessageReceived,
17146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                 service_,
17246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                 app_id,
17346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                 message));
17446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
17546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
17646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void GCMDriverDesktop::IOWorker::OnMessagesDeleted(const std::string& app_id) {
17746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  DCHECK(io_thread_->RunsTasksOnCurrentThread());
17846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
17946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ui_thread_->PostTask(
18046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      FROM_HERE,
18146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      base::Bind(&GCMDriverDesktop::MessagesDeleted, service_, app_id));
18246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
18346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
18446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void GCMDriverDesktop::IOWorker::OnMessageSendError(
18546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    const std::string& app_id,
18646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    const GCMClient::SendErrorDetails& send_error_details) {
18746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  DCHECK(io_thread_->RunsTasksOnCurrentThread());
18846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
18946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ui_thread_->PostTask(
19046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      FROM_HERE,
19146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      base::Bind(&GCMDriverDesktop::MessageSendError, service_, app_id,
19246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                 send_error_details));
19346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
19446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
1955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void GCMDriverDesktop::IOWorker::OnSendAcknowledged(
1965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    const std::string& app_id,
1975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    const std::string& message_id) {
1985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DCHECK(io_thread_->RunsTasksOnCurrentThread());
1995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ui_thread_->PostTask(
2015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      FROM_HERE,
2025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      base::Bind(
2035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          &GCMDriverDesktop::SendAcknowledged, service_, app_id, message_id));
2045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
2055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid GCMDriverDesktop::IOWorker::OnGCMReady(
2071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const std::vector<AccountMapping>& account_mappings) {
20846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ui_thread_->PostTask(
20946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      FROM_HERE,
2101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      base::Bind(
2111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          &GCMDriverDesktop::GCMClientReady, service_, account_mappings));
21246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
21346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
21446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void GCMDriverDesktop::IOWorker::OnActivityRecorded() {
21546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  DCHECK(io_thread_->RunsTasksOnCurrentThread());
21646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // When an activity is recorded, get all the stats and refresh the UI of
21746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // gcm-internals page.
21846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  GetGCMStatistics(false);
21946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
22046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
221f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void GCMDriverDesktop::IOWorker::OnConnected(
222f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    const net::IPEndPoint& ip_endpoint) {
223f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  ui_thread_->PostTask(FROM_HERE,
224f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                       base::Bind(&GCMDriverDesktop::OnConnected,
225f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                                  service_,
226f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                                  ip_endpoint));
227f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
228f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
229f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void GCMDriverDesktop::IOWorker::OnDisconnected() {
230f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  ui_thread_->PostTask(FROM_HERE,
231f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                       base::Bind(&GCMDriverDesktop::OnDisconnected, service_));
232f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
233f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
23446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void GCMDriverDesktop::IOWorker::Start(
23546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    const base::WeakPtr<GCMDriverDesktop>& service) {
23646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  DCHECK(io_thread_->RunsTasksOnCurrentThread());
23746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
23846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  service_ = service;
23946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  gcm_client_->Start();
24046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
24146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
24246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void GCMDriverDesktop::IOWorker::Stop() {
24346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  DCHECK(io_thread_->RunsTasksOnCurrentThread());
24446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
24546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  gcm_client_->Stop();
24646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
24746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
24846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void GCMDriverDesktop::IOWorker::CheckOut() {
24946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  DCHECK(io_thread_->RunsTasksOnCurrentThread());
25046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
25146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  gcm_client_->CheckOut();
25246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
25346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Note that we still need to keep GCMClient instance alive since the
25446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // GCMDriverDesktop may check in again.
25546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
25646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
25746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void GCMDriverDesktop::IOWorker::Register(
25846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    const std::string& app_id,
25946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    const std::vector<std::string>& sender_ids) {
26046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  DCHECK(io_thread_->RunsTasksOnCurrentThread());
26146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
26246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  gcm_client_->Register(app_id, sender_ids);
26346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
26446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
26546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void GCMDriverDesktop::IOWorker::Unregister(const std::string& app_id) {
26646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  DCHECK(io_thread_->RunsTasksOnCurrentThread());
26746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
26846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  gcm_client_->Unregister(app_id);
26946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
27046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
27146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void GCMDriverDesktop::IOWorker::Send(
27246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    const std::string& app_id,
27346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    const std::string& receiver_id,
27446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    const GCMClient::OutgoingMessage& message) {
27546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  DCHECK(io_thread_->RunsTasksOnCurrentThread());
27646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
27746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  gcm_client_->Send(app_id, receiver_id, message);
27846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
27946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
28046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void GCMDriverDesktop::IOWorker::GetGCMStatistics(bool clear_logs) {
28146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  DCHECK(io_thread_->RunsTasksOnCurrentThread());
28246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  gcm::GCMClient::GCMStatistics stats;
28346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
28446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  if (gcm_client_.get()) {
28546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    if (clear_logs)
28646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      gcm_client_->ClearActivityLogs();
28746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    stats = gcm_client_->GetStatistics();
28846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
28946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
29046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ui_thread_->PostTask(
29146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      FROM_HERE,
29246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      base::Bind(&GCMDriverDesktop::GetGCMStatisticsFinished, service_, stats));
29346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
29446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
29546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void GCMDriverDesktop::IOWorker::SetGCMRecording(bool recording) {
29646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  DCHECK(io_thread_->RunsTasksOnCurrentThread());
29746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  gcm::GCMClient::GCMStatistics stats;
29846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
29946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  if (gcm_client_.get()) {
30046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    gcm_client_->SetRecording(recording);
30146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    stats = gcm_client_->GetStatistics();
30246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    stats.gcm_client_created = true;
30346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
30446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
30546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ui_thread_->PostTask(
30646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      FROM_HERE,
30746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      base::Bind(&GCMDriverDesktop::GetGCMStatisticsFinished, service_, stats));
30846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
30946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
310116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid GCMDriverDesktop::IOWorker::SetAccountsForCheckin(
311116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const std::map<std::string, std::string>& account_tokens) {
312116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DCHECK(io_thread_->RunsTasksOnCurrentThread());
313116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
314116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (gcm_client_.get())
315116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    gcm_client_->SetAccountsForCheckin(account_tokens);
316116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
317116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
31803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)void GCMDriverDesktop::IOWorker::UpdateAccountMapping(
31903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    const AccountMapping& account_mapping) {
32003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  DCHECK(io_thread_->RunsTasksOnCurrentThread());
32103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
32203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  if (gcm_client_.get())
32303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    gcm_client_->UpdateAccountMapping(account_mapping);
32403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}
32503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
32603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)void GCMDriverDesktop::IOWorker::RemoveAccountMapping(
32703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    const std::string& account_id) {
32803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  DCHECK(io_thread_->RunsTasksOnCurrentThread());
32903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
33003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  if (gcm_client_.get())
33103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    gcm_client_->RemoveAccountMapping(account_id);
33203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}
33303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
33446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)GCMDriverDesktop::GCMDriverDesktop(
33546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    scoped_ptr<GCMClientFactory> gcm_client_factory,
33646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    const GCMClient::ChromeBuildInfo& chrome_build_info,
3371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    PrefService* prefs,
33846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    const base::FilePath& store_path,
33946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    const scoped_refptr<net::URLRequestContextGetter>& request_context,
34046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    const scoped_refptr<base::SequencedTaskRunner>& ui_thread,
34146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    const scoped_refptr<base::SequencedTaskRunner>& io_thread,
34246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    const scoped_refptr<base::SequencedTaskRunner>& blocking_task_runner)
3431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    : gcm_channel_status_syncer_(
3441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          new GCMChannelStatusSyncer(this, prefs, request_context)),
3451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      signed_in_(false),
346f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      gcm_started_(false),
347f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      gcm_enabled_(true),
348f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      connected_(false),
34946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      ui_thread_(ui_thread),
35046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      io_thread_(io_thread),
35146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      weak_ptr_factory_(this) {
3521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  gcm_enabled_ = gcm_channel_status_syncer_->gcm_enabled();
3531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
35446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Create and initialize the GCMClient. Note that this does not initiate the
35546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // GCM check-in.
35646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  io_worker_.reset(new IOWorker(ui_thread, io_thread));
35746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  io_thread_->PostTask(
35846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      FROM_HERE,
35946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      base::Bind(&GCMDriverDesktop::IOWorker::Initialize,
36046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                 base::Unretained(io_worker_.get()),
36146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                 base::Passed(&gcm_client_factory),
36246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                 chrome_build_info,
36346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                 store_path,
36446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                 request_context,
36546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                 blocking_task_runner));
36646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
36746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
36846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)GCMDriverDesktop::~GCMDriverDesktop() {
36946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
37046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
371f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void GCMDriverDesktop::Shutdown() {
372f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  DCHECK(ui_thread_->RunsTasksOnCurrentThread());
373f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  GCMDriver::Shutdown();
3741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Dispose the syncer in order to release the reference to
3761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // URLRequestContextGetter that needs to be done before IOThread gets
3771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // deleted.
3781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  gcm_channel_status_syncer_.reset();
3791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
380f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  io_thread_->DeleteSoon(FROM_HERE, io_worker_.release());
38146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
38246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
383f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void GCMDriverDesktop::OnSignedIn() {
384f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  signed_in_ = true;
385f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EnsureStarted();
38646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
38746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
388f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void GCMDriverDesktop::Purge() {
38946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  DCHECK(ui_thread_->RunsTasksOnCurrentThread());
390f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
391f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // We still proceed with the check-out logic even if the check-in is not
392f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // initiated in the current session. This will make sure that all the
393f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // persisted data written previously will get purged.
394f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  signed_in_ = false;
395f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  RemoveCachedData();
396f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
397f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  io_thread_->PostTask(FROM_HERE,
398f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                       base::Bind(&GCMDriverDesktop::IOWorker::CheckOut,
399f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                       base::Unretained(io_worker_.get())));
40046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
40146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
40246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void GCMDriverDesktop::AddAppHandler(const std::string& app_id,
40346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                     GCMAppHandler* handler) {
40446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  DCHECK(ui_thread_->RunsTasksOnCurrentThread());
40546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  GCMDriver::AddAppHandler(app_id, handler);
40646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
40746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)   // Ensures that the GCM service is started when there is an interest.
40846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  EnsureStarted();
40946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
41046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
41146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void GCMDriverDesktop::RemoveAppHandler(const std::string& app_id) {
41246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  DCHECK(ui_thread_->RunsTasksOnCurrentThread());
41346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  GCMDriver::RemoveAppHandler(app_id);
41446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
41546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Stops the GCM service when no app intends to consume it.
41646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  if (app_handlers().empty())
41746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    Stop();
41846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
41946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
4201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid GCMDriverDesktop::AddConnectionObserver(GCMConnectionObserver* observer) {
4211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  connection_observer_list_.AddObserver(observer);
4221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
4231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
4241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid GCMDriverDesktop::RemoveConnectionObserver(
4251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    GCMConnectionObserver* observer) {
4261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  connection_observer_list_.RemoveObserver(observer);
4271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
4281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
42946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void GCMDriverDesktop::Enable() {
43046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  DCHECK(ui_thread_->RunsTasksOnCurrentThread());
43146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
43246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  if (gcm_enabled_)
43346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    return;
43446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  gcm_enabled_ = true;
43546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
43646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  EnsureStarted();
43746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
43846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
43946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void GCMDriverDesktop::Disable() {
44046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  DCHECK(ui_thread_->RunsTasksOnCurrentThread());
44146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
44246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  if (!gcm_enabled_)
44346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    return;
44446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  gcm_enabled_ = false;
44546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
44646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  Stop();
44746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
44846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
44946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void GCMDriverDesktop::Stop() {
45046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  DCHECK(ui_thread_->RunsTasksOnCurrentThread());
45146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
45246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // No need to stop GCM service if not started yet.
453f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (!gcm_started_)
45446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    return;
45546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
4561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  gcm_channel_status_syncer_->Stop();
4571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
45846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  RemoveCachedData();
45946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
46046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  io_thread_->PostTask(
46146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      FROM_HERE,
46246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      base::Bind(&GCMDriverDesktop::IOWorker::Stop,
46346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                 base::Unretained(io_worker_.get())));
46446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
46546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
46646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void GCMDriverDesktop::RegisterImpl(
46746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    const std::string& app_id,
46846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    const std::vector<std::string>& sender_ids) {
46946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Delay the register operation until GCMClient is ready.
47046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  if (!delayed_task_controller_->CanRunTaskWithoutDelay()) {
47146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    delayed_task_controller_->AddTask(base::Bind(&GCMDriverDesktop::DoRegister,
47246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                                 weak_ptr_factory_.GetWeakPtr(),
47346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                                 app_id,
47446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                                 sender_ids));
47546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    return;
47646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
47746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
47846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  DoRegister(app_id, sender_ids);
47946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
48046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
48146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void GCMDriverDesktop::DoRegister(const std::string& app_id,
48246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                  const std::vector<std::string>& sender_ids) {
48346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  DCHECK(ui_thread_->RunsTasksOnCurrentThread());
48446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  if (!HasRegisterCallback(app_id)) {
48546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    // The callback could have been removed when the app is uninstalled.
48646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    return;
48746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
48846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
48946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  io_thread_->PostTask(
49046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      FROM_HERE,
49146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      base::Bind(&GCMDriverDesktop::IOWorker::Register,
49246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                 base::Unretained(io_worker_.get()),
49346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                 app_id,
49446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                 sender_ids));
49546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
49646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
49746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void GCMDriverDesktop::UnregisterImpl(const std::string& app_id) {
49846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Delay the unregister operation until GCMClient is ready.
49946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  if (!delayed_task_controller_->CanRunTaskWithoutDelay()) {
50046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    delayed_task_controller_->AddTask(
50146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        base::Bind(&GCMDriverDesktop::DoUnregister,
50246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                   weak_ptr_factory_.GetWeakPtr(),
50346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                   app_id));
50446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    return;
50546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
50646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
50746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  DoUnregister(app_id);
50846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
50946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
51046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void GCMDriverDesktop::DoUnregister(const std::string& app_id) {
51146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  DCHECK(ui_thread_->RunsTasksOnCurrentThread());
51246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
51346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Ask the server to unregister it. There could be a small chance that the
51446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // unregister request fails. If this occurs, it does not bring any harm since
51546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // we simply reject the messages/events received from the server.
51646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  io_thread_->PostTask(
51746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      FROM_HERE,
51846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      base::Bind(&GCMDriverDesktop::IOWorker::Unregister,
51946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                 base::Unretained(io_worker_.get()),
52046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                 app_id));
52146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
52246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
52346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void GCMDriverDesktop::SendImpl(const std::string& app_id,
52446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                const std::string& receiver_id,
52546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                const GCMClient::OutgoingMessage& message) {
52646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Delay the send operation until all GCMClient is ready.
52746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  if (!delayed_task_controller_->CanRunTaskWithoutDelay()) {
52846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    delayed_task_controller_->AddTask(base::Bind(&GCMDriverDesktop::DoSend,
52946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                                 weak_ptr_factory_.GetWeakPtr(),
53046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                                 app_id,
53146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                                 receiver_id,
53246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                                 message));
53346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    return;
53446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
53546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
53646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  DoSend(app_id, receiver_id, message);
53746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
53846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
53946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void GCMDriverDesktop::DoSend(const std::string& app_id,
54046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                              const std::string& receiver_id,
54146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                              const GCMClient::OutgoingMessage& message) {
54246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  DCHECK(ui_thread_->RunsTasksOnCurrentThread());
54346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  io_thread_->PostTask(
54446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      FROM_HERE,
54546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      base::Bind(&GCMDriverDesktop::IOWorker::Send,
54646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                 base::Unretained(io_worker_.get()),
54746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                 app_id,
54846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                 receiver_id,
54946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                 message));
55046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
55146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
55246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)GCMClient* GCMDriverDesktop::GetGCMClientForTesting() const {
55346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  DCHECK(ui_thread_->RunsTasksOnCurrentThread());
55446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  return io_worker_ ? io_worker_->gcm_client_for_testing() : NULL;
55546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
55646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
55746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)bool GCMDriverDesktop::IsStarted() const {
55846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  DCHECK(ui_thread_->RunsTasksOnCurrentThread());
559f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  return gcm_started_;
56046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
56146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
562f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)bool GCMDriverDesktop::IsConnected() const {
563f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  return connected_;
564f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
565f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
56646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void GCMDriverDesktop::GetGCMStatistics(
56746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    const GetGCMStatisticsCallback& callback,
56846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    bool clear_logs) {
56946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  DCHECK(ui_thread_->RunsTasksOnCurrentThread());
57046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  DCHECK(!callback.is_null());
57146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
57246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  request_gcm_statistics_callback_ = callback;
57346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  io_thread_->PostTask(
57446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      FROM_HERE,
57546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      base::Bind(&GCMDriverDesktop::IOWorker::GetGCMStatistics,
57646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                 base::Unretained(io_worker_.get()),
57746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                 clear_logs));
57846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
57946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
58046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void GCMDriverDesktop::SetGCMRecording(const GetGCMStatisticsCallback& callback,
58146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                       bool recording) {
58246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  DCHECK(ui_thread_->RunsTasksOnCurrentThread());
58346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
58446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  request_gcm_statistics_callback_ = callback;
58546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  io_thread_->PostTask(
58646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      FROM_HERE,
58746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      base::Bind(&GCMDriverDesktop::IOWorker::SetGCMRecording,
58846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                 base::Unretained(io_worker_.get()),
58946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                 recording));
59046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
59146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
59203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)void GCMDriverDesktop::UpdateAccountMapping(
59303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    const AccountMapping& account_mapping) {
59403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  DCHECK(ui_thread_->RunsTasksOnCurrentThread());
59503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
59603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  io_thread_->PostTask(
59703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      FROM_HERE,
59803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      base::Bind(&GCMDriverDesktop::IOWorker::UpdateAccountMapping,
59903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                 base::Unretained(io_worker_.get()),
60003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                 account_mapping));
60103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}
60203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
60303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)void GCMDriverDesktop::RemoveAccountMapping(const std::string& account_id) {
60403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  DCHECK(ui_thread_->RunsTasksOnCurrentThread());
60503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
60603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  io_thread_->PostTask(
60703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      FROM_HERE,
60803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      base::Bind(&GCMDriverDesktop::IOWorker::RemoveAccountMapping,
60903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                 base::Unretained(io_worker_.get()),
61003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                 account_id));
61103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}
61203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
613116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid GCMDriverDesktop::SetAccountsForCheckin(
614116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const std::map<std::string, std::string>& account_tokens) {
615116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DCHECK(ui_thread_->RunsTasksOnCurrentThread());
616116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
617116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  io_thread_->PostTask(
618116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      FROM_HERE,
619116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      base::Bind(&GCMDriverDesktop::IOWorker::SetAccountsForCheckin,
620116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                 base::Unretained(io_worker_.get()),
621116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                 account_tokens));
622116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
623116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
62446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)GCMClient::Result GCMDriverDesktop::EnsureStarted() {
62546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  DCHECK(ui_thread_->RunsTasksOnCurrentThread());
62646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
627f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (gcm_started_)
628f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return GCMClient::SUCCESS;
629f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
63046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  if (!gcm_enabled_)
63146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    return GCMClient::GCM_DISABLED;
63246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
63346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Have any app requested the service?
63446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  if (app_handlers().empty())
63546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    return GCMClient::UNKNOWN_ERROR;
63646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
637f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // TODO(jianli): To be removed when sign-in enforcement is dropped.
638116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (!signed_in_ && !GCMDriver::IsAllowedForAllUsers())
63946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    return GCMClient::NOT_SIGNED_IN;
64046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
64146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  DCHECK(!delayed_task_controller_);
6421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  delayed_task_controller_.reset(new GCMDelayedTaskController);
6431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
6441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Polling for channel status is only needed when GCM is supported for all
6451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // users.
6461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (GCMDriver::IsAllowedForAllUsers())
6471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    gcm_channel_status_syncer_->EnsureStarted();
6481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
6491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  UMA_HISTOGRAM_BOOLEAN("GCM.UserSignedIn", signed_in_);
65046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
65146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Note that we need to pass weak pointer again since the existing weak
65246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // pointer in IOWorker might have been invalidated when check-out occurs.
65346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  io_thread_->PostTask(
65446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      FROM_HERE,
65546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      base::Bind(&GCMDriverDesktop::IOWorker::Start,
65646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                 base::Unretained(io_worker_.get()),
65746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                 weak_ptr_factory_.GetWeakPtr()));
65846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
659f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  gcm_started_ = true;
66046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  return GCMClient::SUCCESS;
66146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
66246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
66346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void GCMDriverDesktop::RemoveCachedData() {
66446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  DCHECK(ui_thread_->RunsTasksOnCurrentThread());
66546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Remove all the queued tasks since they no longer make sense after
66646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // GCM service is stopped.
66746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  weak_ptr_factory_.InvalidateWeakPtrs();
66846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
669f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  gcm_started_ = false;
67046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  delayed_task_controller_.reset();
67146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ClearCallbacks();
67246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
67346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
67446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void GCMDriverDesktop::MessageReceived(
67546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    const std::string& app_id,
67646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    const GCMClient::IncomingMessage& message) {
67746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  DCHECK(ui_thread_->RunsTasksOnCurrentThread());
67846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
679f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Drop the event if the service has been stopped.
680f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (!gcm_started_)
68146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    return;
68246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
68346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  GetAppHandler(app_id)->OnMessage(app_id, message);
68446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
68546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
68646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void GCMDriverDesktop::MessagesDeleted(const std::string& app_id) {
68746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  DCHECK(ui_thread_->RunsTasksOnCurrentThread());
68846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
689f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Drop the event if the service has been stopped.
690f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (!gcm_started_)
69146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    return;
69246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
69346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  GetAppHandler(app_id)->OnMessagesDeleted(app_id);
69446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
69546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
69646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void GCMDriverDesktop::MessageSendError(
69746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    const std::string& app_id,
69846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    const GCMClient::SendErrorDetails& send_error_details) {
69946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  DCHECK(ui_thread_->RunsTasksOnCurrentThread());
70046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
701f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Drop the event if the service has been stopped.
702f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (!gcm_started_)
70346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    return;
70446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
70546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  GetAppHandler(app_id)->OnSendError(app_id, send_error_details);
70646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
70746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
7085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void GCMDriverDesktop::SendAcknowledged(const std::string& app_id,
7095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                        const std::string& message_id) {
7105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DCHECK(ui_thread_->RunsTasksOnCurrentThread());
7115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
7125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Drop the event if the service has been stopped.
7135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (!gcm_started_)
7145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return;
7155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
7165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  GetAppHandler(app_id)->OnSendAcknowledged(app_id, message_id);
7175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
7185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
7191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid GCMDriverDesktop::GCMClientReady(
7201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const std::vector<AccountMapping>& account_mappings) {
72146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  DCHECK(ui_thread_->RunsTasksOnCurrentThread());
72246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
72346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  delayed_task_controller_->SetReady();
72446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
72546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
726f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void GCMDriverDesktop::OnConnected(const net::IPEndPoint& ip_endpoint) {
727f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  DCHECK(ui_thread_->RunsTasksOnCurrentThread());
728f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
729f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  connected_ = true;
730f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
731116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Drop the event if the service has been stopped.
732116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (!gcm_started_)
733f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return;
734f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
7351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  FOR_EACH_OBSERVER(GCMConnectionObserver,
7361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                    connection_observer_list_,
7371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                    OnConnected(ip_endpoint));
738f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
739f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
740f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void GCMDriverDesktop::OnDisconnected() {
741f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  DCHECK(ui_thread_->RunsTasksOnCurrentThread());
742f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
743f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  connected_ = false;
744f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
745116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Drop the event if the service has been stopped.
746116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (!gcm_started_)
747f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return;
748f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
7491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  FOR_EACH_OBSERVER(
7501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      GCMConnectionObserver, connection_observer_list_, OnDisconnected());
751f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
752f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
75346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void GCMDriverDesktop::GetGCMStatisticsFinished(
75446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    const GCMClient::GCMStatistics& stats) {
75546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  DCHECK(ui_thread_->RunsTasksOnCurrentThread());
75646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
75746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Normally request_gcm_statistics_callback_ would not be null.
75846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  if (!request_gcm_statistics_callback_.is_null())
75946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    request_gcm_statistics_callback_.Run(stats);
76046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  else
76146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    LOG(WARNING) << "request_gcm_statistics_callback_ is NULL.";
76246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
76346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
76446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}  // namespace gcm
765f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
766