| Index: chrome/browser/system_monitor/media_transfer_protocol_device_observer_win_unittest.cc
|
| diff --git a/chrome/browser/system_monitor/media_transfer_protocol_device_observer_win_unittest.cc b/chrome/browser/system_monitor/media_transfer_protocol_device_observer_win_unittest.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..4efe9a6338fd52d8440e92cb8a71dadf1c4a9dc3
|
| --- /dev/null
|
| +++ b/chrome/browser/system_monitor/media_transfer_protocol_device_observer_win_unittest.cc
|
| @@ -0,0 +1,233 @@
|
| +// Copyright (c) 2012 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.
|
| +//
|
| +// MediaTransferProtocolDeviceObserverWin unit tests.
|
| +
|
| +#include "chrome/browser/system_monitor/media_transfer_protocol_device_observer_win.h"
|
| +
|
| +#include "base/memory/scoped_ptr.h"
|
| +#include "base/message_loop.h"
|
| +#include "base/string16.h"
|
| +#include "base/system_monitor/system_monitor.h"
|
| +#include "base/test/mock_devices_changed_observer.h"
|
| +#include "base/threading/sequenced_worker_pool.h"
|
| +#include "content/public/test/test_browser_thread.h"
|
| +#include "testing/gtest/include/gtest/gtest.h"
|
| +
|
| +namespace chrome {
|
| +namespace mtp {
|
| +
|
| +using testing::_;
|
| +
|
| +namespace {
|
| +
|
| +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 kMtpDeviceWithMultipleStorage[] =
|
| + L"\\?\usb#vid_FF&pid_18#32&2&1#{ab33-1de4-f22e-1882-9724})";
|
| +
|
| +// Sample mtp device storage information.
|
| +const char16 kDeviceFriendlyName[] = 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";
|
| +
|
| +} // namespace
|
| +
|
| +class MediaTransferProtocolDeviceObserverWinTestWrapper
|
| + : public MediaTransferProtocolDeviceObserverWin {
|
| + public:
|
| + MediaTransferProtocolDeviceObserverWinTestWrapper() {
|
| + }
|
| +
|
| + private:
|
| + // Avoids code deleting the object while there are references to it.
|
| + // Aside from the base::RefCountedThreadSafe friend class, any attempts to
|
| + // call this dtor will result in a compile-time error.
|
| + virtual ~MediaTransferProtocolDeviceObserverWinTestWrapper() {}
|
| +
|
| + // Override MediaTransferProtocolDeviceObserverWin::InitOnBlockingThread.
|
| + void InitOnBlockingThread() OVERRIDE {
|
| + }
|
| +
|
| + // Override MediaTransferProtocolDeviceObserverWin::GetStorageName.
|
| + virtual string16 GetStorageName(LPWSTR pnp_device_id) OVERRIDE {
|
| + string16 device_interface = string16(pnp_device_id);
|
| + if (device_interface == string16(kMtpDeviceWithInvalidInfo))
|
| + return string16();
|
| + return string16(kDeviceFriendlyName);
|
| + }
|
| +
|
| + // Override MediaTransferProtocolDeviceObserverWin::GetStorages.
|
| + virtual bool GetStorages(LPWSTR pnp_device_id,
|
| + std::vector<DeviceStorageInfo>* storages) OVERRIDE {
|
| + string16 device_interface = string16(pnp_device_id);
|
| + if (device_interface == string16(kMtpDeviceWithInvalidInfo))
|
| + return false;
|
| +
|
| + DeviceStorageInfo storageA;
|
| + storageA.unique_id = kStorageUniqueIdA;
|
| + storageA.storage_object_id = kStorageObjectIdA;
|
| + storages->push_back(storageA);
|
| +
|
| + if (device_interface == string16(kMtpDeviceWithMultipleStorage)) {
|
| + DeviceStorageInfo storageB;
|
| + storageB.unique_id = kStorageUniqueIdB;
|
| + storageB.storage_object_id = kStorageObjectIdB;
|
| + storages->push_back(storageB);
|
| + }
|
| + return true;
|
| + }
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(MediaTransferProtocolDeviceObserverWinTestWrapper);
|
| +};
|
| +
|
| +// A class to test the functionality of MediaTransferProtocolDeviceObserverWin
|
| +// member functions.
|
| +class MediaTransferProtocolDeviceObserverWinTest : public testing::Test {
|
| + public:
|
| + MediaTransferProtocolDeviceObserverWinTest()
|
| + : ui_loop_(MessageLoop::TYPE_UI),
|
| + ui_thread_(content::BrowserThread::UI, &ui_loop_) {
|
| + }
|
| +
|
| + virtual ~MediaTransferProtocolDeviceObserverWinTest() {
|
| + }
|
| +
|
| + protected:
|
| + virtual void SetUp() OVERRIDE {
|
| + mock_devices_changed_observer_.reset(new base::MockDevicesChangedObserver);
|
| + system_monitor_.AddDevicesChangedObserver(
|
| + mock_devices_changed_observer_.get());
|
| + // Initialize the test subject.
|
| + notifications_ = new MediaTransferProtocolDeviceObserverWinTestWrapper();
|
| + notifications_->Init();
|
| + RunAllPending();
|
| + }
|
| +
|
| + virtual void TearDown() OVERRIDE {
|
| + RunAllPending();
|
| + notifications_ = NULL;
|
| + system_monitor_.RemoveDevicesChangedObserver(
|
| + mock_devices_changed_observer_.get());
|
| + }
|
| +
|
| + // Returns the device changed observer object.
|
| + base::MockDevicesChangedObserver& observer() {
|
| + return *mock_devices_changed_observer_;
|
| + }
|
| +
|
| + // Notifies MediaTransferProtocolDeviceObserverWin about the attachment of
|
| + // mtp storage device given the |pnp_device_id|.
|
| + void MtpDeviceAttached(const string16& pnp_device_id) {
|
| + notifications_->HandleMtpDeviceEventOnUIThread(true, pnp_device_id);
|
| + RunAllPending();
|
| + }
|
| +
|
| + // Notifies MediaTransferProtocolDeviceObserverWin about the detachment of
|
| + // mtp storage device given the |pnp_device_id|.
|
| + void MtpDeviceDetached(const string16& pnp_device_id) {
|
| + notifications_->HandleMtpDeviceEventOnUIThread(false, pnp_device_id);
|
| + RunAllPending();
|
| + }
|
| +
|
| + // Runs all the pending tasks on UI thread and blocking thread.
|
| + void RunAllPending() {
|
| + ui_loop_.RunAllPending();
|
| + content::BrowserThread::GetBlockingPool()->FlushForTesting();
|
| + ui_loop_.RunAllPending();
|
| + }
|
| +
|
| + private:
|
| + // Message loop to run the test on.
|
| + MessageLoop ui_loop_;
|
| + content::TestBrowserThread ui_thread_;
|
| +
|
| + // SystemMonitor and DevicesChangedObserver to hook together to test.
|
| + base::SystemMonitor system_monitor_;
|
| + scoped_ptr<base::MockDevicesChangedObserver> mock_devices_changed_observer_;
|
| +
|
| + scoped_refptr<MediaTransferProtocolDeviceObserverWinTestWrapper>
|
| + notifications_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(MediaTransferProtocolDeviceObserverWinTest);
|
| +};
|
| +
|
| +// Test to verify basic mtp storage attach and detach notifications.
|
| +TEST_F(MediaTransferProtocolDeviceObserverWinTest, BasicAttachDetach) {
|
| + testing::Sequence mock_sequence;
|
| +
|
| + EXPECT_CALL(observer(),
|
| + OnRemovableStorageAttached(kStorageUniqueIdA,
|
| + string16(kStorageLabelA),
|
| + string16(kMtpDeviceWithValidInfo)))
|
| + .InSequence(mock_sequence);
|
| +
|
| + // Attach a mtp device.
|
| + MtpDeviceAttached(kMtpDeviceWithValidInfo);
|
| +
|
| + EXPECT_CALL(observer(), OnRemovableStorageDetached(kStorageUniqueIdA))
|
| + .InSequence(mock_sequence);
|
| +
|
| + // Detach the attached device.
|
| + MtpDeviceDetached(kMtpDeviceWithValidInfo);
|
| +}
|
| +
|
| +// 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(MediaTransferProtocolDeviceObserverWinTest, DeviceWithInvalidInfo) {
|
| + EXPECT_CALL(observer(), OnRemovableStorageAttached(_, _, _)).Times(0);
|
| +
|
| + // Attach the mtp storage with invalid storage info.
|
| + MtpDeviceAttached(kMtpDeviceWithInvalidInfo);
|
| +
|
| + EXPECT_CALL(observer(), OnRemovableStorageDetached(_)).Times(0);
|
| +
|
| + // Detach the attached storage.
|
| + MtpDeviceDetached(kMtpDeviceWithInvalidInfo);
|
| +}
|
| +
|
| +// Attach a device with two data storages. Verify that attach/detach
|
| +// notifications are sent out for each removable storage.
|
| +TEST_F(MediaTransferProtocolDeviceObserverWinTest, DeviceWithMultipleStorages) {
|
| + testing::Sequence mock_sequence;
|
| +
|
| + EXPECT_CALL(observer(),
|
| + OnRemovableStorageAttached(
|
| + kStorageUniqueIdA,
|
| + string16(kStorageLabelA),
|
| + string16(kMtpDeviceWithMultipleStorage)))
|
| + .InSequence(mock_sequence);
|
| +
|
| + EXPECT_CALL(observer(),
|
| + OnRemovableStorageAttached(
|
| + kStorageUniqueIdB,
|
| + string16(kStorageLabelB),
|
| + string16(kMtpDeviceWithMultipleStorage)))
|
| + .InSequence(mock_sequence);
|
| +
|
| + // Attach the mtp device with multiple storage.
|
| + MtpDeviceAttached(kMtpDeviceWithMultipleStorage);
|
| +
|
| + EXPECT_CALL(observer(), OnRemovableStorageDetached(kStorageUniqueIdA))
|
| + .InSequence(mock_sequence);
|
| + EXPECT_CALL(observer(), OnRemovableStorageDetached(kStorageUniqueIdB))
|
| + .InSequence(mock_sequence);
|
| +
|
| + // Detach the attached device.
|
| + MtpDeviceDetached(kMtpDeviceWithMultipleStorage);
|
| +}
|
| +
|
| +} // namespace mtp
|
| +} // namespace chrome
|
|
|