1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "components/gcm_driver/fake_gcm_client.h"
8 #include "base/logging.h"
9 #include "base/message_loop/message_loop.h"
10 #include "base/sequenced_task_runner.h"
11 #include "base/strings/string_number_conversions.h"
12 #include "base/sys_byteorder.h"
13 #include "base/time/time.h"
14 #include "base/timer/timer.h"
15 #include "google_apis/gcm/base/encryptor.h"
16 #include "google_apis/gcm/engine/account_mapping.h"
17 #include "net/base/ip_endpoint.h"
21 FakeGCMClient::FakeGCMClient(
22 const scoped_refptr
<base::SequencedTaskRunner
>& ui_thread
,
23 const scoped_refptr
<base::SequencedTaskRunner
>& io_thread
)
26 start_mode_(DELAYED_START
),
27 start_mode_overridding_(RESPECT_START_MODE
),
28 ui_thread_(ui_thread
),
29 io_thread_(io_thread
),
30 weak_ptr_factory_(this) {
33 FakeGCMClient::~FakeGCMClient() {
36 void FakeGCMClient::Initialize(
37 const ChromeBuildInfo
& chrome_build_info
,
38 const base::FilePath
& store_path
,
39 const scoped_refptr
<base::SequencedTaskRunner
>& blocking_task_runner
,
40 const scoped_refptr
<net::URLRequestContextGetter
>&
41 url_request_context_getter
,
42 scoped_ptr
<Encryptor
> encryptor
,
47 void FakeGCMClient::Start(StartMode start_mode
) {
48 DCHECK(io_thread_
->RunsTasksOnCurrentThread());
53 if (start_mode
== IMMEDIATE_START
)
54 start_mode_
= IMMEDIATE_START
;
55 if (start_mode_
== DELAYED_START
||
56 start_mode_overridding_
== FORCE_TO_ALWAYS_DELAY_START_GCM
) {
63 void FakeGCMClient::DoStart() {
65 base::MessageLoop::current()->PostTask(
67 base::Bind(&FakeGCMClient::Started
,
68 weak_ptr_factory_
.GetWeakPtr()));
71 void FakeGCMClient::Stop() {
72 DCHECK(io_thread_
->RunsTasksOnCurrentThread());
74 delegate_
->OnDisconnected();
77 void FakeGCMClient::Register(const std::string
& app_id
,
78 const std::vector
<std::string
>& sender_ids
) {
79 DCHECK(io_thread_
->RunsTasksOnCurrentThread());
81 std::string registration_id
= GetRegistrationIdFromSenderIds(sender_ids
);
82 base::MessageLoop::current()->PostTask(
84 base::Bind(&FakeGCMClient::RegisterFinished
,
85 weak_ptr_factory_
.GetWeakPtr(),
90 void FakeGCMClient::Unregister(const std::string
& app_id
) {
91 DCHECK(io_thread_
->RunsTasksOnCurrentThread());
93 base::MessageLoop::current()->PostTask(
95 base::Bind(&FakeGCMClient::UnregisterFinished
,
96 weak_ptr_factory_
.GetWeakPtr(),
100 void FakeGCMClient::Send(const std::string
& app_id
,
101 const std::string
& receiver_id
,
102 const OutgoingMessage
& message
) {
103 DCHECK(io_thread_
->RunsTasksOnCurrentThread());
105 base::MessageLoop::current()->PostTask(
107 base::Bind(&FakeGCMClient::SendFinished
,
108 weak_ptr_factory_
.GetWeakPtr(),
113 void FakeGCMClient::SetRecording(bool recording
) {
116 void FakeGCMClient::ClearActivityLogs() {
119 GCMClient::GCMStatistics
FakeGCMClient::GetStatistics() const {
120 return GCMClient::GCMStatistics();
123 void FakeGCMClient::SetAccountTokens(
124 const std::vector
<AccountTokenInfo
>& account_tokens
) {
127 void FakeGCMClient::UpdateAccountMapping(
128 const AccountMapping
& account_mapping
) {
131 void FakeGCMClient::RemoveAccountMapping(const std::string
& account_id
) {
134 void FakeGCMClient::SetLastTokenFetchTime(const base::Time
& time
) {
137 void FakeGCMClient::UpdateHeartbeatTimer(scoped_ptr
<base::Timer
> timer
) {
140 void FakeGCMClient::PerformDelayedStart() {
141 DCHECK(ui_thread_
->RunsTasksOnCurrentThread());
143 io_thread_
->PostTask(
145 base::Bind(&FakeGCMClient::DoStart
, weak_ptr_factory_
.GetWeakPtr()));
148 void FakeGCMClient::ReceiveMessage(const std::string
& app_id
,
149 const IncomingMessage
& message
) {
150 DCHECK(ui_thread_
->RunsTasksOnCurrentThread());
152 io_thread_
->PostTask(
154 base::Bind(&FakeGCMClient::MessageReceived
,
155 weak_ptr_factory_
.GetWeakPtr(),
160 void FakeGCMClient::DeleteMessages(const std::string
& app_id
) {
161 DCHECK(ui_thread_
->RunsTasksOnCurrentThread());
163 io_thread_
->PostTask(
165 base::Bind(&FakeGCMClient::MessagesDeleted
,
166 weak_ptr_factory_
.GetWeakPtr(),
170 std::string
FakeGCMClient::GetRegistrationIdFromSenderIds(
171 const std::vector
<std::string
>& sender_ids
) const {
172 // GCMService normalizes the sender IDs by making them sorted.
173 std::vector
<std::string
> normalized_sender_ids
= sender_ids
;
174 std::sort(normalized_sender_ids
.begin(), normalized_sender_ids
.end());
176 // Simulate the registration_id by concaternating all sender IDs.
177 // Set registration_id to empty to denote an error if sender_ids contains a
179 std::string registration_id
;
180 if (sender_ids
.size() != 1 ||
181 sender_ids
[0].find("error") == std::string::npos
) {
182 for (size_t i
= 0; i
< normalized_sender_ids
.size(); ++i
) {
184 registration_id
+= ",";
185 registration_id
+= normalized_sender_ids
[i
];
188 return registration_id
;
191 void FakeGCMClient::Started() {
192 delegate_
->OnGCMReady(std::vector
<AccountMapping
>(), base::Time());
193 delegate_
->OnConnected(net::IPEndPoint());
196 void FakeGCMClient::RegisterFinished(const std::string
& app_id
,
197 const std::string
& registrion_id
) {
198 delegate_
->OnRegisterFinished(
199 app_id
, registrion_id
, registrion_id
.empty() ? SERVER_ERROR
: SUCCESS
);
202 void FakeGCMClient::UnregisterFinished(const std::string
& app_id
) {
203 delegate_
->OnUnregisterFinished(app_id
, GCMClient::SUCCESS
);
206 void FakeGCMClient::SendFinished(const std::string
& app_id
,
207 const OutgoingMessage
& message
) {
208 delegate_
->OnSendFinished(app_id
, message
.id
, SUCCESS
);
210 // Simulate send error if message id contains a hint.
211 if (message
.id
.find("error") != std::string::npos
) {
212 SendErrorDetails send_error_details
;
213 send_error_details
.message_id
= message
.id
;
214 send_error_details
.result
= NETWORK_ERROR
;
215 send_error_details
.additional_data
= message
.data
;
216 base::MessageLoop::current()->PostDelayedTask(
218 base::Bind(&FakeGCMClient::MessageSendError
,
219 weak_ptr_factory_
.GetWeakPtr(),
222 base::TimeDelta::FromMilliseconds(200));
223 } else if(message
.id
.find("ack") != std::string::npos
) {
224 base::MessageLoop::current()->PostDelayedTask(
226 base::Bind(&FakeGCMClient::SendAcknowledgement
,
227 weak_ptr_factory_
.GetWeakPtr(),
230 base::TimeDelta::FromMilliseconds(200));
235 void FakeGCMClient::MessageReceived(const std::string
& app_id
,
236 const IncomingMessage
& message
) {
238 delegate_
->OnMessageReceived(app_id
, message
);
241 void FakeGCMClient::MessagesDeleted(const std::string
& app_id
) {
243 delegate_
->OnMessagesDeleted(app_id
);
246 void FakeGCMClient::MessageSendError(
247 const std::string
& app_id
,
248 const GCMClient::SendErrorDetails
& send_error_details
) {
250 delegate_
->OnMessageSendError(app_id
, send_error_details
);
253 void FakeGCMClient::SendAcknowledgement(const std::string
& app_id
,
254 const std::string
& message_id
) {
256 delegate_
->OnSendAcknowledged(app_id
, message_id
);