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)
     24     : host_(host),
     25       path_(path),
     26       render_process_id_(render_process_id),
     27       weak_factory_(this) {
     28   task_runner_ =
     29       BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE);
     30 }
     31 
     32 PepperExternalFileRefBackend::~PepperExternalFileRefBackend() {}
     33 
     34 int32_t PepperExternalFileRefBackend::MakeDirectory(
     35     ppapi::host::ReplyMessageContext reply_context,
     36     int32_t make_directory_flags) {
     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(
     92       reply_context,
     93       PpapiPluginMsg_FileRef_GetAbsolutePathReply(path_.AsUTF8Unsafe()));
     94 
     95   // Use PP_OK_COMPLETIONPENDING instead of PP_OK since we've already sent our
     96   // reply above.
     97   return PP_OK_COMPLETIONPENDING;
     98 }
     99 
    100 fileapi::FileSystemURL PepperExternalFileRefBackend::GetFileSystemURL() const {
    101   return fileapi::FileSystemURL();
    102 }
    103 
    104 base::FilePath PepperExternalFileRefBackend::GetExternalFilePath() const {
    105   return path_;
    106 }
    107 
    108 int32_t PepperExternalFileRefBackend::CanRead() const {
    109   if (!ChildProcessSecurityPolicyImpl::GetInstance()->CanReadFile(
    110           render_process_id_, path_)) {
    111     return PP_ERROR_NOACCESS;
    112   }
    113   return PP_OK;
    114 }
    115 
    116 int32_t PepperExternalFileRefBackend::CanWrite() const {
    117   // Platform files have coarse-grained grants in ChildProcessSecurityPolicy.
    118   return CanReadWrite();
    119 }
    120 
    121 int32_t PepperExternalFileRefBackend::CanCreate() const {
    122   // Platform files have coarse-grained grants in ChildProcessSecurityPolicy.
    123   return CanReadWrite();
    124 }
    125 
    126 int32_t PepperExternalFileRefBackend::CanReadWrite() const {
    127   if (!ChildProcessSecurityPolicyImpl::GetInstance()->CanCreateReadWriteFile(
    128           render_process_id_, path_)) {
    129     return PP_ERROR_NOACCESS;
    130   }
    131   return PP_OK;
    132 }
    133 
    134 void PepperExternalFileRefBackend::DidFinish(
    135     ppapi::host::ReplyMessageContext reply_context,
    136     const IPC::Message& msg,
    137     base::File::Error error) {
    138   reply_context.params.set_result(ppapi::FileErrorToPepperError(error));
    139   host_->SendReply(reply_context, msg);
    140 }
    141 
    142 void PepperExternalFileRefBackend::GetMetadataComplete(
    143     ppapi::host::ReplyMessageContext reply_context,
    144     const base::File::Error error,
    145     const base::File::Info& file_info) {
    146   reply_context.params.set_result(ppapi::FileErrorToPepperError(error));
    147 
    148   PP_FileInfo pp_file_info;
    149   if (error == base::File::FILE_OK) {
    150     ppapi::FileInfoToPepperFileInfo(
    151         file_info, PP_FILESYSTEMTYPE_EXTERNAL, &pp_file_info);
    152   } else {
    153     memset(&pp_file_info, 0, sizeof(pp_file_info));
    154   }
    155 
    156   host_->SendReply(reply_context,
    157                    PpapiPluginMsg_FileRef_QueryReply(pp_file_info));
    158 }
    159 
    160 }  // namespace content
    161