Home | History | Annotate | Download | only in storage_monitor
      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