blob: ef2acf05aa3b33ef73895c92fafc1e6882359a65 [file] [log] [blame]
[email protected]accbbc92014-05-15 21:28:591// Copyright 2014 The Chromium Authors. All rights reserved.
[email protected]b16a7c52013-11-20 01:18:592// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
[email protected]8d41e5a2014-05-28 03:18:495#include "components/gcm_driver/fake_gcm_client.h"
[email protected]b16a7c52013-11-20 01:18:596
avi26062922015-12-26 00:14:187#include <stddef.h>
8
dcheng0917ec42015-11-19 07:00:209#include <algorithm>
10
[email protected]b16a7c52013-11-20 01:18:5911#include "base/bind.h"
skyostilb0daa012015-06-02 19:03:4812#include "base/location.h"
[email protected]b16a7c52013-11-20 01:18:5913#include "base/logging.h"
[email protected]1795df51a2014-05-22 20:18:0414#include "base/sequenced_task_runner.h"
skyostilb0daa012015-06-02 19:03:4815#include "base/single_thread_task_runner.h"
jianli15aecc152014-10-07 03:03:5316#include "base/strings/string_number_conversions.h"
[email protected]b16a7c52013-11-20 01:18:5917#include "base/sys_byteorder.h"
skyostilb0daa012015-06-02 19:03:4818#include "base/thread_task_runner_handle.h"
[email protected]b16a7c52013-11-20 01:18:5919#include "base/time/time.h"
chirantan192a9212014-12-06 03:30:4520#include "base/timer/timer.h"
[email protected]446f73c22014-05-14 20:47:1821#include "google_apis/gcm/base/encryptor.h"
fgorskid578c18b2014-09-24 23:40:1722#include "google_apis/gcm/engine/account_mapping.h"
[email protected]fc6078a2014-06-14 08:28:4323#include "net/base/ip_endpoint.h"
[email protected]b16a7c52013-11-20 01:18:5924
25namespace gcm {
26
jianli012b5c82015-05-28 01:41:2927// static
28std::string FakeGCMClient::GenerateGCMRegistrationID(
29 const std::vector<std::string>& sender_ids) {
30 // GCMService normalizes the sender IDs by making them sorted.
31 std::vector<std::string> normalized_sender_ids = sender_ids;
32 std::sort(normalized_sender_ids.begin(), normalized_sender_ids.end());
33
34 // Simulate the registration_id by concaternating all sender IDs.
35 // Set registration_id to empty to denote an error if sender_ids contains a
36 // hint.
37 std::string registration_id;
38 if (sender_ids.size() != 1 ||
39 sender_ids[0].find("error") == std::string::npos) {
40 for (size_t i = 0; i < normalized_sender_ids.size(); ++i) {
41 if (i > 0)
42 registration_id += ",";
43 registration_id += normalized_sender_ids[i];
44 }
45 }
46 return registration_id;
47}
48
49// static
50std::string FakeGCMClient::GenerateInstanceIDToken(
51 const std::string& authorized_entity, const std::string& scope) {
52 if (authorized_entity.find("error") != std::string::npos)
53 return "";
54 std::string token(authorized_entity);
55 token += ",";
56 token += scope;
57 return token;
58}
59
[email protected]1795df51a2014-05-22 20:18:0460FakeGCMClient::FakeGCMClient(
[email protected]1795df51a2014-05-22 20:18:0461 const scoped_refptr<base::SequencedTaskRunner>& ui_thread,
62 const scoped_refptr<base::SequencedTaskRunner>& io_thread)
[email protected]5799d052014-02-12 20:47:3963 : delegate_(NULL),
jianli19562592015-01-12 20:16:3064 started_(false),
jianlif3e52af42015-01-21 23:18:4765 start_mode_(DELAYED_START),
66 start_mode_overridding_(RESPECT_START_MODE),
[email protected]1795df51a2014-05-22 20:18:0467 ui_thread_(ui_thread),
68 io_thread_(io_thread),
[email protected]d3a4b2e2014-02-27 13:46:5469 weak_ptr_factory_(this) {
[email protected]b16a7c52013-11-20 01:18:5970}
71
[email protected]accbbc92014-05-15 21:28:5972FakeGCMClient::~FakeGCMClient() {
[email protected]b16a7c52013-11-20 01:18:5973}
74
[email protected]accbbc92014-05-15 21:28:5975void FakeGCMClient::Initialize(
[email protected]8ad80512014-05-23 09:40:4776 const ChromeBuildInfo& chrome_build_info,
[email protected]e2a4a8012014-02-07 22:32:5277 const base::FilePath& store_path,
78 const scoped_refptr<base::SequencedTaskRunner>& blocking_task_runner,
79 const scoped_refptr<net::URLRequestContextGetter>&
[email protected]5799d052014-02-12 20:47:3980 url_request_context_getter,
[email protected]446f73c22014-05-14 20:47:1881 scoped_ptr<Encryptor> encryptor,
[email protected]5799d052014-02-12 20:47:3982 Delegate* delegate) {
83 delegate_ = delegate;
[email protected]e2a4a8012014-02-07 22:32:5284}
85
jianlif3e52af42015-01-21 23:18:4786void FakeGCMClient::Start(StartMode start_mode) {
[email protected]1795df51a2014-05-22 20:18:0487 DCHECK(io_thread_->RunsTasksOnCurrentThread());
[email protected]d3a4b2e2014-02-27 13:46:5488
jianlif3e52af42015-01-21 23:18:4789 if (started_)
[email protected]d3a4b2e2014-02-27 13:46:5490 return;
jianlif3e52af42015-01-21 23:18:4791
92 if (start_mode == IMMEDIATE_START)
93 start_mode_ = IMMEDIATE_START;
94 if (start_mode_ == DELAYED_START ||
95 start_mode_overridding_ == FORCE_TO_ALWAYS_DELAY_START_GCM) {
96 return;
97 }
98
99 DoStart();
[email protected]d3a4b2e2014-02-27 13:46:54100}
101
jianlif3e52af42015-01-21 23:18:47102void FakeGCMClient::DoStart() {
jianli19562592015-01-12 20:16:30103 started_ = true;
skyostilb0daa012015-06-02 19:03:48104 base::ThreadTaskRunnerHandle::Get()->PostTask(
[email protected]d3a4b2e2014-02-27 13:46:54105 FROM_HERE,
skyostilb0daa012015-06-02 19:03:48106 base::Bind(&FakeGCMClient::Started, weak_ptr_factory_.GetWeakPtr()));
[email protected]d3a4b2e2014-02-27 13:46:54107}
108
[email protected]accbbc92014-05-15 21:28:59109void FakeGCMClient::Stop() {
[email protected]1795df51a2014-05-22 20:18:04110 DCHECK(io_thread_->RunsTasksOnCurrentThread());
jianli19562592015-01-12 20:16:30111 started_ = false;
[email protected]fc6078a2014-06-14 08:28:43112 delegate_->OnDisconnected();
[email protected]21fee5482014-03-05 00:57:15113}
114
jianli7a0c9b62015-05-26 23:24:47115void FakeGCMClient::Register(
116 const linked_ptr<RegistrationInfo>& registration_info) {
[email protected]1795df51a2014-05-22 20:18:04117 DCHECK(io_thread_->RunsTasksOnCurrentThread());
[email protected]b16a7c52013-11-20 01:18:59118
jianli012b5c82015-05-28 01:41:29119 std::string registration_id;
120
jianli7a0c9b62015-05-26 23:24:47121 GCMRegistrationInfo* gcm_registration_info =
122 GCMRegistrationInfo::FromRegistrationInfo(registration_info.get());
jianli012b5c82015-05-28 01:41:29123 if (gcm_registration_info) {
124 registration_id = GenerateGCMRegistrationID(
125 gcm_registration_info->sender_ids);
126 }
jianli7a0c9b62015-05-26 23:24:47127
jianli012b5c82015-05-28 01:41:29128 InstanceIDTokenInfo* instance_id_token_info =
129 InstanceIDTokenInfo::FromRegistrationInfo(registration_info.get());
130 if (instance_id_token_info) {
131 registration_id = GenerateInstanceIDToken(
132 instance_id_token_info->authorized_entity,
133 instance_id_token_info->scope);
134 }
135
skyostilb0daa012015-06-02 19:03:48136 base::ThreadTaskRunnerHandle::Get()->PostTask(
137 FROM_HERE, base::Bind(&FakeGCMClient::RegisterFinished,
138 weak_ptr_factory_.GetWeakPtr(), registration_info,
139 registration_id));
[email protected]b16a7c52013-11-20 01:18:59140}
141
jianli7a0c9b62015-05-26 23:24:47142void FakeGCMClient::Unregister(
143 const linked_ptr<RegistrationInfo>& registration_info) {
[email protected]1795df51a2014-05-22 20:18:04144 DCHECK(io_thread_->RunsTasksOnCurrentThread());
[email protected]0e88e1d12014-03-19 06:53:08145
skyostilb0daa012015-06-02 19:03:48146 base::ThreadTaskRunnerHandle::Get()->PostTask(
147 FROM_HERE, base::Bind(&FakeGCMClient::UnregisterFinished,
148 weak_ptr_factory_.GetWeakPtr(), registration_info));
[email protected]b16a7c52013-11-20 01:18:59149}
150
[email protected]accbbc92014-05-15 21:28:59151void FakeGCMClient::Send(const std::string& app_id,
[email protected]b16a7c52013-11-20 01:18:59152 const std::string& receiver_id,
153 const OutgoingMessage& message) {
[email protected]1795df51a2014-05-22 20:18:04154 DCHECK(io_thread_->RunsTasksOnCurrentThread());
[email protected]b16a7c52013-11-20 01:18:59155
skyostilb0daa012015-06-02 19:03:48156 base::ThreadTaskRunnerHandle::Get()->PostTask(
157 FROM_HERE, base::Bind(&FakeGCMClient::SendFinished,
158 weak_ptr_factory_.GetWeakPtr(), app_id, message));
[email protected]b16a7c52013-11-20 01:18:59159}
160
peteree284ba52016-02-01 11:53:28161void FakeGCMClient::RecordDecryptionFailure(
162 const std::string& app_id,
peter266a2aa42016-02-19 18:51:39163 GCMEncryptionProvider::DecryptionResult result) {
164 recorder_.RecordDecryptionFailure(app_id, result);
peteree284ba52016-02-01 11:53:28165}
166
[email protected]accbbc92014-05-15 21:28:59167void FakeGCMClient::SetRecording(bool recording) {
peteree284ba52016-02-01 11:53:28168 recorder_.set_is_recording(recording);
[email protected]436bcb82014-04-18 00:40:57169}
170
[email protected]accbbc92014-05-15 21:28:59171void FakeGCMClient::ClearActivityLogs() {
peteree284ba52016-02-01 11:53:28172 recorder_.Clear();
[email protected]436bcb82014-04-18 00:40:57173}
174
[email protected]accbbc92014-05-15 21:28:59175GCMClient::GCMStatistics FakeGCMClient::GetStatistics() const {
peteree284ba52016-02-01 11:53:28176 GCMClient::GCMStatistics statistics;
177 statistics.is_recording = recorder_.is_recording();
178
179 recorder_.CollectActivities(&statistics.recorded_activities);
180 return statistics;
[email protected]35601812014-03-07 19:52:43181}
182
fgorski58b9dfc2014-09-29 16:46:18183void FakeGCMClient::SetAccountTokens(
184 const std::vector<AccountTokenInfo>& account_tokens) {
[email protected]7df5ef22014-07-17 07:35:58185}
186
[email protected]72d4f252014-08-20 22:34:28187void FakeGCMClient::UpdateAccountMapping(
188 const AccountMapping& account_mapping) {
189}
190
191void FakeGCMClient::RemoveAccountMapping(const std::string& account_id) {
192}
193
fgorski5df101702014-10-28 02:09:31194void FakeGCMClient::SetLastTokenFetchTime(const base::Time& time) {
195}
196
chirantan192a9212014-12-06 03:30:45197void FakeGCMClient::UpdateHeartbeatTimer(scoped_ptr<base::Timer> timer) {
198}
199
jianli10018b2d2015-05-11 21:14:13200void FakeGCMClient::AddInstanceIDData(const std::string& app_id,
jianli7a0c9b62015-05-26 23:24:47201 const std::string& instance_id,
202 const std::string& extra_data) {
jianliea8534872015-06-22 21:06:22203 instance_id_data_[app_id] = make_pair(instance_id, extra_data);
jianli10018b2d2015-05-11 21:14:13204}
205
206void FakeGCMClient::RemoveInstanceIDData(const std::string& app_id) {
jianliea8534872015-06-22 21:06:22207 instance_id_data_.erase(app_id);
jianli10018b2d2015-05-11 21:14:13208}
209
jianli7a0c9b62015-05-26 23:24:47210void FakeGCMClient::GetInstanceIDData(const std::string& app_id,
211 std::string* instance_id,
212 std::string* extra_data) {
jianliea8534872015-06-22 21:06:22213 auto iter = instance_id_data_.find(app_id);
214 if (iter == instance_id_data_.end()) {
215 instance_id->clear();
216 extra_data->clear();
217 return;
218 }
219
220 *instance_id = iter->second.first;
221 *extra_data = iter->second.second;
jianli10018b2d2015-05-11 21:14:13222}
223
fgorski22754462015-05-14 00:05:22224void FakeGCMClient::AddHeartbeatInterval(const std::string& scope,
225 int interval_ms) {
226}
227
228void FakeGCMClient::RemoveHeartbeatInterval(const std::string& scope) {
229}
230
jianlif3e52af42015-01-21 23:18:47231void FakeGCMClient::PerformDelayedStart() {
[email protected]1795df51a2014-05-22 20:18:04232 DCHECK(ui_thread_->RunsTasksOnCurrentThread());
[email protected]d3a4b2e2014-02-27 13:46:54233
[email protected]1795df51a2014-05-22 20:18:04234 io_thread_->PostTask(
[email protected]d3a4b2e2014-02-27 13:46:54235 FROM_HERE,
jianlif3e52af42015-01-21 23:18:47236 base::Bind(&FakeGCMClient::DoStart, weak_ptr_factory_.GetWeakPtr()));
[email protected]b16a7c52013-11-20 01:18:59237}
238
[email protected]accbbc92014-05-15 21:28:59239void FakeGCMClient::ReceiveMessage(const std::string& app_id,
[email protected]b16a7c52013-11-20 01:18:59240 const IncomingMessage& message) {
[email protected]1795df51a2014-05-22 20:18:04241 DCHECK(ui_thread_->RunsTasksOnCurrentThread());
[email protected]b16a7c52013-11-20 01:18:59242
[email protected]1795df51a2014-05-22 20:18:04243 io_thread_->PostTask(
[email protected]b16a7c52013-11-20 01:18:59244 FROM_HERE,
[email protected]accbbc92014-05-15 21:28:59245 base::Bind(&FakeGCMClient::MessageReceived,
[email protected]d3a4b2e2014-02-27 13:46:54246 weak_ptr_factory_.GetWeakPtr(),
[email protected]b16a7c52013-11-20 01:18:59247 app_id,
248 message));
249}
250
[email protected]accbbc92014-05-15 21:28:59251void FakeGCMClient::DeleteMessages(const std::string& app_id) {
[email protected]1795df51a2014-05-22 20:18:04252 DCHECK(ui_thread_->RunsTasksOnCurrentThread());
[email protected]b16a7c52013-11-20 01:18:59253
[email protected]1795df51a2014-05-22 20:18:04254 io_thread_->PostTask(
[email protected]b16a7c52013-11-20 01:18:59255 FROM_HERE,
[email protected]accbbc92014-05-15 21:28:59256 base::Bind(&FakeGCMClient::MessagesDeleted,
[email protected]d3a4b2e2014-02-27 13:46:54257 weak_ptr_factory_.GetWeakPtr(),
[email protected]b16a7c52013-11-20 01:18:59258 app_id));
259}
260
jianlif3e52af42015-01-21 23:18:47261void FakeGCMClient::Started() {
fgorski5df101702014-10-28 02:09:31262 delegate_->OnGCMReady(std::vector<AccountMapping>(), base::Time());
[email protected]fc6078a2014-06-14 08:28:43263 delegate_->OnConnected(net::IPEndPoint());
[email protected]d3a4b2e2014-02-27 13:46:54264}
265
jianli7a0c9b62015-05-26 23:24:47266void FakeGCMClient::RegisterFinished(
267 const linked_ptr<RegistrationInfo>& registration_info,
268 const std::string& registrion_id) {
[email protected]5799d052014-02-12 20:47:39269 delegate_->OnRegisterFinished(
jianli7a0c9b62015-05-26 23:24:47270 registration_info,
271 registrion_id,
272 registrion_id.empty() ? SERVER_ERROR : SUCCESS);
[email protected]b16a7c52013-11-20 01:18:59273}
274
jianli7a0c9b62015-05-26 23:24:47275void FakeGCMClient::UnregisterFinished(
276 const linked_ptr<RegistrationInfo>& registration_info) {
277 delegate_->OnUnregisterFinished(registration_info, GCMClient::SUCCESS);
[email protected]0e88e1d12014-03-19 06:53:08278}
279
[email protected]accbbc92014-05-15 21:28:59280void FakeGCMClient::SendFinished(const std::string& app_id,
[email protected]c6fe36b2014-03-11 10:58:12281 const OutgoingMessage& message) {
282 delegate_->OnSendFinished(app_id, message.id, SUCCESS);
[email protected]b16a7c52013-11-20 01:18:59283
284 // Simulate send error if message id contains a hint.
[email protected]c6fe36b2014-03-11 10:58:12285 if (message.id.find("error") != std::string::npos) {
286 SendErrorDetails send_error_details;
287 send_error_details.message_id = message.id;
288 send_error_details.result = NETWORK_ERROR;
289 send_error_details.additional_data = message.data;
skyostilb0daa012015-06-02 19:03:48290 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
[email protected]b16a7c52013-11-20 01:18:59291 FROM_HERE,
[email protected]accbbc92014-05-15 21:28:59292 base::Bind(&FakeGCMClient::MessageSendError,
skyostilb0daa012015-06-02 19:03:48293 weak_ptr_factory_.GetWeakPtr(), app_id, send_error_details),
[email protected]b16a7c52013-11-20 01:18:59294 base::TimeDelta::FromMilliseconds(200));
[email protected]292af2b22014-08-06 19:42:45295 } else if(message.id.find("ack") != std::string::npos) {
skyostilb0daa012015-06-02 19:03:48296 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
[email protected]292af2b22014-08-06 19:42:45297 FROM_HERE,
298 base::Bind(&FakeGCMClient::SendAcknowledgement,
skyostilb0daa012015-06-02 19:03:48299 weak_ptr_factory_.GetWeakPtr(), app_id, message.id),
[email protected]292af2b22014-08-06 19:42:45300 base::TimeDelta::FromMilliseconds(200));
[email protected]b16a7c52013-11-20 01:18:59301 }
302}
303
[email protected]accbbc92014-05-15 21:28:59304void FakeGCMClient::MessageReceived(const std::string& app_id,
[email protected]5799d052014-02-12 20:47:39305 const IncomingMessage& message) {
306 if (delegate_)
307 delegate_->OnMessageReceived(app_id, message);
[email protected]b16a7c52013-11-20 01:18:59308}
309
[email protected]accbbc92014-05-15 21:28:59310void FakeGCMClient::MessagesDeleted(const std::string& app_id) {
[email protected]5799d052014-02-12 20:47:39311 if (delegate_)
312 delegate_->OnMessagesDeleted(app_id);
[email protected]b16a7c52013-11-20 01:18:59313}
314
[email protected]accbbc92014-05-15 21:28:59315void FakeGCMClient::MessageSendError(
[email protected]c6fe36b2014-03-11 10:58:12316 const std::string& app_id,
317 const GCMClient::SendErrorDetails& send_error_details) {
[email protected]5799d052014-02-12 20:47:39318 if (delegate_)
[email protected]c6fe36b2014-03-11 10:58:12319 delegate_->OnMessageSendError(app_id, send_error_details);
[email protected]b16a7c52013-11-20 01:18:59320}
321
[email protected]292af2b22014-08-06 19:42:45322void FakeGCMClient::SendAcknowledgement(const std::string& app_id,
323 const std::string& message_id) {
324 if (delegate_)
325 delegate_->OnSendAcknowledged(app_id, message_id);
326}
327
[email protected]b16a7c52013-11-20 01:18:59328} // namespace gcm