| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 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/browser/renderer_host/pepper/pepper_file_io_host.h" | 5 #include "content/browser/renderer_host/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/files/file_util_proxy.h" | 10 #include "base/files/file_util_proxy.h" |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 79 } | 79 } |
| 80 | 80 |
| 81 } // namespace | 81 } // namespace |
| 82 | 82 |
| 83 PepperFileIOHost::PepperFileIOHost(BrowserPpapiHostImpl* host, | 83 PepperFileIOHost::PepperFileIOHost(BrowserPpapiHostImpl* host, |
| 84 PP_Instance instance, | 84 PP_Instance instance, |
| 85 PP_Resource resource) | 85 PP_Resource resource) |
| 86 : ResourceHost(host->GetPpapiHost(), instance, resource), | 86 : ResourceHost(host->GetPpapiHost(), instance, resource), |
| 87 browser_ppapi_host_(host), | 87 browser_ppapi_host_(host), |
| 88 render_process_host_(NULL), | 88 render_process_host_(NULL), |
| 89 file_(base::kInvalidPlatformFileValue), | 89 file_(BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE)), |
| 90 open_flags_(0), | 90 open_flags_(0), |
| 91 file_system_type_(PP_FILESYSTEMTYPE_INVALID), | 91 file_system_type_(PP_FILESYSTEMTYPE_INVALID), |
| 92 max_written_offset_(0), | 92 max_written_offset_(0), |
| 93 check_quota_(false), | 93 check_quota_(false), |
| 94 weak_factory_(this) { | 94 weak_factory_(this) { |
| 95 int unused; | 95 int unused; |
| 96 if (!host->GetRenderFrameIDsForInstance( | 96 if (!host->GetRenderFrameIDsForInstance( |
| 97 instance, &render_process_id_, &unused)) { | 97 instance, &render_process_id_, &unused)) { |
| 98 render_process_id_ = -1; | 98 render_process_id_ = -1; |
| 99 } | 99 } |
| 100 file_message_loop_ = | |
| 101 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE); | |
| 102 } | 100 } |
| 103 | 101 |
| 104 PepperFileIOHost::~PepperFileIOHost() {} | 102 PepperFileIOHost::~PepperFileIOHost() {} |
| 105 | 103 |
| 106 int32_t PepperFileIOHost::OnResourceMessageReceived( | 104 int32_t PepperFileIOHost::OnResourceMessageReceived( |
| 107 const IPC::Message& msg, | 105 const IPC::Message& msg, |
| 108 ppapi::host::HostMessageContext* context) { | 106 ppapi::host::HostMessageContext* context) { |
| 109 PPAPI_BEGIN_MESSAGE_MAP(PepperFileIOHost, msg) | 107 PPAPI_BEGIN_MESSAGE_MAP(PepperFileIOHost, msg) |
| 110 PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_FileIO_Open, OnHostMsgOpen) | 108 PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_FileIO_Open, OnHostMsgOpen) |
| 111 PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_FileIO_Touch, OnHostMsgTouch) | 109 PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_FileIO_Touch, OnHostMsgTouch) |
| (...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 258 } | 256 } |
| 259 } | 257 } |
| 260 | 258 |
| 261 ExecutePlatformOpenFileCallback( | 259 ExecutePlatformOpenFileCallback( |
| 262 reply_context, result, base::PassPlatformFile(&file), true); | 260 reply_context, result, base::PassPlatformFile(&file), true); |
| 263 } | 261 } |
| 264 | 262 |
| 265 void PepperFileIOHost::GotResolvedRenderProcessId( | 263 void PepperFileIOHost::GotResolvedRenderProcessId( |
| 266 ppapi::host::ReplyMessageContext reply_context, | 264 ppapi::host::ReplyMessageContext reply_context, |
| 267 base::FilePath path, | 265 base::FilePath path, |
| 268 int platform_file_flags, | 266 int file_flags, |
| 269 base::ProcessId resolved_render_process_id) { | 267 base::ProcessId resolved_render_process_id) { |
| 270 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 268 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 271 resolved_render_process_id_ = resolved_render_process_id; | 269 resolved_render_process_id_ = resolved_render_process_id; |
| 272 base::FileUtilProxy::CreateOrOpen( | 270 file_.CreateOrOpen( |
| 273 file_message_loop_, | |
| 274 path, | 271 path, |
| 275 platform_file_flags, | 272 file_flags, |
| 276 base::Bind(&PepperFileIOHost::ExecutePlatformOpenFileCallback, | 273 base::Bind(&PepperFileIOHost::OnOpenProxyCallback, |
| 277 weak_factory_.GetWeakPtr(), | 274 weak_factory_.GetWeakPtr(), |
| 278 reply_context)); | 275 reply_context)); |
| 279 } | 276 } |
| 280 | 277 |
| 281 int32_t PepperFileIOHost::OnHostMsgTouch( | 278 int32_t PepperFileIOHost::OnHostMsgTouch( |
| 282 ppapi::host::HostMessageContext* context, | 279 ppapi::host::HostMessageContext* context, |
| 283 PP_Time last_access_time, | 280 PP_Time last_access_time, |
| 284 PP_Time last_modified_time) { | 281 PP_Time last_modified_time) { |
| 285 int32_t rv = state_manager_.CheckOperationState( | 282 int32_t rv = state_manager_.CheckOperationState( |
| 286 FileIOStateManager::OPERATION_EXCLUSIVE, true); | 283 FileIOStateManager::OPERATION_EXCLUSIVE, true); |
| 287 if (rv != PP_OK) | 284 if (rv != PP_OK) |
| 288 return rv; | 285 return rv; |
| 289 | 286 |
| 290 if (!base::FileUtilProxy::Touch( | 287 if (!file_.SetTimes( |
| 291 file_message_loop_, | |
| 292 file_, | |
| 293 PPTimeToTime(last_access_time), | 288 PPTimeToTime(last_access_time), |
| 294 PPTimeToTime(last_modified_time), | 289 PPTimeToTime(last_modified_time), |
| 295 base::Bind(&PepperFileIOHost::ExecutePlatformGeneralCallback, | 290 base::Bind(&PepperFileIOHost::ExecutePlatformGeneralCallback, |
| 296 weak_factory_.GetWeakPtr(), | 291 weak_factory_.GetWeakPtr(), |
| 297 context->MakeReplyMessageContext()))) | 292 context->MakeReplyMessageContext()))) { |
| 298 return PP_ERROR_FAILED; | 293 return PP_ERROR_FAILED; |
| 294 } |
| 299 | 295 |
| 300 state_manager_.SetPendingOperation(FileIOStateManager::OPERATION_EXCLUSIVE); | 296 state_manager_.SetPendingOperation(FileIOStateManager::OPERATION_EXCLUSIVE); |
| 301 return PP_OK_COMPLETIONPENDING; | 297 return PP_OK_COMPLETIONPENDING; |
| 302 } | 298 } |
| 303 | 299 |
| 304 int32_t PepperFileIOHost::OnHostMsgSetLength( | 300 int32_t PepperFileIOHost::OnHostMsgSetLength( |
| 305 ppapi::host::HostMessageContext* context, | 301 ppapi::host::HostMessageContext* context, |
| 306 int64_t length) { | 302 int64_t length) { |
| 307 int32_t rv = state_manager_.CheckOperationState( | 303 int32_t rv = state_manager_.CheckOperationState( |
| 308 FileIOStateManager::OPERATION_EXCLUSIVE, true); | 304 FileIOStateManager::OPERATION_EXCLUSIVE, true); |
| 309 if (rv != PP_OK) | 305 if (rv != PP_OK) |
| 310 return rv; | 306 return rv; |
| 311 if (length < 0) | 307 if (length < 0) |
| 312 return PP_ERROR_BADARGUMENT; | 308 return PP_ERROR_BADARGUMENT; |
| 313 | 309 |
| 314 // Quota checks are performed on the plugin side, in order to use the same | 310 // Quota checks are performed on the plugin side, in order to use the same |
| 315 // quota reservation and request system as Write. | 311 // quota reservation and request system as Write. |
| 316 | 312 |
| 317 if (!base::FileUtilProxy::Truncate( | 313 if (!file_.SetLength( |
| 318 file_message_loop_, | |
| 319 file_, | |
| 320 length, | 314 length, |
| 321 base::Bind(&PepperFileIOHost::ExecutePlatformGeneralCallback, | 315 base::Bind(&PepperFileIOHost::ExecutePlatformGeneralCallback, |
| 322 weak_factory_.GetWeakPtr(), | 316 weak_factory_.GetWeakPtr(), |
| 323 context->MakeReplyMessageContext()))) | 317 context->MakeReplyMessageContext()))) { |
| 324 return PP_ERROR_FAILED; | 318 return PP_ERROR_FAILED; |
| 319 } |
| 325 | 320 |
| 326 state_manager_.SetPendingOperation(FileIOStateManager::OPERATION_EXCLUSIVE); | 321 state_manager_.SetPendingOperation(FileIOStateManager::OPERATION_EXCLUSIVE); |
| 327 return PP_OK_COMPLETIONPENDING; | 322 return PP_OK_COMPLETIONPENDING; |
| 328 } | 323 } |
| 329 | 324 |
| 330 int32_t PepperFileIOHost::OnHostMsgFlush( | 325 int32_t PepperFileIOHost::OnHostMsgFlush( |
| 331 ppapi::host::HostMessageContext* context) { | 326 ppapi::host::HostMessageContext* context) { |
| 332 int32_t rv = state_manager_.CheckOperationState( | 327 int32_t rv = state_manager_.CheckOperationState( |
| 333 FileIOStateManager::OPERATION_EXCLUSIVE, true); | 328 FileIOStateManager::OPERATION_EXCLUSIVE, true); |
| 334 if (rv != PP_OK) | 329 if (rv != PP_OK) |
| 335 return rv; | 330 return rv; |
| 336 | 331 |
| 337 if (!base::FileUtilProxy::Flush( | 332 if (!file_.Flush( |
| 338 file_message_loop_, | |
| 339 file_, | |
| 340 base::Bind(&PepperFileIOHost::ExecutePlatformGeneralCallback, | 333 base::Bind(&PepperFileIOHost::ExecutePlatformGeneralCallback, |
| 341 weak_factory_.GetWeakPtr(), | 334 weak_factory_.GetWeakPtr(), |
| 342 context->MakeReplyMessageContext()))) | 335 context->MakeReplyMessageContext()))) { |
| 343 return PP_ERROR_FAILED; | 336 return PP_ERROR_FAILED; |
| 337 } |
| 344 | 338 |
| 345 state_manager_.SetPendingOperation(FileIOStateManager::OPERATION_EXCLUSIVE); | 339 state_manager_.SetPendingOperation(FileIOStateManager::OPERATION_EXCLUSIVE); |
| 346 return PP_OK_COMPLETIONPENDING; | 340 return PP_OK_COMPLETIONPENDING; |
| 347 } | 341 } |
| 348 | 342 |
| 349 int32_t PepperFileIOHost::OnHostMsgClose( | 343 int32_t PepperFileIOHost::OnHostMsgClose( |
| 350 ppapi::host::HostMessageContext* context, | 344 ppapi::host::HostMessageContext* context, |
| 351 const ppapi::FileGrowth& file_growth) { | 345 const ppapi::FileGrowth& file_growth) { |
| 352 if (check_quota_) { | 346 if (check_quota_) { |
| 353 file_system_host_->CloseQuotaFile(this, file_growth); | 347 file_system_host_->CloseQuotaFile(this, file_growth); |
| 354 check_quota_ = false; | 348 check_quota_ = false; |
| 355 } | 349 } |
| 356 | 350 |
| 357 if (file_ != base::kInvalidPlatformFileValue) { | 351 if (file_.IsValid()) { |
| 358 base::FileUtilProxy::Close(file_message_loop_, | 352 file_.Close(base::Bind(&PepperFileIOHost::DidCloseFile, |
| 359 file_, | 353 weak_factory_.GetWeakPtr())); |
| 360 base::Bind(&PepperFileIOHost::DidCloseFile, | |
| 361 weak_factory_.GetWeakPtr())); | |
| 362 file_ = base::kInvalidPlatformFileValue; | |
| 363 } | 354 } |
| 364 return PP_OK; | 355 return PP_OK; |
| 365 } | 356 } |
| 366 | 357 |
| 367 void PepperFileIOHost::DidOpenQuotaFile( | 358 void PepperFileIOHost::DidOpenQuotaFile( |
| 368 ppapi::host::ReplyMessageContext reply_context, | 359 ppapi::host::ReplyMessageContext reply_context, |
| 369 base::PlatformFile file, | 360 base::PlatformFile file, |
| 370 int64_t max_written_offset) { | 361 int64_t max_written_offset) { |
| 371 max_written_offset_ = max_written_offset; | 362 max_written_offset_ = max_written_offset; |
| 372 | 363 |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 418 } | 409 } |
| 419 | 410 |
| 420 void PepperFileIOHost::ExecutePlatformGeneralCallback( | 411 void PepperFileIOHost::ExecutePlatformGeneralCallback( |
| 421 ppapi::host::ReplyMessageContext reply_context, | 412 ppapi::host::ReplyMessageContext reply_context, |
| 422 base::File::Error error_code) { | 413 base::File::Error error_code) { |
| 423 reply_context.params.set_result(ppapi::FileErrorToPepperError(error_code)); | 414 reply_context.params.set_result(ppapi::FileErrorToPepperError(error_code)); |
| 424 host()->SendReply(reply_context, PpapiPluginMsg_FileIO_GeneralReply()); | 415 host()->SendReply(reply_context, PpapiPluginMsg_FileIO_GeneralReply()); |
| 425 state_manager_.SetOperationFinished(); | 416 state_manager_.SetOperationFinished(); |
| 426 } | 417 } |
| 427 | 418 |
| 419 // TODO(rvargas): this method should go away when FileApi moves to use File. |
| 428 void PepperFileIOHost::ExecutePlatformOpenFileCallback( | 420 void PepperFileIOHost::ExecutePlatformOpenFileCallback( |
| 429 ppapi::host::ReplyMessageContext reply_context, | 421 ppapi::host::ReplyMessageContext reply_context, |
| 430 base::File::Error error_code, | 422 base::File::Error error_code, |
| 431 base::PassPlatformFile file, | 423 base::PassPlatformFile file, |
| 432 bool unused_created) { | 424 bool unused_created) { |
| 425 DCHECK(!file_.IsValid()); |
| 426 file_.SetFile(base::File(file.ReleaseValue())); |
| 427 |
| 428 OnOpenProxyCallback(reply_context, error_code); |
| 429 } |
| 430 |
| 431 void PepperFileIOHost::OnOpenProxyCallback( |
| 432 ppapi::host::ReplyMessageContext reply_context, |
| 433 base::File::Error error_code) { |
| 433 int32_t pp_error = ppapi::FileErrorToPepperError(error_code); | 434 int32_t pp_error = ppapi::FileErrorToPepperError(error_code); |
| 434 DCHECK(file_ == base::kInvalidPlatformFileValue); | 435 if (file_.IsValid() && !AddFileToReplyContext(open_flags_, &reply_context)) |
| 435 file_ = file.ReleaseValue(); | |
| 436 | |
| 437 if (file_ != base::kInvalidPlatformFileValue && | |
| 438 !AddFileToReplyContext(open_flags_, &reply_context)) | |
| 439 pp_error = PP_ERROR_FAILED; | 436 pp_error = PP_ERROR_FAILED; |
| 440 | 437 |
| 441 PP_Resource quota_file_system = 0; | 438 PP_Resource quota_file_system = 0; |
| 442 if (pp_error == PP_OK) { | 439 if (pp_error == PP_OK) { |
| 443 state_manager_.SetOpenSucceed(); | 440 state_manager_.SetOpenSucceed(); |
| 444 // A non-zero resource id signals the plugin side to check quota. | 441 // A non-zero resource id signals the plugin side to check quota. |
| 445 if (check_quota_) | 442 if (check_quota_) |
| 446 quota_file_system = file_system_host_->pp_resource(); | 443 quota_file_system = file_system_host_->pp_resource(); |
| 447 } | 444 } |
| 448 | 445 |
| (...skipping 11 matching lines...) Expand all Loading... |
| 460 | 457 |
| 461 bool PepperFileIOHost::AddFileToReplyContext( | 458 bool PepperFileIOHost::AddFileToReplyContext( |
| 462 int32_t open_flags, | 459 int32_t open_flags, |
| 463 ppapi::host::ReplyMessageContext* reply_context) const { | 460 ppapi::host::ReplyMessageContext* reply_context) const { |
| 464 base::ProcessId plugin_process_id = | 461 base::ProcessId plugin_process_id = |
| 465 base::GetProcId(browser_ppapi_host_->GetPluginProcessHandle()); | 462 base::GetProcId(browser_ppapi_host_->GetPluginProcessHandle()); |
| 466 if (plugin_process_id == base::kNullProcessId) | 463 if (plugin_process_id == base::kNullProcessId) |
| 467 plugin_process_id = resolved_render_process_id_; | 464 plugin_process_id = resolved_render_process_id_; |
| 468 | 465 |
| 469 IPC::PlatformFileForTransit transit_file = | 466 IPC::PlatformFileForTransit transit_file = |
| 470 BrokerGetFileHandleForProcess(file_, plugin_process_id, false); | 467 BrokerGetFileHandleForProcess(file_.GetPlatformFile(), plugin_process_id, |
| 468 false); |
| 471 if (transit_file == IPC::InvalidPlatformFileForTransit()) | 469 if (transit_file == IPC::InvalidPlatformFileForTransit()) |
| 472 return false; | 470 return false; |
| 473 | 471 |
| 474 ppapi::proxy::SerializedHandle file_handle; | 472 ppapi::proxy::SerializedHandle file_handle; |
| 475 // A non-zero resource id signals NaClIPCAdapter to create a NaClQuotaDesc. | 473 // A non-zero resource id signals NaClIPCAdapter to create a NaClQuotaDesc. |
| 476 PP_Resource quota_file_io = check_quota_ ? pp_resource() : 0; | 474 PP_Resource quota_file_io = check_quota_ ? pp_resource() : 0; |
| 477 file_handle.set_file_handle(transit_file, open_flags, quota_file_io); | 475 file_handle.set_file_handle(transit_file, open_flags, quota_file_io); |
| 478 reply_context->params.AppendHandle(file_handle); | 476 reply_context->params.AppendHandle(file_handle); |
| 479 return true; | 477 return true; |
| 480 } | 478 } |
| 481 | 479 |
| 482 } // namespace content | 480 } // namespace content |
| OLD | NEW |