• 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_external_file_ref_backend.h"
6 
7 #include "base/files/file_path.h"
8 #include "base/files/file_util_proxy.h"
9 #include "content/browser/child_process_security_policy_impl.h"
10 #include "content/public/browser/browser_thread.h"
11 #include "ppapi/c/pp_errors.h"
12 #include "ppapi/c/pp_time.h"
13 #include "ppapi/host/ppapi_host.h"
14 #include "ppapi/proxy/ppapi_messages.h"
15 #include "ppapi/shared_impl/file_type_conversion.h"
16 #include "ppapi/shared_impl/time_conversion.h"
17 
18 namespace content {
19 
PepperExternalFileRefBackend(ppapi::host::PpapiHost * host,int render_process_id,const base::FilePath & path)20 PepperExternalFileRefBackend::PepperExternalFileRefBackend(
21     ppapi::host::PpapiHost* host,
22     int render_process_id,
23     const base::FilePath& path) : host_(host),
24                                   path_(path),
25                                   render_process_id_(render_process_id),
26                                   weak_factory_(this) {
27   task_runner_ =
28       BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE);
29 }
30 
~PepperExternalFileRefBackend()31 PepperExternalFileRefBackend::~PepperExternalFileRefBackend() {
32 }
33 
MakeDirectory(ppapi::host::ReplyMessageContext reply_context,bool make_ancestors)34 int32_t PepperExternalFileRefBackend::MakeDirectory(
35     ppapi::host::ReplyMessageContext reply_context,
36     bool make_ancestors) {
37   // This operation isn't supported for external filesystems.
38   return PP_ERROR_NOACCESS;
39 }
40 
Touch(ppapi::host::ReplyMessageContext reply_context,PP_Time last_access_time,PP_Time last_modified_time)41 int32_t PepperExternalFileRefBackend::Touch(
42     ppapi::host::ReplyMessageContext reply_context,
43     PP_Time last_access_time,
44     PP_Time last_modified_time) {
45   IPC::Message reply_msg = PpapiPluginMsg_FileRef_TouchReply();
46   base::FileUtilProxy::Touch(
47       task_runner_.get(),
48       path_,
49       ppapi::PPTimeToTime(last_access_time),
50       ppapi::PPTimeToTime(last_modified_time),
51       base::Bind(&PepperExternalFileRefBackend::DidFinish,
52                  weak_factory_.GetWeakPtr(),
53                  reply_context,
54                  reply_msg));
55   return PP_OK_COMPLETIONPENDING;
56 }
57 
Delete(ppapi::host::ReplyMessageContext reply_context)58 int32_t PepperExternalFileRefBackend::Delete(
59     ppapi::host::ReplyMessageContext reply_context) {
60   // This operation isn't supported for external filesystems.
61   return PP_ERROR_NOACCESS;
62 }
63 
Rename(ppapi::host::ReplyMessageContext reply_context,PepperFileRefHost * new_file_ref)64 int32_t PepperExternalFileRefBackend::Rename(
65     ppapi::host::ReplyMessageContext reply_context,
66     PepperFileRefHost* new_file_ref) {
67   // This operation isn't supported for external filesystems.
68   return PP_ERROR_NOACCESS;
69 }
70 
Query(ppapi::host::ReplyMessageContext reply_context)71 int32_t PepperExternalFileRefBackend::Query(
72     ppapi::host::ReplyMessageContext reply_context) {
73   bool ok = base::FileUtilProxy::GetFileInfo(
74       task_runner_.get(),
75       path_,
76       base::Bind(&PepperExternalFileRefBackend::GetMetadataComplete,
77                  weak_factory_.GetWeakPtr(),
78                  reply_context));
79   DCHECK(ok);
80   return PP_OK_COMPLETIONPENDING;
81 }
82 
ReadDirectoryEntries(ppapi::host::ReplyMessageContext context)83 int32_t PepperExternalFileRefBackend::ReadDirectoryEntries(
84     ppapi::host::ReplyMessageContext context) {
85   // This operation isn't supported for external filesystems.
86   return PP_ERROR_NOACCESS;
87 }
88 
GetAbsolutePath(ppapi::host::ReplyMessageContext reply_context)89 int32_t PepperExternalFileRefBackend::GetAbsolutePath(
90     ppapi::host::ReplyMessageContext reply_context) {
91   host_->SendReply(reply_context,
92       PpapiPluginMsg_FileRef_GetAbsolutePathReply(path_.AsUTF8Unsafe()));
93 
94   // Use PP_OK_COMPLETIONPENDING instead of PP_OK since we've already sent our
95   // reply above.
96   return PP_OK_COMPLETIONPENDING;
97 }
98 
GetFileSystemURL() const99 fileapi::FileSystemURL PepperExternalFileRefBackend::GetFileSystemURL() const {
100   return fileapi::FileSystemURL();
101 }
102 
GetExternalFilePath() const103 base::FilePath PepperExternalFileRefBackend::GetExternalFilePath() const {
104   return path_;
105 }
106 
CanRead() const107 int32_t PepperExternalFileRefBackend::CanRead() const {
108   if (!ChildProcessSecurityPolicyImpl::GetInstance()->
109           CanReadFile(render_process_id_, path_)) {
110     return PP_ERROR_NOACCESS;
111   }
112   return PP_OK;
113 }
114 
CanWrite() const115 int32_t PepperExternalFileRefBackend::CanWrite() const {
116   // Platform files have coarse-grained grants in ChildProcessSecurityPolicy.
117   return CanReadWrite();
118 }
119 
CanCreate() const120 int32_t PepperExternalFileRefBackend::CanCreate() const {
121   // Platform files have coarse-grained grants in ChildProcessSecurityPolicy.
122   return CanReadWrite();
123 }
124 
CanReadWrite() const125 int32_t PepperExternalFileRefBackend::CanReadWrite() const {
126   if (!ChildProcessSecurityPolicyImpl::GetInstance()->
127           CanCreateReadWriteFile(render_process_id_, path_)) {
128     return PP_ERROR_NOACCESS;
129   }
130   return PP_OK;
131 }
132 
DidFinish(ppapi::host::ReplyMessageContext reply_context,const IPC::Message & msg,base::PlatformFileError error)133 void PepperExternalFileRefBackend::DidFinish(
134     ppapi::host::ReplyMessageContext reply_context,
135     const IPC::Message& msg,
136     base::PlatformFileError error) {
137   reply_context.params.set_result(ppapi::PlatformFileErrorToPepperError(error));
138   host_->SendReply(reply_context, msg);
139 }
140 
GetMetadataComplete(ppapi::host::ReplyMessageContext reply_context,const base::PlatformFileError error,const base::PlatformFileInfo & file_info)141 void PepperExternalFileRefBackend::GetMetadataComplete(
142     ppapi::host::ReplyMessageContext reply_context,
143     const base::PlatformFileError error,
144     const base::PlatformFileInfo& file_info) {
145   reply_context.params.set_result(ppapi::PlatformFileErrorToPepperError(error));
146 
147   PP_FileInfo pp_file_info;
148   if (error == base::PLATFORM_FILE_OK) {
149     ppapi::PlatformFileInfoToPepperFileInfo(
150         file_info, PP_FILESYSTEMTYPE_EXTERNAL, &pp_file_info);
151   } else {
152     memset(&pp_file_info, 0, sizeof(pp_file_info));
153   }
154 
155   host_->SendReply(reply_context,
156                    PpapiPluginMsg_FileRef_QueryReply(pp_file_info));
157 }
158 
159 }  // namespace content
160