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

Side by Side Diff: chrome/browser/chromeos/file_manager/volume_manager.cc

Issue 246293011: Mount MTP devices in Chrome OS Files.app. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebase + fix test (handle null StorageMonitor in some tests) Created 6 years, 7 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 | Annotate | Revision Log
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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_manager/volume_manager.h" 5 #include "chrome/browser/chromeos/file_manager/volume_manager.h"
6 6
7 #include "base/basictypes.h" 7 #include "base/basictypes.h"
8 #include "base/bind.h" 8 #include "base/bind.h"
9 #include "base/callback.h" 9 #include "base/callback.h"
10 #include "base/command_line.h" 10 #include "base/command_line.h"
11 #include "base/files/file_path.h" 11 #include "base/files/file_path.h"
12 #include "base/logging.h" 12 #include "base/logging.h"
13 #include "base/memory/singleton.h" 13 #include "base/memory/singleton.h"
14 #include "base/prefs/pref_service.h" 14 #include "base/prefs/pref_service.h"
15 #include "base/strings/utf_string_conversions.h"
15 #include "chrome/browser/chromeos/drive/drive_integration_service.h" 16 #include "chrome/browser/chromeos/drive/drive_integration_service.h"
16 #include "chrome/browser/chromeos/drive/file_errors.h" 17 #include "chrome/browser/chromeos/drive/file_errors.h"
17 #include "chrome/browser/chromeos/drive/file_system_interface.h" 18 #include "chrome/browser/chromeos/drive/file_system_interface.h"
18 #include "chrome/browser/chromeos/drive/file_system_util.h" 19 #include "chrome/browser/chromeos/drive/file_system_util.h"
19 #include "chrome/browser/chromeos/file_manager/mounted_disk_monitor.h" 20 #include "chrome/browser/chromeos/file_manager/mounted_disk_monitor.h"
20 #include "chrome/browser/chromeos/file_manager/path_util.h" 21 #include "chrome/browser/chromeos/file_manager/path_util.h"
21 #include "chrome/browser/chromeos/file_manager/volume_manager_factory.h" 22 #include "chrome/browser/chromeos/file_manager/volume_manager_factory.h"
22 #include "chrome/browser/chromeos/file_manager/volume_manager_observer.h" 23 #include "chrome/browser/chromeos/file_manager/volume_manager_observer.h"
23 #include "chrome/browser/chromeos/file_system_provider/provided_file_system_info .h" 24 #include "chrome/browser/chromeos/file_system_provider/provided_file_system_info .h"
24 #include "chrome/browser/chromeos/profiles/profile_helper.h" 25 #include "chrome/browser/chromeos/profiles/profile_helper.h"
25 #include "chrome/browser/local_discovery/storage/privet_filesystem_constants.h" 26 #include "chrome/browser/local_discovery/storage/privet_filesystem_constants.h"
27 #include "chrome/browser/media_galleries/fileapi/mtp_device_map_service.h"
26 #include "chrome/browser/profiles/profile.h" 28 #include "chrome/browser/profiles/profile.h"
27 #include "chrome/common/chrome_switches.h" 29 #include "chrome/common/chrome_switches.h"
28 #include "chrome/common/pref_names.h" 30 #include "chrome/common/pref_names.h"
31 #include "chromeos/chromeos_switches.h"
29 #include "chromeos/dbus/cros_disks_client.h" 32 #include "chromeos/dbus/cros_disks_client.h"
30 #include "chromeos/disks/disk_mount_manager.h" 33 #include "chromeos/disks/disk_mount_manager.h"
34 #include "components/storage_monitor/storage_monitor.h"
31 #include "content/public/browser/browser_context.h" 35 #include "content/public/browser/browser_context.h"
32 #include "content/public/browser/browser_thread.h" 36 #include "content/public/browser/browser_thread.h"
33 #include "webkit/browser/fileapi/external_mount_points.h" 37 #include "webkit/browser/fileapi/external_mount_points.h"
34 38
35 namespace file_manager { 39 namespace file_manager {
36 namespace { 40 namespace {
37 41
38 // A named constant to be passed to the |is_remounting| parameter. 42 // A named constant to be passed to the |is_remounting| parameter.
39 const bool kNotRemounting = false; 43 const bool kNotRemounting = false;
40 44
45 const char kFileManagerMTPMountNamePrefix[] = "fileman-mtp-";
46
41 // Registers |path| as the "Downloads" folder to the FileSystem API backend. 47 // Registers |path| as the "Downloads" folder to the FileSystem API backend.
42 // If another folder is already mounted. It revokes and overrides the old one. 48 // If another folder is already mounted. It revokes and overrides the old one.
43 bool RegisterDownloadsMountPoint(Profile* profile, const base::FilePath& path) { 49 bool RegisterDownloadsMountPoint(Profile* profile, const base::FilePath& path) {
44 // Although we show only profile's own "Downloads" folder in Files.app, 50 // Although we show only profile's own "Downloads" folder in Files.app,
45 // in the backend we need to mount all profile's download directory globally. 51 // in the backend we need to mount all profile's download directory globally.
46 // Otherwise, Files.app cannot support cross-profile file copies, etc. 52 // Otherwise, Files.app cannot support cross-profile file copies, etc.
47 // For this reason, we need to register to the global GetSystemInstance(). 53 // For this reason, we need to register to the global GetSystemInstance().
48 const std::string mount_point_name = 54 const std::string mount_point_name =
49 file_manager::util::GetDownloadsMountPointName(profile); 55 file_manager::util::GetDownloadsMountPointName(profile);
50 fileapi::ExternalMountPoints* const mount_points = 56 fileapi::ExternalMountPoints* const mount_points =
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after
208 volume_info.type = VOLUME_TYPE_PROVIDED; 214 volume_info.type = VOLUME_TYPE_PROVIDED;
209 volume_info.mount_path = file_system_info.mount_path(); 215 volume_info.mount_path = file_system_info.mount_path();
210 volume_info.mount_condition = chromeos::disks::MOUNT_CONDITION_NONE; 216 volume_info.mount_condition = chromeos::disks::MOUNT_CONDITION_NONE;
211 volume_info.is_parent = true; 217 volume_info.is_parent = true;
212 volume_info.is_read_only = true; 218 volume_info.is_read_only = true;
213 volume_info.volume_id = GenerateVolumeId(volume_info); 219 volume_info.volume_id = GenerateVolumeId(volume_info);
214 volume_info.file_system_id = file_system_info.file_system_id(); 220 volume_info.file_system_id = file_system_info.file_system_id();
215 return volume_info; 221 return volume_info;
216 } 222 }
217 223
224 std::string GetMountPointNameForMediaStorage(
225 const storage_monitor::StorageInfo& info) {
226 std::string name(kFileManagerMTPMountNamePrefix);
227 name += info.device_id();
228 return name;
229 }
230
218 } // namespace 231 } // namespace
219 232
220 VolumeInfo::VolumeInfo() 233 VolumeInfo::VolumeInfo()
221 : file_system_id(0), 234 : file_system_id(0),
222 type(VOLUME_TYPE_GOOGLE_DRIVE), 235 type(VOLUME_TYPE_GOOGLE_DRIVE),
223 mount_condition(chromeos::disks::MOUNT_CONDITION_NONE), 236 mount_condition(chromeos::disks::MOUNT_CONDITION_NONE),
224 is_parent(false), 237 is_parent(false),
225 is_read_only(false) {} 238 is_read_only(false) {}
226 239
227 VolumeInfo::~VolumeInfo() { 240 VolumeInfo::~VolumeInfo() {
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
364 weak_ptr_factory_.GetWeakPtr())); 377 weak_ptr_factory_.GetWeakPtr()));
365 378
366 // Subscribe to Privet volume lister. 379 // Subscribe to Privet volume lister.
367 if (CommandLine::ForCurrentProcess()->HasSwitch( 380 if (CommandLine::ForCurrentProcess()->HasSwitch(
368 switches::kEnablePrivetStorage)) { 381 switches::kEnablePrivetStorage)) {
369 privet_volume_lister_.reset(new local_discovery::PrivetVolumeLister( 382 privet_volume_lister_.reset(new local_discovery::PrivetVolumeLister(
370 base::Bind(&VolumeManager::OnPrivetVolumesAvailable, 383 base::Bind(&VolumeManager::OnPrivetVolumesAvailable,
371 weak_ptr_factory_.GetWeakPtr()))); 384 weak_ptr_factory_.GetWeakPtr())));
372 privet_volume_lister_->Start(); 385 privet_volume_lister_->Start();
373 } 386 }
387
388 // Subscribe to storage monitor for MTP notifications.
389 if (CommandLine::ForCurrentProcess()->HasSwitch(
390 chromeos::switches::kEnableFileManagerMTP) &&
391 storage_monitor::StorageMonitor::GetInstance()) {
392 storage_monitor::StorageMonitor::GetInstance()->EnsureInitialized(
393 base::Bind(&VolumeManager::OnStorageMonitorInitialized,
394 weak_ptr_factory_.GetWeakPtr()));
395 }
374 } 396 }
375 397
376 void VolumeManager::Shutdown() { 398 void VolumeManager::Shutdown() {
377 weak_ptr_factory_.InvalidateWeakPtrs(); 399 weak_ptr_factory_.InvalidateWeakPtrs();
378 400
379 pref_change_registrar_.RemoveAll(); 401 pref_change_registrar_.RemoveAll();
380 disk_mount_manager_->RemoveObserver(this); 402 disk_mount_manager_->RemoveObserver(this);
403 if (storage_monitor::StorageMonitor::GetInstance())
404 storage_monitor::StorageMonitor::GetInstance()->RemoveObserver(this);
381 405
382 if (drive_integration_service_) 406 if (drive_integration_service_)
383 drive_integration_service_->RemoveObserver(this); 407 drive_integration_service_->RemoveObserver(this);
384 408
385 if (file_system_provider_service_) 409 if (file_system_provider_service_)
386 file_system_provider_service_->RemoveObserver(this); 410 file_system_provider_service_->RemoveObserver(this);
387 } 411 }
388 412
389 void VolumeManager::AddObserver(VolumeManagerObserver* observer) { 413 void VolumeManager::AddObserver(VolumeManagerObserver* observer) {
390 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 414 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
(...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after
677 701
678 void VolumeManager::OnPrivetVolumesAvailable( 702 void VolumeManager::OnPrivetVolumesAvailable(
679 const local_discovery::PrivetVolumeLister::VolumeList& volumes) { 703 const local_discovery::PrivetVolumeLister::VolumeList& volumes) {
680 for (local_discovery::PrivetVolumeLister::VolumeList::const_iterator i = 704 for (local_discovery::PrivetVolumeLister::VolumeList::const_iterator i =
681 volumes.begin(); i != volumes.end(); i++) { 705 volumes.begin(); i != volumes.end(); i++) {
682 VolumeInfo volume_info = CreatePrivetVolumeInfo(*i); 706 VolumeInfo volume_info = CreatePrivetVolumeInfo(*i);
683 DoMountEvent(chromeos::MOUNT_ERROR_NONE, volume_info, false); 707 DoMountEvent(chromeos::MOUNT_ERROR_NONE, volume_info, false);
684 } 708 }
685 } 709 }
686 710
711 void VolumeManager::OnRemovableStorageAttached(
712 const storage_monitor::StorageInfo& info) {
713 if (!storage_monitor::StorageInfo::IsMTPDevice(info.device_id()))
714 return;
715
716 const base::FilePath path = base::FilePath::FromUTF8Unsafe(info.location());
717 const std::string fsid = GetMountPointNameForMediaStorage(info);
718 const std::string name = base::UTF16ToUTF8(info.GetDisplayName(false));
719
720 bool result =
721 fileapi::ExternalMountPoints::GetSystemInstance()->RegisterFileSystem(
722 fsid, fileapi::kFileSystemTypeDeviceMediaAsFileStorage,
723 fileapi::FileSystemMountOption(), path);
724 DCHECK(result);
725 content::BrowserThread::PostTask(
726 content::BrowserThread::IO, FROM_HERE, base::Bind(
727 &MTPDeviceMapService::RegisterMTPFileSystem,
728 base::Unretained(MTPDeviceMapService::GetInstance()),
729 info.location(), fsid));
730
731 VolumeInfo volume_info;
732 volume_info.type = VOLUME_TYPE_MTP;
733 volume_info.mount_path = path;
734 volume_info.mount_condition = chromeos::disks::MOUNT_CONDITION_NONE;
735 volume_info.is_parent = true;
736 volume_info.is_read_only = true;
737 volume_info.volume_id = "mtp:" + name;
738 volume_info.source_path = path;
739 volume_info.device_type = chromeos::DEVICE_TYPE_MOBILE;
740 DoMountEvent(chromeos::MOUNT_ERROR_NONE, volume_info, false);
741 }
742
743 void VolumeManager::OnRemovableStorageDetached(
744 const storage_monitor::StorageInfo& info) {
745 if (!storage_monitor::StorageInfo::IsMTPDevice(info.device_id()))
746 return;
747
748 for (std::map<std::string, VolumeInfo>::iterator it =
749 mounted_volumes_.begin(); it != mounted_volumes_.end(); ++it) {
750 if (it->second.source_path.value() == info.location()) {
751 DoUnmountEvent(chromeos::MOUNT_ERROR_NONE, VolumeInfo(it->second));
752
753 const std::string fsid = GetMountPointNameForMediaStorage(info);
754 fileapi::ExternalMountPoints::GetSystemInstance()->RevokeFileSystem(
755 fsid);
756 content::BrowserThread::PostTask(
757 content::BrowserThread::IO, FROM_HERE, base::Bind(
758 &MTPDeviceMapService::RevokeMTPFileSystem,
759 base::Unretained(MTPDeviceMapService::GetInstance()),
760 fsid));
761 return;
762 }
763 }
764 }
765
766 void VolumeManager::OnStorageMonitorInitialized() {
767 std::vector<storage_monitor::StorageInfo> storages =
768 storage_monitor::StorageMonitor::GetInstance()->GetAllAvailableStorages();
769 for (size_t i = 0; i < storages.size(); ++i)
770 OnRemovableStorageAttached(storages[i]);
771 storage_monitor::StorageMonitor::GetInstance()->AddObserver(this);
772 }
773
687 void VolumeManager::DoMountEvent(chromeos::MountError error_code, 774 void VolumeManager::DoMountEvent(chromeos::MountError error_code,
688 const VolumeInfo& volume_info, 775 const VolumeInfo& volume_info,
689 bool is_remounting) { 776 bool is_remounting) {
690 // Archive files are mounted globally in system. We however don't want to show 777 // Archive files are mounted globally in system. We however don't want to show
691 // archives from profile-specific folders (Drive/Downloads) of other users in 778 // archives from profile-specific folders (Drive/Downloads) of other users in
692 // multi-profile session. To this end, we filter out archives not on the 779 // multi-profile session. To this end, we filter out archives not on the
693 // volumes already mounted on this VolumeManager instance. 780 // volumes already mounted on this VolumeManager instance.
694 if (volume_info.type == VOLUME_TYPE_MOUNTED_ARCHIVE_FILE) { 781 if (volume_info.type == VOLUME_TYPE_MOUNTED_ARCHIVE_FILE) {
695 // Source may be in Drive cache folder under the current profile directory. 782 // Source may be in Drive cache folder under the current profile directory.
696 bool from_current_profile = 783 bool from_current_profile =
(...skipping 29 matching lines...) Expand all
726 return; 813 return;
727 if (error_code == chromeos::MOUNT_ERROR_NONE) 814 if (error_code == chromeos::MOUNT_ERROR_NONE)
728 mounted_volumes_.erase(volume_info.volume_id); 815 mounted_volumes_.erase(volume_info.volume_id);
729 816
730 FOR_EACH_OBSERVER(VolumeManagerObserver, 817 FOR_EACH_OBSERVER(VolumeManagerObserver,
731 observers_, 818 observers_,
732 OnVolumeUnmounted(error_code, volume_info)); 819 OnVolumeUnmounted(error_code, volume_info));
733 } 820 }
734 821
735 } // namespace file_manager 822 } // namespace file_manager
OLDNEW
« no previous file with comments | « chrome/browser/chromeos/file_manager/volume_manager.h ('k') | chrome/browser/chromeos/fileapi/file_system_backend.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698