| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "content/renderer/pepper/pepper_file_io_host.h" | 5 #include "content/renderer/pepper/pepper_file_io_host.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/callback.h" | 8 #include "base/callback.h" |
| 9 #include "base/callback_helpers.h" | 9 #include "base/callback_helpers.h" |
| 10 #include "base/command_line.h" | 10 #include "base/command_line.h" |
| 11 #include "base/files/file_util_proxy.h" | 11 #include "base/files/file_util_proxy.h" |
| 12 #include "content/child/child_thread.h" | 12 #include "content/child/child_thread.h" |
| 13 #include "content/child/fileapi/file_system_dispatcher.h" | 13 #include "content/child/fileapi/file_system_dispatcher.h" |
| 14 #include "content/child/quota_dispatcher.h" | 14 #include "content/child/quota_dispatcher.h" |
| 15 #include "content/common/fileapi/file_system_messages.h" | 15 #include "content/common/fileapi/file_system_messages.h" |
| 16 #include "content/common/view_messages.h" | 16 #include "content/common/view_messages.h" |
| 17 #include "content/public/common/content_client.h" | 17 #include "content/public/common/content_client.h" |
| 18 #include "content/public/renderer/content_renderer_client.h" | 18 #include "content/public/renderer/content_renderer_client.h" |
| 19 #include "content/renderer/pepper/host_globals.h" | 19 #include "content/renderer/pepper/host_globals.h" |
| 20 #include "content/renderer/pepper/pepper_browser_connection.h" | |
| 21 #include "content/renderer/pepper/pepper_plugin_instance_impl.h" | 20 #include "content/renderer/pepper/pepper_plugin_instance_impl.h" |
| 22 #include "content/renderer/pepper/plugin_module.h" | 21 #include "content/renderer/pepper/ppb_file_ref_impl.h" |
| 23 #include "content/renderer/pepper/quota_file_io.h" | 22 #include "content/renderer/pepper/quota_file_io.h" |
| 24 #include "content/renderer/pepper/renderer_ppapi_host_impl.h" | |
| 25 #include "content/renderer/render_thread_impl.h" | 23 #include "content/renderer/render_thread_impl.h" |
| 26 #include "ppapi/c/pp_errors.h" | 24 #include "ppapi/c/pp_errors.h" |
| 27 #include "ppapi/c/ppb_file_io.h" | 25 #include "ppapi/c/ppb_file_io.h" |
| 28 #include "ppapi/host/dispatch_host_message.h" | 26 #include "ppapi/host/dispatch_host_message.h" |
| 29 #include "ppapi/host/ppapi_host.h" | 27 #include "ppapi/host/ppapi_host.h" |
| 30 #include "ppapi/proxy/ppapi_messages.h" | 28 #include "ppapi/proxy/ppapi_messages.h" |
| 31 #include "ppapi/shared_impl/file_type_conversion.h" | 29 #include "ppapi/shared_impl/file_type_conversion.h" |
| 32 #include "ppapi/shared_impl/time_conversion.h" | 30 #include "ppapi/shared_impl/time_conversion.h" |
| 33 #include "ppapi/thunk/enter.h" | 31 #include "ppapi/thunk/enter.h" |
| 34 #include "third_party/WebKit/public/web/WebPluginContainer.h" | 32 #include "third_party/WebKit/public/web/WebPluginContainer.h" |
| 35 | 33 |
| 36 namespace content { | 34 namespace content { |
| 37 | 35 |
| 38 using ppapi::FileIOStateManager; | 36 using ppapi::FileIOStateManager; |
| 39 using ppapi::PPTimeToTime; | 37 using ppapi::PPTimeToTime; |
| 40 using ppapi::host::ReplyMessageContext; | 38 using ppapi::host::ReplyMessageContext; |
| 41 using ppapi::thunk::EnterResourceNoLock; | 39 using ppapi::thunk::EnterResourceNoLock; |
| 40 using ppapi::thunk::PPB_FileRef_API; |
| 42 | 41 |
| 43 namespace { | 42 namespace { |
| 44 | 43 |
| 45 typedef base::Callback<void (base::PlatformFileError)> PlatformGeneralCallback; | 44 typedef base::Callback<void (base::PlatformFileError)> PlatformGeneralCallback; |
| 46 | 45 |
| 47 int32_t ErrorOrByteNumber(int32_t pp_error, int32_t byte_number) { | 46 int32_t ErrorOrByteNumber(int32_t pp_error, int32_t byte_number) { |
| 48 // On the plugin side, some callbacks expect a parameter that means different | 47 // On the plugin side, some callbacks expect a parameter that means different |
| 49 // things depending on whether is negative or not. We translate for those | 48 // things depending on whether is negative or not. We translate for those |
| 50 // callbacks here. | 49 // callbacks here. |
| 51 return pp_error == PP_OK ? byte_number : pp_error; | 50 return pp_error == PP_OK ? byte_number : pp_error; |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 131 PepperFileIOHost::NotifyCloseFileCallback()); | 130 PepperFileIOHost::NotifyCloseFileCallback()); |
| 132 } | 131 } |
| 133 | 132 |
| 134 } // namespace | 133 } // namespace |
| 135 | 134 |
| 136 PepperFileIOHost::PepperFileIOHost(RendererPpapiHost* host, | 135 PepperFileIOHost::PepperFileIOHost(RendererPpapiHost* host, |
| 137 PP_Instance instance, | 136 PP_Instance instance, |
| 138 PP_Resource resource) | 137 PP_Resource resource) |
| 139 : ResourceHost(host->GetPpapiHost(), instance, resource), | 138 : ResourceHost(host->GetPpapiHost(), instance, resource), |
| 140 renderer_ppapi_host_(host), | 139 renderer_ppapi_host_(host), |
| 141 plugin_instance_(HostGlobals::Get()->GetInstance(instance)), | |
| 142 file_(base::kInvalidPlatformFileValue), | 140 file_(base::kInvalidPlatformFileValue), |
| 143 file_system_type_(PP_FILESYSTEMTYPE_INVALID), | 141 file_system_type_(PP_FILESYSTEMTYPE_INVALID), |
| 144 quota_policy_(quota::kQuotaLimitTypeUnknown), | 142 quota_policy_(quota::kQuotaLimitTypeUnknown), |
| 145 is_running_in_process_(host->IsRunningInProcess()), | 143 is_running_in_process_(host->IsRunningInProcess()), |
| 146 open_flags_(0), | 144 open_flags_(0), |
| 147 routing_id_(RenderThreadImpl::current()->GenerateRoutingID()), | 145 routing_id_(RenderThreadImpl::current()->GenerateRoutingID()), |
| 148 weak_factory_(this) { | 146 weak_factory_(this) { |
| 149 ChildThread::current()->AddRoute(routing_id_, this); | 147 ChildThread::current()->AddRoute(routing_id_, this); |
| 150 } | 148 } |
| 151 | 149 |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 224 | 222 |
| 225 // TODO(tommycli): Eventually just pass the Pepper flags straight to the | 223 // TODO(tommycli): Eventually just pass the Pepper flags straight to the |
| 226 // FileSystemDispatcher so it can handle doing the security check. | 224 // FileSystemDispatcher so it can handle doing the security check. |
| 227 int platform_file_flags = 0; | 225 int platform_file_flags = 0; |
| 228 open_flags_ = open_flags; | 226 open_flags_ = open_flags; |
| 229 if (!ppapi::PepperFileOpenFlagsToPlatformFileFlags(open_flags, | 227 if (!ppapi::PepperFileOpenFlagsToPlatformFileFlags(open_flags, |
| 230 &platform_file_flags)) { | 228 &platform_file_flags)) { |
| 231 return PP_ERROR_BADARGUMENT; | 229 return PP_ERROR_BADARGUMENT; |
| 232 } | 230 } |
| 233 | 231 |
| 234 RenderView* render_view = | 232 EnterResourceNoLock<PPB_FileRef_API> enter(file_ref_resource, true); |
| 235 renderer_ppapi_host_->GetRenderViewForInstance(pp_instance()); | 233 if (enter.failed()) |
| 236 PepperBrowserConnection* browser_connection = | 234 return PP_ERROR_BADRESOURCE; |
| 237 PepperBrowserConnection::Get(render_view); | |
| 238 int child_process_id = plugin_instance_->module()->GetPluginChildId(); | |
| 239 | 235 |
| 240 // Explicitly set child_process_id to 0 if we're running in process. This is | 236 PPB_FileRef_API* file_ref_api = enter.object(); |
| 241 // necessary in the case where we're a host for a resource in "the trusted | 237 PP_FileSystemType type = file_ref_api->GetFileSystemType(); |
| 242 // NaCl plugin". In that case, we may have already done work for the | 238 if (type != PP_FILESYSTEMTYPE_LOCALPERSISTENT && |
| 243 // untrusted plugin, and the call above will give a non-zero | 239 type != PP_FILESYSTEMTYPE_LOCALTEMPORARY && |
| 244 // child_process_id. | 240 type != PP_FILESYSTEMTYPE_EXTERNAL && |
| 245 if (renderer_ppapi_host_->IsRunningInProcess()) | 241 type != PP_FILESYSTEMTYPE_ISOLATED) |
| 246 child_process_id = 0; | 242 return PP_ERROR_FAILED; |
| 243 file_system_type_ = type; |
| 247 | 244 |
| 248 std::vector<PP_Resource> resources; | 245 PPB_FileRef_Impl* file_ref = static_cast<PPB_FileRef_Impl*>(file_ref_api); |
| 249 resources.push_back(file_ref_resource); | 246 if (file_ref->HasValidFileSystem()) { |
| 250 browser_connection->SendBrowserFileRefGetInfo( | 247 file_system_url_ = file_ref->GetFileSystemURL(); |
| 251 child_process_id, | |
| 252 resources, | |
| 253 base::Bind(&PepperFileIOHost::DidGetFileRefInfo, | |
| 254 weak_factory_.GetWeakPtr(), | |
| 255 context->MakeReplyMessageContext(), | |
| 256 platform_file_flags)); | |
| 257 state_manager_.SetPendingOperation(FileIOStateManager::OPERATION_EXCLUSIVE); | |
| 258 return PP_OK_COMPLETIONPENDING; | |
| 259 } | |
| 260 | 248 |
| 261 void PepperFileIOHost::DidGetFileRefInfo( | |
| 262 ppapi::host::ReplyMessageContext reply_context, | |
| 263 int platform_file_flags, | |
| 264 const std::vector<ppapi::FileRefDetailedInfo>& infos) { | |
| 265 if (infos.size() != 1) { | |
| 266 reply_context.params.set_result(PP_ERROR_FAILED); | |
| 267 host()->SendReply(reply_context, | |
| 268 PpapiPluginMsg_FileIO_OpenReply()); | |
| 269 return; | |
| 270 } | |
| 271 | |
| 272 file_system_type_ = infos[0].file_system_type; | |
| 273 if (file_system_type_ != PP_FILESYSTEMTYPE_EXTERNAL) { | |
| 274 file_system_url_ = GURL(infos[0].file_system_url_spec); | |
| 275 FileSystemDispatcher* file_system_dispatcher = | 249 FileSystemDispatcher* file_system_dispatcher = |
| 276 ChildThread::current()->file_system_dispatcher(); | 250 ChildThread::current()->file_system_dispatcher(); |
| 277 | |
| 278 AsyncOpenFileSystemURLCallback callback = base::Bind( | 251 AsyncOpenFileSystemURLCallback callback = base::Bind( |
| 279 &PepperFileIOHost::ExecutePlatformOpenFileSystemURLCallback, | 252 &PepperFileIOHost::ExecutePlatformOpenFileSystemURLCallback, |
| 280 weak_factory_.GetWeakPtr(), | 253 weak_factory_.GetWeakPtr(), |
| 281 reply_context); | 254 context->MakeReplyMessageContext()); |
| 282 file_system_dispatcher->OpenFile( | 255 file_system_dispatcher->OpenFile( |
| 283 file_system_url_, platform_file_flags, | 256 file_system_url_, platform_file_flags, |
| 284 base::Bind(&DidOpenFileSystemURL, callback), | 257 base::Bind(&DidOpenFileSystemURL, callback), |
| 285 base::Bind(&DidFailOpenFileSystemURL, callback)); | 258 base::Bind(&DidFailOpenFileSystemURL, callback)); |
| 286 } else { | 259 } else { |
| 260 if (file_system_type_ != PP_FILESYSTEMTYPE_EXTERNAL) |
| 261 return PP_ERROR_FAILED; |
| 287 int message_id = pending_async_open_files_.Add(new AsyncOpenFileCallback( | 262 int message_id = pending_async_open_files_.Add(new AsyncOpenFileCallback( |
| 288 base::Bind(&PepperFileIOHost::ExecutePlatformOpenFileCallback, | 263 base::Bind(&PepperFileIOHost::ExecutePlatformOpenFileCallback, |
| 289 weak_factory_.GetWeakPtr(), | 264 weak_factory_.GetWeakPtr(), |
| 290 reply_context))); | 265 context->MakeReplyMessageContext()))); |
| 291 RenderThreadImpl::current()->Send(new ViewHostMsg_AsyncOpenPepperFile( | 266 RenderThreadImpl::current()->Send(new ViewHostMsg_AsyncOpenPepperFile( |
| 292 routing_id_, infos[0].external_path, open_flags_, message_id)); | 267 routing_id_, file_ref->GetSystemPath(), open_flags, message_id)); |
| 293 } | 268 } |
| 269 |
| 270 state_manager_.SetPendingOperation(FileIOStateManager::OPERATION_EXCLUSIVE); |
| 271 return PP_OK_COMPLETIONPENDING; |
| 294 } | 272 } |
| 295 | 273 |
| 296 int32_t PepperFileIOHost::OnHostMsgTouch( | 274 int32_t PepperFileIOHost::OnHostMsgTouch( |
| 297 ppapi::host::HostMessageContext* context, | 275 ppapi::host::HostMessageContext* context, |
| 298 PP_Time last_access_time, | 276 PP_Time last_access_time, |
| 299 PP_Time last_modified_time) { | 277 PP_Time last_modified_time) { |
| 300 int32_t rv = state_manager_.CheckOperationState( | 278 int32_t rv = state_manager_.CheckOperationState( |
| 301 FileIOStateManager::OPERATION_EXCLUSIVE, true); | 279 FileIOStateManager::OPERATION_EXCLUSIVE, true); |
| 302 if (rv != PP_OK) | 280 if (rv != PP_OK) |
| 303 return rv; | 281 return rv; |
| (...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 586 // On the plugin side, the callback expects a parameter with different meaning | 564 // On the plugin side, the callback expects a parameter with different meaning |
| 587 // depends on whether is negative or not. It is the result here. We translate | 565 // depends on whether is negative or not. It is the result here. We translate |
| 588 // for the callback. | 566 // for the callback. |
| 589 int32_t pp_error = ppapi::PlatformFileErrorToPepperError(error_code); | 567 int32_t pp_error = ppapi::PlatformFileErrorToPepperError(error_code); |
| 590 reply_context.params.set_result(ErrorOrByteNumber(pp_error, bytes_written)); | 568 reply_context.params.set_result(ErrorOrByteNumber(pp_error, bytes_written)); |
| 591 host()->SendReply(reply_context, PpapiPluginMsg_FileIO_GeneralReply()); | 569 host()->SendReply(reply_context, PpapiPluginMsg_FileIO_GeneralReply()); |
| 592 state_manager_.SetOperationFinished(); | 570 state_manager_.SetOperationFinished(); |
| 593 } | 571 } |
| 594 | 572 |
| 595 } // namespace content | 573 } // namespace content |
| OLD | NEW |