Home | History | Annotate | Download | only in gcm
      1 // Copyright 2013 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 "chrome/browser/services/gcm/gcm_client_mock.h"
      6 
      7 #include "base/bind.h"
      8 #include "base/logging.h"
      9 #include "base/message_loop/message_loop.h"
     10 #include "base/sys_byteorder.h"
     11 #include "base/time/time.h"
     12 #include "content/public/browser/browser_thread.h"
     13 
     14 namespace gcm {
     15 
     16 namespace {
     17 
     18 // Converts the 8-byte prefix of a string into a uint64 value.
     19 uint64 HashToUInt64(const std::string& hash) {
     20   uint64 value;
     21   DCHECK_GE(hash.size(), sizeof(value));
     22   memcpy(&value, hash.data(), sizeof(value));
     23   return base::HostToNet64(value);
     24 }
     25 
     26 }  // namespace
     27 
     28 GCMClientMock::GCMClientMock() : checkin_failure_enabled_(false) {
     29 }
     30 
     31 GCMClientMock::~GCMClientMock() {
     32 }
     33 
     34 void GCMClientMock::CheckIn(const std::string& username, Delegate* delegate) {
     35   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
     36 
     37   DCHECK(delegates_.find(username) == delegates_.end());
     38   delegates_[username] = delegate;
     39 
     40   // Simulate the android_id and secret by some sort of hashing.
     41   CheckInInfo checkin_info;
     42   if (!checkin_failure_enabled_)
     43     checkin_info = GetCheckInInfoFromUsername(username);
     44 
     45   base::MessageLoop::current()->PostTask(
     46       FROM_HERE,
     47       base::Bind(&GCMClientMock::CheckInFinished,
     48                  base::Unretained(this),
     49                  username,
     50                  checkin_info));
     51 }
     52 
     53 void GCMClientMock::Register(const std::string& username,
     54                              const std::string& app_id,
     55                              const std::string& cert,
     56                              const std::vector<std::string>& sender_ids) {
     57   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
     58 
     59   std::string registration_id = GetRegistrationIdFromSenderIds(sender_ids);
     60 
     61   base::MessageLoop::current()->PostTask(
     62       FROM_HERE,
     63       base::Bind(&GCMClientMock::RegisterFinished,
     64                  base::Unretained(this),
     65                  username,
     66                  app_id,
     67                  registration_id));
     68 }
     69 
     70 void GCMClientMock::Unregister(const std::string& username,
     71                                const std::string& app_id) {
     72 }
     73 
     74 void GCMClientMock::Send(const std::string& username,
     75                          const std::string& app_id,
     76                          const std::string& receiver_id,
     77                          const OutgoingMessage& message) {
     78   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
     79 
     80   base::MessageLoop::current()->PostTask(
     81       FROM_HERE,
     82       base::Bind(&GCMClientMock::SendFinished,
     83                  base::Unretained(this),
     84                  username,
     85                  app_id,
     86                  message.id));
     87 }
     88 
     89 bool GCMClientMock::IsLoading() const {
     90   return false;
     91 }
     92 
     93 void GCMClientMock::ReceiveMessage(const std::string& username,
     94                                    const std::string& app_id,
     95                                    const IncomingMessage& message) {
     96   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
     97 
     98   content::BrowserThread::PostTask(
     99       content::BrowserThread::IO,
    100       FROM_HERE,
    101       base::Bind(&GCMClientMock::MessageReceived,
    102                  base::Unretained(this),
    103                  username,
    104                  app_id,
    105                  message));
    106 }
    107 
    108 void GCMClientMock::DeleteMessages(const std::string& username,
    109                                    const std::string& app_id) {
    110   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
    111 
    112   content::BrowserThread::PostTask(
    113       content::BrowserThread::IO,
    114       FROM_HERE,
    115       base::Bind(&GCMClientMock::MessagesDeleted,
    116                  base::Unretained(this),
    117                  username,
    118                  app_id));
    119 }
    120 
    121 GCMClient::CheckInInfo GCMClientMock::GetCheckInInfoFromUsername(
    122     const std::string& username) const {
    123   CheckInInfo checkin_info;
    124   checkin_info.android_id = HashToUInt64(username);
    125   checkin_info.secret = checkin_info.android_id / 10;
    126   return checkin_info;
    127 }
    128 
    129 std::string GCMClientMock::GetRegistrationIdFromSenderIds(
    130     const std::vector<std::string>& sender_ids) const {
    131   // Simulate the registration_id by concaternating all sender IDs.
    132   // Set registration_id to empty to denote an error if sender_ids contains a
    133   // hint.
    134   std::string registration_id;
    135   if (sender_ids.size() != 1 ||
    136       sender_ids[0].find("error") == std::string::npos) {
    137     for (size_t i = 0; i < sender_ids.size(); ++i) {
    138       if (i > 0)
    139         registration_id += ",";
    140       registration_id += sender_ids[i];
    141     }
    142   }
    143   return registration_id;
    144 }
    145 
    146 GCMClient::Delegate* GCMClientMock::GetDelegate(
    147     const std::string& username) const {
    148   std::map<std::string, Delegate*>::const_iterator iter =
    149       delegates_.find(username);
    150   DCHECK(iter != delegates_.end());
    151   return iter->second;
    152 }
    153 
    154 void GCMClientMock::CheckInFinished(std::string username,
    155                                     CheckInInfo checkin_info) {
    156   GetDelegate(username)->OnCheckInFinished(
    157       checkin_info, checkin_info.IsValid() ? SUCCESS : SERVER_ERROR);
    158 }
    159 
    160 void GCMClientMock::RegisterFinished(std::string username,
    161                                      std::string app_id,
    162                                      std::string registrion_id) {
    163   GetDelegate(username)->OnRegisterFinished(
    164       app_id, registrion_id, registrion_id.empty() ? SERVER_ERROR : SUCCESS);
    165 }
    166 
    167 void GCMClientMock::SendFinished(std::string username,
    168                                  std::string app_id,
    169                                  std::string message_id) {
    170   GetDelegate(username)->OnSendFinished(app_id, message_id, SUCCESS);
    171 
    172   // Simulate send error if message id contains a hint.
    173   if (message_id.find("error") != std::string::npos) {
    174     base::MessageLoop::current()->PostDelayedTask(
    175         FROM_HERE,
    176         base::Bind(&GCMClientMock::MessageSendError,
    177                    base::Unretained(this),
    178                    username,
    179                    app_id,
    180                    message_id),
    181         base::TimeDelta::FromMilliseconds(200));
    182   }
    183 }
    184 
    185 void GCMClientMock::MessageReceived(std::string username,
    186                                     std::string app_id,
    187                                     IncomingMessage message) {
    188   GetDelegate(username)->OnMessageReceived(app_id, message);
    189 }
    190 
    191 void GCMClientMock::MessagesDeleted(std::string username, std::string app_id) {
    192   GetDelegate(username)->OnMessagesDeleted(app_id);
    193 }
    194 
    195 void GCMClientMock::MessageSendError(std::string username,
    196                                      std::string app_id,
    197                                      std::string message_id) {
    198   GetDelegate(username)->OnMessageSendError(app_id, message_id, NETWORK_ERROR);
    199 }
    200 
    201 }  // namespace gcm
    202