Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(136)

Side by Side Diff: ppapi/proxy/ppb_file_io_proxy.cc

Issue 8764003: Implement a proxy for Pepper FileIO. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Homestarmy Created 9 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « ppapi/proxy/ppb_file_io_proxy.h ('k') | ppapi/proxy/ppb_file_ref_proxy.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2011 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 "ppapi/proxy/ppb_file_io_proxy.h"
6
7 #include "ppapi/c/pp_errors.h"
8 #include "ppapi/proxy/enter_proxy.h"
9 #include "ppapi/proxy/ppapi_messages.h"
10 #include "ppapi/proxy/ppb_file_ref_proxy.h"
11 #include "ppapi/shared_impl/ppapi_globals.h"
12 #include "ppapi/shared_impl/ppb_file_io_shared.h"
13 #include "ppapi/shared_impl/resource.h"
14 #include "ppapi/shared_impl/resource_tracker.h"
15
16 using ppapi::thunk::PPB_FileIO_API;
17 using ppapi::thunk::PPB_FileRef_API;
18
19 namespace ppapi {
20 namespace proxy {
21
22 namespace {
23
24 // The maximum size we'll support reading in one chunk. The renderer process
25 // must allocate a buffer sized according to the request of the plugin. To
26 // keep things from getting out of control, we cap the read size to this value.
27 // This should generally be OK since the API specifies that it may perform a
28 // partial read.
29 static const int32_t kMaxReadSize = 33554432; // 32MB
30
31 typedef EnterHostFromHostResourceForceCallback<PPB_FileIO_API> EnterHostFileIO;
32 typedef EnterPluginFromHostResource<PPB_FileIO_API> EnterPluginFileIO;
33
34 class FileIO : public PPB_FileIO_Shared {
35 public:
36 explicit FileIO(const HostResource& host_resource);
37 virtual ~FileIO();
38
39 // PPB_FileIO_API implementation (not provided by FileIOImpl).
40 virtual void Close() OVERRIDE;
41 virtual int32_t GetOSFileDescriptor() OVERRIDE;
42 virtual int32_t WillWrite(int64_t offset,
43 int32_t bytes_to_write,
44 PP_CompletionCallback callback) OVERRIDE;
45 virtual int32_t WillSetLength(int64_t length,
46 PP_CompletionCallback callback) OVERRIDE;
47
48 private:
49 // FileIOImpl overrides.
50 virtual int32_t OpenValidated(PP_Resource file_ref_resource,
51 PPB_FileRef_API* file_ref_api,
52 int32_t open_flags,
53 PP_CompletionCallback callback) OVERRIDE;
54 virtual int32_t QueryValidated(PP_FileInfo* info,
55 PP_CompletionCallback callback) OVERRIDE;
56 virtual int32_t TouchValidated(PP_Time last_access_time,
57 PP_Time last_modified_time,
58 PP_CompletionCallback callback) OVERRIDE;
59 virtual int32_t ReadValidated(int64_t offset,
60 char* buffer,
61 int32_t bytes_to_read,
62 PP_CompletionCallback callback) OVERRIDE;
63 virtual int32_t WriteValidated(int64_t offset,
64 const char* buffer,
65 int32_t bytes_to_write,
66 PP_CompletionCallback callback) OVERRIDE;
67 virtual int32_t SetLengthValidated(int64_t length,
68 PP_CompletionCallback callback) OVERRIDE;
69 virtual int32_t FlushValidated(PP_CompletionCallback callback) OVERRIDE;
70
71 PluginDispatcher* GetDispatcher() const {
72 return PluginDispatcher::GetForResource(this);
73 }
74
75 static const ApiID kApiID = API_ID_PPB_FILE_IO;
76
77 DISALLOW_IMPLICIT_CONSTRUCTORS(FileIO);
78 };
79
80 FileIO::FileIO(const HostResource& host_resource)
81 : PPB_FileIO_Shared(host_resource) {
82 }
83
84 FileIO::~FileIO() {
85 Close();
86 }
87
88 void FileIO::Close() {
89 if (file_open_) {
90 GetDispatcher()->Send(new PpapiHostMsg_PPBFileIO_Close(kApiID,
91 host_resource()));
92 }
93 }
94
95 int32_t FileIO::GetOSFileDescriptor() {
96 return -1;
97 }
98
99 int32_t FileIO::WillWrite(int64_t offset,
100 int32_t bytes_to_write,
101 PP_CompletionCallback callback) {
102 GetDispatcher()->Send(new PpapiHostMsg_PPBFileIO_WillWrite(
103 kApiID, host_resource(), offset, bytes_to_write));
104 RegisterCallback(OPERATION_EXCLUSIVE, callback, NULL, NULL);
105 return PP_OK_COMPLETIONPENDING;
106 }
107
108 int32_t FileIO::WillSetLength(int64_t length,
109 PP_CompletionCallback callback) {
110 GetDispatcher()->Send(new PpapiHostMsg_PPBFileIO_WillSetLength(
111 kApiID, host_resource(), length));
112 RegisterCallback(OPERATION_EXCLUSIVE, callback, NULL, NULL);
113 return PP_OK_COMPLETIONPENDING;
114 }
115
116 int32_t FileIO::OpenValidated(PP_Resource file_ref_resource,
117 PPB_FileRef_API* file_ref_api,
118 int32_t open_flags,
119 PP_CompletionCallback callback) {
120 Resource* file_ref_object =
121 PpapiGlobals::Get()->GetResourceTracker()->GetResource(file_ref_resource);
122
123 GetDispatcher()->Send(new PpapiHostMsg_PPBFileIO_Open(
124 kApiID, host_resource(), file_ref_object->host_resource(), open_flags));
125 RegisterCallback(OPERATION_EXCLUSIVE, callback, NULL, NULL);
126 return PP_OK_COMPLETIONPENDING;
127 }
128
129 int32_t FileIO::QueryValidated(PP_FileInfo* info,
130 PP_CompletionCallback callback) {
131 GetDispatcher()->Send(new PpapiHostMsg_PPBFileIO_Query(
132 kApiID, host_resource()));
133 RegisterCallback(OPERATION_EXCLUSIVE, callback, NULL, info);
134 return PP_OK_COMPLETIONPENDING;
135 }
136
137 int32_t FileIO::TouchValidated(PP_Time last_access_time,
138 PP_Time last_modified_time,
139 PP_CompletionCallback callback) {
140 GetDispatcher()->Send(new PpapiHostMsg_PPBFileIO_Touch(
141 kApiID, host_resource(), last_access_time, last_modified_time));
142 RegisterCallback(OPERATION_EXCLUSIVE, callback, NULL, NULL);
143 return PP_OK_COMPLETIONPENDING;
144 }
145
146 int32_t FileIO::ReadValidated(int64_t offset,
147 char* buffer,
148 int32_t bytes_to_read,
149 PP_CompletionCallback callback) {
150 GetDispatcher()->Send(new PpapiHostMsg_PPBFileIO_Read(
151 kApiID, host_resource(), offset, bytes_to_read));
152 RegisterCallback(OPERATION_READ, callback, buffer, NULL);
153 return PP_OK_COMPLETIONPENDING;
154 }
155
156 int32_t FileIO::WriteValidated(int64_t offset,
157 const char* buffer,
158 int32_t bytes_to_write,
159 PP_CompletionCallback callback) {
160 // TODO(brettw) it would be nice to use a shared memory buffer for large
161 // writes rather than having to copy to a string (which will involve a number
162 // of extra copies to serialize over IPC).
163 GetDispatcher()->Send(new PpapiHostMsg_PPBFileIO_Write(
164 kApiID, host_resource(), offset, std::string(buffer, bytes_to_write)));
165 RegisterCallback(OPERATION_WRITE, callback, NULL, NULL);
166 return PP_OK_COMPLETIONPENDING;
167 }
168
169 int32_t FileIO::SetLengthValidated(int64_t length,
170 PP_CompletionCallback callback) {
171 GetDispatcher()->Send(new PpapiHostMsg_PPBFileIO_SetLength(
172 kApiID, host_resource(), length));
173 RegisterCallback(OPERATION_EXCLUSIVE, callback, NULL, NULL);
174 return PP_OK_COMPLETIONPENDING;
175 }
176
177 int32_t FileIO::FlushValidated(PP_CompletionCallback callback) {
178 GetDispatcher()->Send(new PpapiHostMsg_PPBFileIO_Flush(
179 kApiID, host_resource()));
180 RegisterCallback(OPERATION_EXCLUSIVE, callback, NULL, NULL);
181 return PP_OK_COMPLETIONPENDING;
182 }
183
184 } // namespace
185
186 // -----------------------------------------------------------------------------
187
188 PPB_FileIO_Proxy::PPB_FileIO_Proxy(Dispatcher* dispatcher)
189 : InterfaceProxy(dispatcher),
190 callback_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) {
191 }
192
193 PPB_FileIO_Proxy::~PPB_FileIO_Proxy() {
194 }
195
196 // static
197 PP_Resource PPB_FileIO_Proxy::CreateProxyResource(PP_Instance instance) {
198 PluginDispatcher* dispatcher = PluginDispatcher::GetForInstance(instance);
199 if (!dispatcher)
200 return 0;
201
202 HostResource result;
203 dispatcher->Send(new PpapiHostMsg_PPBFileIO_Create(kApiID, instance,
204 &result));
205 if (result.is_null())
206 return 0;
207 return (new FileIO(result))->GetReference();
208 }
209
210 bool PPB_FileIO_Proxy::OnMessageReceived(const IPC::Message& msg) {
211 bool handled = true;
212 IPC_BEGIN_MESSAGE_MAP(PPB_FileIO_Proxy, msg)
213 // Plugin -> host message.
214 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFileIO_Create, OnHostMsgCreate)
215 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFileIO_Open, OnHostMsgOpen)
216 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFileIO_Close, OnHostMsgClose)
217 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFileIO_Query, OnHostMsgQuery)
218 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFileIO_Touch, OnHostMsgTouch)
219 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFileIO_Read, OnHostMsgRead)
220 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFileIO_Write, OnHostMsgWrite)
221 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFileIO_SetLength, OnHostMsgSetLength)
222 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFileIO_Flush, OnHostMsgFlush)
223 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFileIO_WillWrite, OnHostMsgWillWrite)
224 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFileIO_WillSetLength,
225 OnHostMsgWillSetLength)
226
227 // Host -> plugin messages.
228 IPC_MESSAGE_HANDLER(PpapiMsg_PPBFileIO_GeneralComplete,
229 OnPluginMsgGeneralComplete)
230 IPC_MESSAGE_HANDLER(PpapiMsg_PPBFileIO_OpenFileComplete,
231 OnPluginMsgOpenFileComplete)
232 IPC_MESSAGE_HANDLER(PpapiMsg_PPBFileIO_QueryComplete,
233 OnPluginMsgQueryComplete)
234 IPC_MESSAGE_HANDLER(PpapiMsg_PPBFileIO_ReadComplete,
235 OnPluginMsgReadComplete)
236 IPC_MESSAGE_UNHANDLED(handled = false)
237 IPC_END_MESSAGE_MAP()
238 return handled;
239 }
240
241 void PPB_FileIO_Proxy::OnHostMsgCreate(PP_Instance instance,
242 HostResource* result) {
243 thunk::EnterResourceCreation enter(instance);
244 if (enter.succeeded()) {
245 result->SetHostResource(instance,
246 enter.functions()->CreateFileIO(instance));
247 }
248 }
249
250 void PPB_FileIO_Proxy::OnHostMsgOpen(const HostResource& host_resource,
251 const HostResource& file_ref_resource,
252 int32_t open_flags) {
253 EnterHostFileIO enter(host_resource, callback_factory_,
254 &PPB_FileIO_Proxy::OpenFileCallbackCompleteInHost, host_resource);
255 if (enter.succeeded()) {
256 enter.SetResult(enter.object()->Open(
257 file_ref_resource.host_resource(), open_flags, enter.callback()));
258 }
259 }
260
261 void PPB_FileIO_Proxy::OnHostMsgClose(const HostResource& host_resource) {
262 EnterHostFromHostResource<PPB_FileIO_API> enter(host_resource);
263 if (enter.succeeded())
264 enter.object()->Close();
265 }
266
267 void PPB_FileIO_Proxy::OnHostMsgQuery(const HostResource& host_resource) {
268 // The callback will take charge of deleting the FileInfo. The contents must
269 // be defined so we don't send garbage to the plugin in the failure case.
270 PP_FileInfo* info = new PP_FileInfo;
271 memset(info, 0, sizeof(PP_FileInfo));
272 EnterHostFileIO enter(host_resource, callback_factory_,
273 &PPB_FileIO_Proxy::QueryCallbackCompleteInHost,
274 host_resource, info);
275 if (enter.succeeded())
276 enter.SetResult(enter.object()->Query(info, enter.callback()));
277 }
278
279 void PPB_FileIO_Proxy::OnHostMsgTouch(const HostResource& host_resource,
280 PP_Time last_access_time,
281 PP_Time last_modified_time) {
282 EnterHostFileIO enter(host_resource, callback_factory_,
283 &PPB_FileIO_Proxy::GeneralCallbackCompleteInHost,
284 host_resource);
285 if (enter.succeeded()) {
286 enter.SetResult(enter.object()->Touch(last_access_time, last_modified_time,
287 enter.callback()));
288 }
289 }
290
291 void PPB_FileIO_Proxy::OnHostMsgRead(const HostResource& host_resource,
292 int64_t offset,
293 int32_t bytes_to_read) {
294 // Validate bytes_to_read before allocating below. This value is coming from
295 // the untrusted plugin.
296 bytes_to_read = std::min(bytes_to_read, kMaxReadSize);
297 if (bytes_to_read < 0) {
298 ReadCallbackCompleteInHost(PP_ERROR_FAILED, host_resource,
299 new std::string());
300 return;
301 }
302
303 // The callback will take charge of deleting the string.
304 std::string* dest = new std::string;
305 dest->resize(bytes_to_read);
306 EnterHostFileIO enter(host_resource, callback_factory_,
307 &PPB_FileIO_Proxy::ReadCallbackCompleteInHost,
308 host_resource, dest);
309 if (enter.succeeded()) {
310 enter.SetResult(enter.object()->Read(offset,
311 bytes_to_read > 0 ? &(*dest)[0] : NULL,
312 bytes_to_read, enter.callback()));
313 }
314 }
315
316 void PPB_FileIO_Proxy::OnHostMsgWrite(const HostResource& host_resource,
317 int64_t offset,
318 const std::string& data) {
319 EnterHostFileIO enter(host_resource, callback_factory_,
320 &PPB_FileIO_Proxy::GeneralCallbackCompleteInHost,
321 host_resource);
322 if (enter.succeeded()) {
323 enter.SetResult(enter.object()->Write(offset, data.data(), data.size(),
324 enter.callback()));
325 }
326 }
327
328 void PPB_FileIO_Proxy::OnHostMsgSetLength(const HostResource& host_resource,
329 int64_t length) {
330 EnterHostFileIO enter(host_resource, callback_factory_,
331 &PPB_FileIO_Proxy::GeneralCallbackCompleteInHost,
332 host_resource);
333 if (enter.succeeded())
334 enter.SetResult(enter.object()->SetLength(length, enter.callback()));
335 }
336
337 void PPB_FileIO_Proxy::OnHostMsgFlush(const HostResource& host_resource) {
338 EnterHostFileIO enter(host_resource, callback_factory_,
339 &PPB_FileIO_Proxy::GeneralCallbackCompleteInHost,
340 host_resource);
341 if (enter.succeeded())
342 enter.SetResult(enter.object()->Flush(enter.callback()));
343 }
344
345 void PPB_FileIO_Proxy::OnHostMsgWillWrite(const HostResource& host_resource,
346 int64_t offset,
347 int32_t bytes_to_write) {
348 EnterHostFileIO enter(host_resource, callback_factory_,
349 &PPB_FileIO_Proxy::GeneralCallbackCompleteInHost,
350 host_resource);
351 if (enter.succeeded()) {
352 enter.SetResult(enter.object()->WillWrite(offset, bytes_to_write,
353 enter.callback()));
354 }
355 }
356
357 void PPB_FileIO_Proxy::OnHostMsgWillSetLength(const HostResource& host_resource,
358 int64_t length) {
359 EnterHostFileIO enter(host_resource, callback_factory_,
360 &PPB_FileIO_Proxy::GeneralCallbackCompleteInHost,
361 host_resource);
362 if (enter.succeeded())
363 enter.SetResult(enter.object()->WillSetLength(length, enter.callback()));
364 }
365
366 void PPB_FileIO_Proxy::OnPluginMsgGeneralComplete(
367 const HostResource& host_resource,
368 int32_t result) {
369 EnterPluginFileIO enter(host_resource);
370 if (enter.succeeded())
371 static_cast<FileIO*>(enter.object())->ExecuteGeneralCallback(result);
372 }
373
374 void PPB_FileIO_Proxy::OnPluginMsgOpenFileComplete(
375 const HostResource& host_resource,
376 int32_t result) {
377 EnterPluginFileIO enter(host_resource);
378 if (enter.succeeded())
379 static_cast<FileIO*>(enter.object())->ExecuteOpenFileCallback(result);
380 }
381
382 void PPB_FileIO_Proxy::OnPluginMsgQueryComplete(
383 const HostResource& host_resource,
384 int32_t result,
385 const PP_FileInfo& info) {
386 EnterPluginFileIO enter(host_resource);
387 if (enter.succeeded())
388 static_cast<FileIO*>(enter.object())->ExecuteQueryCallback(result, info);
389 }
390
391 void PPB_FileIO_Proxy::OnPluginMsgReadComplete(
392 const HostResource& host_resource,
393 int32_t result,
394 const std::string& data) {
395 EnterPluginFileIO enter(host_resource);
396 if (enter.succeeded()) {
397 // The result code should contain the data size if it's positive.
398 DCHECK((result < 0 && data.size() == 0) ||
399 result == static_cast<int32_t>(data.size()));
400 static_cast<FileIO*>(enter.object())->ExecuteReadCallback(result,
401 data.data());
402 }
403 }
404
405 void PPB_FileIO_Proxy::GeneralCallbackCompleteInHost(
406 int32_t pp_error,
407 const HostResource& host_resource) {
408 Send(new PpapiMsg_PPBFileIO_GeneralComplete(kApiID, host_resource, pp_error));
409 }
410
411 void PPB_FileIO_Proxy::OpenFileCallbackCompleteInHost(
412 int32_t pp_error,
413 const HostResource& host_resource) {
414 Send(new PpapiMsg_PPBFileIO_OpenFileComplete(kApiID, host_resource,
415 pp_error));
416 }
417
418 void PPB_FileIO_Proxy::QueryCallbackCompleteInHost(
419 int32_t pp_error,
420 const HostResource& host_resource,
421 PP_FileInfo* info) {
422 Send(new PpapiMsg_PPBFileIO_QueryComplete(kApiID, host_resource, pp_error,
423 *info));
424 delete info;
425 }
426
427 void PPB_FileIO_Proxy::ReadCallbackCompleteInHost(
428 int32_t pp_error,
429 const HostResource& host_resource,
430 std::string* data) {
431 // Only send the amount of data in the string that was actually read.
432 if (pp_error >= 0) {
433 DCHECK(pp_error <= static_cast<int32_t>(data->size()));
434 data->resize(pp_error);
435 }
436 Send(new PpapiMsg_PPBFileIO_ReadComplete(kApiID, host_resource, pp_error,
437 *data));
438 delete data;
439 }
440
441 } // namespace proxy
442 } // namespace ppapi
OLDNEW
« no previous file with comments | « ppapi/proxy/ppb_file_io_proxy.h ('k') | ppapi/proxy/ppb_file_ref_proxy.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698