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

Side by Side Diff: chrome/browser/system_monitor/image_capture_device_browser_mac.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: Created 8 years 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 #import "chrome/browser/system_monitor/image_capture_device_browser_mac.h"
6
7 #include "base/file_util.h"
8 #include "base/system_monitor/system_monitor.h"
9 #include "chrome/browser/system_monitor/disk_info_mac.h"
10 #include "chrome/browser/system_monitor/media_storage_util.h"
11 #include "content/public/browser/browser_thread.h"
12
13 ImageCaptureDeviceBrowserMac* g_image_capture_device_browser;
sail 2012/12/12 20:53:20 It doesn't seem like you really need a singleton.
Greg Billock 2012/12/13 00:31:58 Yes. I can't see where that's exposed, though. Wha
sail 2012/12/13 02:14:00 Ahh, you're right, k maybe have the C++ class be a
14 const char kRootPath[] = "/";
15
16 @implementation ImageCaptureDeviceBrowserMac
17
18 @synthesize cameras = cameras_;
19
20 - (id)init {
21 cameras_ = [[NSMutableArray alloc] initWithCapacity:0];
22
23 device_browser_ = [[ICDeviceBrowser alloc] init];
24 device_browser_.delegate = self;
25 device_browser_.browsedDeviceTypeMask =
26 device_browser_.browsedDeviceTypeMask |
27 ICDeviceTypeMaskCamera | ICDeviceLocationTypeMaskLocal;
28 [device_browser_ start];
29 g_image_capture_device_browser = self;
30 return self;
31 }
32
33 - (void)close {
34 device_browser_.delegate = NULL;
35 [device_browser_ stop];
36 [device_browser_ release];
37 [cameras_ release];
38 }
39
40 - (ImageCaptureCameraInterface*)openDeviceByUUID:(std::string&)uuid {
41 // TODO: refcount here?
42 for (ICCameraDevice* camera in cameras_) {
43 NSString* camera_id = [camera UUIDString];
44 if (base::SysNSStringToUTF8(camera_id) == uuid) {
45 return [[ImageCaptureCameraInterface alloc] init:camera];
sail 2012/12/12 20:53:20 In Objective-C, the naming scheme implies the owne
Greg Billock 2012/12/13 00:31:58 OK, I think I got this. Also changed the name to u
sail 2012/12/13 02:14:00 Actually, you should do one or the other. If you n
Greg Billock 2012/12/14 00:39:59 Done.
46 }
47 }
48 return nil;
49 }
50
51 + (ImageCaptureDeviceBrowserMac*)Get {
52 return g_image_capture_device_browser;
53 }
54
55 // Method delegates for device added and removed
sail 2012/12/12 20:53:20 don't need this
Greg Billock 2012/12/13 00:31:58 Done.
56 //
57 // Device browser maintains list of cameras as key-value pairs, so delegate
58 // must call willChangeValueForKey to modify list
59 - (void)deviceBrowser:(ICDeviceBrowser*)browser
60 didAddDevice:(ICDevice*)addedDevice moreComing:(BOOL)moreComing {
61 if (addedDevice.type & ICDeviceTypeCamera) {
sail 2012/12/12 20:53:20 should do early return instead
Greg Billock 2012/12/13 00:31:58 Done.
62 ICCameraDevice* camera_device = (ICCameraDevice*)addedDevice;
sail 2012/12/12 20:53:20 local variable names in Objective-C classes should
Greg Billock 2012/12/13 00:31:58 Done.
63
64 NSString* name = [addedDevice name];
65 NSString* mount_point = [camera_device mountPoint];
66 NSString* uuid = [camera_device UUIDString];
67
68 // implement manual observer notification for the cameras property
69 [self willChangeValueForKey:@"cameras"];
70 [cameras_ addObject:addedDevice];
71 [self didChangeValueForKey:@"cameras"];
72
73 chrome::DiskInfoMac info = chrome::DiskInfoMac::BuildDiskInfoFromICDevice(
74 base::SysNSStringToUTF8(uuid),
75 base::SysNSStringToUTF16(name),
76 FilePath(base::SysNSStringToUTF8(mount_point)));
77 base::SystemMonitor::Get()->ProcessRemovableStorageAttached(
78 chrome::MediaStorageUtil::MakeDeviceId(info.type(), info.device_id()),
79 info.device_name(), info.mount_point().value());
80 }
81 }
82
83 - (void)deviceBrowser:(ICDeviceBrowser*)browser
84 didRemoveDevice:(ICDevice*)device moreGoing:(BOOL)moreGoing {
85 if (device.type & ICDeviceTypeCamera) {
86 NSString* name = [device name];
87
88 ICCameraDevice* camera_device = (ICCameraDevice*)device;
89 NSString* mount_point = [camera_device mountPoint];
90 NSString* uuid = [camera_device UUIDString];
91
92 // implement manual observer notification for the cameras property
93 [self willChangeValueForKey:@"cameras"];
sail 2012/12/12 20:53:20 Are you planning on using key value observers? I'd
Greg Billock 2012/12/13 00:31:58 No. This is boilerplate from the ImageCapture samp
sail 2012/12/13 02:14:00 Yea, it's safe to remove
Greg Billock 2012/12/14 00:39:59 Done.
94 [cameras_ removeObject:device];
95 [self didChangeValueForKey:@"cameras"];
96
97 chrome::DiskInfoMac info = chrome::DiskInfoMac::BuildDiskInfoFromICDevice(
98 base::SysNSStringToUTF8(uuid),
99 base::SysNSStringToUTF16(name),
100 FilePath(base::SysNSStringToUTF8(mount_point)));
101 base::SystemMonitor::Get()->ProcessRemovableStorageDetached(
102 chrome::MediaStorageUtil::MakeDeviceId(info.type(), info.device_id()));
103 }
104 }
105
106 @end // ImageCaptureDeviceBrowserMac
107
108 @implementation ImageCaptureCameraInterface
109
110 - (id)init:(ICCameraDevice*)camera_device {
111 camera_ = camera_device;
112 camera_.delegate = self;
113 return self;
114 }
115
116 - (void)open {
117 [camera_ requestOpenSession];
118 }
119
120 - (void)close {
121 [camera_ requestCloseSession];
122 camera_.delegate = NULL;
123 }
124
125 - (void)setListener:(ImageCaptureDeviceListener*)listener {
126 listener_ = listener;
127 }
128
129 - (void)DownloadFile:(const std::string&)name
130 localPath:(const FilePath&)local_path {
131 // Find the file with that name and start download.
132 for (ICCameraItem* item in [camera_ mediaFiles]) {
133 std::string item_name = base::SysNSStringToUTF8([item name]);
134 if (item_name == name) {
135 NSMutableDictionary* options =
136 [NSMutableDictionary dictionaryWithCapacity:3];
137 NSString* fileURLString =
138 [NSString stringWithUTF8String:local_path.DirName().value().c_str()];
139 [options setObject:[NSURL fileURLWithPath:fileURLString isDirectory:YES]
140 forKey:ICDownloadsDirectoryURL];
141 NSString* filename =
142 [NSString stringWithUTF8String:local_path.BaseName().value().c_str()];
143 [options setObject:filename forKey:ICSaveAsFilename];
144 [options setObject:[NSNumber numberWithBool:YES] forKey:ICOverwrite];
145
146 [camera_ requestDownloadFile:(ICCameraFile*)item
147 options:options
148 downloadDelegate:self
149 didDownloadSelector:
150 @selector(didDownloadFile:error:options:contextInfo:)
151 contextInfo:NULL];
152 return;
153 }
154 }
155
156 if (listener_)
157 listener_->DownloadedFile(name, base::PLATFORM_FILE_ERROR_NOT_FOUND);
158 }
159
160 // Delegates for ICCameraDeviceDelegate
161
162 - (void)cameraDevice:(ICCameraDevice*)camera didAddItem:(ICCameraItem*)item {
163 std::string name = base::SysNSStringToUTF8([item name]);
164 base::PlatformFileInfo info;
165 info.size = 0;
166 info.is_directory = false;
167 if ([[item UTI] isEqualToString:(NSString*)kUTTypeFolder])
168 info.is_directory = true;
169 else
170 info.size = [(ICCameraFile*)item fileSize];
171 info.is_symbolic_link = false;
172 info.last_modified =
173 base::Time::FromDoubleT([[item modificationDate] timeIntervalSince1970]);
174 info.creation_time =
175 base::Time::FromDoubleT([[item creationDate] timeIntervalSince1970]);
176 info.last_accessed = info.last_modified;
177
178 if (listener_)
179 listener_->ItemAdded(name, info);
180 }
181
182 - (void)cameraDevice:(ICCameraDevice*)camera didAddItems:(NSArray*)items {
183 for (ICCameraItem* item in items)
184 [self cameraDevice:camera didAddItem:item];
185 }
186
187 - (void)didRemoveDevice:(ICDevice*)device {
188 device.delegate = NULL;
189 // Note: handled by ICDeviceBrowser::didRemoveDevice
190 [device.userData setObject:[NSNumber numberWithBool:NO] forKey:@"ready"];
191 [device.userData setObject:[NSNumber numberWithBool:NO] forKey:@"open"];
192 if (listener_) {
193 listener_->DeviceRemoved();
194 [self setListener:nil];
195 }
196 }
197
198 // Notifies that a session was opened with the given device; potentially
199 // with an error.
200 - (void)device:(ICDevice*)device didOpenSessionWithError:(NSError*)error {
201 if (error == NULL)
202 [device.userData setObject:[NSNumber numberWithBool:YES] forKey:@"open"];
203 else
204 [device.userData setObject:error forKey:@"error"];
205 }
206
207 // Notifies that the device is ready for commands (i.e. download images)
208 - (void)deviceDidBecomeReady:(ICDevice*)device {
209 [device.userData setObject:[NSNumber numberWithBool:YES] forKey:@"ready"];
210 }
211
212 - (void)device:(ICDevice*)device didEncounterError:(NSError*)error {
213 [device.userData setObject:error forKey:@"error"];
214 [device.userData setObject:[NSNumber numberWithBool:NO] forKey:@"open"];
215 }
216
217 // All metadata is now loaded.
218 - (void)deviceDidBecomeReadyWithCompleteContentCatalog:(ICDevice*)device {
219 if (device.type & ICDeviceTypeCamera) {
220 [device.userData setValue:(id)kCFBooleanTrue forKey:@"complete"];
221 }
222 if (listener_)
223 listener_->NoMoreItems();
224 }
225
226 // Delegates for ICCameraDeviceDownloadDelegate
227
228 void RenameFileAndReturn(const std::string& name,
229 const FilePath& downloaded_filename,
230 const FilePath& desired_filename,
231 ImageCaptureCameraInterface* caller) {
232 int64 edsize = 0;
233 file_util::GetFileSize(downloaded_filename, &edsize);
234 bool error = file_util::ReplaceFile(downloaded_filename, desired_filename);
235 [caller DidRenameDownloadFile:name withError:error];
236 }
237
238 - (void)didDownloadFile:(ICCameraFile*)file error:(NSError*)error
239 options:(NSDictionary*)options contextInfo:(void*)contextInfo {
240 std::string name = base::SysNSStringToUTF8([file name]);
241 base::PlatformFileError err = base::PLATFORM_FILE_OK;
242
243 // ImageCapture does not save the file into the name we give it in the
244 // options. It picks a new name according to it's best lights, so we need
245 // to rename the file.
246 std::string saved_filename =
247 base::SysNSStringToUTF8([options objectForKey:ICSavedFilename]);
248 std::string save_as_filename =
249 base::SysNSStringToUTF8([options objectForKey:ICSaveAsFilename]);
250 if (!error && (saved_filename != save_as_filename)) {
251 FilePath save_dir(base::SysNSStringToUTF8(
252 [[options objectForKey:ICDownloadsDirectoryURL] path]));
253 FilePath save_as_path = save_dir.Append(save_as_filename);
254 FilePath saved_path = save_dir.Append(saved_filename);
255 // !!! should really pass a weak pointer or a refptr or something.
256 content::BrowserThread::PostTask(content::BrowserThread::FILE, FROM_HERE,
257 base::Bind(&RenameFileAndReturn, name, saved_path, save_as_path, self));
258 return;
259 }
260
261 if (error)
262 err = base::PLATFORM_FILE_ERROR_FAILED;
263
264 if (listener_)
265 listener_->DownloadedFile(name, err);
266 }
267
268 - (void)DidRenameDownloadFile:(const std::string&)name
269 withError:(bool)rename_error {
270 if (listener_) {
271 listener_->DownloadedFile(name,
272 rename_error ? base::PLATFORM_FILE_OK
273 : base::PLATFORM_FILE_ERROR_FAILED);
274 }
275 }
276
277 @end // ImageCaptureCameraInterface
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698