OLD | NEW |
---|---|
(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 "base/thread_task_runner_handle.h" | |
17 #include "chrome/browser/system_monitor/image_capture_device.h" | |
18 #include "chrome/browser/system_monitor/image_capture_device_manager.h" | |
19 #include "content/public/test/test_browser_thread.h" | |
20 #include "testing/gtest/include/gtest/gtest.h" | |
21 | |
22 namespace { | |
23 | |
24 const char kDeviceId[] = "id"; | |
25 const char kTestFileContents[] = "test"; | |
26 | |
27 } // namespace | |
28 | |
29 @interface MockICCameraDevice : ICCameraDevice { | |
30 @private | |
31 scoped_nsobject<NSMutableArray> allMediaFiles_; | |
32 } | |
33 | |
34 - (void)addMediaFile:(ICCameraFile*)file; | |
35 | |
36 @end | |
37 | |
38 @implementation MockICCameraDevice | |
39 | |
40 - (NSString*)mountPoint { | |
41 return @"mountPoint"; | |
42 } | |
43 | |
44 - (NSString*)name { | |
45 return @"name"; | |
46 } | |
47 | |
48 - (NSString*)UUIDString { | |
49 return base::SysUTF8ToNSString(kDeviceId); | |
50 } | |
51 | |
52 - (ICDeviceType)type { | |
53 return ICDeviceTypeCamera; | |
54 } | |
55 | |
56 - (void)requestOpenSession { | |
57 } | |
58 | |
59 - (void)requestCloseSession { | |
60 } | |
61 | |
62 - (NSArray*)mediaFiles { | |
63 return allMediaFiles_; | |
64 } | |
65 | |
66 - (void)addMediaFile:(ICCameraFile*)file { | |
67 if (!allMediaFiles_.get()) | |
68 allMediaFiles_.reset([NSMutableArray arrayWithCapacity:1]); | |
69 [allMediaFiles_ addObject:file]; | |
70 } | |
71 | |
72 - (void)requestDownloadFile:(ICCameraFile*)file | |
73 options:(NSDictionary*)options | |
74 downloadDelegate:(id<ICCameraDeviceDownloadDelegate>)downloadDelegate | |
75 didDownloadSelector:(SEL)selector | |
76 contextInfo:(void*)contextInfo { | |
77 FilePath saveDir(base::SysNSStringToUTF8( | |
78 [[options objectForKey:ICDownloadsDirectoryURL] path])); | |
79 std::string saveAsFilename = | |
80 base::SysNSStringToUTF8([options objectForKey:ICSaveAsFilename]); | |
81 // It appears that the ImageCapture library adds an extension to the requested | |
82 // filename. Do that here to require a rename. | |
83 saveAsFilename += ".jpg"; | |
84 FilePath toBeSaved = saveDir.Append(saveAsFilename); | |
sail
2012/12/26 18:52:37
maybe avoid a new local variable by doing saveDir
Greg Billock
2013/01/03 20:59:55
Could do, It isn't a directory though. I don't thi
sail
2013/01/03 21:50:28
Ah, ok to leave as is then.
| |
85 ASSERT_EQ(static_cast<int>(strlen(kTestFileContents)), | |
sail
2012/12/26 18:52:37
EXPECT_EQ ?
Greg Billock
2013/01/03 20:59:55
This is more a low-level thing, so it if fails, it
| |
86 file_util::WriteFile(toBeSaved, kTestFileContents, | |
sail
2012/12/26 18:52:37
could this be moved to the test? currently it's ha
Greg Billock
2013/01/03 20:59:55
It can't really be moved, since this mimics the be
| |
87 strlen(kTestFileContents))); | |
88 | |
89 NSMutableDictionary* returnOptions = | |
90 [NSMutableDictionary dictionaryWithDictionary:options]; | |
91 [returnOptions setObject:base::SysUTF8ToNSString(saveAsFilename) | |
92 forKey:ICSavedFilename]; | |
93 | |
94 [downloadDelegate didDownloadFile:file | |
95 error:nil | |
96 options:returnOptions | |
97 contextInfo:contextInfo]; | |
98 } | |
99 | |
100 @end | |
101 | |
102 @interface MockICCameraFile : ICCameraFile { | |
103 @private | |
104 scoped_nsobject<NSString> name_; | |
105 scoped_nsobject<NSDate> date_; | |
106 } | |
107 | |
108 - (id)init:(NSString*)name; | |
109 | |
110 @end | |
111 | |
112 @implementation MockICCameraFile | |
113 | |
114 - (id)init:(NSString*)name { | |
115 if ((self = [super init])) { | |
116 name_.reset([NSString stringWithString:name]); | |
117 date_.reset([[NSDate dateWithNaturalLanguageString:@"12/12/12"] retain]); | |
118 } | |
119 return self; | |
120 } | |
121 | |
122 - (NSString*)name { | |
123 return name_.get(); | |
124 } | |
125 | |
126 - (NSString*)UTI { | |
127 return base::mac::CFToNSCast(kUTTypeImage); | |
128 } | |
129 | |
130 - (NSDate*)modificationDate { | |
131 return date_.get(); | |
132 } | |
133 | |
134 - (NSDate*)creationDate { | |
135 return date_.get(); | |
136 } | |
137 | |
138 - (off_t)fileSize { | |
139 return 1000; | |
140 } | |
141 | |
142 @end | |
143 | |
144 class TestCameraListener | |
145 : public ImageCaptureDeviceListener, | |
146 public base::SupportsWeakPtr<TestCameraListener> { | |
147 public: | |
148 TestCameraListener() : completed_(false), removed_(false) {} | |
149 virtual ~TestCameraListener() {} | |
150 | |
151 virtual void ItemAdded(const std::string& name, | |
152 const base::PlatformFileInfo& info) OVERRIDE { | |
153 items_.push_back(name); | |
154 } | |
155 | |
156 virtual void NoMoreItems() OVERRIDE { | |
157 completed_ = true; | |
158 } | |
159 | |
160 virtual void DownloadedFile(const std::string& name, | |
161 base::PlatformFileError error) OVERRIDE { | |
162 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | |
sail
2012/12/26 18:52:37
EXPECT_TRUE ?
Greg Billock
2013/01/03 20:59:55
Done.
| |
163 downloads_.push_back(name); | |
164 last_error_ = error; | |
165 } | |
166 | |
167 virtual void DeviceRemoved() OVERRIDE { | |
168 removed_ = true; | |
169 } | |
170 | |
171 std::vector<std::string> items() { return items_; } | |
172 std::vector<std::string> downloads() { return downloads_; } | |
173 bool completed() { return completed_; } | |
174 bool removed() { return removed_; } | |
175 base::PlatformFileError last_error() { return last_error_; } | |
176 | |
177 private: | |
178 std::vector<std::string> items_; | |
179 std::vector<std::string> downloads_; | |
180 bool completed_; | |
181 bool removed_; | |
182 base::PlatformFileError last_error_; | |
sail
2012/12/26 18:52:37
needs to be initialized in constructor
Greg Billock
2013/01/03 20:59:55
Done.
| |
183 }; | |
184 | |
185 class ImageCaptureDeviceManagerTest : public testing::Test { | |
186 public: | |
187 virtual void SetUp() OVERRIDE { | |
188 base::SystemMonitor::AllocateSystemIOPorts(); | |
189 system_monitor_.reset(new base::SystemMonitor()); | |
190 ui_thread_.reset(new content::TestBrowserThread( | |
191 content::BrowserThread::UI, &message_loop_)); | |
192 } | |
193 | |
194 ICCameraDevice* AttachDevice( | |
195 chrome::ImageCaptureDeviceManager* manager) { | |
196 // Ownership will be passed to the device browser delegate. | |
197 ICCameraDevice* device = [MockICCameraDevice alloc]; | |
sail
2012/12/26 18:52:37
should be
MockICCameraDevice* device = [[[MockICCa
Greg Billock
2013/01/03 20:59:55
Making this change makes the registrations fail, p
sail
2013/01/03 21:50:28
I did a quick audit of the code and couldn't find
Greg Billock
2013/01/03 23:09:42
It didn't crash; it just leaves no registered devi
| |
198 id<ICDeviceBrowserDelegate> delegate = manager->device_browser(); | |
199 [delegate deviceBrowser:nil didAddDevice:device moreComing:NO]; | |
200 return device; | |
201 } | |
202 | |
203 void DetachDevice(chrome::ImageCaptureDeviceManager* manager, | |
204 ICCameraDevice* device) { | |
205 id<ICDeviceBrowserDelegate> delegate = manager->device_browser(); | |
206 [delegate deviceBrowser:nil didRemoveDevice:device moreGoing:NO]; | |
207 } | |
208 | |
209 protected: | |
210 MessageLoopForUI message_loop_; | |
211 scoped_ptr<content::TestBrowserThread> ui_thread_; | |
212 scoped_ptr<base::SystemMonitor> system_monitor_; | |
213 TestCameraListener listener_; | |
214 }; | |
215 | |
216 TEST_F(ImageCaptureDeviceManagerTest, TestAttachDetach) { | |
217 chrome::ImageCaptureDeviceManager manager; | |
218 ICCameraDevice* device = AttachDevice(&manager); | |
219 | |
220 std::vector<base::SystemMonitor::RemovableStorageInfo> devices = | |
221 system_monitor_->GetAttachedRemovableStorage(); | |
222 | |
223 ASSERT_EQ(1U, devices.size()); | |
224 EXPECT_EQ(std::string("ic:") + kDeviceId, devices[0].device_id); | |
225 | |
226 DetachDevice(&manager, device); | |
227 devices = system_monitor_->GetAttachedRemovableStorage(); | |
228 ASSERT_EQ(0U, devices.size()); | |
229 }; | |
230 | |
231 TEST_F(ImageCaptureDeviceManagerTest, OpenCamera) { | |
232 chrome::ImageCaptureDeviceManager manager; | |
233 ICCameraDevice* device = AttachDevice(&manager); | |
234 | |
235 EXPECT_FALSE(chrome::ImageCaptureDeviceManager::deviceForUUID( | |
236 "nonexistent")); | |
237 | |
238 scoped_nsobject<ImageCaptureDevice> camera( | |
sail
2012/12/26 18:52:37
you don't even need the scoped_nsobject here, you
Greg Billock
2013/01/03 20:59:55
deviceForUUID is creating a new one, though. Won't
| |
239 [chrome::ImageCaptureDeviceManager::deviceForUUID(kDeviceId) | |
240 retain]); | |
241 | |
242 [camera setListener:listener_.AsWeakPtr()]; | |
243 [camera open]; | |
244 | |
245 scoped_nsobject<MockICCameraFile> picture1( | |
246 [[MockICCameraFile alloc] init:@"pic1"]); | |
247 [camera cameraDevice:nil didAddItem:picture1]; | |
248 scoped_nsobject<MockICCameraFile> picture2( | |
249 [[MockICCameraFile alloc] init:@"pic2"]); | |
250 [camera cameraDevice:nil didAddItem:picture2]; | |
251 ASSERT_EQ(2U, listener_.items().size()); | |
252 EXPECT_EQ("pic1", listener_.items()[0]); | |
253 EXPECT_EQ("pic2", listener_.items()[1]); | |
254 EXPECT_FALSE(listener_.completed()); | |
255 | |
256 [camera deviceDidBecomeReadyWithCompleteContentCatalog:nil]; | |
257 ASSERT_EQ(2U, listener_.items().size()); | |
258 EXPECT_TRUE(listener_.completed()); | |
259 | |
260 [camera close]; | |
261 DetachDevice(&manager, device); | |
262 EXPECT_FALSE(chrome::ImageCaptureDeviceManager::deviceForUUID( | |
263 kDeviceId)); | |
264 } | |
265 | |
266 TEST_F(ImageCaptureDeviceManagerTest, RemoveCamera) { | |
267 chrome::ImageCaptureDeviceManager manager; | |
268 ICCameraDevice* device = AttachDevice(&manager); | |
269 | |
270 scoped_nsobject<ImageCaptureDevice> camera( | |
sail
2012/12/26 18:52:37
same as above, no need for scoped_nsobject + retai
| |
271 [chrome::ImageCaptureDeviceManager::deviceForUUID(kDeviceId) | |
272 retain]); | |
273 | |
274 [camera setListener:listener_.AsWeakPtr()]; | |
275 [camera open]; | |
276 | |
277 [camera didRemoveDevice:device]; | |
278 EXPECT_TRUE(listener_.removed()); | |
279 } | |
280 | |
281 TEST_F(ImageCaptureDeviceManagerTest, DownloadFile) { | |
282 scoped_ptr<content::TestBrowserThread> file_thread_( | |
283 new content::TestBrowserThread( | |
284 content::BrowserThread::FILE, &message_loop_)); | |
285 | |
286 chrome::ImageCaptureDeviceManager manager; | |
287 ICCameraDevice* device = AttachDevice(&manager); | |
288 | |
289 scoped_nsobject<ImageCaptureDevice> camera( | |
sail
2012/12/26 18:52:37
same as above, no need for scoped_nsobject + retai
| |
290 [chrome::ImageCaptureDeviceManager::deviceForUUID(kDeviceId) | |
291 retain]); | |
292 | |
293 [camera setListener:listener_.AsWeakPtr()]; | |
294 [camera open]; | |
295 | |
296 const char kTestFileName[] = "pic1"; | |
297 | |
298 scoped_nsobject<MockICCameraFile> picture1( | |
299 [[MockICCameraFile alloc] init:@"pic1"]); | |
300 [base::mac::ObjCCastStrict<MockICCameraDevice>(device) | |
301 addMediaFile:picture1]; | |
302 [camera cameraDevice:nil didAddItem:picture1]; | |
303 | |
304 base::ScopedTempDir temp_dir; | |
305 ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); | |
306 | |
307 EXPECT_EQ(0U, listener_.downloads().size()); | |
308 | |
309 FilePath temp_file = temp_dir.path().Append("tempfile"); | |
310 [camera downloadFile:std::string("nonexistent") localPath:temp_file]; | |
311 message_loop_.RunUntilIdle(); | |
312 ASSERT_EQ(1U, listener_.downloads().size()); | |
313 EXPECT_EQ("nonexistent", listener_.downloads()[0]); | |
314 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND, listener_.last_error()); | |
315 | |
316 [camera downloadFile:std::string(kTestFileName) localPath:temp_file]; | |
sail
2012/12/26 18:52:37
instead of creating std::string here just change t
Greg Billock
2013/01/03 20:59:55
Done.
| |
317 message_loop_.RunUntilIdle(); | |
318 | |
319 ASSERT_EQ(2U, listener_.downloads().size()); | |
320 EXPECT_EQ(kTestFileName, listener_.downloads()[1]); | |
321 ASSERT_EQ(base::PLATFORM_FILE_OK, listener_.last_error()); | |
322 char file_contents[5]; | |
323 ASSERT_EQ(4, file_util::ReadFile(temp_file, file_contents, | |
324 strlen(kTestFileContents))); | |
325 EXPECT_EQ(kTestFileContents, | |
326 std::string(file_contents, strlen(kTestFileContents))); | |
327 } | |
OLD | NEW |