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"
17 FakeGCMClient::FakeGCMClient(
19 const scoped_refptr
<base::SequencedTaskRunner
>& ui_thread
,
20 const scoped_refptr
<base::SequencedTaskRunner
>& io_thread
)
22 status_(UNINITIALIZED
),
23 start_mode_(start_mode
),
24 ui_thread_(ui_thread
),
25 io_thread_(io_thread
),
26 weak_ptr_factory_(this) {
29 FakeGCMClient::~FakeGCMClient() {
32 void FakeGCMClient::Initialize(
33 const ChromeBuildInfo
& chrome_build_info
,
34 const base::FilePath
& store_path
,
35 const std::vector
<std::string
>& account_ids
,
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());
66 void FakeGCMClient::CheckOut() {
67 DCHECK(io_thread_
->RunsTasksOnCurrentThread());
68 status_
= CHECKED_OUT
;
71 void FakeGCMClient::Register(const std::string
& app_id
,
72 const std::vector
<std::string
>& sender_ids
) {
73 DCHECK(io_thread_
->RunsTasksOnCurrentThread());
75 std::string registration_id
= GetRegistrationIdFromSenderIds(sender_ids
);
76 base::MessageLoop::current()->PostTask(
78 base::Bind(&FakeGCMClient::RegisterFinished
,
79 weak_ptr_factory_
.GetWeakPtr(),
84 void FakeGCMClient::Unregister(const std::string
& app_id
) {
85 DCHECK(io_thread_
->RunsTasksOnCurrentThread());
87 base::MessageLoop::current()->PostTask(
89 base::Bind(&FakeGCMClient::UnregisterFinished
,
90 weak_ptr_factory_
.GetWeakPtr(),
94 void FakeGCMClient::Send(const std::string
& app_id
,
95 const std::string
& receiver_id
,
96 const OutgoingMessage
& message
) {
97 DCHECK(io_thread_
->RunsTasksOnCurrentThread());
99 base::MessageLoop::current()->PostTask(
101 base::Bind(&FakeGCMClient::SendFinished
,
102 weak_ptr_factory_
.GetWeakPtr(),
107 void FakeGCMClient::SetRecording(bool recording
) {
110 void FakeGCMClient::ClearActivityLogs() {
113 GCMClient::GCMStatistics
FakeGCMClient::GetStatistics() const {
114 return GCMClient::GCMStatistics();
117 void FakeGCMClient::PerformDelayedLoading() {
118 DCHECK(ui_thread_
->RunsTasksOnCurrentThread());
120 io_thread_
->PostTask(
122 base::Bind(&FakeGCMClient::DoLoading
, weak_ptr_factory_
.GetWeakPtr()));
125 void FakeGCMClient::ReceiveMessage(const std::string
& app_id
,
126 const IncomingMessage
& message
) {
127 DCHECK(ui_thread_
->RunsTasksOnCurrentThread());
129 io_thread_
->PostTask(
131 base::Bind(&FakeGCMClient::MessageReceived
,
132 weak_ptr_factory_
.GetWeakPtr(),
137 void FakeGCMClient::DeleteMessages(const std::string
& app_id
) {
138 DCHECK(ui_thread_
->RunsTasksOnCurrentThread());
140 io_thread_
->PostTask(
142 base::Bind(&FakeGCMClient::MessagesDeleted
,
143 weak_ptr_factory_
.GetWeakPtr(),
148 std::string
FakeGCMClient::GetRegistrationIdFromSenderIds(
149 const std::vector
<std::string
>& sender_ids
) {
150 // GCMService normalizes the sender IDs by making them sorted.
151 std::vector
<std::string
> normalized_sender_ids
= sender_ids
;
152 std::sort(normalized_sender_ids
.begin(), normalized_sender_ids
.end());
154 // Simulate the registration_id by concaternating all sender IDs.
155 // Set registration_id to empty to denote an error if sender_ids contains a
157 std::string registration_id
;
158 if (sender_ids
.size() != 1 ||
159 sender_ids
[0].find("error") == std::string::npos
) {
160 for (size_t i
= 0; i
< normalized_sender_ids
.size(); ++i
) {
162 registration_id
+= ",";
163 registration_id
+= normalized_sender_ids
[i
];
166 return registration_id
;
169 void FakeGCMClient::CheckinFinished() {
170 delegate_
->OnGCMReady();
173 void FakeGCMClient::RegisterFinished(const std::string
& app_id
,
174 const std::string
& registrion_id
) {
175 delegate_
->OnRegisterFinished(
176 app_id
, registrion_id
, registrion_id
.empty() ? SERVER_ERROR
: SUCCESS
);
179 void FakeGCMClient::UnregisterFinished(const std::string
& app_id
) {
180 delegate_
->OnUnregisterFinished(app_id
, GCMClient::SUCCESS
);
183 void FakeGCMClient::SendFinished(const std::string
& app_id
,
184 const OutgoingMessage
& message
) {
185 delegate_
->OnSendFinished(app_id
, message
.id
, SUCCESS
);
187 // Simulate send error if message id contains a hint.
188 if (message
.id
.find("error") != std::string::npos
) {
189 SendErrorDetails send_error_details
;
190 send_error_details
.message_id
= message
.id
;
191 send_error_details
.result
= NETWORK_ERROR
;
192 send_error_details
.additional_data
= message
.data
;
193 base::MessageLoop::current()->PostDelayedTask(
195 base::Bind(&FakeGCMClient::MessageSendError
,
196 weak_ptr_factory_
.GetWeakPtr(),
199 base::TimeDelta::FromMilliseconds(200));
203 void FakeGCMClient::MessageReceived(const std::string
& app_id
,
204 const IncomingMessage
& message
) {
206 delegate_
->OnMessageReceived(app_id
, message
);
209 void FakeGCMClient::MessagesDeleted(const std::string
& app_id
) {
211 delegate_
->OnMessagesDeleted(app_id
);
214 void FakeGCMClient::MessageSendError(
215 const std::string
& app_id
,
216 const GCMClient::SendErrorDetails
& send_error_details
) {
218 delegate_
->OnMessageSendError(app_id
, send_error_details
);