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 "google_apis/gcm/base/encryptor.h"
15 #include "google_apis/gcm/engine/account_mapping.h"
16 #include "net/base/ip_endpoint.h"
20 FakeGCMClient::FakeGCMClient(
22 const scoped_refptr
<base::SequencedTaskRunner
>& ui_thread
,
23 const scoped_refptr
<base::SequencedTaskRunner
>& io_thread
)
26 status_(UNINITIALIZED
),
27 start_mode_(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() {
48 DCHECK(io_thread_
->RunsTasksOnCurrentThread());
49 DCHECK_NE(STARTED
, status_
);
51 if (start_mode_
== DELAY_START
)
56 void FakeGCMClient::DoLoading() {
58 base::MessageLoop::current()->PostTask(
60 base::Bind(&FakeGCMClient::CheckinFinished
,
61 weak_ptr_factory_
.GetWeakPtr()));
64 void FakeGCMClient::Stop() {
65 DCHECK(io_thread_
->RunsTasksOnCurrentThread());
67 delegate_
->OnDisconnected();
70 void FakeGCMClient::CheckOut() {
71 DCHECK(io_thread_
->RunsTasksOnCurrentThread());
72 status_
= CHECKED_OUT
;
76 void FakeGCMClient::Register(const std::string
& app_id
,
77 const std::vector
<std::string
>& sender_ids
) {
78 DCHECK(io_thread_
->RunsTasksOnCurrentThread());
80 std::string registration_id
= GetRegistrationIdFromSenderIds(sender_ids
);
81 base::MessageLoop::current()->PostTask(
83 base::Bind(&FakeGCMClient::RegisterFinished
,
84 weak_ptr_factory_
.GetWeakPtr(),
89 void FakeGCMClient::Unregister(const std::string
& app_id
) {
90 DCHECK(io_thread_
->RunsTasksOnCurrentThread());
92 base::MessageLoop::current()->PostTask(
94 base::Bind(&FakeGCMClient::UnregisterFinished
,
95 weak_ptr_factory_
.GetWeakPtr(),
99 void FakeGCMClient::Send(const std::string
& app_id
,
100 const std::string
& receiver_id
,
101 const OutgoingMessage
& message
) {
102 DCHECK(io_thread_
->RunsTasksOnCurrentThread());
104 base::MessageLoop::current()->PostTask(
106 base::Bind(&FakeGCMClient::SendFinished
,
107 weak_ptr_factory_
.GetWeakPtr(),
112 void FakeGCMClient::SetRecording(bool recording
) {
115 void FakeGCMClient::ClearActivityLogs() {
118 GCMClient::GCMStatistics
FakeGCMClient::GetStatistics() const {
119 return GCMClient::GCMStatistics();
122 void FakeGCMClient::SetAccountTokens(
123 const std::vector
<AccountTokenInfo
>& account_tokens
) {
126 void FakeGCMClient::UpdateAccountMapping(
127 const AccountMapping
& account_mapping
) {
130 void FakeGCMClient::RemoveAccountMapping(const std::string
& account_id
) {
133 void FakeGCMClient::PerformDelayedLoading() {
134 DCHECK(ui_thread_
->RunsTasksOnCurrentThread());
136 io_thread_
->PostTask(
138 base::Bind(&FakeGCMClient::DoLoading
, weak_ptr_factory_
.GetWeakPtr()));
141 void FakeGCMClient::ReceiveMessage(const std::string
& app_id
,
142 const IncomingMessage
& message
) {
143 DCHECK(ui_thread_
->RunsTasksOnCurrentThread());
145 io_thread_
->PostTask(
147 base::Bind(&FakeGCMClient::MessageReceived
,
148 weak_ptr_factory_
.GetWeakPtr(),
153 void FakeGCMClient::DeleteMessages(const std::string
& app_id
) {
154 DCHECK(ui_thread_
->RunsTasksOnCurrentThread());
156 io_thread_
->PostTask(
158 base::Bind(&FakeGCMClient::MessagesDeleted
,
159 weak_ptr_factory_
.GetWeakPtr(),
163 std::string
FakeGCMClient::GetRegistrationIdFromSenderIds(
164 const std::vector
<std::string
>& sender_ids
) const {
165 // GCMService normalizes the sender IDs by making them sorted.
166 std::vector
<std::string
> normalized_sender_ids
= sender_ids
;
167 std::sort(normalized_sender_ids
.begin(), normalized_sender_ids
.end());
169 // Simulate the registration_id by concaternating all sender IDs.
170 // Set registration_id to empty to denote an error if sender_ids contains a
172 std::string registration_id
;
173 if (sender_ids
.size() != 1 ||
174 sender_ids
[0].find("error") == std::string::npos
) {
175 for (size_t i
= 0; i
< normalized_sender_ids
.size(); ++i
) {
177 registration_id
+= ",";
178 registration_id
+= normalized_sender_ids
[i
];
180 registration_id
+= base::IntToString(sequence_id_
);
182 return registration_id
;
185 void FakeGCMClient::CheckinFinished() {
186 delegate_
->OnGCMReady(std::vector
<AccountMapping
>());
187 delegate_
->OnConnected(net::IPEndPoint());
190 void FakeGCMClient::RegisterFinished(const std::string
& app_id
,
191 const std::string
& registrion_id
) {
192 delegate_
->OnRegisterFinished(
193 app_id
, registrion_id
, registrion_id
.empty() ? SERVER_ERROR
: SUCCESS
);
196 void FakeGCMClient::UnregisterFinished(const std::string
& app_id
) {
197 delegate_
->OnUnregisterFinished(app_id
, GCMClient::SUCCESS
);
200 void FakeGCMClient::SendFinished(const std::string
& app_id
,
201 const OutgoingMessage
& message
) {
202 delegate_
->OnSendFinished(app_id
, message
.id
, SUCCESS
);
204 // Simulate send error if message id contains a hint.
205 if (message
.id
.find("error") != std::string::npos
) {
206 SendErrorDetails send_error_details
;
207 send_error_details
.message_id
= message
.id
;
208 send_error_details
.result
= NETWORK_ERROR
;
209 send_error_details
.additional_data
= message
.data
;
210 base::MessageLoop::current()->PostDelayedTask(
212 base::Bind(&FakeGCMClient::MessageSendError
,
213 weak_ptr_factory_
.GetWeakPtr(),
216 base::TimeDelta::FromMilliseconds(200));
217 } else if(message
.id
.find("ack") != std::string::npos
) {
218 base::MessageLoop::current()->PostDelayedTask(
220 base::Bind(&FakeGCMClient::SendAcknowledgement
,
221 weak_ptr_factory_
.GetWeakPtr(),
224 base::TimeDelta::FromMilliseconds(200));
229 void FakeGCMClient::MessageReceived(const std::string
& app_id
,
230 const IncomingMessage
& message
) {
232 delegate_
->OnMessageReceived(app_id
, message
);
235 void FakeGCMClient::MessagesDeleted(const std::string
& app_id
) {
237 delegate_
->OnMessagesDeleted(app_id
);
240 void FakeGCMClient::MessageSendError(
241 const std::string
& app_id
,
242 const GCMClient::SendErrorDetails
& send_error_details
) {
244 delegate_
->OnMessageSendError(app_id
, send_error_details
);
247 void FakeGCMClient::SendAcknowledgement(const std::string
& app_id
,
248 const std::string
& message_id
) {
250 delegate_
->OnSendAcknowledged(app_id
, message_id
);