fake_gcm_client.cc revision 1675a649fd7a8b3cb80ffddae2dc181f122353c5
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 5#include "components/gcm_driver/fake_gcm_client.h" 6 7#include "base/bind.h" 8#include "base/logging.h" 9#include "base/message_loop/message_loop.h" 10#include "base/sequenced_task_runner.h" 11#include "base/strings/string_number_conversions.h" 12#include "base/sys_byteorder.h" 13#include "base/time/time.h" 14#include "google_apis/gcm/base/encryptor.h" 15#include "google_apis/gcm/engine/account_mapping.h" 16#include "net/base/ip_endpoint.h" 17 18namespace gcm { 19 20FakeGCMClient::FakeGCMClient( 21 StartMode start_mode, 22 const scoped_refptr<base::SequencedTaskRunner>& ui_thread, 23 const scoped_refptr<base::SequencedTaskRunner>& io_thread) 24 : delegate_(NULL), 25 sequence_id_(0), 26 status_(UNINITIALIZED), 27 start_mode_(start_mode), 28 ui_thread_(ui_thread), 29 io_thread_(io_thread), 30 weak_ptr_factory_(this) { 31} 32 33FakeGCMClient::~FakeGCMClient() { 34} 35 36void FakeGCMClient::Initialize( 37 const ChromeBuildInfo& chrome_build_info, 38 const base::FilePath& store_path, 39 const scoped_refptr<base::SequencedTaskRunner>& blocking_task_runner, 40 const scoped_refptr<net::URLRequestContextGetter>& 41 url_request_context_getter, 42 scoped_ptr<Encryptor> encryptor, 43 Delegate* delegate) { 44 delegate_ = delegate; 45} 46 47void FakeGCMClient::Start() { 48 DCHECK(io_thread_->RunsTasksOnCurrentThread()); 49 DCHECK_NE(STARTED, status_); 50 51 if (start_mode_ == DELAY_START) 52 return; 53 DoLoading(); 54} 55 56void FakeGCMClient::DoLoading() { 57 status_ = STARTED; 58 base::MessageLoop::current()->PostTask( 59 FROM_HERE, 60 base::Bind(&FakeGCMClient::CheckinFinished, 61 weak_ptr_factory_.GetWeakPtr())); 62} 63 64void FakeGCMClient::Stop() { 65 DCHECK(io_thread_->RunsTasksOnCurrentThread()); 66 status_ = STOPPED; 67 delegate_->OnDisconnected(); 68} 69 70void FakeGCMClient::CheckOut() { 71 DCHECK(io_thread_->RunsTasksOnCurrentThread()); 72 status_ = CHECKED_OUT; 73 sequence_id_++; 74} 75 76void FakeGCMClient::Register(const std::string& app_id, 77 const std::vector<std::string>& sender_ids) { 78 DCHECK(io_thread_->RunsTasksOnCurrentThread()); 79 80 std::string registration_id = GetRegistrationIdFromSenderIds(sender_ids); 81 base::MessageLoop::current()->PostTask( 82 FROM_HERE, 83 base::Bind(&FakeGCMClient::RegisterFinished, 84 weak_ptr_factory_.GetWeakPtr(), 85 app_id, 86 registration_id)); 87} 88 89void FakeGCMClient::Unregister(const std::string& app_id) { 90 DCHECK(io_thread_->RunsTasksOnCurrentThread()); 91 92 base::MessageLoop::current()->PostTask( 93 FROM_HERE, 94 base::Bind(&FakeGCMClient::UnregisterFinished, 95 weak_ptr_factory_.GetWeakPtr(), 96 app_id)); 97} 98 99void FakeGCMClient::Send(const std::string& app_id, 100 const std::string& receiver_id, 101 const OutgoingMessage& message) { 102 DCHECK(io_thread_->RunsTasksOnCurrentThread()); 103 104 base::MessageLoop::current()->PostTask( 105 FROM_HERE, 106 base::Bind(&FakeGCMClient::SendFinished, 107 weak_ptr_factory_.GetWeakPtr(), 108 app_id, 109 message)); 110} 111 112void FakeGCMClient::SetRecording(bool recording) { 113} 114 115void FakeGCMClient::ClearActivityLogs() { 116} 117 118GCMClient::GCMStatistics FakeGCMClient::GetStatistics() const { 119 return GCMClient::GCMStatistics(); 120} 121 122void FakeGCMClient::SetAccountsForCheckin( 123 const std::map<std::string, std::string>& account_tokens) { 124} 125 126void FakeGCMClient::UpdateAccountMapping( 127 const AccountMapping& account_mapping) { 128} 129 130void FakeGCMClient::RemoveAccountMapping(const std::string& account_id) { 131} 132 133void FakeGCMClient::PerformDelayedLoading() { 134 DCHECK(ui_thread_->RunsTasksOnCurrentThread()); 135 136 io_thread_->PostTask( 137 FROM_HERE, 138 base::Bind(&FakeGCMClient::DoLoading, weak_ptr_factory_.GetWeakPtr())); 139} 140 141void FakeGCMClient::ReceiveMessage(const std::string& app_id, 142 const IncomingMessage& message) { 143 DCHECK(ui_thread_->RunsTasksOnCurrentThread()); 144 145 io_thread_->PostTask( 146 FROM_HERE, 147 base::Bind(&FakeGCMClient::MessageReceived, 148 weak_ptr_factory_.GetWeakPtr(), 149 app_id, 150 message)); 151} 152 153void FakeGCMClient::DeleteMessages(const std::string& app_id) { 154 DCHECK(ui_thread_->RunsTasksOnCurrentThread()); 155 156 io_thread_->PostTask( 157 FROM_HERE, 158 base::Bind(&FakeGCMClient::MessagesDeleted, 159 weak_ptr_factory_.GetWeakPtr(), 160 app_id)); 161} 162 163std::string FakeGCMClient::GetRegistrationIdFromSenderIds( 164 const std::vector<std::string>& sender_ids) const { 165 // GCMService normalizes the sender IDs by making them sorted. 166 std::vector<std::string> normalized_sender_ids = sender_ids; 167 std::sort(normalized_sender_ids.begin(), normalized_sender_ids.end()); 168 169 // Simulate the registration_id by concaternating all sender IDs. 170 // Set registration_id to empty to denote an error if sender_ids contains a 171 // hint. 172 std::string registration_id; 173 if (sender_ids.size() != 1 || 174 sender_ids[0].find("error") == std::string::npos) { 175 for (size_t i = 0; i < normalized_sender_ids.size(); ++i) { 176 if (i > 0) 177 registration_id += ","; 178 registration_id += normalized_sender_ids[i]; 179 } 180 registration_id += base::IntToString(sequence_id_); 181 } 182 return registration_id; 183} 184 185void FakeGCMClient::CheckinFinished() { 186 delegate_->OnGCMReady(std::vector<AccountMapping>()); 187 delegate_->OnConnected(net::IPEndPoint()); 188} 189 190void FakeGCMClient::RegisterFinished(const std::string& app_id, 191 const std::string& registrion_id) { 192 delegate_->OnRegisterFinished( 193 app_id, registrion_id, registrion_id.empty() ? SERVER_ERROR : SUCCESS); 194} 195 196void FakeGCMClient::UnregisterFinished(const std::string& app_id) { 197 delegate_->OnUnregisterFinished(app_id, GCMClient::SUCCESS); 198} 199 200void FakeGCMClient::SendFinished(const std::string& app_id, 201 const OutgoingMessage& message) { 202 delegate_->OnSendFinished(app_id, message.id, SUCCESS); 203 204 // Simulate send error if message id contains a hint. 205 if (message.id.find("error") != std::string::npos) { 206 SendErrorDetails send_error_details; 207 send_error_details.message_id = message.id; 208 send_error_details.result = NETWORK_ERROR; 209 send_error_details.additional_data = message.data; 210 base::MessageLoop::current()->PostDelayedTask( 211 FROM_HERE, 212 base::Bind(&FakeGCMClient::MessageSendError, 213 weak_ptr_factory_.GetWeakPtr(), 214 app_id, 215 send_error_details), 216 base::TimeDelta::FromMilliseconds(200)); 217 } else if(message.id.find("ack") != std::string::npos) { 218 base::MessageLoop::current()->PostDelayedTask( 219 FROM_HERE, 220 base::Bind(&FakeGCMClient::SendAcknowledgement, 221 weak_ptr_factory_.GetWeakPtr(), 222 app_id, 223 message.id), 224 base::TimeDelta::FromMilliseconds(200)); 225 226 } 227} 228 229void FakeGCMClient::MessageReceived(const std::string& app_id, 230 const IncomingMessage& message) { 231 if (delegate_) 232 delegate_->OnMessageReceived(app_id, message); 233} 234 235void FakeGCMClient::MessagesDeleted(const std::string& app_id) { 236 if (delegate_) 237 delegate_->OnMessagesDeleted(app_id); 238} 239 240void FakeGCMClient::MessageSendError( 241 const std::string& app_id, 242 const GCMClient::SendErrorDetails& send_error_details) { 243 if (delegate_) 244 delegate_->OnMessageSendError(app_id, send_error_details); 245} 246 247void FakeGCMClient::SendAcknowledgement(const std::string& app_id, 248 const std::string& message_id) { 249 if (delegate_) 250 delegate_->OnSendAcknowledged(app_id, message_id); 251} 252 253} // namespace gcm 254