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

Side by Side Diff: base/prefs/json_pref_store.cc

Issue 12286020: Replace FilePath with base::FilePath. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 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 | Annotate | Revision Log
« no previous file with comments | « base/platform_file_unittest.cc ('k') | base/prefs/json_pref_store_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "base/prefs/json_pref_store.h" 5 #include "base/prefs/json_pref_store.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/callback.h" 10 #include "base/callback.h"
11 #include "base/file_util.h" 11 #include "base/file_util.h"
12 #include "base/json/json_file_value_serializer.h" 12 #include "base/json/json_file_value_serializer.h"
13 #include "base/json/json_string_value_serializer.h" 13 #include "base/json/json_string_value_serializer.h"
14 #include "base/memory/ref_counted.h" 14 #include "base/memory/ref_counted.h"
15 #include "base/message_loop_proxy.h" 15 #include "base/message_loop_proxy.h"
16 #include "base/sequenced_task_runner.h" 16 #include "base/sequenced_task_runner.h"
17 #include "base/threading/sequenced_worker_pool.h" 17 #include "base/threading/sequenced_worker_pool.h"
18 #include "base/values.h" 18 #include "base/values.h"
19 19
20 namespace { 20 namespace {
21 21
22 // Some extensions we'll tack on to copies of the Preferences files. 22 // Some extensions we'll tack on to copies of the Preferences files.
23 const FilePath::CharType* kBadExtension = FILE_PATH_LITERAL("bad"); 23 const base::FilePath::CharType* kBadExtension = FILE_PATH_LITERAL("bad");
24 24
25 // Differentiates file loading between origin thread and passed 25 // Differentiates file loading between origin thread and passed
26 // (aka file) thread. 26 // (aka file) thread.
27 class FileThreadDeserializer 27 class FileThreadDeserializer
28 : public base::RefCountedThreadSafe<FileThreadDeserializer> { 28 : public base::RefCountedThreadSafe<FileThreadDeserializer> {
29 public: 29 public:
30 FileThreadDeserializer(JsonPrefStore* delegate, 30 FileThreadDeserializer(JsonPrefStore* delegate,
31 base::SequencedTaskRunner* sequenced_task_runner) 31 base::SequencedTaskRunner* sequenced_task_runner)
32 : no_dir_(false), 32 : no_dir_(false),
33 error_(PersistentPrefStore::PREF_READ_ERROR_NONE), 33 error_(PersistentPrefStore::PREF_READ_ERROR_NONE),
34 delegate_(delegate), 34 delegate_(delegate),
35 sequenced_task_runner_(sequenced_task_runner), 35 sequenced_task_runner_(sequenced_task_runner),
36 origin_loop_proxy_(base::MessageLoopProxy::current()) { 36 origin_loop_proxy_(base::MessageLoopProxy::current()) {
37 } 37 }
38 38
39 void Start(const FilePath& path) { 39 void Start(const base::FilePath& path) {
40 DCHECK(origin_loop_proxy_->BelongsToCurrentThread()); 40 DCHECK(origin_loop_proxy_->BelongsToCurrentThread());
41 sequenced_task_runner_->PostTask( 41 sequenced_task_runner_->PostTask(
42 FROM_HERE, 42 FROM_HERE,
43 base::Bind(&FileThreadDeserializer::ReadFileAndReport, 43 base::Bind(&FileThreadDeserializer::ReadFileAndReport,
44 this, path)); 44 this, path));
45 } 45 }
46 46
47 // Deserializes JSON on the sequenced task runner. 47 // Deserializes JSON on the sequenced task runner.
48 void ReadFileAndReport(const FilePath& path) { 48 void ReadFileAndReport(const base::FilePath& path) {
49 DCHECK(sequenced_task_runner_->RunsTasksOnCurrentThread()); 49 DCHECK(sequenced_task_runner_->RunsTasksOnCurrentThread());
50 50
51 value_.reset(DoReading(path, &error_, &no_dir_)); 51 value_.reset(DoReading(path, &error_, &no_dir_));
52 52
53 origin_loop_proxy_->PostTask( 53 origin_loop_proxy_->PostTask(
54 FROM_HERE, 54 FROM_HERE,
55 base::Bind(&FileThreadDeserializer::ReportOnOriginThread, this)); 55 base::Bind(&FileThreadDeserializer::ReportOnOriginThread, this));
56 } 56 }
57 57
58 // Reports deserialization result on the origin thread. 58 // Reports deserialization result on the origin thread.
59 void ReportOnOriginThread() { 59 void ReportOnOriginThread() {
60 DCHECK(origin_loop_proxy_->BelongsToCurrentThread()); 60 DCHECK(origin_loop_proxy_->BelongsToCurrentThread());
61 delegate_->OnFileRead(value_.release(), error_, no_dir_); 61 delegate_->OnFileRead(value_.release(), error_, no_dir_);
62 } 62 }
63 63
64 static Value* DoReading(const FilePath& path, 64 static Value* DoReading(const base::FilePath& path,
65 PersistentPrefStore::PrefReadError* error, 65 PersistentPrefStore::PrefReadError* error,
66 bool* no_dir) { 66 bool* no_dir) {
67 int error_code; 67 int error_code;
68 std::string error_msg; 68 std::string error_msg;
69 JSONFileValueSerializer serializer(path); 69 JSONFileValueSerializer serializer(path);
70 Value* value = serializer.Deserialize(&error_code, &error_msg); 70 Value* value = serializer.Deserialize(&error_code, &error_msg);
71 HandleErrors(value, path, error_code, error_msg, error); 71 HandleErrors(value, path, error_code, error_msg, error);
72 *no_dir = !file_util::PathExists(path.DirName()); 72 *no_dir = !file_util::PathExists(path.DirName());
73 return value; 73 return value;
74 } 74 }
75 75
76 static void HandleErrors(const Value* value, 76 static void HandleErrors(const Value* value,
77 const FilePath& path, 77 const base::FilePath& path,
78 int error_code, 78 int error_code,
79 const std::string& error_msg, 79 const std::string& error_msg,
80 PersistentPrefStore::PrefReadError* error); 80 PersistentPrefStore::PrefReadError* error);
81 81
82 private: 82 private:
83 friend class base::RefCountedThreadSafe<FileThreadDeserializer>; 83 friend class base::RefCountedThreadSafe<FileThreadDeserializer>;
84 ~FileThreadDeserializer() {} 84 ~FileThreadDeserializer() {}
85 85
86 bool no_dir_; 86 bool no_dir_;
87 PersistentPrefStore::PrefReadError error_; 87 PersistentPrefStore::PrefReadError error_;
88 scoped_ptr<Value> value_; 88 scoped_ptr<Value> value_;
89 const scoped_refptr<JsonPrefStore> delegate_; 89 const scoped_refptr<JsonPrefStore> delegate_;
90 const scoped_refptr<base::SequencedTaskRunner> sequenced_task_runner_; 90 const scoped_refptr<base::SequencedTaskRunner> sequenced_task_runner_;
91 const scoped_refptr<base::MessageLoopProxy> origin_loop_proxy_; 91 const scoped_refptr<base::MessageLoopProxy> origin_loop_proxy_;
92 }; 92 };
93 93
94 // static 94 // static
95 void FileThreadDeserializer::HandleErrors( 95 void FileThreadDeserializer::HandleErrors(
96 const Value* value, 96 const Value* value,
97 const FilePath& path, 97 const base::FilePath& path,
98 int error_code, 98 int error_code,
99 const std::string& error_msg, 99 const std::string& error_msg,
100 PersistentPrefStore::PrefReadError* error) { 100 PersistentPrefStore::PrefReadError* error) {
101 *error = PersistentPrefStore::PREF_READ_ERROR_NONE; 101 *error = PersistentPrefStore::PREF_READ_ERROR_NONE;
102 if (!value) { 102 if (!value) {
103 DVLOG(1) << "Error while loading JSON file: " << error_msg 103 DVLOG(1) << "Error while loading JSON file: " << error_msg
104 << ", file: " << path.value(); 104 << ", file: " << path.value();
105 switch (error_code) { 105 switch (error_code) {
106 case JSONFileValueSerializer::JSON_ACCESS_DENIED: 106 case JSONFileValueSerializer::JSON_ACCESS_DENIED:
107 *error = PersistentPrefStore::PREF_READ_ERROR_ACCESS_DENIED; 107 *error = PersistentPrefStore::PREF_READ_ERROR_ACCESS_DENIED;
108 break; 108 break;
109 case JSONFileValueSerializer::JSON_CANNOT_READ_FILE: 109 case JSONFileValueSerializer::JSON_CANNOT_READ_FILE:
110 *error = PersistentPrefStore::PREF_READ_ERROR_FILE_OTHER; 110 *error = PersistentPrefStore::PREF_READ_ERROR_FILE_OTHER;
111 break; 111 break;
112 case JSONFileValueSerializer::JSON_FILE_LOCKED: 112 case JSONFileValueSerializer::JSON_FILE_LOCKED:
113 *error = PersistentPrefStore::PREF_READ_ERROR_FILE_LOCKED; 113 *error = PersistentPrefStore::PREF_READ_ERROR_FILE_LOCKED;
114 break; 114 break;
115 case JSONFileValueSerializer::JSON_NO_SUCH_FILE: 115 case JSONFileValueSerializer::JSON_NO_SUCH_FILE:
116 *error = PersistentPrefStore::PREF_READ_ERROR_NO_FILE; 116 *error = PersistentPrefStore::PREF_READ_ERROR_NO_FILE;
117 break; 117 break;
118 default: 118 default:
119 *error = PersistentPrefStore::PREF_READ_ERROR_JSON_PARSE; 119 *error = PersistentPrefStore::PREF_READ_ERROR_JSON_PARSE;
120 // JSON errors indicate file corruption of some sort. 120 // JSON errors indicate file corruption of some sort.
121 // Since the file is corrupt, move it to the side and continue with 121 // Since the file is corrupt, move it to the side and continue with
122 // empty preferences. This will result in them losing their settings. 122 // empty preferences. This will result in them losing their settings.
123 // We keep the old file for possible support and debugging assistance 123 // We keep the old file for possible support and debugging assistance
124 // as well as to detect if they're seeing these errors repeatedly. 124 // as well as to detect if they're seeing these errors repeatedly.
125 // TODO(erikkay) Instead, use the last known good file. 125 // TODO(erikkay) Instead, use the last known good file.
126 FilePath bad = path.ReplaceExtension(kBadExtension); 126 base::FilePath bad = path.ReplaceExtension(kBadExtension);
127 127
128 // If they've ever had a parse error before, put them in another bucket. 128 // If they've ever had a parse error before, put them in another bucket.
129 // TODO(erikkay) if we keep this error checking for very long, we may 129 // TODO(erikkay) if we keep this error checking for very long, we may
130 // want to differentiate between recent and long ago errors. 130 // want to differentiate between recent and long ago errors.
131 if (file_util::PathExists(bad)) 131 if (file_util::PathExists(bad))
132 *error = PersistentPrefStore::PREF_READ_ERROR_JSON_REPEAT; 132 *error = PersistentPrefStore::PREF_READ_ERROR_JSON_REPEAT;
133 file_util::Move(path, bad); 133 file_util::Move(path, bad);
134 break; 134 break;
135 } 135 }
136 } else if (!value->IsType(Value::TYPE_DICTIONARY)) { 136 } else if (!value->IsType(Value::TYPE_DICTIONARY)) {
137 *error = PersistentPrefStore::PREF_READ_ERROR_JSON_TYPE; 137 *error = PersistentPrefStore::PREF_READ_ERROR_JSON_TYPE;
138 } 138 }
139 } 139 }
140 140
141 } // namespace 141 } // namespace
142 142
143 scoped_refptr<base::SequencedTaskRunner> JsonPrefStore::GetTaskRunnerForFile( 143 scoped_refptr<base::SequencedTaskRunner> JsonPrefStore::GetTaskRunnerForFile(
144 const FilePath& filename, 144 const base::FilePath& filename,
145 base::SequencedWorkerPool* worker_pool) { 145 base::SequencedWorkerPool* worker_pool) {
146 std::string token("json_pref_store-"); 146 std::string token("json_pref_store-");
147 token.append(filename.AsUTF8Unsafe()); 147 token.append(filename.AsUTF8Unsafe());
148 return worker_pool->GetSequencedTaskRunnerWithShutdownBehavior( 148 return worker_pool->GetSequencedTaskRunnerWithShutdownBehavior(
149 worker_pool->GetNamedSequenceToken(token), 149 worker_pool->GetNamedSequenceToken(token),
150 base::SequencedWorkerPool::BLOCK_SHUTDOWN); 150 base::SequencedWorkerPool::BLOCK_SHUTDOWN);
151 } 151 }
152 152
153 JsonPrefStore::JsonPrefStore(const FilePath& filename, 153 JsonPrefStore::JsonPrefStore(const base::FilePath& filename,
154 base::SequencedTaskRunner* sequenced_task_runner) 154 base::SequencedTaskRunner* sequenced_task_runner)
155 : path_(filename), 155 : path_(filename),
156 sequenced_task_runner_(sequenced_task_runner), 156 sequenced_task_runner_(sequenced_task_runner),
157 prefs_(new DictionaryValue()), 157 prefs_(new DictionaryValue()),
158 read_only_(false), 158 read_only_(false),
159 writer_(filename, sequenced_task_runner), 159 writer_(filename, sequenced_task_runner),
160 error_delegate_(NULL), 160 error_delegate_(NULL),
161 initialized_(false), 161 initialized_(false),
162 read_error_(PREF_READ_ERROR_OTHER) { 162 read_error_(PREF_READ_ERROR_OTHER) {
163 } 163 }
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after
348 copy->Set(key, new base::ListValue); 348 copy->Set(key, new base::ListValue);
349 } else if (value->IsType(base::Value::TYPE_DICTIONARY)) { 349 } else if (value->IsType(base::Value::TYPE_DICTIONARY)) {
350 const base::DictionaryValue* dict = NULL; 350 const base::DictionaryValue* dict = NULL;
351 if (value->GetAsDictionary(&dict) && dict->empty()) 351 if (value->GetAsDictionary(&dict) && dict->empty())
352 copy->Set(key, new base::DictionaryValue); 352 copy->Set(key, new base::DictionaryValue);
353 } 353 }
354 } 354 }
355 355
356 return serializer.Serialize(*(copy.get())); 356 return serializer.Serialize(*(copy.get()));
357 } 357 }
OLDNEW
« no previous file with comments | « base/platform_file_unittest.cc ('k') | base/prefs/json_pref_store_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698