Chromium Code Reviews| Index: chrome/browser/chromeos/file_system_provider/service.cc |
| diff --git a/chrome/browser/chromeos/file_system_provider/service.cc b/chrome/browser/chromeos/file_system_provider/service.cc |
| index f0ac9602408640b2a4a3afc44dec7c82c24b1303..1b2cecd51baa750487c02d988e6c3c284e68c799 100644 |
| --- a/chrome/browser/chromeos/file_system_provider/service.cc |
| +++ b/chrome/browser/chromeos/file_system_provider/service.cc |
| @@ -53,12 +53,25 @@ Service::Service(Profile* profile, |
| file_system_factory_(base::Bind(CreateProvidedFileSystem)), |
| weak_ptr_factory_(this) { |
| extension_registry_->AddObserver(this); |
| + |
| + // Store previously mounted file systems in order to be able to remount |
| + // them once related extensions are loaded. |
| + PrefService* pref_service = profile_->GetPrefs(); |
| + DCHECK(pref_service); |
| + |
| + const base::DictionaryValue* file_systems = |
| + pref_service->GetDictionary(prefs::kFileSystemProviderMounted); |
| + DCHECK(file_systems); |
| + |
| + file_systems_to_restore_.reset(file_systems->DeepCopy()); |
|
hashimoto
2014/07/04 06:38:42
Do we need this code now?
You can read the diction
mtomasz
2014/07/04 07:50:42
It makes things easier. Note, that In #420 we want
hashimoto
2014/07/07 11:07:46
You can save a list of file systems to be removed
mtomasz
2014/07/08 01:52:09
Done.
|
| } |
| Service::~Service() { |
| extension_registry_->RemoveObserver(this); |
| - RememberFileSystems(); |
| + // Provided file systems should be already unmounted because of receiving |
| + // OnExtensionUnload calls for each installed extension. However, for tests |
| + // we may still have mounted extensions. |
| ProvidedFileSystemMap::iterator it = file_system_map_.begin(); |
| while (it != file_system_map_.end()) { |
| const std::string file_system_id = |
| @@ -66,7 +79,8 @@ Service::~Service() { |
| const std::string extension_id = |
| it->second->GetFileSystemInfo().extension_id(); |
| ++it; |
| - const bool unmount_result = UnmountFileSystem(extension_id, file_system_id); |
| + const bool unmount_result = UnmountFileSystem( |
| + extension_id, file_system_id, UNMOUNT_REASON_SHUTDOWN); |
| DCHECK(unmount_result); |
| } |
| @@ -157,6 +171,7 @@ bool Service::MountFileSystem(const std::string& extension_id, |
| file_system_map_[FileSystemKey(extension_id, file_system_id)] = file_system; |
| mount_point_name_to_key_map_[mount_point_name] = |
| FileSystemKey(extension_id, file_system_id); |
| + RememberFileSystem(file_system_info); |
| FOR_EACH_OBSERVER( |
| Observer, |
| @@ -167,7 +182,8 @@ bool Service::MountFileSystem(const std::string& extension_id, |
| } |
| bool Service::UnmountFileSystem(const std::string& extension_id, |
| - const std::string& file_system_id) { |
| + const std::string& file_system_id, |
| + UnmountReason reason) { |
| DCHECK(thread_checker_.CalledOnValidThread()); |
| const ProvidedFileSystemMap::iterator file_system_it = |
| @@ -207,6 +223,10 @@ bool Service::UnmountFileSystem(const std::string& extension_id, |
| mount_point_name_to_key_map_.erase(mount_point_name); |
| + if (reason == UNMOUNT_REASON_USER) |
|
hashimoto
2014/07/04 06:38:42
multiple lines should be accommodated with {}.
mtomasz
2014/07/04 07:50:42
Done.
|
| + ForgetFileSystem(file_system_info.extension_id(), |
| + file_system_info.file_system_id()); |
| + |
| delete file_system_it->second; |
| file_system_map_.erase(file_system_it); |
| @@ -258,11 +278,6 @@ void Service::OnExtensionUnloaded( |
| content::BrowserContext* browser_context, |
| const extensions::Extension* extension, |
| extensions::UnloadedExtensionInfo::Reason reason) { |
| - // If the reason is not a profile shutdown, then forget the mounted file |
| - // systems from preferences. |
| - if (reason != extensions::UnloadedExtensionInfo::REASON_PROFILE_SHUTDOWN) |
| - ForgetFileSystems(extension->id()); |
| - |
| // Unmount all of the provided file systems associated with this extension. |
| ProvidedFileSystemMap::iterator it = file_system_map_.begin(); |
| while (it != file_system_map_.end()) { |
| @@ -273,7 +288,11 @@ void Service::OnExtensionUnloaded( |
| ++it; |
| if (file_system_info.extension_id() == extension->id()) { |
| const bool unmount_result = UnmountFileSystem( |
| - file_system_info.extension_id(), file_system_info.file_system_id()); |
| + file_system_info.extension_id(), |
| + file_system_info.file_system_id(), |
| + reason == extensions::UnloadedExtensionInfo::REASON_PROFILE_SHUTDOWN |
| + ? UNMOUNT_REASON_SHUTDOWN |
| + : UNMOUNT_REASON_USER); |
| DCHECK(unmount_result); |
| } |
| } |
| @@ -314,69 +333,75 @@ void Service::OnRequestUnmountStatus( |
| } |
| } |
| -void Service::RememberFileSystems() { |
| - base::DictionaryValue extensions; |
| - const std::vector<ProvidedFileSystemInfo> file_system_info_list = |
| - GetProvidedFileSystemInfoList(); |
| +void Service::RememberFileSystem( |
| + const ProvidedFileSystemInfo& file_system_info) { |
| + base::DictionaryValue* file_system = new base::DictionaryValue(); |
| + file_system->SetString(kPrefKeyFileSystemId, |
| + file_system_info.file_system_id()); |
| + file_system->SetString(kPrefKeyFileSystemName, |
| + file_system_info.file_system_name()); |
| - for (std::vector<ProvidedFileSystemInfo>::const_iterator it = |
| - file_system_info_list.begin(); |
| - it != file_system_info_list.end(); |
| - ++it) { |
| - base::ListValue* file_systems = NULL; |
| - if (!extensions.GetList(it->extension_id(), &file_systems)) { |
| - file_systems = new base::ListValue(); |
| - extensions.Set(it->extension_id(), file_systems); |
| - } |
| + PrefService* pref_service = profile_->GetPrefs(); |
| + DCHECK(pref_service); |
| + |
| + DictionaryPrefUpdate dict_update(pref_service, |
| + prefs::kFileSystemProviderMounted); |
| - base::DictionaryValue* file_system = new base::DictionaryValue(); |
| - file_system->SetString(kPrefKeyFileSystemId, it->file_system_id()); |
| - file_system->SetString(kPrefKeyFileSystemName, it->file_system_name()); |
| - file_systems->Append(file_system); |
| + base::DictionaryValue* file_systems_per_extension = NULL; |
| + if (!dict_update->GetDictionary(file_system_info.extension_id(), |
| + &file_systems_per_extension)) { |
| + file_systems_per_extension = new base::DictionaryValue(); |
| + dict_update->Set(file_system_info.extension_id(), |
| + file_systems_per_extension); |
| } |
| - PrefService* pref_service = profile_->GetPrefs(); |
| - DCHECK(pref_service); |
| - pref_service->Set(prefs::kFileSystemProviderMounted, extensions); |
| + file_systems_per_extension->SetWithoutPathExpansion( |
| + file_system_info.file_system_id(), file_system); |
| pref_service->CommitPendingWrite(); |
|
hashimoto
2014/07/04 06:38:42
pref_service.h says CommitPendingWrite() should be
mtomasz
2014/07/04 07:50:42
If a crash happens, then we don't want to lose mou
|
| } |
| -void Service::ForgetFileSystems(const std::string& extension_id) { |
| +void Service::ForgetFileSystem(const std::string& extension_id, |
| + const std::string& file_system_id) { |
| PrefService* pref_service = profile_->GetPrefs(); |
| DCHECK(pref_service); |
| - DictionaryPrefUpdate update(pref_service, prefs::kFileSystemProviderMounted); |
| - base::DictionaryValue* extensions = update.Get(); |
| - DCHECK(extensions); |
| - |
| - extensions->Remove(extension_id, NULL); |
| -} |
| + DictionaryPrefUpdate dict_update(pref_service, |
| + prefs::kFileSystemProviderMounted); |
| -void Service::RestoreFileSystems(const std::string& extension_id) { |
| - PrefService* pref_service = profile_->GetPrefs(); |
| - DCHECK(pref_service); |
| + base::DictionaryValue* file_systems_per_extension = NULL; |
| + if (!dict_update->GetDictionary(extension_id, &file_systems_per_extension)) { |
| + return; // Nothing to forget. |
| + } |
| - const base::DictionaryValue* extensions = |
| - pref_service->GetDictionary(prefs::kFileSystemProviderMounted); |
| - DCHECK(extensions); |
| + file_systems_per_extension->RemoveWithoutPathExpansion(file_system_id, NULL); |
| + if (!file_systems_per_extension->size()) |
| + dict_update->Remove(extension_id, NULL); |
| - const base::ListValue* file_systems = NULL; |
| + pref_service->CommitPendingWrite(); |
|
hashimoto
2014/07/04 06:38:41
ditto.
mtomasz
2014/07/04 07:50:42
Done.
|
| +} |
| - if (!extensions->GetList(extension_id, &file_systems)) |
| - return; |
| +void Service::RestoreFileSystems(const std::string& extension_id) { |
| + const base::DictionaryValue* file_systems_per_extension = NULL; |
| + if (!file_systems_to_restore_->GetDictionary(extension_id, |
| + &file_systems_per_extension)) { |
| + return; // Nothing to restore. |
| + } |
| - for (size_t i = 0; i < file_systems->GetSize(); ++i) { |
| + for (base::DictionaryValue::Iterator it(*file_systems_per_extension); |
| + !it.IsAtEnd(); |
| + it.Advance()) { |
| + const base::Value* file_system_value = NULL; |
| const base::DictionaryValue* file_system = NULL; |
| - file_systems->GetDictionary(i, &file_system); |
| - DCHECK(file_system); |
| + file_systems_per_extension->GetWithoutPathExpansion(it.key(), |
| + &file_system_value); |
| + DCHECK(file_system_value); |
| std::string file_system_id; |
| - file_system->GetString(kPrefKeyFileSystemId, &file_system_id); |
| - DCHECK(!file_system_id.empty()); |
| - |
| std::string file_system_name; |
| - file_system->GetString(kPrefKeyFileSystemName, &file_system_name); |
| - DCHECK(!file_system_name.empty()); |
| + if (file_system_value->GetAsDictionary(&file_system)) { |
| + file_system->GetString(kPrefKeyFileSystemId, &file_system_id); |
| + file_system->GetString(kPrefKeyFileSystemName, &file_system_name); |
| + } |
| if (file_system_id.empty() || file_system_name.empty()) { |
| LOG(ERROR) |
| @@ -390,8 +415,13 @@ void Service::RestoreFileSystems(const std::string& extension_id) { |
| LOG(ERROR) << "Failed to restore a provided file system from " |
| << "preferences: " << extension_id << ", " << file_system_id |
| << ", " << file_system_name << "."; |
| + // In case of remounting during startup, forget the file system from |
| + // preferences. |
| + ForgetFileSystem(extension_id, file_system_id); |
| } |
| } |
| + |
| + file_systems_to_restore_->Remove(extension_id, NULL); |
| } |
| } // namespace file_system_provider |