// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "content/renderer/pepper/pepper_file_io_host.h"

#include "base/bind.h"
#include "base/callback.h"
#include "base/callback_helpers.h"
#include "base/command_line.h"
#include "base/files/file_util_proxy.h"
#include "content/child/child_thread.h"
#include "content/child/fileapi/file_system_dispatcher.h"
#include "content/child/quota_dispatcher.h"
#include "content/common/fileapi/file_system_messages.h"
#include "content/common/view_messages.h"
#include "content/public/common/content_client.h"
#include "content/public/renderer/content_renderer_client.h"
#include "content/renderer/pepper/host_globals.h"
#include "content/renderer/pepper/pepper_plugin_instance_impl.h"
#include "content/renderer/pepper/ppb_file_ref_impl.h"
#include "content/renderer/pepper/quota_file_io.h"
#include "content/renderer/render_thread_impl.h"
#include "ppapi/c/pp_errors.h"
#include "ppapi/host/dispatch_host_message.h"
#include "ppapi/host/ppapi_host.h"
#include "ppapi/proxy/ppapi_messages.h"
#include "ppapi/shared_impl/file_type_conversion.h"
#include "ppapi/shared_impl/time_conversion.h"
#include "ppapi/thunk/enter.h"
#include "third_party/WebKit/public/web/WebPluginContainer.h"

namespace content {

using ppapi::FileIOStateManager;
using ppapi::PPTimeToTime;
using ppapi::host::ReplyMessageContext;
using ppapi::thunk::EnterResourceNoLock;
using ppapi::thunk::PPB_FileRef_API;

namespace {

// The maximum size we'll support reading in one chunk. The renderer process
// must allocate a buffer sized according to the request of the plugin. To
// keep things from getting out of control, we cap the read size to this value.
// This should generally be OK since the API specifies that it may perform a
// partial read.
static const int32_t kMaxReadSize = 32 * 1024 * 1024;  // 32MB

typedef base::Callback<void (base::PlatformFileError)> PlatformGeneralCallback;

int32_t ErrorOrByteNumber(int32_t pp_error, int32_t byte_number) {
  // On the plugin side, some callbacks expect a parameter that means different
  // things depending on whether is negative or not.  We translate for those
  // callbacks here.
  return pp_error == PP_OK ? byte_number : pp_error;
}

class QuotaCallbackTranslator : public QuotaDispatcher::Callback {
 public:
  typedef QuotaFileIO::Delegate::AvailableSpaceCallback PluginCallback;
  explicit QuotaCallbackTranslator(const PluginCallback& cb) : callback_(cb) {}
  virtual void DidQueryStorageUsageAndQuota(int64 usage, int64 quota) OVERRIDE {
    callback_.Run(std::max(static_cast<int64>(0), quota - usage));
  }
  virtual void DidGrantStorageQuota(int64 granted_quota) OVERRIDE {
    NOTREACHED();
  }
  virtual void DidFail(quota::QuotaStatusCode error) OVERRIDE {
    callback_.Run(0);
  }
 private:
  PluginCallback callback_;
};

class QuotaFileIODelegate : public QuotaFileIO::Delegate {
 public:
  QuotaFileIODelegate() {}
  virtual ~QuotaFileIODelegate() {}

  virtual void QueryAvailableSpace(
      const GURL& origin,
      quota::StorageType type,
      const AvailableSpaceCallback& callback) OVERRIDE {
    ChildThread::current()->quota_dispatcher()->QueryStorageUsageAndQuota(
        origin, type, new QuotaCallbackTranslator(callback));
  }
  virtual void WillUpdateFile(const GURL& file_path) OVERRIDE {
    ChildThread::current()->Send(new FileSystemHostMsg_WillUpdate(file_path));
  }
  virtual void DidUpdateFile(const GURL& file_path, int64_t delta) OVERRIDE {
    ChildThread::current()->Send(new FileSystemHostMsg_DidUpdate(
        file_path, delta));
  }
  virtual scoped_refptr<base::MessageLoopProxy>
      GetFileThreadMessageLoopProxy() OVERRIDE {
    return RenderThreadImpl::current()->GetFileThreadMessageLoopProxy();
  }
};

typedef base::Callback<
    void (base::PlatformFileError error,
          base::PassPlatformFile file,
          quota::QuotaLimitType quota_policy,
          const PepperFileIOHost::NotifyCloseFileCallback& close_file_callback)>
    AsyncOpenFileSystemURLCallback;

void DoNotifyCloseFile(int file_open_id, base::PlatformFileError error) {
  ChildThread::current()->file_system_dispatcher()->NotifyCloseFile(
      file_open_id);
}

void DidOpenFileSystemURL(const AsyncOpenFileSystemURLCallback& callback,
                          base::PlatformFile file,
                          int file_open_id,
                          quota::QuotaLimitType quota_policy) {
  callback.Run(base::PLATFORM_FILE_OK,
               base::PassPlatformFile(&file),
               quota_policy,
               base::Bind(&DoNotifyCloseFile, file_open_id));
  // Make sure we won't leak file handle if the requester has died.
  if (file != base::kInvalidPlatformFileValue) {
    base::FileUtilProxy::Close(
        RenderThreadImpl::current()->GetFileThreadMessageLoopProxy().get(),
        file,
        base::Bind(&DoNotifyCloseFile, file_open_id));
  }
}

void DidFailOpenFileSystemURL(const AsyncOpenFileSystemURLCallback& callback,
    base::PlatformFileError error_code) {
  base::PlatformFile invalid_file = base::kInvalidPlatformFileValue;
  callback.Run(error_code,
               base::PassPlatformFile(&invalid_file),
               quota::kQuotaLimitTypeUnknown,
               PepperFileIOHost::NotifyCloseFileCallback());
}

}  // namespace

PepperFileIOHost::PepperFileIOHost(RendererPpapiHost* host,
                                   PP_Instance instance,
                                   PP_Resource resource)
    : ResourceHost(host->GetPpapiHost(), instance, resource),
      file_(base::kInvalidPlatformFileValue),
      file_system_type_(PP_FILESYSTEMTYPE_INVALID),
      quota_policy_(quota::kQuotaLimitTypeUnknown),
      is_running_in_process_(host->IsRunningInProcess()),
      open_flags_(0),
      weak_factory_(this),
      routing_id_(RenderThreadImpl::current()->GenerateRoutingID()) {
      ChildThread::current()->AddRoute(routing_id_, this);
}

PepperFileIOHost::~PepperFileIOHost() {
  OnHostMsgClose(NULL);
  ChildThread::current()->RemoveRoute(routing_id_);
}

int32_t PepperFileIOHost::OnResourceMessageReceived(
    const IPC::Message& msg,
    ppapi::host::HostMessageContext* context) {
  IPC_BEGIN_MESSAGE_MAP(PepperFileIOHost, msg)
    PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_FileIO_Open,
                                      OnHostMsgOpen)
    PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_FileIO_Query,
                                        OnHostMsgQuery)
    PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_FileIO_Touch,
                                      OnHostMsgTouch)
    PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_FileIO_Read,
                                      OnHostMsgRead)
    PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_FileIO_Write,
                                      OnHostMsgWrite)
    PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_FileIO_SetLength,
                                      OnHostMsgSetLength)
    PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_FileIO_Flush,
                                        OnHostMsgFlush)
    PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_FileIO_Close,
                                        OnHostMsgClose)
    PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_FileIO_WillWrite,
                                      OnHostMsgWillWrite)
    PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_FileIO_WillSetLength,
                                      OnHostMsgWillSetLength)
    PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_FileIO_GetOSFileDescriptor,
                                        OnHostMsgGetOSFileDescriptor)
    PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_FileIO_RequestOSFileHandle,
                                        OnHostMsgRequestOSFileHandle)
  IPC_END_MESSAGE_MAP()
  return PP_ERROR_FAILED;
}

bool PepperFileIOHost::OnMessageReceived(const IPC::Message& msg) {
  bool handled = true;
  IPC_BEGIN_MESSAGE_MAP(PepperFileIOHost, msg)
    IPC_MESSAGE_HANDLER(ViewMsg_AsyncOpenPepperFile_ACK, OnAsyncFileOpened)
    IPC_MESSAGE_UNHANDLED(handled = false)
  IPC_END_MESSAGE_MAP()
  return handled;
}

void PepperFileIOHost::OnAsyncFileOpened(
    base::PlatformFileError error_code,
    IPC::PlatformFileForTransit file_for_transit,
    int message_id) {
  AsyncOpenFileCallback* callback =
      pending_async_open_files_.Lookup(message_id);
  DCHECK(callback);
  pending_async_open_files_.Remove(message_id);

  base::PlatformFile file =
      IPC::PlatformFileForTransitToPlatformFile(file_for_transit);
  callback->Run(error_code, base::PassPlatformFile(&file));
  // Make sure we won't leak file handle if the requester has died.
  if (file != base::kInvalidPlatformFileValue) {
    base::FileUtilProxy::Close(
        RenderThreadImpl::current()->GetFileThreadMessageLoopProxy().get(),
        file,
        base::FileUtilProxy::StatusCallback());
  }
  delete callback;
}

int32_t PepperFileIOHost::OnHostMsgOpen(
    ppapi::host::HostMessageContext* context,
    PP_Resource file_ref_resource,
    int32_t open_flags) {
  int32_t rv = state_manager_.CheckOperationState(
      FileIOStateManager::OPERATION_EXCLUSIVE, false);
  if (rv != PP_OK)
    return rv;

  // TODO(tommycli): Eventually just pass the Pepper flags straight to the
  // FileSystemDispatcher so it can handle doing the security check.
  int platform_file_flags = 0;
  open_flags_ = open_flags;
  if (!::ppapi::PepperFileOpenFlagsToPlatformFileFlags(open_flags,
                                                       &platform_file_flags)) {
    return PP_ERROR_BADARGUMENT;
  }

  EnterResourceNoLock<PPB_FileRef_API> enter(file_ref_resource, true);
  if (enter.failed())
    return PP_ERROR_BADRESOURCE;

  PPB_FileRef_API* file_ref_api = enter.object();
  PP_FileSystemType type = file_ref_api->GetFileSystemType();
  if (type != PP_FILESYSTEMTYPE_LOCALPERSISTENT &&
      type != PP_FILESYSTEMTYPE_LOCALTEMPORARY &&
      type != PP_FILESYSTEMTYPE_EXTERNAL &&
      type != PP_FILESYSTEMTYPE_ISOLATED)
    return PP_ERROR_FAILED;
  file_system_type_ = type;

  PPB_FileRef_Impl* file_ref = static_cast<PPB_FileRef_Impl*>(file_ref_api);
  if (file_ref->HasValidFileSystem()) {
    file_system_url_ = file_ref->GetFileSystemURL();

    FileSystemDispatcher* file_system_dispatcher =
        ChildThread::current()->file_system_dispatcher();
    AsyncOpenFileSystemURLCallback callback = base::Bind(
        &PepperFileIOHost::ExecutePlatformOpenFileSystemURLCallback,
        weak_factory_.GetWeakPtr(),
        context->MakeReplyMessageContext());
    file_system_dispatcher->OpenFile(
        file_system_url_, platform_file_flags,
        base::Bind(&DidOpenFileSystemURL, callback),
        base::Bind(&DidFailOpenFileSystemURL, callback));
  } else {
    if (file_system_type_ != PP_FILESYSTEMTYPE_EXTERNAL)
      return PP_ERROR_FAILED;
    int message_id = pending_async_open_files_.Add(new AsyncOpenFileCallback(
        base::Bind(&PepperFileIOHost::ExecutePlatformOpenFileCallback,
                    weak_factory_.GetWeakPtr(),
                    context->MakeReplyMessageContext())));
    RenderThreadImpl::current()->Send(new ViewHostMsg_AsyncOpenPepperFile(
        routing_id_, file_ref->GetSystemPath(), open_flags, message_id));
  }

  state_manager_.SetPendingOperation(FileIOStateManager::OPERATION_EXCLUSIVE);
  return PP_OK_COMPLETIONPENDING;
}

int32_t PepperFileIOHost::OnHostMsgQuery(
    ppapi::host::HostMessageContext* context) {
  int32_t rv = state_manager_.CheckOperationState(
      FileIOStateManager::OPERATION_EXCLUSIVE, true);
  if (rv != PP_OK)
    return rv;

  if (!base::FileUtilProxy::GetFileInfoFromPlatformFile(
          RenderThreadImpl::current()->GetFileThreadMessageLoopProxy().get(),
          file_,
          base::Bind(&PepperFileIOHost::ExecutePlatformQueryCallback,
                     weak_factory_.GetWeakPtr(),
                     context->MakeReplyMessageContext())))
    return PP_ERROR_FAILED;

  state_manager_.SetPendingOperation(FileIOStateManager::OPERATION_EXCLUSIVE);
  return PP_OK_COMPLETIONPENDING;
}

int32_t PepperFileIOHost::OnHostMsgTouch(
    ppapi::host::HostMessageContext* context,
    PP_Time last_access_time,
    PP_Time last_modified_time) {
  int32_t rv = state_manager_.CheckOperationState(
      FileIOStateManager::OPERATION_EXCLUSIVE, true);
  if (rv != PP_OK)
    return rv;

  if (file_system_type_ != PP_FILESYSTEMTYPE_EXTERNAL) {
    FileSystemDispatcher* file_system_dispatcher =
        ChildThread::current()->file_system_dispatcher();
    file_system_dispatcher->TouchFile(
        file_system_url_,
        PPTimeToTime(last_access_time),
        PPTimeToTime(last_modified_time),
        base::Bind(&PepperFileIOHost::ExecutePlatformGeneralCallback,
                    weak_factory_.GetWeakPtr(),
                    context->MakeReplyMessageContext()));
    state_manager_.SetPendingOperation(FileIOStateManager::OPERATION_EXCLUSIVE);
    return PP_OK_COMPLETIONPENDING;
  }

  // TODO(nhiroki): fix a failure of FileIO.Touch for an external filesystem on
  // Mac and Linux due to sandbox restrictions (http://crbug.com/101128).
  if (!base::FileUtilProxy::Touch(
          RenderThreadImpl::current()->GetFileThreadMessageLoopProxy().get(),
          file_,
          PPTimeToTime(last_access_time),
          PPTimeToTime(last_modified_time),
          base::Bind(&PepperFileIOHost::ExecutePlatformGeneralCallback,
                     weak_factory_.GetWeakPtr(),
                     context->MakeReplyMessageContext())))
    return PP_ERROR_FAILED;

  state_manager_.SetPendingOperation(FileIOStateManager::OPERATION_EXCLUSIVE);
  return PP_OK_COMPLETIONPENDING;
}

int32_t PepperFileIOHost::OnHostMsgRead(
    ppapi::host::HostMessageContext* context,
    int64_t offset,
    int32_t max_read_length) {
  int32_t rv = state_manager_.CheckOperationState(
      FileIOStateManager::OPERATION_READ, true);
  if (rv != PP_OK)
    return rv;

  // Validate max_read_length before allocating below. This value is coming from
  // the untrusted plugin.
  if (max_read_length < 0) {
    ReplyMessageContext reply_context = context->MakeReplyMessageContext();
    reply_context.params.set_result(PP_ERROR_FAILED);
    host()->SendReply(reply_context,
                      PpapiPluginMsg_FileIO_ReadReply(std::string()));
    return PP_OK_COMPLETIONPENDING;
  }

  if (!base::FileUtilProxy::Read(
          RenderThreadImpl::current()->GetFileThreadMessageLoopProxy().get(),
          file_,
          offset,
          max_read_length,
          base::Bind(&PepperFileIOHost::ExecutePlatformReadCallback,
                     weak_factory_.GetWeakPtr(),
                     context->MakeReplyMessageContext())))
    return PP_ERROR_FAILED;

  state_manager_.SetPendingOperation(FileIOStateManager::OPERATION_READ);
  return PP_OK_COMPLETIONPENDING;
}

int32_t PepperFileIOHost::OnHostMsgWrite(
    ppapi::host::HostMessageContext* context,
    int64_t offset,
    const std::string& buffer) {
  int32_t rv = state_manager_.CheckOperationState(
      FileIOStateManager::OPERATION_WRITE, true);
  if (rv != PP_OK)
    return rv;

  if (quota_file_io_) {
    if (!quota_file_io_->Write(
            offset, buffer.c_str(), buffer.size(),
            base::Bind(&PepperFileIOHost::ExecutePlatformWriteCallback,
                       weak_factory_.GetWeakPtr(),
                       context->MakeReplyMessageContext())))
      return PP_ERROR_FAILED;
  } else {
    if (!base::FileUtilProxy::Write(
            RenderThreadImpl::current()->GetFileThreadMessageLoopProxy().get(),
            file_,
            offset,
            buffer.c_str(),
            buffer.size(),
            base::Bind(&PepperFileIOHost::ExecutePlatformWriteCallback,
                       weak_factory_.GetWeakPtr(),
                       context->MakeReplyMessageContext())))
      return PP_ERROR_FAILED;
  }

  state_manager_.SetPendingOperation(FileIOStateManager::OPERATION_WRITE);
  return PP_OK_COMPLETIONPENDING;
}

int32_t PepperFileIOHost::OnHostMsgSetLength(
    ppapi::host::HostMessageContext* context,
    int64_t length) {
  int32_t rv = state_manager_.CheckOperationState(
      FileIOStateManager::OPERATION_EXCLUSIVE, true);
  if (rv != PP_OK)
    return rv;

  if (file_system_type_ != PP_FILESYSTEMTYPE_EXTERNAL) {
    FileSystemDispatcher* file_system_dispatcher =
        ChildThread::current()->file_system_dispatcher();
    file_system_dispatcher->Truncate(
        file_system_url_, length, NULL,
        base::Bind(&PepperFileIOHost::ExecutePlatformGeneralCallback,
                   weak_factory_.GetWeakPtr(),
                   context->MakeReplyMessageContext()));
  } else {
    // TODO(nhiroki): fix a failure of FileIO.SetLength for an external
    // filesystem on Mac due to sandbox restrictions (http://crbug.com/156077).
    if (!base::FileUtilProxy::Truncate(
            RenderThreadImpl::current()->GetFileThreadMessageLoopProxy().get(),
            file_,
            length,
            base::Bind(&PepperFileIOHost::ExecutePlatformGeneralCallback,
                       weak_factory_.GetWeakPtr(),
                       context->MakeReplyMessageContext())))
      return PP_ERROR_FAILED;
  }

  state_manager_.SetPendingOperation(FileIOStateManager::OPERATION_EXCLUSIVE);
  return PP_OK_COMPLETIONPENDING;
}

int32_t PepperFileIOHost::OnHostMsgFlush(
    ppapi::host::HostMessageContext* context) {
  int32_t rv = state_manager_.CheckOperationState(
      FileIOStateManager::OPERATION_EXCLUSIVE, true);
  if (rv != PP_OK)
    return rv;

  if (!base::FileUtilProxy::Flush(
          RenderThreadImpl::current()->GetFileThreadMessageLoopProxy().get(),
          file_,
          base::Bind(&PepperFileIOHost::ExecutePlatformGeneralCallback,
                     weak_factory_.GetWeakPtr(),
                     context->MakeReplyMessageContext())))
    return PP_ERROR_FAILED;

  state_manager_.SetPendingOperation(FileIOStateManager::OPERATION_EXCLUSIVE);
  return PP_OK_COMPLETIONPENDING;
}

int32_t PepperFileIOHost::OnHostMsgClose(
    ppapi::host::HostMessageContext* context) {
  if (file_ != base::kInvalidPlatformFileValue) {
    base::FileUtilProxy::Close(
        RenderThreadImpl::current()->GetFileThreadMessageLoopProxy().get(),
        file_,
        base::ResetAndReturn(&notify_close_file_callback_));
    file_ = base::kInvalidPlatformFileValue;
    quota_file_io_.reset();
  }
  return PP_OK;
}

int32_t PepperFileIOHost::OnHostMsgWillWrite(
    ppapi::host::HostMessageContext* context,
    int64_t offset,
    int32_t bytes_to_write) {
  int32_t rv = state_manager_.CheckOperationState(
      FileIOStateManager::OPERATION_EXCLUSIVE, true);
  if (rv != PP_OK)
    return rv;

  if (!quota_file_io_)
    return PP_OK;

  if (!quota_file_io_->WillWrite(
          offset, bytes_to_write,
          base::Bind(&PepperFileIOHost::ExecutePlatformWriteCallback,
                     weak_factory_.GetWeakPtr(),
                     context->MakeReplyMessageContext())))
    return PP_ERROR_FAILED;

  state_manager_.SetPendingOperation(FileIOStateManager::OPERATION_EXCLUSIVE);
  return PP_OK_COMPLETIONPENDING;
}

int32_t PepperFileIOHost::OnHostMsgWillSetLength(
    ppapi::host::HostMessageContext* context,
    int64_t length) {
  int32_t rv = state_manager_.CheckOperationState(
      FileIOStateManager::OPERATION_EXCLUSIVE, true);
  if (rv != PP_OK)
    return rv;

  if (!quota_file_io_)
    return PP_OK;

  if (!quota_file_io_->WillSetLength(
          length,
          base::Bind(&PepperFileIOHost::ExecutePlatformGeneralCallback,
                     weak_factory_.GetWeakPtr(),
                     context->MakeReplyMessageContext())))
    return PP_ERROR_FAILED;

  state_manager_.SetPendingOperation(FileIOStateManager::OPERATION_EXCLUSIVE);
  return PP_OK_COMPLETIONPENDING;
}

int32_t PepperFileIOHost::OnHostMsgRequestOSFileHandle(
    ppapi::host::HostMessageContext* context) {
  if (!is_running_in_process_ &&
      quota_policy_ != quota::kQuotaLimitTypeUnlimited)
    return PP_ERROR_FAILED;

  RendererPpapiHost* renderer_ppapi_host =
      RendererPpapiHost::GetForPPInstance(pp_instance());

  // Whitelist to make it privately accessible.
  if (!GetContentClient()->renderer()->IsPluginAllowedToCallRequestOSFileHandle(
          renderer_ppapi_host->GetContainerForInstance(pp_instance())))
    return PP_ERROR_NOACCESS;

  IPC::PlatformFileForTransit file =
      renderer_ppapi_host->ShareHandleWithRemote(file_, false);
  if (file == IPC::InvalidPlatformFileForTransit())
    return PP_ERROR_FAILED;
  ppapi::host::ReplyMessageContext reply_context =
      context->MakeReplyMessageContext();
  ppapi::proxy::SerializedHandle file_handle;
  file_handle.set_file_handle(file, open_flags_);
  reply_context.params.AppendHandle(file_handle);
  host()->SendReply(reply_context,
                    PpapiPluginMsg_FileIO_RequestOSFileHandleReply());
  return PP_OK_COMPLETIONPENDING;
}

int32_t PepperFileIOHost::OnHostMsgGetOSFileDescriptor(
    ppapi::host::HostMessageContext* context) {
  if (!is_running_in_process_)
    return PP_ERROR_FAILED;

  int32_t fd =
#if defined(OS_POSIX)
      file_;
#elif defined(OS_WIN)
      reinterpret_cast<uintptr_t>(file_);
#else
      -1;
#endif

  host()->SendReply(context->MakeReplyMessageContext(),
                    PpapiPluginMsg_FileIO_GetOSFileDescriptorReply(fd));
  return PP_OK_COMPLETIONPENDING;
}

void PepperFileIOHost::ExecutePlatformGeneralCallback(
    ppapi::host::ReplyMessageContext reply_context,
    base::PlatformFileError error_code) {
  reply_context.params.set_result(
      ::ppapi::PlatformFileErrorToPepperError(error_code));
  host()->SendReply(reply_context, PpapiPluginMsg_FileIO_GeneralReply());
  state_manager_.SetOperationFinished();
}

void PepperFileIOHost::ExecutePlatformOpenFileCallback(
    ppapi::host::ReplyMessageContext reply_context,
    base::PlatformFileError error_code,
    base::PassPlatformFile file) {
  int32_t pp_error = ::ppapi::PlatformFileErrorToPepperError(error_code);
  if (pp_error == PP_OK)
    state_manager_.SetOpenSucceed();

  DCHECK(file_ == base::kInvalidPlatformFileValue);
  file_ = file.ReleaseValue();

  DCHECK(!quota_file_io_.get());
  if (file_ != base::kInvalidPlatformFileValue &&
      (file_system_type_ == PP_FILESYSTEMTYPE_LOCALTEMPORARY ||
       file_system_type_ == PP_FILESYSTEMTYPE_LOCALPERSISTENT)) {
    quota_file_io_.reset(new QuotaFileIO(
        new QuotaFileIODelegate, file_, file_system_url_, file_system_type_));
  }

  reply_context.params.set_result(pp_error);
  host()->SendReply(reply_context, PpapiPluginMsg_FileIO_OpenReply());
  state_manager_.SetOperationFinished();
}

void PepperFileIOHost::ExecutePlatformOpenFileSystemURLCallback(
    ppapi::host::ReplyMessageContext reply_context,
    base::PlatformFileError error_code,
    base::PassPlatformFile file,
    quota::QuotaLimitType quota_policy,
    const PepperFileIOHost::NotifyCloseFileCallback& callback) {
  if (error_code == base::PLATFORM_FILE_OK)
    notify_close_file_callback_ = callback;
  quota_policy_ = quota_policy;
  ExecutePlatformOpenFileCallback(reply_context, error_code, file);
}

void PepperFileIOHost::ExecutePlatformQueryCallback(
    ppapi::host::ReplyMessageContext reply_context,
    base::PlatformFileError error_code,
    const base::PlatformFileInfo& file_info) {
  PP_FileInfo pp_info;
  ppapi::PlatformFileInfoToPepperFileInfo(file_info, file_system_type_,
                                          &pp_info);

  int32_t pp_error = ::ppapi::PlatformFileErrorToPepperError(error_code);
  reply_context.params.set_result(pp_error);
  host()->SendReply(reply_context,
                    PpapiPluginMsg_FileIO_QueryReply(pp_info));
  state_manager_.SetOperationFinished();
}

void PepperFileIOHost::ExecutePlatformReadCallback(
    ppapi::host::ReplyMessageContext reply_context,
    base::PlatformFileError error_code,
    const char* data, int bytes_read) {
  int32_t pp_error = ::ppapi::PlatformFileErrorToPepperError(error_code);

  // Only send the amount of data in the string that was actually read.
  std::string buffer;
  if (pp_error == PP_OK)
    buffer.append(data, bytes_read);
  reply_context.params.set_result(ErrorOrByteNumber(pp_error, bytes_read));
  host()->SendReply(reply_context, PpapiPluginMsg_FileIO_ReadReply(buffer));
  state_manager_.SetOperationFinished();
}

void PepperFileIOHost::ExecutePlatformWriteCallback(
    ppapi::host::ReplyMessageContext reply_context,
    base::PlatformFileError error_code,
    int bytes_written) {
  // On the plugin side, the callback expects a parameter with different meaning
  // depends on whether is negative or not. It is the result here. We translate
  // for the callback.
  int32_t pp_error = ::ppapi::PlatformFileErrorToPepperError(error_code);
  reply_context.params.set_result(ErrorOrByteNumber(pp_error, bytes_written));
  host()->SendReply(reply_context, PpapiPluginMsg_FileIO_GeneralReply());
  state_manager_.SetOperationFinished();
}

}  // namespace content
