| 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..c4a25bde62e2e9cd321a049543f9f5f397cb22db 100644
|
| --- a/chrome/browser/chromeos/file_system_provider/service.cc
|
| +++ b/chrome/browser/chromeos/file_system_provider/service.cc
|
| @@ -53,12 +53,26 @@ 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());
|
| }
|
|
|
| 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.
|
| + // TODO(mtomasz): Create a TestingService class and remove this code.
|
| ProvidedFileSystemMap::iterator it = file_system_map_.begin();
|
| while (it != file_system_map_.end()) {
|
| const std::string file_system_id =
|
| @@ -66,7 +80,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 +172,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 +183,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 +224,11 @@ bool Service::UnmountFileSystem(const std::string& extension_id,
|
|
|
| mount_point_name_to_key_map_.erase(mount_point_name);
|
|
|
| + if (reason == UNMOUNT_REASON_USER) {
|
| + 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 +280,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 +290,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 +335,72 @@ void Service::OnRequestUnmountStatus(
|
| }
|
| }
|
|
|
| -void Service::RememberFileSystems() {
|
| - base::DictionaryValue extensions;
|
| - const std::vector<ProvidedFileSystemInfo> file_system_info_list =
|
| - GetProvidedFileSystemInfoList();
|
| -
|
| - 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);
|
| - }
|
| -
|
| - 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);
|
| - }
|
| +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());
|
|
|
| PrefService* pref_service = profile_->GetPrefs();
|
| DCHECK(pref_service);
|
| - pref_service->Set(prefs::kFileSystemProviderMounted, extensions);
|
| - pref_service->CommitPendingWrite();
|
| -}
|
|
|
| -void Service::ForgetFileSystems(const std::string& extension_id) {
|
| - PrefService* pref_service = profile_->GetPrefs();
|
| - DCHECK(pref_service);
|
| + DictionaryPrefUpdate dict_update(pref_service,
|
| + prefs::kFileSystemProviderMounted);
|
|
|
| - DictionaryPrefUpdate update(pref_service, prefs::kFileSystemProviderMounted);
|
| - base::DictionaryValue* extensions = update.Get();
|
| - DCHECK(extensions);
|
| + 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);
|
| + }
|
|
|
| - extensions->Remove(extension_id, NULL);
|
| + file_systems_per_extension->SetWithoutPathExpansion(
|
| + file_system_info.file_system_id(), file_system);
|
| }
|
|
|
| -void Service::RestoreFileSystems(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);
|
|
|
| - const base::DictionaryValue* extensions =
|
| - pref_service->GetDictionary(prefs::kFileSystemProviderMounted);
|
| - DCHECK(extensions);
|
| + DictionaryPrefUpdate dict_update(pref_service,
|
| + prefs::kFileSystemProviderMounted);
|
| +
|
| + base::DictionaryValue* file_systems_per_extension = NULL;
|
| + if (!dict_update->GetDictionary(extension_id, &file_systems_per_extension)) {
|
| + return; // Nothing to forget.
|
| + }
|
|
|
| - const base::ListValue* file_systems = NULL;
|
| + file_systems_per_extension->RemoveWithoutPathExpansion(file_system_id, NULL);
|
| + if (!file_systems_per_extension->size())
|
| + dict_update->Remove(extension_id, NULL);
|
| +}
|
|
|
| - 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 +414,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
|
|
|