blob: 4bc1b6b96069047737e027f59daed0f532bc8e16 [file] [log] [blame]
// Copyright 2018 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_INVALIDATION_IMPL_FCM_INVALIDATION_LISTENER_H_
#define COMPONENTS_INVALIDATION_IMPL_FCM_INVALIDATION_LISTENER_H_
#include <memory>
#include "base/callback_forward.h"
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "components/invalidation/impl/fcm_sync_network_channel.h"
#include "components/invalidation/impl/invalidation_client.h"
#include "components/invalidation/impl/invalidation_listener.h"
#include "components/invalidation/impl/logger.h"
#include "components/invalidation/impl/per_user_topic_registration_manager.h"
#include "components/invalidation/impl/unacked_invalidation_set.h"
#include "components/invalidation/public/ack_handler.h"
#include "components/invalidation/public/invalidation_object_id.h"
#include "components/invalidation/public/invalidation_util.h"
#include "components/invalidation/public/invalidator_state.h"
#include "services/network/public/mojom/url_loader_factory.mojom.h"
namespace syncer {
class TopicInvalidationMap;
// A simple wrapper around PerUserTopicInvalidationClient that
// handles all the startup/shutdown details and hookups.
// By implementing the AckHandler interface it tracks the messages
// which were passed to InvalidationHandlers.
class FCMInvalidationListener : public InvalidationListener,
public AckHandler,
FCMSyncNetworkChannel::Observer,
PerUserTopicRegistrationManager::Observer {
public:
typedef base::OnceCallback<std::unique_ptr<InvalidationClient>(
NetworkChannel* network_channel,
Logger* logger,
InvalidationListener*)>
CreateInvalidationClientCallback;
class Delegate {
public:
virtual ~Delegate();
virtual void OnInvalidate(const TopicInvalidationMap& invalidations) = 0;
virtual void OnInvalidatorStateChange(InvalidatorState state) = 0;
};
explicit FCMInvalidationListener(
std::unique_ptr<FCMSyncNetworkChannel> network_channel);
~FCMInvalidationListener() override;
void Start(
CreateInvalidationClientCallback create_invalidation_client_callback,
Delegate* delegate,
std::unique_ptr<PerUserTopicRegistrationManager>
per_user_topic_registration_manager);
// Update the set of object IDs that we're interested in getting
// notifications for. May be called at any time.
void UpdateRegisteredTopics(const TopicSet& topics);
// InvalidationListener implementation.
void Ready(InvalidationClient* client) override;
void Invalidate(InvalidationClient* client,
const std::string& payload,
const std::string& private_topic,
const std::string& public_topic,
int64_t version) override;
void InformTokenRecieved(InvalidationClient* client,
const std::string& token) override;
// AckHandler implementation.
void Acknowledge(const invalidation::ObjectId& id,
const syncer::AckHandle& handle) override;
void Drop(const invalidation::ObjectId& id,
const syncer::AckHandle& handle) override;
// FCMSyncNetworkChannel::Observer implementation.
void OnFCMSyncNetworkChannelStateChanged(
InvalidatorState invalidator_state) override;
// PerUserTopicRegistrationManager::Observer implementation.
void OnSubscriptionChannelStateChanged(
InvalidatorState invalidator_state) override;
void DoRegistrationUpdate();
void StopForTest();
TopicSet GetRegisteredIdsForTest() const;
base::WeakPtr<FCMInvalidationListener> AsWeakPtr();
private:
void Stop();
InvalidatorState GetState() const;
void EmitStateChange();
// Sends invalidations to their appropriate destination.
//
// If there are no observers registered for them, they will be saved for
// later.
//
// If there are observers registered, they will be saved (to make sure we
// don't drop them until they've been acted on) and emitted to the observers.
void DispatchInvalidations(const TopicInvalidationMap& invalidations);
// Saves invalidations.
//
// This call isn't synchronous so we can't guarantee these invalidations will
// be safely on disk by the end of the call, but it should ensure that the
// data makes it to disk eventually.
void SaveInvalidations(const TopicInvalidationMap& to_save);
// Emits previously saved invalidations to their registered observers.
void EmitSavedInvalidations(const TopicInvalidationMap& to_emit);
// Generate a Dictionary with all the debugging information.
std::unique_ptr<base::DictionaryValue> CollectDebugData() const;
std::unique_ptr<FCMSyncNetworkChannel> network_channel_;
UnackedInvalidationsMap unacked_invalidations_map_;
Delegate* delegate_;
Logger logger_;
std::unique_ptr<InvalidationClient> invalidation_client_;
// Stored to pass to |per_user_topic_registration_manager_| on start.
TopicSet registered_topics_;
// The states of the HTTP and FCM channel.
InvalidatorState subscription_channel_state_;
InvalidatorState fcm_network_state_;
std::unique_ptr<PerUserTopicRegistrationManager>
per_user_topic_registration_manager_;
std::string token_;
// Prevents call to DoRegistrationUpdate in cases when
// UpdateRegisteredTopics wasn't called. For example, InformTokenRecieved
// can trigger DoRegistrationUpdate before any invalidation handler has
// requested registration for topics.
bool ids_update_requested_ = false;
base::WeakPtrFactory<FCMInvalidationListener> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(FCMInvalidationListener);
};
} // namespace syncer
#endif // COMPONENTS_INVALIDATION_IMPL_FCM_INVALIDATION_LISTENER_H_