blob: eaa66c894d182fea831ea919e8b275cdc9edd992 [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"
gab7966d312016-05-11 20:35:0118#include "base/threading/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,
dchenga77e28eb2016-04-21 21:34:3781 std::unique_ptr<Encryptor> encryptor,
[email protected]5799d052014-02-12 20:47:3982 Delegate* delegate) {
johnme627dc8c72016-08-19 21:49:3983 product_category_for_subtypes_ =
84 chrome_build_info.product_category_for_subtypes;
[email protected]5799d052014-02-12 20:47:3985 delegate_ = delegate;
[email protected]e2a4a8012014-02-07 22:32:5286}
87
jianlif3e52af42015-01-21 23:18:4788void FakeGCMClient::Start(StartMode start_mode) {
[email protected]1795df51a2014-05-22 20:18:0489 DCHECK(io_thread_->RunsTasksOnCurrentThread());
[email protected]d3a4b2e2014-02-27 13:46:5490
jianlif3e52af42015-01-21 23:18:4791 if (started_)
[email protected]d3a4b2e2014-02-27 13:46:5492 return;
jianlif3e52af42015-01-21 23:18:4793
94 if (start_mode == IMMEDIATE_START)
95 start_mode_ = IMMEDIATE_START;
96 if (start_mode_ == DELAYED_START ||
97 start_mode_overridding_ == FORCE_TO_ALWAYS_DELAY_START_GCM) {
98 return;
99 }
100
101 DoStart();
[email protected]d3a4b2e2014-02-27 13:46:54102}
103
jianlif3e52af42015-01-21 23:18:47104void FakeGCMClient::DoStart() {
jianli19562592015-01-12 20:16:30105 started_ = true;
skyostilb0daa012015-06-02 19:03:48106 base::ThreadTaskRunnerHandle::Get()->PostTask(
[email protected]d3a4b2e2014-02-27 13:46:54107 FROM_HERE,
skyostilb0daa012015-06-02 19:03:48108 base::Bind(&FakeGCMClient::Started, weak_ptr_factory_.GetWeakPtr()));
[email protected]d3a4b2e2014-02-27 13:46:54109}
110
[email protected]accbbc92014-05-15 21:28:59111void FakeGCMClient::Stop() {
[email protected]1795df51a2014-05-22 20:18:04112 DCHECK(io_thread_->RunsTasksOnCurrentThread());
jianli19562592015-01-12 20:16:30113 started_ = false;
[email protected]fc6078a2014-06-14 08:28:43114 delegate_->OnDisconnected();
[email protected]21fee5482014-03-05 00:57:15115}
116
jianli7a0c9b62015-05-26 23:24:47117void FakeGCMClient::Register(
118 const linked_ptr<RegistrationInfo>& registration_info) {
[email protected]1795df51a2014-05-22 20:18:04119 DCHECK(io_thread_->RunsTasksOnCurrentThread());
[email protected]b16a7c52013-11-20 01:18:59120
jianli012b5c82015-05-28 01:41:29121 std::string registration_id;
122
jianli7a0c9b62015-05-26 23:24:47123 GCMRegistrationInfo* gcm_registration_info =
124 GCMRegistrationInfo::FromRegistrationInfo(registration_info.get());
jianli012b5c82015-05-28 01:41:29125 if (gcm_registration_info) {
126 registration_id = GenerateGCMRegistrationID(
127 gcm_registration_info->sender_ids);
128 }
jianli7a0c9b62015-05-26 23:24:47129
jianli012b5c82015-05-28 01:41:29130 InstanceIDTokenInfo* instance_id_token_info =
131 InstanceIDTokenInfo::FromRegistrationInfo(registration_info.get());
132 if (instance_id_token_info) {
133 registration_id = GenerateInstanceIDToken(
134 instance_id_token_info->authorized_entity,
135 instance_id_token_info->scope);
136 }
137
skyostilb0daa012015-06-02 19:03:48138 base::ThreadTaskRunnerHandle::Get()->PostTask(
139 FROM_HERE, base::Bind(&FakeGCMClient::RegisterFinished,
140 weak_ptr_factory_.GetWeakPtr(), registration_info,
141 registration_id));
[email protected]b16a7c52013-11-20 01:18:59142}
143
jianli7a0c9b62015-05-26 23:24:47144void FakeGCMClient::Unregister(
145 const linked_ptr<RegistrationInfo>& registration_info) {
[email protected]1795df51a2014-05-22 20:18:04146 DCHECK(io_thread_->RunsTasksOnCurrentThread());
[email protected]0e88e1d12014-03-19 06:53:08147
skyostilb0daa012015-06-02 19:03:48148 base::ThreadTaskRunnerHandle::Get()->PostTask(
149 FROM_HERE, base::Bind(&FakeGCMClient::UnregisterFinished,
150 weak_ptr_factory_.GetWeakPtr(), registration_info));
[email protected]b16a7c52013-11-20 01:18:59151}
152
[email protected]accbbc92014-05-15 21:28:59153void FakeGCMClient::Send(const std::string& app_id,
[email protected]b16a7c52013-11-20 01:18:59154 const std::string& receiver_id,
155 const OutgoingMessage& message) {
[email protected]1795df51a2014-05-22 20:18:04156 DCHECK(io_thread_->RunsTasksOnCurrentThread());
[email protected]b16a7c52013-11-20 01:18:59157
skyostilb0daa012015-06-02 19:03:48158 base::ThreadTaskRunnerHandle::Get()->PostTask(
159 FROM_HERE, base::Bind(&FakeGCMClient::SendFinished,
160 weak_ptr_factory_.GetWeakPtr(), app_id, message));
[email protected]b16a7c52013-11-20 01:18:59161}
162
peteree284ba52016-02-01 11:53:28163void FakeGCMClient::RecordDecryptionFailure(
164 const std::string& app_id,
peter266a2aa42016-02-19 18:51:39165 GCMEncryptionProvider::DecryptionResult result) {
166 recorder_.RecordDecryptionFailure(app_id, result);
peteree284ba52016-02-01 11:53:28167}
168
[email protected]accbbc92014-05-15 21:28:59169void FakeGCMClient::SetRecording(bool recording) {
peteree284ba52016-02-01 11:53:28170 recorder_.set_is_recording(recording);
[email protected]436bcb82014-04-18 00:40:57171}
172
[email protected]accbbc92014-05-15 21:28:59173void FakeGCMClient::ClearActivityLogs() {
peteree284ba52016-02-01 11:53:28174 recorder_.Clear();
[email protected]436bcb82014-04-18 00:40:57175}
176
[email protected]accbbc92014-05-15 21:28:59177GCMClient::GCMStatistics FakeGCMClient::GetStatistics() const {
peteree284ba52016-02-01 11:53:28178 GCMClient::GCMStatistics statistics;
179 statistics.is_recording = recorder_.is_recording();
180
181 recorder_.CollectActivities(&statistics.recorded_activities);
182 return statistics;
[email protected]35601812014-03-07 19:52:43183}
184
fgorski58b9dfc2014-09-29 16:46:18185void FakeGCMClient::SetAccountTokens(
186 const std::vector<AccountTokenInfo>& account_tokens) {
[email protected]7df5ef22014-07-17 07:35:58187}
188
[email protected]72d4f252014-08-20 22:34:28189void FakeGCMClient::UpdateAccountMapping(
190 const AccountMapping& account_mapping) {
191}
192
193void FakeGCMClient::RemoveAccountMapping(const std::string& account_id) {
194}
195
fgorski5df101702014-10-28 02:09:31196void FakeGCMClient::SetLastTokenFetchTime(const base::Time& time) {
197}
198
dchenga77e28eb2016-04-21 21:34:37199void FakeGCMClient::UpdateHeartbeatTimer(std::unique_ptr<base::Timer> timer) {}
chirantan192a9212014-12-06 03:30:45200
jianli10018b2d2015-05-11 21:14:13201void FakeGCMClient::AddInstanceIDData(const std::string& app_id,
jianli7a0c9b62015-05-26 23:24:47202 const std::string& instance_id,
203 const std::string& extra_data) {
jianliea8534872015-06-22 21:06:22204 instance_id_data_[app_id] = make_pair(instance_id, extra_data);
jianli10018b2d2015-05-11 21:14:13205}
206
207void FakeGCMClient::RemoveInstanceIDData(const std::string& app_id) {
jianliea8534872015-06-22 21:06:22208 instance_id_data_.erase(app_id);
jianli10018b2d2015-05-11 21:14:13209}
210
jianli7a0c9b62015-05-26 23:24:47211void FakeGCMClient::GetInstanceIDData(const std::string& app_id,
212 std::string* instance_id,
213 std::string* extra_data) {
jianliea8534872015-06-22 21:06:22214 auto iter = instance_id_data_.find(app_id);
215 if (iter == instance_id_data_.end()) {
216 instance_id->clear();
217 extra_data->clear();
218 return;
219 }
220
221 *instance_id = iter->second.first;
222 *extra_data = iter->second.second;
jianli10018b2d2015-05-11 21:14:13223}
224
fgorski22754462015-05-14 00:05:22225void FakeGCMClient::AddHeartbeatInterval(const std::string& scope,
226 int interval_ms) {
227}
228
229void FakeGCMClient::RemoveHeartbeatInterval(const std::string& scope) {
230}
231
jianlif3e52af42015-01-21 23:18:47232void FakeGCMClient::PerformDelayedStart() {
[email protected]1795df51a2014-05-22 20:18:04233 DCHECK(ui_thread_->RunsTasksOnCurrentThread());
[email protected]d3a4b2e2014-02-27 13:46:54234
[email protected]1795df51a2014-05-22 20:18:04235 io_thread_->PostTask(
[email protected]d3a4b2e2014-02-27 13:46:54236 FROM_HERE,
jianlif3e52af42015-01-21 23:18:47237 base::Bind(&FakeGCMClient::DoStart, weak_ptr_factory_.GetWeakPtr()));
[email protected]b16a7c52013-11-20 01:18:59238}
239
[email protected]accbbc92014-05-15 21:28:59240void FakeGCMClient::ReceiveMessage(const std::string& app_id,
[email protected]b16a7c52013-11-20 01:18:59241 const IncomingMessage& message) {
[email protected]1795df51a2014-05-22 20:18:04242 DCHECK(ui_thread_->RunsTasksOnCurrentThread());
[email protected]b16a7c52013-11-20 01:18:59243
[email protected]1795df51a2014-05-22 20:18:04244 io_thread_->PostTask(
[email protected]b16a7c52013-11-20 01:18:59245 FROM_HERE,
[email protected]accbbc92014-05-15 21:28:59246 base::Bind(&FakeGCMClient::MessageReceived,
[email protected]d3a4b2e2014-02-27 13:46:54247 weak_ptr_factory_.GetWeakPtr(),
[email protected]b16a7c52013-11-20 01:18:59248 app_id,
249 message));
250}
251
[email protected]accbbc92014-05-15 21:28:59252void FakeGCMClient::DeleteMessages(const std::string& app_id) {
[email protected]1795df51a2014-05-22 20:18:04253 DCHECK(ui_thread_->RunsTasksOnCurrentThread());
[email protected]b16a7c52013-11-20 01:18:59254
[email protected]1795df51a2014-05-22 20:18:04255 io_thread_->PostTask(
[email protected]b16a7c52013-11-20 01:18:59256 FROM_HERE,
[email protected]accbbc92014-05-15 21:28:59257 base::Bind(&FakeGCMClient::MessagesDeleted,
[email protected]d3a4b2e2014-02-27 13:46:54258 weak_ptr_factory_.GetWeakPtr(),
[email protected]b16a7c52013-11-20 01:18:59259 app_id));
260}
261
jianlif3e52af42015-01-21 23:18:47262void FakeGCMClient::Started() {
fgorski5df101702014-10-28 02:09:31263 delegate_->OnGCMReady(std::vector<AccountMapping>(), base::Time());
[email protected]fc6078a2014-06-14 08:28:43264 delegate_->OnConnected(net::IPEndPoint());
[email protected]d3a4b2e2014-02-27 13:46:54265}
266
jianli7a0c9b62015-05-26 23:24:47267void FakeGCMClient::RegisterFinished(
268 const linked_ptr<RegistrationInfo>& registration_info,
269 const std::string& registrion_id) {
[email protected]5799d052014-02-12 20:47:39270 delegate_->OnRegisterFinished(
jianli7a0c9b62015-05-26 23:24:47271 registration_info,
272 registrion_id,
273 registrion_id.empty() ? SERVER_ERROR : SUCCESS);
[email protected]b16a7c52013-11-20 01:18:59274}
275
jianli7a0c9b62015-05-26 23:24:47276void FakeGCMClient::UnregisterFinished(
277 const linked_ptr<RegistrationInfo>& registration_info) {
278 delegate_->OnUnregisterFinished(registration_info, GCMClient::SUCCESS);
[email protected]0e88e1d12014-03-19 06:53:08279}
280
[email protected]accbbc92014-05-15 21:28:59281void FakeGCMClient::SendFinished(const std::string& app_id,
[email protected]c6fe36b2014-03-11 10:58:12282 const OutgoingMessage& message) {
283 delegate_->OnSendFinished(app_id, message.id, SUCCESS);
[email protected]b16a7c52013-11-20 01:18:59284
285 // Simulate send error if message id contains a hint.
[email protected]c6fe36b2014-03-11 10:58:12286 if (message.id.find("error") != std::string::npos) {
287 SendErrorDetails send_error_details;
288 send_error_details.message_id = message.id;
289 send_error_details.result = NETWORK_ERROR;
290 send_error_details.additional_data = message.data;
skyostilb0daa012015-06-02 19:03:48291 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
[email protected]b16a7c52013-11-20 01:18:59292 FROM_HERE,
[email protected]accbbc92014-05-15 21:28:59293 base::Bind(&FakeGCMClient::MessageSendError,
skyostilb0daa012015-06-02 19:03:48294 weak_ptr_factory_.GetWeakPtr(), app_id, send_error_details),
[email protected]b16a7c52013-11-20 01:18:59295 base::TimeDelta::FromMilliseconds(200));
[email protected]292af2b22014-08-06 19:42:45296 } else if(message.id.find("ack") != std::string::npos) {
skyostilb0daa012015-06-02 19:03:48297 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
[email protected]292af2b22014-08-06 19:42:45298 FROM_HERE,
299 base::Bind(&FakeGCMClient::SendAcknowledgement,
skyostilb0daa012015-06-02 19:03:48300 weak_ptr_factory_.GetWeakPtr(), app_id, message.id),
[email protected]292af2b22014-08-06 19:42:45301 base::TimeDelta::FromMilliseconds(200));
[email protected]b16a7c52013-11-20 01:18:59302 }
303}
304
[email protected]accbbc92014-05-15 21:28:59305void FakeGCMClient::MessageReceived(const std::string& app_id,
[email protected]5799d052014-02-12 20:47:39306 const IncomingMessage& message) {
307 if (delegate_)
308 delegate_->OnMessageReceived(app_id, message);
[email protected]b16a7c52013-11-20 01:18:59309}
310
[email protected]accbbc92014-05-15 21:28:59311void FakeGCMClient::MessagesDeleted(const std::string& app_id) {
[email protected]5799d052014-02-12 20:47:39312 if (delegate_)
313 delegate_->OnMessagesDeleted(app_id);
[email protected]b16a7c52013-11-20 01:18:59314}
315
[email protected]accbbc92014-05-15 21:28:59316void FakeGCMClient::MessageSendError(
[email protected]c6fe36b2014-03-11 10:58:12317 const std::string& app_id,
318 const GCMClient::SendErrorDetails& send_error_details) {
[email protected]5799d052014-02-12 20:47:39319 if (delegate_)
[email protected]c6fe36b2014-03-11 10:58:12320 delegate_->OnMessageSendError(app_id, send_error_details);
[email protected]b16a7c52013-11-20 01:18:59321}
322
[email protected]292af2b22014-08-06 19:42:45323void FakeGCMClient::SendAcknowledgement(const std::string& app_id,
324 const std::string& message_id) {
325 if (delegate_)
326 delegate_->OnSendAcknowledged(app_id, message_id);
327}
328
[email protected]b16a7c52013-11-20 01:18:59329} // namespace gcm