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::SetLastTokenFetchTime(const base::Time
& time
) {
136 void FakeGCMClient::PerformDelayedLoading() {
137 DCHECK(ui_thread_
->RunsTasksOnCurrentThread());
139 io_thread_
->PostTask(
141 base::Bind(&FakeGCMClient::DoLoading
, weak_ptr_factory_
.GetWeakPtr()));
144 void FakeGCMClient::ReceiveMessage(const std::string
& app_id
,
145 const IncomingMessage
& message
) {
146 DCHECK(ui_thread_
->RunsTasksOnCurrentThread());
148 io_thread_
->PostTask(
150 base::Bind(&FakeGCMClient::MessageReceived
,
151 weak_ptr_factory_
.GetWeakPtr(),
156 void FakeGCMClient::DeleteMessages(const std::string
& app_id
) {
157 DCHECK(ui_thread_
->RunsTasksOnCurrentThread());
159 io_thread_
->PostTask(
161 base::Bind(&FakeGCMClient::MessagesDeleted
,
162 weak_ptr_factory_
.GetWeakPtr(),
166 std::string
FakeGCMClient::GetRegistrationIdFromSenderIds(
167 const std::vector
<std::string
>& sender_ids
) const {
168 // GCMService normalizes the sender IDs by making them sorted.
169 std::vector
<std::string
> normalized_sender_ids
= sender_ids
;
170 std::sort(normalized_sender_ids
.begin(), normalized_sender_ids
.end());
172 // Simulate the registration_id by concaternating all sender IDs.
173 // Set registration_id to empty to denote an error if sender_ids contains a
175 std::string registration_id
;
176 if (sender_ids
.size() != 1 ||
177 sender_ids
[0].find("error") == std::string::npos
) {
178 for (size_t i
= 0; i
< normalized_sender_ids
.size(); ++i
) {
180 registration_id
+= ",";
181 registration_id
+= normalized_sender_ids
[i
];
183 registration_id
+= base::IntToString(sequence_id_
);
185 return registration_id
;
188 void FakeGCMClient::CheckinFinished() {
189 delegate_
->OnGCMReady(std::vector
<AccountMapping
>(), base::Time());
190 delegate_
->OnConnected(net::IPEndPoint());
193 void FakeGCMClient::RegisterFinished(const std::string
& app_id
,
194 const std::string
& registrion_id
) {
195 delegate_
->OnRegisterFinished(
196 app_id
, registrion_id
, registrion_id
.empty() ? SERVER_ERROR
: SUCCESS
);
199 void FakeGCMClient::UnregisterFinished(const std::string
& app_id
) {
200 delegate_
->OnUnregisterFinished(app_id
, GCMClient::SUCCESS
);
203 void FakeGCMClient::SendFinished(const std::string
& app_id
,
204 const OutgoingMessage
& message
) {
205 delegate_
->OnSendFinished(app_id
, message
.id
, SUCCESS
);
207 // Simulate send error if message id contains a hint.
208 if (message
.id
.find("error") != std::string::npos
) {
209 SendErrorDetails send_error_details
;
210 send_error_details
.message_id
= message
.id
;
211 send_error_details
.result
= NETWORK_ERROR
;
212 send_error_details
.additional_data
= message
.data
;
213 base::MessageLoop::current()->PostDelayedTask(
215 base::Bind(&FakeGCMClient::MessageSendError
,
216 weak_ptr_factory_
.GetWeakPtr(),
219 base::TimeDelta::FromMilliseconds(200));
220 } else if(message
.id
.find("ack") != std::string::npos
) {
221 base::MessageLoop::current()->PostDelayedTask(
223 base::Bind(&FakeGCMClient::SendAcknowledgement
,
224 weak_ptr_factory_
.GetWeakPtr(),
227 base::TimeDelta::FromMilliseconds(200));
232 void FakeGCMClient::MessageReceived(const std::string
& app_id
,
233 const IncomingMessage
& message
) {
235 delegate_
->OnMessageReceived(app_id
, message
);
238 void FakeGCMClient::MessagesDeleted(const std::string
& app_id
) {
240 delegate_
->OnMessagesDeleted(app_id
);
243 void FakeGCMClient::MessageSendError(
244 const std::string
& app_id
,
245 const GCMClient::SendErrorDetails
& send_error_details
) {
247 delegate_
->OnMessageSendError(app_id
, send_error_details
);
250 void FakeGCMClient::SendAcknowledgement(const std::string
& app_id
,
251 const std::string
& message_id
) {
253 delegate_
->OnSendAcknowledged(app_id
, message_id
);