| 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 |