1 // Copyright (c) 2012 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 #include <string> 6 7 #include "base/file_util.h" 8 #include "base/files/scoped_temp_dir.h" 9 #include "base/message_loop/message_loop.h" 10 #include "base/strings/utf_string_conversions.h" 11 #include "base/synchronization/waitable_event.h" 12 #include "chrome/browser/storage_monitor/media_storage_util.h" 13 #include "chrome/browser/storage_monitor/removable_device_constants.h" 14 #include "chrome/browser/storage_monitor/storage_monitor.h" 15 #include "chrome/browser/storage_monitor/test_storage_monitor.h" 16 #include "chrome/test/base/testing_browser_process.h" 17 #include "content/public/browser/browser_thread.h" 18 #include "content/public/test/test_browser_thread.h" 19 #include "testing/gtest/include/gtest/gtest.h" 20 21 namespace chrome { 22 23 namespace { 24 25 const char kImageCaptureDeviceId[] = "ic:xyz"; 26 27 } // namespace 28 29 using content::BrowserThread; 30 31 class MediaStorageUtilTest : public testing::Test { 32 public: 33 MediaStorageUtilTest() 34 : ui_thread_(BrowserThread::UI, &message_loop_), 35 file_thread_(BrowserThread::FILE) {} 36 virtual ~MediaStorageUtilTest() { } 37 38 // Verify mounted device type. 39 void CheckDeviceType(const base::FilePath& mount_point, 40 bool expected_val) { 41 if (expected_val) 42 EXPECT_TRUE(MediaStorageUtil::HasDcim(mount_point)); 43 else 44 EXPECT_FALSE(MediaStorageUtil::HasDcim(mount_point)); 45 } 46 47 void ProcessAttach(const std::string& id, 48 const string16& name, 49 const base::FilePath::StringType& location) { 50 StorageInfo info(id, name, location, string16(), string16(), string16(), 0); 51 monitor_->receiver()->ProcessAttach(info); 52 } 53 54 protected: 55 // Create mount point for the test device. 56 base::FilePath CreateMountPoint(bool create_dcim_dir) { 57 base::FilePath path(scoped_temp_dir_.path()); 58 if (create_dcim_dir) 59 path = path.Append(kDCIMDirectoryName); 60 if (!file_util::CreateDirectory(path)) 61 return base::FilePath(); 62 return scoped_temp_dir_.path(); 63 } 64 65 virtual void SetUp() OVERRIDE { 66 monitor_ = chrome::test::TestStorageMonitor::CreateAndInstall(); 67 ASSERT_TRUE(scoped_temp_dir_.CreateUniqueTempDir()); 68 file_thread_.Start(); 69 } 70 71 virtual void TearDown() OVERRIDE { 72 WaitForFileThread(); 73 } 74 75 static void PostQuitToUIThread() { 76 BrowserThread::PostTask(BrowserThread::UI, 77 FROM_HERE, 78 base::MessageLoop::QuitClosure()); 79 } 80 81 static void WaitForFileThread() { 82 BrowserThread::PostTask(BrowserThread::FILE, 83 FROM_HERE, 84 base::Bind(&PostQuitToUIThread)); 85 base::MessageLoop::current()->Run(); 86 } 87 88 base::MessageLoop message_loop_; 89 90 private: 91 chrome::test::TestStorageMonitor* monitor_; 92 content::TestBrowserThread ui_thread_; 93 content::TestBrowserThread file_thread_; 94 base::ScopedTempDir scoped_temp_dir_; 95 }; 96 97 // Test to verify that HasDcim() function returns true for the given media 98 // device mount point. 99 TEST_F(MediaStorageUtilTest, MediaDeviceAttached) { 100 // Create a dummy mount point with DCIM Directory. 101 base::FilePath mount_point(CreateMountPoint(true)); 102 BrowserThread::PostTask( 103 BrowserThread::FILE, FROM_HERE, 104 base::Bind(&MediaStorageUtilTest::CheckDeviceType, 105 base::Unretained(this), mount_point, true)); 106 message_loop_.RunUntilIdle(); 107 } 108 109 // Test to verify that HasDcim() function returns false for a given non-media 110 // device mount point. 111 TEST_F(MediaStorageUtilTest, NonMediaDeviceAttached) { 112 // Create a dummy mount point without DCIM Directory. 113 base::FilePath mount_point(CreateMountPoint(false)); 114 BrowserThread::PostTask( 115 BrowserThread::FILE, FROM_HERE, 116 base::Bind(&MediaStorageUtilTest::CheckDeviceType, 117 base::Unretained(this), mount_point, false)); 118 message_loop_.RunUntilIdle(); 119 } 120 121 TEST_F(MediaStorageUtilTest, CanCreateFileSystemForImageCapture) { 122 EXPECT_TRUE(MediaStorageUtil::CanCreateFileSystem(kImageCaptureDeviceId, 123 base::FilePath())); 124 EXPECT_FALSE(MediaStorageUtil::CanCreateFileSystem( 125 "dcim:xyz", base::FilePath(FILE_PATH_LITERAL("relative")))); 126 EXPECT_FALSE(MediaStorageUtil::CanCreateFileSystem( 127 "dcim:xyz", base::FilePath(FILE_PATH_LITERAL("../refparent")))); 128 } 129 130 TEST_F(MediaStorageUtilTest, DetectDeviceFiltered) { 131 MediaStorageUtil::DeviceIdSet devices; 132 devices.insert(kImageCaptureDeviceId); 133 134 base::WaitableEvent event(true, false); 135 base::Closure signal_event = 136 base::Bind(&base::WaitableEvent::Signal, base::Unretained(&event)); 137 138 // We need signal_event to be executed on the FILE thread, as the test thread 139 // is blocked. Therefore, we invoke FilterAttachedDevices on the FILE thread. 140 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, 141 base::Bind(&MediaStorageUtil::FilterAttachedDevices, 142 base::Unretained(&devices), signal_event)); 143 event.Wait(); 144 EXPECT_FALSE(devices.find(kImageCaptureDeviceId) != devices.end()); 145 146 ProcessAttach(kImageCaptureDeviceId, ASCIIToUTF16("name"), 147 FILE_PATH_LITERAL("/location")); 148 devices.insert(kImageCaptureDeviceId); 149 event.Reset(); 150 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, 151 base::Bind(&MediaStorageUtil::FilterAttachedDevices, 152 base::Unretained(&devices), signal_event)); 153 event.Wait(); 154 155 EXPECT_TRUE(devices.find(kImageCaptureDeviceId) != devices.end()); 156 } 157 158 } // namespace chrome 159