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_DRIVER_H_ 6 #define COMPONENTS_GCM_DRIVER_GCM_DRIVER_H_ 7 8 #include <map> 9 #include <string> 10 #include <vector> 11 12 #include "base/callback.h" 13 #include "base/macros.h" 14 #include "base/memory/ref_counted.h" 15 #include "base/memory/weak_ptr.h" 16 #include "base/threading/thread_checker.h" 17 #include "base/time/time.h" 18 #include "components/gcm_driver/common/gcm_message.h" 19 #include "components/gcm_driver/crypto/gcm_encryption_provider.h" 20 #include "components/gcm_driver/gcm_client.h" 21 22 namespace base { 23 class FilePath; 24 class SequencedTaskRunner; 25 } // namespace base 26 27 namespace gcm { 28 29 class GCMAppHandler; 30 class GCMConnectionObserver; 31 enum class GCMDecryptionResult; 32 enum class GCMEncryptionResult; 33 struct AccountMapping; 34 35 // Provides the InstanceID support via GCMDriver. 36 class InstanceIDHandler { 37 public: 38 using GetTokenCallback = base::OnceCallback<void(const std::string& token, 39 GCMClient::Result result)>; 40 using ValidateTokenCallback = base::OnceCallback<void(bool is_valid)>; 41 using DeleteTokenCallback = 42 base::OnceCallback<void(GCMClient::Result result)>; 43 using GetInstanceIDDataCallback = 44 base::OnceCallback<void(const std::string& instance_id, 45 const std::string& extra_data)>; 46 47 InstanceIDHandler(); 48 virtual ~InstanceIDHandler(); 49 50 // Token service. 51 virtual void GetToken(const std::string& app_id, 52 const std::string& authorized_entity, 53 const std::string& scope, 54 base::TimeDelta time_to_live, 55 const std::map<std::string, std::string>& options, 56 GetTokenCallback callback) = 0; 57 virtual void ValidateToken(const std::string& app_id, 58 const std::string& authorized_entity, 59 const std::string& scope, 60 const std::string& token, 61 ValidateTokenCallback callback) = 0; 62 virtual void DeleteToken(const std::string& app_id, 63 const std::string& authorized_entity, 64 const std::string& scope, 65 DeleteTokenCallback callback) = 0; 66 void DeleteAllTokensForApp(const std::string& app_id, 67 DeleteTokenCallback callback); 68 69 // Persistence support. 70 virtual void AddInstanceIDData(const std::string& app_id, 71 const std::string& instance_id, 72 const std::string& extra_data) = 0; 73 virtual void RemoveInstanceIDData(const std::string& app_id) = 0; 74 virtual void GetInstanceIDData(const std::string& app_id, 75 GetInstanceIDDataCallback callback) = 0; 76 77 private: 78 DISALLOW_COPY_AND_ASSIGN(InstanceIDHandler); 79 }; 80 81 // Bridge between GCM users in Chrome and the platform-specific implementation. 82 // Obtain instances of this object by using |GCMProfileServiceFactory|. 83 class GCMDriver { 84 public: 85 // Max number of sender IDs that can be passed to |Register| on desktop. 86 constexpr static size_t kMaxSenders = 100; 87 88 using GCMAppHandlerMap = std::map<std::string, GCMAppHandler*>; 89 using RegisterCallback = 90 base::OnceCallback<void(const std::string& registration_id, 91 GCMClient::Result result)>; 92 using ValidateRegistrationCallback = base::OnceCallback<void(bool is_valid)>; 93 using UnregisterCallback = base::OnceCallback<void(GCMClient::Result result)>; 94 using SendCallback = base::OnceCallback<void(const std::string& message_id, 95 GCMClient::Result result)>; 96 using GetEncryptionInfoCallback = 97 base::OnceCallback<void(std::string p256dh, std::string auth_secret)>; 98 using EncryptMessageCallback = 99 base::OnceCallback<void(GCMEncryptionResult result, std::string message)>; 100 using DecryptMessageCallback = 101 base::OnceCallback<void(GCMDecryptionResult result, std::string message)>; 102 103 using GetGCMStatisticsCallback = 104 base::OnceCallback<void(const GCMClient::GCMStatistics& stats)>; 105 using GCMStatisticsRecordingCallback = 106 base::RepeatingCallback<void(const GCMClient::GCMStatistics& stats)>; 107 108 // Enumeration to be used with GetGCMStatistics() for indicating whether the 109 // existing logs should be cleared or kept. 110 enum ClearActivityLogs { CLEAR_LOGS, KEEP_LOGS }; 111 112 GCMDriver( 113 const base::FilePath& store_path, 114 const scoped_refptr<base::SequencedTaskRunner>& blocking_task_runner); 115 virtual ~GCMDriver(); 116 117 // Registers |sender_ids| for an app. *Use |InstanceID| instead in new code.* 118 // 119 // A registration ID will be returned by the GCM server. On Android, only a 120 // single sender ID is supported, but instead multiple simultaneous 121 // registrations are allowed. 122 // |app_id|: application ID. 123 // |sender_ids|: list of IDs of the servers allowed to send messages to the 124 // application. The IDs are assigned by the Google API Console. 125 // Max number of IDs is 1 on Android, |kMaxSenders| on desktop. 126 // |callback|: to be called once the asynchronous operation is done. 127 void Register(const std::string& app_id, 128 const std::vector<std::string>& sender_ids, 129 RegisterCallback callback); 130 131 // Checks that the provided |sender_ids| and |registration_id| matches the 132 // stored registration info for |app_id|. 133 virtual void ValidateRegistration(const std::string& app_id, 134 const std::vector<std::string>& sender_ids, 135 const std::string& registration_id, 136 ValidateRegistrationCallback callback) = 0; 137 138 // Unregisters all sender_ids for an app. Only works on non-Android. Will also 139 // remove any encryption keys associated with the |app_id|. 140 // |app_id|: application ID. 141 // |callback|: to be called once the asynchronous operation is done. 142 void Unregister(const std::string& app_id, UnregisterCallback callback); 143 144 // Unregisters an (app_id, sender_id) pair from using GCM. Only works on 145 // Android. Will also remove any encryption keys associated with the |app_id|. 146 // TODO(jianli): Switch to using GCM's unsubscribe API. 147 // |app_id|: application ID. 148 // |sender_id|: the sender ID that was passed when registering. 149 // |callback|: to be called once the asynchronous operation is done. 150 void UnregisterWithSenderId(const std::string& app_id, 151 const std::string& sender_id, 152 UnregisterCallback callback); 153 154 // Sends a message to a given receiver. 155 // |app_id|: application ID. 156 // |receiver_id|: registration ID of the receiver party. 157 // |message|: message to be sent. 158 // |callback|: to be called once the asynchronous operation is done. 159 void Send(const std::string& app_id, 160 const std::string& receiver_id, 161 const OutgoingMessage& message, 162 SendCallback callback); 163 164 // Get the public encryption key and the authentication secret associated with 165 // |app_id|. If none have been associated with |app_id| yet, they will be 166 // created. The |callback| will be invoked when it is available. Only use with 167 // GCM registrations; use InstanceID::GetEncryptionInfo for InstanceID tokens. 168 virtual void GetEncryptionInfo(const std::string& app_id, 169 GetEncryptionInfoCallback callback); 170 171 // Attempts to encrypt the |message| using draft-ietf-webpush-encryption-08 172 // scheme using keys from internal key store. Either GetEncryptionInfo or 173 // InstanceID::GetEncryptionInfo must be called once for keys to be available. 174 // |callback| will be called asynchronously when |message| has been encrypted. 175 // A dispatchable message will be used in case of success, an empty message in 176 // case of failure. 177 virtual void EncryptMessage(const std::string& app_id, 178 const std::string& authorized_entity, 179 const std::string& p256dh, 180 const std::string& auth_secret, 181 const std::string& message, 182 EncryptMessageCallback callback); 183 184 // Attempts to decrypt the |message|using draft-ietf-webpush-encryption-08 185 // scheme using keys from internal key store. Either GetEncryptionInfo or 186 // InstanceID::GetEncryptionInfo must be called once for keys to be available. 187 // |callback| will be called asynchronously when |message| has been decrypted. 188 // A dispatchable message will be used in case of success, an empty message in 189 // case of failure. 190 // TODO(crbug/1045907): Decouple this from GCMDriver. 191 virtual void DecryptMessage(const std::string& app_id, 192 const std::string& authorized_entity, 193 const std::string& message, 194 DecryptMessageCallback callback); 195 app_handlers()196 const GCMAppHandlerMap& app_handlers() const { return app_handlers_; } 197 198 // This method must be called before destroying the GCMDriver. Once it has 199 // been called, no other GCMDriver methods may be used. 200 virtual void Shutdown(); 201 202 // Called when the user signs in to or out of a GAIA account. 203 virtual void OnSignedIn() = 0; 204 virtual void OnSignedOut() = 0; 205 206 // Adds a handler for a given app. 207 virtual void AddAppHandler(const std::string& app_id, GCMAppHandler* handler); 208 209 // Remove the handler for a given app. 210 virtual void RemoveAppHandler(const std::string& app_id); 211 212 // Returns the handler for the given app. May return a nullptr when no handler 213 // could be found for the |app_id|. 214 GCMAppHandler* GetAppHandler(const std::string& app_id); 215 216 // Adds a connection state observer. 217 virtual void AddConnectionObserver(GCMConnectionObserver* observer) = 0; 218 219 // Removes a connection state observer. 220 virtual void RemoveConnectionObserver(GCMConnectionObserver* observer) = 0; 221 222 // For testing purpose. Always NULL on Android. 223 virtual GCMClient* GetGCMClientForTesting() const = 0; 224 225 // Returns true if the service was started. 226 virtual bool IsStarted() const = 0; 227 228 // Returns true if the gcm client has an open and active connection. 229 virtual bool IsConnected() const = 0; 230 231 // Get GCM client internal states and statistics. The activity logs will be 232 // cleared before returning the stats when |clear_logs| is set to CLEAR_LOGS. 233 virtual void GetGCMStatistics(GetGCMStatisticsCallback callback, 234 ClearActivityLogs clear_logs) = 0; 235 236 // Enables/disables GCM activity recording, and then returns the stats. 237 // |callback| will be called for new activity. 238 virtual void SetGCMRecording(const GCMStatisticsRecordingCallback& callback, 239 bool recording) = 0; 240 241 // sets a list of signed in accounts with OAuth2 access tokens, when GCMDriver 242 // works in context of a signed in entity (e.g. browser profile where user is 243 // signed into sync). 244 // |account_tokens|: list of email addresses, account IDs and OAuth2 access 245 // tokens. 246 virtual void SetAccountTokens( 247 const std::vector<GCMClient::AccountTokenInfo>& account_tokens) = 0; 248 249 // Updates the |account_mapping| information in persistent store. 250 virtual void UpdateAccountMapping(const AccountMapping& account_mapping) = 0; 251 252 // Removes the account mapping information reated to |account_id| from 253 // persistent store. 254 virtual void RemoveAccountMapping(const CoreAccountId& account_id) = 0; 255 256 // Getter and setter of last token fetch time. 257 virtual base::Time GetLastTokenFetchTime() = 0; 258 virtual void SetLastTokenFetchTime(const base::Time& time) = 0; 259 260 // Sets whether or not GCM should try to wake the system from suspend in order 261 // to send a heartbeat message. 262 virtual void WakeFromSuspendForHeartbeat(bool wake) = 0; 263 264 // These methods must only be used by the InstanceID system. 265 // The InstanceIDHandler provides an implementation for the InstanceID system. 266 virtual InstanceIDHandler* GetInstanceIDHandlerInternal() = 0; 267 // Allows the InstanceID system to integrate with GCM encryption storage. 268 virtual GCMEncryptionProvider* GetEncryptionProviderInternal(); 269 270 // Adds or removes a custom client requested heartbeat interval. If multiple 271 // components set that setting, the lowest setting will be used. If the 272 // setting is outside of GetMax/MinClientHeartbeatIntervalMs() it will be 273 // ignored. If a new setting is less than the currently used, the connection 274 // will be reset with the new heartbeat. Client that no longer require 275 // aggressive heartbeats, should remove their requested interval. Heartbeats 276 // set this way survive connection/Chrome restart. 277 // 278 // GCM Driver can decide to postpone the action until Client is properly 279 // initialized, hence this setting can be called at any time. 280 // 281 // Server can overwrite the setting to a different value. 282 // 283 // |scope| is used to identify the component that requests a custom interval 284 // to be set, and allows that component to later revoke the setting. 285 // |interval_ms| should be between 2 minues and 15 minues (28 minues on 286 // cellular networks). For details check 287 // GetMin/MaxClientHeartbeatItnervalMs() in HeartbeatManager. 288 virtual void AddHeartbeatInterval(const std::string& scope, 289 int interval_ms) = 0; 290 virtual void RemoveHeartbeatInterval(const std::string& scope) = 0; 291 292 protected: 293 // Ensures that the GCM service starts (if necessary conditions are met). 294 virtual GCMClient::Result EnsureStarted(GCMClient::StartMode start_mode) = 0; 295 296 // Platform-specific implementation of Register. 297 virtual void RegisterImpl(const std::string& app_id, 298 const std::vector<std::string>& sender_ids) = 0; 299 300 // Platform-specific implementation of Unregister. 301 virtual void UnregisterImpl(const std::string& app_id) = 0; 302 303 // Platform-specific implementation of UnregisterWithSenderId. 304 virtual void UnregisterWithSenderIdImpl(const std::string& app_id, 305 const std::string& sender_id); 306 307 // Platform-specific implementation of Send. 308 virtual void SendImpl(const std::string& app_id, 309 const std::string& receiver_id, 310 const OutgoingMessage& message) = 0; 311 312 // Platform-specific implementation of recording message decryption failures. 313 virtual void RecordDecryptionFailure(const std::string& app_id, 314 GCMDecryptionResult result) = 0; 315 316 // Runs the Register callback. 317 void RegisterFinished(const std::string& app_id, 318 const std::string& registration_id, 319 GCMClient::Result result); 320 321 // To be called when a registration for |app_id| has been unregistered, having 322 // |result| as the result of the unregistration. Will remove any encryption 323 // information associated with the |app_id| and then calls UnregisterFinished. 324 void RemoveEncryptionInfoAfterUnregister(const std::string& app_id, 325 GCMClient::Result result); 326 327 // Runs the Unregister callback. 328 void UnregisterFinished(const std::string& app_id, GCMClient::Result result); 329 330 // Runs the Send callback. 331 void SendFinished(const std::string& app_id, 332 const std::string& message_id, 333 GCMClient::Result result); 334 335 bool HasRegisterCallback(const std::string& app_id); 336 337 void ClearCallbacks(); 338 339 // Dispatches the OnMessage event to the app handler associated with |app_id|. 340 // If |message| has been encrypted, it will be decrypted asynchronously and 341 // dispatched when the decryption operation was successful. Otherwise, the 342 // |message| will be dispatched immediately to the handler for |app_id|. 343 void DispatchMessage(const std::string& app_id, 344 const IncomingMessage& message); 345 346 private: 347 // Common code shared by Unregister and UnregisterWithSenderId. 348 void UnregisterInternal(const std::string& app_id, 349 const std::string* sender_id, 350 UnregisterCallback callback); 351 352 // Dispatches the OnMessage event to the app handler associated with |app_id| 353 // if |result| indicates that it is safe to do so, or will report a decryption 354 // failure for the |app_id| otherwise. 355 void DispatchMessageInternal(const std::string& app_id, 356 GCMDecryptionResult result, 357 IncomingMessage message); 358 359 // Called after unregistration completes in order to trigger the pending 360 // registration. 361 void RegisterAfterUnregister( 362 const std::string& app_id, 363 const std::vector<std::string>& normalized_sender_ids, 364 UnregisterCallback unregister_callback, 365 GCMClient::Result result); 366 367 void OnMessageEncrypted(EncryptMessageCallback callback, 368 GCMEncryptionResult result, 369 std::string message); 370 371 void OnMessageDecrypted(DecryptMessageCallback callback, 372 GCMDecryptionResult result, 373 IncomingMessage message); 374 375 // Callback map (from app_id to callback) for Register. 376 std::map<std::string, RegisterCallback> register_callbacks_; 377 378 // Callback map (from app_id to callback) for Unregister. 379 std::map<std::string, UnregisterCallback> unregister_callbacks_; 380 381 // Callback map (from <app_id, message_id> to callback) for Send. 382 std::map<std::pair<std::string, std::string>, SendCallback> send_callbacks_; 383 384 // The encryption provider, used for key management and decryption of 385 // encrypted, incoming messages. 386 GCMEncryptionProvider encryption_provider_; 387 388 // App handler map (from app_id to handler pointer). The handler is not owned. 389 GCMAppHandlerMap app_handlers_; 390 391 base::WeakPtrFactory<GCMDriver> weak_ptr_factory_{this}; 392 393 DISALLOW_COPY_AND_ASSIGN(GCMDriver); 394 }; 395 396 } // namespace gcm 397 398 #endif // COMPONENTS_GCM_DRIVER_GCM_DRIVER_H_ 399