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