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. 4 // 5 // MediaTransferProtocolDeviceObserverLinux unit tests. 6 7 #include "components/storage_monitor/media_transfer_protocol_device_observer_linux.h" 8 9 #include <string> 10 11 #include "base/memory/scoped_ptr.h" 12 #include "base/run_loop.h" 13 #include "base/strings/utf_string_conversions.h" 14 #include "components/storage_monitor/mock_removable_storage_observer.h" 15 #include "components/storage_monitor/storage_info.h" 16 #include "components/storage_monitor/storage_monitor.h" 17 #include "components/storage_monitor/test_storage_monitor.h" 18 #include "content/public/test/test_browser_thread_bundle.h" 19 #include "device/media_transfer_protocol/media_transfer_protocol_manager.h" 20 #include "testing/gtest/include/gtest/gtest.h" 21 22 namespace storage_monitor { 23 24 namespace { 25 26 // Sample mtp device storage information. 27 const char kStorageLabel[] = "Camera V1.0"; 28 const char kStorageLocation[] = "/usb:2,2,88888"; 29 const char kStorageUniqueId[] = "VendorModelSerial:COM:MOD2012:283"; 30 const char kStorageWithInvalidInfo[] = "usb:2,3,11111"; 31 const char kStorageWithValidInfo[] = "usb:2,2,88888"; 32 const char kStorageVendor[] = "ExampleVendor"; 33 const char kStorageProductName[] = "ExampleCamera"; 34 35 // Returns the mtp device id given the |unique_id|. 36 std::string GetMtpDeviceId(const std::string& unique_id) { 37 return StorageInfo::MakeDeviceId(StorageInfo::MTP_OR_PTP, unique_id); 38 } 39 40 // Helper function to get the device storage details such as device id, label 41 // and location. On success, fills in |id|, |label|, |location|, |vendor_name|, 42 // and |product_name|. 43 void GetStorageInfo(const std::string& storage_name, 44 device::MediaTransferProtocolManager* mtp_manager, 45 std::string* id, 46 base::string16* label, 47 std::string* location, 48 base::string16* vendor_name, 49 base::string16* product_name) { 50 if (storage_name == kStorageWithInvalidInfo) 51 return; // Do not set any storage details. 52 53 ASSERT_EQ(kStorageWithValidInfo, storage_name); 54 55 *id = GetMtpDeviceId(kStorageUniqueId); 56 *label = base::ASCIIToUTF16(kStorageLabel); 57 *location = kStorageLocation; 58 *vendor_name = base::ASCIIToUTF16(kStorageVendor); 59 *product_name = base::ASCIIToUTF16(kStorageProductName); 60 } 61 62 class TestMediaTransferProtocolDeviceObserverLinux 63 : public MediaTransferProtocolDeviceObserverLinux { 64 public: 65 TestMediaTransferProtocolDeviceObserverLinux( 66 StorageMonitor::Receiver* receiver, 67 device::MediaTransferProtocolManager* mtp_manager) 68 : MediaTransferProtocolDeviceObserverLinux(receiver, mtp_manager, 69 &GetStorageInfo) { 70 } 71 72 // Notifies MediaTransferProtocolDeviceObserverLinux about the attachment of 73 // mtp storage device given the |storage_name|. 74 void MtpStorageAttached(const std::string& storage_name) { 75 StorageChanged(true, storage_name); 76 base::RunLoop().RunUntilIdle(); 77 } 78 79 // Notifies MediaTransferProtocolDeviceObserverLinux about the detachment of 80 // mtp storage device given the |storage_name|. 81 void MtpStorageDetached(const std::string& storage_name) { 82 StorageChanged(false, storage_name); 83 base::RunLoop().RunUntilIdle(); 84 } 85 86 private: 87 DISALLOW_COPY_AND_ASSIGN(TestMediaTransferProtocolDeviceObserverLinux); 88 }; 89 90 } // namespace 91 92 // A class to test the functionality of MediaTransferProtocolDeviceObserverLinux 93 // member functions. 94 class MediaTransferProtocolDeviceObserverLinuxTest : public testing::Test { 95 public: 96 MediaTransferProtocolDeviceObserverLinuxTest() 97 : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP) {} 98 99 virtual ~MediaTransferProtocolDeviceObserverLinuxTest() {} 100 101 protected: 102 virtual void SetUp() OVERRIDE { 103 mock_storage_observer_.reset(new MockRemovableStorageObserver); 104 TestStorageMonitor* monitor = TestStorageMonitor::CreateAndInstall(); 105 mtp_device_observer_.reset( 106 new TestMediaTransferProtocolDeviceObserverLinux( 107 monitor->receiver(), monitor->media_transfer_protocol_manager())); 108 monitor->AddObserver(mock_storage_observer_.get()); 109 } 110 111 virtual void TearDown() OVERRIDE { 112 StorageMonitor* monitor = StorageMonitor::GetInstance(); 113 monitor->RemoveObserver(mock_storage_observer_.get()); 114 mtp_device_observer_.reset(); 115 TestStorageMonitor::Destroy(); 116 } 117 118 // Returns the device changed observer object. 119 MockRemovableStorageObserver& observer() { 120 return *mock_storage_observer_; 121 } 122 123 TestMediaTransferProtocolDeviceObserverLinux* mtp_device_observer() { 124 return mtp_device_observer_.get(); 125 } 126 127 private: 128 content::TestBrowserThreadBundle thread_bundle_; 129 130 scoped_ptr<TestMediaTransferProtocolDeviceObserverLinux> mtp_device_observer_; 131 scoped_ptr<MockRemovableStorageObserver> mock_storage_observer_; 132 133 DISALLOW_COPY_AND_ASSIGN(MediaTransferProtocolDeviceObserverLinuxTest); 134 }; 135 136 // Test to verify basic mtp storage attach and detach notifications. 137 TEST_F(MediaTransferProtocolDeviceObserverLinuxTest, BasicAttachDetach) { 138 std::string device_id = GetMtpDeviceId(kStorageUniqueId); 139 140 // Attach a mtp storage. 141 mtp_device_observer()->MtpStorageAttached(kStorageWithValidInfo); 142 143 EXPECT_EQ(1, observer().attach_calls()); 144 EXPECT_EQ(0, observer().detach_calls()); 145 EXPECT_EQ(device_id, observer().last_attached().device_id()); 146 EXPECT_EQ(kStorageLocation, observer().last_attached().location()); 147 EXPECT_EQ(base::ASCIIToUTF16(kStorageVendor), 148 observer().last_attached().vendor_name()); 149 EXPECT_EQ(base::ASCIIToUTF16(kStorageProductName), 150 observer().last_attached().model_name()); 151 152 // Detach the attached storage. 153 mtp_device_observer()->MtpStorageDetached(kStorageWithValidInfo); 154 155 EXPECT_EQ(1, observer().attach_calls()); 156 EXPECT_EQ(1, observer().detach_calls()); 157 EXPECT_EQ(device_id, observer().last_detached().device_id()); 158 } 159 160 // When a mtp storage device with invalid storage label and id is 161 // attached/detached, there should not be any device attach/detach 162 // notifications. 163 TEST_F(MediaTransferProtocolDeviceObserverLinuxTest, StorageWithInvalidInfo) { 164 // Attach the mtp storage with invalid storage info. 165 mtp_device_observer()->MtpStorageAttached(kStorageWithInvalidInfo); 166 167 // Detach the attached storage. 168 mtp_device_observer()->MtpStorageDetached(kStorageWithInvalidInfo); 169 170 EXPECT_EQ(0, observer().attach_calls()); 171 EXPECT_EQ(0, observer().detach_calls()); 172 } 173 174 } // namespace storage_monitor 175