1cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
2f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// found in the LICENSE file.
4f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
5cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "components/gcm_driver/fake_gcm_client.h"
6f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
7f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/bind.h"
8f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/logging.h"
9f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/message_loop/message_loop.h"
10cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/sequenced_task_runner.h"
11f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/sys_byteorder.h"
12f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/time/time.h"
13cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "google_apis/gcm/base/encryptor.h"
14f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "net/base/ip_endpoint.h"
15f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
16f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)namespace gcm {
17f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
18cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)FakeGCMClient::FakeGCMClient(
19cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    StartMode start_mode,
20cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const scoped_refptr<base::SequencedTaskRunner>& ui_thread,
21cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const scoped_refptr<base::SequencedTaskRunner>& io_thread)
225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    : delegate_(NULL),
23a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      status_(UNINITIALIZED),
24cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      start_mode_(start_mode),
25cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      ui_thread_(ui_thread),
26cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      io_thread_(io_thread),
27a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      weak_ptr_factory_(this) {
28f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
29f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
30cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)FakeGCMClient::~FakeGCMClient() {
31f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
32f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
33cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void FakeGCMClient::Initialize(
34cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const ChromeBuildInfo& chrome_build_info,
355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const base::FilePath& store_path,
365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const scoped_refptr<base::SequencedTaskRunner>& blocking_task_runner,
375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const scoped_refptr<net::URLRequestContextGetter>&
385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        url_request_context_getter,
39cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    scoped_ptr<Encryptor> encryptor,
405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    Delegate* delegate) {
415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  delegate_ = delegate;
42f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
43f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
44cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void FakeGCMClient::Start() {
45cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK(io_thread_->RunsTasksOnCurrentThread());
46cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK_NE(STARTED, status_);
47a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
48cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (start_mode_ == DELAY_START)
49a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return;
50a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DoLoading();
51a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
52a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
53cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void FakeGCMClient::DoLoading() {
54cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  status_ = STARTED;
55a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  base::MessageLoop::current()->PostTask(
56a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      FROM_HERE,
57cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      base::Bind(&FakeGCMClient::CheckinFinished,
58a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                 weak_ptr_factory_.GetWeakPtr()));
59a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
60a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
61cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void FakeGCMClient::Stop() {
62cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK(io_thread_->RunsTasksOnCurrentThread());
63a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  status_ = STOPPED;
64f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  delegate_->OnDisconnected();
65a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
66a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
67cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void FakeGCMClient::CheckOut() {
68cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK(io_thread_->RunsTasksOnCurrentThread());
69a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  status_ = CHECKED_OUT;
70f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
71f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
72cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void FakeGCMClient::Register(const std::string& app_id,
73f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                             const std::vector<std::string>& sender_ids) {
74cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK(io_thread_->RunsTasksOnCurrentThread());
75f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
76c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  std::string registration_id = GetRegistrationIdFromSenderIds(sender_ids);
77f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  base::MessageLoop::current()->PostTask(
78f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      FROM_HERE,
79cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      base::Bind(&FakeGCMClient::RegisterFinished,
80a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                 weak_ptr_factory_.GetWeakPtr(),
81f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                 app_id,
82f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                 registration_id));
83f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
84f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
85cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void FakeGCMClient::Unregister(const std::string& app_id) {
86cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK(io_thread_->RunsTasksOnCurrentThread());
8723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
8823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  base::MessageLoop::current()->PostTask(
8923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      FROM_HERE,
90cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      base::Bind(&FakeGCMClient::UnregisterFinished,
9123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)                 weak_ptr_factory_.GetWeakPtr(),
9223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)                 app_id));
93f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
94f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
95cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void FakeGCMClient::Send(const std::string& app_id,
96f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                         const std::string& receiver_id,
97f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                         const OutgoingMessage& message) {
98cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK(io_thread_->RunsTasksOnCurrentThread());
99f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
100f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  base::MessageLoop::current()->PostTask(
101f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      FROM_HERE,
102cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      base::Bind(&FakeGCMClient::SendFinished,
103a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                 weak_ptr_factory_.GetWeakPtr(),
104f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                 app_id,
105a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                 message));
106f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
107f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
108cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void FakeGCMClient::SetRecording(bool recording) {
1090529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
1100529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
111cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void FakeGCMClient::ClearActivityLogs() {
1120529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
1130529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
114cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)GCMClient::GCMStatistics FakeGCMClient::GetStatistics() const {
115a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return GCMClient::GCMStatistics();
116a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
117a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
118cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void FakeGCMClient::PerformDelayedLoading() {
119cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK(ui_thread_->RunsTasksOnCurrentThread());
120a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
121cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  io_thread_->PostTask(
122a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      FROM_HERE,
123cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      base::Bind(&FakeGCMClient::DoLoading, weak_ptr_factory_.GetWeakPtr()));
124f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
125f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
126cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void FakeGCMClient::ReceiveMessage(const std::string& app_id,
127f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                   const IncomingMessage& message) {
128cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK(ui_thread_->RunsTasksOnCurrentThread());
129f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
130cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  io_thread_->PostTask(
131f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      FROM_HERE,
132cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      base::Bind(&FakeGCMClient::MessageReceived,
133a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                 weak_ptr_factory_.GetWeakPtr(),
134f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                 app_id,
135f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                 message));
136f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
137f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
138cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void FakeGCMClient::DeleteMessages(const std::string& app_id) {
139cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK(ui_thread_->RunsTasksOnCurrentThread());
140f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
141cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  io_thread_->PostTask(
142f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      FROM_HERE,
143cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      base::Bind(&FakeGCMClient::MessagesDeleted,
144a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                 weak_ptr_factory_.GetWeakPtr(),
145f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                 app_id));
146f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
147f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// static
149cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)std::string FakeGCMClient::GetRegistrationIdFromSenderIds(
1505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const std::vector<std::string>& sender_ids) {
1515c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // GCMService normalizes the sender IDs by making them sorted.
1525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::vector<std::string> normalized_sender_ids = sender_ids;
1535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::sort(normalized_sender_ids.begin(), normalized_sender_ids.end());
1545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
155f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Simulate the registration_id by concaternating all sender IDs.
156f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Set registration_id to empty to denote an error if sender_ids contains a
157f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // hint.
158f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  std::string registration_id;
159f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (sender_ids.size() != 1 ||
160f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      sender_ids[0].find("error") == std::string::npos) {
1615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    for (size_t i = 0; i < normalized_sender_ids.size(); ++i) {
162f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      if (i > 0)
163f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        registration_id += ",";
1645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      registration_id += normalized_sender_ids[i];
165f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    }
166f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
167f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return registration_id;
168f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
169f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
170cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void FakeGCMClient::CheckinFinished() {
171a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  delegate_->OnGCMReady();
172f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  delegate_->OnConnected(net::IPEndPoint());
173a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
174a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
175cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void FakeGCMClient::RegisterFinished(const std::string& app_id,
1765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                     const std::string& registrion_id) {
1775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  delegate_->OnRegisterFinished(
178f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      app_id, registrion_id, registrion_id.empty() ? SERVER_ERROR : SUCCESS);
179f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
180f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
181cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void FakeGCMClient::UnregisterFinished(const std::string& app_id) {
18223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  delegate_->OnUnregisterFinished(app_id, GCMClient::SUCCESS);
18323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)}
18423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
185cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void FakeGCMClient::SendFinished(const std::string& app_id,
186a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                 const OutgoingMessage& message) {
187a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  delegate_->OnSendFinished(app_id, message.id, SUCCESS);
188f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
189f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Simulate send error if message id contains a hint.
190a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (message.id.find("error") != std::string::npos) {
191a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    SendErrorDetails send_error_details;
192a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    send_error_details.message_id = message.id;
193a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    send_error_details.result = NETWORK_ERROR;
194a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    send_error_details.additional_data = message.data;
195f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    base::MessageLoop::current()->PostDelayedTask(
196f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        FROM_HERE,
197cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        base::Bind(&FakeGCMClient::MessageSendError,
198a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                   weak_ptr_factory_.GetWeakPtr(),
199f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                   app_id,
200a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                   send_error_details),
201f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        base::TimeDelta::FromMilliseconds(200));
202f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
203f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
204f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
205cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void FakeGCMClient::MessageReceived(const std::string& app_id,
2065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                    const IncomingMessage& message) {
2075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (delegate_)
2085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    delegate_->OnMessageReceived(app_id, message);
2095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
2105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
211cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void FakeGCMClient::MessagesDeleted(const std::string& app_id) {
2125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (delegate_)
2135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    delegate_->OnMessagesDeleted(app_id);
214f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
215f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
216cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void FakeGCMClient::MessageSendError(
217a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const std::string& app_id,
218a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const GCMClient::SendErrorDetails& send_error_details) {
2195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (delegate_)
220a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    delegate_->OnMessageSendError(app_id, send_error_details);
221f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
222f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
223f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}  // namespace gcm
224