blob: ea8992435f6cbf86db2518ad6098ba0002fa882d [file] [log] [blame]
[email protected]b16a7c52013-11-20 01:18:591// Copyright 2013 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.
4
5#include "chrome/browser/services/gcm/gcm_client_mock.h"
6
7#include "base/bind.h"
8#include "base/logging.h"
9#include "base/message_loop/message_loop.h"
10#include "base/sys_byteorder.h"
11#include "base/time/time.h"
12#include "content/public/browser/browser_thread.h"
13
14namespace gcm {
15
16namespace {
17
18// Converts the 8-byte prefix of a string into a uint64 value.
19uint64 HashToUInt64(const std::string& hash) {
20 uint64 value;
21 DCHECK_GE(hash.size(), sizeof(value));
22 memcpy(&value, hash.data(), sizeof(value));
23 return base::HostToNet64(value);
24}
25
26} // namespace
27
[email protected]1b1c3cd2013-12-17 18:40:0428GCMClientMock::GCMClientMock()
29 : is_loading_(false),
30 simulate_server_error_(false) {
[email protected]b16a7c52013-11-20 01:18:5931}
32
33GCMClientMock::~GCMClientMock() {
34}
35
[email protected]1b1c3cd2013-12-17 18:40:0436void GCMClientMock::SetUserDelegate(const std::string& username,
37 Delegate* delegate) {
[email protected]b16a7c52013-11-20 01:18:5938 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
39
[email protected]1b1c3cd2013-12-17 18:40:0440 if (delegate)
41 delegates_[username] = delegate;
42 else
43 delegates_.erase(username);
44}
45
46void GCMClientMock::CheckIn(const std::string& username) {
47 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
[email protected]b16a7c52013-11-20 01:18:5948
49 // Simulate the android_id and secret by some sort of hashing.
[email protected]cb9c0002014-01-09 01:37:0350 CheckinInfo checkin_info;
[email protected]1b1c3cd2013-12-17 18:40:0451 if (!simulate_server_error_)
[email protected]cb9c0002014-01-09 01:37:0352 checkin_info = GetCheckinInfoFromUsername(username);
[email protected]b16a7c52013-11-20 01:18:5953
54 base::MessageLoop::current()->PostTask(
55 FROM_HERE,
[email protected]eb44a8a2013-11-26 19:55:5356 base::Bind(&GCMClientMock::CheckInFinished,
[email protected]b16a7c52013-11-20 01:18:5957 base::Unretained(this),
58 username,
59 checkin_info));
60}
61
62void GCMClientMock::Register(const std::string& username,
63 const std::string& app_id,
64 const std::string& cert,
65 const std::vector<std::string>& sender_ids) {
66 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
67
[email protected]1b1c3cd2013-12-17 18:40:0468 std::string registration_id;
69 if (!simulate_server_error_)
70 registration_id = GetRegistrationIdFromSenderIds(sender_ids);
[email protected]b16a7c52013-11-20 01:18:5971
72 base::MessageLoop::current()->PostTask(
73 FROM_HERE,
74 base::Bind(&GCMClientMock::RegisterFinished,
75 base::Unretained(this),
76 username,
77 app_id,
78 registration_id));
79}
80
81void GCMClientMock::Unregister(const std::string& username,
82 const std::string& app_id) {
83}
84
85void GCMClientMock::Send(const std::string& username,
86 const std::string& app_id,
87 const std::string& receiver_id,
88 const OutgoingMessage& message) {
89 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
90
91 base::MessageLoop::current()->PostTask(
92 FROM_HERE,
93 base::Bind(&GCMClientMock::SendFinished,
94 base::Unretained(this),
95 username,
96 app_id,
97 message.id));
98}
99
100bool GCMClientMock::IsLoading() const {
[email protected]1b1c3cd2013-12-17 18:40:04101 return is_loading_;
[email protected]b16a7c52013-11-20 01:18:59102}
103
104void GCMClientMock::ReceiveMessage(const std::string& username,
105 const std::string& app_id,
106 const IncomingMessage& message) {
107 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
108
109 content::BrowserThread::PostTask(
110 content::BrowserThread::IO,
111 FROM_HERE,
112 base::Bind(&GCMClientMock::MessageReceived,
[email protected]d2281382013-11-22 21:48:54113 base::Unretained(this),
114 username,
[email protected]b16a7c52013-11-20 01:18:59115 app_id,
116 message));
117}
118
119void GCMClientMock::DeleteMessages(const std::string& username,
120 const std::string& app_id) {
121 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
122
123 content::BrowserThread::PostTask(
124 content::BrowserThread::IO,
125 FROM_HERE,
126 base::Bind(&GCMClientMock::MessagesDeleted,
[email protected]d2281382013-11-22 21:48:54127 base::Unretained(this),
128 username,
[email protected]b16a7c52013-11-20 01:18:59129 app_id));
130}
131
[email protected]1b1c3cd2013-12-17 18:40:04132void GCMClientMock::SetIsLoading(bool is_loading) {
133 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
134
135 if (is_loading == is_loading_)
136 return;
137 is_loading_ = is_loading;
138
139 if (is_loading_)
140 return;
141 content::BrowserThread::PostTask(
142 content::BrowserThread::IO,
143 FROM_HERE,
144 base::Bind(&GCMClientMock::LoadingCompleted,
145 base::Unretained(this)));
146}
147
148// static
[email protected]cb9c0002014-01-09 01:37:03149GCMClient::CheckinInfo GCMClientMock::GetCheckinInfoFromUsername(
[email protected]1b1c3cd2013-12-17 18:40:04150 const std::string& username) {
[email protected]cb9c0002014-01-09 01:37:03151 CheckinInfo checkin_info;
[email protected]b16a7c52013-11-20 01:18:59152 checkin_info.android_id = HashToUInt64(username);
153 checkin_info.secret = checkin_info.android_id / 10;
154 return checkin_info;
155}
156
[email protected]1b1c3cd2013-12-17 18:40:04157// static
[email protected]b16a7c52013-11-20 01:18:59158std::string GCMClientMock::GetRegistrationIdFromSenderIds(
[email protected]1b1c3cd2013-12-17 18:40:04159 const std::vector<std::string>& sender_ids) {
[email protected]c7f7b532014-01-24 07:24:45160 // GCMProfileService normalizes the sender IDs by making them sorted.
161 std::vector<std::string> normalized_sender_ids = sender_ids;
162 std::sort(normalized_sender_ids.begin(), normalized_sender_ids.end());
163
[email protected]b16a7c52013-11-20 01:18:59164 // Simulate the registration_id by concaternating all sender IDs.
165 // Set registration_id to empty to denote an error if sender_ids contains a
166 // hint.
167 std::string registration_id;
168 if (sender_ids.size() != 1 ||
169 sender_ids[0].find("error") == std::string::npos) {
[email protected]c7f7b532014-01-24 07:24:45170 for (size_t i = 0; i < normalized_sender_ids.size(); ++i) {
[email protected]b16a7c52013-11-20 01:18:59171 if (i > 0)
172 registration_id += ",";
[email protected]c7f7b532014-01-24 07:24:45173 registration_id += normalized_sender_ids[i];
[email protected]b16a7c52013-11-20 01:18:59174 }
175 }
176 return registration_id;
177}
178
179GCMClient::Delegate* GCMClientMock::GetDelegate(
180 const std::string& username) const {
181 std::map<std::string, Delegate*>::const_iterator iter =
182 delegates_.find(username);
[email protected]c7f7b532014-01-24 07:24:45183 return iter == delegates_.end() ? NULL : iter->second;
[email protected]b16a7c52013-11-20 01:18:59184}
185
[email protected]eb44a8a2013-11-26 19:55:53186void GCMClientMock::CheckInFinished(std::string username,
[email protected]cb9c0002014-01-09 01:37:03187 CheckinInfo checkin_info) {
[email protected]c7f7b532014-01-24 07:24:45188 GCMClient::Delegate* delegate = GetDelegate(username);
189 DCHECK(delegate);
190 delegate->OnCheckInFinished(
[email protected]b16a7c52013-11-20 01:18:59191 checkin_info, checkin_info.IsValid() ? SUCCESS : SERVER_ERROR);
192}
193
194void GCMClientMock::RegisterFinished(std::string username,
195 std::string app_id,
196 std::string registrion_id) {
[email protected]c7f7b532014-01-24 07:24:45197 GCMClient::Delegate* delegate = GetDelegate(username);
198 DCHECK(delegate);
199 delegate->OnRegisterFinished(
[email protected]b16a7c52013-11-20 01:18:59200 app_id, registrion_id, registrion_id.empty() ? SERVER_ERROR : SUCCESS);
201}
202
203void GCMClientMock::SendFinished(std::string username,
204 std::string app_id,
205 std::string message_id) {
[email protected]c7f7b532014-01-24 07:24:45206 GCMClient::Delegate* delegate = GetDelegate(username);
207 DCHECK(delegate);
208 delegate->OnSendFinished(app_id, message_id, SUCCESS);
[email protected]b16a7c52013-11-20 01:18:59209
210 // Simulate send error if message id contains a hint.
211 if (message_id.find("error") != std::string::npos) {
212 base::MessageLoop::current()->PostDelayedTask(
213 FROM_HERE,
214 base::Bind(&GCMClientMock::MessageSendError,
215 base::Unretained(this),
216 username,
217 app_id,
218 message_id),
219 base::TimeDelta::FromMilliseconds(200));
220 }
221}
222
223void GCMClientMock::MessageReceived(std::string username,
224 std::string app_id,
225 IncomingMessage message) {
[email protected]c7f7b532014-01-24 07:24:45226 GCMClient::Delegate* delegate = GetDelegate(username);
227 if (delegate)
228 delegate->OnMessageReceived(app_id, message);
[email protected]b16a7c52013-11-20 01:18:59229}
230
231void GCMClientMock::MessagesDeleted(std::string username, std::string app_id) {
[email protected]c7f7b532014-01-24 07:24:45232 GCMClient::Delegate* delegate = GetDelegate(username);
233 if (delegate)
234 delegate->OnMessagesDeleted(app_id);
[email protected]b16a7c52013-11-20 01:18:59235}
236
237void GCMClientMock::MessageSendError(std::string username,
238 std::string app_id,
239 std::string message_id) {
[email protected]c7f7b532014-01-24 07:24:45240 GCMClient::Delegate* delegate = GetDelegate(username);
241 if (delegate)
242 delegate->OnMessageSendError(app_id, message_id, NETWORK_ERROR);
[email protected]b16a7c52013-11-20 01:18:59243}
244
[email protected]1b1c3cd2013-12-17 18:40:04245void GCMClientMock::LoadingCompleted() {
246 for (std::map<std::string, Delegate*>::const_iterator iter =
247 delegates_.begin();
248 iter != delegates_.end(); ++iter) {
249 iter->second->OnLoadingCompleted();
250 }
251}
252
[email protected]b16a7c52013-11-20 01:18:59253} // namespace gcm