OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "ppapi/proxy/file_io_resource.h" | 5 #include "ppapi/proxy/file_io_resource.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "ipc/ipc_message.h" | 8 #include "ipc/ipc_message.h" |
9 #include "ppapi/c/pp_errors.h" | 9 #include "ppapi/c/pp_errors.h" |
10 #include "ppapi/proxy/plugin_globals.h" | |
10 #include "ppapi/proxy/ppapi_messages.h" | 11 #include "ppapi/proxy/ppapi_messages.h" |
11 #include "ppapi/shared_impl/array_writer.h" | 12 #include "ppapi/shared_impl/array_writer.h" |
13 #include "ppapi/shared_impl/file_type_conversion.h" | |
12 #include "ppapi/shared_impl/ppapi_globals.h" | 14 #include "ppapi/shared_impl/ppapi_globals.h" |
15 #include "ppapi/shared_impl/proxy_lock.h" | |
13 #include "ppapi/shared_impl/resource_tracker.h" | 16 #include "ppapi/shared_impl/resource_tracker.h" |
14 #include "ppapi/thunk/enter.h" | 17 #include "ppapi/thunk/enter.h" |
15 #include "ppapi/thunk/ppb_file_ref_api.h" | 18 #include "ppapi/thunk/ppb_file_ref_api.h" |
16 | 19 |
17 using ppapi::thunk::EnterResourceNoLock; | 20 using ppapi::thunk::EnterResourceNoLock; |
18 using ppapi::thunk::PPB_FileIO_API; | 21 using ppapi::thunk::PPB_FileIO_API; |
19 using ppapi::thunk::PPB_FileRef_API; | 22 using ppapi::thunk::PPB_FileRef_API; |
20 | 23 |
21 namespace { | 24 namespace { |
22 | 25 |
23 // An adapter to let Read() share the same implementation with ReadToArray(). | 26 // An adapter to let Read() share the same implementation with ReadToArray(). |
24 void* DummyGetDataBuffer(void* user_data, uint32_t count, uint32_t size) { | 27 void* DummyGetDataBuffer(void* user_data, uint32_t count, uint32_t size) { |
25 return user_data; | 28 return user_data; |
26 } | 29 } |
27 | 30 |
31 typedef base::Callback<void(base::PlatformFileError, | |
32 const base::PlatformFileInfo&)> QueryCallback; | |
33 | |
34 // Reads from a file. This should only be called on the file thread. | |
35 void DoQuery(base::PlatformFile file, | |
36 const QueryCallback& callback) { | |
37 base::PlatformFileError error = base::PLATFORM_FILE_OK; | |
38 base::PlatformFileInfo file_info; | |
39 if (!GetPlatformFileInfo(file, &file_info)) | |
40 error = base::PLATFORM_FILE_ERROR_FAILED; | |
41 | |
42 // Detect whether this plugin is running out-of-process. If so, we can invoke | |
43 // the callback directly. If we are running in-process, we must post a task | |
44 // since there is no proxy lock and any resource access would be unsafe. | |
45 // TODO(bbudge) Remove this when in-process support is eliminated. | |
46 if (ppapi::PpapiGlobals::Get()->GetProxyLock()) { | |
47 callback.Run(error, file_info); | |
48 } else { | |
49 ppapi::PpapiGlobals::Get()->GetMainThreadMessageLoop()->PostTask( | |
50 FROM_HERE, | |
51 Bind(callback, error, file_info)); | |
52 } | |
53 } | |
54 | |
55 typedef base::Callback<void(base::PlatformFileError, | |
56 const char* /* data */, | |
57 int /* bytes read */)> ReadCallback; | |
58 | |
59 // Reads file info. This should only be called on the file thread. | |
60 void DoRead(base::PlatformFile file, | |
61 int64 offset, | |
62 int bytes_to_read, | |
63 const ReadCallback& callback) { | |
64 scoped_ptr<char[]> buffer(new char[bytes_to_read]); | |
65 int bytes_read = | |
66 base::ReadPlatformFile(file, offset, buffer.get(), bytes_to_read); | |
67 base::PlatformFileError error = (bytes_read < 0) ? | |
68 base::PLATFORM_FILE_ERROR_FAILED : base::PLATFORM_FILE_OK; | |
69 | |
70 // Detect whether this plugin is running out-of-process. See note in DoQuery. | |
71 if (ppapi::PpapiGlobals::Get()->GetProxyLock()) { | |
72 callback.Run(error, buffer.get(), bytes_read); | |
bbudge
2013/08/06 20:58:05
David: is it safe to pass the buffer this way? cal
| |
73 } else { | |
74 // We can't use base::Passed to transfer buffer since scoped_ptr arguments | |
75 // aren't supported by RunWhileLocked. Transfer ownership to the callback. | |
76 ppapi::PpapiGlobals::Get()->GetMainThreadMessageLoop()->PostTask( | |
77 FROM_HERE, | |
78 Bind(callback, error, base::Owned(buffer.release()), bytes_read)); | |
79 } | |
80 } | |
81 | |
82 void DoClose(base::PlatformFile file) { | |
83 base::ClosePlatformFile(file); | |
84 } | |
85 | |
28 } // namespace | 86 } // namespace |
29 | 87 |
30 namespace ppapi { | 88 namespace ppapi { |
31 namespace proxy { | 89 namespace proxy { |
32 | 90 |
33 FileIOResource::FileIOResource(Connection connection, PP_Instance instance) | 91 FileIOResource::FileIOResource(Connection connection, PP_Instance instance) |
34 : PluginResource(connection, instance) { | 92 : PluginResource(connection, instance), |
93 file_handle_(PP_kInvalidFileHandle), | |
94 file_system_type_(PP_FILESYSTEMTYPE_INVALID) { | |
35 SendCreate(RENDERER, PpapiHostMsg_FileIO_Create()); | 95 SendCreate(RENDERER, PpapiHostMsg_FileIO_Create()); |
36 } | 96 } |
37 | 97 |
38 FileIOResource::~FileIOResource() { | 98 FileIOResource::~FileIOResource() { |
99 CloseFileHandle(); | |
39 } | 100 } |
40 | 101 |
41 PPB_FileIO_API* FileIOResource::AsPPB_FileIO_API() { | 102 PPB_FileIO_API* FileIOResource::AsPPB_FileIO_API() { |
42 return this; | 103 return this; |
43 } | 104 } |
44 | 105 |
45 int32_t FileIOResource::Open(PP_Resource file_ref, | 106 int32_t FileIOResource::Open(PP_Resource file_ref, |
46 int32_t open_flags, | 107 int32_t open_flags, |
47 scoped_refptr<TrackedCallback> callback) { | 108 scoped_refptr<TrackedCallback> callback) { |
48 EnterResourceNoLock<PPB_FileRef_API> enter(file_ref, true); | 109 EnterResourceNoLock<PPB_FileRef_API> enter(file_ref, true); |
49 if (enter.failed()) | 110 if (enter.failed()) |
50 return PP_ERROR_BADRESOURCE; | 111 return PP_ERROR_BADRESOURCE; |
51 | 112 |
113 PPB_FileRef_API* file_ref_api = enter.object(); | |
114 PP_FileSystemType type = file_ref_api->GetFileSystemType(); | |
115 if (type != PP_FILESYSTEMTYPE_LOCALPERSISTENT && | |
116 type != PP_FILESYSTEMTYPE_LOCALTEMPORARY && | |
117 type != PP_FILESYSTEMTYPE_EXTERNAL && | |
118 type != PP_FILESYSTEMTYPE_ISOLATED) { | |
119 NOTREACHED(); | |
120 return PP_ERROR_FAILED; | |
121 } | |
122 file_system_type_ = type; | |
123 | |
52 int32_t rv = state_manager_.CheckOperationState( | 124 int32_t rv = state_manager_.CheckOperationState( |
53 FileIOStateManager::OPERATION_EXCLUSIVE, false); | 125 FileIOStateManager::OPERATION_EXCLUSIVE, false); |
54 if (rv != PP_OK) | 126 if (rv != PP_OK) |
55 return rv; | 127 return rv; |
56 | 128 |
57 Call<PpapiPluginMsg_FileIO_OpenReply>(RENDERER, | 129 Call<PpapiPluginMsg_FileIO_OpenReply>(RENDERER, |
58 PpapiHostMsg_FileIO_Open( | 130 PpapiHostMsg_FileIO_Open( |
59 enter.resource()->host_resource().host_resource(), | 131 enter.resource()->host_resource().host_resource(), |
60 open_flags), | 132 open_flags), |
61 base::Bind(&FileIOResource::OnPluginMsgOpenFileComplete, this, | 133 base::Bind(&FileIOResource::OnPluginMsgOpenFileComplete, this, |
62 callback)); | 134 callback)); |
63 | 135 |
64 state_manager_.SetPendingOperation(FileIOStateManager::OPERATION_EXCLUSIVE); | 136 state_manager_.SetPendingOperation(FileIOStateManager::OPERATION_EXCLUSIVE); |
65 return PP_OK_COMPLETIONPENDING; | 137 return PP_OK_COMPLETIONPENDING; |
66 } | 138 } |
67 | 139 |
68 int32_t FileIOResource::Query(PP_FileInfo* info, | 140 int32_t FileIOResource::Query(PP_FileInfo* info, |
69 scoped_refptr<TrackedCallback> callback) { | 141 scoped_refptr<TrackedCallback> callback) { |
70 int32_t rv = state_manager_.CheckOperationState( | 142 int32_t rv = state_manager_.CheckOperationState( |
71 FileIOStateManager::OPERATION_EXCLUSIVE, true); | 143 FileIOStateManager::OPERATION_EXCLUSIVE, true); |
72 if (rv != PP_OK) | 144 if (rv != PP_OK) |
73 return rv; | 145 return rv; |
74 | 146 |
75 Call<PpapiPluginMsg_FileIO_QueryReply>(RENDERER, | 147 if (file_handle_ == base::kInvalidPlatformFileValue) |
76 PpapiHostMsg_FileIO_Query(), | 148 return PP_ERROR_FAILED; |
77 base::Bind(&FileIOResource::OnPluginMsgQueryComplete, this, | 149 |
78 callback, info)); | 150 PpapiGlobals::Get()->GetFileTaskRunner(pp_instance())->PostTask( |
151 FROM_HERE, | |
152 Bind(&DoQuery, file_handle_, | |
153 RunWhileLocked(base::Bind(&FileIOResource::OnQueryComplete, this, | |
154 callback, info)))); | |
79 | 155 |
80 state_manager_.SetPendingOperation(FileIOStateManager::OPERATION_EXCLUSIVE); | 156 state_manager_.SetPendingOperation(FileIOStateManager::OPERATION_EXCLUSIVE); |
81 return PP_OK_COMPLETIONPENDING; | 157 return PP_OK_COMPLETIONPENDING; |
82 } | 158 } |
83 | 159 |
84 int32_t FileIOResource::Touch(PP_Time last_access_time, | 160 int32_t FileIOResource::Touch(PP_Time last_access_time, |
85 PP_Time last_modified_time, | 161 PP_Time last_modified_time, |
86 scoped_refptr<TrackedCallback> callback) { | 162 scoped_refptr<TrackedCallback> callback) { |
87 int32_t rv = state_manager_.CheckOperationState( | 163 int32_t rv = state_manager_.CheckOperationState( |
88 FileIOStateManager::OPERATION_EXCLUSIVE, true); | 164 FileIOStateManager::OPERATION_EXCLUSIVE, true); |
(...skipping 14 matching lines...) Expand all Loading... | |
103 int32_t bytes_to_read, | 179 int32_t bytes_to_read, |
104 scoped_refptr<TrackedCallback> callback) { | 180 scoped_refptr<TrackedCallback> callback) { |
105 int32_t rv = state_manager_.CheckOperationState( | 181 int32_t rv = state_manager_.CheckOperationState( |
106 FileIOStateManager::OPERATION_READ, true); | 182 FileIOStateManager::OPERATION_READ, true); |
107 if (rv != PP_OK) | 183 if (rv != PP_OK) |
108 return rv; | 184 return rv; |
109 | 185 |
110 PP_ArrayOutput output_adapter; | 186 PP_ArrayOutput output_adapter; |
111 output_adapter.GetDataBuffer = &DummyGetDataBuffer; | 187 output_adapter.GetDataBuffer = &DummyGetDataBuffer; |
112 output_adapter.user_data = buffer; | 188 output_adapter.user_data = buffer; |
113 state_manager_.SetPendingOperation(FileIOStateManager::OPERATION_READ); | |
114 return ReadValidated(offset, bytes_to_read, output_adapter, callback); | 189 return ReadValidated(offset, bytes_to_read, output_adapter, callback); |
115 } | 190 } |
116 | 191 |
117 int32_t FileIOResource::ReadToArray(int64_t offset, | 192 int32_t FileIOResource::ReadToArray(int64_t offset, |
118 int32_t max_read_length, | 193 int32_t max_read_length, |
119 PP_ArrayOutput* array_output, | 194 PP_ArrayOutput* array_output, |
120 scoped_refptr<TrackedCallback> callback) { | 195 scoped_refptr<TrackedCallback> callback) { |
121 DCHECK(array_output); | 196 DCHECK(array_output); |
122 int32_t rv = state_manager_.CheckOperationState( | 197 int32_t rv = state_manager_.CheckOperationState( |
123 FileIOStateManager::OPERATION_READ, true); | 198 FileIOStateManager::OPERATION_READ, true); |
124 if (rv != PP_OK) | 199 if (rv != PP_OK) |
125 return rv; | 200 return rv; |
126 | 201 |
127 state_manager_.SetPendingOperation(FileIOStateManager::OPERATION_READ); | |
128 return ReadValidated(offset, max_read_length, *array_output, callback); | 202 return ReadValidated(offset, max_read_length, *array_output, callback); |
129 } | 203 } |
130 | 204 |
131 int32_t FileIOResource::Write(int64_t offset, | 205 int32_t FileIOResource::Write(int64_t offset, |
132 const char* buffer, | 206 const char* buffer, |
133 int32_t bytes_to_write, | 207 int32_t bytes_to_write, |
134 scoped_refptr<TrackedCallback> callback) { | 208 scoped_refptr<TrackedCallback> callback) { |
135 int32_t rv = state_manager_.CheckOperationState( | 209 int32_t rv = state_manager_.CheckOperationState( |
136 FileIOStateManager::OPERATION_WRITE, true); | 210 FileIOStateManager::OPERATION_WRITE, true); |
137 if (rv != PP_OK) | 211 if (rv != PP_OK) |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
174 Call<PpapiPluginMsg_FileIO_GeneralReply>(RENDERER, | 248 Call<PpapiPluginMsg_FileIO_GeneralReply>(RENDERER, |
175 PpapiHostMsg_FileIO_Flush(), | 249 PpapiHostMsg_FileIO_Flush(), |
176 base::Bind(&FileIOResource::OnPluginMsgGeneralComplete, this, | 250 base::Bind(&FileIOResource::OnPluginMsgGeneralComplete, this, |
177 callback)); | 251 callback)); |
178 | 252 |
179 state_manager_.SetPendingOperation(FileIOStateManager::OPERATION_EXCLUSIVE); | 253 state_manager_.SetPendingOperation(FileIOStateManager::OPERATION_EXCLUSIVE); |
180 return PP_OK_COMPLETIONPENDING; | 254 return PP_OK_COMPLETIONPENDING; |
181 } | 255 } |
182 | 256 |
183 void FileIOResource::Close() { | 257 void FileIOResource::Close() { |
258 CloseFileHandle(); | |
184 Post(RENDERER, PpapiHostMsg_FileIO_Close()); | 259 Post(RENDERER, PpapiHostMsg_FileIO_Close()); |
185 } | 260 } |
186 | 261 |
187 int32_t FileIOResource::GetOSFileDescriptor() { | 262 int32_t FileIOResource::GetOSFileDescriptor() { |
188 int32_t file_descriptor; | 263 int32_t file_descriptor; |
189 // Only available when running in process. | 264 // Only available when running in process. |
190 SyncCall<PpapiPluginMsg_FileIO_GetOSFileDescriptorReply>( | 265 SyncCall<PpapiPluginMsg_FileIO_GetOSFileDescriptorReply>( |
191 RENDERER, PpapiHostMsg_FileIO_GetOSFileDescriptor(), &file_descriptor); | 266 RENDERER, PpapiHostMsg_FileIO_GetOSFileDescriptor(), &file_descriptor); |
192 return file_descriptor; | 267 return file_descriptor; |
193 } | 268 } |
194 | 269 |
270 int32_t FileIOResource::RequestOSFileHandle( | |
271 PP_FileHandle* handle, | |
272 scoped_refptr<TrackedCallback> callback) { | |
273 int32_t rv = state_manager_.CheckOperationState( | |
274 FileIOStateManager::OPERATION_EXCLUSIVE, true); | |
275 if (rv != PP_OK) | |
276 return rv; | |
277 | |
278 Call<PpapiPluginMsg_FileIO_RequestOSFileHandleReply>(RENDERER, | |
279 PpapiHostMsg_FileIO_RequestOSFileHandle(), | |
280 base::Bind(&FileIOResource::OnPluginMsgRequestOSFileHandleComplete, this, | |
281 callback, handle)); | |
282 | |
283 state_manager_.SetPendingOperation(FileIOStateManager::OPERATION_EXCLUSIVE); | |
284 return PP_OK_COMPLETIONPENDING; | |
285 } | |
286 | |
195 int32_t FileIOResource::WillWrite(int64_t offset, | 287 int32_t FileIOResource::WillWrite(int64_t offset, |
196 int32_t bytes_to_write, | 288 int32_t bytes_to_write, |
197 scoped_refptr<TrackedCallback> callback) { | 289 scoped_refptr<TrackedCallback> callback) { |
198 Call<PpapiPluginMsg_FileIO_GeneralReply>(RENDERER, | 290 Call<PpapiPluginMsg_FileIO_GeneralReply>(RENDERER, |
199 PpapiHostMsg_FileIO_WillWrite(offset, bytes_to_write), | 291 PpapiHostMsg_FileIO_WillWrite(offset, bytes_to_write), |
200 base::Bind(&FileIOResource::OnPluginMsgGeneralComplete, this, | 292 base::Bind(&FileIOResource::OnPluginMsgGeneralComplete, this, |
201 callback)); | 293 callback)); |
294 | |
202 state_manager_.SetPendingOperation(FileIOStateManager::OPERATION_EXCLUSIVE); | 295 state_manager_.SetPendingOperation(FileIOStateManager::OPERATION_EXCLUSIVE); |
203 return PP_OK_COMPLETIONPENDING; | 296 return PP_OK_COMPLETIONPENDING; |
204 } | 297 } |
205 | 298 |
206 int32_t FileIOResource::WillSetLength(int64_t length, | 299 int32_t FileIOResource::WillSetLength(int64_t length, |
207 scoped_refptr<TrackedCallback> callback) { | 300 scoped_refptr<TrackedCallback> callback) { |
208 Call<PpapiPluginMsg_FileIO_GeneralReply>(RENDERER, | 301 Call<PpapiPluginMsg_FileIO_GeneralReply>(RENDERER, |
209 PpapiHostMsg_FileIO_WillSetLength(length), | 302 PpapiHostMsg_FileIO_WillSetLength(length), |
210 base::Bind(&FileIOResource::OnPluginMsgGeneralComplete, this, | 303 base::Bind(&FileIOResource::OnPluginMsgGeneralComplete, this, |
211 callback)); | 304 callback)); |
305 | |
212 state_manager_.SetPendingOperation(FileIOStateManager::OPERATION_EXCLUSIVE); | 306 state_manager_.SetPendingOperation(FileIOStateManager::OPERATION_EXCLUSIVE); |
213 return PP_OK_COMPLETIONPENDING; | 307 return PP_OK_COMPLETIONPENDING; |
214 } | 308 } |
215 | 309 |
216 int32_t FileIOResource::ReadValidated(int64_t offset, | 310 int32_t FileIOResource::ReadValidated(int64_t offset, |
217 int32_t bytes_to_read, | 311 int32_t bytes_to_read, |
218 const PP_ArrayOutput& array_output, | 312 const PP_ArrayOutput& array_output, |
219 scoped_refptr<TrackedCallback> callback) { | 313 scoped_refptr<TrackedCallback> callback) { |
220 Call<PpapiPluginMsg_FileIO_ReadReply>(RENDERER, | 314 if (file_handle_ == base::kInvalidPlatformFileValue) |
221 PpapiHostMsg_FileIO_Read(offset, bytes_to_read), | 315 return PP_ERROR_FAILED; |
222 base::Bind(&FileIOResource::OnPluginMsgReadComplete, this, | 316 if (bytes_to_read < 0) |
223 callback, array_output)); | 317 return PP_ERROR_FAILED; |
318 | |
319 PpapiGlobals::Get()->GetFileTaskRunner(pp_instance())->PostTask( | |
320 FROM_HERE, | |
321 Bind(&DoRead, file_handle_, offset, bytes_to_read, | |
322 RunWhileLocked(base::Bind(&FileIOResource::OnReadComplete, this, | |
323 callback, array_output)))); | |
324 | |
325 state_manager_.SetPendingOperation(FileIOStateManager::OPERATION_READ); | |
224 return PP_OK_COMPLETIONPENDING; | 326 return PP_OK_COMPLETIONPENDING; |
225 } | 327 } |
226 | 328 |
227 int32_t FileIOResource::RequestOSFileHandle( | 329 void FileIOResource::CloseFileHandle() { |
228 PP_FileHandle* handle, | 330 if (file_handle_ != base::kInvalidPlatformFileValue) { |
229 scoped_refptr<TrackedCallback> callback) { | 331 base::TaskRunner* file_task_runner = |
230 int32_t rv = state_manager_.CheckOperationState( | 332 PpapiGlobals::Get()->GetFileTaskRunner(pp_instance()); |
231 FileIOStateManager::OPERATION_EXCLUSIVE, true); | 333 file_task_runner->PostTask(FROM_HERE, |
232 if (rv != PP_OK) | 334 base::Bind(&DoClose, file_handle_)); |
233 return rv; | |
234 | 335 |
235 Call<PpapiPluginMsg_FileIO_RequestOSFileHandleReply>(RENDERER, | 336 file_handle_ = base::kInvalidPlatformFileValue; |
236 PpapiHostMsg_FileIO_RequestOSFileHandle(), | 337 } |
237 base::Bind(&FileIOResource::OnPluginMsgRequestOSFileHandleComplete, this, | 338 } |
238 callback, handle)); | |
239 | 339 |
240 state_manager_.SetPendingOperation(FileIOStateManager::OPERATION_EXCLUSIVE); | 340 void FileIOResource::OnQueryComplete( |
241 return PP_OK_COMPLETIONPENDING; | 341 scoped_refptr<TrackedCallback> callback, |
342 PP_FileInfo* output_info, | |
343 base::PlatformFileError error_code, | |
344 const base::PlatformFileInfo& file_info) { | |
345 DCHECK(state_manager_.get_pending_operation() == | |
346 FileIOStateManager::OPERATION_EXCLUSIVE); | |
347 | |
348 if (!TrackedCallback::IsPending(callback)) { | |
349 state_manager_.SetOperationFinished(); | |
350 return; | |
351 } | |
352 | |
353 int32_t result = ::ppapi::PlatformFileErrorToPepperError(error_code); | |
354 if (result == PP_OK) { | |
355 ppapi::PlatformFileInfoToPepperFileInfo(file_info, file_system_type_, | |
356 output_info); | |
357 } | |
358 | |
359 // End this operation now, so the user's callback can execute another FileIO | |
360 // operation, assuming there are no other pending operations. | |
361 state_manager_.SetOperationFinished(); | |
362 callback->Run(result); | |
363 } | |
364 | |
365 void FileIOResource::OnReadComplete( | |
366 scoped_refptr<TrackedCallback> callback, | |
367 PP_ArrayOutput array_output, | |
368 base::PlatformFileError error_code, | |
369 const char* data, int bytes_read) { | |
370 DCHECK(state_manager_.get_pending_operation() == | |
371 FileIOStateManager::OPERATION_READ); | |
372 | |
373 if (!TrackedCallback::IsPending(callback)) { | |
374 state_manager_.SetOperationFinished(); | |
375 return; | |
376 } | |
377 | |
378 int32_t result = ::ppapi::PlatformFileErrorToPepperError(error_code); | |
379 if (result == PP_OK) { | |
380 result = std::max(0, bytes_read); | |
381 ArrayWriter output; | |
382 output.set_pp_array_output(array_output); | |
383 if (output.is_valid()) | |
384 output.StoreArray(data, result); | |
385 else | |
386 result = PP_ERROR_FAILED; | |
387 } | |
388 | |
389 // End this operation now, so the user's callback can execute another FileIO | |
390 // operation, assuming there are no other pending operations. | |
391 state_manager_.SetOperationFinished(); | |
392 callback->Run(result); | |
242 } | 393 } |
243 | 394 |
244 void FileIOResource::OnPluginMsgGeneralComplete( | 395 void FileIOResource::OnPluginMsgGeneralComplete( |
245 scoped_refptr<TrackedCallback> callback, | 396 scoped_refptr<TrackedCallback> callback, |
246 const ResourceMessageReplyParams& params) { | 397 const ResourceMessageReplyParams& params) { |
247 DCHECK(state_manager_.get_pending_operation() == | 398 DCHECK(state_manager_.get_pending_operation() == |
248 FileIOStateManager::OPERATION_EXCLUSIVE || | 399 FileIOStateManager::OPERATION_EXCLUSIVE || |
249 state_manager_.get_pending_operation() == | 400 state_manager_.get_pending_operation() == |
250 FileIOStateManager::OPERATION_WRITE); | 401 FileIOStateManager::OPERATION_WRITE); |
251 // End the operation now. The callback may perform another file operation. | 402 // End this operation now, so the user's callback can execute another FileIO |
403 // operation, assuming there are no other pending operations. | |
252 state_manager_.SetOperationFinished(); | 404 state_manager_.SetOperationFinished(); |
253 callback->Run(params.result()); | 405 callback->Run(params.result()); |
254 } | 406 } |
255 | 407 |
256 void FileIOResource::OnPluginMsgOpenFileComplete( | 408 void FileIOResource::OnPluginMsgOpenFileComplete( |
257 scoped_refptr<TrackedCallback> callback, | 409 scoped_refptr<TrackedCallback> callback, |
258 const ResourceMessageReplyParams& params) { | 410 const ResourceMessageReplyParams& params) { |
259 DCHECK(state_manager_.get_pending_operation() == | 411 DCHECK(state_manager_.get_pending_operation() == |
260 FileIOStateManager::OPERATION_EXCLUSIVE); | 412 FileIOStateManager::OPERATION_EXCLUSIVE); |
261 if (params.result() == PP_OK) | 413 if (params.result() == PP_OK) |
262 state_manager_.SetOpenSucceed(); | 414 state_manager_.SetOpenSucceed(); |
263 // End the operation now. The callback may perform another file operation. | 415 |
416 int32_t result = params.result(); | |
417 IPC::PlatformFileForTransit transit_file; | |
418 if (result == PP_OK && !params.TakeFileHandleAtIndex(0, &transit_file)) | |
419 result = PP_ERROR_FAILED; | |
420 file_handle_ = IPC::PlatformFileForTransitToPlatformFile(transit_file); | |
421 | |
422 // End this operation now, so the user's callback can execute another FileIO | |
423 // operation, assuming there are no other pending operations. | |
264 state_manager_.SetOperationFinished(); | 424 state_manager_.SetOperationFinished(); |
265 callback->Run(params.result()); | 425 callback->Run(params.result()); |
266 } | 426 } |
267 | 427 |
268 void FileIOResource::OnPluginMsgQueryComplete( | |
269 scoped_refptr<TrackedCallback> callback, | |
270 PP_FileInfo* output_info, | |
271 const ResourceMessageReplyParams& params, | |
272 const PP_FileInfo& info) { | |
273 DCHECK(state_manager_.get_pending_operation() == | |
274 FileIOStateManager::OPERATION_EXCLUSIVE); | |
275 *output_info = info; | |
276 // End the operation now. The callback may perform another file operation. | |
277 state_manager_.SetOperationFinished(); | |
278 callback->Run(params.result()); | |
279 } | |
280 | |
281 void FileIOResource::OnPluginMsgReadComplete( | |
282 scoped_refptr<TrackedCallback> callback, | |
283 PP_ArrayOutput array_output, | |
284 const ResourceMessageReplyParams& params, | |
285 const std::string& data) { | |
286 DCHECK(state_manager_.get_pending_operation() == | |
287 FileIOStateManager::OPERATION_READ); | |
288 | |
289 // The result code should contain the data size if it's positive. | |
290 int32_t result = params.result(); | |
291 DCHECK((result < 0 && data.size() == 0) || | |
292 result == static_cast<int32_t>(data.size())); | |
293 | |
294 ArrayWriter output; | |
295 output.set_pp_array_output(array_output); | |
296 if (output.is_valid()) | |
297 output.StoreArray(data.data(), std::max(0, result)); | |
298 else | |
299 result = PP_ERROR_FAILED; | |
300 | |
301 // End the operation now. The callback may perform another file operation. | |
302 state_manager_.SetOperationFinished(); | |
303 callback->Run(result); | |
304 } | |
305 | |
306 void FileIOResource::OnPluginMsgRequestOSFileHandleComplete( | 428 void FileIOResource::OnPluginMsgRequestOSFileHandleComplete( |
307 scoped_refptr<TrackedCallback> callback, | 429 scoped_refptr<TrackedCallback> callback, |
308 PP_FileHandle* output_handle, | 430 PP_FileHandle* output_handle, |
309 const ResourceMessageReplyParams& params) { | 431 const ResourceMessageReplyParams& params) { |
310 DCHECK(state_manager_.get_pending_operation() == | 432 DCHECK(state_manager_.get_pending_operation() == |
311 FileIOStateManager::OPERATION_EXCLUSIVE); | 433 FileIOStateManager::OPERATION_EXCLUSIVE); |
312 | 434 |
313 if (!TrackedCallback::IsPending(callback)) { | 435 if (!TrackedCallback::IsPending(callback)) { |
314 state_manager_.SetOperationFinished(); | 436 state_manager_.SetOperationFinished(); |
315 return; | 437 return; |
316 } | 438 } |
317 | 439 |
318 int32_t result = params.result(); | 440 int32_t result = params.result(); |
319 IPC::PlatformFileForTransit transit_file; | 441 IPC::PlatformFileForTransit transit_file; |
320 if (!params.TakeFileHandleAtIndex(0, &transit_file)) | 442 if (!params.TakeFileHandleAtIndex(0, &transit_file)) |
321 result = PP_ERROR_FAILED; | 443 result = PP_ERROR_FAILED; |
322 *output_handle = IPC::PlatformFileForTransitToPlatformFile(transit_file); | 444 *output_handle = IPC::PlatformFileForTransitToPlatformFile(transit_file); |
323 | 445 |
324 // End the operation now. The callback may perform another file operation. | 446 // End this operation now, so the user's callback can execute another FileIO |
447 // operation, assuming there are no other pending operations. | |
325 state_manager_.SetOperationFinished(); | 448 state_manager_.SetOperationFinished(); |
326 callback->Run(result); | 449 callback->Run(result); |
327 } | 450 } |
328 | 451 |
329 } // namespace proxy | 452 } // namespace proxy |
330 } // namespace ppapi | 453 } // namespace ppapi |
OLD | NEW |