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
3 // found in the LICENSE file.
5 #include "content/browser/renderer_host/pepper/pepper_file_system_browser_host.h"
8 #include "base/callback.h"
9 #include "content/public/browser/browser_ppapi_host.h"
10 #include "content/public/browser/browser_thread.h"
11 #include "content/public/browser/render_process_host.h"
12 #include "content/public/browser/storage_partition.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_type_conversion.h"
18 #include "webkit/browser/fileapi/file_system_context.h"
19 #include "webkit/browser/fileapi/file_system_operation_runner.h"
20 #include "webkit/common/fileapi/file_system_util.h"
26 scoped_refptr<fileapi::FileSystemContext>
27 GetFileSystemContextFromRenderId(int render_process_id) {
28 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
29 RenderProcessHost* render_process_host =
30 RenderProcessHost::FromID(render_process_id);
31 if (!render_process_host)
33 StoragePartition* storage_partition =
34 render_process_host->GetStoragePartition();
35 if (!storage_partition)
37 return storage_partition->GetFileSystemContext();
42 PepperFileSystemBrowserHost::PepperFileSystemBrowserHost(BrowserPpapiHost* host,
45 PP_FileSystemType type)
46 : ResourceHost(host->GetPpapiHost(), instance, resource),
47 browser_ppapi_host_(host),
55 void PepperFileSystemBrowserHost::OpenExisting(const GURL& root_url,
56 const base::Closure& callback) {
58 int render_process_id = 0;
60 if (!browser_ppapi_host_->GetRenderViewIDsForInstance(
61 pp_instance(), &render_process_id, &unused)) {
65 // Get the file system context asynchronously, and then complete the Open
66 // operation by calling |callback|.
67 BrowserThread::PostTaskAndReplyWithResult(
70 base::Bind(&GetFileSystemContextFromRenderId, render_process_id),
71 base::Bind(&PepperFileSystemBrowserHost::OpenExistingWithContext,
72 weak_factory_.GetWeakPtr(), callback));
75 PepperFileSystemBrowserHost::~PepperFileSystemBrowserHost() {
76 // TODO(teravest): Create a FileSystemOperationRunner
77 // per-PepperFileSystemBrowserHost, force users of this FileSystem to use it,
78 // and call Shutdown() on it here.
81 int32_t PepperFileSystemBrowserHost::OnResourceMessageReceived(
82 const IPC::Message& msg,
83 ppapi::host::HostMessageContext* context) {
84 IPC_BEGIN_MESSAGE_MAP(PepperFileSystemBrowserHost, msg)
85 PPAPI_DISPATCH_HOST_RESOURCE_CALL(
86 PpapiHostMsg_FileSystem_Open,
88 PPAPI_DISPATCH_HOST_RESOURCE_CALL(
89 PpapiHostMsg_FileSystem_InitIsolatedFileSystem,
90 OnHostMsgInitIsolatedFileSystem)
92 return PP_ERROR_FAILED;
95 bool PepperFileSystemBrowserHost::IsFileSystemHost() {
99 int32_t PepperFileSystemBrowserHost::OnHostMsgOpen(
100 ppapi::host::HostMessageContext* context,
101 int64_t /* unused */) {
102 // TODO(raymes): The file system size is now unused by FileSystemDispatcher.
103 // Figure out why. Why is the file system size signed?
105 // Not allow multiple opens.
107 return PP_ERROR_INPROGRESS;
110 fileapi::FileSystemType file_system_type;
112 case PP_FILESYSTEMTYPE_LOCALTEMPORARY:
113 file_system_type = fileapi::kFileSystemTypeTemporary;
115 case PP_FILESYSTEMTYPE_LOCALPERSISTENT:
116 file_system_type = fileapi::kFileSystemTypePersistent;
118 case PP_FILESYSTEMTYPE_EXTERNAL:
119 file_system_type = fileapi::kFileSystemTypeExternal;
122 return PP_ERROR_FAILED;
125 int render_process_id = 0;
127 if (!browser_ppapi_host_->GetRenderViewIDsForInstance(pp_instance(),
130 return PP_ERROR_FAILED;
132 BrowserThread::PostTaskAndReplyWithResult(
135 base::Bind(&GetFileSystemContextFromRenderId, render_process_id),
136 base::Bind(&PepperFileSystemBrowserHost::GotFileSystemContext,
137 weak_factory_.GetWeakPtr(),
138 context->MakeReplyMessageContext(),
140 return PP_OK_COMPLETIONPENDING;
143 void PepperFileSystemBrowserHost::OpenExistingWithContext(
144 const base::Closure& callback,
145 scoped_refptr<fileapi::FileSystemContext> fs_context) {
146 if (fs_context.get()) {
149 // If there is no file system context, we log a warning and continue with an
150 // invalid resource (which will produce errors when used), since we have no
151 // way to communicate the error to the caller.
152 LOG(WARNING) << "Could not retrieve file system context.";
154 fs_context_ = fs_context;
158 void PepperFileSystemBrowserHost::GotFileSystemContext(
159 ppapi::host::ReplyMessageContext reply_context,
160 fileapi::FileSystemType file_system_type,
161 scoped_refptr<fileapi::FileSystemContext> fs_context) {
162 if (!fs_context.get()) {
163 OpenFileSystemComplete(
164 reply_context, GURL(), std::string(), base::PLATFORM_FILE_ERROR_FAILED);
167 GURL origin = browser_ppapi_host_->GetDocumentURLForInstance(
168 pp_instance()).GetOrigin();
169 fs_context->OpenFileSystem(origin, file_system_type,
170 fileapi::OPEN_FILE_SYSTEM_CREATE_IF_NONEXISTENT,
171 base::Bind(&PepperFileSystemBrowserHost::OpenFileSystemComplete,
172 weak_factory_.GetWeakPtr(),
174 fs_context_ = fs_context;
177 void PepperFileSystemBrowserHost::GotIsolatedFileSystemContext(
178 ppapi::host::ReplyMessageContext reply_context,
179 scoped_refptr<fileapi::FileSystemContext> fs_context) {
180 fs_context_ = fs_context;
181 if (fs_context.get())
182 reply_context.params.set_result(PP_OK);
184 reply_context.params.set_result(PP_ERROR_FAILED);
185 host()->SendReply(reply_context,
186 PpapiPluginMsg_FileSystem_InitIsolatedFileSystemReply());
189 void PepperFileSystemBrowserHost::OpenFileSystemComplete(
190 ppapi::host::ReplyMessageContext reply_context,
192 const std::string& /* unused */,
193 base::PlatformFileError error) {
194 int32 pp_error = ppapi::PlatformFileErrorToPepperError(error);
195 if (pp_error == PP_OK) {
199 reply_context.params.set_result(pp_error);
200 host()->SendReply(reply_context, PpapiPluginMsg_FileSystem_OpenReply());
203 int32_t PepperFileSystemBrowserHost::OnHostMsgInitIsolatedFileSystem(
204 ppapi::host::HostMessageContext* context,
205 const std::string& fsid) {
206 // Do not allow multiple opens.
208 return PP_ERROR_INPROGRESS;
210 // Do a sanity check.
211 if (!fileapi::ValidateIsolatedFileSystemId(fsid))
212 return PP_ERROR_BADARGUMENT;
214 browser_ppapi_host_->GetDocumentURLForInstance(pp_instance());
215 root_url_ = GURL(fileapi::GetIsolatedFileSystemRootURIString(
216 url.GetOrigin(), fsid, "crxfs"));
219 int render_process_id = 0;
221 if (!browser_ppapi_host_->GetRenderViewIDsForInstance(pp_instance(),
224 return PP_ERROR_FAILED;
226 BrowserThread::PostTaskAndReplyWithResult(
229 base::Bind(&GetFileSystemContextFromRenderId, render_process_id),
230 base::Bind(&PepperFileSystemBrowserHost::GotIsolatedFileSystemContext,
231 weak_factory_.GetWeakPtr(),
232 context->MakeReplyMessageContext()));
233 return PP_OK_COMPLETIONPENDING;
236 } // namespace content