file_stream_writer.cc revision 5f1c94371a64b3196d4be9466099bb892df9b88e
15f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
25f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// found in the LICENSE file.
45f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
55f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "chrome/browser/chromeos/file_system_provider/fileapi/file_stream_writer.h"
65f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
75f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "base/debug/trace_event.h"
85f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "base/memory/ref_counted.h"
95f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "chrome/browser/chromeos/file_system_provider/fileapi/provider_async_file_util.h"
105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "chrome/browser/chromeos/file_system_provider/mount_path_util.h"
115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "chrome/browser/chromeos/file_system_provider/provided_file_system_interface.h"
125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/public/browser/browser_thread.h"
135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "net/base/io_buffer.h"
145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "net/base/net_errors.h"
155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)using content::BrowserThread;
175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)namespace chromeos {
195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)namespace file_system_provider {
205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)namespace {
215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Dicards the callback from CloseFile().
235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void EmptyStatusCallback(base::File::Error /* result */) {
245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Opens a file for writing and calls the completion callback. Must be called
275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// on UI thread.
285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void OpenFileOnUIThread(
295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    const fileapi::FileSystemURL& url,
305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    const FileStreamWriter::OpenFileCompletedCallback& callback) {
315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DCHECK_CURRENTLY_ON(BrowserThread::UI);
325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  util::FileSystemURLParser parser(url);
345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (!parser.Parse()) {
355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    callback.Run(base::WeakPtr<ProvidedFileSystemInterface>(),
365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                 base::FilePath(),
375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                 0 /* file_handle */,
385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                 base::File::FILE_ERROR_SECURITY);
395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return;
405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  parser.file_system()->OpenFile(
435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      parser.file_path(),
445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      ProvidedFileSystemInterface::OPEN_FILE_MODE_WRITE,
455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      base::Bind(
465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          callback, parser.file_system()->GetWeakPtr(), parser.file_path()));
475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Forwards results of calling OpenFileOnUIThread back to the IO thread.
505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void OnOpenFileCompletedOnUIThread(
515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    const FileStreamWriter::OpenFileCompletedCallback& callback,
525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    base::WeakPtr<ProvidedFileSystemInterface> file_system,
535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    const base::FilePath& file_path,
545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    int file_handle,
555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    base::File::Error result) {
565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DCHECK_CURRENTLY_ON(BrowserThread::UI);
575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  BrowserThread::PostTask(
585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      BrowserThread::IO,
595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      FROM_HERE,
605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      base::Bind(callback, file_system, file_path, file_handle, result));
615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Closes a file. Ignores result, since it is called from a constructor.
645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Must be called on UI thread.
655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void CloseFileOnUIThread(base::WeakPtr<ProvidedFileSystemInterface> file_system,
665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                         int file_handle) {
675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DCHECK_CURRENTLY_ON(BrowserThread::UI);
685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (file_system.get())
695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    file_system->CloseFile(file_handle, base::Bind(&EmptyStatusCallback));
705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Requests writing bytes to the file. In case of either success or a failure
735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// |callback| is executed. Must be called on UI thread.
745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void WriteFileOnUIThread(
755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    base::WeakPtr<ProvidedFileSystemInterface> file_system,
765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    int file_handle,
775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    scoped_refptr<net::IOBuffer> buffer,
785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    int64 offset,
795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    int length,
805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    const fileapi::AsyncFileUtil::StatusCallback& callback) {
815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DCHECK_CURRENTLY_ON(BrowserThread::UI);
825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // If the file system got unmounted, then abort the writing operation.
845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (!file_system.get()) {
855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    callback.Run(base::File::FILE_ERROR_ABORT);
865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return;
875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  file_system->WriteFile(file_handle, buffer, offset, length, callback);
905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Forward the completion callback to IO thread.
935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void OnWriteFileCompletedOnUIThread(
945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    const fileapi::AsyncFileUtil::StatusCallback& callback,
955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    base::File::Error result) {
965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DCHECK_CURRENTLY_ON(BrowserThread::UI);
975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  BrowserThread::PostTask(
985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      BrowserThread::IO, FROM_HERE, base::Bind(callback, result));
995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
1005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}  // namespace
1025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)FileStreamWriter::FileStreamWriter(const fileapi::FileSystemURL& url,
1045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                   int64 initial_offset)
1055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    : url_(url),
1065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      current_offset_(initial_offset),
1075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      state_(NOT_INITIALIZED),
1085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      file_handle_(0),
1095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      weak_ptr_factory_(this) {
1105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
1115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)FileStreamWriter::~FileStreamWriter() {
1135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  BrowserThread::PostTask(
1145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      BrowserThread::UI,
1155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      FROM_HERE,
1165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      base::Bind(&CloseFileOnUIThread, file_system_, file_handle_));
1175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
1185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void FileStreamWriter::Initialize(
1205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    const base::Closure& pending_closure,
1215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    const net::CompletionCallback& error_callback) {
1225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DCHECK_EQ(NOT_INITIALIZED, state_);
1235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  state_ = INITIALIZING;
1245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  BrowserThread::PostTask(
1265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      BrowserThread::UI,
1275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      FROM_HERE,
1285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      base::Bind(&OpenFileOnUIThread,
1295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                 url_,
1305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                 base::Bind(&OnOpenFileCompletedOnUIThread,
1315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                            base::Bind(&FileStreamWriter::OnOpenFileCompleted,
1325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                       weak_ptr_factory_.GetWeakPtr(),
1335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                       pending_closure,
1345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                       error_callback))));
1355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
1365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void FileStreamWriter::OnOpenFileCompleted(
1385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    const base::Closure& pending_closure,
1395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    const net::CompletionCallback& error_callback,
1405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    base::WeakPtr<ProvidedFileSystemInterface> file_system,
1415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    const base::FilePath& file_path,
1425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    int file_handle,
1435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    base::File::Error result) {
1445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DCHECK_CURRENTLY_ON(BrowserThread::IO);
1455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DCHECK_EQ(INITIALIZING, state_);
1465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // In case of an error, return immediately using the |error_callback| of the
1485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Write() pending request.
1495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (result != base::File::FILE_OK) {
1505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    state_ = FAILED;
1515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    error_callback.Run(net::FileErrorToNetError(result));
1525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return;
1535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
1545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  file_system_ = file_system;
1565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  file_path_ = file_path;
1575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  file_handle_ = file_handle;
1585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DCHECK_LT(0, file_handle);
1595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DCHECK_EQ(base::File::FILE_OK, result);
1605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  state_ = INITIALIZED;
1615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Run the task waiting for the initialization to be completed.
1635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  pending_closure.Run();
1645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
1655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)int FileStreamWriter::Write(net::IOBuffer* buffer,
1675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                            int buffer_length,
1685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                            const net::CompletionCallback& callback) {
1695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DCHECK_CURRENTLY_ON(BrowserThread::IO);
1705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  TRACE_EVENT_ASYNC_BEGIN1("file_system_provider",
1715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                           "FileStreamWriter::Write",
1725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                           this,
1735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                           "buffer_length",
1745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                           buffer_length);
1755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  switch (state_) {
1775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    case NOT_INITIALIZED:
1785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      // Lazily initialize with the first call to Write().
1795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      Initialize(base::Bind(&FileStreamWriter::WriteAfterInitialized,
1805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                            weak_ptr_factory_.GetWeakPtr(),
1815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                            make_scoped_refptr(buffer),
1825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                            buffer_length,
1835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                            base::Bind(&FileStreamWriter::OnWriteCompleted,
1845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                       weak_ptr_factory_.GetWeakPtr(),
1855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                       callback)),
1865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                 base::Bind(&FileStreamWriter::OnWriteCompleted,
1875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                            weak_ptr_factory_.GetWeakPtr(),
1885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                            callback));
1895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      break;
1905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    case INITIALIZING:
1925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      NOTREACHED();
1935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      break;
1945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    case INITIALIZED:
1965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      WriteAfterInitialized(buffer,
1975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                            buffer_length,
1985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                            base::Bind(&FileStreamWriter::OnWriteCompleted,
1995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                       weak_ptr_factory_.GetWeakPtr(),
2005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                       callback));
2015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      break;
2025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    case FAILED:
2045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      NOTREACHED();
2055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      break;
2065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
2075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return net::ERR_IO_PENDING;
2095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
2105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)int FileStreamWriter::Cancel(const net::CompletionCallback& callback) {
2125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  NOTIMPLEMENTED();
2135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return net::ERR_FAILED;
2145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
2155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)int FileStreamWriter::Flush(const net::CompletionCallback& callback) {
2175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (state_ != INITIALIZED)
2185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return net::ERR_FAILED;
2195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return net::OK;
2215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
2225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void FileStreamWriter::OnWriteFileCompleted(
2245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    int buffer_length,
2255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    const net::CompletionCallback& callback,
2265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    base::File::Error result) {
2275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DCHECK_CURRENTLY_ON(BrowserThread::IO);
2285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DCHECK_EQ(INITIALIZED, state_);
2295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (result != base::File::FILE_OK) {
2315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    state_ = FAILED;
2325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    callback.Run(net::FileErrorToNetError(result));
2335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return;
2345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
2355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  current_offset_ += buffer_length;
2375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  callback.Run(buffer_length);
2385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
2395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void FileStreamWriter::OnWriteCompleted(net::CompletionCallback callback,
2415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                        int result) {
2425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DCHECK_CURRENTLY_ON(BrowserThread::IO);
2435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  callback.Run(result);
2445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  TRACE_EVENT_ASYNC_END0(
2455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      "file_system_provider", "FileStreamWriter::Write", this);
2465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
2475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void FileStreamWriter::WriteAfterInitialized(
2495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    scoped_refptr<net::IOBuffer> buffer,
2505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    int buffer_length,
2515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    const net::CompletionCallback& callback) {
2525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DCHECK_CURRENTLY_ON(BrowserThread::IO);
2535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DCHECK_EQ(INITIALIZED, state_);
2545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  BrowserThread::PostTask(
2565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      BrowserThread::UI,
2575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      FROM_HERE,
2585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      base::Bind(&WriteFileOnUIThread,
2595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                 file_system_,
2605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                 file_handle_,
2615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                 buffer,
2625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                 current_offset_,
2635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                 buffer_length,
2645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                 base::Bind(&OnWriteFileCompletedOnUIThread,
2655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                            base::Bind(&FileStreamWriter::OnWriteFileCompleted,
2665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                       weak_ptr_factory_.GetWeakPtr(),
2675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                       buffer_length,
2685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                       callback))));
2695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
2705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}  // namespace file_system_provider
2725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}  // namespace chromeos
273