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,
3371675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch    const std::string& channel_status_request_url,
3381675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch    const std::string& user_agent,
3391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    PrefService* prefs,
34046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    const base::FilePath& store_path,
34146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    const scoped_refptr<net::URLRequestContextGetter>& request_context,
34246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    const scoped_refptr<base::SequencedTaskRunner>& ui_thread,
34346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    const scoped_refptr<base::SequencedTaskRunner>& io_thread,
34446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    const scoped_refptr<base::SequencedTaskRunner>& blocking_task_runner)
3451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    : gcm_channel_status_syncer_(
3461675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch          new GCMChannelStatusSyncer(this,
3471675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch                                     prefs,
3481675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch                                     channel_status_request_url,
3491675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch                                     user_agent,
3501675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch                                     request_context)),
3511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      signed_in_(false),
352f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      gcm_started_(false),
353f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      gcm_enabled_(true),
354f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      connected_(false),
35546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      ui_thread_(ui_thread),
35646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      io_thread_(io_thread),
35746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      weak_ptr_factory_(this) {
3581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  gcm_enabled_ = gcm_channel_status_syncer_->gcm_enabled();
3591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
36046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Create and initialize the GCMClient. Note that this does not initiate the
36146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // GCM check-in.
36246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  io_worker_.reset(new IOWorker(ui_thread, io_thread));
36346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  io_thread_->PostTask(
36446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      FROM_HERE,
36546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      base::Bind(&GCMDriverDesktop::IOWorker::Initialize,
36646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                 base::Unretained(io_worker_.get()),
36746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                 base::Passed(&gcm_client_factory),
36846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                 chrome_build_info,
36946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                 store_path,
37046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                 request_context,
37146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                 blocking_task_runner));
37246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
37346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
37446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)GCMDriverDesktop::~GCMDriverDesktop() {
37546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
37646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
377f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void GCMDriverDesktop::Shutdown() {
378f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  DCHECK(ui_thread_->RunsTasksOnCurrentThread());
379f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  GCMDriver::Shutdown();
3801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Dispose the syncer in order to release the reference to
3821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // URLRequestContextGetter that needs to be done before IOThread gets
3831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // deleted.
3841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  gcm_channel_status_syncer_.reset();
3851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
386f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  io_thread_->DeleteSoon(FROM_HERE, io_worker_.release());
38746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
38846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
389f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void GCMDriverDesktop::OnSignedIn() {
390f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  signed_in_ = true;
391f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EnsureStarted();
39246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
39346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
3941675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdochvoid GCMDriverDesktop::OnSignedOut() {
3951675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch  signed_in_ = false;
3961675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch
3971675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch  // When sign-in enforcement is not dropped, we will stop the GCM connection
3981675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch  // when the user signs out.
3991675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch  if (!GCMDriver::IsAllowedForAllUsers())
4001675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch    Stop();
4011675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch}
4021675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch
403f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void GCMDriverDesktop::Purge() {
40446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  DCHECK(ui_thread_->RunsTasksOnCurrentThread());
405f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
406f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  RemoveCachedData();
407f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
408f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  io_thread_->PostTask(FROM_HERE,
409f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                       base::Bind(&GCMDriverDesktop::IOWorker::CheckOut,
410f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                       base::Unretained(io_worker_.get())));
41146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
41246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
41346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void GCMDriverDesktop::AddAppHandler(const std::string& app_id,
41446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                     GCMAppHandler* handler) {
41546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  DCHECK(ui_thread_->RunsTasksOnCurrentThread());
41646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  GCMDriver::AddAppHandler(app_id, handler);
41746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
41846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)   // Ensures that the GCM service is started when there is an interest.
41946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  EnsureStarted();
42046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
42146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
42246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void GCMDriverDesktop::RemoveAppHandler(const std::string& app_id) {
42346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  DCHECK(ui_thread_->RunsTasksOnCurrentThread());
42446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  GCMDriver::RemoveAppHandler(app_id);
42546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
42646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Stops the GCM service when no app intends to consume it.
4271675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch  if (app_handlers().empty()) {
42846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    Stop();
4291675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch    gcm_channel_status_syncer_->Stop();
4301675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch  }
43146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
43246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
4331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid GCMDriverDesktop::AddConnectionObserver(GCMConnectionObserver* observer) {
4341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  connection_observer_list_.AddObserver(observer);
4351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
4361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
4371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid GCMDriverDesktop::RemoveConnectionObserver(
4381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    GCMConnectionObserver* observer) {
4391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  connection_observer_list_.RemoveObserver(observer);
4401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
4411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
44246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void GCMDriverDesktop::Enable() {
44346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  DCHECK(ui_thread_->RunsTasksOnCurrentThread());
44446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
44546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  if (gcm_enabled_)
44646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    return;
44746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  gcm_enabled_ = true;
44846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
44946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  EnsureStarted();
45046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
45146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
45246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void GCMDriverDesktop::Disable() {
45346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  DCHECK(ui_thread_->RunsTasksOnCurrentThread());
45446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
45546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  if (!gcm_enabled_)
45646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    return;
45746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  gcm_enabled_ = false;
45846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
45946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  Stop();
46046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
46146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
46246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void GCMDriverDesktop::Stop() {
46346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  DCHECK(ui_thread_->RunsTasksOnCurrentThread());
46446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
46546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // No need to stop GCM service if not started yet.
466f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (!gcm_started_)
46746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    return;
46846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
46946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  RemoveCachedData();
47046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
47146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  io_thread_->PostTask(
47246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      FROM_HERE,
47346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      base::Bind(&GCMDriverDesktop::IOWorker::Stop,
47446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                 base::Unretained(io_worker_.get())));
47546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
47646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
47746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void GCMDriverDesktop::RegisterImpl(
47846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    const std::string& app_id,
47946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    const std::vector<std::string>& sender_ids) {
48046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Delay the register operation until GCMClient is ready.
48146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  if (!delayed_task_controller_->CanRunTaskWithoutDelay()) {
48246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    delayed_task_controller_->AddTask(base::Bind(&GCMDriverDesktop::DoRegister,
48346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                                 weak_ptr_factory_.GetWeakPtr(),
48446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                                 app_id,
48546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                                 sender_ids));
48646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    return;
48746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
48846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
48946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  DoRegister(app_id, sender_ids);
49046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
49146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
49246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void GCMDriverDesktop::DoRegister(const std::string& app_id,
49346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                  const std::vector<std::string>& sender_ids) {
49446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  DCHECK(ui_thread_->RunsTasksOnCurrentThread());
49546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  if (!HasRegisterCallback(app_id)) {
49646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    // The callback could have been removed when the app is uninstalled.
49746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    return;
49846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
49946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
50046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  io_thread_->PostTask(
50146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      FROM_HERE,
50246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      base::Bind(&GCMDriverDesktop::IOWorker::Register,
50346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                 base::Unretained(io_worker_.get()),
50446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                 app_id,
50546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                 sender_ids));
50646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
50746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
50846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void GCMDriverDesktop::UnregisterImpl(const std::string& app_id) {
50946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Delay the unregister operation until GCMClient is ready.
51046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  if (!delayed_task_controller_->CanRunTaskWithoutDelay()) {
51146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    delayed_task_controller_->AddTask(
51246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        base::Bind(&GCMDriverDesktop::DoUnregister,
51346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                   weak_ptr_factory_.GetWeakPtr(),
51446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                   app_id));
51546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    return;
51646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
51746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
51846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  DoUnregister(app_id);
51946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
52046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
52146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void GCMDriverDesktop::DoUnregister(const std::string& app_id) {
52246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  DCHECK(ui_thread_->RunsTasksOnCurrentThread());
52346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
52446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Ask the server to unregister it. There could be a small chance that the
52546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // unregister request fails. If this occurs, it does not bring any harm since
52646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // we simply reject the messages/events received from the server.
52746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  io_thread_->PostTask(
52846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      FROM_HERE,
52946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      base::Bind(&GCMDriverDesktop::IOWorker::Unregister,
53046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                 base::Unretained(io_worker_.get()),
53146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                 app_id));
53246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
53346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
53446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void GCMDriverDesktop::SendImpl(const std::string& app_id,
53546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                const std::string& receiver_id,
53646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                const GCMClient::OutgoingMessage& message) {
53746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Delay the send operation until all GCMClient is ready.
53846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  if (!delayed_task_controller_->CanRunTaskWithoutDelay()) {
53946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    delayed_task_controller_->AddTask(base::Bind(&GCMDriverDesktop::DoSend,
54046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                                 weak_ptr_factory_.GetWeakPtr(),
54146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                                 app_id,
54246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                                 receiver_id,
54346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                                 message));
54446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    return;
54546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
54646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
54746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  DoSend(app_id, receiver_id, message);
54846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
54946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
55046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void GCMDriverDesktop::DoSend(const std::string& app_id,
55146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                              const std::string& receiver_id,
55246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                              const GCMClient::OutgoingMessage& message) {
55346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  DCHECK(ui_thread_->RunsTasksOnCurrentThread());
55446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  io_thread_->PostTask(
55546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      FROM_HERE,
55646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      base::Bind(&GCMDriverDesktop::IOWorker::Send,
55746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                 base::Unretained(io_worker_.get()),
55846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                 app_id,
55946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                 receiver_id,
56046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                 message));
56146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
56246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
56346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)GCMClient* GCMDriverDesktop::GetGCMClientForTesting() const {
56446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  DCHECK(ui_thread_->RunsTasksOnCurrentThread());
56546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  return io_worker_ ? io_worker_->gcm_client_for_testing() : NULL;
56646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
56746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
56846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)bool GCMDriverDesktop::IsStarted() const {
56946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  DCHECK(ui_thread_->RunsTasksOnCurrentThread());
570f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  return gcm_started_;
57146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
57246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
573f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)bool GCMDriverDesktop::IsConnected() const {
574f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  return connected_;
575f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
576f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
57746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void GCMDriverDesktop::GetGCMStatistics(
57846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    const GetGCMStatisticsCallback& callback,
57946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    bool clear_logs) {
58046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  DCHECK(ui_thread_->RunsTasksOnCurrentThread());
58146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  DCHECK(!callback.is_null());
58246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
58346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  request_gcm_statistics_callback_ = callback;
58446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  io_thread_->PostTask(
58546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      FROM_HERE,
58646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      base::Bind(&GCMDriverDesktop::IOWorker::GetGCMStatistics,
58746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                 base::Unretained(io_worker_.get()),
58846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                 clear_logs));
58946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
59046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
59146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void GCMDriverDesktop::SetGCMRecording(const GetGCMStatisticsCallback& callback,
59246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                       bool recording) {
59346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  DCHECK(ui_thread_->RunsTasksOnCurrentThread());
59446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
59546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  request_gcm_statistics_callback_ = callback;
59646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  io_thread_->PostTask(
59746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      FROM_HERE,
59846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      base::Bind(&GCMDriverDesktop::IOWorker::SetGCMRecording,
59946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                 base::Unretained(io_worker_.get()),
60046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                 recording));
60146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
60246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
60303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)void GCMDriverDesktop::UpdateAccountMapping(
60403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    const AccountMapping& account_mapping) {
60503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  DCHECK(ui_thread_->RunsTasksOnCurrentThread());
60603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
60703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  io_thread_->PostTask(
60803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      FROM_HERE,
60903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      base::Bind(&GCMDriverDesktop::IOWorker::UpdateAccountMapping,
61003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                 base::Unretained(io_worker_.get()),
61103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                 account_mapping));
61203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}
61303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
61403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)void GCMDriverDesktop::RemoveAccountMapping(const std::string& account_id) {
61503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  DCHECK(ui_thread_->RunsTasksOnCurrentThread());
61603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
61703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  io_thread_->PostTask(
61803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      FROM_HERE,
61903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      base::Bind(&GCMDriverDesktop::IOWorker::RemoveAccountMapping,
62003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                 base::Unretained(io_worker_.get()),
62103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                 account_id));
62203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}
62303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
624116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid GCMDriverDesktop::SetAccountsForCheckin(
625116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const std::map<std::string, std::string>& account_tokens) {
626116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DCHECK(ui_thread_->RunsTasksOnCurrentThread());
627116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
628116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  io_thread_->PostTask(
629116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      FROM_HERE,
630116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      base::Bind(&GCMDriverDesktop::IOWorker::SetAccountsForCheckin,
631116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                 base::Unretained(io_worker_.get()),
632116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                 account_tokens));
633116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
634116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
63546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)GCMClient::Result GCMDriverDesktop::EnsureStarted() {
63646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  DCHECK(ui_thread_->RunsTasksOnCurrentThread());
63746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
638f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (gcm_started_)
639f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return GCMClient::SUCCESS;
640f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
6411675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch  if (!gcm_enabled_) {
6421675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch    // Poll for channel status in order to find out when it is re-enabled when
6431675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch    // GCM is currently disabled.
6441675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch    if (GCMDriver::IsAllowedForAllUsers())
6451675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch      gcm_channel_status_syncer_->EnsureStarted();
6461675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch
64746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    return GCMClient::GCM_DISABLED;
6481675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch  }
64946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
65046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Have any app requested the service?
65146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  if (app_handlers().empty())
65246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    return GCMClient::UNKNOWN_ERROR;
65346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
654f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // TODO(jianli): To be removed when sign-in enforcement is dropped.
655116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (!signed_in_ && !GCMDriver::IsAllowedForAllUsers())
65646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    return GCMClient::NOT_SIGNED_IN;
65746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
65846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  DCHECK(!delayed_task_controller_);
6591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  delayed_task_controller_.reset(new GCMDelayedTaskController);
6601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
6611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Polling for channel status is only needed when GCM is supported for all
6621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // users.
6631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (GCMDriver::IsAllowedForAllUsers())
6641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    gcm_channel_status_syncer_->EnsureStarted();
6651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
6661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  UMA_HISTOGRAM_BOOLEAN("GCM.UserSignedIn", signed_in_);
66746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
66846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Note that we need to pass weak pointer again since the existing weak
66946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // pointer in IOWorker might have been invalidated when check-out occurs.
67046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  io_thread_->PostTask(
67146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      FROM_HERE,
67246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      base::Bind(&GCMDriverDesktop::IOWorker::Start,
67346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                 base::Unretained(io_worker_.get()),
67446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                 weak_ptr_factory_.GetWeakPtr()));
67546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
676f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  gcm_started_ = true;
67746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  return GCMClient::SUCCESS;
67846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
67946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
68046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void GCMDriverDesktop::RemoveCachedData() {
68146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  DCHECK(ui_thread_->RunsTasksOnCurrentThread());
68246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Remove all the queued tasks since they no longer make sense after
68346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // GCM service is stopped.
68446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  weak_ptr_factory_.InvalidateWeakPtrs();
68546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
686f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  gcm_started_ = false;
68746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  delayed_task_controller_.reset();
68846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ClearCallbacks();
68946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
69046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
69146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void GCMDriverDesktop::MessageReceived(
69246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    const std::string& app_id,
69346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    const GCMClient::IncomingMessage& message) {
69446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  DCHECK(ui_thread_->RunsTasksOnCurrentThread());
69546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
696f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Drop the event if the service has been stopped.
697f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (!gcm_started_)
69846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    return;
69946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
70046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  GetAppHandler(app_id)->OnMessage(app_id, message);
70146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
70246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
70346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void GCMDriverDesktop::MessagesDeleted(const std::string& app_id) {
70446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  DCHECK(ui_thread_->RunsTasksOnCurrentThread());
70546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
706f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Drop the event if the service has been stopped.
707f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (!gcm_started_)
70846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    return;
70946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
71046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  GetAppHandler(app_id)->OnMessagesDeleted(app_id);
71146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
71246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
71346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void GCMDriverDesktop::MessageSendError(
71446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    const std::string& app_id,
71546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    const GCMClient::SendErrorDetails& send_error_details) {
71646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  DCHECK(ui_thread_->RunsTasksOnCurrentThread());
71746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
718f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Drop the event if the service has been stopped.
719f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (!gcm_started_)
72046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    return;
72146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
72246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  GetAppHandler(app_id)->OnSendError(app_id, send_error_details);
72346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
72446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
7255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void GCMDriverDesktop::SendAcknowledged(const std::string& app_id,
7265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                        const std::string& message_id) {
7275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DCHECK(ui_thread_->RunsTasksOnCurrentThread());
7285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
7295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Drop the event if the service has been stopped.
7305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (!gcm_started_)
7315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return;
7325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
7335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  GetAppHandler(app_id)->OnSendAcknowledged(app_id, message_id);
7345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
7355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
7361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid GCMDriverDesktop::GCMClientReady(
7371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const std::vector<AccountMapping>& account_mappings) {
73846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  DCHECK(ui_thread_->RunsTasksOnCurrentThread());
73946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
74046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  delayed_task_controller_->SetReady();
74146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
74246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
743f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void GCMDriverDesktop::OnConnected(const net::IPEndPoint& ip_endpoint) {
744f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  DCHECK(ui_thread_->RunsTasksOnCurrentThread());
745f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
746f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  connected_ = true;
747f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
748116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Drop the event if the service has been stopped.
749116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (!gcm_started_)
750f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return;
751f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
7521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  FOR_EACH_OBSERVER(GCMConnectionObserver,
7531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                    connection_observer_list_,
7541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                    OnConnected(ip_endpoint));
755f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
756f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
757f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void GCMDriverDesktop::OnDisconnected() {
758f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  DCHECK(ui_thread_->RunsTasksOnCurrentThread());
759f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
760f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  connected_ = false;
761f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
762116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Drop the event if the service has been stopped.
763116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (!gcm_started_)
764f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return;
765f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
7661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  FOR_EACH_OBSERVER(
7671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      GCMConnectionObserver, connection_observer_list_, OnDisconnected());
768f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
769f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
77046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void GCMDriverDesktop::GetGCMStatisticsFinished(
77146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    const GCMClient::GCMStatistics& stats) {
77246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  DCHECK(ui_thread_->RunsTasksOnCurrentThread());
77346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
77446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Normally request_gcm_statistics_callback_ would not be null.
77546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  if (!request_gcm_statistics_callback_.is_null())
77646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    request_gcm_statistics_callback_.Run(stats);
77746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  else
77846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    LOG(WARNING) << "request_gcm_statistics_callback_ is NULL.";
77946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
78046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
78146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}  // namespace gcm
782f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
783