| 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 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 71 if (!host) | 71 if (!host) |
| 72 return false; | 72 return false; |
| 73 return client->IsPluginAllowedToCallRequestOSFileHandle( | 73 return client->IsPluginAllowedToCallRequestOSFileHandle( |
| 74 host->GetBrowserContext(), document_url); | 74 host->GetBrowserContext(), document_url); |
| 75 } | 75 } |
| 76 | 76 |
| 77 bool FileOpenForWrite(int32_t open_flags) { | 77 bool FileOpenForWrite(int32_t open_flags) { |
| 78 return (open_flags & (PP_FILEOPENFLAG_WRITE | PP_FILEOPENFLAG_APPEND)) != 0; | 78 return (open_flags & (PP_FILEOPENFLAG_WRITE | PP_FILEOPENFLAG_APPEND)) != 0; |
| 79 } | 79 } |
| 80 | 80 |
| 81 void FileCloser(base::File auto_close) { |
| 82 } |
| 83 |
| 84 void DidCloseFile(const base::Closure& on_close_callback) { |
| 85 if (!on_close_callback.is_null()) |
| 86 on_close_callback.Run(); |
| 87 } |
| 88 |
| 89 void DidOpenFile(base::WeakPtr<PepperFileIOHost> file_host, |
| 90 fileapi::FileSystemOperation::OpenFileCallback callback, |
| 91 base::File file, |
| 92 const base::Closure& on_close_callback) { |
| 93 if (file_host) { |
| 94 callback.Run(file.Pass(), on_close_callback); |
| 95 } else { |
| 96 BrowserThread::PostTaskAndReply( |
| 97 BrowserThread::FILE, |
| 98 FROM_HERE, |
| 99 base::Bind(&FileCloser, base::Passed(&file)), |
| 100 base::Bind(&DidCloseFile, on_close_callback)); |
| 101 } |
| 102 } |
| 103 |
| 81 } // namespace | 104 } // namespace |
| 82 | 105 |
| 83 PepperFileIOHost::PepperFileIOHost(BrowserPpapiHostImpl* host, | 106 PepperFileIOHost::PepperFileIOHost(BrowserPpapiHostImpl* host, |
| 84 PP_Instance instance, | 107 PP_Instance instance, |
| 85 PP_Resource resource) | 108 PP_Resource resource) |
| 86 : ResourceHost(host->GetPpapiHost(), instance, resource), | 109 : ResourceHost(host->GetPpapiHost(), instance, resource), |
| 87 browser_ppapi_host_(host), | 110 browser_ppapi_host_(host), |
| 88 render_process_host_(NULL), | 111 render_process_host_(NULL), |
| 89 file_(BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE)), | 112 file_(BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE)), |
| 90 open_flags_(0), | 113 open_flags_(0), |
| 91 file_system_type_(PP_FILESYSTEMTYPE_INVALID), | 114 file_system_type_(PP_FILESYSTEMTYPE_INVALID), |
| 92 max_written_offset_(0), | 115 max_written_offset_(0), |
| 93 check_quota_(false), | 116 check_quota_(false) { |
| 94 weak_factory_(this) { | |
| 95 int unused; | 117 int unused; |
| 96 if (!host->GetRenderFrameIDsForInstance( | 118 if (!host->GetRenderFrameIDsForInstance( |
| 97 instance, &render_process_id_, &unused)) { | 119 instance, &render_process_id_, &unused)) { |
| 98 render_process_id_ = -1; | 120 render_process_id_ = -1; |
| 99 } | 121 } |
| 100 } | 122 } |
| 101 | 123 |
| 102 PepperFileIOHost::~PepperFileIOHost() {} | 124 PepperFileIOHost::~PepperFileIOHost() {} |
| 103 | 125 |
| 104 int32_t PepperFileIOHost::OnResourceMessageReceived( | 126 int32_t PepperFileIOHost::OnResourceMessageReceived( |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 177 } | 199 } |
| 178 } | 200 } |
| 179 if (!CanOpenFileSystemURLWithPepperFlags( | 201 if (!CanOpenFileSystemURLWithPepperFlags( |
| 180 open_flags, render_process_id_, file_system_url_)) | 202 open_flags, render_process_id_, file_system_url_)) |
| 181 return PP_ERROR_NOACCESS; | 203 return PP_ERROR_NOACCESS; |
| 182 BrowserThread::PostTaskAndReplyWithResult( | 204 BrowserThread::PostTaskAndReplyWithResult( |
| 183 BrowserThread::UI, | 205 BrowserThread::UI, |
| 184 FROM_HERE, | 206 FROM_HERE, |
| 185 base::Bind(&GetUIThreadStuffForInternalFileSystems, render_process_id_), | 207 base::Bind(&GetUIThreadStuffForInternalFileSystems, render_process_id_), |
| 186 base::Bind(&PepperFileIOHost::GotUIThreadStuffForInternalFileSystems, | 208 base::Bind(&PepperFileIOHost::GotUIThreadStuffForInternalFileSystems, |
| 187 weak_factory_.GetWeakPtr(), | 209 AsWeakPtr(), |
| 188 context->MakeReplyMessageContext(), | 210 context->MakeReplyMessageContext(), |
| 189 platform_file_flags)); | 211 platform_file_flags)); |
| 190 } else { | 212 } else { |
| 191 base::FilePath path = file_ref_host->GetExternalFilePath(); | 213 base::FilePath path = file_ref_host->GetExternalFilePath(); |
| 192 if (!CanOpenWithPepperFlags(open_flags, render_process_id_, path)) | 214 if (!CanOpenWithPepperFlags(open_flags, render_process_id_, path)) |
| 193 return PP_ERROR_NOACCESS; | 215 return PP_ERROR_NOACCESS; |
| 194 BrowserThread::PostTaskAndReplyWithResult( | 216 BrowserThread::PostTaskAndReplyWithResult( |
| 195 BrowserThread::UI, | 217 BrowserThread::UI, |
| 196 FROM_HERE, | 218 FROM_HERE, |
| 197 base::Bind(&GetResolvedRenderProcessId, render_process_id_), | 219 base::Bind(&GetResolvedRenderProcessId, render_process_id_), |
| 198 base::Bind(&PepperFileIOHost::GotResolvedRenderProcessId, | 220 base::Bind(&PepperFileIOHost::GotResolvedRenderProcessId, |
| 199 weak_factory_.GetWeakPtr(), | 221 AsWeakPtr(), |
| 200 context->MakeReplyMessageContext(), | 222 context->MakeReplyMessageContext(), |
| 201 path, | 223 path, |
| 202 platform_file_flags)); | 224 platform_file_flags)); |
| 203 } | 225 } |
| 204 state_manager_.SetPendingOperation(FileIOStateManager::OPERATION_EXCLUSIVE); | 226 state_manager_.SetPendingOperation(FileIOStateManager::OPERATION_EXCLUSIVE); |
| 205 return PP_OK_COMPLETIONPENDING; | 227 return PP_OK_COMPLETIONPENDING; |
| 206 } | 228 } |
| 207 | 229 |
| 208 void PepperFileIOHost::GotUIThreadStuffForInternalFileSystems( | 230 void PepperFileIOHost::GotUIThreadStuffForInternalFileSystems( |
| 209 ppapi::host::ReplyMessageContext reply_context, | 231 ppapi::host::ReplyMessageContext reply_context, |
| (...skipping 10 matching lines...) Expand all Loading... |
| 220 } | 242 } |
| 221 | 243 |
| 222 if (!file_system_context_->GetFileSystemBackend(file_system_url_.type())) { | 244 if (!file_system_context_->GetFileSystemBackend(file_system_url_.type())) { |
| 223 reply_context.params.set_result(PP_ERROR_FAILED); | 245 reply_context.params.set_result(PP_ERROR_FAILED); |
| 224 SendOpenErrorReply(reply_context); | 246 SendOpenErrorReply(reply_context); |
| 225 return; | 247 return; |
| 226 } | 248 } |
| 227 | 249 |
| 228 DCHECK(file_system_host_.get()); | 250 DCHECK(file_system_host_.get()); |
| 229 DCHECK(file_system_host_->GetFileSystemOperationRunner()); | 251 DCHECK(file_system_host_->GetFileSystemOperationRunner()); |
| 252 |
| 230 file_system_host_->GetFileSystemOperationRunner()->OpenFile( | 253 file_system_host_->GetFileSystemOperationRunner()->OpenFile( |
| 231 file_system_url_, | 254 file_system_url_, |
| 232 platform_file_flags, | 255 platform_file_flags, |
| 233 base::Bind(&PepperFileIOHost::DidOpenInternalFile, | 256 base::Bind(&DidOpenFile, |
| 234 weak_factory_.GetWeakPtr(), | 257 AsWeakPtr(), |
| 235 reply_context)); | 258 base::Bind(&PepperFileIOHost::DidOpenInternalFile, |
| 259 AsWeakPtr(), |
| 260 reply_context))); |
| 236 } | 261 } |
| 237 | 262 |
| 238 void PepperFileIOHost::DidOpenInternalFile( | 263 void PepperFileIOHost::DidOpenInternalFile( |
| 239 ppapi::host::ReplyMessageContext reply_context, | 264 ppapi::host::ReplyMessageContext reply_context, |
| 240 base::File file, | 265 base::File file, |
| 241 const base::Closure& on_close_callback) { | 266 const base::Closure& on_close_callback) { |
| 242 if (file.IsValid()) { | 267 if (file.IsValid()) { |
| 243 on_close_callback_ = on_close_callback; | 268 on_close_callback_ = on_close_callback; |
| 244 | 269 |
| 245 if (FileOpenForWrite(open_flags_) && file_system_host_->ChecksQuota()) { | 270 if (FileOpenForWrite(open_flags_) && file_system_host_->ChecksQuota()) { |
| 246 check_quota_ = true; | 271 check_quota_ = true; |
| 247 file_system_host_->OpenQuotaFile( | 272 file_system_host_->OpenQuotaFile( |
| 248 this, | 273 this, |
| 249 file_system_url_, | 274 file_system_url_, |
| 250 base::Bind(&PepperFileIOHost::DidOpenQuotaFile, | 275 base::Bind(&PepperFileIOHost::DidOpenQuotaFile, |
| 251 weak_factory_.GetWeakPtr(), | 276 AsWeakPtr(), |
| 252 reply_context, | 277 reply_context, |
| 253 base::Passed(&file))); | 278 base::Passed(&file))); |
| 254 return; | 279 return; |
| 255 } | 280 } |
| 256 } | 281 } |
| 257 | 282 |
| 258 DCHECK(!file_.IsValid()); | 283 DCHECK(!file_.IsValid()); |
| 259 base::File::Error error = | 284 base::File::Error error = |
| 260 file.IsValid() ? base::File::FILE_OK : file.error_details(); | 285 file.IsValid() ? base::File::FILE_OK : file.error_details(); |
| 261 file_.SetFile(file.Pass()); | 286 file_.SetFile(file.Pass()); |
| 262 OnOpenProxyCallback(reply_context, error); | 287 OnOpenProxyCallback(reply_context, error); |
| 263 } | 288 } |
| 264 | 289 |
| 265 void PepperFileIOHost::GotResolvedRenderProcessId( | 290 void PepperFileIOHost::GotResolvedRenderProcessId( |
| 266 ppapi::host::ReplyMessageContext reply_context, | 291 ppapi::host::ReplyMessageContext reply_context, |
| 267 base::FilePath path, | 292 base::FilePath path, |
| 268 int file_flags, | 293 int file_flags, |
| 269 base::ProcessId resolved_render_process_id) { | 294 base::ProcessId resolved_render_process_id) { |
| 270 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 295 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 271 resolved_render_process_id_ = resolved_render_process_id; | 296 resolved_render_process_id_ = resolved_render_process_id; |
| 272 file_.CreateOrOpen( | 297 file_.CreateOrOpen( |
| 273 path, | 298 path, |
| 274 file_flags, | 299 file_flags, |
| 275 base::Bind(&PepperFileIOHost::OnOpenProxyCallback, | 300 base::Bind(&PepperFileIOHost::OnOpenProxyCallback, |
| 276 weak_factory_.GetWeakPtr(), | 301 AsWeakPtr(), |
| 277 reply_context)); | 302 reply_context)); |
| 278 } | 303 } |
| 279 | 304 |
| 280 int32_t PepperFileIOHost::OnHostMsgTouch( | 305 int32_t PepperFileIOHost::OnHostMsgTouch( |
| 281 ppapi::host::HostMessageContext* context, | 306 ppapi::host::HostMessageContext* context, |
| 282 PP_Time last_access_time, | 307 PP_Time last_access_time, |
| 283 PP_Time last_modified_time) { | 308 PP_Time last_modified_time) { |
| 284 int32_t rv = state_manager_.CheckOperationState( | 309 int32_t rv = state_manager_.CheckOperationState( |
| 285 FileIOStateManager::OPERATION_EXCLUSIVE, true); | 310 FileIOStateManager::OPERATION_EXCLUSIVE, true); |
| 286 if (rv != PP_OK) | 311 if (rv != PP_OK) |
| 287 return rv; | 312 return rv; |
| 288 | 313 |
| 289 if (!file_.SetTimes( | 314 if (!file_.SetTimes( |
| 290 PPTimeToTime(last_access_time), | 315 PPTimeToTime(last_access_time), |
| 291 PPTimeToTime(last_modified_time), | 316 PPTimeToTime(last_modified_time), |
| 292 base::Bind(&PepperFileIOHost::ExecutePlatformGeneralCallback, | 317 base::Bind(&PepperFileIOHost::ExecutePlatformGeneralCallback, |
| 293 weak_factory_.GetWeakPtr(), | 318 AsWeakPtr(), |
| 294 context->MakeReplyMessageContext()))) { | 319 context->MakeReplyMessageContext()))) { |
| 295 return PP_ERROR_FAILED; | 320 return PP_ERROR_FAILED; |
| 296 } | 321 } |
| 297 | 322 |
| 298 state_manager_.SetPendingOperation(FileIOStateManager::OPERATION_EXCLUSIVE); | 323 state_manager_.SetPendingOperation(FileIOStateManager::OPERATION_EXCLUSIVE); |
| 299 return PP_OK_COMPLETIONPENDING; | 324 return PP_OK_COMPLETIONPENDING; |
| 300 } | 325 } |
| 301 | 326 |
| 302 int32_t PepperFileIOHost::OnHostMsgSetLength( | 327 int32_t PepperFileIOHost::OnHostMsgSetLength( |
| 303 ppapi::host::HostMessageContext* context, | 328 ppapi::host::HostMessageContext* context, |
| 304 int64_t length) { | 329 int64_t length) { |
| 305 int32_t rv = state_manager_.CheckOperationState( | 330 int32_t rv = state_manager_.CheckOperationState( |
| 306 FileIOStateManager::OPERATION_EXCLUSIVE, true); | 331 FileIOStateManager::OPERATION_EXCLUSIVE, true); |
| 307 if (rv != PP_OK) | 332 if (rv != PP_OK) |
| 308 return rv; | 333 return rv; |
| 309 if (length < 0) | 334 if (length < 0) |
| 310 return PP_ERROR_BADARGUMENT; | 335 return PP_ERROR_BADARGUMENT; |
| 311 | 336 |
| 312 // Quota checks are performed on the plugin side, in order to use the same | 337 // Quota checks are performed on the plugin side, in order to use the same |
| 313 // quota reservation and request system as Write. | 338 // quota reservation and request system as Write. |
| 314 | 339 |
| 315 if (!file_.SetLength( | 340 if (!file_.SetLength( |
| 316 length, | 341 length, |
| 317 base::Bind(&PepperFileIOHost::ExecutePlatformGeneralCallback, | 342 base::Bind(&PepperFileIOHost::ExecutePlatformGeneralCallback, |
| 318 weak_factory_.GetWeakPtr(), | 343 AsWeakPtr(), |
| 319 context->MakeReplyMessageContext()))) { | 344 context->MakeReplyMessageContext()))) { |
| 320 return PP_ERROR_FAILED; | 345 return PP_ERROR_FAILED; |
| 321 } | 346 } |
| 322 | 347 |
| 323 state_manager_.SetPendingOperation(FileIOStateManager::OPERATION_EXCLUSIVE); | 348 state_manager_.SetPendingOperation(FileIOStateManager::OPERATION_EXCLUSIVE); |
| 324 return PP_OK_COMPLETIONPENDING; | 349 return PP_OK_COMPLETIONPENDING; |
| 325 } | 350 } |
| 326 | 351 |
| 327 int32_t PepperFileIOHost::OnHostMsgFlush( | 352 int32_t PepperFileIOHost::OnHostMsgFlush( |
| 328 ppapi::host::HostMessageContext* context) { | 353 ppapi::host::HostMessageContext* context) { |
| 329 int32_t rv = state_manager_.CheckOperationState( | 354 int32_t rv = state_manager_.CheckOperationState( |
| 330 FileIOStateManager::OPERATION_EXCLUSIVE, true); | 355 FileIOStateManager::OPERATION_EXCLUSIVE, true); |
| 331 if (rv != PP_OK) | 356 if (rv != PP_OK) |
| 332 return rv; | 357 return rv; |
| 333 | 358 |
| 334 if (!file_.Flush( | 359 if (!file_.Flush( |
| 335 base::Bind(&PepperFileIOHost::ExecutePlatformGeneralCallback, | 360 base::Bind(&PepperFileIOHost::ExecutePlatformGeneralCallback, |
| 336 weak_factory_.GetWeakPtr(), | 361 AsWeakPtr(), |
| 337 context->MakeReplyMessageContext()))) { | 362 context->MakeReplyMessageContext()))) { |
| 338 return PP_ERROR_FAILED; | 363 return PP_ERROR_FAILED; |
| 339 } | 364 } |
| 340 | 365 |
| 341 state_manager_.SetPendingOperation(FileIOStateManager::OPERATION_EXCLUSIVE); | 366 state_manager_.SetPendingOperation(FileIOStateManager::OPERATION_EXCLUSIVE); |
| 342 return PP_OK_COMPLETIONPENDING; | 367 return PP_OK_COMPLETIONPENDING; |
| 343 } | 368 } |
| 344 | 369 |
| 345 int32_t PepperFileIOHost::OnHostMsgClose( | 370 int32_t PepperFileIOHost::OnHostMsgClose( |
| 346 ppapi::host::HostMessageContext* context, | 371 ppapi::host::HostMessageContext* context, |
| 347 const ppapi::FileGrowth& file_growth) { | 372 const ppapi::FileGrowth& file_growth) { |
| 348 if (check_quota_) { | 373 if (check_quota_) { |
| 349 file_system_host_->CloseQuotaFile(this, file_growth); | 374 file_system_host_->CloseQuotaFile(this, file_growth); |
| 350 check_quota_ = false; | 375 check_quota_ = false; |
| 351 } | 376 } |
| 352 | 377 |
| 353 if (file_.IsValid()) { | 378 if (file_.IsValid()) { |
| 354 file_.Close(base::Bind(&PepperFileIOHost::DidCloseFile, | 379 file_.Close(base::Bind(&PepperFileIOHost::DidCloseFile, |
| 355 weak_factory_.GetWeakPtr())); | 380 AsWeakPtr())); |
| 356 } | 381 } |
| 357 return PP_OK; | 382 return PP_OK; |
| 358 } | 383 } |
| 359 | 384 |
| 360 void PepperFileIOHost::DidOpenQuotaFile( | 385 void PepperFileIOHost::DidOpenQuotaFile( |
| 361 ppapi::host::ReplyMessageContext reply_context, | 386 ppapi::host::ReplyMessageContext reply_context, |
| 362 base::File file, | 387 base::File file, |
| 363 int64_t max_written_offset) { | 388 int64_t max_written_offset) { |
| 364 DCHECK(!file_.IsValid()); | 389 DCHECK(!file_.IsValid()); |
| 365 DCHECK(file.IsValid()); | 390 DCHECK(file.IsValid()); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 384 | 409 |
| 385 GURL document_url = | 410 GURL document_url = |
| 386 browser_ppapi_host_->GetDocumentURLForInstance(pp_instance()); | 411 browser_ppapi_host_->GetDocumentURLForInstance(pp_instance()); |
| 387 BrowserThread::PostTaskAndReplyWithResult( | 412 BrowserThread::PostTaskAndReplyWithResult( |
| 388 BrowserThread::UI, | 413 BrowserThread::UI, |
| 389 FROM_HERE, | 414 FROM_HERE, |
| 390 base::Bind(&GetPluginAllowedToCallRequestOSFileHandle, | 415 base::Bind(&GetPluginAllowedToCallRequestOSFileHandle, |
| 391 render_process_id_, | 416 render_process_id_, |
| 392 document_url), | 417 document_url), |
| 393 base::Bind(&PepperFileIOHost::GotPluginAllowedToCallRequestOSFileHandle, | 418 base::Bind(&PepperFileIOHost::GotPluginAllowedToCallRequestOSFileHandle, |
| 394 weak_factory_.GetWeakPtr(), | 419 AsWeakPtr(), |
| 395 context->MakeReplyMessageContext())); | 420 context->MakeReplyMessageContext())); |
| 396 return PP_OK_COMPLETIONPENDING; | 421 return PP_OK_COMPLETIONPENDING; |
| 397 } | 422 } |
| 398 | 423 |
| 399 void PepperFileIOHost::GotPluginAllowedToCallRequestOSFileHandle( | 424 void PepperFileIOHost::GotPluginAllowedToCallRequestOSFileHandle( |
| 400 ppapi::host::ReplyMessageContext reply_context, | 425 ppapi::host::ReplyMessageContext reply_context, |
| 401 bool plugin_allowed) { | 426 bool plugin_allowed) { |
| 402 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 427 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 403 if (!browser_ppapi_host_->external_plugin() || | 428 if (!browser_ppapi_host_->external_plugin() || |
| 404 host()->permissions().HasPermission(ppapi::PERMISSION_PRIVATE) || | 429 host()->permissions().HasPermission(ppapi::PERMISSION_PRIVATE) || |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 463 | 488 |
| 464 ppapi::proxy::SerializedHandle file_handle; | 489 ppapi::proxy::SerializedHandle file_handle; |
| 465 // A non-zero resource id signals NaClIPCAdapter to create a NaClQuotaDesc. | 490 // A non-zero resource id signals NaClIPCAdapter to create a NaClQuotaDesc. |
| 466 PP_Resource quota_file_io = check_quota_ ? pp_resource() : 0; | 491 PP_Resource quota_file_io = check_quota_ ? pp_resource() : 0; |
| 467 file_handle.set_file_handle(transit_file, open_flags, quota_file_io); | 492 file_handle.set_file_handle(transit_file, open_flags, quota_file_io); |
| 468 reply_context->params.AppendHandle(file_handle); | 493 reply_context->params.AppendHandle(file_handle); |
| 469 return true; | 494 return true; |
| 470 } | 495 } |
| 471 | 496 |
| 472 } // namespace content | 497 } // namespace content |
| OLD | NEW |