• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
4 
5 #include "content/browser/renderer_host/pepper/pepper_file_ref_host.h"
6 
7 #include <string>
8 
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 "webkit/browser/fileapi/file_permission_policy.h"
21 
22 using ppapi::host::ResourceHost;
23 
24 namespace content {
25 
~PepperFileRefBackend()26 PepperFileRefBackend::~PepperFileRefBackend() {
27 }
28 
PepperFileRefHost(BrowserPpapiHost * host,PP_Instance instance,PP_Resource resource,PP_Resource file_system,const std::string & path)29 PepperFileRefHost::PepperFileRefHost(BrowserPpapiHost* host,
30                                      PP_Instance instance,
31                                      PP_Resource resource,
32                                      PP_Resource file_system,
33                                      const std::string& path)
34     : ResourceHost(host->GetPpapiHost(), instance, resource),
35       host_(host),
36       fs_type_(PP_FILESYSTEMTYPE_INVALID) {
37   if (!ppapi::IsValidInternalPath(path))
38     return;
39 
40   int render_process_id;
41   int unused;
42   if (!host->GetRenderViewIDsForInstance(instance,
43                                          &render_process_id,
44                                          &unused)) {
45     return;
46   }
47 
48   ResourceHost* fs_resource_host =
49       host->GetPpapiHost()->GetResourceHost(file_system);
50   if (fs_resource_host == NULL) {
51     DLOG(ERROR) << "Couldn't find FileSystem host: " << resource
52                 << " path: " << path;
53     return;
54   }
55 
56   if (!fs_resource_host->IsFileSystemHost()) {
57     DLOG(ERROR) << "Filesystem PP_Resource is not PepperFileSystemBrowserHost";
58     return;
59   }
60 
61   PepperFileSystemBrowserHost* file_system_host =
62       static_cast<PepperFileSystemBrowserHost*>(fs_resource_host);
63   file_system_host_ = file_system_host->AsWeakPtr();
64   fs_type_ = file_system_host->GetType();
65   if ((fs_type_ != PP_FILESYSTEMTYPE_LOCALPERSISTENT) &&
66       (fs_type_ != PP_FILESYSTEMTYPE_LOCALTEMPORARY) &&
67       (fs_type_ != PP_FILESYSTEMTYPE_ISOLATED)) {
68     DLOG(ERROR) << "Unsupported filesystem type: " << fs_type_;
69     return;
70   }
71 
72   backend_.reset(new PepperInternalFileRefBackend(
73       host->GetPpapiHost(),
74       render_process_id,
75       file_system_host->AsWeakPtr(),
76       path));
77 }
78 
PepperFileRefHost(BrowserPpapiHost * host,PP_Instance instance,PP_Resource resource,const base::FilePath & external_path)79 PepperFileRefHost::PepperFileRefHost(BrowserPpapiHost* host,
80                                      PP_Instance instance,
81                                      PP_Resource resource,
82                                      const base::FilePath& external_path)
83     : ResourceHost(host->GetPpapiHost(), instance, resource),
84       host_(host),
85       fs_type_(PP_FILESYSTEMTYPE_EXTERNAL) {
86   if (!ppapi::IsValidExternalPath(external_path))
87     return;
88 
89   int render_process_id;
90   int unused;
91   if (!host->GetRenderViewIDsForInstance(instance,
92                                          &render_process_id,
93                                          &unused)) {
94     return;
95   }
96 
97   backend_.reset(new PepperExternalFileRefBackend(host->GetPpapiHost(),
98                                                   render_process_id,
99                                                   external_path));
100 }
101 
~PepperFileRefHost()102 PepperFileRefHost::~PepperFileRefHost() {
103 }
104 
IsFileRefHost()105 bool PepperFileRefHost::IsFileRefHost() {
106   return true;
107 }
108 
GetFileSystemType() const109 PP_FileSystemType PepperFileRefHost::GetFileSystemType() const {
110   return fs_type_;
111 }
112 
GetFileSystemURL() const113 fileapi::FileSystemURL PepperFileRefHost::GetFileSystemURL() const {
114   if (backend_)
115     return backend_->GetFileSystemURL();
116   return fileapi::FileSystemURL();
117 }
118 
GetExternalFilePath() const119 base::FilePath PepperFileRefHost::GetExternalFilePath() const {
120   if (backend_)
121     return backend_->GetExternalFilePath();
122   return base::FilePath();
123 }
124 
125 base::WeakPtr<PepperFileSystemBrowserHost>
GetFileSystemHost() const126 PepperFileRefHost::GetFileSystemHost() const {
127   return file_system_host_;
128 }
129 
CanRead() const130 int32_t PepperFileRefHost::CanRead() const {
131   if (backend_)
132     return backend_->CanRead();
133   return PP_ERROR_FAILED;
134 }
135 
CanWrite() const136 int32_t PepperFileRefHost::CanWrite() const {
137   if (backend_)
138     return backend_->CanWrite();
139   return PP_ERROR_FAILED;
140 }
141 
CanCreate() const142 int32_t PepperFileRefHost::CanCreate() const {
143   if (backend_)
144     return backend_->CanCreate();
145   return PP_ERROR_FAILED;
146 }
147 
CanReadWrite() const148 int32_t PepperFileRefHost::CanReadWrite() const {
149   if (backend_)
150     return backend_->CanReadWrite();
151   return PP_ERROR_FAILED;
152 }
153 
OnResourceMessageReceived(const IPC::Message & msg,ppapi::host::HostMessageContext * context)154 int32_t PepperFileRefHost::OnResourceMessageReceived(
155     const IPC::Message& msg,
156     ppapi::host::HostMessageContext* context) {
157   if (!backend_)
158     return PP_ERROR_FAILED;
159 
160   IPC_BEGIN_MESSAGE_MAP(PepperFileRefHost, msg)
161     PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_FileRef_MakeDirectory,
162                                       OnMakeDirectory);
163     PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_FileRef_Touch,
164                                       OnTouch);
165     PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_FileRef_Delete,
166                                         OnDelete);
167     PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_FileRef_Rename,
168                                       OnRename);
169     PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_FileRef_Query,
170                                         OnQuery);
171     PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(
172         PpapiHostMsg_FileRef_ReadDirectoryEntries,
173         OnReadDirectoryEntries);
174     PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_FileRef_GetAbsolutePath,
175                                         OnGetAbsolutePath);
176 
177   IPC_END_MESSAGE_MAP()
178   return PP_ERROR_FAILED;
179 }
180 
OnMakeDirectory(ppapi::host::HostMessageContext * context,bool make_ancestors)181 int32_t PepperFileRefHost::OnMakeDirectory(
182     ppapi::host::HostMessageContext* context,
183     bool make_ancestors) {
184   int32_t rv = CanCreate();
185   if (rv != PP_OK)
186     return rv;
187   return backend_->MakeDirectory(context->MakeReplyMessageContext(),
188                                  make_ancestors);
189 }
190 
OnTouch(ppapi::host::HostMessageContext * context,PP_Time last_access_time,PP_Time last_modified_time)191 int32_t PepperFileRefHost::OnTouch(ppapi::host::HostMessageContext* context,
192                                    PP_Time last_access_time,
193                                    PP_Time last_modified_time) {
194   // TODO(teravest): Change this to be kWriteFilePermissions here and in
195   // fileapi_message_filter.
196   int32_t rv = CanCreate();
197   if (rv != PP_OK)
198     return rv;
199   return backend_->Touch(context->MakeReplyMessageContext(),
200                          last_access_time,
201                          last_modified_time);
202 }
203 
OnDelete(ppapi::host::HostMessageContext * context)204 int32_t PepperFileRefHost::OnDelete(ppapi::host::HostMessageContext* context) {
205   int32_t rv = CanWrite();
206   if (rv != PP_OK)
207     return rv;
208   return backend_->Delete(context->MakeReplyMessageContext());
209 }
210 
OnRename(ppapi::host::HostMessageContext * context,PP_Resource new_file_ref)211 int32_t PepperFileRefHost::OnRename(ppapi::host::HostMessageContext* context,
212                                     PP_Resource new_file_ref) {
213   int32_t rv = CanReadWrite();
214   if (rv != PP_OK)
215     return rv;
216 
217   ResourceHost* resource_host =
218       host_->GetPpapiHost()->GetResourceHost(new_file_ref);
219   if (!resource_host)
220     return PP_ERROR_BADRESOURCE;
221 
222   PepperFileRefHost* file_ref_host = NULL;
223   if (resource_host->IsFileRefHost())
224     file_ref_host = static_cast<PepperFileRefHost*>(resource_host);
225   if (!file_ref_host)
226     return PP_ERROR_BADRESOURCE;
227 
228   rv = file_ref_host->CanCreate();
229   if (rv != PP_OK)
230     return rv;
231 
232   return backend_->Rename(context->MakeReplyMessageContext(),
233                           file_ref_host);
234 }
235 
OnQuery(ppapi::host::HostMessageContext * context)236 int32_t PepperFileRefHost::OnQuery(ppapi::host::HostMessageContext* context) {
237   int32_t rv = CanRead();
238   if (rv != PP_OK)
239     return rv;
240   return backend_->Query(context->MakeReplyMessageContext());
241 }
242 
OnReadDirectoryEntries(ppapi::host::HostMessageContext * context)243 int32_t PepperFileRefHost::OnReadDirectoryEntries(
244     ppapi::host::HostMessageContext* context) {
245   int32_t rv = CanRead();
246   if (rv != PP_OK)
247     return rv;
248   return backend_->ReadDirectoryEntries(context->MakeReplyMessageContext());
249 }
250 
OnGetAbsolutePath(ppapi::host::HostMessageContext * context)251 int32_t PepperFileRefHost::OnGetAbsolutePath(
252     ppapi::host::HostMessageContext* context) {
253   if (!host_->GetPpapiHost()->permissions().HasPermission(
254       ppapi::PERMISSION_PRIVATE))
255     return PP_ERROR_NOACCESS;
256   return backend_->GetAbsolutePath(context->MakeReplyMessageContext());
257 }
258 
259 }  // namespace content
260