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