OLD | NEW |
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 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_galleries/fileapi/device_media_async_file_util.h" | 5 #include "chrome/browser/media_galleries/fileapi/device_media_async_file_util.h" |
6 | 6 |
7 #include "base/callback.h" | 7 #include "base/callback.h" |
8 #include "base/file_util.h" | 8 #include "base/file_util.h" |
9 #include "base/single_thread_task_runner.h" | 9 #include "base/single_thread_task_runner.h" |
10 #include "base/task_runner_util.h" | 10 #include "base/task_runner_util.h" |
(...skipping 28 matching lines...) Expand all Loading... |
39 | 39 |
40 // Called when GetFileInfo method call failed to get the details of file | 40 // Called when GetFileInfo method call failed to get the details of file |
41 // specified by the requested url. |callback| is invoked to notify the | 41 // specified by the requested url. |callback| is invoked to notify the |
42 // caller about the file |error|. | 42 // caller about the file |error|. |
43 void OnGetFileInfoError(const AsyncFileUtil::GetFileInfoCallback& callback, | 43 void OnGetFileInfoError(const AsyncFileUtil::GetFileInfoCallback& callback, |
44 base::File::Error error) { | 44 base::File::Error error) { |
45 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); | 45 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); |
46 callback.Run(error, base::File::Info()); | 46 callback.Run(error, base::File::Info()); |
47 } | 47 } |
48 | 48 |
| 49 // Called after OnDidGetFileInfo finishes media check. |
| 50 // |callback| is invoked to complete the GetFileInfo request. |
| 51 void OnDidCheckMediaForGetFileInfo( |
| 52 const AsyncFileUtil::GetFileInfoCallback& callback, |
| 53 const base::File::Info& file_info, |
| 54 bool is_valid_file) { |
| 55 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); |
| 56 if (!is_valid_file) { |
| 57 OnGetFileInfoError(callback, base::File::FILE_ERROR_NOT_FOUND); |
| 58 return; |
| 59 } |
| 60 callback.Run(base::File::FILE_OK, file_info); |
| 61 } |
| 62 |
| 63 // Called after OnDidReadDirectory finishes media check. |
| 64 // |callback| is invoked to complete the ReadDirectory request. |
| 65 void OnDidCheckMediaForReadDirectory( |
| 66 const AsyncFileUtil::ReadDirectoryCallback& callback, |
| 67 bool has_more, |
| 68 const AsyncFileUtil::EntryList& file_list) { |
| 69 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); |
| 70 callback.Run(base::File::FILE_OK, file_list, has_more); |
| 71 } |
| 72 |
49 // Called when ReadDirectory method call failed to enumerate the directory | 73 // Called when ReadDirectory method call failed to enumerate the directory |
50 // objects. |callback| is invoked to notify the caller about the |error| | 74 // objects. |callback| is invoked to notify the caller about the |error| |
51 // that occured while reading the directory objects. | 75 // that occured while reading the directory objects. |
52 void OnReadDirectoryError(const AsyncFileUtil::ReadDirectoryCallback& callback, | 76 void OnReadDirectoryError(const AsyncFileUtil::ReadDirectoryCallback& callback, |
53 base::File::Error error) { | 77 base::File::Error error) { |
54 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); | 78 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); |
55 callback.Run(error, AsyncFileUtil::EntryList(), false /*no more*/); | 79 callback.Run(error, AsyncFileUtil::EntryList(), false /*no more*/); |
56 } | 80 } |
57 | 81 |
58 // Called on a blocking pool thread to create a snapshot file to hold the | 82 // Called on a blocking pool thread to create a snapshot file to hold the |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
157 snapshot_file_path, | 181 snapshot_file_path, |
158 base::Bind(&OnDidCreateSnapshotFile, | 182 base::Bind(&OnDidCreateSnapshotFile, |
159 callback, | 183 callback, |
160 make_scoped_refptr(context->task_runner()), | 184 make_scoped_refptr(context->task_runner()), |
161 validate_media_files), | 185 validate_media_files), |
162 base::Bind(&OnCreateSnapshotFileError, callback)); | 186 base::Bind(&OnCreateSnapshotFileError, callback)); |
163 } | 187 } |
164 | 188 |
165 } // namespace | 189 } // namespace |
166 | 190 |
| 191 class DeviceMediaAsyncFileUtil::MediaPathFilterWrapper |
| 192 : public base::RefCountedThreadSafe<MediaPathFilterWrapper> { |
| 193 public: |
| 194 MediaPathFilterWrapper(); |
| 195 |
| 196 // Check if entries in |file_list| look like media files. |
| 197 // Append the ones that look like media files to |results|. |
| 198 // Should run on a media task runner. |
| 199 AsyncFileUtil::EntryList FilterMediaEntries( |
| 200 const AsyncFileUtil::EntryList& file_list); |
| 201 |
| 202 // Check if |path| looks like a media file. |
| 203 bool CheckFilePath(const base::FilePath& path); |
| 204 |
| 205 private: |
| 206 friend class base::RefCountedThreadSafe<MediaPathFilterWrapper>; |
| 207 |
| 208 virtual ~MediaPathFilterWrapper(); |
| 209 |
| 210 scoped_ptr<MediaPathFilter> media_path_filter_; |
| 211 |
| 212 DISALLOW_COPY_AND_ASSIGN(MediaPathFilterWrapper); |
| 213 }; |
| 214 |
| 215 DeviceMediaAsyncFileUtil::MediaPathFilterWrapper::MediaPathFilterWrapper() |
| 216 : media_path_filter_(new MediaPathFilter) { |
| 217 } |
| 218 |
| 219 DeviceMediaAsyncFileUtil::MediaPathFilterWrapper::~MediaPathFilterWrapper() { |
| 220 } |
| 221 |
| 222 AsyncFileUtil::EntryList |
| 223 DeviceMediaAsyncFileUtil::MediaPathFilterWrapper::FilterMediaEntries( |
| 224 const AsyncFileUtil::EntryList& file_list) { |
| 225 AsyncFileUtil::EntryList results; |
| 226 for (size_t i = 0; i < file_list.size(); ++i) { |
| 227 const fileapi::DirectoryEntry& entry = file_list[i]; |
| 228 if (entry.is_directory || CheckFilePath(base::FilePath(entry.name))) { |
| 229 results.push_back(entry); |
| 230 } |
| 231 } |
| 232 return results; |
| 233 } |
| 234 |
| 235 bool DeviceMediaAsyncFileUtil::MediaPathFilterWrapper::CheckFilePath( |
| 236 const base::FilePath& path) { |
| 237 return media_path_filter_->Match(path); |
| 238 } |
| 239 |
167 DeviceMediaAsyncFileUtil::~DeviceMediaAsyncFileUtil() { | 240 DeviceMediaAsyncFileUtil::~DeviceMediaAsyncFileUtil() { |
168 } | 241 } |
169 | 242 |
170 // static | 243 // static |
171 scoped_ptr<DeviceMediaAsyncFileUtil> DeviceMediaAsyncFileUtil::Create( | 244 scoped_ptr<DeviceMediaAsyncFileUtil> DeviceMediaAsyncFileUtil::Create( |
172 const base::FilePath& profile_path, | 245 const base::FilePath& profile_path, |
173 MediaFileValidationType validation_type) { | 246 MediaFileValidationType validation_type) { |
174 DCHECK(!profile_path.empty()); | 247 DCHECK(!profile_path.empty()); |
175 return make_scoped_ptr( | 248 return make_scoped_ptr( |
176 new DeviceMediaAsyncFileUtil(profile_path, validation_type)); | 249 new DeviceMediaAsyncFileUtil(profile_path, validation_type)); |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
234 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); | 307 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); |
235 MTPDeviceAsyncDelegate* delegate = GetMTPDeviceDelegate(url); | 308 MTPDeviceAsyncDelegate* delegate = GetMTPDeviceDelegate(url); |
236 if (!delegate) { | 309 if (!delegate) { |
237 OnGetFileInfoError(callback, base::File::FILE_ERROR_NOT_FOUND); | 310 OnGetFileInfoError(callback, base::File::FILE_ERROR_NOT_FOUND); |
238 return; | 311 return; |
239 } | 312 } |
240 delegate->GetFileInfo( | 313 delegate->GetFileInfo( |
241 url.path(), | 314 url.path(), |
242 base::Bind(&DeviceMediaAsyncFileUtil::OnDidGetFileInfo, | 315 base::Bind(&DeviceMediaAsyncFileUtil::OnDidGetFileInfo, |
243 weak_ptr_factory_.GetWeakPtr(), | 316 weak_ptr_factory_.GetWeakPtr(), |
| 317 base::Passed(&context), |
| 318 url.path(), |
244 callback), | 319 callback), |
245 base::Bind(&OnGetFileInfoError, callback)); | 320 base::Bind(&OnGetFileInfoError, callback)); |
246 } | 321 } |
247 | 322 |
248 void DeviceMediaAsyncFileUtil::ReadDirectory( | 323 void DeviceMediaAsyncFileUtil::ReadDirectory( |
249 scoped_ptr<FileSystemOperationContext> context, | 324 scoped_ptr<FileSystemOperationContext> context, |
250 const FileSystemURL& url, | 325 const FileSystemURL& url, |
251 const ReadDirectoryCallback& callback) { | 326 const ReadDirectoryCallback& callback) { |
252 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); | 327 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); |
253 MTPDeviceAsyncDelegate* delegate = GetMTPDeviceDelegate(url); | 328 MTPDeviceAsyncDelegate* delegate = GetMTPDeviceDelegate(url); |
254 if (!delegate) { | 329 if (!delegate) { |
255 OnReadDirectoryError(callback, base::File::FILE_ERROR_NOT_FOUND); | 330 OnReadDirectoryError(callback, base::File::FILE_ERROR_NOT_FOUND); |
256 return; | 331 return; |
257 } | 332 } |
258 delegate->ReadDirectory( | 333 delegate->ReadDirectory( |
259 url.path(), | 334 url.path(), |
260 base::Bind(&DeviceMediaAsyncFileUtil::OnDidReadDirectory, | 335 base::Bind(&DeviceMediaAsyncFileUtil::OnDidReadDirectory, |
261 weak_ptr_factory_.GetWeakPtr(), | 336 weak_ptr_factory_.GetWeakPtr(), |
| 337 base::Passed(&context), |
262 callback), | 338 callback), |
263 base::Bind(&OnReadDirectoryError, callback)); | 339 base::Bind(&OnReadDirectoryError, callback)); |
264 } | 340 } |
265 | 341 |
266 void DeviceMediaAsyncFileUtil::Touch( | 342 void DeviceMediaAsyncFileUtil::Touch( |
267 scoped_ptr<FileSystemOperationContext> context, | 343 scoped_ptr<FileSystemOperationContext> context, |
268 const FileSystemURL& url, | 344 const FileSystemURL& url, |
269 const base::Time& last_access_time, | 345 const base::Time& last_access_time, |
270 const base::Time& last_modified_time, | 346 const base::Time& last_modified_time, |
271 const StatusCallback& callback) { | 347 const StatusCallback& callback) { |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
383 url, | 459 url, |
384 offset, | 460 offset, |
385 expected_modification_time, | 461 expected_modification_time, |
386 validate_media_files()))); | 462 validate_media_files()))); |
387 } | 463 } |
388 | 464 |
389 DeviceMediaAsyncFileUtil::DeviceMediaAsyncFileUtil( | 465 DeviceMediaAsyncFileUtil::DeviceMediaAsyncFileUtil( |
390 const base::FilePath& profile_path, | 466 const base::FilePath& profile_path, |
391 MediaFileValidationType validation_type) | 467 MediaFileValidationType validation_type) |
392 : profile_path_(profile_path), | 468 : profile_path_(profile_path), |
393 validation_type_(validation_type), | |
394 weak_ptr_factory_(this) { | 469 weak_ptr_factory_(this) { |
| 470 if (validation_type == APPLY_MEDIA_FILE_VALIDATION) { |
| 471 media_path_filter_wrapper_ = new MediaPathFilterWrapper; |
| 472 } |
395 } | 473 } |
396 | 474 |
397 void DeviceMediaAsyncFileUtil::OnDidGetFileInfo( | 475 void DeviceMediaAsyncFileUtil::OnDidGetFileInfo( |
398 const GetFileInfoCallback& callback, | 476 scoped_ptr<FileSystemOperationContext> context, |
| 477 const base::FilePath& path, |
| 478 const AsyncFileUtil::GetFileInfoCallback& callback, |
399 const base::File::Info& file_info) { | 479 const base::File::Info& file_info) { |
400 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); | 480 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); |
401 callback.Run(base::File::FILE_OK, file_info); | 481 if (file_info.is_directory || !validate_media_files()) { |
| 482 OnDidCheckMediaForGetFileInfo(callback, file_info, true /* valid */); |
| 483 return; |
| 484 } |
| 485 |
| 486 base::PostTaskAndReplyWithResult( |
| 487 context->task_runner(), |
| 488 FROM_HERE, |
| 489 base::Bind(&MediaPathFilterWrapper::CheckFilePath, |
| 490 media_path_filter_wrapper_, |
| 491 path), |
| 492 base::Bind(&OnDidCheckMediaForGetFileInfo, callback, file_info)); |
402 } | 493 } |
403 | 494 |
404 void DeviceMediaAsyncFileUtil::OnDidReadDirectory( | 495 void DeviceMediaAsyncFileUtil::OnDidReadDirectory( |
405 const ReadDirectoryCallback& callback, | 496 scoped_ptr<fileapi::FileSystemOperationContext> context, |
406 const EntryList& file_list, | 497 const AsyncFileUtil::ReadDirectoryCallback& callback, |
| 498 const AsyncFileUtil::EntryList& file_list, |
407 bool has_more) { | 499 bool has_more) { |
408 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); | 500 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); |
409 callback.Run(base::File::FILE_OK, file_list, has_more); | 501 if (!validate_media_files()) { |
| 502 OnDidCheckMediaForReadDirectory(callback, has_more, file_list); |
| 503 return; |
| 504 } |
| 505 |
| 506 base::PostTaskAndReplyWithResult( |
| 507 context->task_runner(), |
| 508 FROM_HERE, |
| 509 base::Bind(&MediaPathFilterWrapper::FilterMediaEntries, |
| 510 media_path_filter_wrapper_, |
| 511 file_list), |
| 512 base::Bind(&OnDidCheckMediaForReadDirectory, callback, has_more)); |
410 } | 513 } |
411 | 514 |
412 bool DeviceMediaAsyncFileUtil::validate_media_files() const { | 515 bool DeviceMediaAsyncFileUtil::validate_media_files() const { |
413 return validation_type_ == APPLY_MEDIA_FILE_VALIDATION; | 516 return media_path_filter_wrapper_.get() != NULL; |
414 } | 517 } |
OLD | NEW |