12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved. 22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file. 42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/media_galleries/fileapi/device_media_async_file_util.h" 62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/callback.h" 81320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/files/file_util.h" 92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/single_thread_task_runner.h" 1090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "base/task_runner_util.h" 11c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/media_galleries/fileapi/media_path_filter.h" 12c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/media_galleries/fileapi/mtp_device_async_delegate.h" 13c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/media_galleries/fileapi/mtp_device_map_service.h" 145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/media_galleries/fileapi/mtp_file_stream_reader.h" 15a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)#include "chrome/browser/media_galleries/fileapi/native_media_file_util.h" 16a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "chrome/browser/media_galleries/fileapi/readahead_file_stream_reader.h" 17bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch#include "content/public/browser/browser_thread.h" 181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/blob/file_stream_reader.h" 191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/file_system_context.h" 201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/file_system_operation_context.h" 211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/file_system_url.h" 221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/native_file_util.h" 231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/common/blob/shareable_file_reference.h" 242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)using storage::AsyncFileUtil; 2603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)using storage::FileSystemOperationContext; 2703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)using storage::FileSystemURL; 2803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)using storage::ShareableFileReference; 29c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace { 312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 32bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdochconst char kDeviceMediaAsyncFileUtilTempDir[] = "DeviceMediaFileSystem"; 332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 34bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben MurdochMTPDeviceAsyncDelegate* GetMTPDeviceDelegate(const FileSystemURL& url) { 35e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch DCHECK_CURRENTLY_ON(content::BrowserThread::IO); 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return MTPDeviceMapService::GetInstance()->GetMTPDeviceAsyncDelegate( 37bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch url.filesystem_id()); 382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 40cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Called when GetFileInfo method call failed to get the details of file 41cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// specified by the requested url. |callback| is invoked to notify the 42cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// caller about the file |error|. 43cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void OnGetFileInfoError(const AsyncFileUtil::GetFileInfoCallback& callback, 44cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::File::Error error) { 45cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DCHECK_CURRENTLY_ON(content::BrowserThread::IO); 46cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) callback.Run(error, base::File::Info()); 47cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 48cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 49cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Called after OnDidGetFileInfo finishes media check. 50cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// |callback| is invoked to complete the GetFileInfo request. 51cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void OnDidCheckMediaForGetFileInfo( 52cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const AsyncFileUtil::GetFileInfoCallback& callback, 53cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const base::File::Info& file_info, 54cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) bool is_valid_file) { 55cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DCHECK_CURRENTLY_ON(content::BrowserThread::IO); 56cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (!is_valid_file) { 57cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) OnGetFileInfoError(callback, base::File::FILE_ERROR_NOT_FOUND); 58cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return; 59cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 60cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) callback.Run(base::File::FILE_OK, file_info); 61cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 62cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 63cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Called after OnDidReadDirectory finishes media check. 64cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// |callback| is invoked to complete the ReadDirectory request. 65cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void OnDidCheckMediaForReadDirectory( 66cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const AsyncFileUtil::ReadDirectoryCallback& callback, 67cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) bool has_more, 68cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const AsyncFileUtil::EntryList& file_list) { 69cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DCHECK_CURRENTLY_ON(content::BrowserThread::IO); 70cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) callback.Run(base::File::FILE_OK, file_list, has_more); 71cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 72cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 73cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Called when ReadDirectory method call failed to enumerate the directory 74cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// objects. |callback| is invoked to notify the caller about the |error| 75cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// that occured while reading the directory objects. 76cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void OnReadDirectoryError(const AsyncFileUtil::ReadDirectoryCallback& callback, 77cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::File::Error error) { 78cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DCHECK_CURRENTLY_ON(content::BrowserThread::IO); 79cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) callback.Run(error, AsyncFileUtil::EntryList(), false /*no more*/); 80cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 81cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Called on a blocking pool thread to create a snapshot file to hold the 83a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch// contents of |device_file_path|. The snapshot file is created in the 84a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch// "profile_path/kDeviceMediaAsyncFileUtilTempDir" directory. Return the 85a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch// snapshot file path or an empty path on failure. 86a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochbase::FilePath CreateSnapshotFileOnBlockingPool( 872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::FilePath& device_file_path, 88a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch const base::FilePath& profile_path) { 89a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch base::FilePath snapshot_file_path; 90effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch base::FilePath media_file_system_dir_path = 91bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch profile_path.AppendASCII(kDeviceMediaAsyncFileUtilTempDir); 92effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (!base::CreateDirectory(media_file_system_dir_path) || 93effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch !base::CreateTemporaryFileInDir(media_file_system_dir_path, 94a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch &snapshot_file_path)) { 952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LOG(WARNING) << "Could not create media snapshot file " 96effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch << media_file_system_dir_path.value(); 97a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch snapshot_file_path = base::FilePath(); 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 99a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch return snapshot_file_path; 1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 102cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Called after OnDidCreateSnapshotFile finishes media check. 103cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// |callback| is invoked to complete the CreateSnapshotFile request. 104cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void OnDidCheckMediaForCreateSnapshotFile( 105cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const AsyncFileUtil::CreateSnapshotFileCallback& callback, 106cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const base::File::Info& file_info, 10703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) scoped_refptr<storage::ShareableFileReference> platform_file, 108cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::File::Error error) { 109cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DCHECK_CURRENTLY_ON(content::BrowserThread::IO); 110cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::FilePath platform_path(platform_file.get()->path()); 111cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (error != base::File::FILE_OK) 112cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) platform_file = NULL; 113cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) callback.Run(error, file_info, platform_path, platform_file); 114cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 115cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 116cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Called when the snapshot file specified by the |platform_path| is 117cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// successfully created. |file_info| contains the device media file details 118cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// for which the snapshot file is created. 119cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void OnDidCreateSnapshotFile( 120cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const AsyncFileUtil::CreateSnapshotFileCallback& callback, 121cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::SequencedTaskRunner* media_task_runner, 122cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) bool validate_media_files, 123cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const base::File::Info& file_info, 124cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const base::FilePath& platform_path) { 125cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DCHECK_CURRENTLY_ON(content::BrowserThread::IO); 12603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) scoped_refptr<storage::ShareableFileReference> file = 127cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ShareableFileReference::GetOrCreate( 128cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) platform_path, 129cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ShareableFileReference::DELETE_ON_FINAL_RELEASE, 130cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) media_task_runner); 131cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 132cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (validate_media_files) { 133cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::PostTaskAndReplyWithResult( 134cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) media_task_runner, 135cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) FROM_HERE, 136cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::Bind(&NativeMediaFileUtil::IsMediaFile, platform_path), 137cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::Bind(&OnDidCheckMediaForCreateSnapshotFile, 138cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) callback, 139cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) file_info, 140cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) file)); 141cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } else { 142cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) OnDidCheckMediaForCreateSnapshotFile(callback, file_info, file, 143cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::File::FILE_OK); 144cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 145cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 146cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 147cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Called when CreateSnapshotFile method call fails. |callback| is invoked to 148cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// notify the caller about the |error|. 149cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void OnCreateSnapshotFileError( 150cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const AsyncFileUtil::CreateSnapshotFileCallback& callback, 151cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::File::Error error) { 152cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DCHECK_CURRENTLY_ON(content::BrowserThread::IO); 153cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) callback.Run(error, base::File::Info(), base::FilePath(), 154cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) scoped_refptr<ShareableFileReference>()); 155cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 156cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 157cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Called when the snapshot file specified by the |snapshot_file_path| is 158cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// created to hold the contents of the url.path(). If the snapshot 159cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// file is successfully created, |snapshot_file_path| will be an non-empty 160cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// file path. In case of failure, |snapshot_file_path| will be an empty file 161cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// path. Forwards the CreateSnapshot request to the delegate to copy the 162cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// contents of url.path() to |snapshot_file_path|. 163cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void OnSnapshotFileCreatedRunTask( 164cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) scoped_ptr<FileSystemOperationContext> context, 165cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const AsyncFileUtil::CreateSnapshotFileCallback& callback, 166cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const FileSystemURL& url, 167cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) bool validate_media_files, 168cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const base::FilePath& snapshot_file_path) { 169cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DCHECK_CURRENTLY_ON(content::BrowserThread::IO); 170cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (snapshot_file_path.empty()) { 171cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) OnCreateSnapshotFileError(callback, base::File::FILE_ERROR_FAILED); 172cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return; 173cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 174cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) MTPDeviceAsyncDelegate* delegate = GetMTPDeviceDelegate(url); 175cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (!delegate) { 176cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) OnCreateSnapshotFileError(callback, base::File::FILE_ERROR_NOT_FOUND); 177cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return; 178cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 179cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) delegate->CreateSnapshotFile( 180cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) url.path(), // device file path 181cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) snapshot_file_path, 182cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::Bind(&OnDidCreateSnapshotFile, 183cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) callback, 184cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) make_scoped_refptr(context->task_runner()), 185cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) validate_media_files), 186cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::Bind(&OnCreateSnapshotFileError, callback)); 187cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 188cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace 1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 191cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)class DeviceMediaAsyncFileUtil::MediaPathFilterWrapper 192cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) : public base::RefCountedThreadSafe<MediaPathFilterWrapper> { 193cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) public: 194cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) MediaPathFilterWrapper(); 195cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 196cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Check if entries in |file_list| look like media files. 197cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Append the ones that look like media files to |results|. 198cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Should run on a media task runner. 199cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) AsyncFileUtil::EntryList FilterMediaEntries( 200cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const AsyncFileUtil::EntryList& file_list); 201cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 202cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Check if |path| looks like a media file. 203cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) bool CheckFilePath(const base::FilePath& path); 204cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 205cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) private: 206cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) friend class base::RefCountedThreadSafe<MediaPathFilterWrapper>; 207cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 208cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) virtual ~MediaPathFilterWrapper(); 209cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 210cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) scoped_ptr<MediaPathFilter> media_path_filter_; 211cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 212cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(MediaPathFilterWrapper); 213cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}; 214cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 215cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)DeviceMediaAsyncFileUtil::MediaPathFilterWrapper::MediaPathFilterWrapper() 216cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) : media_path_filter_(new MediaPathFilter) { 217cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 218cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 219cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)DeviceMediaAsyncFileUtil::MediaPathFilterWrapper::~MediaPathFilterWrapper() { 220cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 221cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 222cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)AsyncFileUtil::EntryList 223cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)DeviceMediaAsyncFileUtil::MediaPathFilterWrapper::FilterMediaEntries( 224cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const AsyncFileUtil::EntryList& file_list) { 225cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) AsyncFileUtil::EntryList results; 226cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) for (size_t i = 0; i < file_list.size(); ++i) { 22703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) const storage::DirectoryEntry& entry = file_list[i]; 228cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (entry.is_directory || CheckFilePath(base::FilePath(entry.name))) { 229cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) results.push_back(entry); 230cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 231cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 232cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return results; 233cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 234cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 235cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)bool DeviceMediaAsyncFileUtil::MediaPathFilterWrapper::CheckFilePath( 236cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const base::FilePath& path) { 237cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return media_path_filter_->Match(path); 238cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 239cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)DeviceMediaAsyncFileUtil::~DeviceMediaAsyncFileUtil() { 2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static 244cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)scoped_ptr<DeviceMediaAsyncFileUtil> DeviceMediaAsyncFileUtil::Create( 2455c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const base::FilePath& profile_path, 2465c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu MediaFileValidationType validation_type) { 2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!profile_path.empty()); 248cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return make_scoped_ptr( 249cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) new DeviceMediaAsyncFileUtil(profile_path, validation_type)); 2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 252a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool DeviceMediaAsyncFileUtil::SupportsStreaming( 25303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) const storage::FileSystemURL& url) { 254e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch DCHECK_CURRENTLY_ON(content::BrowserThread::IO); 255a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) MTPDeviceAsyncDelegate* delegate = GetMTPDeviceDelegate(url); 256a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!delegate) 257a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return false; 258a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return delegate->IsStreaming(); 259a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 260a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 2617dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid DeviceMediaAsyncFileUtil::CreateOrOpen( 262868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_ptr<FileSystemOperationContext> context, 2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const FileSystemURL& url, 2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int file_flags, 2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const CreateOrOpenCallback& callback) { 266e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch DCHECK_CURRENTLY_ON(content::BrowserThread::IO); 267a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // Returns an error if any unsupported flag is found. 268a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch if (file_flags & ~(base::File::FLAG_OPEN | 269a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch base::File::FLAG_READ | 270a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch base::File::FLAG_WRITE_ATTRIBUTES)) { 271cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) callback.Run(base::File(base::File::FILE_ERROR_SECURITY), base::Closure()); 272a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch return; 273a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch } 274a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch CreateSnapshotFile( 275a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch context.Pass(), 276a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch url, 277a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch base::Bind(&NativeMediaFileUtil::CreatedSnapshotFileForCreateOrOpen, 278a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch make_scoped_refptr(context->task_runner()), 279a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch file_flags, 280a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch callback)); 2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2837dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid DeviceMediaAsyncFileUtil::EnsureFileExists( 284868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_ptr<FileSystemOperationContext> context, 2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const FileSystemURL& url, 2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const EnsureFileExistsCallback& callback) { 287e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch DCHECK_CURRENTLY_ON(content::BrowserThread::IO); 2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NOTIMPLEMENTED(); 2895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) callback.Run(base::File::FILE_ERROR_SECURITY, false); 2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2927dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid DeviceMediaAsyncFileUtil::CreateDirectory( 293868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_ptr<FileSystemOperationContext> context, 2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const FileSystemURL& url, 2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool exclusive, 2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool recursive, 2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const StatusCallback& callback) { 298e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch DCHECK_CURRENTLY_ON(content::BrowserThread::IO); 2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NOTIMPLEMENTED(); 3005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) callback.Run(base::File::FILE_ERROR_SECURITY); 3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3037dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid DeviceMediaAsyncFileUtil::GetFileInfo( 304868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_ptr<FileSystemOperationContext> context, 3052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const FileSystemURL& url, 3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const GetFileInfoCallback& callback) { 307e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch DCHECK_CURRENTLY_ON(content::BrowserThread::IO); 308bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch MTPDeviceAsyncDelegate* delegate = GetMTPDeviceDelegate(url); 3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!delegate) { 3105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) OnGetFileInfoError(callback, base::File::FILE_ERROR_NOT_FOUND); 3117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return; 3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) delegate->GetFileInfo( 3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) url.path(), 3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&DeviceMediaAsyncFileUtil::OnDidGetFileInfo, 3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) weak_ptr_factory_.GetWeakPtr(), 3175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) make_scoped_refptr(context->task_runner()), 318cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) url.path(), 319bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch callback), 320cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::Bind(&OnGetFileInfoError, callback)); 3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid DeviceMediaAsyncFileUtil::ReadDirectory( 324868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_ptr<FileSystemOperationContext> context, 3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const FileSystemURL& url, 3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const ReadDirectoryCallback& callback) { 327e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch DCHECK_CURRENTLY_ON(content::BrowserThread::IO); 328bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch MTPDeviceAsyncDelegate* delegate = GetMTPDeviceDelegate(url); 3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!delegate) { 3305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) OnReadDirectoryError(callback, base::File::FILE_ERROR_NOT_FOUND); 3317dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return; 3322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) delegate->ReadDirectory( 3342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) url.path(), 3352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&DeviceMediaAsyncFileUtil::OnDidReadDirectory, 3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) weak_ptr_factory_.GetWeakPtr(), 3375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) make_scoped_refptr(context->task_runner()), 3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) callback), 339cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::Bind(&OnReadDirectoryError, callback)); 3402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3427dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid DeviceMediaAsyncFileUtil::Touch( 343868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_ptr<FileSystemOperationContext> context, 3442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const FileSystemURL& url, 3452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::Time& last_access_time, 3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::Time& last_modified_time, 3472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const StatusCallback& callback) { 348e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch DCHECK_CURRENTLY_ON(content::BrowserThread::IO); 3492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NOTIMPLEMENTED(); 3505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) callback.Run(base::File::FILE_ERROR_SECURITY); 3512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3537dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid DeviceMediaAsyncFileUtil::Truncate( 354868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_ptr<FileSystemOperationContext> context, 3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const FileSystemURL& url, 3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int64 length, 3572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const StatusCallback& callback) { 358e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch DCHECK_CURRENTLY_ON(content::BrowserThread::IO); 3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NOTIMPLEMENTED(); 3605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) callback.Run(base::File::FILE_ERROR_SECURITY); 3612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3637dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid DeviceMediaAsyncFileUtil::CopyFileLocal( 364868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_ptr<FileSystemOperationContext> context, 3652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const FileSystemURL& src_url, 3662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const FileSystemURL& dest_url, 36768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) CopyOrMoveOption option, 36858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) const CopyFileProgressCallback& progress_callback, 3692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const StatusCallback& callback) { 370e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch DCHECK_CURRENTLY_ON(content::BrowserThread::IO); 3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NOTIMPLEMENTED(); 3725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) callback.Run(base::File::FILE_ERROR_SECURITY); 3732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3757dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid DeviceMediaAsyncFileUtil::MoveFileLocal( 376868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_ptr<FileSystemOperationContext> context, 3772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const FileSystemURL& src_url, 3782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const FileSystemURL& dest_url, 37968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) CopyOrMoveOption option, 3802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const StatusCallback& callback) { 381e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch DCHECK_CURRENTLY_ON(content::BrowserThread::IO); 3822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NOTIMPLEMENTED(); 3835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) callback.Run(base::File::FILE_ERROR_SECURITY); 3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3867dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid DeviceMediaAsyncFileUtil::CopyInForeignFile( 387868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_ptr<FileSystemOperationContext> context, 3882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::FilePath& src_file_path, 3892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const FileSystemURL& dest_url, 3902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const StatusCallback& callback) { 391e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch DCHECK_CURRENTLY_ON(content::BrowserThread::IO); 3922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NOTIMPLEMENTED(); 3935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) callback.Run(base::File::FILE_ERROR_SECURITY); 3942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3967dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid DeviceMediaAsyncFileUtil::DeleteFile( 397868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_ptr<FileSystemOperationContext> context, 3982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const FileSystemURL& url, 3992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const StatusCallback& callback) { 400e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch DCHECK_CURRENTLY_ON(content::BrowserThread::IO); 4012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NOTIMPLEMENTED(); 4025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) callback.Run(base::File::FILE_ERROR_SECURITY); 4032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4057dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid DeviceMediaAsyncFileUtil::DeleteDirectory( 406868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_ptr<FileSystemOperationContext> context, 4072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const FileSystemURL& url, 4082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const StatusCallback& callback) { 409e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch DCHECK_CURRENTLY_ON(content::BrowserThread::IO); 4102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NOTIMPLEMENTED(); 4115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) callback.Run(base::File::FILE_ERROR_SECURITY); 412eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 413eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 4147dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid DeviceMediaAsyncFileUtil::DeleteRecursively( 415eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<FileSystemOperationContext> context, 416eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const FileSystemURL& url, 417eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const StatusCallback& callback) { 418e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch DCHECK_CURRENTLY_ON(content::BrowserThread::IO); 4195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) callback.Run(base::File::FILE_ERROR_INVALID_OPERATION); 4202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid DeviceMediaAsyncFileUtil::CreateSnapshotFile( 423868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_ptr<FileSystemOperationContext> context, 4242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const FileSystemURL& url, 4252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const CreateSnapshotFileCallback& callback) { 426e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch DCHECK_CURRENTLY_ON(content::BrowserThread::IO); 427bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch MTPDeviceAsyncDelegate* delegate = GetMTPDeviceDelegate(url); 4282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!delegate) { 4295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) OnCreateSnapshotFileError(callback, base::File::FILE_ERROR_NOT_FOUND); 4307dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return; 4312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 433a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch scoped_refptr<base::SequencedTaskRunner> task_runner(context->task_runner()); 434a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch base::PostTaskAndReplyWithResult( 4351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci task_runner.get(), 436a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch FROM_HERE, 437cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::Bind(&CreateSnapshotFileOnBlockingPool, url.path(), profile_path_), 438cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::Bind(&OnSnapshotFileCreatedRunTask, 439a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch base::Passed(&context), 440a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch callback, 441cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) url, 442cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) validate_media_files())); 4432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 44503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)scoped_ptr<storage::FileStreamReader> 4465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)DeviceMediaAsyncFileUtil::GetFileStreamReader( 4475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const FileSystemURL& url, 4485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int64 offset, 4495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const base::Time& expected_modification_time, 45003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) storage::FileSystemContext* context) { 4515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) MTPDeviceAsyncDelegate* delegate = GetMTPDeviceDelegate(url); 4525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!delegate) 45303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) return scoped_ptr<storage::FileStreamReader>(); 4545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(delegate->IsStreaming()); 45603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) return scoped_ptr<storage::FileStreamReader>(new ReadaheadFileStreamReader( 45703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) new MTPFileStreamReader(context, 45803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) url, 45903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) offset, 46003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) expected_modification_time, 46103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) validate_media_files()))); 4625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 4635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)DeviceMediaAsyncFileUtil::DeviceMediaAsyncFileUtil( 4655c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const base::FilePath& profile_path, 4665c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu MediaFileValidationType validation_type) 4672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : profile_path_(profile_path), 468c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) weak_ptr_factory_(this) { 469cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (validation_type == APPLY_MEDIA_FILE_VALIDATION) { 470cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) media_path_filter_wrapper_ = new MediaPathFilterWrapper; 471cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 4722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DeviceMediaAsyncFileUtil::OnDidGetFileInfo( 4755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base::SequencedTaskRunner* task_runner, 476cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const base::FilePath& path, 4772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const AsyncFileUtil::GetFileInfoCallback& callback, 4785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const base::File::Info& file_info) { 479cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DCHECK_CURRENTLY_ON(content::BrowserThread::IO); 480cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (file_info.is_directory || !validate_media_files()) { 481cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) OnDidCheckMediaForGetFileInfo(callback, file_info, true /* valid */); 482cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return; 483cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 4842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 485cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::PostTaskAndReplyWithResult( 4865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) task_runner, 487cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) FROM_HERE, 488cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::Bind(&MediaPathFilterWrapper::CheckFilePath, 489cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) media_path_filter_wrapper_, 490cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) path), 491cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::Bind(&OnDidCheckMediaForGetFileInfo, callback, file_info)); 4922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DeviceMediaAsyncFileUtil::OnDidReadDirectory( 4955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base::SequencedTaskRunner* task_runner, 4962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const AsyncFileUtil::ReadDirectoryCallback& callback, 4972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const AsyncFileUtil::EntryList& file_list, 4982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool has_more) { 499cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DCHECK_CURRENTLY_ON(content::BrowserThread::IO); 500cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (!validate_media_files()) { 501cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) OnDidCheckMediaForReadDirectory(callback, has_more, file_list); 502cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return; 5035c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu } 504a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 505cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::PostTaskAndReplyWithResult( 5065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) task_runner, 507cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) FROM_HERE, 508cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::Bind(&MediaPathFilterWrapper::FilterMediaEntries, 509cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) media_path_filter_wrapper_, 510cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) file_list), 511cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::Bind(&OnDidCheckMediaForReadDirectory, callback, has_more)); 5122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 514cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)bool DeviceMediaAsyncFileUtil::validate_media_files() const { 515cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return media_path_filter_wrapper_.get() != NULL; 5162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 517