158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// found in the LICENSE file.
458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "chrome/browser/chromeos/file_manager/volume_manager.h"
658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "base/basictypes.h"
8d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "base/bind.h"
9d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "base/callback.h"
1058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "base/files/file_path.h"
1158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "base/logging.h"
1258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "base/memory/singleton.h"
1358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "base/prefs/pref_service.h"
14d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "chrome/browser/chromeos/drive/drive_integration_service.h"
1558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "chrome/browser/chromeos/drive/file_errors.h"
1658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "chrome/browser/chromeos/drive/file_system_interface.h"
1758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "chrome/browser/chromeos/drive/file_system_util.h"
1858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "chrome/browser/chromeos/file_manager/mounted_disk_monitor.h"
190f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "chrome/browser/chromeos/file_manager/path_util.h"
2058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "chrome/browser/chromeos/file_manager/volume_manager_factory.h"
2158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "chrome/browser/chromeos/file_manager/volume_manager_observer.h"
2258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "chrome/browser/profiles/profile.h"
2358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "chrome/common/pref_names.h"
2458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "chromeos/dbus/cros_disks_client.h"
2558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "chromeos/disks/disk_mount_manager.h"
2658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "content/public/browser/browser_thread.h"
270f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "webkit/browser/fileapi/external_mount_points.h"
2858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
2958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)namespace file_manager {
3058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)namespace {
3158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
3258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// Called on completion of MarkCacheFileAsUnmounted.
3358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void OnMarkCacheFileAsUnmounted(drive::FileError error) {
3458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // Do nothing.
3558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
3658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
3758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)VolumeType MountTypeToVolumeType(
3858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    chromeos::MountType type) {
3958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  switch (type) {
404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    case chromeos::MOUNT_TYPE_INVALID:
414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      // We don't expect this value, but list here, so that when any value
424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      // is added to the enum definition but this is not edited, the compiler
434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      // warns it.
444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      break;
4558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    case chromeos::MOUNT_TYPE_DEVICE:
4658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      return VOLUME_TYPE_REMOVABLE_DISK_PARTITION;
4758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    case chromeos::MOUNT_TYPE_ARCHIVE:
4858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      return VOLUME_TYPE_MOUNTED_ARCHIVE_FILE;
4958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
5058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  NOTREACHED();
5258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return VOLUME_TYPE_DOWNLOADS_DIRECTORY;
5358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
5458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
55f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Returns a string representation of the given volume type.
56f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)std::string VolumeTypeToString(VolumeType type) {
57f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  switch (type) {
58f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    case VOLUME_TYPE_GOOGLE_DRIVE:
59f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      return "drive";
60f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    case VOLUME_TYPE_DOWNLOADS_DIRECTORY:
61f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      return "downloads";
62f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    case VOLUME_TYPE_REMOVABLE_DISK_PARTITION:
63f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      return "removable";
64f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    case VOLUME_TYPE_MOUNTED_ARCHIVE_FILE:
65f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      return "archive";
66f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
67f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  NOTREACHED();
68f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return "";
69f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
70f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
71f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Generates a unique volume ID for the given volume info.
72f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)std::string GenerateVolumeId(const VolumeInfo& volume_info) {
73f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // For the same volume type, base names are unique, as mount points are
74f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // flat for the same volume type.
75f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return (VolumeTypeToString(volume_info.type) + ":" +
76f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)          volume_info.mount_path.BaseName().AsUTF8Unsafe());
77f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
78f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
79d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// Returns the VolumeInfo for Drive file system.
80d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)VolumeInfo CreateDriveVolumeInfo() {
81d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  const base::FilePath& drive_path = drive::util::GetDriveMountPointPath();
82d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
83d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  VolumeInfo volume_info;
84d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  volume_info.type = VOLUME_TYPE_GOOGLE_DRIVE;
854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  volume_info.device_type = chromeos::DEVICE_TYPE_UNKNOWN;
86d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  volume_info.source_path = drive_path;
87d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  volume_info.mount_path = drive_path;
88d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  volume_info.mount_condition = chromeos::disks::MOUNT_CONDITION_NONE;
89d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  volume_info.is_parent = false;
904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  volume_info.is_read_only = false;
91f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  volume_info.volume_id = GenerateVolumeId(volume_info);
92d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  return volume_info;
93d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)}
94d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
9558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)VolumeInfo CreateDownloadsVolumeInfo(
9658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    const base::FilePath& downloads_path) {
9758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  VolumeInfo volume_info;
9858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  volume_info.type = VOLUME_TYPE_DOWNLOADS_DIRECTORY;
994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  volume_info.device_type = chromeos::DEVICE_TYPE_UNKNOWN;
10058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // Keep source_path empty.
10158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  volume_info.mount_path = downloads_path;
10258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  volume_info.mount_condition = chromeos::disks::MOUNT_CONDITION_NONE;
10358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  volume_info.is_parent = false;
1044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  volume_info.is_read_only = false;
105f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  volume_info.volume_id = GenerateVolumeId(volume_info);
10658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return volume_info;
10758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
10858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
10958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)VolumeInfo CreateVolumeInfoFromMountPointInfo(
11058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    const chromeos::disks::DiskMountManager::MountPointInfo& mount_point,
11158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    const chromeos::disks::DiskMountManager::Disk* disk) {
11258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  VolumeInfo volume_info;
11358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  volume_info.type = MountTypeToVolumeType(mount_point.mount_type);
11458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  volume_info.source_path = base::FilePath(mount_point.source_path);
11558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  volume_info.mount_path = base::FilePath(mount_point.mount_path);
11658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  volume_info.mount_condition = mount_point.mount_condition;
11758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (disk) {
1184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    volume_info.device_type = disk->device_type();
11958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    volume_info.system_path_prefix =
12058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        base::FilePath(disk->system_path_prefix());
12158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    volume_info.drive_label = disk->drive_label();
12258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    volume_info.is_parent = disk->is_parent();
1234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    volume_info.is_read_only = disk->is_read_only();
12458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  } else {
1254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    volume_info.device_type = chromeos::DEVICE_TYPE_UNKNOWN;
12658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    volume_info.is_parent = false;
1274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    volume_info.is_read_only = false;
12858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
129f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  volume_info.volume_id = GenerateVolumeId(volume_info);
13058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
13158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return volume_info;
13258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
13358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
13458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}  // namespace
13558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
13658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)VolumeInfo::VolumeInfo() {
13758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
13858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
13958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)VolumeInfo::~VolumeInfo() {
14058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
14158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
14258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)VolumeManager::VolumeManager(
14358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    Profile* profile,
144d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    drive::DriveIntegrationService* drive_integration_service,
14558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    chromeos::PowerManagerClient* power_manager_client,
14658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    chromeos::disks::DiskMountManager* disk_mount_manager)
14758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    : profile_(profile),
148d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      drive_integration_service_(drive_integration_service),
14958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      disk_mount_manager_(disk_mount_manager),
15058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      mounted_disk_monitor_(
15158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          new MountedDiskMonitor(power_manager_client, disk_mount_manager)) {
15258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  DCHECK(disk_mount_manager);
15358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
15458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
15558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)VolumeManager::~VolumeManager() {
15658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
15758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
15858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)VolumeManager* VolumeManager::Get(content::BrowserContext* context) {
15958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return VolumeManagerFactory::Get(context);
16058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
16158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
16258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void VolumeManager::Initialize() {
1630f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // Path to mount user folders have changed several times. We need to migrate
1640f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // the old preferences on paths to the new format when needed. For the detail,
1650f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // see the comments in file_manager::util::MigratePathFromOldFormat,
1660f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // TODO(kinaba): Remove this are several rounds of releases.
1670f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  const char* kPathPreference[] = {
1680f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      prefs::kDownloadDefaultDirectory,
1690f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      prefs::kSelectFileLastDirectory,
1700f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      prefs::kSaveFileDefaultDirectory,
1710f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  };
1720f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  for (size_t i = 0; i < arraysize(kPathPreference); ++i) {
1730f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    const base::FilePath old_path =
1740f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)        profile_->GetPrefs()->GetFilePath(kPathPreference[i]);
1750f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    base::FilePath new_path;
1760f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    if (!old_path.empty() &&
1770f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)        file_manager::util::MigratePathFromOldFormat(profile_,
1780f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                                                     old_path, &new_path)) {
1790f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      profile_->GetPrefs()->SetFilePath(kPathPreference[i], new_path);
1800f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    }
1810f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  }
1820f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
1830f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // Register 'Downloads' folder for the profile to the file system.
1840f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  fileapi::ExternalMountPoints* mount_points =
1850f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      content::BrowserContext::GetMountPoints(profile_);
1860f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  DCHECK(mount_points);
1870f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
1880f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  const base::FilePath downloads_folder =
1890f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      file_manager::util::GetDownloadsFolderForProfile(profile_);
1900f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  bool success = mount_points->RegisterFileSystem(
1910f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      downloads_folder.BaseName().AsUTF8Unsafe(),
1920f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      fileapi::kFileSystemTypeNativeLocal,
193a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      fileapi::FileSystemMountOption(),
1940f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      downloads_folder);
1950f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  DCHECK(success);
1960f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
1970f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // Subscribe to DriveIntegrationService.
198d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  if (drive_integration_service_)
199d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    drive_integration_service_->AddObserver(this);
200d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
201d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // Subscribe to DiskMountManager.
20258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  disk_mount_manager_->AddObserver(this);
20358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  disk_mount_manager_->RequestMountInfoRefresh();
204d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
205d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // Subscribe to Profile Preference change.
206d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  pref_change_registrar_.Init(profile_->GetPrefs());
207d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  pref_change_registrar_.Add(
208d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      prefs::kExternalStorageDisabled,
209d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      base::Bind(&VolumeManager::OnExternalStorageDisabledChanged,
210d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                 base::Unretained(this)));
21158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
21258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
21358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void VolumeManager::Shutdown() {
214d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  pref_change_registrar_.RemoveAll();
21558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  disk_mount_manager_->RemoveObserver(this);
216d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
217d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  if (drive_integration_service_)
218d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    drive_integration_service_->RemoveObserver(this);
21958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
22058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
22158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void VolumeManager::AddObserver(VolumeManagerObserver* observer) {
22258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
22358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  DCHECK(observer);
22458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  observers_.AddObserver(observer);
22558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
22658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
22758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void VolumeManager::RemoveObserver(VolumeManagerObserver* observer) {
22858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
22958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  DCHECK(observer);
23058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  observers_.RemoveObserver(observer);
23158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
23258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
23358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)std::vector<VolumeInfo> VolumeManager::GetVolumeInfoList() const {
23458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
23558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
23658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  std::vector<VolumeInfo> result;
23758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
238d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // Adds "Drive" volume.
239d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  if (drive_integration_service_ && drive_integration_service_->IsMounted())
240d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    result.push_back(CreateDriveVolumeInfo());
24158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
24258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // Adds "Downloads".
2430f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // Usually, the path of the directory is where we registered in Initialize(),
2440f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // but in tests, the mount point may be overridden. To take it into account,
2450f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // here we explicitly retrieves the path from the file API mount points.
2460f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  fileapi::ExternalMountPoints* fileapi_mount_points =
2470f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      content::BrowserContext::GetMountPoints(profile_);
2480f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  DCHECK(fileapi_mount_points);
2490f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  base::FilePath downloads;
2500f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  if (fileapi_mount_points->GetRegisteredPath("Downloads", &downloads))
2510f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    result.push_back(CreateDownloadsVolumeInfo(downloads));
25258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
25358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // Adds disks (both removable disks and zip archives).
25458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  const chromeos::disks::DiskMountManager::MountPointMap& mount_points =
25558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      disk_mount_manager_->mount_points();
25658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  for (chromeos::disks::DiskMountManager::MountPointMap::const_iterator it =
25758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)           mount_points.begin();
25858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)       it != mount_points.end(); ++it) {
2594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    result.push_back(CreateVolumeInfoFromMountPointInfo(
2604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        it->second,
2614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        disk_mount_manager_->FindDiskBySourcePath(it->second.source_path)));
26258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
26358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
26458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return result;
26558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
26658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
267f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)bool VolumeManager::FindVolumeInfoById(const std::string& volume_id,
268f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                       VolumeInfo* result) const {
269f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
270f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK(result);
271f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
272f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  std::vector<VolumeInfo> info_list = GetVolumeInfoList();
273f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  for (size_t i = 0; i < info_list.size(); ++i) {
274f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (info_list[i].volume_id == volume_id) {
275f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      *result = info_list[i];
276f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      return true;
277f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    }
278f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
279f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
280f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return false;
281f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
282f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
283d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)void VolumeManager::OnFileSystemMounted() {
284d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
285d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
286d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // Raise mount event.
287d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // We can pass chromeos::MOUNT_ERROR_NONE even when authentication is failed
288d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // or network is unreachable. These two errors will be handled later.
289d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  VolumeInfo volume_info = CreateDriveVolumeInfo();
290d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  FOR_EACH_OBSERVER(VolumeManagerObserver, observers_,
291d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                    OnVolumeMounted(chromeos::MOUNT_ERROR_NONE,
292d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                                    volume_info,
293d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                                    false));  // Not remounting.
294d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)}
295d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
296d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)void VolumeManager::OnFileSystemBeingUnmounted() {
297d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
298d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
299d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  VolumeInfo volume_info = CreateDriveVolumeInfo();
300d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  FOR_EACH_OBSERVER(
301d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      VolumeManagerObserver, observers_,
302d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      OnVolumeUnmounted(chromeos::MOUNT_ERROR_NONE, volume_info));
303d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)}
304d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
30558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void VolumeManager::OnDiskEvent(
30658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    chromeos::disks::DiskMountManager::DiskEvent event,
30758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    const chromeos::disks::DiskMountManager::Disk* disk) {
30858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
30958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
31058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // Disregard hidden devices.
31158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (disk->is_hidden())
31258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return;
31358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
31458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  switch (event) {
31558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    case chromeos::disks::DiskMountManager::DISK_ADDED: {
31658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      if (disk->device_path().empty()) {
31758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        DVLOG(1) << "Empty system path for " << disk->device_path();
31858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        return;
31958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      }
32058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
32158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      bool mounting = false;
32258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      if (disk->mount_path().empty() && disk->has_media() &&
32358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          !profile_->GetPrefs()->GetBoolean(prefs::kExternalStorageDisabled)) {
32458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        // If disk is not mounted yet and it has media and there is no policy
32558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        // forbidding external storage, give it a try.
32658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        // Initiate disk mount operation. MountPath auto-detects the filesystem
32758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        // format if the second argument is empty. The third argument (mount
32858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        // label) is not used in a disk mount operation.
32958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        disk_mount_manager_->MountPath(
33058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)            disk->device_path(), std::string(), std::string(),
33158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)            chromeos::MOUNT_TYPE_DEVICE);
33258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        mounting = true;
33358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      }
33458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
33558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      // Notify to observers.
33658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      FOR_EACH_OBSERVER(VolumeManagerObserver, observers_,
33758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                        OnDiskAdded(*disk, mounting));
33858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      return;
33958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    }
34058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
34158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    case chromeos::disks::DiskMountManager::DISK_REMOVED:
34258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      // If the disk is already mounted, unmount it.
34358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      if (!disk->mount_path().empty()) {
34458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        disk_mount_manager_->UnmountPath(
34558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)            disk->mount_path(),
34658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)            chromeos::UNMOUNT_OPTIONS_LAZY,
34758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)            chromeos::disks::DiskMountManager::UnmountPathCallback());
34858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      }
34958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
35058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      // Notify to observers.
35158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      FOR_EACH_OBSERVER(VolumeManagerObserver, observers_,
35258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                        OnDiskRemoved(*disk));
35358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      return;
35458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
35558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    case chromeos::disks::DiskMountManager::DISK_CHANGED:
35658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      DVLOG(1) << "Ignore CHANGED event.";
35758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      return;
35858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
35958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  NOTREACHED();
36058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
36158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
36258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void VolumeManager::OnDeviceEvent(
36358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    chromeos::disks::DiskMountManager::DeviceEvent event,
36458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    const std::string& device_path) {
36558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
36658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  DVLOG(1) << "OnDeviceEvent: " << event << ", " << device_path;
36758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
36858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  switch (event) {
36958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    case chromeos::disks::DiskMountManager::DEVICE_ADDED:
37058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      FOR_EACH_OBSERVER(VolumeManagerObserver, observers_,
37158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                        OnDeviceAdded(device_path));
37258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      return;
37358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    case chromeos::disks::DiskMountManager::DEVICE_REMOVED:
37458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      FOR_EACH_OBSERVER(VolumeManagerObserver, observers_,
37558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                        OnDeviceRemoved(device_path));
37658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      return;
37758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    case chromeos::disks::DiskMountManager::DEVICE_SCANNED:
37858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      DVLOG(1) << "Ignore SCANNED event: " << device_path;
37958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      return;
38058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
38158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  NOTREACHED();
38258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
38358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
38458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void VolumeManager::OnMountEvent(
38558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    chromeos::disks::DiskMountManager::MountEvent event,
38658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    chromeos::MountError error_code,
38758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    const chromeos::disks::DiskMountManager::MountPointInfo& mount_info) {
38858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
3894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DCHECK_NE(chromeos::MOUNT_TYPE_INVALID, mount_info.mount_type);
39058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
39158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (mount_info.mount_type == chromeos::MOUNT_TYPE_ARCHIVE) {
39258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // If the file is not mounted now, tell it to drive file system so that
39358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // it can handle file caching correctly.
39458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // Note that drive file system knows if the file is managed by drive file
39558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // system or not, so here we report all paths.
39658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    if ((event == chromeos::disks::DiskMountManager::MOUNTING &&
39758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)         error_code != chromeos::MOUNT_ERROR_NONE) ||
39858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        (event == chromeos::disks::DiskMountManager::UNMOUNTING &&
39958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)         error_code == chromeos::MOUNT_ERROR_NONE)) {
40058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      drive::FileSystemInterface* file_system =
40158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          drive::util::GetFileSystemByProfile(profile_);
40258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      if (file_system) {
40358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        file_system->MarkCacheFileAsUnmounted(
40458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)            base::FilePath(mount_info.source_path),
40558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)            base::Bind(&OnMarkCacheFileAsUnmounted));
40658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      }
40758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    }
40858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
40958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
41058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // Notify a mounting/unmounting event to observers.
41158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  const chromeos::disks::DiskMountManager::Disk* disk =
41258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      disk_mount_manager_->FindDiskBySourcePath(mount_info.source_path);
41358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  VolumeInfo volume_info =
41458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      CreateVolumeInfoFromMountPointInfo(mount_info, disk);
41558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  switch (event) {
41658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    case chromeos::disks::DiskMountManager::MOUNTING: {
41758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      bool is_remounting =
41858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          disk && mounted_disk_monitor_->DiskIsRemounting(*disk);
41958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      FOR_EACH_OBSERVER(
42058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          VolumeManagerObserver, observers_,
42158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          OnVolumeMounted(error_code, volume_info, is_remounting));
42258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      return;
42358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    }
42458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    case chromeos::disks::DiskMountManager::UNMOUNTING:
42558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      FOR_EACH_OBSERVER(VolumeManagerObserver, observers_,
42658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                        OnVolumeUnmounted(error_code, volume_info));
42758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      return;
42858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
42958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  NOTREACHED();
43058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
43158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
43258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void VolumeManager::OnFormatEvent(
43358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    chromeos::disks::DiskMountManager::FormatEvent event,
43458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    chromeos::FormatError error_code,
43558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    const std::string& device_path) {
43658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
43758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  DVLOG(1) << "OnDeviceEvent: " << event << ", " << error_code
43858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)           << ", " << device_path;
43958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
44058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  switch (event) {
44158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    case chromeos::disks::DiskMountManager::FORMAT_STARTED:
44258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      FOR_EACH_OBSERVER(
44358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          VolumeManagerObserver, observers_,
44458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          OnFormatStarted(device_path,
44558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                          error_code == chromeos::FORMAT_ERROR_NONE));
44658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      return;
44758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    case chromeos::disks::DiskMountManager::FORMAT_COMPLETED:
44858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      if (error_code == chromeos::FORMAT_ERROR_NONE) {
44958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        // If format is completed successfully, try to mount the device.
45058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        // MountPath auto-detects filesystem format if second argument is
45158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        // empty. The third argument (mount label) is not used in a disk mount
45258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        // operation.
45358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        disk_mount_manager_->MountPath(
45458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)            device_path, std::string(), std::string(),
45558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)            chromeos::MOUNT_TYPE_DEVICE);
45658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      }
45758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
45858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      FOR_EACH_OBSERVER(
45958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          VolumeManagerObserver, observers_,
46058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          OnFormatCompleted(device_path,
46158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                            error_code == chromeos::FORMAT_ERROR_NONE));
46258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
46358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      return;
46458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
46558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  NOTREACHED();
46658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
46758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
468d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)void VolumeManager::OnExternalStorageDisabledChanged() {
469d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // If the policy just got disabled we have to unmount every device currently
470d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // mounted. The opposite is fine - we can let the user re-plug her device to
471d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // make it available.
472d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  if (profile_->GetPrefs()->GetBoolean(prefs::kExternalStorageDisabled)) {
473d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    // We do not iterate on mount_points directly, because mount_points can
474d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    // be changed by UnmountPath().
475d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    // TODO(hidehiko): Is it necessary to unmount mounted archives, too, here?
476d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    while (!disk_mount_manager_->mount_points().empty()) {
477d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      std::string mount_path =
478d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)          disk_mount_manager_->mount_points().begin()->second.mount_path;
479d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      disk_mount_manager_->UnmountPath(
480d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)          mount_path,
481d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)          chromeos::UNMOUNT_OPTIONS_NONE,
482d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)          chromeos::disks::DiskMountManager::UnmountPathCallback());
483d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    }
484d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  }
485d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)}
486d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
48758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}  // namespace file_manager
488