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#ifndef CHROME_BROWSER_PREFS_LEVELDB_PREF_STORE_H_
6#define CHROME_BROWSER_PREFS_LEVELDB_PREF_STORE_H_
7
8#include <set>
9#include <string>
10
11#include "base/basictypes.h"
12#include "base/compiler_specific.h"
13#include "base/files/file_path.h"
14#include "base/memory/scoped_ptr.h"
15#include "base/message_loop/message_loop_proxy.h"
16#include "base/observer_list.h"
17#include "base/prefs/persistent_pref_store.h"
18#include "base/prefs/pref_value_map.h"
19#include "base/timer/timer.h"
20
21namespace base {
22class DictionaryValue;
23class SequencedTaskRunner;
24class Value;
25}
26
27namespace leveldb {
28class DB;
29}
30
31// A writable PrefStore implementation that is used for user preferences.
32class LevelDBPrefStore : public PersistentPrefStore {
33 public:
34  // |sequenced_task_runner| is must be a shutdown-blocking task runner, ideally
35  // created by GetTaskRunnerForFile() method above.
36  LevelDBPrefStore(const base::FilePath& pref_filename,
37                   base::SequencedTaskRunner* sequenced_task_runner);
38
39  // PrefStore overrides:
40  virtual bool GetValue(const std::string& key,
41                        const base::Value** result) const OVERRIDE;
42  virtual void AddObserver(PrefStore::Observer* observer) OVERRIDE;
43  virtual void RemoveObserver(PrefStore::Observer* observer) OVERRIDE;
44  virtual bool HasObservers() const OVERRIDE;
45  virtual bool IsInitializationComplete() const OVERRIDE;
46
47  // PersistentPrefStore overrides:
48  virtual bool GetMutableValue(const std::string& key,
49                               base::Value** result) OVERRIDE;
50  // Takes ownership of value.
51  virtual void SetValue(const std::string& key, base::Value* value) OVERRIDE;
52  virtual void SetValueSilently(const std::string& key,
53                                base::Value* value) OVERRIDE;
54  virtual void RemoveValue(const std::string& key) OVERRIDE;
55  virtual bool ReadOnly() const OVERRIDE;
56  virtual PrefReadError GetReadError() const OVERRIDE;
57  virtual PrefReadError ReadPrefs() OVERRIDE;
58  virtual void ReadPrefsAsync(ReadErrorDelegate* error_delegate) OVERRIDE;
59  virtual void CommitPendingWrite() OVERRIDE;
60  virtual void ReportValueChanged(const std::string& key) OVERRIDE;
61
62 private:
63  struct ReadingResults;
64  class FileThreadSerializer;
65
66  virtual ~LevelDBPrefStore();
67
68  static scoped_ptr<ReadingResults> DoReading(const base::FilePath& path);
69  static void OpenDB(const base::FilePath& path,
70                     ReadingResults* reading_results);
71  void OnStorageRead(scoped_ptr<ReadingResults> reading_results);
72
73  void PersistFromUIThread();
74  void RemoveFromUIThread(const std::string& key);
75  void ScheduleWrite();
76
77  void SetValueInternal(const std::string& key,
78                        base::Value* value,
79                        bool notify);
80  void NotifyObservers(const std::string& key);
81  void MarkForInsertion(const std::string& key, const std::string& value);
82  void MarkForDeletion(const std::string& key);
83
84  base::FilePath path_;
85
86  const scoped_refptr<base::SequencedTaskRunner> sequenced_task_runner_;
87  const scoped_refptr<base::SequencedTaskRunner> original_task_runner_;
88
89  PrefValueMap prefs_;
90
91  bool read_only_;
92
93  ObserverList<PrefStore::Observer, true> observers_;
94
95  scoped_ptr<ReadErrorDelegate> error_delegate_;
96
97  bool initialized_;
98  PrefReadError read_error_;
99
100  // This object is created on the UI thread right after preferences are loaded
101  // from disk. A message to delete it is sent to the FILE thread by
102  // ~LevelDBPrefStore.
103  scoped_ptr<FileThreadSerializer> serializer_;
104
105  // Changes are accumulated in |keys_to_delete_| and |keys_to_set_| and are
106  // stored in the database according to |timer_|.
107  std::set<std::string> keys_to_delete_;
108  std::map<std::string, std::string> keys_to_set_;
109  base::OneShotTimer<LevelDBPrefStore> timer_;
110
111  base::WeakPtrFactory<LevelDBPrefStore> weak_ptr_factory_;
112
113  DISALLOW_COPY_AND_ASSIGN(LevelDBPrefStore);
114};
115
116#endif  // CHROME_BROWSER_PREFS_LEVELDB_PREF_STORE_H_
117