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 "google_apis/gcm/engine/account_mapping.h"
15 #include "net/base/ip_endpoint.h"
19 FakeGCMClient::FakeGCMClient(
21 const scoped_refptr<base::SequencedTaskRunner>& ui_thread,
22 const scoped_refptr<base::SequencedTaskRunner>& io_thread)
24 status_(UNINITIALIZED),
25 start_mode_(start_mode),
26 ui_thread_(ui_thread),
27 io_thread_(io_thread),
28 weak_ptr_factory_(this) {
31 FakeGCMClient::~FakeGCMClient() {
34 void FakeGCMClient::Initialize(
35 const ChromeBuildInfo& chrome_build_info,
36 const base::FilePath& store_path,
37 const scoped_refptr<base::SequencedTaskRunner>& blocking_task_runner,
38 const scoped_refptr<net::URLRequestContextGetter>&
39 url_request_context_getter,
40 scoped_ptr<Encryptor> encryptor,
45 void FakeGCMClient::Start() {
46 DCHECK(io_thread_->RunsTasksOnCurrentThread());
47 DCHECK_NE(STARTED, status_);
49 if (start_mode_ == DELAY_START)
54 void FakeGCMClient::DoLoading() {
56 base::MessageLoop::current()->PostTask(
58 base::Bind(&FakeGCMClient::CheckinFinished,
59 weak_ptr_factory_.GetWeakPtr()));
62 void FakeGCMClient::Stop() {
63 DCHECK(io_thread_->RunsTasksOnCurrentThread());
65 delegate_->OnDisconnected();
68 void FakeGCMClient::CheckOut() {
69 DCHECK(io_thread_->RunsTasksOnCurrentThread());
70 status_ = CHECKED_OUT;
73 void FakeGCMClient::Register(const std::string& app_id,
74 const std::vector<std::string>& sender_ids) {
75 DCHECK(io_thread_->RunsTasksOnCurrentThread());
77 std::string registration_id = GetRegistrationIdFromSenderIds(sender_ids);
78 base::MessageLoop::current()->PostTask(
80 base::Bind(&FakeGCMClient::RegisterFinished,
81 weak_ptr_factory_.GetWeakPtr(),
86 void FakeGCMClient::Unregister(const std::string& app_id) {
87 DCHECK(io_thread_->RunsTasksOnCurrentThread());
89 base::MessageLoop::current()->PostTask(
91 base::Bind(&FakeGCMClient::UnregisterFinished,
92 weak_ptr_factory_.GetWeakPtr(),
96 void FakeGCMClient::Send(const std::string& app_id,
97 const std::string& receiver_id,
98 const OutgoingMessage& message) {
99 DCHECK(io_thread_->RunsTasksOnCurrentThread());
101 base::MessageLoop::current()->PostTask(
103 base::Bind(&FakeGCMClient::SendFinished,
104 weak_ptr_factory_.GetWeakPtr(),
109 void FakeGCMClient::SetRecording(bool recording) {
112 void FakeGCMClient::ClearActivityLogs() {
115 GCMClient::GCMStatistics FakeGCMClient::GetStatistics() const {
116 return GCMClient::GCMStatistics();
119 void FakeGCMClient::SetAccountsForCheckin(
120 const std::map<std::string, std::string>& account_tokens) {
123 void FakeGCMClient::UpdateAccountMapping(
124 const AccountMapping& account_mapping) {
127 void FakeGCMClient::RemoveAccountMapping(const std::string& account_id) {
130 void FakeGCMClient::PerformDelayedLoading() {
131 DCHECK(ui_thread_->RunsTasksOnCurrentThread());
133 io_thread_->PostTask(
135 base::Bind(&FakeGCMClient::DoLoading, weak_ptr_factory_.GetWeakPtr()));
138 void FakeGCMClient::ReceiveMessage(const std::string& app_id,
139 const IncomingMessage& message) {
140 DCHECK(ui_thread_->RunsTasksOnCurrentThread());
142 io_thread_->PostTask(
144 base::Bind(&FakeGCMClient::MessageReceived,
145 weak_ptr_factory_.GetWeakPtr(),
150 void FakeGCMClient::DeleteMessages(const std::string& app_id) {
151 DCHECK(ui_thread_->RunsTasksOnCurrentThread());
153 io_thread_->PostTask(
155 base::Bind(&FakeGCMClient::MessagesDeleted,
156 weak_ptr_factory_.GetWeakPtr(),
161 std::string FakeGCMClient::GetRegistrationIdFromSenderIds(
162 const std::vector<std::string>& sender_ids) {
163 // GCMService normalizes the sender IDs by making them sorted.
164 std::vector<std::string> normalized_sender_ids = sender_ids;
165 std::sort(normalized_sender_ids.begin(), normalized_sender_ids.end());
167 // Simulate the registration_id by concaternating all sender IDs.
168 // Set registration_id to empty to denote an error if sender_ids contains a
170 std::string registration_id;
171 if (sender_ids.size() != 1 ||
172 sender_ids[0].find("error") == std::string::npos) {
173 for (size_t i = 0; i < normalized_sender_ids.size(); ++i) {
175 registration_id += ",";
176 registration_id += normalized_sender_ids[i];
179 return registration_id;
182 void FakeGCMClient::CheckinFinished() {
183 delegate_->OnGCMReady(std::vector<AccountMapping>());
184 delegate_->OnConnected(net::IPEndPoint());
187 void FakeGCMClient::RegisterFinished(const std::string& app_id,
188 const std::string& registrion_id) {
189 delegate_->OnRegisterFinished(
190 app_id, registrion_id, registrion_id.empty() ? SERVER_ERROR : SUCCESS);
193 void FakeGCMClient::UnregisterFinished(const std::string& app_id) {
194 delegate_->OnUnregisterFinished(app_id, GCMClient::SUCCESS);
197 void FakeGCMClient::SendFinished(const std::string& app_id,
198 const OutgoingMessage& message) {
199 delegate_->OnSendFinished(app_id, message.id, SUCCESS);
201 // Simulate send error if message id contains a hint.
202 if (message.id.find("error") != std::string::npos) {
203 SendErrorDetails send_error_details;
204 send_error_details.message_id = message.id;
205 send_error_details.result = NETWORK_ERROR;
206 send_error_details.additional_data = message.data;
207 base::MessageLoop::current()->PostDelayedTask(
209 base::Bind(&FakeGCMClient::MessageSendError,
210 weak_ptr_factory_.GetWeakPtr(),
213 base::TimeDelta::FromMilliseconds(200));
214 } else if(message.id.find("ack") != std::string::npos) {
215 base::MessageLoop::current()->PostDelayedTask(
217 base::Bind(&FakeGCMClient::SendAcknowledgement,
218 weak_ptr_factory_.GetWeakPtr(),
221 base::TimeDelta::FromMilliseconds(200));
226 void FakeGCMClient::MessageReceived(const std::string& app_id,
227 const IncomingMessage& message) {
229 delegate_->OnMessageReceived(app_id, message);
232 void FakeGCMClient::MessagesDeleted(const std::string& app_id) {
234 delegate_->OnMessagesDeleted(app_id);
237 void FakeGCMClient::MessageSendError(
238 const std::string& app_id,
239 const GCMClient::SendErrorDetails& send_error_details) {
241 delegate_->OnMessageSendError(app_id, send_error_details);
244 void FakeGCMClient::SendAcknowledgement(const std::string& app_id,
245 const std::string& message_id) {
247 delegate_->OnSendAcknowledged(app_id, message_id);