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

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 use second cast 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_7) || \
22 MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_7
23
24 @interface NSObject (ICCameraDeviceDelegateLionAPI)
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 [static_cast<NSObject<ICCameraDeviceDownloadDelegate>*>(downloadDelegate)
122 didDownloadFile:file
123 error:nil
124 options:returnOptions
125 contextInfo:contextInfo];
126 }
127
128 @end
129
130 @interface MockICCameraFile : ICCameraFile {
131 @private
132 scoped_nsobject<NSString> name_;
133 scoped_nsobject<NSDate> date_;
134 }
135
136 - (id)init:(NSString*)name;
137
138 @end
139
140 @implementation MockICCameraFile
141
142 - (id)init:(NSString*)name {
143 if ((self = [super init])) {
144 name_.reset([name retain]);
145 date_.reset([[NSDate dateWithNaturalLanguageString:@"12/12/12"] retain]);
146 }
147 return self;
148 }
149
150 - (NSString*)name {
151 return name_.get();
152 }
153
154 - (NSString*)UTI {
155 return base::mac::CFToNSCast(kUTTypeImage);
156 }
157
158 - (NSDate*)modificationDate {
159 return date_.get();
160 }
161
162 - (NSDate*)creationDate {
163 return date_.get();
164 }
165
166 - (off_t)fileSize {
167 return 1000;
168 }
169
170 @end
171
172 class TestCameraListener
173 : public ImageCaptureDeviceListener,
174 public base::SupportsWeakPtr<TestCameraListener> {
175 public:
176 TestCameraListener()
177 : completed_(false),
178 removed_(false),
179 last_error_(base::PLATFORM_FILE_ERROR_INVALID_URL) {}
180 virtual ~TestCameraListener() {}
181
182 virtual void ItemAdded(const std::string& name,
183 const base::PlatformFileInfo& info) OVERRIDE {
184 items_.push_back(name);
185 }
186
187 virtual void NoMoreItems() OVERRIDE {
188 completed_ = true;
189 }
190
191 virtual void DownloadedFile(const std::string& name,
192 base::PlatformFileError error) OVERRIDE {
193 EXPECT_TRUE(content::BrowserThread::CurrentlyOn(
194 content::BrowserThread::UI));
195 downloads_.push_back(name);
196 last_error_ = error;
197 }
198
199 virtual void DeviceRemoved() OVERRIDE {
200 removed_ = true;
201 }
202
203 std::vector<std::string> items() const { return items_; }
204 std::vector<std::string> downloads() const { return downloads_; }
205 bool completed() const { return completed_; }
206 bool removed() const { return removed_; }
207 base::PlatformFileError last_error() const { return last_error_; }
208
209 private:
210 std::vector<std::string> items_;
211 std::vector<std::string> downloads_;
212 bool completed_;
213 bool removed_;
214 base::PlatformFileError last_error_;
215 };
216
217 class ImageCaptureDeviceManagerTest : public testing::Test {
218 public:
219 virtual void SetUp() OVERRIDE {
220 base::SystemMonitor::AllocateSystemIOPorts();
221 system_monitor_.reset(new base::SystemMonitor());
222 ui_thread_.reset(new content::TestBrowserThread(
223 content::BrowserThread::UI, &message_loop_));
224 }
225
226 MockICCameraDevice* AttachDevice(
227 chrome::ImageCaptureDeviceManager* manager) {
228 // Ownership will be passed to the device browser delegate.
229 scoped_nsobject<MockICCameraDevice> device(
230 [[MockICCameraDevice alloc] init]);
231 id<ICDeviceBrowserDelegate> delegate = manager->device_browser();
232 [delegate deviceBrowser:nil didAddDevice:device moreComing:NO];
233 return device.autorelease();
234 }
235
236 void DetachDevice(chrome::ImageCaptureDeviceManager* manager,
237 ICCameraDevice* device) {
238 id<ICDeviceBrowserDelegate> delegate = manager->device_browser();
239 [delegate deviceBrowser:nil didRemoveDevice:device moreGoing:NO];
240 }
241
242 protected:
243 MessageLoopForUI message_loop_;
244 scoped_ptr<content::TestBrowserThread> ui_thread_;
245 scoped_ptr<base::SystemMonitor> system_monitor_;
246 TestCameraListener listener_;
247 };
248
249 TEST_F(ImageCaptureDeviceManagerTest, TestAttachDetach) {
250 chrome::ImageCaptureDeviceManager manager;
251 ICCameraDevice* device = AttachDevice(&manager);
252 std::vector<base::SystemMonitor::RemovableStorageInfo> devices =
253 system_monitor_->GetAttachedRemovableStorage();
254
255 ASSERT_EQ(1U, devices.size());
256 EXPECT_EQ(std::string("ic:") + kDeviceId, devices[0].device_id);
257
258 DetachDevice(&manager, device);
259 devices = system_monitor_->GetAttachedRemovableStorage();
260 ASSERT_EQ(0U, devices.size());
261 };
262
263 TEST_F(ImageCaptureDeviceManagerTest, OpenCamera) {
264 chrome::ImageCaptureDeviceManager manager;
265 ICCameraDevice* device = AttachDevice(&manager);
266
267 EXPECT_FALSE(chrome::ImageCaptureDeviceManager::deviceForUUID(
268 "nonexistent"));
269
270 scoped_nsobject<ImageCaptureDevice> camera(
271 [chrome::ImageCaptureDeviceManager::deviceForUUID(kDeviceId)
272 retain]);
273
274 [camera setListener:listener_.AsWeakPtr()];
275 [camera open];
276
277 scoped_nsobject<MockICCameraFile> picture1(
278 [[MockICCameraFile alloc] init:@"pic1"]);
279 [camera cameraDevice:nil didAddItem:picture1];
280 scoped_nsobject<MockICCameraFile> picture2(
281 [[MockICCameraFile alloc] init:@"pic2"]);
282 [camera cameraDevice:nil didAddItem:picture2];
283 ASSERT_EQ(2U, listener_.items().size());
284 EXPECT_EQ("pic1", listener_.items()[0]);
285 EXPECT_EQ("pic2", listener_.items()[1]);
286 EXPECT_FALSE(listener_.completed());
287
288 [camera deviceDidBecomeReadyWithCompleteContentCatalog:nil];
289
290 ASSERT_EQ(2U, listener_.items().size());
291 EXPECT_TRUE(listener_.completed());
292
293 [camera close];
294 DetachDevice(&manager, device);
295 EXPECT_FALSE(chrome::ImageCaptureDeviceManager::deviceForUUID(
296 kDeviceId));
297 }
298
299 TEST_F(ImageCaptureDeviceManagerTest, RemoveCamera) {
300 chrome::ImageCaptureDeviceManager manager;
301 ICCameraDevice* device = AttachDevice(&manager);
302
303 scoped_nsobject<ImageCaptureDevice> camera(
304 [chrome::ImageCaptureDeviceManager::deviceForUUID(kDeviceId)
305 retain]);
306
307 [camera setListener:listener_.AsWeakPtr()];
308 [camera open];
309
310 [camera didRemoveDevice:device];
311 EXPECT_TRUE(listener_.removed());
312 }
313
314 TEST_F(ImageCaptureDeviceManagerTest, DownloadFile) {
315 scoped_ptr<content::TestBrowserThread> file_thread_(
316 new content::TestBrowserThread(
317 content::BrowserThread::FILE, &message_loop_));
318
319 chrome::ImageCaptureDeviceManager manager;
320 MockICCameraDevice* device = AttachDevice(&manager);
321
322 scoped_nsobject<ImageCaptureDevice> camera(
323 [chrome::ImageCaptureDeviceManager::deviceForUUID(kDeviceId)
324 retain]);
325
326 [camera setListener:listener_.AsWeakPtr()];
327 [camera open];
328
329 std::string kTestFileName("pic1");
330
331 scoped_nsobject<MockICCameraFile> picture1(
332 [[MockICCameraFile alloc]
333 init:base::SysUTF8ToNSString(kTestFileName)]);
334 [device addMediaFile:picture1];
335 [camera cameraDevice:nil didAddItem:picture1];
336
337 base::ScopedTempDir temp_dir;
338 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
339
340 EXPECT_EQ(0U, listener_.downloads().size());
341
342 // Test that a nonexistent file we ask to be downloaded will
343 // return us a not-found error.
344 FilePath temp_file = temp_dir.path().Append("tempfile");
345 [camera downloadFile:std::string("nonexistent") localPath:temp_file];
346 message_loop_.RunUntilIdle();
347 ASSERT_EQ(1U, listener_.downloads().size());
348 EXPECT_EQ("nonexistent", listener_.downloads()[0]);
349 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND, listener_.last_error());
350
351 // Test that an existing file we ask to be downloaded will end up in
352 // the location we specify. The mock system will copy testing file
353 // contents to a separate filename, mimicking the ImageCaptureCore
354 // library behavior. Our code then renames the file onto the requested
355 // destination.
356 [camera downloadFile:kTestFileName localPath:temp_file];
357 message_loop_.RunUntilIdle();
358
359 ASSERT_EQ(2U, listener_.downloads().size());
360 EXPECT_EQ(kTestFileName, listener_.downloads()[1]);
361 ASSERT_EQ(base::PLATFORM_FILE_OK, listener_.last_error());
362 char file_contents[5];
363 ASSERT_EQ(4, file_util::ReadFile(temp_file, file_contents,
364 strlen(kTestFileContents)));
365 EXPECT_EQ(kTestFileContents,
366 std::string(file_contents, strlen(kTestFileContents)));
367
368 [camera didRemoveDevice:device];
369 }
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