blob: 6c12c0a453b4e10e19ef09fb9a7089d17e38ffc3 [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.
#include "components/invalidation/impl/per_user_topic_invalidation_client.h"
#include "base/bind.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "components/invalidation/impl/invalidation_listener.h"
#include "components/invalidation/impl/logger.h"
#include "components/invalidation/impl/network_channel.h"
namespace {
const char kPrivatTopicName[] = "/topics";
const int kPrivatTopicNameSize = 7;
}
namespace syncer {
std::unique_ptr<InvalidationClient> CreatePerUserTopicInvalidationClient(
NetworkChannel* network,
Logger* logger,
InvalidationListener* listener) {
return std::make_unique<PerUserTopicInvalidationClient>(network, logger,
listener);
}
PerUserTopicInvalidationClient::PerUserTopicInvalidationClient(
NetworkChannel* network,
Logger* logger,
InvalidationListener* listener)
: network_(network),
logger_(logger),
listener_(listener),
weak_factory_(this) {
RegisterWithNetwork();
TLOG(logger_, INFO, "Created client");
}
PerUserTopicInvalidationClient::~PerUserTopicInvalidationClient() {}
void PerUserTopicInvalidationClient::RegisterWithNetwork() {
// Install ourselves as a receiver for server messages.
network_->SetMessageReceiver(
base::BindRepeating(&PerUserTopicInvalidationClient::MessageReceiver,
weak_factory_.GetWeakPtr()));
network_->SetTokenReceiver(
base::BindRepeating(&PerUserTopicInvalidationClient::TokenReceiver,
weak_factory_.GetWeakPtr()));
}
void PerUserTopicInvalidationClient::Start() {
if (ticl_protocol_started_) {
TLOG(logger_, SEVERE, "Ignoring start call since already started");
return;
}
FinishStartingTiclAndInformListener();
}
void PerUserTopicInvalidationClient::Stop() {
TLOG(logger_, INFO, "Ticl being stopped");
ticl_protocol_started_ = false;
}
void PerUserTopicInvalidationClient::FinishStartingTiclAndInformListener() {
DCHECK(!ticl_protocol_started_);
ticl_protocol_started_ = true;
GetListener()->Ready(this);
TLOG(logger_, INFO, "Ticl started");
}
void PerUserTopicInvalidationClient::MessageReceiver(
const std::string& payload,
const std::string& private_topic,
const std::string& public_topic,
const std::string& version) {
std::string private_topic_name = private_topic;
if (base::StartsWith(private_topic, kPrivatTopicName,
base::CompareCase::INSENSITIVE_ASCII)) {
// FCM protocol requires topic to start with"/topics" to topic name.
// Reason why it is necessary to strip the prefix is that later the shorter
// topic name is used for indexing into maps.
private_topic_name = private_topic.substr(kPrivatTopicNameSize);
}
int64_t v = 0;
if (!base::StringToInt64(version, &v)) {
// Version must always be in the message and
// in addition version must be number.
// TODO(melandory): Report Error to listener;
}
GetListener()->Invalidate(this, payload, private_topic_name, public_topic, v);
}
void PerUserTopicInvalidationClient::TokenReceiver(const std::string& token) {
GetListener()->InformTokenRecieved(this, token);
if (!ticl_protocol_started_)
FinishStartingTiclAndInformListener();
}
} // namespace invalidation