OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 "apps/saved_files_service.h" | 5 #include "apps/saved_files_service_impl.h" |
6 | 6 |
7 #include <stdint.h> | 7 #include <stdint.h> |
8 | 8 |
9 #include <algorithm> | 9 #include <algorithm> |
10 #include <map> | 10 #include <map> |
11 #include <unordered_map> | 11 #include <unordered_map> |
12 #include <utility> | 12 #include <utility> |
13 | 13 |
14 #include "apps/saved_files_service_factory.h" | 14 #include "apps/saved_files_service_factory.h" |
15 #include "base/memory/ptr_util.h" | 15 #include "base/memory/ptr_util.h" |
16 #include "base/value_conversions.h" | 16 #include "base/value_conversions.h" |
17 #include "content/public/browser/browser_context.h" | 17 #include "content/public/browser/browser_context.h" |
18 #include "content/public/browser/notification_service.h" | 18 #include "content/public/browser/notification_service.h" |
19 #include "extensions/browser/extension_host.h" | 19 #include "extensions/browser/extension_host.h" |
20 #include "extensions/browser/extension_prefs.h" | 20 #include "extensions/browser/extension_prefs.h" |
21 #include "extensions/browser/extension_system.h" | 21 #include "extensions/browser/extension_system.h" |
22 #include "extensions/browser/notification_types.h" | 22 #include "extensions/browser/notification_types.h" |
23 #include "extensions/common/permissions/api_permission.h" | 23 #include "extensions/common/permissions/api_permission.h" |
24 #include "extensions/common/permissions/permission_set.h" | 24 #include "extensions/common/permissions/permission_set.h" |
25 #include "extensions/common/permissions/permissions_data.h" | 25 #include "extensions/common/permissions/permissions_data.h" |
26 | 26 |
27 namespace apps { | 27 namespace apps { |
28 | 28 |
29 using extensions::APIPermission; | 29 using extensions::APIPermission; |
30 using extensions::Extension; | 30 using extensions::Extension; |
31 using extensions::ExtensionHost; | 31 using extensions::ExtensionHost; |
32 using extensions::ExtensionPrefs; | 32 using extensions::ExtensionPrefs; |
| 33 using extensions::SavedFilesService; |
33 | 34 |
34 namespace { | 35 namespace { |
35 | 36 |
36 // Preference keys | 37 // Preference keys |
37 | 38 |
38 // The file entries that the app has permission to access. | 39 // The file entries that the app has permission to access. |
39 const char kFileEntries[] = "file_entries"; | 40 const char kFileEntries[] = "file_entries"; |
40 | 41 |
41 // The path to a file entry that the app had permission to access. | 42 // The path to a file entry that the app had permission to access. |
42 const char kFileEntryPath[] = "path"; | 43 const char kFileEntryPath[] = "path"; |
43 | 44 |
44 // Whether or not the the entry refers to a directory. | 45 // Whether or not the the entry refers to a directory. |
45 const char kFileEntryIsDirectory[] = "is_directory"; | 46 const char kFileEntryIsDirectory[] = "is_directory"; |
46 | 47 |
47 // The sequence number in the LRU of the file entry. | 48 // The sequence number in the LRU of the file entry. |
48 const char kFileEntrySequenceNumber[] = "sequence_number"; | 49 const char kFileEntrySequenceNumber[] = "sequence_number"; |
49 | 50 |
50 const size_t kMaxSavedFileEntries = 500; | 51 const size_t kMaxSavedFileEntries = 500; |
51 const int kMaxSequenceNumber = INT32_MAX; | 52 const int kMaxSequenceNumber = INT32_MAX; |
52 | 53 |
53 // These might be different to the constant values in tests. | 54 // These might be different to the constant values in tests. |
54 size_t g_max_saved_file_entries = kMaxSavedFileEntries; | 55 size_t g_max_saved_file_entries = kMaxSavedFileEntries; |
55 int g_max_sequence_number = kMaxSequenceNumber; | 56 int g_max_sequence_number = kMaxSequenceNumber; |
56 | 57 |
57 // Persists a SavedFileEntry in ExtensionPrefs. | 58 // Persists a saved file entry in ExtensionPrefs. |
58 void AddSavedFileEntry(ExtensionPrefs* prefs, | 59 void AddSavedFileEntry(ExtensionPrefs* prefs, |
59 const std::string& extension_id, | 60 const std::string& extension_id, |
60 const SavedFileEntry& file_entry) { | 61 const SavedFilesService::Entry& file_entry) { |
61 ExtensionPrefs::ScopedDictionaryUpdate update( | 62 ExtensionPrefs::ScopedDictionaryUpdate update(prefs, extension_id, |
62 prefs, extension_id, kFileEntries); | 63 kFileEntries); |
63 auto file_entries = update.Create(); | 64 auto file_entries = update.Create(); |
64 DCHECK(!file_entries->GetDictionaryWithoutPathExpansion(file_entry.id, NULL)); | 65 DCHECK(!file_entries->GetDictionaryWithoutPathExpansion(file_entry.id, NULL)); |
65 | 66 |
66 std::unique_ptr<base::DictionaryValue> file_entry_dict = | 67 std::unique_ptr<base::DictionaryValue> file_entry_dict = |
67 base::MakeUnique<base::DictionaryValue>(); | 68 base::MakeUnique<base::DictionaryValue>(); |
68 file_entry_dict->Set(kFileEntryPath, CreateFilePathValue(file_entry.path)); | 69 file_entry_dict->Set(kFileEntryPath, CreateFilePathValue(file_entry.path)); |
69 file_entry_dict->SetBoolean(kFileEntryIsDirectory, file_entry.is_directory); | 70 file_entry_dict->SetBoolean(kFileEntryIsDirectory, file_entry.is_directory); |
70 file_entry_dict->SetInteger(kFileEntrySequenceNumber, | 71 file_entry_dict->SetInteger(kFileEntrySequenceNumber, |
71 file_entry.sequence_number); | 72 file_entry.sequence_number); |
72 file_entries->SetWithoutPathExpansion(file_entry.id, | 73 file_entries->SetWithoutPathExpansion(file_entry.id, |
73 std::move(file_entry_dict)); | 74 std::move(file_entry_dict)); |
74 } | 75 } |
75 | 76 |
76 // Updates the sequence_number of a SavedFileEntry persisted in ExtensionPrefs. | 77 // Updates the sequence_number of a saved file entry persisted in |
| 78 // ExtensionPrefs. |
77 void UpdateSavedFileEntry(ExtensionPrefs* prefs, | 79 void UpdateSavedFileEntry(ExtensionPrefs* prefs, |
78 const std::string& extension_id, | 80 const std::string& extension_id, |
79 const SavedFileEntry& file_entry) { | 81 const SavedFilesService::Entry& file_entry) { |
80 ExtensionPrefs::ScopedDictionaryUpdate update( | 82 ExtensionPrefs::ScopedDictionaryUpdate update(prefs, extension_id, |
81 prefs, extension_id, kFileEntries); | 83 kFileEntries); |
82 auto file_entries = update.Get(); | 84 auto file_entries = update.Get(); |
83 DCHECK(file_entries); | 85 DCHECK(file_entries); |
84 std::unique_ptr<prefs::DictionaryValueUpdate> file_entry_dict; | 86 std::unique_ptr<prefs::DictionaryValueUpdate> file_entry_dict; |
85 file_entries->GetDictionaryWithoutPathExpansion(file_entry.id, | 87 file_entries->GetDictionaryWithoutPathExpansion(file_entry.id, |
86 &file_entry_dict); | 88 &file_entry_dict); |
87 DCHECK(file_entry_dict); | 89 DCHECK(file_entry_dict); |
88 file_entry_dict->SetInteger(kFileEntrySequenceNumber, | 90 file_entry_dict->SetInteger(kFileEntrySequenceNumber, |
89 file_entry.sequence_number); | 91 file_entry.sequence_number); |
90 } | 92 } |
91 | 93 |
92 // Removes a SavedFileEntry from ExtensionPrefs. | 94 // Removes a saved file entry from ExtensionPrefs. |
93 void RemoveSavedFileEntry(ExtensionPrefs* prefs, | 95 void RemoveSavedFileEntry(ExtensionPrefs* prefs, |
94 const std::string& extension_id, | 96 const std::string& extension_id, |
95 const std::string& file_entry_id) { | 97 const std::string& file_entry_id) { |
96 ExtensionPrefs::ScopedDictionaryUpdate update( | 98 ExtensionPrefs::ScopedDictionaryUpdate update(prefs, extension_id, |
97 prefs, extension_id, kFileEntries); | 99 kFileEntries); |
98 auto file_entries = update.Create(); | 100 auto file_entries = update.Create(); |
99 file_entries->RemoveWithoutPathExpansion(file_entry_id, NULL); | 101 file_entries->RemoveWithoutPathExpansion(file_entry_id, NULL); |
100 } | 102 } |
101 | 103 |
102 // Clears all SavedFileEntry for the app from ExtensionPrefs. | 104 // Clears all saved file entries for the app from ExtensionPrefs. |
103 void ClearSavedFileEntries(ExtensionPrefs* prefs, | 105 void ClearSavedFileEntries(ExtensionPrefs* prefs, |
104 const std::string& extension_id) { | 106 const std::string& extension_id) { |
105 prefs->UpdateExtensionPref(extension_id, kFileEntries, nullptr); | 107 prefs->UpdateExtensionPref(extension_id, kFileEntries, nullptr); |
106 } | 108 } |
107 | 109 |
108 // Returns all SavedFileEntries for the app. | 110 // Returns all saved file entries for the app. |
109 std::vector<SavedFileEntry> GetSavedFileEntries( | 111 std::vector<SavedFilesService::Entry> GetSavedFileEntries( |
110 ExtensionPrefs* prefs, | 112 ExtensionPrefs* prefs, |
111 const std::string& extension_id) { | 113 const std::string& extension_id) { |
112 std::vector<SavedFileEntry> result; | 114 std::vector<SavedFilesService::Entry> result; |
113 const base::DictionaryValue* file_entries = NULL; | 115 const base::DictionaryValue* file_entries = NULL; |
114 if (!prefs->ReadPrefAsDictionary(extension_id, kFileEntries, &file_entries)) | 116 if (!prefs->ReadPrefAsDictionary(extension_id, kFileEntries, &file_entries)) |
115 return result; | 117 return result; |
116 | 118 |
117 for (base::DictionaryValue::Iterator it(*file_entries); !it.IsAtEnd(); | 119 for (base::DictionaryValue::Iterator it(*file_entries); !it.IsAtEnd(); |
118 it.Advance()) { | 120 it.Advance()) { |
119 const base::DictionaryValue* file_entry = NULL; | 121 const base::DictionaryValue* file_entry = NULL; |
120 if (!it.value().GetAsDictionary(&file_entry)) | 122 if (!it.value().GetAsDictionary(&file_entry)) |
121 continue; | 123 continue; |
122 const base::Value* path_value; | 124 const base::Value* path_value; |
123 if (!file_entry->Get(kFileEntryPath, &path_value)) | 125 if (!file_entry->Get(kFileEntryPath, &path_value)) |
124 continue; | 126 continue; |
125 base::FilePath file_path; | 127 base::FilePath file_path; |
126 if (!GetValueAsFilePath(*path_value, &file_path)) | 128 if (!GetValueAsFilePath(*path_value, &file_path)) |
127 continue; | 129 continue; |
128 bool is_directory = false; | 130 bool is_directory = false; |
129 file_entry->GetBoolean(kFileEntryIsDirectory, &is_directory); | 131 file_entry->GetBoolean(kFileEntryIsDirectory, &is_directory); |
130 int sequence_number = 0; | 132 int sequence_number = 0; |
131 if (!file_entry->GetInteger(kFileEntrySequenceNumber, &sequence_number)) | 133 if (!file_entry->GetInteger(kFileEntrySequenceNumber, &sequence_number)) |
132 continue; | 134 continue; |
133 if (!sequence_number) | 135 if (!sequence_number) |
134 continue; | 136 continue; |
135 result.push_back( | 137 result.push_back(SavedFilesService::Entry(it.key(), file_path, is_directory, |
136 SavedFileEntry(it.key(), file_path, is_directory, sequence_number)); | 138 sequence_number)); |
137 } | 139 } |
138 return result; | 140 return result; |
139 } | 141 } |
140 | 142 |
141 } // namespace | 143 } // namespace |
142 | 144 |
143 SavedFileEntry::SavedFileEntry() : is_directory(false), sequence_number(0) {} | 145 class SavedFilesServiceImpl::SavedFiles { |
144 | |
145 SavedFileEntry::SavedFileEntry(const std::string& id, | |
146 const base::FilePath& path, | |
147 bool is_directory, | |
148 int sequence_number) | |
149 : id(id), | |
150 path(path), | |
151 is_directory(is_directory), | |
152 sequence_number(sequence_number) {} | |
153 | |
154 class SavedFilesService::SavedFiles { | |
155 public: | 146 public: |
156 SavedFiles(content::BrowserContext* context, const std::string& extension_id); | 147 SavedFiles(content::BrowserContext* context, const std::string& extension_id); |
157 ~SavedFiles(); | 148 ~SavedFiles(); |
158 | 149 |
159 void RegisterFileEntry(const std::string& id, | 150 void RegisterFileEntry(const std::string& id, |
160 const base::FilePath& file_path, | 151 const base::FilePath& file_path, |
161 bool is_directory); | 152 bool is_directory); |
162 void EnqueueFileEntry(const std::string& id); | 153 void EnqueueFileEntry(const std::string& id); |
163 bool IsRegistered(const std::string& id) const; | 154 bool IsRegistered(const std::string& id) const; |
164 const SavedFileEntry* GetFileEntry(const std::string& id) const; | 155 const Entry* GetFileEntry(const std::string& id) const; |
165 std::vector<SavedFileEntry> GetAllFileEntries() const; | 156 std::vector<Entry> GetAllFileEntries() const; |
166 | 157 |
167 private: | 158 private: |
168 // Compacts sequence numbers if the largest sequence number is | 159 // Compacts sequence numbers if the largest sequence number is |
169 // g_max_sequence_number. Outside of testing, it is set to kint32max, so this | 160 // g_max_sequence_number. Outside of testing, it is set to kint32max, so this |
170 // will almost never do any real work. | 161 // will almost never do any real work. |
171 void MaybeCompactSequenceNumbers(); | 162 void MaybeCompactSequenceNumbers(); |
172 | 163 |
173 void LoadSavedFileEntriesFromPreferences(); | 164 void LoadSavedFileEntriesFromPreferences(); |
174 | 165 |
175 content::BrowserContext* context_; | 166 content::BrowserContext* context_; |
176 const std::string extension_id_; | 167 const std::string extension_id_; |
177 | 168 |
178 // Contains all file entries that have been registered, keyed by ID. | 169 // Contains all file entries that have been registered, keyed by ID. |
179 std::unordered_map<std::string, std::unique_ptr<SavedFileEntry>> | 170 std::unordered_map<std::string, std::unique_ptr<Entry>> |
180 registered_file_entries_; | 171 registered_file_entries_; |
181 | 172 |
182 // The queue of file entries that have been retained, keyed by | 173 // The queue of file entries that have been retained, keyed by |
183 // sequence_number. Values are a subset of values in registered_file_entries_. | 174 // sequence_number. Values are a subset of values in registered_file_entries_. |
184 // This should be kept in sync with file entries stored in extension prefs. | 175 // This should be kept in sync with file entries stored in extension prefs. |
185 std::map<int, SavedFileEntry*> saved_file_lru_; | 176 std::map<int, Entry*> saved_file_lru_; |
186 | 177 |
187 DISALLOW_COPY_AND_ASSIGN(SavedFiles); | 178 DISALLOW_COPY_AND_ASSIGN(SavedFiles); |
188 }; | 179 }; |
189 | 180 |
190 // static | 181 // static |
191 SavedFilesService* SavedFilesService::Get(content::BrowserContext* context) { | 182 SavedFilesServiceImpl* SavedFilesServiceImpl::Get( |
192 return SavedFilesServiceFactory::GetForBrowserContext(context); | 183 content::BrowserContext* context) { |
| 184 return SavedFilesServiceImplFactory::GetForBrowserContext(context); |
193 } | 185 } |
194 | 186 |
195 SavedFilesService::SavedFilesService(content::BrowserContext* context) | 187 SavedFilesServiceImpl::SavedFilesServiceImpl(content::BrowserContext* context) |
196 : context_(context) { | 188 : context_(context) { |
197 registrar_.Add(this, | 189 registrar_.Add(this, extensions::NOTIFICATION_EXTENSION_HOST_DESTROYED, |
198 extensions::NOTIFICATION_EXTENSION_HOST_DESTROYED, | |
199 content::NotificationService::AllSources()); | 190 content::NotificationService::AllSources()); |
200 } | 191 } |
201 | 192 |
202 SavedFilesService::~SavedFilesService() {} | 193 SavedFilesServiceImpl::~SavedFilesServiceImpl() {} |
203 | 194 |
204 void SavedFilesService::Observe(int type, | 195 void SavedFilesServiceImpl::Observe( |
205 const content::NotificationSource& source, | 196 int type, |
206 const content::NotificationDetails& details) { | 197 const content::NotificationSource& source, |
| 198 const content::NotificationDetails& details) { |
207 DCHECK_EQ(extensions::NOTIFICATION_EXTENSION_HOST_DESTROYED, type); | 199 DCHECK_EQ(extensions::NOTIFICATION_EXTENSION_HOST_DESTROYED, type); |
208 ExtensionHost* host = content::Details<ExtensionHost>(details).ptr(); | 200 ExtensionHost* host = content::Details<ExtensionHost>(details).ptr(); |
209 const Extension* extension = host->extension(); | 201 const Extension* extension = host->extension(); |
210 if (extension) { | 202 if (extension) { |
211 ClearQueueIfNoRetainPermission(extension); | 203 ClearQueueIfNoRetainPermission(extension); |
212 Clear(extension->id()); | 204 Clear(extension->id()); |
213 } | 205 } |
214 } | 206 } |
215 | 207 |
216 void SavedFilesService::RegisterFileEntry(const std::string& extension_id, | 208 void SavedFilesServiceImpl::RegisterFileEntry(const std::string& extension_id, |
217 const std::string& id, | 209 const std::string& id, |
218 const base::FilePath& file_path, | 210 const base::FilePath& file_path, |
219 bool is_directory) { | 211 bool is_directory) { |
220 GetOrInsert(extension_id)->RegisterFileEntry(id, file_path, is_directory); | 212 GetOrInsert(extension_id)->RegisterFileEntry(id, file_path, is_directory); |
221 } | 213 } |
222 | 214 |
223 void SavedFilesService::EnqueueFileEntry(const std::string& extension_id, | 215 void SavedFilesServiceImpl::EnqueueFileEntry(const std::string& extension_id, |
224 const std::string& id) { | 216 const std::string& id) { |
225 GetOrInsert(extension_id)->EnqueueFileEntry(id); | 217 GetOrInsert(extension_id)->EnqueueFileEntry(id); |
226 } | 218 } |
227 | 219 |
228 std::vector<SavedFileEntry> SavedFilesService::GetAllFileEntries( | 220 std::vector<SavedFilesService::Entry> SavedFilesServiceImpl::GetAllFileEntries( |
229 const std::string& extension_id) { | 221 const std::string& extension_id) { |
230 SavedFiles* saved_files = Get(extension_id); | 222 SavedFiles* saved_files = Get(extension_id); |
231 if (saved_files) | 223 if (saved_files) |
232 return saved_files->GetAllFileEntries(); | 224 return saved_files->GetAllFileEntries(); |
233 return GetSavedFileEntries(ExtensionPrefs::Get(context_), extension_id); | 225 return GetSavedFileEntries(ExtensionPrefs::Get(context_), extension_id); |
234 } | 226 } |
235 | 227 |
236 bool SavedFilesService::IsRegistered(const std::string& extension_id, | 228 bool SavedFilesServiceImpl::IsRegistered(const std::string& extension_id, |
237 const std::string& id) { | 229 const std::string& id) { |
238 return GetOrInsert(extension_id)->IsRegistered(id); | 230 return GetOrInsert(extension_id)->IsRegistered(id); |
239 } | 231 } |
240 | 232 |
241 const SavedFileEntry* SavedFilesService::GetFileEntry( | 233 const SavedFilesService::Entry* SavedFilesServiceImpl::GetFileEntry( |
242 const std::string& extension_id, | 234 const std::string& extension_id, |
243 const std::string& id) { | 235 const std::string& id) { |
244 return GetOrInsert(extension_id)->GetFileEntry(id); | 236 return GetOrInsert(extension_id)->GetFileEntry(id); |
245 } | 237 } |
246 | 238 |
247 void SavedFilesService::ClearQueueIfNoRetainPermission( | 239 void SavedFilesServiceImpl::ClearQueueIfNoRetainPermission( |
248 const Extension* extension) { | 240 const Extension* extension) { |
249 if (!extension->permissions_data()->active_permissions().HasAPIPermission( | 241 if (!extension->permissions_data()->active_permissions().HasAPIPermission( |
250 APIPermission::kFileSystemRetainEntries)) { | 242 APIPermission::kFileSystemRetainEntries)) { |
251 ClearQueue(extension); | 243 ClearQueue(extension); |
252 } | 244 } |
253 } | 245 } |
254 | 246 |
255 void SavedFilesService::ClearQueue(const extensions::Extension* extension) { | 247 void SavedFilesServiceImpl::ClearQueue(const extensions::Extension* extension) { |
256 ClearSavedFileEntries(ExtensionPrefs::Get(context_), extension->id()); | 248 ClearSavedFileEntries(ExtensionPrefs::Get(context_), extension->id()); |
257 Clear(extension->id()); | 249 Clear(extension->id()); |
258 } | 250 } |
259 | 251 |
260 void SavedFilesService::OnApplicationTerminating() { | 252 void SavedFilesServiceImpl::OnApplicationTerminating() { |
261 // Stop listening to NOTIFICATION_EXTENSION_HOST_DESTROYED in particular | 253 // Stop listening to NOTIFICATION_EXTENSION_HOST_DESTROYED in particular |
262 // as all extension hosts will be destroyed as a result of shutdown. | 254 // as all extension hosts will be destroyed as a result of shutdown. |
263 registrar_.RemoveAll(); | 255 registrar_.RemoveAll(); |
264 } | 256 } |
265 | 257 |
266 SavedFilesService::SavedFiles* SavedFilesService::Get( | 258 SavedFilesServiceImpl::SavedFiles* SavedFilesServiceImpl::Get( |
267 const std::string& extension_id) const { | 259 const std::string& extension_id) const { |
268 auto it = extension_id_to_saved_files_.find(extension_id); | 260 auto it = extension_id_to_saved_files_.find(extension_id); |
269 if (it != extension_id_to_saved_files_.end()) | 261 if (it != extension_id_to_saved_files_.end()) |
270 return it->second.get(); | 262 return it->second.get(); |
271 | 263 |
272 return NULL; | 264 return NULL; |
273 } | 265 } |
274 | 266 |
275 SavedFilesService::SavedFiles* SavedFilesService::GetOrInsert( | 267 SavedFilesServiceImpl::SavedFiles* SavedFilesServiceImpl::GetOrInsert( |
276 const std::string& extension_id) { | 268 const std::string& extension_id) { |
277 SavedFiles* saved_files = Get(extension_id); | 269 SavedFiles* saved_files = Get(extension_id); |
278 if (saved_files) | 270 if (saved_files) |
279 return saved_files; | 271 return saved_files; |
280 | 272 |
281 std::unique_ptr<SavedFiles> scoped_saved_files( | 273 std::unique_ptr<SavedFiles> scoped_saved_files( |
282 new SavedFiles(context_, extension_id)); | 274 new SavedFiles(context_, extension_id)); |
283 saved_files = scoped_saved_files.get(); | 275 saved_files = scoped_saved_files.get(); |
284 extension_id_to_saved_files_.insert( | 276 extension_id_to_saved_files_.insert( |
285 std::make_pair(extension_id, std::move(scoped_saved_files))); | 277 std::make_pair(extension_id, std::move(scoped_saved_files))); |
286 return saved_files; | 278 return saved_files; |
287 } | 279 } |
288 | 280 |
289 void SavedFilesService::Clear(const std::string& extension_id) { | 281 void SavedFilesServiceImpl::Clear(const std::string& extension_id) { |
290 extension_id_to_saved_files_.erase(extension_id); | 282 extension_id_to_saved_files_.erase(extension_id); |
291 } | 283 } |
292 | 284 |
293 SavedFilesService::SavedFiles::SavedFiles(content::BrowserContext* context, | 285 SavedFilesServiceImpl::SavedFiles::SavedFiles(content::BrowserContext* context, |
294 const std::string& extension_id) | 286 const std::string& extension_id) |
295 : context_(context), extension_id_(extension_id) { | 287 : context_(context), extension_id_(extension_id) { |
296 LoadSavedFileEntriesFromPreferences(); | 288 LoadSavedFileEntriesFromPreferences(); |
297 } | 289 } |
298 | 290 |
299 SavedFilesService::SavedFiles::~SavedFiles() {} | 291 SavedFilesServiceImpl::SavedFiles::~SavedFiles() {} |
300 | 292 |
301 void SavedFilesService::SavedFiles::RegisterFileEntry( | 293 void SavedFilesServiceImpl::SavedFiles::RegisterFileEntry( |
302 const std::string& id, | 294 const std::string& id, |
303 const base::FilePath& file_path, | 295 const base::FilePath& file_path, |
304 bool is_directory) { | 296 bool is_directory) { |
305 auto it = registered_file_entries_.find(id); | 297 auto it = registered_file_entries_.find(id); |
306 if (it != registered_file_entries_.end()) | 298 if (it != registered_file_entries_.end()) |
307 return; | 299 return; |
308 | 300 |
309 registered_file_entries_[id] = | 301 registered_file_entries_[id] = |
310 base::MakeUnique<SavedFileEntry>(id, file_path, is_directory, 0); | 302 base::MakeUnique<Entry>(id, file_path, is_directory, 0); |
311 } | 303 } |
312 | 304 |
313 void SavedFilesService::SavedFiles::EnqueueFileEntry(const std::string& id) { | 305 void SavedFilesServiceImpl::SavedFiles::EnqueueFileEntry( |
| 306 const std::string& id) { |
314 auto it = registered_file_entries_.find(id); | 307 auto it = registered_file_entries_.find(id); |
315 DCHECK(it != registered_file_entries_.end()); | 308 DCHECK(it != registered_file_entries_.end()); |
316 | 309 |
317 SavedFileEntry* file_entry = it->second.get(); | 310 Entry* file_entry = it->second.get(); |
318 int old_sequence_number = file_entry->sequence_number; | 311 int old_sequence_number = file_entry->sequence_number; |
319 if (!saved_file_lru_.empty()) { | 312 if (!saved_file_lru_.empty()) { |
320 // Get the sequence number after the last file entry in the LRU. | 313 // Get the sequence number after the last file entry in the LRU. |
321 std::map<int, SavedFileEntry*>::reverse_iterator it = | 314 std::map<int, Entry*>::reverse_iterator it = saved_file_lru_.rbegin(); |
322 saved_file_lru_.rbegin(); | |
323 if (it->second == file_entry) | 315 if (it->second == file_entry) |
324 return; | 316 return; |
325 | 317 |
326 file_entry->sequence_number = it->first + 1; | 318 file_entry->sequence_number = it->first + 1; |
327 } else { | 319 } else { |
328 // The first sequence number is 1, as 0 means the entry is not in the LRU. | 320 // The first sequence number is 1, as 0 means the entry is not in the LRU. |
329 file_entry->sequence_number = 1; | 321 file_entry->sequence_number = 1; |
330 } | 322 } |
331 saved_file_lru_.insert( | 323 saved_file_lru_.insert( |
332 std::make_pair(file_entry->sequence_number, file_entry)); | 324 std::make_pair(file_entry->sequence_number, file_entry)); |
333 ExtensionPrefs* prefs = ExtensionPrefs::Get(context_); | 325 ExtensionPrefs* prefs = ExtensionPrefs::Get(context_); |
334 if (old_sequence_number) { | 326 if (old_sequence_number) { |
335 saved_file_lru_.erase(old_sequence_number); | 327 saved_file_lru_.erase(old_sequence_number); |
336 UpdateSavedFileEntry(prefs, extension_id_, *file_entry); | 328 UpdateSavedFileEntry(prefs, extension_id_, *file_entry); |
337 } else { | 329 } else { |
338 AddSavedFileEntry(prefs, extension_id_, *file_entry); | 330 AddSavedFileEntry(prefs, extension_id_, *file_entry); |
339 if (saved_file_lru_.size() > g_max_saved_file_entries) { | 331 if (saved_file_lru_.size() > g_max_saved_file_entries) { |
340 std::map<int, SavedFileEntry*>::iterator it = saved_file_lru_.begin(); | 332 std::map<int, Entry*>::iterator it = saved_file_lru_.begin(); |
341 it->second->sequence_number = 0; | 333 it->second->sequence_number = 0; |
342 RemoveSavedFileEntry(prefs, extension_id_, it->second->id); | 334 RemoveSavedFileEntry(prefs, extension_id_, it->second->id); |
343 saved_file_lru_.erase(it); | 335 saved_file_lru_.erase(it); |
344 } | 336 } |
345 } | 337 } |
346 MaybeCompactSequenceNumbers(); | 338 MaybeCompactSequenceNumbers(); |
347 } | 339 } |
348 | 340 |
349 bool SavedFilesService::SavedFiles::IsRegistered(const std::string& id) const { | 341 bool SavedFilesServiceImpl::SavedFiles::IsRegistered( |
| 342 const std::string& id) const { |
350 auto it = registered_file_entries_.find(id); | 343 auto it = registered_file_entries_.find(id); |
351 return it != registered_file_entries_.end(); | 344 return it != registered_file_entries_.end(); |
352 } | 345 } |
353 | 346 |
354 const SavedFileEntry* SavedFilesService::SavedFiles::GetFileEntry( | 347 const SavedFilesService::Entry* SavedFilesServiceImpl::SavedFiles::GetFileEntry( |
355 const std::string& id) const { | 348 const std::string& id) const { |
356 auto it = registered_file_entries_.find(id); | 349 auto it = registered_file_entries_.find(id); |
357 if (it == registered_file_entries_.end()) | 350 if (it == registered_file_entries_.end()) |
358 return NULL; | 351 return NULL; |
359 | 352 |
360 return it->second.get(); | 353 return it->second.get(); |
361 } | 354 } |
362 | 355 |
363 std::vector<SavedFileEntry> SavedFilesService::SavedFiles::GetAllFileEntries() | 356 std::vector<SavedFilesService::Entry> |
364 const { | 357 SavedFilesServiceImpl::SavedFiles::GetAllFileEntries() const { |
365 std::vector<SavedFileEntry> result; | 358 std::vector<Entry> result; |
366 for (auto it = registered_file_entries_.begin(); | 359 for (auto it = registered_file_entries_.begin(); |
367 it != registered_file_entries_.end(); ++it) { | 360 it != registered_file_entries_.end(); ++it) { |
368 result.push_back(*it->second.get()); | 361 result.push_back(*it->second.get()); |
369 } | 362 } |
370 return result; | 363 return result; |
371 } | 364 } |
372 | 365 |
373 void SavedFilesService::SavedFiles::MaybeCompactSequenceNumbers() { | 366 void SavedFilesServiceImpl::SavedFiles::MaybeCompactSequenceNumbers() { |
374 DCHECK_GE(g_max_sequence_number, 0); | 367 DCHECK_GE(g_max_sequence_number, 0); |
375 DCHECK_GE(static_cast<size_t>(g_max_sequence_number), | 368 DCHECK_GE(static_cast<size_t>(g_max_sequence_number), |
376 g_max_saved_file_entries); | 369 g_max_saved_file_entries); |
377 std::map<int, SavedFileEntry*>::reverse_iterator it = | 370 std::map<int, Entry*>::reverse_iterator it = saved_file_lru_.rbegin(); |
378 saved_file_lru_.rbegin(); | |
379 if (it == saved_file_lru_.rend()) | 371 if (it == saved_file_lru_.rend()) |
380 return; | 372 return; |
381 | 373 |
382 // Only compact sequence numbers if the last entry's sequence number is the | 374 // Only compact sequence numbers if the last entry's sequence number is the |
383 // maximum value. This should almost never be the case. | 375 // maximum value. This should almost never be the case. |
384 if (it->first < g_max_sequence_number) | 376 if (it->first < g_max_sequence_number) |
385 return; | 377 return; |
386 | 378 |
387 int sequence_number = 0; | 379 int sequence_number = 0; |
388 ExtensionPrefs* prefs = ExtensionPrefs::Get(context_); | 380 ExtensionPrefs* prefs = ExtensionPrefs::Get(context_); |
389 for (std::map<int, SavedFileEntry*>::iterator it = saved_file_lru_.begin(); | 381 for (std::map<int, Entry*>::iterator it = saved_file_lru_.begin(); |
390 it != saved_file_lru_.end(); | 382 it != saved_file_lru_.end(); ++it) { |
391 ++it) { | |
392 sequence_number++; | 383 sequence_number++; |
393 if (it->second->sequence_number == sequence_number) | 384 if (it->second->sequence_number == sequence_number) |
394 continue; | 385 continue; |
395 | 386 |
396 SavedFileEntry* file_entry = it->second; | 387 Entry* file_entry = it->second; |
397 file_entry->sequence_number = sequence_number; | 388 file_entry->sequence_number = sequence_number; |
398 UpdateSavedFileEntry(prefs, extension_id_, *file_entry); | 389 UpdateSavedFileEntry(prefs, extension_id_, *file_entry); |
399 saved_file_lru_.erase(it++); | 390 saved_file_lru_.erase(it++); |
400 // Provide the following element as an insert hint. While optimized | 391 // Provide the following element as an insert hint. While optimized |
401 // insertion time with the following element as a hint is only supported by | 392 // insertion time with the following element as a hint is only supported by |
402 // the spec in C++11, the implementations do support this. | 393 // the spec in C++11, the implementations do support this. |
403 it = saved_file_lru_.insert( | 394 it = saved_file_lru_.insert( |
404 it, std::make_pair(file_entry->sequence_number, file_entry)); | 395 it, std::make_pair(file_entry->sequence_number, file_entry)); |
405 } | 396 } |
406 } | 397 } |
407 | 398 |
408 void SavedFilesService::SavedFiles::LoadSavedFileEntriesFromPreferences() { | 399 void SavedFilesServiceImpl::SavedFiles::LoadSavedFileEntriesFromPreferences() { |
409 ExtensionPrefs* prefs = ExtensionPrefs::Get(context_); | 400 ExtensionPrefs* prefs = ExtensionPrefs::Get(context_); |
410 std::vector<SavedFileEntry> saved_entries = | 401 std::vector<Entry> saved_entries = GetSavedFileEntries(prefs, extension_id_); |
411 GetSavedFileEntries(prefs, extension_id_); | 402 for (std::vector<Entry>::iterator it = saved_entries.begin(); |
412 for (std::vector<SavedFileEntry>::iterator it = saved_entries.begin(); | 403 it != saved_entries.end(); ++it) { |
413 it != saved_entries.end(); | 404 std::unique_ptr<Entry> file_entry(new Entry(*it)); |
414 ++it) { | |
415 std::unique_ptr<SavedFileEntry> file_entry(new SavedFileEntry(*it)); | |
416 const std::string& id = file_entry->id; | 405 const std::string& id = file_entry->id; |
417 saved_file_lru_.insert( | 406 saved_file_lru_.insert( |
418 std::make_pair(file_entry->sequence_number, file_entry.get())); | 407 std::make_pair(file_entry->sequence_number, file_entry.get())); |
419 registered_file_entries_[id] = std::move(file_entry); | 408 registered_file_entries_[id] = std::move(file_entry); |
420 } | 409 } |
421 } | 410 } |
422 | 411 |
423 // static | 412 // static |
424 void SavedFilesService::SetMaxSequenceNumberForTest(int max_value) { | 413 void SavedFilesServiceImpl::SetMaxSequenceNumberForTest(int max_value) { |
425 g_max_sequence_number = max_value; | 414 g_max_sequence_number = max_value; |
426 } | 415 } |
427 | 416 |
428 // static | 417 // static |
429 void SavedFilesService::ClearMaxSequenceNumberForTest() { | 418 void SavedFilesServiceImpl::ClearMaxSequenceNumberForTest() { |
430 g_max_sequence_number = kMaxSequenceNumber; | 419 g_max_sequence_number = kMaxSequenceNumber; |
431 } | 420 } |
432 | 421 |
433 // static | 422 // static |
434 void SavedFilesService::SetLruSizeForTest(int size) { | 423 void SavedFilesServiceImpl::SetLruSizeForTest(int size) { |
435 g_max_saved_file_entries = size; | 424 g_max_saved_file_entries = size; |
436 } | 425 } |
437 | 426 |
438 // static | 427 // static |
439 void SavedFilesService::ClearLruSizeForTest() { | 428 void SavedFilesServiceImpl::ClearLruSizeForTest() { |
440 g_max_saved_file_entries = kMaxSavedFileEntries; | 429 g_max_saved_file_entries = kMaxSavedFileEntries; |
441 } | 430 } |
442 | 431 |
443 } // namespace apps | 432 } // namespace apps |
OLD | NEW |