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::PerformDelayedLoading() {
123 DCHECK(ui_thread_->RunsTasksOnCurrentThread());
125 io_thread_->PostTask(
127 base::Bind(&FakeGCMClient::DoLoading, weak_ptr_factory_.GetWeakPtr()));
130 void FakeGCMClient::ReceiveMessage(const std::string& app_id,
131 const IncomingMessage& message) {
132 DCHECK(ui_thread_->RunsTasksOnCurrentThread());
134 io_thread_->PostTask(
136 base::Bind(&FakeGCMClient::MessageReceived,
137 weak_ptr_factory_.GetWeakPtr(),
142 void FakeGCMClient::DeleteMessages(const std::string& app_id) {
143 DCHECK(ui_thread_->RunsTasksOnCurrentThread());
145 io_thread_->PostTask(
147 base::Bind(&FakeGCMClient::MessagesDeleted,
148 weak_ptr_factory_.GetWeakPtr(),
153 std::string FakeGCMClient::GetRegistrationIdFromSenderIds(
154 const std::vector<std::string>& sender_ids) {
155 // GCMService normalizes the sender IDs by making them sorted.
156 std::vector<std::string> normalized_sender_ids = sender_ids;
157 std::sort(normalized_sender_ids.begin(), normalized_sender_ids.end());
159 // Simulate the registration_id by concaternating all sender IDs.
160 // Set registration_id to empty to denote an error if sender_ids contains a
162 std::string registration_id;
163 if (sender_ids.size() != 1 ||
164 sender_ids[0].find("error") == std::string::npos) {
165 for (size_t i = 0; i < normalized_sender_ids.size(); ++i) {
167 registration_id += ",";
168 registration_id += normalized_sender_ids[i];
171 return registration_id;
174 void FakeGCMClient::CheckinFinished() {
175 delegate_->OnGCMReady();
176 delegate_->OnConnected(net::IPEndPoint());
179 void FakeGCMClient::RegisterFinished(const std::string& app_id,
180 const std::string& registrion_id) {
181 delegate_->OnRegisterFinished(
182 app_id, registrion_id, registrion_id.empty() ? SERVER_ERROR : SUCCESS);
185 void FakeGCMClient::UnregisterFinished(const std::string& app_id) {
186 delegate_->OnUnregisterFinished(app_id, GCMClient::SUCCESS);
189 void FakeGCMClient::SendFinished(const std::string& app_id,
190 const OutgoingMessage& message) {
191 delegate_->OnSendFinished(app_id, message.id, SUCCESS);
193 // Simulate send error if message id contains a hint.
194 if (message.id.find("error") != std::string::npos) {
195 SendErrorDetails send_error_details;
196 send_error_details.message_id = message.id;
197 send_error_details.result = NETWORK_ERROR;
198 send_error_details.additional_data = message.data;
199 base::MessageLoop::current()->PostDelayedTask(
201 base::Bind(&FakeGCMClient::MessageSendError,
202 weak_ptr_factory_.GetWeakPtr(),
205 base::TimeDelta::FromMilliseconds(200));
206 } else if(message.id.find("ack") != std::string::npos) {
207 base::MessageLoop::current()->PostDelayedTask(
209 base::Bind(&FakeGCMClient::SendAcknowledgement,
210 weak_ptr_factory_.GetWeakPtr(),
213 base::TimeDelta::FromMilliseconds(200));
218 void FakeGCMClient::MessageReceived(const std::string& app_id,
219 const IncomingMessage& message) {
221 delegate_->OnMessageReceived(app_id, message);
224 void FakeGCMClient::MessagesDeleted(const std::string& app_id) {
226 delegate_->OnMessagesDeleted(app_id);
229 void FakeGCMClient::MessageSendError(
230 const std::string& app_id,
231 const GCMClient::SendErrorDetails& send_error_details) {
233 delegate_->OnMessageSendError(app_id, send_error_details);
236 void FakeGCMClient::SendAcknowledgement(const std::string& app_id,
237 const std::string& message_id) {
239 delegate_->OnSendAcknowledged(app_id, message_id);