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

Side by Side Diff: chrome/browser/system_monitor/image_capture_device.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: Delete unused factory 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.h"
6
7 #include "base/file_util.h"
8 #include "base/system_monitor/system_monitor.h"
9 #include "chrome/browser/system_monitor/media_storage_util.h"
10 #include "content/public/browser/browser_thread.h"
11
12 namespace {
13
14 void RenameFileAndReturn(const std::string& name,
15 const FilePath& downloaded_filename,
16 const FilePath& desired_filename,
17 ImageCaptureDevice* device) {
18 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE));
19 bool success = file_util::ReplaceFile(downloaded_filename, desired_filename);
20 [device renamedFile:name
21 result:(success ? base::PLATFORM_FILE_OK
22 : base::PLATFORM_FILE_ERROR_NOT_FOUND)];
23 }
24
25 base::Time NSDateToBaseTime(NSDate* date) {
26 return base::Time::FromDoubleT([date timeIntervalSince1970]);
27 }
28
29 void ListenerItemAdded(base::WeakPtr<ImageCaptureDeviceListener> listener,
30 std::string name,
31 base::PlatformFileInfo info) {
32 listener->ItemAdded(name, info);
33 }
34
35 void ListenerNoMoreItems(base::WeakPtr<ImageCaptureDeviceListener> listener) {
36 listener->NoMoreItems();
37 }
38
39 void ListenerDownloadedFile(base::WeakPtr<ImageCaptureDeviceListener> listener,
40 std::string name,
41 base::PlatformFileError error) {
42 listener->DownloadedFile(name, error);
43 }
44
45 void ListenerDeviceRemoved(base::WeakPtr<ImageCaptureDeviceListener> listener) {
46 listener->DeviceRemoved();
47 }
48
49 } // namespace
50
51 @implementation ImageCaptureDevice
52
53 - (id)initWithCameraDevice:(ICCameraDevice*)cameraDevice {
54 if ((self = [super init])) {
55 camera_.reset([cameraDevice retain]);
56 [camera_ setDelegate:self];
57 }
58 return self;
59 }
60
61 - (void)setListener:(base::WeakPtr<ImageCaptureDeviceListener>)listener
62 taskRunner:(base::TaskRunner*)pool {
63 listener_ = listener;
64 pool_ = pool;
65 }
66
67 - (void)open {
68 [camera_ requestOpenSession];
69 }
70
71 - (void)dealloc {
72 // Make sure the session was closed before destruction.
73 DCHECK(![camera_ delegate]);
74 [super dealloc];
75 }
76
77 - (void)close {
78 [camera_ requestCloseSession];
79 [camera_ setDelegate:nil];
80 }
81
82 - (void)downloadFile:(const std::string&)name
83 localPath:(const FilePath&)localPath {
84 // Find the file with that name and start download.
85 for (ICCameraItem* item in [camera_ mediaFiles]) {
86 std::string itemName = base::SysNSStringToUTF8([item name]);
87 if (itemName == name) {
88 // To create save options for ImageCapture, we need to
89 // split the target filename into directory/name
90 // and encode the directory as a URL.
91 NSString* saveDirectory =
92 base::mac::FilePathToNSString(localPath.DirName());
93 NSString* saveFilename =
94 base::mac::FilePathToNSString(localPath.BaseName());
95
96 NSMutableDictionary* options =
97 [NSMutableDictionary dictionaryWithCapacity:3];
98 [options setObject:[NSURL fileURLWithPath:saveDirectory isDirectory:YES]
99 forKey:ICDownloadsDirectoryURL];
100 [options setObject:saveFilename forKey:ICSaveAsFilename];
101 [options setObject:[NSNumber numberWithBool:YES] forKey:ICOverwrite];
102
103 [camera_ requestDownloadFile:base::mac::ObjCCastStrict<ICCameraFile>(item)
104 options:options
105 downloadDelegate:self
106 didDownloadSelector:
107 @selector(didDownloadFile:error:options:contextInfo:)
108 contextInfo:NULL];
109 return;
110 }
111 }
112
113 if (pool_.get()) {
114 pool_->PostTask(FROM_HERE,
115 base::Bind(&ListenerDownloadedFile,
116 listener_,
117 name,
118 base::PLATFORM_FILE_ERROR_NOT_FOUND));
119 }
120 }
121
122 - (void)cameraDevice:(ICCameraDevice*)camera didAddItem:(ICCameraItem*)item {
123 std::string name = base::SysNSStringToUTF8([item name]);
124 base::PlatformFileInfo info;
125 if ([[item UTI] isEqualToString:base::mac::CFToNSCast(kUTTypeFolder)])
126 info.is_directory = true;
127 else
128 info.size = [base::mac::ObjCCastStrict<ICCameraFile>(item) fileSize];
129 info.last_modified = NSDateToBaseTime([item modificationDate]);
130 info.creation_time = NSDateToBaseTime([item creationDate]);
131 info.last_accessed = info.last_modified;
132
133 if (pool_.get()) {
134 pool_->PostTask(FROM_HERE,
135 base::Bind(&ListenerItemAdded,
136 listener_,
137 name, info));
138 }
139 }
140 - (void)cameraDevice:(ICCameraDevice*)camera didAddItems:(NSArray*)items {
141 for (ICCameraItem* item in items)
142 [self cameraDevice:camera didAddItem:item];
143 }
144
145 - (void)didRemoveDevice:(ICDevice*)device {
146 device.delegate = NULL;
147 if (pool_.get()) {
148 pool_->PostTask(FROM_HERE,
149 base::Bind(&ListenerDeviceRemoved,
150 listener_));
151 }
152 }
153
154 // Notifies that a session was opened with the given device; potentially
155 // with an error.
156 - (void)device:(ICDevice*)device didOpenSessionWithError:(NSError*)error {
157 if (error)
158 [self didRemoveDevice:camera_];
159 }
160
161 - (void)device:(ICDevice*)device didEncounterError:(NSError*)error {
162 if (error) {
163 if (pool_.get()) {
164 pool_->PostTask(FROM_HERE,
165 base::Bind(&ListenerDeviceRemoved, listener_));
166 }
167 }
168 }
169
170 // When this message is received, all media metadata is now loaded.
171 - (void)deviceDidBecomeReadyWithCompleteContentCatalog:(ICDevice*)device {
172 if (pool_.get()) {
173 pool_->PostTask(FROM_HERE,
174 base::Bind(&ListenerNoMoreItems, listener_));
175 }
176 }
177
178 - (void)didDownloadFile:(ICCameraFile*)file
179 error:(NSError*)error
180 options:(NSDictionary*)options
181 contextInfo:(void*)contextInfo {
182 std::string name = base::SysNSStringToUTF8([file name]);
183
184 if (error) {
185 if (pool_.get()) {
186 pool_->PostTask(FROM_HERE,
187 base::Bind(&ListenerDownloadedFile,
188 listener_,
189 name,
190 base::PLATFORM_FILE_ERROR_FAILED));
191 }
192 return;
193 }
194
195 std::string savedFilename =
196 base::SysNSStringToUTF8([options objectForKey:ICSavedFilename]);
197 std::string saveAsFilename =
198 base::SysNSStringToUTF8([options objectForKey:ICSaveAsFilename]);
199 if (savedFilename == saveAsFilename) {
200 if (pool_.get()) {
201 pool_->PostTask(FROM_HERE,
202 base::Bind(&ListenerDownloadedFile,
203 listener_,
204 name,
205 base::PLATFORM_FILE_OK));
206 }
207 return;
208 }
209
210 // ImageCapture did not save the file into the name we give it in the
211 // options. It picks a new name according to its best lights, so we need
212 // to rename the file.
213 FilePath save_dir(base::SysNSStringToUTF8(
214 [[options objectForKey:ICDownloadsDirectoryURL] path]));
215 FilePath saveAsPath = save_dir.Append(saveAsFilename);
216 FilePath savedPath = save_dir.Append(savedFilename);
217 [self retain];
218 content::BrowserThread::PostTask(content::BrowserThread::FILE, FROM_HERE,
219 base::Bind(&RenameFileAndReturn,
220 name, savedPath, saveAsPath, self));
221 }
222
223 // Called upon successful rename
224 - (void)renamedFile:(const std::string&)name
225 result:(base::PlatformFileError)errorCode {
226 [self release];
sail 2012/12/19 20:41:39 this isn't a good idea on the file thread
Greg Billock 2012/12/19 21:19:17 Really? are the NSObject refcounters not threadsaf
sail 2012/12/19 21:32:49 The release may cause the object to be deleted. Th
Greg Billock 2012/12/19 22:08:55 Docs specifically say it is safe to delete WeakPtr
sail 2012/12/19 22:52:05 I don't think you are correct. Basically WeakPtr<
227 if (pool_.get()) {
228 pool_->PostTask(FROM_HERE,
229 base::Bind(&ListenerDownloadedFile,
230 listener_, name, errorCode));
sail 2012/12/19 20:41:39 you can't do this on the file thread
Greg Billock 2012/12/19 21:19:17 What do you mean by "this"?
sail 2012/12/19 21:32:49 this -> listener_
Greg Billock 2012/12/19 22:08:55 The docs say specifically that you can copy WeakPt
231 }
232 }
233
234 @end // ImageCaptureDevice
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698