Home | History | Annotate | Download | only in file_manager
      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
      3 // found in the LICENSE file.
      4 
      5 #include "chrome/browser/chromeos/file_manager/volume_manager.h"
      6 
      7 #include <string>
      8 #include <vector>
      9 
     10 #include "base/basictypes.h"
     11 #include "base/prefs/pref_service.h"
     12 #include "base/strings/utf_string_conversions.h"
     13 #include "chrome/browser/chromeos/file_manager/fake_disk_mount_manager.h"
     14 #include "chrome/browser/chromeos/file_manager/volume_manager_observer.h"
     15 #include "chrome/browser/chromeos/file_system_provider/fake_provided_file_system.h"
     16 #include "chrome/browser/chromeos/file_system_provider/service.h"
     17 #include "chrome/common/pref_names.h"
     18 #include "chrome/test/base/testing_profile.h"
     19 #include "chromeos/dbus/fake_power_manager_client.h"
     20 #include "chromeos/disks/disk_mount_manager.h"
     21 #include "components/storage_monitor/storage_info.h"
     22 #include "content/public/test/test_browser_thread_bundle.h"
     23 #include "extensions/browser/extension_registry.h"
     24 #include "testing/gtest/include/gtest/gtest.h"
     25 
     26 namespace file_manager {
     27 namespace {
     28 
     29 class LoggingObserver : public VolumeManagerObserver {
     30  public:
     31   struct Event {
     32     enum EventType {
     33       DISK_ADDED,
     34       DISK_REMOVED,
     35       DEVICE_ADDED,
     36       DEVICE_REMOVED,
     37       VOLUME_MOUNTED,
     38       VOLUME_UNMOUNTED,
     39       FORMAT_STARTED,
     40       FORMAT_COMPLETED,
     41     } type;
     42 
     43     // Available on DEVICE_ADDED, DEVICE_REMOVED, VOLUME_MOUNTED,
     44     // VOLUME_UNMOUNTED, FORMAT_STARTED and FORMAT_COMPLETED.
     45     std::string device_path;
     46 
     47     // Available on DISK_ADDED.
     48     bool mounting;
     49 
     50     // Available on DEVICE_REMOVED;
     51     bool hard_unplugged;
     52 
     53     // Available on VOLUME_MOUNTED and VOLUME_UNMOUNTED.
     54     chromeos::MountError mount_error;
     55 
     56     // Available on VOLUME_MOUNTED.
     57     bool is_remounting;
     58 
     59     // Available on FORMAT_STARTED and FORMAT_COMPLETED.
     60     bool success;
     61   };
     62 
     63   LoggingObserver() {}
     64   virtual ~LoggingObserver() {}
     65 
     66   const std::vector<Event>& events() const { return events_; }
     67 
     68   // VolumeManagerObserver overrides.
     69   virtual void OnDiskAdded(const chromeos::disks::DiskMountManager::Disk& disk,
     70                            bool mounting) OVERRIDE {
     71     Event event;
     72     event.type = Event::DISK_ADDED;
     73     event.device_path = disk.device_path();  // Keep only device_path.
     74     event.mounting = mounting;
     75     events_.push_back(event);
     76   }
     77 
     78   virtual void OnDiskRemoved(
     79       const chromeos::disks::DiskMountManager::Disk& disk) OVERRIDE {
     80     Event event;
     81     event.type = Event::DISK_REMOVED;
     82     event.device_path = disk.device_path();  // Keep only device_path.
     83     events_.push_back(event);
     84   }
     85 
     86   virtual void OnDeviceAdded(const std::string& device_path) OVERRIDE {
     87     Event event;
     88     event.type = Event::DEVICE_ADDED;
     89     event.device_path = device_path;
     90     events_.push_back(event);
     91   }
     92 
     93   virtual void OnDeviceRemoved(const std::string& device_path,
     94                                bool hard_unplugged) OVERRIDE {
     95     Event event;
     96     event.type = Event::DEVICE_REMOVED;
     97     event.device_path = device_path;
     98     event.hard_unplugged = hard_unplugged;
     99     events_.push_back(event);
    100   }
    101 
    102   virtual void OnVolumeMounted(chromeos::MountError error_code,
    103                                const VolumeInfo& volume_info,
    104                                bool is_remounting) OVERRIDE {
    105     Event event;
    106     event.type = Event::VOLUME_MOUNTED;
    107     event.device_path = volume_info.source_path.AsUTF8Unsafe();
    108     event.mount_error = error_code;
    109     event.is_remounting = is_remounting;
    110     events_.push_back(event);
    111   }
    112 
    113   virtual void OnVolumeUnmounted(chromeos::MountError error_code,
    114                                  const VolumeInfo& volume_info) OVERRIDE {
    115     Event event;
    116     event.type = Event::VOLUME_UNMOUNTED;
    117     event.device_path = volume_info.source_path.AsUTF8Unsafe();
    118     event.mount_error = error_code;
    119     events_.push_back(event);
    120   }
    121 
    122   virtual void OnFormatStarted(
    123       const std::string& device_path, bool success) OVERRIDE {
    124     Event event;
    125     event.type = Event::FORMAT_STARTED;
    126     event.device_path = device_path;
    127     event.success = success;
    128     events_.push_back(event);
    129   }
    130 
    131   virtual void OnFormatCompleted(
    132       const std::string& device_path, bool success) OVERRIDE {
    133     Event event;
    134     event.type = Event::FORMAT_COMPLETED;
    135     event.device_path = device_path;
    136     event.success = success;
    137     events_.push_back(event);
    138   }
    139 
    140  private:
    141   std::vector<Event> events_;
    142 
    143   DISALLOW_COPY_AND_ASSIGN(LoggingObserver);
    144 };
    145 
    146 }  // namespace
    147 
    148 class VolumeManagerTest : public testing::Test {
    149  protected:
    150   // Helper class that contains per-profile objects.
    151   class ProfileEnvironment {
    152    public:
    153     ProfileEnvironment(chromeos::PowerManagerClient* power_manager_client,
    154                        chromeos::disks::DiskMountManager* disk_manager)
    155         : profile_(new TestingProfile),
    156           extension_registry_(
    157               new extensions::ExtensionRegistry(profile_.get())),
    158           file_system_provider_service_(
    159               new chromeos::file_system_provider::Service(
    160                   profile_.get(),
    161                   extension_registry_.get())),
    162           volume_manager_(
    163               new VolumeManager(profile_.get(),
    164                                 NULL,  // DriveIntegrationService
    165                                 power_manager_client,
    166                                 disk_manager,
    167                                 file_system_provider_service_.get())) {
    168       file_system_provider_service_->SetFileSystemFactoryForTesting(base::Bind(
    169           &chromeos::file_system_provider::FakeProvidedFileSystem::Create));
    170     }
    171 
    172     Profile* profile() const { return profile_.get(); }
    173     VolumeManager* volume_manager() const { return volume_manager_.get(); }
    174 
    175    private:
    176     scoped_ptr<TestingProfile> profile_;
    177     scoped_ptr<extensions::ExtensionRegistry> extension_registry_;
    178     scoped_ptr<chromeos::file_system_provider::Service>
    179         file_system_provider_service_;
    180     scoped_ptr<VolumeManager> volume_manager_;
    181   };
    182 
    183   virtual void SetUp() OVERRIDE {
    184     power_manager_client_.reset(new chromeos::FakePowerManagerClient);
    185     disk_mount_manager_.reset(new FakeDiskMountManager);
    186     main_profile_.reset(new ProfileEnvironment(power_manager_client_.get(),
    187                                                disk_mount_manager_.get()));
    188   }
    189 
    190   Profile* profile() const { return main_profile_->profile(); }
    191   VolumeManager* volume_manager() const {
    192     return main_profile_->volume_manager();
    193   }
    194 
    195   content::TestBrowserThreadBundle thread_bundle_;
    196   scoped_ptr<chromeos::FakePowerManagerClient> power_manager_client_;
    197   scoped_ptr<FakeDiskMountManager> disk_mount_manager_;
    198   scoped_ptr<ProfileEnvironment> main_profile_;
    199 };
    200 
    201 TEST_F(VolumeManagerTest, OnDriveFileSystemMountAndUnmount) {
    202   LoggingObserver observer;
    203   volume_manager()->AddObserver(&observer);
    204 
    205   volume_manager()->OnFileSystemMounted();
    206 
    207   ASSERT_EQ(1U, observer.events().size());
    208   LoggingObserver::Event event = observer.events()[0];
    209   EXPECT_EQ(LoggingObserver::Event::VOLUME_MOUNTED, event.type);
    210   EXPECT_EQ(drive::util::GetDriveMountPointPath(profile()).AsUTF8Unsafe(),
    211             event.device_path);
    212   EXPECT_EQ(chromeos::MOUNT_ERROR_NONE, event.mount_error);
    213   EXPECT_FALSE(event.is_remounting);
    214 
    215   volume_manager()->OnFileSystemBeingUnmounted();
    216 
    217   ASSERT_EQ(2U, observer.events().size());
    218   event = observer.events()[1];
    219   EXPECT_EQ(LoggingObserver::Event::VOLUME_UNMOUNTED, event.type);
    220   EXPECT_EQ(drive::util::GetDriveMountPointPath(profile()).AsUTF8Unsafe(),
    221             event.device_path);
    222   EXPECT_EQ(chromeos::MOUNT_ERROR_NONE, event.mount_error);
    223 
    224   volume_manager()->RemoveObserver(&observer);
    225 }
    226 
    227 TEST_F(VolumeManagerTest, OnDriveFileSystemUnmountWithoutMount) {
    228   LoggingObserver observer;
    229   volume_manager()->AddObserver(&observer);
    230   volume_manager()->OnFileSystemBeingUnmounted();
    231 
    232   // Unmount event for non-mounted volume is not reported.
    233   ASSERT_EQ(0U, observer.events().size());
    234   volume_manager()->RemoveObserver(&observer);
    235 }
    236 
    237 TEST_F(VolumeManagerTest, OnDiskEvent_Hidden) {
    238   LoggingObserver observer;
    239   volume_manager()->AddObserver(&observer);
    240 
    241   const bool kIsHidden = true;
    242   const chromeos::disks::DiskMountManager::Disk kDisk(
    243       "device1", "", "", "", "", "", "", "", "", "", "", "",
    244       chromeos::DEVICE_TYPE_UNKNOWN, 0, false, false, false, false, kIsHidden);
    245 
    246   volume_manager()->OnDiskEvent(
    247       chromeos::disks::DiskMountManager::DISK_ADDED, &kDisk);
    248   EXPECT_EQ(0U, observer.events().size());
    249 
    250   volume_manager()->OnDiskEvent(
    251       chromeos::disks::DiskMountManager::DISK_REMOVED, &kDisk);
    252   EXPECT_EQ(0U, observer.events().size());
    253 
    254   volume_manager()->OnDiskEvent(
    255       chromeos::disks::DiskMountManager::DISK_CHANGED, &kDisk);
    256   EXPECT_EQ(0U, observer.events().size());
    257 
    258   volume_manager()->RemoveObserver(&observer);
    259 }
    260 
    261 TEST_F(VolumeManagerTest, OnDiskEvent_Added) {
    262   // Enable external storage.
    263   profile()->GetPrefs()->SetBoolean(prefs::kExternalStorageDisabled, false);
    264 
    265   LoggingObserver observer;
    266   volume_manager()->AddObserver(&observer);
    267 
    268   const chromeos::disks::DiskMountManager::Disk kEmptyDevicePathDisk(
    269       "",  // empty device path.
    270       "", "", "", "", "", "", "", "", "", "", "",
    271       chromeos::DEVICE_TYPE_UNKNOWN, 0, false, false, false, false, false);
    272   volume_manager()->OnDiskEvent(
    273       chromeos::disks::DiskMountManager::DISK_ADDED, &kEmptyDevicePathDisk);
    274   EXPECT_EQ(0U, observer.events().size());
    275 
    276   const bool kHasMedia = true;
    277   const chromeos::disks::DiskMountManager::Disk kMediaDisk(
    278       "device1", "", "", "", "", "", "", "", "", "", "", "",
    279       chromeos::DEVICE_TYPE_UNKNOWN, 0, false, false, kHasMedia, false, false);
    280   volume_manager()->OnDiskEvent(
    281       chromeos::disks::DiskMountManager::DISK_ADDED, &kMediaDisk);
    282   ASSERT_EQ(1U, observer.events().size());
    283   const LoggingObserver::Event& event = observer.events()[0];
    284   EXPECT_EQ(LoggingObserver::Event::DISK_ADDED, event.type);
    285   EXPECT_EQ("device1", event.device_path);
    286   EXPECT_TRUE(event.mounting);
    287 
    288   ASSERT_EQ(1U, disk_mount_manager_->mount_requests().size());
    289   const FakeDiskMountManager::MountRequest& mount_request =
    290       disk_mount_manager_->mount_requests()[0];
    291   EXPECT_EQ("device1", mount_request.source_path);
    292   EXPECT_EQ("", mount_request.source_format);
    293   EXPECT_EQ("", mount_request.mount_label);
    294   EXPECT_EQ(chromeos::MOUNT_TYPE_DEVICE, mount_request.type);
    295 
    296   volume_manager()->RemoveObserver(&observer);
    297 }
    298 
    299 TEST_F(VolumeManagerTest, OnDiskEvent_AddedNonMounting) {
    300   // Enable external storage.
    301   profile()->GetPrefs()->SetBoolean(prefs::kExternalStorageDisabled, false);
    302 
    303   // Device which is already mounted.
    304   {
    305     LoggingObserver observer;
    306     volume_manager()->AddObserver(&observer);
    307 
    308     const bool kHasMedia = true;
    309     const chromeos::disks::DiskMountManager::Disk kMountedMediaDisk(
    310         "device1", "mounted", "", "", "", "", "", "", "", "", "", "",
    311         chromeos::DEVICE_TYPE_UNKNOWN, 0, false, false,
    312         kHasMedia, false, false);
    313     volume_manager()->OnDiskEvent(
    314         chromeos::disks::DiskMountManager::DISK_ADDED, &kMountedMediaDisk);
    315     ASSERT_EQ(1U, observer.events().size());
    316     const LoggingObserver::Event& event = observer.events()[0];
    317     EXPECT_EQ(LoggingObserver::Event::DISK_ADDED, event.type);
    318     EXPECT_EQ("device1", event.device_path);
    319     EXPECT_FALSE(event.mounting);
    320 
    321     ASSERT_EQ(0U, disk_mount_manager_->mount_requests().size());
    322 
    323     volume_manager()->RemoveObserver(&observer);
    324   }
    325 
    326   // Device without media.
    327   {
    328     LoggingObserver observer;
    329     volume_manager()->AddObserver(&observer);
    330 
    331     const bool kWithoutMedia = false;
    332     const chromeos::disks::DiskMountManager::Disk kNoMediaDisk(
    333         "device1", "", "", "", "", "", "", "", "", "", "", "",
    334         chromeos::DEVICE_TYPE_UNKNOWN, 0, false, false,
    335         kWithoutMedia, false, false);
    336     volume_manager()->OnDiskEvent(
    337         chromeos::disks::DiskMountManager::DISK_ADDED, &kNoMediaDisk);
    338     ASSERT_EQ(1U, observer.events().size());
    339     const LoggingObserver::Event& event = observer.events()[0];
    340     EXPECT_EQ(LoggingObserver::Event::DISK_ADDED, event.type);
    341     EXPECT_EQ("device1", event.device_path);
    342     EXPECT_FALSE(event.mounting);
    343 
    344     ASSERT_EQ(0U, disk_mount_manager_->mount_requests().size());
    345 
    346     volume_manager()->RemoveObserver(&observer);
    347   }
    348 
    349   // External storage is disabled.
    350   {
    351     profile()->GetPrefs()->SetBoolean(prefs::kExternalStorageDisabled, true);
    352 
    353     LoggingObserver observer;
    354     volume_manager()->AddObserver(&observer);
    355 
    356     const bool kHasMedia = true;
    357     const chromeos::disks::DiskMountManager::Disk kMediaDisk(
    358         "device1", "", "", "", "", "", "", "", "", "", "", "",
    359         chromeos::DEVICE_TYPE_UNKNOWN, 0, false, false,
    360         kHasMedia, false, false);
    361     volume_manager()->OnDiskEvent(
    362         chromeos::disks::DiskMountManager::DISK_ADDED, &kMediaDisk);
    363     ASSERT_EQ(1U, observer.events().size());
    364     const LoggingObserver::Event& event = observer.events()[0];
    365     EXPECT_EQ(LoggingObserver::Event::DISK_ADDED, event.type);
    366     EXPECT_EQ("device1", event.device_path);
    367     EXPECT_FALSE(event.mounting);
    368 
    369     ASSERT_EQ(0U, disk_mount_manager_->mount_requests().size());
    370 
    371     volume_manager()->RemoveObserver(&observer);
    372   }
    373 }
    374 
    375 TEST_F(VolumeManagerTest, OnDiskEvent_Removed) {
    376   LoggingObserver observer;
    377   volume_manager()->AddObserver(&observer);
    378 
    379   const chromeos::disks::DiskMountManager::Disk kMountedDisk(
    380       "device1", "mount_path", "", "", "", "", "", "", "", "", "", "",
    381       chromeos::DEVICE_TYPE_UNKNOWN, 0, false, false, false, false, false);
    382   volume_manager()->OnDiskEvent(
    383       chromeos::disks::DiskMountManager::DISK_REMOVED, &kMountedDisk);
    384 
    385   ASSERT_EQ(1U, observer.events().size());
    386   const LoggingObserver::Event& event = observer.events()[0];
    387   EXPECT_EQ(LoggingObserver::Event::DISK_REMOVED, event.type);
    388   EXPECT_EQ("device1", event.device_path);
    389 
    390   ASSERT_EQ(1U, disk_mount_manager_->unmount_requests().size());
    391   const FakeDiskMountManager::UnmountRequest& unmount_request =
    392       disk_mount_manager_->unmount_requests()[0];
    393   EXPECT_EQ("mount_path", unmount_request.mount_path);
    394   EXPECT_EQ(chromeos::UNMOUNT_OPTIONS_LAZY, unmount_request.options);
    395 
    396   volume_manager()->RemoveObserver(&observer);
    397 }
    398 
    399 TEST_F(VolumeManagerTest, OnDiskEvent_RemovedNotMounted) {
    400   LoggingObserver observer;
    401   volume_manager()->AddObserver(&observer);
    402 
    403   const chromeos::disks::DiskMountManager::Disk kNotMountedDisk(
    404       "device1", "", "", "", "", "", "", "", "", "", "", "",
    405       chromeos::DEVICE_TYPE_UNKNOWN, 0, false, false, false, false, false);
    406   volume_manager()->OnDiskEvent(
    407       chromeos::disks::DiskMountManager::DISK_REMOVED, &kNotMountedDisk);
    408 
    409   ASSERT_EQ(1U, observer.events().size());
    410   const LoggingObserver::Event& event = observer.events()[0];
    411   EXPECT_EQ(LoggingObserver::Event::DISK_REMOVED, event.type);
    412   EXPECT_EQ("device1", event.device_path);
    413 
    414   ASSERT_EQ(0U, disk_mount_manager_->unmount_requests().size());
    415 
    416   volume_manager()->RemoveObserver(&observer);
    417 }
    418 
    419 TEST_F(VolumeManagerTest, OnDiskEvent_Changed) {
    420   // Changed event should cause mounting (if possible).
    421   LoggingObserver observer;
    422   volume_manager()->AddObserver(&observer);
    423 
    424   const chromeos::disks::DiskMountManager::Disk kDisk(
    425       "device1", "", "", "", "", "", "", "", "", "", "", "",
    426       chromeos::DEVICE_TYPE_UNKNOWN, 0, false, false, true, false, false);
    427   volume_manager()->OnDiskEvent(
    428       chromeos::disks::DiskMountManager::DISK_CHANGED, &kDisk);
    429 
    430   EXPECT_EQ(1U, observer.events().size());
    431   EXPECT_EQ(1U, disk_mount_manager_->mount_requests().size());
    432   EXPECT_EQ(0U, disk_mount_manager_->unmount_requests().size());
    433 
    434   volume_manager()->RemoveObserver(&observer);
    435 }
    436 
    437 TEST_F(VolumeManagerTest, OnDeviceEvent_Added) {
    438   LoggingObserver observer;
    439   volume_manager()->AddObserver(&observer);
    440 
    441   volume_manager()->OnDeviceEvent(
    442       chromeos::disks::DiskMountManager::DEVICE_ADDED, "device1");
    443 
    444   ASSERT_EQ(1U, observer.events().size());
    445   const LoggingObserver::Event& event = observer.events()[0];
    446   EXPECT_EQ(LoggingObserver::Event::DEVICE_ADDED, event.type);
    447   EXPECT_EQ("device1", event.device_path);
    448 
    449   volume_manager()->RemoveObserver(&observer);
    450 }
    451 
    452 TEST_F(VolumeManagerTest, OnDeviceEvent_Removed) {
    453   LoggingObserver observer;
    454   volume_manager()->AddObserver(&observer);
    455 
    456   volume_manager()->OnDeviceEvent(
    457       chromeos::disks::DiskMountManager::DEVICE_REMOVED, "device1");
    458 
    459   ASSERT_EQ(1U, observer.events().size());
    460   const LoggingObserver::Event& event = observer.events()[0];
    461   EXPECT_EQ(LoggingObserver::Event::DEVICE_REMOVED, event.type);
    462   EXPECT_EQ("device1", event.device_path);
    463 
    464   volume_manager()->RemoveObserver(&observer);
    465 }
    466 
    467 TEST_F(VolumeManagerTest, OnDeviceEvent_Scanned) {
    468   LoggingObserver observer;
    469   volume_manager()->AddObserver(&observer);
    470 
    471   volume_manager()->OnDeviceEvent(
    472       chromeos::disks::DiskMountManager::DEVICE_SCANNED, "device1");
    473 
    474   // SCANNED event is just ignored.
    475   EXPECT_EQ(0U, observer.events().size());
    476 
    477   volume_manager()->RemoveObserver(&observer);
    478 }
    479 
    480 TEST_F(VolumeManagerTest, OnMountEvent_MountingAndUnmounting) {
    481   LoggingObserver observer;
    482   volume_manager()->AddObserver(&observer);
    483 
    484   const chromeos::disks::DiskMountManager::MountPointInfo kMountPoint(
    485       "device1",
    486       "mount1",
    487       chromeos::MOUNT_TYPE_DEVICE,
    488       chromeos::disks::MOUNT_CONDITION_NONE);
    489 
    490   volume_manager()->OnMountEvent(chromeos::disks::DiskMountManager::MOUNTING,
    491                                 chromeos::MOUNT_ERROR_NONE,
    492                                 kMountPoint);
    493 
    494   ASSERT_EQ(1U, observer.events().size());
    495   LoggingObserver::Event event = observer.events()[0];
    496   EXPECT_EQ(LoggingObserver::Event::VOLUME_MOUNTED, event.type);
    497   EXPECT_EQ("device1", event.device_path);
    498   EXPECT_EQ(chromeos::MOUNT_ERROR_NONE, event.mount_error);
    499   EXPECT_FALSE(event.is_remounting);
    500 
    501   volume_manager()->OnMountEvent(chromeos::disks::DiskMountManager::UNMOUNTING,
    502                                 chromeos::MOUNT_ERROR_NONE,
    503                                 kMountPoint);
    504 
    505   ASSERT_EQ(2U, observer.events().size());
    506   event = observer.events()[1];
    507   EXPECT_EQ(LoggingObserver::Event::VOLUME_UNMOUNTED, event.type);
    508   EXPECT_EQ("device1", event.device_path);
    509   EXPECT_EQ(chromeos::MOUNT_ERROR_NONE, event.mount_error);
    510 
    511   volume_manager()->RemoveObserver(&observer);
    512 }
    513 
    514 TEST_F(VolumeManagerTest, OnMountEvent_Remounting) {
    515   scoped_ptr<chromeos::disks::DiskMountManager::Disk> disk(
    516       new chromeos::disks::DiskMountManager::Disk(
    517           "device1", "", "", "", "", "", "", "", "", "", "uuid1", "",
    518           chromeos::DEVICE_TYPE_UNKNOWN, 0,
    519           false, false, false, false, false));
    520   disk_mount_manager_->AddDiskForTest(disk.release());
    521   disk_mount_manager_->MountPath(
    522       "device1", "", "", chromeos::MOUNT_TYPE_DEVICE);
    523 
    524   // Emulate system suspend and then resume.
    525   {
    526     power_manager_client_->SendSuspendImminent();
    527     power_manager_client_->SendSuspendDone();
    528 
    529     // After resume, the device is unmounted and then mounted.
    530     disk_mount_manager_->UnmountPath(
    531         "device1", chromeos::UNMOUNT_OPTIONS_NONE,
    532         chromeos::disks::DiskMountManager::UnmountPathCallback());
    533     disk_mount_manager_->MountPath(
    534         "device1", "", "", chromeos::MOUNT_TYPE_DEVICE);
    535   }
    536 
    537   LoggingObserver observer;
    538   volume_manager()->AddObserver(&observer);
    539 
    540   const chromeos::disks::DiskMountManager::MountPointInfo kMountPoint(
    541       "device1",
    542       "mount1",
    543       chromeos::MOUNT_TYPE_DEVICE,
    544       chromeos::disks::MOUNT_CONDITION_NONE);
    545 
    546   volume_manager()->OnMountEvent(chromeos::disks::DiskMountManager::MOUNTING,
    547                                 chromeos::MOUNT_ERROR_NONE,
    548                                 kMountPoint);
    549 
    550   ASSERT_EQ(1U, observer.events().size());
    551   const LoggingObserver::Event& event = observer.events()[0];
    552   EXPECT_EQ(LoggingObserver::Event::VOLUME_MOUNTED, event.type);
    553   EXPECT_EQ("device1", event.device_path);
    554   EXPECT_EQ(chromeos::MOUNT_ERROR_NONE, event.mount_error);
    555   EXPECT_TRUE(event.is_remounting);
    556 
    557   volume_manager()->RemoveObserver(&observer);
    558 }
    559 
    560 TEST_F(VolumeManagerTest, OnMountEvent_UnmountingWithoutMounting) {
    561   LoggingObserver observer;
    562   volume_manager()->AddObserver(&observer);
    563 
    564   const chromeos::disks::DiskMountManager::MountPointInfo kMountPoint(
    565       "device1",
    566       "mount1",
    567       chromeos::MOUNT_TYPE_DEVICE,
    568       chromeos::disks::MOUNT_CONDITION_NONE);
    569 
    570   volume_manager()->OnMountEvent(chromeos::disks::DiskMountManager::UNMOUNTING,
    571                                 chromeos::MOUNT_ERROR_NONE,
    572                                 kMountPoint);
    573 
    574   // Unmount event for a disk not mounted in this manager is not reported.
    575   ASSERT_EQ(0U, observer.events().size());
    576 
    577   volume_manager()->RemoveObserver(&observer);
    578 }
    579 
    580 TEST_F(VolumeManagerTest, OnFormatEvent_Started) {
    581   LoggingObserver observer;
    582   volume_manager()->AddObserver(&observer);
    583 
    584   volume_manager()->OnFormatEvent(
    585       chromeos::disks::DiskMountManager::FORMAT_STARTED,
    586       chromeos::FORMAT_ERROR_NONE,
    587       "device1");
    588 
    589   ASSERT_EQ(1U, observer.events().size());
    590   const LoggingObserver::Event& event = observer.events()[0];
    591   EXPECT_EQ(LoggingObserver::Event::FORMAT_STARTED, event.type);
    592   EXPECT_EQ("device1", event.device_path);
    593   EXPECT_TRUE(event.success);
    594 
    595   volume_manager()->RemoveObserver(&observer);
    596 }
    597 
    598 TEST_F(VolumeManagerTest, OnFormatEvent_StartFailed) {
    599   LoggingObserver observer;
    600   volume_manager()->AddObserver(&observer);
    601 
    602   volume_manager()->OnFormatEvent(
    603       chromeos::disks::DiskMountManager::FORMAT_STARTED,
    604       chromeos::FORMAT_ERROR_UNKNOWN,
    605       "device1");
    606 
    607   ASSERT_EQ(1U, observer.events().size());
    608   const LoggingObserver::Event& event = observer.events()[0];
    609   EXPECT_EQ(LoggingObserver::Event::FORMAT_STARTED, event.type);
    610   EXPECT_EQ("device1", event.device_path);
    611   EXPECT_FALSE(event.success);
    612 
    613   volume_manager()->RemoveObserver(&observer);
    614 }
    615 
    616 TEST_F(VolumeManagerTest, OnFormatEvent_Completed) {
    617   LoggingObserver observer;
    618   volume_manager()->AddObserver(&observer);
    619 
    620   volume_manager()->OnFormatEvent(
    621       chromeos::disks::DiskMountManager::FORMAT_COMPLETED,
    622       chromeos::FORMAT_ERROR_NONE,
    623       "device1");
    624 
    625   ASSERT_EQ(1U, observer.events().size());
    626   const LoggingObserver::Event& event = observer.events()[0];
    627   EXPECT_EQ(LoggingObserver::Event::FORMAT_COMPLETED, event.type);
    628   EXPECT_EQ("device1", event.device_path);
    629   EXPECT_TRUE(event.success);
    630 
    631   // When "format" is successfully done, VolumeManager requests to mount it.
    632   ASSERT_EQ(1U, disk_mount_manager_->mount_requests().size());
    633   const FakeDiskMountManager::MountRequest& mount_request =
    634       disk_mount_manager_->mount_requests()[0];
    635   EXPECT_EQ("device1", mount_request.source_path);
    636   EXPECT_EQ("", mount_request.source_format);
    637   EXPECT_EQ("", mount_request.mount_label);
    638   EXPECT_EQ(chromeos::MOUNT_TYPE_DEVICE, mount_request.type);
    639 
    640   volume_manager()->RemoveObserver(&observer);
    641 }
    642 
    643 TEST_F(VolumeManagerTest, OnFormatEvent_CompletedFailed) {
    644   LoggingObserver observer;
    645   volume_manager()->AddObserver(&observer);
    646 
    647   volume_manager()->OnFormatEvent(
    648       chromeos::disks::DiskMountManager::FORMAT_COMPLETED,
    649       chromeos::FORMAT_ERROR_UNKNOWN,
    650       "device1");
    651 
    652   ASSERT_EQ(1U, observer.events().size());
    653   const LoggingObserver::Event& event = observer.events()[0];
    654   EXPECT_EQ(LoggingObserver::Event::FORMAT_COMPLETED, event.type);
    655   EXPECT_EQ("device1", event.device_path);
    656   EXPECT_FALSE(event.success);
    657 
    658   EXPECT_EQ(0U, disk_mount_manager_->mount_requests().size());
    659 
    660   volume_manager()->RemoveObserver(&observer);
    661 }
    662 
    663 TEST_F(VolumeManagerTest, OnExternalStorageDisabledChanged) {
    664   // Here create two mount points.
    665   disk_mount_manager_->MountPath(
    666       "mount1", "", "", chromeos::MOUNT_TYPE_DEVICE);
    667   disk_mount_manager_->MountPath(
    668       "mount2", "", "", chromeos::MOUNT_TYPE_DEVICE);
    669 
    670   // Initially, there are two mount points.
    671   ASSERT_EQ(2U, disk_mount_manager_->mount_points().size());
    672   ASSERT_EQ(0U, disk_mount_manager_->unmount_requests().size());
    673 
    674   // Emulate to set kExternalStorageDisabled to false.
    675   profile()->GetPrefs()->SetBoolean(prefs::kExternalStorageDisabled, false);
    676   volume_manager()->OnExternalStorageDisabledChanged();
    677 
    678   // Expect no effects.
    679   EXPECT_EQ(2U, disk_mount_manager_->mount_points().size());
    680   EXPECT_EQ(0U, disk_mount_manager_->unmount_requests().size());
    681 
    682   // Emulate to set kExternalStorageDisabled to true.
    683   profile()->GetPrefs()->SetBoolean(prefs::kExternalStorageDisabled, true);
    684   volume_manager()->OnExternalStorageDisabledChanged();
    685 
    686   // The all mount points should be unmounted.
    687   EXPECT_EQ(0U, disk_mount_manager_->mount_points().size());
    688 
    689   EXPECT_EQ(2U, disk_mount_manager_->unmount_requests().size());
    690   const FakeDiskMountManager::UnmountRequest& unmount_request1 =
    691       disk_mount_manager_->unmount_requests()[0];
    692   EXPECT_EQ("mount1", unmount_request1.mount_path);
    693 
    694   const FakeDiskMountManager::UnmountRequest& unmount_request2 =
    695       disk_mount_manager_->unmount_requests()[1];
    696   EXPECT_EQ("mount2", unmount_request2.mount_path);
    697 }
    698 
    699 TEST_F(VolumeManagerTest, ExternalStorageDisabledPolicyMultiProfile) {
    700   ProfileEnvironment secondary(power_manager_client_.get(),
    701                                disk_mount_manager_.get());
    702   volume_manager()->Initialize();
    703   secondary.volume_manager()->Initialize();
    704 
    705   // Simulates the case that the main profile has kExternalStorageDisabled set
    706   // as false, and the secondary profile has the config set to true.
    707   profile()->GetPrefs()->SetBoolean(prefs::kExternalStorageDisabled, false);
    708   secondary.profile()->GetPrefs()->SetBoolean(prefs::kExternalStorageDisabled,
    709                                               true);
    710 
    711   LoggingObserver main_observer, secondary_observer;
    712   volume_manager()->AddObserver(&main_observer);
    713   secondary.volume_manager()->AddObserver(&secondary_observer);
    714 
    715   // Add 1 disk.
    716   const chromeos::disks::DiskMountManager::Disk kMediaDisk(
    717       "device1", "", "", "", "", "", "", "", "", "", "", "",
    718       chromeos::DEVICE_TYPE_UNKNOWN, 0, false, false, true, false, false);
    719   volume_manager()->OnDiskEvent(
    720       chromeos::disks::DiskMountManager::DISK_ADDED, &kMediaDisk);
    721   secondary.volume_manager()->OnDiskEvent(
    722       chromeos::disks::DiskMountManager::DISK_ADDED, &kMediaDisk);
    723 
    724   // The profile with external storage enabled should have mounted the volume.
    725   bool has_volume_mounted = false;
    726   for (size_t i = 0; i < main_observer.events().size(); ++i) {
    727     if (main_observer.events()[i].type ==
    728         LoggingObserver::Event::VOLUME_MOUNTED)
    729       has_volume_mounted = true;
    730   }
    731   EXPECT_TRUE(has_volume_mounted);
    732 
    733   // The other profiles with external storage disabled should have not.
    734   has_volume_mounted = false;
    735   for (size_t i = 0; i < secondary_observer.events().size(); ++i) {
    736     if (secondary_observer.events()[i].type ==
    737         LoggingObserver::Event::VOLUME_MOUNTED)
    738       has_volume_mounted = true;
    739   }
    740   EXPECT_FALSE(has_volume_mounted);
    741 
    742   volume_manager()->RemoveObserver(&main_observer);
    743   secondary.volume_manager()->RemoveObserver(&secondary_observer);
    744 }
    745 
    746 TEST_F(VolumeManagerTest, GetVolumeInfoList) {
    747   volume_manager()->Initialize();  // Adds "Downloads"
    748   std::vector<VolumeInfo> info_list = volume_manager()->GetVolumeInfoList();
    749   ASSERT_EQ(1u, info_list.size());
    750   EXPECT_EQ("downloads:Downloads", info_list[0].volume_id);
    751   EXPECT_EQ(VOLUME_TYPE_DOWNLOADS_DIRECTORY, info_list[0].type);
    752 }
    753 
    754 TEST_F(VolumeManagerTest, FindVolumeInfoById) {
    755   volume_manager()->Initialize();  // Adds "Downloads"
    756   VolumeInfo volume_info;
    757   ASSERT_FALSE(volume_manager()->FindVolumeInfoById(
    758       "nonexistent", &volume_info));
    759   ASSERT_TRUE(volume_manager()->FindVolumeInfoById(
    760       "downloads:Downloads", &volume_info));
    761   EXPECT_EQ("downloads:Downloads", volume_info.volume_id);
    762   EXPECT_EQ(VOLUME_TYPE_DOWNLOADS_DIRECTORY, volume_info.type);
    763 }
    764 
    765 TEST_F(VolumeManagerTest, ArchiveSourceFiltering) {
    766   LoggingObserver observer;
    767   volume_manager()->AddObserver(&observer);
    768 
    769   // Mount a USB stick.
    770   volume_manager()->OnMountEvent(
    771       chromeos::disks::DiskMountManager::MOUNTING,
    772       chromeos::MOUNT_ERROR_NONE,
    773       chromeos::disks::DiskMountManager::MountPointInfo(
    774           "/removable/usb",
    775           "/removable/usb",
    776           chromeos::MOUNT_TYPE_DEVICE,
    777           chromeos::disks::MOUNT_CONDITION_NONE));
    778 
    779   // Mount a zip archive in the stick.
    780   volume_manager()->OnMountEvent(
    781       chromeos::disks::DiskMountManager::MOUNTING,
    782       chromeos::MOUNT_ERROR_NONE,
    783       chromeos::disks::DiskMountManager::MountPointInfo(
    784           "/removable/usb/1.zip",
    785           "/archive/1",
    786           chromeos::MOUNT_TYPE_ARCHIVE,
    787           chromeos::disks::MOUNT_CONDITION_NONE));
    788   VolumeInfo volume_info;
    789   ASSERT_TRUE(volume_manager()->FindVolumeInfoById("archive:1", &volume_info));
    790   EXPECT_EQ("/archive/1", volume_info.mount_path.AsUTF8Unsafe());
    791   EXPECT_EQ(2u, observer.events().size());
    792 
    793   // Mount a zip archive in the previous zip archive.
    794   volume_manager()->OnMountEvent(
    795       chromeos::disks::DiskMountManager::MOUNTING,
    796       chromeos::MOUNT_ERROR_NONE,
    797       chromeos::disks::DiskMountManager::MountPointInfo(
    798           "/archive/1/2.zip",
    799           "/archive/2",
    800           chromeos::MOUNT_TYPE_ARCHIVE,
    801           chromeos::disks::MOUNT_CONDITION_NONE));
    802   ASSERT_TRUE(volume_manager()->FindVolumeInfoById("archive:2", &volume_info));
    803   EXPECT_EQ("/archive/2", volume_info.mount_path.AsUTF8Unsafe());
    804   EXPECT_EQ(3u, observer.events().size());
    805 
    806   // A zip file is mounted from other profile. It must be ignored in the current
    807   // VolumeManager.
    808   volume_manager()->OnMountEvent(
    809       chromeos::disks::DiskMountManager::MOUNTING,
    810       chromeos::MOUNT_ERROR_NONE,
    811       chromeos::disks::DiskMountManager::MountPointInfo(
    812           "/other/profile/drive/folder/3.zip",
    813           "/archive/3",
    814           chromeos::MOUNT_TYPE_ARCHIVE,
    815           chromeos::disks::MOUNT_CONDITION_NONE));
    816   EXPECT_FALSE(volume_manager()->FindVolumeInfoById("archive:3", &volume_info));
    817   EXPECT_EQ(3u, observer.events().size());
    818 }
    819 
    820 TEST_F(VolumeManagerTest, HardUnplugged) {
    821   LoggingObserver observer;
    822   volume_manager()->AddObserver(&observer);
    823   volume_manager()->OnDeviceEvent(
    824       chromeos::disks::DiskMountManager::DEVICE_REMOVED, "device1");
    825 
    826   // Disk that has a mount path is removed.
    827   chromeos::disks::DiskMountManager::Disk disk("device1",
    828                                                "/mount/path",
    829                                                "",
    830                                                "",
    831                                                "",
    832                                                "",
    833                                                "",
    834                                                "",
    835                                                "",
    836                                                "",
    837                                                "uuid1",
    838                                                "device1",
    839                                                chromeos::DEVICE_TYPE_UNKNOWN,
    840                                                0,
    841                                                false,
    842                                                false,
    843                                                false,
    844                                                false,
    845                                                false);
    846   disk_mount_manager_->InvokeDiskEventForTest(
    847       chromeos::disks::DiskMountManager::DISK_REMOVED, &disk);
    848 
    849   volume_manager()->OnDeviceEvent(
    850       chromeos::disks::DiskMountManager::DEVICE_REMOVED, "device1");
    851 
    852   EXPECT_EQ(2u, observer.events().size());
    853   EXPECT_EQ(LoggingObserver::Event::DEVICE_REMOVED, observer.events()[0].type);
    854   EXPECT_EQ(LoggingObserver::Event::DEVICE_REMOVED, observer.events()[1].type);
    855   EXPECT_FALSE(observer.events()[0].hard_unplugged);
    856   EXPECT_TRUE(observer.events()[1].hard_unplugged);
    857 }
    858 
    859 TEST_F(VolumeManagerTest, MTPPlugAndUnplug) {
    860   LoggingObserver observer;
    861   volume_manager()->AddObserver(&observer);
    862 
    863   storage_monitor::StorageInfo info(
    864       storage_monitor::StorageInfo::MakeDeviceId(
    865           storage_monitor::StorageInfo::MTP_OR_PTP, "dummy-device-id"),
    866       FILE_PATH_LITERAL("/dummy/device/location"),
    867       base::UTF8ToUTF16("label"),
    868       base::UTF8ToUTF16("vendor"),
    869       base::UTF8ToUTF16("model"),
    870       12345 /* size */);
    871 
    872   storage_monitor::StorageInfo non_mtp_info(
    873       storage_monitor::StorageInfo::MakeDeviceId(
    874           storage_monitor::StorageInfo::IPHOTO, "dummy-device-id2"),
    875       FILE_PATH_LITERAL("/dummy/device/location2"),
    876       base::UTF8ToUTF16("label2"),
    877       base::UTF8ToUTF16("vendor2"),
    878       base::UTF8ToUTF16("model2"),
    879       12345 /* size */);
    880 
    881   // Attach
    882   volume_manager()->OnRemovableStorageAttached(info);
    883   ASSERT_EQ(1u, observer.events().size());
    884   EXPECT_EQ(LoggingObserver::Event::VOLUME_MOUNTED, observer.events()[0].type);
    885 
    886   VolumeInfo volume_info;
    887   ASSERT_TRUE(volume_manager()->FindVolumeInfoById("mtp:model", &volume_info));
    888   EXPECT_EQ(VOLUME_TYPE_MTP, volume_info.type);
    889 
    890   // Non MTP events from storage monitor are ignored.
    891   volume_manager()->OnRemovableStorageAttached(non_mtp_info);
    892   EXPECT_EQ(1u, observer.events().size());
    893 
    894   // Detach
    895   volume_manager()->OnRemovableStorageDetached(info);
    896   ASSERT_EQ(2u, observer.events().size());
    897   EXPECT_EQ(LoggingObserver::Event::VOLUME_UNMOUNTED,
    898             observer.events()[1].type);
    899 
    900   EXPECT_FALSE(volume_manager()->FindVolumeInfoById("mtp:model", &volume_info));
    901 }
    902 
    903 }  // namespace file_manager
    904