diff options
12 files changed, 504 insertions, 320 deletions
diff --git a/chrome/browser/system_monitor/portable_device_watcher_win.h b/chrome/browser/system_monitor/portable_device_watcher_win.h index 4b95af4..86f1535 100644 --- a/chrome/browser/system_monitor/portable_device_watcher_win.h +++ b/chrome/browser/system_monitor/portable_device_watcher_win.h @@ -24,6 +24,10 @@ class FilePath; namespace chrome { +namespace test { +class TestPortableDeviceWatcherWin; +} + // This class watches the portable device mount points and sends notifications // to base::SystemMonitor about the attached/detached media transfer protocol // (MTP) devices. This is a singleton class instantiated by @@ -83,7 +87,7 @@ class PortableDeviceWatcherWin { string16* storage_object_id); private: - friend class TestPortableDeviceWatcherWin; + friend class test::TestPortableDeviceWatcherWin; // Key: MTP device storage unique id. // Value: Metadata for the given storage. @@ -96,13 +100,13 @@ class PortableDeviceWatcherWin { // Helpers to enumerate existing MTP storage devices. virtual void EnumerateAttachedDevices(); - virtual void OnDidEnumerateAttachedDevices(const Devices* devices, - const bool result); + void OnDidEnumerateAttachedDevices(const Devices* devices, + const bool result); // Helpers to handle device attach event. virtual void HandleDeviceAttachEvent(const string16& pnp_device_id); - virtual void OnDidHandleDeviceAttachEvent( - const DeviceDetails* device_details, const bool result); + void OnDidHandleDeviceAttachEvent(const DeviceDetails* device_details, + const bool result); // Handles the detach event of the device specified by |pnp_device_id|. void HandleDeviceDetachEvent(const string16& pnp_device_id); diff --git a/chrome/browser/system_monitor/removable_device_notifications_window_win.h b/chrome/browser/system_monitor/removable_device_notifications_window_win.h index b88a1f4..5bc5a99 100644 --- a/chrome/browser/system_monitor/removable_device_notifications_window_win.h +++ b/chrome/browser/system_monitor/removable_device_notifications_window_win.h @@ -15,6 +15,10 @@ class FilePath; namespace chrome { +namespace test { +class TestRemovableDeviceNotificationsWindowWin; +} + class PortableDeviceWatcherWin; class VolumeMountWatcherWin; @@ -42,7 +46,7 @@ class RemovableDeviceNotificationsWindowWin private: class PortableDeviceNotifications; - friend class TestRemovableDeviceNotificationsWindowWin; + friend class test::TestRemovableDeviceNotificationsWindowWin; // To support unit tests, this constructor takes |volume_mount_watcher| and // |portable_device_watcher| objects. These params are either constructed in 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 56e58e2..81514e2 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 @@ -2,304 +2,34 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/system_monitor/removable_device_notifications_window_win.h" - +#include <windows.h> #include <dbt.h> #include <string> #include <vector> -#include "base/file_util.h" -#include "base/files/scoped_temp_dir.h" #include "base/memory/ref_counted.h" #include "base/memory/scoped_ptr.h" #include "base/message_loop.h" #include "base/system_monitor/system_monitor.h" #include "base/test/mock_devices_changed_observer.h" -#include "base/utf_string_conversions.h" #include "chrome/browser/system_monitor/media_storage_util.h" #include "chrome/browser/system_monitor/portable_device_watcher_win.h" #include "chrome/browser/system_monitor/removable_device_constants.h" +#include "chrome/browser/system_monitor/test_portable_device_watcher_win.h" +#include "chrome/browser/system_monitor/test_removable_device_notifications_window_win.h" +#include "chrome/browser/system_monitor/test_volume_mount_watcher_win.h" #include "chrome/browser/system_monitor/volume_mount_watcher_win.h" #include "content/public/test/test_browser_thread.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" namespace chrome { - -typedef std::vector<int> DeviceIndices; -typedef std::vector<FilePath> AttachedDevices; - -namespace { +namespace test { using content::BrowserThread; -// MTP device interface path constants. -const char16 kMTPDeviceWithInvalidInfo[] = - L"\\?\usb#vid_00&pid_00#0&2&1#{0000-0000-0000-0000-0000})"; -const char16 kMTPDeviceWithValidInfo[] = - L"\\?\usb#vid_ff&pid_000f#32&2&1#{abcd-1234-ffde-1112-9172})"; -const char16 kMTPDeviceWithMultipleStorageObjects[] = - L"\\?\usb#vid_ff&pid_18#32&2&1#{ab33-1de4-f22e-1882-9724})"; - -// Sample MTP device storage information. -const char16 kMTPDeviceFriendlyName[] = L"Camera V1.1"; -const char16 kStorageLabelA[] = L"Camera V1.1 (s10001)"; -const char16 kStorageLabelB[] = L"Camera V1.1 (s20001)"; -const char16 kStorageObjectIdA[] = L"s10001"; -const char16 kStorageObjectIdB[] = L"s20001"; -const char kStorageUniqueIdA[] = - "mtp:StorageSerial:SID-{s10001, D, 12378}:123123"; -const char kStorageUniqueIdB[] = - "mtp:StorageSerial:SID-{s20001, S, 2238}:123123"; - -// Inputs of 'A:\' - 'Z:\' are valid. 'N:\' is not removable. -bool GetMassStorageDeviceDetails(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); -} - -AttachedDevices GetTestAttachedDevices() { - AttachedDevices 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; -} - -// Returns the persistent storage unique id of the device specified by the -// |pnp_device_id|. |storage_object_id| specifies the temporary object -// identifier that uniquely identifies the object on the device. -std::string GetMTPStorageUniqueId(const string16& pnp_device_id, - const string16& storage_object_id) { - if (storage_object_id == kStorageObjectIdA) - return kStorageUniqueIdA; - return (storage_object_id == kStorageObjectIdB) ? - kStorageUniqueIdB : std::string(); -} - -// Returns the storage name of the device specified by |pnp_device_id|. -// |storage_object_id| specifies the temporary object identifier that -// uniquely identifies the object on the device. -string16 GetMTPStorageName(const string16& pnp_device_id, - const string16& storage_object_id) { - if (pnp_device_id == kMTPDeviceWithInvalidInfo) - return string16(); - - if (storage_object_id == kStorageObjectIdA) - return kStorageLabelA; - return (storage_object_id == kStorageObjectIdB) ? - kStorageLabelB : string16(); -} - -// Returns a list of storage object identifiers of the device given a -// |pnp_device_id|. -PortableDeviceWatcherWin::StorageObjectIDs GetMTPStorageObjectIds( - const string16& pnp_device_id) { - PortableDeviceWatcherWin::StorageObjectIDs storage_object_ids; - storage_object_ids.push_back(kStorageObjectIdA); - if (pnp_device_id == kMTPDeviceWithMultipleStorageObjects) - storage_object_ids.push_back(kStorageObjectIdB); - return storage_object_ids; -} - -// Gets the MTP device storage details given a |pnp_device_id| and -// |storage_object_id|. On success, returns true and fills in -// |device_location|, |unique_id| and |name|. -void GetMTPStorageDetails(const string16& pnp_device_id, - const string16& storage_object_id, - string16* device_location, - std::string* unique_id, - string16* name) { - std::string storage_unique_id = GetMTPStorageUniqueId(pnp_device_id, - storage_object_id); - - if (device_location) - *device_location = UTF8ToUTF16("\\\\" + storage_unique_id); - - if (unique_id) - *unique_id = storage_unique_id; - - if (name) - *name = GetMTPStorageName(pnp_device_id, storage_object_id); -} - -// Returns a list of device storage details for the given device specified by -// |pnp_device_id|. -PortableDeviceWatcherWin::StorageObjects GetDeviceStorageObjects( - const string16& pnp_device_id) { - PortableDeviceWatcherWin::StorageObjects storage_objects; - PortableDeviceWatcherWin::StorageObjectIDs storage_object_ids = - GetMTPStorageObjectIds(pnp_device_id); - for (PortableDeviceWatcherWin::StorageObjectIDs::const_iterator it = - storage_object_ids.begin(); it != storage_object_ids.end(); ++it) { - storage_objects.push_back(PortableDeviceWatcherWin::DeviceStorageObject( - *it, GetMTPStorageUniqueId(pnp_device_id, *it))); - } - return storage_objects; -} - -} // namespace - - -// TestPortableDeviceWatcherWin ----------------------------------------------- - -class TestPortableDeviceWatcherWin : public PortableDeviceWatcherWin { - public: - TestPortableDeviceWatcherWin(); - virtual ~TestPortableDeviceWatcherWin(); - - private: - // PortableDeviceWatcherWin: - virtual void EnumerateAttachedDevices() OVERRIDE; - virtual void HandleDeviceAttachEvent(const string16& pnp_device_id) OVERRIDE; - - DISALLOW_COPY_AND_ASSIGN(TestPortableDeviceWatcherWin); -}; - -TestPortableDeviceWatcherWin::TestPortableDeviceWatcherWin() { -} - -TestPortableDeviceWatcherWin::~TestPortableDeviceWatcherWin() { -} - -void TestPortableDeviceWatcherWin::EnumerateAttachedDevices() { -} - -void TestPortableDeviceWatcherWin::HandleDeviceAttachEvent( - const string16& pnp_device_id) { - DeviceDetails device_details = { - (pnp_device_id != kMTPDeviceWithInvalidInfo) ? - kMTPDeviceFriendlyName : string16(), - pnp_device_id, - GetDeviceStorageObjects(pnp_device_id) - }; - OnDidHandleDeviceAttachEvent(&device_details, true); -} - - -// TestVolumeMountWatcherWin -------------------------------------------------- - -class TestVolumeMountWatcherWin : public VolumeMountWatcherWin { - public: - TestVolumeMountWatcherWin(); - - void set_pre_attach_devices(bool pre_attach_devices) { - pre_attach_devices_ = pre_attach_devices; - } - - private: - // Private, this class is ref-counted. - virtual ~TestVolumeMountWatcherWin(); - - // VolumeMountWatcherWin: - virtual bool GetDeviceInfo(const FilePath& device_path, - string16* device_location, - std::string* unique_id, - string16* name, - bool* removable) OVERRIDE; - virtual AttachedDevices GetAttachedDevices() OVERRIDE; - - // Set to true to pre-attach test devices. - bool pre_attach_devices_; - - DISALLOW_COPY_AND_ASSIGN(TestVolumeMountWatcherWin); -}; - -TestVolumeMountWatcherWin::TestVolumeMountWatcherWin() - : pre_attach_devices_(false) { -} - -TestVolumeMountWatcherWin::~TestVolumeMountWatcherWin() { -} - -bool TestVolumeMountWatcherWin::GetDeviceInfo(const FilePath& device_path, - string16* device_location, - std::string* unique_id, - string16* name, - bool* removable) { - return GetMassStorageDeviceDetails(device_path, device_location, unique_id, - name, removable); -} - -AttachedDevices TestVolumeMountWatcherWin::GetAttachedDevices() { - return pre_attach_devices_ ? - GetTestAttachedDevices() : AttachedDevices(); -} - - -// TestRemovableDeviceNotificationsWindowWin ----------------------------------- - -class TestRemovableDeviceNotificationsWindowWin - : public RemovableDeviceNotificationsWindowWin { - public: - TestRemovableDeviceNotificationsWindowWin( - TestVolumeMountWatcherWin* volume_mount_watcher, - TestPortableDeviceWatcherWin* portable_device_watcher); - - virtual ~TestRemovableDeviceNotificationsWindowWin(); - - void InitWithTestData(bool pre_attach_devices); - void InjectDeviceChange(UINT event_type, DWORD data); - - private: - scoped_refptr<TestVolumeMountWatcherWin> volume_mount_watcher_; -}; - -TestRemovableDeviceNotificationsWindowWin:: - TestRemovableDeviceNotificationsWindowWin( - TestVolumeMountWatcherWin* volume_mount_watcher, - TestPortableDeviceWatcherWin* portable_device_watcher) - : RemovableDeviceNotificationsWindowWin(volume_mount_watcher, - portable_device_watcher), - volume_mount_watcher_(volume_mount_watcher) { - DCHECK(volume_mount_watcher_); -} - -TestRemovableDeviceNotificationsWindowWin:: - ~TestRemovableDeviceNotificationsWindowWin() { -} - -void TestRemovableDeviceNotificationsWindowWin::InitWithTestData( - bool pre_attach_devices) { - volume_mount_watcher_->set_pre_attach_devices(pre_attach_devices); - Init(); -} - -void TestRemovableDeviceNotificationsWindowWin::InjectDeviceChange( - UINT event_type, - DWORD data) { - OnDeviceChange(event_type, data); -} - +typedef std::vector<int> DeviceIndices; // RemovableDeviceNotificationsWindowWinTest ----------------------------------- @@ -313,7 +43,7 @@ class RemovableDeviceNotificationsWindowWinTest : public testing::Test { virtual void SetUp() OVERRIDE; virtual void TearDown() OVERRIDE; - void AddMassStorageDeviceAttachExpectation(FilePath drive); + void AddMassStorageDeviceAttachExpectation(const FilePath& drive); void PreAttachDevices(); // Runs all the pending tasks on UI thread, FILE thread and blocking thread. @@ -334,6 +64,7 @@ class RemovableDeviceNotificationsWindowWinTest : public testing::Test { string16* storage_object_id); scoped_ptr<TestRemovableDeviceNotificationsWindowWin> window_; + scoped_refptr<TestVolumeMountWatcherWin> volume_mount_watcher_; private: MessageLoopForUI message_loop_; @@ -342,7 +73,6 @@ class RemovableDeviceNotificationsWindowWinTest : public testing::Test { base::SystemMonitor system_monitor_; base::MockDevicesChangedObserver observer_; - scoped_refptr<TestVolumeMountWatcherWin> volume_mount_watcher_; }; RemovableDeviceNotificationsWindowWinTest:: @@ -371,12 +101,12 @@ void RemovableDeviceNotificationsWindowWinTest::TearDown() { } void RemovableDeviceNotificationsWindowWinTest:: - AddMassStorageDeviceAttachExpectation(FilePath drive) { + AddMassStorageDeviceAttachExpectation(const FilePath& drive) { std::string unique_id; string16 device_name; bool removable; - ASSERT_TRUE(GetMassStorageDeviceDetails(drive, NULL, &unique_id, - &device_name, &removable)); + ASSERT_TRUE(volume_mount_watcher_->GetDeviceInfo( + drive, NULL, &unique_id, &device_name, &removable)); if (removable) { MediaStorageUtil::Type type = MediaStorageUtil::REMOVABLE_MASS_STORAGE_NO_DCIM; @@ -391,8 +121,11 @@ void RemovableDeviceNotificationsWindowWinTest::PreAttachDevices() { window_.reset(); { testing::InSequence sequence; - AttachedDevices initial_devices = GetTestAttachedDevices(); - for (AttachedDevices::const_iterator it = initial_devices.begin(); + ASSERT_TRUE(volume_mount_watcher_.get()); + volume_mount_watcher_->set_pre_attach_devices(true); + std::vector<FilePath> initial_devices = + volume_mount_watcher_->GetAttachedDevices(); + for (std::vector<FilePath>::const_iterator it = initial_devices.begin(); it != initial_devices.end(); ++it) { AddMassStorageDeviceAttachExpectation(*it); } @@ -419,7 +152,8 @@ void RemovableDeviceNotificationsWindowWinTest:: for (DeviceIndices::const_iterator it = device_indices.begin(); it != device_indices.end(); ++it) { volume_broadcast.dbcv_unitmask |= 0x1 << *it; - AddMassStorageDeviceAttachExpectation(DriveNumberToFilePath(*it)); + AddMassStorageDeviceAttachExpectation( + VolumeMountWatcherWin::DriveNumberToFilePath(*it)); } } window_->InjectDeviceChange(DBT_DEVICEARRIVAL, @@ -441,8 +175,9 @@ void RemovableDeviceNotificationsWindowWinTest:: volume_broadcast.dbcv_unitmask |= 0x1 << *it; std::string unique_id; bool removable; - ASSERT_TRUE(GetMassStorageDeviceDetails(DriveNumberToFilePath(*it), NULL, - &unique_id, NULL, &removable)); + ASSERT_TRUE(volume_mount_watcher_->GetDeviceInfo( + VolumeMountWatcherWin::DriveNumberToFilePath(*it), NULL, &unique_id, + NULL, &removable)); if (removable) { MediaStorageUtil::Type type = MediaStorageUtil::REMOVABLE_MASS_STORAGE_NO_DCIM; @@ -477,13 +212,15 @@ void RemovableDeviceNotificationsWindowWinTest::DoMTPDeviceTest( { testing::InSequence sequence; PortableDeviceWatcherWin::StorageObjectIDs storage_object_ids = - GetMTPStorageObjectIds(pnp_device_id); + TestPortableDeviceWatcherWin::GetMTPStorageObjectIds(pnp_device_id); for (PortableDeviceWatcherWin::StorageObjectIDs::const_iterator it = storage_object_ids.begin(); it != storage_object_ids.end(); ++it) { std::string unique_id; string16 name; string16 location; - GetMTPStorageDetails(pnp_device_id, *it, &location, &unique_id, &name); + TestPortableDeviceWatcherWin::GetMTPStorageDetails(pnp_device_id, *it, + &location, &unique_id, + &name); if (test_attach) { EXPECT_CALL(observer_, OnRemovableStorageAttached(unique_id, name, location)) @@ -615,8 +352,8 @@ TEST_F(RemovableDeviceNotificationsWindowWinTest, DISABLED_DeviceInfoForPath) { std::string unique_id; string16 device_name; bool removable; - ASSERT_TRUE(GetMassStorageDeviceDetails(removable_device, NULL, &unique_id, - &device_name, &removable)); + ASSERT_TRUE(volume_mount_watcher_->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); @@ -628,8 +365,8 @@ TEST_F(RemovableDeviceNotificationsWindowWinTest, DISABLED_DeviceInfoForPath) { FilePath fixed_device(L"N:\\"); EXPECT_TRUE(window_->GetDeviceInfoForPath(fixed_device, &device_info)); - ASSERT_TRUE(GetMassStorageDeviceDetails(fixed_device, NULL, &unique_id, - &device_name, &removable)); + ASSERT_TRUE(volume_mount_watcher_->GetDeviceInfo( + fixed_device, NULL, &unique_id, &device_name, &removable)); EXPECT_FALSE(removable); device_id = MediaStorageUtil::MakeDeviceId( MediaStorageUtil::FIXED_MASS_STORAGE, unique_id); @@ -640,45 +377,60 @@ TEST_F(RemovableDeviceNotificationsWindowWinTest, DISABLED_DeviceInfoForPath) { // Test to verify basic MTP storage attach and detach notifications. TEST_F(RemovableDeviceNotificationsWindowWinTest, MTPDeviceBasicAttachDetach) { - DoMTPDeviceTest(kMTPDeviceWithValidInfo, true); - DoMTPDeviceTest(kMTPDeviceWithValidInfo, false); + DoMTPDeviceTest(TestPortableDeviceWatcherWin::kMTPDeviceWithValidInfo, true); + DoMTPDeviceTest(TestPortableDeviceWatcherWin::kMTPDeviceWithValidInfo, false); } // When a MTP storage device with invalid storage label and id is // attached/detached, there should not be any device attach/detach // notifications. TEST_F(RemovableDeviceNotificationsWindowWinTest, MTPDeviceWithInvalidInfo) { - DoMTPDeviceTest(kMTPDeviceWithInvalidInfo, true); - DoMTPDeviceTest(kMTPDeviceWithInvalidInfo, false); + DoMTPDeviceTest(TestPortableDeviceWatcherWin::kMTPDeviceWithInvalidInfo, + true); + DoMTPDeviceTest(TestPortableDeviceWatcherWin::kMTPDeviceWithInvalidInfo, + false); } // Attach a device with two data partitions. Verify that attach/detach // notifications are sent out for each removable storage. TEST_F(RemovableDeviceNotificationsWindowWinTest, MTPDeviceWithMultipleStorageObjects) { - DoMTPDeviceTest(kMTPDeviceWithMultipleStorageObjects, true); - DoMTPDeviceTest(kMTPDeviceWithMultipleStorageObjects, false); + DoMTPDeviceTest(TestPortableDeviceWatcherWin::kMTPDeviceWithMultipleStorages, + true); + DoMTPDeviceTest(TestPortableDeviceWatcherWin::kMTPDeviceWithMultipleStorages, + false); +} + +TEST_F(RemovableDeviceNotificationsWindowWinTest, DriveNumberToFilePath) { + EXPECT_EQ(L"A:\\", VolumeMountWatcherWin::DriveNumberToFilePath(0).value()); + EXPECT_EQ(L"Y:\\", VolumeMountWatcherWin::DriveNumberToFilePath(24).value()); + EXPECT_EQ(L"", VolumeMountWatcherWin::DriveNumberToFilePath(-1).value()); + EXPECT_EQ(L"", VolumeMountWatcherWin::DriveNumberToFilePath(199).value()); } // Given a MTP storage persistent id, GetMTPStorageInfo() should fetch the // device interface path and local storage object identifier. TEST_F(RemovableDeviceNotificationsWindowWinTest, GetMTPStorageInfoFromDeviceId) { - DoMTPDeviceTest(kMTPDeviceWithValidInfo, true); + DoMTPDeviceTest(TestPortableDeviceWatcherWin::kMTPDeviceWithValidInfo, true); PortableDeviceWatcherWin::StorageObjects storage_objects = - GetDeviceStorageObjects(kMTPDeviceWithValidInfo); + TestPortableDeviceWatcherWin::GetDeviceStorageObjects( + TestPortableDeviceWatcherWin::kMTPDeviceWithValidInfo); for (PortableDeviceWatcherWin::StorageObjects::const_iterator it = - storage_objects.begin(); it != storage_objects.end(); ++it) { + storage_objects.begin(); + it != storage_objects.end(); ++it) { string16 pnp_device_id; string16 storage_object_id; ASSERT_TRUE(GetMTPStorageInfo(it->object_persistent_id, &pnp_device_id, &storage_object_id)); - EXPECT_EQ(kMTPDeviceWithValidInfo, pnp_device_id); + EXPECT_EQ(string16(TestPortableDeviceWatcherWin::kMTPDeviceWithValidInfo), + pnp_device_id); EXPECT_EQ(it->object_persistent_id, - GetMTPStorageUniqueId(pnp_device_id, storage_object_id)); + TestPortableDeviceWatcherWin::GetMTPStorageUniqueId( + pnp_device_id, storage_object_id)); } - - DoMTPDeviceTest(kMTPDeviceWithValidInfo, false); + DoMTPDeviceTest(TestPortableDeviceWatcherWin::kMTPDeviceWithValidInfo, false); } +} // namespace test } // namespace chrome diff --git a/chrome/browser/system_monitor/test_portable_device_watcher_win.cc b/chrome/browser/system_monitor/test_portable_device_watcher_win.cc new file mode 100644 index 0000000..01d76ab --- /dev/null +++ b/chrome/browser/system_monitor/test_portable_device_watcher_win.cc @@ -0,0 +1,131 @@ +// Copyright (c) 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// TestPortableDeviceWatcherWin implementation. + +#include "chrome/browser/system_monitor/test_portable_device_watcher_win.h" + +#include <vector> + +#include "base/utf_string_conversions.h" + +namespace chrome { +namespace test { +namespace { + +// Sample MTP device storage information. +const char16 kMTPDeviceFriendlyName[] = L"Camera V1.1"; +const char16 kStorageLabelA[] = L"Camera V1.1 (s10001)"; +const char16 kStorageLabelB[] = L"Camera V1.1 (s20001)"; +const char16 kStorageObjectIdA[] = L"s10001"; +const char16 kStorageObjectIdB[] = L"s20001"; +const char kStorageUniqueIdA[] = + "mtp:StorageSerial:SID-{s10001, D, 12378}:123123"; +const char kStorageUniqueIdB[] = + "mtp:StorageSerial:SID-{s20001, S, 2238}:123123"; + +// Returns the storage name of the device specified by |pnp_device_id|. +// |storage_object_id| specifies the string ID that uniquely identifies the +// object on the device. +string16 GetMTPStorageName(const string16& pnp_device_id, + const string16& storage_object_id) { + if (pnp_device_id == TestPortableDeviceWatcherWin::kMTPDeviceWithInvalidInfo) + return string16(); + + if (storage_object_id == kStorageObjectIdA) + return kStorageLabelA; + return (storage_object_id == kStorageObjectIdB) ? + kStorageLabelB : string16(); +} + +} // namespace + +// TestPortableDeviceWatcherWin ------------------------------------------------ + +// static +const char16 TestPortableDeviceWatcherWin::kMTPDeviceWithMultipleStorages[] = + L"\\?\usb#vid_ff&pid_18#32&2&1#{ab33-1de4-f22e-1882-9724})"; +const char16 TestPortableDeviceWatcherWin::kMTPDeviceWithInvalidInfo[] = + L"\\?\usb#vid_00&pid_00#0&2&1#{0000-0000-0000-0000-0000})"; +const char16 TestPortableDeviceWatcherWin::kMTPDeviceWithValidInfo[] = + L"\\?\usb#vid_ff&pid_000f#32&2&1#{abcd-1234-ffde-1112-9172})"; + +TestPortableDeviceWatcherWin::TestPortableDeviceWatcherWin() { +} + +TestPortableDeviceWatcherWin::~TestPortableDeviceWatcherWin() { +} + +// static +std::string TestPortableDeviceWatcherWin::GetMTPStorageUniqueId( + const string16& pnp_device_id, + const string16& storage_object_id) { + if (storage_object_id == kStorageObjectIdA) + return kStorageUniqueIdA; + return (storage_object_id == kStorageObjectIdB) ? + kStorageUniqueIdB : std::string(); +} + +// static +PortableDeviceWatcherWin::StorageObjectIDs +TestPortableDeviceWatcherWin::GetMTPStorageObjectIds( + const string16& pnp_device_id) { + PortableDeviceWatcherWin::StorageObjectIDs storage_object_ids; + storage_object_ids.push_back(kStorageObjectIdA); + if (pnp_device_id == kMTPDeviceWithMultipleStorages) + storage_object_ids.push_back(kStorageObjectIdB); + return storage_object_ids; +} + +// static +void TestPortableDeviceWatcherWin::GetMTPStorageDetails( + const string16& pnp_device_id, + const string16& storage_object_id, + string16* device_location, + std::string* unique_id, + string16* name) { + std::string storage_unique_id = GetMTPStorageUniqueId(pnp_device_id, + storage_object_id); + if (device_location) + *device_location = UTF8ToUTF16("\\\\" + storage_unique_id); + + if (unique_id) + *unique_id = storage_unique_id; + + if (name) + *name = GetMTPStorageName(pnp_device_id, storage_object_id); +} + +// static +PortableDeviceWatcherWin::StorageObjects +TestPortableDeviceWatcherWin::GetDeviceStorageObjects( + const string16& pnp_device_id) { + PortableDeviceWatcherWin::StorageObjects storage_objects; + PortableDeviceWatcherWin::StorageObjectIDs storage_object_ids = + GetMTPStorageObjectIds(pnp_device_id); + for (PortableDeviceWatcherWin::StorageObjectIDs::const_iterator it = + storage_object_ids.begin(); + it != storage_object_ids.end(); ++it) { + storage_objects.push_back(DeviceStorageObject( + *it, GetMTPStorageUniqueId(pnp_device_id, *it))); + } + return storage_objects; +} + +void TestPortableDeviceWatcherWin::EnumerateAttachedDevices() { +} + +void TestPortableDeviceWatcherWin::HandleDeviceAttachEvent( + const string16& pnp_device_id) { + DeviceDetails device_details = { + (pnp_device_id != kMTPDeviceWithInvalidInfo) ? + kMTPDeviceFriendlyName : string16(), + pnp_device_id, + GetDeviceStorageObjects(pnp_device_id) + }; + OnDidHandleDeviceAttachEvent(&device_details, true); +} + +} // namespace test +} // namespace chrome
\ No newline at end of file diff --git a/chrome/browser/system_monitor/test_portable_device_watcher_win.h b/chrome/browser/system_monitor/test_portable_device_watcher_win.h new file mode 100644 index 0000000..0c49d7c --- /dev/null +++ b/chrome/browser/system_monitor/test_portable_device_watcher_win.h @@ -0,0 +1,63 @@ +// Copyright (c) 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// This file contains a subclass of PortableDeviceWatcherWin to expose some +// functionality for testing. + +#ifndef CHROME_BROWSER_SYSTEM_MONITOR_TEST_PORTABLE_DEVICE_WATCHER_WIN_H_ +#define CHROME_BROWSER_SYSTEM_MONITOR_TEST_PORTABLE_DEVICE_WATCHER_WIN_H_ + +#include <string> + +#include "base/string16.h" +#include "chrome/browser/system_monitor/portable_device_watcher_win.h" + +namespace chrome { +namespace test { + +class TestPortableDeviceWatcherWin : public PortableDeviceWatcherWin { + public: + static const char16 kMTPDeviceWithMultipleStorages[]; + static const char16 kMTPDeviceWithInvalidInfo[]; + static const char16 kMTPDeviceWithValidInfo[]; + + TestPortableDeviceWatcherWin(); + virtual ~TestPortableDeviceWatcherWin(); + + // Returns the persistent storage unique id of the device specified by the + // |pnp_device_id|. |storage_object_id| specifies the string ID that uniquely + // identifies the object on the device. + static std::string GetMTPStorageUniqueId(const string16& pnp_device_id, + const string16& storage_object_id); + + // Returns a list of storage object identifiers of the media transfer protocol + // (MTP) device given a |pnp_device_id|. + static PortableDeviceWatcherWin::StorageObjectIDs GetMTPStorageObjectIds( + const string16& pnp_device_id); + + // Gets the media transfer protocol (MTP) device storage details given a + // |pnp_device_id| and |storage_object_id|. + static void GetMTPStorageDetails(const string16& pnp_device_id, + const string16& storage_object_id, + string16* device_location, + std::string* unique_id, + string16* name); + + // Returns a list of device storage details for the given device specified by + // |pnp_device_id|. + static PortableDeviceWatcherWin::StorageObjects GetDeviceStorageObjects( + const string16& pnp_device_id); + + private: + // PortableDeviceWatcherWin: + virtual void EnumerateAttachedDevices() OVERRIDE; + virtual void HandleDeviceAttachEvent(const string16& pnp_device_id) OVERRIDE; + + DISALLOW_COPY_AND_ASSIGN(TestPortableDeviceWatcherWin); +}; + +} // namespace test +} // namespace chrome + +#endif // CHROME_BROWSER_SYSTEM_MONITOR_TEST_PORTABLE_DEVICE_WATCHER_WIN_H_
\ No newline at end of file diff --git a/chrome/browser/system_monitor/test_removable_device_notifications_window_win.cc b/chrome/browser/system_monitor/test_removable_device_notifications_window_win.cc new file mode 100644 index 0000000..3b3742e --- /dev/null +++ b/chrome/browser/system_monitor/test_removable_device_notifications_window_win.cc @@ -0,0 +1,43 @@ +// Copyright (c) 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// TestRemovableDeviceNotificationsWindowWin implementation. + +#include "chrome/browser/system_monitor/test_removable_device_notifications_window_win.h" + +#include "chrome/browser/system_monitor/test_portable_device_watcher_win.h" +#include "chrome/browser/system_monitor/test_volume_mount_watcher_win.h" + +namespace chrome { +namespace test { + +TestRemovableDeviceNotificationsWindowWin:: + TestRemovableDeviceNotificationsWindowWin( + TestVolumeMountWatcherWin* volume_mount_watcher, + TestPortableDeviceWatcherWin* portable_device_watcher) + : RemovableDeviceNotificationsWindowWin(volume_mount_watcher, + portable_device_watcher), + volume_mount_watcher_(volume_mount_watcher) { + DCHECK(volume_mount_watcher_); + DCHECK(portable_device_watcher); +} + +TestRemovableDeviceNotificationsWindowWin:: + ~TestRemovableDeviceNotificationsWindowWin() { +} + +void TestRemovableDeviceNotificationsWindowWin::InitWithTestData( + bool pre_attach_devices) { + volume_mount_watcher_->set_pre_attach_devices(pre_attach_devices); + Init(); +} + +void TestRemovableDeviceNotificationsWindowWin::InjectDeviceChange( + UINT event_type, + DWORD data) { + OnDeviceChange(event_type, data); +} + +} // namespace test +} // namespace chrome
\ No newline at end of file diff --git a/chrome/browser/system_monitor/test_removable_device_notifications_window_win.h b/chrome/browser/system_monitor/test_removable_device_notifications_window_win.h new file mode 100644 index 0000000..afc5000 --- /dev/null +++ b/chrome/browser/system_monitor/test_removable_device_notifications_window_win.h @@ -0,0 +1,43 @@ +// Copyright (c) 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// This file contains a subclass of RemovableDeviceNotificationsWindowWin to +// simulate device changed events for testing. + +#ifndef CHROME_BROWSER_SYSTEM_MONITOR_TEST_REMOVABLE_DEVICE_NOTIFICATIONS_WINDOW_WIN_H_ +#define CHROME_BROWSER_SYSTEM_MONITOR_TEST_REMOVABLE_DEVICE_NOTIFICATIONS_WINDOW_WIN_H_ + +#include <windows.h> + +#include "base/memory/ref_counted.h" +#include "chrome/browser/system_monitor/removable_device_notifications_window_win.h" + +namespace chrome { +namespace test { + +class TestPortableDeviceWatcherWin; +class TestVolumeMountWatcherWin; + +class TestRemovableDeviceNotificationsWindowWin + : public RemovableDeviceNotificationsWindowWin { + public: + TestRemovableDeviceNotificationsWindowWin( + TestVolumeMountWatcherWin* volume_mount_watcher, + TestPortableDeviceWatcherWin* portable_device_watcher); + + virtual ~TestRemovableDeviceNotificationsWindowWin(); + + void InitWithTestData(bool pre_attach_devices); + void InjectDeviceChange(UINT event_type, DWORD data); + + private: + scoped_refptr<TestVolumeMountWatcherWin> volume_mount_watcher_; + + DISALLOW_COPY_AND_ASSIGN(TestRemovableDeviceNotificationsWindowWin); +}; + +} // namespace test +} // namespace chrome + +#endif // CHROME_BROWSER_SYSTEM_MONITOR_TEST_REMOVABLE_DEVICE_NOTIFICATIONS_WINDOW_WIN_H_
\ No newline at end of file diff --git a/chrome/browser/system_monitor/test_volume_mount_watcher_win.cc b/chrome/browser/system_monitor/test_volume_mount_watcher_win.cc new file mode 100644 index 0000000..2514f38 --- /dev/null +++ b/chrome/browser/system_monitor/test_volume_mount_watcher_win.cc @@ -0,0 +1,80 @@ +// Copyright (c) 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// TestVolumeMountWatcherWin implementation. + +#include "chrome/browser/system_monitor/test_volume_mount_watcher_win.h" + +#include "base/file_path.h" + +namespace chrome { +namespace test { + +namespace { + +// Gets the details of the mass storage device specified by the |device_path|. +// |device_path| inputs of 'A:\' - 'Z:\' are valid. 'N:\' is not removable. +bool GetMassStorageDeviceDetails(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; +} + +// Returns a list of attached device locations. +std::vector<FilePath> GetTestAttachedDevices() { + std::vector<FilePath> result; + result.push_back(VolumeMountWatcherWin::DriveNumberToFilePath(0)); + result.push_back(VolumeMountWatcherWin::DriveNumberToFilePath(1)); + result.push_back(VolumeMountWatcherWin::DriveNumberToFilePath(2)); + result.push_back(VolumeMountWatcherWin::DriveNumberToFilePath(3)); + result.push_back(VolumeMountWatcherWin::DriveNumberToFilePath(5)); + result.push_back(VolumeMountWatcherWin::DriveNumberToFilePath(7)); + result.push_back(VolumeMountWatcherWin::DriveNumberToFilePath(25)); + return result; +} + +} // namespace + +// TestVolumeMountWatcherWin --------------------------------------------------- + +TestVolumeMountWatcherWin::TestVolumeMountWatcherWin() + : pre_attach_devices_(false) { +} + +bool TestVolumeMountWatcherWin::GetDeviceInfo(const FilePath& device_path, + string16* device_location, + std::string* unique_id, + string16* name, + bool* removable) { + return GetMassStorageDeviceDetails(device_path, device_location, unique_id, + name, removable); +} + +std::vector<FilePath> TestVolumeMountWatcherWin::GetAttachedDevices() { + return pre_attach_devices_ ? + GetTestAttachedDevices() : std::vector<FilePath>(); +} + +TestVolumeMountWatcherWin::~TestVolumeMountWatcherWin() { +} + +} // namespace test +} // namespace chrome
\ No newline at end of file diff --git a/chrome/browser/system_monitor/test_volume_mount_watcher_win.h b/chrome/browser/system_monitor/test_volume_mount_watcher_win.h new file mode 100644 index 0000000..231baec --- /dev/null +++ b/chrome/browser/system_monitor/test_volume_mount_watcher_win.h @@ -0,0 +1,51 @@ +// Copyright (c) 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// This file contains a subclass of VolumeMountWatcherWin to expose some +// functionality for testing. + +#ifndef CHROME_BROWSER_SYSTEM_MONITOR_TEST_VOLUME_MOUNT_WATCHER_WIN_H_ +#define CHROME_BROWSER_SYSTEM_MONITOR_TEST_VOLUME_MOUNT_WATCHER_WIN_H_ + +#include <string> +#include <vector> + +#include "base/string16.h" +#include "chrome/browser/system_monitor/volume_mount_watcher_win.h" + +class FilePath; + +namespace chrome { +namespace test { + +class TestVolumeMountWatcherWin : public VolumeMountWatcherWin { + public: + TestVolumeMountWatcherWin(); + + void set_pre_attach_devices(bool pre_attach_devices) { + pre_attach_devices_ = pre_attach_devices; + } + + // VolumeMountWatcherWin: + virtual bool GetDeviceInfo(const FilePath& device_path, + string16* device_location, + std::string* unique_id, + string16* name, + bool* removable) OVERRIDE; + virtual std::vector<FilePath> GetAttachedDevices() OVERRIDE; + + private: + // Private, this class is ref-counted. + virtual ~TestVolumeMountWatcherWin(); + + // Set to true to pre-attach test devices. + bool pre_attach_devices_; + + DISALLOW_COPY_AND_ASSIGN(TestVolumeMountWatcherWin); +}; + +} // namespace test +} // namespace chrome + +#endif // CHROME_BROWSER_SYSTEM_MONITOR_TEST_VOLUME_MOUNT_WATCHER_WIN_H_
\ No newline at end of file diff --git a/chrome/browser/system_monitor/volume_mount_watcher_win.cc b/chrome/browser/system_monitor/volume_mount_watcher_win.cc index 41b7574..c17d227 100644 --- a/chrome/browser/system_monitor/volume_mount_watcher_win.cc +++ b/chrome/browser/system_monitor/volume_mount_watcher_win.cc @@ -46,13 +46,6 @@ uint32 GetVolumeBitMaskFromBroadcastHeader(LPARAM data) { return 0; } -FilePath DriveNumberToFilePath(int drive_number) { - DCHECK_LT(drive_number, 26); - string16 path(L"_:\\"); - path[0] = L'A' + drive_number; - return FilePath(path); -} - // Returns true if |data| represents a logical volume structure. bool IsLogicalVolumeStructure(LPARAM data) { DEV_BROADCAST_HDR* broadcast_hdr = @@ -111,6 +104,15 @@ namespace chrome { VolumeMountWatcherWin::VolumeMountWatcherWin() { } +// static +FilePath VolumeMountWatcherWin::DriveNumberToFilePath(int drive_number) { + if (drive_number < 0 || drive_number > 25) + return FilePath(); + string16 path(L"_:\\"); + path[0] = L'A' + drive_number; + return FilePath(path); +} + void VolumeMountWatcherWin::Init() { // When VolumeMountWatcherWin is created, the message pumps are not running // so a posted task from the constructor would never run. Therefore, do all diff --git a/chrome/browser/system_monitor/volume_mount_watcher_win.h b/chrome/browser/system_monitor/volume_mount_watcher_win.h index 0dadca7..474f3b5 100644 --- a/chrome/browser/system_monitor/volume_mount_watcher_win.h +++ b/chrome/browser/system_monitor/volume_mount_watcher_win.h @@ -25,6 +25,11 @@ class VolumeMountWatcherWin public: VolumeMountWatcherWin(); + // Returns the volume file path of the drive specified by the |drive_number|. + // |drive_number| inputs of 0 - 25 are valid. Returns an empty file path if + // the |drive_number| is invalid. + static FilePath DriveNumberToFilePath(int drive_number); + // Must be called after the file thread is created. void Init(); diff --git a/chrome/chrome_tests_unit.gypi b/chrome/chrome_tests_unit.gypi index 57b757c..cd39b24d 100644 --- a/chrome/chrome_tests_unit.gypi +++ b/chrome/chrome_tests_unit.gypi @@ -1148,13 +1148,19 @@ 'browser/system_monitor/media_device_notifications_utils_unittest.cc', 'browser/system_monitor/media_storage_util_unittest.cc', 'browser/system_monitor/media_transfer_protocol_device_observer_linux_unittest.cc', + 'browser/system_monitor/mock_removable_storage_observer.cc', + 'browser/system_monitor/mock_removable_storage_observer.h', 'browser/system_monitor/removable_device_notifications_chromeos_unittest.cc', 'browser/system_monitor/removable_device_notifications_linux_unittest.cc', 'browser/system_monitor/removable_device_notifications_mac_unittest.mm', 'browser/system_monitor/removable_device_notifications_window_win_unittest.cc', - 'browser/system_monitor/mock_removable_storage_observer.cc', - 'browser/system_monitor/mock_removable_storage_observer.h', 'browser/system_monitor/removable_storage_notifications_unittest.cc', + 'browser/system_monitor/test_portable_device_watcher_win.cc', + 'browser/system_monitor/test_portable_device_watcher_win.h', + 'browser/system_monitor/test_removable_device_notifications_window_win.cc', + 'browser/system_monitor/test_removable_device_notifications_window_win.h', + 'browser/system_monitor/test_volume_mount_watcher_win.cc', + 'browser/system_monitor/test_volume_mount_watcher_win.h', 'browser/tab_contents/render_view_context_menu_test_util.cc', 'browser/tab_contents/render_view_context_menu_test_util.h', 'browser/tab_contents/render_view_context_menu_unittest.cc', |