1cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "components/invalidation/invalidator_storage.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include <string>
8116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include <utility>
9116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/base64.h"
11116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "base/basictypes.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
13116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "base/memory/scoped_ptr.h"
14116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "base/prefs/pref_registry_simple.h"
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/prefs/pref_service.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/values.h"
17cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "components/invalidation/invalidation_prefs.h"
18116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "components/invalidation/unacked_invalidation_set.h"
19cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "components/pref_registry/pref_registry_syncable.h"
20116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "google/cacheinvalidation/types.pb.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)const char kInvalidatorMaxInvalidationVersions[] =
25f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    "invalidator.max_invalidation_versions";
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)bool ValueToUnackedInvalidationStorageMap(
285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const base::ListValue& value,
29f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    syncer::UnackedInvalidationsMap* map) {
30f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  for (size_t i = 0; i != value.GetSize(); ++i) {
31f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    invalidation::ObjectId invalid_id;
32f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    syncer::UnackedInvalidationSet storage(invalid_id);
33f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const base::DictionaryValue* dict;
34f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (!value.GetDictionary(i, &dict) || !storage.ResetFromValue(*dict)) {
35f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      DLOG(WARNING) << "Failed to parse ObjectState at position " << i;
36f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      return false;
37f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    }
38f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    map->insert(std::make_pair(storage.object_id(), storage));
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
43f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)scoped_ptr<base::ListValue> UnackedInvalidationStorageMapToValue(
44f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const syncer::UnackedInvalidationsMap& map) {
45f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_ptr<base::ListValue> value(new base::ListValue);
46f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  for (syncer::UnackedInvalidationsMap::const_iterator it = map.begin();
47f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)       it != map.end(); ++it) {
48f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    value->Append(it->second.ToValue().release());
49f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
50f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return value.Pass();
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)namespace invalidation {
56a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static
587dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid InvalidatorStorage::RegisterProfilePrefs(
59c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    user_prefs::PrefRegistrySyncable* registry) {
60f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  registry->RegisterListPref(prefs::kInvalidatorSavedInvalidations,
61c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                             user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
62c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  registry->RegisterStringPref(
63c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      prefs::kInvalidatorInvalidationState,
64c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      std::string(),
65c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
66c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  registry->RegisterStringPref(
67c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      prefs::kInvalidatorClientId,
68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      std::string(),
69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
70f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
71f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // This pref is obsolete.  We register it so we can clear it.
72f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // At some point in the future, it will be safe to remove this.
73f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  registry->RegisterListPref(kInvalidatorMaxInvalidationVersions,
74f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                             user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
77116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// static
78116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid InvalidatorStorage::RegisterPrefs(PrefRegistrySimple* registry) {
79116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  registry->RegisterListPref(prefs::kInvalidatorSavedInvalidations);
80116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  registry->RegisterStringPref(prefs::kInvalidatorInvalidationState,
81116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                               std::string());
82116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  registry->RegisterStringPref(prefs::kInvalidatorClientId, std::string());
83116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
84116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)InvalidatorStorage::InvalidatorStorage(PrefService* pref_service)
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : pref_service_(pref_service) {
87116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DCHECK(pref_service_);
88116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (pref_service_->FindPreference(kInvalidatorMaxInvalidationVersions))
89116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    pref_service_->ClearPref(kInvalidatorMaxInvalidationVersions);
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)InvalidatorStorage::~InvalidatorStorage() {
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
950529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochvoid InvalidatorStorage::ClearAndSetNewClientId(const std::string& client_id) {
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
97c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  Clear();  // We can't reuse our old invalidation state if the ID changes.
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  pref_service_->SetString(prefs::kInvalidatorClientId, client_id);
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)std::string InvalidatorStorage::GetInvalidatorClientId() const {
102f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return pref_service_->GetString(prefs::kInvalidatorClientId);
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void InvalidatorStorage::SetBootstrapData(const std::string& data) {
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string base64_data;
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::Base64Encode(data, &base64_data);
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pref_service_->SetString(prefs::kInvalidatorInvalidationState,
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           base64_data);
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string InvalidatorStorage::GetBootstrapData() const {
114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string base64_data(
115f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      pref_service_->GetString(prefs::kInvalidatorInvalidationState));
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string data;
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::Base64Decode(base64_data, &data);
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return data;
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
121f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void InvalidatorStorage::SetSavedInvalidations(
122f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      const syncer::UnackedInvalidationsMap& map) {
123f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_ptr<base::ListValue> value(UnackedInvalidationStorageMapToValue(map));
124f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  pref_service_->Set(prefs::kInvalidatorSavedInvalidations, *value.get());
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
127f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)syncer::UnackedInvalidationsMap
128f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)InvalidatorStorage::GetSavedInvalidations() const {
129f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  syncer::UnackedInvalidationsMap map;
130f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const base::ListValue* value =
131f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      pref_service_->GetList(prefs::kInvalidatorSavedInvalidations);
132f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (!ValueToUnackedInvalidationStorageMap(*value, &map)) {
133f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return syncer::UnackedInvalidationsMap();
134f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  } else {
135f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return map;
1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
139f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void InvalidatorStorage::Clear() {
1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
141f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  pref_service_->ClearPref(prefs::kInvalidatorSavedInvalidations);
142f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  pref_service_->ClearPref(prefs::kInvalidatorClientId);
143f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  pref_service_->ClearPref(prefs::kInvalidatorInvalidationState);
1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
146a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)}  // namespace invalidation
147