Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(348)

Side by Side Diff: chrome/browser/chromeos/file_system_provider/service.cc

Issue 625463002: [fsp] Add support for observing entries and notifying about changes. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebased. Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698