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

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: Split delegate class 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 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()->EnsureInitialized(
392 base::Bind(&VolumeManager::OnStorageMonitorInitialized,
393 weak_ptr_factory_.GetWeakPtr()));
394 }
374 } 395 }
375 396
376 void VolumeManager::Shutdown() { 397 void VolumeManager::Shutdown() {
377 weak_ptr_factory_.InvalidateWeakPtrs(); 398 weak_ptr_factory_.InvalidateWeakPtrs();
378 399
379 pref_change_registrar_.RemoveAll(); 400 pref_change_registrar_.RemoveAll();
380 disk_mount_manager_->RemoveObserver(this); 401 disk_mount_manager_->RemoveObserver(this);
402 storage_monitor::StorageMonitor::GetInstance()->RemoveObserver(this);
381 403
382 if (drive_integration_service_) 404 if (drive_integration_service_)
383 drive_integration_service_->RemoveObserver(this); 405 drive_integration_service_->RemoveObserver(this);
384 406
385 if (file_system_provider_service_) 407 if (file_system_provider_service_)
386 file_system_provider_service_->RemoveObserver(this); 408 file_system_provider_service_->RemoveObserver(this);
387 } 409 }
388 410
389 void VolumeManager::AddObserver(VolumeManagerObserver* observer) { 411 void VolumeManager::AddObserver(VolumeManagerObserver* observer) {
390 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 412 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
(...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after
677 699
678 void VolumeManager::OnPrivetVolumesAvailable( 700 void VolumeManager::OnPrivetVolumesAvailable(
679 const local_discovery::PrivetVolumeLister::VolumeList& volumes) { 701 const local_discovery::PrivetVolumeLister::VolumeList& volumes) {
680 for (local_discovery::PrivetVolumeLister::VolumeList::const_iterator i = 702 for (local_discovery::PrivetVolumeLister::VolumeList::const_iterator i =
681 volumes.begin(); i != volumes.end(); i++) { 703 volumes.begin(); i != volumes.end(); i++) {
682 VolumeInfo volume_info = CreatePrivetVolumeInfo(*i); 704 VolumeInfo volume_info = CreatePrivetVolumeInfo(*i);
683 DoMountEvent(chromeos::MOUNT_ERROR_NONE, volume_info, false); 705 DoMountEvent(chromeos::MOUNT_ERROR_NONE, volume_info, false);
684 } 706 }
685 } 707 }
686 708
709 void VolumeManager::OnRemovableStorageAttached(
710 const storage_monitor::StorageInfo& info) {
711 if (!storage_monitor::StorageInfo::IsMTPDevice(info.device_id()))
712 return;
713
714 const base::FilePath path = base::FilePath::FromUTF8Unsafe(info.location());
715 const std::string fsid = GetMountPointNameForMediaStorage(info);
716 const std::string name = base::UTF16ToUTF8(info.GetDisplayName(false));
717
718 bool result =
719 fileapi::ExternalMountPoints::GetSystemInstance()->RegisterFileSystem(
720 fsid, fileapi::kFileSystemTypeDeviceMediaAsFileStorage,
721 fileapi::FileSystemMountOption(), path);
722 DCHECK(result);
723 content::BrowserThread::PostTask(
724 content::BrowserThread::IO, FROM_HERE, base::Bind(
725 &MTPDeviceMapService::RegisterMTPFileSystem,
726 base::Unretained(MTPDeviceMapService::GetInstance()),
727 info.location(), fsid));
728
729 VolumeInfo volume_info;
730 volume_info.type = VOLUME_TYPE_MTP;
731 volume_info.mount_path = path;
732 volume_info.mount_condition = chromeos::disks::MOUNT_CONDITION_NONE;
733 volume_info.is_parent = true;
734 volume_info.is_read_only = true;
735 volume_info.volume_id = "mtp:" + name;
736 volume_info.source_path = path;
737 volume_info.device_type = chromeos::DEVICE_TYPE_MOBILE;
738 DoMountEvent(chromeos::MOUNT_ERROR_NONE, volume_info, false);
739 }
740
741 void VolumeManager::OnRemovableStorageDetached(
742 const storage_monitor::StorageInfo& info) {
743 if (!storage_monitor::StorageInfo::IsMTPDevice(info.device_id()))
744 return;
745
746 for (std::map<std::string, VolumeInfo>::iterator it =
747 mounted_volumes_.begin(); it != mounted_volumes_.end(); ++it) {
748 if (it->second.source_path.value() == info.location()) {
749 DoUnmountEvent(chromeos::MOUNT_ERROR_NONE, VolumeInfo(it->second));
750
751 const std::string fsid = GetMountPointNameForMediaStorage(info);
752 fileapi::ExternalMountPoints::GetSystemInstance()->RevokeFileSystem(
753 fsid);
754 content::BrowserThread::PostTask(
755 content::BrowserThread::IO, FROM_HERE, base::Bind(
756 &MTPDeviceMapService::RevokeMTPFileSystem,
757 base::Unretained(MTPDeviceMapService::GetInstance()),
758 fsid));
759 return;
760 }
761 }
762 }
763
764 void VolumeManager::OnStorageMonitorInitialized() {
765 std::vector<storage_monitor::StorageInfo> storages =
766 storage_monitor::StorageMonitor::GetInstance()->GetAllAvailableStorages();
767 for (size_t i = 0; i < storages.size(); ++i)
768 OnRemovableStorageAttached(storages[i]);
769 storage_monitor::StorageMonitor::GetInstance()->AddObserver(this);
770 }
771
687 void VolumeManager::DoMountEvent(chromeos::MountError error_code, 772 void VolumeManager::DoMountEvent(chromeos::MountError error_code,
688 const VolumeInfo& volume_info, 773 const VolumeInfo& volume_info,
689 bool is_remounting) { 774 bool is_remounting) {
690 // Archive files are mounted globally in system. We however don't want to show 775 // 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 776 // 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 777 // multi-profile session. To this end, we filter out archives not on the
693 // volumes already mounted on this VolumeManager instance. 778 // volumes already mounted on this VolumeManager instance.
694 if (volume_info.type == VOLUME_TYPE_MOUNTED_ARCHIVE_FILE) { 779 if (volume_info.type == VOLUME_TYPE_MOUNTED_ARCHIVE_FILE) {
695 // Source may be in Drive cache folder under the current profile directory. 780 // Source may be in Drive cache folder under the current profile directory.
696 bool from_current_profile = 781 bool from_current_profile =
(...skipping 29 matching lines...) Expand all
726 return; 811 return;
727 if (error_code == chromeos::MOUNT_ERROR_NONE) 812 if (error_code == chromeos::MOUNT_ERROR_NONE)
728 mounted_volumes_.erase(volume_info.volume_id); 813 mounted_volumes_.erase(volume_info.volume_id);
729 814
730 FOR_EACH_OBSERVER(VolumeManagerObserver, 815 FOR_EACH_OBSERVER(VolumeManagerObserver,
731 observers_, 816 observers_,
732 OnVolumeUnmounted(error_code, volume_info)); 817 OnVolumeUnmounted(error_code, volume_info));
733 } 818 }
734 819
735 } // namespace file_manager 820 } // namespace file_manager
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698