fcm_invalidation_listener.h 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. // Copyright 2018 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_INVALIDATION_IMPL_FCM_INVALIDATION_LISTENER_H_
  5. #define COMPONENTS_INVALIDATION_IMPL_FCM_INVALIDATION_LISTENER_H_
  6. #include <memory>
  7. #include "base/callback_forward.h"
  8. #include "base/memory/raw_ptr.h"
  9. #include "base/memory/weak_ptr.h"
  10. #include "base/values.h"
  11. #include "components/invalidation/impl/channels_states.h"
  12. #include "components/invalidation/impl/fcm_sync_network_channel.h"
  13. #include "components/invalidation/impl/per_user_topic_subscription_manager.h"
  14. #include "components/invalidation/impl/unacked_invalidation_set.h"
  15. #include "components/invalidation/public/ack_handler.h"
  16. #include "components/invalidation/public/invalidation_util.h"
  17. #include "components/invalidation/public/invalidator_state.h"
  18. namespace invalidation {
  19. class TopicInvalidationMap;
  20. // Receives InstanceID tokens and actual invalidations from FCM via
  21. // FCMSyncNetworkChannel, and dispatches them to its delegate (in practice, the
  22. // FCMInvalidationService). Stores invalidations in memory until they were
  23. // actually acked by the corresponding InvalidationHandler (tracked via the
  24. // AckHandler interface).
  25. // Also tracks the set of topics we're interested in (only invalidations for
  26. // these topics will get dispatched) and passes them to
  27. // PerUserTopicSubscriptionManager for subscription or unsubscription.
  28. class FCMInvalidationListener
  29. : public AckHandler,
  30. public FCMSyncNetworkChannel::Observer,
  31. public PerUserTopicSubscriptionManager::Observer {
  32. public:
  33. class Delegate {
  34. public:
  35. virtual ~Delegate() = default;
  36. virtual void OnInvalidate(const TopicInvalidationMap& invalidations) = 0;
  37. virtual void OnInvalidatorStateChange(InvalidatorState state) = 0;
  38. };
  39. explicit FCMInvalidationListener(
  40. std::unique_ptr<FCMSyncNetworkChannel> network_channel);
  41. FCMInvalidationListener(const FCMInvalidationListener& other) = delete;
  42. FCMInvalidationListener& operator=(const FCMInvalidationListener& other) =
  43. delete;
  44. ~FCMInvalidationListener() override;
  45. void Start(Delegate* delegate,
  46. std::unique_ptr<PerUserTopicSubscriptionManager>
  47. per_user_topic_subscription_manager);
  48. // Update the set of topics for which we want to get invalidations. May be
  49. // called at any time.
  50. void UpdateInterestedTopics(const Topics& topics);
  51. // Called when the InstanceID token is revoked (usually because the InstanceID
  52. // itself was deleted). Note that while this class receives new tokens
  53. // internally (via FCMSyncNetworkChannel), the deletion flow is triggered
  54. // externally, so it needs to be explicitly notified of token revocations.
  55. void ClearInstanceIDToken();
  56. // AckHandler implementation.
  57. void Acknowledge(const Topic& topic, const AckHandle& handle) override;
  58. void Drop(const Topic& topic, const AckHandle& handle) override;
  59. // FCMSyncNetworkChannel::Observer implementation.
  60. void OnFCMChannelStateChanged(FcmChannelState state) override;
  61. // PerUserTopicSubscriptionManager::Observer implementation.
  62. void OnSubscriptionChannelStateChanged(
  63. SubscriptionChannelState state) override;
  64. virtual void RequestDetailedStatus(
  65. const base::RepeatingCallback<void(base::Value::Dict)>& callback) const;
  66. void StartForTest(Delegate* delegate);
  67. void EmitStateChangeForTest(InvalidatorState state);
  68. void EmitSavedInvalidationsForTest(const TopicInvalidationMap& to_emit);
  69. private:
  70. // Callbacks for the |network_channel_|.
  71. void InvalidationReceived(const std::string& payload,
  72. const std::string& private_topic,
  73. const std::string& public_topic,
  74. int64_t version);
  75. void TokenReceived(const std::string& instance_id_token);
  76. // Passes the |interested_topics_| to |per_user_topic_subscription_manager_|
  77. // for subscription/unsubscription.
  78. void DoSubscriptionUpdate();
  79. void Stop();
  80. // Derives overall state based on |subscription_channel_state_| and
  81. // |fcm_network_state_|.
  82. InvalidatorState GetState() const;
  83. void EmitStateChange();
  84. // Sends invalidations to their appropriate destination.
  85. //
  86. // If there are no observers registered for them, they will be saved for
  87. // later.
  88. //
  89. // If there are observers registered, they will be saved (to make sure we
  90. // don't drop them until they've been acted on) and emitted to the observers.
  91. void DispatchInvalidations(const TopicInvalidationMap& invalidations);
  92. // Saves invalidations.
  93. //
  94. // This call isn't synchronous so we can't guarantee these invalidations will
  95. // be safely on disk by the end of the call, but it should ensure that the
  96. // data makes it to disk eventually.
  97. void SaveInvalidations(const TopicInvalidationMap& to_save);
  98. // Emits previously saved invalidations to their registered observers.
  99. void EmitSavedInvalidations(const TopicInvalidationMap& to_emit);
  100. // Generate a Dictionary with all the debugging information.
  101. base::Value::Dict CollectDebugData() const;
  102. std::unique_ptr<FCMSyncNetworkChannel> network_channel_;
  103. UnackedInvalidationsMap unacked_invalidations_map_;
  104. raw_ptr<Delegate> delegate_ = nullptr;
  105. // The set of topics for which we want to receive invalidations. We'll pass
  106. // these to |per_user_topic_subscription_manager_| for (un)subscription.
  107. Topics interested_topics_;
  108. // The states of the HTTP and FCM channel.
  109. SubscriptionChannelState subscription_channel_state_ =
  110. SubscriptionChannelState::NOT_STARTED;
  111. FcmChannelState fcm_network_state_ = FcmChannelState::NOT_STARTED;
  112. std::unique_ptr<PerUserTopicSubscriptionManager>
  113. per_user_topic_subscription_manager_;
  114. std::string instance_id_token_;
  115. // Prevents call to DoSubscriptionUpdate in cases when
  116. // UpdateInterestedTopics wasn't called. For example, InformTokenReceived
  117. // can trigger DoSubscriptionUpdate before any invalidation handler has
  118. // requested registration for topics.
  119. bool topics_update_requested_ = false;
  120. base::WeakPtrFactory<FCMInvalidationListener> weak_factory_{this};
  121. };
  122. } // namespace invalidation
  123. #endif // COMPONENTS_INVALIDATION_IMPL_FCM_INVALIDATION_LISTENER_H_