Home | History | Annotate | Download | only in pepper
      1 // Copyright 2013 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "content/browser/renderer_host/pepper/pepper_external_file_ref_backend.h"
      6 
      7 #include "base/files/file_path.h"
      8 #include "base/files/file_util_proxy.h"
      9 #include "content/browser/child_process_security_policy_impl.h"
     10 #include "content/public/browser/browser_thread.h"
     11 #include "ppapi/c/pp_errors.h"
     12 #include "ppapi/c/pp_time.h"
     13 #include "ppapi/host/ppapi_host.h"
     14 #include "ppapi/proxy/ppapi_messages.h"
     15 #include "ppapi/shared_impl/file_type_conversion.h"
     16 #include "ppapi/shared_impl/time_conversion.h"
     17 
     18 namespace content {
     19 
     20 PepperExternalFileRefBackend::PepperExternalFileRefBackend(
     21     ppapi::host::PpapiHost* host,
     22     int render_process_id,
     23     const base::FilePath& path) : host_(host),
     24                                   path_(path),
     25                                   render_process_id_(render_process_id),
     26                                   weak_factory_(this) {
     27   task_runner_ =
     28       BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE);
     29 }
     30 
     31 PepperExternalFileRefBackend::~PepperExternalFileRefBackend() {
     32 }
     33 
     34 int32_t PepperExternalFileRefBackend::MakeDirectory(
     35     ppapi::host::ReplyMessageContext reply_context,
     36     bool make_ancestors) {
     37   // This operation isn't supported for external filesystems.
     38   return PP_ERROR_NOACCESS;
     39 }
     40 
     41 int32_t PepperExternalFileRefBackend::Touch(
     42     ppapi::host::ReplyMessageContext reply_context,
     43     PP_Time last_access_time,
     44     PP_Time last_modified_time) {
     45   IPC::Message reply_msg = PpapiPluginMsg_FileRef_TouchReply();
     46   base::FileUtilProxy::Touch(
     47       task_runner_.get(),
     48       path_,
     49       ppapi::PPTimeToTime(last_access_time),
     50       ppapi::PPTimeToTime(last_modified_time),
     51       base::Bind(&PepperExternalFileRefBackend::DidFinish,
     52                  weak_factory_.GetWeakPtr(),
     53                  reply_context,
     54                  reply_msg));
     55   return PP_OK_COMPLETIONPENDING;
     56 }
     57 
     58 int32_t PepperExternalFileRefBackend::Delete(
     59     ppapi::host::ReplyMessageContext reply_context) {
     60   // This operation isn't supported for external filesystems.
     61   return PP_ERROR_NOACCESS;
     62 }
     63 
     64 int32_t PepperExternalFileRefBackend::Rename(
     65     ppapi::host::ReplyMessageContext reply_context,
     66     PepperFileRefHost* new_file_ref) {
     67   // This operation isn't supported for external filesystems.
     68   return PP_ERROR_NOACCESS;
     69 }
     70 
     71 int32_t PepperExternalFileRefBackend::Query(
     72     ppapi::host::ReplyMessageContext reply_context) {
     73   bool ok = base::FileUtilProxy::GetFileInfo(
     74       task_runner_.get(),
     75       path_,
     76       base::Bind(&PepperExternalFileRefBackend::GetMetadataComplete,
     77                  weak_factory_.GetWeakPtr(),
     78                  reply_context));
     79   DCHECK(ok);
     80   return PP_OK_COMPLETIONPENDING;
     81 }
     82 
     83 int32_t PepperExternalFileRefBackend::ReadDirectoryEntries(
     84     ppapi::host::ReplyMessageContext context) {
     85   // This operation isn't supported for external filesystems.
     86   return PP_ERROR_NOACCESS;
     87 }
     88 
     89 int32_t PepperExternalFileRefBackend::GetAbsolutePath(
     90     ppapi::host::ReplyMessageContext reply_context) {
     91   host_->SendReply(reply_context,
     92       PpapiPluginMsg_FileRef_GetAbsolutePathReply(path_.AsUTF8Unsafe()));
     93   return PP_OK;
     94 }
     95 
     96 fileapi::FileSystemURL PepperExternalFileRefBackend::GetFileSystemURL() const {
     97   return fileapi::FileSystemURL();
     98 }
     99 
    100 std::string PepperExternalFileRefBackend::GetFileSystemURLSpec() const {
    101   return std::string();
    102 }
    103 
    104 base::FilePath PepperExternalFileRefBackend::GetExternalPath() const {
    105   return path_;
    106 }
    107 
    108 int32_t PepperExternalFileRefBackend::CanRead() const {
    109   if (!ChildProcessSecurityPolicyImpl::GetInstance()->
    110           CanReadFile(render_process_id_, path_)) {
    111     return PP_ERROR_NOACCESS;
    112   }
    113   return PP_OK;
    114 }
    115 
    116 int32_t PepperExternalFileRefBackend::CanWrite() const {
    117   if (!ChildProcessSecurityPolicyImpl::GetInstance()->
    118           CanWriteFile(render_process_id_, path_)) {
    119     return PP_ERROR_NOACCESS;
    120   }
    121   return PP_OK;
    122 }
    123 
    124 int32_t PepperExternalFileRefBackend::CanCreate() const {
    125   if (!ChildProcessSecurityPolicyImpl::GetInstance()->
    126           CanCreateFile(render_process_id_, path_)) {
    127     return PP_ERROR_NOACCESS;
    128   }
    129   return PP_OK;
    130 }
    131 
    132 int32_t PepperExternalFileRefBackend::CanReadWrite() const {
    133   ChildProcessSecurityPolicyImpl* policy =
    134         ChildProcessSecurityPolicyImpl::GetInstance();
    135   if (!policy->CanReadFile(render_process_id_, path_) ||
    136       !policy->CanWriteFile(render_process_id_, path_)) {
    137     return PP_ERROR_NOACCESS;
    138   }
    139   return PP_OK;
    140 }
    141 
    142 void PepperExternalFileRefBackend::DidFinish(
    143     ppapi::host::ReplyMessageContext reply_context,
    144     const IPC::Message& msg,
    145     base::PlatformFileError error) {
    146   reply_context.params.set_result(ppapi::PlatformFileErrorToPepperError(error));
    147   host_->SendReply(reply_context, msg);
    148 }
    149 
    150 void PepperExternalFileRefBackend::GetMetadataComplete(
    151     ppapi::host::ReplyMessageContext reply_context,
    152     const base::PlatformFileError error,
    153     const base::PlatformFileInfo& file_info) {
    154   reply_context.params.set_result(ppapi::PlatformFileErrorToPepperError(error));
    155 
    156   PP_FileInfo pp_file_info;
    157   if (error == base::PLATFORM_FILE_OK) {
    158     ppapi::PlatformFileInfoToPepperFileInfo(
    159         file_info, PP_FILESYSTEMTYPE_EXTERNAL, &pp_file_info);
    160   } else {
    161     memset(&pp_file_info, 0, sizeof(pp_file_info));
    162   }
    163 
    164   host_->SendReply(reply_context,
    165                    PpapiPluginMsg_FileRef_QueryReply(pp_file_info));
    166 }
    167 
    168 }  // namespace content
    169