123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395 |
- // 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_
|