Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / content / browser / renderer_host / pepper / pepper_file_ref_host.cc
blob6a1d9affe235f485f7041641a6f7777444c2020b
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_ref_host.h"
7 #include <string>
9 #include "content/browser/renderer_host/pepper/pepper_external_file_ref_backend.h"
10 #include "content/browser/renderer_host/pepper/pepper_file_system_browser_host.h"
11 #include "content/browser/renderer_host/pepper/pepper_internal_file_ref_backend.h"
12 #include "ppapi/c/pp_errors.h"
13 #include "ppapi/c/pp_file_info.h"
14 #include "ppapi/c/pp_instance.h"
15 #include "ppapi/c/pp_resource.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_ref_util.h"
20 #include "storage/browser/fileapi/file_permission_policy.h"
22 using ppapi::host::ResourceHost;
24 namespace content {
26 PepperFileRefBackend::~PepperFileRefBackend() {}
28 PepperFileRefHost::PepperFileRefHost(BrowserPpapiHost* host,
29 PP_Instance instance,
30 PP_Resource resource,
31 PP_Resource file_system,
32 const std::string& path)
33 : ResourceHost(host->GetPpapiHost(), instance, resource),
34 host_(host),
35 fs_type_(PP_FILESYSTEMTYPE_INVALID) {
36 if (!ppapi::IsValidInternalPath(path))
37 return;
39 int render_process_id;
40 int unused;
41 if (!host->GetRenderFrameIDsForInstance(
42 instance, &render_process_id, &unused)) {
43 return;
46 ResourceHost* fs_resource_host =
47 host->GetPpapiHost()->GetResourceHost(file_system);
48 if (fs_resource_host == NULL) {
49 DLOG(ERROR) << "Couldn't find FileSystem host: " << resource
50 << " path: " << path;
51 return;
54 if (!fs_resource_host->IsFileSystemHost()) {
55 DLOG(ERROR) << "Filesystem PP_Resource is not PepperFileSystemBrowserHost";
56 return;
59 PepperFileSystemBrowserHost* file_system_host =
60 static_cast<PepperFileSystemBrowserHost*>(fs_resource_host);
61 file_system_host_ = file_system_host->AsWeakPtr();
62 fs_type_ = file_system_host->GetType();
63 if ((fs_type_ != PP_FILESYSTEMTYPE_LOCALPERSISTENT) &&
64 (fs_type_ != PP_FILESYSTEMTYPE_LOCALTEMPORARY) &&
65 (fs_type_ != PP_FILESYSTEMTYPE_EXTERNAL) &&
66 (fs_type_ != PP_FILESYSTEMTYPE_ISOLATED)) {
67 DLOG(ERROR) << "Unsupported filesystem type: " << fs_type_;
68 return;
70 if ((fs_type_ == PP_FILESYSTEMTYPE_EXTERNAL) &&
71 (!file_system_host->GetRootUrl().is_valid())) {
72 DLOG(ERROR) << "Native external filesystems are not supported by this "
73 << "constructor.";
74 return;
77 backend_.reset(new PepperInternalFileRefBackend(host->GetPpapiHost(),
78 render_process_id,
79 file_system_host->AsWeakPtr(),
80 path));
83 PepperFileRefHost::PepperFileRefHost(BrowserPpapiHost* host,
84 PP_Instance instance,
85 PP_Resource resource,
86 const base::FilePath& external_path)
87 : ResourceHost(host->GetPpapiHost(), instance, resource),
88 host_(host),
89 fs_type_(PP_FILESYSTEMTYPE_EXTERNAL) {
90 if (!ppapi::IsValidExternalPath(external_path))
91 return;
93 int render_process_id;
94 int unused;
95 if (!host->GetRenderFrameIDsForInstance(
96 instance, &render_process_id, &unused)) {
97 return;
100 backend_.reset(new PepperExternalFileRefBackend(
101 host->GetPpapiHost(), render_process_id, external_path));
104 PepperFileRefHost::~PepperFileRefHost() {}
106 bool PepperFileRefHost::IsFileRefHost() { return true; }
108 PP_FileSystemType PepperFileRefHost::GetFileSystemType() const {
109 return fs_type_;
112 storage::FileSystemURL PepperFileRefHost::GetFileSystemURL() const {
113 if (backend_)
114 return backend_->GetFileSystemURL();
115 return storage::FileSystemURL();
118 base::FilePath PepperFileRefHost::GetExternalFilePath() const {
119 if (backend_)
120 return backend_->GetExternalFilePath();
121 return base::FilePath();
124 base::WeakPtr<PepperFileSystemBrowserHost>
125 PepperFileRefHost::GetFileSystemHost() const {
126 return file_system_host_;
129 int32_t PepperFileRefHost::CanRead() const {
130 if (backend_)
131 return backend_->CanRead();
132 return PP_ERROR_FAILED;
135 int32_t PepperFileRefHost::CanWrite() const {
136 if (backend_)
137 return backend_->CanWrite();
138 return PP_ERROR_FAILED;
141 int32_t PepperFileRefHost::CanCreate() const {
142 if (backend_)
143 return backend_->CanCreate();
144 return PP_ERROR_FAILED;
147 int32_t PepperFileRefHost::CanReadWrite() const {
148 if (backend_)
149 return backend_->CanReadWrite();
150 return PP_ERROR_FAILED;
153 int32_t PepperFileRefHost::OnResourceMessageReceived(
154 const IPC::Message& msg,
155 ppapi::host::HostMessageContext* context) {
156 if (!backend_)
157 return PP_ERROR_FAILED;
159 PPAPI_BEGIN_MESSAGE_MAP(PepperFileRefHost, msg)
160 PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_FileRef_MakeDirectory,
161 OnMakeDirectory)
162 PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_FileRef_Touch, OnTouch)
163 PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_FileRef_Delete, OnDelete)
164 PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_FileRef_Rename, OnRename)
165 PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_FileRef_Query, OnQuery)
166 PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(
167 PpapiHostMsg_FileRef_ReadDirectoryEntries, OnReadDirectoryEntries)
168 PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_FileRef_GetAbsolutePath,
169 OnGetAbsolutePath)
170 PPAPI_END_MESSAGE_MAP()
171 return PP_ERROR_FAILED;
174 int32_t PepperFileRefHost::OnMakeDirectory(
175 ppapi::host::HostMessageContext* context,
176 int32_t make_directory_flags) {
177 int32_t rv = CanCreate();
178 if (rv != PP_OK)
179 return rv;
180 return backend_->MakeDirectory(context->MakeReplyMessageContext(),
181 make_directory_flags);
184 int32_t PepperFileRefHost::OnTouch(ppapi::host::HostMessageContext* context,
185 PP_Time last_access_time,
186 PP_Time last_modified_time) {
187 // TODO(teravest): Change this to be kWriteFilePermissions here and in
188 // fileapi_message_filter.
189 int32_t rv = CanCreate();
190 if (rv != PP_OK)
191 return rv;
192 return backend_->Touch(
193 context->MakeReplyMessageContext(), last_access_time, last_modified_time);
196 int32_t PepperFileRefHost::OnDelete(ppapi::host::HostMessageContext* context) {
197 int32_t rv = CanWrite();
198 if (rv != PP_OK)
199 return rv;
200 return backend_->Delete(context->MakeReplyMessageContext());
203 int32_t PepperFileRefHost::OnRename(ppapi::host::HostMessageContext* context,
204 PP_Resource new_file_ref) {
205 int32_t rv = CanReadWrite();
206 if (rv != PP_OK)
207 return rv;
209 ResourceHost* resource_host =
210 host_->GetPpapiHost()->GetResourceHost(new_file_ref);
211 if (!resource_host)
212 return PP_ERROR_BADRESOURCE;
214 PepperFileRefHost* file_ref_host = NULL;
215 if (resource_host->IsFileRefHost())
216 file_ref_host = static_cast<PepperFileRefHost*>(resource_host);
217 if (!file_ref_host)
218 return PP_ERROR_BADRESOURCE;
220 rv = file_ref_host->CanCreate();
221 if (rv != PP_OK)
222 return rv;
224 return backend_->Rename(context->MakeReplyMessageContext(), file_ref_host);
227 int32_t PepperFileRefHost::OnQuery(ppapi::host::HostMessageContext* context) {
228 int32_t rv = CanRead();
229 if (rv != PP_OK)
230 return rv;
231 return backend_->Query(context->MakeReplyMessageContext());
234 int32_t PepperFileRefHost::OnReadDirectoryEntries(
235 ppapi::host::HostMessageContext* context) {
236 int32_t rv = CanRead();
237 if (rv != PP_OK)
238 return rv;
239 return backend_->ReadDirectoryEntries(context->MakeReplyMessageContext());
242 int32_t PepperFileRefHost::OnGetAbsolutePath(
243 ppapi::host::HostMessageContext* context) {
244 if (!host_->GetPpapiHost()->permissions().HasPermission(
245 ppapi::PERMISSION_PRIVATE))
246 return PP_ERROR_NOACCESS;
247 return backend_->GetAbsolutePath(context->MakeReplyMessageContext());
250 } // namespace content