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 |