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

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: Created 6 years, 8 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 kFileManagerMountNamePrefix[] = "fileman";
vandebo (ex-Chrome) 2014/04/23 16:24:44 nit: maybe make this MTP specific - kFileManagerMT
kinaba 2014/04/24 01:33:30 Done.
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(kFileManagerMountNamePrefix);
227 name += "-mtp-";
228 name += info.device_id();
229 return name;
230 }
231
218 } // namespace 232 } // namespace
219 233
220 VolumeInfo::VolumeInfo() 234 VolumeInfo::VolumeInfo()
221 : file_system_id(0), 235 : file_system_id(0),
222 type(VOLUME_TYPE_GOOGLE_DRIVE), 236 type(VOLUME_TYPE_GOOGLE_DRIVE),
223 mount_condition(chromeos::disks::MOUNT_CONDITION_NONE), 237 mount_condition(chromeos::disks::MOUNT_CONDITION_NONE),
224 is_parent(false), 238 is_parent(false),
225 is_read_only(false) {} 239 is_read_only(false) {}
226 240
227 VolumeInfo::~VolumeInfo() { 241 VolumeInfo::~VolumeInfo() {
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
364 weak_ptr_factory_.GetWeakPtr())); 378 weak_ptr_factory_.GetWeakPtr()));
365 379
366 // Subscribe to Privet volume lister. 380 // Subscribe to Privet volume lister.
367 if (CommandLine::ForCurrentProcess()->HasSwitch( 381 if (CommandLine::ForCurrentProcess()->HasSwitch(
368 switches::kEnablePrivetStorage)) { 382 switches::kEnablePrivetStorage)) {
369 privet_volume_lister_.reset(new local_discovery::PrivetVolumeLister( 383 privet_volume_lister_.reset(new local_discovery::PrivetVolumeLister(
370 base::Bind(&VolumeManager::OnPrivetVolumesAvailable, 384 base::Bind(&VolumeManager::OnPrivetVolumesAvailable,
371 weak_ptr_factory_.GetWeakPtr()))); 385 weak_ptr_factory_.GetWeakPtr())));
372 privet_volume_lister_->Start(); 386 privet_volume_lister_->Start();
373 } 387 }
388
389 // Subscribe MTP storage monitor.
vandebo (ex-Chrome) 2014/04/23 16:24:44 nit: Subscribe to storage monitor for MTP notifica
kinaba 2014/04/24 01:33:30 Done.
390 if (CommandLine::ForCurrentProcess()->HasSwitch(
391 chromeos::switches::kEnableFileManagerMTP)) {
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 storage_monitor::StorageMonitor::GetInstance()->RemoveObserver(this);
381 404
382 if (drive_integration_service_) 405 if (drive_integration_service_)
383 drive_integration_service_->RemoveObserver(this); 406 drive_integration_service_->RemoveObserver(this);
384 407
385 if (file_system_provider_service_) 408 if (file_system_provider_service_)
386 file_system_provider_service_->RemoveObserver(this); 409 file_system_provider_service_->RemoveObserver(this);
387 } 410 }
388 411
389 void VolumeManager::AddObserver(VolumeManagerObserver* observer) { 412 void VolumeManager::AddObserver(VolumeManagerObserver* observer) {
390 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 413 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
(...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after
677 700
678 void VolumeManager::OnPrivetVolumesAvailable( 701 void VolumeManager::OnPrivetVolumesAvailable(
679 const local_discovery::PrivetVolumeLister::VolumeList& volumes) { 702 const local_discovery::PrivetVolumeLister::VolumeList& volumes) {
680 for (local_discovery::PrivetVolumeLister::VolumeList::const_iterator i = 703 for (local_discovery::PrivetVolumeLister::VolumeList::const_iterator i =
681 volumes.begin(); i != volumes.end(); i++) { 704 volumes.begin(); i != volumes.end(); i++) {
682 VolumeInfo volume_info = CreatePrivetVolumeInfo(*i); 705 VolumeInfo volume_info = CreatePrivetVolumeInfo(*i);
683 DoMountEvent(chromeos::MOUNT_ERROR_NONE, volume_info, false); 706 DoMountEvent(chromeos::MOUNT_ERROR_NONE, volume_info, false);
684 } 707 }
685 } 708 }
686 709
710 void VolumeManager::OnRemovableStorageAttached(
711 const storage_monitor::StorageInfo& info) {
712 if (!storage_monitor::StorageInfo::IsMediaDevice(info.device_id()))
vandebo (ex-Chrome) 2014/04/23 16:24:44 On CrOS, IsMediaDevice() && !IsMassStorageDevice()
kinaba 2014/04/24 01:33:30 Done (Added IsMTPDevice)
713 return;
714
715 const base::FilePath path = base::FilePath::FromUTF8Unsafe(info.location());
716 const std::string fsid = GetMountPointNameForMediaStorage(info);
717 const std::string name = base::UTF16ToUTF8(info.GetDisplayName(false));
718
719 bool result =
720 fileapi::ExternalMountPoints::GetSystemInstance()->RegisterFileSystem(
721 fsid, fileapi::kFileSystemTypeDeviceMediaAsFileStorage,
722 fileapi::FileSystemMountOption(), path);
723 DCHECK(result);
724 content::BrowserThread::PostTask(
725 content::BrowserThread::IO, FROM_HERE, base::Bind(
726 &MTPDeviceMapService::RegisterMTPFileSystem,
727 base::Unretained(MTPDeviceMapService::GetInstance()),
728 info.location(), fsid));
729
730 VolumeInfo volume_info;
731 volume_info.type = VOLUME_TYPE_MTP;
732 volume_info.mount_path = path;
733 volume_info.mount_condition = chromeos::disks::MOUNT_CONDITION_NONE;
734 volume_info.is_parent = true;
735 volume_info.is_read_only = true;
736 volume_info.volume_id = "mtp:" + name;
737 volume_info.source_path = path;
738 volume_info.device_type = chromeos::DEVICE_TYPE_MOBILE;
739 DoMountEvent(chromeos::MOUNT_ERROR_NONE, volume_info, false);
740 }
741
742 void VolumeManager::OnRemovableStorageDetached(
743 const storage_monitor::StorageInfo& info) {
744 if (!storage_monitor::StorageInfo::IsMediaDevice(info.device_id()))
745 return;
746
747 for (std::map<std::string, VolumeInfo>::iterator it =
748 mounted_volumes_.begin(); it != mounted_volumes_.end(); ++it) {
749 if (it->second.source_path.value() == info.location()) {
750 DoUnmountEvent(chromeos::MOUNT_ERROR_NONE, VolumeInfo(it->second));
751
752 const std::string fsid = GetMountPointNameForMediaStorage(info);
753 fileapi::ExternalMountPoints::GetSystemInstance()->RevokeFileSystem(
754 fsid);
755 content::BrowserThread::PostTask(
756 content::BrowserThread::IO, FROM_HERE, base::Bind(
757 &MTPDeviceMapService::RevokeMTPFileSystem,
758 base::Unretained(MTPDeviceMapService::GetInstance()),
759 fsid));
760 return;
761 }
762 }
763 }
764
765 void VolumeManager::OnStorageMonitorInitialized() {
766 std::vector<storage_monitor::StorageInfo> storages =
767 storage_monitor::StorageMonitor::GetInstance()->GetAllAvailableStorages();
768 for (size_t i = 0; i < storages.size(); ++i)
769 OnRemovableStorageAttached(storages[i]);
770 storage_monitor::StorageMonitor::GetInstance()->AddObserver(this);
771 }
772
687 void VolumeManager::DoMountEvent(chromeos::MountError error_code, 773 void VolumeManager::DoMountEvent(chromeos::MountError error_code,
688 const VolumeInfo& volume_info, 774 const VolumeInfo& volume_info,
689 bool is_remounting) { 775 bool is_remounting) {
690 // Archive files are mounted globally in system. We however don't want to show 776 // 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 777 // 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 778 // multi-profile session. To this end, we filter out archives not on the
693 // volumes already mounted on this VolumeManager instance. 779 // volumes already mounted on this VolumeManager instance.
694 if (volume_info.type == VOLUME_TYPE_MOUNTED_ARCHIVE_FILE) { 780 if (volume_info.type == VOLUME_TYPE_MOUNTED_ARCHIVE_FILE) {
695 // Source may be in Drive cache folder under the current profile directory. 781 // Source may be in Drive cache folder under the current profile directory.
696 bool from_current_profile = 782 bool from_current_profile =
(...skipping 29 matching lines...) Expand all
726 return; 812 return;
727 if (error_code == chromeos::MOUNT_ERROR_NONE) 813 if (error_code == chromeos::MOUNT_ERROR_NONE)
728 mounted_volumes_.erase(volume_info.volume_id); 814 mounted_volumes_.erase(volume_info.volume_id);
729 815
730 FOR_EACH_OBSERVER(VolumeManagerObserver, 816 FOR_EACH_OBSERVER(VolumeManagerObserver,
731 observers_, 817 observers_,
732 OnVolumeUnmounted(error_code, volume_info)); 818 OnVolumeUnmounted(error_code, volume_info));
733 } 819 }
734 820
735 } // namespace file_manager 821 } // namespace file_manager
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698