• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <string>
10 #include <vector>
11 
12 #include "base/compiler_specific.h"
13 #include "base/memory/ref_counted.h"
14 #include "base/memory/weak_ptr.h"
15 #include "base/stl_util.h"
16 #include "components/gcm_driver/gcm_client.h"
17 #include "components/gcm_driver/gcm_stats_recorder_impl.h"
18 #include "google_apis/gcm/base/mcs_message.h"
19 #include "google_apis/gcm/engine/gcm_store.h"
20 #include "google_apis/gcm/engine/gservices_settings.h"
21 #include "google_apis/gcm/engine/mcs_client.h"
22 #include "google_apis/gcm/engine/registration_request.h"
23 #include "google_apis/gcm/engine/unregistration_request.h"
24 #include "google_apis/gcm/protocol/android_checkin.pb.h"
25 #include "google_apis/gcm/protocol/checkin.pb.h"
26 #include "net/base/net_log.h"
27 #include "net/url_request/url_request_context_getter.h"
28 
29 class GURL;
30 
31 namespace base {
32 class Clock;
33 class Time;
34 }  // namespace base
35 
36 namespace mcs_proto {
37 class DataMessageStanza;
38 }  // namespace mcs_proto
39 
40 namespace net {
41 class HttpNetworkSession;
42 }  // namespace net
43 
44 namespace gcm {
45 
46 class CheckinRequest;
47 class ConnectionFactory;
48 class GCMClientImplTest;
49 
50 // Helper class for building GCM internals. Allows tests to inject fake versions
51 // as necessary.
52 class GCMInternalsBuilder {
53  public:
54   GCMInternalsBuilder();
55   virtual ~GCMInternalsBuilder();
56 
57   virtual scoped_ptr<base::Clock> BuildClock();
58   virtual scoped_ptr<MCSClient> BuildMCSClient(
59       const std::string& version,
60       base::Clock* clock,
61       ConnectionFactory* connection_factory,
62       GCMStore* gcm_store,
63       GCMStatsRecorder* recorder);
64   virtual scoped_ptr<ConnectionFactory> BuildConnectionFactory(
65       const std::vector<GURL>& endpoints,
66       const net::BackoffEntry::Policy& backoff_policy,
67       scoped_refptr<net::HttpNetworkSession> network_session,
68       net::NetLog* net_log,
69       GCMStatsRecorder* recorder);
70 };
71 
72 // Implements the GCM Client. It is used to coordinate MCS Client (communication
73 // with MCS) and other pieces of GCM infrastructure like Registration and
74 // Checkins. It also allows for registering user delegates that host
75 // applications that send and receive messages.
76 class GCMClientImpl
77     : public GCMClient, public GCMStatsRecorder::Delegate,
78       public ConnectionFactory::ConnectionListener {
79  public:
80   explicit GCMClientImpl(scoped_ptr<GCMInternalsBuilder> internals_builder);
81   virtual ~GCMClientImpl();
82 
83   // GCMClient implementation.
84   virtual void Initialize(
85       const ChromeBuildInfo& chrome_build_info,
86       const base::FilePath& store_path,
87       const scoped_refptr<base::SequencedTaskRunner>& blocking_task_runner,
88       const scoped_refptr<net::URLRequestContextGetter>&
89           url_request_context_getter,
90       scoped_ptr<Encryptor> encryptor,
91       GCMClient::Delegate* delegate) OVERRIDE;
92   virtual void Start() OVERRIDE;
93   virtual void Stop() OVERRIDE;
94   virtual void CheckOut() OVERRIDE;
95   virtual void Register(const std::string& app_id,
96                         const std::vector<std::string>& sender_ids) OVERRIDE;
97   virtual void Unregister(const std::string& app_id) OVERRIDE;
98   virtual void Send(const std::string& app_id,
99                     const std::string& receiver_id,
100                     const OutgoingMessage& message) OVERRIDE;
101   virtual void SetRecording(bool recording) OVERRIDE;
102   virtual void ClearActivityLogs() OVERRIDE;
103   virtual GCMStatistics GetStatistics() const OVERRIDE;
104 
105   // GCMStatsRecorder::Delegate implemenation.
106   virtual void OnActivityRecorded() OVERRIDE;
107 
108   // ConnectionFactory::ConnectionListener implementation.
109   virtual void OnConnected(const GURL& current_server,
110                            const net::IPEndPoint& ip_endpoint) OVERRIDE;
111   virtual void OnDisconnected() OVERRIDE;
112 
113  private:
114   // State representation of the GCMClient.
115   // Any change made to this enum should have corresponding change in the
116   // GetStateString(...) function.
117   enum State {
118     // Uninitialized.
119     UNINITIALIZED,
120     // Initialized,
121     INITIALIZED,
122     // GCM store loading is in progress.
123     LOADING,
124     // Initial device checkin is in progress.
125     INITIAL_DEVICE_CHECKIN,
126     // Ready to accept requests.
127     READY,
128   };
129 
130   // The check-in info for the user. Returned by the server.
131   struct CheckinInfo {
CheckinInfoCheckinInfo132     CheckinInfo() : android_id(0), secret(0) {}
IsValidCheckinInfo133     bool IsValid() const { return android_id != 0 && secret != 0; }
ResetCheckinInfo134     void Reset() {
135       android_id = 0;
136       secret = 0;
137     }
138 
139     uint64 android_id;
140     uint64 secret;
141   };
142 
143   // Collection of pending registration requests. Keys are app IDs, while values
144   // are pending registration requests to obtain a registration ID for
145   // requesting application.
146   typedef std::map<std::string, RegistrationRequest*>
147       PendingRegistrationRequests;
148 
149   // Collection of pending unregistration requests. Keys are app IDs, while
150   // values are pending unregistration requests to disable the registration ID
151   // currently assigned to the application.
152   typedef std::map<std::string, UnregistrationRequest*>
153       PendingUnregistrationRequests;
154 
155   friend class GCMClientImplTest;
156 
157   // Returns text representation of the enum State.
158   std::string GetStateString() const;
159 
160   // Callbacks for the MCSClient.
161   // Receives messages and dispatches them to relevant user delegates.
162   void OnMessageReceivedFromMCS(const gcm::MCSMessage& message);
163   // Receives confirmation of sent messages or information about errors.
164   void OnMessageSentToMCS(int64 user_serial_number,
165                           const std::string& app_id,
166                           const std::string& message_id,
167                           MCSClient::MessageSendStatus status);
168   // Receives information about mcs_client_ errors.
169   void OnMCSError();
170 
171   // Runs after GCM Store load is done to trigger continuation of the
172   // initialization.
173   void OnLoadCompleted(scoped_ptr<GCMStore::LoadResult> result);
174   // Initializes mcs_client_, which handles the connection to MCS.
175   void InitializeMCSClient(scoped_ptr<GCMStore::LoadResult> result);
176   // Complets the first time device checkin.
177   void OnFirstTimeDeviceCheckinCompleted(const CheckinInfo& checkin_info);
178   // Starts a login on mcs_client_.
179   void StartMCSLogin();
180   // Resets state to before initialization.
181   void ResetState();
182   // Sets state to ready. This will initiate the MCS login and notify the
183   // delegates.
184   void OnReady();
185 
186   // Starts a first time device checkin.
187   void StartCheckin();
188   // Completes the device checkin request by parsing the |checkin_response|.
189   // Function also cleans up the pending checkin.
190   void OnCheckinCompleted(
191       const checkin_proto::AndroidCheckinResponse& checkin_response);
192 
193   // Callback passed to GCMStore::SetGServicesSettings.
194   void SetGServicesSettingsCallback(bool success);
195 
196   // Schedules next periodic device checkin and makes sure there is at most one
197   // pending checkin at a time. This function is meant to be called after a
198   // successful checkin.
199   void SchedulePeriodicCheckin();
200   // Gets the time until next checkin.
201   base::TimeDelta GetTimeToNextCheckin() const;
202   // Callback for setting last checkin time in the |gcm_store_|.
203   void SetLastCheckinTimeCallback(bool success);
204 
205   // Callback for persisting device credentials in the |gcm_store_|.
206   void SetDeviceCredentialsCallback(bool success);
207 
208   // Callback for persisting registration info in the |gcm_store_|.
209   void UpdateRegistrationCallback(bool success);
210 
211   // Completes the registration request.
212   void OnRegisterCompleted(const std::string& app_id,
213                            const std::vector<std::string>& sender_ids,
214                            RegistrationRequest::Status status,
215                            const std::string& registration_id);
216 
217   // Completes the unregistration request.
218   void OnUnregisterCompleted(const std::string& app_id,
219                              UnregistrationRequest::Status status);
220 
221   // Completes the GCM store destroy request.
222   void OnGCMStoreDestroyed(bool success);
223 
224   // Handles incoming data message and dispatches it the delegate of this class.
225   void HandleIncomingMessage(const gcm::MCSMessage& message);
226 
227   // Fires OnMessageReceived event on the delegate of this class, based on the
228   // details in |data_message_stanza| and |message_data|.
229   void HandleIncomingDataMessage(
230       const mcs_proto::DataMessageStanza& data_message_stanza,
231       MessageData& message_data);
232 
233   // Fires OnMessageSendError event on the delegate of this calss, based on the
234   // details in |data_message_stanza| and |message_data|.
235   void HandleIncomingSendError(
236       const mcs_proto::DataMessageStanza& data_message_stanza,
237       MessageData& message_data);
238 
239   // Builder for the GCM internals (mcs client, etc.).
240   scoped_ptr<GCMInternalsBuilder> internals_builder_;
241 
242   // Recorder that logs GCM activities.
243   GCMStatsRecorderImpl recorder_;
244 
245   // State of the GCM Client Implementation.
246   State state_;
247 
248   GCMClient::Delegate* delegate_;
249 
250   // Device checkin info (android ID and security token used by device).
251   CheckinInfo device_checkin_info_;
252 
253   // Clock used for timing of retry logic. Passed in for testing. Owned by
254   // GCMClientImpl.
255   scoped_ptr<base::Clock> clock_;
256 
257   // Information about the chrome build.
258   // TODO(fgorski): Check if it can be passed in constructor and made const.
259   ChromeBuildInfo chrome_build_info_;
260 
261   // Persistent data store for keeping device credentials, messages and user to
262   // serial number mappings.
263   scoped_ptr<GCMStore> gcm_store_;
264 
265   scoped_refptr<net::HttpNetworkSession> network_session_;
266   net::BoundNetLog net_log_;
267   scoped_ptr<ConnectionFactory> connection_factory_;
268   scoped_refptr<net::URLRequestContextGetter> url_request_context_getter_;
269 
270   // Controls receiving and sending of packets and reliable message queueing.
271   scoped_ptr<MCSClient> mcs_client_;
272 
273   scoped_ptr<CheckinRequest> checkin_request_;
274 
275   // Cached registration info.
276   RegistrationInfoMap registrations_;
277 
278   // Currently pending registration requests. GCMClientImpl owns the
279   // RegistrationRequests.
280   PendingRegistrationRequests pending_registration_requests_;
281   STLValueDeleter<PendingRegistrationRequests>
282       pending_registration_requests_deleter_;
283 
284   // Currently pending unregistration requests. GCMClientImpl owns the
285   // UnregistrationRequests.
286   PendingUnregistrationRequests pending_unregistration_requests_;
287   STLValueDeleter<PendingUnregistrationRequests>
288       pending_unregistration_requests_deleter_;
289 
290   // G-services settings that were provided by MCS.
291   GServicesSettings gservices_settings_;
292 
293   // Time of the last successful checkin.
294   base::Time last_checkin_time_;
295 
296   // Factory for creating references when scheduling periodic checkin.
297   base::WeakPtrFactory<GCMClientImpl> periodic_checkin_ptr_factory_;
298 
299   // Factory for creating references in callbacks.
300   base::WeakPtrFactory<GCMClientImpl> weak_ptr_factory_;
301 
302   DISALLOW_COPY_AND_ASSIGN(GCMClientImpl);
303 };
304 
305 }  // namespace gcm
306 
307 #endif  // COMPONENTS_GCM_DRIVER_GCM_CLIENT_IMPL_H_
308