gcm_client_impl.h revision 116680a4aac90f2aa7413d9095a592090648e557
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 30class GURL; 31 32namespace base { 33class Clock; 34class Time; 35} // namespace base 36 37namespace mcs_proto { 38class DataMessageStanza; 39} // namespace mcs_proto 40 41namespace net { 42class HttpNetworkSession; 43} // namespace net 44 45namespace gcm { 46 47class CheckinRequest; 48class ConnectionFactory; 49class GCMClientImplTest; 50 51// Helper class for building GCM internals. Allows tests to inject fake versions 52// as necessary. 53class 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. 78class 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 109 // GCMStatsRecorder::Delegate implemenation. 110 virtual void OnActivityRecorded() OVERRIDE; 111 112 // ConnectionFactory::ConnectionListener implementation. 113 virtual void OnConnected(const GURL& current_server, 114 const net::IPEndPoint& ip_endpoint) OVERRIDE; 115 virtual void OnDisconnected() OVERRIDE; 116 117 private: 118 // State representation of the GCMClient. 119 // Any change made to this enum should have corresponding change in the 120 // GetStateString(...) function. 121 enum State { 122 // Uninitialized. 123 UNINITIALIZED, 124 // Initialized, 125 INITIALIZED, 126 // GCM store loading is in progress. 127 LOADING, 128 // Initial device checkin is in progress. 129 INITIAL_DEVICE_CHECKIN, 130 // Ready to accept requests. 131 READY, 132 }; 133 134 // The check-in info for the device. 135 // TODO(fgorski): Convert to a class with explicit getters/setters. 136 struct CheckinInfo { 137 CheckinInfo(); 138 ~CheckinInfo(); 139 bool IsValid() const { return android_id != 0 && secret != 0; } 140 void SnapshotCheckinAccounts(); 141 void Reset(); 142 143 // Android ID of the device as assigned by the server. 144 uint64 android_id; 145 // Security token of the device as assigned by the server. 146 uint64 secret; 147 // True if accounts were already provided through SetAccountsForCheckin(), 148 // or when |last_checkin_accounts| was loaded as empty. 149 bool accounts_set; 150 // Map of account email addresses and OAuth2 tokens that will be sent to the 151 // checkin server on a next checkin. 152 std::map<std::string, std::string> account_tokens; 153 // As set of accounts last checkin was completed with. 154 std::set<std::string> last_checkin_accounts; 155 }; 156 157 // Collection of pending registration requests. Keys are app IDs, while values 158 // are pending registration requests to obtain a registration ID for 159 // requesting application. 160 typedef std::map<std::string, RegistrationRequest*> 161 PendingRegistrationRequests; 162 163 // Collection of pending unregistration requests. Keys are app IDs, while 164 // values are pending unregistration requests to disable the registration ID 165 // currently assigned to the application. 166 typedef std::map<std::string, UnregistrationRequest*> 167 PendingUnregistrationRequests; 168 169 friend class GCMClientImplTest; 170 171 // Returns text representation of the enum State. 172 std::string GetStateString() const; 173 174 // Callbacks for the MCSClient. 175 // Receives messages and dispatches them to relevant user delegates. 176 void OnMessageReceivedFromMCS(const gcm::MCSMessage& message); 177 // Receives confirmation of sent messages or information about errors. 178 void OnMessageSentToMCS(int64 user_serial_number, 179 const std::string& app_id, 180 const std::string& message_id, 181 MCSClient::MessageSendStatus status); 182 // Receives information about mcs_client_ errors. 183 void OnMCSError(); 184 185 // Runs after GCM Store load is done to trigger continuation of the 186 // initialization. 187 void OnLoadCompleted(scoped_ptr<GCMStore::LoadResult> result); 188 // Initializes mcs_client_, which handles the connection to MCS. 189 void InitializeMCSClient(scoped_ptr<GCMStore::LoadResult> result); 190 // Complets the first time device checkin. 191 void OnFirstTimeDeviceCheckinCompleted(const CheckinInfo& checkin_info); 192 // Starts a login on mcs_client_. 193 void StartMCSLogin(); 194 // Resets state to before initialization. 195 void ResetState(); 196 // Sets state to ready. This will initiate the MCS login and notify the 197 // delegates. 198 void OnReady(); 199 200 // Starts a first time device checkin. 201 void StartCheckin(); 202 // Completes the device checkin request by parsing the |checkin_response|. 203 // Function also cleans up the pending checkin. 204 void OnCheckinCompleted( 205 const checkin_proto::AndroidCheckinResponse& checkin_response); 206 207 // Callback passed to GCMStore::SetGServicesSettings. 208 void SetGServicesSettingsCallback(bool success); 209 210 // Schedules next periodic device checkin and makes sure there is at most one 211 // pending checkin at a time. This function is meant to be called after a 212 // successful checkin. 213 void SchedulePeriodicCheckin(); 214 // Gets the time until next checkin. 215 base::TimeDelta GetTimeToNextCheckin() const; 216 // Callback for setting last checkin information in the |gcm_store_|. 217 void SetLastCheckinInfoCallback(bool success); 218 219 // Callback for persisting device credentials in the |gcm_store_|. 220 void SetDeviceCredentialsCallback(bool success); 221 222 // Callback for persisting registration info in the |gcm_store_|. 223 void UpdateRegistrationCallback(bool success); 224 225 // Completes the registration request. 226 void OnRegisterCompleted(const std::string& app_id, 227 const std::vector<std::string>& sender_ids, 228 RegistrationRequest::Status status, 229 const std::string& registration_id); 230 231 // Completes the unregistration request. 232 void OnUnregisterCompleted(const std::string& app_id, 233 UnregistrationRequest::Status status); 234 235 // Completes the GCM store destroy request. 236 void OnGCMStoreDestroyed(bool success); 237 238 // Handles incoming data message and dispatches it the delegate of this class. 239 void HandleIncomingMessage(const gcm::MCSMessage& message); 240 241 // Fires OnMessageReceived event on the delegate of this class, based on the 242 // details in |data_message_stanza| and |message_data|. 243 void HandleIncomingDataMessage( 244 const mcs_proto::DataMessageStanza& data_message_stanza, 245 MessageData& message_data); 246 247 // Fires OnMessageSendError event on the delegate of this calss, based on the 248 // details in |data_message_stanza| and |message_data|. 249 void HandleIncomingSendError( 250 const mcs_proto::DataMessageStanza& data_message_stanza, 251 MessageData& message_data); 252 253 // Builder for the GCM internals (mcs client, etc.). 254 scoped_ptr<GCMInternalsBuilder> internals_builder_; 255 256 // Recorder that logs GCM activities. 257 GCMStatsRecorderImpl recorder_; 258 259 // State of the GCM Client Implementation. 260 State state_; 261 262 GCMClient::Delegate* delegate_; 263 264 // Device checkin info (android ID and security token used by device). 265 CheckinInfo device_checkin_info_; 266 267 // Clock used for timing of retry logic. Passed in for testing. Owned by 268 // GCMClientImpl. 269 scoped_ptr<base::Clock> clock_; 270 271 // Information about the chrome build. 272 // TODO(fgorski): Check if it can be passed in constructor and made const. 273 ChromeBuildInfo chrome_build_info_; 274 275 // Persistent data store for keeping device credentials, messages and user to 276 // serial number mappings. 277 scoped_ptr<GCMStore> gcm_store_; 278 279 scoped_refptr<net::HttpNetworkSession> network_session_; 280 net::BoundNetLog net_log_; 281 scoped_ptr<ConnectionFactory> connection_factory_; 282 scoped_refptr<net::URLRequestContextGetter> url_request_context_getter_; 283 284 // Controls receiving and sending of packets and reliable message queueing. 285 scoped_ptr<MCSClient> mcs_client_; 286 287 scoped_ptr<CheckinRequest> checkin_request_; 288 289 // Cached registration info. 290 RegistrationInfoMap registrations_; 291 292 // Currently pending registration requests. GCMClientImpl owns the 293 // RegistrationRequests. 294 PendingRegistrationRequests pending_registration_requests_; 295 STLValueDeleter<PendingRegistrationRequests> 296 pending_registration_requests_deleter_; 297 298 // Currently pending unregistration requests. GCMClientImpl owns the 299 // UnregistrationRequests. 300 PendingUnregistrationRequests pending_unregistration_requests_; 301 STLValueDeleter<PendingUnregistrationRequests> 302 pending_unregistration_requests_deleter_; 303 304 // G-services settings that were provided by MCS. 305 GServicesSettings gservices_settings_; 306 307 // Time of the last successful checkin. 308 base::Time last_checkin_time_; 309 310 // Factory for creating references when scheduling periodic checkin. 311 base::WeakPtrFactory<GCMClientImpl> periodic_checkin_ptr_factory_; 312 313 // Factory for creating references in callbacks. 314 base::WeakPtrFactory<GCMClientImpl> weak_ptr_factory_; 315 316 DISALLOW_COPY_AND_ASSIGN(GCMClientImpl); 317}; 318 319} // namespace gcm 320 321#endif // COMPONENTS_GCM_DRIVER_GCM_CLIENT_IMPL_H_ 322