1 // Copyright (c) 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/renderer/pepper/pepper_file_system_host.h" 6 7 #include "base/bind.h" 8 #include "base/callback.h" 9 #include "content/child/child_thread.h" 10 #include "content/child/fileapi/file_system_dispatcher.h" 11 #include "content/common/pepper_file_util.h" 12 #include "content/renderer/pepper/pepper_plugin_instance_impl.h" 13 #include "content/public/renderer/render_view.h" 14 #include "content/public/renderer/renderer_ppapi_host.h" 15 #include "ppapi/c/pp_errors.h" 16 #include "ppapi/host/dispatch_host_message.h" 17 #include "ppapi/host/ppapi_host.h" 18 #include "ppapi/proxy/ppapi_messages.h" 19 #include "ppapi/shared_impl/file_system_util.h" 20 #include "ppapi/shared_impl/file_type_conversion.h" 21 #include "storage/common/fileapi/file_system_util.h" 22 #include "third_party/WebKit/public/web/WebDocument.h" 23 #include "third_party/WebKit/public/web/WebFrame.h" 24 #include "third_party/WebKit/public/web/WebView.h" 25 26 namespace content { 27 28 PepperFileSystemHost::PepperFileSystemHost(RendererPpapiHost* host, 29 PP_Instance instance, 30 PP_Resource resource, 31 PP_FileSystemType type) 32 : ResourceHost(host->GetPpapiHost(), instance, resource), 33 renderer_ppapi_host_(host), 34 type_(type), 35 opened_(false), 36 called_open_(false), 37 weak_factory_(this) {} 38 39 PepperFileSystemHost::PepperFileSystemHost(RendererPpapiHost* host, 40 PP_Instance instance, 41 PP_Resource resource, 42 const GURL& root_url, 43 PP_FileSystemType type) 44 : ResourceHost(host->GetPpapiHost(), instance, resource), 45 renderer_ppapi_host_(host), 46 type_(type), 47 opened_(true), 48 root_url_(root_url), 49 called_open_(true), 50 weak_factory_(this) {} 51 52 PepperFileSystemHost::~PepperFileSystemHost() {} 53 54 int32_t PepperFileSystemHost::OnResourceMessageReceived( 55 const IPC::Message& msg, 56 ppapi::host::HostMessageContext* context) { 57 PPAPI_BEGIN_MESSAGE_MAP(PepperFileSystemHost, msg) 58 PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_FileSystem_Open, 59 OnHostMsgOpen) 60 PPAPI_DISPATCH_HOST_RESOURCE_CALL( 61 PpapiHostMsg_FileSystem_InitIsolatedFileSystem, 62 OnHostMsgInitIsolatedFileSystem) 63 PPAPI_END_MESSAGE_MAP() 64 return PP_ERROR_FAILED; 65 } 66 67 bool PepperFileSystemHost::IsFileSystemHost() { return true; } 68 69 void PepperFileSystemHost::DidOpenFileSystem( 70 const std::string& /* name_unused */, 71 const GURL& root) { 72 opened_ = true; 73 root_url_ = root; 74 reply_context_.params.set_result(PP_OK); 75 host()->SendReply(reply_context_, PpapiPluginMsg_FileSystem_OpenReply()); 76 reply_context_ = ppapi::host::ReplyMessageContext(); 77 } 78 79 void PepperFileSystemHost::DidFailOpenFileSystem(base::File::Error error) { 80 int32 pp_error = ppapi::FileErrorToPepperError(error); 81 opened_ = (pp_error == PP_OK); 82 reply_context_.params.set_result(pp_error); 83 host()->SendReply(reply_context_, PpapiPluginMsg_FileSystem_OpenReply()); 84 reply_context_ = ppapi::host::ReplyMessageContext(); 85 } 86 87 int32_t PepperFileSystemHost::OnHostMsgOpen( 88 ppapi::host::HostMessageContext* context, 89 int64_t expected_size) { 90 // Not allow multiple opens. 91 if (called_open_) 92 return PP_ERROR_INPROGRESS; 93 called_open_ = true; 94 95 storage::FileSystemType file_system_type = 96 PepperFileSystemTypeToFileSystemType(type_); 97 if (file_system_type == storage::kFileSystemTypeUnknown) 98 return PP_ERROR_FAILED; 99 100 GURL document_url = renderer_ppapi_host_->GetDocumentURL(pp_instance()); 101 if (!document_url.is_valid()) 102 return PP_ERROR_FAILED; 103 104 FileSystemDispatcher* file_system_dispatcher = 105 ChildThread::current()->file_system_dispatcher(); 106 reply_context_ = context->MakeReplyMessageContext(); 107 file_system_dispatcher->OpenFileSystem( 108 document_url.GetOrigin(), 109 file_system_type, 110 base::Bind(&PepperFileSystemHost::DidOpenFileSystem, 111 weak_factory_.GetWeakPtr()), 112 base::Bind(&PepperFileSystemHost::DidFailOpenFileSystem, 113 weak_factory_.GetWeakPtr())); 114 return PP_OK_COMPLETIONPENDING; 115 } 116 117 int32_t PepperFileSystemHost::OnHostMsgInitIsolatedFileSystem( 118 ppapi::host::HostMessageContext* context, 119 const std::string& fsid, 120 PP_IsolatedFileSystemType_Private type) { 121 // Do not allow multiple opens. 122 if (called_open_) 123 return PP_ERROR_INPROGRESS; 124 called_open_ = true; 125 126 // Do a sanity check. 127 if (!storage::ValidateIsolatedFileSystemId(fsid)) 128 return PP_ERROR_BADARGUMENT; 129 130 RenderView* view = 131 renderer_ppapi_host_->GetRenderViewForInstance(pp_instance()); 132 if (!view) 133 return PP_ERROR_FAILED; 134 135 const GURL& url = view->GetWebView()->mainFrame()->document().url(); 136 const std::string root_name = ppapi::IsolatedFileSystemTypeToRootName(type); 137 if (root_name.empty()) 138 return PP_ERROR_BADARGUMENT; 139 root_url_ = GURL(storage::GetIsolatedFileSystemRootURIString( 140 url.GetOrigin(), fsid, root_name)); 141 opened_ = true; 142 return PP_OK; 143 } 144 145 } // namespace content 146