OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | |
mtomasz
2014/10/20 05:37:43
(Most of the file is moved from service.cc.)
| |
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 "chrome/browser/chromeos/file_system_provider/registry.h" | |
6 | |
7 #include "base/files/file_path.h" | |
8 #include "base/prefs/pref_service.h" | |
9 #include "base/prefs/scoped_user_pref_update.h" | |
10 #include "base/stl_util.h" | |
11 #include "chrome/browser/chromeos/file_system_provider/mount_path_util.h" | |
12 #include "chrome/browser/chromeos/file_system_provider/observer.h" | |
13 #include "chrome/browser/chromeos/file_system_provider/provided_file_system.h" | |
14 #include "chrome/browser/chromeos/file_system_provider/provided_file_system_info .h" | |
15 #include "chrome/browser/chromeos/file_system_provider/service_factory.h" | |
16 #include "chrome/browser/profiles/profile.h" | |
17 #include "chrome/common/pref_names.h" | |
18 #include "components/pref_registry/pref_registry_syncable.h" | |
19 #include "extensions/browser/extension_registry.h" | |
20 #include "extensions/browser/extension_system.h" | |
21 #include "storage/browser/fileapi/external_mount_points.h" | |
22 | |
23 namespace chromeos { | |
24 namespace file_system_provider { | |
25 | |
26 const char kPrefKeyFileSystemId[] = "file-system-id"; | |
27 const char kPrefKeyDisplayName[] = "display-name"; | |
28 const char kPrefKeyWritable[] = "writable"; | |
29 const char kPrefKeySupportsNotifyTag[] = "supports-notify-tag"; | |
30 const char kPrefKeyObservedEntries[] = "observed-entries"; | |
31 const char kPrefKeyObservedEntryEntryPath[] = "entry-path"; | |
32 const char kPrefKeyObservedEntryRecursive[] = "recursive"; | |
33 const char kPrefKeyObservedEntryLastTag[] = "last-tag"; | |
34 | |
35 void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry) { | |
36 registry->RegisterDictionaryPref( | |
37 prefs::kFileSystemProviderMounted, | |
38 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); | |
39 } | |
40 | |
41 Registry::Registry(Profile* profile) : profile_(profile) { | |
42 } | |
43 | |
44 Registry::~Registry() { | |
45 } | |
46 | |
47 void Registry::RememberFileSystem( | |
48 const ProvidedFileSystemInfo& file_system_info, | |
49 const ObservedEntries& observed_entries) { | |
50 base::DictionaryValue* const file_system = new base::DictionaryValue(); | |
51 file_system->SetStringWithoutPathExpansion(kPrefKeyFileSystemId, | |
52 file_system_info.file_system_id()); | |
53 file_system->SetStringWithoutPathExpansion(kPrefKeyDisplayName, | |
54 file_system_info.display_name()); | |
55 file_system->SetBooleanWithoutPathExpansion(kPrefKeyWritable, | |
56 file_system_info.writable()); | |
57 file_system->SetBooleanWithoutPathExpansion( | |
58 kPrefKeySupportsNotifyTag, file_system_info.supports_notify_tag()); | |
59 | |
60 base::DictionaryValue* const observed_entries_value = | |
61 new base::DictionaryValue(); | |
62 file_system->SetWithoutPathExpansion(kPrefKeyObservedEntries, | |
63 observed_entries_value); | |
64 | |
65 for (ObservedEntries::const_iterator it = observed_entries.begin(); | |
66 it != observed_entries.end(); | |
67 ++it) { | |
68 base::DictionaryValue* const observed_entry = new base::DictionaryValue(); | |
69 observed_entries_value->SetWithoutPathExpansion(it->first.value(), | |
70 observed_entry); | |
71 observed_entry->SetStringWithoutPathExpansion( | |
72 kPrefKeyObservedEntryEntryPath, it->second.entry_path.value()); | |
73 observed_entry->SetBooleanWithoutPathExpansion( | |
74 kPrefKeyObservedEntryRecursive, it->second.recursive); | |
75 observed_entry->SetStringWithoutPathExpansion(kPrefKeyObservedEntryLastTag, | |
76 it->second.last_tag); | |
77 } | |
78 | |
79 PrefService* const pref_service = profile_->GetPrefs(); | |
80 DCHECK(pref_service); | |
81 | |
82 DictionaryPrefUpdate dict_update(pref_service, | |
83 prefs::kFileSystemProviderMounted); | |
84 | |
85 base::DictionaryValue* file_systems_per_extension = NULL; | |
86 if (!dict_update->GetDictionaryWithoutPathExpansion( | |
87 file_system_info.extension_id(), &file_systems_per_extension)) { | |
88 file_systems_per_extension = new base::DictionaryValue(); | |
89 dict_update->SetWithoutPathExpansion(file_system_info.extension_id(), | |
90 file_systems_per_extension); | |
91 } | |
92 | |
93 file_systems_per_extension->SetWithoutPathExpansion( | |
94 file_system_info.file_system_id(), file_system); | |
95 } | |
96 | |
97 void Registry::ForgetFileSystem(const std::string& extension_id, | |
98 const std::string& file_system_id) { | |
99 PrefService* const pref_service = profile_->GetPrefs(); | |
100 DCHECK(pref_service); | |
101 | |
102 DictionaryPrefUpdate dict_update(pref_service, | |
103 prefs::kFileSystemProviderMounted); | |
104 | |
105 base::DictionaryValue* file_systems_per_extension = NULL; | |
106 if (!dict_update->GetDictionaryWithoutPathExpansion( | |
107 extension_id, &file_systems_per_extension)) | |
108 return; // Nothing to forget. | |
109 | |
110 file_systems_per_extension->RemoveWithoutPathExpansion(file_system_id, NULL); | |
111 if (!file_systems_per_extension->size()) | |
112 dict_update->Remove(extension_id, NULL); | |
113 } | |
114 | |
115 scoped_ptr<Registry::RestoredFileSystems> Registry::RestoreFileSystems( | |
116 const std::string& extension_id) { | |
117 PrefService* const pref_service = profile_->GetPrefs(); | |
118 DCHECK(pref_service); | |
119 | |
120 const base::DictionaryValue* const file_systems = | |
121 pref_service->GetDictionary(prefs::kFileSystemProviderMounted); | |
122 DCHECK(file_systems); | |
123 | |
124 const base::DictionaryValue* file_systems_per_extension = NULL; | |
125 if (!file_systems->GetDictionaryWithoutPathExpansion( | |
126 extension_id, &file_systems_per_extension)) { | |
127 return make_scoped_ptr(new RestoredFileSystems); // Nothing to restore. | |
128 } | |
129 | |
130 scoped_ptr<RestoredFileSystems> restored_file_systems( | |
131 new RestoredFileSystems); | |
132 | |
133 for (base::DictionaryValue::Iterator it(*file_systems_per_extension); | |
134 !it.IsAtEnd(); | |
135 it.Advance()) { | |
136 const base::Value* file_system_value = NULL; | |
137 const base::DictionaryValue* file_system = NULL; | |
138 file_systems_per_extension->GetWithoutPathExpansion(it.key(), | |
139 &file_system_value); | |
140 DCHECK(file_system_value); | |
141 | |
142 std::string file_system_id; | |
143 std::string display_name; | |
144 bool writable = false; | |
145 bool supports_notify_tag = false; | |
146 | |
147 if (!file_system_value->GetAsDictionary(&file_system) || | |
148 !file_system->GetStringWithoutPathExpansion(kPrefKeyFileSystemId, | |
149 &file_system_id) || | |
150 !file_system->GetStringWithoutPathExpansion(kPrefKeyDisplayName, | |
151 &display_name) || | |
152 !file_system->GetBooleanWithoutPathExpansion(kPrefKeyWritable, | |
153 &writable) || | |
154 !file_system->GetBooleanWithoutPathExpansion(kPrefKeySupportsNotifyTag, | |
155 &supports_notify_tag) || | |
156 file_system_id.empty() || display_name.empty()) { | |
157 LOG(ERROR) | |
158 << "Malformed provided file system information in preferences."; | |
159 continue; | |
160 } | |
161 | |
162 MountOptions options; | |
163 options.file_system_id = file_system_id; | |
164 options.display_name = display_name; | |
165 options.writable = writable; | |
166 options.supports_notify_tag = supports_notify_tag; | |
167 | |
168 RestoredFileSystem restored_file_system; | |
169 restored_file_system.extension_id = extension_id; | |
170 restored_file_system.options = options; | |
171 | |
172 // Restore observed entries. It's optional, since this field is new. | |
173 const base::DictionaryValue* observed_entries = NULL; | |
174 if (file_system->GetDictionaryWithoutPathExpansion(kPrefKeyObservedEntries, | |
175 &observed_entries)) { | |
176 for (base::DictionaryValue::Iterator it(*observed_entries); !it.IsAtEnd(); | |
177 it.Advance()) { | |
178 const base::Value* observed_entry_value = NULL; | |
179 const base::DictionaryValue* observed_entry = NULL; | |
180 observed_entries->GetWithoutPathExpansion(it.key(), | |
181 &observed_entry_value); | |
182 DCHECK(file_system_value); | |
183 | |
184 std::string entry_path; | |
185 bool recursive = false; | |
186 std::string last_tag; | |
187 | |
188 if (!observed_entry_value->GetAsDictionary(&observed_entry) || | |
189 !observed_entry->GetStringWithoutPathExpansion( | |
190 kPrefKeyObservedEntryEntryPath, &entry_path) || | |
191 !observed_entry->GetBooleanWithoutPathExpansion( | |
192 kPrefKeyObservedEntryRecursive, &recursive) || | |
193 !observed_entry->GetStringWithoutPathExpansion( | |
194 kPrefKeyObservedEntryLastTag, &last_tag) || | |
195 it.key() != entry_path || entry_path.empty() || | |
196 (!options.supports_notify_tag && !last_tag.empty())) { | |
197 LOG(ERROR) << "Malformed observed entry information in preferences."; | |
198 continue; | |
199 } | |
200 | |
201 ObservedEntry restored_observed_entry; | |
202 restored_observed_entry.entry_path = | |
203 base::FilePath::FromUTF8Unsafe(entry_path); | |
204 restored_observed_entry.recursive = recursive; | |
205 restored_observed_entry.last_tag = last_tag; | |
206 restored_file_system | |
207 .observed_entries[base::FilePath::FromUTF8Unsafe(entry_path)] = | |
208 restored_observed_entry; | |
209 } | |
210 } | |
211 restored_file_systems->push_back(restored_file_system); | |
212 } | |
213 | |
214 return restored_file_systems.Pass(); | |
215 } | |
216 | |
217 void Registry::UpdateObservedEntryTag( | |
218 const ProvidedFileSystemInfo& file_system_info, | |
219 const ObservedEntry& observed_entry) { | |
220 PrefService* const pref_service = profile_->GetPrefs(); | |
221 DCHECK(pref_service); | |
222 | |
223 // TODO(mtomasz): Consider optimizing it by moving information about observed | |
224 // entries, or even file systems to leveldb. | |
225 DictionaryPrefUpdate dict_update(pref_service, | |
226 prefs::kFileSystemProviderMounted); | |
227 | |
228 // All of the following checks should not happen in healthy environment. | |
229 // However, since they rely on storage, DCHECKs can't be used. | |
230 base::DictionaryValue* file_systems_per_extension = NULL; | |
231 base::DictionaryValue* file_system = NULL; | |
232 base::DictionaryValue* observed_entries = NULL; | |
233 base::DictionaryValue* observed_entry_value = NULL; | |
234 if (!dict_update->GetDictionaryWithoutPathExpansion( | |
235 file_system_info.extension_id(), &file_systems_per_extension) || | |
236 !file_systems_per_extension->GetDictionaryWithoutPathExpansion( | |
237 file_system_info.file_system_id(), &file_system) || | |
238 !file_system->GetDictionaryWithoutPathExpansion(kPrefKeyObservedEntries, | |
239 &observed_entries) || | |
240 !observed_entries->GetDictionaryWithoutPathExpansion( | |
241 observed_entry.entry_path.value(), &observed_entry_value)) { | |
242 // Broken preferences. | |
243 LOG(ERROR) << "Broken preferences detected while updating a tag."; | |
244 return; | |
245 } | |
246 | |
247 observed_entry_value->SetStringWithoutPathExpansion( | |
248 kPrefKeyObservedEntryLastTag, observed_entry.last_tag); | |
249 } | |
250 | |
251 } // namespace file_system_provider | |
252 } // namespace chromeos | |
OLD | NEW |