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