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(file_system_value); | |
hirono
2014/10/17 08:22:23
nit: This check is redundant.
mtomasz
2014/10/20 05:11:56
Why? GetWithoutPathExpansion may fail if the key i
hirono
2014/10/20 05:18:49
It looks the value has been already checked at #47
mtomasz
2014/10/20 05:23:27
You're right! Fixed.
| |
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 |