| 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/ppb_file_ref_impl.h" | 5 #include "content/renderer/pepper/ppb_file_ref_impl.h" |
| 6 | 6 |
| 7 #include "base/files/file_util_proxy.h" | 7 #include "base/files/file_util_proxy.h" |
| 8 #include "base/platform_file.h" | 8 #include "base/platform_file.h" |
| 9 #include "base/strings/string_util.h" | 9 #include "base/strings/string_util.h" |
| 10 #include "base/strings/utf_string_conversions.h" | 10 #include "base/strings/utf_string_conversions.h" |
| 11 #include "content/child/fileapi/file_system_dispatcher.h" | 11 #include "content/child/fileapi/file_system_dispatcher.h" |
| 12 #include "content/common/view_messages.h" |
| 12 #include "content/renderer/pepper/common.h" | 13 #include "content/renderer/pepper/common.h" |
| 13 #include "content/renderer/pepper/pepper_file_system_host.h" | 14 #include "content/renderer/pepper/pepper_file_system_host.h" |
| 14 #include "content/renderer/pepper/pepper_helper_impl.h" | 15 #include "content/renderer/pepper/pepper_helper_impl.h" |
| 15 #include "content/renderer/pepper/pepper_plugin_instance_impl.h" | |
| 16 #include "content/renderer/pepper/plugin_module.h" | 16 #include "content/renderer/pepper/plugin_module.h" |
| 17 #include "content/renderer/pepper/renderer_ppapi_host_impl.h" | 17 #include "content/renderer/pepper/renderer_ppapi_host_impl.h" |
| 18 #include "content/renderer/pepper/resource_helper.h" | |
| 19 #include "content/renderer/render_thread_impl.h" | 18 #include "content/renderer/render_thread_impl.h" |
| 20 #include "net/base/escape.h" | 19 #include "net/base/escape.h" |
| 21 #include "ppapi/c/pp_errors.h" | 20 #include "ppapi/c/pp_errors.h" |
| 22 #include "ppapi/c/ppb_file_io.h" | 21 #include "ppapi/c/ppb_file_io.h" |
| 23 #include "ppapi/host/ppapi_host.h" | 22 #include "ppapi/host/ppapi_host.h" |
| 24 #include "ppapi/shared_impl/file_type_conversion.h" | 23 #include "ppapi/shared_impl/file_type_conversion.h" |
| 25 #include "ppapi/shared_impl/time_conversion.h" | 24 #include "ppapi/shared_impl/time_conversion.h" |
| 26 #include "ppapi/shared_impl/var.h" | 25 #include "ppapi/shared_impl/var.h" |
| 27 #include "ppapi/thunk/enter.h" | 26 #include "ppapi/thunk/enter.h" |
| 28 #include "ppapi/thunk/ppb_file_system_api.h" | 27 #include "ppapi/thunk/ppb_file_system_api.h" |
| (...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 213 return; | 212 return; |
| 214 callback->Run(::ppapi::PlatformFileErrorToPepperError(error_code)); | 213 callback->Run(::ppapi::PlatformFileErrorToPepperError(error_code)); |
| 215 } | 214 } |
| 216 | 215 |
| 217 } // namespace | 216 } // namespace |
| 218 | 217 |
| 219 PPB_FileRef_Impl::PPB_FileRef_Impl(const PPB_FileRef_CreateInfo& info, | 218 PPB_FileRef_Impl::PPB_FileRef_Impl(const PPB_FileRef_CreateInfo& info, |
| 220 PP_Resource file_system) | 219 PP_Resource file_system) |
| 221 : PPB_FileRef_Shared(::ppapi::OBJECT_IS_IMPL, info), | 220 : PPB_FileRef_Shared(::ppapi::OBJECT_IS_IMPL, info), |
| 222 file_system_(file_system), | 221 file_system_(file_system), |
| 223 external_file_system_path_() { | 222 external_file_system_path_(), |
| 223 routing_id_(MSG_ROUTING_NONE) { |
| 224 if (RenderThreadImpl::current()) { // NULL in tests. |
| 225 routing_id_ = RenderThreadImpl::current()->GenerateRoutingID(); |
| 226 ChildThread::current()->AddRoute(routing_id_, this); |
| 227 } |
| 224 } | 228 } |
| 225 | 229 |
| 226 PPB_FileRef_Impl::PPB_FileRef_Impl(const PPB_FileRef_CreateInfo& info, | 230 PPB_FileRef_Impl::PPB_FileRef_Impl(const PPB_FileRef_CreateInfo& info, |
| 227 const base::FilePath& external_file_path) | 231 const base::FilePath& external_file_path) |
| 228 : PPB_FileRef_Shared(::ppapi::OBJECT_IS_IMPL, info), | 232 : PPB_FileRef_Shared(::ppapi::OBJECT_IS_IMPL, info), |
| 229 file_system_(), | 233 file_system_(), |
| 230 external_file_system_path_(external_file_path) { | 234 external_file_system_path_(external_file_path), |
| 235 routing_id_(MSG_ROUTING_NONE) { |
| 236 if (RenderThreadImpl::current()) { // NULL in tests. |
| 237 routing_id_ = RenderThreadImpl::current()->GenerateRoutingID(); |
| 238 ChildThread::current()->AddRoute(routing_id_, this); |
| 239 } |
| 231 } | 240 } |
| 232 | 241 |
| 233 PPB_FileRef_Impl::~PPB_FileRef_Impl() { | 242 PPB_FileRef_Impl::~PPB_FileRef_Impl() { |
| 243 if (RenderThreadImpl::current()) |
| 244 ChildThread::current()->RemoveRoute(routing_id_); |
| 234 } | 245 } |
| 235 | 246 |
| 236 // static | 247 // static |
| 237 PPB_FileRef_Impl* PPB_FileRef_Impl::CreateInternal(PP_Instance instance, | 248 PPB_FileRef_Impl* PPB_FileRef_Impl::CreateInternal(PP_Instance instance, |
| 238 PP_Resource pp_file_system, | 249 PP_Resource pp_file_system, |
| 239 const std::string& path) { | 250 const std::string& path) { |
| 240 PepperPluginInstanceImpl* plugin_instance = | 251 PepperFileSystemHost* fs_host = GetFileSystemHostInternal( |
| 241 ResourceHelper::PPInstanceToPluginInstance(instance); | 252 instance, pp_file_system); |
| 242 if (!plugin_instance || !plugin_instance->helper()) | 253 if (!fs_host) |
| 243 return 0; | 254 return 0; |
| 244 | 255 |
| 245 PepperFileSystemHost* host = GetFileSystemHostInternal( | 256 PP_FileSystemType type = fs_host->GetType(); |
| 246 instance, pp_file_system); | |
| 247 if (!host) | |
| 248 return 0; | |
| 249 | |
| 250 PP_FileSystemType type = host->GetType(); | |
| 251 if (type != PP_FILESYSTEMTYPE_LOCALPERSISTENT && | 257 if (type != PP_FILESYSTEMTYPE_LOCALPERSISTENT && |
| 252 type != PP_FILESYSTEMTYPE_LOCALTEMPORARY && | 258 type != PP_FILESYSTEMTYPE_LOCALTEMPORARY && |
| 253 type != PP_FILESYSTEMTYPE_EXTERNAL && | 259 type != PP_FILESYSTEMTYPE_EXTERNAL && |
| 254 type != PP_FILESYSTEMTYPE_ISOLATED) | 260 type != PP_FILESYSTEMTYPE_ISOLATED) |
| 255 return 0; | 261 return 0; |
| 256 | 262 |
| 257 PPB_FileRef_CreateInfo info; | 263 PPB_FileRef_CreateInfo info; |
| 258 info.resource = HostResource::MakeInstanceOnly(instance); | 264 info.resource = HostResource::MakeInstanceOnly(instance); |
| 259 info.file_system_plugin_resource = pp_file_system; | 265 info.file_system_plugin_resource = pp_file_system; |
| 260 info.file_system_type = type; | 266 info.file_system_type = type; |
| (...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 415 // start with a storage type identifier that looks like a path segment. | 421 // start with a storage type identifier that looks like a path segment. |
| 416 | 422 |
| 417 PepperFileSystemHost* host = GetFileSystemHost(); | 423 PepperFileSystemHost* host = GetFileSystemHost(); |
| 418 if (!host) | 424 if (!host) |
| 419 return GURL(); | 425 return GURL(); |
| 420 | 426 |
| 421 return GURL(host->GetRootUrl()).Resolve(net::EscapePath( | 427 return GURL(host->GetRootUrl()).Resolve(net::EscapePath( |
| 422 virtual_path.substr(1))); | 428 virtual_path.substr(1))); |
| 423 } | 429 } |
| 424 | 430 |
| 431 bool PPB_FileRef_Impl::OnMessageReceived(const IPC::Message& msg) { |
| 432 bool handled = true; |
| 433 IPC_BEGIN_MESSAGE_MAP(PPB_FileRef_Impl, msg) |
| 434 IPC_MESSAGE_HANDLER(ViewMsg_AsyncOpenPepperFile_ACK, OnAsyncFileOpened) |
| 435 IPC_MESSAGE_UNHANDLED(handled = false) |
| 436 IPC_END_MESSAGE_MAP() |
| 437 return handled; |
| 438 } |
| 439 |
| 440 void PPB_FileRef_Impl::OnAsyncFileOpened( |
| 441 base::PlatformFileError error_code, |
| 442 IPC::PlatformFileForTransit file_for_transit, |
| 443 int message_id) { |
| 444 AsyncOpenFileCallback* callback = |
| 445 pending_async_open_files_.Lookup(message_id); |
| 446 DCHECK(callback); |
| 447 pending_async_open_files_.Remove(message_id); |
| 448 |
| 449 base::PlatformFile file = |
| 450 IPC::PlatformFileForTransitToPlatformFile(file_for_transit); |
| 451 callback->Run(error_code, base::PassPlatformFile(&file)); |
| 452 // Make sure we won't leak file handle if the requester has died. |
| 453 if (file != base::kInvalidPlatformFileValue) { |
| 454 base::FileUtilProxy::Close( |
| 455 RenderThreadImpl::current()->GetFileThreadMessageLoopProxy().get(), |
| 456 file, |
| 457 base::FileUtilProxy::StatusCallback()); |
| 458 } |
| 459 delete callback; |
| 460 } |
| 461 |
| 425 bool PPB_FileRef_Impl::IsValidNonExternalFileSystem() const { | 462 bool PPB_FileRef_Impl::IsValidNonExternalFileSystem() const { |
| 426 PepperFileSystemHost* host = GetFileSystemHost(); | 463 PepperFileSystemHost* host = GetFileSystemHost(); |
| 427 return HasValidFileSystem() && host && | 464 return HasValidFileSystem() && host && |
| 428 host->GetType() != PP_FILESYSTEMTYPE_EXTERNAL; | 465 host->GetType() != PP_FILESYSTEMTYPE_EXTERNAL; |
| 429 } | 466 } |
| 430 | 467 |
| 431 bool PPB_FileRef_Impl::HasValidFileSystem() const { | 468 bool PPB_FileRef_Impl::HasValidFileSystem() const { |
| 432 PepperFileSystemHost* host = GetFileSystemHost(); | 469 PepperFileSystemHost* host = GetFileSystemHost(); |
| 433 return host && host->IsOpened(); | 470 return host && host->IsOpened(); |
| 434 } | 471 } |
| 435 | 472 |
| 436 int32_t PPB_FileRef_Impl::Query(PP_FileInfo* info, | 473 int32_t PPB_FileRef_Impl::Query(PP_FileInfo* info, |
| 437 scoped_refptr<TrackedCallback> callback) { | 474 scoped_refptr<TrackedCallback> callback) { |
| 438 NOTREACHED(); | 475 NOTREACHED(); |
| 439 return PP_ERROR_FAILED; | 476 return PP_ERROR_FAILED; |
| 440 } | 477 } |
| 441 | 478 |
| 442 int32_t PPB_FileRef_Impl::QueryInHost( | 479 int32_t PPB_FileRef_Impl::QueryInHost( |
| 443 linked_ptr<PP_FileInfo> info, | 480 linked_ptr<PP_FileInfo> info, |
| 444 scoped_refptr<TrackedCallback> callback) { | 481 scoped_refptr<TrackedCallback> callback) { |
| 445 scoped_refptr<PepperPluginInstanceImpl> plugin_instance = | |
| 446 ResourceHelper::GetPluginInstance(this); | |
| 447 if (!plugin_instance.get()) | |
| 448 return PP_ERROR_FAILED; | |
| 449 | |
| 450 if (!file_system_) { | 482 if (!file_system_) { |
| 451 // External file system | 483 // External file system |
| 452 // We have to do something totally different for external file systems. | 484 // We have to do something totally different for external file systems. |
| 453 | 485 |
| 454 // TODO(teravest): Use the SequencedWorkerPool instead. | 486 // TODO(teravest): Use the SequencedWorkerPool instead. |
| 455 scoped_refptr<base::TaskRunner> task_runner = | 487 scoped_refptr<base::TaskRunner> task_runner = |
| 456 RenderThreadImpl::current()->GetFileThreadMessageLoopProxy(); | 488 RenderThreadImpl::current()->GetFileThreadMessageLoopProxy(); |
| 457 if (!plugin_instance->helper()->AsyncOpenFile( | 489 |
| 458 GetSystemPath(), | 490 int message_id = pending_async_open_files_.Add(new AsyncOpenFileCallback( |
| 459 PP_FILEOPENFLAG_READ, | 491 base::Bind(&QueryCallback, task_runner, info, callback))); |
| 460 base::Bind(&QueryCallback, task_runner, info, callback))) | 492 RenderThreadImpl::current()->Send(new ViewHostMsg_AsyncOpenPepperFile( |
| 461 return PP_ERROR_FAILED; | 493 routing_id_, |
| 494 GetSystemPath(), |
| 495 PP_FILEOPENFLAG_READ, |
| 496 message_id)); |
| 462 } else { | 497 } else { |
| 463 // Non-external file system | 498 // Non-external file system |
| 464 if (!HasValidFileSystem()) | 499 if (!HasValidFileSystem()) |
| 465 return PP_ERROR_NOACCESS; | 500 return PP_ERROR_NOACCESS; |
| 466 | 501 |
| 467 PP_FileSystemType file_system_type = GetFileSystemHost()->GetType(); | 502 PP_FileSystemType file_system_type = GetFileSystemHost()->GetType(); |
| 468 FileSystemDispatcher* file_system_dispatcher = | 503 FileSystemDispatcher* file_system_dispatcher = |
| 469 ChildThread::current()->file_system_dispatcher(); | 504 ChildThread::current()->file_system_dispatcher(); |
| 470 file_system_dispatcher->ReadMetadata( | 505 file_system_dispatcher->ReadMetadata( |
| 471 GetFileSystemURL(), | 506 GetFileSystemURL(), |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 512 if (!resource || !ppapi_host) | 547 if (!resource || !ppapi_host) |
| 513 return NULL; | 548 return NULL; |
| 514 ppapi::host::ResourceHost* resource_host = | 549 ppapi::host::ResourceHost* resource_host = |
| 515 ppapi_host->GetResourceHost(resource); | 550 ppapi_host->GetResourceHost(resource); |
| 516 if (resource_host && resource_host->IsFileSystemHost()) | 551 if (resource_host && resource_host->IsFileSystemHost()) |
| 517 return static_cast<PepperFileSystemHost*>(resource_host); | 552 return static_cast<PepperFileSystemHost*>(resource_host); |
| 518 return NULL; | 553 return NULL; |
| 519 } | 554 } |
| 520 | 555 |
| 521 } // namespace content | 556 } // namespace content |
| OLD | NEW |