| 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.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 "chrome/browser/chrome_notification_types.h" | 17 #include "chrome/browser/chrome_notification_types.h" |
| 18 #include "chrome/browser/profiles/profile.h" | 18 #include "content/public/browser/browser_context.h" |
| 19 #include "content/public/browser/notification_service.h" | 19 #include "content/public/browser/notification_service.h" |
| 20 #include "extensions/browser/extension_host.h" | 20 #include "extensions/browser/extension_host.h" |
| 21 #include "extensions/browser/extension_prefs.h" | 21 #include "extensions/browser/extension_prefs.h" |
| 22 #include "extensions/browser/extension_system.h" | 22 #include "extensions/browser/extension_system.h" |
| 23 #include "extensions/browser/notification_types.h" | 23 #include "extensions/browser/notification_types.h" |
| 24 #include "extensions/common/permissions/api_permission.h" | 24 #include "extensions/common/permissions/api_permission.h" |
| 25 #include "extensions/common/permissions/permission_set.h" | 25 #include "extensions/common/permissions/permission_set.h" |
| 26 #include "extensions/common/permissions/permissions_data.h" | 26 #include "extensions/common/permissions/permissions_data.h" |
| 27 | 27 |
| 28 namespace apps { | 28 namespace apps { |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 151 const base::FilePath& path, | 151 const base::FilePath& path, |
| 152 bool is_directory, | 152 bool is_directory, |
| 153 int sequence_number) | 153 int sequence_number) |
| 154 : id(id), | 154 : id(id), |
| 155 path(path), | 155 path(path), |
| 156 is_directory(is_directory), | 156 is_directory(is_directory), |
| 157 sequence_number(sequence_number) {} | 157 sequence_number(sequence_number) {} |
| 158 | 158 |
| 159 class SavedFilesService::SavedFiles { | 159 class SavedFilesService::SavedFiles { |
| 160 public: | 160 public: |
| 161 SavedFiles(Profile* profile, const std::string& extension_id); | 161 SavedFiles(content::BrowserContext* context, const std::string& extension_id); |
| 162 ~SavedFiles(); | 162 ~SavedFiles(); |
| 163 | 163 |
| 164 void RegisterFileEntry(const std::string& id, | 164 void RegisterFileEntry(const std::string& id, |
| 165 const base::FilePath& file_path, | 165 const base::FilePath& file_path, |
| 166 bool is_directory); | 166 bool is_directory); |
| 167 void EnqueueFileEntry(const std::string& id); | 167 void EnqueueFileEntry(const std::string& id); |
| 168 bool IsRegistered(const std::string& id) const; | 168 bool IsRegistered(const std::string& id) const; |
| 169 const SavedFileEntry* GetFileEntry(const std::string& id) const; | 169 const SavedFileEntry* GetFileEntry(const std::string& id) const; |
| 170 std::vector<SavedFileEntry> GetAllFileEntries() const; | 170 std::vector<SavedFileEntry> GetAllFileEntries() const; |
| 171 | 171 |
| 172 private: | 172 private: |
| 173 // Compacts sequence numbers if the largest sequence number is | 173 // Compacts sequence numbers if the largest sequence number is |
| 174 // g_max_sequence_number. Outside of testing, it is set to kint32max, so this | 174 // g_max_sequence_number. Outside of testing, it is set to kint32max, so this |
| 175 // will almost never do any real work. | 175 // will almost never do any real work. |
| 176 void MaybeCompactSequenceNumbers(); | 176 void MaybeCompactSequenceNumbers(); |
| 177 | 177 |
| 178 void LoadSavedFileEntriesFromPreferences(); | 178 void LoadSavedFileEntriesFromPreferences(); |
| 179 | 179 |
| 180 Profile* profile_; | 180 content::BrowserContext* context_; |
| 181 const std::string extension_id_; | 181 const std::string extension_id_; |
| 182 | 182 |
| 183 // Contains all file entries that have been registered, keyed by ID. | 183 // Contains all file entries that have been registered, keyed by ID. |
| 184 std::unordered_map<std::string, std::unique_ptr<SavedFileEntry>> | 184 std::unordered_map<std::string, std::unique_ptr<SavedFileEntry>> |
| 185 registered_file_entries_; | 185 registered_file_entries_; |
| 186 | 186 |
| 187 // The queue of file entries that have been retained, keyed by | 187 // The queue of file entries that have been retained, keyed by |
| 188 // sequence_number. Values are a subset of values in registered_file_entries_. | 188 // sequence_number. Values are a subset of values in registered_file_entries_. |
| 189 // This should be kept in sync with file entries stored in extension prefs. | 189 // This should be kept in sync with file entries stored in extension prefs. |
| 190 std::map<int, SavedFileEntry*> saved_file_lru_; | 190 std::map<int, SavedFileEntry*> saved_file_lru_; |
| 191 | 191 |
| 192 DISALLOW_COPY_AND_ASSIGN(SavedFiles); | 192 DISALLOW_COPY_AND_ASSIGN(SavedFiles); |
| 193 }; | 193 }; |
| 194 | 194 |
| 195 // static | 195 // static |
| 196 SavedFilesService* SavedFilesService::Get(Profile* profile) { | 196 SavedFilesService* SavedFilesService::Get(content::BrowserContext* context) { |
| 197 return SavedFilesServiceFactory::GetForProfile(profile); | 197 return SavedFilesServiceFactory::GetForBrowserContext(context); |
| 198 } | 198 } |
| 199 | 199 |
| 200 SavedFilesService::SavedFilesService(Profile* profile) : profile_(profile) { | 200 SavedFilesService::SavedFilesService(content::BrowserContext* context) |
| 201 : context_(context) { |
| 201 registrar_.Add(this, | 202 registrar_.Add(this, |
| 202 extensions::NOTIFICATION_EXTENSION_HOST_DESTROYED, | 203 extensions::NOTIFICATION_EXTENSION_HOST_DESTROYED, |
| 203 content::NotificationService::AllSources()); | 204 content::NotificationService::AllSources()); |
| 204 registrar_.Add(this, | 205 registrar_.Add(this, |
| 205 chrome::NOTIFICATION_APP_TERMINATING, | 206 chrome::NOTIFICATION_APP_TERMINATING, |
| 206 content::NotificationService::AllSources()); | 207 content::NotificationService::AllSources()); |
| 207 } | 208 } |
| 208 | 209 |
| 209 SavedFilesService::~SavedFilesService() {} | 210 SavedFilesService::~SavedFilesService() {} |
| 210 | 211 |
| (...skipping 30 matching lines...) Expand all Loading... |
| 241 void SavedFilesService::EnqueueFileEntry(const std::string& extension_id, | 242 void SavedFilesService::EnqueueFileEntry(const std::string& extension_id, |
| 242 const std::string& id) { | 243 const std::string& id) { |
| 243 GetOrInsert(extension_id)->EnqueueFileEntry(id); | 244 GetOrInsert(extension_id)->EnqueueFileEntry(id); |
| 244 } | 245 } |
| 245 | 246 |
| 246 std::vector<SavedFileEntry> SavedFilesService::GetAllFileEntries( | 247 std::vector<SavedFileEntry> SavedFilesService::GetAllFileEntries( |
| 247 const std::string& extension_id) { | 248 const std::string& extension_id) { |
| 248 SavedFiles* saved_files = Get(extension_id); | 249 SavedFiles* saved_files = Get(extension_id); |
| 249 if (saved_files) | 250 if (saved_files) |
| 250 return saved_files->GetAllFileEntries(); | 251 return saved_files->GetAllFileEntries(); |
| 251 return GetSavedFileEntries(ExtensionPrefs::Get(profile_), extension_id); | 252 return GetSavedFileEntries(ExtensionPrefs::Get(context_), extension_id); |
| 252 } | 253 } |
| 253 | 254 |
| 254 bool SavedFilesService::IsRegistered(const std::string& extension_id, | 255 bool SavedFilesService::IsRegistered(const std::string& extension_id, |
| 255 const std::string& id) { | 256 const std::string& id) { |
| 256 return GetOrInsert(extension_id)->IsRegistered(id); | 257 return GetOrInsert(extension_id)->IsRegistered(id); |
| 257 } | 258 } |
| 258 | 259 |
| 259 const SavedFileEntry* SavedFilesService::GetFileEntry( | 260 const SavedFileEntry* SavedFilesService::GetFileEntry( |
| 260 const std::string& extension_id, | 261 const std::string& extension_id, |
| 261 const std::string& id) { | 262 const std::string& id) { |
| 262 return GetOrInsert(extension_id)->GetFileEntry(id); | 263 return GetOrInsert(extension_id)->GetFileEntry(id); |
| 263 } | 264 } |
| 264 | 265 |
| 265 void SavedFilesService::ClearQueueIfNoRetainPermission( | 266 void SavedFilesService::ClearQueueIfNoRetainPermission( |
| 266 const Extension* extension) { | 267 const Extension* extension) { |
| 267 if (!extension->permissions_data()->active_permissions().HasAPIPermission( | 268 if (!extension->permissions_data()->active_permissions().HasAPIPermission( |
| 268 APIPermission::kFileSystemRetainEntries)) { | 269 APIPermission::kFileSystemRetainEntries)) { |
| 269 ClearQueue(extension); | 270 ClearQueue(extension); |
| 270 } | 271 } |
| 271 } | 272 } |
| 272 | 273 |
| 273 void SavedFilesService::ClearQueue(const extensions::Extension* extension) { | 274 void SavedFilesService::ClearQueue(const extensions::Extension* extension) { |
| 274 ClearSavedFileEntries(ExtensionPrefs::Get(profile_), extension->id()); | 275 ClearSavedFileEntries(ExtensionPrefs::Get(context_), extension->id()); |
| 275 Clear(extension->id()); | 276 Clear(extension->id()); |
| 276 } | 277 } |
| 277 | 278 |
| 278 SavedFilesService::SavedFiles* SavedFilesService::Get( | 279 SavedFilesService::SavedFiles* SavedFilesService::Get( |
| 279 const std::string& extension_id) const { | 280 const std::string& extension_id) const { |
| 280 auto it = extension_id_to_saved_files_.find(extension_id); | 281 auto it = extension_id_to_saved_files_.find(extension_id); |
| 281 if (it != extension_id_to_saved_files_.end()) | 282 if (it != extension_id_to_saved_files_.end()) |
| 282 return it->second.get(); | 283 return it->second.get(); |
| 283 | 284 |
| 284 return NULL; | 285 return NULL; |
| 285 } | 286 } |
| 286 | 287 |
| 287 SavedFilesService::SavedFiles* SavedFilesService::GetOrInsert( | 288 SavedFilesService::SavedFiles* SavedFilesService::GetOrInsert( |
| 288 const std::string& extension_id) { | 289 const std::string& extension_id) { |
| 289 SavedFiles* saved_files = Get(extension_id); | 290 SavedFiles* saved_files = Get(extension_id); |
| 290 if (saved_files) | 291 if (saved_files) |
| 291 return saved_files; | 292 return saved_files; |
| 292 | 293 |
| 293 std::unique_ptr<SavedFiles> scoped_saved_files( | 294 std::unique_ptr<SavedFiles> scoped_saved_files( |
| 294 new SavedFiles(profile_, extension_id)); | 295 new SavedFiles(context_, extension_id)); |
| 295 saved_files = scoped_saved_files.get(); | 296 saved_files = scoped_saved_files.get(); |
| 296 extension_id_to_saved_files_.insert( | 297 extension_id_to_saved_files_.insert( |
| 297 std::make_pair(extension_id, std::move(scoped_saved_files))); | 298 std::make_pair(extension_id, std::move(scoped_saved_files))); |
| 298 return saved_files; | 299 return saved_files; |
| 299 } | 300 } |
| 300 | 301 |
| 301 void SavedFilesService::Clear(const std::string& extension_id) { | 302 void SavedFilesService::Clear(const std::string& extension_id) { |
| 302 extension_id_to_saved_files_.erase(extension_id); | 303 extension_id_to_saved_files_.erase(extension_id); |
| 303 } | 304 } |
| 304 | 305 |
| 305 SavedFilesService::SavedFiles::SavedFiles(Profile* profile, | 306 SavedFilesService::SavedFiles::SavedFiles(content::BrowserContext* context, |
| 306 const std::string& extension_id) | 307 const std::string& extension_id) |
| 307 : profile_(profile), extension_id_(extension_id) { | 308 : context_(context), extension_id_(extension_id) { |
| 308 LoadSavedFileEntriesFromPreferences(); | 309 LoadSavedFileEntriesFromPreferences(); |
| 309 } | 310 } |
| 310 | 311 |
| 311 SavedFilesService::SavedFiles::~SavedFiles() {} | 312 SavedFilesService::SavedFiles::~SavedFiles() {} |
| 312 | 313 |
| 313 void SavedFilesService::SavedFiles::RegisterFileEntry( | 314 void SavedFilesService::SavedFiles::RegisterFileEntry( |
| 314 const std::string& id, | 315 const std::string& id, |
| 315 const base::FilePath& file_path, | 316 const base::FilePath& file_path, |
| 316 bool is_directory) { | 317 bool is_directory) { |
| 317 auto it = registered_file_entries_.find(id); | 318 auto it = registered_file_entries_.find(id); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 335 if (it->second == file_entry) | 336 if (it->second == file_entry) |
| 336 return; | 337 return; |
| 337 | 338 |
| 338 file_entry->sequence_number = it->first + 1; | 339 file_entry->sequence_number = it->first + 1; |
| 339 } else { | 340 } else { |
| 340 // The first sequence number is 1, as 0 means the entry is not in the LRU. | 341 // The first sequence number is 1, as 0 means the entry is not in the LRU. |
| 341 file_entry->sequence_number = 1; | 342 file_entry->sequence_number = 1; |
| 342 } | 343 } |
| 343 saved_file_lru_.insert( | 344 saved_file_lru_.insert( |
| 344 std::make_pair(file_entry->sequence_number, file_entry)); | 345 std::make_pair(file_entry->sequence_number, file_entry)); |
| 345 ExtensionPrefs* prefs = ExtensionPrefs::Get(profile_); | 346 ExtensionPrefs* prefs = ExtensionPrefs::Get(context_); |
| 346 if (old_sequence_number) { | 347 if (old_sequence_number) { |
| 347 saved_file_lru_.erase(old_sequence_number); | 348 saved_file_lru_.erase(old_sequence_number); |
| 348 UpdateSavedFileEntry(prefs, extension_id_, *file_entry); | 349 UpdateSavedFileEntry(prefs, extension_id_, *file_entry); |
| 349 } else { | 350 } else { |
| 350 AddSavedFileEntry(prefs, extension_id_, *file_entry); | 351 AddSavedFileEntry(prefs, extension_id_, *file_entry); |
| 351 if (saved_file_lru_.size() > g_max_saved_file_entries) { | 352 if (saved_file_lru_.size() > g_max_saved_file_entries) { |
| 352 std::map<int, SavedFileEntry*>::iterator it = saved_file_lru_.begin(); | 353 std::map<int, SavedFileEntry*>::iterator it = saved_file_lru_.begin(); |
| 353 it->second->sequence_number = 0; | 354 it->second->sequence_number = 0; |
| 354 RemoveSavedFileEntry(prefs, extension_id_, it->second->id); | 355 RemoveSavedFileEntry(prefs, extension_id_, it->second->id); |
| 355 saved_file_lru_.erase(it); | 356 saved_file_lru_.erase(it); |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 390 saved_file_lru_.rbegin(); | 391 saved_file_lru_.rbegin(); |
| 391 if (it == saved_file_lru_.rend()) | 392 if (it == saved_file_lru_.rend()) |
| 392 return; | 393 return; |
| 393 | 394 |
| 394 // Only compact sequence numbers if the last entry's sequence number is the | 395 // Only compact sequence numbers if the last entry's sequence number is the |
| 395 // maximum value. This should almost never be the case. | 396 // maximum value. This should almost never be the case. |
| 396 if (it->first < g_max_sequence_number) | 397 if (it->first < g_max_sequence_number) |
| 397 return; | 398 return; |
| 398 | 399 |
| 399 int sequence_number = 0; | 400 int sequence_number = 0; |
| 400 ExtensionPrefs* prefs = ExtensionPrefs::Get(profile_); | 401 ExtensionPrefs* prefs = ExtensionPrefs::Get(context_); |
| 401 for (std::map<int, SavedFileEntry*>::iterator it = saved_file_lru_.begin(); | 402 for (std::map<int, SavedFileEntry*>::iterator it = saved_file_lru_.begin(); |
| 402 it != saved_file_lru_.end(); | 403 it != saved_file_lru_.end(); |
| 403 ++it) { | 404 ++it) { |
| 404 sequence_number++; | 405 sequence_number++; |
| 405 if (it->second->sequence_number == sequence_number) | 406 if (it->second->sequence_number == sequence_number) |
| 406 continue; | 407 continue; |
| 407 | 408 |
| 408 SavedFileEntry* file_entry = it->second; | 409 SavedFileEntry* file_entry = it->second; |
| 409 file_entry->sequence_number = sequence_number; | 410 file_entry->sequence_number = sequence_number; |
| 410 UpdateSavedFileEntry(prefs, extension_id_, *file_entry); | 411 UpdateSavedFileEntry(prefs, extension_id_, *file_entry); |
| 411 saved_file_lru_.erase(it++); | 412 saved_file_lru_.erase(it++); |
| 412 // Provide the following element as an insert hint. While optimized | 413 // Provide the following element as an insert hint. While optimized |
| 413 // insertion time with the following element as a hint is only supported by | 414 // insertion time with the following element as a hint is only supported by |
| 414 // the spec in C++11, the implementations do support this. | 415 // the spec in C++11, the implementations do support this. |
| 415 it = saved_file_lru_.insert( | 416 it = saved_file_lru_.insert( |
| 416 it, std::make_pair(file_entry->sequence_number, file_entry)); | 417 it, std::make_pair(file_entry->sequence_number, file_entry)); |
| 417 } | 418 } |
| 418 } | 419 } |
| 419 | 420 |
| 420 void SavedFilesService::SavedFiles::LoadSavedFileEntriesFromPreferences() { | 421 void SavedFilesService::SavedFiles::LoadSavedFileEntriesFromPreferences() { |
| 421 ExtensionPrefs* prefs = ExtensionPrefs::Get(profile_); | 422 ExtensionPrefs* prefs = ExtensionPrefs::Get(context_); |
| 422 std::vector<SavedFileEntry> saved_entries = | 423 std::vector<SavedFileEntry> saved_entries = |
| 423 GetSavedFileEntries(prefs, extension_id_); | 424 GetSavedFileEntries(prefs, extension_id_); |
| 424 for (std::vector<SavedFileEntry>::iterator it = saved_entries.begin(); | 425 for (std::vector<SavedFileEntry>::iterator it = saved_entries.begin(); |
| 425 it != saved_entries.end(); | 426 it != saved_entries.end(); |
| 426 ++it) { | 427 ++it) { |
| 427 std::unique_ptr<SavedFileEntry> file_entry(new SavedFileEntry(*it)); | 428 std::unique_ptr<SavedFileEntry> file_entry(new SavedFileEntry(*it)); |
| 428 const std::string& id = file_entry->id; | 429 const std::string& id = file_entry->id; |
| 429 saved_file_lru_.insert( | 430 saved_file_lru_.insert( |
| 430 std::make_pair(file_entry->sequence_number, file_entry.get())); | 431 std::make_pair(file_entry->sequence_number, file_entry.get())); |
| 431 registered_file_entries_[id] = std::move(file_entry); | 432 registered_file_entries_[id] = std::move(file_entry); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 446 void SavedFilesService::SetLruSizeForTest(int size) { | 447 void SavedFilesService::SetLruSizeForTest(int size) { |
| 447 g_max_saved_file_entries = size; | 448 g_max_saved_file_entries = size; |
| 448 } | 449 } |
| 449 | 450 |
| 450 // static | 451 // static |
| 451 void SavedFilesService::ClearLruSizeForTest() { | 452 void SavedFilesService::ClearLruSizeForTest() { |
| 452 g_max_saved_file_entries = kMaxSavedFileEntries; | 453 g_max_saved_file_entries = kMaxSavedFileEntries; |
| 453 } | 454 } |
| 454 | 455 |
| 455 } // namespace apps | 456 } // namespace apps |
| OLD | NEW |