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_
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"
38 class DataMessageStanza
;
39 } // namespace mcs_proto
42 class HttpNetworkSession
;
48 class ConnectionFactory
;
49 class GCMClientImplTest
;
51 // Helper class for building GCM internals. Allows tests to inject fake versions
53 class GCMInternalsBuilder
{
55 GCMInternalsBuilder();
56 virtual ~GCMInternalsBuilder();
58 virtual scoped_ptr
<base::Clock
> BuildClock();
59 virtual scoped_ptr
<MCSClient
> BuildMCSClient(
60 const std::string
& version
,
62 ConnectionFactory
* connection_factory
,
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
,
71 GCMStatsRecorder
* recorder
);
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.
79 : public GCMClient
, public GCMStatsRecorder::Delegate
,
80 public ConnectionFactory::ConnectionListener
{
82 explicit GCMClientImpl(scoped_ptr
<GCMInternalsBuilder
> internals_builder
);
83 ~GCMClientImpl() override
;
85 // GCMClient implementation.
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 void Start() override
;
96 void CheckOut() override
;
97 void Register(const std::string
& app_id
,
98 const std::vector
<std::string
>& sender_ids
) override
;
99 void Unregister(const std::string
& app_id
) override
;
100 void Send(const std::string
& app_id
,
101 const std::string
& receiver_id
,
102 const OutgoingMessage
& message
) override
;
103 void SetRecording(bool recording
) override
;
104 void ClearActivityLogs() override
;
105 GCMStatistics
GetStatistics() const override
;
106 void SetAccountTokens(
107 const std::vector
<AccountTokenInfo
>& account_tokens
) override
;
108 void UpdateAccountMapping(const AccountMapping
& account_mapping
) override
;
109 void RemoveAccountMapping(const std::string
& account_id
) override
;
110 void SetLastTokenFetchTime(const base::Time
& time
) override
;
111 void UpdateHeartbeatTimer(scoped_ptr
<base::Timer
> timer
) override
;
113 // GCMStatsRecorder::Delegate implemenation.
114 void OnActivityRecorded() override
;
116 // ConnectionFactory::ConnectionListener implementation.
117 void OnConnected(const GURL
& current_server
,
118 const net::IPEndPoint
& ip_endpoint
) override
;
119 void OnDisconnected() override
;
122 // State representation of the GCMClient.
123 // Any change made to this enum should have corresponding change in the
124 // GetStateString(...) function.
130 // GCM store loading is in progress.
132 // Initial device checkin is in progress.
133 INITIAL_DEVICE_CHECKIN
,
134 // Ready to accept requests.
138 // The check-in info for the device.
139 // TODO(fgorski): Convert to a class with explicit getters/setters.
143 bool IsValid() const { return android_id
!= 0 && secret
!= 0; }
144 void SnapshotCheckinAccounts();
147 // Android ID of the device as assigned by the server.
149 // Security token of the device as assigned by the server.
151 // True if accounts were already provided through SetAccountsForCheckin(),
152 // or when |last_checkin_accounts| was loaded as empty.
154 // Map of account email addresses and OAuth2 tokens that will be sent to the
155 // checkin server on a next checkin.
156 std::map
<std::string
, std::string
> account_tokens
;
157 // As set of accounts last checkin was completed with.
158 std::set
<std::string
> last_checkin_accounts
;
161 // Collection of pending registration requests. Keys are app IDs, while values
162 // are pending registration requests to obtain a registration ID for
163 // requesting application.
164 typedef std::map
<std::string
, RegistrationRequest
*>
165 PendingRegistrationRequests
;
167 // Collection of pending unregistration requests. Keys are app IDs, while
168 // values are pending unregistration requests to disable the registration ID
169 // currently assigned to the application.
170 typedef std::map
<std::string
, UnregistrationRequest
*>
171 PendingUnregistrationRequests
;
173 friend class GCMClientImplTest
;
175 // Returns text representation of the enum State.
176 std::string
GetStateString() const;
178 // Callbacks for the MCSClient.
179 // Receives messages and dispatches them to relevant user delegates.
180 void OnMessageReceivedFromMCS(const gcm::MCSMessage
& message
);
181 // Receives confirmation of sent messages or information about errors.
182 void OnMessageSentToMCS(int64 user_serial_number
,
183 const std::string
& app_id
,
184 const std::string
& message_id
,
185 MCSClient::MessageSendStatus status
);
186 // Receives information about mcs_client_ errors.
189 // Runs after GCM Store load is done to trigger continuation of the
191 void OnLoadCompleted(scoped_ptr
<GCMStore::LoadResult
> result
);
192 // Initializes mcs_client_, which handles the connection to MCS.
193 void InitializeMCSClient(scoped_ptr
<GCMStore::LoadResult
> result
);
194 // Complets the first time device checkin.
195 void OnFirstTimeDeviceCheckinCompleted(const CheckinInfo
& checkin_info
);
196 // Starts a login on mcs_client_.
197 void StartMCSLogin();
198 // Resets state to before initialization.
200 // Sets state to ready. This will initiate the MCS login and notify the
202 void OnReady(const std::vector
<AccountMapping
>& account_mappings
,
203 const base::Time
& last_token_fetch_time
);
205 // Starts a first time device checkin.
207 // Completes the device checkin request by parsing the |checkin_response|.
208 // Function also cleans up the pending checkin.
209 void OnCheckinCompleted(
210 const checkin_proto::AndroidCheckinResponse
& checkin_response
);
212 // Callback passed to GCMStore::SetGServicesSettings.
213 void SetGServicesSettingsCallback(bool success
);
215 // Schedules next periodic device checkin and makes sure there is at most one
216 // pending checkin at a time. This function is meant to be called after a
217 // successful checkin.
218 void SchedulePeriodicCheckin();
219 // Gets the time until next checkin.
220 base::TimeDelta
GetTimeToNextCheckin() const;
221 // Callback for setting last checkin information in the |gcm_store_|.
222 void SetLastCheckinInfoCallback(bool success
);
224 // Callback for persisting device credentials in the |gcm_store_|.
225 void SetDeviceCredentialsCallback(bool success
);
227 // Callback for persisting registration info in the |gcm_store_|.
228 void UpdateRegistrationCallback(bool success
);
230 // Callback for all store operations that do not try to recover, if write in
231 // |gcm_store_| fails.
232 void DefaultStoreCallback(bool success
);
234 // Callback for store operation where result does not matter.
235 void IgnoreWriteResultCallback(bool success
);
237 // Completes the registration request.
238 void OnRegisterCompleted(const std::string
& app_id
,
239 const std::vector
<std::string
>& sender_ids
,
240 RegistrationRequest::Status status
,
241 const std::string
& registration_id
);
243 // Completes the unregistration request.
244 void OnUnregisterCompleted(const std::string
& app_id
,
245 UnregistrationRequest::Status status
);
247 // Completes the GCM store destroy request.
248 void OnGCMStoreDestroyed(bool success
);
250 // Handles incoming data message and dispatches it the delegate of this class.
251 void HandleIncomingMessage(const gcm::MCSMessage
& message
);
253 // Fires OnMessageReceived event on the delegate of this class, based on the
254 // details in |data_message_stanza| and |message_data|.
255 void HandleIncomingDataMessage(
256 const mcs_proto::DataMessageStanza
& data_message_stanza
,
257 MessageData
& message_data
);
259 // Fires OnMessageSendError event on the delegate of this calss, based on the
260 // details in |data_message_stanza| and |message_data|.
261 void HandleIncomingSendError(
262 const mcs_proto::DataMessageStanza
& data_message_stanza
,
263 MessageData
& message_data
);
265 // Builder for the GCM internals (mcs client, etc.).
266 scoped_ptr
<GCMInternalsBuilder
> internals_builder_
;
268 // Recorder that logs GCM activities.
269 GCMStatsRecorderImpl recorder_
;
271 // State of the GCM Client Implementation.
274 GCMClient::Delegate
* delegate_
;
276 // Device checkin info (android ID and security token used by device).
277 CheckinInfo device_checkin_info_
;
279 // Clock used for timing of retry logic. Passed in for testing. Owned by
281 scoped_ptr
<base::Clock
> clock_
;
283 // Information about the chrome build.
284 // TODO(fgorski): Check if it can be passed in constructor and made const.
285 ChromeBuildInfo chrome_build_info_
;
287 // Persistent data store for keeping device credentials, messages and user to
288 // serial number mappings.
289 scoped_ptr
<GCMStore
> gcm_store_
;
291 scoped_refptr
<net::HttpNetworkSession
> network_session_
;
292 net::BoundNetLog net_log_
;
293 scoped_ptr
<ConnectionFactory
> connection_factory_
;
294 scoped_refptr
<net::URLRequestContextGetter
> url_request_context_getter_
;
296 // Controls receiving and sending of packets and reliable message queueing.
297 scoped_ptr
<MCSClient
> mcs_client_
;
299 scoped_ptr
<CheckinRequest
> checkin_request_
;
301 // Cached registration info.
302 RegistrationInfoMap registrations_
;
304 // Currently pending registration requests. GCMClientImpl owns the
305 // RegistrationRequests.
306 PendingRegistrationRequests pending_registration_requests_
;
307 STLValueDeleter
<PendingRegistrationRequests
>
308 pending_registration_requests_deleter_
;
310 // Currently pending unregistration requests. GCMClientImpl owns the
311 // UnregistrationRequests.
312 PendingUnregistrationRequests pending_unregistration_requests_
;
313 STLValueDeleter
<PendingUnregistrationRequests
>
314 pending_unregistration_requests_deleter_
;
316 // G-services settings that were provided by MCS.
317 GServicesSettings gservices_settings_
;
319 // Time of the last successful checkin.
320 base::Time last_checkin_time_
;
322 // Factory for creating references when scheduling periodic checkin.
323 base::WeakPtrFactory
<GCMClientImpl
> periodic_checkin_ptr_factory_
;
325 // Factory for creating references in callbacks.
326 base::WeakPtrFactory
<GCMClientImpl
> weak_ptr_factory_
;
328 DISALLOW_COPY_AND_ASSIGN(GCMClientImpl
);
333 #endif // COMPONENTS_GCM_DRIVER_GCM_CLIENT_IMPL_H_