diff options
Diffstat (limited to 'chromium/components/gcm_driver/gcm_driver.h')
-rw-r--r-- | chromium/components/gcm_driver/gcm_driver.h | 395 |
1 files changed, 395 insertions, 0 deletions
diff --git a/chromium/components/gcm_driver/gcm_driver.h b/chromium/components/gcm_driver/gcm_driver.h new file mode 100644 index 00000000000..fbbf86d2064 --- /dev/null +++ b/chromium/components/gcm_driver/gcm_driver.h @@ -0,0 +1,395 @@ +// 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_DRIVER_H_ +#define COMPONENTS_GCM_DRIVER_GCM_DRIVER_H_ + +#include <map> +#include <string> +#include <vector> + +#include "base/callback.h" +#include "base/memory/ref_counted.h" +#include "base/memory/weak_ptr.h" +#include "base/threading/thread_checker.h" +#include "base/time/time.h" +#include "components/gcm_driver/common/gcm_message.h" +#include "components/gcm_driver/crypto/gcm_encryption_provider.h" +#include "components/gcm_driver/gcm_client.h" + +namespace base { +class FilePath; +class SequencedTaskRunner; +} // namespace base + +namespace gcm { + +class GCMAppHandler; +class GCMConnectionObserver; +enum class GCMDecryptionResult; +enum class GCMEncryptionResult; +struct AccountMapping; + +// Provides the InstanceID support via GCMDriver. +class InstanceIDHandler { + public: + using GetTokenCallback = base::OnceCallback<void(const std::string& token, + GCMClient::Result result)>; + using ValidateTokenCallback = base::OnceCallback<void(bool is_valid)>; + using DeleteTokenCallback = + base::OnceCallback<void(GCMClient::Result result)>; + using GetInstanceIDDataCallback = + base::OnceCallback<void(const std::string& instance_id, + const std::string& extra_data)>; + + InstanceIDHandler(); + + InstanceIDHandler(const InstanceIDHandler&) = delete; + InstanceIDHandler& operator=(const InstanceIDHandler&) = delete; + + virtual ~InstanceIDHandler(); + + // Token service. + virtual void GetToken(const std::string& app_id, + const std::string& authorized_entity, + const std::string& scope, + base::TimeDelta time_to_live, + GetTokenCallback callback) = 0; + virtual void ValidateToken(const std::string& app_id, + const std::string& authorized_entity, + const std::string& scope, + const std::string& token, + ValidateTokenCallback callback) = 0; + virtual void DeleteToken(const std::string& app_id, + const std::string& authorized_entity, + const std::string& scope, + DeleteTokenCallback callback) = 0; + void DeleteAllTokensForApp(const std::string& app_id, + DeleteTokenCallback callback); + + // Persistence support. + virtual void AddInstanceIDData(const std::string& app_id, + const std::string& instance_id, + const std::string& extra_data) = 0; + virtual void RemoveInstanceIDData(const std::string& app_id) = 0; + virtual void GetInstanceIDData(const std::string& app_id, + GetInstanceIDDataCallback callback) = 0; +}; + +// Bridge between GCM users in Chrome and the platform-specific implementation. +// Obtain instances of this object by using |GCMProfileServiceFactory|. +class GCMDriver { + public: + // Max number of sender IDs that can be passed to |Register| on desktop. + constexpr static size_t kMaxSenders = 100; + + using GCMAppHandlerMap = std::map<std::string, GCMAppHandler*>; + using RegisterCallback = + base::OnceCallback<void(const std::string& registration_id, + GCMClient::Result result)>; + using ValidateRegistrationCallback = base::OnceCallback<void(bool is_valid)>; + using UnregisterCallback = base::OnceCallback<void(GCMClient::Result result)>; + using SendCallback = base::OnceCallback<void(const std::string& message_id, + GCMClient::Result result)>; + using GetEncryptionInfoCallback = + base::OnceCallback<void(std::string p256dh, std::string auth_secret)>; + using EncryptMessageCallback = + base::OnceCallback<void(GCMEncryptionResult result, std::string message)>; + using DecryptMessageCallback = + base::OnceCallback<void(GCMDecryptionResult result, std::string message)>; + + using GetGCMStatisticsCallback = + base::OnceCallback<void(const GCMClient::GCMStatistics& stats)>; + using GCMStatisticsRecordingCallback = + base::RepeatingCallback<void(const GCMClient::GCMStatistics& stats)>; + + // Enumeration to be used with GetGCMStatistics() for indicating whether the + // existing logs should be cleared or kept. + enum ClearActivityLogs { CLEAR_LOGS, KEEP_LOGS }; + + GCMDriver( + const base::FilePath& store_path, + const scoped_refptr<base::SequencedTaskRunner>& blocking_task_runner); + + GCMDriver(const GCMDriver&) = delete; + GCMDriver& operator=(const GCMDriver&) = delete; + + virtual ~GCMDriver(); + + // Registers |sender_ids| for an app. *Use |InstanceID| instead in new code.* + // + // A registration ID will be returned by the GCM server. On Android, only a + // single sender ID is supported, but instead multiple simultaneous + // registrations are allowed. + // |app_id|: application ID. + // |sender_ids|: list of IDs of the servers allowed to send messages to the + // application. The IDs are assigned by the Google API Console. + // Max number of IDs is 1 on Android, |kMaxSenders| on desktop. + // |callback|: to be called once the asynchronous operation is done. + void Register(const std::string& app_id, + const std::vector<std::string>& sender_ids, + RegisterCallback callback); + + // Checks that the provided |sender_ids| and |registration_id| matches the + // stored registration info for |app_id|. + virtual void ValidateRegistration(const std::string& app_id, + const std::vector<std::string>& sender_ids, + const std::string& registration_id, + ValidateRegistrationCallback callback) = 0; + + // Unregisters all sender_ids for an app. Only works on non-Android. Will also + // remove any encryption keys associated with the |app_id|. + // |app_id|: application ID. + // |callback|: to be called once the asynchronous operation is done. + void Unregister(const std::string& app_id, UnregisterCallback callback); + + // Unregisters an (app_id, sender_id) pair from using GCM. Only works on + // Android. Will also remove any encryption keys associated with the |app_id|. + // TODO(jianli): Switch to using GCM's unsubscribe API. + // |app_id|: application ID. + // |sender_id|: the sender ID that was passed when registering. + // |callback|: to be called once the asynchronous operation is done. + void UnregisterWithSenderId(const std::string& app_id, + const std::string& sender_id, + UnregisterCallback callback); + + // Sends a message to a given receiver. + // |app_id|: application ID. + // |receiver_id|: registration ID of the receiver party. + // |message|: message to be sent. + // |callback|: to be called once the asynchronous operation is done. + void Send(const std::string& app_id, + const std::string& receiver_id, + const OutgoingMessage& message, + SendCallback callback); + + // Get the public encryption key and the authentication secret associated with + // |app_id|. If none have been associated with |app_id| yet, they will be + // created. The |callback| will be invoked when it is available. Only use with + // GCM registrations; use InstanceID::GetEncryptionInfo for InstanceID tokens. + virtual void GetEncryptionInfo(const std::string& app_id, + GetEncryptionInfoCallback callback); + + // Attempts to encrypt the |message| using draft-ietf-webpush-encryption-08 + // scheme using keys from internal key store. Either GetEncryptionInfo or + // InstanceID::GetEncryptionInfo must be called once for keys to be available. + // |callback| will be called asynchronously when |message| has been encrypted. + // A dispatchable message will be used in case of success, an empty message in + // case of failure. + virtual void EncryptMessage(const std::string& app_id, + const std::string& authorized_entity, + const std::string& p256dh, + const std::string& auth_secret, + const std::string& message, + EncryptMessageCallback callback); + + // Attempts to decrypt the |message|using draft-ietf-webpush-encryption-08 + // scheme using keys from internal key store. Either GetEncryptionInfo or + // InstanceID::GetEncryptionInfo must be called once for keys to be available. + // |callback| will be called asynchronously when |message| has been decrypted. + // A dispatchable message will be used in case of success, an empty message in + // case of failure. + // TODO(crbug/1045907): Decouple this from GCMDriver. + virtual void DecryptMessage(const std::string& app_id, + const std::string& authorized_entity, + const std::string& message, + DecryptMessageCallback callback); + + const GCMAppHandlerMap& app_handlers() const { return app_handlers_; } + + // This method must be called before destroying the GCMDriver. Once it has + // been called, no other GCMDriver methods may be used. + virtual void Shutdown(); + + // Called when the user signs in to or out of a GAIA account. + virtual void OnSignedIn() = 0; + virtual void OnSignedOut() = 0; + + // Adds a handler for a given app. + virtual void AddAppHandler(const std::string& app_id, GCMAppHandler* handler); + + // Remove the handler for a given app. + virtual void RemoveAppHandler(const std::string& app_id); + + // Returns the handler for the given app. May return a nullptr when no handler + // could be found for the |app_id|. + GCMAppHandler* GetAppHandler(const std::string& app_id); + + // Adds a connection state observer. + virtual void AddConnectionObserver(GCMConnectionObserver* observer) = 0; + + // Removes a connection state observer. + virtual void RemoveConnectionObserver(GCMConnectionObserver* observer) = 0; + + // For testing purpose. Always NULL on Android. + virtual GCMClient* GetGCMClientForTesting() const = 0; + + // Returns true if the service was started. + virtual bool IsStarted() const = 0; + + // Returns true if the gcm client has an open and active connection. + virtual bool IsConnected() const = 0; + + // Get GCM client internal states and statistics. The activity logs will be + // cleared before returning the stats when |clear_logs| is set to CLEAR_LOGS. + virtual void GetGCMStatistics(GetGCMStatisticsCallback callback, + ClearActivityLogs clear_logs) = 0; + + // Enables/disables GCM activity recording, and then returns the stats. + // |callback| will be called for new activity. + virtual void SetGCMRecording(const GCMStatisticsRecordingCallback& callback, + bool recording) = 0; + + // sets a list of signed in accounts with OAuth2 access tokens, when GCMDriver + // works in context of a signed in entity (e.g. browser profile where user is + // signed into sync). + // |account_tokens|: list of email addresses, account IDs and OAuth2 access + // tokens. + virtual void SetAccountTokens( + const std::vector<GCMClient::AccountTokenInfo>& account_tokens) = 0; + + // Updates the |account_mapping| information in persistent store. + virtual void UpdateAccountMapping(const AccountMapping& account_mapping) = 0; + + // Removes the account mapping information reated to |account_id| from + // persistent store. + virtual void RemoveAccountMapping(const CoreAccountId& account_id) = 0; + + // Getter and setter of last token fetch time. + virtual base::Time GetLastTokenFetchTime() = 0; + virtual void SetLastTokenFetchTime(const base::Time& time) = 0; + + // These methods must only be used by the InstanceID system. + // The InstanceIDHandler provides an implementation for the InstanceID system. + virtual InstanceIDHandler* GetInstanceIDHandlerInternal() = 0; + // Allows the InstanceID system to integrate with GCM encryption storage. + virtual GCMEncryptionProvider* GetEncryptionProviderInternal(); + + // Adds or removes a custom client requested heartbeat interval. If multiple + // components set that setting, the lowest setting will be used. If the + // setting is outside of GetMax/MinClientHeartbeatIntervalMs() it will be + // ignored. If a new setting is less than the currently used, the connection + // will be reset with the new heartbeat. Client that no longer require + // aggressive heartbeats, should remove their requested interval. Heartbeats + // set this way survive connection/Chrome restart. + // + // GCM Driver can decide to postpone the action until Client is properly + // initialized, hence this setting can be called at any time. + // + // Server can overwrite the setting to a different value. + // + // |scope| is used to identify the component that requests a custom interval + // to be set, and allows that component to later revoke the setting. + // |interval_ms| should be between 2 minues and 15 minues (28 minues on + // cellular networks). For details check + // GetMin/MaxClientHeartbeatItnervalMs() in HeartbeatManager. + virtual void AddHeartbeatInterval(const std::string& scope, + int interval_ms) = 0; + virtual void RemoveHeartbeatInterval(const std::string& scope) = 0; + + protected: + // Ensures that the GCM service starts (if necessary conditions are met). + virtual GCMClient::Result EnsureStarted(GCMClient::StartMode start_mode) = 0; + + // Platform-specific implementation of Register. + virtual void RegisterImpl(const std::string& app_id, + const std::vector<std::string>& sender_ids) = 0; + + // Platform-specific implementation of Unregister. + virtual void UnregisterImpl(const std::string& app_id) = 0; + + // Platform-specific implementation of UnregisterWithSenderId. + virtual void UnregisterWithSenderIdImpl(const std::string& app_id, + const std::string& sender_id); + + // Platform-specific implementation of Send. + virtual void SendImpl(const std::string& app_id, + const std::string& receiver_id, + const OutgoingMessage& message) = 0; + + // Platform-specific implementation of recording message decryption failures. + virtual void RecordDecryptionFailure(const std::string& app_id, + GCMDecryptionResult result) = 0; + + // Runs the Register callback. + void RegisterFinished(const std::string& app_id, + const std::string& registration_id, + GCMClient::Result result); + + // To be called when a registration for |app_id| has been unregistered, having + // |result| as the result of the unregistration. Will remove any encryption + // information associated with the |app_id| and then calls UnregisterFinished. + void RemoveEncryptionInfoAfterUnregister(const std::string& app_id, + GCMClient::Result result); + + // Runs the Unregister callback. + void UnregisterFinished(const std::string& app_id, GCMClient::Result result); + + // Runs the Send callback. + void SendFinished(const std::string& app_id, + const std::string& message_id, + GCMClient::Result result); + + bool HasRegisterCallback(const std::string& app_id); + + void ClearCallbacks(); + + // Dispatches the OnMessage event to the app handler associated with |app_id|. + // If |message| has been encrypted, it will be decrypted asynchronously and + // dispatched when the decryption operation was successful. Otherwise, the + // |message| will be dispatched immediately to the handler for |app_id|. + void DispatchMessage(const std::string& app_id, + const IncomingMessage& message); + + private: + // Common code shared by Unregister and UnregisterWithSenderId. + void UnregisterInternal(const std::string& app_id, + const std::string* sender_id, + UnregisterCallback callback); + + // Dispatches the OnMessage event to the app handler associated with |app_id| + // if |result| indicates that it is safe to do so, or will report a decryption + // failure for the |app_id| otherwise. + void DispatchMessageInternal(const std::string& app_id, + GCMDecryptionResult result, + IncomingMessage message); + + // Called after unregistration completes in order to trigger the pending + // registration. + void RegisterAfterUnregister( + const std::string& app_id, + const std::vector<std::string>& normalized_sender_ids, + UnregisterCallback unregister_callback, + GCMClient::Result result); + + void OnMessageEncrypted(EncryptMessageCallback callback, + GCMEncryptionResult result, + std::string message); + + void OnMessageDecrypted(DecryptMessageCallback callback, + GCMDecryptionResult result, + IncomingMessage message); + + // Callback map (from app_id to callback) for Register. + std::map<std::string, RegisterCallback> register_callbacks_; + + // Callback map (from app_id to callback) for Unregister. + std::map<std::string, UnregisterCallback> unregister_callbacks_; + + // Callback map (from <app_id, message_id> to callback) for Send. + std::map<std::pair<std::string, std::string>, SendCallback> send_callbacks_; + + // The encryption provider, used for key management and decryption of + // encrypted, incoming messages. + GCMEncryptionProvider encryption_provider_; + + // App handler map (from app_id to handler pointer). The handler is not owned. + GCMAppHandlerMap app_handlers_; + + base::WeakPtrFactory<GCMDriver> weak_ptr_factory_{this}; +}; + +} // namespace gcm + +#endif // COMPONENTS_GCM_DRIVER_GCM_DRIVER_H_ |