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"
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
;
26 PepperFileRefBackend::~PepperFileRefBackend() {}
28 PepperFileRefHost::PepperFileRefHost(BrowserPpapiHost
* host
,
31 PP_Resource file_system
,
32 const std::string
& path
)
33 : ResourceHost(host
->GetPpapiHost(), instance
, resource
),
35 fs_type_(PP_FILESYSTEMTYPE_INVALID
) {
36 if (!ppapi::IsValidInternalPath(path
))
39 int render_process_id
;
41 if (!host
->GetRenderFrameIDsForInstance(
42 instance
, &render_process_id
, &unused
)) {
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
54 if (!fs_resource_host
->IsFileSystemHost()) {
55 DLOG(ERROR
) << "Filesystem PP_Resource is not PepperFileSystemBrowserHost";
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_
;
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 "
77 backend_
.reset(new PepperInternalFileRefBackend(host
->GetPpapiHost(),
79 file_system_host
->AsWeakPtr(),
83 PepperFileRefHost::PepperFileRefHost(BrowserPpapiHost
* host
,
86 const base::FilePath
& external_path
)
87 : ResourceHost(host
->GetPpapiHost(), instance
, resource
),
89 fs_type_(PP_FILESYSTEMTYPE_EXTERNAL
) {
90 if (!ppapi::IsValidExternalPath(external_path
))
93 int render_process_id
;
95 if (!host
->GetRenderFrameIDsForInstance(
96 instance
, &render_process_id
, &unused
)) {
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 {
112 storage::FileSystemURL
PepperFileRefHost::GetFileSystemURL() const {
114 return backend_
->GetFileSystemURL();
115 return storage::FileSystemURL();
118 base::FilePath
PepperFileRefHost::GetExternalFilePath() const {
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 {
131 return backend_
->CanRead();
132 return PP_ERROR_FAILED
;
135 int32_t PepperFileRefHost::CanWrite() const {
137 return backend_
->CanWrite();
138 return PP_ERROR_FAILED
;
141 int32_t PepperFileRefHost::CanCreate() const {
143 return backend_
->CanCreate();
144 return PP_ERROR_FAILED
;
147 int32_t PepperFileRefHost::CanReadWrite() const {
149 return backend_
->CanReadWrite();
150 return PP_ERROR_FAILED
;
153 int32_t PepperFileRefHost::OnResourceMessageReceived(
154 const IPC::Message
& msg
,
155 ppapi::host::HostMessageContext
* context
) {
157 return PP_ERROR_FAILED
;
159 PPAPI_BEGIN_MESSAGE_MAP(PepperFileRefHost
, msg
)
160 PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_FileRef_MakeDirectory
,
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
,
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();
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();
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();
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();
209 ResourceHost
* resource_host
=
210 host_
->GetPpapiHost()->GetResourceHost(new_file_ref
);
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
);
218 return PP_ERROR_BADRESOURCE
;
220 rv
= file_ref_host
->CanCreate();
224 return backend_
->Rename(context
->MakeReplyMessageContext(), file_ref_host
);
227 int32_t PepperFileRefHost::OnQuery(ppapi::host::HostMessageContext
* context
) {
228 int32_t rv
= CanRead();
231 return backend_
->Query(context
->MakeReplyMessageContext());
234 int32_t PepperFileRefHost::OnReadDirectoryEntries(
235 ppapi::host::HostMessageContext
* context
) {
236 int32_t rv
= CanRead();
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