Commit d3fd9ec3 authored by Tanja Gornak's avatar Tanja Gornak Committed by Commit Bot

[Tango->FCM] Drop all registrations on instanceID token change.

Bug: 895080
Change-Id: I131b9dd086f4a935552ac288cc4f690fd9f7ba16
Reviewed-on: https://chromium-review.googlesource.com/c/1278762
Commit-Queue: Tatiana Gornak <melandory@chromium.org>
Reviewed-by: default avatarPavel Yatsuk <pavely@chromium.org>
Cr-Commit-Position: refs/heads/master@{#600794}
parent a4195e59
...@@ -30,6 +30,9 @@ namespace { ...@@ -30,6 +30,9 @@ namespace {
const char kTypeRegisteredForInvalidation[] = const char kTypeRegisteredForInvalidation[] =
"invalidation.registered_for_invalidation"; "invalidation.registered_for_invalidation";
const char kActiveRegistrationToken[] =
"invalidation.active_registration_token";
const char kInvalidationRegistrationScope[] = const char kInvalidationRegistrationScope[] =
"https://firebaseperusertopics-pa.googleapis.com"; "https://firebaseperusertopics-pa.googleapis.com";
...@@ -76,6 +79,7 @@ static const net::BackoffEntry::Policy kBackoffPolicy = { ...@@ -76,6 +79,7 @@ static const net::BackoffEntry::Policy kBackoffPolicy = {
void PerUserTopicRegistrationManager::RegisterProfilePrefs( void PerUserTopicRegistrationManager::RegisterProfilePrefs(
PrefRegistrySimple* registry) { PrefRegistrySimple* registry) {
registry->RegisterDictionaryPref(kTypeRegisteredForInvalidation); registry->RegisterDictionaryPref(kTypeRegisteredForInvalidation);
registry->RegisterStringPref(kActiveRegistrationToken, std::string());
} }
struct PerUserTopicRegistrationManager::RegistrationEntry { struct PerUserTopicRegistrationManager::RegistrationEntry {
...@@ -168,8 +172,7 @@ void PerUserTopicRegistrationManager::UpdateRegisteredTopics( ...@@ -168,8 +172,7 @@ void PerUserTopicRegistrationManager::UpdateRegisteredTopics(
const std::string& instance_id_token) { const std::string& instance_id_token) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
token_ = instance_id_token; token_ = instance_id_token;
// TODO(melandory): On change of token registrations DropAllSavedRegistrationsOnTokenChange(instance_id_token);
// should be re-requested.
for (const auto& topic : topics) { for (const auto& topic : topics) {
// If id isn't registered, schedule the registration. // If id isn't registered, schedule the registration.
if (topic_to_private_topic_.find(topic) == topic_to_private_topic_.end()) { if (topic_to_private_topic_.find(topic) == topic_to_private_topic_.end()) {
...@@ -338,4 +341,24 @@ void PerUserTopicRegistrationManager::OnAccessTokenRequestFailed( ...@@ -338,4 +341,24 @@ void PerUserTopicRegistrationManager::OnAccessTokenRequestFailed(
base::Unretained(this))); base::Unretained(this)));
} }
void PerUserTopicRegistrationManager::DropAllSavedRegistrationsOnTokenChange(
const std::string& instance_id_token) {
std::string current_token = local_state_->GetString(kActiveRegistrationToken);
if (current_token.empty()) {
local_state_->SetString(kActiveRegistrationToken, instance_id_token);
return;
}
if (current_token == instance_id_token) {
return;
}
local_state_->SetString(kActiveRegistrationToken, instance_id_token);
DictionaryPrefUpdate update(local_state_, kTypeRegisteredForInvalidation);
for (const auto& topic : topic_to_private_topic_) {
update->RemoveKey(topic.first);
}
topic_to_private_topic_.clear();
// TODO(melandory): Figure out if the unsubscribe request should be
// sent with the old token.
}
} // namespace syncer } // namespace syncer
...@@ -78,6 +78,9 @@ class INVALIDATION_EXPORT PerUserTopicRegistrationManager { ...@@ -78,6 +78,9 @@ class INVALIDATION_EXPORT PerUserTopicRegistrationManager {
void OnAccessTokenRequestSucceeded(std::string access_token); void OnAccessTokenRequestSucceeded(std::string access_token);
void OnAccessTokenRequestFailed(GoogleServiceAuthError error); void OnAccessTokenRequestFailed(GoogleServiceAuthError error);
void DropAllSavedRegistrationsOnTokenChange(
const std::string& instance_id_token);
std::map<Topic, std::unique_ptr<RegistrationEntry>> registration_statuses_; std::map<Topic, std::unique_ptr<RegistrationEntry>> registration_statuses_;
// For registered ids it maps the id value to the topic value. // For registered ids it maps the id value to the topic value.
......
...@@ -4,10 +4,13 @@ ...@@ -4,10 +4,13 @@
#include "components/invalidation/impl/per_user_topic_registration_manager.h" #include "components/invalidation/impl/per_user_topic_registration_manager.h"
#include "base/json/json_string_value_serializer.h"
#include "base/json/json_writer.h"
#include "base/macros.h" #include "base/macros.h"
#include "base/message_loop/message_loop.h" #include "base/message_loop/message_loop.h"
#include "base/stl_util.h" #include "base/stl_util.h"
#include "base/strings/stringprintf.h" #include "base/strings/stringprintf.h"
#include "base/values.h"
#include "components/invalidation/impl/json_unsafe_parser.h" #include "components/invalidation/impl/json_unsafe_parser.h"
#include "components/invalidation/impl/profile_identity_provider.h" #include "components/invalidation/impl/profile_identity_provider.h"
#include "components/invalidation/public/invalidation_util.h" #include "components/invalidation/public/invalidation_util.h"
...@@ -32,6 +35,9 @@ const char kProjectId[] = "8181035976"; ...@@ -32,6 +35,9 @@ const char kProjectId[] = "8181035976";
const char kTypeRegisteredForInvalidation[] = const char kTypeRegisteredForInvalidation[] =
"invalidation.registered_for_invalidation"; "invalidation.registered_for_invalidation";
const char kActiveRegistrationToken[] =
"invalidation.active_registration_token";
const char kFakeInstanceIdToken[] = "fake_instance_id_token"; const char kFakeInstanceIdToken[] = "fake_instance_id_token";
std::string IndexToName(size_t index) { std::string IndexToName(size_t index) {
...@@ -59,10 +65,10 @@ network::ResourceResponseHead CreateHeadersForTest(int responce_code) { ...@@ -59,10 +65,10 @@ network::ResourceResponseHead CreateHeadersForTest(int responce_code) {
return head; return head;
} }
GURL FullSubscriptionUrl() { GURL FullSubscriptionUrl(const std::string& token) {
return GURL(base::StringPrintf( return GURL(base::StringPrintf(
"%s/v1/perusertopics/%s/rel/topics/?subscriber_token=%s", "%s/v1/perusertopics/%s/rel/topics/?subscriber_token=%s",
kInvalidationRegistrationScope, kProjectId, kFakeInstanceIdToken)); kInvalidationRegistrationScope, kProjectId, token.c_str()));
} }
GURL FullUnSubscriptionUrlForTopic(const std::string& topic) { GURL FullUnSubscriptionUrlForTopic(const std::string& topic) {
...@@ -114,15 +120,18 @@ class PerUserTopicRegistrationManagerTest : public testing::Test { ...@@ -114,15 +120,18 @@ class PerUserTopicRegistrationManagerTest : public testing::Test {
TestingPrefServiceSimple* pref_service() { return &pref_service_; } TestingPrefServiceSimple* pref_service() { return &pref_service_; }
void AddCorrectSubscriptionResponce() { void AddCorrectSubscriptionResponce(
std::string response_body = R"( const std::string& private_topic = std::string(),
{ const std::string& token = kFakeInstanceIdToken) {
"privateTopicName": "test-pr" std::unique_ptr<base::DictionaryValue> value(new base::DictionaryValue());
} value->SetString("privateTopicName",
)"; private_topic.empty() ? "test-pr" : private_topic.c_str());
std::string serialized_response;
JSONStringValueSerializer serializer(&serialized_response);
serializer.Serialize(*value);
url_loader_factory()->AddResponse( url_loader_factory()->AddResponse(
FullSubscriptionUrl(), CreateHeadersForTest(net::HTTP_OK), FullSubscriptionUrl(token), CreateHeadersForTest(net::HTTP_OK),
response_body, CreateStatusForTest(net::OK, response_body)); serialized_response, CreateStatusForTest(net::OK, serialized_response));
} }
void AddCorrectUnSubscriptionResponceForTopic(const std::string& topic) { void AddCorrectUnSubscriptionResponceForTopic(const std::string& topic) {
...@@ -155,7 +164,8 @@ TEST_F(PerUserTopicRegistrationManagerTest, ...@@ -155,7 +164,8 @@ TEST_F(PerUserTopicRegistrationManagerTest,
std::string response_body; std::string response_body;
url_loader_factory()->AddResponse( url_loader_factory()->AddResponse(
FullSubscriptionUrl(), CreateHeadersForTest(net::HTTP_OK), response_body, FullSubscriptionUrl(kFakeInstanceIdToken),
CreateHeadersForTest(net::HTTP_OK), response_body,
CreateStatusForTest(net::OK, response_body)); CreateStatusForTest(net::OK, response_body));
per_user_topic_registration_manager->UpdateRegisteredTopics( per_user_topic_registration_manager->UpdateRegisteredTopics(
...@@ -234,4 +244,55 @@ TEST_F(PerUserTopicRegistrationManagerTest, ...@@ -234,4 +244,55 @@ TEST_F(PerUserTopicRegistrationManagerTest,
} }
} }
TEST_F(PerUserTopicRegistrationManagerTest,
ShouldDropSavedTopicsOnTokenChange) {
TopicSet ids = GetSequenceOfTopics(kInvalidationObjectIdsCount);
auto per_user_topic_registration_manager = BuildRegistrationManager();
EXPECT_TRUE(per_user_topic_registration_manager->GetRegisteredIds().empty());
AddCorrectSubscriptionResponce("old-token-topic");
per_user_topic_registration_manager->UpdateRegisteredTopics(
ids, kFakeInstanceIdToken);
base::RunLoop().RunUntilIdle();
EXPECT_EQ(ids, per_user_topic_registration_manager->GetRegisteredIds());
for (const auto& id : ids) {
const base::DictionaryValue* topics =
pref_service()->GetDictionary(kTypeRegisteredForInvalidation);
const base::Value* private_topic_value =
topics->FindKeyOfType(id, base::Value::Type::STRING);
ASSERT_NE(private_topic_value, nullptr);
std::string private_topic;
private_topic_value->GetAsString(&private_topic);
EXPECT_EQ(private_topic, "old-token-topic");
}
EXPECT_EQ(kFakeInstanceIdToken,
pref_service()->GetString(kActiveRegistrationToken));
std::string token = "new-fake-token";
AddCorrectSubscriptionResponce("new-token-topic", token);
per_user_topic_registration_manager->UpdateRegisteredTopics(ids, token);
base::RunLoop().RunUntilIdle();
EXPECT_EQ(token, pref_service()->GetString(kActiveRegistrationToken));
EXPECT_EQ(ids, per_user_topic_registration_manager->GetRegisteredIds());
for (const auto& id : ids) {
const base::DictionaryValue* topics =
pref_service()->GetDictionary(kTypeRegisteredForInvalidation);
const base::Value* private_topic_value =
topics->FindKeyOfType(id, base::Value::Type::STRING);
ASSERT_NE(private_topic_value, nullptr);
std::string private_topic;
private_topic_value->GetAsString(&private_topic);
EXPECT_EQ(private_topic, "new-token-topic");
}
}
} // namespace syncer } // namespace syncer
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment