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_H_
6 #define COMPONENTS_GCM_DRIVER_GCM_CLIENT_H_
7 
8 #include <stdint.h>
9 
10 #include <map>
11 #include <memory>
12 #include <string>
13 #include <vector>
14 
15 #include "base/memory/scoped_refptr.h"
16 #include "components/gcm_driver/common/gcm_message.h"
17 #include "components/gcm_driver/gcm_activity.h"
18 #include "components/gcm_driver/registration_info.h"
19 #include "google_apis/gaia/core_account_id.h"
20 #include "mojo/public/cpp/bindings/pending_receiver.h"
21 #include "services/network/public/mojom/proxy_resolving_socket.mojom-forward.h"
22 
23 namespace base {
24 class FilePath;
25 class RetainingOneShotTimer;
26 class SequencedTaskRunner;
27 }  // namespace base
28 
29 namespace net {
30 class IPEndPoint;
31 }  // namespace net
32 
33 namespace network {
34 class NetworkConnectionTracker;
35 class SharedURLLoaderFactory;
36 }  // namespace network
37 
38 namespace gcm {
39 
40 struct AccountMapping;
41 class Encryptor;
42 enum class GCMDecryptionResult;
43 
44 // Interface that encapsulates the network communications with the Google Cloud
45 // Messaging server. This interface is not supposed to be thread-safe.
46 class GCMClient {
47  public:
48   // Controls how GCM is being started. At first, GCMClient will be initialized
49   // and GCM store will be loaded. Then GCM connection may or may not be
50   // initiated depending on this enum value.
51   enum StartMode {
52     // GCM should be started only when it is being actually used. If no
53     // registration record is found, GCM will not kick off.
54     DELAYED_START,
55     // GCM should be started immediately.
56     IMMEDIATE_START
57   };
58 
59   // Used for UMA. Can add enum values, but never renumber or delete and reuse.
60   enum Result {
61     // Successful operation.
62     SUCCESS,
63     // Invalid parameter.
64     INVALID_PARAMETER,
65     // GCM is disabled.
66     GCM_DISABLED,
67     // Previous asynchronous operation is still pending to finish. Certain
68     // operation, like register, is only allowed one at a time.
69     ASYNC_OPERATION_PENDING,
70     // Network socket error.
71     NETWORK_ERROR,
72     // Problem at the server.
73     SERVER_ERROR,
74     // Exceeded the specified TTL during message sending.
75     TTL_EXCEEDED,
76     // Other errors.
77     UNKNOWN_ERROR,
78 
79     // Used for UMA. Keep kMaxValue up to date and sync with histograms.xml.
80     kMaxValue = UNKNOWN_ERROR
81   };
82 
83   enum ChromePlatform {
84     PLATFORM_WIN,
85     PLATFORM_MAC,
86     PLATFORM_LINUX,
87     PLATFORM_CROS,
88     PLATFORM_IOS,
89     PLATFORM_ANDROID,
90     PLATFORM_BSD,
91     PLATFORM_UNSPECIFIED
92   };
93 
94   enum ChromeChannel {
95     CHANNEL_STABLE,
96     CHANNEL_BETA,
97     CHANNEL_DEV,
98     CHANNEL_CANARY,
99     CHANNEL_UNKNOWN
100   };
101 
102   struct ChromeBuildInfo {
103     ChromeBuildInfo();
104     ~ChromeBuildInfo();
105 
106     ChromePlatform platform;
107     ChromeChannel channel;
108     std::string version;
109     std::string product_category_for_subtypes;
110   };
111 
112   // Detailed information of the Send Error event.
113   struct SendErrorDetails {
114     SendErrorDetails();
115     SendErrorDetails(const SendErrorDetails& other);
116     ~SendErrorDetails();
117 
118     std::string message_id;
119     MessageData additional_data;
120     Result result;
121   };
122 
123   // Internal states and activity statistics of a GCM client.
124   struct GCMStatistics {
125    public:
126     GCMStatistics();
127     GCMStatistics(const GCMStatistics& other);
128     ~GCMStatistics();
129 
130     bool is_recording;
131     bool gcm_client_created;
132     std::string gcm_client_state;
133     bool connection_client_created;
134     std::string connection_state;
135     base::Time last_checkin;
136     base::Time next_checkin;
137     uint64_t android_id;
138     uint64_t android_secret;
139     std::vector<std::string> registered_app_ids;
140     int send_queue_size;
141     int resend_queue_size;
142 
143     RecordedActivities recorded_activities;
144   };
145 
146   // Information about account.
147   struct AccountTokenInfo {
148     CoreAccountId account_id;
149     std::string email;
150     std::string access_token;
151   };
152 
153   // A delegate interface that allows the GCMClient instance to interact with
154   // its caller, i.e. notifying asynchronous event.
155   class Delegate {
156    public:
157     // Called when the registration completed successfully or an error occurs.
158     // |registration_info|: the specific information required for the
159     //                      registration.
160     // |registration_id|: non-empty if the registration completed successfully.
161     // |result|: the type of the error if an error occured, success otherwise.
162     virtual void OnRegisterFinished(
163         scoped_refptr<RegistrationInfo> registration_info,
164         const std::string& registration_id,
165         Result result) = 0;
166 
167     // Called when the unregistration completed.
168     // |registration_info|: the specific information required for the
169     //                      registration.
170     // |result|: result of the unregistration.
171     virtual void OnUnregisterFinished(
172         scoped_refptr<RegistrationInfo> registration_info,
173         GCMClient::Result result) = 0;
174 
175     // Called when the message is scheduled to send successfully or an error
176     // occurs.
177     // |app_id|: application ID.
178     // |message_id|: ID of the message being sent.
179     // |result|: the type of the error if an error occured, success otherwise.
180     virtual void OnSendFinished(const std::string& app_id,
181                                 const std::string& message_id,
182                                 Result result) = 0;
183 
184     // Called when a message has been received.
185     // |app_id|: application ID.
186     // |message|: message received.
187     virtual void OnMessageReceived(const std::string& app_id,
188                                    const IncomingMessage& message) = 0;
189 
190     // Called when some messages have been deleted from the server.
191     // |app_id|: application ID.
192     virtual void OnMessagesDeleted(const std::string& app_id) = 0;
193 
194     // Called when a message failed to send to the server.
195     // |app_id|: application ID.
196     // |send_error_detials|: Details of the send error event, like mesasge ID.
197     virtual void OnMessageSendError(
198         const std::string& app_id,
199         const SendErrorDetails& send_error_details) = 0;
200 
201     // Called when a message was acknowledged by the GCM server.
202     // |app_id|: application ID.
203     // |message_id|: ID of the acknowledged message.
204     virtual void OnSendAcknowledged(const std::string& app_id,
205                                     const std::string& message_id) = 0;
206 
207     // Called when the GCM becomes ready. To get to this state, GCMClient
208     // finished loading from the GCM store and retrieved the device check-in
209     // from the server if it hadn't yet.
210     // |account_mappings|: a persisted list of accounts mapped to this GCM
211     //                     client.
212     // |last_token_fetch_time|: time of a last successful token fetch.
213     virtual void OnGCMReady(const std::vector<AccountMapping>& account_mappings,
214                             const base::Time& last_token_fetch_time) = 0;
215 
216     // Called when activities are being recorded and a new activity has just
217     // been recorded.
218     virtual void OnActivityRecorded() = 0;
219 
220     // Called when a new connection is established and a successful handshake
221     // has been performed.
222     virtual void OnConnected(const net::IPEndPoint& ip_endpoint) = 0;
223 
224     // Called when the connection is interrupted.
225     virtual void OnDisconnected() = 0;
226 
227     // Called when the GCM store is reset (e.g. due to corruption), which
228     // changes the device ID, invalidating all prior registrations.
229     virtual void OnStoreReset() = 0;
230   };
231 
232   GCMClient();
233   virtual ~GCMClient();
234 
235   // Begins initialization of the GCM Client. This will not trigger a
236   // connection. Must be called on |io_task_runner|.
237   // |chrome_build_info|: chrome info, i.e., version, channel and etc.
238   // |store_path|: path to the GCM store.
239   // |remove_account_mappings_with_email_key|: Whether account mappings having
240   //     email as account key should be removed while loading. Required
241   //     during the migration of account identifier from email to Gaia ID.
242   // |blocking_task_runner|: for running blocking file tasks.
243   // |io_task_runner|: for running IO tasks. When provided, it could be a
244   //     wrapper on top of base::ThreadTaskRunnerHandle::Get() to provide power
245   //     management featueres so that a delayed task posted to it can wake the
246   //     system up from sleep to perform the task.
247   // |get_socket_factory_callback|: a callback that can accept a receiver for a
248   //     network::mojom::ProxyResolvingSocketFactory. It needs to be safe to
249   //     run on any thread.
250   // |delegate|: the delegate whose methods will be called asynchronously in
251   //     response to events and messages.
252   virtual void Initialize(
253       const ChromeBuildInfo& chrome_build_info,
254       const base::FilePath& store_path,
255       bool remove_account_mappings_with_email_key,
256       const scoped_refptr<base::SequencedTaskRunner>& blocking_task_runner,
257       scoped_refptr<base::SequencedTaskRunner> io_task_runner,
258       base::RepeatingCallback<void(
259           mojo::PendingReceiver<network::mojom::ProxyResolvingSocketFactory>)>
260           get_socket_factory_callback,
261       const scoped_refptr<network::SharedURLLoaderFactory>& url_loader_factory,
262       network::NetworkConnectionTracker* network_connection_tracker_,
263       std::unique_ptr<Encryptor> encryptor,
264       Delegate* delegate) = 0;
265 
266   // This will initiate the GCM connection only if |start_mode| means to start
267   // the GCM immediately or the GCM registration records are found in the store.
268   // Note that it is OK to call Start multiple times and the implementation
269   // should handle it gracefully.
270   virtual void Start(StartMode start_mode) = 0;
271 
272   // Stops using the GCM service. This will not erase the persisted data.
273   virtual void Stop() = 0;
274 
275   // Registers with the server to access the provided service.
276   // Delegate::OnRegisterFinished will be called asynchronously upon completion.
277   // |registration_info|: the specific information required for the
278   //                      registration. For GCM, it will contain app id and
279   //                      sender IDs. For InstanceID, it will contain app_id,
280   //                      authorized entity and scope.
281   virtual void Register(scoped_refptr<RegistrationInfo> registration_info) = 0;
282 
283   // Checks that the provided |registration_id| (aka token for Instance ID
284   // registrations) matches the stored registration info. Also checks sender IDs
285   // match for GCM registrations.
286   virtual bool ValidateRegistration(
287       scoped_refptr<RegistrationInfo> registration_info,
288       const std::string& registration_id) = 0;
289 
290   // Unregisters from the server to stop accessing the provided service.
291   // Delegate::OnUnregisterFinished will be called asynchronously upon
292   // completion.
293   // |registration_info|: the specific information required for the
294   //                      registration. For GCM, it will contain app id (sender
295   //                      IDs can be ingored). For InstanceID, it will contain
296   //                      app id, authorized entity and scope.
297   virtual void Unregister(
298       scoped_refptr<RegistrationInfo> registration_info) = 0;
299 
300   // Sends a message to a given receiver. Delegate::OnSendFinished will be
301   // called asynchronously upon completion.
302   // |app_id|: application ID.
303   // |receiver_id|: registration ID of the receiver party.
304   // |message|: message to be sent.
305   virtual void Send(const std::string& app_id,
306                     const std::string& receiver_id,
307                     const OutgoingMessage& message) = 0;
308 
309   // Records a decryption failure due to |result| for the |app_id|.
310   virtual void RecordDecryptionFailure(const std::string& app_id,
311                                        GCMDecryptionResult result) = 0;
312 
313   // Enables or disables internal activity recording.
314   virtual void SetRecording(bool recording) = 0;
315 
316   // Clear all recorded GCM activity logs.
317   virtual void ClearActivityLogs() = 0;
318 
319   // Gets internal states and statistics.
320   virtual GCMStatistics GetStatistics() const = 0;
321 
322   // Sets a list of accounts with OAuth2 tokens for the next checkin.
323   // |account_tokens|: list of email addresses, account IDs and OAuth2 access
324   //                   tokens.
325   virtual void SetAccountTokens(
326       const std::vector<AccountTokenInfo>& account_tokens) = 0;
327 
328   // Persists the |account_mapping| in the store.
329   virtual void UpdateAccountMapping(const AccountMapping& account_mapping) = 0;
330 
331   // Removes the account mapping related to |account_id| from the persistent
332   // store.
333   virtual void RemoveAccountMapping(const CoreAccountId& account_id) = 0;
334 
335   // Sets last token fetch time in persistent store.
336   virtual void SetLastTokenFetchTime(const base::Time& time) = 0;
337 
338   // Updates the timer used by the HeartbeatManager for sending heartbeats.
339   virtual void UpdateHeartbeatTimer(
340       std::unique_ptr<base::RetainingOneShotTimer> timer) = 0;
341 
342   // Adds the Instance ID data for a specific app to the persistent store.
343   virtual void AddInstanceIDData(const std::string& app_id,
344                                  const std::string& instance_id,
345                                  const std::string& extra_data) = 0;
346 
347   // Removes the Instance ID data for a specific app from the persistent store.
348   virtual void RemoveInstanceIDData(const std::string& app_id) = 0;
349 
350   // Retrieves the Instance ID data for a specific app from the persistent
351   // store.
352   virtual void GetInstanceIDData(const std::string& app_id,
353                                  std::string* instance_id,
354                                  std::string* extra_data) = 0;
355 
356   // Gets and sets custom heartbeat interval for the MCS connection.
357   // |scope| is used to identify the component that requests a custom interval
358   // to be set, and allows that component to later revoke the setting. It should
359   // be unique.
360   virtual void AddHeartbeatInterval(const std::string& scope,
361                                     int interval_ms) = 0;
362   virtual void RemoveHeartbeatInterval(const std::string& scope) = 0;
363 };
364 
365 }  // namespace gcm
366 
367 #endif  // COMPONENTS_GCM_DRIVER_GCM_CLIENT_H_
368