Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(526)

Side by Side Diff: net/sdch/sdch_owner.cc

Issue 1634653003: Abstract pref storage from net::SdchOwner (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@net_prefs
Patch Set: Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "net/sdch/sdch_owner.h" 5 #include "net/sdch/sdch_owner.h"
6 6
7 #include <utility> 7 #include <utility>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/debug/alias.h" 10 #include "base/debug/alias.h"
11 #include "base/logging.h" 11 #include "base/logging.h"
12 #include "base/macros.h" 12 #include "base/macros.h"
13 #include "base/metrics/histogram_macros.h" 13 #include "base/metrics/histogram_macros.h"
14 #include "base/prefs/persistent_pref_store.h"
15 #include "base/prefs/value_map_pref_store.h"
16 #include "base/strings/string_util.h" 14 #include "base/strings/string_util.h"
17 #include "base/time/default_clock.h" 15 #include "base/time/default_clock.h"
18 #include "base/values.h" 16 #include "base/values.h"
19 #include "net/base/sdch_manager.h" 17 #include "net/base/sdch_manager.h"
20 #include "net/base/sdch_net_log_params.h" 18 #include "net/base/sdch_net_log_params.h"
21 19
22 namespace net { 20 namespace net {
23 21
24 namespace { 22 namespace {
25 23
26 enum PersistenceFailureReason {
27 // File didn't exist; is being created.
28 PERSISTENCE_FAILURE_REASON_NO_FILE = 1,
29
30 // Error reading in information, but should be able to write.
31 PERSISTENCE_FAILURE_REASON_READ_FAILED = 2,
32
33 // Error leading to abort on attempted persistence.
34 PERSISTENCE_FAILURE_REASON_WRITE_FAILED = 3,
35
36 PERSISTENCE_FAILURE_REASON_MAX = 4
37 };
38
39 // Dictionaries that haven't been touched in 24 hours may be evicted 24 // Dictionaries that haven't been touched in 24 hours may be evicted
40 // to make room for new dictionaries. 25 // to make room for new dictionaries.
41 const int kFreshnessLifetimeHours = 24; 26 const int kFreshnessLifetimeHours = 24;
42 27
43 // Dictionaries that have never been used only stay fresh for one hour. 28 // Dictionaries that have never been used only stay fresh for one hour.
44 const int kNeverUsedFreshnessLifetimeHours = 1; 29 const int kNeverUsedFreshnessLifetimeHours = 1;
45 30
46 void RecordPersistenceFailure(PersistenceFailureReason failure_reason) { 31 void RecordPersistenceFailure(
47 UMA_HISTOGRAM_ENUMERATION("Sdch3.PersistenceFailureReason", failure_reason, 32 SdchOwner::PrefStorage::ReadError failure_reason) {
48 PERSISTENCE_FAILURE_REASON_MAX); 33 UMA_HISTOGRAM_ENUMERATION(
34 "Sdch3.PersistenceFailureReason", failure_reason,
35 SdchOwner::PrefStorage::PERSISTENCE_FAILURE_REASON_MAX);
49 } 36 }
50 37
51 // Schema specifications and access routines. 38 // Schema specifications and access routines.
52 39
53 // The persistent prefs store is conceptually shared with any other network 40 // The persistent prefs store is conceptually shared with any other network
54 // stack systems that want to persist data over browser restarts, and so 41 // stack systems that want to persist data over browser restarts, and so
55 // use of it must be namespace restricted. 42 // use of it must be namespace restricted.
56 // Schema: 43 // Schema:
57 // pref_store_->GetValue(kPreferenceName) -> Dictionary { 44 // pref_store_->GetValue() -> Dictionary {
58 // 'version' -> 2 [int] 45 // 'version' -> 2 [int]
59 // 'dictionaries' -> Dictionary { 46 // 'dictionaries' -> Dictionary {
60 // server_hash -> { 47 // server_hash -> {
61 // 'url' -> URL [string] 48 // 'url' -> URL [string]
62 // 'last_used' -> seconds since unix epoch [double] 49 // 'last_used' -> seconds since unix epoch [double]
63 // 'created_time' -> seconds since unix epoch [double] 50 // 'created_time' -> seconds since unix epoch [double]
64 // 'use_count' -> use count [int] 51 // 'use_count' -> use count [int]
65 // 'size' -> size [int] 52 // 'size' -> size [int]
66 // } 53 // }
67 // } 54 // }
68 const char kPreferenceName[] = "SDCH";
69 const char kVersionKey[] = "version"; 55 const char kVersionKey[] = "version";
70 const char kDictionariesKey[] = "dictionaries"; 56 const char kDictionariesKey[] = "dictionaries";
71 const char kDictionaryUrlKey[] = "url"; 57 const char kDictionaryUrlKey[] = "url";
72 const char kDictionaryLastUsedKey[] = "last_used"; 58 const char kDictionaryLastUsedKey[] = "last_used";
73 const char kDictionaryCreatedTimeKey[] = "created_time"; 59 const char kDictionaryCreatedTimeKey[] = "created_time";
74 const char kDictionaryUseCountKey[] = "use_count"; 60 const char kDictionaryUseCountKey[] = "use_count";
75 const char kDictionarySizeKey[] = "size"; 61 const char kDictionarySizeKey[] = "size";
76 62
77 const int kVersion = 2; 63 const int kVersion = 2;
78 64
65 // A simple implementation of pref storage that just stores the value in
66 // memory.
67 class ValueMapPrefStorage : public SdchOwner::PrefStorage {
68 public:
69 ValueMapPrefStorage() {}
70 ~ValueMapPrefStorage() override {}
71
72 ReadError GetReadError() const override { return PERSISTENCE_FAILURE_NONE; }
73
74 bool GetValue(const base::DictionaryValue** result) const override {
75 *result = &storage_;
76 return true;
77 }
78 bool GetMutableValue(base::DictionaryValue** result) override {
79 *result = &storage_;
80 return true;
81 }
82 void SetValue(scoped_ptr<base::DictionaryValue> value) override {
83 storage_.Clear();
84 storage_.MergeDictionary(value.get());
85 }
86
87 void ReportValueChanged() override {}
88
89 // This storage class requires no special initialization.
90 bool IsInitializationComplete() override { return true; }
91 void StartObservingInit(SdchOwner* observer) override {}
92 void StopObservingInit() override {}
93
94 private:
95 base::DictionaryValue storage_;
96
97 DISALLOW_COPY_AND_ASSIGN(ValueMapPrefStorage);
98 };
99
79 // This function returns store[kPreferenceName/kDictionariesKey]. The caller 100 // This function returns store[kPreferenceName/kDictionariesKey]. The caller
80 // is responsible for making sure any needed calls to 101 // is responsible for making sure any needed calls to
81 // |store->ReportValueChanged()| occur. 102 // |store->ReportValueChanged()| occur.
82 base::DictionaryValue* GetPersistentStoreDictionaryMap( 103 base::DictionaryValue* GetPersistentStoreDictionaryMap(
83 WriteablePrefStore* store) { 104 SdchOwner::PrefStorage* store) {
84 base::Value* result = nullptr; 105 base::DictionaryValue* preference_dictionary = nullptr;
85 bool success = store->GetMutableValue(kPreferenceName, &result); 106 bool success = store->GetMutableValue(&preference_dictionary);
86 DCHECK(success); 107 DCHECK(success);
87 108
88 base::DictionaryValue* preference_dictionary = nullptr;
89 success = result->GetAsDictionary(&preference_dictionary);
90 DCHECK(success);
91 DCHECK(preference_dictionary);
92
93 base::DictionaryValue* dictionary_list_dictionary = nullptr; 109 base::DictionaryValue* dictionary_list_dictionary = nullptr;
94 success = preference_dictionary->GetDictionary(kDictionariesKey, 110 success = preference_dictionary->GetDictionary(kDictionariesKey,
95 &dictionary_list_dictionary); 111 &dictionary_list_dictionary);
96 DCHECK(success); 112 DCHECK(success);
97 DCHECK(dictionary_list_dictionary); 113 DCHECK(dictionary_list_dictionary);
98 114
99 return dictionary_list_dictionary; 115 return dictionary_list_dictionary;
100 } 116 }
101 117
102 // This function initializes a pref store with an empty version of the 118 // This function initializes a pref store with an empty version of the
103 // above schema, removing anything previously in the store under 119 // above schema, removing anything previously in the store under
104 // kPreferenceName. 120 // kPreferenceName.
105 void InitializePrefStore(WriteablePrefStore* store) { 121 void InitializePrefStore(SdchOwner::PrefStorage* store) {
106 scoped_ptr<base::DictionaryValue> empty_store(new base::DictionaryValue); 122 scoped_ptr<base::DictionaryValue> empty_store(new base::DictionaryValue);
107 empty_store->SetInteger(kVersionKey, kVersion); 123 empty_store->SetInteger(kVersionKey, kVersion);
108 empty_store->Set(kDictionariesKey, 124 empty_store->Set(kDictionariesKey,
109 make_scoped_ptr(new base::DictionaryValue)); 125 make_scoped_ptr(new base::DictionaryValue));
110 store->SetValue(kPreferenceName, std::move(empty_store), 126 store->SetValue(std::move(empty_store));
111 WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
112 } 127 }
113 128
114 // A class to allow iteration over all dictionaries in the pref store, and 129 // A class to allow iteration over all dictionaries in the pref store, and
115 // easy lookup of the information associated with those dictionaries. 130 // easy lookup of the information associated with those dictionaries.
116 // Note that this is an "Iterator" in the same sense (and for the same 131 // Note that this is an "Iterator" in the same sense (and for the same
117 // reasons) that base::Dictionary::Iterator is an iterator--it allows 132 // reasons) that base::Dictionary::Iterator is an iterator--it allows
118 // iterating over all the dictionaries in the preference store, but it 133 // iterating over all the dictionaries in the preference store, but it
119 // does not allow use as an STL iterator because the container it 134 // does not allow use as an STL iterator because the container it
120 // is iterating over does not export begin()/end() methods. This iterator can 135 // is iterating over does not export begin()/end() methods. This iterator can
121 // only be safely used on sanitized pref stores that are known to conform to the 136 // only be safely used on sanitized pref stores that are known to conform to the
122 // pref store schema. 137 // pref store schema.
123 class DictionaryPreferenceIterator { 138 class DictionaryPreferenceIterator {
124 public: 139 public:
125 explicit DictionaryPreferenceIterator(WriteablePrefStore* pref_store); 140 explicit DictionaryPreferenceIterator(SdchOwner::PrefStorage* pref_store);
126 141
127 bool IsAtEnd() const; 142 bool IsAtEnd() const;
128 void Advance(); 143 void Advance();
129 144
130 const std::string& server_hash() const { return server_hash_; } 145 const std::string& server_hash() const { return server_hash_; }
131 const GURL& url() const { return url_; } 146 const GURL& url() const { return url_; }
132 base::Time last_used() const { return last_used_; } 147 base::Time last_used() const { return last_used_; }
133 base::Time created_time() const { return created_time_; } 148 base::Time created_time() const { return created_time_; }
134 int use_count() const { return use_count_; } 149 int use_count() const { return use_count_; }
135 int size() const { return size_; } 150 int size() const { return size_; }
136 151
137 private: 152 private:
138 // Load Dictionary silently skipping any that are malformed. 153 // Load Dictionary silently skipping any that are malformed.
139 void LoadNextDictionary(); 154 void LoadNextDictionary();
140 // Try to load Dictionary from current iterator's position. Returns true if 155 // Try to load Dictionary from current iterator's position. Returns true if
141 // succeeded. 156 // succeeded.
142 bool TryLoadDictionary(); 157 bool TryLoadDictionary();
143 158
144 std::string server_hash_; 159 std::string server_hash_;
145 GURL url_; 160 GURL url_;
146 base::Time last_used_; 161 base::Time last_used_;
147 base::Time created_time_; 162 base::Time created_time_;
148 int use_count_; 163 int use_count_;
149 int size_; 164 int size_;
150 165
151 base::DictionaryValue::Iterator dictionary_iterator_; 166 base::DictionaryValue::Iterator dictionary_iterator_;
152 }; 167 };
153 168
154 DictionaryPreferenceIterator::DictionaryPreferenceIterator( 169 DictionaryPreferenceIterator::DictionaryPreferenceIterator(
155 WriteablePrefStore* pref_store) 170 SdchOwner::PrefStorage* pref_store)
156 : use_count_(0), 171 : use_count_(0),
157 size_(0), 172 size_(0),
158 dictionary_iterator_(*GetPersistentStoreDictionaryMap(pref_store)) { 173 dictionary_iterator_(*GetPersistentStoreDictionaryMap(pref_store)) {
159 LoadNextDictionary(); 174 LoadNextDictionary();
160 } 175 }
161 176
162 bool DictionaryPreferenceIterator::IsAtEnd() const { 177 bool DictionaryPreferenceIterator::IsAtEnd() const {
163 return dictionary_iterator_.IsAtEnd(); 178 return dictionary_iterator_.IsAtEnd();
164 } 179 }
165 180
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
208 223
209 double created_time_seconds = 0; 224 double created_time_seconds = 0;
210 success = dict->GetDouble(kDictionaryCreatedTimeKey, &created_time_seconds); 225 success = dict->GetDouble(kDictionaryCreatedTimeKey, &created_time_seconds);
211 if (!success) 226 if (!success)
212 return false; 227 return false;
213 created_time_ = base::Time::FromDoubleT(created_time_seconds); 228 created_time_ = base::Time::FromDoubleT(created_time_seconds);
214 229
215 return true; 230 return true;
216 } 231 }
217 232
218 // Triggers a ReportValueChanged() on the specified WriteablePrefStore 233 // Triggers a ReportValueChanged() when the object goes out of scope.
219 // when the object goes out of scope.
220 class ScopedPrefNotifier { 234 class ScopedPrefNotifier {
221 public: 235 public:
222 // Caller must guarantee lifetime of |*pref_store| exceeds the 236 // Caller must guarantee lifetime of |*pref_store| exceeds the
223 // lifetime of this object. 237 // lifetime of this object.
224 ScopedPrefNotifier(WriteablePrefStore* pref_store) 238 ScopedPrefNotifier(SdchOwner::PrefStorage* pref_store)
225 : pref_store_(pref_store) {} 239 : pref_store_(pref_store) {
226 ~ScopedPrefNotifier() { 240 DCHECK(pref_store);
227 pref_store_->ReportValueChanged(
228 kPreferenceName, WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
229 } 241 }
242 ~ScopedPrefNotifier() { pref_store_->ReportValueChanged(); }
230 243
231 private: 244 private:
232 WriteablePrefStore* pref_store_; 245 SdchOwner::PrefStorage* pref_store_;
233 246
234 DISALLOW_COPY_AND_ASSIGN(ScopedPrefNotifier); 247 DISALLOW_COPY_AND_ASSIGN(ScopedPrefNotifier);
235 }; 248 };
236 249
237 } // namespace 250 } // namespace
238 251
239 // Adjust SDCH limits downwards for mobile. 252 // Adjust SDCH limits downwards for mobile.
240 #if defined(OS_ANDROID) || defined(OS_IOS) 253 #if defined(OS_ANDROID) || defined(OS_IOS)
241 // static 254 // static
242 const size_t SdchOwner::kMaxTotalDictionarySize = 2 * 500 * 1000; 255 const size_t SdchOwner::kMaxTotalDictionarySize = 2 * 500 * 1000;
243 #else 256 #else
244 // static 257 // static
245 const size_t SdchOwner::kMaxTotalDictionarySize = 20 * 1000 * 1000; 258 const size_t SdchOwner::kMaxTotalDictionarySize = 20 * 1000 * 1000;
246 #endif 259 #endif
247 260
261 SdchOwner::PrefStorage::~PrefStorage() {}
262
248 // Somewhat arbitrary, but we assume a dictionary smaller than 263 // Somewhat arbitrary, but we assume a dictionary smaller than
249 // 50K isn't going to do anyone any good. Note that this still doesn't 264 // 50K isn't going to do anyone any good. Note that this still doesn't
250 // prevent download and addition unless there is less than this 265 // prevent download and addition unless there is less than this
251 // amount of space available in storage. 266 // amount of space available in storage.
252 const size_t SdchOwner::kMinSpaceForDictionaryFetch = 50 * 1000; 267 const size_t SdchOwner::kMinSpaceForDictionaryFetch = 50 * 1000;
253 268
254 void SdchOwner::RecordDictionaryFate(enum DictionaryFate fate) { 269 void SdchOwner::RecordDictionaryFate(enum DictionaryFate fate) {
255 UMA_HISTOGRAM_ENUMERATION("Sdch3.DictionaryFate", fate, DICTIONARY_FATE_MAX); 270 UMA_HISTOGRAM_ENUMERATION("Sdch3.DictionaryFate", fate, DICTIONARY_FATE_MAX);
256 } 271 }
257 272
(...skipping 22 matching lines...) Expand all
280 total_dictionary_bytes_(0), 295 total_dictionary_bytes_(0),
281 clock_(new base::DefaultClock), 296 clock_(new base::DefaultClock),
282 max_total_dictionary_size_(kMaxTotalDictionarySize), 297 max_total_dictionary_size_(kMaxTotalDictionarySize),
283 min_space_for_dictionary_fetch_(kMinSpaceForDictionaryFetch), 298 min_space_for_dictionary_fetch_(kMinSpaceForDictionaryFetch),
284 memory_pressure_listener_( 299 memory_pressure_listener_(
285 base::Bind(&SdchOwner::OnMemoryPressure, 300 base::Bind(&SdchOwner::OnMemoryPressure,
286 // Because |memory_pressure_listener_| is owned by 301 // Because |memory_pressure_listener_| is owned by
287 // SdchOwner, the SdchOwner object will be available 302 // SdchOwner, the SdchOwner object will be available
288 // for the lifetime of |memory_pressure_listener_|. 303 // for the lifetime of |memory_pressure_listener_|.
289 base::Unretained(this))), 304 base::Unretained(this))),
290 in_memory_pref_store_(new ValueMapPrefStore()), 305 in_memory_pref_store_(new ValueMapPrefStorage()),
291 external_pref_store_(nullptr), 306 external_pref_store_(nullptr),
292 pref_store_(in_memory_pref_store_.get()), 307 pref_store_(in_memory_pref_store_.get()),
293 creation_time_(clock_->Now()) { 308 creation_time_(clock_->Now()) {
294 manager_->AddObserver(this); 309 manager_->AddObserver(this);
295 InitializePrefStore(pref_store_); 310 InitializePrefStore(pref_store_);
296 } 311 }
297 312
298 SdchOwner::~SdchOwner() { 313 SdchOwner::~SdchOwner() {
299 for (DictionaryPreferenceIterator it(pref_store_); !it.IsAtEnd(); 314 for (DictionaryPreferenceIterator it(pref_store_); !it.IsAtEnd();
300 it.Advance()) { 315 it.Advance()) {
301 int new_uses = it.use_count() - use_counts_at_load_[it.server_hash()]; 316 int new_uses = it.use_count() - use_counts_at_load_[it.server_hash()];
302 DictionaryFate fate = IsPersistingDictionaries() ? 317 DictionaryFate fate = IsPersistingDictionaries() ?
303 DICTIONARY_FATE_UNLOAD_FOR_DESTRUCTION : 318 DICTIONARY_FATE_UNLOAD_FOR_DESTRUCTION :
304 DICTIONARY_FATE_EVICT_FOR_DESTRUCTION; 319 DICTIONARY_FATE_EVICT_FOR_DESTRUCTION;
305 RecordDictionaryEvictionOrUnload(it.server_hash(), it.size(), new_uses, 320 RecordDictionaryEvictionOrUnload(it.server_hash(), it.size(), new_uses,
306 fate); 321 fate);
307 } 322 }
308 manager_->RemoveObserver(this); 323 manager_->RemoveObserver(this);
309 324
310 // This object only observes the external store during loading, 325 // This object only observes the external store during loading,
311 // i.e. before it's made the default preferences store. 326 // i.e. before it's made the default preferences store.
312 if (external_pref_store_) 327 if (external_pref_store_ && pref_store_ != external_pref_store_.get())
313 external_pref_store_->RemoveObserver(this); 328 external_pref_store_->StopObservingInit();
314 329
315 int64_t object_lifetime = (clock_->Now() - creation_time_).InMilliseconds(); 330 int64_t object_lifetime = (clock_->Now() - creation_time_).InMilliseconds();
316 for (const auto& val : consumed_byte_seconds_) { 331 for (const auto& val : consumed_byte_seconds_) {
317 if (object_lifetime > 0) { 332 if (object_lifetime > 0) {
318 // Objects that are created and immediately destroyed don't add any memory 333 // Objects that are created and immediately destroyed don't add any memory
319 // pressure over time (and also cause a crash here). 334 // pressure over time (and also cause a crash here).
320 UMA_HISTOGRAM_MEMORY_KB("Sdch3.TimeWeightedMemoryUse", 335 UMA_HISTOGRAM_MEMORY_KB("Sdch3.TimeWeightedMemoryUse",
321 val / object_lifetime); 336 val / object_lifetime);
322 } 337 }
323 } 338 }
324
325 } 339 }
326 340
327 void SdchOwner::EnablePersistentStorage(PersistentPrefStore* pref_store) { 341 void SdchOwner::EnablePersistentStorage(scoped_ptr<PrefStorage> pref_store) {
328 DCHECK(!external_pref_store_); 342 DCHECK(!external_pref_store_);
329 external_pref_store_ = pref_store; 343 DCHECK(pref_store);
330 external_pref_store_->AddObserver(this); 344 external_pref_store_ = std::move(pref_store);
345 external_pref_store_->StartObservingInit(this);
331 346
332 if (external_pref_store_->IsInitializationComplete()) 347 if (external_pref_store_->IsInitializationComplete())
333 OnInitializationCompleted(true); 348 OnPrefStorageInitializationComplete(true);
334 } 349 }
335 350
336 void SdchOwner::SetMaxTotalDictionarySize(size_t max_total_dictionary_size) { 351 void SdchOwner::SetMaxTotalDictionarySize(size_t max_total_dictionary_size) {
337 max_total_dictionary_size_ = max_total_dictionary_size; 352 max_total_dictionary_size_ = max_total_dictionary_size;
338 } 353 }
339 354
340 void SdchOwner::SetMinSpaceForDictionaryFetch( 355 void SdchOwner::SetMinSpaceForDictionaryFetch(
341 size_t min_space_for_dictionary_fetch) { 356 size_t min_space_for_dictionary_fetch) {
342 min_space_for_dictionary_fetch_ = min_space_for_dictionary_fetch; 357 min_space_for_dictionary_fetch_ = min_space_for_dictionary_fetch;
343 } 358 }
(...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after
574 base::Unretained(this), base::Time(), base::Time::Now(), 0)); 589 base::Unretained(this), base::Time(), base::Time::Now(), 0));
575 } 590 }
576 591
577 void SdchOwner::OnClearDictionaries() { 592 void SdchOwner::OnClearDictionaries() {
578 total_dictionary_bytes_ = 0; 593 total_dictionary_bytes_ = 0;
579 fetcher_->Cancel(); 594 fetcher_->Cancel();
580 595
581 InitializePrefStore(pref_store_); 596 InitializePrefStore(pref_store_);
582 } 597 }
583 598
584 void SdchOwner::OnPrefValueChanged(const std::string& key) { 599 void SdchOwner::OnPrefStorageInitializationComplete(bool succeeded) {
585 } 600 PrefStorage::ReadError error = external_pref_store_->GetReadError();
586
587 void SdchOwner::OnInitializationCompleted(bool succeeded) {
588 PersistentPrefStore::PrefReadError error =
589 external_pref_store_->GetReadError();
590 // Errors on load are self-correcting; if dictionaries were not 601 // Errors on load are self-correcting; if dictionaries were not
591 // persisted from the last instance of the browser, they will be 602 // persisted from the last instance of the browser, they will be
592 // faulted in by user action over time. However, if a load error 603 // faulted in by user action over time. However, if a load error
593 // means that the dictionary information won't be able to be persisted, 604 // means that the dictionary information won't be able to be persisted,
594 // the in memory pref store is left in place. 605 // the in memory pref store is left in place.
595 if (!succeeded) { 606 if (!succeeded) {
596 // Failure means a write failed, since read failures are recoverable. 607 // Failure means a write failed, since read failures are recoverable.
597 DCHECK_NE( 608 external_pref_store_->StopObservingInit();
598 error,
599 PersistentPrefStore::PREF_READ_ERROR_ASYNCHRONOUS_TASK_INCOMPLETE);
600 DCHECK_NE(error,
601 PersistentPrefStore::PREF_READ_ERROR_MAX_ENUM);
602
603 LOG(ERROR) << "Pref store write failed: " << error;
604 external_pref_store_->RemoveObserver(this);
605 external_pref_store_ = nullptr; 609 external_pref_store_ = nullptr;
606 RecordPersistenceFailure(PERSISTENCE_FAILURE_REASON_WRITE_FAILED); 610 RecordPersistenceFailure(
611 PrefStorage::PERSISTENCE_FAILURE_REASON_WRITE_FAILED);
607 return; 612 return;
608 } 613 }
609 switch (external_pref_store_->GetReadError()) {
610 case PersistentPrefStore::PREF_READ_ERROR_NONE:
611 break;
612 614
613 case PersistentPrefStore::PREF_READ_ERROR_NO_FILE: 615 if (error != PrefStorage::PERSISTENCE_FAILURE_NONE)
614 // First time reading; the file will be created. 616 RecordPersistenceFailure(error);
615 RecordPersistenceFailure(PERSISTENCE_FAILURE_REASON_NO_FILE);
616 break;
617
618 case PersistentPrefStore::PREF_READ_ERROR_JSON_PARSE:
619 case PersistentPrefStore::PREF_READ_ERROR_JSON_TYPE:
620 case PersistentPrefStore::PREF_READ_ERROR_FILE_OTHER:
621 case PersistentPrefStore::PREF_READ_ERROR_FILE_LOCKED:
622 case PersistentPrefStore::PREF_READ_ERROR_JSON_REPEAT:
623 RecordPersistenceFailure(PERSISTENCE_FAILURE_REASON_READ_FAILED);
624 break;
625
626 case PersistentPrefStore::PREF_READ_ERROR_ACCESS_DENIED:
627 case PersistentPrefStore::PREF_READ_ERROR_FILE_NOT_SPECIFIED:
628 case PersistentPrefStore::PREF_READ_ERROR_ASYNCHRONOUS_TASK_INCOMPLETE:
629 case PersistentPrefStore::PREF_READ_ERROR_MAX_ENUM:
630 // Shouldn't ever happen. ACCESS_DENIED and FILE_NOT_SPECIFIED should
631 // imply !succeeded, and TASK_INCOMPLETE should never be delivered.
632 NOTREACHED();
633 break;
634 }
635
636 617
637 // Load in what was stored before chrome exited previously. 618 // Load in what was stored before chrome exited previously.
638 const base::Value* sdch_persistence_value = nullptr;
639 const base::DictionaryValue* sdch_persistence_dictionary = nullptr; 619 const base::DictionaryValue* sdch_persistence_dictionary = nullptr;
640 620
641 // The GetPersistentStore() routine above assumes data formatted 621 // The GetPersistentStore() routine above assumes data formatted
642 // according to the schema described at the top of this file. Since 622 // according to the schema described at the top of this file. Since
643 // this data comes from disk, to avoid disk corruption resulting in 623 // this data comes from disk, to avoid disk corruption resulting in
644 // persistent chrome errors this code avoids those assupmtions. 624 // persistent chrome errors this code avoids those assupmtions.
645 if (external_pref_store_->GetValue(kPreferenceName, 625 if (external_pref_store_->GetValue(&sdch_persistence_dictionary))
646 &sdch_persistence_value) &&
647 sdch_persistence_value->GetAsDictionary(&sdch_persistence_dictionary)) {
648 SchedulePersistedDictionaryLoads(*sdch_persistence_dictionary); 626 SchedulePersistedDictionaryLoads(*sdch_persistence_dictionary);
649 }
650 627
651 // Reset the persistent store and update it with the accumulated 628 // Reset the persistent store and update it with the accumulated
652 // information from the local store. 629 // information from the local store.
653 InitializePrefStore(external_pref_store_); 630 InitializePrefStore(external_pref_store_.get());
654 631
655 ScopedPrefNotifier scoped_pref_notifier(external_pref_store_); 632 ScopedPrefNotifier scoped_pref_notifier(external_pref_store_.get());
656 GetPersistentStoreDictionaryMap(external_pref_store_) 633 GetPersistentStoreDictionaryMap(external_pref_store_.get())
657 ->Swap(GetPersistentStoreDictionaryMap(in_memory_pref_store_.get())); 634 ->Swap(GetPersistentStoreDictionaryMap(in_memory_pref_store_.get()));
658 635
659 // This object can stop waiting on (i.e. observing) the external preference 636 // This object can stop waiting on (i.e. observing) the external preference
660 // store and switch over to using it as the primary preference store. 637 // store and switch over to using it as the primary preference store.
661 pref_store_ = external_pref_store_; 638 pref_store_ = external_pref_store_.get();
662 external_pref_store_->RemoveObserver(this); 639 external_pref_store_->StopObservingInit();
663 external_pref_store_ = nullptr;
664 in_memory_pref_store_ = nullptr; 640 in_memory_pref_store_ = nullptr;
665 } 641 }
666 642
667 void SdchOwner::SetClockForTesting(scoped_ptr<base::Clock> clock) { 643 void SdchOwner::SetClockForTesting(scoped_ptr<base::Clock> clock) {
668 clock_ = std::move(clock); 644 clock_ = std::move(clock);
669 } 645 }
670 646
671 int SdchOwner::GetDictionaryCountForTesting() const { 647 int SdchOwner::GetDictionaryCountForTesting() const {
672 int count = 0; 648 int count = 0;
673 for (DictionaryPreferenceIterator it(pref_store_); !it.IsAtEnd(); 649 for (DictionaryPreferenceIterator it(pref_store_); !it.IsAtEnd();
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
760 } 736 }
761 737
762 return true; 738 return true;
763 } 739 }
764 740
765 bool SdchOwner::IsPersistingDictionaries() const { 741 bool SdchOwner::IsPersistingDictionaries() const {
766 return in_memory_pref_store_.get() != nullptr; 742 return in_memory_pref_store_.get() != nullptr;
767 } 743 }
768 744
769 } // namespace net 745 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698