Fix AfterTyping experiment for Android.
[chromium-blink-merge.git] / components / gcm_driver / gcm_client_impl.h
blobfd084d7e7e34a9d94cb60e8cce2b3508a9c0d392
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_
8 #include <map>
9 #include <set>
10 #include <string>
11 #include <utility>
12 #include <vector>
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"
31 class GURL;
33 namespace base {
34 class Clock;
35 class Time;
36 } // namespace base
38 namespace mcs_proto {
39 class DataMessageStanza;
40 } // namespace mcs_proto
42 namespace net {
43 class HttpNetworkSession;
44 } // namespace net
46 namespace gcm {
48 class CheckinRequest;
49 class ConnectionFactory;
50 class GCMClientImplTest;
52 // Helper class for building GCM internals. Allows tests to inject fake versions
53 // as necessary.
54 class GCMInternalsBuilder {
55 public:
56 GCMInternalsBuilder();
57 virtual ~GCMInternalsBuilder();
59 virtual scoped_ptr<base::Clock> BuildClock();
60 virtual scoped_ptr<MCSClient> BuildMCSClient(
61 const std::string& version,
62 base::Clock* clock,
63 ConnectionFactory* connection_factory,
64 GCMStore* gcm_store,
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,
71 net::NetLog* net_log,
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.
79 class GCMClientImpl
80 : public GCMClient, public GCMStatsRecorder::Delegate,
81 public ConnectionFactory::ConnectionListener {
82 public:
83 // State representation of the GCMClient.
84 // Any change made to this enum should have corresponding change in the
85 // GetStateString(...) function.
86 enum State {
87 // Uninitialized.
88 UNINITIALIZED,
89 // Initialized,
90 INITIALIZED,
91 // GCM store loading is in progress.
92 LOADING,
93 // GCM store is loaded.
94 LOADED,
95 // Initial device checkin is in progress.
96 INITIAL_DEVICE_CHECKIN,
97 // Ready to accept requests.
98 READY,
101 explicit GCMClientImpl(scoped_ptr<GCMInternalsBuilder> internals_builder);
102 ~GCMClientImpl() override;
104 // GCMClient implementation.
105 void Initialize(
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;
116 void Unregister(
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;
148 private:
149 // The check-in info for the device.
150 // TODO(fgorski): Convert to a class with explicit getters/setters.
151 struct CheckinInfo {
152 CheckinInfo();
153 ~CheckinInfo();
154 bool IsValid() const { return android_id != 0 && secret != 0; }
155 void SnapshotCheckinAccounts();
156 void Reset();
158 // Android ID of the device as assigned by the server.
159 uint64 android_id;
160 // Security token of the device as assigned by the server.
161 uint64 secret;
162 // True if accounts were already provided through SetAccountsForCheckin(),
163 // or when |last_checkin_accounts| was loaded as empty.
164 bool accounts_set;
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.
201 void OnMCSError();
203 // Runs after GCM Store load is done to trigger continuation of the
204 // initialization.
205 void OnLoadCompleted(scoped_ptr<GCMStore::LoadResult> result);
206 // Starts the GCM.
207 void StartGCM();
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.
215 void ResetStore();
216 // Sets state to ready. This will initiate the MCS login and notify the
217 // delegates.
218 void OnReady(const std::vector<AccountMapping>& account_mappings,
219 const base::Time& last_token_fetch_time);
221 // Starts a first time device checkin.
222 void StartCheckin();
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.
295 void ResetCache();
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.
304 State state_;
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
318 // GCMClientImpl.
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
368 // and extra data.
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);
383 } // namespace gcm
385 #endif // COMPONENTS_GCM_DRIVER_GCM_CLIENT_IMPL_H_