• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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|.
GetMtpDeviceId(const std::string & 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|.
GetStorageInfo(const std::string & storage_name,device::MediaTransferProtocolManager * mtp_manager,std::string * id,base::string16 * label,std::string * location,base::string16 * vendor_name,base::string16 * 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:
TestMediaTransferProtocolDeviceObserverLinux(StorageMonitor::Receiver * receiver,device::MediaTransferProtocolManager * mtp_manager)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|.
MtpStorageAttached(const std::string & 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|.
MtpStorageDetached(const std::string & 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:
MediaTransferProtocolDeviceObserverLinuxTest()96   MediaTransferProtocolDeviceObserverLinuxTest()
97       : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP) {}
98 
~MediaTransferProtocolDeviceObserverLinuxTest()99   virtual ~MediaTransferProtocolDeviceObserverLinuxTest() {}
100 
101  protected:
SetUp()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 
TearDown()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.
observer()119   MockRemovableStorageObserver& observer() {
120     return *mock_storage_observer_;
121   }
122 
mtp_device_observer()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.
TEST_F(MediaTransferProtocolDeviceObserverLinuxTest,BasicAttachDetach)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.
TEST_F(MediaTransferProtocolDeviceObserverLinuxTest,StorageWithInvalidInfo)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