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 VOLUME_MOUNTED and VOLUME_UNMOUNTED.
     51     chromeos::MountError mount_error;
     52 
     53     // Available on FORMAT_STARTED and FORMAT_COMPLETED.
     54     bool success;
     55   };
     56 
     57   LoggingObserver() {}
     58   virtual ~LoggingObserver() {}
     59 
     60   const std::vector<Event>& events() const { return events_; }
     61 
     62   // VolumeManagerObserver overrides.
     63   virtual void OnDiskAdded(const chromeos::disks::DiskMountManager::Disk& disk,
     64                            bool mounting) OVERRIDE {
     65     Event event;
     66     event.type = Event::DISK_ADDED;
     67     event.device_path = disk.device_path();  // Keep only device_path.
     68     event.mounting = mounting;
     69     events_.push_back(event);
     70   }
     71 
     72   virtual void OnDiskRemoved(
     73       const chromeos::disks::DiskMountManager::Disk& disk) OVERRIDE {
     74     Event event;
     75     event.type = Event::DISK_REMOVED;
     76     event.device_path = disk.device_path();  // Keep only device_path.
     77     events_.push_back(event);
     78   }
     79 
     80   virtual void OnDeviceAdded(const std::string& device_path) OVERRIDE {
     81     Event event;
     82     event.type = Event::DEVICE_ADDED;
     83     event.device_path = device_path;
     84     events_.push_back(event);
     85   }
     86 
     87   virtual void OnDeviceRemoved(const std::string& device_path) OVERRIDE {
     88     Event event;
     89     event.type = Event::DEVICE_REMOVED;
     90     event.device_path = device_path;
     91     events_.push_back(event);
     92   }
     93 
     94   virtual void OnVolumeMounted(chromeos::MountError error_code,
     95                                const VolumeInfo& volume_info) OVERRIDE {
     96     Event event;
     97     event.type = Event::VOLUME_MOUNTED;
     98     event.device_path = volume_info.source_path.AsUTF8Unsafe();
     99     event.mount_error = error_code;
    100     events_.push_back(event);
    101   }
    102 
    103   virtual void OnVolumeUnmounted(chromeos::MountError error_code,
    104                                  const VolumeInfo& volume_info) OVERRIDE {
    105     Event event;
    106     event.type = Event::VOLUME_UNMOUNTED;
    107     event.device_path = volume_info.source_path.AsUTF8Unsafe();
    108     event.mount_error = error_code;
    109     events_.push_back(event);
    110   }
    111 
    112   virtual void OnFormatStarted(
    113       const std::string& device_path, bool success) OVERRIDE {
    114     Event event;
    115     event.type = Event::FORMAT_STARTED;
    116     event.device_path = device_path;
    117     event.success = success;
    118     events_.push_back(event);
    119   }
    120 
    121   virtual void OnFormatCompleted(
    122       const std::string& device_path, bool success) OVERRIDE {
    123     Event event;
    124     event.type = Event::FORMAT_COMPLETED;
    125     event.device_path = device_path;
    126     event.success = success;
    127     events_.push_back(event);
    128   }
    129 
    130  private:
    131   std::vector<Event> events_;
    132 
    133   DISALLOW_COPY_AND_ASSIGN(LoggingObserver);
    134 };
    135 
    136 }  // namespace
    137 
    138 class VolumeManagerTest : public testing::Test {
    139  protected:
    140   // Helper class that contains per-profile objects.
    141   class ProfileEnvironment {
    142    public:
    143     ProfileEnvironment(chromeos::PowerManagerClient* power_manager_client,
    144                        chromeos::disks::DiskMountManager* disk_manager)
    145         : profile_(new TestingProfile),
    146           extension_registry_(
    147               new extensions::ExtensionRegistry(profile_.get())),
    148           file_system_provider_service_(
    149               new chromeos::file_system_provider::Service(
    150                   profile_.get(),
    151                   extension_registry_.get())),
    152           volume_manager_(
    153               new VolumeManager(profile_.get(),
    154                                 NULL,  // DriveIntegrationService
    155                                 power_manager_client,
    156                                 disk_manager,
    157                                 file_system_provider_service_.get())) {
    158       file_system_provider_service_->SetFileSystemFactoryForTesting(base::Bind(
    159           &chromeos::file_system_provider::FakeProvidedFileSystem::Create));
    160     }
    161 
    162     Profile* profile() const { return profile_.get(); }
    163     VolumeManager* volume_manager() const { return volume_manager_.get(); }
    164 
    165    private:
    166     scoped_ptr<TestingProfile> profile_;
    167     scoped_ptr<extensions::ExtensionRegistry> extension_registry_;
    168     scoped_ptr<chromeos::file_system_provider::Service>
    169         file_system_provider_service_;
    170     scoped_ptr<VolumeManager> volume_manager_;
    171   };
    172 
    173   virtual void SetUp() OVERRIDE {
    174     power_manager_client_.reset(new chromeos::FakePowerManagerClient);
    175     disk_mount_manager_.reset(new FakeDiskMountManager);
    176     main_profile_.reset(new ProfileEnvironment(power_manager_client_.get(),
    177                                                disk_mount_manager_.get()));
    178   }
    179 
    180   Profile* profile() const { return main_profile_->profile(); }
    181   VolumeManager* volume_manager() const {
    182     return main_profile_->volume_manager();
    183   }
    184 
    185   content::TestBrowserThreadBundle thread_bundle_;
    186   scoped_ptr<chromeos::FakePowerManagerClient> power_manager_client_;
    187   scoped_ptr<FakeDiskMountManager> disk_mount_manager_;
    188   scoped_ptr<ProfileEnvironment> main_profile_;
    189 };
    190 
    191 TEST_F(VolumeManagerTest, OnDriveFileSystemMountAndUnmount) {
    192   LoggingObserver observer;
    193   volume_manager()->AddObserver(&observer);
    194 
    195   volume_manager()->OnFileSystemMounted();
    196 
    197   ASSERT_EQ(1U, observer.events().size());
    198   LoggingObserver::Event event = observer.events()[0];
    199   EXPECT_EQ(LoggingObserver::Event::VOLUME_MOUNTED, event.type);
    200   EXPECT_EQ(drive::util::GetDriveMountPointPath(profile()).AsUTF8Unsafe(),
    201             event.device_path);
    202   EXPECT_EQ(chromeos::MOUNT_ERROR_NONE, event.mount_error);
    203 
    204   volume_manager()->OnFileSystemBeingUnmounted();
    205 
    206   ASSERT_EQ(2U, observer.events().size());
    207   event = observer.events()[1];
    208   EXPECT_EQ(LoggingObserver::Event::VOLUME_UNMOUNTED, event.type);
    209   EXPECT_EQ(drive::util::GetDriveMountPointPath(profile()).AsUTF8Unsafe(),
    210             event.device_path);
    211   EXPECT_EQ(chromeos::MOUNT_ERROR_NONE, event.mount_error);
    212 
    213   volume_manager()->RemoveObserver(&observer);
    214 }
    215 
    216 TEST_F(VolumeManagerTest, OnDriveFileSystemUnmountWithoutMount) {
    217   LoggingObserver observer;
    218   volume_manager()->AddObserver(&observer);
    219   volume_manager()->OnFileSystemBeingUnmounted();
    220 
    221   // Unmount event for non-mounted volume is not reported.
    222   ASSERT_EQ(0U, observer.events().size());
    223   volume_manager()->RemoveObserver(&observer);
    224 }
    225 
    226 TEST_F(VolumeManagerTest, OnDiskEvent_Hidden) {
    227   LoggingObserver observer;
    228   volume_manager()->AddObserver(&observer);
    229 
    230   const bool kIsHidden = true;
    231   const chromeos::disks::DiskMountManager::Disk kDisk(
    232       "device1", "", "", "", "", "", "", "", "", "", "", "",
    233       chromeos::DEVICE_TYPE_UNKNOWN, 0, false, false, false, false, false,
    234       kIsHidden);
    235 
    236   volume_manager()->OnDiskEvent(
    237       chromeos::disks::DiskMountManager::DISK_ADDED, &kDisk);
    238   EXPECT_EQ(0U, observer.events().size());
    239 
    240   volume_manager()->OnDiskEvent(
    241       chromeos::disks::DiskMountManager::DISK_REMOVED, &kDisk);
    242   EXPECT_EQ(0U, observer.events().size());
    243 
    244   volume_manager()->OnDiskEvent(
    245       chromeos::disks::DiskMountManager::DISK_CHANGED, &kDisk);
    246   EXPECT_EQ(0U, observer.events().size());
    247 
    248   volume_manager()->RemoveObserver(&observer);
    249 }
    250 
    251 TEST_F(VolumeManagerTest, OnDiskEvent_Added) {
    252   // Enable external storage.
    253   profile()->GetPrefs()->SetBoolean(prefs::kExternalStorageDisabled, false);
    254 
    255   LoggingObserver observer;
    256   volume_manager()->AddObserver(&observer);
    257 
    258   const chromeos::disks::DiskMountManager::Disk kEmptyDevicePathDisk(
    259       "",  // empty device path.
    260       "", "", "", "", "", "", "", "", "", "", "",
    261       chromeos::DEVICE_TYPE_UNKNOWN, 0, false, false, false, false, false,
    262       false);
    263   volume_manager()->OnDiskEvent(
    264       chromeos::disks::DiskMountManager::DISK_ADDED, &kEmptyDevicePathDisk);
    265   EXPECT_EQ(0U, observer.events().size());
    266 
    267   const bool kHasMedia = true;
    268   const chromeos::disks::DiskMountManager::Disk kMediaDisk(
    269       "device1", "", "", "", "", "", "", "", "", "", "", "",
    270       chromeos::DEVICE_TYPE_UNKNOWN, 0, false, false, kHasMedia, false, false,
    271       false);
    272   volume_manager()->OnDiskEvent(
    273       chromeos::disks::DiskMountManager::DISK_ADDED, &kMediaDisk);
    274   ASSERT_EQ(1U, observer.events().size());
    275   const LoggingObserver::Event& event = observer.events()[0];
    276   EXPECT_EQ(LoggingObserver::Event::DISK_ADDED, event.type);
    277   EXPECT_EQ("device1", event.device_path);
    278   EXPECT_TRUE(event.mounting);
    279 
    280   ASSERT_EQ(1U, disk_mount_manager_->mount_requests().size());
    281   const FakeDiskMountManager::MountRequest& mount_request =
    282       disk_mount_manager_->mount_requests()[0];
    283   EXPECT_EQ("device1", mount_request.source_path);
    284   EXPECT_EQ("", mount_request.source_format);
    285   EXPECT_EQ("", mount_request.mount_label);
    286   EXPECT_EQ(chromeos::MOUNT_TYPE_DEVICE, mount_request.type);
    287 
    288   volume_manager()->RemoveObserver(&observer);
    289 }
    290 
    291 TEST_F(VolumeManagerTest, OnDiskEvent_AddedNonMounting) {
    292   // Enable external storage.
    293   profile()->GetPrefs()->SetBoolean(prefs::kExternalStorageDisabled, false);
    294 
    295   // Device which is already mounted.
    296   {
    297     LoggingObserver observer;
    298     volume_manager()->AddObserver(&observer);
    299 
    300     const bool kHasMedia = true;
    301     const chromeos::disks::DiskMountManager::Disk kMountedMediaDisk(
    302         "device1", "mounted", "", "", "", "", "", "", "", "", "", "",
    303         chromeos::DEVICE_TYPE_UNKNOWN, 0, false, false,
    304         kHasMedia, false, false, false);
    305     volume_manager()->OnDiskEvent(
    306         chromeos::disks::DiskMountManager::DISK_ADDED, &kMountedMediaDisk);
    307     ASSERT_EQ(1U, observer.events().size());
    308     const LoggingObserver::Event& event = observer.events()[0];
    309     EXPECT_EQ(LoggingObserver::Event::DISK_ADDED, event.type);
    310     EXPECT_EQ("device1", event.device_path);
    311     EXPECT_FALSE(event.mounting);
    312 
    313     ASSERT_EQ(0U, disk_mount_manager_->mount_requests().size());
    314 
    315     volume_manager()->RemoveObserver(&observer);
    316   }
    317 
    318   // Device without media.
    319   {
    320     LoggingObserver observer;
    321     volume_manager()->AddObserver(&observer);
    322 
    323     const bool kWithoutMedia = false;
    324     const chromeos::disks::DiskMountManager::Disk kNoMediaDisk(
    325         "device1", "", "", "", "", "", "", "", "", "", "", "",
    326         chromeos::DEVICE_TYPE_UNKNOWN, 0, false, false,
    327         kWithoutMedia, false, false, false);
    328     volume_manager()->OnDiskEvent(
    329         chromeos::disks::DiskMountManager::DISK_ADDED, &kNoMediaDisk);
    330     ASSERT_EQ(1U, observer.events().size());
    331     const LoggingObserver::Event& event = observer.events()[0];
    332     EXPECT_EQ(LoggingObserver::Event::DISK_ADDED, event.type);
    333     EXPECT_EQ("device1", event.device_path);
    334     EXPECT_FALSE(event.mounting);
    335 
    336     ASSERT_EQ(0U, disk_mount_manager_->mount_requests().size());
    337 
    338     volume_manager()->RemoveObserver(&observer);
    339   }
    340 
    341   // External storage is disabled.
    342   {
    343     profile()->GetPrefs()->SetBoolean(prefs::kExternalStorageDisabled, true);
    344 
    345     LoggingObserver observer;
    346     volume_manager()->AddObserver(&observer);
    347 
    348     const bool kHasMedia = true;
    349     const chromeos::disks::DiskMountManager::Disk kMediaDisk(
    350         "device1", "", "", "", "", "", "", "", "", "", "", "",
    351         chromeos::DEVICE_TYPE_UNKNOWN, 0, false, false,
    352         kHasMedia, false, false, false);
    353     volume_manager()->OnDiskEvent(
    354         chromeos::disks::DiskMountManager::DISK_ADDED, &kMediaDisk);
    355     ASSERT_EQ(1U, observer.events().size());
    356     const LoggingObserver::Event& event = observer.events()[0];
    357     EXPECT_EQ(LoggingObserver::Event::DISK_ADDED, event.type);
    358     EXPECT_EQ("device1", event.device_path);
    359     EXPECT_FALSE(event.mounting);
    360 
    361     ASSERT_EQ(0U, disk_mount_manager_->mount_requests().size());
    362 
    363     volume_manager()->RemoveObserver(&observer);
    364   }
    365 }
    366 
    367 TEST_F(VolumeManagerTest, OnDiskEvent_Removed) {
    368   LoggingObserver observer;
    369   volume_manager()->AddObserver(&observer);
    370 
    371   const chromeos::disks::DiskMountManager::Disk kMountedDisk(
    372       "device1", "mount_path", "", "", "", "", "", "", "", "", "", "",
    373       chromeos::DEVICE_TYPE_UNKNOWN, 0, false, false, false, false, false,
    374       false);
    375   volume_manager()->OnDiskEvent(
    376       chromeos::disks::DiskMountManager::DISK_REMOVED, &kMountedDisk);
    377 
    378   ASSERT_EQ(1U, observer.events().size());
    379   const LoggingObserver::Event& event = observer.events()[0];
    380   EXPECT_EQ(LoggingObserver::Event::DISK_REMOVED, event.type);
    381   EXPECT_EQ("device1", event.device_path);
    382 
    383   ASSERT_EQ(1U, disk_mount_manager_->unmount_requests().size());
    384   const FakeDiskMountManager::UnmountRequest& unmount_request =
    385       disk_mount_manager_->unmount_requests()[0];
    386   EXPECT_EQ("mount_path", unmount_request.mount_path);
    387   EXPECT_EQ(chromeos::UNMOUNT_OPTIONS_LAZY, unmount_request.options);
    388 
    389   volume_manager()->RemoveObserver(&observer);
    390 }
    391 
    392 TEST_F(VolumeManagerTest, OnDiskEvent_RemovedNotMounted) {
    393   LoggingObserver observer;
    394   volume_manager()->AddObserver(&observer);
    395 
    396   const chromeos::disks::DiskMountManager::Disk kNotMountedDisk(
    397       "device1", "", "", "", "", "", "", "", "", "", "", "",
    398       chromeos::DEVICE_TYPE_UNKNOWN, 0, false, false, false, false, false,
    399       false);
    400   volume_manager()->OnDiskEvent(
    401       chromeos::disks::DiskMountManager::DISK_REMOVED, &kNotMountedDisk);
    402 
    403   ASSERT_EQ(1U, observer.events().size());
    404   const LoggingObserver::Event& event = observer.events()[0];
    405   EXPECT_EQ(LoggingObserver::Event::DISK_REMOVED, event.type);
    406   EXPECT_EQ("device1", event.device_path);
    407 
    408   ASSERT_EQ(0U, disk_mount_manager_->unmount_requests().size());
    409 
    410   volume_manager()->RemoveObserver(&observer);
    411 }
    412 
    413 TEST_F(VolumeManagerTest, OnDiskEvent_Changed) {
    414   // Changed event should cause mounting (if possible).
    415   LoggingObserver observer;
    416   volume_manager()->AddObserver(&observer);
    417 
    418   const chromeos::disks::DiskMountManager::Disk kDisk(
    419       "device1", "", "", "", "", "", "", "", "", "", "", "",
    420       chromeos::DEVICE_TYPE_UNKNOWN, 0, false, false, true, false, false,
    421       false);
    422   volume_manager()->OnDiskEvent(
    423       chromeos::disks::DiskMountManager::DISK_CHANGED, &kDisk);
    424 
    425   EXPECT_EQ(1U, observer.events().size());
    426   EXPECT_EQ(1U, disk_mount_manager_->mount_requests().size());
    427   EXPECT_EQ(0U, disk_mount_manager_->unmount_requests().size());
    428 
    429   volume_manager()->RemoveObserver(&observer);
    430 }
    431 
    432 TEST_F(VolumeManagerTest, OnDeviceEvent_Added) {
    433   LoggingObserver observer;
    434   volume_manager()->AddObserver(&observer);
    435 
    436   volume_manager()->OnDeviceEvent(
    437       chromeos::disks::DiskMountManager::DEVICE_ADDED, "device1");
    438 
    439   ASSERT_EQ(1U, observer.events().size());
    440   const LoggingObserver::Event& event = observer.events()[0];
    441   EXPECT_EQ(LoggingObserver::Event::DEVICE_ADDED, event.type);
    442   EXPECT_EQ("device1", event.device_path);
    443 
    444   volume_manager()->RemoveObserver(&observer);
    445 }
    446 
    447 TEST_F(VolumeManagerTest, OnDeviceEvent_Removed) {
    448   LoggingObserver observer;
    449   volume_manager()->AddObserver(&observer);
    450 
    451   volume_manager()->OnDeviceEvent(
    452       chromeos::disks::DiskMountManager::DEVICE_REMOVED, "device1");
    453 
    454   ASSERT_EQ(1U, observer.events().size());
    455   const LoggingObserver::Event& event = observer.events()[0];
    456   EXPECT_EQ(LoggingObserver::Event::DEVICE_REMOVED, event.type);
    457   EXPECT_EQ("device1", event.device_path);
    458 
    459   volume_manager()->RemoveObserver(&observer);
    460 }
    461 
    462 TEST_F(VolumeManagerTest, OnDeviceEvent_Scanned) {
    463   LoggingObserver observer;
    464   volume_manager()->AddObserver(&observer);
    465 
    466   volume_manager()->OnDeviceEvent(
    467       chromeos::disks::DiskMountManager::DEVICE_SCANNED, "device1");
    468 
    469   // SCANNED event is just ignored.
    470   EXPECT_EQ(0U, observer.events().size());
    471 
    472   volume_manager()->RemoveObserver(&observer);
    473 }
    474 
    475 TEST_F(VolumeManagerTest, OnMountEvent_MountingAndUnmounting) {
    476   LoggingObserver observer;
    477   volume_manager()->AddObserver(&observer);
    478 
    479   const chromeos::disks::DiskMountManager::MountPointInfo kMountPoint(
    480       "device1",
    481       "mount1",
    482       chromeos::MOUNT_TYPE_DEVICE,
    483       chromeos::disks::MOUNT_CONDITION_NONE);
    484 
    485   volume_manager()->OnMountEvent(chromeos::disks::DiskMountManager::MOUNTING,
    486                                 chromeos::MOUNT_ERROR_NONE,
    487                                 kMountPoint);
    488 
    489   ASSERT_EQ(1U, observer.events().size());
    490   LoggingObserver::Event event = observer.events()[0];
    491   EXPECT_EQ(LoggingObserver::Event::VOLUME_MOUNTED, event.type);
    492   EXPECT_EQ("device1", event.device_path);
    493   EXPECT_EQ(chromeos::MOUNT_ERROR_NONE, event.mount_error);
    494 
    495   volume_manager()->OnMountEvent(chromeos::disks::DiskMountManager::UNMOUNTING,
    496                                 chromeos::MOUNT_ERROR_NONE,
    497                                 kMountPoint);
    498 
    499   ASSERT_EQ(2U, observer.events().size());
    500   event = observer.events()[1];
    501   EXPECT_EQ(LoggingObserver::Event::VOLUME_UNMOUNTED, event.type);
    502   EXPECT_EQ("device1", event.device_path);
    503   EXPECT_EQ(chromeos::MOUNT_ERROR_NONE, event.mount_error);
    504 
    505   volume_manager()->RemoveObserver(&observer);
    506 }
    507 
    508 TEST_F(VolumeManagerTest, OnMountEvent_Remounting) {
    509   scoped_ptr<chromeos::disks::DiskMountManager::Disk> disk(
    510       new chromeos::disks::DiskMountManager::Disk(
    511           "device1", "", "", "", "", "", "", "", "", "", "uuid1", "",
    512           chromeos::DEVICE_TYPE_UNKNOWN, 0,
    513           false, false, false, false, false, false));
    514   disk_mount_manager_->AddDiskForTest(disk.release());
    515   disk_mount_manager_->MountPath(
    516       "device1", "", "", chromeos::MOUNT_TYPE_DEVICE);
    517 
    518   const chromeos::disks::DiskMountManager::MountPointInfo kMountPoint(
    519       "device1",
    520       "mount1",
    521       chromeos::MOUNT_TYPE_DEVICE,
    522       chromeos::disks::MOUNT_CONDITION_NONE);
    523 
    524   volume_manager()->OnMountEvent(
    525       chromeos::disks::DiskMountManager::MOUNTING,
    526       chromeos::MOUNT_ERROR_NONE,
    527       kMountPoint);
    528 
    529   LoggingObserver observer;
    530 
    531   // Emulate system suspend and then resume.
    532   {
    533     power_manager_client_->SendSuspendImminent();
    534     power_manager_client_->SendSuspendDone();
    535 
    536     // After resume, the device is unmounted and then mounted.
    537     volume_manager()->OnMountEvent(
    538         chromeos::disks::DiskMountManager::UNMOUNTING,
    539         chromeos::MOUNT_ERROR_NONE,
    540         kMountPoint);
    541 
    542     // Observe what happened for the mount event.
    543     volume_manager()->AddObserver(&observer);
    544 
    545     volume_manager()->OnMountEvent(
    546         chromeos::disks::DiskMountManager::MOUNTING,
    547         chromeos::MOUNT_ERROR_NONE,
    548         kMountPoint);
    549   }
    550 
    551   ASSERT_EQ(1U, observer.events().size());
    552   const LoggingObserver::Event& event = observer.events()[0];
    553   EXPECT_EQ(LoggingObserver::Event::VOLUME_MOUNTED, event.type);
    554   EXPECT_EQ("device1", event.device_path);
    555   EXPECT_EQ(chromeos::MOUNT_ERROR_NONE, event.mount_error);
    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       false);
    720   volume_manager()->OnDiskEvent(
    721       chromeos::disks::DiskMountManager::DISK_ADDED, &kMediaDisk);
    722   secondary.volume_manager()->OnDiskEvent(
    723       chromeos::disks::DiskMountManager::DISK_ADDED, &kMediaDisk);
    724 
    725   // The profile with external storage enabled should have mounted the volume.
    726   bool has_volume_mounted = false;
    727   for (size_t i = 0; i < main_observer.events().size(); ++i) {
    728     if (main_observer.events()[i].type ==
    729         LoggingObserver::Event::VOLUME_MOUNTED)
    730       has_volume_mounted = true;
    731   }
    732   EXPECT_TRUE(has_volume_mounted);
    733 
    734   // The other profiles with external storage disabled should have not.
    735   has_volume_mounted = false;
    736   for (size_t i = 0; i < secondary_observer.events().size(); ++i) {
    737     if (secondary_observer.events()[i].type ==
    738         LoggingObserver::Event::VOLUME_MOUNTED)
    739       has_volume_mounted = true;
    740   }
    741   EXPECT_FALSE(has_volume_mounted);
    742 
    743   volume_manager()->RemoveObserver(&main_observer);
    744   secondary.volume_manager()->RemoveObserver(&secondary_observer);
    745 }
    746 
    747 TEST_F(VolumeManagerTest, GetVolumeInfoList) {
    748   volume_manager()->Initialize();  // Adds "Downloads"
    749   std::vector<VolumeInfo> info_list = volume_manager()->GetVolumeInfoList();
    750   ASSERT_EQ(1u, info_list.size());
    751   EXPECT_EQ("downloads:Downloads", info_list[0].volume_id);
    752   EXPECT_EQ(VOLUME_TYPE_DOWNLOADS_DIRECTORY, info_list[0].type);
    753 }
    754 
    755 TEST_F(VolumeManagerTest, FindVolumeInfoById) {
    756   volume_manager()->Initialize();  // Adds "Downloads"
    757   VolumeInfo volume_info;
    758   ASSERT_FALSE(volume_manager()->FindVolumeInfoById(
    759       "nonexistent", &volume_info));
    760   ASSERT_TRUE(volume_manager()->FindVolumeInfoById(
    761       "downloads:Downloads", &volume_info));
    762   EXPECT_EQ("downloads:Downloads", volume_info.volume_id);
    763   EXPECT_EQ(VOLUME_TYPE_DOWNLOADS_DIRECTORY, volume_info.type);
    764 }
    765 
    766 TEST_F(VolumeManagerTest, ArchiveSourceFiltering) {
    767   LoggingObserver observer;
    768   volume_manager()->AddObserver(&observer);
    769 
    770   // Mount a USB stick.
    771   volume_manager()->OnMountEvent(
    772       chromeos::disks::DiskMountManager::MOUNTING,
    773       chromeos::MOUNT_ERROR_NONE,
    774       chromeos::disks::DiskMountManager::MountPointInfo(
    775           "/removable/usb",
    776           "/removable/usb",
    777           chromeos::MOUNT_TYPE_DEVICE,
    778           chromeos::disks::MOUNT_CONDITION_NONE));
    779 
    780   // Mount a zip archive in the stick.
    781   volume_manager()->OnMountEvent(
    782       chromeos::disks::DiskMountManager::MOUNTING,
    783       chromeos::MOUNT_ERROR_NONE,
    784       chromeos::disks::DiskMountManager::MountPointInfo(
    785           "/removable/usb/1.zip",
    786           "/archive/1",
    787           chromeos::MOUNT_TYPE_ARCHIVE,
    788           chromeos::disks::MOUNT_CONDITION_NONE));
    789   VolumeInfo volume_info;
    790   ASSERT_TRUE(volume_manager()->FindVolumeInfoById("archive:1", &volume_info));
    791   EXPECT_EQ("/archive/1", volume_info.mount_path.AsUTF8Unsafe());
    792   EXPECT_EQ(2u, observer.events().size());
    793 
    794   // Mount a zip archive in the previous zip archive.
    795   volume_manager()->OnMountEvent(
    796       chromeos::disks::DiskMountManager::MOUNTING,
    797       chromeos::MOUNT_ERROR_NONE,
    798       chromeos::disks::DiskMountManager::MountPointInfo(
    799           "/archive/1/2.zip",
    800           "/archive/2",
    801           chromeos::MOUNT_TYPE_ARCHIVE,
    802           chromeos::disks::MOUNT_CONDITION_NONE));
    803   ASSERT_TRUE(volume_manager()->FindVolumeInfoById("archive:2", &volume_info));
    804   EXPECT_EQ("/archive/2", volume_info.mount_path.AsUTF8Unsafe());
    805   EXPECT_EQ(3u, observer.events().size());
    806 
    807   // A zip file is mounted from other profile. It must be ignored in the current
    808   // VolumeManager.
    809   volume_manager()->OnMountEvent(
    810       chromeos::disks::DiskMountManager::MOUNTING,
    811       chromeos::MOUNT_ERROR_NONE,
    812       chromeos::disks::DiskMountManager::MountPointInfo(
    813           "/other/profile/drive/folder/3.zip",
    814           "/archive/3",
    815           chromeos::MOUNT_TYPE_ARCHIVE,
    816           chromeos::disks::MOUNT_CONDITION_NONE));
    817   EXPECT_FALSE(volume_manager()->FindVolumeInfoById("archive:3", &volume_info));
    818   EXPECT_EQ(3u, observer.events().size());
    819 }
    820 
    821 TEST_F(VolumeManagerTest, MTPPlugAndUnplug) {
    822   LoggingObserver observer;
    823   volume_manager()->AddObserver(&observer);
    824 
    825   storage_monitor::StorageInfo info(
    826       storage_monitor::StorageInfo::MakeDeviceId(
    827           storage_monitor::StorageInfo::MTP_OR_PTP, "dummy-device-id"),
    828       FILE_PATH_LITERAL("/dummy/device/location"),
    829       base::UTF8ToUTF16("label"),
    830       base::UTF8ToUTF16("vendor"),
    831       base::UTF8ToUTF16("model"),
    832       12345 /* size */);
    833 
    834   storage_monitor::StorageInfo non_mtp_info(
    835       storage_monitor::StorageInfo::MakeDeviceId(
    836           storage_monitor::StorageInfo::IPHOTO, "dummy-device-id2"),
    837       FILE_PATH_LITERAL("/dummy/device/location2"),
    838       base::UTF8ToUTF16("label2"),
    839       base::UTF8ToUTF16("vendor2"),
    840       base::UTF8ToUTF16("model2"),
    841       12345 /* size */);
    842 
    843   // Attach
    844   volume_manager()->OnRemovableStorageAttached(info);
    845   ASSERT_EQ(1u, observer.events().size());
    846   EXPECT_EQ(LoggingObserver::Event::VOLUME_MOUNTED, observer.events()[0].type);
    847 
    848   VolumeInfo volume_info;
    849   ASSERT_TRUE(volume_manager()->FindVolumeInfoById("mtp:model", &volume_info));
    850   EXPECT_EQ(VOLUME_TYPE_MTP, volume_info.type);
    851 
    852   // Non MTP events from storage monitor are ignored.
    853   volume_manager()->OnRemovableStorageAttached(non_mtp_info);
    854   EXPECT_EQ(1u, observer.events().size());
    855 
    856   // Detach
    857   volume_manager()->OnRemovableStorageDetached(info);
    858   ASSERT_EQ(2u, observer.events().size());
    859   EXPECT_EQ(LoggingObserver::Event::VOLUME_UNMOUNTED,
    860             observer.events()[1].type);
    861 
    862   EXPECT_FALSE(volume_manager()->FindVolumeInfoById("mtp:model", &volume_info));
    863 }
    864 
    865 }  // namespace file_manager
    866