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

Side by Side Diff: chrome/browser/system_monitor/image_capture_device_manager_unittest.mm

Issue 11442057: [Media Galleries] Add an ImageCaptureCore listener for Mac. (part 2) (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Add declarations for 10.8 methods 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 unified diff | Download patch | Annotate | Revision Log
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
6 #import <Foundation/Foundation.h>
7 #import <ImageCaptureCore/ImageCaptureCore.h>
8
9 #include "base/file_path.h"
10 #include "base/file_util.h"
11 #include "base/files/scoped_temp_dir.h"
12 #include "base/mac/foundation_util.h"
13 #include "base/memory/weak_ptr.h"
14 #include "base/message_loop.h"
15 #include "base/system_monitor/system_monitor.h"
16 #include "chrome/browser/system_monitor/image_capture_device.h"
17 #include "chrome/browser/system_monitor/image_capture_device_manager.h"
18 #include "content/public/test/test_browser_thread.h"
19 #include "testing/gtest/include/gtest/gtest.h"
20
21 #if !defined(MAC_OS_X_VERSION_10_6) || \
22 MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_6
23
24 @interface ICCameraDeviceDelegate (SnowLeopardAPI)
25 - (void)deviceDidBecomeReadyWithCompleteContentCatalog:(ICDevice*)device;
26 - (void)didDownloadFile:(ICCameraFile*)file
27 error:(NSError*)error
28 options:(NSDictionary*)options
29 contextInfo:(void*)contextInfo;
30 @end
31
32 @interface NSScreen (LionAPI)
33 - (CGFloat)backingScaleFactor;
sail 2013/01/10 18:34:31 don't need this and the one below
Greg Billock 2013/01/10 21:42:15 Oops! Removed. On 2013/01/10 18:34:31, sail wrote
34 @end
35
36 @interface NSWindow (LionAPI)
37 - (CGFloat)backingScaleFactor;
38 @end
39
40 #endif // 10.6
41
42 namespace {
43
44 const char kDeviceId[] = "id";
45 const char kTestFileContents[] = "test";
46
47 } // namespace
48
49 // Private ICCameraDevice method needed to properly initialize the object.
50 @interface NSObject (PrivateAPIICCameraDevice)
51 - (id)initWithDictionary:(id)properties;
52 @end
53
54 @interface MockICCameraDevice : ICCameraDevice {
55 @private
56 scoped_nsobject<NSMutableArray> allMediaFiles_;
57 }
58
59 - (void)addMediaFile:(ICCameraFile*)file;
60
61 @end
62
63 @implementation MockICCameraDevice
64
65 - (id)init {
66 if ((self = [super initWithDictionary:[NSDictionary dictionary]])) {
67 }
68 return self;
69 }
70
71 - (NSString*)mountPoint {
72 return @"mountPoint";
73 }
74
75 - (NSString*)name {
76 return @"name";
77 }
78
79 - (NSString*)UUIDString {
80 return base::SysUTF8ToNSString(kDeviceId);
81 }
82
83 - (ICDeviceType)type {
84 return ICDeviceTypeCamera;
85 }
86
87 - (void)requestOpenSession {
88 }
89
90 - (void)requestCloseSession {
91 }
92
93 - (NSArray*)mediaFiles {
94 return allMediaFiles_;
95 }
96
97 - (void)addMediaFile:(ICCameraFile*)file {
98 if (!allMediaFiles_.get())
99 allMediaFiles_.reset([[NSMutableArray alloc] init]);
100 [allMediaFiles_ addObject:file];
101 }
102
103 // This method does approximately what the internal ImageCapture platform
104 // library is observed to do: take the download save-as filename and mangle
105 // it to attach an extension, then return that new filename to the caller
106 // in the options.
107 - (void)requestDownloadFile:(ICCameraFile*)file
108 options:(NSDictionary*)options
109 downloadDelegate:(id<ICCameraDeviceDownloadDelegate>)downloadDelegate
110 didDownloadSelector:(SEL)selector
111 contextInfo:(void*)contextInfo {
112 FilePath saveDir(base::SysNSStringToUTF8(
113 [[options objectForKey:ICDownloadsDirectoryURL] path]));
114 std::string saveAsFilename =
115 base::SysNSStringToUTF8([options objectForKey:ICSaveAsFilename]);
116 // It appears that the ImageCapture library adds an extension to the requested
117 // filename. Do that here to require a rename.
118 saveAsFilename += ".jpg";
119 FilePath toBeSaved = saveDir.Append(saveAsFilename);
120 ASSERT_EQ(static_cast<int>(strlen(kTestFileContents)),
121 file_util::WriteFile(toBeSaved, kTestFileContents,
122 strlen(kTestFileContents)));
123
124 NSMutableDictionary* returnOptions =
125 [NSMutableDictionary dictionaryWithDictionary:options];
126 [returnOptions setObject:base::SysUTF8ToNSString(saveAsFilename)
127 forKey:ICSavedFilename];
128
129 [downloadDelegate didDownloadFile:file
130 error:nil
131 options:returnOptions
132 contextInfo:contextInfo];
133 }
134
135 @end
136
137 @interface MockICCameraFile : ICCameraFile {
138 @private
139 scoped_nsobject<NSString> name_;
140 scoped_nsobject<NSDate> date_;
141 }
142
143 - (id)init:(NSString*)name;
144
145 @end
146
147 @implementation MockICCameraFile
148
149 - (id)init:(NSString*)name {
150 if ((self = [super init])) {
151 name_.reset([name retain]);
152 date_.reset([[NSDate dateWithNaturalLanguageString:@"12/12/12"] retain]);
153 }
154 return self;
155 }
156
157 - (NSString*)name {
158 return name_.get();
159 }
160
161 - (NSString*)UTI {
162 return base::mac::CFToNSCast(kUTTypeImage);
163 }
164
165 - (NSDate*)modificationDate {
166 return date_.get();
167 }
168
169 - (NSDate*)creationDate {
170 return date_.get();
171 }
172
173 - (off_t)fileSize {
174 return 1000;
175 }
176
177 @end
178
179 class TestCameraListener
180 : public ImageCaptureDeviceListener,
181 public base::SupportsWeakPtr<TestCameraListener> {
182 public:
183 TestCameraListener()
184 : completed_(false),
185 removed_(false),
186 last_error_(base::PLATFORM_FILE_ERROR_INVALID_URL) {}
187 virtual ~TestCameraListener() {}
188
189 virtual void ItemAdded(const std::string& name,
190 const base::PlatformFileInfo& info) OVERRIDE {
191 items_.push_back(name);
192 }
193
194 virtual void NoMoreItems() OVERRIDE {
195 completed_ = true;
196 }
197
198 virtual void DownloadedFile(const std::string& name,
199 base::PlatformFileError error) OVERRIDE {
200 EXPECT_TRUE(content::BrowserThread::CurrentlyOn(
201 content::BrowserThread::UI));
202 downloads_.push_back(name);
203 last_error_ = error;
204 }
205
206 virtual void DeviceRemoved() OVERRIDE {
207 removed_ = true;
208 }
209
210 std::vector<std::string> items() const { return items_; }
211 std::vector<std::string> downloads() const { return downloads_; }
212 bool completed() const { return completed_; }
213 bool removed() const { return removed_; }
214 base::PlatformFileError last_error() const { return last_error_; }
215
216 private:
217 std::vector<std::string> items_;
218 std::vector<std::string> downloads_;
219 bool completed_;
220 bool removed_;
221 base::PlatformFileError last_error_;
222 };
223
224 class ImageCaptureDeviceManagerTest : public testing::Test {
225 public:
226 virtual void SetUp() OVERRIDE {
227 base::SystemMonitor::AllocateSystemIOPorts();
228 system_monitor_.reset(new base::SystemMonitor());
229 ui_thread_.reset(new content::TestBrowserThread(
230 content::BrowserThread::UI, &message_loop_));
231 }
232
233 MockICCameraDevice* AttachDevice(
234 chrome::ImageCaptureDeviceManager* manager) {
235 // Ownership will be passed to the device browser delegate.
236 scoped_nsobject<MockICCameraDevice> device(
237 [[MockICCameraDevice alloc] init]);
238 id<ICDeviceBrowserDelegate> delegate = manager->device_browser();
239 [delegate deviceBrowser:nil didAddDevice:device moreComing:NO];
240 return device.autorelease();
241 }
242
243 void DetachDevice(chrome::ImageCaptureDeviceManager* manager,
244 ICCameraDevice* device) {
245 id<ICDeviceBrowserDelegate> delegate = manager->device_browser();
246 [delegate deviceBrowser:nil didRemoveDevice:device moreGoing:NO];
247 }
248
249 protected:
250 MessageLoopForUI message_loop_;
251 scoped_ptr<content::TestBrowserThread> ui_thread_;
252 scoped_ptr<base::SystemMonitor> system_monitor_;
253 TestCameraListener listener_;
254 };
255
256 TEST_F(ImageCaptureDeviceManagerTest, TestAttachDetach) {
257 chrome::ImageCaptureDeviceManager manager;
258 ICCameraDevice* device = AttachDevice(&manager);
259 std::vector<base::SystemMonitor::RemovableStorageInfo> devices =
260 system_monitor_->GetAttachedRemovableStorage();
261
262 ASSERT_EQ(1U, devices.size());
263 EXPECT_EQ(std::string("ic:") + kDeviceId, devices[0].device_id);
264
265 DetachDevice(&manager, device);
266 devices = system_monitor_->GetAttachedRemovableStorage();
267 ASSERT_EQ(0U, devices.size());
268 };
269
270 TEST_F(ImageCaptureDeviceManagerTest, OpenCamera) {
271 chrome::ImageCaptureDeviceManager manager;
272 ICCameraDevice* device = AttachDevice(&manager);
273
274 EXPECT_FALSE(chrome::ImageCaptureDeviceManager::deviceForUUID(
275 "nonexistent"));
276
277 scoped_nsobject<ImageCaptureDevice> camera(
278 [chrome::ImageCaptureDeviceManager::deviceForUUID(kDeviceId)
279 retain]);
280
281 [camera setListener:listener_.AsWeakPtr()];
282 [camera open];
283
284 scoped_nsobject<MockICCameraFile> picture1(
285 [[MockICCameraFile alloc] init:@"pic1"]);
286 [camera cameraDevice:nil didAddItem:picture1];
287 scoped_nsobject<MockICCameraFile> picture2(
288 [[MockICCameraFile alloc] init:@"pic2"]);
289 [camera cameraDevice:nil didAddItem:picture2];
290 ASSERT_EQ(2U, listener_.items().size());
291 EXPECT_EQ("pic1", listener_.items()[0]);
292 EXPECT_EQ("pic2", listener_.items()[1]);
293 EXPECT_FALSE(listener_.completed());
294
295 [camera deviceDidBecomeReadyWithCompleteContentCatalog:nil];
296 ASSERT_EQ(2U, listener_.items().size());
297 EXPECT_TRUE(listener_.completed());
298
299 [camera close];
300 DetachDevice(&manager, device);
301 EXPECT_FALSE(chrome::ImageCaptureDeviceManager::deviceForUUID(
302 kDeviceId));
303 }
304
305 TEST_F(ImageCaptureDeviceManagerTest, RemoveCamera) {
306 chrome::ImageCaptureDeviceManager manager;
307 ICCameraDevice* device = AttachDevice(&manager);
308
309 scoped_nsobject<ImageCaptureDevice> camera(
310 [chrome::ImageCaptureDeviceManager::deviceForUUID(kDeviceId)
311 retain]);
312
313 [camera setListener:listener_.AsWeakPtr()];
314 [camera open];
315
316 [camera didRemoveDevice:device];
317 EXPECT_TRUE(listener_.removed());
318 }
319
320 TEST_F(ImageCaptureDeviceManagerTest, DownloadFile) {
321 scoped_ptr<content::TestBrowserThread> file_thread_(
322 new content::TestBrowserThread(
323 content::BrowserThread::FILE, &message_loop_));
324
325 chrome::ImageCaptureDeviceManager manager;
326 MockICCameraDevice* device = AttachDevice(&manager);
327
328 scoped_nsobject<ImageCaptureDevice> camera(
329 [chrome::ImageCaptureDeviceManager::deviceForUUID(kDeviceId)
330 retain]);
331
332 [camera setListener:listener_.AsWeakPtr()];
333 [camera open];
334
335 std::string kTestFileName("pic1");
336
337 scoped_nsobject<MockICCameraFile> picture1(
338 [[MockICCameraFile alloc]
339 init:base::SysUTF8ToNSString(kTestFileName)]);
340 [device addMediaFile:picture1];
341 [camera cameraDevice:nil didAddItem:picture1];
342
343 base::ScopedTempDir temp_dir;
344 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
345
346 EXPECT_EQ(0U, listener_.downloads().size());
347
348 // Test that a nonexistent file we ask to be downloaded will
349 // return us a not-found error.
350 FilePath temp_file = temp_dir.path().Append("tempfile");
351 [camera downloadFile:std::string("nonexistent") localPath:temp_file];
352 message_loop_.RunUntilIdle();
353 ASSERT_EQ(1U, listener_.downloads().size());
354 EXPECT_EQ("nonexistent", listener_.downloads()[0]);
355 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND, listener_.last_error());
356
357 // Test that an existing file we ask to be downloaded will end up in
358 // the location we specify. The mock system will copy testing file
359 // contents to a separate filename, mimicking the ImageCaptureCore
360 // library behavior. Our code then renames the file onto the requested
361 // destination.
362 [camera downloadFile:kTestFileName localPath:temp_file];
363 message_loop_.RunUntilIdle();
364
365 ASSERT_EQ(2U, listener_.downloads().size());
366 EXPECT_EQ(kTestFileName, listener_.downloads()[1]);
367 ASSERT_EQ(base::PLATFORM_FILE_OK, listener_.last_error());
368 char file_contents[5];
369 ASSERT_EQ(4, file_util::ReadFile(temp_file, file_contents,
370 strlen(kTestFileContents)));
371 EXPECT_EQ(kTestFileContents,
372 std::string(file_contents, strlen(kTestFileContents)));
373
374 [camera didRemoveDevice:device];
375 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698