1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132
|
// Copyright 2018 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef COMPONENTS_INVALIDATION_IMPL_INVALIDATOR_REGISTRAR_WITH_MEMORY_H_
#define COMPONENTS_INVALIDATION_IMPL_INVALIDATOR_REGISTRAR_WITH_MEMORY_H_
#include <map>
#include <optional>
#include <set>
#include <string>
#include "base/feature_list.h"
#include "base/memory/raw_ptr.h"
#include "base/observer_list.h"
#include "base/sequence_checker.h"
#include "components/invalidation/public/invalidation_export.h"
#include "components/invalidation/public/invalidation_handler.h"
#include "components/prefs/pref_registry_simple.h"
#include "components/prefs/pref_service.h"
class PrefRegistrySimple;
class PrefService;
namespace invalidation {
class Invalidation;
// A helper class for FCMInvalidationService. It helps keep track of registered
// handlers and which topic registrations are associated with each handler.
class INVALIDATION_EXPORT InvalidatorRegistrarWithMemory {
public:
InvalidatorRegistrarWithMemory(PrefService* prefs,
const std::string& sender_id);
InvalidatorRegistrarWithMemory(const InvalidatorRegistrarWithMemory& other) =
delete;
InvalidatorRegistrarWithMemory& operator=(
const InvalidatorRegistrarWithMemory& other) = delete;
// It is an error to have registered handlers on destruction.
~InvalidatorRegistrarWithMemory();
// RegisterProfilePrefs and RegisterPrefs register the same prefs, because on
// device level (sign in screen, device local account) we spin up separate
// InvalidationService and on profile level (when user signed in) we have
// another InvalidationService, and we want to keep profile data in an
// encrypted area of disk. While device data which is public can be kept in an
// unencrypted area.
static void RegisterProfilePrefs(PrefRegistrySimple* registry);
static void RegisterPrefs(PrefRegistrySimple* registry);
// Starts sending notifications to |handler|. |handler| must not be nullptr,
// and it must not already be registered.
void AddObserver(InvalidationHandler* handler);
bool HasObserver(const InvalidationHandler* handler) const;
// Stops sending notifications to |handler|. |handler| must not be nullptr,
// and it must already be registered. Note that this doesn't unregister the
// topics associated with |handler| from the server.
void RemoveObserver(const InvalidationHandler* handler);
// Updates the set of topics associated with |handler|. |handler| must not be
// nullptr, and must already be registered. A topic must be registered for at
// most one handler. If any of the |topics| is already registered to a
// different handler, returns false. Note that this also updates the
// *subscribed* topics - assuming that whoever called this will also send
// (un)subscription requests to the server. However, this method does *not*
// unsubscribe from the topics which were not registered since browser
// startup.
[[nodiscard]] bool UpdateRegisteredTopics(InvalidationHandler* handler,
const TopicMap& topics);
// Returns all topics currently registered to |handler|.
TopicMap GetRegisteredTopics(InvalidationHandler* handler) const;
// Returns the set of all topics that (we think) we are subscribed to on the
// server. This is the set of topics which were registered to some handler and
// not unregistered (via UpdateRegisteredTopics()). This includes topics whose
// *handler* has been unregistered without unregistering the topic itself
// first (e.g. because Chrome was restarted and the handler hasn't registered
// itself again yet).
TopicMap GetAllSubscribedTopics() const;
// Dispatches incoming invalidation to the corresponding handler based on its
// topic.
// Invalidations for topics with no corresponding handler are returned.
std::optional<Invalidation> DispatchInvalidationToHandlers(
const Invalidation& invalidation);
// Dispatches a notification that the client has successfully subscribed to
// `topic` to handlers.
void DispatchSuccessfullySubscribedToHandlers(const Topic& topic);
// Updates the invalidator state to the given one and then notifies
// all handlers. Note that the order is important; handlers that
// call GetInvalidatorState() when notified will see the new state.
void UpdateInvalidatorState(InvalidatorState state);
// Returns the current invalidator state. When called from within
// InvalidationHandler::OnInvalidatorStateChange(), this returns the
// updated state.
InvalidatorState GetInvalidatorState() const;
private:
// Checks if any of the |new_topics| is already registered for a *different*
// handler than the given one.
bool HasDuplicateTopicRegistration(InvalidationHandler* handler,
const TopicMap& new_topics) const;
SEQUENCE_CHECKER(sequence_checker_);
base::ObserverList<InvalidationHandler, true> handlers_;
// Note: When a handler is unregistered, its entry is removed from
// |registered_handler_to_topics_map_| but NOT from
// |handler_name_to_subscribed_topics_map_|.
std::map<InvalidationHandler*, TopicMap, std::less<>>
registered_handler_to_topics_map_;
std::map<std::string, TopicMap> handler_name_to_subscribed_topics_map_;
InvalidatorState state_;
// This can be either a regular (Profile-attached) PrefService or the local
// state PrefService.
const raw_ptr<PrefService> prefs_;
// The FCM sender ID.
const std::string sender_id_;
};
} // namespace invalidation
#endif // COMPONENTS_INVALIDATION_IMPL_INVALIDATOR_REGISTRAR_WITH_MEMORY_H_
|