Index: chrome/browser/system_monitor/removable_device_notifications_window_win_unittest.cc |
diff --git a/chrome/browser/system_monitor/removable_device_notifications_window_win_unittest.cc b/chrome/browser/system_monitor/removable_device_notifications_window_win_unittest.cc |
index 0996447fbef409e08426f788ac3d196a33d4ba14..2c9c3805f7e73801ac50718b1c6c5ad657cae700 100644 |
--- a/chrome/browser/system_monitor/removable_device_notifications_window_win_unittest.cc |
+++ b/chrome/browser/system_monitor/removable_device_notifications_window_win_unittest.cc |
@@ -13,7 +13,6 @@ |
#include "base/memory/scoped_ptr.h" |
#include "base/message_loop.h" |
#include "base/scoped_temp_dir.h" |
-#include "base/string_number_conversions.h" |
#include "base/system_monitor/system_monitor.h" |
#include "base/test/mock_devices_changed_observer.h" |
#include "chrome/browser/system_monitor/media_storage_util.h" |
@@ -24,66 +23,138 @@ |
namespace { |
using content::BrowserThread; |
+using chrome::RemovableDeviceNotificationsWindowWin; |
+ |
+// Inputs of 'A:\' - 'Z:\' are valid. 'N:\' is not removable. |
+bool GetDeviceInfo(const FilePath& device_path, string16* device_location, |
+ std::string* unique_id, string16* name, bool* removable) { |
+ if (device_path.value().length() != 3 || device_path.value()[0] < L'A' || |
+ device_path.value()[0] > L'Z') { |
+ return false; |
+ } |
+ |
+ if (device_location) |
+ *device_location = device_path.value(); |
+ if (unique_id) { |
+ *unique_id = "\\\\?\\Volume{00000000-0000-0000-0000-000000000000}\\"; |
+ (*unique_id)[11] = device_path.value()[0]; |
+ } |
+ if (name) |
+ *name = device_path.Append(L" Drive").LossyDisplayName(); |
+ if (removable) |
+ *removable = device_path.value()[0] != L'N'; |
+ return true; |
+} |
+ |
+FilePath DriveNumberToFilePath(int drive_number) { |
+ FilePath::StringType path(L"_:\\"); |
+ path[0] = L'A' + drive_number; |
+ return FilePath(path); |
+} |
-LRESULT GetVolumeName(LPCWSTR drive, |
- LPWSTR volume_name, |
- unsigned int volume_name_length) { |
- DCHECK(volume_name_length > wcslen(drive) + 2); |
- *volume_name = 'V'; |
- wcscpy(volume_name + 1, drive); |
- return TRUE; |
+std::vector<FilePath> GetTestAttachedDevices() { |
+ std::vector<FilePath> result; |
+ result.push_back(DriveNumberToFilePath(0)); |
+ result.push_back(DriveNumberToFilePath(1)); |
+ result.push_back(DriveNumberToFilePath(2)); |
+ result.push_back(DriveNumberToFilePath(3)); |
+ result.push_back(DriveNumberToFilePath(5)); |
+ result.push_back(DriveNumberToFilePath(7)); |
+ result.push_back(DriveNumberToFilePath(25)); |
+ return result; |
} |
} // namespace |
namespace chrome { |
-using chrome::RemovableDeviceNotificationsWindowWin; |
-using testing::_; |
+class TestRemovableDeviceNotificationsWindowWin |
+ : public RemovableDeviceNotificationsWindowWin { |
+ public: |
+ TestRemovableDeviceNotificationsWindowWin() { |
+ } |
+ |
+ void InitWithTestData() { |
+ InitForTest(&GetDeviceInfo, &NoAttachedDevices); |
+ } |
+ |
+ void InitWithTestDataAndAttachedDevices() { |
+ InitForTest(&GetDeviceInfo, &GetTestAttachedDevices); |
+ } |
+ |
+ void InjectDeviceChange(UINT event_type, DWORD data) { |
+ OnDeviceChange(event_type, data); |
+ } |
+ |
+ private: |
+ virtual ~TestRemovableDeviceNotificationsWindowWin() { |
+ } |
+ |
+ static std::vector<FilePath> NoAttachedDevices() { |
+ std::vector<FilePath> result; |
+ return result; |
+ } |
+}; |
class RemovableDeviceNotificationsWindowWinTest : public testing::Test { |
public: |
RemovableDeviceNotificationsWindowWinTest() |
: ui_thread_(BrowserThread::UI, &message_loop_), |
- file_thread_(BrowserThread::FILE) { } |
+ file_thread_(BrowserThread::FILE, &message_loop_) { } |
virtual ~RemovableDeviceNotificationsWindowWinTest() { } |
protected: |
virtual void SetUp() OVERRIDE { |
ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
- file_thread_.Start(); |
- window_ = new RemovableDeviceNotificationsWindowWin(&GetVolumeName); |
+ window_ = new TestRemovableDeviceNotificationsWindowWin; |
+ window_->InitWithTestData(); |
system_monitor_.AddDevicesChangedObserver(&observer_); |
} |
virtual void TearDown() { |
+ message_loop_.RunAllPending(); |
system_monitor_.RemoveDevicesChangedObserver(&observer_); |
- WaitForFileThread(); |
} |
- static void PostQuitToUIThread() { |
- BrowserThread::PostTask(BrowserThread::UI, |
- FROM_HERE, |
- MessageLoop::QuitClosure()); |
+ void AddAttachExpectation(FilePath drive) { |
+ std::string unique_id; |
+ string16 device_name; |
+ bool removable; |
+ ASSERT_TRUE(GetDeviceInfo(drive, NULL, &unique_id, &device_name, |
+ &removable)); |
+ if (removable) { |
+ MediaStorageUtil::Type type = |
+ MediaStorageUtil::REMOVABLE_MASS_STORAGE_NO_DCIM; |
+ std::string device_id = MediaStorageUtil::MakeDeviceId(type, unique_id); |
+ EXPECT_CALL(observer_, OnRemovableStorageAttached(device_id, device_name, |
+ drive.value())) |
+ .Times(1); |
+ } |
} |
- static void WaitForFileThread() { |
- BrowserThread::PostTask(BrowserThread::FILE, |
- FROM_HERE, |
- base::Bind(&PostQuitToUIThread)); |
- MessageLoop::current()->Run(); |
+ void PreAttachDevices() { |
+ window_ = NULL; |
+ { |
+ testing::InSequence sequence; |
+ std::vector<FilePath> initial_devices = GetTestAttachedDevices(); |
+ for (size_t i = 0; i < initial_devices.size(); i++) |
+ AddAttachExpectation(initial_devices[i]); |
+ } |
+ window_ = new TestRemovableDeviceNotificationsWindowWin(); |
+ window_->InitWithTestDataAndAttachedDevices(); |
+ message_loop_.RunAllPending(); |
} |
void DoDevicesAttachedTest(const std::vector<int>& device_indices); |
void DoDevicesDetachedTest(const std::vector<int>& device_indices); |
- MessageLoop message_loop_; |
+ MessageLoopForUI message_loop_; |
content::TestBrowserThread ui_thread_; |
content::TestBrowserThread file_thread_; |
base::SystemMonitor system_monitor_; |
base::MockDevicesChangedObserver observer_; |
- scoped_refptr<RemovableDeviceNotificationsWindowWin> window_; |
+ scoped_refptr<TestRemovableDeviceNotificationsWindowWin> window_; |
}; |
void RemovableDeviceNotificationsWindowWinTest::DoDevicesAttachedTest( |
@@ -99,18 +170,11 @@ void RemovableDeviceNotificationsWindowWinTest::DoDevicesAttachedTest( |
it != device_indices.end(); |
++it) { |
volume_broadcast.dbcv_unitmask |= 0x1 << *it; |
- std::wstring drive(L"_:\\"); |
- drive[0] = 'A' + *it; |
- FilePath::StringType name = L"V" + drive; |
- std::string device_id = MediaStorageUtil::MakeDeviceId( |
- MediaStorageUtil::REMOVABLE_MASS_STORAGE_WITH_DCIM, |
- base::IntToString(*it)); |
- EXPECT_CALL(observer_, OnRemovableStorageAttached(device_id, name, drive)) |
- .Times(0); |
+ AddAttachExpectation(DriveNumberToFilePath(*it)); |
} |
} |
- window_->OnDeviceChange(DBT_DEVICEARRIVAL, |
- reinterpret_cast<DWORD>(&volume_broadcast)); |
+ window_->InjectDeviceChange(DBT_DEVICEARRIVAL, |
+ reinterpret_cast<DWORD>(&volume_broadcast)); |
message_loop_.RunAllPending(); |
} |
@@ -127,19 +191,25 @@ void RemovableDeviceNotificationsWindowWinTest::DoDevicesDetachedTest( |
it != device_indices.end(); |
++it) { |
volume_broadcast.dbcv_unitmask |= 0x1 << *it; |
- std::string device_id = MediaStorageUtil::MakeDeviceId( |
- MediaStorageUtil::REMOVABLE_MASS_STORAGE_WITH_DCIM, |
- base::IntToString(*it)); |
- EXPECT_CALL(observer_, OnRemovableStorageDetached(device_id)).Times(0); |
+ std::string unique_id; |
+ bool removable; |
+ ASSERT_TRUE(GetDeviceInfo(DriveNumberToFilePath(*it), NULL, &unique_id, |
+ NULL, &removable)); |
+ if (removable) { |
+ MediaStorageUtil::Type type = |
+ MediaStorageUtil::REMOVABLE_MASS_STORAGE_NO_DCIM; |
+ std::string device_id = MediaStorageUtil::MakeDeviceId(type, unique_id); |
+ EXPECT_CALL(observer_, OnRemovableStorageDetached(device_id)).Times(1); |
+ } |
} |
} |
- window_->OnDeviceChange(DBT_DEVICEREMOVECOMPLETE, |
- reinterpret_cast<DWORD>(&volume_broadcast)); |
+ window_->InjectDeviceChange(DBT_DEVICEREMOVECOMPLETE, |
+ reinterpret_cast<DWORD>(&volume_broadcast)); |
message_loop_.RunAllPending(); |
} |
TEST_F(RemovableDeviceNotificationsWindowWinTest, RandomMessage) { |
- window_->OnDeviceChange(DBT_DEVICEQUERYREMOVE, NULL); |
+ window_->InjectDeviceChange(DBT_DEVICEQUERYREMOVE, NULL); |
message_loop_.RunAllPending(); |
} |
@@ -148,6 +218,7 @@ TEST_F(RemovableDeviceNotificationsWindowWinTest, DevicesAttached) { |
device_indices.push_back(1); |
device_indices.push_back(5); |
device_indices.push_back(7); |
+ device_indices.push_back(13); |
DoDevicesAttachedTest(device_indices); |
} |
@@ -177,15 +248,20 @@ TEST_F(RemovableDeviceNotificationsWindowWinTest, DevicesAttachedAdjacentBits) { |
} |
TEST_F(RemovableDeviceNotificationsWindowWinTest, DevicesDetached) { |
+ PreAttachDevices(); |
+ |
std::vector<int> device_indices; |
device_indices.push_back(1); |
device_indices.push_back(5); |
device_indices.push_back(7); |
+ device_indices.push_back(13); |
DoDevicesDetachedTest(device_indices); |
} |
TEST_F(RemovableDeviceNotificationsWindowWinTest, DevicesDetachedHighBoundary) { |
+ PreAttachDevices(); |
+ |
std::vector<int> device_indices; |
device_indices.push_back(25); |
@@ -193,6 +269,8 @@ TEST_F(RemovableDeviceNotificationsWindowWinTest, DevicesDetachedHighBoundary) { |
} |
TEST_F(RemovableDeviceNotificationsWindowWinTest, DevicesDetachedLowBoundary) { |
+ PreAttachDevices(); |
+ |
std::vector<int> device_indices; |
device_indices.push_back(0); |
@@ -200,6 +278,8 @@ TEST_F(RemovableDeviceNotificationsWindowWinTest, DevicesDetachedLowBoundary) { |
} |
TEST_F(RemovableDeviceNotificationsWindowWinTest, DevicesDetachedAdjacentBits) { |
+ PreAttachDevices(); |
+ |
std::vector<int> device_indices; |
device_indices.push_back(0); |
device_indices.push_back(1); |
@@ -209,4 +289,44 @@ TEST_F(RemovableDeviceNotificationsWindowWinTest, DevicesDetachedAdjacentBits) { |
DoDevicesDetachedTest(device_indices); |
} |
+TEST_F(RemovableDeviceNotificationsWindowWinTest, DeviceInfoFoPath) { |
+ PreAttachDevices(); |
+ |
+ // An invalid path. |
+ EXPECT_FALSE(window_->GetDeviceInfoForPath(FilePath(L"COM1:\\"), NULL)); |
+ |
+ // An unconnected removable device. |
+ EXPECT_FALSE(window_->GetDeviceInfoForPath(FilePath(L"E:\\"), NULL)); |
+ |
+ // A connected removable device. |
+ FilePath removable_device(L"F:\\"); |
+ base::SystemMonitor::RemovableStorageInfo device_info; |
+ EXPECT_TRUE(window_->GetDeviceInfoForPath(removable_device, &device_info)); |
+ |
+ std::string unique_id; |
+ string16 device_name; |
+ bool removable; |
+ ASSERT_TRUE(GetDeviceInfo(removable_device, NULL, &unique_id, &device_name, |
+ &removable)); |
+ EXPECT_TRUE(removable); |
+ std::string device_id = MediaStorageUtil::MakeDeviceId( |
+ MediaStorageUtil::REMOVABLE_MASS_STORAGE_NO_DCIM, unique_id); |
+ EXPECT_EQ(device_id, device_info.device_id); |
+ EXPECT_EQ(device_name, device_info.name); |
+ EXPECT_EQ(removable_device.value(), device_info.location); |
+ |
+ // A fixed device. |
+ FilePath fixed_device(L"N:\\"); |
+ EXPECT_TRUE(window_->GetDeviceInfoForPath(fixed_device, &device_info)); |
+ |
+ ASSERT_TRUE(GetDeviceInfo(fixed_device, NULL, &unique_id, &device_name, |
+ &removable)); |
+ EXPECT_FALSE(removable); |
+ device_id = MediaStorageUtil::MakeDeviceId( |
+ MediaStorageUtil::FIXED_MASS_STORAGE, unique_id); |
+ EXPECT_EQ(device_id, device_info.device_id); |
+ EXPECT_EQ(device_name, device_info.name); |
+ EXPECT_EQ(fixed_device.value(), device_info.location); |
+} |
+ |
} // namespace chrome |