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.
5 #ifndef COMPONENTS_GCM_DRIVER_GCM_CLIENT_IMPL_H_
6 #define COMPONENTS_GCM_DRIVER_GCM_CLIENT_IMPL_H_
14 #include "base/compiler_specific.h"
15 #include "base/memory/ref_counted.h"
16 #include "base/memory/weak_ptr.h"
17 #include "base/stl_util.h"
18 #include "components/gcm_driver/gcm_client.h"
19 #include "components/gcm_driver/gcm_stats_recorder_impl.h"
20 #include "google_apis/gcm/base/mcs_message.h"
21 #include "google_apis/gcm/engine/gcm_store.h"
22 #include "google_apis/gcm/engine/gservices_settings.h"
23 #include "google_apis/gcm/engine/mcs_client.h"
24 #include "google_apis/gcm/engine/registration_request.h"
25 #include "google_apis/gcm/engine/unregistration_request.h"
26 #include "google_apis/gcm/protocol/android_checkin.pb.h"
27 #include "google_apis/gcm/protocol/checkin.pb.h"
28 #include "net/log/net_log.h"
29 #include "net/url_request/url_request_context_getter.h"
39 class DataMessageStanza
;
40 } // namespace mcs_proto
43 class HttpNetworkSession
;
49 class ConnectionFactory
;
50 class GCMClientImplTest
;
52 // Helper class for building GCM internals. Allows tests to inject fake versions
54 class GCMInternalsBuilder
{
56 GCMInternalsBuilder();
57 virtual ~GCMInternalsBuilder();
59 virtual scoped_ptr
<base::Clock
> BuildClock();
60 virtual scoped_ptr
<MCSClient
> BuildMCSClient(
61 const std::string
& version
,
63 ConnectionFactory
* connection_factory
,
65 GCMStatsRecorder
* recorder
);
66 virtual scoped_ptr
<ConnectionFactory
> BuildConnectionFactory(
67 const std::vector
<GURL
>& endpoints
,
68 const net::BackoffEntry::Policy
& backoff_policy
,
69 const scoped_refptr
<net::HttpNetworkSession
>& gcm_network_session
,
70 const scoped_refptr
<net::HttpNetworkSession
>& http_network_session
,
72 GCMStatsRecorder
* recorder
);
75 // Implements the GCM Client. It is used to coordinate MCS Client (communication
76 // with MCS) and other pieces of GCM infrastructure like Registration and
77 // Checkins. It also allows for registering user delegates that host
78 // applications that send and receive messages.
80 : public GCMClient
, public GCMStatsRecorder::Delegate
,
81 public ConnectionFactory::ConnectionListener
{
83 // State representation of the GCMClient.
84 // Any change made to this enum should have corresponding change in the
85 // GetStateString(...) function.
91 // GCM store loading is in progress.
93 // GCM store is loaded.
95 // Initial device checkin is in progress.
96 INITIAL_DEVICE_CHECKIN
,
97 // Ready to accept requests.
101 explicit GCMClientImpl(scoped_ptr
<GCMInternalsBuilder
> internals_builder
);
102 ~GCMClientImpl() override
;
104 // GCMClient implementation.
106 const ChromeBuildInfo
& chrome_build_info
,
107 const base::FilePath
& store_path
,
108 const scoped_refptr
<base::SequencedTaskRunner
>& blocking_task_runner
,
109 const scoped_refptr
<net::URLRequestContextGetter
>&
110 url_request_context_getter
,
111 scoped_ptr
<Encryptor
> encryptor
,
112 GCMClient::Delegate
* delegate
) override
;
113 void Start(StartMode start_mode
) override
;
114 void Stop() override
;
115 void Register(const linked_ptr
<RegistrationInfo
>& registration_info
) override
;
117 const linked_ptr
<RegistrationInfo
>& registration_info
) override
;
118 void Send(const std::string
& app_id
,
119 const std::string
& receiver_id
,
120 const OutgoingMessage
& message
) override
;
121 void SetRecording(bool recording
) override
;
122 void ClearActivityLogs() override
;
123 GCMStatistics
GetStatistics() const override
;
124 void SetAccountTokens(
125 const std::vector
<AccountTokenInfo
>& account_tokens
) override
;
126 void UpdateAccountMapping(const AccountMapping
& account_mapping
) override
;
127 void RemoveAccountMapping(const std::string
& account_id
) override
;
128 void SetLastTokenFetchTime(const base::Time
& time
) override
;
129 void UpdateHeartbeatTimer(scoped_ptr
<base::Timer
> timer
) override
;
130 void AddInstanceIDData(const std::string
& app_id
,
131 const std::string
& instance_id
,
132 const std::string
& extra_data
) override
;
133 void RemoveInstanceIDData(const std::string
& app_id
) override
;
134 void GetInstanceIDData(const std::string
& app_id
,
135 std::string
* instance_id
,
136 std::string
* extra_data
) override
;
137 void AddHeartbeatInterval(const std::string
& scope
, int interval_ms
) override
;
138 void RemoveHeartbeatInterval(const std::string
& scope
) override
;
140 // GCMStatsRecorder::Delegate implemenation.
141 void OnActivityRecorded() override
;
143 // ConnectionFactory::ConnectionListener implementation.
144 void OnConnected(const GURL
& current_server
,
145 const net::IPEndPoint
& ip_endpoint
) override
;
146 void OnDisconnected() override
;
149 // The check-in info for the device.
150 // TODO(fgorski): Convert to a class with explicit getters/setters.
154 bool IsValid() const { return android_id
!= 0 && secret
!= 0; }
155 void SnapshotCheckinAccounts();
158 // Android ID of the device as assigned by the server.
160 // Security token of the device as assigned by the server.
162 // True if accounts were already provided through SetAccountsForCheckin(),
163 // or when |last_checkin_accounts| was loaded as empty.
165 // Map of account email addresses and OAuth2 tokens that will be sent to the
166 // checkin server on a next checkin.
167 std::map
<std::string
, std::string
> account_tokens
;
168 // As set of accounts last checkin was completed with.
169 std::set
<std::string
> last_checkin_accounts
;
172 // Collection of pending registration requests. Keys are RegistrationInfo
173 // instance, while values are pending registration requests to obtain a
174 // registration ID for requesting application.
175 typedef std::map
<linked_ptr
<RegistrationInfo
>,
176 RegistrationRequest
*,
177 RegistrationInfoComparer
> PendingRegistrationRequests
;
179 // Collection of pending unregistration requests. Keys are RegistrationInfo
180 // instance, while values are pending unregistration requests to disable the
181 // registration ID currently assigned to the application.
182 typedef std::map
<linked_ptr
<RegistrationInfo
>,
183 UnregistrationRequest
*,
184 RegistrationInfoComparer
> PendingUnregistrationRequests
;
186 friend class GCMClientImplTest
;
187 friend class GCMClientInstanceIDTest
;
189 // Returns text representation of the enum State.
190 std::string
GetStateString() const;
192 // Callbacks for the MCSClient.
193 // Receives messages and dispatches them to relevant user delegates.
194 void OnMessageReceivedFromMCS(const gcm::MCSMessage
& message
);
195 // Receives confirmation of sent messages or information about errors.
196 void OnMessageSentToMCS(int64 user_serial_number
,
197 const std::string
& app_id
,
198 const std::string
& message_id
,
199 MCSClient::MessageSendStatus status
);
200 // Receives information about mcs_client_ errors.
203 // Runs after GCM Store load is done to trigger continuation of the
205 void OnLoadCompleted(scoped_ptr
<GCMStore::LoadResult
> result
);
208 // Initializes mcs_client_, which handles the connection to MCS.
209 void InitializeMCSClient();
210 // Complets the first time device checkin.
211 void OnFirstTimeDeviceCheckinCompleted(const CheckinInfo
& checkin_info
);
212 // Starts a login on mcs_client_.
213 void StartMCSLogin();
214 // Resets the GCM store when it is corrupted.
216 // Sets state to ready. This will initiate the MCS login and notify the
218 void OnReady(const std::vector
<AccountMapping
>& account_mappings
,
219 const base::Time
& last_token_fetch_time
);
221 // Starts a first time device checkin.
223 // Completes the device checkin request by parsing the |checkin_response|.
224 // Function also cleans up the pending checkin.
225 void OnCheckinCompleted(
226 const checkin_proto::AndroidCheckinResponse
& checkin_response
);
228 // Callback passed to GCMStore::SetGServicesSettings.
229 void SetGServicesSettingsCallback(bool success
);
231 // Schedules next periodic device checkin and makes sure there is at most one
232 // pending checkin at a time. This function is meant to be called after a
233 // successful checkin.
234 void SchedulePeriodicCheckin();
235 // Gets the time until next checkin.
236 base::TimeDelta
GetTimeToNextCheckin() const;
237 // Callback for setting last checkin information in the |gcm_store_|.
238 void SetLastCheckinInfoCallback(bool success
);
240 // Callback for persisting device credentials in the |gcm_store_|.
241 void SetDeviceCredentialsCallback(bool success
);
243 // Callback for persisting registration info in the |gcm_store_|.
244 void UpdateRegistrationCallback(bool success
);
246 // Callback for all store operations that do not try to recover, if write in
247 // |gcm_store_| fails.
248 void DefaultStoreCallback(bool success
);
250 // Callback for store operation where result does not matter.
251 void IgnoreWriteResultCallback(bool success
);
253 // Callback for destroying the GCM store.
254 void DestroyStoreCallback(bool success
);
256 // Callback for resetting the GCM store. The store will be reloaded.
257 void ResetStoreCallback(bool success
);
259 // Completes the registration request.
260 void OnRegisterCompleted(
261 const linked_ptr
<RegistrationInfo
>& registration_info
,
262 RegistrationRequest::Status status
,
263 const std::string
& registration_id
);
265 // Completes the unregistration request.
266 void OnUnregisterCompleted(
267 const linked_ptr
<RegistrationInfo
>& registration_info
,
268 UnregistrationRequest::Status status
);
270 // Completes the GCM store destroy request.
271 void OnGCMStoreDestroyed(bool success
);
273 // Handles incoming data message and dispatches it the delegate of this class.
274 void HandleIncomingMessage(const gcm::MCSMessage
& message
);
276 // Fires OnMessageReceived event on the delegate of this class, based on the
277 // details in |data_message_stanza| and |message_data|.
278 void HandleIncomingDataMessage(
279 const mcs_proto::DataMessageStanza
& data_message_stanza
,
280 MessageData
& message_data
);
282 // Fires OnMessageSendError event on the delegate of this calss, based on the
283 // details in |data_message_stanza| and |message_data|.
284 void HandleIncomingSendError(
285 const mcs_proto::DataMessageStanza
& data_message_stanza
,
286 MessageData
& message_data
);
288 // Is there any standalone app being registered for GCM?
289 bool HasStandaloneRegisteredApp() const;
291 // Destroys the store when it is not needed.
292 void DestroyStoreWhenNotNeeded();
294 // Reset all cahced values.
297 // Builder for the GCM internals (mcs client, etc.).
298 scoped_ptr
<GCMInternalsBuilder
> internals_builder_
;
300 // Recorder that logs GCM activities.
301 GCMStatsRecorderImpl recorder_
;
303 // State of the GCM Client Implementation.
306 GCMClient::Delegate
* delegate_
;
308 // Flag to indicate if the GCM should be delay started until it is actually
309 // used in either of the following cases:
310 // 1) The GCM store contains the registration records.
311 // 2) GCM functionailities are explicitly called.
312 StartMode start_mode_
;
314 // Device checkin info (android ID and security token used by device).
315 CheckinInfo device_checkin_info_
;
317 // Clock used for timing of retry logic. Passed in for testing. Owned by
319 scoped_ptr
<base::Clock
> clock_
;
321 // Information about the chrome build.
322 // TODO(fgorski): Check if it can be passed in constructor and made const.
323 ChromeBuildInfo chrome_build_info_
;
325 // Persistent data store for keeping device credentials, messages and user to
326 // serial number mappings.
327 scoped_ptr
<GCMStore
> gcm_store_
;
329 // Data loaded from the GCM store.
330 scoped_ptr
<GCMStore::LoadResult
> load_result_
;
332 // Tracks if the GCM store has been reset. This is used to prevent from
333 // resetting and loading from the store again and again.
334 bool gcm_store_reset_
;
336 scoped_refptr
<net::HttpNetworkSession
> network_session_
;
337 net::BoundNetLog net_log_
;
338 scoped_ptr
<ConnectionFactory
> connection_factory_
;
339 scoped_refptr
<net::URLRequestContextGetter
> url_request_context_getter_
;
341 // Controls receiving and sending of packets and reliable message queueing.
342 scoped_ptr
<MCSClient
> mcs_client_
;
344 scoped_ptr
<CheckinRequest
> checkin_request_
;
346 // Cached registration info.
347 RegistrationInfoMap registrations_
;
349 // Currently pending registration requests. GCMClientImpl owns the
350 // RegistrationRequests.
351 PendingRegistrationRequests pending_registration_requests_
;
352 STLValueDeleter
<PendingRegistrationRequests
>
353 pending_registration_requests_deleter_
;
355 // Currently pending unregistration requests. GCMClientImpl owns the
356 // UnregistrationRequests.
357 PendingUnregistrationRequests pending_unregistration_requests_
;
358 STLValueDeleter
<PendingUnregistrationRequests
>
359 pending_unregistration_requests_deleter_
;
361 // G-services settings that were provided by MCS.
362 GServicesSettings gservices_settings_
;
364 // Time of the last successful checkin.
365 base::Time last_checkin_time_
;
367 // Cached instance ID data, key is app ID and value is pair of instance ID
369 std::map
<std::string
, std::pair
<std::string
, std::string
>> instance_id_data_
;
371 // Factory for creating references when scheduling periodic checkin.
372 base::WeakPtrFactory
<GCMClientImpl
> periodic_checkin_ptr_factory_
;
374 // Factory for wiping out GCM store.
375 base::WeakPtrFactory
<GCMClientImpl
> destroying_gcm_store_ptr_factory_
;
377 // Factory for creating references in callbacks.
378 base::WeakPtrFactory
<GCMClientImpl
> weak_ptr_factory_
;
380 DISALLOW_COPY_AND_ASSIGN(GCMClientImpl
);
385 #endif // COMPONENTS_GCM_DRIVER_GCM_CLIENT_IMPL_H_