Home | History | Annotate | Download | only in gcm_driver
      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 
     18 namespace gcm {
     19 
     20 FakeGCMClient::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 
     33 FakeGCMClient::~FakeGCMClient() {
     34 }
     35 
     36 void 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 
     47 void 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 
     56 void 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 
     64 void FakeGCMClient::Stop() {
     65   DCHECK(io_thread_->RunsTasksOnCurrentThread());
     66   status_ = STOPPED;
     67   delegate_->OnDisconnected();
     68 }
     69 
     70 void FakeGCMClient::CheckOut() {
     71   DCHECK(io_thread_->RunsTasksOnCurrentThread());
     72   status_ = CHECKED_OUT;
     73   sequence_id_++;
     74 }
     75 
     76 void 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 
     89 void 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 
     99 void 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 
    112 void FakeGCMClient::SetRecording(bool recording) {
    113 }
    114 
    115 void FakeGCMClient::ClearActivityLogs() {
    116 }
    117 
    118 GCMClient::GCMStatistics FakeGCMClient::GetStatistics() const {
    119   return GCMClient::GCMStatistics();
    120 }
    121 
    122 void FakeGCMClient::SetAccountsForCheckin(
    123     const std::map<std::string, std::string>& account_tokens) {
    124 }
    125 
    126 void FakeGCMClient::UpdateAccountMapping(
    127     const AccountMapping& account_mapping) {
    128 }
    129 
    130 void FakeGCMClient::RemoveAccountMapping(const std::string& account_id) {
    131 }
    132 
    133 void 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 
    141 void 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 
    153 void 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 
    163 std::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 
    185 void FakeGCMClient::CheckinFinished() {
    186   delegate_->OnGCMReady(std::vector<AccountMapping>());
    187   delegate_->OnConnected(net::IPEndPoint());
    188 }
    189 
    190 void 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 
    196 void FakeGCMClient::UnregisterFinished(const std::string& app_id) {
    197   delegate_->OnUnregisterFinished(app_id, GCMClient::SUCCESS);
    198 }
    199 
    200 void 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 
    229 void FakeGCMClient::MessageReceived(const std::string& app_id,
    230                                     const IncomingMessage& message) {
    231   if (delegate_)
    232     delegate_->OnMessageReceived(app_id, message);
    233 }
    234 
    235 void FakeGCMClient::MessagesDeleted(const std::string& app_id) {
    236   if (delegate_)
    237     delegate_->OnMessagesDeleted(app_id);
    238 }
    239 
    240 void 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 
    247 void 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