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 66c7df347a5b9c5a5a45198db76777334974453c..0527cac200b99dd5d22f91c1d4aed9c1ade66262 100644 |
--- a/chrome/browser/chromeos/file_system_provider/service.cc |
+++ b/chrome/browser/chromeos/file_system_provider/service.cc |
@@ -53,11 +53,23 @@ 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()); |
+ pref_service->ClearPref(prefs::kFileSystemProviderMounted); |
hashimoto
2014/07/02 08:59:37
Is it OK to clear the pref at this point?
Extensio
mtomasz
2014/07/03 05:24:07
Done.
|
+ pref_service->CommitPendingWrite(); |
} |
Service::~Service() { |
extension_registry_->RemoveObserver(this); |
- RememberFileSystems(); |
ProvidedFileSystemMap::iterator it = file_system_map_.begin(); |
while (it != file_system_map_.end()) { |
@@ -66,7 +78,7 @@ Service::~Service() { |
const std::string extension_id = |
it->second->GetFileSystemInfo().extension_id(); |
++it; |
- UnmountFileSystem(extension_id, file_system_id); |
+ UnmountFileSystem(extension_id, file_system_id, UNMOUNT_MODE_SHUTDOWN); |
} |
DCHECK_EQ(0u, file_system_map_.size()); |
@@ -156,6 +168,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, |
@@ -166,7 +179,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, |
+ UnmountMode mode) { |
DCHECK(thread_checker_.CalledOnValidThread()); |
const ProvidedFileSystemMap::iterator file_system_it = |
@@ -206,6 +220,9 @@ bool Service::UnmountFileSystem(const std::string& extension_id, |
mount_point_name_to_key_map_.erase(mount_point_name); |
+ if (mode == UNMOUNT_MODE_USER) |
+ ForgetFileSystem(file_system_info); |
+ |
delete file_system_it->second; |
file_system_map_.erase(file_system_it); |
@@ -257,11 +274,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()) { |
@@ -271,8 +283,12 @@ void Service::OnExtensionUnloaded( |
// by the UnmountFileSystem() call. |
++it; |
if (file_system_info.extension_id() == extension->id()) { |
- bool result = UnmountFileSystem(file_system_info.extension_id(), |
- file_system_info.file_system_id()); |
+ bool result = UnmountFileSystem( |
+ file_system_info.extension_id(), |
+ file_system_info.file_system_id(), |
+ reason == extensions::UnloadedExtensionInfo::REASON_PROFILE_SHUTDOWN |
hashimoto
2014/07/02 08:59:37
If this method gets called during shutdown, is it
mtomasz
2014/07/03 05:24:07
That's correct but but not in case of unit tests.
hashimoto
2014/07/04 06:38:41
Please add a TODO comment to remove the redundant
mtomasz
2014/07/04 07:50:42
Done.
|
+ ? UNMOUNT_MODE_SHUTDOWN |
+ : UNMOUNT_MODE_USER); |
DCHECK(result); |
} |
} |
@@ -313,69 +329,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, |
hashimoto
2014/07/02 08:59:37
Please use one of "FooWithoutPathExpansion" or "Fo
mtomasz
2014/07/03 05:24:07
Currently I'm using WithoutPathExpansion only when
hashimoto
2014/07/04 06:38:41
The problem is that nothing can prevent you and ot
mtomasz
2014/07/04 07:50:42
Do you want me to use WithoutPathExpansion variant
hashimoto
2014/07/07 11:07:46
What Set/Get does is Set/GetWithoutPathExpansion +
mtomasz
2014/07/08 01:52:08
According to code search's xrefs:
DictionaryValue:
hashimoto
2014/07/09 08:36:39
So what?
Generally speaking, WithoutPathExpansion(
mtomasz
2014/07/09 09:18:17
DictionaryValue::SetString() sounds like a default
hashimoto
2014/07/11 06:09:05
Set() has a shorter name and is popular only becau
mtomasz
2014/07/11 06:10:36
Got it. That makes sense.
|
+ 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); |
- 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); |
+ DictionaryPrefUpdate dict_update(pref_service, |
+ prefs::kFileSystemProviderMounted); |
+ |
+ 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(); |
} |
-void Service::ForgetFileSystems(const std::string& extension_id) { |
+void Service::ForgetFileSystem(const ProvidedFileSystemInfo& file_system_info) { |
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(file_system_info.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_info.file_system_id(), NULL); |
+ if (!file_systems_per_extension->size()) |
+ dict_update->Remove(file_system_info.extension_id(), NULL); |
- const base::ListValue* file_systems = NULL; |
+ pref_service->CommitPendingWrite(); |
+} |
- 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, |
hashimoto
2014/07/02 08:59:37
Is it OK to be unable to read prefs saved by the o
mtomasz
2014/07/03 05:24:07
Yes. The API is not released yet, and it is availa
|
+ &file_systems_per_extension)) { |
+ return; // Nothing to restore. |
+ } |
- for (size_t i = 0; i < file_systems->GetSize(); ++i) { |
+ base::DictionaryValue::Iterator it(*file_systems_per_extension); |
+ while (!it.IsAtEnd()) { |
hashimoto
2014/07/02 08:59:37
nit: How about "for (base::DicationaryValue::Itera
mtomasz
2014/07/03 05:24:07
Done.
|
+ 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,7 +412,11 @@ void Service::RestoreFileSystems(const std::string& extension_id) { |
<< "preferences: " << extension_id << ", " << file_system_id |
<< ", " << file_system_name << "."; |
} |
+ |
+ it.Advance(); |
} |
+ |
+ file_systems_to_restore_->Remove(extension_id, NULL); |
} |
} // namespace file_system_provider |