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

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

Issue 11419131: Refactor FileIO to the new design (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: int32_t Created 8 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
« 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 }
294
295 int32_t PPB_FileIO_Impl::GetOSFileDescriptor() {
296 #if defined(OS_POSIX)
297 return file_;
298 #elif defined(OS_WIN)
299 return reinterpret_cast<uintptr_t>(file_);
300 #else
301 #error "Platform not supported."
302 #endif
303 }
304
305 int32_t PPB_FileIO_Impl::WillWrite(int64_t offset,
306 int32_t bytes_to_write,
307 scoped_refptr<TrackedCallback> callback) {
308 int32_t rv = CommonCallValidation(true, OPERATION_EXCLUSIVE);
309 if (rv != PP_OK)
310 return rv;
311
312 if (!quota_file_io_.get())
313 return PP_OK;
314
315 if (!quota_file_io_->WillWrite(
316 offset, bytes_to_write,
317 base::Bind(&PPB_FileIO_Impl::ExecutePlatformWillWriteCallback,
318 weak_factory_.GetWeakPtr())))
319 return PP_ERROR_FAILED;
320
321 RegisterCallback(OPERATION_EXCLUSIVE, callback, NULL, NULL);
322 return PP_OK_COMPLETIONPENDING;
323 }
324
325 int32_t PPB_FileIO_Impl::WillSetLength(
326 int64_t length,
327 scoped_refptr<TrackedCallback> callback) {
328 int32_t rv = CommonCallValidation(true, OPERATION_EXCLUSIVE);
329 if (rv != PP_OK)
330 return rv;
331
332 if (!quota_file_io_.get())
333 return PP_OK;
334
335 if (!quota_file_io_->WillSetLength(
336 length,
337 base::Bind(&PPB_FileIO_Impl::ExecutePlatformGeneralCallback,
338 weak_factory_.GetWeakPtr())))
339 return PP_ERROR_FAILED;
340
341 RegisterCallback(OPERATION_EXCLUSIVE, callback, NULL, NULL);
342 return PP_OK_COMPLETIONPENDING;
343 }
344
345 PluginDelegate* PPB_FileIO_Impl::GetPluginDelegate() {
346 return ResourceHelper::GetPluginDelegate(this);
347 }
348
349 void PPB_FileIO_Impl::ExecutePlatformGeneralCallback(
350 base::PlatformFileError error_code) {
351 ExecuteGeneralCallback(::ppapi::PlatformFileErrorToPepperError(error_code));
352 }
353
354 void PPB_FileIO_Impl::ExecutePlatformOpenFileCallback(
355 base::PlatformFileError error_code,
356 base::PassPlatformFile file) {
357 DCHECK(file_ == base::kInvalidPlatformFileValue);
358 file_ = file.ReleaseValue();
359
360 DCHECK(!quota_file_io_.get());
361 if (file_ != base::kInvalidPlatformFileValue &&
362 (file_system_type_ == PP_FILESYSTEMTYPE_LOCALTEMPORARY ||
363 file_system_type_ == PP_FILESYSTEMTYPE_LOCALPERSISTENT)) {
364 quota_file_io_.reset(new QuotaFileIO(
365 pp_instance(), file_, file_system_url_, file_system_type_));
366 }
367
368 ExecuteOpenFileCallback(::ppapi::PlatformFileErrorToPepperError(error_code));
369 }
370
371 void PPB_FileIO_Impl::ExecutePlatformOpenFileSystemURLCallback(
372 base::PlatformFileError error_code,
373 base::PassPlatformFile file,
374 const PluginDelegate::NotifyCloseFileCallback& callback) {
375 if (error_code == base::PLATFORM_FILE_OK)
376 notify_close_file_callback_ = callback;
377 ExecutePlatformOpenFileCallback(error_code, file);
378 }
379
380 void PPB_FileIO_Impl::ExecutePlatformQueryCallback(
381 base::PlatformFileError error_code,
382 const base::PlatformFileInfo& file_info) {
383 PP_FileInfo pp_info;
384 pp_info.size = file_info.size;
385 pp_info.creation_time = TimeToPPTime(file_info.creation_time);
386 pp_info.last_access_time = TimeToPPTime(file_info.last_accessed);
387 pp_info.last_modified_time = TimeToPPTime(file_info.last_modified);
388 pp_info.system_type = file_system_type_;
389 if (file_info.is_directory)
390 pp_info.type = PP_FILETYPE_DIRECTORY;
391 else
392 pp_info.type = PP_FILETYPE_REGULAR;
393
394 ExecuteQueryCallback(::ppapi::PlatformFileErrorToPepperError(error_code),
395 pp_info);
396 }
397
398 void PPB_FileIO_Impl::ExecutePlatformReadCallback(
399 base::PlatformFileError error_code,
400 const char* data, int bytes_read) {
401 // Map the error code, OK getting mapped to the # of bytes read.
402 int32_t pp_result = ::ppapi::PlatformFileErrorToPepperError(error_code);
403 pp_result = pp_result == PP_OK ? bytes_read : pp_result;
404 ExecuteReadCallback(pp_result, data);
405 }
406
407 void PPB_FileIO_Impl::ExecutePlatformWriteCallback(
408 base::PlatformFileError error_code,
409 int bytes_written) {
410 int32_t pp_result = ::ppapi::PlatformFileErrorToPepperError(error_code);
411 ExecuteGeneralCallback(pp_result == PP_OK ? bytes_written : pp_result);
412 }
413
414 void PPB_FileIO_Impl::ExecutePlatformWillWriteCallback(
415 base::PlatformFileError error_code,
416 int bytes_written) {
417 if (pending_op_ != OPERATION_EXCLUSIVE || callbacks_.empty()) {
418 NOTREACHED();
419 return;
420 }
421
422 if (error_code != base::PLATFORM_FILE_OK) {
423 RunAndRemoveFirstPendingCallback(
424 ::ppapi::PlatformFileErrorToPepperError(error_code));
425 } else {
426 RunAndRemoveFirstPendingCallback(bytes_written);
427 }
428 }
429
430 } // namespace ppapi
431 } // 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