Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(82)

Side by Side Diff: chrome/browser/system_monitor/removable_device_notifications_window_win_unittest.cc

Issue 10911350: Update Windows System Monitor Removable Device Impl. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebase Created 8 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « chrome/browser/system_monitor/removable_device_notifications_window_win.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/system_monitor/removable_device_notifications_window_wi n.h" 5 #include "chrome/browser/system_monitor/removable_device_notifications_window_wi n.h"
6 6
7 #include <dbt.h> 7 #include <dbt.h>
8 8
9 #include <string> 9 #include <string>
10 #include <vector> 10 #include <vector>
11 11
12 #include "base/file_util.h" 12 #include "base/file_util.h"
13 #include "base/memory/scoped_ptr.h" 13 #include "base/memory/scoped_ptr.h"
14 #include "base/message_loop.h" 14 #include "base/message_loop.h"
15 #include "base/scoped_temp_dir.h" 15 #include "base/scoped_temp_dir.h"
16 #include "base/string_number_conversions.h"
17 #include "base/system_monitor/system_monitor.h" 16 #include "base/system_monitor/system_monitor.h"
18 #include "base/test/mock_devices_changed_observer.h" 17 #include "base/test/mock_devices_changed_observer.h"
19 #include "chrome/browser/system_monitor/media_storage_util.h" 18 #include "chrome/browser/system_monitor/media_storage_util.h"
20 #include "content/public/test/test_browser_thread.h" 19 #include "content/public/test/test_browser_thread.h"
21 #include "testing/gmock/include/gmock/gmock.h" 20 #include "testing/gmock/include/gmock/gmock.h"
22 #include "testing/gtest/include/gtest/gtest.h" 21 #include "testing/gtest/include/gtest/gtest.h"
23 22
24 namespace { 23 namespace {
25 24
26 using content::BrowserThread; 25 using content::BrowserThread;
26 using chrome::RemovableDeviceNotificationsWindowWin;
27 27
28 LRESULT GetVolumeName(LPCWSTR drive, 28 // Inputs of 'A:\' - 'Z:\' are valid. 'N:\' is not removable.
29 LPWSTR volume_name, 29 bool GetDeviceInfo(const FilePath& device_path, string16* device_location,
30 unsigned int volume_name_length) { 30 std::string* unique_id, string16* name, bool* removable) {
31 DCHECK(volume_name_length > wcslen(drive) + 2); 31 if (device_path.value().length() != 3 || device_path.value()[0] < L'A' ||
32 *volume_name = 'V'; 32 device_path.value()[0] > L'Z') {
33 wcscpy(volume_name + 1, drive); 33 return false;
34 return TRUE; 34 }
35
36 if (device_location)
37 *device_location = device_path.value();
38 if (unique_id) {
39 *unique_id = "\\\\?\\Volume{00000000-0000-0000-0000-000000000000}\\";
40 (*unique_id)[11] = device_path.value()[0];
41 }
42 if (name)
43 *name = device_path.Append(L" Drive").LossyDisplayName();
44 if (removable)
45 *removable = device_path.value()[0] != L'N';
46 return true;
47 }
48
49 FilePath DriveNumberToFilePath(int drive_number) {
50 FilePath::StringType path(L"_:\\");
51 path[0] = L'A' + drive_number;
52 return FilePath(path);
53 }
54
55 std::vector<FilePath> GetTestAttachedDevices() {
56 std::vector<FilePath> result;
57 result.push_back(DriveNumberToFilePath(0));
58 result.push_back(DriveNumberToFilePath(1));
59 result.push_back(DriveNumberToFilePath(2));
60 result.push_back(DriveNumberToFilePath(3));
61 result.push_back(DriveNumberToFilePath(5));
62 result.push_back(DriveNumberToFilePath(7));
63 result.push_back(DriveNumberToFilePath(25));
64 return result;
35 } 65 }
36 66
37 } // namespace 67 } // namespace
38 68
39 namespace chrome { 69 namespace chrome {
40 70
41 using chrome::RemovableDeviceNotificationsWindowWin; 71 class TestRemovableDeviceNotificationsWindowWin
42 using testing::_; 72 : public RemovableDeviceNotificationsWindowWin {
73 public:
74 TestRemovableDeviceNotificationsWindowWin() {
75 }
76
77 void InitWithTestData() {
78 InitForTest(&GetDeviceInfo, &NoAttachedDevices);
79 }
80
81 void InitWithTestDataAndAttachedDevices() {
82 InitForTest(&GetDeviceInfo, &GetTestAttachedDevices);
83 }
84
85 void InjectDeviceChange(UINT event_type, DWORD data) {
86 OnDeviceChange(event_type, data);
87 }
88
89 private:
90 virtual ~TestRemovableDeviceNotificationsWindowWin() {
91 }
92
93 static std::vector<FilePath> NoAttachedDevices() {
94 std::vector<FilePath> result;
95 return result;
96 }
97 };
43 98
44 class RemovableDeviceNotificationsWindowWinTest : public testing::Test { 99 class RemovableDeviceNotificationsWindowWinTest : public testing::Test {
45 public: 100 public:
46 RemovableDeviceNotificationsWindowWinTest() 101 RemovableDeviceNotificationsWindowWinTest()
47 : ui_thread_(BrowserThread::UI, &message_loop_), 102 : ui_thread_(BrowserThread::UI, &message_loop_),
48 file_thread_(BrowserThread::FILE) { } 103 file_thread_(BrowserThread::FILE, &message_loop_) { }
49 virtual ~RemovableDeviceNotificationsWindowWinTest() { } 104 virtual ~RemovableDeviceNotificationsWindowWinTest() { }
50 105
51 protected: 106 protected:
52 virtual void SetUp() OVERRIDE { 107 virtual void SetUp() OVERRIDE {
53 ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::UI)); 108 ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::UI));
54 file_thread_.Start(); 109 window_ = new TestRemovableDeviceNotificationsWindowWin;
55 window_ = new RemovableDeviceNotificationsWindowWin(&GetVolumeName); 110 window_->InitWithTestData();
56 system_monitor_.AddDevicesChangedObserver(&observer_); 111 system_monitor_.AddDevicesChangedObserver(&observer_);
57 } 112 }
58 113
59 virtual void TearDown() { 114 virtual void TearDown() {
115 message_loop_.RunAllPending();
60 system_monitor_.RemoveDevicesChangedObserver(&observer_); 116 system_monitor_.RemoveDevicesChangedObserver(&observer_);
61 WaitForFileThread();
62 } 117 }
63 118
64 static void PostQuitToUIThread() { 119 void AddAttachExpectation(FilePath drive) {
65 BrowserThread::PostTask(BrowserThread::UI, 120 std::string unique_id;
66 FROM_HERE, 121 string16 device_name;
67 MessageLoop::QuitClosure()); 122 bool removable;
123 ASSERT_TRUE(GetDeviceInfo(drive, NULL, &unique_id, &device_name,
124 &removable));
125 if (removable) {
126 MediaStorageUtil::Type type =
127 MediaStorageUtil::REMOVABLE_MASS_STORAGE_NO_DCIM;
128 std::string device_id = MediaStorageUtil::MakeDeviceId(type, unique_id);
129 EXPECT_CALL(observer_, OnRemovableStorageAttached(device_id, device_name,
130 drive.value()))
131 .Times(1);
132 }
68 } 133 }
69 134
70 static void WaitForFileThread() { 135 void PreAttachDevices() {
71 BrowserThread::PostTask(BrowserThread::FILE, 136 window_ = NULL;
72 FROM_HERE, 137 {
73 base::Bind(&PostQuitToUIThread)); 138 testing::InSequence sequence;
74 MessageLoop::current()->Run(); 139 std::vector<FilePath> initial_devices = GetTestAttachedDevices();
140 for (size_t i = 0; i < initial_devices.size(); i++)
141 AddAttachExpectation(initial_devices[i]);
142 }
143 window_ = new TestRemovableDeviceNotificationsWindowWin();
144 window_->InitWithTestDataAndAttachedDevices();
145 message_loop_.RunAllPending();
75 } 146 }
76 147
77 void DoDevicesAttachedTest(const std::vector<int>& device_indices); 148 void DoDevicesAttachedTest(const std::vector<int>& device_indices);
78 void DoDevicesDetachedTest(const std::vector<int>& device_indices); 149 void DoDevicesDetachedTest(const std::vector<int>& device_indices);
79 150
80 MessageLoop message_loop_; 151 MessageLoopForUI message_loop_;
81 content::TestBrowserThread ui_thread_; 152 content::TestBrowserThread ui_thread_;
82 content::TestBrowserThread file_thread_; 153 content::TestBrowserThread file_thread_;
83 154
84 base::SystemMonitor system_monitor_; 155 base::SystemMonitor system_monitor_;
85 base::MockDevicesChangedObserver observer_; 156 base::MockDevicesChangedObserver observer_;
86 scoped_refptr<RemovableDeviceNotificationsWindowWin> window_; 157 scoped_refptr<TestRemovableDeviceNotificationsWindowWin> window_;
87 }; 158 };
88 159
89 void RemovableDeviceNotificationsWindowWinTest::DoDevicesAttachedTest( 160 void RemovableDeviceNotificationsWindowWinTest::DoDevicesAttachedTest(
90 const std::vector<int>& device_indices) { 161 const std::vector<int>& device_indices) {
91 DEV_BROADCAST_VOLUME volume_broadcast; 162 DEV_BROADCAST_VOLUME volume_broadcast;
92 volume_broadcast.dbcv_size = sizeof(volume_broadcast); 163 volume_broadcast.dbcv_size = sizeof(volume_broadcast);
93 volume_broadcast.dbcv_devicetype = DBT_DEVTYP_VOLUME; 164 volume_broadcast.dbcv_devicetype = DBT_DEVTYP_VOLUME;
94 volume_broadcast.dbcv_unitmask = 0x0; 165 volume_broadcast.dbcv_unitmask = 0x0;
95 volume_broadcast.dbcv_flags = 0x0; 166 volume_broadcast.dbcv_flags = 0x0;
96 { 167 {
97 testing::InSequence sequence; 168 testing::InSequence sequence;
98 for (std::vector<int>::const_iterator it = device_indices.begin(); 169 for (std::vector<int>::const_iterator it = device_indices.begin();
99 it != device_indices.end(); 170 it != device_indices.end();
100 ++it) { 171 ++it) {
101 volume_broadcast.dbcv_unitmask |= 0x1 << *it; 172 volume_broadcast.dbcv_unitmask |= 0x1 << *it;
102 std::wstring drive(L"_:\\"); 173 AddAttachExpectation(DriveNumberToFilePath(*it));
103 drive[0] = 'A' + *it;
104 FilePath::StringType name = L"V" + drive;
105 std::string device_id = MediaStorageUtil::MakeDeviceId(
106 MediaStorageUtil::REMOVABLE_MASS_STORAGE_WITH_DCIM,
107 base::IntToString(*it));
108 EXPECT_CALL(observer_, OnRemovableStorageAttached(device_id, name, drive))
109 .Times(0);
110 } 174 }
111 } 175 }
112 window_->OnDeviceChange(DBT_DEVICEARRIVAL, 176 window_->InjectDeviceChange(DBT_DEVICEARRIVAL,
113 reinterpret_cast<DWORD>(&volume_broadcast)); 177 reinterpret_cast<DWORD>(&volume_broadcast));
114 message_loop_.RunAllPending(); 178 message_loop_.RunAllPending();
115 } 179 }
116 180
117 void RemovableDeviceNotificationsWindowWinTest::DoDevicesDetachedTest( 181 void RemovableDeviceNotificationsWindowWinTest::DoDevicesDetachedTest(
118 const std::vector<int>& device_indices) { 182 const std::vector<int>& device_indices) {
119 DEV_BROADCAST_VOLUME volume_broadcast; 183 DEV_BROADCAST_VOLUME volume_broadcast;
120 volume_broadcast.dbcv_size = sizeof(volume_broadcast); 184 volume_broadcast.dbcv_size = sizeof(volume_broadcast);
121 volume_broadcast.dbcv_devicetype = DBT_DEVTYP_VOLUME; 185 volume_broadcast.dbcv_devicetype = DBT_DEVTYP_VOLUME;
122 volume_broadcast.dbcv_unitmask = 0x0; 186 volume_broadcast.dbcv_unitmask = 0x0;
123 volume_broadcast.dbcv_flags = 0x0; 187 volume_broadcast.dbcv_flags = 0x0;
124 { 188 {
125 testing::InSequence sequence; 189 testing::InSequence sequence;
126 for (std::vector<int>::const_iterator it = device_indices.begin(); 190 for (std::vector<int>::const_iterator it = device_indices.begin();
127 it != device_indices.end(); 191 it != device_indices.end();
128 ++it) { 192 ++it) {
129 volume_broadcast.dbcv_unitmask |= 0x1 << *it; 193 volume_broadcast.dbcv_unitmask |= 0x1 << *it;
130 std::string device_id = MediaStorageUtil::MakeDeviceId( 194 std::string unique_id;
131 MediaStorageUtil::REMOVABLE_MASS_STORAGE_WITH_DCIM, 195 bool removable;
132 base::IntToString(*it)); 196 ASSERT_TRUE(GetDeviceInfo(DriveNumberToFilePath(*it), NULL, &unique_id,
133 EXPECT_CALL(observer_, OnRemovableStorageDetached(device_id)).Times(0); 197 NULL, &removable));
198 if (removable) {
199 MediaStorageUtil::Type type =
200 MediaStorageUtil::REMOVABLE_MASS_STORAGE_NO_DCIM;
201 std::string device_id = MediaStorageUtil::MakeDeviceId(type, unique_id);
202 EXPECT_CALL(observer_, OnRemovableStorageDetached(device_id)).Times(1);
203 }
134 } 204 }
135 } 205 }
136 window_->OnDeviceChange(DBT_DEVICEREMOVECOMPLETE, 206 window_->InjectDeviceChange(DBT_DEVICEREMOVECOMPLETE,
137 reinterpret_cast<DWORD>(&volume_broadcast)); 207 reinterpret_cast<DWORD>(&volume_broadcast));
138 message_loop_.RunAllPending(); 208 message_loop_.RunAllPending();
139 } 209 }
140 210
141 TEST_F(RemovableDeviceNotificationsWindowWinTest, RandomMessage) { 211 TEST_F(RemovableDeviceNotificationsWindowWinTest, RandomMessage) {
142 window_->OnDeviceChange(DBT_DEVICEQUERYREMOVE, NULL); 212 window_->InjectDeviceChange(DBT_DEVICEQUERYREMOVE, NULL);
143 message_loop_.RunAllPending(); 213 message_loop_.RunAllPending();
144 } 214 }
145 215
146 TEST_F(RemovableDeviceNotificationsWindowWinTest, DevicesAttached) { 216 TEST_F(RemovableDeviceNotificationsWindowWinTest, DevicesAttached) {
147 std::vector<int> device_indices; 217 std::vector<int> device_indices;
148 device_indices.push_back(1); 218 device_indices.push_back(1);
149 device_indices.push_back(5); 219 device_indices.push_back(5);
150 device_indices.push_back(7); 220 device_indices.push_back(7);
221 device_indices.push_back(13);
151 222
152 DoDevicesAttachedTest(device_indices); 223 DoDevicesAttachedTest(device_indices);
153 } 224 }
154 225
155 TEST_F(RemovableDeviceNotificationsWindowWinTest, DevicesAttachedHighBoundary) { 226 TEST_F(RemovableDeviceNotificationsWindowWinTest, DevicesAttachedHighBoundary) {
156 std::vector<int> device_indices; 227 std::vector<int> device_indices;
157 device_indices.push_back(25); 228 device_indices.push_back(25);
158 229
159 DoDevicesAttachedTest(device_indices); 230 DoDevicesAttachedTest(device_indices);
160 } 231 }
161 232
162 TEST_F(RemovableDeviceNotificationsWindowWinTest, DevicesAttachedLowBoundary) { 233 TEST_F(RemovableDeviceNotificationsWindowWinTest, DevicesAttachedLowBoundary) {
163 std::vector<int> device_indices; 234 std::vector<int> device_indices;
164 device_indices.push_back(0); 235 device_indices.push_back(0);
165 236
166 DoDevicesAttachedTest(device_indices); 237 DoDevicesAttachedTest(device_indices);
167 } 238 }
168 239
169 TEST_F(RemovableDeviceNotificationsWindowWinTest, DevicesAttachedAdjacentBits) { 240 TEST_F(RemovableDeviceNotificationsWindowWinTest, DevicesAttachedAdjacentBits) {
170 std::vector<int> device_indices; 241 std::vector<int> device_indices;
171 device_indices.push_back(0); 242 device_indices.push_back(0);
172 device_indices.push_back(1); 243 device_indices.push_back(1);
173 device_indices.push_back(2); 244 device_indices.push_back(2);
174 device_indices.push_back(3); 245 device_indices.push_back(3);
175 246
176 DoDevicesAttachedTest(device_indices); 247 DoDevicesAttachedTest(device_indices);
177 } 248 }
178 249
179 TEST_F(RemovableDeviceNotificationsWindowWinTest, DevicesDetached) { 250 TEST_F(RemovableDeviceNotificationsWindowWinTest, DevicesDetached) {
251 PreAttachDevices();
252
180 std::vector<int> device_indices; 253 std::vector<int> device_indices;
181 device_indices.push_back(1); 254 device_indices.push_back(1);
182 device_indices.push_back(5); 255 device_indices.push_back(5);
183 device_indices.push_back(7); 256 device_indices.push_back(7);
257 device_indices.push_back(13);
184 258
185 DoDevicesDetachedTest(device_indices); 259 DoDevicesDetachedTest(device_indices);
186 } 260 }
187 261
188 TEST_F(RemovableDeviceNotificationsWindowWinTest, DevicesDetachedHighBoundary) { 262 TEST_F(RemovableDeviceNotificationsWindowWinTest, DevicesDetachedHighBoundary) {
263 PreAttachDevices();
264
189 std::vector<int> device_indices; 265 std::vector<int> device_indices;
190 device_indices.push_back(25); 266 device_indices.push_back(25);
191 267
192 DoDevicesDetachedTest(device_indices); 268 DoDevicesDetachedTest(device_indices);
193 } 269 }
194 270
195 TEST_F(RemovableDeviceNotificationsWindowWinTest, DevicesDetachedLowBoundary) { 271 TEST_F(RemovableDeviceNotificationsWindowWinTest, DevicesDetachedLowBoundary) {
272 PreAttachDevices();
273
196 std::vector<int> device_indices; 274 std::vector<int> device_indices;
197 device_indices.push_back(0); 275 device_indices.push_back(0);
198 276
199 DoDevicesDetachedTest(device_indices); 277 DoDevicesDetachedTest(device_indices);
200 } 278 }
201 279
202 TEST_F(RemovableDeviceNotificationsWindowWinTest, DevicesDetachedAdjacentBits) { 280 TEST_F(RemovableDeviceNotificationsWindowWinTest, DevicesDetachedAdjacentBits) {
281 PreAttachDevices();
282
203 std::vector<int> device_indices; 283 std::vector<int> device_indices;
204 device_indices.push_back(0); 284 device_indices.push_back(0);
205 device_indices.push_back(1); 285 device_indices.push_back(1);
206 device_indices.push_back(2); 286 device_indices.push_back(2);
207 device_indices.push_back(3); 287 device_indices.push_back(3);
208 288
209 DoDevicesDetachedTest(device_indices); 289 DoDevicesDetachedTest(device_indices);
210 } 290 }
211 291
292 TEST_F(RemovableDeviceNotificationsWindowWinTest, DeviceInfoFoPath) {
293 PreAttachDevices();
294
295 // An invalid path.
296 EXPECT_FALSE(window_->GetDeviceInfoForPath(FilePath(L"COM1:\\"), NULL));
297
298 // An unconnected removable device.
299 EXPECT_FALSE(window_->GetDeviceInfoForPath(FilePath(L"E:\\"), NULL));
300
301 // A connected removable device.
302 FilePath removable_device(L"F:\\");
303 base::SystemMonitor::RemovableStorageInfo device_info;
304 EXPECT_TRUE(window_->GetDeviceInfoForPath(removable_device, &device_info));
305
306 std::string unique_id;
307 string16 device_name;
308 bool removable;
309 ASSERT_TRUE(GetDeviceInfo(removable_device, NULL, &unique_id, &device_name,
310 &removable));
311 EXPECT_TRUE(removable);
312 std::string device_id = MediaStorageUtil::MakeDeviceId(
313 MediaStorageUtil::REMOVABLE_MASS_STORAGE_NO_DCIM, unique_id);
314 EXPECT_EQ(device_id, device_info.device_id);
315 EXPECT_EQ(device_name, device_info.name);
316 EXPECT_EQ(removable_device.value(), device_info.location);
317
318 // A fixed device.
319 FilePath fixed_device(L"N:\\");
320 EXPECT_TRUE(window_->GetDeviceInfoForPath(fixed_device, &device_info));
321
322 ASSERT_TRUE(GetDeviceInfo(fixed_device, NULL, &unique_id, &device_name,
323 &removable));
324 EXPECT_FALSE(removable);
325 device_id = MediaStorageUtil::MakeDeviceId(
326 MediaStorageUtil::FIXED_MASS_STORAGE, unique_id);
327 EXPECT_EQ(device_id, device_info.device_id);
328 EXPECT_EQ(device_name, device_info.name);
329 EXPECT_EQ(fixed_device.value(), device_info.location);
330 }
331
212 } // namespace chrome 332 } // namespace chrome
OLDNEW
« no previous file with comments | « chrome/browser/system_monitor/removable_device_notifications_window_win.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698