1 // Copyright 2013 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "content/renderer/pepper/pepper_file_system_host.h"
8 #include "base/callback.h"
9 #include "content/common/pepper_file_util.h"
10 #include "content/public/renderer/render_frame.h"
11 #include "content/public/renderer/renderer_ppapi_host.h"
12 #include "content/renderer/pepper/pepper_plugin_instance_impl.h"
13 #include "ppapi/c/pp_errors.h"
14 #include "ppapi/host/dispatch_host_message.h"
15 #include "ppapi/host/ppapi_host.h"
16 #include "ppapi/proxy/ppapi_messages.h"
17 #include "ppapi/shared_impl/file_system_util.h"
18 #include "ppapi/shared_impl/file_type_conversion.h"
19 #include "storage/common/file_system/file_system_util.h"
20 #include "third_party/abseil-cpp/absl/types/optional.h"
21 #include "third_party/blink/public/common/browser_interface_broker_proxy.h"
22 #include "third_party/blink/public/mojom/filesystem/file_system.mojom.h"
23 #include "third_party/blink/public/web/web_document.h"
24 #include "third_party/blink/public/web/web_local_frame.h"
25 #include "third_party/blink/public/web/web_view.h"
31 absl::optional<blink::mojom::FileSystemType>
32 PepperFileSystemTypeToMojoFileSystemType(PP_FileSystemType type) {
34 case PP_FILESYSTEMTYPE_LOCALTEMPORARY:
35 return blink::mojom::FileSystemType::kTemporary;
36 case PP_FILESYSTEMTYPE_LOCALPERSISTENT:
37 return blink::mojom::FileSystemType::kPersistent;
38 case PP_FILESYSTEMTYPE_EXTERNAL:
39 return blink::mojom::FileSystemType::kExternal;
47 PepperFileSystemHost::PepperFileSystemHost(RendererPpapiHost* host,
50 PP_FileSystemType type)
51 : ResourceHost(host->GetPpapiHost(), instance, resource),
52 renderer_ppapi_host_(host),
55 called_open_(false) {}
57 PepperFileSystemHost::PepperFileSystemHost(RendererPpapiHost* host,
61 PP_FileSystemType type)
62 : ResourceHost(host->GetPpapiHost(), instance, resource),
63 renderer_ppapi_host_(host),
69 PepperFileSystemHost::~PepperFileSystemHost() {}
71 int32_t PepperFileSystemHost::OnResourceMessageReceived(
72 const IPC::Message& msg,
73 ppapi::host::HostMessageContext* context) {
74 PPAPI_BEGIN_MESSAGE_MAP(PepperFileSystemHost, msg)
75 PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_FileSystem_Open,
77 PPAPI_DISPATCH_HOST_RESOURCE_CALL(
78 PpapiHostMsg_FileSystem_InitIsolatedFileSystem,
79 OnHostMsgInitIsolatedFileSystem)
80 PPAPI_END_MESSAGE_MAP()
81 LOG(ERROR) << "Resource message unresolved";
82 return PP_ERROR_FAILED;
85 bool PepperFileSystemHost::IsFileSystemHost() { return true; }
87 void PepperFileSystemHost::DidOpenFileSystem(
88 const std::string& /* name_unused */,
90 base::File::Error error) {
91 if (error != base::File::FILE_OK) {
92 DidFailOpenFileSystem(error);
97 reply_context_.params.set_result(PP_OK);
98 host()->SendReply(reply_context_, PpapiPluginMsg_FileSystem_OpenReply());
99 reply_context_ = ppapi::host::ReplyMessageContext();
102 void PepperFileSystemHost::DidFailOpenFileSystem(base::File::Error error) {
103 int32_t pp_error = ppapi::FileErrorToPepperError(error);
104 opened_ = (pp_error == PP_OK);
105 reply_context_.params.set_result(pp_error);
106 host()->SendReply(reply_context_, PpapiPluginMsg_FileSystem_OpenReply());
107 reply_context_ = ppapi::host::ReplyMessageContext();
110 int32_t PepperFileSystemHost::OnHostMsgOpen(
111 ppapi::host::HostMessageContext* context,
112 int64_t expected_size) {
113 // Not allow multiple opens.
115 LOG(ERROR) << "Already an open called - not allow multiple opens";
116 return PP_ERROR_INPROGRESS;
120 absl::optional<blink::mojom::FileSystemType> file_system_type =
121 PepperFileSystemTypeToMojoFileSystemType(type_);
122 if (!file_system_type.has_value()) {
123 LOG(ERROR) << "Unknown file system type";
124 return PP_ERROR_FAILED;
127 GURL document_url = renderer_ppapi_host_->GetDocumentURL(pp_instance());
128 if (!document_url.is_valid()) {
129 LOG(ERROR) << "Invalid document URL";
130 return PP_ERROR_FAILED;
133 reply_context_ = context->MakeReplyMessageContext();
134 blink::mojom::FileSystemManager* file_system_manager = GetFileSystemManager();
135 if (file_system_manager == nullptr)
136 return PP_ERROR_FAILED;
138 file_system_manager->Open(
139 url::Origin::Create(document_url), file_system_type.value(),
140 base::BindOnce(&PepperFileSystemHost::DidOpenFileSystem, AsWeakPtr()));
141 return PP_OK_COMPLETIONPENDING;
144 int32_t PepperFileSystemHost::OnHostMsgInitIsolatedFileSystem(
145 ppapi::host::HostMessageContext* context,
146 const std::string& fsid,
147 PP_IsolatedFileSystemType_Private type) {
148 // Do not allow multiple opens.
150 LOG(ERROR) << "Already an open called - not allow multiple opens";
151 return PP_ERROR_INPROGRESS;
155 // Do a sanity check.
156 if (!storage::ValidateIsolatedFileSystemId(fsid)) {
157 LOG(ERROR) << "Cannot validate isolated file system ID";
158 return PP_ERROR_BADARGUMENT;
162 renderer_ppapi_host_->GetRenderFrameForInstance(pp_instance());
164 LOG(ERROR) << "Cannot get render view";
165 return PP_ERROR_FAILED;
168 url::Origin main_frame_origin(
169 frame->GetWebView()->MainFrame()->GetSecurityOrigin());
170 const std::string root_name = ppapi::IsolatedFileSystemTypeToRootName(type);
171 if (root_name.empty()) {
172 LOG(ERROR) << "Cannot get isolated file system root name";
173 return PP_ERROR_BADARGUMENT;
175 root_url_ = GURL(storage::GetIsolatedFileSystemRootURIString(
176 main_frame_origin.GetURL(), fsid, root_name));
181 blink::mojom::FileSystemManager* PepperFileSystemHost::GetFileSystemManager() {
182 if (!file_system_manager_remote_) {
184 renderer_ppapi_host_->GetRenderFrameForInstance(pp_instance());
187 frame->GetBrowserInterfaceBroker()->GetInterface(
188 file_system_manager_remote_.BindNewPipeAndPassReceiver());
190 return file_system_manager_remote_.get();
193 } // namespace content