gcm_client_impl.h 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431
  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. #ifndef COMPONENTS_GCM_DRIVER_GCM_CLIENT_IMPL_H_
  5. #define COMPONENTS_GCM_DRIVER_GCM_CLIENT_IMPL_H_
  6. #include <stdint.h>
  7. #include <map>
  8. #include <memory>
  9. #include <set>
  10. #include <string>
  11. #include <utility>
  12. #include <vector>
  13. #include "base/compiler_specific.h"
  14. #include "base/memory/raw_ptr.h"
  15. #include "base/memory/ref_counted.h"
  16. #include "base/memory/weak_ptr.h"
  17. #include "base/time/time.h"
  18. #include "base/timer/timer.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 "mojo/public/cpp/bindings/pending_receiver.h"
  30. #include "net/http/http_status_code.h"
  31. #include "services/network/public/mojom/proxy_resolving_socket.mojom.h"
  32. class GURL;
  33. namespace base {
  34. class Clock;
  35. class Time;
  36. } // namespace base
  37. namespace mcs_proto {
  38. class DataMessageStanza;
  39. } // namespace mcs_proto
  40. namespace network {
  41. class NetworkConnectionTracker;
  42. class SharedURLLoaderFactory;
  43. } // namespace network
  44. namespace gcm {
  45. class CheckinRequest;
  46. class ConnectionFactory;
  47. class GCMClientImplTest;
  48. // Helper class for building GCM internals. Allows tests to inject fake versions
  49. // as necessary.
  50. class GCMInternalsBuilder {
  51. public:
  52. GCMInternalsBuilder();
  53. virtual ~GCMInternalsBuilder();
  54. virtual base::Clock* GetClock();
  55. virtual std::unique_ptr<MCSClient> BuildMCSClient(
  56. const std::string& version,
  57. base::Clock* clock,
  58. ConnectionFactory* connection_factory,
  59. GCMStore* gcm_store,
  60. scoped_refptr<base::SequencedTaskRunner> io_task_runner,
  61. GCMStatsRecorder* recorder);
  62. virtual std::unique_ptr<ConnectionFactory> BuildConnectionFactory(
  63. const std::vector<GURL>& endpoints,
  64. const net::BackoffEntry::Policy& backoff_policy,
  65. base::RepeatingCallback<void(
  66. mojo::PendingReceiver<network::mojom::ProxyResolvingSocketFactory>)>
  67. get_socket_factory_callback,
  68. scoped_refptr<base::SequencedTaskRunner> io_task_runner,
  69. GCMStatsRecorder* recorder,
  70. network::NetworkConnectionTracker* network_connection_tracker);
  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. // State representation of the GCMClient.
  81. // Any change made to this enum should have corresponding change in the
  82. // GetStateString(...) function.
  83. enum State {
  84. // Uninitialized.
  85. UNINITIALIZED,
  86. // Initialized,
  87. INITIALIZED,
  88. // GCM store loading is in progress.
  89. LOADING,
  90. // GCM store is loaded.
  91. LOADED,
  92. // Initial device checkin is in progress.
  93. INITIAL_DEVICE_CHECKIN,
  94. // Ready to accept requests.
  95. READY,
  96. };
  97. explicit GCMClientImpl(
  98. std::unique_ptr<GCMInternalsBuilder> internals_builder);
  99. GCMClientImpl(const GCMClientImpl&) = delete;
  100. GCMClientImpl& operator=(const GCMClientImpl&) = delete;
  101. ~GCMClientImpl() override;
  102. // GCMClient implementation.
  103. void Initialize(
  104. const ChromeBuildInfo& chrome_build_info,
  105. const base::FilePath& store_path,
  106. bool remove_account_mappings_with_email_key,
  107. const scoped_refptr<base::SequencedTaskRunner>& blocking_task_runner,
  108. scoped_refptr<base::SequencedTaskRunner> io_task_runner,
  109. base::RepeatingCallback<void(
  110. mojo::PendingReceiver<network::mojom::ProxyResolvingSocketFactory>)>
  111. get_socket_factory_callback,
  112. const scoped_refptr<network::SharedURLLoaderFactory>& url_loader_factory,
  113. network::NetworkConnectionTracker* network_connection_tracker,
  114. std::unique_ptr<Encryptor> encryptor,
  115. GCMClient::Delegate* delegate) override;
  116. void Start(StartMode start_mode) override;
  117. void Stop() override;
  118. void Register(scoped_refptr<RegistrationInfo> registration_info) override;
  119. bool ValidateRegistration(scoped_refptr<RegistrationInfo> registration_info,
  120. const std::string& registration_id) override;
  121. void Unregister(scoped_refptr<RegistrationInfo> registration_info) override;
  122. void Send(const std::string& app_id,
  123. const std::string& receiver_id,
  124. const OutgoingMessage& message) override;
  125. void RecordDecryptionFailure(const std::string& app_id,
  126. GCMDecryptionResult result) override;
  127. void SetRecording(bool recording) override;
  128. void ClearActivityLogs() override;
  129. GCMStatistics GetStatistics() const override;
  130. void SetAccountTokens(
  131. const std::vector<AccountTokenInfo>& account_tokens) override;
  132. void UpdateAccountMapping(const AccountMapping& account_mapping) override;
  133. void RemoveAccountMapping(const CoreAccountId& account_id) override;
  134. void SetLastTokenFetchTime(const base::Time& time) override;
  135. void UpdateHeartbeatTimer(
  136. std::unique_ptr<base::RetainingOneShotTimer> timer) override;
  137. void AddInstanceIDData(const std::string& app_id,
  138. const std::string& instance_id,
  139. const std::string& extra_data) override;
  140. void RemoveInstanceIDData(const std::string& app_id) override;
  141. void GetInstanceIDData(const std::string& app_id,
  142. std::string* instance_id,
  143. std::string* extra_data) override;
  144. void AddHeartbeatInterval(const std::string& scope, int interval_ms) override;
  145. void RemoveHeartbeatInterval(const std::string& scope) override;
  146. // GCMStatsRecorder::Delegate implemenation.
  147. void OnActivityRecorded() override;
  148. // ConnectionFactory::ConnectionListener implementation.
  149. void OnConnected(const GURL& current_server,
  150. const net::IPEndPoint& ip_endpoint) override;
  151. void OnDisconnected() override;
  152. private:
  153. // The check-in info for the device.
  154. // TODO(fgorski): Convert to a class with explicit getters/setters.
  155. struct CheckinInfo {
  156. CheckinInfo();
  157. ~CheckinInfo();
  158. bool IsValid() const { return android_id != 0 && secret != 0; }
  159. void SnapshotCheckinAccounts();
  160. void Reset();
  161. // Android ID of the device as assigned by the server.
  162. uint64_t android_id;
  163. // Security token of the device as assigned by the server.
  164. uint64_t secret;
  165. // True if accounts were already provided through SetAccountsForCheckin(),
  166. // or when |last_checkin_accounts| was loaded as empty.
  167. bool accounts_set;
  168. // Map of account email addresses and OAuth2 tokens that will be sent to the
  169. // checkin server on a next checkin.
  170. std::map<std::string, std::string> account_tokens;
  171. // As set of accounts last checkin was completed with.
  172. std::set<std::string> last_checkin_accounts;
  173. };
  174. // Reasons for resetting the GCM Store.
  175. // Note: this enum is recorded into a histogram. Do not change enum value
  176. // or order.
  177. enum ResetReason {
  178. LOAD_FAILURE, // GCM store failed to load, but the store exists.
  179. CHECKIN_REJECTED, // Checkin was rejected by server.
  180. RESET_REASON_COUNT,
  181. };
  182. // Collection of pending registration requests. Keys are RegistrationInfo
  183. // instance, while values are pending registration requests to obtain a
  184. // registration ID for requesting application.
  185. using PendingRegistrationRequests =
  186. std::map<scoped_refptr<RegistrationInfo>,
  187. std::unique_ptr<RegistrationRequest>,
  188. RegistrationInfoComparer>;
  189. // Collection of pending unregistration requests. Keys are RegistrationInfo
  190. // instance, while values are pending unregistration requests to disable the
  191. // registration ID currently assigned to the application.
  192. using PendingUnregistrationRequests =
  193. std::map<scoped_refptr<RegistrationInfo>,
  194. std::unique_ptr<UnregistrationRequest>,
  195. RegistrationInfoComparer>;
  196. friend class GCMClientImplTest;
  197. friend class GCMClientInstanceIDTest;
  198. // Returns text representation of the enum State.
  199. std::string GetStateString() const;
  200. // Callbacks for the MCSClient.
  201. // Receives messages and dispatches them to relevant user delegates.
  202. void OnMessageReceivedFromMCS(const gcm::MCSMessage& message);
  203. // Receives confirmation of sent messages or information about errors.
  204. void OnMessageSentToMCS(int64_t user_serial_number,
  205. const std::string& app_id,
  206. const std::string& message_id,
  207. MCSClient::MessageSendStatus status);
  208. // Receives information about mcs_client_ errors.
  209. void OnMCSError();
  210. // Runs after GCM Store load is done to trigger continuation of the
  211. // initialization.
  212. void OnLoadCompleted(std::unique_ptr<GCMStore::LoadResult> result);
  213. // Starts the GCM.
  214. void StartGCM();
  215. // Initializes mcs_client_, which handles the connection to MCS.
  216. void InitializeMCSClient();
  217. // Complets the first time device checkin.
  218. void OnFirstTimeDeviceCheckinCompleted(const CheckinInfo& checkin_info);
  219. // Starts a login on mcs_client_.
  220. void StartMCSLogin();
  221. // Resets the GCM store when it is corrupted.
  222. void ResetStore();
  223. // Sets state to ready. This will initiate the MCS login and notify the
  224. // delegates.
  225. void OnReady(const std::vector<AccountMapping>& account_mappings,
  226. const base::Time& last_token_fetch_time);
  227. // Starts a first time device checkin.
  228. void StartCheckin();
  229. // Completes the device checkin request by parsing the |checkin_response|.
  230. // Function also cleans up the pending checkin.
  231. void OnCheckinCompleted(
  232. net::HttpStatusCode response_code,
  233. const checkin_proto::AndroidCheckinResponse& checkin_response);
  234. // Callback passed to GCMStore::SetGServicesSettings.
  235. void SetGServicesSettingsCallback(bool success);
  236. // Schedules next periodic device checkin and makes sure there is at most one
  237. // pending checkin at a time. This function is meant to be called after a
  238. // successful checkin.
  239. void SchedulePeriodicCheckin();
  240. // Gets the time until next checkin.
  241. base::TimeDelta GetTimeToNextCheckin() const;
  242. // Callback for setting last checkin information in the |gcm_store_|.
  243. void SetLastCheckinInfoCallback(bool success);
  244. // Callback for persisting device credentials in the |gcm_store_|.
  245. void SetDeviceCredentialsCallback(bool success);
  246. // Callback for persisting registration info in the |gcm_store_|.
  247. void UpdateRegistrationCallback(bool success);
  248. // Callback for all store operations that do not try to recover, if write in
  249. // |gcm_store_| fails.
  250. void DefaultStoreCallback(bool success);
  251. // Callback for store operation where result does not matter.
  252. void IgnoreWriteResultCallback(const std::string& operation_suffix_for_uma,
  253. bool success);
  254. // Callback for destroying the GCM store.
  255. void DestroyStoreCallback(bool success);
  256. // Callback for resetting the GCM store. The store will be reloaded.
  257. void ResetStoreCallback(bool success);
  258. // Completes the registration request.
  259. void OnRegisterCompleted(scoped_refptr<RegistrationInfo> registration_info,
  260. RegistrationRequest::Status status,
  261. const std::string& registration_id);
  262. // Completes the unregistration request.
  263. void OnUnregisterCompleted(scoped_refptr<RegistrationInfo> registration_info,
  264. UnregistrationRequest::Status status);
  265. // Completes the GCM store destroy request.
  266. void OnGCMStoreDestroyed(bool success);
  267. // Handles incoming data message and dispatches it the delegate of this class.
  268. void HandleIncomingMessage(const gcm::MCSMessage& message);
  269. // Fires OnMessageReceived event on the delegate of this class, based on the
  270. // details in |data_message_stanza| and |message_data|.
  271. void HandleIncomingDataMessage(
  272. const std::string& app_id,
  273. bool was_subtype,
  274. const mcs_proto::DataMessageStanza& data_message_stanza,
  275. MessageData& message_data);
  276. // Fires OnMessagesDeleted event on the delegate of this class, based on the
  277. // details in |data_message_stanza| and |message_data|.
  278. void HandleIncomingDeletedMessages(
  279. const std::string& app_id,
  280. const mcs_proto::DataMessageStanza& data_message_stanza,
  281. MessageData& message_data);
  282. // Fires OnMessageSendError event on the delegate of this class, based on the
  283. // details in |data_message_stanza| and |message_data|.
  284. void HandleIncomingSendError(
  285. const std::string& app_id,
  286. const mcs_proto::DataMessageStanza& data_message_stanza,
  287. MessageData& message_data);
  288. // Is there any standalone app being registered for GCM?
  289. bool HasStandaloneRegisteredApp() const;
  290. // Destroys the store when it is not needed.
  291. void DestroyStoreWhenNotNeeded();
  292. // Reset all cahced values.
  293. void ResetCache();
  294. // Builder for the GCM internals (mcs client, etc.).
  295. std::unique_ptr<GCMInternalsBuilder> internals_builder_;
  296. // Recorder that logs GCM activities.
  297. GCMStatsRecorderImpl recorder_;
  298. // State of the GCM Client Implementation.
  299. State state_;
  300. raw_ptr<GCMClient::Delegate> delegate_;
  301. // Flag to indicate if the GCM should be delay started until it is actually
  302. // used in either of the following cases:
  303. // 1) The GCM store contains the registration records.
  304. // 2) GCM functionailities are explicitly called.
  305. StartMode start_mode_;
  306. // Device checkin info (android ID and security token used by device).
  307. CheckinInfo device_checkin_info_;
  308. // Clock used for timing of retry logic. Passed in for testing.
  309. raw_ptr<base::Clock> clock_;
  310. // Information about the chrome build.
  311. // TODO(fgorski): Check if it can be passed in constructor and made const.
  312. ChromeBuildInfo chrome_build_info_;
  313. // Persistent data store for keeping device credentials, messages and user to
  314. // serial number mappings.
  315. std::unique_ptr<GCMStore> gcm_store_;
  316. // Data loaded from the GCM store.
  317. std::unique_ptr<GCMStore::LoadResult> load_result_;
  318. // Tracks if the GCM store has been reset. This is used to prevent from
  319. // resetting and loading from the store again and again.
  320. bool gcm_store_reset_;
  321. std::unique_ptr<ConnectionFactory> connection_factory_;
  322. base::RepeatingCallback<void(
  323. mojo::PendingReceiver<network::mojom::ProxyResolvingSocketFactory>)>
  324. get_socket_factory_callback_;
  325. scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory_;
  326. raw_ptr<network::NetworkConnectionTracker> network_connection_tracker_;
  327. scoped_refptr<base::SequencedTaskRunner> io_task_runner_;
  328. // Controls receiving and sending of packets and reliable message queueing.
  329. // Must be destroyed before |network_session_|.
  330. std::unique_ptr<MCSClient> mcs_client_;
  331. std::unique_ptr<CheckinRequest> checkin_request_;
  332. // Cached registration info.
  333. RegistrationInfoMap registrations_;
  334. // Currently pending registration requests. GCMClientImpl owns the
  335. // RegistrationRequests.
  336. PendingRegistrationRequests pending_registration_requests_;
  337. // Currently pending unregistration requests. GCMClientImpl owns the
  338. // UnregistrationRequests.
  339. PendingUnregistrationRequests pending_unregistration_requests_;
  340. // G-services settings that were provided by MCS.
  341. GServicesSettings gservices_settings_;
  342. // Time of the last successful checkin.
  343. base::Time last_checkin_time_;
  344. // Cached instance ID data, key is app ID and value is pair of instance ID
  345. // and extra data.
  346. std::map<std::string, std::pair<std::string, std::string>> instance_id_data_;
  347. // Factory for creating references when scheduling periodic checkin.
  348. base::WeakPtrFactory<GCMClientImpl> periodic_checkin_ptr_factory_{this};
  349. // Factory for wiping out GCM store.
  350. base::WeakPtrFactory<GCMClientImpl> destroying_gcm_store_ptr_factory_{this};
  351. // Factory for creating references in callbacks.
  352. base::WeakPtrFactory<GCMClientImpl> weak_ptr_factory_{this};
  353. };
  354. } // namespace gcm
  355. #endif // COMPONENTS_GCM_DRIVER_GCM_CLIENT_IMPL_H_