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

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

Powered by Google App Engine
This is Rietveld 408576698