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 #ifndef COMPONENTS_GCM_DRIVER_GCM_CLIENT_IMPL_H_
      6 #define COMPONENTS_GCM_DRIVER_GCM_CLIENT_IMPL_H_
      7 
      8 #include <map>
      9 #include <string>
     10 #include <vector>
     11 
     12 #include "base/compiler_specific.h"
     13 #include "base/memory/ref_counted.h"
     14 #include "base/memory/weak_ptr.h"
     15 #include "base/stl_util.h"
     16 #include "components/gcm_driver/gcm_client.h"
     17 #include "components/gcm_driver/gcm_stats_recorder_impl.h"
     18 #include "google_apis/gcm/base/mcs_message.h"
     19 #include "google_apis/gcm/engine/gcm_store.h"
     20 #include "google_apis/gcm/engine/gservices_settings.h"
     21 #include "google_apis/gcm/engine/mcs_client.h"
     22 #include "google_apis/gcm/engine/registration_request.h"
     23 #include "google_apis/gcm/engine/unregistration_request.h"
     24 #include "google_apis/gcm/protocol/android_checkin.pb.h"
     25 #include "google_apis/gcm/protocol/checkin.pb.h"
     26 #include "net/base/net_log.h"
     27 #include "net/url_request/url_request_context_getter.h"
     28 
     29 class GURL;
     30 
     31 namespace base {
     32 class Clock;
     33 class Time;
     34 }  // namespace base
     35 
     36 namespace mcs_proto {
     37 class DataMessageStanza;
     38 }  // namespace mcs_proto
     39 
     40 namespace net {
     41 class HttpNetworkSession;
     42 }  // namespace net
     43 
     44 namespace gcm {
     45 
     46 class CheckinRequest;
     47 class ConnectionFactory;
     48 class GCMClientImplTest;
     49 
     50 // Helper class for building GCM internals. Allows tests to inject fake versions
     51 // as necessary.
     52 class GCMInternalsBuilder {
     53  public:
     54   GCMInternalsBuilder();
     55   virtual ~GCMInternalsBuilder();
     56 
     57   virtual scoped_ptr<base::Clock> BuildClock();
     58   virtual scoped_ptr<MCSClient> BuildMCSClient(
     59       const std::string& version,
     60       base::Clock* clock,
     61       ConnectionFactory* connection_factory,
     62       GCMStore* gcm_store,
     63       GCMStatsRecorder* recorder);
     64   virtual scoped_ptr<ConnectionFactory> BuildConnectionFactory(
     65       const std::vector<GURL>& endpoints,
     66       const net::BackoffEntry::Policy& backoff_policy,
     67       scoped_refptr<net::HttpNetworkSession> network_session,
     68       net::NetLog* net_log,
     69       GCMStatsRecorder* recorder);
     70 };
     71 
     72 // Implements the GCM Client. It is used to coordinate MCS Client (communication
     73 // with MCS) and other pieces of GCM infrastructure like Registration and
     74 // Checkins. It also allows for registering user delegates that host
     75 // applications that send and receive messages.
     76 class GCMClientImpl
     77     : public GCMClient, public GCMStatsRecorder::Delegate,
     78       public ConnectionFactory::ConnectionListener {
     79  public:
     80   explicit GCMClientImpl(scoped_ptr<GCMInternalsBuilder> internals_builder);
     81   virtual ~GCMClientImpl();
     82 
     83   // GCMClient implementation.
     84   virtual void Initialize(
     85       const ChromeBuildInfo& chrome_build_info,
     86       const base::FilePath& store_path,
     87       const scoped_refptr<base::SequencedTaskRunner>& blocking_task_runner,
     88       const scoped_refptr<net::URLRequestContextGetter>&
     89           url_request_context_getter,
     90       scoped_ptr<Encryptor> encryptor,
     91       GCMClient::Delegate* delegate) OVERRIDE;
     92   virtual void Start() OVERRIDE;
     93   virtual void Stop() OVERRIDE;
     94   virtual void CheckOut() OVERRIDE;
     95   virtual void Register(const std::string& app_id,
     96                         const std::vector<std::string>& sender_ids) OVERRIDE;
     97   virtual void Unregister(const std::string& app_id) OVERRIDE;
     98   virtual void Send(const std::string& app_id,
     99                     const std::string& receiver_id,
    100                     const OutgoingMessage& message) OVERRIDE;
    101   virtual void SetRecording(bool recording) OVERRIDE;
    102   virtual void ClearActivityLogs() OVERRIDE;
    103   virtual GCMStatistics GetStatistics() const OVERRIDE;
    104 
    105   // GCMStatsRecorder::Delegate implemenation.
    106   virtual void OnActivityRecorded() OVERRIDE;
    107 
    108   // ConnectionFactory::ConnectionListener implementation.
    109   virtual void OnConnected(const GURL& current_server,
    110                            const net::IPEndPoint& ip_endpoint) OVERRIDE;
    111   virtual void OnDisconnected() OVERRIDE;
    112 
    113  private:
    114   // State representation of the GCMClient.
    115   // Any change made to this enum should have corresponding change in the
    116   // GetStateString(...) function.
    117   enum State {
    118     // Uninitialized.
    119     UNINITIALIZED,
    120     // Initialized,
    121     INITIALIZED,
    122     // GCM store loading is in progress.
    123     LOADING,
    124     // Initial device checkin is in progress.
    125     INITIAL_DEVICE_CHECKIN,
    126     // Ready to accept requests.
    127     READY,
    128   };
    129 
    130   // The check-in info for the user. Returned by the server.
    131   struct CheckinInfo {
    132     CheckinInfo() : android_id(0), secret(0) {}
    133     bool IsValid() const { return android_id != 0 && secret != 0; }
    134     void Reset() {
    135       android_id = 0;
    136       secret = 0;
    137     }
    138 
    139     uint64 android_id;
    140     uint64 secret;
    141   };
    142 
    143   // Collection of pending registration requests. Keys are app IDs, while values
    144   // are pending registration requests to obtain a registration ID for
    145   // requesting application.
    146   typedef std::map<std::string, RegistrationRequest*>
    147       PendingRegistrationRequests;
    148 
    149   // Collection of pending unregistration requests. Keys are app IDs, while
    150   // values are pending unregistration requests to disable the registration ID
    151   // currently assigned to the application.
    152   typedef std::map<std::string, UnregistrationRequest*>
    153       PendingUnregistrationRequests;
    154 
    155   friend class GCMClientImplTest;
    156 
    157   // Returns text representation of the enum State.
    158   std::string GetStateString() const;
    159 
    160   // Callbacks for the MCSClient.
    161   // Receives messages and dispatches them to relevant user delegates.
    162   void OnMessageReceivedFromMCS(const gcm::MCSMessage& message);
    163   // Receives confirmation of sent messages or information about errors.
    164   void OnMessageSentToMCS(int64 user_serial_number,
    165                           const std::string& app_id,
    166                           const std::string& message_id,
    167                           MCSClient::MessageSendStatus status);
    168   // Receives information about mcs_client_ errors.
    169   void OnMCSError();
    170 
    171   // Runs after GCM Store load is done to trigger continuation of the
    172   // initialization.
    173   void OnLoadCompleted(scoped_ptr<GCMStore::LoadResult> result);
    174   // Initializes mcs_client_, which handles the connection to MCS.
    175   void InitializeMCSClient(scoped_ptr<GCMStore::LoadResult> result);
    176   // Complets the first time device checkin.
    177   void OnFirstTimeDeviceCheckinCompleted(const CheckinInfo& checkin_info);
    178   // Starts a login on mcs_client_.
    179   void StartMCSLogin();
    180   // Resets state to before initialization.
    181   void ResetState();
    182   // Sets state to ready. This will initiate the MCS login and notify the
    183   // delegates.
    184   void OnReady();
    185 
    186   // Starts a first time device checkin.
    187   void StartCheckin();
    188   // Completes the device checkin request by parsing the |checkin_response|.
    189   // Function also cleans up the pending checkin.
    190   void OnCheckinCompleted(
    191       const checkin_proto::AndroidCheckinResponse& checkin_response);
    192 
    193   // Callback passed to GCMStore::SetGServicesSettings.
    194   void SetGServicesSettingsCallback(bool success);
    195 
    196   // Schedules next periodic device checkin and makes sure there is at most one
    197   // pending checkin at a time. This function is meant to be called after a
    198   // successful checkin.
    199   void SchedulePeriodicCheckin();
    200   // Gets the time until next checkin.
    201   base::TimeDelta GetTimeToNextCheckin() const;
    202   // Callback for setting last checkin time in the |gcm_store_|.
    203   void SetLastCheckinTimeCallback(bool success);
    204 
    205   // Callback for persisting device credentials in the |gcm_store_|.
    206   void SetDeviceCredentialsCallback(bool success);
    207 
    208   // Callback for persisting registration info in the |gcm_store_|.
    209   void UpdateRegistrationCallback(bool success);
    210 
    211   // Completes the registration request.
    212   void OnRegisterCompleted(const std::string& app_id,
    213                            const std::vector<std::string>& sender_ids,
    214                            RegistrationRequest::Status status,
    215                            const std::string& registration_id);
    216 
    217   // Completes the unregistration request.
    218   void OnUnregisterCompleted(const std::string& app_id,
    219                              UnregistrationRequest::Status status);
    220 
    221   // Completes the GCM store destroy request.
    222   void OnGCMStoreDestroyed(bool success);
    223 
    224   // Handles incoming data message and dispatches it the delegate of this class.
    225   void HandleIncomingMessage(const gcm::MCSMessage& message);
    226 
    227   // Fires OnMessageReceived event on the delegate of this class, based on the
    228   // details in |data_message_stanza| and |message_data|.
    229   void HandleIncomingDataMessage(
    230       const mcs_proto::DataMessageStanza& data_message_stanza,
    231       MessageData& message_data);
    232 
    233   // Fires OnMessageSendError event on the delegate of this calss, based on the
    234   // details in |data_message_stanza| and |message_data|.
    235   void HandleIncomingSendError(
    236       const mcs_proto::DataMessageStanza& data_message_stanza,
    237       MessageData& message_data);
    238 
    239   // Builder for the GCM internals (mcs client, etc.).
    240   scoped_ptr<GCMInternalsBuilder> internals_builder_;
    241 
    242   // Recorder that logs GCM activities.
    243   GCMStatsRecorderImpl recorder_;
    244 
    245   // State of the GCM Client Implementation.
    246   State state_;
    247 
    248   GCMClient::Delegate* delegate_;
    249 
    250   // Device checkin info (android ID and security token used by device).
    251   CheckinInfo device_checkin_info_;
    252 
    253   // Clock used for timing of retry logic. Passed in for testing. Owned by
    254   // GCMClientImpl.
    255   scoped_ptr<base::Clock> clock_;
    256 
    257   // Information about the chrome build.
    258   // TODO(fgorski): Check if it can be passed in constructor and made const.
    259   ChromeBuildInfo chrome_build_info_;
    260 
    261   // Persistent data store for keeping device credentials, messages and user to
    262   // serial number mappings.
    263   scoped_ptr<GCMStore> gcm_store_;
    264 
    265   scoped_refptr<net::HttpNetworkSession> network_session_;
    266   net::BoundNetLog net_log_;
    267   scoped_ptr<ConnectionFactory> connection_factory_;
    268   scoped_refptr<net::URLRequestContextGetter> url_request_context_getter_;
    269 
    270   // Controls receiving and sending of packets and reliable message queueing.
    271   scoped_ptr<MCSClient> mcs_client_;
    272 
    273   scoped_ptr<CheckinRequest> checkin_request_;
    274 
    275   // Cached registration info.
    276   RegistrationInfoMap registrations_;
    277 
    278   // Currently pending registration requests. GCMClientImpl owns the
    279   // RegistrationRequests.
    280   PendingRegistrationRequests pending_registration_requests_;
    281   STLValueDeleter<PendingRegistrationRequests>
    282       pending_registration_requests_deleter_;
    283 
    284   // Currently pending unregistration requests. GCMClientImpl owns the
    285   // UnregistrationRequests.
    286   PendingUnregistrationRequests pending_unregistration_requests_;
    287   STLValueDeleter<PendingUnregistrationRequests>
    288       pending_unregistration_requests_deleter_;
    289 
    290   // G-services settings that were provided by MCS.
    291   GServicesSettings gservices_settings_;
    292 
    293   // Time of the last successful checkin.
    294   base::Time last_checkin_time_;
    295 
    296   // Factory for creating references when scheduling periodic checkin.
    297   base::WeakPtrFactory<GCMClientImpl> periodic_checkin_ptr_factory_;
    298 
    299   // Factory for creating references in callbacks.
    300   base::WeakPtrFactory<GCMClientImpl> weak_ptr_factory_;
    301 
    302   DISALLOW_COPY_AND_ASSIGN(GCMClientImpl);
    303 };
    304 
    305 }  // namespace gcm
    306 
    307 #endif  // COMPONENTS_GCM_DRIVER_GCM_CLIENT_IMPL_H_
    308