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

Side by Side 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: Disable GalleryNameMTP test for mac Created 7 years, 10 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 unified diff | Download patch
OLDNEW
(Empty)
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 #import <Foundation/Foundation.h>
6 #import <ImageCaptureCore/ImageCaptureCore.h>
7
8 #include "base/file_util.h"
9 #include "base/mac/cocoa_protocols.h"
10 #include "base/mac/foundation_util.h"
11 #include "base/memory/scoped_nsobject.h"
12 #include "base/message_loop.h"
13 #include "base/synchronization/waitable_event.h"
14 #include "base/sys_string_conversions.h"
15 #include "base/test/sequenced_worker_pool_owner.h"
16 #include "base/threading/sequenced_worker_pool.h"
17 #include "chrome/browser/media_gallery/mac/mtp_device_delegate_impl_mac.h"
18 #include "chrome/browser/system_monitor/image_capture_device_manager.h"
19 #include "chrome/browser/system_monitor/test_removable_storage_notifications.h"
20 #include "content/public/browser/browser_thread.h"
21 #include "content/public/test/test_browser_thread.h"
22 #include "testing/gtest/include/gtest/gtest.h"
23 #include "webkit/fileapi/file_system_file_util.h"
24
25 #if !defined(MAC_OS_X_VERSION_10_7) || \
26 MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_7
27
28 @interface NSObject (ICCameraDeviceDelegateLionAPI)
29 - (void)deviceDidBecomeReadyWithCompleteContentCatalog:(ICDevice*)device;
30 - (void)didDownloadFile:(ICCameraFile*)file
31 error:(NSError*)error
32 options:(NSDictionary*)options
33 contextInfo:(void*)contextInfo;
34 @end
35
36 #endif // 10.6
37
38 namespace {
39
40 const char kDeviceId[] = "id";
41 const char kTestFileContents[] = "test";
42
43 } // namespace
44
45 @interface MockMTPICCameraDevice : ICCameraDevice {
46 @private
47 scoped_nsobject<NSMutableArray> allMediaFiles_;
48 }
49
50 - (void)addMediaFile:(ICCameraFile*)file;
51
52 @end
53
54 @implementation MockMTPICCameraDevice
55
56 - (NSString*)mountPoint {
57 return @"mountPoint";
58 }
59
60 - (NSString*)name {
61 return @"name";
62 }
63
64 - (NSString*)UUIDString {
65 return base::SysUTF8ToNSString(kDeviceId);
66 }
67
68 - (ICDeviceType)type {
69 return ICDeviceTypeCamera;
70 }
71
72 - (void)requestOpenSession {
73 }
74
75 - (void)requestCloseSession {
76 }
77
78 - (NSArray*)mediaFiles {
79 return allMediaFiles_;
80 }
81
82 - (void)addMediaFile:(ICCameraFile*)file {
83 if (!allMediaFiles_.get())
84 allMediaFiles_.reset([[NSMutableArray alloc] init]);
85 [allMediaFiles_ addObject:file];
86 }
87
88 - (void)requestDownloadFile:(ICCameraFile*)file
89 options:(NSDictionary*)options
90 downloadDelegate:(id<ICCameraDeviceDownloadDelegate>)downloadDelegate
91 didDownloadSelector:(SEL)selector
92 contextInfo:(void*)contextInfo {
93 FilePath saveDir(base::SysNSStringToUTF8(
94 [[options objectForKey:ICDownloadsDirectoryURL] path]));
95 std::string saveAsFilename =
96 base::SysNSStringToUTF8([options objectForKey:ICSaveAsFilename]);
97 // It appears that the ImageCapture library adds an extension to the requested
98 // filename. Do that here to require a rename.
99 saveAsFilename += ".jpg";
100 FilePath toBeSaved = saveDir.Append(saveAsFilename);
101 ASSERT_EQ(static_cast<int>(strlen(kTestFileContents)),
102 file_util::WriteFile(toBeSaved, kTestFileContents,
103 strlen(kTestFileContents)));
104
105 NSMutableDictionary* returnOptions =
106 [NSMutableDictionary dictionaryWithDictionary:options];
107 [returnOptions setObject:base::SysUTF8ToNSString(saveAsFilename)
108 forKey:ICSavedFilename];
109
110 [static_cast<NSObject<ICCameraDeviceDownloadDelegate>*>(downloadDelegate)
111 didDownloadFile:file
112 error:nil
113 options:returnOptions
114 contextInfo:contextInfo];
115 }
116
117 @end
118
119 @interface MockMTPICCameraFile : ICCameraFile {
120 @private
121 scoped_nsobject<NSString> name_;
122 scoped_nsobject<NSDate> date_;
123 }
124
125 - (id)init:(NSString*)name;
126
127 @end
128
129 @implementation MockMTPICCameraFile
130
131 - (id)init:(NSString*)name {
132 if ((self = [super init])) {
133 name_.reset([name retain]);
134 date_.reset([[NSDate dateWithNaturalLanguageString:@"12/12/12"] retain]);
135 }
136 return self;
137 }
138
139 - (NSString*)name {
140 return name_.get();
141 }
142
143 - (NSString*)UTI {
144 return base::mac::CFToNSCast(kUTTypeImage);
145 }
146
147 - (NSDate*)modificationDate {
148 return date_.get();
149 }
150
151 - (NSDate*)creationDate {
152 return date_.get();
153 }
154
155 - (off_t)fileSize {
156 return 1000;
157 }
158
159 @end
160
161 // Advances the enumerator. When the method returns, signals the waiting
162 // event.
163 void EnumerateAndSignal(
164 fileapi::FileSystemFileUtil::AbstractFileEnumerator* enumerator,
165 base::WaitableEvent* event,
166 FilePath* path) {
167 *path = enumerator->Next();
168 event->Signal();
169 }
170
171 class MTPDeviceDelegateImplMacTest : public testing::Test {
172 public:
173 MTPDeviceDelegateImplMacTest() : camera_(NULL), delegate_(NULL) {}
174
175 virtual void SetUp() OVERRIDE {
176 ui_thread_.reset(new content::TestBrowserThread(
177 content::BrowserThread::UI, &message_loop_));
178
179 manager_.SetNotifications(notifications_.receiver());
180
181 camera_ = [MockMTPICCameraDevice alloc];
182 id<ICDeviceBrowserDelegate> delegate = manager_.device_browser();
183 [delegate deviceBrowser:nil didAddDevice:camera_ moreComing:NO];
184
185 base::SequencedWorkerPool* pool = content::BrowserThread::GetBlockingPool();
186 task_runner_ = pool->GetSequencedTaskRunner(
187 pool->GetNamedSequenceToken("token-name"));
188 delegate_ = new chrome::MTPDeviceDelegateImplMac(
189 "id", "/ic:id", task_runner_.get());
190 }
191
192 virtual void TearDown() OVERRIDE {
193 id<ICDeviceBrowserDelegate> delegate = manager_.device_browser();
194 [delegate deviceBrowser:nil didRemoveDevice:camera_ moreGoing:NO];
195
196 task_runner_->PostTask(FROM_HERE,
197 base::Bind(&chrome::MTPDeviceDelegateImplMac::
198 CancelPendingTasksAndDeleteDelegate,
199 base::Unretained(delegate_)));
200 }
201
202 protected:
203 MessageLoopForUI message_loop_;
204 scoped_ptr<content::TestBrowserThread> ui_thread_;
205 chrome::test::TestRemovableStorageNotifications notifications_;
206 chrome::ImageCaptureDeviceManager manager_;
207 ICCameraDevice* camera_;
208 scoped_refptr<base::SequencedTaskRunner> task_runner_;
209
210 // This object needs special deletion inside the above |task_runner_|.
211 chrome::MTPDeviceDelegateImplMac* delegate_;
212
213 private:
214 DISALLOW_COPY_AND_ASSIGN(MTPDeviceDelegateImplMacTest);
215 };
216
217 TEST_F(MTPDeviceDelegateImplMacTest, TestGetRootFileInfo) {
218 base::PlatformFileInfo info;
219 // Making a fresh delegate should have a single file entry for the synthetic
220 // root directory, with the name equal to the device id string.
221 EXPECT_EQ(base::PLATFORM_FILE_OK,
222 delegate_->GetFileInfo(FilePath("/ic:id"), &info));
223 EXPECT_TRUE(info.is_directory);
224 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND,
225 delegate_->GetFileInfo(FilePath("/nonexistent"), &info));
226
227 // Signal the delegate that no files are coming.
228 delegate_->NoMoreItems();
229
230 scoped_ptr<fileapi::FileSystemFileUtil::AbstractFileEnumerator> enumerator =
231 delegate_->CreateFileEnumerator(FilePath("/ic:id"), true);
232 EXPECT_TRUE(enumerator->Next().empty());
233 }
234
235 TEST_F(MTPDeviceDelegateImplMacTest, TestGetFileInfo) {
236 base::Time time1 = base::Time::Now();
237 base::PlatformFileInfo info1;
238 info1.size = 1;
239 info1.is_directory = false;
240 info1.is_symbolic_link = false;
241 info1.last_modified = time1;
242 info1.last_accessed = time1;
243 info1.creation_time = time1;
244 delegate_->ItemAdded("name1", info1);
245
246 base::PlatformFileInfo info;
247 EXPECT_EQ(base::PLATFORM_FILE_OK,
248 delegate_->GetFileInfo(FilePath("/ic:id/name1"), &info));
249 EXPECT_EQ(info1.size, info.size);
250 EXPECT_EQ(info1.is_directory, info.is_directory);
251 EXPECT_EQ(info1.last_modified, info.last_modified);
252 EXPECT_EQ(info1.last_accessed, info.last_accessed);
253 EXPECT_EQ(info1.creation_time, info.creation_time);
254
255 info1.size = 2;
256 delegate_->ItemAdded("name2", info1);
257 delegate_->NoMoreItems();
258
259 EXPECT_EQ(base::PLATFORM_FILE_OK,
260 delegate_->GetFileInfo(FilePath("/ic:id/name2"), &info));
261 EXPECT_EQ(info1.size, info.size);
262
263 scoped_ptr<fileapi::FileSystemFileUtil::AbstractFileEnumerator> enumerator =
264 delegate_->CreateFileEnumerator(FilePath("/ic:id"), true);
265 FilePath next = enumerator->Next();
266 ASSERT_FALSE(next.empty());
267 EXPECT_EQ(1, enumerator->Size());
268 EXPECT_EQ(time1, enumerator->LastModifiedTime());
269 EXPECT_FALSE(enumerator->IsDirectory());
270 EXPECT_EQ("/ic:id/name1", next.value());
271
272 next = enumerator->Next();
273 ASSERT_FALSE(next.empty());
274 EXPECT_EQ(2, enumerator->Size());
275 EXPECT_EQ(time1, enumerator->LastModifiedTime());
276 EXPECT_FALSE(enumerator->IsDirectory());
277 EXPECT_EQ("/ic:id/name2", next.value());
278
279 next = enumerator->Next();
280 EXPECT_TRUE(next.empty());
281 }
282
283 TEST_F(MTPDeviceDelegateImplMacTest, TestIgnoreDirectories) {
284 base::Time time1 = base::Time::Now();
285 base::PlatformFileInfo info1;
286 info1.size = 1;
287 info1.is_directory = false;
288 info1.is_symbolic_link = false;
289 info1.last_modified = time1;
290 info1.last_accessed = time1;
291 info1.creation_time = time1;
292 delegate_->ItemAdded("name1", info1);
293
294 info1.is_directory = true;
295 delegate_->ItemAdded("dir1", info1);
296 delegate_->ItemAdded("dir2", info1);
297
298 info1.is_directory = false;
299 delegate_->ItemAdded("name2", info1);
300 delegate_->NoMoreItems();
301
302 scoped_ptr<fileapi::FileSystemFileUtil::AbstractFileEnumerator> enumerator =
303 delegate_->CreateFileEnumerator(FilePath("/ic:id"), true);
304 FilePath next = enumerator->Next();
305 ASSERT_FALSE(next.empty());
306 EXPECT_EQ("/ic:id/name1", next.value());
307
308 next = enumerator->Next();
309 ASSERT_FALSE(next.empty());
310 EXPECT_EQ("/ic:id/name2", next.value());
311
312 next = enumerator->Next();
313 EXPECT_TRUE(next.empty());
314 }
315
316 TEST_F(MTPDeviceDelegateImplMacTest, EnumeratorWaitsForEntries) {
317 base::Time time1 = base::Time::Now();
318 base::PlatformFileInfo info1;
319 info1.size = 1;
320 info1.is_directory = false;
321 info1.is_symbolic_link = false;
322 info1.last_modified = time1;
323 info1.last_accessed = time1;
324 info1.creation_time = time1;
325 delegate_->ItemAdded("name1", info1);
326
327 scoped_ptr<fileapi::FileSystemFileUtil::AbstractFileEnumerator> enumerator =
328 delegate_->CreateFileEnumerator(FilePath("/ic:id"), true);
329 // Event is manually reset, initially unsignaled
330 base::WaitableEvent event(true, false);
331 FilePath next;
332 task_runner_->PostTask(FROM_HERE,
333 base::Bind(&EnumerateAndSignal,
334 enumerator.get(), &event, &next));
335 message_loop_.RunUntilIdle();
336 ASSERT_TRUE(event.IsSignaled());
337 EXPECT_EQ("/ic:id/name1", next.value());
338
339 event.Reset();
340
341 // This method will block until it is sure there are no more items.
342 task_runner_->PostTask(FROM_HERE,
343 base::Bind(&EnumerateAndSignal,
344 enumerator.get(), &event, &next));
345 message_loop_.RunUntilIdle();
346 ASSERT_FALSE(event.IsSignaled());
347 delegate_->NoMoreItems();
348 event.Wait();
349 ASSERT_TRUE(event.IsSignaled());
350 EXPECT_TRUE(next.empty());
351 message_loop_.RunUntilIdle();
352 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698