fake_gcm_client.cc 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335
  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.
  4. #include "components/gcm_driver/fake_gcm_client.h"
  5. #include <stddef.h>
  6. #include <algorithm>
  7. #include "base/bind.h"
  8. #include "base/check.h"
  9. #include "base/location.h"
  10. #include "base/strings/string_number_conversions.h"
  11. #include "base/sys_byteorder.h"
  12. #include "base/task/sequenced_task_runner.h"
  13. #include "base/task/single_thread_task_runner.h"
  14. #include "base/threading/thread_task_runner_handle.h"
  15. #include "base/time/time.h"
  16. #include "base/timer/timer.h"
  17. #include "google_apis/gcm/base/encryptor.h"
  18. #include "google_apis/gcm/engine/account_mapping.h"
  19. #include "net/base/ip_endpoint.h"
  20. namespace gcm {
  21. // static
  22. std::string FakeGCMClient::GenerateGCMRegistrationID(
  23. const std::vector<std::string>& sender_ids) {
  24. // GCMService normalizes the sender IDs by making them sorted.
  25. std::vector<std::string> normalized_sender_ids = sender_ids;
  26. std::sort(normalized_sender_ids.begin(), normalized_sender_ids.end());
  27. // Simulate the registration_id by concaternating all sender IDs.
  28. // Set registration_id to empty to denote an error if sender_ids contains a
  29. // hint.
  30. std::string registration_id;
  31. if (sender_ids.size() != 1 ||
  32. sender_ids[0].find("error") == std::string::npos) {
  33. for (size_t i = 0; i < normalized_sender_ids.size(); ++i) {
  34. if (i > 0)
  35. registration_id += ",";
  36. registration_id += normalized_sender_ids[i];
  37. }
  38. }
  39. return registration_id;
  40. }
  41. // static
  42. std::string FakeGCMClient::GenerateInstanceIDToken(
  43. const std::string& authorized_entity, const std::string& scope) {
  44. if (authorized_entity.find("error") != std::string::npos)
  45. return "";
  46. std::string token(authorized_entity);
  47. token += ",";
  48. token += scope;
  49. return token;
  50. }
  51. FakeGCMClient::FakeGCMClient(
  52. const scoped_refptr<base::SequencedTaskRunner>& ui_thread,
  53. const scoped_refptr<base::SequencedTaskRunner>& io_thread)
  54. : delegate_(nullptr),
  55. started_(false),
  56. start_mode_(DELAYED_START),
  57. start_mode_overridding_(RESPECT_START_MODE),
  58. ui_thread_(ui_thread),
  59. io_thread_(io_thread) {}
  60. FakeGCMClient::~FakeGCMClient() {
  61. }
  62. void FakeGCMClient::Initialize(
  63. const ChromeBuildInfo& chrome_build_info,
  64. const base::FilePath& store_path,
  65. bool remove_account_mappings_with_email_key,
  66. const scoped_refptr<base::SequencedTaskRunner>& blocking_task_runner,
  67. scoped_refptr<base::SequencedTaskRunner> io_task_runner,
  68. base::RepeatingCallback<void(
  69. mojo::PendingReceiver<network::mojom::ProxyResolvingSocketFactory>)>
  70. get_socket_factory_callback,
  71. const scoped_refptr<network::SharedURLLoaderFactory>& url_loader_factory,
  72. network::NetworkConnectionTracker* network_connection_tracker,
  73. std::unique_ptr<Encryptor> encryptor,
  74. Delegate* delegate) {
  75. product_category_for_subtypes_ =
  76. chrome_build_info.product_category_for_subtypes;
  77. delegate_ = delegate;
  78. }
  79. void FakeGCMClient::Start(StartMode start_mode) {
  80. DCHECK(io_thread_->RunsTasksInCurrentSequence());
  81. if (started_)
  82. return;
  83. if (start_mode == IMMEDIATE_START)
  84. start_mode_ = IMMEDIATE_START;
  85. if (start_mode_ == DELAYED_START ||
  86. start_mode_overridding_ == FORCE_TO_ALWAYS_DELAY_START_GCM) {
  87. return;
  88. }
  89. DoStart();
  90. }
  91. void FakeGCMClient::DoStart() {
  92. started_ = true;
  93. base::ThreadTaskRunnerHandle::Get()->PostTask(
  94. FROM_HERE,
  95. base::BindOnce(&FakeGCMClient::Started, weak_ptr_factory_.GetWeakPtr()));
  96. }
  97. void FakeGCMClient::Stop() {
  98. DCHECK(io_thread_->RunsTasksInCurrentSequence());
  99. started_ = false;
  100. delegate_->OnDisconnected();
  101. }
  102. void FakeGCMClient::Register(
  103. scoped_refptr<RegistrationInfo> registration_info) {
  104. DCHECK(io_thread_->RunsTasksInCurrentSequence());
  105. std::string registration_id;
  106. GCMRegistrationInfo* gcm_registration_info =
  107. GCMRegistrationInfo::FromRegistrationInfo(registration_info.get());
  108. if (gcm_registration_info) {
  109. registration_id = GenerateGCMRegistrationID(
  110. gcm_registration_info->sender_ids);
  111. }
  112. InstanceIDTokenInfo* instance_id_token_info =
  113. InstanceIDTokenInfo::FromRegistrationInfo(registration_info.get());
  114. if (instance_id_token_info) {
  115. registration_id = GenerateInstanceIDToken(
  116. instance_id_token_info->authorized_entity,
  117. instance_id_token_info->scope);
  118. }
  119. base::ThreadTaskRunnerHandle::Get()->PostTask(
  120. FROM_HERE, base::BindOnce(&FakeGCMClient::RegisterFinished,
  121. weak_ptr_factory_.GetWeakPtr(),
  122. std::move(registration_info), registration_id));
  123. }
  124. bool FakeGCMClient::ValidateRegistration(
  125. scoped_refptr<RegistrationInfo> registration_info,
  126. const std::string& registration_id) {
  127. return true;
  128. }
  129. void FakeGCMClient::Unregister(
  130. scoped_refptr<RegistrationInfo> registration_info) {
  131. DCHECK(io_thread_->RunsTasksInCurrentSequence());
  132. base::ThreadTaskRunnerHandle::Get()->PostTask(
  133. FROM_HERE,
  134. base::BindOnce(&FakeGCMClient::UnregisterFinished,
  135. weak_ptr_factory_.GetWeakPtr(), registration_info));
  136. }
  137. void FakeGCMClient::Send(const std::string& app_id,
  138. const std::string& receiver_id,
  139. const OutgoingMessage& message) {
  140. DCHECK(io_thread_->RunsTasksInCurrentSequence());
  141. base::ThreadTaskRunnerHandle::Get()->PostTask(
  142. FROM_HERE,
  143. base::BindOnce(&FakeGCMClient::SendFinished,
  144. weak_ptr_factory_.GetWeakPtr(), app_id, message));
  145. }
  146. void FakeGCMClient::RecordDecryptionFailure(const std::string& app_id,
  147. GCMDecryptionResult result) {
  148. recorder_.RecordDecryptionFailure(app_id, result);
  149. }
  150. void FakeGCMClient::SetRecording(bool recording) {
  151. recorder_.set_is_recording(recording);
  152. }
  153. void FakeGCMClient::ClearActivityLogs() {
  154. recorder_.Clear();
  155. }
  156. GCMClient::GCMStatistics FakeGCMClient::GetStatistics() const {
  157. GCMClient::GCMStatistics statistics;
  158. statistics.is_recording = recorder_.is_recording();
  159. recorder_.CollectActivities(&statistics.recorded_activities);
  160. return statistics;
  161. }
  162. void FakeGCMClient::SetAccountTokens(
  163. const std::vector<AccountTokenInfo>& account_tokens) {
  164. }
  165. void FakeGCMClient::UpdateAccountMapping(
  166. const AccountMapping& account_mapping) {
  167. }
  168. void FakeGCMClient::RemoveAccountMapping(const CoreAccountId& account_id) {}
  169. void FakeGCMClient::SetLastTokenFetchTime(const base::Time& time) {
  170. }
  171. void FakeGCMClient::UpdateHeartbeatTimer(
  172. std::unique_ptr<base::RetainingOneShotTimer> timer) {}
  173. void FakeGCMClient::AddInstanceIDData(const std::string& app_id,
  174. const std::string& instance_id,
  175. const std::string& extra_data) {
  176. instance_id_data_[app_id] = make_pair(instance_id, extra_data);
  177. }
  178. void FakeGCMClient::RemoveInstanceIDData(const std::string& app_id) {
  179. instance_id_data_.erase(app_id);
  180. }
  181. void FakeGCMClient::GetInstanceIDData(const std::string& app_id,
  182. std::string* instance_id,
  183. std::string* extra_data) {
  184. auto iter = instance_id_data_.find(app_id);
  185. if (iter == instance_id_data_.end()) {
  186. instance_id->clear();
  187. extra_data->clear();
  188. return;
  189. }
  190. *instance_id = iter->second.first;
  191. *extra_data = iter->second.second;
  192. }
  193. void FakeGCMClient::AddHeartbeatInterval(const std::string& scope,
  194. int interval_ms) {
  195. }
  196. void FakeGCMClient::RemoveHeartbeatInterval(const std::string& scope) {
  197. }
  198. void FakeGCMClient::PerformDelayedStart() {
  199. DCHECK(ui_thread_->RunsTasksInCurrentSequence());
  200. io_thread_->PostTask(
  201. FROM_HERE,
  202. base::BindOnce(&FakeGCMClient::DoStart, weak_ptr_factory_.GetWeakPtr()));
  203. }
  204. void FakeGCMClient::ReceiveMessage(const std::string& app_id,
  205. const IncomingMessage& message) {
  206. DCHECK(ui_thread_->RunsTasksInCurrentSequence());
  207. io_thread_->PostTask(
  208. FROM_HERE,
  209. base::BindOnce(&FakeGCMClient::MessageReceived,
  210. weak_ptr_factory_.GetWeakPtr(), app_id, message));
  211. }
  212. void FakeGCMClient::DeleteMessages(const std::string& app_id) {
  213. DCHECK(ui_thread_->RunsTasksInCurrentSequence());
  214. io_thread_->PostTask(FROM_HERE,
  215. base::BindOnce(&FakeGCMClient::MessagesDeleted,
  216. weak_ptr_factory_.GetWeakPtr(), app_id));
  217. }
  218. void FakeGCMClient::Started() {
  219. delegate_->OnGCMReady(std::vector<AccountMapping>(), base::Time());
  220. delegate_->OnConnected(net::IPEndPoint());
  221. }
  222. void FakeGCMClient::RegisterFinished(
  223. scoped_refptr<RegistrationInfo> registration_info,
  224. const std::string& registrion_id) {
  225. delegate_->OnRegisterFinished(std::move(registration_info), registrion_id,
  226. registrion_id.empty() ? SERVER_ERROR : SUCCESS);
  227. }
  228. void FakeGCMClient::UnregisterFinished(
  229. scoped_refptr<RegistrationInfo> registration_info) {
  230. delegate_->OnUnregisterFinished(std::move(registration_info),
  231. GCMClient::SUCCESS);
  232. }
  233. void FakeGCMClient::SendFinished(const std::string& app_id,
  234. const OutgoingMessage& message) {
  235. delegate_->OnSendFinished(app_id, message.id, SUCCESS);
  236. // Simulate send error if message id contains a hint.
  237. if (message.id.find("error") != std::string::npos) {
  238. SendErrorDetails send_error_details;
  239. send_error_details.message_id = message.id;
  240. send_error_details.result = NETWORK_ERROR;
  241. send_error_details.additional_data = message.data;
  242. base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
  243. FROM_HERE,
  244. base::BindOnce(&FakeGCMClient::MessageSendError,
  245. weak_ptr_factory_.GetWeakPtr(), app_id,
  246. send_error_details),
  247. base::Milliseconds(200));
  248. } else if(message.id.find("ack") != std::string::npos) {
  249. base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
  250. FROM_HERE,
  251. base::BindOnce(&FakeGCMClient::SendAcknowledgement,
  252. weak_ptr_factory_.GetWeakPtr(), app_id, message.id),
  253. base::Milliseconds(200));
  254. }
  255. }
  256. void FakeGCMClient::MessageReceived(const std::string& app_id,
  257. const IncomingMessage& message) {
  258. if (delegate_)
  259. delegate_->OnMessageReceived(app_id, message);
  260. }
  261. void FakeGCMClient::MessagesDeleted(const std::string& app_id) {
  262. if (delegate_)
  263. delegate_->OnMessagesDeleted(app_id);
  264. }
  265. void FakeGCMClient::MessageSendError(
  266. const std::string& app_id,
  267. const GCMClient::SendErrorDetails& send_error_details) {
  268. if (delegate_)
  269. delegate_->OnMessageSendError(app_id, send_error_details);
  270. }
  271. void FakeGCMClient::SendAcknowledgement(const std::string& app_id,
  272. const std::string& message_id) {
  273. if (delegate_)
  274. delegate_->OnSendAcknowledged(app_id, message_id);
  275. }
  276. } // namespace gcm