123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431 |
- // Copyright 2014 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- #ifndef COMPONENTS_GCM_DRIVER_GCM_CLIENT_IMPL_H_
- #define COMPONENTS_GCM_DRIVER_GCM_CLIENT_IMPL_H_
- #include <stdint.h>
- #include <map>
- #include <memory>
- #include <set>
- #include <string>
- #include <utility>
- #include <vector>
- #include "base/compiler_specific.h"
- #include "base/memory/raw_ptr.h"
- #include "base/memory/ref_counted.h"
- #include "base/memory/weak_ptr.h"
- #include "base/time/time.h"
- #include "base/timer/timer.h"
- #include "components/gcm_driver/gcm_client.h"
- #include "components/gcm_driver/gcm_stats_recorder_impl.h"
- #include "google_apis/gcm/base/mcs_message.h"
- #include "google_apis/gcm/engine/gcm_store.h"
- #include "google_apis/gcm/engine/gservices_settings.h"
- #include "google_apis/gcm/engine/mcs_client.h"
- #include "google_apis/gcm/engine/registration_request.h"
- #include "google_apis/gcm/engine/unregistration_request.h"
- #include "google_apis/gcm/protocol/android_checkin.pb.h"
- #include "google_apis/gcm/protocol/checkin.pb.h"
- #include "mojo/public/cpp/bindings/pending_receiver.h"
- #include "net/http/http_status_code.h"
- #include "services/network/public/mojom/proxy_resolving_socket.mojom.h"
- class GURL;
- namespace base {
- class Clock;
- class Time;
- } // namespace base
- namespace mcs_proto {
- class DataMessageStanza;
- } // namespace mcs_proto
- namespace network {
- class NetworkConnectionTracker;
- class SharedURLLoaderFactory;
- } // namespace network
- namespace gcm {
- class CheckinRequest;
- class ConnectionFactory;
- class GCMClientImplTest;
- // Helper class for building GCM internals. Allows tests to inject fake versions
- // as necessary.
- class GCMInternalsBuilder {
- public:
- GCMInternalsBuilder();
- virtual ~GCMInternalsBuilder();
- virtual base::Clock* GetClock();
- virtual std::unique_ptr<MCSClient> BuildMCSClient(
- const std::string& version,
- base::Clock* clock,
- ConnectionFactory* connection_factory,
- GCMStore* gcm_store,
- scoped_refptr<base::SequencedTaskRunner> io_task_runner,
- GCMStatsRecorder* recorder);
- virtual std::unique_ptr<ConnectionFactory> BuildConnectionFactory(
- const std::vector<GURL>& endpoints,
- const net::BackoffEntry::Policy& backoff_policy,
- base::RepeatingCallback<void(
- mojo::PendingReceiver<network::mojom::ProxyResolvingSocketFactory>)>
- get_socket_factory_callback,
- scoped_refptr<base::SequencedTaskRunner> io_task_runner,
- GCMStatsRecorder* recorder,
- network::NetworkConnectionTracker* network_connection_tracker);
- };
- // Implements the GCM Client. It is used to coordinate MCS Client (communication
- // with MCS) and other pieces of GCM infrastructure like Registration and
- // Checkins. It also allows for registering user delegates that host
- // applications that send and receive messages.
- class GCMClientImpl
- : public GCMClient, public GCMStatsRecorder::Delegate,
- public ConnectionFactory::ConnectionListener {
- public:
- // State representation of the GCMClient.
- // Any change made to this enum should have corresponding change in the
- // GetStateString(...) function.
- enum State {
- // Uninitialized.
- UNINITIALIZED,
- // Initialized,
- INITIALIZED,
- // GCM store loading is in progress.
- LOADING,
- // GCM store is loaded.
- LOADED,
- // Initial device checkin is in progress.
- INITIAL_DEVICE_CHECKIN,
- // Ready to accept requests.
- READY,
- };
- explicit GCMClientImpl(
- std::unique_ptr<GCMInternalsBuilder> internals_builder);
- GCMClientImpl(const GCMClientImpl&) = delete;
- GCMClientImpl& operator=(const GCMClientImpl&) = delete;
- ~GCMClientImpl() override;
- // GCMClient implementation.
- void Initialize(
- const ChromeBuildInfo& chrome_build_info,
- const base::FilePath& store_path,
- bool remove_account_mappings_with_email_key,
- const scoped_refptr<base::SequencedTaskRunner>& blocking_task_runner,
- scoped_refptr<base::SequencedTaskRunner> io_task_runner,
- base::RepeatingCallback<void(
- mojo::PendingReceiver<network::mojom::ProxyResolvingSocketFactory>)>
- get_socket_factory_callback,
- const scoped_refptr<network::SharedURLLoaderFactory>& url_loader_factory,
- network::NetworkConnectionTracker* network_connection_tracker,
- std::unique_ptr<Encryptor> encryptor,
- GCMClient::Delegate* delegate) override;
- void Start(StartMode start_mode) override;
- void Stop() override;
- void Register(scoped_refptr<RegistrationInfo> registration_info) override;
- bool ValidateRegistration(scoped_refptr<RegistrationInfo> registration_info,
- const std::string& registration_id) override;
- void Unregister(scoped_refptr<RegistrationInfo> registration_info) override;
- void Send(const std::string& app_id,
- const std::string& receiver_id,
- const OutgoingMessage& message) override;
- void RecordDecryptionFailure(const std::string& app_id,
- GCMDecryptionResult result) override;
- void SetRecording(bool recording) override;
- void ClearActivityLogs() override;
- GCMStatistics GetStatistics() const override;
- void SetAccountTokens(
- const std::vector<AccountTokenInfo>& account_tokens) override;
- void UpdateAccountMapping(const AccountMapping& account_mapping) override;
- void RemoveAccountMapping(const CoreAccountId& account_id) override;
- void SetLastTokenFetchTime(const base::Time& time) override;
- void UpdateHeartbeatTimer(
- std::unique_ptr<base::RetainingOneShotTimer> timer) override;
- void AddInstanceIDData(const std::string& app_id,
- const std::string& instance_id,
- const std::string& extra_data) override;
- void RemoveInstanceIDData(const std::string& app_id) override;
- void GetInstanceIDData(const std::string& app_id,
- std::string* instance_id,
- std::string* extra_data) override;
- void AddHeartbeatInterval(const std::string& scope, int interval_ms) override;
- void RemoveHeartbeatInterval(const std::string& scope) override;
- // GCMStatsRecorder::Delegate implemenation.
- void OnActivityRecorded() override;
- // ConnectionFactory::ConnectionListener implementation.
- void OnConnected(const GURL& current_server,
- const net::IPEndPoint& ip_endpoint) override;
- void OnDisconnected() override;
- private:
- // The check-in info for the device.
- // TODO(fgorski): Convert to a class with explicit getters/setters.
- struct CheckinInfo {
- CheckinInfo();
- ~CheckinInfo();
- bool IsValid() const { return android_id != 0 && secret != 0; }
- void SnapshotCheckinAccounts();
- void Reset();
- // Android ID of the device as assigned by the server.
- uint64_t android_id;
- // Security token of the device as assigned by the server.
- uint64_t secret;
- // True if accounts were already provided through SetAccountsForCheckin(),
- // or when |last_checkin_accounts| was loaded as empty.
- bool accounts_set;
- // Map of account email addresses and OAuth2 tokens that will be sent to the
- // checkin server on a next checkin.
- std::map<std::string, std::string> account_tokens;
- // As set of accounts last checkin was completed with.
- std::set<std::string> last_checkin_accounts;
- };
- // Reasons for resetting the GCM Store.
- // Note: this enum is recorded into a histogram. Do not change enum value
- // or order.
- enum ResetReason {
- LOAD_FAILURE, // GCM store failed to load, but the store exists.
- CHECKIN_REJECTED, // Checkin was rejected by server.
- RESET_REASON_COUNT,
- };
- // Collection of pending registration requests. Keys are RegistrationInfo
- // instance, while values are pending registration requests to obtain a
- // registration ID for requesting application.
- using PendingRegistrationRequests =
- std::map<scoped_refptr<RegistrationInfo>,
- std::unique_ptr<RegistrationRequest>,
- RegistrationInfoComparer>;
- // Collection of pending unregistration requests. Keys are RegistrationInfo
- // instance, while values are pending unregistration requests to disable the
- // registration ID currently assigned to the application.
- using PendingUnregistrationRequests =
- std::map<scoped_refptr<RegistrationInfo>,
- std::unique_ptr<UnregistrationRequest>,
- RegistrationInfoComparer>;
- friend class GCMClientImplTest;
- friend class GCMClientInstanceIDTest;
- // Returns text representation of the enum State.
- std::string GetStateString() const;
- // Callbacks for the MCSClient.
- // Receives messages and dispatches them to relevant user delegates.
- void OnMessageReceivedFromMCS(const gcm::MCSMessage& message);
- // Receives confirmation of sent messages or information about errors.
- void OnMessageSentToMCS(int64_t user_serial_number,
- const std::string& app_id,
- const std::string& message_id,
- MCSClient::MessageSendStatus status);
- // Receives information about mcs_client_ errors.
- void OnMCSError();
- // Runs after GCM Store load is done to trigger continuation of the
- // initialization.
- void OnLoadCompleted(std::unique_ptr<GCMStore::LoadResult> result);
- // Starts the GCM.
- void StartGCM();
- // Initializes mcs_client_, which handles the connection to MCS.
- void InitializeMCSClient();
- // Complets the first time device checkin.
- void OnFirstTimeDeviceCheckinCompleted(const CheckinInfo& checkin_info);
- // Starts a login on mcs_client_.
- void StartMCSLogin();
- // Resets the GCM store when it is corrupted.
- void ResetStore();
- // Sets state to ready. This will initiate the MCS login and notify the
- // delegates.
- void OnReady(const std::vector<AccountMapping>& account_mappings,
- const base::Time& last_token_fetch_time);
- // Starts a first time device checkin.
- void StartCheckin();
- // Completes the device checkin request by parsing the |checkin_response|.
- // Function also cleans up the pending checkin.
- void OnCheckinCompleted(
- net::HttpStatusCode response_code,
- const checkin_proto::AndroidCheckinResponse& checkin_response);
- // Callback passed to GCMStore::SetGServicesSettings.
- void SetGServicesSettingsCallback(bool success);
- // Schedules next periodic device checkin and makes sure there is at most one
- // pending checkin at a time. This function is meant to be called after a
- // successful checkin.
- void SchedulePeriodicCheckin();
- // Gets the time until next checkin.
- base::TimeDelta GetTimeToNextCheckin() const;
- // Callback for setting last checkin information in the |gcm_store_|.
- void SetLastCheckinInfoCallback(bool success);
- // Callback for persisting device credentials in the |gcm_store_|.
- void SetDeviceCredentialsCallback(bool success);
- // Callback for persisting registration info in the |gcm_store_|.
- void UpdateRegistrationCallback(bool success);
- // Callback for all store operations that do not try to recover, if write in
- // |gcm_store_| fails.
- void DefaultStoreCallback(bool success);
- // Callback for store operation where result does not matter.
- void IgnoreWriteResultCallback(const std::string& operation_suffix_for_uma,
- bool success);
- // Callback for destroying the GCM store.
- void DestroyStoreCallback(bool success);
- // Callback for resetting the GCM store. The store will be reloaded.
- void ResetStoreCallback(bool success);
- // Completes the registration request.
- void OnRegisterCompleted(scoped_refptr<RegistrationInfo> registration_info,
- RegistrationRequest::Status status,
- const std::string& registration_id);
- // Completes the unregistration request.
- void OnUnregisterCompleted(scoped_refptr<RegistrationInfo> registration_info,
- UnregistrationRequest::Status status);
- // Completes the GCM store destroy request.
- void OnGCMStoreDestroyed(bool success);
- // Handles incoming data message and dispatches it the delegate of this class.
- void HandleIncomingMessage(const gcm::MCSMessage& message);
- // Fires OnMessageReceived event on the delegate of this class, based on the
- // details in |data_message_stanza| and |message_data|.
- void HandleIncomingDataMessage(
- const std::string& app_id,
- bool was_subtype,
- const mcs_proto::DataMessageStanza& data_message_stanza,
- MessageData& message_data);
- // Fires OnMessagesDeleted event on the delegate of this class, based on the
- // details in |data_message_stanza| and |message_data|.
- void HandleIncomingDeletedMessages(
- const std::string& app_id,
- const mcs_proto::DataMessageStanza& data_message_stanza,
- MessageData& message_data);
- // Fires OnMessageSendError event on the delegate of this class, based on the
- // details in |data_message_stanza| and |message_data|.
- void HandleIncomingSendError(
- const std::string& app_id,
- const mcs_proto::DataMessageStanza& data_message_stanza,
- MessageData& message_data);
- // Is there any standalone app being registered for GCM?
- bool HasStandaloneRegisteredApp() const;
- // Destroys the store when it is not needed.
- void DestroyStoreWhenNotNeeded();
- // Reset all cahced values.
- void ResetCache();
- // Builder for the GCM internals (mcs client, etc.).
- std::unique_ptr<GCMInternalsBuilder> internals_builder_;
- // Recorder that logs GCM activities.
- GCMStatsRecorderImpl recorder_;
- // State of the GCM Client Implementation.
- State state_;
- raw_ptr<GCMClient::Delegate> delegate_;
- // Flag to indicate if the GCM should be delay started until it is actually
- // used in either of the following cases:
- // 1) The GCM store contains the registration records.
- // 2) GCM functionailities are explicitly called.
- StartMode start_mode_;
- // Device checkin info (android ID and security token used by device).
- CheckinInfo device_checkin_info_;
- // Clock used for timing of retry logic. Passed in for testing.
- raw_ptr<base::Clock> clock_;
- // Information about the chrome build.
- // TODO(fgorski): Check if it can be passed in constructor and made const.
- ChromeBuildInfo chrome_build_info_;
- // Persistent data store for keeping device credentials, messages and user to
- // serial number mappings.
- std::unique_ptr<GCMStore> gcm_store_;
- // Data loaded from the GCM store.
- std::unique_ptr<GCMStore::LoadResult> load_result_;
- // Tracks if the GCM store has been reset. This is used to prevent from
- // resetting and loading from the store again and again.
- bool gcm_store_reset_;
- std::unique_ptr<ConnectionFactory> connection_factory_;
- base::RepeatingCallback<void(
- mojo::PendingReceiver<network::mojom::ProxyResolvingSocketFactory>)>
- get_socket_factory_callback_;
- scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory_;
- raw_ptr<network::NetworkConnectionTracker> network_connection_tracker_;
- scoped_refptr<base::SequencedTaskRunner> io_task_runner_;
- // Controls receiving and sending of packets and reliable message queueing.
- // Must be destroyed before |network_session_|.
- std::unique_ptr<MCSClient> mcs_client_;
- std::unique_ptr<CheckinRequest> checkin_request_;
- // Cached registration info.
- RegistrationInfoMap registrations_;
- // Currently pending registration requests. GCMClientImpl owns the
- // RegistrationRequests.
- PendingRegistrationRequests pending_registration_requests_;
- // Currently pending unregistration requests. GCMClientImpl owns the
- // UnregistrationRequests.
- PendingUnregistrationRequests pending_unregistration_requests_;
- // G-services settings that were provided by MCS.
- GServicesSettings gservices_settings_;
- // Time of the last successful checkin.
- base::Time last_checkin_time_;
- // Cached instance ID data, key is app ID and value is pair of instance ID
- // and extra data.
- std::map<std::string, std::pair<std::string, std::string>> instance_id_data_;
- // Factory for creating references when scheduling periodic checkin.
- base::WeakPtrFactory<GCMClientImpl> periodic_checkin_ptr_factory_{this};
- // Factory for wiping out GCM store.
- base::WeakPtrFactory<GCMClientImpl> destroying_gcm_store_ptr_factory_{this};
- // Factory for creating references in callbacks.
- base::WeakPtrFactory<GCMClientImpl> weak_ptr_factory_{this};
- };
- } // namespace gcm
- #endif // COMPONENTS_GCM_DRIVER_GCM_CLIENT_IMPL_H_
|