OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 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 "chrome/browser/chromeos/file_system_provider/service.h" | 5 #include "chrome/browser/chromeos/file_system_provider/service.h" |
6 | 6 |
7 #include "base/files/file_path.h" | 7 #include "base/files/file_path.h" |
8 #include "base/prefs/pref_service.h" | 8 #include "base/prefs/pref_service.h" |
9 #include "base/prefs/scoped_user_pref_update.h" | 9 #include "base/prefs/scoped_user_pref_update.h" |
10 #include "base/stl_util.h" | 10 #include "base/stl_util.h" |
(...skipping 22 matching lines...) Expand all Loading... |
33 DCHECK(profile); | 33 DCHECK(profile); |
34 return new ProvidedFileSystem(profile, file_system_info); | 34 return new ProvidedFileSystem(profile, file_system_info); |
35 } | 35 } |
36 | 36 |
37 } // namespace | 37 } // namespace |
38 | 38 |
39 const char kPrefKeyFileSystemId[] = "file-system-id"; | 39 const char kPrefKeyFileSystemId[] = "file-system-id"; |
40 const char kPrefKeyDisplayName[] = "display-name"; | 40 const char kPrefKeyDisplayName[] = "display-name"; |
41 const char kPrefKeyWritable[] = "writable"; | 41 const char kPrefKeyWritable[] = "writable"; |
42 const char kPrefKeySupportsNotifyTag[] = "supports-notify-tag"; | 42 const char kPrefKeySupportsNotifyTag[] = "supports-notify-tag"; |
| 43 const char kPrefKeyObservedEntries[] = "observed-entries"; |
| 44 const char kPrefKeyObservedEntryEntryPath[] = "entry-path"; |
| 45 const char kPrefKeyObservedEntryRecursive[] = "recursive"; |
| 46 const char kPrefKeyObservedEntryLastTag[] = "last-tag"; |
43 | 47 |
44 void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry) { | 48 void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry) { |
45 registry->RegisterDictionaryPref( | 49 registry->RegisterDictionaryPref( |
46 prefs::kFileSystemProviderMounted, | 50 prefs::kFileSystemProviderMounted, |
47 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); | 51 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); |
48 } | 52 } |
49 | 53 |
50 Service::Service(Profile* profile, | 54 Service::Service(Profile* profile, |
51 extensions::ExtensionRegistry* extension_registry) | 55 extensions::ExtensionRegistry* extension_registry) |
52 : profile_(profile), | 56 : profile_(profile), |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
156 // mount_path = /provided/b33f1337-hello_world-5aa5 | 160 // mount_path = /provided/b33f1337-hello_world-5aa5 |
157 ProvidedFileSystemInfo file_system_info(extension_id, options, mount_path); | 161 ProvidedFileSystemInfo file_system_info(extension_id, options, mount_path); |
158 | 162 |
159 ProvidedFileSystemInterface* file_system = | 163 ProvidedFileSystemInterface* file_system = |
160 file_system_factory_.Run(profile_, file_system_info); | 164 file_system_factory_.Run(profile_, file_system_info); |
161 DCHECK(file_system); | 165 DCHECK(file_system); |
162 file_system_map_[FileSystemKey(extension_id, options.file_system_id)] = | 166 file_system_map_[FileSystemKey(extension_id, options.file_system_id)] = |
163 file_system; | 167 file_system; |
164 mount_point_name_to_key_map_[mount_point_name] = | 168 mount_point_name_to_key_map_[mount_point_name] = |
165 FileSystemKey(extension_id, options.file_system_id); | 169 FileSystemKey(extension_id, options.file_system_id); |
166 RememberFileSystem(file_system_info); | 170 RememberFileSystem(file_system_info, *file_system->GetObservedEntries()); |
167 | 171 |
168 FOR_EACH_OBSERVER( | 172 FOR_EACH_OBSERVER( |
169 Observer, | 173 Observer, |
170 observers_, | 174 observers_, |
171 OnProvidedFileSystemMount(file_system_info, base::File::FILE_OK)); | 175 OnProvidedFileSystemMount(file_system_info, base::File::FILE_OK)); |
172 | 176 |
173 return true; | 177 return true; |
174 } | 178 } |
175 | 179 |
176 bool Service::UnmountFileSystem(const std::string& extension_id, | 180 bool Service::UnmountFileSystem(const std::string& extension_id, |
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
332 ChangeType change_type, | 336 ChangeType change_type, |
333 const ChildChanges& child_changes, | 337 const ChildChanges& child_changes, |
334 const base::Closure& callback) { | 338 const base::Closure& callback) { |
335 callback.Run(); | 339 callback.Run(); |
336 } | 340 } |
337 | 341 |
338 void Service::OnObservedEntryTagUpdated( | 342 void Service::OnObservedEntryTagUpdated( |
339 const ProvidedFileSystemInfo& file_system_info, | 343 const ProvidedFileSystemInfo& file_system_info, |
340 const base::FilePath& observed_path, | 344 const base::FilePath& observed_path, |
341 const std::string& tag) { | 345 const std::string& tag) { |
342 // TODO(mtomasz): Store tags of observed entries in preferences, or better | 346 PrefService* const pref_service = profile_->GetPrefs(); |
343 // in leveldb. | 347 DCHECK(pref_service); |
| 348 |
| 349 // TODO(mtomasz): Consider optimizing it by moving information about observed |
| 350 // entries, or even file systems to leveldb. |
| 351 DictionaryPrefUpdate dict_update(pref_service, |
| 352 prefs::kFileSystemProviderMounted); |
| 353 |
| 354 // All of the following checks should not happen in healthy environment. |
| 355 // However, since they rely on storage, DCHECKs can't be used. |
| 356 base::DictionaryValue* file_systems_per_extension = NULL; |
| 357 base::DictionaryValue* file_system = NULL; |
| 358 base::DictionaryValue* observed_entries = NULL; |
| 359 base::DictionaryValue* observed_entry = NULL; |
| 360 if (!dict_update->GetDictionaryWithoutPathExpansion( |
| 361 file_system_info.extension_id(), &file_systems_per_extension) || |
| 362 !file_systems_per_extension->GetDictionaryWithoutPathExpansion( |
| 363 file_system_info.file_system_id(), &file_system) || |
| 364 !file_system->GetDictionaryWithoutPathExpansion(kPrefKeyObservedEntries, |
| 365 &observed_entries) || |
| 366 !observed_entries->GetDictionaryWithoutPathExpansion( |
| 367 observed_path.value(), &observed_entry)) { |
| 368 // Broken preferences. |
| 369 LOG(ERROR) << "Broken preferences detected while updating a tag."; |
| 370 return; |
| 371 } |
| 372 |
| 373 observed_entry->SetStringWithoutPathExpansion(kPrefKeyObservedEntryLastTag, |
| 374 tag); |
344 } | 375 } |
345 | 376 |
346 void Service::OnObservedEntryListChanged( | 377 void Service::OnObservedEntryListChanged( |
347 const ProvidedFileSystemInfo& file_system_info, | 378 const ProvidedFileSystemInfo& file_system_info, |
348 const ObservedEntries& observed_entries) { | 379 const ObservedEntries& observed_entries) { |
349 // TODO(mtomasz): Store observed entries in preferences or leveldb. | 380 RememberFileSystem(file_system_info, observed_entries); |
350 } | 381 } |
351 | 382 |
352 void Service::RememberFileSystem( | 383 void Service::RememberFileSystem(const ProvidedFileSystemInfo& file_system_info, |
353 const ProvidedFileSystemInfo& file_system_info) { | 384 const ObservedEntries& observed_entries) { |
354 base::DictionaryValue* file_system = new base::DictionaryValue(); | 385 base::DictionaryValue* const file_system = new base::DictionaryValue(); |
355 file_system->SetStringWithoutPathExpansion(kPrefKeyFileSystemId, | 386 file_system->SetStringWithoutPathExpansion(kPrefKeyFileSystemId, |
356 file_system_info.file_system_id()); | 387 file_system_info.file_system_id()); |
357 file_system->SetStringWithoutPathExpansion(kPrefKeyDisplayName, | 388 file_system->SetStringWithoutPathExpansion(kPrefKeyDisplayName, |
358 file_system_info.display_name()); | 389 file_system_info.display_name()); |
359 file_system->SetBooleanWithoutPathExpansion(kPrefKeyWritable, | 390 file_system->SetBooleanWithoutPathExpansion(kPrefKeyWritable, |
360 file_system_info.writable()); | 391 file_system_info.writable()); |
361 file_system->SetBooleanWithoutPathExpansion( | 392 file_system->SetBooleanWithoutPathExpansion( |
362 kPrefKeySupportsNotifyTag, file_system_info.supports_notify_tag()); | 393 kPrefKeySupportsNotifyTag, file_system_info.supports_notify_tag()); |
363 | 394 |
| 395 base::DictionaryValue* const observed_entries_value = |
| 396 new base::DictionaryValue(); |
| 397 file_system->SetWithoutPathExpansion(kPrefKeyObservedEntries, |
| 398 observed_entries_value); |
| 399 |
| 400 for (ObservedEntries::const_iterator it = observed_entries.begin(); |
| 401 it != observed_entries.end(); |
| 402 ++it) { |
| 403 base::DictionaryValue* const observed_entry = new base::DictionaryValue(); |
| 404 observed_entries_value->SetWithoutPathExpansion(it->first.value(), |
| 405 observed_entry); |
| 406 observed_entry->SetStringWithoutPathExpansion( |
| 407 kPrefKeyObservedEntryEntryPath, it->second.entry_path.value()); |
| 408 observed_entry->SetBooleanWithoutPathExpansion( |
| 409 kPrefKeyObservedEntryRecursive, it->second.recursive); |
| 410 observed_entry->SetStringWithoutPathExpansion(kPrefKeyObservedEntryLastTag, |
| 411 it->second.last_tag); |
| 412 } |
| 413 |
364 PrefService* const pref_service = profile_->GetPrefs(); | 414 PrefService* const pref_service = profile_->GetPrefs(); |
365 DCHECK(pref_service); | 415 DCHECK(pref_service); |
366 | 416 |
367 DictionaryPrefUpdate dict_update(pref_service, | 417 DictionaryPrefUpdate dict_update(pref_service, |
368 prefs::kFileSystemProviderMounted); | 418 prefs::kFileSystemProviderMounted); |
369 | 419 |
370 base::DictionaryValue* file_systems_per_extension = NULL; | 420 base::DictionaryValue* file_systems_per_extension = NULL; |
371 if (!dict_update->GetDictionaryWithoutPathExpansion( | 421 if (!dict_update->GetDictionaryWithoutPathExpansion( |
372 file_system_info.extension_id(), &file_systems_per_extension)) { | 422 file_system_info.extension_id(), &file_systems_per_extension)) { |
373 file_systems_per_extension = new base::DictionaryValue(); | 423 file_systems_per_extension = new base::DictionaryValue(); |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
438 &display_name) || | 488 &display_name) || |
439 !file_system->GetBooleanWithoutPathExpansion(kPrefKeyWritable, | 489 !file_system->GetBooleanWithoutPathExpansion(kPrefKeyWritable, |
440 &writable) || | 490 &writable) || |
441 !file_system->GetBooleanWithoutPathExpansion(kPrefKeySupportsNotifyTag, | 491 !file_system->GetBooleanWithoutPathExpansion(kPrefKeySupportsNotifyTag, |
442 &supports_notify_tag) || | 492 &supports_notify_tag) || |
443 file_system_id.empty() || display_name.empty()) { | 493 file_system_id.empty() || display_name.empty()) { |
444 LOG(ERROR) | 494 LOG(ERROR) |
445 << "Malformed provided file system information in preferences."; | 495 << "Malformed provided file system information in preferences."; |
446 continue; | 496 continue; |
447 } | 497 } |
| 498 |
448 MountOptions options; | 499 MountOptions options; |
449 options.file_system_id = file_system_id; | 500 options.file_system_id = file_system_id; |
450 options.display_name = display_name; | 501 options.display_name = display_name; |
451 options.writable = writable; | 502 options.writable = writable; |
452 options.supports_notify_tag = supports_notify_tag; | 503 options.supports_notify_tag = supports_notify_tag; |
| 504 |
453 const bool result = MountFileSystem(extension_id, options); | 505 const bool result = MountFileSystem(extension_id, options); |
454 if (!result) { | 506 if (!result) { |
455 LOG(ERROR) << "Failed to restore a provided file system from " | 507 LOG(ERROR) << "Failed to restore a provided file system from " |
456 << "preferences: " << extension_id << ", " << file_system_id | 508 << "preferences: " << extension_id << ", " << file_system_id |
457 << ", " << display_name << "."; | 509 << ", " << display_name << "."; |
458 // Since remounting of the file system failed, then remove it from | 510 // Since remounting of the file system failed, then remove it from |
459 // preferences to avoid remounting it over and over again with a failure. | 511 // preferences to avoid remounting it over and over again with a failure. |
460 ForgetFileSystem(extension_id, file_system_id); | 512 ForgetFileSystem(extension_id, file_system_id); |
461 } | 513 } |
| 514 |
| 515 // Restore observed entries. It's optional, since this field is new. |
| 516 const base::DictionaryValue* observed_entries = NULL; |
| 517 if (file_system->GetDictionaryWithoutPathExpansion(kPrefKeyObservedEntries, |
| 518 &observed_entries)) { |
| 519 ProvidedFileSystemInterface* const restored_file_system = |
| 520 GetProvidedFileSystem(extension_id, file_system_id); |
| 521 DCHECK(restored_file_system); |
| 522 |
| 523 for (base::DictionaryValue::Iterator it(*observed_entries); !it.IsAtEnd(); |
| 524 it.Advance()) { |
| 525 const base::Value* observed_entry_value = NULL; |
| 526 const base::DictionaryValue* observed_entry = NULL; |
| 527 observed_entries->GetWithoutPathExpansion(it.key(), |
| 528 &observed_entry_value); |
| 529 DCHECK(observed_entry_value); |
| 530 |
| 531 std::string entry_path; |
| 532 bool recursive = false; |
| 533 std::string last_tag; |
| 534 |
| 535 if (!observed_entry_value->GetAsDictionary(&observed_entry) || |
| 536 !observed_entry->GetStringWithoutPathExpansion( |
| 537 kPrefKeyObservedEntryEntryPath, &entry_path) || |
| 538 !observed_entry->GetBooleanWithoutPathExpansion( |
| 539 kPrefKeyObservedEntryRecursive, &recursive) || |
| 540 !observed_entry->GetStringWithoutPathExpansion( |
| 541 kPrefKeyObservedEntryLastTag, &last_tag) || |
| 542 it.key() != entry_path || entry_path.empty() || |
| 543 (!options.supports_notify_tag && !last_tag.empty())) { |
| 544 LOG(ERROR) << "Malformed observed entry information in preferences."; |
| 545 continue; |
| 546 } |
| 547 |
| 548 ObservedEntry restored_observed_entry; |
| 549 restored_observed_entry.entry_path = |
| 550 base::FilePath::FromUTF8Unsafe(entry_path); |
| 551 restored_observed_entry.recursive = recursive; |
| 552 restored_observed_entry.last_tag = last_tag; |
| 553 (*restored_file_system |
| 554 ->GetObservedEntries())[restored_observed_entry.entry_path] = |
| 555 restored_observed_entry; |
| 556 } |
| 557 } |
462 } | 558 } |
463 } | 559 } |
464 | 560 |
465 } // namespace file_system_provider | 561 } // namespace file_system_provider |
466 } // namespace chromeos | 562 } // namespace chromeos |
OLD | NEW |