Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2706)

Unified Diff: chrome/browser/media_gallery/mac/mtp_device_delegate_impl_mac_unittest.mm

Issue 11416089: [Media Galleries] Filesystem interface for Mac PTP/MTP devices using ImageCaptureCore (part 3) (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Add locking in delegate Created 7 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/media_gallery/mac/mtp_device_delegate_impl_mac_unittest.mm
diff --git a/chrome/browser/media_gallery/mac/mtp_device_delegate_impl_mac_unittest.mm b/chrome/browser/media_gallery/mac/mtp_device_delegate_impl_mac_unittest.mm
new file mode 100644
index 0000000000000000000000000000000000000000..fc933e73b30048846de4537d121fac14d605f3bc
--- /dev/null
+++ b/chrome/browser/media_gallery/mac/mtp_device_delegate_impl_mac_unittest.mm
@@ -0,0 +1,337 @@
+// 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.
+
+#import <Foundation/Foundation.h>
+#import <ImageCaptureCore/ImageCaptureCore.h>
+
+#include "base/file_util.h"
+#include "base/mac/foundation_util.h"
+#include "base/memory/scoped_nsobject.h"
+#include "base/message_loop.h"
+#include "base/synchronization/waitable_event.h"
+#include "base/sys_string_conversions.h"
+#include "base/system_monitor/system_monitor.h"
+#include "base/test/sequenced_worker_pool_owner.h"
+#include "base/threading/sequenced_worker_pool.h"
+#include "chrome/browser/media_gallery/mac/mtp_device_delegate_impl_mac.h"
+#include "chrome/browser/system_monitor/image_capture_device_manager.h"
+#include "content/public/browser/browser_thread.h"
+#include "content/public/test/test_browser_thread.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "webkit/fileapi/file_system_file_util.h"
+
+namespace {
+
+const char kDeviceId[] = "id";
+const char kTestFileContents[] = "test";
+
+} // namespace
+
+@interface MockMTPICCameraDevice : ICCameraDevice {
+ @private
+ scoped_nsobject<NSMutableArray> allMediaFiles_;
+}
+
+- (void)addMediaFile:(ICCameraFile*)file;
+
+@end
+
+@implementation MockMTPICCameraDevice
+
+- (NSString*)mountPoint {
+ return @"mountPoint";
+}
+
+- (NSString*)name {
+ return @"name";
+}
+
+- (NSString*)UUIDString {
+ return base::SysUTF8ToNSString(kDeviceId);
+}
+
+- (ICDeviceType)type {
+ return ICDeviceTypeCamera;
+}
+
+- (void)requestOpenSession {
+}
+
+- (void)requestCloseSession {
+}
+
+- (NSArray*)mediaFiles {
+ return allMediaFiles_;
+}
+
+- (void)addMediaFile:(ICCameraFile*)file {
+ if (!allMediaFiles_.get())
+ allMediaFiles_.reset([[NSMutableArray alloc] init]);
+ [allMediaFiles_ addObject:file];
+}
+
+- (void)requestDownloadFile:(ICCameraFile*)file
+ options:(NSDictionary*)options
+ downloadDelegate:(id<ICCameraDeviceDownloadDelegate>)downloadDelegate
+ didDownloadSelector:(SEL)selector
+ contextInfo:(void*)contextInfo {
+ FilePath saveDir(base::SysNSStringToUTF8(
+ [[options objectForKey:ICDownloadsDirectoryURL] path]));
+ std::string saveAsFilename =
+ base::SysNSStringToUTF8([options objectForKey:ICSaveAsFilename]);
+ // It appears that the ImageCapture library adds an extension to the requested
+ // filename. Do that here to require a rename.
+ saveAsFilename += ".jpg";
+ FilePath toBeSaved = saveDir.Append(saveAsFilename);
+ ASSERT_EQ(static_cast<int>(strlen(kTestFileContents)),
+ file_util::WriteFile(toBeSaved, kTestFileContents,
+ strlen(kTestFileContents)));
+
+ NSMutableDictionary* returnOptions =
+ [NSMutableDictionary dictionaryWithDictionary:options];
+ [returnOptions setObject:base::SysUTF8ToNSString(saveAsFilename)
+ forKey:ICSavedFilename];
+
+ [downloadDelegate didDownloadFile:file
+ error:nil
+ options:returnOptions
+ contextInfo:contextInfo];
+}
+
+@end
+
+@interface MockMTPICCameraFile : ICCameraFile {
+ @private
+ scoped_nsobject<NSString> name_;
+ scoped_nsobject<NSDate> date_;
+}
+
+- (id)init:(NSString*)name;
+
+@end
+
+@implementation MockMTPICCameraFile
+
+- (id)init:(NSString*)name {
+ if ((self = [super init])) {
+ name_.reset([name retain]);
+ date_.reset([[NSDate dateWithNaturalLanguageString:@"12/12/12"] retain]);
+ }
+ return self;
+}
+
+- (NSString*)name {
+ return name_.get();
+}
+
+- (NSString*)UTI {
+ return base::mac::CFToNSCast(kUTTypeImage);
+}
+
+- (NSDate*)modificationDate {
+ return date_.get();
+}
+
+- (NSDate*)creationDate {
+ return date_.get();
+}
+
+- (off_t)fileSize {
+ return 1000;
+}
+
+@end
+
+// Advances the enumerator. When the method returns, signals the waiting
+// event.
+void EnumerateAndSignal(
+ fileapi::FileSystemFileUtil::AbstractFileEnumerator* enumerator,
+ base::WaitableEvent* event,
+ FilePath* path) {
+ *path = enumerator->Next();
+ event->Signal();
+}
+
+class MTPDeviceDelegateImplMacTest : public testing::Test {
+ public:
+ MTPDeviceDelegateImplMacTest() : camera_(NULL), delegate_(NULL) {}
+
+ virtual void SetUp() OVERRIDE {
+ base::SystemMonitor::AllocateSystemIOPorts();
+ system_monitor_.reset(new base::SystemMonitor());
+ ui_thread_.reset(new content::TestBrowserThread(
+ content::BrowserThread::UI, &message_loop_));
+
+ camera_ = [MockMTPICCameraDevice alloc];
+ id<ICDeviceBrowserDelegate> delegate = manager_.device_browser();
+ [delegate deviceBrowser:nil didAddDevice:camera_ moreComing:NO];
+
+ base::SequencedWorkerPool* pool = content::BrowserThread::GetBlockingPool();
+ task_runner_ = pool->GetSequencedTaskRunner(
+ pool->GetNamedSequenceToken("token-name"));
+ delegate_ = new chrome::MTPDeviceDelegateImplMac(
+ "id", "/ic:id", task_runner_.get());
+ }
+
+ virtual void TearDown() OVERRIDE {
+ id<ICDeviceBrowserDelegate> delegate = manager_.device_browser();
+ [delegate deviceBrowser:nil didRemoveDevice:camera_ moreGoing:NO];
+
+ task_runner_->PostTask(FROM_HERE,
+ base::Bind(&chrome::MTPDeviceDelegateImplMac::
+ CancelPendingTasksAndDeleteDelegate,
+ base::Unretained(delegate_)));
+ }
+
+ protected:
+ MessageLoopForUI message_loop_;
+ scoped_ptr<content::TestBrowserThread> ui_thread_;
+ scoped_ptr<base::SystemMonitor> system_monitor_;
+ chrome::ImageCaptureDeviceManager manager_;
+ ICCameraDevice* camera_;
+ scoped_refptr<base::SequencedTaskRunner> task_runner_;
+
+ // This object needs special deletion inside the above |task_runner_|.
+ chrome::MTPDeviceDelegateImplMac* delegate_;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(MTPDeviceDelegateImplMacTest);
+};
+
+TEST_F(MTPDeviceDelegateImplMacTest, TestGetRootFileInfo) {
+ base::PlatformFileInfo info;
+ // Making a fresh delegate should have a single file entry for the synthetic
+ // root directory, with the name equal to the device id string.
+ EXPECT_EQ(base::PLATFORM_FILE_OK,
+ delegate_->GetFileInfo(FilePath("/ic:id"), &info));
+ EXPECT_TRUE(info.is_directory);
+ EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND,
+ delegate_->GetFileInfo(FilePath("/nonexistent"), &info));
+
+ // Signal the delegate that no files are coming.
+ delegate_->NoMoreItems();
+
+ scoped_ptr<fileapi::FileSystemFileUtil::AbstractFileEnumerator> enumerator =
+ delegate_->CreateFileEnumerator(FilePath("/ic:id"), true);
+ EXPECT_TRUE(enumerator->Next().empty());
+}
+
+TEST_F(MTPDeviceDelegateImplMacTest, TestGetFileInfo) {
+ base::Time time1 = base::Time::Now();
+ base::PlatformFileInfo info1;
+ info1.size = 1;
+ info1.is_directory = false;
+ info1.is_symbolic_link = false;
+ info1.last_modified = time1;
+ info1.last_accessed = time1;
+ info1.creation_time = time1;
+ delegate_->ItemAdded("name1", info1);
+
+ base::PlatformFileInfo info;
+ EXPECT_EQ(base::PLATFORM_FILE_OK,
+ delegate_->GetFileInfo(FilePath("/ic:id/name1"), &info));
+ EXPECT_EQ(info1.size, info.size);
+ EXPECT_EQ(info1.is_directory, info.is_directory);
+ EXPECT_EQ(info1.last_modified, info.last_modified);
+ EXPECT_EQ(info1.last_accessed, info.last_accessed);
+ EXPECT_EQ(info1.creation_time, info.creation_time);
+
+ info1.size = 2;
+ delegate_->ItemAdded("name2", info1);
+ delegate_->NoMoreItems();
+
+ EXPECT_EQ(base::PLATFORM_FILE_OK,
+ delegate_->GetFileInfo(FilePath("/ic:id/name2"), &info));
+ EXPECT_EQ(info1.size, info.size);
+
+ scoped_ptr<fileapi::FileSystemFileUtil::AbstractFileEnumerator> enumerator =
+ delegate_->CreateFileEnumerator(FilePath("/ic:id"), true);
+ FilePath next = enumerator->Next();
+ ASSERT_FALSE(next.empty());
+ EXPECT_EQ(1, enumerator->Size());
+ EXPECT_EQ(time1, enumerator->LastModifiedTime());
+ EXPECT_FALSE(enumerator->IsDirectory());
+ EXPECT_EQ("/ic:id/name1", next.value());
+
+ next = enumerator->Next();
+ ASSERT_FALSE(next.empty());
+ EXPECT_EQ(2, enumerator->Size());
+ EXPECT_EQ(time1, enumerator->LastModifiedTime());
+ EXPECT_FALSE(enumerator->IsDirectory());
+ EXPECT_EQ("/ic:id/name2", next.value());
+
+ next = enumerator->Next();
+ EXPECT_TRUE(next.empty());
+}
+
+TEST_F(MTPDeviceDelegateImplMacTest, TestIgnoreDirectories) {
+ base::Time time1 = base::Time::Now();
+ base::PlatformFileInfo info1;
+ info1.size = 1;
+ info1.is_directory = false;
+ info1.is_symbolic_link = false;
+ info1.last_modified = time1;
+ info1.last_accessed = time1;
+ info1.creation_time = time1;
+ delegate_->ItemAdded("name1", info1);
+
+ info1.is_directory = true;
+ delegate_->ItemAdded("dir1", info1);
+ delegate_->ItemAdded("dir2", info1);
+
+ info1.is_directory = false;
+ delegate_->ItemAdded("name2", info1);
+ delegate_->NoMoreItems();
+
+ scoped_ptr<fileapi::FileSystemFileUtil::AbstractFileEnumerator> enumerator =
+ delegate_->CreateFileEnumerator(FilePath("/ic:id"), true);
+ FilePath next = enumerator->Next();
+ ASSERT_FALSE(next.empty());
+ EXPECT_EQ("/ic:id/name1", next.value());
+
+ next = enumerator->Next();
+ ASSERT_FALSE(next.empty());
+ EXPECT_EQ("/ic:id/name2", next.value());
+
+ next = enumerator->Next();
+ EXPECT_TRUE(next.empty());
+}
+
+TEST_F(MTPDeviceDelegateImplMacTest, EnumeratorWaitsForEntries) {
+ base::Time time1 = base::Time::Now();
+ base::PlatformFileInfo info1;
+ info1.size = 1;
+ info1.is_directory = false;
+ info1.is_symbolic_link = false;
+ info1.last_modified = time1;
+ info1.last_accessed = time1;
+ info1.creation_time = time1;
+ delegate_->ItemAdded("name1", info1);
+
+ scoped_ptr<fileapi::FileSystemFileUtil::AbstractFileEnumerator> enumerator =
+ delegate_->CreateFileEnumerator(FilePath("/ic:id"), true);
+ // Event is manually reset, initially unsignaled
+ base::WaitableEvent event(true, false);
+ FilePath next;
+ task_runner_->PostTask(FROM_HERE,
+ base::Bind(&EnumerateAndSignal,
+ enumerator.get(), &event, &next));
+ message_loop_.RunUntilIdle();
+ ASSERT_TRUE(event.IsSignaled());
+ EXPECT_EQ("/ic:id/name1", next.value());
+
+ event.Reset();
+
+ // This method will block until it is sure there are no more items.
+ task_runner_->PostTask(FROM_HERE,
+ base::Bind(&EnumerateAndSignal,
+ enumerator.get(), &event, &next));
+ message_loop_.RunUntilIdle();
+ ASSERT_FALSE(event.IsSignaled());
+ delegate_->NoMoreItems();
+ event.Wait();
+ ASSERT_TRUE(event.IsSignaled());
+ EXPECT_TRUE(next.empty());
+ message_loop_.RunUntilIdle();
+}

Powered by Google App Engine
This is Rietveld 408576698