Roll src/third_party/WebKit a3b4a2e:7441784 (svn 202551:202552)
[chromium-blink-merge.git] / extensions / browser / value_store / value_store_frontend.cc
blob33cdce72a5c55c9a0ccefa7cc48956f1b97eec9c
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.
5 #include "extensions/browser/value_store/value_store_frontend.h"
7 #include "base/bind.h"
8 #include "base/files/file_path.h"
9 #include "base/logging.h"
10 #include "base/trace_event/trace_event.h"
11 #include "content/public/browser/browser_thread.h"
12 #include "extensions/browser/value_store/leveldb_value_store.h"
14 using content::BrowserThread;
16 class ValueStoreFrontend::Backend : public base::RefCountedThreadSafe<Backend> {
17 public:
18 Backend() : storage_(NULL) {}
20 void Init(const std::string& uma_client_name, const base::FilePath& db_path) {
21 DCHECK_CURRENTLY_ON(BrowserThread::FILE);
22 DCHECK(!storage_);
23 TRACE_EVENT0("ValueStoreFrontend::Backend", "Init");
24 db_path_ = db_path;
25 storage_ = new LeveldbValueStore(uma_client_name, db_path);
28 // This variant is useful for testing (using a mock ValueStore).
29 void InitWithStore(scoped_ptr<ValueStore> storage) {
30 DCHECK_CURRENTLY_ON(BrowserThread::FILE);
31 DCHECK(!storage_);
32 storage_ = storage.release();
35 void Get(const std::string& key,
36 const ValueStoreFrontend::ReadCallback& callback) {
37 DCHECK_CURRENTLY_ON(BrowserThread::FILE);
38 ValueStore::ReadResult result = storage_->Get(key);
40 // Extract the value from the ReadResult and pass ownership of it to the
41 // callback.
42 scoped_ptr<base::Value> value;
43 if (!result->HasError()) {
44 result->settings().RemoveWithoutPathExpansion(key, &value);
45 } else {
46 LOG(WARNING) << "Reading " << key << " from " << db_path_.value()
47 << " failed: " << result->error().message;
50 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
51 base::Bind(&ValueStoreFrontend::Backend::RunCallback,
52 this, callback, base::Passed(&value)));
55 void Set(const std::string& key, scoped_ptr<base::Value> value) {
56 DCHECK_CURRENTLY_ON(BrowserThread::FILE);
57 // We don't need the old value, so skip generating changes.
58 ValueStore::WriteResult result = storage_->Set(
59 ValueStore::IGNORE_QUOTA | ValueStore::NO_GENERATE_CHANGES,
60 key,
61 *value.get());
62 LOG_IF(ERROR, result->HasError()) << "Error while writing " << key << " to "
63 << db_path_.value();
66 void Remove(const std::string& key) {
67 DCHECK_CURRENTLY_ON(BrowserThread::FILE);
68 storage_->Remove(key);
71 private:
72 friend class base::RefCountedThreadSafe<Backend>;
74 virtual ~Backend() {
75 if (BrowserThread::CurrentlyOn(BrowserThread::FILE)) {
76 delete storage_;
77 } else {
78 BrowserThread::DeleteSoon(BrowserThread::FILE, FROM_HERE, storage_);
82 void RunCallback(const ValueStoreFrontend::ReadCallback& callback,
83 scoped_ptr<base::Value> value) {
84 DCHECK_CURRENTLY_ON(BrowserThread::UI);
85 callback.Run(value.Pass());
88 // The actual ValueStore that handles persisting the data to disk. Used
89 // exclusively on the FILE thread.
90 ValueStore* storage_;
92 base::FilePath db_path_;
94 DISALLOW_COPY_AND_ASSIGN(Backend);
97 ValueStoreFrontend::ValueStoreFrontend()
98 : backend_(new Backend()) {
101 ValueStoreFrontend::ValueStoreFrontend(const std::string& uma_client_name,
102 const base::FilePath& db_path)
103 : backend_(new Backend()) {
104 Init(uma_client_name, db_path);
107 ValueStoreFrontend::ValueStoreFrontend(scoped_ptr<ValueStore> value_store)
108 : backend_(new Backend()) {
109 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
110 base::Bind(&ValueStoreFrontend::Backend::InitWithStore,
111 backend_, base::Passed(&value_store)));
114 ValueStoreFrontend::~ValueStoreFrontend() {
115 DCHECK(CalledOnValidThread());
118 void ValueStoreFrontend::Init(const std::string& uma_client_name,
119 const base::FilePath& db_path) {
120 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
121 base::Bind(&ValueStoreFrontend::Backend::Init,
122 backend_, uma_client_name, db_path));
125 void ValueStoreFrontend::Get(const std::string& key,
126 const ReadCallback& callback) {
127 DCHECK(CalledOnValidThread());
129 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
130 base::Bind(&ValueStoreFrontend::Backend::Get,
131 backend_, key, callback));
134 void ValueStoreFrontend::Set(const std::string& key,
135 scoped_ptr<base::Value> value) {
136 DCHECK(CalledOnValidThread());
138 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
139 base::Bind(&ValueStoreFrontend::Backend::Set,
140 backend_, key, base::Passed(&value)));
143 void ValueStoreFrontend::Remove(const std::string& key) {
144 DCHECK(CalledOnValidThread());
146 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
147 base::Bind(&ValueStoreFrontend::Backend::Remove,
148 backend_, key));