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" |
11 #include "chrome/browser/chromeos/file_system_provider/mount_path_util.h" | 11 #include "chrome/browser/chromeos/file_system_provider/mount_path_util.h" |
12 #include "chrome/browser/chromeos/file_system_provider/observer.h" | 12 #include "chrome/browser/chromeos/file_system_provider/observer.h" |
13 #include "chrome/browser/chromeos/file_system_provider/provided_file_system.h" | 13 #include "chrome/browser/chromeos/file_system_provider/provided_file_system.h" |
14 #include "chrome/browser/chromeos/file_system_provider/provided_file_system_info
.h" | 14 #include "chrome/browser/chromeos/file_system_provider/provided_file_system_info
.h" |
15 #include "chrome/browser/chromeos/file_system_provider/provided_file_system_inte
rface.h" | |
16 #include "chrome/browser/chromeos/file_system_provider/service_factory.h" | 15 #include "chrome/browser/chromeos/file_system_provider/service_factory.h" |
17 #include "chrome/common/pref_names.h" | 16 #include "chrome/common/pref_names.h" |
18 #include "components/pref_registry/pref_registry_syncable.h" | 17 #include "components/pref_registry/pref_registry_syncable.h" |
19 #include "extensions/browser/extension_registry.h" | 18 #include "extensions/browser/extension_registry.h" |
20 #include "extensions/browser/extension_system.h" | 19 #include "extensions/browser/extension_system.h" |
21 #include "storage/browser/fileapi/external_mount_points.h" | 20 #include "storage/browser/fileapi/external_mount_points.h" |
22 | 21 |
23 namespace chromeos { | 22 namespace chromeos { |
24 namespace file_system_provider { | 23 namespace file_system_provider { |
25 namespace { | 24 namespace { |
26 | 25 |
27 // Maximum number of file systems to be mounted in the same time, per profile. | 26 // Maximum number of file systems to be mounted in the same time, per profile. |
28 const size_t kMaxFileSystems = 16; | 27 const size_t kMaxFileSystems = 16; |
29 | 28 |
30 // Default factory for provided file systems. |profile| must not be NULL. | 29 // Default factory for provided file systems. |profile| must not be NULL. |
31 ProvidedFileSystemInterface* CreateProvidedFileSystem( | 30 ProvidedFileSystemInterface* CreateProvidedFileSystem( |
32 Profile* profile, | 31 Profile* profile, |
33 const ProvidedFileSystemInfo& file_system_info) { | 32 const ProvidedFileSystemInfo& file_system_info) { |
34 DCHECK(profile); | 33 DCHECK(profile); |
35 return new ProvidedFileSystem(profile, file_system_info); | 34 return new ProvidedFileSystem(profile, file_system_info); |
36 } | 35 } |
37 | 36 |
38 } // namespace | 37 } // namespace |
39 | 38 |
40 const char kPrefKeyFileSystemId[] = "file-system-id"; | 39 const char kPrefKeyFileSystemId[] = "file-system-id"; |
41 const char kPrefKeyDisplayName[] = "display-name"; | 40 const char kPrefKeyDisplayName[] = "display-name"; |
42 const char kPrefKeyWritable[] = "writable"; | 41 const char kPrefKeyWritable[] = "writable"; |
| 42 const char kPrefKeySupportsNotifyTag[] = "supports-notify-tag"; |
43 | 43 |
44 void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry) { | 44 void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry) { |
45 registry->RegisterDictionaryPref( | 45 registry->RegisterDictionaryPref( |
46 prefs::kFileSystemProviderMounted, | 46 prefs::kFileSystemProviderMounted, |
47 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); | 47 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); |
48 } | 48 } |
49 | 49 |
50 Service::Service(Profile* profile, | 50 Service::Service(Profile* profile, |
51 extensions::ExtensionRegistry* extension_registry) | 51 extensions::ExtensionRegistry* extension_registry) |
52 : profile_(profile), | 52 : profile_(profile), |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
96 | 96 |
97 void Service::SetFileSystemFactoryForTesting( | 97 void Service::SetFileSystemFactoryForTesting( |
98 const FileSystemFactoryCallback& factory_callback) { | 98 const FileSystemFactoryCallback& factory_callback) { |
99 DCHECK(!factory_callback.is_null()); | 99 DCHECK(!factory_callback.is_null()); |
100 file_system_factory_ = factory_callback; | 100 file_system_factory_ = factory_callback; |
101 } | 101 } |
102 | 102 |
103 bool Service::MountFileSystem(const std::string& extension_id, | 103 bool Service::MountFileSystem(const std::string& extension_id, |
104 const std::string& file_system_id, | 104 const std::string& file_system_id, |
105 const std::string& display_name, | 105 const std::string& display_name, |
106 bool writable) { | 106 bool writable, |
| 107 bool supports_notify_tag) { |
107 DCHECK(thread_checker_.CalledOnValidThread()); | 108 DCHECK(thread_checker_.CalledOnValidThread()); |
108 | 109 |
109 // If already exists a file system provided by the same extension with this | 110 // If already exists a file system provided by the same extension with this |
110 // id, then abort. | 111 // id, then abort. |
111 if (GetProvidedFileSystem(extension_id, file_system_id)) { | 112 if (GetProvidedFileSystem(extension_id, file_system_id)) { |
112 FOR_EACH_OBSERVER(Observer, | 113 FOR_EACH_OBSERVER(Observer, |
113 observers_, | 114 observers_, |
114 OnProvidedFileSystemMount(ProvidedFileSystemInfo(), | 115 OnProvidedFileSystemMount(ProvidedFileSystemInfo(), |
115 base::File::FILE_ERROR_EXISTS)); | 116 base::File::FILE_ERROR_EXISTS)); |
116 return false; | 117 return false; |
(...skipping 30 matching lines...) Expand all Loading... |
147 base::File::FILE_ERROR_INVALID_OPERATION)); | 148 base::File::FILE_ERROR_INVALID_OPERATION)); |
148 return false; | 149 return false; |
149 } | 150 } |
150 | 151 |
151 // Store the file system descriptor. Use the mount point name as the file | 152 // Store the file system descriptor. Use the mount point name as the file |
152 // system provider file system id. | 153 // system provider file system id. |
153 // Examples: | 154 // Examples: |
154 // file_system_id = hello_world | 155 // file_system_id = hello_world |
155 // mount_point_name = b33f1337-hello_world-5aa5 | 156 // mount_point_name = b33f1337-hello_world-5aa5 |
156 // writable = false | 157 // writable = false |
| 158 // supports_notify_tag = false |
157 // mount_path = /provided/b33f1337-hello_world-5aa5 | 159 // mount_path = /provided/b33f1337-hello_world-5aa5 |
158 ProvidedFileSystemInfo file_system_info( | 160 ProvidedFileSystemInfo file_system_info(extension_id, |
159 extension_id, file_system_id, display_name, writable, mount_path); | 161 file_system_id, |
| 162 display_name, |
| 163 writable, |
| 164 supports_notify_tag, |
| 165 mount_path); |
160 | 166 |
161 ProvidedFileSystemInterface* file_system = | 167 ProvidedFileSystemInterface* file_system = |
162 file_system_factory_.Run(profile_, file_system_info); | 168 file_system_factory_.Run(profile_, file_system_info); |
163 DCHECK(file_system); | 169 DCHECK(file_system); |
164 file_system_map_[FileSystemKey(extension_id, file_system_id)] = file_system; | 170 file_system_map_[FileSystemKey(extension_id, file_system_id)] = file_system; |
165 mount_point_name_to_key_map_[mount_point_name] = | 171 mount_point_name_to_key_map_[mount_point_name] = |
166 FileSystemKey(extension_id, file_system_id); | 172 FileSystemKey(extension_id, file_system_id); |
167 RememberFileSystem(file_system_info); | 173 RememberFileSystem(file_system_info); |
168 | 174 |
169 FOR_EACH_OBSERVER( | 175 FOR_EACH_OBSERVER( |
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
320 // Notify observers about failure in unmounting, since mount() will not be | 326 // Notify observers about failure in unmounting, since mount() will not be |
321 // called by the provided file system. In case of success mount() will be | 327 // called by the provided file system. In case of success mount() will be |
322 // invoked, and observers notified, so there is no need to call them now. | 328 // invoked, and observers notified, so there is no need to call them now. |
323 if (error != base::File::FILE_OK) { | 329 if (error != base::File::FILE_OK) { |
324 FOR_EACH_OBSERVER(Observer, | 330 FOR_EACH_OBSERVER(Observer, |
325 observers_, | 331 observers_, |
326 OnProvidedFileSystemUnmount(file_system_info, error)); | 332 OnProvidedFileSystemUnmount(file_system_info, error)); |
327 } | 333 } |
328 } | 334 } |
329 | 335 |
| 336 void Service::OnObservedEntryChanged( |
| 337 const ProvidedFileSystemInfo& file_system_info, |
| 338 const base::FilePath& observed_path, |
| 339 ChangeType change_type, |
| 340 const ChildChanges& child_changes, |
| 341 const base::Closure& callback) { |
| 342 callback.Run(); |
| 343 } |
| 344 |
| 345 void Service::OnObservedEntryTagUpdated( |
| 346 const ProvidedFileSystemInfo& file_system_info, |
| 347 const base::FilePath& observed_path) { |
| 348 // TODO(mtomasz): Store tags of observed entries in preferences, or better |
| 349 // in leveldb. |
| 350 } |
| 351 |
| 352 void Service::OnObservedEntryListChanged( |
| 353 const ProvidedFileSystemInfo& file_system_info) { |
| 354 // TODO(mtomasz): Store observed entries in preferences or leveldb. |
| 355 } |
| 356 |
330 void Service::RememberFileSystem( | 357 void Service::RememberFileSystem( |
331 const ProvidedFileSystemInfo& file_system_info) { | 358 const ProvidedFileSystemInfo& file_system_info) { |
332 base::DictionaryValue* file_system = new base::DictionaryValue(); | 359 base::DictionaryValue* file_system = new base::DictionaryValue(); |
333 file_system->SetStringWithoutPathExpansion(kPrefKeyFileSystemId, | 360 file_system->SetStringWithoutPathExpansion(kPrefKeyFileSystemId, |
334 file_system_info.file_system_id()); | 361 file_system_info.file_system_id()); |
335 file_system->SetStringWithoutPathExpansion(kPrefKeyDisplayName, | 362 file_system->SetStringWithoutPathExpansion(kPrefKeyDisplayName, |
336 file_system_info.display_name()); | 363 file_system_info.display_name()); |
337 file_system->SetBooleanWithoutPathExpansion(kPrefKeyWritable, | 364 file_system->SetBooleanWithoutPathExpansion(kPrefKeyWritable, |
338 file_system_info.writable()); | 365 file_system_info.writable()); |
| 366 file_system->SetBooleanWithoutPathExpansion( |
| 367 kPrefKeySupportsNotifyTag, file_system_info.supports_notify_tag()); |
339 | 368 |
340 PrefService* const pref_service = profile_->GetPrefs(); | 369 PrefService* const pref_service = profile_->GetPrefs(); |
341 DCHECK(pref_service); | 370 DCHECK(pref_service); |
342 | 371 |
343 DictionaryPrefUpdate dict_update(pref_service, | 372 DictionaryPrefUpdate dict_update(pref_service, |
344 prefs::kFileSystemProviderMounted); | 373 prefs::kFileSystemProviderMounted); |
345 | 374 |
346 base::DictionaryValue* file_systems_per_extension = NULL; | 375 base::DictionaryValue* file_systems_per_extension = NULL; |
347 if (!dict_update->GetDictionaryWithoutPathExpansion( | 376 if (!dict_update->GetDictionaryWithoutPathExpansion( |
348 file_system_info.extension_id(), &file_systems_per_extension)) { | 377 file_system_info.extension_id(), &file_systems_per_extension)) { |
(...skipping 18 matching lines...) Expand all Loading... |
367 if (!dict_update->GetDictionaryWithoutPathExpansion( | 396 if (!dict_update->GetDictionaryWithoutPathExpansion( |
368 extension_id, &file_systems_per_extension)) | 397 extension_id, &file_systems_per_extension)) |
369 return; // Nothing to forget. | 398 return; // Nothing to forget. |
370 | 399 |
371 file_systems_per_extension->RemoveWithoutPathExpansion(file_system_id, NULL); | 400 file_systems_per_extension->RemoveWithoutPathExpansion(file_system_id, NULL); |
372 if (!file_systems_per_extension->size()) | 401 if (!file_systems_per_extension->size()) |
373 dict_update->Remove(extension_id, NULL); | 402 dict_update->Remove(extension_id, NULL); |
374 } | 403 } |
375 | 404 |
376 void Service::RestoreFileSystems(const std::string& extension_id) { | 405 void Service::RestoreFileSystems(const std::string& extension_id) { |
| 406 // TODO(mtomasz): Restore observed entries together with their tags. |
377 PrefService* const pref_service = profile_->GetPrefs(); | 407 PrefService* const pref_service = profile_->GetPrefs(); |
378 DCHECK(pref_service); | 408 DCHECK(pref_service); |
379 | 409 |
380 const base::DictionaryValue* const file_systems = | 410 const base::DictionaryValue* const file_systems = |
381 pref_service->GetDictionary(prefs::kFileSystemProviderMounted); | 411 pref_service->GetDictionary(prefs::kFileSystemProviderMounted); |
382 DCHECK(file_systems); | 412 DCHECK(file_systems); |
383 | 413 |
384 const base::DictionaryValue* file_systems_per_extension = NULL; | 414 const base::DictionaryValue* file_systems_per_extension = NULL; |
385 if (!file_systems->GetDictionaryWithoutPathExpansion( | 415 if (!file_systems->GetDictionaryWithoutPathExpansion( |
386 extension_id, &file_systems_per_extension)) | 416 extension_id, &file_systems_per_extension)) { |
387 return; // Nothing to restore. | 417 return; // Nothing to restore. |
| 418 } |
388 | 419 |
389 // Use a copy of the dictionary, since the original one may be modified while | 420 // Use a copy of the dictionary, since the original one may be modified while |
390 // iterating over it. | 421 // iterating over it. |
391 scoped_ptr<const base::DictionaryValue> file_systems_per_extension_copy( | 422 scoped_ptr<const base::DictionaryValue> file_systems_per_extension_copy( |
392 file_systems_per_extension->DeepCopy()); | 423 file_systems_per_extension->DeepCopy()); |
393 | 424 |
394 for (base::DictionaryValue::Iterator it(*file_systems_per_extension_copy); | 425 for (base::DictionaryValue::Iterator it(*file_systems_per_extension_copy); |
395 !it.IsAtEnd(); | 426 !it.IsAtEnd(); |
396 it.Advance()) { | 427 it.Advance()) { |
397 const base::Value* file_system_value = NULL; | 428 const base::Value* file_system_value = NULL; |
398 const base::DictionaryValue* file_system = NULL; | 429 const base::DictionaryValue* file_system = NULL; |
399 file_systems_per_extension_copy->GetWithoutPathExpansion( | 430 file_systems_per_extension_copy->GetWithoutPathExpansion( |
400 it.key(), &file_system_value); | 431 it.key(), &file_system_value); |
401 DCHECK(file_system_value); | 432 DCHECK(file_system_value); |
402 | 433 |
403 std::string file_system_id; | 434 std::string file_system_id; |
404 std::string display_name; | 435 std::string display_name; |
405 bool writable; | 436 bool writable = false; |
| 437 bool supports_notify_tag = false; |
406 | 438 |
407 if (!file_system_value->GetAsDictionary(&file_system) || | 439 if (!file_system_value->GetAsDictionary(&file_system) || |
408 !file_system->GetStringWithoutPathExpansion(kPrefKeyFileSystemId, | 440 !file_system->GetStringWithoutPathExpansion(kPrefKeyFileSystemId, |
409 &file_system_id) || | 441 &file_system_id) || |
410 !file_system->GetStringWithoutPathExpansion(kPrefKeyDisplayName, | 442 !file_system->GetStringWithoutPathExpansion(kPrefKeyDisplayName, |
411 &display_name) || | 443 &display_name) || |
412 !file_system->GetBooleanWithoutPathExpansion(kPrefKeyWritable, | 444 !file_system->GetBooleanWithoutPathExpansion(kPrefKeyWritable, |
413 &writable) || | 445 &writable) || |
| 446 !file_system->GetBooleanWithoutPathExpansion(kPrefKeySupportsNotifyTag, |
| 447 &supports_notify_tag) || |
414 file_system_id.empty() || display_name.empty()) { | 448 file_system_id.empty() || display_name.empty()) { |
415 LOG(ERROR) | 449 LOG(ERROR) |
416 << "Malformed provided file system information in preferences."; | 450 << "Malformed provided file system information in preferences."; |
417 continue; | 451 continue; |
418 } | 452 } |
419 | 453 const bool result = MountFileSystem(extension_id, |
420 const bool result = | 454 file_system_id, |
421 MountFileSystem(extension_id, file_system_id, display_name, writable); | 455 display_name, |
| 456 writable, |
| 457 supports_notify_tag); |
422 if (!result) { | 458 if (!result) { |
423 LOG(ERROR) << "Failed to restore a provided file system from " | 459 LOG(ERROR) << "Failed to restore a provided file system from " |
424 << "preferences: " << extension_id << ", " << file_system_id | 460 << "preferences: " << extension_id << ", " << file_system_id |
425 << ", " << display_name << "."; | 461 << ", " << display_name << "."; |
426 // Since remounting of the file system failed, then remove it from | 462 // Since remounting of the file system failed, then remove it from |
427 // preferences to avoid remounting it over and over again with a failure. | 463 // preferences to avoid remounting it over and over again with a failure. |
428 ForgetFileSystem(extension_id, file_system_id); | 464 ForgetFileSystem(extension_id, file_system_id); |
429 } | 465 } |
430 } | 466 } |
431 } | 467 } |
432 | 468 |
433 } // namespace file_system_provider | 469 } // namespace file_system_provider |
434 } // namespace chromeos | 470 } // namespace chromeos |
OLD | NEW |