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

Side by Side Diff: chrome/browser/media_gallery/mac/mtp_device_delegate_impl_mac.mm

Issue 12255023: [Media Galleries] Switch Mac MTP delegate to async interface. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Reorder some functions, add some more comments Created 7 years, 9 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
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/media_gallery/mac/mtp_device_delegate_impl_mac.h" 5 #include "chrome/browser/media_gallery/mac/mtp_device_delegate_impl_mac.h"
6 6
7 #include "base/memory/scoped_nsobject.h" 7 #include "base/memory/scoped_nsobject.h"
8 #include "base/sequenced_task_runner.h"
9 #include "base/sequenced_task_runner_helpers.h"
10 #include "base/threading/sequenced_worker_pool.h" 8 #include "base/threading/sequenced_worker_pool.h"
11 #include "chrome/browser/media_gallery/mtp_device_delegate_impl.h" 9 #include "chrome/browser/media_gallery/mtp_device_delegate_impl.h"
12 #include "chrome/browser/storage_monitor/image_capture_device.h" 10 #include "chrome/browser/storage_monitor/image_capture_device.h"
13 #include "chrome/browser/storage_monitor/image_capture_device_manager.h" 11 #include "chrome/browser/storage_monitor/image_capture_device_manager.h"
14 #include "chrome/browser/storage_monitor/media_storage_util.h" 12 #include "chrome/browser/storage_monitor/media_storage_util.h"
15 #include "content/public/browser/browser_thread.h" 13 #include "content/public/browser/browser_thread.h"
14 #include "webkit/fileapi/async_file_util.h"
16 15
17 namespace chrome { 16 namespace chrome {
18 17
18 namespace {
19
20 using fileapi::MTPDeviceAsyncDelegate;
21 typedef MTPDeviceAsyncDelegate::CreateSnapshotFileSuccessCallback
22 CreateSnapshotFileSuccessCallback;
23 typedef MTPDeviceAsyncDelegate::ErrorCallback ErrorCallback;
24 typedef MTPDeviceAsyncDelegate::GetFileInfoSuccessCallback
25 GetFileInfoSuccessCallback;
26 typedef MTPDeviceAsyncDelegate::ReadDirectorySuccessCallback
27 ReadDirectorySuccessCallback;
28
29 } // namespace
30
19 // This class handles the UI-thread hand-offs needed to interface 31 // This class handles the UI-thread hand-offs needed to interface
20 // with the ImageCapture library. It will forward callbacks to 32 // with the ImageCapture library. It will forward callbacks to
21 // its delegate on the task runner with which it is created. All 33 // its delegate on the task runner with which it is created. All
22 // interactions with it are done on the UI thread, but it may be 34 // interactions with it are done on the UI thread, but it may be
23 // created/destroyed on another thread. 35 // created/destroyed on another thread.
24 class MTPDeviceDelegateImplMac::DeviceListener 36 class MTPDeviceDelegateImplMac::DeviceListener
25 : public ImageCaptureDeviceListener, 37 : public ImageCaptureDeviceListener,
26 public base::SupportsWeakPtr<DeviceListener> { 38 public base::SupportsWeakPtr<DeviceListener> {
27 public: 39 public:
28 DeviceListener(MTPDeviceDelegateImplMac* delegate) 40 DeviceListener(MTPDeviceDelegateImplMac* delegate)
29 : delegate_(delegate) {} 41 : delegate_(delegate) {}
30 virtual ~DeviceListener() {} 42 virtual ~DeviceListener() {}
31 43
32 void OpenCameraSession(const std::string& device_id); 44 void OpenCameraSession(const std::string& device_id);
33 void CloseCameraSessionAndDelete(); 45 void CloseCameraSessionAndDelete();
34 46
35 void DownloadFile(const std::string& name, const base::FilePath& local_path); 47 void DownloadFile(const std::string& name, const base::FilePath& local_path);
36 48
37 // ImageCaptureDeviceListener 49 // ImageCaptureDeviceListener
38 virtual void ItemAdded(const std::string& name, 50 virtual void ItemAdded(const std::string& name,
39 const base::PlatformFileInfo& info) OVERRIDE; 51 const base::PlatformFileInfo& info) OVERRIDE;
40 virtual void NoMoreItems() OVERRIDE; 52 virtual void NoMoreItems() OVERRIDE;
41 virtual void DownloadedFile(const std::string& name, 53 virtual void DownloadedFile(const std::string& name,
42 base::PlatformFileError error) OVERRIDE; 54 base::PlatformFileError error) OVERRIDE;
43 virtual void DeviceRemoved() OVERRIDE; 55 virtual void DeviceRemoved() OVERRIDE;
44 56
57 // Used during delegate destruction to ensure there are no more calls
58 // to the delegate by the listener.
59 virtual void ResetDelegate();
60
45 private: 61 private:
46 scoped_nsobject<ImageCaptureDevice> camera_device_; 62 scoped_nsobject<ImageCaptureDevice> camera_device_;
47 63
48 // Weak pointer 64 // Weak pointer
49 MTPDeviceDelegateImplMac* delegate_; 65 MTPDeviceDelegateImplMac* delegate_;
50 66
51 DISALLOW_COPY_AND_ASSIGN(DeviceListener); 67 DISALLOW_COPY_AND_ASSIGN(DeviceListener);
52 }; 68 };
53 69
54 void MTPDeviceDelegateImplMac::DeviceListener::OpenCameraSession( 70 void MTPDeviceDelegateImplMac::DeviceListener::OpenCameraSession(
(...skipping 13 matching lines...) Expand all
68 84
69 void MTPDeviceDelegateImplMac::DeviceListener::DownloadFile( 85 void MTPDeviceDelegateImplMac::DeviceListener::DownloadFile(
70 const std::string& name, 86 const std::string& name,
71 const base::FilePath& local_path) { 87 const base::FilePath& local_path) {
72 [camera_device_ downloadFile:name localPath:local_path]; 88 [camera_device_ downloadFile:name localPath:local_path];
73 } 89 }
74 90
75 void MTPDeviceDelegateImplMac::DeviceListener::ItemAdded( 91 void MTPDeviceDelegateImplMac::DeviceListener::ItemAdded(
76 const std::string& name, 92 const std::string& name,
77 const base::PlatformFileInfo& info) { 93 const base::PlatformFileInfo& info) {
78 delegate_->ItemAdded(name, info); 94 if (delegate_)
95 delegate_->ItemAdded(name, info);
79 } 96 }
80 97
81 void MTPDeviceDelegateImplMac::DeviceListener::NoMoreItems() { 98 void MTPDeviceDelegateImplMac::DeviceListener::NoMoreItems() {
82 delegate_->NoMoreItems(); 99 if (delegate_)
100 delegate_->NoMoreItems();
83 } 101 }
84 102
85 void MTPDeviceDelegateImplMac::DeviceListener::DownloadedFile( 103 void MTPDeviceDelegateImplMac::DeviceListener::DownloadedFile(
86 const std::string& name, 104 const std::string& name,
87 base::PlatformFileError error) { 105 base::PlatformFileError error) {
88 delegate_->DownloadedFile(name, error); 106 if (delegate_)
107 delegate_->DownloadedFile(name, error);
89 } 108 }
90 109
91 void MTPDeviceDelegateImplMac::DeviceListener::DeviceRemoved() { 110 void MTPDeviceDelegateImplMac::DeviceListener::DeviceRemoved() {
92 [camera_device_ close]; 111 [camera_device_ close];
93 camera_device_.reset(); 112 camera_device_.reset();
113 if (delegate_)
114 delegate_->NoMoreItems();
115 }
116
117 void MTPDeviceDelegateImplMac::DeviceListener::ResetDelegate() {
118 delegate_ = NULL;
94 } 119 }
95 120
96 MTPDeviceDelegateImplMac::MTPDeviceDelegateImplMac( 121 MTPDeviceDelegateImplMac::MTPDeviceDelegateImplMac(
97 const std::string& device_id, 122 const std::string& device_id,
98 const base::FilePath::StringType& synthetic_path, 123 const base::FilePath::StringType& synthetic_path)
99 base::SequencedTaskRunner* media_task_runner)
100 : device_id_(device_id), 124 : device_id_(device_id),
101 root_path_(synthetic_path), 125 root_path_(synthetic_path),
102 media_task_runner_(media_task_runner),
103 enumerator_(NULL),
104 file_download_event_(NULL),
105 file_download_error_(base::PLATFORM_FILE_OK),
106 received_all_files_(false) { 126 received_all_files_(false) {
107 127
108 // Make a synthetic entry for the root of the filesystem. 128 // Make a synthetic entry for the root of the filesystem.
109 base::PlatformFileInfo info; 129 base::PlatformFileInfo info;
110 info.is_directory = true; 130 info.is_directory = true;
111 file_info_[root_path_.value()] = info; 131 file_info_[root_path_.value()] = info;
112 132
113 camera_interface_.reset(new DeviceListener(this)); 133 camera_interface_.reset(new DeviceListener(this));
114 content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE, 134 content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE,
115 base::Bind(&DeviceListener::OpenCameraSession, 135 base::Bind(&DeviceListener::OpenCameraSession,
116 base::Unretained(camera_interface_.get()), 136 base::Unretained(camera_interface_.get()),
117 device_id_)); 137 device_id_));
118 } 138 }
119 139
120 MTPDeviceDelegateImplMac::~MTPDeviceDelegateImplMac() { 140 MTPDeviceDelegateImplMac::~MTPDeviceDelegateImplMac() {
121 DCHECK(media_task_runner_->RunsTasksOnCurrentThread());
122 DCHECK(enumerator_ == NULL);
123 } 141 }
124 142
125 base::PlatformFileError MTPDeviceDelegateImplMac::GetFileInfo( 143 namespace {
144
145 void ForwardGetFileInfo(
146 base::PlatformFileInfo* info,
147 base::PlatformFileError* error,
148 const GetFileInfoSuccessCallback& success_callback,
149 const ErrorCallback& error_callback) {
150 scoped_ptr<base::PlatformFileInfo> info_deleter(info);
151 scoped_ptr<base::PlatformFileError> error_deleter(error);
152
153 if (*error == base::PLATFORM_FILE_OK) {
154 success_callback.Run(*info);
155 } else {
156 error_callback.Run(*error);
157 }
158 }
159
160 } // namespace
161
162 void MTPDeviceDelegateImplMac::GetFileInfo(
126 const base::FilePath& file_path, 163 const base::FilePath& file_path,
127 base::PlatformFileInfo* file_info) { 164 const GetFileInfoSuccessCallback& success_callback,
128 base::AutoLock lock(mutex_); 165 const ErrorCallback& error_callback) {
166 base::PlatformFileInfo* info = new base::PlatformFileInfo;
167 base::PlatformFileError* error = new base::PlatformFileError;
168 content::BrowserThread::PostTaskAndReply(content::BrowserThread::UI,
Lei Zhang 2013/03/04 22:45:01 You can do PostTaskAndReplyWithResults, such that
Greg Billock 2013/03/06 00:28:30 Used Owned() here and in ReadDir.
169 FROM_HERE,
170 base::Bind(&MTPDeviceDelegateImplMac::GetFileInfoImpl,
171 base::Unretained(this), file_path, info, error),
172 base::Bind(&ForwardGetFileInfo,
173 info, error, success_callback, error_callback));
174 }
175
176 void MTPDeviceDelegateImplMac::ReadDirectory(
177 const base::FilePath& root,
178 const ReadDirectorySuccessCallback& success_callback,
179 const ErrorCallback& error_callback) {
180 content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE,
181 base::Bind(&MTPDeviceDelegateImplMac::ReadDirectoryImpl,
182 base::Unretained(this),
183 root, success_callback, error_callback));
184 }
185
186 void MTPDeviceDelegateImplMac::CreateSnapshotFile(
187 const base::FilePath& device_file_path,
188 const base::FilePath& local_path,
189 const CreateSnapshotFileSuccessCallback& success_callback,
190 const ErrorCallback& error_callback) {
191 content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE,
192 base::Bind(&MTPDeviceDelegateImplMac::DownloadFile,
193 base::Unretained(this),
194 device_file_path, local_path,
195 success_callback, error_callback));
196 }
197
198 void MTPDeviceDelegateImplMac::CancelPendingTasksAndDeleteDelegate() {
199 content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE,
200 base::Bind(&MTPDeviceDelegateImplMac::CancelAndDelete,
201 base::Unretained(this)));
202 }
203
204 void MTPDeviceDelegateImplMac::GetFileInfoImpl(
205 const base::FilePath& file_path,
206 base::PlatformFileInfo* file_info,
207 base::PlatformFileError* error) {
208 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
129 base::hash_map<base::FilePath::StringType, 209 base::hash_map<base::FilePath::StringType,
130 base::PlatformFileInfo>::const_iterator i = 210 base::PlatformFileInfo>::const_iterator i =
131 file_info_.find(file_path.value()); 211 file_info_.find(file_path.value());
132 if (i == file_info_.end()) 212 if (i == file_info_.end()) {
133 return base::PLATFORM_FILE_ERROR_NOT_FOUND; 213 *error = base::PLATFORM_FILE_ERROR_NOT_FOUND;
134 214 return;
215 }
135 *file_info = i->second; 216 *file_info = i->second;
136 return base::PLATFORM_FILE_OK; 217 *error = base::PLATFORM_FILE_OK;
137 } 218 }
138 219
139 scoped_ptr<fileapi::FileSystemFileUtil::AbstractFileEnumerator> 220 void MTPDeviceDelegateImplMac::ReadDirectoryImpl(
140 MTPDeviceDelegateImplMac::CreateFileEnumerator(const base::FilePath& root, 221 const base::FilePath& root,
141 bool recursive) { 222 const ReadDirectorySuccessCallback& success_callback,
142 base::AutoLock lock(mutex_); 223 const ErrorCallback& error_callback) {
143 DCHECK(!enumerator_); 224 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
144 enumerator_ = new Enumerator(this); 225 read_directory_success_callback_ = success_callback;
Lei Zhang 2013/03/04 22:45:01 Isn't it possible for this delegate to receive mul
Greg Billock 2013/03/06 00:28:30 I'm not sure. I'll ask.
145 return make_scoped_ptr(enumerator_) 226 read_directory_error_callback_ = error_callback;
Lei Zhang 2013/03/04 22:45:01 |read_directory_error_callback_| never gets called
Greg Billock 2013/03/06 00:28:30 Yes. I'm not sure what to do about that. Schedule
146 .PassAs<fileapi::FileSystemFileUtil::AbstractFileEnumerator>(); 227
228 if (received_all_files_)
229 NotifyReadDir();
230
231 // TODO(gbillock): Need to add a task on a timeout or something for
232 // the read dir failure?
147 } 233 }
148 234
149 base::PlatformFileError MTPDeviceDelegateImplMac::CreateSnapshotFile( 235 void MTPDeviceDelegateImplMac::DownloadFile(
150 const base::FilePath& device_file_path, 236 const base::FilePath& device_file_path,
151 const base::FilePath& local_path, 237 const base::FilePath& local_path,
152 base::PlatformFileInfo* file_info) { 238 const CreateSnapshotFileSuccessCallback& success_callback,
153 base::PlatformFileError error = GetFileInfo(device_file_path, file_info); 239 const ErrorCallback& error_callback) {
154 if (error != base::PLATFORM_FILE_OK) 240 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
155 return error; 241 read_file_success_callback_ = success_callback;
242 read_file_error_callback_ = error_callback;
156 243
157 // Set up to wait for download. Callers are ensuring this particular function 244 base::PlatformFileError error;
158 // will not be re-entered. 245 base::PlatformFileInfo info;
159 base::WaitableEvent waiter(true, false); 246 GetFileInfoImpl(device_file_path, &info, &error);
160 { 247 if (error != base::PLATFORM_FILE_OK) {
161 base::AutoLock lock(mutex_); 248 content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE,
162 DCHECK(file_download_event_ == NULL); 249 base::Bind(read_file_error_callback_,
163 file_download_event_ = &waiter; 250 error));
251 read_file_success_callback_.Reset();
252 read_file_error_callback_.Reset();
253 return;
164 } 254 }
165 255
166 // Start the download in the UI thread. 256 camera_interface_->DownloadFile(device_file_path.BaseName().value(),
167 content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE, 257 local_path);
168 base::Bind(&DeviceListener::DownloadFile,
169 base::Unretained(camera_interface_.get()),
170 device_file_path.BaseName().value(), local_path));
171 waiter.Wait();
172 {
173 base::AutoLock lock(mutex_);
174 file_download_event_ = NULL;
175 error = file_download_error_;
176 }
177
178 // Modify the last modified time to null. This prevents the time stamp
179 // verification in LocalFileStreamReader.
180 file_info->last_modified = base::Time();
181
182 return error;
183 } 258 }
184 259
185 void MTPDeviceDelegateImplMac::CancelPendingTasksAndDeleteDelegate() { 260 void MTPDeviceDelegateImplMac::CancelAndDelete() {
261 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
186 // Artificially pretend that we have already gotten all items we're going 262 // Artificially pretend that we have already gotten all items we're going
187 // to get. 263 // to get.
188 NoMoreItems(); 264 NoMoreItems();
189 265
190 { 266 CancelDownloads();
191 base::AutoLock lock(mutex_);
192 // Artificially wake up any downloads pending with an error code.
193 if (file_download_event_) {
194 file_download_error_ = base::PLATFORM_FILE_ERROR_FAILED;
195 file_download_event_->Signal();
196 }
197 }
198 267
199 // Schedule the camera session to be closed and the interface deleted. 268 // Schedule the camera session to be closed and the interface deleted.
269 camera_interface_->ResetDelegate();
200 content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE, 270 content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE,
201 base::Bind(&DeviceListener::CloseCameraSessionAndDelete, 271 base::Bind(&DeviceListener::CloseCameraSessionAndDelete,
202 base::Unretained(camera_interface_.release()))); 272 base::Unretained(camera_interface_.release())));
203 273
204 media_task_runner_->DeleteSoon(FROM_HERE, this); 274 delete this;
205 } 275 }
206 276
277 void MTPDeviceDelegateImplMac::CancelDownloads() {
278 // TODO(gbillock): implement.
279 read_file_success_callback_.Reset();
280 read_file_error_callback_.Reset();
281 }
282
283 // Called on the UI thread by the listener
207 void MTPDeviceDelegateImplMac::ItemAdded( 284 void MTPDeviceDelegateImplMac::ItemAdded(
208 const std::string& name, const base::PlatformFileInfo& info) { 285 const std::string& name, const base::PlatformFileInfo& info) {
209 base::AutoLock lock(mutex_);
210
211 // Make sure that if we're canceled and an enumerator is awake, that
212 // it will stay consistent. May need to revisit this if we need
213 // notifications of files added after we think we're done.
214 if (received_all_files_) 286 if (received_all_files_)
215 return; 287 return;
216 288
217 // TODO(gbillock): Currently we flatten all files into a single 289 // TODO(gbillock): Currently we flatten all files into a single
218 // directory. That's pretty much how PTP devices work, but if we want 290 // directory. That's pretty much how PTP devices work, but if we want
219 // to support ImageCapture for USB, we need to change this. 291 // to support ImageCapture for USB, we need to change this.
220 if (info.is_directory) 292 if (info.is_directory)
221 return; 293 return;
222 294
223 base::FilePath item_filename = root_path_.Append(name); 295 base::FilePath item_filename = root_path_.Append(name);
224 file_info_[item_filename.value()] = info; 296 file_info_[item_filename.value()] = info;
225 file_paths_.push_back(item_filename); 297 file_paths_.push_back(item_filename);
226 298
227 if (enumerator_) 299 // TODO(gbillock): Should we send new files to
228 enumerator_->ItemsChanged(); 300 // read_directory_success_callback?
229 } 301 }
230 302
303 // Called in the UI thread by delegate.
231 void MTPDeviceDelegateImplMac::NoMoreItems() { 304 void MTPDeviceDelegateImplMac::NoMoreItems() {
232 base::AutoLock lock(mutex_);
233 received_all_files_ = true; 305 received_all_files_ = true;
234 306 NotifyReadDir();
235 if (enumerator_)
236 enumerator_->ItemsChanged();
237 } 307 }
238 308
309 void ForwardReadDir(
310 const ReadDirectorySuccessCallback& success_callback,
311 fileapi::AsyncFileUtil::EntryList* entry_list,
312 bool has_more) {
313 scoped_ptr<fileapi::AsyncFileUtil::EntryList> list_deleter(entry_list);
314 success_callback.Run(*entry_list, has_more);
315 }
316
317 void MTPDeviceDelegateImplMac::NotifyReadDir() {
318 if (!read_directory_success_callback_.is_null()) {
319 // TODO(gbillock): should we just switch to using this directly internally
320 // instead of PlatformFileInfo?
321 fileapi::AsyncFileUtil::EntryList* entry_list =
322 new fileapi::AsyncFileUtil::EntryList;
323 for (size_t i = 0; i < file_paths_.size(); ++i) {
324 base::PlatformFileInfo info = file_info_[file_paths_[i].value()];
325 base::FileUtilProxy::Entry entry;
326 entry.name = file_paths_[i].value();
327 entry.is_directory = info.is_directory;
328 entry.size = info.size;
329 entry.last_modified_time = info.last_modified;
330 entry_list->push_back(entry);
331 }
332 content::BrowserThread::PostTask(content::BrowserThread::IO,
333 FROM_HERE,
334 base::Bind(&ForwardReadDir,
335 read_directory_success_callback_, entry_list, false));
336
337 read_directory_success_callback_.Reset();
338 read_directory_error_callback_.Reset();
339 }
340 }
341
342 // Invoked on UI thread from the listener.
239 void MTPDeviceDelegateImplMac::DownloadedFile( 343 void MTPDeviceDelegateImplMac::DownloadedFile(
240 const std::string& name, base::PlatformFileError error) { 344 const std::string& name, base::PlatformFileError error) {
241 // If we're cancelled and deleting, we have already signaled all enumerators. 345 // If we're cancelled and deleting, we may have deleted the camera.
242 if (!camera_interface_.get()) 346 if (!camera_interface_.get())
243 return; 347 return;
244 348
245 base::AutoLock lock(mutex_); 349 if (!read_file_success_callback_.is_null()) {
246 file_download_error_ = error; 350 if (error == base::PLATFORM_FILE_OK) {
247 file_download_event_->Signal(); 351 base::FilePath path(name);
352 base::PlatformFileInfo info = file_info_[path.value()];
353 content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE,
354 base::Bind(read_file_success_callback_, info, path));
355 } else {
356 content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE,
357 base::Bind(read_file_error_callback_, error));
358 }
359 read_file_success_callback_.Reset();
360 read_file_error_callback_.Reset();
361 }
248 } 362 }
249 363
250 base::FilePath MTPDeviceDelegateImplMac::GetFile(size_t index) { 364 void CreateMTPDeviceAsyncDelegate(
251 base::AutoLock lock(mutex_); 365 const base::FilePath::StringType& device_location,
252 if (index >= file_paths_.size()) 366 const CreateMTPDeviceAsyncDelegateCallback& cb) {
253 return base::FilePath(); 367 std::string device_name =
254 else 368 base::FilePath(device_location).BaseName().value();
255 return file_paths_[index];
256 }
257
258 bool MTPDeviceDelegateImplMac::ReceivedAllFiles() {
259 base::AutoLock lock(mutex_);
260 return received_all_files_;
261 }
262
263 void MTPDeviceDelegateImplMac::RemoveEnumerator(Enumerator* enumerator) {
264 base::AutoLock lock(mutex_);
265 DCHECK(enumerator_ == enumerator);
266 enumerator_ = NULL;
267 }
268
269 MTPDeviceDelegateImplMac::Enumerator::Enumerator(
270 MTPDeviceDelegateImplMac* delegate)
271 : delegate_(delegate),
272 position_(0),
273 wait_for_items_(false, false) {}
274
275 MTPDeviceDelegateImplMac::Enumerator::~Enumerator() {
276 delegate_->RemoveEnumerator(this);
277 }
278
279 base::FilePath MTPDeviceDelegateImplMac::Enumerator::Next() {
280 base::FilePath next_file = delegate_->GetFile(position_);
281 while (next_file.empty() && !delegate_->ReceivedAllFiles()) {
282 wait_for_items_.Wait();
283 next_file = delegate_->GetFile(position_);
284 }
285
286 position_++;
287 return next_file;
288 }
289
290 int64 MTPDeviceDelegateImplMac::Enumerator::Size() {
291 base::PlatformFileInfo info;
292 delegate_->GetFileInfo(delegate_->GetFile(position_ - 1), &info);
293 return info.size;
294 }
295
296 base::Time MTPDeviceDelegateImplMac::Enumerator::LastModifiedTime() {
297 base::PlatformFileInfo info;
298 delegate_->GetFileInfo(delegate_->GetFile(position_ - 1), &info);
299 return info.last_modified;
300 }
301
302 bool MTPDeviceDelegateImplMac::Enumerator::IsDirectory() {
303 base::PlatformFileInfo info;
304 delegate_->GetFileInfo(delegate_->GetFile(position_ - 1), &info);
305 return info.is_directory;
306 }
307
308 void MTPDeviceDelegateImplMac::Enumerator::ItemsChanged() {
309 wait_for_items_.Signal();
310 }
311
312 void CreateMTPDeviceDelegate(const std::string& device_location,
313 base::SequencedTaskRunner* media_task_runner,
314 const CreateMTPDeviceDelegateCallback& cb) {
315 std::string device_name = base::FilePath(device_location).BaseName().value();
316 std::string device_id; 369 std::string device_id;
317 MediaStorageUtil::Type type; 370 MediaStorageUtil::Type type;
318 bool cracked = MediaStorageUtil::CrackDeviceId(device_name, 371 bool cracked = MediaStorageUtil::CrackDeviceId(device_name,
319 &type, &device_id); 372 &type, &device_id);
320 DCHECK(cracked); 373 DCHECK(cracked);
321 DCHECK_EQ(MediaStorageUtil::MAC_IMAGE_CAPTURE, type); 374 DCHECK_EQ(MediaStorageUtil::MAC_IMAGE_CAPTURE, type);
322 375
323 cb.Run(new MTPDeviceDelegateImplMac(device_id, device_location, 376 cb.Run(new MTPDeviceDelegateImplMac(device_id, device_location));
324 media_task_runner));
325 } 377 }
326 378
327 } // namespace chrome 379 } // namespace chrome
328 380
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698