[Autofill] remove *MultiInfo* functions
[chromium-blink-merge.git] / components / storage_monitor / storage_monitor_win_unittest.cc
blob1db435f717a01e408967fd399692dbce19c32f53
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.
5 #include <windows.h>
6 #include <dbt.h>
8 #include <string>
9 #include <vector>
11 #include "base/memory/ref_counted.h"
12 #include "base/memory/scoped_ptr.h"
13 #include "base/run_loop.h"
14 #include "base/strings/utf_string_conversions.h"
15 #include "base/synchronization/waitable_event.h"
16 #include "components/storage_monitor/mock_removable_storage_observer.h"
17 #include "components/storage_monitor/portable_device_watcher_win.h"
18 #include "components/storage_monitor/removable_device_constants.h"
19 #include "components/storage_monitor/storage_info.h"
20 #include "components/storage_monitor/storage_monitor_win.h"
21 #include "components/storage_monitor/test_portable_device_watcher_win.h"
22 #include "components/storage_monitor/test_storage_monitor.h"
23 #include "components/storage_monitor/test_storage_monitor_win.h"
24 #include "components/storage_monitor/test_volume_mount_watcher_win.h"
25 #include "components/storage_monitor/volume_mount_watcher_win.h"
26 #include "content/public/browser/browser_thread.h"
27 #include "content/public/test/test_browser_thread_bundle.h"
28 #include "testing/gtest/include/gtest/gtest.h"
30 using base::ASCIIToUTF16;
31 using content::BrowserThread;
33 typedef std::vector<int> DeviceIndices;
35 // StorageMonitorWinTest -------------------------------------------------------
37 namespace storage_monitor {
39 class StorageMonitorWinTest : public testing::Test {
40 public:
41 StorageMonitorWinTest();
42 ~StorageMonitorWinTest() override;
44 protected:
45 // testing::Test:
46 void SetUp() override;
47 void TearDown() override;
49 void PreAttachDevices();
51 // Runs all the pending tasks on UI thread, FILE thread and blocking thread.
52 void RunUntilIdle();
54 void DoMassStorageDeviceAttachedTest(const DeviceIndices& device_indices);
55 void DoMassStorageDevicesDetachedTest(const DeviceIndices& device_indices);
57 // Injects a device attach or detach change (depending on the value of
58 // |test_attach|) and tests that the appropriate handler is called.
59 void DoMTPDeviceTest(const base::string16& pnp_device_id, bool test_attach);
61 // Gets the MTP details of the storage specified by the |storage_device_id|.
62 // On success, returns true and fills in |pnp_device_id| and
63 // |storage_object_id|.
64 bool GetMTPStorageInfo(const std::string& storage_device_id,
65 base::string16* pnp_device_id,
66 base::string16* storage_object_id);
68 scoped_ptr<TestStorageMonitorWin> monitor_;
70 // Weak pointer; owned by the device notifications class.
71 TestVolumeMountWatcherWin* volume_mount_watcher_;
73 MockRemovableStorageObserver observer_;
75 private:
76 content::TestBrowserThreadBundle thread_bundle_;
78 DISALLOW_COPY_AND_ASSIGN(StorageMonitorWinTest);
81 StorageMonitorWinTest::StorageMonitorWinTest() {
84 StorageMonitorWinTest::~StorageMonitorWinTest() {
87 void StorageMonitorWinTest::SetUp() {
88 volume_mount_watcher_ = new TestVolumeMountWatcherWin;
89 monitor_.reset(new TestStorageMonitorWin(volume_mount_watcher_,
90 new TestPortableDeviceWatcherWin));
92 monitor_->Init();
93 RunUntilIdle();
94 monitor_->AddObserver(&observer_);
97 void StorageMonitorWinTest::TearDown() {
98 RunUntilIdle();
99 monitor_->RemoveObserver(&observer_);
101 // Windows storage monitor must be destroyed on the same thread
102 // as construction.
103 monitor_.reset();
106 void StorageMonitorWinTest::PreAttachDevices() {
107 monitor_.reset();
108 volume_mount_watcher_ = new TestVolumeMountWatcherWin;
109 volume_mount_watcher_->SetAttachedDevicesFake();
111 int expect_attach_calls = 0;
112 std::vector<base::FilePath> initial_devices =
113 volume_mount_watcher_->GetAttachedDevicesCallback().Run();
114 for (std::vector<base::FilePath>::const_iterator it = initial_devices.begin();
115 it != initial_devices.end(); ++it) {
116 bool removable;
117 ASSERT_TRUE(volume_mount_watcher_->GetDeviceRemovable(*it, &removable));
118 if (removable)
119 expect_attach_calls++;
122 monitor_.reset(new TestStorageMonitorWin(volume_mount_watcher_,
123 new TestPortableDeviceWatcherWin));
125 monitor_->AddObserver(&observer_);
126 monitor_->Init();
128 EXPECT_EQ(0u, volume_mount_watcher_->devices_checked().size());
130 // This dance is because attachment bounces through a couple of
131 // closures, which need to be executed to finish the process.
132 RunUntilIdle();
133 volume_mount_watcher_->FlushWorkerPoolForTesting();
134 RunUntilIdle();
136 std::vector<base::FilePath> checked_devices =
137 volume_mount_watcher_->devices_checked();
138 sort(checked_devices.begin(), checked_devices.end());
139 EXPECT_EQ(initial_devices, checked_devices);
140 EXPECT_EQ(expect_attach_calls, observer_.attach_calls());
141 EXPECT_EQ(0, observer_.detach_calls());
144 void StorageMonitorWinTest::RunUntilIdle() {
145 volume_mount_watcher_->FlushWorkerPoolForTesting();
146 base::RunLoop().RunUntilIdle();
149 void StorageMonitorWinTest::DoMassStorageDeviceAttachedTest(
150 const DeviceIndices& device_indices) {
151 DEV_BROADCAST_VOLUME volume_broadcast;
152 volume_broadcast.dbcv_size = sizeof(volume_broadcast);
153 volume_broadcast.dbcv_devicetype = DBT_DEVTYP_VOLUME;
154 volume_broadcast.dbcv_unitmask = 0x0;
155 volume_broadcast.dbcv_flags = 0x0;
157 int expect_attach_calls = observer_.attach_calls();
158 for (DeviceIndices::const_iterator it = device_indices.begin();
159 it != device_indices.end(); ++it) {
160 volume_broadcast.dbcv_unitmask |= 0x1 << *it;
161 bool removable;
162 ASSERT_TRUE(volume_mount_watcher_->GetDeviceRemovable(
163 VolumeMountWatcherWin::DriveNumberToFilePath(*it), &removable));
164 if (removable)
165 expect_attach_calls++;
167 monitor_->InjectDeviceChange(DBT_DEVICEARRIVAL,
168 reinterpret_cast<DWORD>(&volume_broadcast));
170 RunUntilIdle();
171 volume_mount_watcher_->FlushWorkerPoolForTesting();
172 RunUntilIdle();
174 EXPECT_EQ(expect_attach_calls, observer_.attach_calls());
175 EXPECT_EQ(0, observer_.detach_calls());
178 void StorageMonitorWinTest::DoMassStorageDevicesDetachedTest(
179 const DeviceIndices& device_indices) {
180 DEV_BROADCAST_VOLUME volume_broadcast;
181 volume_broadcast.dbcv_size = sizeof(volume_broadcast);
182 volume_broadcast.dbcv_devicetype = DBT_DEVTYP_VOLUME;
183 volume_broadcast.dbcv_unitmask = 0x0;
184 volume_broadcast.dbcv_flags = 0x0;
186 int pre_attach_calls = observer_.attach_calls();
187 int expect_detach_calls = 0;
188 for (DeviceIndices::const_iterator it = device_indices.begin();
189 it != device_indices.end(); ++it) {
190 volume_broadcast.dbcv_unitmask |= 0x1 << *it;
191 StorageInfo info;
192 ASSERT_TRUE(volume_mount_watcher_->GetDeviceInfo(
193 VolumeMountWatcherWin::DriveNumberToFilePath(*it), &info));
194 if (StorageInfo::IsRemovableDevice(info.device_id()))
195 ++expect_detach_calls;
197 monitor_->InjectDeviceChange(DBT_DEVICEREMOVECOMPLETE,
198 reinterpret_cast<DWORD>(&volume_broadcast));
199 RunUntilIdle();
200 EXPECT_EQ(pre_attach_calls, observer_.attach_calls());
201 EXPECT_EQ(expect_detach_calls, observer_.detach_calls());
204 void StorageMonitorWinTest::DoMTPDeviceTest(const base::string16& pnp_device_id,
205 bool test_attach) {
206 GUID guidDevInterface = GUID_NULL;
207 HRESULT hr = CLSIDFromString(kWPDDevInterfaceGUID, &guidDevInterface);
208 if (FAILED(hr))
209 return;
211 size_t device_id_size = pnp_device_id.size() * sizeof(base::char16);
212 size_t size = sizeof(DEV_BROADCAST_DEVICEINTERFACE) + device_id_size;
213 scoped_ptr<DEV_BROADCAST_DEVICEINTERFACE, base::FreeDeleter>
214 dev_interface_broadcast(
215 static_cast<DEV_BROADCAST_DEVICEINTERFACE*>(malloc(size)));
216 DCHECK(dev_interface_broadcast.get());
217 ZeroMemory(dev_interface_broadcast.get(), size);
218 dev_interface_broadcast->dbcc_size = size;
219 dev_interface_broadcast->dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
220 dev_interface_broadcast->dbcc_classguid = guidDevInterface;
221 memcpy(dev_interface_broadcast->dbcc_name, pnp_device_id.data(),
222 device_id_size);
224 int expect_attach_calls = observer_.attach_calls();
225 int expect_detach_calls = observer_.detach_calls();
226 PortableDeviceWatcherWin::StorageObjectIDs storage_object_ids =
227 TestPortableDeviceWatcherWin::GetMTPStorageObjectIds(pnp_device_id);
228 for (PortableDeviceWatcherWin::StorageObjectIDs::const_iterator it =
229 storage_object_ids.begin(); it != storage_object_ids.end(); ++it) {
230 std::string unique_id;
231 base::string16 name;
232 base::string16 location;
233 TestPortableDeviceWatcherWin::GetMTPStorageDetails(pnp_device_id, *it,
234 &location, &unique_id,
235 &name);
236 if (test_attach && !name.empty() && !unique_id.empty())
237 expect_attach_calls++;
238 else if (!name.empty() && !unique_id.empty())
239 expect_detach_calls++;
242 monitor_->InjectDeviceChange(
243 test_attach ? DBT_DEVICEARRIVAL : DBT_DEVICEREMOVECOMPLETE,
244 reinterpret_cast<DWORD>(dev_interface_broadcast.get()));
246 RunUntilIdle();
247 EXPECT_EQ(expect_attach_calls, observer_.attach_calls());
248 EXPECT_EQ(expect_detach_calls, observer_.detach_calls());
251 bool StorageMonitorWinTest::GetMTPStorageInfo(
252 const std::string& storage_device_id,
253 base::string16* pnp_device_id,
254 base::string16* storage_object_id) {
255 return monitor_->GetMTPStorageInfoFromDeviceId(storage_device_id,
256 pnp_device_id,
257 storage_object_id);
260 TEST_F(StorageMonitorWinTest, RandomMessage) {
261 monitor_->InjectDeviceChange(DBT_DEVICEQUERYREMOVE, NULL);
262 RunUntilIdle();
265 TEST_F(StorageMonitorWinTest, DevicesAttached) {
266 DeviceIndices device_indices;
267 device_indices.push_back(1); // B
268 device_indices.push_back(5); // F
269 device_indices.push_back(7); // H
270 device_indices.push_back(13); // N
271 DoMassStorageDeviceAttachedTest(device_indices);
273 StorageInfo info;
274 EXPECT_TRUE(monitor_->volume_mount_watcher()->GetDeviceInfo(
275 base::FilePath(ASCIIToUTF16("F:\\")), &info));
276 EXPECT_EQ(ASCIIToUTF16("F:\\"), info.location());
277 EXPECT_EQ("dcim:\\\\?\\Volume{F0000000-0000-0000-0000-000000000000}\\",
278 info.device_id());
279 EXPECT_EQ(ASCIIToUTF16("F:\\ Drive"), info.storage_label());
281 EXPECT_FALSE(monitor_->GetStorageInfoForPath(
282 base::FilePath(ASCIIToUTF16("G:\\")), &info));
283 EXPECT_TRUE(monitor_->GetStorageInfoForPath(
284 base::FilePath(ASCIIToUTF16("F:\\")), &info));
285 StorageInfo info1;
286 EXPECT_TRUE(monitor_->GetStorageInfoForPath(
287 base::FilePath(ASCIIToUTF16("F:\\subdir")), &info1));
288 StorageInfo info2;
289 EXPECT_TRUE(monitor_->GetStorageInfoForPath(
290 base::FilePath(ASCIIToUTF16("F:\\subdir\\sub")), &info2));
291 EXPECT_EQ(ASCIIToUTF16("F:\\ Drive"), info.storage_label());
292 EXPECT_EQ(ASCIIToUTF16("F:\\ Drive"), info1.storage_label());
293 EXPECT_EQ(ASCIIToUTF16("F:\\ Drive"), info2.storage_label());
296 TEST_F(StorageMonitorWinTest, PathMountDevices) {
297 PreAttachDevices();
298 int init_storages = monitor_->GetAllAvailableStorages().size();
300 volume_mount_watcher_->AddDeviceForTesting(
301 base::FilePath(FILE_PATH_LITERAL("F:\\mount1")),
302 "dcim:mount1", L"mount1", 100);
303 volume_mount_watcher_->AddDeviceForTesting(
304 base::FilePath(FILE_PATH_LITERAL("F:\\mount1\\subdir")),
305 "dcim:mount1subdir", L"mount1subdir", 100);
306 volume_mount_watcher_->AddDeviceForTesting(
307 base::FilePath(FILE_PATH_LITERAL("F:\\mount2")),
308 "dcim:mount2", L"mount2", 100);
309 RunUntilIdle();
310 EXPECT_EQ(init_storages + 3, monitor_->GetAllAvailableStorages().size());
312 StorageInfo info;
313 EXPECT_TRUE(monitor_->GetStorageInfoForPath(
314 base::FilePath(ASCIIToUTF16("F:\\dir")), &info));
315 EXPECT_EQ(L"F:\\ Drive", info.GetDisplayName(false));
316 EXPECT_TRUE(monitor_->GetStorageInfoForPath(
317 base::FilePath(ASCIIToUTF16("F:\\mount1")), &info));
318 EXPECT_EQ(L"mount1", info.GetDisplayName(false));
319 EXPECT_TRUE(monitor_->GetStorageInfoForPath(
320 base::FilePath(ASCIIToUTF16("F:\\mount1\\dir")), &info));
321 EXPECT_EQ(L"mount1", info.GetDisplayName(false));
322 EXPECT_TRUE(monitor_->GetStorageInfoForPath(
323 base::FilePath(ASCIIToUTF16("F:\\mount2\\dir")), &info));
324 EXPECT_EQ(L"mount2", info.GetDisplayName(false));
325 EXPECT_TRUE(monitor_->GetStorageInfoForPath(
326 base::FilePath(ASCIIToUTF16("F:\\mount1\\subdir")), &info));
327 EXPECT_EQ(L"mount1subdir", info.GetDisplayName(false));
328 EXPECT_TRUE(monitor_->GetStorageInfoForPath(
329 base::FilePath(ASCIIToUTF16("F:\\mount1\\subdir\\dir")), &info));
330 EXPECT_EQ(L"mount1subdir", info.GetDisplayName(false));
331 EXPECT_TRUE(monitor_->GetStorageInfoForPath(
332 base::FilePath(ASCIIToUTF16("F:\\mount1\\subdir\\dir\\dir")), &info));
333 EXPECT_EQ(L"mount1subdir", info.GetDisplayName(false));
336 TEST_F(StorageMonitorWinTest, DevicesAttachedHighBoundary) {
337 DeviceIndices device_indices;
338 device_indices.push_back(25);
340 DoMassStorageDeviceAttachedTest(device_indices);
343 TEST_F(StorageMonitorWinTest, DevicesAttachedLowBoundary) {
344 DeviceIndices device_indices;
345 device_indices.push_back(0);
347 DoMassStorageDeviceAttachedTest(device_indices);
350 TEST_F(StorageMonitorWinTest, DevicesAttachedAdjacentBits) {
351 DeviceIndices device_indices;
352 device_indices.push_back(0);
353 device_indices.push_back(1);
354 device_indices.push_back(2);
355 device_indices.push_back(3);
357 DoMassStorageDeviceAttachedTest(device_indices);
360 TEST_F(StorageMonitorWinTest, DevicesDetached) {
361 PreAttachDevices();
363 DeviceIndices device_indices;
364 device_indices.push_back(1);
365 device_indices.push_back(5);
366 device_indices.push_back(7);
367 device_indices.push_back(13);
369 DoMassStorageDevicesDetachedTest(device_indices);
372 TEST_F(StorageMonitorWinTest, DevicesDetachedHighBoundary) {
373 PreAttachDevices();
375 DeviceIndices device_indices;
376 device_indices.push_back(25);
378 DoMassStorageDevicesDetachedTest(device_indices);
381 TEST_F(StorageMonitorWinTest, DevicesDetachedLowBoundary) {
382 PreAttachDevices();
384 DeviceIndices device_indices;
385 device_indices.push_back(0);
387 DoMassStorageDevicesDetachedTest(device_indices);
390 TEST_F(StorageMonitorWinTest, DevicesDetachedAdjacentBits) {
391 PreAttachDevices();
393 DeviceIndices device_indices;
394 device_indices.push_back(0);
395 device_indices.push_back(1);
396 device_indices.push_back(2);
397 device_indices.push_back(3);
399 DoMassStorageDevicesDetachedTest(device_indices);
402 TEST_F(StorageMonitorWinTest, DuplicateAttachCheckSuppressed) {
403 // Make sure the original C: mount notification makes it all the
404 // way through.
405 RunUntilIdle();
406 volume_mount_watcher_->FlushWorkerPoolForTesting();
407 RunUntilIdle();
409 volume_mount_watcher_->BlockDeviceCheckForTesting();
410 base::FilePath kAttachedDevicePath =
411 VolumeMountWatcherWin::DriveNumberToFilePath(8); // I:
413 DEV_BROADCAST_VOLUME volume_broadcast;
414 volume_broadcast.dbcv_size = sizeof(volume_broadcast);
415 volume_broadcast.dbcv_devicetype = DBT_DEVTYP_VOLUME;
416 volume_broadcast.dbcv_flags = 0x0;
417 volume_broadcast.dbcv_unitmask = 0x100; // I: drive
418 monitor_->InjectDeviceChange(DBT_DEVICEARRIVAL,
419 reinterpret_cast<DWORD>(&volume_broadcast));
421 EXPECT_EQ(0u, volume_mount_watcher_->devices_checked().size());
423 // Re-attach the same volume. We haven't released the mock device check
424 // event, so there'll be pending calls in the UI thread to finish the
425 // device check notification, blocking the duplicate device injection.
426 monitor_->InjectDeviceChange(DBT_DEVICEARRIVAL,
427 reinterpret_cast<DWORD>(&volume_broadcast));
429 EXPECT_EQ(0u, volume_mount_watcher_->devices_checked().size());
430 volume_mount_watcher_->ReleaseDeviceCheck();
431 RunUntilIdle();
432 volume_mount_watcher_->ReleaseDeviceCheck();
434 // Now let all attach notifications finish running. We'll only get one
435 // finish-attach call.
436 volume_mount_watcher_->FlushWorkerPoolForTesting();
437 RunUntilIdle();
439 const std::vector<base::FilePath>& checked_devices =
440 volume_mount_watcher_->devices_checked();
441 ASSERT_EQ(1u, checked_devices.size());
442 EXPECT_EQ(kAttachedDevicePath, checked_devices[0]);
444 // We'll receive a duplicate check now that the first check has fully cleared.
445 monitor_->InjectDeviceChange(DBT_DEVICEARRIVAL,
446 reinterpret_cast<DWORD>(&volume_broadcast));
447 volume_mount_watcher_->FlushWorkerPoolForTesting();
448 volume_mount_watcher_->ReleaseDeviceCheck();
449 RunUntilIdle();
451 ASSERT_EQ(2u, checked_devices.size());
452 EXPECT_EQ(kAttachedDevicePath, checked_devices[0]);
453 EXPECT_EQ(kAttachedDevicePath, checked_devices[1]);
456 TEST_F(StorageMonitorWinTest, DeviceInfoForPath) {
457 PreAttachDevices();
459 StorageInfo device_info;
460 // An invalid path.
461 EXPECT_FALSE(monitor_->GetStorageInfoForPath(base::FilePath(L"COM1:\\"),
462 &device_info));
464 // An unconnected removable device.
465 EXPECT_FALSE(monitor_->GetStorageInfoForPath(base::FilePath(L"E:\\"),
466 &device_info));
468 // A connected removable device.
469 base::FilePath removable_device(L"F:\\");
470 EXPECT_TRUE(monitor_->GetStorageInfoForPath(removable_device, &device_info));
472 StorageInfo info;
473 ASSERT_TRUE(volume_mount_watcher_->GetDeviceInfo(removable_device, &info));
474 EXPECT_TRUE(StorageInfo::IsRemovableDevice(info.device_id()));
475 EXPECT_EQ(info.device_id(), device_info.device_id());
476 EXPECT_EQ(info.GetDisplayName(false), device_info.GetDisplayName(false));
477 EXPECT_EQ(info.location(), device_info.location());
478 EXPECT_EQ(1000000, info.total_size_in_bytes());
480 // A fixed device.
481 base::FilePath fixed_device(L"N:\\");
482 EXPECT_TRUE(monitor_->GetStorageInfoForPath(fixed_device, &device_info));
484 ASSERT_TRUE(volume_mount_watcher_->GetDeviceInfo(
485 fixed_device, &info));
486 EXPECT_FALSE(StorageInfo::IsRemovableDevice(info.device_id()));
487 EXPECT_EQ(info.device_id(), device_info.device_id());
488 EXPECT_EQ(info.GetDisplayName(false), device_info.GetDisplayName(false));
489 EXPECT_EQ(info.location(), device_info.location());
492 // Test to verify basic MTP storage attach and detach notifications.
493 TEST_F(StorageMonitorWinTest, MTPDeviceBasicAttachDetach) {
494 DoMTPDeviceTest(TestPortableDeviceWatcherWin::kMTPDeviceWithValidInfo, true);
495 DoMTPDeviceTest(TestPortableDeviceWatcherWin::kMTPDeviceWithValidInfo, false);
498 // When a MTP storage device with invalid storage label and id is
499 // attached/detached, there should not be any device attach/detach
500 // notifications.
501 TEST_F(StorageMonitorWinTest, MTPDeviceWithInvalidInfo) {
502 DoMTPDeviceTest(TestPortableDeviceWatcherWin::kMTPDeviceWithInvalidInfo,
503 true);
504 DoMTPDeviceTest(TestPortableDeviceWatcherWin::kMTPDeviceWithInvalidInfo,
505 false);
508 // Attach a device with two data partitions. Verify that attach/detach
509 // notifications are sent out for each removable storage.
510 TEST_F(StorageMonitorWinTest, MTPDeviceWithMultipleStorageObjects) {
511 DoMTPDeviceTest(TestPortableDeviceWatcherWin::kMTPDeviceWithMultipleStorages,
512 true);
513 DoMTPDeviceTest(TestPortableDeviceWatcherWin::kMTPDeviceWithMultipleStorages,
514 false);
517 TEST_F(StorageMonitorWinTest, DriveNumberToFilePath) {
518 EXPECT_EQ(L"A:\\", VolumeMountWatcherWin::DriveNumberToFilePath(0).value());
519 EXPECT_EQ(L"Y:\\", VolumeMountWatcherWin::DriveNumberToFilePath(24).value());
520 EXPECT_EQ(L"", VolumeMountWatcherWin::DriveNumberToFilePath(-1).value());
521 EXPECT_EQ(L"", VolumeMountWatcherWin::DriveNumberToFilePath(199).value());
524 // Given a MTP storage persistent id, GetMTPStorageInfo() should fetch the
525 // device interface path and local storage object identifier.
526 TEST_F(StorageMonitorWinTest, GetMTPStorageInfoFromDeviceId) {
527 DoMTPDeviceTest(TestPortableDeviceWatcherWin::kMTPDeviceWithValidInfo, true);
528 PortableDeviceWatcherWin::StorageObjects storage_objects =
529 TestPortableDeviceWatcherWin::GetDeviceStorageObjects(
530 TestPortableDeviceWatcherWin::kMTPDeviceWithValidInfo);
531 for (PortableDeviceWatcherWin::StorageObjects::const_iterator it =
532 storage_objects.begin();
533 it != storage_objects.end(); ++it) {
534 base::string16 pnp_device_id;
535 base::string16 storage_object_id;
536 ASSERT_TRUE(GetMTPStorageInfo(it->object_persistent_id, &pnp_device_id,
537 &storage_object_id));
538 base::string16 expected(
539 TestPortableDeviceWatcherWin::kMTPDeviceWithValidInfo);
540 EXPECT_EQ(expected, pnp_device_id);
541 EXPECT_EQ(it->object_persistent_id,
542 TestPortableDeviceWatcherWin::GetMTPStorageUniqueId(
543 pnp_device_id, storage_object_id));
545 DoMTPDeviceTest(TestPortableDeviceWatcherWin::kMTPDeviceWithValidInfo, false);
548 } // namespace storage_monitor