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 "base/optional.h"
10 #include "content/common/pepper_file_util.h"
11 #include "content/public/common/service_names.mojom.h"
12 #include "content/public/renderer/render_view.h"
13 #include "content/public/renderer/renderer_ppapi_host.h"
14 #include "content/renderer/pepper/pepper_plugin_instance_impl.h"
15 #include "content/renderer/render_thread_impl.h"
16 #include "ppapi/c/pp_errors.h"
17 #include "ppapi/host/dispatch_host_message.h"
18 #include "ppapi/host/ppapi_host.h"
19 #include "ppapi/proxy/ppapi_messages.h"
20 #include "ppapi/shared_impl/file_system_util.h"
21 #include "ppapi/shared_impl/file_type_conversion.h"
22 #include "storage/common/file_system/file_system_util.h"
23 #include "third_party/blink/public/mojom/filesystem/file_system.mojom.h"
24 #include "third_party/blink/public/web/web_document.h"
25 #include "third_party/blink/public/web/web_local_frame.h"
26 #include "third_party/blink/public/web/web_view.h"
27
28 namespace content {
29
30 namespace {
31
32 base::Optional<blink::mojom::FileSystemType>
PepperFileSystemTypeToMojoFileSystemType(PP_FileSystemType type)33 PepperFileSystemTypeToMojoFileSystemType(PP_FileSystemType type) {
34 switch (type) {
35 case PP_FILESYSTEMTYPE_LOCALTEMPORARY:
36 return blink::mojom::FileSystemType::kTemporary;
37 case PP_FILESYSTEMTYPE_LOCALPERSISTENT:
38 return blink::mojom::FileSystemType::kPersistent;
39 case PP_FILESYSTEMTYPE_EXTERNAL:
40 return blink::mojom::FileSystemType::kExternal;
41 default:
42 return base::nullopt;
43 }
44 }
45
46 } // namespace
47
PepperFileSystemHost(RendererPpapiHost * host,PP_Instance instance,PP_Resource resource,PP_FileSystemType type)48 PepperFileSystemHost::PepperFileSystemHost(RendererPpapiHost* host,
49 PP_Instance instance,
50 PP_Resource resource,
51 PP_FileSystemType type)
52 : ResourceHost(host->GetPpapiHost(), instance, resource),
53 renderer_ppapi_host_(host),
54 type_(type),
55 opened_(false),
56 called_open_(false) {}
57
PepperFileSystemHost(RendererPpapiHost * host,PP_Instance instance,PP_Resource resource,const GURL & root_url,PP_FileSystemType type)58 PepperFileSystemHost::PepperFileSystemHost(RendererPpapiHost* host,
59 PP_Instance instance,
60 PP_Resource resource,
61 const GURL& root_url,
62 PP_FileSystemType type)
63 : ResourceHost(host->GetPpapiHost(), instance, resource),
64 renderer_ppapi_host_(host),
65 type_(type),
66 opened_(true),
67 root_url_(root_url),
68 called_open_(true) {}
69
~PepperFileSystemHost()70 PepperFileSystemHost::~PepperFileSystemHost() {}
71
OnResourceMessageReceived(const IPC::Message & msg,ppapi::host::HostMessageContext * context)72 int32_t PepperFileSystemHost::OnResourceMessageReceived(
73 const IPC::Message& msg,
74 ppapi::host::HostMessageContext* context) {
75 PPAPI_BEGIN_MESSAGE_MAP(PepperFileSystemHost, msg)
76 PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_FileSystem_Open,
77 OnHostMsgOpen)
78 PPAPI_DISPATCH_HOST_RESOURCE_CALL(
79 PpapiHostMsg_FileSystem_InitIsolatedFileSystem,
80 OnHostMsgInitIsolatedFileSystem)
81 PPAPI_END_MESSAGE_MAP()
82 return PP_ERROR_FAILED;
83 }
84
IsFileSystemHost()85 bool PepperFileSystemHost::IsFileSystemHost() { return true; }
86
DidOpenFileSystem(const std::string &,const GURL & root,base::File::Error error)87 void PepperFileSystemHost::DidOpenFileSystem(
88 const std::string& /* name_unused */,
89 const GURL& root,
90 base::File::Error error) {
91 if (error != base::File::FILE_OK) {
92 DidFailOpenFileSystem(error);
93 return;
94 }
95 opened_ = true;
96 root_url_ = root;
97 reply_context_.params.set_result(PP_OK);
98 host()->SendReply(reply_context_, PpapiPluginMsg_FileSystem_OpenReply());
99 reply_context_ = ppapi::host::ReplyMessageContext();
100 }
101
DidFailOpenFileSystem(base::File::Error error)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();
108 }
109
OnHostMsgOpen(ppapi::host::HostMessageContext * context,int64_t expected_size)110 int32_t PepperFileSystemHost::OnHostMsgOpen(
111 ppapi::host::HostMessageContext* context,
112 int64_t expected_size) {
113 // Not allow multiple opens.
114 if (called_open_)
115 return PP_ERROR_INPROGRESS;
116 called_open_ = true;
117
118 base::Optional<blink::mojom::FileSystemType> file_system_type =
119 PepperFileSystemTypeToMojoFileSystemType(type_);
120 if (!file_system_type.has_value())
121 return PP_ERROR_FAILED;
122
123 GURL document_url = renderer_ppapi_host_->GetDocumentURL(pp_instance());
124 if (!document_url.is_valid())
125 return PP_ERROR_FAILED;
126
127 reply_context_ = context->MakeReplyMessageContext();
128 GetFileSystemManager().Open(
129 url::Origin::Create(document_url), file_system_type.value(),
130 base::BindOnce(&PepperFileSystemHost::DidOpenFileSystem, AsWeakPtr()));
131 return PP_OK_COMPLETIONPENDING;
132 }
133
OnHostMsgInitIsolatedFileSystem(ppapi::host::HostMessageContext * context,const std::string & fsid,PP_IsolatedFileSystemType_Private type)134 int32_t PepperFileSystemHost::OnHostMsgInitIsolatedFileSystem(
135 ppapi::host::HostMessageContext* context,
136 const std::string& fsid,
137 PP_IsolatedFileSystemType_Private type) {
138 // Do not allow multiple opens.
139 if (called_open_)
140 return PP_ERROR_INPROGRESS;
141 called_open_ = true;
142
143 // Do a sanity check.
144 if (!storage::ValidateIsolatedFileSystemId(fsid))
145 return PP_ERROR_BADARGUMENT;
146
147 RenderView* view =
148 renderer_ppapi_host_->GetRenderViewForInstance(pp_instance());
149 if (!view)
150 return PP_ERROR_FAILED;
151
152 url::Origin main_frame_origin(
153 view->GetWebView()->MainFrame()->GetSecurityOrigin());
154 const std::string root_name = ppapi::IsolatedFileSystemTypeToRootName(type);
155 if (root_name.empty())
156 return PP_ERROR_BADARGUMENT;
157 root_url_ = GURL(storage::GetIsolatedFileSystemRootURIString(
158 main_frame_origin.GetURL(), fsid, root_name));
159 opened_ = true;
160 return PP_OK;
161 }
162
GetFileSystemManager()163 blink::mojom::FileSystemManager& PepperFileSystemHost::GetFileSystemManager() {
164 if (!file_system_manager_) {
165 ChildThreadImpl::current()->BindHostReceiver(
166 file_system_manager_.BindNewPipeAndPassReceiver());
167 }
168 return *file_system_manager_;
169 }
170
171 } // namespace content
172