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"
161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/file_system_operation_context.h"
171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/file_system_url.h"
181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/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() :
605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                 base::Bind(&google_apis::RunTaskWithTaskRunner,
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(),
775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      base::Bind(&google_apis::RunTaskWithTaskRunner,
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,
11103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    storage::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
11703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  scoped_refptr<storage::ShareableFileReference> file_reference =
11803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      storage::ShareableFileReference::GetOrCreate(storage::ScopedFile(
11903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)          local_path, scope_out_policy, BrowserThread::GetBlockingPool()));
1207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  callback.Run(error, file_info, local_path, file_reference);
1217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
1227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
1237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}  // namespace
1247dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
1255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)AsyncFileUtil::AsyncFileUtil() {
1267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
1277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
1287dbb3d5cf0c15f500944d211057644d6a2f37371Ben MurdochAsyncFileUtil::~AsyncFileUtil() {
1297dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
1307dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
1317dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid AsyncFileUtil::CreateOrOpen(
13203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    scoped_ptr<storage::FileSystemOperationContext> context,
13303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    const storage::FileSystemURL& url,
1347dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    int file_flags,
1357dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const CreateOrOpenCallback& callback) {
1367dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
1377dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
1387dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  base::FilePath file_path = util::ExtractDrivePathFromFileSystemUrl(url);
1397dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (file_path.empty()) {
140cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    callback.Run(base::File(base::File::FILE_ERROR_NOT_FOUND), base::Closure());
1417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    return;
1427dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
1437dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
1445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const fileapi_internal::FileSystemGetter getter =
1455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::Bind(&fileapi_internal::GetFileSystemFromUrl, url);
1467dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  PostFileSystemCallback(
1475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      getter,
1487dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      base::Bind(&fileapi_internal::OpenFile,
1497dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                 file_path, file_flags,
1507dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                 google_apis::CreateRelayCallback(
151effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                     base::Bind(&RunCreateOrOpenFileCallback, callback))),
1527dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      base::Bind(&RunCreateOrOpenFileCallbackOnError,
1535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                 callback, base::File::FILE_ERROR_FAILED));
1547dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
1557dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
1567dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid AsyncFileUtil::EnsureFileExists(
15703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    scoped_ptr<storage::FileSystemOperationContext> context,
15803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    const storage::FileSystemURL& url,
1597dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const EnsureFileExistsCallback& callback) {
1607dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
1617dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
1627dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  base::FilePath file_path = util::ExtractDrivePathFromFileSystemUrl(url);
1637dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (file_path.empty()) {
1645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    callback.Run(base::File::FILE_ERROR_NOT_FOUND, false);
1657dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    return;
1667dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
1677dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
1687dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  PostFileSystemCallback(
1695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::Bind(&fileapi_internal::GetFileSystemFromUrl, url),
1707dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      base::Bind(&fileapi_internal::CreateFile,
1717dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                 file_path, true /* is_exlusive */,
1727dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                 google_apis::CreateRelayCallback(
1737dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                     base::Bind(&RunEnsureFileExistsCallback, callback))),
1745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::Bind(callback, base::File::FILE_ERROR_FAILED, false));
1757dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
1767dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
1777dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid AsyncFileUtil::CreateDirectory(
17803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    scoped_ptr<storage::FileSystemOperationContext> context,
17903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    const storage::FileSystemURL& url,
1807dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    bool exclusive,
1817dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    bool recursive,
1827dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const StatusCallback& callback) {
1837dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
1847dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
1857dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  base::FilePath file_path = util::ExtractDrivePathFromFileSystemUrl(url);
1867dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (file_path.empty()) {
1875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    callback.Run(base::File::FILE_ERROR_NOT_FOUND);
1887dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    return;
1897dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
1907dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
1917dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  PostFileSystemCallback(
1925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::Bind(&fileapi_internal::GetFileSystemFromUrl, url),
1937dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      base::Bind(&fileapi_internal::CreateDirectory,
1947dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                 file_path, exclusive, recursive,
1957dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                 google_apis::CreateRelayCallback(callback)),
1965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::Bind(callback, base::File::FILE_ERROR_FAILED));
1977dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
1987dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
1997dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid AsyncFileUtil::GetFileInfo(
20003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    scoped_ptr<storage::FileSystemOperationContext> context,
20103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    const storage::FileSystemURL& url,
2027dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const GetFileInfoCallback& callback) {
2037dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
2047dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2057dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  base::FilePath file_path = util::ExtractDrivePathFromFileSystemUrl(url);
2067dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (file_path.empty()) {
2075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    callback.Run(base::File::FILE_ERROR_NOT_FOUND, base::File::Info());
2087dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    return;
2097dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
2107dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  PostFileSystemCallback(
2125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::Bind(&fileapi_internal::GetFileSystemFromUrl, url),
2137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      base::Bind(&fileapi_internal::GetFileInfo,
2147dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                 file_path, google_apis::CreateRelayCallback(callback)),
2155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::Bind(callback, base::File::FILE_ERROR_FAILED,
2165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                 base::File::Info()));
2177dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
2187dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2197dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid AsyncFileUtil::ReadDirectory(
22003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    scoped_ptr<storage::FileSystemOperationContext> context,
22103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    const storage::FileSystemURL& url,
2227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const ReadDirectoryCallback& callback) {
2237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
2247dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2257dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  base::FilePath file_path = util::ExtractDrivePathFromFileSystemUrl(url);
2267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (file_path.empty()) {
2275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    callback.Run(base::File::FILE_ERROR_NOT_FOUND, EntryList(), false);
2287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    return;
2297dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
2307dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2317dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  PostFileSystemCallback(
2325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::Bind(&fileapi_internal::GetFileSystemFromUrl, url),
2337dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      base::Bind(&fileapi_internal::ReadDirectory,
2347dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                 file_path, google_apis::CreateRelayCallback(callback)),
2355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::Bind(callback, base::File::FILE_ERROR_FAILED,
2367dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                 EntryList(), false));
2377dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
2387dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2397dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid AsyncFileUtil::Touch(
24003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    scoped_ptr<storage::FileSystemOperationContext> context,
24103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    const storage::FileSystemURL& url,
2427dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const base::Time& last_access_time,
2437dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const base::Time& last_modified_time,
2447dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const StatusCallback& callback) {
2457dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
2467dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2477dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  base::FilePath file_path = util::ExtractDrivePathFromFileSystemUrl(url);
2487dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (file_path.empty()) {
2495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    callback.Run(base::File::FILE_ERROR_NOT_FOUND);
2507dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    return;
2517dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
2527dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2537dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  PostFileSystemCallback(
2545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::Bind(&fileapi_internal::GetFileSystemFromUrl, url),
2557dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      base::Bind(&fileapi_internal::TouchFile,
2567dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                 file_path, last_access_time, last_modified_time,
2577dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                 google_apis::CreateRelayCallback(callback)),
2585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::Bind(callback, base::File::FILE_ERROR_FAILED));
2597dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
2607dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2617dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid AsyncFileUtil::Truncate(
26203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    scoped_ptr<storage::FileSystemOperationContext> context,
26303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    const storage::FileSystemURL& url,
2647dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    int64 length,
2657dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const StatusCallback& callback) {
2667dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
2677dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2687dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  base::FilePath file_path = util::ExtractDrivePathFromFileSystemUrl(url);
2697dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (file_path.empty()) {
2705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    callback.Run(base::File::FILE_ERROR_NOT_FOUND);
2717dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    return;
2727dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
2737dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2747dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  PostFileSystemCallback(
2755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::Bind(&fileapi_internal::GetFileSystemFromUrl, url),
2767dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      base::Bind(&fileapi_internal::Truncate,
2777dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                 file_path, length, google_apis::CreateRelayCallback(callback)),
2785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::Bind(callback, base::File::FILE_ERROR_FAILED));
2797dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
2807dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2817dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid AsyncFileUtil::CopyFileLocal(
28203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    scoped_ptr<storage::FileSystemOperationContext> context,
28303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    const storage::FileSystemURL& src_url,
28403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    const storage::FileSystemURL& dest_url,
28568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    CopyOrMoveOption option,
28658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    const CopyFileProgressCallback& progress_callback,
2877dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const StatusCallback& callback) {
2887dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
2897dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2907dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  base::FilePath src_path = util::ExtractDrivePathFromFileSystemUrl(src_url);
2917dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  base::FilePath dest_path = util::ExtractDrivePathFromFileSystemUrl(dest_url);
2927dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (src_path.empty() || dest_path.empty()) {
2935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    callback.Run(base::File::FILE_ERROR_NOT_FOUND);
2947dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    return;
2957dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
2967dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // TODO(kinaba): crbug.com/339794.
2985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Assumption here is that |src_url| and |dest_url| are always from the same
2995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // profile. This indeed holds as long as we mount different profiles onto
3005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // different mount point. Hence, using GetFileSystemFromUrl(dest_url) is safe.
3015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // This will change after we introduce cross-profile sharing etc., and we
3025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // need to deal with files from different profiles here.
3037dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  PostFileSystemCallback(
3045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::Bind(&fileapi_internal::GetFileSystemFromUrl, dest_url),
3054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      base::Bind(
3064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)          &fileapi_internal::Copy,
30703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)          src_path,
30803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)          dest_path,
30903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)          option == storage::FileSystemOperation::OPTION_PRESERVE_LAST_MODIFIED,
3104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)          google_apis::CreateRelayCallback(callback)),
3115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::Bind(callback, base::File::FILE_ERROR_FAILED));
3127dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
3137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
3147dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid AsyncFileUtil::MoveFileLocal(
31503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    scoped_ptr<storage::FileSystemOperationContext> context,
31603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    const storage::FileSystemURL& src_url,
31703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    const storage::FileSystemURL& dest_url,
31868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    CopyOrMoveOption option,
3197dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const StatusCallback& callback) {
3207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
3217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
3227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  base::FilePath src_path = util::ExtractDrivePathFromFileSystemUrl(src_url);
3237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  base::FilePath dest_path = util::ExtractDrivePathFromFileSystemUrl(dest_url);
3247dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (src_path.empty() || dest_path.empty()) {
3255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    callback.Run(base::File::FILE_ERROR_NOT_FOUND);
3267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    return;
3277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
3287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
3295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // TODO(kinaba): see the comment in CopyFileLocal(). |src_url| and |dest_url|
3305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // always return the same FileSystem by GetFileSystemFromUrl, but we need to
3315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // change it in order to support cross-profile file sharing etc.
3327dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  PostFileSystemCallback(
3335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::Bind(&fileapi_internal::GetFileSystemFromUrl, dest_url),
334a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::Bind(&fileapi_internal::Move,
335a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                 src_path, dest_path,
336a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                 google_apis::CreateRelayCallback(callback)),
3375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::Bind(callback, base::File::FILE_ERROR_FAILED));
3387dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
3397dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
3407dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid AsyncFileUtil::CopyInForeignFile(
34103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    scoped_ptr<storage::FileSystemOperationContext> context,
3427dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const base::FilePath& src_file_path,
34303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    const storage::FileSystemURL& dest_url,
3447dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const StatusCallback& callback) {
3457dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
3467dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
3477dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  base::FilePath dest_path = util::ExtractDrivePathFromFileSystemUrl(dest_url);
3487dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (dest_path.empty()) {
3495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    callback.Run(base::File::FILE_ERROR_NOT_FOUND);
3507dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    return;
3517dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
3527dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
3537dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  PostFileSystemCallback(
3545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::Bind(&fileapi_internal::GetFileSystemFromUrl, dest_url),
3557dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      base::Bind(&fileapi_internal::CopyInForeignFile,
3567dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                 src_file_path, dest_path,
3577dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                 google_apis::CreateRelayCallback(callback)),
3585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::Bind(callback, base::File::FILE_ERROR_FAILED));
3597dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
3607dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
3617dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid AsyncFileUtil::DeleteFile(
36203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    scoped_ptr<storage::FileSystemOperationContext> context,
36303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    const storage::FileSystemURL& url,
3647dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const StatusCallback& callback) {
3657dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
3667dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
3677dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  base::FilePath file_path = util::ExtractDrivePathFromFileSystemUrl(url);
3687dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (file_path.empty()) {
3695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    callback.Run(base::File::FILE_ERROR_NOT_FOUND);
3707dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    return;
3717dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
3727dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
3737dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  PostFileSystemCallback(
3745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::Bind(&fileapi_internal::GetFileSystemFromUrl, url),
3757dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      base::Bind(&fileapi_internal::Remove,
3767dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                 file_path, false /* not recursive */,
3777dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                 google_apis::CreateRelayCallback(callback)),
3785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::Bind(callback, base::File::FILE_ERROR_FAILED));
3797dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
3807dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
3817dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid AsyncFileUtil::DeleteDirectory(
38203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    scoped_ptr<storage::FileSystemOperationContext> context,
38303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    const storage::FileSystemURL& url,
3847dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const StatusCallback& callback) {
3857dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
3867dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
3877dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  base::FilePath file_path = util::ExtractDrivePathFromFileSystemUrl(url);
3887dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (file_path.empty()) {
3895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    callback.Run(base::File::FILE_ERROR_NOT_FOUND);
3907dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    return;
3917dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
3927dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
3937dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  PostFileSystemCallback(
3945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::Bind(&fileapi_internal::GetFileSystemFromUrl, url),
3957dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      base::Bind(&fileapi_internal::Remove,
3967dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                 file_path, false /* not recursive */,
3977dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                 google_apis::CreateRelayCallback(callback)),
3985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::Bind(callback, base::File::FILE_ERROR_FAILED));
3997dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
4007dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
4017dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid AsyncFileUtil::DeleteRecursively(
40203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    scoped_ptr<storage::FileSystemOperationContext> context,
40303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    const storage::FileSystemURL& url,
4047dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const StatusCallback& callback) {
4057dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
4067dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
4077dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  base::FilePath file_path = util::ExtractDrivePathFromFileSystemUrl(url);
4087dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (file_path.empty()) {
4095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    callback.Run(base::File::FILE_ERROR_NOT_FOUND);
4107dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    return;
4117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
4127dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
4137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  PostFileSystemCallback(
4145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::Bind(&fileapi_internal::GetFileSystemFromUrl, url),
4157dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      base::Bind(&fileapi_internal::Remove,
4167dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                 file_path, true /* recursive */,
4177dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                 google_apis::CreateRelayCallback(callback)),
4185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::Bind(callback, base::File::FILE_ERROR_FAILED));
4197dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
4207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
4217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid AsyncFileUtil::CreateSnapshotFile(
42203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    scoped_ptr<storage::FileSystemOperationContext> context,
42303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    const storage::FileSystemURL& url,
4247dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const CreateSnapshotFileCallback& callback) {
4257dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
4267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
4277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  base::FilePath file_path = util::ExtractDrivePathFromFileSystemUrl(url);
4287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (file_path.empty()) {
4295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    callback.Run(base::File::FILE_ERROR_NOT_FOUND,
4305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                 base::File::Info(),
4317dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                 base::FilePath(),
43203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                 scoped_refptr<storage::ShareableFileReference>());
4337dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    return;
4347dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
4357dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
4367dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  PostFileSystemCallback(
4375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::Bind(&fileapi_internal::GetFileSystemFromUrl, url),
4387dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      base::Bind(&fileapi_internal::CreateSnapshotFile,
4397dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                 file_path,
4407dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                 google_apis::CreateRelayCallback(
4417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                     base::Bind(&RunCreateSnapshotFileCallback, callback))),
4427dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      base::Bind(callback,
4435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                 base::File::FILE_ERROR_FAILED,
4445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                 base::File::Info(),
4457dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                 base::FilePath(),
44603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                 scoped_refptr<storage::ShareableFileReference>()));
4477dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
4487dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
4497dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}  // namespace internal
4507dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}  // namespace drive
451