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/sys_byteorder.h"
12 #include "base/time/time.h"
13 #include "google_apis/gcm/base/encryptor.h"
14 #include "net/base/ip_endpoint.h"
18 FakeGCMClient::FakeGCMClient(
20 const scoped_refptr
<base::SequencedTaskRunner
>& ui_thread
,
21 const scoped_refptr
<base::SequencedTaskRunner
>& io_thread
)
23 status_(UNINITIALIZED
),
24 start_mode_(start_mode
),
25 ui_thread_(ui_thread
),
26 io_thread_(io_thread
),
27 weak_ptr_factory_(this) {
30 FakeGCMClient::~FakeGCMClient() {
33 void FakeGCMClient::Initialize(
34 const ChromeBuildInfo
& chrome_build_info
,
35 const base::FilePath
& store_path
,
36 const scoped_refptr
<base::SequencedTaskRunner
>& blocking_task_runner
,
37 const scoped_refptr
<net::URLRequestContextGetter
>&
38 url_request_context_getter
,
39 scoped_ptr
<Encryptor
> encryptor
,
44 void FakeGCMClient::Start() {
45 DCHECK(io_thread_
->RunsTasksOnCurrentThread());
46 DCHECK_NE(STARTED
, status_
);
48 if (start_mode_
== DELAY_START
)
53 void FakeGCMClient::DoLoading() {
55 base::MessageLoop::current()->PostTask(
57 base::Bind(&FakeGCMClient::CheckinFinished
,
58 weak_ptr_factory_
.GetWeakPtr()));
61 void FakeGCMClient::Stop() {
62 DCHECK(io_thread_
->RunsTasksOnCurrentThread());
64 delegate_
->OnDisconnected();
67 void FakeGCMClient::CheckOut() {
68 DCHECK(io_thread_
->RunsTasksOnCurrentThread());
69 status_
= CHECKED_OUT
;
72 void FakeGCMClient::Register(const std::string
& app_id
,
73 const std::vector
<std::string
>& sender_ids
) {
74 DCHECK(io_thread_
->RunsTasksOnCurrentThread());
76 std::string registration_id
= GetRegistrationIdFromSenderIds(sender_ids
);
77 base::MessageLoop::current()->PostTask(
79 base::Bind(&FakeGCMClient::RegisterFinished
,
80 weak_ptr_factory_
.GetWeakPtr(),
85 void FakeGCMClient::Unregister(const std::string
& app_id
) {
86 DCHECK(io_thread_
->RunsTasksOnCurrentThread());
88 base::MessageLoop::current()->PostTask(
90 base::Bind(&FakeGCMClient::UnregisterFinished
,
91 weak_ptr_factory_
.GetWeakPtr(),
95 void FakeGCMClient::Send(const std::string
& app_id
,
96 const std::string
& receiver_id
,
97 const OutgoingMessage
& message
) {
98 DCHECK(io_thread_
->RunsTasksOnCurrentThread());
100 base::MessageLoop::current()->PostTask(
102 base::Bind(&FakeGCMClient::SendFinished
,
103 weak_ptr_factory_
.GetWeakPtr(),
108 void FakeGCMClient::SetRecording(bool recording
) {
111 void FakeGCMClient::ClearActivityLogs() {
114 GCMClient::GCMStatistics
FakeGCMClient::GetStatistics() const {
115 return GCMClient::GCMStatistics();
118 void FakeGCMClient::SetAccountsForCheckin(
119 const std::map
<std::string
, std::string
>& account_tokens
) {
122 void FakeGCMClient::UpdateAccountMapping(
123 const AccountMapping
& account_mapping
) {
126 void FakeGCMClient::RemoveAccountMapping(const std::string
& account_id
) {
129 void FakeGCMClient::PerformDelayedLoading() {
130 DCHECK(ui_thread_
->RunsTasksOnCurrentThread());
132 io_thread_
->PostTask(
134 base::Bind(&FakeGCMClient::DoLoading
, weak_ptr_factory_
.GetWeakPtr()));
137 void FakeGCMClient::ReceiveMessage(const std::string
& app_id
,
138 const IncomingMessage
& message
) {
139 DCHECK(ui_thread_
->RunsTasksOnCurrentThread());
141 io_thread_
->PostTask(
143 base::Bind(&FakeGCMClient::MessageReceived
,
144 weak_ptr_factory_
.GetWeakPtr(),
149 void FakeGCMClient::DeleteMessages(const std::string
& app_id
) {
150 DCHECK(ui_thread_
->RunsTasksOnCurrentThread());
152 io_thread_
->PostTask(
154 base::Bind(&FakeGCMClient::MessagesDeleted
,
155 weak_ptr_factory_
.GetWeakPtr(),
160 std::string
FakeGCMClient::GetRegistrationIdFromSenderIds(
161 const std::vector
<std::string
>& sender_ids
) {
162 // GCMService normalizes the sender IDs by making them sorted.
163 std::vector
<std::string
> normalized_sender_ids
= sender_ids
;
164 std::sort(normalized_sender_ids
.begin(), normalized_sender_ids
.end());
166 // Simulate the registration_id by concaternating all sender IDs.
167 // Set registration_id to empty to denote an error if sender_ids contains a
169 std::string registration_id
;
170 if (sender_ids
.size() != 1 ||
171 sender_ids
[0].find("error") == std::string::npos
) {
172 for (size_t i
= 0; i
< normalized_sender_ids
.size(); ++i
) {
174 registration_id
+= ",";
175 registration_id
+= normalized_sender_ids
[i
];
178 return registration_id
;
181 void FakeGCMClient::CheckinFinished() {
182 delegate_
->OnGCMReady();
183 delegate_
->OnConnected(net::IPEndPoint());
186 void FakeGCMClient::RegisterFinished(const std::string
& app_id
,
187 const std::string
& registrion_id
) {
188 delegate_
->OnRegisterFinished(
189 app_id
, registrion_id
, registrion_id
.empty() ? SERVER_ERROR
: SUCCESS
);
192 void FakeGCMClient::UnregisterFinished(const std::string
& app_id
) {
193 delegate_
->OnUnregisterFinished(app_id
, GCMClient::SUCCESS
);
196 void FakeGCMClient::SendFinished(const std::string
& app_id
,
197 const OutgoingMessage
& message
) {
198 delegate_
->OnSendFinished(app_id
, message
.id
, SUCCESS
);
200 // Simulate send error if message id contains a hint.
201 if (message
.id
.find("error") != std::string::npos
) {
202 SendErrorDetails send_error_details
;
203 send_error_details
.message_id
= message
.id
;
204 send_error_details
.result
= NETWORK_ERROR
;
205 send_error_details
.additional_data
= message
.data
;
206 base::MessageLoop::current()->PostDelayedTask(
208 base::Bind(&FakeGCMClient::MessageSendError
,
209 weak_ptr_factory_
.GetWeakPtr(),
212 base::TimeDelta::FromMilliseconds(200));
213 } else if(message
.id
.find("ack") != std::string::npos
) {
214 base::MessageLoop::current()->PostDelayedTask(
216 base::Bind(&FakeGCMClient::SendAcknowledgement
,
217 weak_ptr_factory_
.GetWeakPtr(),
220 base::TimeDelta::FromMilliseconds(200));
225 void FakeGCMClient::MessageReceived(const std::string
& app_id
,
226 const IncomingMessage
& message
) {
228 delegate_
->OnMessageReceived(app_id
, message
);
231 void FakeGCMClient::MessagesDeleted(const std::string
& app_id
) {
233 delegate_
->OnMessagesDeleted(app_id
);
236 void FakeGCMClient::MessageSendError(
237 const std::string
& app_id
,
238 const GCMClient::SendErrorDetails
& send_error_details
) {
240 delegate_
->OnMessageSendError(app_id
, send_error_details
);
243 void FakeGCMClient::SendAcknowledgement(const std::string
& app_id
,
244 const std::string
& message_id
) {
246 delegate_
->OnSendAcknowledged(app_id
, message_id
);