1868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
2868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// found in the LICENSE file.
4868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
51320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/file_system_operation_runner.h"
6868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
7868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/bind.h"
858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "base/message_loop/message_loop_proxy.h"
958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "base/stl_util.h"
107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "net/url_request/url_request_context.h"
111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/blob/blob_url_request_job_factory.h"
121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/file_observers.h"
131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/file_stream_writer.h"
141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/file_system_context.h"
151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/file_system_operation.h"
161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/file_writer_delegate.h"
171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/common/blob/shareable_file_reference.h"
18868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)namespace storage {
20868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
21868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)typedef FileSystemOperationRunner::OperationID OperationID;
22868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
2358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)class FileSystemOperationRunner::BeginOperationScoper
2458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    : public base::SupportsWeakPtr<
2558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          FileSystemOperationRunner::BeginOperationScoper> {
2658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) public:
2758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  BeginOperationScoper() {}
2858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) private:
2958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(BeginOperationScoper);
3058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)};
3158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
3258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)FileSystemOperationRunner::OperationHandle::OperationHandle() {}
3358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)FileSystemOperationRunner::OperationHandle::~OperationHandle() {}
34868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
35868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)FileSystemOperationRunner::~FileSystemOperationRunner() {
36868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
37868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
38868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void FileSystemOperationRunner::Shutdown() {
39868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  operations_.Clear();
40868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
41868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
42868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)OperationID FileSystemOperationRunner::CreateFile(
43868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    const FileSystemURL& url,
44868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    bool exclusive,
45868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    const StatusCallback& callback) {
465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::File::Error error = base::File::FILE_OK;
47868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  FileSystemOperation* operation =
48868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      file_system_context_->CreateFileSystemOperation(url, &error);
4958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
5058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  BeginOperationScoper scope;
5158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  OperationHandle handle = BeginOperation(operation, scope.AsWeakPtr());
52868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!operation) {
5358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    DidFinish(handle, callback, error);
5458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return handle.id;
55868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
5658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  PrepareForWrite(handle.id, url);
57868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  operation->CreateFile(
58868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      url, exclusive,
59868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      base::Bind(&FileSystemOperationRunner::DidFinish, AsWeakPtr(),
6058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                 handle, callback));
6158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return handle.id;
62868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
63868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
64868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)OperationID FileSystemOperationRunner::CreateDirectory(
65868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    const FileSystemURL& url,
66868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    bool exclusive,
67868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    bool recursive,
68868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    const StatusCallback& callback) {
695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::File::Error error = base::File::FILE_OK;
70868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  FileSystemOperation* operation =
71868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      file_system_context_->CreateFileSystemOperation(url, &error);
7258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  BeginOperationScoper scope;
7358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  OperationHandle handle = BeginOperation(operation, scope.AsWeakPtr());
74868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!operation) {
7558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    DidFinish(handle, callback, error);
7658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return handle.id;
77868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
7858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  PrepareForWrite(handle.id, url);
79868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  operation->CreateDirectory(
80868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      url, exclusive, recursive,
81868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      base::Bind(&FileSystemOperationRunner::DidFinish, AsWeakPtr(),
8258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                 handle, callback));
8358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return handle.id;
84868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
85868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
86868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)OperationID FileSystemOperationRunner::Copy(
87868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    const FileSystemURL& src_url,
88868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    const FileSystemURL& dest_url,
8968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    CopyOrMoveOption option,
9058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    const CopyProgressCallback& progress_callback,
91868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    const StatusCallback& callback) {
925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::File::Error error = base::File::FILE_OK;
93868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  FileSystemOperation* operation =
94868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      file_system_context_->CreateFileSystemOperation(dest_url, &error);
9558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  BeginOperationScoper scope;
9658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  OperationHandle handle = BeginOperation(operation, scope.AsWeakPtr());
97868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!operation) {
9858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    DidFinish(handle, callback, error);
9958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return handle.id;
100868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
10158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  PrepareForWrite(handle.id, dest_url);
10258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  PrepareForRead(handle.id, src_url);
103868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  operation->Copy(
10468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      src_url, dest_url, option,
105d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      progress_callback.is_null() ?
106d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)          CopyProgressCallback() :
107d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)          base::Bind(&FileSystemOperationRunner::OnCopyProgress, AsWeakPtr(),
108d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                     handle, progress_callback),
109868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      base::Bind(&FileSystemOperationRunner::DidFinish, AsWeakPtr(),
11058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                 handle, callback));
11158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return handle.id;
112868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
113868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
114868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)OperationID FileSystemOperationRunner::Move(
115868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    const FileSystemURL& src_url,
116868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    const FileSystemURL& dest_url,
11768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    CopyOrMoveOption option,
118868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    const StatusCallback& callback) {
1195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::File::Error error = base::File::FILE_OK;
120868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  FileSystemOperation* operation =
121868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      file_system_context_->CreateFileSystemOperation(dest_url, &error);
12258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  BeginOperationScoper scope;
12358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  OperationHandle handle = BeginOperation(operation, scope.AsWeakPtr());
124868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!operation) {
12558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    DidFinish(handle, callback, error);
12658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return handle.id;
127868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
12858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  PrepareForWrite(handle.id, dest_url);
12958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  PrepareForWrite(handle.id, src_url);
130868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  operation->Move(
13168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      src_url, dest_url, option,
132868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      base::Bind(&FileSystemOperationRunner::DidFinish, AsWeakPtr(),
13358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                 handle, callback));
13458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return handle.id;
135868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
136868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
137868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)OperationID FileSystemOperationRunner::DirectoryExists(
138868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    const FileSystemURL& url,
139868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    const StatusCallback& callback) {
1405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::File::Error error = base::File::FILE_OK;
141868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  FileSystemOperation* operation =
142868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      file_system_context_->CreateFileSystemOperation(url, &error);
14358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  BeginOperationScoper scope;
14458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  OperationHandle handle = BeginOperation(operation, scope.AsWeakPtr());
145868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!operation) {
14658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    DidFinish(handle, callback, error);
14758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return handle.id;
148868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
14958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  PrepareForRead(handle.id, url);
150868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  operation->DirectoryExists(
151868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      url,
152868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      base::Bind(&FileSystemOperationRunner::DidFinish, AsWeakPtr(),
15358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                 handle, callback));
15458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return handle.id;
155868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
156868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
157868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)OperationID FileSystemOperationRunner::FileExists(
158868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    const FileSystemURL& url,
159868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    const StatusCallback& callback) {
1605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::File::Error error = base::File::FILE_OK;
161868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  FileSystemOperation* operation =
162868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      file_system_context_->CreateFileSystemOperation(url, &error);
16358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  BeginOperationScoper scope;
16458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  OperationHandle handle = BeginOperation(operation, scope.AsWeakPtr());
165868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!operation) {
16658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    DidFinish(handle, callback, error);
16758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return handle.id;
168868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
16958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  PrepareForRead(handle.id, url);
170868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  operation->FileExists(
171868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      url,
172868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      base::Bind(&FileSystemOperationRunner::DidFinish, AsWeakPtr(),
17358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                 handle, callback));
17458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return handle.id;
175868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
176868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
177868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)OperationID FileSystemOperationRunner::GetMetadata(
178868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    const FileSystemURL& url,
179868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    const GetMetadataCallback& callback) {
1805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::File::Error error = base::File::FILE_OK;
181868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  FileSystemOperation* operation =
182868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      file_system_context_->CreateFileSystemOperation(url, &error);
18358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  BeginOperationScoper scope;
18458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  OperationHandle handle = BeginOperation(operation, scope.AsWeakPtr());
185868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!operation) {
1865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    DidGetMetadata(handle, callback, error, base::File::Info());
18758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return handle.id;
188868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
18958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  PrepareForRead(handle.id, url);
190868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  operation->GetMetadata(
191868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      url,
192868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      base::Bind(&FileSystemOperationRunner::DidGetMetadata, AsWeakPtr(),
19358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                 handle, callback));
19458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return handle.id;
195868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
196868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
197868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)OperationID FileSystemOperationRunner::ReadDirectory(
198868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    const FileSystemURL& url,
199868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    const ReadDirectoryCallback& callback) {
2005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::File::Error error = base::File::FILE_OK;
201868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  FileSystemOperation* operation =
202868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      file_system_context_->CreateFileSystemOperation(url, &error);
20358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  BeginOperationScoper scope;
20458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  OperationHandle handle = BeginOperation(operation, scope.AsWeakPtr());
205868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!operation) {
20658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    DidReadDirectory(handle, callback, error, std::vector<DirectoryEntry>(),
20758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                     false);
20858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return handle.id;
209868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
21058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  PrepareForRead(handle.id, url);
211868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  operation->ReadDirectory(
212868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      url,
213868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      base::Bind(&FileSystemOperationRunner::DidReadDirectory, AsWeakPtr(),
21458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                 handle, callback));
21558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return handle.id;
216868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
217868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
218868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)OperationID FileSystemOperationRunner::Remove(
219868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    const FileSystemURL& url, bool recursive,
220868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    const StatusCallback& callback) {
2215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::File::Error error = base::File::FILE_OK;
222868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  FileSystemOperation* operation =
223868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      file_system_context_->CreateFileSystemOperation(url, &error);
22458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  BeginOperationScoper scope;
22558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  OperationHandle handle = BeginOperation(operation, scope.AsWeakPtr());
226868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!operation) {
22758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    DidFinish(handle, callback, error);
22858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return handle.id;
229868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
23058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  PrepareForWrite(handle.id, url);
231868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  operation->Remove(
232868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      url, recursive,
233868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      base::Bind(&FileSystemOperationRunner::DidFinish, AsWeakPtr(),
23458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                 handle, callback));
23558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return handle.id;
236868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
237868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
238868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)OperationID FileSystemOperationRunner::Write(
239868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    const net::URLRequestContext* url_request_context,
240868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    const FileSystemURL& url,
24103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    scoped_ptr<storage::BlobDataHandle> blob,
242868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    int64 offset,
243868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    const WriteCallback& callback) {
2445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::File::Error error = base::File::FILE_OK;
245868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  FileSystemOperation* operation =
246868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      file_system_context_->CreateFileSystemOperation(url, &error);
24758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
24858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  BeginOperationScoper scope;
24958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  OperationHandle handle = BeginOperation(operation, scope.AsWeakPtr());
250868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!operation) {
25158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    DidWrite(handle, callback, error, 0, true);
25258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return handle.id;
253868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
2547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
2557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<FileStreamWriter> writer(
2567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      file_system_context_->CreateFileStreamWriter(url, offset));
2577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (!writer) {
2587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    // Write is not supported.
2595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    DidWrite(handle, callback, base::File::FILE_ERROR_SECURITY, 0, true);
26058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return handle.id;
2617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
2627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
263010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  FileWriterDelegate::FlushPolicy flush_policy =
264010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      file_system_context_->ShouldFlushOnWriteCompletion(url.type())
265010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)          ? FileWriterDelegate::FLUSH_ON_COMPLETION
266010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)          : FileWriterDelegate::NO_FLUSH_ON_COMPLETION;
2677d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<FileWriterDelegate> writer_delegate(
268010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      new FileWriterDelegate(writer.Pass(), flush_policy));
2697d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
27058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  scoped_ptr<net::URLRequest> blob_request(
27103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      storage::BlobProtocolHandler::CreateBlobRequest(
27203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)          blob.Pass(), url_request_context, writer_delegate.get()));
27358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
27458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  PrepareForWrite(handle.id, url);
275868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  operation->Write(
2767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      url, writer_delegate.Pass(), blob_request.Pass(),
277868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      base::Bind(&FileSystemOperationRunner::DidWrite, AsWeakPtr(),
27858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                 handle, callback));
27958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return handle.id;
280868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
281868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
282868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)OperationID FileSystemOperationRunner::Truncate(
283868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    const FileSystemURL& url, int64 length,
284868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    const StatusCallback& callback) {
2855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::File::Error error = base::File::FILE_OK;
286868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  FileSystemOperation* operation =
287868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      file_system_context_->CreateFileSystemOperation(url, &error);
28858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  BeginOperationScoper scope;
28958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  OperationHandle handle = BeginOperation(operation, scope.AsWeakPtr());
290868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!operation) {
29158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    DidFinish(handle, callback, error);
29258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return handle.id;
293868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
29458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  PrepareForWrite(handle.id, url);
295868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  operation->Truncate(
296868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      url, length,
297868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      base::Bind(&FileSystemOperationRunner::DidFinish, AsWeakPtr(),
29858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                 handle, callback));
29958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return handle.id;
300868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
301868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
302868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void FileSystemOperationRunner::Cancel(
303868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    OperationID id,
304868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    const StatusCallback& callback) {
30558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (ContainsKey(finished_operations_, id)) {
30658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    DCHECK(!ContainsKey(stray_cancel_callbacks_, id));
30758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    stray_cancel_callbacks_[id] = callback;
308868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return;
309868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
31058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  FileSystemOperation* operation = operations_.Lookup(id);
311d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  if (!operation) {
312d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    // There is no operation with |id|.
3135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    callback.Run(base::File::FILE_ERROR_INVALID_OPERATION);
314d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    return;
315d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  }
316868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  operation->Cancel(callback);
317868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
318868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
319868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)OperationID FileSystemOperationRunner::TouchFile(
320868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    const FileSystemURL& url,
321868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    const base::Time& last_access_time,
322868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    const base::Time& last_modified_time,
323868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    const StatusCallback& callback) {
3245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::File::Error error = base::File::FILE_OK;
325868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  FileSystemOperation* operation =
326868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      file_system_context_->CreateFileSystemOperation(url, &error);
32758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  BeginOperationScoper scope;
32858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  OperationHandle handle = BeginOperation(operation, scope.AsWeakPtr());
329868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!operation) {
33058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    DidFinish(handle, callback, error);
33158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return handle.id;
332868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
33358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  PrepareForWrite(handle.id, url);
334868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  operation->TouchFile(
335868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      url, last_access_time, last_modified_time,
336868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      base::Bind(&FileSystemOperationRunner::DidFinish, AsWeakPtr(),
33758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                 handle, callback));
33858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return handle.id;
339868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
340868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
341868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)OperationID FileSystemOperationRunner::OpenFile(
342868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    const FileSystemURL& url,
343868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    int file_flags,
344868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    const OpenFileCallback& callback) {
3455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::File::Error error = base::File::FILE_OK;
346868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  FileSystemOperation* operation =
347868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      file_system_context_->CreateFileSystemOperation(url, &error);
34858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  BeginOperationScoper scope;
34958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  OperationHandle handle = BeginOperation(operation, scope.AsWeakPtr());
350868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!operation) {
351cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    DidOpenFile(handle, callback, base::File(error), base::Closure());
35258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return handle.id;
353868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
354868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (file_flags &
355cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      (base::File::FLAG_CREATE | base::File::FLAG_OPEN_ALWAYS |
356cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)       base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_OPEN_TRUNCATED |
357cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)       base::File::FLAG_WRITE | base::File::FLAG_EXCLUSIVE_WRITE |
358cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)       base::File::FLAG_DELETE_ON_CLOSE |
359cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)       base::File::FLAG_WRITE_ATTRIBUTES)) {
36058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    PrepareForWrite(handle.id, url);
361868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  } else {
36258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    PrepareForRead(handle.id, url);
363868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
364868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  operation->OpenFile(
3650f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      url, file_flags,
366868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      base::Bind(&FileSystemOperationRunner::DidOpenFile, AsWeakPtr(),
36758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                 handle, callback));
36858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return handle.id;
369868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
370868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
371868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)OperationID FileSystemOperationRunner::CreateSnapshotFile(
372868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    const FileSystemURL& url,
373868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    const SnapshotFileCallback& callback) {
3745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::File::Error error = base::File::FILE_OK;
375868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  FileSystemOperation* operation =
376868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      file_system_context_->CreateFileSystemOperation(url, &error);
37758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  BeginOperationScoper scope;
37858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  OperationHandle handle = BeginOperation(operation, scope.AsWeakPtr());
379868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!operation) {
3805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    DidCreateSnapshot(handle, callback, error, base::File::Info(),
38158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                      base::FilePath(), NULL);
38258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return handle.id;
383868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
38458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  PrepareForRead(handle.id, url);
385868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  operation->CreateSnapshotFile(
386868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      url,
387868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      base::Bind(&FileSystemOperationRunner::DidCreateSnapshot, AsWeakPtr(),
38858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                 handle, callback));
38958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return handle.id;
390868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
391868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
392868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)OperationID FileSystemOperationRunner::CopyInForeignFile(
393868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    const base::FilePath& src_local_disk_path,
394868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    const FileSystemURL& dest_url,
395868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    const StatusCallback& callback) {
3965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::File::Error error = base::File::FILE_OK;
397424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  FileSystemOperation* operation =
398424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      file_system_context_->CreateFileSystemOperation(dest_url, &error);
39958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  BeginOperationScoper scope;
40058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  OperationHandle handle = BeginOperation(operation, scope.AsWeakPtr());
401868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!operation) {
40258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    DidFinish(handle, callback, error);
40358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return handle.id;
404868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
4051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  PrepareForWrite(handle.id, dest_url);
406424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  operation->CopyInForeignFile(
407868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      src_local_disk_path, dest_url,
408868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      base::Bind(&FileSystemOperationRunner::DidFinish, AsWeakPtr(),
40958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                 handle, callback));
41058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return handle.id;
411868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
412868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
413868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)OperationID FileSystemOperationRunner::RemoveFile(
414868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    const FileSystemURL& url,
415868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    const StatusCallback& callback) {
4165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::File::Error error = base::File::FILE_OK;
417424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  FileSystemOperation* operation =
418424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      file_system_context_->CreateFileSystemOperation(url, &error);
41958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  BeginOperationScoper scope;
42058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  OperationHandle handle = BeginOperation(operation, scope.AsWeakPtr());
421868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!operation) {
42258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    DidFinish(handle, callback, error);
42358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return handle.id;
424868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
4251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  PrepareForWrite(handle.id, url);
426424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  operation->RemoveFile(
427868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      url,
428868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      base::Bind(&FileSystemOperationRunner::DidFinish, AsWeakPtr(),
42958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                 handle, callback));
43058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return handle.id;
431868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
432868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
433868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)OperationID FileSystemOperationRunner::RemoveDirectory(
434868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    const FileSystemURL& url,
435868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    const StatusCallback& callback) {
4365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::File::Error error = base::File::FILE_OK;
437424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  FileSystemOperation* operation =
438424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      file_system_context_->CreateFileSystemOperation(url, &error);
43958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  BeginOperationScoper scope;
44058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  OperationHandle handle = BeginOperation(operation, scope.AsWeakPtr());
441868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!operation) {
44258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    DidFinish(handle, callback, error);
44358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return handle.id;
444868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
4451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  PrepareForWrite(handle.id, url);
446424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  operation->RemoveDirectory(
447868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      url,
448868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      base::Bind(&FileSystemOperationRunner::DidFinish, AsWeakPtr(),
44958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                 handle, callback));
45058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return handle.id;
451868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
452868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
453868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)OperationID FileSystemOperationRunner::CopyFileLocal(
454868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    const FileSystemURL& src_url,
455868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    const FileSystemURL& dest_url,
45668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    CopyOrMoveOption option,
45758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    const CopyFileProgressCallback& progress_callback,
458868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    const StatusCallback& callback) {
4595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::File::Error error = base::File::FILE_OK;
460424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  FileSystemOperation* operation =
461424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      file_system_context_->CreateFileSystemOperation(src_url, &error);
46258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  BeginOperationScoper scope;
46358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  OperationHandle handle = BeginOperation(operation, scope.AsWeakPtr());
464868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!operation) {
46558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    DidFinish(handle, callback, error);
46658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return handle.id;
467868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
4681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  PrepareForRead(handle.id, src_url);
4691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  PrepareForWrite(handle.id, dest_url);
470424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  operation->CopyFileLocal(
47168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      src_url, dest_url, option, progress_callback,
472868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      base::Bind(&FileSystemOperationRunner::DidFinish, AsWeakPtr(),
47358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                 handle, callback));
47458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return handle.id;
475868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
476868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
477868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)OperationID FileSystemOperationRunner::MoveFileLocal(
478868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    const FileSystemURL& src_url,
479868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    const FileSystemURL& dest_url,
48068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    CopyOrMoveOption option,
481868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    const StatusCallback& callback) {
4825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::File::Error error = base::File::FILE_OK;
483424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  FileSystemOperation* operation =
484424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      file_system_context_->CreateFileSystemOperation(src_url, &error);
48558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  BeginOperationScoper scope;
48658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  OperationHandle handle = BeginOperation(operation, scope.AsWeakPtr());
487868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!operation) {
48858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    DidFinish(handle, callback, error);
48958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return handle.id;
490868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
4911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  PrepareForWrite(handle.id, src_url);
4921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  PrepareForWrite(handle.id, dest_url);
493424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  operation->MoveFileLocal(
49468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      src_url, dest_url, option,
495868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      base::Bind(&FileSystemOperationRunner::DidFinish, AsWeakPtr(),
49658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                 handle, callback));
49758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return handle.id;
498868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
499868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
5005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::File::Error FileSystemOperationRunner::SyncGetPlatformPath(
501868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    const FileSystemURL& url,
502868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    base::FilePath* platform_path) {
5035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::File::Error error = base::File::FILE_OK;
5041e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  scoped_ptr<FileSystemOperation> operation(
5051e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      file_system_context_->CreateFileSystemOperation(url, &error));
5061e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (!operation.get())
507868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return error;
508424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  return operation->SyncGetPlatformPath(url, platform_path);
509868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
510868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
511868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)FileSystemOperationRunner::FileSystemOperationRunner(
512868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    FileSystemContext* file_system_context)
513868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    : file_system_context_(file_system_context) {}
514868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
515868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void FileSystemOperationRunner::DidFinish(
51658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    const OperationHandle& handle,
517868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    const StatusCallback& callback,
5185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::File::Error rv) {
51958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (handle.scope) {
52058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    finished_operations_.insert(handle.id);
52158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    base::MessageLoopProxy::current()->PostTask(
52258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        FROM_HERE, base::Bind(&FileSystemOperationRunner::DidFinish,
52358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                              AsWeakPtr(), handle, callback, rv));
52458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return;
52558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
526868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  callback.Run(rv);
52758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  FinishOperation(handle.id);
528868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
529868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
530868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void FileSystemOperationRunner::DidGetMetadata(
53158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    const OperationHandle& handle,
532868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    const GetMetadataCallback& callback,
5335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::File::Error rv,
5345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const base::File::Info& file_info) {
53558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (handle.scope) {
53658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    finished_operations_.insert(handle.id);
53758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    base::MessageLoopProxy::current()->PostTask(
53858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        FROM_HERE, base::Bind(&FileSystemOperationRunner::DidGetMetadata,
53958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                              AsWeakPtr(), handle, callback, rv, file_info));
54058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return;
54158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
5427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  callback.Run(rv, file_info);
54358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  FinishOperation(handle.id);
544868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
545868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
546868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void FileSystemOperationRunner::DidReadDirectory(
54758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    const OperationHandle& handle,
548868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    const ReadDirectoryCallback& callback,
5495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::File::Error rv,
550868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    const std::vector<DirectoryEntry>& entries,
551868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    bool has_more) {
55258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (handle.scope) {
55358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    finished_operations_.insert(handle.id);
55458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    base::MessageLoopProxy::current()->PostTask(
55558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        FROM_HERE, base::Bind(&FileSystemOperationRunner::DidReadDirectory,
55658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                              AsWeakPtr(), handle, callback, rv,
55758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                              entries, has_more));
55858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return;
55958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
560868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  callback.Run(rv, entries, has_more);
5615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (rv != base::File::FILE_OK || !has_more)
56258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    FinishOperation(handle.id);
563868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
564868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
565868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void FileSystemOperationRunner::DidWrite(
56658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    const OperationHandle& handle,
567868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    const WriteCallback& callback,
5685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::File::Error rv,
569868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    int64 bytes,
570868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    bool complete) {
57158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (handle.scope) {
57258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    finished_operations_.insert(handle.id);
57358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    base::MessageLoopProxy::current()->PostTask(
57458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        FROM_HERE, base::Bind(&FileSystemOperationRunner::DidWrite, AsWeakPtr(),
57558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                              handle, callback, rv, bytes, complete));
57658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return;
57758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
578868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  callback.Run(rv, bytes, complete);
5795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (rv != base::File::FILE_OK || complete)
58058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    FinishOperation(handle.id);
581868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
582868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
583868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void FileSystemOperationRunner::DidOpenFile(
58458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    const OperationHandle& handle,
585868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    const OpenFileCallback& callback,
586cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    base::File file,
5870f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    const base::Closure& on_close_callback) {
58858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (handle.scope) {
58958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    finished_operations_.insert(handle.id);
59058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    base::MessageLoopProxy::current()->PostTask(
59158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        FROM_HERE, base::Bind(&FileSystemOperationRunner::DidOpenFile,
592cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                              AsWeakPtr(), handle, callback, Passed(&file),
5930f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                              on_close_callback));
59458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return;
59558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
596cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  callback.Run(file.Pass(), on_close_callback);
59758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  FinishOperation(handle.id);
598868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
599868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
600868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void FileSystemOperationRunner::DidCreateSnapshot(
60158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    const OperationHandle& handle,
602868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    const SnapshotFileCallback& callback,
6035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::File::Error rv,
6045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const base::File::Info& file_info,
605868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    const base::FilePath& platform_path,
60603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    const scoped_refptr<storage::ShareableFileReference>& file_ref) {
60758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (handle.scope) {
60858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    finished_operations_.insert(handle.id);
60958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    base::MessageLoopProxy::current()->PostTask(
61058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        FROM_HERE, base::Bind(&FileSystemOperationRunner::DidCreateSnapshot,
61158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                              AsWeakPtr(), handle, callback, rv, file_info,
61258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                              platform_path, file_ref));
61358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return;
61458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
615868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  callback.Run(rv, file_info, platform_path, file_ref);
61658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  FinishOperation(handle.id);
617868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
618868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
619d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)void FileSystemOperationRunner::OnCopyProgress(
620d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    const OperationHandle& handle,
621d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    const CopyProgressCallback& callback,
622d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    FileSystemOperation::CopyProgressType type,
62368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    const FileSystemURL& source_url,
62468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    const FileSystemURL& dest_url,
625d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    int64 size) {
626d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  if (handle.scope) {
627d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    base::MessageLoopProxy::current()->PostTask(
62868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)        FROM_HERE, base::Bind(
62968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)            &FileSystemOperationRunner::OnCopyProgress,
63068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)            AsWeakPtr(), handle, callback, type, source_url, dest_url, size));
631d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    return;
632d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  }
63368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  callback.Run(type, source_url, dest_url, size);
634d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)}
635d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
636868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void FileSystemOperationRunner::PrepareForWrite(OperationID id,
637868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                                const FileSystemURL& url) {
638868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (file_system_context_->GetUpdateObservers(url.type())) {
639868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    file_system_context_->GetUpdateObservers(url.type())->Notify(
640868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        &FileUpdateObserver::OnStartUpdate, MakeTuple(url));
641868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
642868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  write_target_urls_[id].insert(url);
643868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
644868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
645868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void FileSystemOperationRunner::PrepareForRead(OperationID id,
646868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                               const FileSystemURL& url) {
647868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (file_system_context_->GetAccessObservers(url.type())) {
648868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    file_system_context_->GetAccessObservers(url.type())->Notify(
649868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        &FileAccessObserver::OnAccess, MakeTuple(url));
650868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
651868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
652868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
65358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)FileSystemOperationRunner::OperationHandle
65458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)FileSystemOperationRunner::BeginOperation(
65558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    FileSystemOperation* operation,
65658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    base::WeakPtr<BeginOperationScoper> scope) {
65758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  OperationHandle handle;
65858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  handle.id = operations_.Add(operation);
65958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  handle.scope = scope;
66058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return handle;
66158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
66258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
663868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void FileSystemOperationRunner::FinishOperation(OperationID id) {
664868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  OperationToURLSet::iterator found = write_target_urls_.find(id);
665868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (found != write_target_urls_.end()) {
666868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    const FileSystemURLSet& urls = found->second;
667868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    for (FileSystemURLSet::const_iterator iter = urls.begin();
668868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        iter != urls.end(); ++iter) {
669868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      if (file_system_context_->GetUpdateObservers(iter->type())) {
670868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        file_system_context_->GetUpdateObservers(iter->type())->Notify(
671868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)            &FileUpdateObserver::OnEndUpdate, MakeTuple(*iter));
672868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      }
673868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    }
674868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    write_target_urls_.erase(found);
675868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
67658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
67758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // IDMap::Lookup fails if the operation is NULL, so we don't check
67858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // operations_.Lookup(id) here.
67958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
680868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  operations_.Remove(id);
68158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  finished_operations_.erase(id);
68258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
68358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // Dispatch stray cancel callback if exists.
68458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  std::map<OperationID, StatusCallback>::iterator found_cancel =
68558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      stray_cancel_callbacks_.find(id);
68658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (found_cancel != stray_cancel_callbacks_.end()) {
68758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // This cancel has been requested after the operation has finished,
68858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // so report that we failed to stop it.
6895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    found_cancel->second.Run(base::File::FILE_ERROR_INVALID_OPERATION);
69058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    stray_cancel_callbacks_.erase(found_cancel);
69158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
692868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
693868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
69403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}  // namespace storage
695