Home | History | Annotate | Download | only in invalidation
      1 // Copyright 2014 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "components/invalidation/invalidator_storage.h"
      6 
      7 #include "base/base64.h"
      8 #include "base/bind.h"
      9 #include "base/callback.h"
     10 #include "base/location.h"
     11 #include "base/logging.h"
     12 #include "base/metrics/histogram.h"
     13 #include "base/prefs/pref_service.h"
     14 #include "base/strings/string_number_conversions.h"
     15 #include "base/task_runner.h"
     16 #include "base/values.h"
     17 #include "components/invalidation/invalidation_prefs.h"
     18 #include "components/pref_registry/pref_registry_syncable.h"
     19 
     20 namespace {
     21 
     22 const char kInvalidatorMaxInvalidationVersions[] =
     23     "invalidator.max_invalidation_versions";
     24 
     25 
     26 bool ValueToUnackedInvalidationStorageMap(
     27     const base::ListValue& value,
     28     syncer::UnackedInvalidationsMap* map) {
     29   for (size_t i = 0; i != value.GetSize(); ++i) {
     30     invalidation::ObjectId invalid_id;
     31     syncer::UnackedInvalidationSet storage(invalid_id);
     32     const base::DictionaryValue* dict;
     33     if (!value.GetDictionary(i, &dict) || !storage.ResetFromValue(*dict)) {
     34       DLOG(WARNING) << "Failed to parse ObjectState at position " << i;
     35       return false;
     36     }
     37     map->insert(std::make_pair(storage.object_id(), storage));
     38   }
     39   return true;
     40 }
     41 
     42 scoped_ptr<base::ListValue> UnackedInvalidationStorageMapToValue(
     43     const syncer::UnackedInvalidationsMap& map) {
     44   scoped_ptr<base::ListValue> value(new base::ListValue);
     45   for (syncer::UnackedInvalidationsMap::const_iterator it = map.begin();
     46        it != map.end(); ++it) {
     47     value->Append(it->second.ToValue().release());
     48   }
     49   return value.Pass();
     50 }
     51 
     52 }  // namespace
     53 
     54 namespace invalidation {
     55 
     56 // static
     57 void InvalidatorStorage::RegisterProfilePrefs(
     58     user_prefs::PrefRegistrySyncable* registry) {
     59   registry->RegisterListPref(prefs::kInvalidatorSavedInvalidations,
     60                              user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
     61   registry->RegisterStringPref(
     62       prefs::kInvalidatorInvalidationState,
     63       std::string(),
     64       user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
     65   registry->RegisterStringPref(
     66       prefs::kInvalidatorClientId,
     67       std::string(),
     68       user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
     69 
     70   // This pref is obsolete.  We register it so we can clear it.
     71   // At some point in the future, it will be safe to remove this.
     72   registry->RegisterListPref(kInvalidatorMaxInvalidationVersions,
     73                              user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
     74 }
     75 
     76 InvalidatorStorage::InvalidatorStorage(PrefService* pref_service)
     77     : pref_service_(pref_service) {
     78   DCHECK(pref_service);
     79   pref_service_->ClearPref(kInvalidatorMaxInvalidationVersions);
     80 }
     81 
     82 InvalidatorStorage::~InvalidatorStorage() {
     83 }
     84 
     85 void InvalidatorStorage::ClearAndSetNewClientId(const std::string& client_id) {
     86   DCHECK(thread_checker_.CalledOnValidThread());
     87   Clear();  // We can't reuse our old invalidation state if the ID changes.
     88   pref_service_->SetString(prefs::kInvalidatorClientId, client_id);
     89 }
     90 
     91 std::string InvalidatorStorage::GetInvalidatorClientId() const {
     92   return pref_service_->GetString(prefs::kInvalidatorClientId);
     93 }
     94 
     95 void InvalidatorStorage::SetBootstrapData(const std::string& data) {
     96   DCHECK(thread_checker_.CalledOnValidThread());
     97   std::string base64_data;
     98   base::Base64Encode(data, &base64_data);
     99   pref_service_->SetString(prefs::kInvalidatorInvalidationState,
    100                            base64_data);
    101 }
    102 
    103 std::string InvalidatorStorage::GetBootstrapData() const {
    104   std::string base64_data(
    105       pref_service_->GetString(prefs::kInvalidatorInvalidationState));
    106   std::string data;
    107   base::Base64Decode(base64_data, &data);
    108   return data;
    109 }
    110 
    111 void InvalidatorStorage::SetSavedInvalidations(
    112       const syncer::UnackedInvalidationsMap& map) {
    113   scoped_ptr<base::ListValue> value(UnackedInvalidationStorageMapToValue(map));
    114   pref_service_->Set(prefs::kInvalidatorSavedInvalidations, *value.get());
    115 }
    116 
    117 syncer::UnackedInvalidationsMap
    118 InvalidatorStorage::GetSavedInvalidations() const {
    119   syncer::UnackedInvalidationsMap map;
    120   const base::ListValue* value =
    121       pref_service_->GetList(prefs::kInvalidatorSavedInvalidations);
    122   if (!ValueToUnackedInvalidationStorageMap(*value, &map)) {
    123     return syncer::UnackedInvalidationsMap();
    124   } else {
    125     return map;
    126   }
    127 }
    128 
    129 void InvalidatorStorage::Clear() {
    130   DCHECK(thread_checker_.CalledOnValidThread());
    131   pref_service_->ClearPref(prefs::kInvalidatorSavedInvalidations);
    132   pref_service_->ClearPref(prefs::kInvalidatorClientId);
    133   pref_service_->ClearPref(prefs::kInvalidatorInvalidationState);
    134 }
    135 
    136 }  // namespace invalidation
    137