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

Side by Side Diff: webkit/plugins/ppapi/ppb_file_io_impl.cc

Issue 11941022: Refactor FileIO to the new resource host system. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 7 years, 11 months 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 | « webkit/plugins/ppapi/ppb_file_io_impl.h ('k') | webkit/plugins/ppapi/resource_creation_impl.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) 2012 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 "webkit/plugins/ppapi/ppb_file_io_impl.h"
6
7 #include "base/bind.h"
8 #include "base/callback.h"
9 #include "base/callback_helpers.h"
10 #include "base/file_util.h"
11 #include "base/file_util_proxy.h"
12 #include "base/message_loop_proxy.h"
13 #include "base/platform_file.h"
14 #include "base/logging.h"
15 #include "base/time.h"
16 #include "ppapi/c/ppb_file_io.h"
17 #include "ppapi/c/trusted/ppb_file_io_trusted.h"
18 #include "ppapi/c/pp_completion_callback.h"
19 #include "ppapi/c/pp_errors.h"
20 #include "ppapi/shared_impl/file_type_conversion.h"
21 #include "ppapi/shared_impl/time_conversion.h"
22 #include "ppapi/thunk/enter.h"
23 #include "ppapi/thunk/ppb_file_ref_api.h"
24 #include "webkit/plugins/ppapi/common.h"
25 #include "webkit/plugins/ppapi/file_callbacks.h"
26 #include "webkit/plugins/ppapi/plugin_module.h"
27 #include "webkit/plugins/ppapi/ppapi_plugin_instance.h"
28 #include "webkit/plugins/ppapi/ppb_directory_reader_impl.h"
29 #include "webkit/plugins/ppapi/ppb_file_ref_impl.h"
30 #include "webkit/plugins/ppapi/ppb_file_system_impl.h"
31 #include "webkit/plugins/ppapi/quota_file_io.h"
32 #include "webkit/plugins/ppapi/resource_helper.h"
33
34 using ppapi::PPTimeToTime;
35 using ppapi::TimeToPPTime;
36 using ppapi::TrackedCallback;
37 using ppapi::thunk::PPB_FileRef_API;
38
39 namespace webkit {
40 namespace ppapi {
41
42 namespace {
43
44 typedef base::Callback<void (base::PlatformFileError)> PlatformGeneralCallback;
45
46 class PlatformGeneralCallbackTranslator
47 : public fileapi::FileSystemCallbackDispatcher {
48 public:
49 PlatformGeneralCallbackTranslator(
50 const PlatformGeneralCallback& callback)
51 : callback_(callback) {}
52
53 virtual ~PlatformGeneralCallbackTranslator() {}
54
55 virtual void DidSucceed() OVERRIDE {
56 callback_.Run(base::PLATFORM_FILE_OK);
57 }
58
59 virtual void DidReadMetadata(
60 const base::PlatformFileInfo& file_info,
61 const FilePath& platform_path) OVERRIDE {
62 NOTREACHED();
63 }
64
65 virtual void DidReadDirectory(
66 const std::vector<base::FileUtilProxy::Entry>& entries,
67 bool has_more) OVERRIDE {
68 NOTREACHED();
69 }
70
71 virtual void DidOpenFileSystem(const std::string& name,
72 const GURL& root) OVERRIDE {
73 NOTREACHED();
74 }
75
76 virtual void DidFail(base::PlatformFileError error_code) OVERRIDE {
77 callback_.Run(error_code);
78 }
79
80 virtual void DidWrite(int64 bytes, bool complete) OVERRIDE {
81 NOTREACHED();
82 }
83
84 virtual void DidOpenFile(base::PlatformFile file) OVERRIDE {
85 NOTREACHED();
86 }
87
88 private:
89 PlatformGeneralCallback callback_;
90 };
91
92 } // namespace
93
94 PPB_FileIO_Impl::PPB_FileIO_Impl(PP_Instance instance)
95 : ::ppapi::PPB_FileIO_Shared(instance),
96 file_(base::kInvalidPlatformFileValue),
97 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) {
98 }
99
100 PPB_FileIO_Impl::~PPB_FileIO_Impl() {
101 Close();
102 }
103
104 int32_t PPB_FileIO_Impl::OpenValidated(
105 PP_Resource file_ref_resource,
106 PPB_FileRef_API* file_ref_api,
107 int32_t open_flags,
108 scoped_refptr<TrackedCallback> callback) {
109 PPB_FileRef_Impl* file_ref = static_cast<PPB_FileRef_Impl*>(file_ref_api);
110
111 int flags = 0;
112 if (!::ppapi::PepperFileOpenFlagsToPlatformFileFlags(open_flags, &flags))
113 return PP_ERROR_BADARGUMENT;
114
115 PluginDelegate* plugin_delegate = GetPluginDelegate();
116 if (!plugin_delegate)
117 return PP_ERROR_BADARGUMENT;
118
119 if (file_ref->HasValidFileSystem()) {
120 file_system_url_ = file_ref->GetFileSystemURL();
121 if (!plugin_delegate->AsyncOpenFileSystemURL(
122 file_system_url_, flags,
123 base::Bind(
124 &PPB_FileIO_Impl::ExecutePlatformOpenFileSystemURLCallback,
125 weak_factory_.GetWeakPtr())))
126 return PP_ERROR_FAILED;
127 } else {
128 if (file_system_type_ != PP_FILESYSTEMTYPE_EXTERNAL)
129 return PP_ERROR_FAILED;
130 if (!plugin_delegate->AsyncOpenFile(
131 file_ref->GetSystemPath(), flags,
132 base::Bind(&PPB_FileIO_Impl::ExecutePlatformOpenFileCallback,
133 weak_factory_.GetWeakPtr())))
134 return PP_ERROR_FAILED;
135 }
136
137 RegisterCallback(OPERATION_EXCLUSIVE, callback, NULL, NULL);
138 return PP_OK_COMPLETIONPENDING;
139 }
140
141 int32_t PPB_FileIO_Impl::QueryValidated(
142 PP_FileInfo* info,
143 scoped_refptr<TrackedCallback> callback) {
144 PluginDelegate* plugin_delegate = GetPluginDelegate();
145 if (!plugin_delegate)
146 return PP_ERROR_FAILED;
147
148 if (!base::FileUtilProxy::GetFileInfoFromPlatformFile(
149 plugin_delegate->GetFileThreadMessageLoopProxy(), file_,
150 base::Bind(&PPB_FileIO_Impl::ExecutePlatformQueryCallback,
151 weak_factory_.GetWeakPtr())))
152 return PP_ERROR_FAILED;
153
154 RegisterCallback(OPERATION_EXCLUSIVE, callback, NULL, info);
155 return PP_OK_COMPLETIONPENDING;
156 }
157
158 int32_t PPB_FileIO_Impl::TouchValidated(
159 PP_Time last_access_time,
160 PP_Time last_modified_time,
161 scoped_refptr<TrackedCallback> callback) {
162 PluginDelegate* plugin_delegate = GetPluginDelegate();
163 if (!plugin_delegate)
164 return PP_ERROR_FAILED;
165
166 if (file_system_type_ != PP_FILESYSTEMTYPE_EXTERNAL) {
167 if (!plugin_delegate->Touch(
168 file_system_url_,
169 PPTimeToTime(last_access_time),
170 PPTimeToTime(last_modified_time),
171 new PlatformGeneralCallbackTranslator(
172 base::Bind(&PPB_FileIO_Impl::ExecutePlatformGeneralCallback,
173 weak_factory_.GetWeakPtr()))))
174 return PP_ERROR_FAILED;
175 } else {
176 // TODO(nhiroki): fix a failure of FileIO.Touch for an external filesystem
177 // on Mac and Linux due to sandbox restrictions (http://crbug.com/101128).
178 if (!base::FileUtilProxy::Touch(
179 plugin_delegate->GetFileThreadMessageLoopProxy(),
180 file_, PPTimeToTime(last_access_time),
181 PPTimeToTime(last_modified_time),
182 base::Bind(&PPB_FileIO_Impl::ExecutePlatformGeneralCallback,
183 weak_factory_.GetWeakPtr())))
184 return PP_ERROR_FAILED;
185 }
186
187 RegisterCallback(OPERATION_EXCLUSIVE, callback, NULL, NULL);
188 return PP_OK_COMPLETIONPENDING;
189 }
190
191 int32_t PPB_FileIO_Impl::ReadValidated(
192 int64_t offset,
193 const PP_ArrayOutput& output_array_buffer,
194 int32_t max_read_length,
195 scoped_refptr<TrackedCallback> callback) {
196 PluginDelegate* plugin_delegate = GetPluginDelegate();
197 if (!plugin_delegate)
198 return PP_ERROR_FAILED;
199
200 if (!base::FileUtilProxy::Read(
201 plugin_delegate->GetFileThreadMessageLoopProxy(), file_, offset,
202 max_read_length,
203 base::Bind(&PPB_FileIO_Impl::ExecutePlatformReadCallback,
204 weak_factory_.GetWeakPtr())))
205 return PP_ERROR_FAILED;
206
207 RegisterCallback(OPERATION_READ, callback, &output_array_buffer, NULL);
208 return PP_OK_COMPLETIONPENDING;
209 }
210
211 int32_t PPB_FileIO_Impl::WriteValidated(
212 int64_t offset,
213 const char* buffer,
214 int32_t bytes_to_write,
215 scoped_refptr<TrackedCallback> callback) {
216 PluginDelegate* plugin_delegate = GetPluginDelegate();
217 if (!plugin_delegate)
218 return PP_ERROR_FAILED;
219
220 if (quota_file_io_.get()) {
221 if (!quota_file_io_->Write(
222 offset, buffer, bytes_to_write,
223 base::Bind(&PPB_FileIO_Impl::ExecutePlatformWriteCallback,
224 weak_factory_.GetWeakPtr())))
225 return PP_ERROR_FAILED;
226 } else {
227 if (!base::FileUtilProxy::Write(
228 plugin_delegate->GetFileThreadMessageLoopProxy(), file_, offset,
229 buffer, bytes_to_write,
230 base::Bind(&PPB_FileIO_Impl::ExecutePlatformWriteCallback,
231 weak_factory_.GetWeakPtr())))
232 return PP_ERROR_FAILED;
233 }
234
235 RegisterCallback(OPERATION_WRITE, callback, NULL, NULL);
236 return PP_OK_COMPLETIONPENDING;
237 }
238
239 int32_t PPB_FileIO_Impl::SetLengthValidated(
240 int64_t length,
241 scoped_refptr<TrackedCallback> callback) {
242 PluginDelegate* plugin_delegate = GetPluginDelegate();
243 if (!plugin_delegate)
244 return PP_ERROR_FAILED;
245
246 if (file_system_type_ != PP_FILESYSTEMTYPE_EXTERNAL) {
247 if (!plugin_delegate->SetLength(
248 file_system_url_, length,
249 new PlatformGeneralCallbackTranslator(
250 base::Bind(&PPB_FileIO_Impl::ExecutePlatformGeneralCallback,
251 weak_factory_.GetWeakPtr()))))
252 return PP_ERROR_FAILED;
253 } else {
254 // TODO(nhiroki): fix a failure of FileIO.SetLength for an external
255 // filesystem on Mac due to sandbox restrictions (http://crbug.com/156077).
256 if (!base::FileUtilProxy::Truncate(
257 plugin_delegate->GetFileThreadMessageLoopProxy(), file_, length,
258 base::Bind(&PPB_FileIO_Impl::ExecutePlatformGeneralCallback,
259 weak_factory_.GetWeakPtr())))
260 return PP_ERROR_FAILED;
261 }
262
263 RegisterCallback(OPERATION_EXCLUSIVE, callback, NULL, NULL);
264 return PP_OK_COMPLETIONPENDING;
265 }
266
267 int32_t PPB_FileIO_Impl::FlushValidated(
268 scoped_refptr<TrackedCallback> callback) {
269 PluginDelegate* plugin_delegate = GetPluginDelegate();
270 if (!plugin_delegate)
271 return PP_ERROR_FAILED;
272
273 if (!base::FileUtilProxy::Flush(
274 plugin_delegate->GetFileThreadMessageLoopProxy(), file_,
275 base::Bind(&PPB_FileIO_Impl::ExecutePlatformGeneralCallback,
276 weak_factory_.GetWeakPtr())))
277 return PP_ERROR_FAILED;
278
279 RegisterCallback(OPERATION_EXCLUSIVE, callback, NULL, NULL);
280 return PP_OK_COMPLETIONPENDING;
281 }
282
283 void PPB_FileIO_Impl::Close() {
284 PluginDelegate* plugin_delegate = GetPluginDelegate();
285 if (file_ != base::kInvalidPlatformFileValue && plugin_delegate) {
286 base::FileUtilProxy::Close(
287 plugin_delegate->GetFileThreadMessageLoopProxy(),
288 file_,
289 base::ResetAndReturn(&notify_close_file_callback_));
290 file_ = base::kInvalidPlatformFileValue;
291 quota_file_io_.reset();
292 }
293 // TODO(viettrungluu): Check what happens to the callback (probably the
294 // wrong thing). May need to post abort here. crbug.com/69457
295 }
296
297 int32_t PPB_FileIO_Impl::GetOSFileDescriptor() {
298 #if defined(OS_POSIX)
299 return file_;
300 #elif defined(OS_WIN)
301 return reinterpret_cast<uintptr_t>(file_);
302 #else
303 #error "Platform not supported."
304 #endif
305 }
306
307 int32_t PPB_FileIO_Impl::WillWrite(int64_t offset,
308 int32_t bytes_to_write,
309 scoped_refptr<TrackedCallback> callback) {
310 int32_t rv = CommonCallValidation(true, OPERATION_EXCLUSIVE);
311 if (rv != PP_OK)
312 return rv;
313
314 if (!quota_file_io_.get())
315 return PP_OK;
316
317 if (!quota_file_io_->WillWrite(
318 offset, bytes_to_write,
319 base::Bind(&PPB_FileIO_Impl::ExecutePlatformWillWriteCallback,
320 weak_factory_.GetWeakPtr())))
321 return PP_ERROR_FAILED;
322
323 RegisterCallback(OPERATION_EXCLUSIVE, callback, NULL, NULL);
324 return PP_OK_COMPLETIONPENDING;
325 }
326
327 int32_t PPB_FileIO_Impl::WillSetLength(
328 int64_t length,
329 scoped_refptr<TrackedCallback> callback) {
330 int32_t rv = CommonCallValidation(true, OPERATION_EXCLUSIVE);
331 if (rv != PP_OK)
332 return rv;
333
334 if (!quota_file_io_.get())
335 return PP_OK;
336
337 if (!quota_file_io_->WillSetLength(
338 length,
339 base::Bind(&PPB_FileIO_Impl::ExecutePlatformGeneralCallback,
340 weak_factory_.GetWeakPtr())))
341 return PP_ERROR_FAILED;
342
343 RegisterCallback(OPERATION_EXCLUSIVE, callback, NULL, NULL);
344 return PP_OK_COMPLETIONPENDING;
345 }
346
347 PluginDelegate* PPB_FileIO_Impl::GetPluginDelegate() {
348 return ResourceHelper::GetPluginDelegate(this);
349 }
350
351 void PPB_FileIO_Impl::ExecutePlatformGeneralCallback(
352 base::PlatformFileError error_code) {
353 ExecuteGeneralCallback(::ppapi::PlatformFileErrorToPepperError(error_code));
354 }
355
356 void PPB_FileIO_Impl::ExecutePlatformOpenFileCallback(
357 base::PlatformFileError error_code,
358 base::PassPlatformFile file) {
359 DCHECK(file_ == base::kInvalidPlatformFileValue);
360 file_ = file.ReleaseValue();
361
362 DCHECK(!quota_file_io_.get());
363 if (file_ != base::kInvalidPlatformFileValue &&
364 (file_system_type_ == PP_FILESYSTEMTYPE_LOCALTEMPORARY ||
365 file_system_type_ == PP_FILESYSTEMTYPE_LOCALPERSISTENT)) {
366 quota_file_io_.reset(new QuotaFileIO(
367 pp_instance(), file_, file_system_url_, file_system_type_));
368 }
369
370 ExecuteOpenFileCallback(::ppapi::PlatformFileErrorToPepperError(error_code));
371 }
372
373 void PPB_FileIO_Impl::ExecutePlatformOpenFileSystemURLCallback(
374 base::PlatformFileError error_code,
375 base::PassPlatformFile file,
376 const PluginDelegate::NotifyCloseFileCallback& callback) {
377 if (error_code == base::PLATFORM_FILE_OK)
378 notify_close_file_callback_ = callback;
379 ExecutePlatformOpenFileCallback(error_code, file);
380 }
381
382 void PPB_FileIO_Impl::ExecutePlatformQueryCallback(
383 base::PlatformFileError error_code,
384 const base::PlatformFileInfo& file_info) {
385 PP_FileInfo pp_info;
386 pp_info.size = file_info.size;
387 pp_info.creation_time = TimeToPPTime(file_info.creation_time);
388 pp_info.last_access_time = TimeToPPTime(file_info.last_accessed);
389 pp_info.last_modified_time = TimeToPPTime(file_info.last_modified);
390 pp_info.system_type = file_system_type_;
391 if (file_info.is_directory)
392 pp_info.type = PP_FILETYPE_DIRECTORY;
393 else
394 pp_info.type = PP_FILETYPE_REGULAR;
395
396 ExecuteQueryCallback(::ppapi::PlatformFileErrorToPepperError(error_code),
397 pp_info);
398 }
399
400 void PPB_FileIO_Impl::ExecutePlatformReadCallback(
401 base::PlatformFileError error_code,
402 const char* data, int bytes_read) {
403 // Map the error code, OK getting mapped to the # of bytes read.
404 int32_t pp_result = ::ppapi::PlatformFileErrorToPepperError(error_code);
405 pp_result = pp_result == PP_OK ? bytes_read : pp_result;
406 ExecuteReadCallback(pp_result, data);
407 }
408
409 void PPB_FileIO_Impl::ExecutePlatformWriteCallback(
410 base::PlatformFileError error_code,
411 int bytes_written) {
412 int32_t pp_result = ::ppapi::PlatformFileErrorToPepperError(error_code);
413 ExecuteGeneralCallback(pp_result == PP_OK ? bytes_written : pp_result);
414 }
415
416 void PPB_FileIO_Impl::ExecutePlatformWillWriteCallback(
417 base::PlatformFileError error_code,
418 int bytes_written) {
419 if (pending_op_ != OPERATION_EXCLUSIVE || callbacks_.empty()) {
420 NOTREACHED();
421 return;
422 }
423
424 if (error_code != base::PLATFORM_FILE_OK) {
425 RunAndRemoveFirstPendingCallback(
426 ::ppapi::PlatformFileErrorToPepperError(error_code));
427 } else {
428 RunAndRemoveFirstPendingCallback(bytes_written);
429 }
430 }
431
432 } // namespace ppapi
433 } // namespace webkit
OLDNEW
« no previous file with comments | « webkit/plugins/ppapi/ppb_file_io_impl.h ('k') | webkit/plugins/ppapi/resource_creation_impl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698