OLD | NEW |
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" |
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
205 } | 205 } |
206 | 206 |
207 VolumeManager::~VolumeManager() { | 207 VolumeManager::~VolumeManager() { |
208 } | 208 } |
209 | 209 |
210 VolumeManager* VolumeManager::Get(content::BrowserContext* context) { | 210 VolumeManager* VolumeManager::Get(content::BrowserContext* context) { |
211 return VolumeManagerFactory::Get(context); | 211 return VolumeManagerFactory::Get(context); |
212 } | 212 } |
213 | 213 |
214 void VolumeManager::Initialize() { | 214 void VolumeManager::Initialize() { |
| 215 const bool kNotRemounting = false; |
| 216 |
215 // Path to mount user folders have changed several times. We need to migrate | 217 // Path to mount user folders have changed several times. We need to migrate |
216 // the old preferences on paths to the new format when needed. For the detail, | 218 // the old preferences on paths to the new format when needed. For the detail, |
217 // see the comments in file_manager::util::MigratePathFromOldFormat, | 219 // see the comments in file_manager::util::MigratePathFromOldFormat, |
218 // Note: Preferences related to downloads are handled in download_prefs.cc. | 220 // Note: Preferences related to downloads are handled in download_prefs.cc. |
219 // TODO(kinaba): Remove this after several rounds of releases. | 221 // TODO(kinaba): Remove this after several rounds of releases. |
220 const base::FilePath old_path = | 222 const base::FilePath old_path = |
221 profile_->GetPrefs()->GetFilePath(prefs::kSelectFileLastDirectory); | 223 profile_->GetPrefs()->GetFilePath(prefs::kSelectFileLastDirectory); |
222 base::FilePath new_path; | 224 base::FilePath new_path; |
223 if (!old_path.empty() && | 225 if (!old_path.empty() && |
224 file_manager::util::MigratePathFromOldFormat(profile_, | 226 file_manager::util::MigratePathFromOldFormat(profile_, |
225 old_path, &new_path)) { | 227 old_path, &new_path)) { |
226 profile_->GetPrefs()->SetFilePath(prefs::kSelectFileLastDirectory, | 228 profile_->GetPrefs()->SetFilePath(prefs::kSelectFileLastDirectory, |
227 new_path); | 229 new_path); |
228 } | 230 } |
229 | 231 |
230 // Register 'Downloads' folder for the profile to the file system. | 232 // Register 'Downloads' folder for the profile to the file system. |
231 if (!chromeos::ProfileHelper::IsSigninProfile(profile_)) { | 233 if (!chromeos::ProfileHelper::IsSigninProfile(profile_)) { |
232 const base::FilePath downloads = | 234 const base::FilePath downloads = |
233 file_manager::util::GetDownloadsFolderForProfile(profile_); | 235 file_manager::util::GetDownloadsFolderForProfile(profile_); |
234 const bool success = RegisterDownloadsMountPoint(profile_, downloads); | 236 const bool success = RegisterDownloadsMountPoint(profile_, downloads); |
235 DCHECK(success); | 237 DCHECK(success); |
236 | 238 |
237 DoMountEvent(chromeos::MOUNT_ERROR_NONE, | 239 DoMountEvent(chromeos::MOUNT_ERROR_NONE, |
238 CreateDownloadsVolumeInfo(downloads), | 240 CreateDownloadsVolumeInfo(downloads), |
239 false /* is_remounting */); | 241 kNotRemounting); |
240 } | 242 } |
241 | 243 |
242 // Subscribe to DriveIntegrationService. | 244 // Subscribe to DriveIntegrationService. |
243 if (drive_integration_service_) { | 245 if (drive_integration_service_) { |
244 drive_integration_service_->AddObserver(this); | 246 drive_integration_service_->AddObserver(this); |
245 if (drive_integration_service_->IsMounted()) { | 247 if (drive_integration_service_->IsMounted()) { |
246 DoMountEvent( | 248 DoMountEvent(chromeos::MOUNT_ERROR_NONE, |
247 chromeos::MOUNT_ERROR_NONE, CreateDriveVolumeInfo(profile_), false); | 249 CreateDriveVolumeInfo(profile_), |
| 250 kNotRemounting); |
248 } | 251 } |
249 } | 252 } |
250 | 253 |
251 // Subscribe to DiskMountManager. | 254 // Subscribe to DiskMountManager. |
252 disk_mount_manager_->AddObserver(this); | 255 disk_mount_manager_->AddObserver(this); |
253 | 256 |
| 257 std::vector<VolumeInfo> archives; |
| 258 |
254 const chromeos::disks::DiskMountManager::MountPointMap& mount_points = | 259 const chromeos::disks::DiskMountManager::MountPointMap& mount_points = |
255 disk_mount_manager_->mount_points(); | 260 disk_mount_manager_->mount_points(); |
256 for (chromeos::disks::DiskMountManager::MountPointMap::const_iterator it = | 261 for (chromeos::disks::DiskMountManager::MountPointMap::const_iterator it = |
257 mount_points.begin(); | 262 mount_points.begin(); |
258 it != mount_points.end(); | 263 it != mount_points.end(); |
259 ++it) { | 264 ++it) { |
| 265 if (it->second.mount_type == chromeos::MOUNT_TYPE_ARCHIVE) { |
| 266 // Archives are mounted after other type of volumes. See below. |
| 267 archives.push_back(CreateVolumeInfoFromMountPointInfo(it->second, NULL)); |
| 268 continue; |
| 269 } |
260 DoMountEvent( | 270 DoMountEvent( |
261 chromeos::MOUNT_ERROR_NONE, | 271 chromeos::MOUNT_ERROR_NONE, |
262 CreateVolumeInfoFromMountPointInfo( | 272 CreateVolumeInfoFromMountPointInfo( |
263 it->second, | 273 it->second, |
264 disk_mount_manager_->FindDiskBySourcePath(it->second.source_path)), | 274 disk_mount_manager_->FindDiskBySourcePath(it->second.source_path)), |
265 false /* is_remounting */); | 275 kNotRemounting); |
| 276 } |
| 277 |
| 278 // We mount archives only if they are opened from currently mounted volumes. |
| 279 // To check the condition correctly in DoMountEvent, we care the order. |
| 280 std::vector<bool> done(archives.size(), false); |
| 281 for (size_t i = 0; i < archives.size(); ++i) { |
| 282 if (!done[i]) { |
| 283 std::vector<VolumeInfo> chain; |
| 284 done[i] = true; |
| 285 chain.push_back(archives[i]); |
| 286 |
| 287 // If archives[i]'s source_path is in another archive, mount it first. |
| 288 for (size_t parent = 0; parent < archives.size(); ++parent) { |
| 289 if (!done[parent] && |
| 290 archives[parent].mount_path.IsParent(chain.back().source_path)) { |
| 291 done[parent] = true; |
| 292 chain.push_back(archives[parent]); |
| 293 parent = 0; // Search archives[parent]'s parent from the beginning. |
| 294 } |
| 295 } |
| 296 |
| 297 // Mount from the tail of chain. |
| 298 for (size_t i = chain.size(); i > 0; --i) |
| 299 DoMountEvent(chromeos::MOUNT_ERROR_NONE, chain[i - 1], kNotRemounting); |
| 300 } |
266 } | 301 } |
267 | 302 |
268 disk_mount_manager_->RequestMountInfoRefresh(); | 303 disk_mount_manager_->RequestMountInfoRefresh(); |
269 | 304 |
270 // Subscribe to Profile Preference change. | 305 // Subscribe to Profile Preference change. |
271 pref_change_registrar_.Init(profile_->GetPrefs()); | 306 pref_change_registrar_.Init(profile_->GetPrefs()); |
272 pref_change_registrar_.Add( | 307 pref_change_registrar_.Add( |
273 prefs::kExternalStorageDisabled, | 308 prefs::kExternalStorageDisabled, |
274 base::Bind(&VolumeManager::OnExternalStorageDisabledChanged, | 309 base::Bind(&VolumeManager::OnExternalStorageDisabledChanged, |
275 base::Unretained(this))); | 310 base::Unretained(this))); |
(...skipping 273 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
549 for (local_discovery::PrivetVolumeLister::VolumeList::const_iterator i = | 584 for (local_discovery::PrivetVolumeLister::VolumeList::const_iterator i = |
550 volumes.begin(); i != volumes.end(); i++) { | 585 volumes.begin(); i != volumes.end(); i++) { |
551 VolumeInfo volume_info = CreatePrivetVolumeInfo(*i); | 586 VolumeInfo volume_info = CreatePrivetVolumeInfo(*i); |
552 DoMountEvent(chromeos::MOUNT_ERROR_NONE, volume_info, false); | 587 DoMountEvent(chromeos::MOUNT_ERROR_NONE, volume_info, false); |
553 } | 588 } |
554 } | 589 } |
555 | 590 |
556 void VolumeManager::DoMountEvent(chromeos::MountError error_code, | 591 void VolumeManager::DoMountEvent(chromeos::MountError error_code, |
557 const VolumeInfo& volume_info, | 592 const VolumeInfo& volume_info, |
558 bool is_remounting) { | 593 bool is_remounting) { |
559 // TODO(kinaba): filter zip. | 594 // Archive files are mounted globally in system. We however don't want to show |
| 595 // archives from profile-specific folders (Drive/Downloads) of other users in |
| 596 // multi-profile session. To this end, we filter out archives not on the |
| 597 // volumes already mounted on this VolumeManager instance. |
| 598 if (volume_info.type == VOLUME_TYPE_MOUNTED_ARCHIVE_FILE) { |
| 599 // Source may be in Drive cache folder under the current profile directory. |
| 600 bool from_current_profile = |
| 601 profile_->GetPath().IsParent(volume_info.source_path); |
| 602 for (std::map<std::string, VolumeInfo>::const_iterator iter = |
| 603 mounted_volumes_.begin(); |
| 604 !from_current_profile && iter != mounted_volumes_.end(); |
| 605 ++iter) { |
| 606 if (iter->second.mount_path.IsParent(volume_info.source_path)) |
| 607 from_current_profile = true; |
| 608 } |
| 609 if (!from_current_profile) |
| 610 return; |
| 611 } |
560 | 612 |
561 if (error_code == chromeos::MOUNT_ERROR_NONE || volume_info.mount_condition) | 613 if (error_code == chromeos::MOUNT_ERROR_NONE || volume_info.mount_condition) |
562 mounted_volumes_[volume_info.volume_id] = volume_info; | 614 mounted_volumes_[volume_info.volume_id] = volume_info; |
563 | 615 |
564 FOR_EACH_OBSERVER(VolumeManagerObserver, | 616 FOR_EACH_OBSERVER(VolumeManagerObserver, |
565 observers_, | 617 observers_, |
566 OnVolumeMounted(error_code, volume_info, is_remounting)); | 618 OnVolumeMounted(error_code, volume_info, is_remounting)); |
567 } | 619 } |
568 | 620 |
569 void VolumeManager::DoUnmountEvent(chromeos::MountError error_code, | 621 void VolumeManager::DoUnmountEvent(chromeos::MountError error_code, |
570 const VolumeInfo& volume_info) { | 622 const VolumeInfo& volume_info) { |
571 if (mounted_volumes_.find(volume_info.volume_id) == mounted_volumes_.end()) | 623 if (mounted_volumes_.find(volume_info.volume_id) == mounted_volumes_.end()) |
572 return; | 624 return; |
573 if (error_code == chromeos::MOUNT_ERROR_NONE) | 625 if (error_code == chromeos::MOUNT_ERROR_NONE) |
574 mounted_volumes_.erase(volume_info.volume_id); | 626 mounted_volumes_.erase(volume_info.volume_id); |
575 | 627 |
576 FOR_EACH_OBSERVER(VolumeManagerObserver, | 628 FOR_EACH_OBSERVER(VolumeManagerObserver, |
577 observers_, | 629 observers_, |
578 OnVolumeUnmounted(error_code, volume_info)); | 630 OnVolumeUnmounted(error_code, volume_info)); |
579 } | 631 } |
580 | 632 |
581 } // namespace file_manager | 633 } // namespace file_manager |
OLD | NEW |