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