1 // 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.
5 #include "chrome/browser/services/gcm/gcm_client_mock.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"
18 // Converts the 8-byte prefix of a string into a uint64 value.
19 uint64
HashToUInt64(const std::string
& hash
) {
21 DCHECK_GE(hash
.size(), sizeof(value
));
22 memcpy(&value
, hash
.data(), sizeof(value
));
23 return base::HostToNet64(value
);
28 GCMClientMock::GCMClientMock()
30 simulate_server_error_(false) {
33 GCMClientMock::~GCMClientMock() {
36 void GCMClientMock::SetUserDelegate(const std::string
& username
,
38 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO
));
41 delegates_
[username
] = delegate
;
43 delegates_
.erase(username
);
46 void GCMClientMock::CheckIn(const std::string
& username
) {
47 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO
));
49 // Simulate the android_id and secret by some sort of hashing.
50 CheckinInfo checkin_info
;
51 if (!simulate_server_error_
)
52 checkin_info
= GetCheckinInfoFromUsername(username
);
54 base::MessageLoop::current()->PostTask(
56 base::Bind(&GCMClientMock::CheckInFinished
,
57 base::Unretained(this),
62 void 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
));
68 std::string registration_id
;
69 if (!simulate_server_error_
)
70 registration_id
= GetRegistrationIdFromSenderIds(sender_ids
);
72 base::MessageLoop::current()->PostTask(
74 base::Bind(&GCMClientMock::RegisterFinished
,
75 base::Unretained(this),
81 void GCMClientMock::Unregister(const std::string
& username
,
82 const std::string
& app_id
) {
85 void 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
));
91 base::MessageLoop::current()->PostTask(
93 base::Bind(&GCMClientMock::SendFinished
,
94 base::Unretained(this),
100 bool GCMClientMock::IsLoading() const {
104 void GCMClientMock::ReceiveMessage(const std::string
& username
,
105 const std::string
& app_id
,
106 const IncomingMessage
& message
) {
107 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI
));
109 content::BrowserThread::PostTask(
110 content::BrowserThread::IO
,
112 base::Bind(&GCMClientMock::MessageReceived
,
113 base::Unretained(this),
119 void GCMClientMock::DeleteMessages(const std::string
& username
,
120 const std::string
& app_id
) {
121 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI
));
123 content::BrowserThread::PostTask(
124 content::BrowserThread::IO
,
126 base::Bind(&GCMClientMock::MessagesDeleted
,
127 base::Unretained(this),
132 void GCMClientMock::SetIsLoading(bool is_loading
) {
133 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI
));
135 if (is_loading
== is_loading_
)
137 is_loading_
= is_loading
;
141 content::BrowserThread::PostTask(
142 content::BrowserThread::IO
,
144 base::Bind(&GCMClientMock::LoadingCompleted
,
145 base::Unretained(this)));
149 GCMClient::CheckinInfo
GCMClientMock::GetCheckinInfoFromUsername(
150 const std::string
& username
) {
151 CheckinInfo checkin_info
;
152 checkin_info
.android_id
= HashToUInt64(username
);
153 checkin_info
.secret
= checkin_info
.android_id
/ 10;
158 std::string
GCMClientMock::GetRegistrationIdFromSenderIds(
159 const std::vector
<std::string
>& sender_ids
) {
160 // Simulate the registration_id by concaternating all sender IDs.
161 // Set registration_id to empty to denote an error if sender_ids contains a
163 std::string registration_id
;
164 if (sender_ids
.size() != 1 ||
165 sender_ids
[0].find("error") == std::string::npos
) {
166 for (size_t i
= 0; i
< sender_ids
.size(); ++i
) {
168 registration_id
+= ",";
169 registration_id
+= sender_ids
[i
];
172 return registration_id
;
175 GCMClient::Delegate
* GCMClientMock::GetDelegate(
176 const std::string
& username
) const {
177 std::map
<std::string
, Delegate
*>::const_iterator iter
=
178 delegates_
.find(username
);
179 DCHECK(iter
!= delegates_
.end());
183 void GCMClientMock::CheckInFinished(std::string username
,
184 CheckinInfo checkin_info
) {
185 GetDelegate(username
)->OnCheckInFinished(
186 checkin_info
, checkin_info
.IsValid() ? SUCCESS
: SERVER_ERROR
);
189 void GCMClientMock::RegisterFinished(std::string username
,
191 std::string registrion_id
) {
192 GetDelegate(username
)->OnRegisterFinished(
193 app_id
, registrion_id
, registrion_id
.empty() ? SERVER_ERROR
: SUCCESS
);
196 void GCMClientMock::SendFinished(std::string username
,
198 std::string message_id
) {
199 GetDelegate(username
)->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 base::MessageLoop::current()->PostDelayedTask(
205 base::Bind(&GCMClientMock::MessageSendError
,
206 base::Unretained(this),
210 base::TimeDelta::FromMilliseconds(200));
214 void GCMClientMock::MessageReceived(std::string username
,
216 IncomingMessage message
) {
217 GetDelegate(username
)->OnMessageReceived(app_id
, message
);
220 void GCMClientMock::MessagesDeleted(std::string username
, std::string app_id
) {
221 GetDelegate(username
)->OnMessagesDeleted(app_id
);
224 void GCMClientMock::MessageSendError(std::string username
,
226 std::string message_id
) {
227 GetDelegate(username
)->OnMessageSendError(app_id
, message_id
, NETWORK_ERROR
);
230 void GCMClientMock::LoadingCompleted() {
231 for (std::map
<std::string
, Delegate
*>::const_iterator iter
=
233 iter
!= delegates_
.end(); ++iter
) {
234 iter
->second
->OnLoadingCompleted();