1 // Copyright 2014 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 // TestVolumeMountWatcherWin implementation. 6 7 #include "components/storage_monitor/test_volume_mount_watcher_win.h" 8 9 #include "base/bind.h" 10 #include "base/files/file_path.h" 11 #include "base/files/scoped_temp_dir.h" 12 #include "base/strings/utf_string_conversions.h" 13 #include "components/storage_monitor/storage_info.h" 14 15 namespace storage_monitor { 16 17 namespace { 18 19 base::FilePath GetTempRoot() { 20 base::ScopedTempDir temp_dir; 21 temp_dir.CreateUniqueTempDir(); 22 base::FilePath temp_root = temp_dir.path(); 23 while (temp_root.DirName() != temp_root) 24 temp_root = temp_root.DirName(); 25 return temp_root; 26 } 27 28 std::vector<base::FilePath> FakeGetSingleAttachedDevice() { 29 std::vector<base::FilePath> result; 30 result.push_back(VolumeMountWatcherWin::DriveNumberToFilePath(2)); // C 31 32 // Make sure we are adding the drive on which ScopedTempDir will make 33 // test directories. 34 base::FilePath temp_root = GetTempRoot(); 35 if (temp_root != VolumeMountWatcherWin::DriveNumberToFilePath(2)) 36 result.push_back(temp_root); 37 38 return result; 39 } 40 41 std::vector<base::FilePath> FakeGetAttachedDevices() { 42 std::vector<base::FilePath> result; 43 result.push_back(VolumeMountWatcherWin::DriveNumberToFilePath(0)); // A 44 result.push_back(VolumeMountWatcherWin::DriveNumberToFilePath(1)); // B 45 result.push_back(VolumeMountWatcherWin::DriveNumberToFilePath(2)); // C 46 result.push_back(VolumeMountWatcherWin::DriveNumberToFilePath(3)); // D 47 result.push_back(VolumeMountWatcherWin::DriveNumberToFilePath(5)); // F 48 result.push_back(VolumeMountWatcherWin::DriveNumberToFilePath(7)); // H 49 result.push_back(VolumeMountWatcherWin::DriveNumberToFilePath(13)); // N 50 result.push_back(VolumeMountWatcherWin::DriveNumberToFilePath(25)); // Z 51 return result; 52 } 53 54 // Gets the details of the mass storage device specified by the |device_path|. 55 // |device_path| inputs of 'A:\' - 'Z:\' are valid. 'N:\' is not removable. 56 // 'C:\' is not removable (so that auto-added paths are correctly handled). 57 bool GetMassStorageDeviceDetails(const base::FilePath& device_path, 58 StorageInfo* info) { 59 DCHECK(info); 60 61 // Truncate to root path. 62 base::FilePath path(device_path); 63 if (device_path.value().length() > 3) 64 path = base::FilePath(device_path.value().substr(0, 3)); 65 if (path.value()[0] < L'A' || path.value()[0] > L'Z') 66 return false; 67 68 StorageInfo::Type type = StorageInfo::FIXED_MASS_STORAGE; 69 if (path.value() != base::ASCIIToUTF16("N:\\") && 70 path.value() != base::ASCIIToUTF16("C:\\") && 71 path.value() != GetTempRoot().value()) { 72 type = StorageInfo::REMOVABLE_MASS_STORAGE_WITH_DCIM; 73 } 74 std::string unique_id = 75 "\\\\?\\Volume{00000000-0000-0000-0000-000000000000}\\"; 76 unique_id[11] = device_path.value()[0]; 77 std::string device_id = StorageInfo::MakeDeviceId(type, unique_id); 78 base::string16 storage_label = path.Append(L" Drive").LossyDisplayName(); 79 *info = StorageInfo(device_id, path.value(), storage_label, base::string16(), 80 base::string16(), 1000000); 81 82 return true; 83 } 84 85 } // namespace 86 87 // TestVolumeMountWatcherWin --------------------------------------------------- 88 89 TestVolumeMountWatcherWin::TestVolumeMountWatcherWin() 90 : attached_devices_fake_(false) {} 91 92 TestVolumeMountWatcherWin::~TestVolumeMountWatcherWin() { 93 } 94 95 void TestVolumeMountWatcherWin::AddDeviceForTesting( 96 const base::FilePath& device_path, 97 const std::string& device_id, 98 const base::string16& storage_label, 99 uint64 total_size_in_bytes) { 100 StorageInfo info(device_id, device_path.value(), storage_label, 101 base::string16(), base::string16(), total_size_in_bytes); 102 HandleDeviceAttachEventOnUIThread(device_path, info); 103 } 104 105 void TestVolumeMountWatcherWin::SetAttachedDevicesFake() { 106 attached_devices_fake_ = true; 107 } 108 109 void TestVolumeMountWatcherWin::FlushWorkerPoolForTesting() { 110 device_info_worker_pool_->FlushForTesting(); 111 } 112 113 void TestVolumeMountWatcherWin::DeviceCheckComplete( 114 const base::FilePath& device_path) { 115 devices_checked_.push_back(device_path); 116 if (device_check_complete_event_.get()) 117 device_check_complete_event_->Wait(); 118 VolumeMountWatcherWin::DeviceCheckComplete(device_path); 119 } 120 121 void TestVolumeMountWatcherWin::BlockDeviceCheckForTesting() { 122 device_check_complete_event_.reset(new base::WaitableEvent(false, false)); 123 devices_checked_.clear(); 124 } 125 126 void TestVolumeMountWatcherWin::ReleaseDeviceCheck() { 127 device_check_complete_event_->Signal(); 128 } 129 130 // static 131 bool TestVolumeMountWatcherWin::GetDeviceRemovable( 132 const base::FilePath& device_path, 133 bool* removable) { 134 StorageInfo info; 135 bool success = GetMassStorageDeviceDetails(device_path, &info); 136 *removable = StorageInfo::IsRemovableDevice(info.device_id()); 137 return success; 138 } 139 140 VolumeMountWatcherWin::GetDeviceDetailsCallbackType 141 TestVolumeMountWatcherWin::GetDeviceDetailsCallback() const { 142 return base::Bind(&GetMassStorageDeviceDetails); 143 } 144 145 VolumeMountWatcherWin::GetAttachedDevicesCallbackType 146 TestVolumeMountWatcherWin::GetAttachedDevicesCallback() const { 147 if (attached_devices_fake_) 148 return base::Bind(&FakeGetAttachedDevices); 149 return base::Bind(&FakeGetSingleAttachedDevice); 150 } 151 152 void TestVolumeMountWatcherWin::ShutdownWorkerPool() { 153 device_info_worker_pool_->Shutdown(); 154 } 155 156 } // namespace storage_monitor 157