15d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
27dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// Use of this source code is governed by a BSD-style license that can be
37dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// found in the LICENSE file.
47dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
55d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/chromeos/drive/fileapi/async_file_util.h"
67dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
77dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "base/callback.h"
87dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "base/files/file_path.h"
97dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "base/logging.h"
107dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "base/threading/sequenced_worker_pool.h"
115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/chromeos/drive/drive_integration_service.h"
127dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/browser/chromeos/drive/file_system_util.h"
135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/chromeos/drive/fileapi/fileapi_worker.h"
147dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "content/public/browser/browser_thread.h"
15a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "google_apis/drive/task_util.h"
167dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "webkit/browser/fileapi/file_system_operation_context.h"
177dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "webkit/browser/fileapi/file_system_url.h"
187dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "webkit/common/blob/shareable_file_reference.h"
197dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochusing content::BrowserThread;
217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
22cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)namespace google_apis {
23cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)namespace internal {
24cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
25cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Partial specialization of helper template from google_apis/drive/task_util.h
26cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// to enable google_apis::CreateRelayCallback to work with CreateOrOpenCallback.
27cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)template<typename T2>
28cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)struct ComposedCallback<void(base::File, T2)> {
29cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  static void Run(
30cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      const base::Callback<void(const base::Closure&)>& runner,
31cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      const base::Callback<void(base::File, T2)>& callback,
32cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      base::File arg1, T2 arg2) {
33cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    runner.Run(base::Bind(callback, Passed(&arg1), arg2));
34cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
35cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)};
36cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
37cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}  // namespace internal
38cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}  // namespace google_apis
39cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
407dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochnamespace drive {
417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochnamespace internal {
427dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochnamespace {
437dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
447dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// Posts fileapi_internal::RunFileSystemCallback to UI thread.
457dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// This function must be called on IO thread.
467dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// The |on_error_callback| will be called (on error case) on IO thread.
477dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid PostFileSystemCallback(
487dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const fileapi_internal::FileSystemGetter& file_system_getter,
497dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const base::Callback<void(FileSystemInterface*)>& function,
507dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const base::Closure& on_error_callback) {
517dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
527dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
537dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  BrowserThread::PostTask(
547dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      BrowserThread::UI,
557dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      FROM_HERE,
567dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      base::Bind(&fileapi_internal::RunFileSystemCallback,
577dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                 file_system_getter, function,
587dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                 on_error_callback.is_null() ?
597dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                 base::Closure() :
607dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                 base::Bind(&google_apis::RunTaskOnThread,
617dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                            base::MessageLoopProxy::current(),
627dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                            on_error_callback)));
637dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
647dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
657dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// Runs CreateOrOpenFile callback based on the given |error| and |file|.
667dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid RunCreateOrOpenFileCallback(
677dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const AsyncFileUtil::CreateOrOpenCallback& callback,
68cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    base::File file,
69a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    const base::Closure& close_callback_on_ui_thread) {
707dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
717dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
727dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // It is necessary to make a closure, which runs on file closing here.
737dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // It will be provided as a FileSystem::OpenFileCallback's argument later.
747dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // (crbug.com/259184).
757dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  callback.Run(
76cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      file.Pass(),
77a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      base::Bind(&google_apis::RunTaskOnThread,
78a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI),
79a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                 close_callback_on_ui_thread));
807dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
817dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
827dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// Runs CreateOrOpenFile when the error happens.
837dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid RunCreateOrOpenFileCallbackOnError(
847dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const AsyncFileUtil::CreateOrOpenCallback& callback,
855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::File::Error error) {
86cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  callback.Run(base::File(error), base::Closure());
877dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
887dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
897dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// Runs EnsureFileExistsCallback based on the given |error|.
907dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid RunEnsureFileExistsCallback(
917dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const AsyncFileUtil::EnsureFileExistsCallback& callback,
925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::File::Error error) {
937dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
947dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
957dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // Remember if the file is actually created or not.
965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  bool created = (error == base::File::FILE_OK);
977dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // File::FILE_ERROR_EXISTS is not an actual error here.
995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (error == base::File::FILE_ERROR_EXISTS)
1005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    error = base::File::FILE_OK;
1017dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
1027dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  callback.Run(error, created);
1037dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
1047dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
1057dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// Runs |callback| with the arguments based on the given arguments.
1067dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid RunCreateSnapshotFileCallback(
1077dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const AsyncFileUtil::CreateSnapshotFileCallback& callback,
1085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::File::Error error,
1095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const base::File::Info& file_info,
1107dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const base::FilePath& local_path,
1117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    webkit_blob::ScopedFile::ScopeOutPolicy scope_out_policy) {
1127dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // ShareableFileReference is thread *unsafe* class. So it is necessary to
1137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // create the instance (by invoking GetOrCreate) on IO thread, though
1147dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // most drive file system related operations run on UI thread.
1157dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
1167dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
1177dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  scoped_refptr<webkit_blob::ShareableFileReference> file_reference =
1187dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      webkit_blob::ShareableFileReference::GetOrCreate(webkit_blob::ScopedFile(
1197dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          local_path,
1207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          scope_out_policy,
1217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          BrowserThread::GetBlockingPool()));
1227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  callback.Run(error, file_info, local_path, file_reference);
1237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
1247dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
1257dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}  // namespace
1267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
1275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)AsyncFileUtil::AsyncFileUtil() {
1287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
1297dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
1307dbb3d5cf0c15f500944d211057644d6a2f37371Ben MurdochAsyncFileUtil::~AsyncFileUtil() {
1317dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
1327dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
1337dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid AsyncFileUtil::CreateOrOpen(
1347dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    scoped_ptr<fileapi::FileSystemOperationContext> context,
1357dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const fileapi::FileSystemURL& url,
1367dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    int file_flags,
1377dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const CreateOrOpenCallback& callback) {
1387dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
1397dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
1407dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  base::FilePath file_path = util::ExtractDrivePathFromFileSystemUrl(url);
1417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (file_path.empty()) {
142cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    callback.Run(base::File(base::File::FILE_ERROR_NOT_FOUND), base::Closure());
1437dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    return;
1447dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
1457dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
1465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const fileapi_internal::FileSystemGetter getter =
1475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::Bind(&fileapi_internal::GetFileSystemFromUrl, url);
1487dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  PostFileSystemCallback(
1495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      getter,
1507dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      base::Bind(&fileapi_internal::OpenFile,
1517dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                 file_path, file_flags,
1527dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                 google_apis::CreateRelayCallback(
153effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                     base::Bind(&RunCreateOrOpenFileCallback, callback))),
1547dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      base::Bind(&RunCreateOrOpenFileCallbackOnError,
1555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                 callback, base::File::FILE_ERROR_FAILED));
1567dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
1577dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
1587dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid AsyncFileUtil::EnsureFileExists(
1597dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    scoped_ptr<fileapi::FileSystemOperationContext> context,
1607dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const fileapi::FileSystemURL& url,
1617dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const EnsureFileExistsCallback& callback) {
1627dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
1637dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
1647dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  base::FilePath file_path = util::ExtractDrivePathFromFileSystemUrl(url);
1657dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (file_path.empty()) {
1665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    callback.Run(base::File::FILE_ERROR_NOT_FOUND, false);
1677dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    return;
1687dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
1697dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
1707dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  PostFileSystemCallback(
1715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::Bind(&fileapi_internal::GetFileSystemFromUrl, url),
1727dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      base::Bind(&fileapi_internal::CreateFile,
1737dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                 file_path, true /* is_exlusive */,
1747dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                 google_apis::CreateRelayCallback(
1757dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                     base::Bind(&RunEnsureFileExistsCallback, callback))),
1765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::Bind(callback, base::File::FILE_ERROR_FAILED, false));
1777dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
1787dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
1797dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid AsyncFileUtil::CreateDirectory(
1807dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    scoped_ptr<fileapi::FileSystemOperationContext> context,
1817dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const fileapi::FileSystemURL& url,
1827dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    bool exclusive,
1837dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    bool recursive,
1847dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const StatusCallback& callback) {
1857dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
1867dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
1877dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  base::FilePath file_path = util::ExtractDrivePathFromFileSystemUrl(url);
1887dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (file_path.empty()) {
1895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    callback.Run(base::File::FILE_ERROR_NOT_FOUND);
1907dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    return;
1917dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
1927dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
1937dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  PostFileSystemCallback(
1945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::Bind(&fileapi_internal::GetFileSystemFromUrl, url),
1957dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      base::Bind(&fileapi_internal::CreateDirectory,
1967dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                 file_path, exclusive, recursive,
1977dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                 google_apis::CreateRelayCallback(callback)),
1985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::Bind(callback, base::File::FILE_ERROR_FAILED));
1997dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
2007dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2017dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid AsyncFileUtil::GetFileInfo(
2027dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    scoped_ptr<fileapi::FileSystemOperationContext> context,
2037dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const fileapi::FileSystemURL& url,
2047dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const GetFileInfoCallback& callback) {
2057dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
2067dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2077dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  base::FilePath file_path = util::ExtractDrivePathFromFileSystemUrl(url);
2087dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (file_path.empty()) {
2095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    callback.Run(base::File::FILE_ERROR_NOT_FOUND, base::File::Info());
2107dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    return;
2117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
2127dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  PostFileSystemCallback(
2145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::Bind(&fileapi_internal::GetFileSystemFromUrl, url),
2157dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      base::Bind(&fileapi_internal::GetFileInfo,
2167dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                 file_path, google_apis::CreateRelayCallback(callback)),
2175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::Bind(callback, base::File::FILE_ERROR_FAILED,
2185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                 base::File::Info()));
2197dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
2207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid AsyncFileUtil::ReadDirectory(
2227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    scoped_ptr<fileapi::FileSystemOperationContext> context,
2237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const fileapi::FileSystemURL& url,
2247dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const ReadDirectoryCallback& callback) {
2257dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
2267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  base::FilePath file_path = util::ExtractDrivePathFromFileSystemUrl(url);
2287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (file_path.empty()) {
2295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    callback.Run(base::File::FILE_ERROR_NOT_FOUND, EntryList(), false);
2307dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    return;
2317dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
2327dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2337dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  PostFileSystemCallback(
2345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::Bind(&fileapi_internal::GetFileSystemFromUrl, url),
2357dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      base::Bind(&fileapi_internal::ReadDirectory,
2367dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                 file_path, google_apis::CreateRelayCallback(callback)),
2375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::Bind(callback, base::File::FILE_ERROR_FAILED,
2387dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                 EntryList(), false));
2397dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
2407dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid AsyncFileUtil::Touch(
2427dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    scoped_ptr<fileapi::FileSystemOperationContext> context,
2437dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const fileapi::FileSystemURL& url,
2447dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const base::Time& last_access_time,
2457dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const base::Time& last_modified_time,
2467dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const StatusCallback& callback) {
2477dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
2487dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2497dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  base::FilePath file_path = util::ExtractDrivePathFromFileSystemUrl(url);
2507dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (file_path.empty()) {
2515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    callback.Run(base::File::FILE_ERROR_NOT_FOUND);
2527dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    return;
2537dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
2547dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2557dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  PostFileSystemCallback(
2565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::Bind(&fileapi_internal::GetFileSystemFromUrl, url),
2577dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      base::Bind(&fileapi_internal::TouchFile,
2587dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                 file_path, last_access_time, last_modified_time,
2597dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                 google_apis::CreateRelayCallback(callback)),
2605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::Bind(callback, base::File::FILE_ERROR_FAILED));
2617dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
2627dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2637dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid AsyncFileUtil::Truncate(
2647dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    scoped_ptr<fileapi::FileSystemOperationContext> context,
2657dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const fileapi::FileSystemURL& url,
2667dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    int64 length,
2677dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const StatusCallback& callback) {
2687dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
2697dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2707dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  base::FilePath file_path = util::ExtractDrivePathFromFileSystemUrl(url);
2717dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (file_path.empty()) {
2725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    callback.Run(base::File::FILE_ERROR_NOT_FOUND);
2737dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    return;
2747dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
2757dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2767dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  PostFileSystemCallback(
2775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::Bind(&fileapi_internal::GetFileSystemFromUrl, url),
2787dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      base::Bind(&fileapi_internal::Truncate,
2797dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                 file_path, length, google_apis::CreateRelayCallback(callback)),
2805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::Bind(callback, base::File::FILE_ERROR_FAILED));
2817dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
2827dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2837dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid AsyncFileUtil::CopyFileLocal(
2847dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    scoped_ptr<fileapi::FileSystemOperationContext> context,
2857dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const fileapi::FileSystemURL& src_url,
2867dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const fileapi::FileSystemURL& dest_url,
28768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    CopyOrMoveOption option,
28858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    const CopyFileProgressCallback& progress_callback,
2897dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const StatusCallback& callback) {
2907dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
2917dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2927dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  base::FilePath src_path = util::ExtractDrivePathFromFileSystemUrl(src_url);
2937dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  base::FilePath dest_path = util::ExtractDrivePathFromFileSystemUrl(dest_url);
2947dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (src_path.empty() || dest_path.empty()) {
2955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    callback.Run(base::File::FILE_ERROR_NOT_FOUND);
2967dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    return;
2977dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
2987dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // TODO(kinaba): crbug.com/339794.
3005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Assumption here is that |src_url| and |dest_url| are always from the same
3015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // profile. This indeed holds as long as we mount different profiles onto
3025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // different mount point. Hence, using GetFileSystemFromUrl(dest_url) is safe.
3035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // This will change after we introduce cross-profile sharing etc., and we
3045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // need to deal with files from different profiles here.
3057dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  PostFileSystemCallback(
3065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::Bind(&fileapi_internal::GetFileSystemFromUrl, dest_url),
3074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      base::Bind(
3084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)          &fileapi_internal::Copy,
3094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)          src_path, dest_path,
3104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)          option == fileapi::FileSystemOperation::OPTION_PRESERVE_LAST_MODIFIED,
3114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)          google_apis::CreateRelayCallback(callback)),
3125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::Bind(callback, base::File::FILE_ERROR_FAILED));
3137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
3147dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
3157dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid AsyncFileUtil::MoveFileLocal(
3167dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    scoped_ptr<fileapi::FileSystemOperationContext> context,
3177dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const fileapi::FileSystemURL& src_url,
3187dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const fileapi::FileSystemURL& dest_url,
31968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    CopyOrMoveOption option,
3207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const StatusCallback& callback) {
3217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
3227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
3237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  base::FilePath src_path = util::ExtractDrivePathFromFileSystemUrl(src_url);
3247dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  base::FilePath dest_path = util::ExtractDrivePathFromFileSystemUrl(dest_url);
3257dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (src_path.empty() || dest_path.empty()) {
3265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    callback.Run(base::File::FILE_ERROR_NOT_FOUND);
3277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    return;
3287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
3297dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
3305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // TODO(kinaba): see the comment in CopyFileLocal(). |src_url| and |dest_url|
3315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // always return the same FileSystem by GetFileSystemFromUrl, but we need to
3325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // change it in order to support cross-profile file sharing etc.
3337dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  PostFileSystemCallback(
3345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::Bind(&fileapi_internal::GetFileSystemFromUrl, dest_url),
335a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::Bind(&fileapi_internal::Move,
336a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                 src_path, dest_path,
337a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                 google_apis::CreateRelayCallback(callback)),
3385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::Bind(callback, base::File::FILE_ERROR_FAILED));
3397dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
3407dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
3417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid AsyncFileUtil::CopyInForeignFile(
3427dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    scoped_ptr<fileapi::FileSystemOperationContext> context,
3437dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const base::FilePath& src_file_path,
3447dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const fileapi::FileSystemURL& dest_url,
3457dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const StatusCallback& callback) {
3467dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
3477dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
3487dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  base::FilePath dest_path = util::ExtractDrivePathFromFileSystemUrl(dest_url);
3497dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (dest_path.empty()) {
3505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    callback.Run(base::File::FILE_ERROR_NOT_FOUND);
3517dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    return;
3527dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
3537dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
3547dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  PostFileSystemCallback(
3555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::Bind(&fileapi_internal::GetFileSystemFromUrl, dest_url),
3567dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      base::Bind(&fileapi_internal::CopyInForeignFile,
3577dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                 src_file_path, dest_path,
3587dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                 google_apis::CreateRelayCallback(callback)),
3595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::Bind(callback, base::File::FILE_ERROR_FAILED));
3607dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
3617dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
3627dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid AsyncFileUtil::DeleteFile(
3637dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    scoped_ptr<fileapi::FileSystemOperationContext> context,
3647dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const fileapi::FileSystemURL& url,
3657dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const StatusCallback& callback) {
3667dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
3677dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
3687dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  base::FilePath file_path = util::ExtractDrivePathFromFileSystemUrl(url);
3697dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (file_path.empty()) {
3705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    callback.Run(base::File::FILE_ERROR_NOT_FOUND);
3717dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    return;
3727dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
3737dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
3747dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  PostFileSystemCallback(
3755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::Bind(&fileapi_internal::GetFileSystemFromUrl, url),
3767dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      base::Bind(&fileapi_internal::Remove,
3777dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                 file_path, false /* not recursive */,
3787dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                 google_apis::CreateRelayCallback(callback)),
3795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::Bind(callback, base::File::FILE_ERROR_FAILED));
3807dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
3817dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
3827dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid AsyncFileUtil::DeleteDirectory(
3837dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    scoped_ptr<fileapi::FileSystemOperationContext> context,
3847dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const fileapi::FileSystemURL& url,
3857dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const StatusCallback& callback) {
3867dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
3877dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
3887dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  base::FilePath file_path = util::ExtractDrivePathFromFileSystemUrl(url);
3897dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (file_path.empty()) {
3905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    callback.Run(base::File::FILE_ERROR_NOT_FOUND);
3917dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    return;
3927dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
3937dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
3947dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  PostFileSystemCallback(
3955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::Bind(&fileapi_internal::GetFileSystemFromUrl, url),
3967dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      base::Bind(&fileapi_internal::Remove,
3977dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                 file_path, false /* not recursive */,
3987dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                 google_apis::CreateRelayCallback(callback)),
3995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::Bind(callback, base::File::FILE_ERROR_FAILED));
4007dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
4017dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
4027dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid AsyncFileUtil::DeleteRecursively(
4037dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    scoped_ptr<fileapi::FileSystemOperationContext> context,
4047dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const fileapi::FileSystemURL& url,
4057dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const StatusCallback& callback) {
4067dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
4077dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
4087dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  base::FilePath file_path = util::ExtractDrivePathFromFileSystemUrl(url);
4097dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (file_path.empty()) {
4105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    callback.Run(base::File::FILE_ERROR_NOT_FOUND);
4117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    return;
4127dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
4137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
4147dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  PostFileSystemCallback(
4155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::Bind(&fileapi_internal::GetFileSystemFromUrl, url),
4167dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      base::Bind(&fileapi_internal::Remove,
4177dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                 file_path, true /* recursive */,
4187dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                 google_apis::CreateRelayCallback(callback)),
4195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::Bind(callback, base::File::FILE_ERROR_FAILED));
4207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
4217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
4227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid AsyncFileUtil::CreateSnapshotFile(
4237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    scoped_ptr<fileapi::FileSystemOperationContext> context,
4247dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const fileapi::FileSystemURL& url,
4257dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const CreateSnapshotFileCallback& callback) {
4267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
4277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
4287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  base::FilePath file_path = util::ExtractDrivePathFromFileSystemUrl(url);
4297dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (file_path.empty()) {
4305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    callback.Run(base::File::FILE_ERROR_NOT_FOUND,
4315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                 base::File::Info(),
4327dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                 base::FilePath(),
4337dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                 scoped_refptr<webkit_blob::ShareableFileReference>());
4347dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    return;
4357dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
4367dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
4377dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  PostFileSystemCallback(
4385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::Bind(&fileapi_internal::GetFileSystemFromUrl, url),
4397dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      base::Bind(&fileapi_internal::CreateSnapshotFile,
4407dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                 file_path,
4417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                 google_apis::CreateRelayCallback(
4427dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                     base::Bind(&RunCreateSnapshotFileCallback, callback))),
4437dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      base::Bind(callback,
4445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                 base::File::FILE_ERROR_FAILED,
4455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                 base::File::Info(),
4467dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                 base::FilePath(),
4477dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                 scoped_refptr<webkit_blob::ShareableFileReference>()));
4487dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
4497dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
4507dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}  // namespace internal
4517dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}  // namespace drive
452