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