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

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

Issue 1093383002: [WIP] Provided file system from NACL. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Moved several modules to chromeos folder. Created 5 years, 5 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
OLDNEW
(Empty)
1 // Copyright 2015 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 #include "ppapi/proxy/filesystem_provider_resource.h"
5
6 #include "base/bind.h"
7 #include "base/logging.h"
8 #include "base/memory/scoped_ptr.h"
9 #include "base/numerics/safe_conversions.h"
10 #include "ppapi/c/pp_errors.h"
11 #include "ppapi/proxy/dispatch_reply_message.h"
12 #include "ppapi/proxy/plugin_dispatcher.h"
13 #include "ppapi/proxy/ppapi_messages.h"
14 #include "ppapi/shared_impl/array_var.h"
15 #include "ppapi/shared_impl/dictionary_var.h"
16 #include "ppapi/shared_impl/ppapi_globals.h"
17 #include "ppapi/shared_impl/proxy_lock.h"
18 #include "ppapi/shared_impl/tracked_callback.h"
19 #include "ppapi/shared_impl/var.h"
20 #include "ppapi/shared_impl/var_tracker.h"
21
22 using ppapi::DictionaryVar;
23 using ppapi::ArrayVar;
24
25 namespace ppapi {
26 namespace proxy {
27 namespace {
28
29 const uint32_t kMaximumCachedReplies = 10;
30
31 static std::string PP_ErrorToString(int32_t error) {
32 switch (error) {
33 case PP_OK:
34 return "OK";
35 case PP_ERROR_FAILED:
36 return "FAILED";
37 case PP_ERROR_INPROGRESS:
38 return "IN_USE";
39 case PP_ERROR_FILEEXISTS:
40 return "EXISTS";
41 case PP_ERROR_FILENOTFOUND:
42 return "NOT_FOUND";
43 case PP_ERROR_NOACCESS:
44 return "ACCESS_DENIED";
45 case PP_ERROR_FILE_TOO_MANY_OPENED:
46 return "TOO_MANY_OPENED";
47 case PP_ERROR_NOMEMORY:
48 return "NO_MEMORY";
49 case PP_ERROR_NOSPACE:
50 return "NO_SPACE";
51 case PP_ERROR_NOTADIRECTORY:
52 return "NOT_A_DIRECTORY";
53 case PP_ERROR_NOTSUPPORTED:
54 return "INVALID_OPERATION";
55 case PP_ERROR_SECURITY:
56 return "SECURITY";
57 case PP_ERROR_ABORTED:
58 return "ABORT";
59 case PP_ERROR_NOTAFILE:
60 return "NOT_A_FILE";
61 case PP_ERROR_FILENOTEMPTY:
62 return "NOT_EMPTY";
63 case PP_ERROR_INVALID_URL:
64 return "INVALID_URL";
65 case PP_ERROR_FILE_IO:
66 return "IO";
67 }
68 NOTREACHED();
69 return "";
70 }
71
72 } // namespace
73
74 FilesystemProviderResource::ShmChannelController::ShmChannelController(
75 uint32_t size, FlushResponseCallback callback)
76 : max_size(size),
77 ready(true),
78 callback(callback){
79 }
80 FilesystemProviderResource::ShmChannelController::~ShmChannelController() {
81 }
82
83 bool FilesystemProviderResource::ShmChannelController::EnqueueResponse(
84 scoped_ptr<base::ListValue> response,
85 const char* data, uint32_t data_size) {
86 // If channel ready send it straight away
87 if (ready) {
88 // Flush Request
89 ready = !callback.Run(response.Pass(), data, data_size);
90 if(!ready)
91 return true;
92 }
93 // If channel is not ready or failed to send,
94 // cache the response
95 if( size() + 1 > max_size ) {
96 return false;
97 }
98
99 scoped_ptr<base::BinaryValue> payload(
100 base::BinaryValue::CreateWithCopiedBuffer(static_cast<const char*>(data),
101 data_size));
102 if( !payload.get() )
103 return false;
104
105 response->Append(payload.release());
106 replies.push_back(response.release());
107
108 return true;
109 }
110
111 bool FilesystemProviderResource::ShmChannelController::PushNextResponse() {
112 scoped_ptr<base::ListValue> response;
113 scoped_ptr<base::Value> payload;
114 while (size()>0 && ready ) {
115 // Try to push a response from the queue to
116 // the browser
117 response.reset(replies.front());
118 replies.weak_erase(replies.begin());
119
120 if(!response->Remove(response->GetSize()-1, &payload)||
121 !payload->IsType(base::Value::TYPE_BINARY))
122 continue;
123
124 base::BinaryValue* data = static_cast<base::BinaryValue*>(payload.get());
125 ready = !callback.Run(
126 response.Pass(),
127 data->GetBuffer(),
128 data->GetSize());
129 }
130 return !ready;
131 }
132
133 bool
134 FilesystemProviderResource::ShmChannelController::AckLastPushedResponse() {
135 return ready = true;
136 }
137
138 uint32_t FilesystemProviderResource::ShmChannelController::size() {
139 return replies.size();
140 }
141
142 FilesystemProviderResource::ProvidedFilesystemInfo::ProvidedFilesystemInfo()
143 :filesystem_id("none"),
144 display_name("none"),
145 writable(false),opened_files_limit(0){
146 }
147
148 FilesystemProviderResource::ProvidedFilesystemInfo::~ProvidedFilesystemInfo(){}
149
150 FilesystemProviderResource::ShmBuffer::ShmBuffer(
151 uint32_t read_size, uint32_t write_size,
152 scoped_ptr<base::SharedMemory> shm)
153 : read_size(read_size),write_size(write_size), shm(shm.Pass()) {
154 DCHECK(this->shm);
155 }
156
157 FilesystemProviderResource::ShmBuffer::~ShmBuffer() {}
158
159 FilesystemProviderResource::RequestManager::RequestManager() {}
160
161 FilesystemProviderResource::RequestManager::~RequestManager() {}
162
163 void FilesystemProviderResource::RequestManager::AddRequest(
164 int32_t request_id, PP_OperationType_Dev operation ) {
165 requests_[ request_id ] = OperationStartTimePair(
166 operation,
167 std::chrono::system_clock::now() );
168 }
169
170 bool FilesystemProviderResource::RequestManager::HasRequest(
171 int32_t request_id) {
172 return requests_.find(request_id)!=requests_.end();
173 }
174
175 bool FilesystemProviderResource::RequestManager::RemoveRequest(
176 int32_t request_id, int *out_time_span) {
177 ListOfRequestsIterator it=requests_.find(request_id);
178 if (it==requests_.end())
179 return false;
180
181 // Compute operation time span
182 std::chrono::time_point<std::chrono::system_clock> now =
183 std::chrono::system_clock::now();
184
185 if(out_time_span)
186 *out_time_span = std::chrono::duration_cast<std::chrono::seconds>
187 (now - it->second.second).count();
188 requests_.erase( it );
189 return true;
190 }
191
192 FilesystemProviderResource::FilesystemProviderResource(
193 Connection connection,
194 PP_Instance instance )
195 :PluginResource( connection , instance ),
196 mounted_(false),
197 request_manager_(new RequestManager),
198 read_channel_controller_(
199 new ShmChannelController(
200 kMaximumCachedReplies,
201 base::Bind(&FilesystemProviderResource::FlushReadResponse,
202 this))) {
203 DCHECK(request_manager_);
204 DCHECK(read_channel_controller_);
205 SendCreate(BROWSER, PpapiHostMsg_FilesystemProvider_Create() );
206 }
207
208 FilesystemProviderResource::~FilesystemProviderResource() {
209 }
210
211
212 thunk::PPB_FilesystemProvider_API*
213 FilesystemProviderResource::AsPPB_FilesystemProvider_API() {
214 return this;
215 }
216
217 void FilesystemProviderResource::OnReplyReceived(
218 const ResourceMessageReplyParams &params, const IPC::Message &msg) {
219 if (params.sequence()) {
220 PluginResource::OnReplyReceived(params, msg);
221 return;
222 }
223 PPAPI_BEGIN_MESSAGE_MAP(FilesystemProviderResource, msg)
224 PPAPI_DISPATCH_PLUGIN_RESOURCE_CALL(
225 PpapiPluginMsg_FilesystemProvider_OperationRequest,
226 OnPluginMsgOperationRequest)
227 PPAPI_DISPATCH_PLUGIN_RESOURCE_CALL(
228 PpapiPluginMsg_FilesystemProvider_Buffers,
229 OnPluginMsgBuffersReady)
230 PPAPI_DISPATCH_PLUGIN_RESOURCE_CALL_0(
231 PpapiPluginMsg_FilesystemProvider_ReadAck,
232 OnPluginMsgReadAck)
233 PPAPI_DISPATCH_PLUGIN_RESOURCE_CALL_UNHANDLED(NOTREACHED())
234 PPAPI_END_MESSAGE_MAP()
235 }
236
237 int32_t FilesystemProviderResource::Mount(
238 PP_Var filesystem_id,
239 PP_Var display_name,
240 PP_Bool writable,
241 int32_t opened_files_limit,
242 scoped_refptr<TrackedCallback> callback) {
243 if ( mounted_ )
244 return PP_ERROR_ADDRESS_IN_USE;
245 if ( TrackedCallback::IsPending(mount_callback_) )
246 return PP_ERROR_INPROGRESS;
247
248 StringVar* string_var = nullptr;
249
250 const PP_Var *parameter_p[] = { &filesystem_id, &display_name };
251 std::string *value_p[] = {
252 &filesystem_info_.filesystem_id,
253 &filesystem_info_.display_name
254 };
255
256 for( uint32_t i = 0; i < sizeof( value_p ) / sizeof( value_p[0] ); i++ ) {
257 string_var = StringVar :: FromPPVar( *parameter_p[ i ] );
258 *value_p[ i ] = string_var ? string_var->value() : std::string();
259 }
260
261 filesystem_info_.writable = PP_ToBool( writable );
262 filesystem_info_.opened_files_limit = opened_files_limit;
263
264 // Remember the callback and the address of the return param
265 mount_callback_ = callback;
266
267 // Send mount request to the browser
268 // and receive response in OnPluginMsgMountReply
269 scoped_ptr<base::ListValue> request(
270 filesystem_provider_internal::
271 PluginToBrowserTranslator::GenerateMountMessage(
272 filesystem_info_.filesystem_id, filesystem_info_.display_name,
273 filesystem_info_.writable,filesystem_info_.opened_files_limit));
274 if (!request.get())
275 return PP_ERROR_FAILED;
276
277 Call<PpapiPluginMsg_FilesystemProvider_MountReply>(
278 BROWSER,
279 PpapiHostMsg_FilesystemProvider_Mount(*request),
280 base::Bind(&FilesystemProviderResource::OnPluginMsgMountReply, this));
281 return PP_OK_COMPLETIONPENDING;
282 }
283
284 int32_t FilesystemProviderResource::Unmount(PP_Var filesystemId,
285 scoped_refptr<TrackedCallback> callback ) {
286 if ( !mounted_ )
287 return PP_ERROR_FAILED;
288 if ( TrackedCallback::IsPending(unmount_callback_) )
289 return PP_ERROR_INPROGRESS;
290
291 StringVar* string_var = nullptr;
292
293 string_var = StringVar::FromPPVar( filesystemId );
294 std::string fs_id = string_var ? string_var->value() : std::string();
295
296 if (fs_id!=filesystem_info_.filesystem_id)
297 return PP_ERROR_FAILED;
298
299 // Remember the unmount callback and the address of the return param
300 unmount_callback_ =callback;
301
302 Call < PpapiPluginMsg_FilesystemProvider_UnmountReply >(
303 BROWSER,
304 PpapiHostMsg_FilesystemProvider_Unmount( fs_id ),
305 base::Bind( &FilesystemProviderResource::OnPluginMsgUnmountReply,
306 this )
307 );
308
309 return PP_OK_COMPLETIONPENDING;
310 }
311
312 int32_t FilesystemProviderResource::Notify(PP_Var notify_options) {
313 scoped_ptr<base::ListValue> notification(
314 filesystem_provider_internal::PluginToBrowserTranslator
315 ::GenerateNotifyMessage(notify_options) );
316 if (!notification.get())
317 return PP_ERROR_MALFORMED_INPUT;
318 Post(
319 BROWSER,
320 PpapiHostMsg_FilesystemProvider_Notify(*notification));
321 return PP_OK;
322 }
323
324
325 int32_t FilesystemProviderResource::SendSuccessResponse(
326 PP_OperationType_Dev operation_type,
327 int32_t request_id) {
328
329 scoped_ptr<base::ListValue> response;
330
331 switch( operation_type ) {
332 case PP_OperationType_GETMETADATA:
333 case PP_OperationType_READDIRECTORY:
334 case PP_OperationType_READFILE:
335 return PP_ERROR_BADARGUMENT;
336 default: {
337 // If we can't find a matching request from the browser
338 // bail out
339 int time_span = 0;
340 if( !request_manager_->RemoveRequest(request_id, &time_span) )//
341 return PP_ERROR_BADARGUMENT;
342 if (operation_type==PP_OperationType_UNMOUNT)
343 mounted_ = false;
344 response = filesystem_provider_internal::
345 PluginToBrowserTranslator::GenerateSuccessResponse(
346 operation_type, filesystem_info_.filesystem_id,
347 request_id, time_span );
348 if(!response.get())
349 return PP_ERROR_FAILED;
350 }
351 }
352 Post(
353 BROWSER,
354 PpapiHostMsg_FilesystemProvider_OperationResponse(*response));
355 return PP_OK;
356 }
357
358 int32_t FilesystemProviderResource::SendErrorResponse(
359 PP_OperationType_Dev operation_type,
360 int32_t error,
361 int32_t request_id) {
362
363 int time_span = 0;
364 if( !request_manager_->RemoveRequest(request_id, &time_span) )
365 return PP_ERROR_BADARGUMENT;
366
367 scoped_ptr<base::ListValue> response(
368 filesystem_provider_internal::
369 PluginToBrowserTranslator::GenerateFailureResponse(
370 operation_type, error, filesystem_info_.filesystem_id, request_id,
371 time_span ));
372 if(!response.get())
373 return PP_ERROR_FAILED;
374
375 Post(
376 BROWSER,
377 PpapiHostMsg_FilesystemProvider_OperationResponse(*response));
378 return PP_OK;
379 }
380
381 int32_t FilesystemProviderResource::SendMetadataSuccessResponse(
382 struct PP_Var metadata,
383 int32_t request_id) {
384
385 int time_span = 0;
386 if( !request_manager_->RemoveRequest(request_id, &time_span) )
387 return PP_ERROR_BADARGUMENT;
388
389 scoped_ptr<base::ListValue> response(
390 filesystem_provider_internal::
391 PluginToBrowserTranslator::GenerateMetadataResponse(
392 metadata, request_id, filesystem_info_.filesystem_id, time_span));
393 if(!response.get())
394 return PP_ERROR_FAILED;
395
396 Post(
397 BROWSER,
398 PpapiHostMsg_FilesystemProvider_OperationResponse(*response)
399 );
400 return PP_OK;
401 }
402
403 int32_t FilesystemProviderResource::SendReadDirectorySuccessResponse(
404 PP_Var entries,
405 PP_Bool has_more, int32_t request_id) {
406
407 int time_span = 0;
408 if (has_more) {
409 if (!request_manager_->HasRequest(request_id))
410 return PP_ERROR_BADARGUMENT;
411 } else {
412 if(!request_manager_->RemoveRequest(request_id,&time_span))
413 return PP_ERROR_BADARGUMENT;
414 }
415 scoped_ptr<base::ListValue> response(
416 filesystem_provider_internal::
417 PluginToBrowserTranslator::GenerateReadDirectoryResponse(
418 entries, has_more, request_id,
419 filesystem_info_.filesystem_id, time_span ));
420
421 if(!response.get())
422 return PP_ERROR_FAILED;
423 Post(
424 BROWSER,
425 PpapiHostMsg_FilesystemProvider_OperationResponse(*response) );
426 return PP_OK;
427 }
428
429 int32_t FilesystemProviderResource::SendReadFileSuccessResponse(
430 uint32_t data_size,
431 const void *data,
432 PP_Bool has_more,
433 int32_t request_id) {
434
435 int time_span = 0;
436 // Check if this is an answer to a previous request
437 if (has_more) {
438 if (!request_manager_->HasRequest(request_id))
439 return PP_ERROR_BADARGUMENT;
440 } else {
441 if(!request_manager_->RemoveRequest(request_id,&time_span))
442 return PP_ERROR_BADARGUMENT;
443 }
444 // check if shared memory is ready and the right size
445 if(!read_write_buffer_.get())
446 return PP_ERROR_FAILED;
447 if(data_size > read_write_buffer_->read_size )
448 return PP_ERROR_MESSAGE_TOO_BIG;
449
450 scoped_ptr<base::ListValue> response(
451 filesystem_provider_internal::
452 PluginToBrowserTranslator::GenerateReadFileSuccessResponse(
453 data_size, PP_ToBool( has_more ), request_id, time_span,
454 filesystem_info_.filesystem_id));
455
456 if(!response.get())
457 return PP_ERROR_FAILED;
458
459 // Send response or enqueue it
460 if(!read_channel_controller_->EnqueueResponse(
461 response.Pass(), static_cast<const char*>(data),data_size))
462 return PP_ERROR_FAILED;
463 return PP_OK;
464 }
465
466 int32_t FilesystemProviderResource::GetNextRequest(
467 PP_FilesystemRequest* request, scoped_refptr<TrackedCallback> callback) {
468 if(TrackedCallback::IsPending(get_next_request_callback_))
469 return PP_ERROR_INPROGRESS;
470 // Retain the container address
471 get_next_request_callback_data_ = request;
472 // If buffered requests are pending return the first one
473 if(!received_requests_.empty()) {
474 if(!WriteRequest())
475 return PP_ERROR_FAILED;
476 // By returning PP_OK the callback is run
477 return PP_OK;
478 }
479 // Retain the callback for future execution
480 get_next_request_callback_=callback;
481
482 return PP_OK_COMPLETIONPENDING;
483 }
484
485 int32_t FilesystemProviderResource::ReleaseRequestBuffer(int32_t request_id) {
486 using namespace filesystem_provider_internal;
487 ListOfRequests::iterator it = pending_process_requests_.find(request_id);
488 if(it!=pending_process_requests_.end()) {
489 pending_process_requests_.erase(it);
490 return PP_OK;
491 }
492 return PP_ERROR_FAILED;
493 }
494
495 void FilesystemProviderResource::OnPluginMsgMountReply(
496 const ResourceMessageReplyParams &params) {
497 if (TrackedCallback::IsPending(mount_callback_)) {
498 if (params.result()==PP_OK)
499 mounted_ = true;
500 mount_callback_->Run( params.result() );
501 }
502 }
503
504 void FilesystemProviderResource::OnPluginMsgUnmountReply(
505 const ResourceMessageReplyParams &params) {
506 mounted_ = false;
507 if (TrackedCallback::IsPending( unmount_callback_ )) {
508 unmount_callback_->Run( params.result() );
509 }
510 }
511
512 void FilesystemProviderResource::OnPluginMsgOperationRequest(
513 const ResourceMessageParams &params,
514 const PP_OperationType_Dev &operation,
515 const base::ListValue &operationArgs) {
516 using namespace filesystem_provider_internal;
517 // We shall push the request
518 switch (operation) {
519 case PP_OperationType_ABORT: {
520 scoped_refptr<AbortOperationTranslator>
521 request = AbortOperationTranslator::PopulateFromRequest(
522 operationArgs);
523
524 if (request.get()) {
525 // Retain payload
526 request_manager_->RemoveRequest( request->operation_request_id, NULL);
527 request_manager_->AddRequest( request->request_id, operation);
528 received_requests_.push_back( request);
529 }
530 break;
531 } // PP_OperationType_ABORT
532 case PP_OperationType_CLOSEFILE: {
533 scoped_refptr< CloseFileOperationTranslator >
534 request = CloseFileOperationTranslator::PopulateFromRequest(
535 operationArgs);
536 if (request.get()) {
537 request_manager_->AddRequest( request->request_id, operation);
538 received_requests_.push_back( request );
539 }
540 break;
541 }//PP_OperationType_CLOSEFILE
542 case PP_OperationType_COPYENTRY: {
543 scoped_refptr< CopyEntryOperationTranslator >
544 request = CopyEntryOperationTranslator::PopulateFromRequest(
545 operationArgs);
546 if (request.get()) {
547 request_manager_->AddRequest( request->request_id, operation);
548 received_requests_.push_back( request );
549 }
550 break;
551 }// PP_OperationType_COPYENTRY
552 case PP_OperationType_CREATEDIRECTORY: {
553 scoped_refptr< CreateDirectoryOperationTranslator >
554 request = CreateDirectoryOperationTranslator::PopulateFromRequest(
555 operationArgs);
556 if (request.get()) {
557 request_manager_->AddRequest( request->request_id, operation);
558 received_requests_.push_back( request );
559 }
560 break;
561 }// PP_OperationType_CREATEDIRECTORY
562 case PP_OperationType_CREATEFILE: {
563 scoped_refptr< CreateFileOperationTranslator >
564 request = CreateFileOperationTranslator::PopulateFromRequest(
565 operationArgs);
566 if (request.get()) {
567 request_manager_->AddRequest( request->request_id, operation);
568 received_requests_.push_back( request );
569 }
570 break;
571 }// PP_OperationType_CREATEFILE
572 case PP_OperationType_DELETEENTRY: {
573 scoped_refptr< DeleteEntryOperationTranslator >
574 request = DeleteEntryOperationTranslator::PopulateFromRequest(
575 operationArgs);
576 if (request.get()) {
577 request_manager_->AddRequest( request->request_id, operation);
578 received_requests_.push_back( request );
579 }
580 break;
581 }//PP_OperationType_DELETEENTRY
582 case PP_OperationType_GETMETADATA: {
583 scoped_refptr<GetMetadataOperationTranslator>
584 request = GetMetadataOperationTranslator::PopulateFromRequest(
585 operationArgs);
586 if ( request.get() ) {
587 request_manager_->AddRequest( request->request_id, operation);
588 received_requests_.push_back( request );
589 }
590 break;
591 } // PP_OperationType_GETMETADATA
592 case PP_OperationType_MOVEENTRY: {
593 scoped_refptr<MoveOperationTranslator>
594 request = MoveOperationTranslator::PopulateFromRequest(
595 operationArgs);
596 if (request.get()) {
597 request_manager_->AddRequest( request->request_id, operation);
598 received_requests_.push_back( request );
599 }
600 break;
601 }// PP_OperationType_MOVEENTRY
602 case PP_OperationType_OPENFILE: {
603 scoped_refptr<OpenFileOperationTranslator>
604 request = OpenFileOperationTranslator::PopulateFromRequest(
605 operationArgs);
606 if (request.get()) {
607 request_manager_->AddRequest( request->request_id, operation);
608 received_requests_.push_back( request );
609 }
610 break;
611 }// PP_OperationType_OpenFile
612 case PP_OperationType_READDIRECTORY: {
613 scoped_refptr<ReadDirectoryOperationTranslator>
614 request = ReadDirectoryOperationTranslator::PopulateFromRequest(
615 operationArgs);
616 if (request.get()) {
617 request_manager_->AddRequest( request->request_id, operation);
618 received_requests_.push_back( request );
619 }
620 break;
621 }//PP_OperationType_READDIRECTORY
622 case PP_OperationType_READFILE: {
623 scoped_refptr<ReadFileOperationTranslator>
624 request = ReadFileOperationTranslator::PopulateFromRequest(
625 operationArgs);
626 if (request.get()) {
627 request_manager_->AddRequest( request->request_id, operation);
628 received_requests_.push_back( request );
629 }
630 break;
631 }// PP_OperationType_READFILE
632 case PP_OperationType_TRUNCATEENTRY: {
633 scoped_refptr<TruncateOperationTranslator>
634 request = TruncateOperationTranslator::PopulateFromRequest(
635 operationArgs);
636 if (request.get()) {
637 request_manager_->AddRequest( request->request_id, operation);
638 received_requests_.push_back( request );
639 }
640 break;
641 }//PP_OperationType_TRUNCATEENTRY
642 case PP_OperationType_UNMOUNT: {
643 scoped_refptr<UnmountOperationTranslator>
644 request = UnmountOperationTranslator::PopulateFromRequest(
645 operationArgs);
646 if (request.get()) {
647 request_manager_->AddRequest( request->request_id, operation);
648 received_requests_.push_back( request );
649 }
650 break;
651 }//PP_OperationType_UNMOUNT
652 case PP_OperationType_WRITEFILE: {
653 // If shared mem inited
654 if (read_write_buffer_.get()) {
655 scoped_refptr<WriteFileOperationTranslator>
656 request = WriteFileOperationTranslator::PopulateFromRequest(
657 operationArgs,
658 (char*)read_write_buffer_->shm->memory()+
659 read_write_buffer_->read_size
660 );
661 if (request.get()) {
662 request_manager_->AddRequest( request->request_id, operation);
663 received_requests_.push_back( request );
664 }
665 }
666 SendWriteAck();
667 break;
668 }
669 case PP_OperationType_ADDWATCHER: {
670 scoped_refptr<AddWatcherOperationTranslator>
671 request = AddWatcherOperationTranslator::PopulateFromRequest(
672 operationArgs);
673 if (request.get()) {
674 request_manager_->AddRequest( request->request_id, operation);
675 received_requests_.push_back( request );
676 }
677 break;
678 }
679 case PP_OperationType_REMOVEWATCHER: {
680 scoped_refptr<RemoveWatcherOperationTranslator>
681 request = RemoveWatcherOperationTranslator::PopulateFromRequest(
682 operationArgs);
683 if (request.get()) {
684 request_manager_->AddRequest( request->request_id, operation);
685 received_requests_.push_back( request );
686 }
687 break;
688 }
689 default:
690 break;
691 }
692 if (!TrackedCallback::IsPending(get_next_request_callback_) ||
693 TrackedCallback::IsScheduledToRun(get_next_request_callback_) ||
694 !WriteRequest())
695 return;
696
697 scoped_refptr<TrackedCallback> callback;
698 callback.swap(get_next_request_callback_);
699 // Run callback
700 callback->Run(PP_OK);
701 }
702
703 void FilesystemProviderResource::OnPluginMsgBuffersReady(
704 const ResourceMessageParams& params, uint32_t read_buffer_size,
705 uint32_t write_buffer_size ) {
706
707 std::vector<base::SharedMemoryHandle> shm_handles;
708 params.TakeAllSharedMemoryHandles(&shm_handles);
709
710 scoped_ptr<base::SharedMemory> shm(
711 new base::SharedMemory(shm_handles[0],false));
712 size_t buffer_size = read_buffer_size + write_buffer_size;
713 if (!shm->Map(buffer_size) )
714 return;
715 read_write_buffer_=
716 make_scoped_ptr(new ShmBuffer( read_buffer_size, write_buffer_size,
717 shm.Pass()));
718 }
719
720 // Received when the browser part acks the read from the shm buffer
721 void FilesystemProviderResource::OnPluginMsgReadAck(
722 const ResourceMessageReplyParams& /*params*/) {
723
724 read_channel_controller_->AckLastPushedResponse();
725 read_channel_controller_->PushNextResponse();
726 }
727
728 bool FilesystemProviderResource::WriteRequest()
729 {
730 if(!get_next_request_callback_data_)
731 return false;
732 scoped_ptr<PP_FilesystemRequest > request;
733 scoped_refptr<filesystem_provider_internal::OperationTranslator>
734 message;
735 // The first request that we can decode we put it into the designated
736 // container for the filesystem provider implementation
737 while (received_requests_.size()>0) {
738 message = received_requests_.front();
739 received_requests_.pop_front();
740 request = message->ToFilesystemRequest();
741
742 if(request.get())
743 break;
744 }
745 if(!request.get())
746 return false;
747
748 // Retain the request until the implementation frees it
749 pending_process_requests_.insert(std::make_pair( request->request_id,
750 message ) );
751 *get_next_request_callback_data_ = *request;
752 get_next_request_callback_data_ = NULL;
753 return true;
754 }
755
756 bool FilesystemProviderResource::FlushReadResponse(
757 scoped_ptr<base::ListValue> response, const char*data, uint32_t data_size) {
758 if (!response.get() ||
759 data==NULL)
760 return false;
761 memcpy( read_write_buffer_->shm->memory(), data, data_size);
762
763 Post(BROWSER,
764 PpapiHostMsg_FilesystemProvider_OperationResponse(*response));
765
766 return true;
767 }
768
769 void FilesystemProviderResource::SendWriteAck() {
770 // Send Ack for the request to the browser to signal that the shm
771 // channel can be reused.
772 Post(BROWSER, PpapiHostMsg_FilesystemProvider_WriteAck());
773 }
774
775 namespace filesystem_provider_internal{
776
777 AbortOperationTranslator::AbortOperationTranslator(){}
778 AbortOperationTranslator::~AbortOperationTranslator(){}
779
780 scoped_ptr<PP_FilesystemRequest>
781 AbortOperationTranslator::ToFilesystemRequest() {
782 scoped_ptr<PP_FilesystemRequest> out(new PP_FilesystemRequest);
783 if(!out.get())
784 return nullptr;
785 out->operation_type = PP_OperationType_ABORT;
786 out->request_id = request_id;
787 return out.Pass();
788 }
789
790 // static
791 scoped_refptr<AbortOperationTranslator>
792 AbortOperationTranslator::PopulateFromRequest( const base::ListValue &request) {
793 if( request.empty() )
794 return nullptr;
795
796 const base::Value *dict_value = nullptr;
797 if(!request.Get(0,&dict_value))
798 return nullptr;
799
800 scoped_refptr<AbortOperationTranslator> out(new AbortOperationTranslator());
801 const base::DictionaryValue* dict =
802 static_cast<const base::DictionaryValue*>(dict_value);
803
804 const base::Value* file_system_id_value = NULL;
805 if (!dict->GetWithoutPathExpansion("fileSystemId", &file_system_id_value))
806 return nullptr;
807 if (!file_system_id_value->GetAsString(&out->file_system_id))
808 return nullptr;
809
810 const base::Value* request_id_value = NULL;
811 if (!dict->GetWithoutPathExpansion("requestId", &request_id_value))
812 return nullptr;
813 if (!request_id_value->GetAsInteger(&out->request_id))
814 return nullptr;
815
816 const base::Value* operation_request_id_value = NULL;
817 if (!dict->GetWithoutPathExpansion(
818 "operationRequestId", &operation_request_id_value))
819 return nullptr;
820 if (!operation_request_id_value->GetAsInteger(&out->operation_request_id))
821 return nullptr;
822 return out;
823 }
824
825 CloseFileOperationTranslator::~CloseFileOperationTranslator(){}
826
827 scoped_ptr<PP_FilesystemRequest>
828 CloseFileOperationTranslator::ToFilesystemRequest() {
829 scoped_ptr<PP_FilesystemRequest> out(new PP_FilesystemRequest);
830 if(!out.get())
831 return nullptr;
832
833 out->operation_type = PP_OperationType_CLOSEFILE;
834 out->request_id = request_id;
835 out->value.as_close_file.open_request_id = open_request_id;
836
837 return out.Pass();
838 }
839
840 //static
841 scoped_refptr<CloseFileOperationTranslator>
842 CloseFileOperationTranslator::PopulateFromRequest(
843 const base::ListValue &request) {
844 if( request.empty() )
845 return nullptr;
846
847 const base::Value *dict_value = nullptr;
848 if(!request.Get(0,&dict_value))
849 return nullptr;
850
851 scoped_refptr<CloseFileOperationTranslator>
852 out(new CloseFileOperationTranslator());
853
854 if (!dict_value->IsType(base::Value::TYPE_DICTIONARY))
855 return nullptr;
856 const base::DictionaryValue* dict =
857 static_cast<const base::DictionaryValue*>(dict_value);
858 const base::Value* file_system_id_value = NULL;
859 if (!dict->GetWithoutPathExpansion("fileSystemId", &file_system_id_value))
860 return nullptr;
861 if (!file_system_id_value->GetAsString(&out->file_system_id))
862 return nullptr;
863
864 const base::Value* request_id_value = NULL;
865 if (!dict->GetWithoutPathExpansion("requestId", &request_id_value))
866 return nullptr;
867 if (!request_id_value->GetAsInteger(&out->request_id))
868 return nullptr;
869
870 const base::Value* open_request_id_value = NULL;
871 if (!dict->GetWithoutPathExpansion("openRequestId", &open_request_id_value))
872 return nullptr;
873 if (!open_request_id_value->GetAsInteger(&out->open_request_id))
874 return nullptr;
875
876 return out;
877 }
878
879 CloseFileOperationTranslator::CloseFileOperationTranslator(){}
880
881 //static
882 GetMetadataOperationTranslator::~GetMetadataOperationTranslator(){}
883
884 scoped_ptr<PP_FilesystemRequest>
885 GetMetadataOperationTranslator::ToFilesystemRequest() {
886 scoped_ptr<PP_FilesystemRequest> out(new PP_FilesystemRequest);
887 if(!out.get())
888 return nullptr;
889 out->operation_type = PP_OperationType_GETMETADATA;
890 out->request_id = request_id;
891 out->value.as_metadata.thumbnail = PP_FromBool( thumbnail );
892 out->value.as_metadata.entry_path = entry_path.c_str();
893
894 return out.Pass();
895 }
896
897 scoped_refptr<GetMetadataOperationTranslator>
898 GetMetadataOperationTranslator::PopulateFromRequest(
899 const base::ListValue &request ) {
900
901 if( request.empty() )
902 return nullptr;
903
904 const base::Value *dict_value = nullptr;
905 if(!request.Get(0,&dict_value))
906 return nullptr;
907
908 scoped_refptr<GetMetadataOperationTranslator>
909 out(new GetMetadataOperationTranslator());
910
911 if (!dict_value->IsType(base::Value::TYPE_DICTIONARY))
912 return nullptr;
913 const base::DictionaryValue* dict =
914 static_cast<const base::DictionaryValue*>(dict_value);
915 const base::Value* file_system_id_value = NULL;
916
917 if (!dict->GetWithoutPathExpansion("fileSystemId", &file_system_id_value))
918 return nullptr;
919 if (!file_system_id_value->GetAsString(&out->file_system_id))
920 return nullptr;
921
922 const base::Value* request_id_value = NULL;
923 if (!dict->GetWithoutPathExpansion("requestId", &request_id_value))
924 return nullptr;
925 if (!request_id_value->GetAsInteger(&out->request_id))
926 return nullptr;
927
928 const base::Value* entry_path_value = NULL;
929 if (!dict->GetWithoutPathExpansion("entryPath", &entry_path_value))
930 return nullptr;
931 if (!entry_path_value->GetAsString(&out->entry_path))
932 return nullptr;
933
934 const base::Value* thumbnail_value = NULL;
935 if (!dict->GetWithoutPathExpansion("thumbnail", &thumbnail_value))
936 return nullptr;
937 if (!thumbnail_value->GetAsBoolean(&out->thumbnail))
938 return nullptr;
939 return out;
940 }
941
942 GetMetadataOperationTranslator::GetMetadataOperationTranslator(){}
943
944
945 CopyEntryOperationTranslator::~CopyEntryOperationTranslator(){}
946
947 scoped_ptr<PP_FilesystemRequest>
948 CopyEntryOperationTranslator::ToFilesystemRequest() {
949 scoped_ptr<PP_FilesystemRequest> out(new PP_FilesystemRequest);
950 out->operation_type = PP_OperationType_COPYENTRY;
951 out->request_id = request_id;
952 out->value.as_copy_entry.source_path = source_path.c_str();
953 out->value.as_copy_entry.target_path = target_path.c_str();
954 return out.Pass();
955 }
956
957 // static
958 scoped_refptr<CopyEntryOperationTranslator>
959 CopyEntryOperationTranslator::PopulateFromRequest(
960 const base::ListValue &request) {
961 if( request.empty() )
962 return nullptr;
963
964 const base::Value *dict_value = nullptr;
965 if(!request.Get(0,&dict_value))
966 return nullptr;
967
968 scoped_refptr<CopyEntryOperationTranslator>
969 out(new CopyEntryOperationTranslator());
970 if (!dict_value->IsType(base::Value::TYPE_DICTIONARY))
971 return nullptr;
972
973 const base::DictionaryValue* dict =
974 static_cast<const base::DictionaryValue*>(dict_value);
975 const base::Value* file_system_id_value = NULL;
976 if (!dict->GetWithoutPathExpansion("fileSystemId", &file_system_id_value))
977 return nullptr;
978 if (!file_system_id_value->GetAsString(&out->file_system_id))
979 return nullptr;
980
981 const base::Value* request_id_value = NULL;
982 if (!dict->GetWithoutPathExpansion("requestId", &request_id_value))
983 return nullptr;
984 if (!request_id_value->GetAsInteger(&out->request_id))
985 return nullptr;
986
987 const base::Value* source_path_value = NULL;
988 if (!dict->GetWithoutPathExpansion("sourcePath", &source_path_value))
989 return nullptr;
990 if (!source_path_value->GetAsString(&out->source_path))
991 return nullptr;
992
993 const base::Value* target_path_value = NULL;
994 if (!dict->GetWithoutPathExpansion("targetPath", &target_path_value))
995 return nullptr;
996 if (!target_path_value->GetAsString(&out->target_path))
997 return nullptr;
998 return out;
999
1000 }
1001
1002 CopyEntryOperationTranslator::CopyEntryOperationTranslator(){}
1003
1004 CreateDirectoryOperationTranslator::~CreateDirectoryOperationTranslator(){}
1005
1006 scoped_ptr<PP_FilesystemRequest>
1007 CreateDirectoryOperationTranslator::ToFilesystemRequest() {
1008 scoped_ptr<PP_FilesystemRequest> out(new PP_FilesystemRequest);
1009 if(!out.get())
1010 return nullptr;
1011 out->operation_type = PP_OperationType_CREATEDIRECTORY;
1012 out->request_id = request_id;
1013 out->value.as_create_directory.directory_path = directory_path.c_str();
1014 out->value.as_create_directory.recursive = PP_FromBool(recursive);
1015 return out.Pass();
1016 }
1017
1018 scoped_refptr<CreateDirectoryOperationTranslator>
1019 CreateDirectoryOperationTranslator::PopulateFromRequest(
1020 const base::ListValue &request) {
1021 if( request.empty() )
1022 return nullptr;
1023
1024 const base::Value *dict_value = nullptr;
1025 if(!request.Get(0,&dict_value))
1026 return nullptr;
1027
1028 scoped_refptr<CreateDirectoryOperationTranslator>
1029 out(new CreateDirectoryOperationTranslator());
1030 if (!dict_value->IsType(base::Value::TYPE_DICTIONARY))
1031 return nullptr;
1032
1033 const base::DictionaryValue* dict =
1034 static_cast<const base::DictionaryValue*>(dict_value);
1035 const base::Value* file_system_id_value = NULL;
1036 if (!dict->GetWithoutPathExpansion("fileSystemId", &file_system_id_value))
1037 return nullptr;
1038 if (!file_system_id_value->GetAsString(&out->file_system_id))
1039 return nullptr;
1040
1041 const base::Value* request_id_value = NULL;
1042 if (!dict->GetWithoutPathExpansion("requestId", &request_id_value))
1043 return nullptr;
1044 if (!request_id_value->GetAsInteger(&out->request_id))
1045 return nullptr;
1046
1047 const base::Value* directory_path_value = NULL;
1048 if (!dict->GetWithoutPathExpansion("directoryPath", &directory_path_value))
1049 return nullptr;
1050 if (!directory_path_value->GetAsString(&out->directory_path))
1051 return nullptr;
1052
1053 const base::Value* recursive_value = NULL;
1054 if (!dict->GetWithoutPathExpansion("recursive", &recursive_value))
1055 return nullptr;
1056 if (!recursive_value->GetAsBoolean(&out->recursive))
1057 return nullptr;
1058
1059 return out;
1060 }
1061
1062 CreateDirectoryOperationTranslator::CreateDirectoryOperationTranslator(){}
1063
1064 CreateFileOperationTranslator::~CreateFileOperationTranslator(){}
1065
1066 scoped_ptr<PP_FilesystemRequest>
1067 CreateFileOperationTranslator::ToFilesystemRequest() {
1068 scoped_ptr<PP_FilesystemRequest> out(new PP_FilesystemRequest);
1069 if(!out.get())
1070 return scoped_ptr<PP_FilesystemRequest>();
1071 out->operation_type = PP_OperationType_CREATEFILE;
1072 out->request_id = request_id;
1073 out->value.as_create_file.file_path = file_path.c_str();
1074 return out.Pass();
1075 }
1076
1077 scoped_refptr<CreateFileOperationTranslator>
1078 CreateFileOperationTranslator::PopulateFromRequest(
1079 const base::ListValue &request) {
1080 if( request.empty() )
1081 return nullptr;
1082
1083 const base::Value *dict_value = nullptr;
1084 if(!request.Get(0,&dict_value))
1085 return nullptr;
1086
1087 scoped_refptr<CreateFileOperationTranslator>
1088 out(new CreateFileOperationTranslator());
1089 if (!dict_value->IsType(base::Value::TYPE_DICTIONARY))
1090 return nullptr;
1091
1092 const base::DictionaryValue* dict =
1093 static_cast<const base::DictionaryValue*>(dict_value);
1094 const base::Value* file_system_id_value = NULL;
1095 if (!dict->GetWithoutPathExpansion("fileSystemId", &file_system_id_value))
1096 return nullptr;
1097 if (!file_system_id_value->GetAsString(&out->file_system_id))
1098 return nullptr;
1099
1100 const base::Value* request_id_value = NULL;
1101 if (!dict->GetWithoutPathExpansion("requestId", &request_id_value))
1102 return nullptr;
1103 if (!request_id_value->GetAsInteger(&out->request_id))
1104 return nullptr;
1105
1106 const base::Value* file_path_value = NULL;
1107 if (!dict->GetWithoutPathExpansion("filePath", &file_path_value))
1108 return nullptr;
1109 if (!file_path_value->GetAsString(&out->file_path))
1110 return nullptr;
1111 return out;
1112 }
1113
1114 CreateFileOperationTranslator::CreateFileOperationTranslator(){}
1115
1116 DeleteEntryOperationTranslator::~DeleteEntryOperationTranslator(){}
1117
1118 scoped_ptr<PP_FilesystemRequest>
1119 DeleteEntryOperationTranslator::ToFilesystemRequest() {
1120 scoped_ptr<PP_FilesystemRequest> out(new PP_FilesystemRequest);
1121 out->operation_type = PP_OperationType_DELETEENTRY;
1122 out->request_id = request_id;
1123 out->value.as_delete_entry.entry_path = entry_path.c_str();
1124 out->value.as_delete_entry.recursive = PP_FromBool(recursive);
1125 return out.Pass();
1126 }
1127
1128 scoped_refptr<DeleteEntryOperationTranslator>
1129 DeleteEntryOperationTranslator::PopulateFromRequest(
1130 const base::ListValue &request) {
1131 if( request.empty() )
1132 return nullptr;
1133
1134 const base::Value *dict_value = nullptr;
1135 if(!request.Get(0,&dict_value))
1136 return nullptr;
1137
1138 if (!dict_value->IsType(base::Value::TYPE_DICTIONARY))
1139 return nullptr;
1140
1141
1142 scoped_refptr<DeleteEntryOperationTranslator>
1143 out(new DeleteEntryOperationTranslator());
1144
1145 const base::DictionaryValue* dict =
1146 static_cast<const base::DictionaryValue*>(dict_value);
1147 const base::Value* file_system_id_value = NULL;
1148
1149 if (!dict->GetWithoutPathExpansion("fileSystemId", &file_system_id_value))
1150 return nullptr;
1151 if (!file_system_id_value->GetAsString(&out->file_system_id))
1152 return nullptr;
1153
1154 const base::Value* request_id_value = NULL;
1155 if (!dict->GetWithoutPathExpansion("requestId", &request_id_value))
1156 return nullptr;
1157 if (!request_id_value->GetAsInteger(&out->request_id))
1158 return nullptr;
1159
1160 const base::Value* entry_path_value = NULL;
1161 if (!dict->GetWithoutPathExpansion("entryPath", &entry_path_value))
1162 return nullptr;
1163 if (!entry_path_value->GetAsString(&out->entry_path))
1164 return nullptr;
1165
1166 const base::Value* recursive_value = NULL;
1167 if (!dict->GetWithoutPathExpansion("recursive", &recursive_value))
1168 return nullptr;
1169 if (!recursive_value->GetAsBoolean(&out->recursive))
1170 return nullptr;
1171 return out;
1172 }
1173
1174 DeleteEntryOperationTranslator::DeleteEntryOperationTranslator(){}
1175
1176 MoveOperationTranslator::~MoveOperationTranslator(){}
1177
1178 scoped_ptr<PP_FilesystemRequest>
1179 MoveOperationTranslator::ToFilesystemRequest() {
1180 scoped_ptr<PP_FilesystemRequest> out(new PP_FilesystemRequest);
1181 if(!out.get())
1182 return nullptr;
1183 out->operation_type = PP_OperationType_MOVEENTRY;
1184 out->request_id = request_id;
1185 out->value.as_move_entry.source_path = source_path.c_str();
1186 out->value.as_move_entry.target_path = target_path.c_str();
1187 return out.Pass();
1188 }
1189
1190 scoped_refptr<MoveOperationTranslator>
1191 MoveOperationTranslator::PopulateFromRequest(const base::ListValue &request) {
1192 if( request.empty() )
1193 return nullptr;
1194
1195 const base::Value *dict_value = nullptr;
1196 if(!request.Get(0,&dict_value))
1197 return nullptr;
1198
1199 if (!dict_value->IsType(base::Value::TYPE_DICTIONARY))
1200 return nullptr;
1201
1202 scoped_refptr<MoveOperationTranslator> out(new MoveOperationTranslator());
1203 const base::DictionaryValue* dict =
1204 static_cast<const base::DictionaryValue*>(dict_value);
1205 const base::Value* file_system_id_value = NULL;
1206 if (!dict->GetWithoutPathExpansion("fileSystemId", &file_system_id_value))
1207 return nullptr;
1208 if (!file_system_id_value->GetAsString(&out->file_system_id))
1209 return nullptr;
1210
1211 const base::Value* request_id_value = NULL;
1212 if (!dict->GetWithoutPathExpansion("requestId", &request_id_value))
1213 return nullptr;
1214 if (!request_id_value->GetAsInteger(&out->request_id))
1215 return nullptr;
1216
1217 const base::Value* source_path_value = NULL;
1218 if (!dict->GetWithoutPathExpansion("sourcePath", &source_path_value))
1219 return nullptr;
1220 if (!source_path_value->GetAsString(&out->source_path))
1221 return nullptr;
1222
1223 const base::Value* target_path_value = NULL;
1224 if (!dict->GetWithoutPathExpansion("targetPath", &target_path_value))
1225 return nullptr;
1226 if (!target_path_value->GetAsString(&out->target_path))
1227 return nullptr;
1228 return out;
1229 }
1230
1231 MoveOperationTranslator::MoveOperationTranslator(){}
1232
1233 PP_OpenFileMode_Dev ParseOpenFileMode( const std::string &mode ) {
1234 if (mode=="WRITE")
1235 return PP_OpenFileMode_WRITE;
1236 else if ( mode=="READ" )//( mode=="read")
1237 return PP_OpenFileMode_READ;
1238 else
1239 return PP_OpenFileMode_NONE;
1240 }
1241
1242
1243 OpenFileOperationTranslator::~OpenFileOperationTranslator(){}
1244
1245 scoped_ptr<PP_FilesystemRequest>
1246 OpenFileOperationTranslator::ToFilesystemRequest() {
1247 scoped_ptr<PP_FilesystemRequest> out(new PP_FilesystemRequest);
1248 if(!out.get())
1249 return nullptr;
1250 out->operation_type = PP_OperationType_OPENFILE;
1251 out->request_id = request_id;
1252 out->value.as_open_file.file_path = file_path.c_str();
1253 out->value.as_open_file.mode = mode;
1254 return out.Pass();
1255 }
1256
1257 //static
1258 scoped_refptr<OpenFileOperationTranslator>
1259 OpenFileOperationTranslator::PopulateFromRequest(
1260 const base::ListValue &request) {
1261 if( request.empty() )
1262 return nullptr;
1263
1264 const base::Value *dict_value = nullptr;
1265 if(!request.Get(0,&dict_value))
1266 return nullptr;
1267 if (!dict_value->IsType(base::Value::TYPE_DICTIONARY))
1268 return nullptr;
1269
1270 scoped_refptr<OpenFileOperationTranslator>
1271 out(new OpenFileOperationTranslator());
1272 const base::DictionaryValue* dict =
1273 static_cast<const base::DictionaryValue*>(dict_value);
1274 const base::Value* file_system_id_value = NULL;
1275 if (!dict->GetWithoutPathExpansion("fileSystemId", &file_system_id_value))
1276 return nullptr;
1277 if (!file_system_id_value->GetAsString(&out->file_system_id))
1278 return nullptr;
1279
1280 const base::Value* request_id_value = NULL;
1281 if (!dict->GetWithoutPathExpansion("requestId", &request_id_value))
1282 return nullptr;
1283 if (!request_id_value->GetAsInteger(&out->request_id))
1284 return nullptr;
1285
1286 const base::Value* file_path_value = NULL;
1287 if (!dict->GetWithoutPathExpansion("filePath", &file_path_value))
1288 return nullptr;
1289 if (!file_path_value->GetAsString(&out->file_path))
1290 return nullptr;
1291
1292 const base::Value* mode_value = NULL;
1293 if (!dict->GetWithoutPathExpansion("mode", &mode_value))
1294 return nullptr;
1295 std::string open_file_mode_as_string;
1296 if (!mode_value->GetAsString(&open_file_mode_as_string))
1297 return nullptr;
1298 out->mode = ParseOpenFileMode(open_file_mode_as_string);
1299
1300 return out;
1301 }
1302
1303 OpenFileOperationTranslator::OpenFileOperationTranslator(){}
1304
1305 ReadDirectoryOperationTranslator::~ReadDirectoryOperationTranslator(){}
1306
1307 scoped_ptr<PP_FilesystemRequest>
1308 ReadDirectoryOperationTranslator::ToFilesystemRequest() {
1309 scoped_ptr<PP_FilesystemRequest> out(new PP_FilesystemRequest);
1310 if(!out.get())
1311 return nullptr;
1312 out->operation_type = PP_OperationType_READDIRECTORY;
1313 out->request_id = request_id;
1314 out->value.as_read_directory.directory_path = directory_path.c_str();
1315 return out.Pass();
1316 }
1317
1318 scoped_refptr<ReadDirectoryOperationTranslator>
1319 ReadDirectoryOperationTranslator::PopulateFromRequest(
1320 const base::ListValue &request) {
1321 if( request.empty() )
1322 return nullptr;
1323
1324 const base::Value *dict_value = nullptr;
1325 if(!request.Get(0,&dict_value))
1326 return nullptr;
1327
1328 if (!dict_value->IsType(base::Value::TYPE_DICTIONARY))
1329 return nullptr;
1330
1331 scoped_refptr<ReadDirectoryOperationTranslator>
1332 out(new ReadDirectoryOperationTranslator());
1333
1334 const base::DictionaryValue* dict =
1335 static_cast<const base::DictionaryValue*>(dict_value);
1336 const base::Value* file_system_id_value = NULL;
1337 if (!dict->GetWithoutPathExpansion("fileSystemId", &file_system_id_value))
1338 return nullptr;
1339 if (!file_system_id_value->GetAsString(&out->file_system_id))
1340 return nullptr;
1341
1342 const base::Value* request_id_value = NULL;
1343 if (!dict->GetWithoutPathExpansion("requestId", &request_id_value))
1344 return nullptr;
1345 if (!request_id_value->GetAsInteger(&out->request_id))
1346 return nullptr;
1347
1348 const base::Value* directory_path_value = NULL;
1349 if (!dict->GetWithoutPathExpansion("directoryPath", &directory_path_value))
1350 return nullptr;
1351 if (!directory_path_value->GetAsString(&out->directory_path))
1352 return nullptr;
1353 return out;
1354 }
1355
1356 ReadDirectoryOperationTranslator::ReadDirectoryOperationTranslator(){}
1357
1358 ReadFileOperationTranslator::~ReadFileOperationTranslator(){}
1359
1360 scoped_ptr<PP_FilesystemRequest>
1361 ReadFileOperationTranslator::ToFilesystemRequest() {
1362 scoped_ptr<PP_FilesystemRequest> out(new PP_FilesystemRequest);
1363 if(!out.get())
1364 return scoped_ptr<PP_FilesystemRequest>();
1365 out->operation_type = PP_OperationType_READFILE;
1366 out->request_id = request_id;
1367 out->value.as_read_file.open_request_id = open_request_id;
1368 out->value.as_read_file.offset = offset;
1369 out->value.as_read_file.length = length;
1370 return out.Pass();
1371 }
1372
1373 scoped_refptr<ReadFileOperationTranslator>
1374 ReadFileOperationTranslator::PopulateFromRequest(
1375 const base::ListValue &request) {
1376 if( request.empty() )
1377 return nullptr;
1378
1379 const base::Value *dict_value = nullptr;
1380 if(!request.Get(0,&dict_value))
1381 return nullptr;
1382
1383 if (!dict_value->IsType(base::Value::TYPE_DICTIONARY))
1384 return nullptr;
1385 scoped_refptr<ReadFileOperationTranslator>
1386 out(new ReadFileOperationTranslator());
1387 const base::DictionaryValue* dict =
1388 static_cast<const base::DictionaryValue*>(dict_value);
1389 const base::Value* file_system_id_value = NULL;
1390 if (!dict->GetWithoutPathExpansion("fileSystemId", &file_system_id_value))
1391 return nullptr;
1392 if (!file_system_id_value->GetAsString(&out->file_system_id))
1393 return nullptr;
1394
1395 const base::Value* request_id_value = NULL;
1396 if (!dict->GetWithoutPathExpansion("requestId", &request_id_value))
1397 return nullptr;
1398 if (!request_id_value->GetAsInteger(&out->request_id))
1399 return nullptr;
1400
1401 const base::Value* open_request_id_value = NULL;
1402 if (!dict->GetWithoutPathExpansion("openRequestId", &open_request_id_value))
1403 return nullptr;
1404 if (!open_request_id_value->GetAsInteger(&out->open_request_id))
1405 return nullptr;
1406
1407 const base::Value* offset_value = NULL;
1408 if (!dict->GetWithoutPathExpansion("offset", &offset_value))
1409 return nullptr;
1410 if (!offset_value->GetAsDouble(&out->offset))
1411 return nullptr;
1412
1413 const base::Value* length_value = NULL;
1414 if (!dict->GetWithoutPathExpansion("length", &length_value))
1415 return nullptr;
1416 if (!length_value->GetAsDouble(&out->length))
1417 return nullptr;
1418 return out;
1419 }
1420
1421 ReadFileOperationTranslator::ReadFileOperationTranslator(){}
1422
1423 TruncateOperationTranslator::~TruncateOperationTranslator(){}
1424
1425 scoped_ptr<PP_FilesystemRequest>
1426 TruncateOperationTranslator::ToFilesystemRequest() {
1427 scoped_ptr<PP_FilesystemRequest> out(new PP_FilesystemRequest);
1428 if(!out.get())
1429 return nullptr;
1430 out->operation_type = PP_OperationType_TRUNCATEENTRY;
1431 out->request_id = request_id;
1432 out->value.as_truncate.length = length;
1433 out->value.as_truncate.file_path = file_path.c_str();
1434 return out.Pass();
1435 }
1436
1437 scoped_refptr<TruncateOperationTranslator>
1438 TruncateOperationTranslator::PopulateFromRequest(
1439 const base::ListValue &request) {
1440 if( request.empty() )
1441 return nullptr;
1442
1443 const base::Value *dict_value = nullptr;
1444 if(!request.Get(0,&dict_value))
1445 return nullptr;
1446
1447 if (!dict_value->IsType(base::Value::TYPE_DICTIONARY))
1448 return nullptr;
1449
1450 scoped_refptr<TruncateOperationTranslator>
1451 out(new TruncateOperationTranslator());
1452
1453 const base::DictionaryValue* dict =
1454 static_cast<const base::DictionaryValue*>(dict_value);
1455 const base::Value* file_system_id_value = NULL;
1456 if (!dict->GetWithoutPathExpansion("fileSystemId", &file_system_id_value))
1457 return nullptr;
1458 if (!file_system_id_value->GetAsString(&out->file_system_id))
1459 return nullptr;
1460
1461 const base::Value* request_id_value = NULL;
1462 if (!dict->GetWithoutPathExpansion("requestId", &request_id_value))
1463 return nullptr;
1464 if (!request_id_value->GetAsInteger(&out->request_id))
1465 return nullptr;
1466
1467 const base::Value* file_path_value = NULL;
1468 if (!dict->GetWithoutPathExpansion("filePath", &file_path_value))
1469 return nullptr;
1470 if (!file_path_value->GetAsString(&out->file_path))
1471 return nullptr;
1472
1473 const base::Value* length_value = NULL;
1474 if (!dict->GetWithoutPathExpansion("length", &length_value))
1475 return nullptr;
1476 if (!length_value->GetAsDouble(&out->length))
1477 return nullptr;
1478 return out;
1479 }
1480
1481 TruncateOperationTranslator::TruncateOperationTranslator(){}
1482
1483 UnmountOperationTranslator::~UnmountOperationTranslator(){}
1484
1485 scoped_ptr<PP_FilesystemRequest>
1486 UnmountOperationTranslator::ToFilesystemRequest() {
1487 scoped_ptr<PP_FilesystemRequest> out(new PP_FilesystemRequest);
1488 if(!out.get())
1489 return scoped_ptr<PP_FilesystemRequest>();
1490 out->operation_type = PP_OperationType_UNMOUNT;
1491 out->request_id = request_id;
1492 return out.Pass();
1493 }
1494
1495 scoped_refptr<UnmountOperationTranslator>
1496 UnmountOperationTranslator::PopulateFromRequest(
1497 const base::ListValue &request) {
1498
1499 if( request.empty() )
1500 return nullptr;
1501
1502 const base::Value *dict_value = nullptr;
1503 if(!request.Get(0,&dict_value))
1504 return nullptr;
1505
1506 if (!dict_value->IsType(base::Value::TYPE_DICTIONARY))
1507 return nullptr;
1508
1509 scoped_refptr<UnmountOperationTranslator>
1510 out(new UnmountOperationTranslator());
1511
1512 const base::DictionaryValue* dict =
1513 static_cast<const base::DictionaryValue*>(dict_value);
1514 const base::Value* file_system_id_value = NULL;
1515 if (!dict->GetWithoutPathExpansion("fileSystemId", &file_system_id_value))
1516 return nullptr;
1517 if (!file_system_id_value->GetAsString(&out->file_system_id))
1518 return nullptr;
1519
1520 const base::Value* request_id_value = NULL;
1521 if (!dict->GetWithoutPathExpansion("requestId", &request_id_value))
1522 return nullptr;
1523 if (!request_id_value->GetAsInteger(&out->request_id))
1524 return nullptr;
1525 return out;
1526 }
1527
1528 UnmountOperationTranslator::UnmountOperationTranslator(){}
1529
1530 WriteFileOperationTranslator::~WriteFileOperationTranslator(){}
1531
1532 scoped_ptr<PP_FilesystemRequest>
1533 WriteFileOperationTranslator::ToFilesystemRequest() {
1534 scoped_ptr<PP_FilesystemRequest> out(new PP_FilesystemRequest);
1535 if(!out.get())
1536 return nullptr;
1537 out->operation_type = PP_OperationType_WRITEFILE;
1538 out->request_id = request_id;
1539 out->value.as_write_file.open_request_id = open_request_id;
1540 out->value.as_write_file.offset = offset;
1541 out->value.as_write_file.data_size = data.size();
1542 // Pass the address
1543 if(data.size())
1544 out->value.as_write_file.data = &data[0];
1545 else // or NULL if the browser sent an empty write request
1546 out->value.as_write_file.data = NULL;
1547 return out.Pass();
1548 }
1549
1550 scoped_refptr<WriteFileOperationTranslator>
1551 WriteFileOperationTranslator::PopulateFromRequest(
1552 const base::ListValue &request,
1553 char* memory_address) {
1554
1555 if( request.empty() )
1556 return nullptr;
1557
1558 const base::Value *dict_value = nullptr;
1559 if(!request.Get(0,&dict_value))
1560 return nullptr;
1561
1562 if (!dict_value->IsType(base::Value::TYPE_DICTIONARY))
1563 return nullptr;
1564
1565 scoped_refptr<WriteFileOperationTranslator>
1566 out(new WriteFileOperationTranslator());
1567 const base::DictionaryValue* dict =
1568 static_cast<const base::DictionaryValue*>(dict_value);
1569 const base::Value* file_system_id_value = NULL;
1570 if (!dict->GetWithoutPathExpansion("fileSystemId", &file_system_id_value))
1571 return nullptr;
1572 if (!file_system_id_value->GetAsString(&out->file_system_id))
1573 return nullptr;
1574
1575 const base::Value* request_id_value = NULL;
1576 if (!dict->GetWithoutPathExpansion("requestId", &request_id_value))
1577 return nullptr;
1578 if (!request_id_value->GetAsInteger(&out->request_id))
1579 return nullptr;
1580
1581 const base::Value* open_request_id_value = NULL;
1582 if (!dict->GetWithoutPathExpansion("openRequestId", &open_request_id_value))
1583 return nullptr;
1584 if (!open_request_id_value->GetAsInteger(&out->open_request_id))
1585 return nullptr;
1586
1587 const base::Value* offset_value = NULL;
1588 if (!dict->GetWithoutPathExpansion("offset", &offset_value))
1589 return nullptr;
1590 if (!offset_value->GetAsDouble(&out->offset))
1591 return nullptr;
1592
1593 const base::Value* size_value = NULL;
1594 if (!dict->GetWithoutPathExpansion("size", &size_value))
1595 return nullptr;
1596 if (!size_value->GetAsDouble(&out->size))
1597 return nullptr;
1598
1599 // Buffer what will be cached until released by the FS implementation
1600 out->data.assign(memory_address,
1601 memory_address+static_cast<size_t>(out->size));
1602 return out;
1603 }
1604
1605 WriteFileOperationTranslator::WriteFileOperationTranslator(){}
1606
1607 OperationTranslator::~OperationTranslator(){}
1608
1609 scoped_ptr<base::ListValue>
1610 PluginToBrowserTranslator::GenerateReadFileSuccessResponse(
1611 uint32_t data_size, bool has_more, int32_t request_id,
1612 int time_span, const std::string& filesystem_id) {
1613 size_t index = 0;
1614 scoped_ptr<base::ListValue> response(new base::ListValue);
1615 if( !response->Set(index++,
1616 new base::FundamentalValue(PP_OperationType_READFILE))||
1617 !response->Set(index++, new base::FundamentalValue(true))||// status = suc cess
1618 !response->Set(index++,
1619 new base::StringValue(filesystem_id)) ||
1620 !response->Set(index++, new base::FundamentalValue(request_id)) ||
1621 !response->Set(index++, new base::FundamentalValue(
1622 static_cast<double>(data_size)))||
1623 !response->Set(index++, new base::FundamentalValue(has_more))||
1624 !response->Set(index++, new base::FundamentalValue(time_span)))
1625 return scoped_ptr<base::ListValue>();
1626 return response.Pass();
1627 }
1628
1629 AddWatcherOperationTranslator::~AddWatcherOperationTranslator() {}
1630
1631 scoped_ptr<PP_FilesystemRequest>
1632 AddWatcherOperationTranslator::ToFilesystemRequest() {
1633 scoped_ptr<PP_FilesystemRequest> out(new PP_FilesystemRequest);
1634 if(!out.get())
1635 return scoped_ptr<PP_FilesystemRequest>();
1636 out->operation_type = PP_OperationType_ADDWATCHER;
1637 out->request_id = request_id;
1638 out->value.as_add_watcher.entry_path = this->entry_path.c_str();
1639 out->value.as_add_watcher.recursive = PP_FromBool(this->recursive);
1640 return out.Pass();
1641 }
1642
1643 scoped_refptr<AddWatcherOperationTranslator>
1644 AddWatcherOperationTranslator::PopulateFromRequest(
1645 const base::ListValue& request) {
1646 if( request.empty() )
1647 return nullptr;
1648
1649 const base::Value *dict_value = nullptr;
1650 if(!request.Get(0,&dict_value))
1651 return nullptr;
1652
1653 if (!dict_value->IsType(base::Value::TYPE_DICTIONARY))
1654 return nullptr;
1655
1656 scoped_refptr<AddWatcherOperationTranslator>
1657 out(new AddWatcherOperationTranslator());
1658
1659 const base::DictionaryValue* dict =
1660 static_cast<const base::DictionaryValue*>(dict_value);
1661 const base::Value* file_system_id_value = NULL;
1662 if (!dict->GetWithoutPathExpansion("fileSystemId", &file_system_id_value))
1663 return nullptr;
1664 if (!file_system_id_value->GetAsString(&out->file_system_id))
1665 return nullptr;
1666 const base::Value* request_id_value = NULL;
1667 if (!dict->GetWithoutPathExpansion("requestId", &request_id_value))
1668 return nullptr;
1669 if (!request_id_value->GetAsInteger(&out->request_id))
1670 return nullptr;
1671 const base::Value* entry_path_value = NULL;
1672 if (!dict->GetWithoutPathExpansion("entryPath", &entry_path_value))
1673 return nullptr;
1674 if (!entry_path_value->GetAsString(&out->entry_path))
1675 return nullptr;
1676 const base::Value* recursive_value = NULL;
1677 if (!dict->GetWithoutPathExpansion("recursive",&recursive_value))
1678 return nullptr;
1679 if (!recursive_value->GetAsBoolean(&out->recursive))
1680 return nullptr;
1681
1682 return out;
1683 }
1684
1685 AddWatcherOperationTranslator::AddWatcherOperationTranslator() {}
1686
1687 RemoveWatcherOperationTranslator::~RemoveWatcherOperationTranslator() {
1688
1689 }
1690
1691 scoped_ptr<PP_FilesystemRequest>
1692 RemoveWatcherOperationTranslator::ToFilesystemRequest() {
1693 scoped_ptr<PP_FilesystemRequest> out(new PP_FilesystemRequest);
1694 if(!out.get())
1695 return scoped_ptr<PP_FilesystemRequest>();
1696 out->operation_type = PP_OperationType_REMOVEWATCHER;
1697 out->request_id = request_id;
1698 out->value.as_add_watcher.entry_path = this->entry_path.c_str();
1699 out->value.as_add_watcher.recursive = PP_FromBool(this->recursive);
1700 return out.Pass();
1701 }
1702
1703 scoped_refptr<RemoveWatcherOperationTranslator>
1704 RemoveWatcherOperationTranslator::PopulateFromRequest(
1705 const base::ListValue& request){
1706 if( request.empty() )
1707 return nullptr;
1708
1709 const base::Value *dict_value = nullptr;
1710 if(!request.Get(0,&dict_value))
1711 return nullptr;
1712
1713 if (!dict_value->IsType(base::Value::TYPE_DICTIONARY))
1714 return nullptr;
1715
1716 scoped_refptr<RemoveWatcherOperationTranslator>
1717 out(new RemoveWatcherOperationTranslator());
1718
1719 const base::DictionaryValue* dict =
1720 static_cast<const base::DictionaryValue*>(dict_value);
1721 const base::Value* file_system_id_value = NULL;
1722 if (!dict->GetWithoutPathExpansion("fileSystemId", &file_system_id_value))
1723 return nullptr;
1724 if (!file_system_id_value->GetAsString(&out->file_system_id))
1725 return nullptr;
1726 const base::Value* request_id_value = NULL;
1727 if (!dict->GetWithoutPathExpansion("requestId", &request_id_value))
1728 return nullptr;
1729 if (!request_id_value->GetAsInteger(&out->request_id))
1730 return nullptr;
1731 const base::Value* entry_path_value = NULL;
1732 if (!dict->GetWithoutPathExpansion("entryPath", &entry_path_value))
1733 return nullptr;
1734 if (!entry_path_value->GetAsString(&out->entry_path))
1735 return nullptr;
1736 const base::Value* recursive_value = NULL;
1737 if (!dict->GetWithoutPathExpansion("recursive",&recursive_value))
1738 return nullptr;
1739 if (!recursive_value->GetAsBoolean(&out->recursive))
1740 return nullptr;
1741
1742 return out;
1743 }
1744
1745 RemoveWatcherOperationTranslator::RemoveWatcherOperationTranslator() {}
1746
1747 scoped_ptr<base::ListValue>
1748 PluginToBrowserTranslator::GenerateMountMessage(
1749 std::string filesystem_id, std::string display_name,
1750 bool writable, int32_t opened_files_limit) {
1751
1752 scoped_ptr<base::DictionaryValue> payload(new base::DictionaryValue);
1753 if(!payload.get())
1754 return scoped_ptr<base::ListValue>();
1755 payload->Set("fileSystemId",
1756 new base::StringValue(filesystem_id));
1757 payload->Set("displayName",
1758 new base::StringValue(display_name));
1759 payload->Set("writable",
1760 new base::FundamentalValue(writable));
1761 payload->Set("openedFilesLimit",
1762 new base::FundamentalValue(opened_files_limit));
1763 scoped_ptr<base::ListValue> response(new base::ListValue);
1764 if(!response.get())
1765 return scoped_ptr<base::ListValue>();
1766 response->Set(0,payload.release());
1767 return response.Pass();
1768 }
1769
1770 scoped_ptr<base::ListValue> PluginToBrowserTranslator::GenerateNotifyMessage(
1771 PP_Var notification_options) {
1772 scoped_ptr<base::DictionaryValue> notification(new base::DictionaryValue);
1773
1774 DictionaryVar* dict_var = DictionaryVar::FromPPVar(notification_options);
1775 if(!dict_var)
1776 return nullptr;
1777 for (DictionaryVar::KeyValueMap::const_iterator iter =
1778 dict_var->key_value_map().begin();
1779 iter != dict_var->key_value_map().end();
1780 ++iter) {
1781 const std::string& key = iter->first;
1782 const PP_Var& child_var = iter->second.get();
1783 switch(child_var.type) {
1784 case PP_VARTYPE_STRING: {
1785 StringVar* string = StringVar::FromPPVar(child_var);
1786 if(!string)
1787 return nullptr;
1788 const std::string& value = string->value();
1789
1790 if (key=="fileSystemId") {
1791 notification->SetString(key,value);
1792 } else if (key== "observedPath") {
1793 notification->SetString(key,value);
1794 } else if(key=="tag") {
1795 notification->SetString(key,value);
1796 } else return nullptr;
1797 break;
1798 }
1799 case PP_VARTYPE_BOOL: {
1800 if(key!="recursive")
1801 return nullptr;
1802 notification->SetBoolean("recursive", child_var.value.as_bool);
1803 break;
1804 }
1805 case PP_VARTYPE_INT32: {
1806 if (key!="changeType")
1807 return nullptr;
1808 if (child_var.value.as_int!=PP_ChangeType_CHANGED &&
1809 child_var.value.as_int!=PP_ChangeType_DELETED)
1810 return nullptr;
1811 notification->SetString( "changeType",
1812 child_var.value.as_int!=PP_ChangeType_CHANGED ?
1813 "DELETED" : "CHANGED" );
1814 break;
1815 }
1816 case PP_VARTYPE_ARRAY: {
1817 if (key!="changes")
1818 return nullptr;
1819 scoped_ptr<base::ListValue> changes(new base::ListValue);
1820 if (!changes)
1821 return nullptr;
1822 ArrayVar* array_var = ArrayVar::FromPPVar(child_var);
1823 if(!array_var)
1824 return nullptr;
1825 for( size_t i = 0; i < array_var->elements().size(); ++i ) {
1826 const PP_Var& c_child_var = array_var->elements()[i].get();
1827 if( c_child_var.type != PP_VARTYPE_DICTIONARY )
1828 return nullptr;
1829 DictionaryVar* c = DictionaryVar::FromPPVar(c_child_var);
1830 if (!c)
1831 return nullptr;
1832 scoped_ptr<base::DictionaryValue> change(new base::DictionaryValue);
1833 if (!change)
1834 return nullptr;
1835 for (DictionaryVar::KeyValueMap::const_iterator c_iter =
1836 c->key_value_map().begin();
1837 c_iter != c->key_value_map().end();
1838 ++c_iter) {
1839 const std::string& c_key = c_iter->first;
1840 const PP_Var& c_child_var = c_iter->second.get();
1841 switch(c_child_var.type) {
1842 case PP_VARTYPE_STRING:{
1843 StringVar* string = StringVar::FromPPVar(c_child_var);
1844 if(!string)
1845 return nullptr;
1846 const std::string& c_value = string->value();
1847 if (c_key=="entryPath")
1848 change->SetString(c_key, c_value);
1849 else
1850 return nullptr;
1851 break;
1852 }
1853 case PP_VARTYPE_INT32: {
1854 if (c_key=="changeType")
1855 change->SetString(
1856 c_key,
1857 c_child_var.value.as_int!=PP_ChangeType_CHANGED ?
1858 "DELETED" : "CHANGED");
1859 else
1860 return nullptr;
1861 break;
1862 }
1863 default:
1864 return nullptr;
1865 }
1866 }
1867 changes->Append(change.release());
1868 }
1869 notification->Set(key,changes.release());
1870 break;
1871 }
1872 default:
1873 return nullptr;
1874 }
1875 }
1876
1877 scoped_ptr<base::ListValue> message(new base::ListValue);
1878 if (!message.get())
1879 return nullptr;
1880
1881 message->Append(notification.release());
1882 return message.Pass();
1883 }
1884
1885 scoped_ptr<base::ListValue>
1886 PluginToBrowserTranslator::GenerateSuccessResponse(
1887 PP_OperationType_Dev operation_type,
1888 const std::string &filesystem_id,
1889 int32_t request_id, int time_span) {
1890
1891 scoped_ptr<base::ListValue> response(new base::ListValue);
1892 if(!response.get())
1893 return scoped_ptr<base::ListValue>();
1894 size_t index = 0;
1895 if ( !response->Set(index++, new base::FundamentalValue(operation_type))||
1896 !response->Set(index++,
1897 new base::FundamentalValue(true)) || // status = success
1898 !response->Set(index++,
1899 new base::StringValue(filesystem_id))||
1900 !response->Set(index++, new base::FundamentalValue(request_id)) ||
1901 !response->Set(index++, new base::FundamentalValue(time_span))) {
1902 return scoped_ptr<base::ListValue>();
1903 }
1904 return response.Pass();
1905 }
1906
1907 scoped_ptr<base::ListValue> PluginToBrowserTranslator::GenerateFailureResponse(
1908 PP_OperationType_Dev operation_type, int32_t error,
1909 const std::string &filesystem_id, int32_t request_id, int time_span) {
1910 scoped_ptr<base::ListValue> response(new base::ListValue);
1911 if(!response.get())
1912 return scoped_ptr<base::ListValue>();
1913 size_t index=0;
1914 if ( !response->Set(index++, new base::FundamentalValue(operation_type)) ||
1915 !response->Set(index++,
1916 new base::FundamentalValue(false)) || // status = failure
1917 !response->Set(index++,
1918 new base::StringValue(filesystem_id)) ||
1919 !response->Set(index++, new base::FundamentalValue(request_id)) ||
1920 !response->Set(index++,
1921 new base::StringValue(PP_ErrorToString(error))) ||
1922 !response->Set(index++, new base::FundamentalValue(time_span) ) )
1923 return scoped_ptr<base::ListValue>();
1924 return response.Pass();
1925 }
1926
1927 scoped_ptr<base::ListValue> PluginToBrowserTranslator::GenerateMetadataResponse(
1928 PP_Var metadata, int32_t request_id,
1929 const std::string &filesystem_id, int time_span) {
1930
1931 scoped_ptr<base::DictionaryValue> entry_metadata=
1932 GenerateMetadataListFromPPVar( metadata );
1933 if(!entry_metadata.get())
1934 return nullptr;
1935 scoped_ptr<base::ListValue> response(new base::ListValue);
1936 size_t index = 0;
1937 if (!response->Set(index++,
1938 new base::FundamentalValue(PP_OperationType_GETMETADATA))||
1939 !response->Set(index++, new base::FundamentalValue(true))|| //status = suc cess
1940 !response->Set(index++,
1941 new base::StringValue(filesystem_id) ) ||
1942 !response->Set(index++, new base::FundamentalValue(request_id) ) ||
1943 !response->Set(index++, entry_metadata.release() ) ||
1944 !response->Set(index++, new base::FundamentalValue(time_span) ) )
1945 return nullptr;
1946 return response.Pass();
1947 }
1948
1949 scoped_ptr<base::ListValue>
1950 PluginToBrowserTranslator::GenerateReadDirectoryResponse(
1951 PP_Var entries,
1952 PP_Bool has_more, int32_t request_id,
1953 const std::string &filesystem_id, int time_span) {
1954
1955 scoped_ptr<base::ListValue> response(new base::ListValue);
1956 scoped_ptr<base::ListValue> list_value(new base::ListValue);
1957 if(!list_value.get()||
1958 !response.get())
1959 return nullptr;
1960
1961 ArrayVar* array_var = ArrayVar::FromPPVar(entries);
1962 if(!array_var)
1963 return nullptr;
1964
1965 scoped_ptr<base::DictionaryValue> entry_metadata;
1966 for( size_t i = 0; i < array_var->elements().size(); ++i ) {
1967 const PP_Var& child_var = array_var->elements()[i].get();
1968 if( child_var.type != PP_VARTYPE_DICTIONARY )
1969 return nullptr;
1970 entry_metadata = GenerateMetadataListFromPPVar(child_var);
1971 if(!entry_metadata.get())
1972 return nullptr;
1973 list_value->Set(i,entry_metadata.release());
1974 }
1975
1976 size_t index = 0;
1977 if (!response->Set(index++,
1978 new base::FundamentalValue(PP_OperationType_READDIRECTORY))||
1979 !response->Set(index++,
1980 new base::FundamentalValue(true))|| // status = success
1981 !response->Set(index++,
1982 new base::StringValue(filesystem_id) ) ||
1983 !response->Set(index++, new base::FundamentalValue(request_id) ) ||
1984 !response->Set(index++, list_value.release() ) ||
1985 !response->Set(index++,
1986 new base::FundamentalValue( PP_ToBool( has_more ) ) ) ||
1987 !response->Set(index++, new base::FundamentalValue( time_span ) ) )
1988 return scoped_ptr<base::ListValue>();
1989 return response.Pass();
1990 }
1991
1992 scoped_ptr<base::DictionaryValue>
1993 PluginToBrowserTranslator::GenerateMetadataListFromPPVar(PP_Var metadata) {
1994 scoped_ptr<base::DictionaryValue> entry_metadata(new base::DictionaryValue);
1995 if(!entry_metadata.get())
1996 return nullptr;
1997
1998 DictionaryVar* dict_var = DictionaryVar::FromPPVar(metadata);
1999 if(!dict_var)
2000 return nullptr;
2001 for (DictionaryVar::KeyValueMap::const_iterator iter =
2002 dict_var->key_value_map().begin();
2003 iter != dict_var->key_value_map().end();
2004 ++iter) {
2005 const std::string& key = iter->first;
2006 const PP_Var& child_var = iter->second.get();
2007 switch(child_var.type) {
2008 case PP_VARTYPE_STRING:{
2009 StringVar* string = StringVar::FromPPVar(child_var);
2010 if(!string)
2011 return nullptr;
2012 const std::string& value = string->value();
2013
2014 if (key=="modificationTime") {
2015 scoped_ptr<base::DictionaryValue>
2016 modification_time(new base::DictionaryValue());
2017 if(!modification_time.get())
2018 return nullptr;
2019 modification_time->SetStringWithoutPathExpansion(
2020 "value", value);
2021 entry_metadata->Set(key, modification_time.release());
2022 } else if (key=="name"||key=="mimeType"||key=="thumbnail") {
2023 entry_metadata->SetString(key,value);
2024 } else {
2025 return nullptr;
2026 }
2027 break;
2028 }
2029 case PP_VARTYPE_BOOL: {
2030 if(key!="isDirectory")
2031 return nullptr;
2032 entry_metadata->SetBoolean("isDirectory", child_var.value.as_bool);
2033 break;
2034 }
2035 case PP_VARTYPE_DOUBLE: {
2036 if (key!="size")
2037 return nullptr;
2038 entry_metadata->SetDouble("size", child_var.value.as_double );
2039 break;
2040 }
2041 default:
2042 return nullptr;
2043 }
2044 }
2045 return entry_metadata.Pass();
2046 }
2047
2048
2049
2050 } // namespace
2051 } // namespace proxy
2052 } // namespace ppapi
OLDNEW
« no previous file with comments | « ppapi/proxy/filesystem_provider_resource.h ('k') | ppapi/proxy/filesystem_provider_resource_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698