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