IndexedDBFactory now ForceCloses databases.
[chromium-blink-merge.git] / content / browser / renderer_host / pepper / pepper_internal_file_ref_backend.cc
blob3d191461c436ff501e558e0efcae16fdbc82b413
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_internal_file_ref_backend.h"
7 #include <string>
9 #include "base/callback.h"
10 #include "base/file_util.h"
11 #include "base/files/file_util_proxy.h"
12 #include "content/browser/child_process_security_policy_impl.h"
13 #include "content/browser/fileapi/browser_file_system_helper.h"
14 #include "content/browser/renderer_host/pepper/pepper_file_system_browser_host.h"
15 #include "content/public/browser/browser_context.h"
16 #include "content/public/browser/browser_thread.h"
17 #include "content/public/browser/render_process_host.h"
18 #include "content/public/browser/storage_partition.h"
19 #include "net/base/escape.h"
20 #include "ppapi/c/pp_errors.h"
21 #include "ppapi/c/pp_file_info.h"
22 #include "ppapi/c/pp_instance.h"
23 #include "ppapi/c/pp_resource.h"
24 #include "ppapi/c/ppb_file_ref.h"
25 #include "ppapi/host/dispatch_host_message.h"
26 #include "ppapi/host/ppapi_host.h"
27 #include "ppapi/proxy/ppapi_messages.h"
28 #include "ppapi/shared_impl/file_ref_create_info.h"
29 #include "ppapi/shared_impl/file_ref_util.h"
30 #include "ppapi/shared_impl/file_type_conversion.h"
31 #include "ppapi/shared_impl/scoped_pp_var.h"
32 #include "ppapi/shared_impl/time_conversion.h"
33 #include "ppapi/shared_impl/var.h"
34 #include "ppapi/thunk/enter.h"
35 #include "ppapi/thunk/ppb_file_ref_api.h"
36 #include "ppapi/thunk/ppb_file_system_api.h"
37 #include "webkit/browser/fileapi/file_system_operation.h"
38 #include "webkit/browser/fileapi/file_system_operation_runner.h"
39 #include "webkit/browser/fileapi/file_system_url.h"
40 #include "webkit/common/fileapi/file_system_util.h"
42 using ppapi::host::PpapiHost;
43 using ppapi::host::ResourceHost;
45 namespace content {
47 PepperInternalFileRefBackend::PepperInternalFileRefBackend(
48 PpapiHost* host,
49 int render_process_id,
50 base::WeakPtr<PepperFileSystemBrowserHost> fs_host,
51 const std::string& path) : host_(host),
52 render_process_id_(render_process_id),
53 fs_host_(fs_host),
54 fs_type_(fs_host->GetType()),
55 path_(path),
56 weak_factory_(this) {
57 ppapi::NormalizeInternalPath(&path_);
60 PepperInternalFileRefBackend::~PepperInternalFileRefBackend() {
63 fileapi::FileSystemURL PepperInternalFileRefBackend::GetFileSystemURL() const {
64 if (!fs_url_.is_valid() && fs_host_.get() && fs_host_->IsOpened()) {
65 GURL fs_path = fs_host_->GetRootUrl().Resolve(
66 net::EscapePath(path_.substr(1)));
67 scoped_refptr<fileapi::FileSystemContext> fs_context =
68 GetFileSystemContext();
69 if (fs_context.get())
70 fs_url_ = fs_context->CrackURL(fs_path);
72 return fs_url_;
75 base::FilePath PepperInternalFileRefBackend::GetExternalFilePath() const {
76 return base::FilePath();
79 scoped_refptr<fileapi::FileSystemContext>
80 PepperInternalFileRefBackend::GetFileSystemContext() const {
81 if (!fs_host_.get())
82 return NULL;
83 return fs_host_->GetFileSystemContext();
86 void PepperInternalFileRefBackend::DidFinish(
87 ppapi::host::ReplyMessageContext context,
88 const IPC::Message& msg,
89 base::PlatformFileError error) {
90 context.params.set_result(ppapi::PlatformFileErrorToPepperError(error));
91 host_->SendReply(context, msg);
94 int32_t PepperInternalFileRefBackend::MakeDirectory(
95 ppapi::host::ReplyMessageContext reply_context,
96 int32_t make_directory_flags) {
97 if (!GetFileSystemURL().is_valid())
98 return PP_ERROR_FAILED;
100 GetFileSystemContext()->operation_runner()->CreateDirectory(
101 GetFileSystemURL(),
102 !!(make_directory_flags & PP_MAKEDIRECTORYFLAG_EXCLUSIVE),
103 !!(make_directory_flags & PP_MAKEDIRECTORYFLAG_WITH_ANCESTORS),
104 base::Bind(&PepperInternalFileRefBackend::DidFinish,
105 weak_factory_.GetWeakPtr(),
106 reply_context,
107 PpapiPluginMsg_FileRef_MakeDirectoryReply()));
108 return PP_OK_COMPLETIONPENDING;
111 int32_t PepperInternalFileRefBackend::Touch(
112 ppapi::host::ReplyMessageContext reply_context,
113 PP_Time last_access_time,
114 PP_Time last_modified_time) {
115 if (!GetFileSystemURL().is_valid())
116 return PP_ERROR_FAILED;
118 GetFileSystemContext()->operation_runner()->TouchFile(
119 GetFileSystemURL(),
120 ppapi::PPTimeToTime(last_access_time),
121 ppapi::PPTimeToTime(last_modified_time),
122 base::Bind(&PepperInternalFileRefBackend::DidFinish,
123 weak_factory_.GetWeakPtr(),
124 reply_context,
125 PpapiPluginMsg_FileRef_TouchReply()));
126 return PP_OK_COMPLETIONPENDING;
129 int32_t PepperInternalFileRefBackend::Delete(
130 ppapi::host::ReplyMessageContext reply_context) {
131 if (!GetFileSystemURL().is_valid())
132 return PP_ERROR_FAILED;
134 GetFileSystemContext()->operation_runner()->Remove(
135 GetFileSystemURL(),
136 false,
137 base::Bind(&PepperInternalFileRefBackend::DidFinish,
138 weak_factory_.GetWeakPtr(),
139 reply_context,
140 PpapiPluginMsg_FileRef_DeleteReply()));
141 return PP_OK_COMPLETIONPENDING;
144 int32_t PepperInternalFileRefBackend::Rename(
145 ppapi::host::ReplyMessageContext reply_context,
146 PepperFileRefHost* new_file_ref) {
147 if (!GetFileSystemURL().is_valid())
148 return PP_ERROR_FAILED;
150 fileapi::FileSystemURL new_url = new_file_ref->GetFileSystemURL();
151 if (!new_url.is_valid())
152 return PP_ERROR_FAILED;
153 if (!new_url.IsInSameFileSystem(GetFileSystemURL()))
154 return PP_ERROR_FAILED;
156 GetFileSystemContext()->operation_runner()->Move(
157 GetFileSystemURL(),
158 new_url,
159 fileapi::FileSystemOperation::OPTION_NONE,
160 base::Bind(&PepperInternalFileRefBackend::DidFinish,
161 weak_factory_.GetWeakPtr(),
162 reply_context,
163 PpapiPluginMsg_FileRef_RenameReply()));
164 return PP_OK_COMPLETIONPENDING;
167 int32_t PepperInternalFileRefBackend::Query(
168 ppapi::host::ReplyMessageContext reply_context) {
169 if (!GetFileSystemURL().is_valid())
170 return PP_ERROR_FAILED;
172 GetFileSystemContext()->operation_runner()->GetMetadata(
173 GetFileSystemURL(),
174 base::Bind(&PepperInternalFileRefBackend::GetMetadataComplete,
175 weak_factory_.GetWeakPtr(),
176 reply_context));
177 return PP_OK_COMPLETIONPENDING;
180 void PepperInternalFileRefBackend::GetMetadataComplete(
181 ppapi::host::ReplyMessageContext reply_context,
182 base::PlatformFileError error,
183 const base::PlatformFileInfo& file_info) {
184 reply_context.params.set_result(ppapi::PlatformFileErrorToPepperError(error));
186 PP_FileInfo pp_file_info;
187 if (error == base::PLATFORM_FILE_OK)
188 ppapi::PlatformFileInfoToPepperFileInfo(file_info, fs_type_, &pp_file_info);
189 else
190 memset(&pp_file_info, 0, sizeof(pp_file_info));
192 host_->SendReply(reply_context,
193 PpapiPluginMsg_FileRef_QueryReply(pp_file_info));
196 int32_t PepperInternalFileRefBackend::ReadDirectoryEntries(
197 ppapi::host::ReplyMessageContext reply_context) {
198 if (!GetFileSystemURL().is_valid())
199 return PP_ERROR_FAILED;
201 GetFileSystemContext()->operation_runner()->ReadDirectory(
202 GetFileSystemURL(),
203 base::Bind(&PepperInternalFileRefBackend::ReadDirectoryComplete,
204 weak_factory_.GetWeakPtr(),
205 reply_context));
206 return PP_OK_COMPLETIONPENDING;
209 void PepperInternalFileRefBackend::ReadDirectoryComplete(
210 ppapi::host::ReplyMessageContext context,
211 base::PlatformFileError error,
212 const fileapi::FileSystemOperation::FileEntryList& file_list,
213 bool has_more) {
214 // The current filesystem backend always returns false.
215 DCHECK(!has_more);
217 context.params.set_result(ppapi::PlatformFileErrorToPepperError(error));
219 std::vector<ppapi::FileRefCreateInfo> infos;
220 std::vector<PP_FileType> file_types;
221 if (error == base::PLATFORM_FILE_OK && fs_host_.get()) {
222 std::string dir_path = path_;
223 if (dir_path.empty() || dir_path[dir_path.size() - 1] != '/')
224 dir_path += '/';
226 for (fileapi::FileSystemOperation::FileEntryList::const_iterator it =
227 file_list.begin(); it != file_list.end(); ++it) {
228 if (it->is_directory)
229 file_types.push_back(PP_FILETYPE_DIRECTORY);
230 else
231 file_types.push_back(PP_FILETYPE_REGULAR);
233 ppapi::FileRefCreateInfo info;
234 info.file_system_type = fs_type_;
235 info.file_system_plugin_resource = fs_host_->pp_resource();
236 std::string path =
237 dir_path + fileapi::FilePathToString(base::FilePath(it->name));
238 info.internal_path = path;
239 info.display_name = ppapi::GetNameForInternalFilePath(path);
240 infos.push_back(info);
244 host_->SendReply(context,
245 PpapiPluginMsg_FileRef_ReadDirectoryEntriesReply(infos, file_types));
248 int32_t PepperInternalFileRefBackend::GetAbsolutePath(
249 ppapi::host::ReplyMessageContext reply_context) {
250 host_->SendReply(reply_context,
251 PpapiPluginMsg_FileRef_GetAbsolutePathReply(path_));
252 return PP_OK_COMPLETIONPENDING;
255 int32_t PepperInternalFileRefBackend::CanRead() const {
256 fileapi::FileSystemURL url = GetFileSystemURL();
257 if (!FileSystemURLIsValid(GetFileSystemContext().get(), url))
258 return PP_ERROR_FAILED;
259 if (!ChildProcessSecurityPolicyImpl::GetInstance()->
260 CanReadFileSystemFile(render_process_id_, url)) {
261 return PP_ERROR_NOACCESS;
263 return PP_OK;
266 int32_t PepperInternalFileRefBackend::CanWrite() const {
267 fileapi::FileSystemURL url = GetFileSystemURL();
268 if (!FileSystemURLIsValid(GetFileSystemContext().get(), url))
269 return PP_ERROR_FAILED;
270 if (!ChildProcessSecurityPolicyImpl::GetInstance()->
271 CanWriteFileSystemFile(render_process_id_, url)) {
272 return PP_ERROR_NOACCESS;
274 return PP_OK;
277 int32_t PepperInternalFileRefBackend::CanCreate() const {
278 fileapi::FileSystemURL url = GetFileSystemURL();
279 if (!FileSystemURLIsValid(GetFileSystemContext().get(), url))
280 return PP_ERROR_FAILED;
281 if (!ChildProcessSecurityPolicyImpl::GetInstance()->
282 CanCreateFileSystemFile(render_process_id_, url)) {
283 return PP_ERROR_NOACCESS;
285 return PP_OK;
288 int32_t PepperInternalFileRefBackend::CanReadWrite() const {
289 fileapi::FileSystemURL url = GetFileSystemURL();
290 if (!FileSystemURLIsValid(GetFileSystemContext().get(), url))
291 return PP_ERROR_FAILED;
292 ChildProcessSecurityPolicyImpl* policy =
293 ChildProcessSecurityPolicyImpl::GetInstance();
294 if (!policy->CanReadFileSystemFile(render_process_id_, url) ||
295 !policy->CanWriteFileSystemFile(render_process_id_, url)) {
296 return PP_ERROR_NOACCESS;
298 return PP_OK;
301 } // namespace content