blob: 096b908266f594e89177742608b5dded11a00047 [file] [log] [blame]
// Copyright 2013 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/browser/renderer_host/pepper/pepper_external_file_ref_backend.h"
#include "base/files/file_path.h"
#include "base/files/file_util_proxy.h"
#include "content/browser/child_process_security_policy_impl.h"
#include "content/public/browser/browser_thread.h"
#include "ppapi/c/pp_errors.h"
#include "ppapi/c/pp_time.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"
namespace content {
PepperExternalFileRefBackend::PepperExternalFileRefBackend(
ppapi::host::PpapiHost* host,
int render_process_id,
const base::FilePath& path) : host_(host),
path_(path),
render_process_id_(render_process_id),
weak_factory_(this) {
task_runner_ =
BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE);
}
PepperExternalFileRefBackend::~PepperExternalFileRefBackend() {
}
int32_t PepperExternalFileRefBackend::MakeDirectory(
ppapi::host::ReplyMessageContext reply_context,
bool make_ancestors) {
// This operation isn't supported for external filesystems.
return PP_ERROR_NOACCESS;
}
int32_t PepperExternalFileRefBackend::Touch(
ppapi::host::ReplyMessageContext reply_context,
PP_Time last_access_time,
PP_Time last_modified_time) {
IPC::Message reply_msg = PpapiPluginMsg_FileRef_TouchReply();
base::FileUtilProxy::Touch(
task_runner_.get(),
path_,
ppapi::PPTimeToTime(last_access_time),
ppapi::PPTimeToTime(last_modified_time),
base::Bind(&PepperExternalFileRefBackend::DidFinish,
weak_factory_.GetWeakPtr(),
reply_context,
reply_msg));
return PP_OK_COMPLETIONPENDING;
}
int32_t PepperExternalFileRefBackend::Delete(
ppapi::host::ReplyMessageContext reply_context) {
// This operation isn't supported for external filesystems.
return PP_ERROR_NOACCESS;
}
int32_t PepperExternalFileRefBackend::Rename(
ppapi::host::ReplyMessageContext reply_context,
PepperFileRefHost* new_file_ref) {
// This operation isn't supported for external filesystems.
return PP_ERROR_NOACCESS;
}
int32_t PepperExternalFileRefBackend::Query(
ppapi::host::ReplyMessageContext reply_context) {
bool ok = base::FileUtilProxy::GetFileInfo(
task_runner_.get(),
path_,
base::Bind(&PepperExternalFileRefBackend::GetMetadataComplete,
weak_factory_.GetWeakPtr(),
reply_context));
DCHECK(ok);
return PP_OK_COMPLETIONPENDING;
}
int32_t PepperExternalFileRefBackend::ReadDirectoryEntries(
ppapi::host::ReplyMessageContext context) {
// This operation isn't supported for external filesystems.
return PP_ERROR_NOACCESS;
}
int32_t PepperExternalFileRefBackend::GetAbsolutePath(
ppapi::host::ReplyMessageContext reply_context) {
host_->SendReply(reply_context,
PpapiPluginMsg_FileRef_GetAbsolutePathReply(path_.AsUTF8Unsafe()));
// Use PP_OK_COMPLETIONPENDING instead of PP_OK since we've already sent our
// reply above.
return PP_OK_COMPLETIONPENDING;
}
fileapi::FileSystemURL PepperExternalFileRefBackend::GetFileSystemURL() const {
return fileapi::FileSystemURL();
}
int32_t PepperExternalFileRefBackend::CanRead() const {
if (!ChildProcessSecurityPolicyImpl::GetInstance()->
CanReadFile(render_process_id_, path_)) {
return PP_ERROR_NOACCESS;
}
return PP_OK;
}
int32_t PepperExternalFileRefBackend::CanWrite() const {
if (!ChildProcessSecurityPolicyImpl::GetInstance()->
CanWriteFile(render_process_id_, path_)) {
return PP_ERROR_NOACCESS;
}
return PP_OK;
}
int32_t PepperExternalFileRefBackend::CanCreate() const {
if (!ChildProcessSecurityPolicyImpl::GetInstance()->
CanCreateFile(render_process_id_, path_)) {
return PP_ERROR_NOACCESS;
}
return PP_OK;
}
int32_t PepperExternalFileRefBackend::CanReadWrite() const {
ChildProcessSecurityPolicyImpl* policy =
ChildProcessSecurityPolicyImpl::GetInstance();
if (!policy->CanReadFile(render_process_id_, path_) ||
!policy->CanWriteFile(render_process_id_, path_)) {
return PP_ERROR_NOACCESS;
}
return PP_OK;
}
void PepperExternalFileRefBackend::DidFinish(
ppapi::host::ReplyMessageContext reply_context,
const IPC::Message& msg,
base::PlatformFileError error) {
reply_context.params.set_result(ppapi::PlatformFileErrorToPepperError(error));
host_->SendReply(reply_context, msg);
}
void PepperExternalFileRefBackend::GetMetadataComplete(
ppapi::host::ReplyMessageContext reply_context,
const base::PlatformFileError error,
const base::PlatformFileInfo& file_info) {
reply_context.params.set_result(ppapi::PlatformFileErrorToPepperError(error));
PP_FileInfo pp_file_info;
if (error == base::PLATFORM_FILE_OK) {
ppapi::PlatformFileInfoToPepperFileInfo(
file_info, PP_FILESYSTEMTYPE_EXTERNAL, &pp_file_info);
} else {
memset(&pp_file_info, 0, sizeof(pp_file_info));
}
host_->SendReply(reply_context,
PpapiPluginMsg_FileRef_QueryReply(pp_file_info));
}
} // namespace content