Index: ppapi/proxy/filesystem_provider_resource.cc |
diff --git a/ppapi/proxy/filesystem_provider_resource.cc b/ppapi/proxy/filesystem_provider_resource.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..500b2dc5de2efb7cc07452b80180bb7ffa7c6d41 |
--- /dev/null |
+++ b/ppapi/proxy/filesystem_provider_resource.cc |
@@ -0,0 +1,2052 @@ |
+// Copyright 2015 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+#include "ppapi/proxy/filesystem_provider_resource.h" |
+ |
+#include "base/bind.h" |
+#include "base/logging.h" |
+#include "base/memory/scoped_ptr.h" |
+#include "base/numerics/safe_conversions.h" |
+#include "ppapi/c/pp_errors.h" |
+#include "ppapi/proxy/dispatch_reply_message.h" |
+#include "ppapi/proxy/plugin_dispatcher.h" |
+#include "ppapi/proxy/ppapi_messages.h" |
+#include "ppapi/shared_impl/array_var.h" |
+#include "ppapi/shared_impl/dictionary_var.h" |
+#include "ppapi/shared_impl/ppapi_globals.h" |
+#include "ppapi/shared_impl/proxy_lock.h" |
+#include "ppapi/shared_impl/tracked_callback.h" |
+#include "ppapi/shared_impl/var.h" |
+#include "ppapi/shared_impl/var_tracker.h" |
+ |
+using ppapi::DictionaryVar; |
+using ppapi::ArrayVar; |
+ |
+namespace ppapi { |
+namespace proxy { |
+namespace { |
+ |
+const uint32_t kMaximumCachedReplies = 10; |
+ |
+static std::string PP_ErrorToString(int32_t error) { |
+ switch (error) { |
+ case PP_OK: |
+ return "OK"; |
+ case PP_ERROR_FAILED: |
+ return "FAILED"; |
+ case PP_ERROR_INPROGRESS: |
+ return "IN_USE"; |
+ case PP_ERROR_FILEEXISTS: |
+ return "EXISTS"; |
+ case PP_ERROR_FILENOTFOUND: |
+ return "NOT_FOUND"; |
+ case PP_ERROR_NOACCESS: |
+ return "ACCESS_DENIED"; |
+ case PP_ERROR_FILE_TOO_MANY_OPENED: |
+ return "TOO_MANY_OPENED"; |
+ case PP_ERROR_NOMEMORY: |
+ return "NO_MEMORY"; |
+ case PP_ERROR_NOSPACE: |
+ return "NO_SPACE"; |
+ case PP_ERROR_NOTADIRECTORY: |
+ return "NOT_A_DIRECTORY"; |
+ case PP_ERROR_NOTSUPPORTED: |
+ return "INVALID_OPERATION"; |
+ case PP_ERROR_SECURITY: |
+ return "SECURITY"; |
+ case PP_ERROR_ABORTED: |
+ return "ABORT"; |
+ case PP_ERROR_NOTAFILE: |
+ return "NOT_A_FILE"; |
+ case PP_ERROR_FILENOTEMPTY: |
+ return "NOT_EMPTY"; |
+ case PP_ERROR_INVALID_URL: |
+ return "INVALID_URL"; |
+ case PP_ERROR_FILE_IO: |
+ return "IO"; |
+ } |
+ NOTREACHED(); |
+ return ""; |
+} |
+ |
+} // namespace |
+ |
+FilesystemProviderResource::ShmChannelController::ShmChannelController( |
+ uint32_t size, FlushResponseCallback callback) |
+ : max_size(size), |
+ ready(true), |
+ callback(callback){ |
+} |
+FilesystemProviderResource::ShmChannelController::~ShmChannelController() { |
+} |
+ |
+bool FilesystemProviderResource::ShmChannelController::EnqueueResponse( |
+ scoped_ptr<base::ListValue> response, |
+ const char* data, uint32_t data_size) { |
+ // If channel ready send it straight away |
+ if (ready) { |
+ // Flush Request |
+ ready = !callback.Run(response.Pass(), data, data_size); |
+ if(!ready) |
+ return true; |
+ } |
+ // If channel is not ready or failed to send, |
+ // cache the response |
+ if( size() + 1 > max_size ) { |
+ return false; |
+ } |
+ |
+ scoped_ptr<base::BinaryValue> payload( |
+ base::BinaryValue::CreateWithCopiedBuffer(static_cast<const char*>(data), |
+ data_size)); |
+ if( !payload.get() ) |
+ return false; |
+ |
+ response->Append(payload.release()); |
+ replies.push_back(response.release()); |
+ |
+ return true; |
+} |
+ |
+bool FilesystemProviderResource::ShmChannelController::PushNextResponse() { |
+ scoped_ptr<base::ListValue> response; |
+ scoped_ptr<base::Value> payload; |
+ while (size()>0 && ready ) { |
+ // Try to push a response from the queue to |
+ // the browser |
+ response.reset(replies.front()); |
+ replies.weak_erase(replies.begin()); |
+ |
+ if(!response->Remove(response->GetSize()-1, &payload)|| |
+ !payload->IsType(base::Value::TYPE_BINARY)) |
+ continue; |
+ |
+ base::BinaryValue* data = static_cast<base::BinaryValue*>(payload.get()); |
+ ready = !callback.Run( |
+ response.Pass(), |
+ data->GetBuffer(), |
+ data->GetSize()); |
+ } |
+ return !ready; |
+} |
+ |
+bool |
+FilesystemProviderResource::ShmChannelController::AckLastPushedResponse() { |
+ return ready = true; |
+} |
+ |
+uint32_t FilesystemProviderResource::ShmChannelController::size() { |
+ return replies.size(); |
+} |
+ |
+FilesystemProviderResource::ProvidedFilesystemInfo::ProvidedFilesystemInfo() |
+ :filesystem_id("none"), |
+ display_name("none"), |
+ writable(false),opened_files_limit(0){ |
+} |
+ |
+FilesystemProviderResource::ProvidedFilesystemInfo::~ProvidedFilesystemInfo(){} |
+ |
+FilesystemProviderResource::ShmBuffer::ShmBuffer( |
+ uint32_t read_size, uint32_t write_size, |
+ scoped_ptr<base::SharedMemory> shm) |
+ : read_size(read_size),write_size(write_size), shm(shm.Pass()) { |
+ DCHECK(this->shm); |
+} |
+ |
+FilesystemProviderResource::ShmBuffer::~ShmBuffer() {} |
+ |
+FilesystemProviderResource::RequestManager::RequestManager() {} |
+ |
+FilesystemProviderResource::RequestManager::~RequestManager() {} |
+ |
+void FilesystemProviderResource::RequestManager::AddRequest( |
+ int32_t request_id, PP_OperationType_Dev operation ) { |
+ requests_[ request_id ] = OperationStartTimePair( |
+ operation, |
+ std::chrono::system_clock::now() ); |
+} |
+ |
+bool FilesystemProviderResource::RequestManager::HasRequest( |
+ int32_t request_id) { |
+ return requests_.find(request_id)!=requests_.end(); |
+} |
+ |
+bool FilesystemProviderResource::RequestManager::RemoveRequest( |
+ int32_t request_id, int *out_time_span) { |
+ ListOfRequestsIterator it=requests_.find(request_id); |
+ if (it==requests_.end()) |
+ return false; |
+ |
+ // Compute operation time span |
+ std::chrono::time_point<std::chrono::system_clock> now = |
+ std::chrono::system_clock::now(); |
+ |
+ if(out_time_span) |
+ *out_time_span = std::chrono::duration_cast<std::chrono::seconds> |
+ (now - it->second.second).count(); |
+ requests_.erase( it ); |
+ return true; |
+} |
+ |
+FilesystemProviderResource::FilesystemProviderResource( |
+ Connection connection, |
+ PP_Instance instance ) |
+ :PluginResource( connection , instance ), |
+ mounted_(false), |
+ request_manager_(new RequestManager), |
+ read_channel_controller_( |
+ new ShmChannelController( |
+ kMaximumCachedReplies, |
+ base::Bind(&FilesystemProviderResource::FlushReadResponse, |
+ this))) { |
+ DCHECK(request_manager_); |
+ DCHECK(read_channel_controller_); |
+ SendCreate(BROWSER, PpapiHostMsg_FilesystemProvider_Create() ); |
+} |
+ |
+FilesystemProviderResource::~FilesystemProviderResource() { |
+} |
+ |
+ |
+thunk::PPB_FilesystemProvider_API* |
+FilesystemProviderResource::AsPPB_FilesystemProvider_API() { |
+ return this; |
+} |
+ |
+void FilesystemProviderResource::OnReplyReceived( |
+ const ResourceMessageReplyParams ¶ms, const IPC::Message &msg) { |
+ if (params.sequence()) { |
+ PluginResource::OnReplyReceived(params, msg); |
+ return; |
+ } |
+ PPAPI_BEGIN_MESSAGE_MAP(FilesystemProviderResource, msg) |
+ PPAPI_DISPATCH_PLUGIN_RESOURCE_CALL( |
+ PpapiPluginMsg_FilesystemProvider_OperationRequest, |
+ OnPluginMsgOperationRequest) |
+ PPAPI_DISPATCH_PLUGIN_RESOURCE_CALL( |
+ PpapiPluginMsg_FilesystemProvider_Buffers, |
+ OnPluginMsgBuffersReady) |
+ PPAPI_DISPATCH_PLUGIN_RESOURCE_CALL_0( |
+ PpapiPluginMsg_FilesystemProvider_ReadAck, |
+ OnPluginMsgReadAck) |
+ PPAPI_DISPATCH_PLUGIN_RESOURCE_CALL_UNHANDLED(NOTREACHED()) |
+ PPAPI_END_MESSAGE_MAP() |
+} |
+ |
+int32_t FilesystemProviderResource::Mount( |
+ PP_Var filesystem_id, |
+ PP_Var display_name, |
+ PP_Bool writable, |
+ int32_t opened_files_limit, |
+ scoped_refptr<TrackedCallback> callback) { |
+ if ( mounted_ ) |
+ return PP_ERROR_ADDRESS_IN_USE; |
+ if ( TrackedCallback::IsPending(mount_callback_) ) |
+ return PP_ERROR_INPROGRESS; |
+ |
+ StringVar* string_var = nullptr; |
+ |
+ const PP_Var *parameter_p[] = { &filesystem_id, &display_name }; |
+ std::string *value_p[] = { |
+ &filesystem_info_.filesystem_id, |
+ &filesystem_info_.display_name |
+ }; |
+ |
+ for( uint32_t i = 0; i < sizeof( value_p ) / sizeof( value_p[0] ); i++ ) { |
+ string_var = StringVar :: FromPPVar( *parameter_p[ i ] ); |
+ *value_p[ i ] = string_var ? string_var->value() : std::string(); |
+ } |
+ |
+ filesystem_info_.writable = PP_ToBool( writable ); |
+ filesystem_info_.opened_files_limit = opened_files_limit; |
+ |
+ // Remember the callback and the address of the return param |
+ mount_callback_ = callback; |
+ |
+ // Send mount request to the browser |
+ // and receive response in OnPluginMsgMountReply |
+ scoped_ptr<base::ListValue> request( |
+ filesystem_provider_internal:: |
+ PluginToBrowserTranslator::GenerateMountMessage( |
+ filesystem_info_.filesystem_id, filesystem_info_.display_name, |
+ filesystem_info_.writable,filesystem_info_.opened_files_limit)); |
+ if (!request.get()) |
+ return PP_ERROR_FAILED; |
+ |
+ Call<PpapiPluginMsg_FilesystemProvider_MountReply>( |
+ BROWSER, |
+ PpapiHostMsg_FilesystemProvider_Mount(*request), |
+ base::Bind(&FilesystemProviderResource::OnPluginMsgMountReply, this)); |
+ return PP_OK_COMPLETIONPENDING; |
+} |
+ |
+int32_t FilesystemProviderResource::Unmount(PP_Var filesystemId, |
+ scoped_refptr<TrackedCallback> callback ) { |
+ if ( !mounted_ ) |
+ return PP_ERROR_FAILED; |
+ if ( TrackedCallback::IsPending(unmount_callback_) ) |
+ return PP_ERROR_INPROGRESS; |
+ |
+ StringVar* string_var = nullptr; |
+ |
+ string_var = StringVar::FromPPVar( filesystemId ); |
+ std::string fs_id = string_var ? string_var->value() : std::string(); |
+ |
+ if (fs_id!=filesystem_info_.filesystem_id) |
+ return PP_ERROR_FAILED; |
+ |
+ // Remember the unmount callback and the address of the return param |
+ unmount_callback_ =callback; |
+ |
+ Call < PpapiPluginMsg_FilesystemProvider_UnmountReply >( |
+ BROWSER, |
+ PpapiHostMsg_FilesystemProvider_Unmount( fs_id ), |
+ base::Bind( &FilesystemProviderResource::OnPluginMsgUnmountReply, |
+ this ) |
+ ); |
+ |
+ return PP_OK_COMPLETIONPENDING; |
+} |
+ |
+int32_t FilesystemProviderResource::Notify(PP_Var notify_options) { |
+ scoped_ptr<base::ListValue> notification( |
+ filesystem_provider_internal::PluginToBrowserTranslator |
+ ::GenerateNotifyMessage(notify_options) ); |
+ if (!notification.get()) |
+ return PP_ERROR_MALFORMED_INPUT; |
+ Post( |
+ BROWSER, |
+ PpapiHostMsg_FilesystemProvider_Notify(*notification)); |
+ return PP_OK; |
+} |
+ |
+ |
+int32_t FilesystemProviderResource::SendSuccessResponse( |
+ PP_OperationType_Dev operation_type, |
+ int32_t request_id) { |
+ |
+ scoped_ptr<base::ListValue> response; |
+ |
+ switch( operation_type ) { |
+ case PP_OperationType_GETMETADATA: |
+ case PP_OperationType_READDIRECTORY: |
+ case PP_OperationType_READFILE: |
+ return PP_ERROR_BADARGUMENT; |
+ default: { |
+ // If we can't find a matching request from the browser |
+ // bail out |
+ int time_span = 0; |
+ if( !request_manager_->RemoveRequest(request_id, &time_span) )// |
+ return PP_ERROR_BADARGUMENT; |
+ if (operation_type==PP_OperationType_UNMOUNT) |
+ mounted_ = false; |
+ response = filesystem_provider_internal:: |
+ PluginToBrowserTranslator::GenerateSuccessResponse( |
+ operation_type, filesystem_info_.filesystem_id, |
+ request_id, time_span ); |
+ if(!response.get()) |
+ return PP_ERROR_FAILED; |
+ } |
+ } |
+ Post( |
+ BROWSER, |
+ PpapiHostMsg_FilesystemProvider_OperationResponse(*response)); |
+ return PP_OK; |
+} |
+ |
+int32_t FilesystemProviderResource::SendErrorResponse( |
+ PP_OperationType_Dev operation_type, |
+ int32_t error, |
+ int32_t request_id) { |
+ |
+ int time_span = 0; |
+ if( !request_manager_->RemoveRequest(request_id, &time_span) ) |
+ return PP_ERROR_BADARGUMENT; |
+ |
+ scoped_ptr<base::ListValue> response( |
+ filesystem_provider_internal:: |
+ PluginToBrowserTranslator::GenerateFailureResponse( |
+ operation_type, error, filesystem_info_.filesystem_id, request_id, |
+ time_span )); |
+ if(!response.get()) |
+ return PP_ERROR_FAILED; |
+ |
+ Post( |
+ BROWSER, |
+ PpapiHostMsg_FilesystemProvider_OperationResponse(*response)); |
+ return PP_OK; |
+} |
+ |
+int32_t FilesystemProviderResource::SendMetadataSuccessResponse( |
+ struct PP_Var metadata, |
+ int32_t request_id) { |
+ |
+ int time_span = 0; |
+ if( !request_manager_->RemoveRequest(request_id, &time_span) ) |
+ return PP_ERROR_BADARGUMENT; |
+ |
+ scoped_ptr<base::ListValue> response( |
+ filesystem_provider_internal:: |
+ PluginToBrowserTranslator::GenerateMetadataResponse( |
+ metadata, request_id, filesystem_info_.filesystem_id, time_span)); |
+ if(!response.get()) |
+ return PP_ERROR_FAILED; |
+ |
+ Post( |
+ BROWSER, |
+ PpapiHostMsg_FilesystemProvider_OperationResponse(*response) |
+ ); |
+ return PP_OK; |
+} |
+ |
+int32_t FilesystemProviderResource::SendReadDirectorySuccessResponse( |
+ PP_Var entries, |
+ PP_Bool has_more, int32_t request_id) { |
+ |
+ int time_span = 0; |
+ if (has_more) { |
+ if (!request_manager_->HasRequest(request_id)) |
+ return PP_ERROR_BADARGUMENT; |
+ } else { |
+ if(!request_manager_->RemoveRequest(request_id,&time_span)) |
+ return PP_ERROR_BADARGUMENT; |
+ } |
+ scoped_ptr<base::ListValue> response( |
+ filesystem_provider_internal:: |
+ PluginToBrowserTranslator::GenerateReadDirectoryResponse( |
+ entries, has_more, request_id, |
+ filesystem_info_.filesystem_id, time_span )); |
+ |
+ if(!response.get()) |
+ return PP_ERROR_FAILED; |
+ Post( |
+ BROWSER, |
+ PpapiHostMsg_FilesystemProvider_OperationResponse(*response) ); |
+ return PP_OK; |
+} |
+ |
+int32_t FilesystemProviderResource::SendReadFileSuccessResponse( |
+ uint32_t data_size, |
+ const void *data, |
+ PP_Bool has_more, |
+ int32_t request_id) { |
+ |
+ int time_span = 0; |
+ // Check if this is an answer to a previous request |
+ if (has_more) { |
+ if (!request_manager_->HasRequest(request_id)) |
+ return PP_ERROR_BADARGUMENT; |
+ } else { |
+ if(!request_manager_->RemoveRequest(request_id,&time_span)) |
+ return PP_ERROR_BADARGUMENT; |
+ } |
+ // check if shared memory is ready and the right size |
+ if(!read_write_buffer_.get()) |
+ return PP_ERROR_FAILED; |
+ if(data_size > read_write_buffer_->read_size ) |
+ return PP_ERROR_MESSAGE_TOO_BIG; |
+ |
+ scoped_ptr<base::ListValue> response( |
+ filesystem_provider_internal:: |
+ PluginToBrowserTranslator::GenerateReadFileSuccessResponse( |
+ data_size, PP_ToBool( has_more ), request_id, time_span, |
+ filesystem_info_.filesystem_id)); |
+ |
+ if(!response.get()) |
+ return PP_ERROR_FAILED; |
+ |
+ // Send response or enqueue it |
+ if(!read_channel_controller_->EnqueueResponse( |
+ response.Pass(), static_cast<const char*>(data),data_size)) |
+ return PP_ERROR_FAILED; |
+ return PP_OK; |
+} |
+ |
+int32_t FilesystemProviderResource::GetNextRequest( |
+ PP_FilesystemRequest* request, scoped_refptr<TrackedCallback> callback) { |
+ if(TrackedCallback::IsPending(get_next_request_callback_)) |
+ return PP_ERROR_INPROGRESS; |
+ // Retain the container address |
+ get_next_request_callback_data_ = request; |
+ // If buffered requests are pending return the first one |
+ if(!received_requests_.empty()) { |
+ if(!WriteRequest()) |
+ return PP_ERROR_FAILED; |
+ // By returning PP_OK the callback is run |
+ return PP_OK; |
+ } |
+ // Retain the callback for future execution |
+ get_next_request_callback_=callback; |
+ |
+ return PP_OK_COMPLETIONPENDING; |
+} |
+ |
+int32_t FilesystemProviderResource::ReleaseRequestBuffer(int32_t request_id) { |
+ using namespace filesystem_provider_internal; |
+ ListOfRequests::iterator it = pending_process_requests_.find(request_id); |
+ if(it!=pending_process_requests_.end()) { |
+ pending_process_requests_.erase(it); |
+ return PP_OK; |
+ } |
+ return PP_ERROR_FAILED; |
+} |
+ |
+void FilesystemProviderResource::OnPluginMsgMountReply( |
+ const ResourceMessageReplyParams ¶ms) { |
+ if (TrackedCallback::IsPending(mount_callback_)) { |
+ if (params.result()==PP_OK) |
+ mounted_ = true; |
+ mount_callback_->Run( params.result() ); |
+ } |
+} |
+ |
+void FilesystemProviderResource::OnPluginMsgUnmountReply( |
+ const ResourceMessageReplyParams ¶ms) { |
+ mounted_ = false; |
+ if (TrackedCallback::IsPending( unmount_callback_ )) { |
+ unmount_callback_->Run( params.result() ); |
+ } |
+} |
+ |
+void FilesystemProviderResource::OnPluginMsgOperationRequest( |
+ const ResourceMessageParams ¶ms, |
+ const PP_OperationType_Dev &operation, |
+ const base::ListValue &operationArgs) { |
+using namespace filesystem_provider_internal; |
+// We shall push the request |
+ switch (operation) { |
+ case PP_OperationType_ABORT: { |
+ scoped_refptr<AbortOperationTranslator> |
+ request = AbortOperationTranslator::PopulateFromRequest( |
+ operationArgs); |
+ |
+ if (request.get()) { |
+ // Retain payload |
+ request_manager_->RemoveRequest( request->operation_request_id, NULL); |
+ request_manager_->AddRequest( request->request_id, operation); |
+ received_requests_.push_back( request); |
+ } |
+ break; |
+ } // PP_OperationType_ABORT |
+ case PP_OperationType_CLOSEFILE: { |
+ scoped_refptr< CloseFileOperationTranslator > |
+ request = CloseFileOperationTranslator::PopulateFromRequest( |
+ operationArgs); |
+ if (request.get()) { |
+ request_manager_->AddRequest( request->request_id, operation); |
+ received_requests_.push_back( request ); |
+ } |
+ break; |
+ }//PP_OperationType_CLOSEFILE |
+ case PP_OperationType_COPYENTRY: { |
+ scoped_refptr< CopyEntryOperationTranslator > |
+ request = CopyEntryOperationTranslator::PopulateFromRequest( |
+ operationArgs); |
+ if (request.get()) { |
+ request_manager_->AddRequest( request->request_id, operation); |
+ received_requests_.push_back( request ); |
+ } |
+ break; |
+ }// PP_OperationType_COPYENTRY |
+ case PP_OperationType_CREATEDIRECTORY: { |
+ scoped_refptr< CreateDirectoryOperationTranslator > |
+ request = CreateDirectoryOperationTranslator::PopulateFromRequest( |
+ operationArgs); |
+ if (request.get()) { |
+ request_manager_->AddRequest( request->request_id, operation); |
+ received_requests_.push_back( request ); |
+ } |
+ break; |
+ }// PP_OperationType_CREATEDIRECTORY |
+ case PP_OperationType_CREATEFILE: { |
+ scoped_refptr< CreateFileOperationTranslator > |
+ request = CreateFileOperationTranslator::PopulateFromRequest( |
+ operationArgs); |
+ if (request.get()) { |
+ request_manager_->AddRequest( request->request_id, operation); |
+ received_requests_.push_back( request ); |
+ } |
+ break; |
+ }// PP_OperationType_CREATEFILE |
+ case PP_OperationType_DELETEENTRY: { |
+ scoped_refptr< DeleteEntryOperationTranslator > |
+ request = DeleteEntryOperationTranslator::PopulateFromRequest( |
+ operationArgs); |
+ if (request.get()) { |
+ request_manager_->AddRequest( request->request_id, operation); |
+ received_requests_.push_back( request ); |
+ } |
+ break; |
+ }//PP_OperationType_DELETEENTRY |
+ case PP_OperationType_GETMETADATA: { |
+ scoped_refptr<GetMetadataOperationTranslator> |
+ request = GetMetadataOperationTranslator::PopulateFromRequest( |
+ operationArgs); |
+ if ( request.get() ) { |
+ request_manager_->AddRequest( request->request_id, operation); |
+ received_requests_.push_back( request ); |
+ } |
+ break; |
+ } // PP_OperationType_GETMETADATA |
+ case PP_OperationType_MOVEENTRY: { |
+ scoped_refptr<MoveOperationTranslator> |
+ request = MoveOperationTranslator::PopulateFromRequest( |
+ operationArgs); |
+ if (request.get()) { |
+ request_manager_->AddRequest( request->request_id, operation); |
+ received_requests_.push_back( request ); |
+ } |
+ break; |
+ }// PP_OperationType_MOVEENTRY |
+ case PP_OperationType_OPENFILE: { |
+ scoped_refptr<OpenFileOperationTranslator> |
+ request = OpenFileOperationTranslator::PopulateFromRequest( |
+ operationArgs); |
+ if (request.get()) { |
+ request_manager_->AddRequest( request->request_id, operation); |
+ received_requests_.push_back( request ); |
+ } |
+ break; |
+ }// PP_OperationType_OpenFile |
+ case PP_OperationType_READDIRECTORY: { |
+ scoped_refptr<ReadDirectoryOperationTranslator> |
+ request = ReadDirectoryOperationTranslator::PopulateFromRequest( |
+ operationArgs); |
+ if (request.get()) { |
+ request_manager_->AddRequest( request->request_id, operation); |
+ received_requests_.push_back( request ); |
+ } |
+ break; |
+ }//PP_OperationType_READDIRECTORY |
+ case PP_OperationType_READFILE: { |
+ scoped_refptr<ReadFileOperationTranslator> |
+ request = ReadFileOperationTranslator::PopulateFromRequest( |
+ operationArgs); |
+ if (request.get()) { |
+ request_manager_->AddRequest( request->request_id, operation); |
+ received_requests_.push_back( request ); |
+ } |
+ break; |
+ }// PP_OperationType_READFILE |
+ case PP_OperationType_TRUNCATEENTRY: { |
+ scoped_refptr<TruncateOperationTranslator> |
+ request = TruncateOperationTranslator::PopulateFromRequest( |
+ operationArgs); |
+ if (request.get()) { |
+ request_manager_->AddRequest( request->request_id, operation); |
+ received_requests_.push_back( request ); |
+ } |
+ break; |
+ }//PP_OperationType_TRUNCATEENTRY |
+ case PP_OperationType_UNMOUNT: { |
+ scoped_refptr<UnmountOperationTranslator> |
+ request = UnmountOperationTranslator::PopulateFromRequest( |
+ operationArgs); |
+ if (request.get()) { |
+ request_manager_->AddRequest( request->request_id, operation); |
+ received_requests_.push_back( request ); |
+ } |
+ break; |
+ }//PP_OperationType_UNMOUNT |
+ case PP_OperationType_WRITEFILE: { |
+ // If shared mem inited |
+ if (read_write_buffer_.get()) { |
+ scoped_refptr<WriteFileOperationTranslator> |
+ request = WriteFileOperationTranslator::PopulateFromRequest( |
+ operationArgs, |
+ (char*)read_write_buffer_->shm->memory()+ |
+ read_write_buffer_->read_size |
+ ); |
+ if (request.get()) { |
+ request_manager_->AddRequest( request->request_id, operation); |
+ received_requests_.push_back( request ); |
+ } |
+ } |
+ SendWriteAck(); |
+ break; |
+ } |
+ case PP_OperationType_ADDWATCHER: { |
+ scoped_refptr<AddWatcherOperationTranslator> |
+ request = AddWatcherOperationTranslator::PopulateFromRequest( |
+ operationArgs); |
+ if (request.get()) { |
+ request_manager_->AddRequest( request->request_id, operation); |
+ received_requests_.push_back( request ); |
+ } |
+ break; |
+ } |
+ case PP_OperationType_REMOVEWATCHER: { |
+ scoped_refptr<RemoveWatcherOperationTranslator> |
+ request = RemoveWatcherOperationTranslator::PopulateFromRequest( |
+ operationArgs); |
+ if (request.get()) { |
+ request_manager_->AddRequest( request->request_id, operation); |
+ received_requests_.push_back( request ); |
+ } |
+ break; |
+ } |
+ default: |
+ break; |
+ } |
+ if (!TrackedCallback::IsPending(get_next_request_callback_) || |
+ TrackedCallback::IsScheduledToRun(get_next_request_callback_) || |
+ !WriteRequest()) |
+ return; |
+ |
+ scoped_refptr<TrackedCallback> callback; |
+ callback.swap(get_next_request_callback_); |
+ // Run callback |
+ callback->Run(PP_OK); |
+} |
+ |
+void FilesystemProviderResource::OnPluginMsgBuffersReady( |
+ const ResourceMessageParams& params, uint32_t read_buffer_size, |
+ uint32_t write_buffer_size ) { |
+ |
+ std::vector<base::SharedMemoryHandle> shm_handles; |
+ params.TakeAllSharedMemoryHandles(&shm_handles); |
+ |
+ scoped_ptr<base::SharedMemory> shm( |
+ new base::SharedMemory(shm_handles[0],false)); |
+ size_t buffer_size = read_buffer_size + write_buffer_size; |
+ if (!shm->Map(buffer_size) ) |
+ return; |
+ read_write_buffer_= |
+ make_scoped_ptr(new ShmBuffer( read_buffer_size, write_buffer_size, |
+ shm.Pass())); |
+} |
+ |
+// Received when the browser part acks the read from the shm buffer |
+void FilesystemProviderResource::OnPluginMsgReadAck( |
+ const ResourceMessageReplyParams& /*params*/) { |
+ |
+ read_channel_controller_->AckLastPushedResponse(); |
+ read_channel_controller_->PushNextResponse(); |
+} |
+ |
+bool FilesystemProviderResource::WriteRequest() |
+{ |
+ if(!get_next_request_callback_data_) |
+ return false; |
+ scoped_ptr<PP_FilesystemRequest > request; |
+ scoped_refptr<filesystem_provider_internal::OperationTranslator> |
+ message; |
+ // The first request that we can decode we put it into the designated |
+ // container for the filesystem provider implementation |
+ while (received_requests_.size()>0) { |
+ message = received_requests_.front(); |
+ received_requests_.pop_front(); |
+ request = message->ToFilesystemRequest(); |
+ |
+ if(request.get()) |
+ break; |
+ } |
+ if(!request.get()) |
+ return false; |
+ |
+ // Retain the request until the implementation frees it |
+ pending_process_requests_.insert(std::make_pair( request->request_id, |
+ message ) ); |
+ *get_next_request_callback_data_ = *request; |
+ get_next_request_callback_data_ = NULL; |
+ return true; |
+} |
+ |
+bool FilesystemProviderResource::FlushReadResponse( |
+ scoped_ptr<base::ListValue> response, const char*data, uint32_t data_size) { |
+ if (!response.get() || |
+ data==NULL) |
+ return false; |
+ memcpy( read_write_buffer_->shm->memory(), data, data_size); |
+ |
+ Post(BROWSER, |
+ PpapiHostMsg_FilesystemProvider_OperationResponse(*response)); |
+ |
+ return true; |
+} |
+ |
+void FilesystemProviderResource::SendWriteAck() { |
+ // Send Ack for the request to the browser to signal that the shm |
+ // channel can be reused. |
+ Post(BROWSER, PpapiHostMsg_FilesystemProvider_WriteAck()); |
+} |
+ |
+namespace filesystem_provider_internal{ |
+ |
+AbortOperationTranslator::AbortOperationTranslator(){} |
+AbortOperationTranslator::~AbortOperationTranslator(){} |
+ |
+ scoped_ptr<PP_FilesystemRequest> |
+AbortOperationTranslator::ToFilesystemRequest() { |
+ scoped_ptr<PP_FilesystemRequest> out(new PP_FilesystemRequest); |
+ if(!out.get()) |
+ return nullptr; |
+ out->operation_type = PP_OperationType_ABORT; |
+ out->request_id = request_id; |
+ return out.Pass(); |
+} |
+ |
+// static |
+scoped_refptr<AbortOperationTranslator> |
+AbortOperationTranslator::PopulateFromRequest( const base::ListValue &request) { |
+ if( request.empty() ) |
+ return nullptr; |
+ |
+ const base::Value *dict_value = nullptr; |
+ if(!request.Get(0,&dict_value)) |
+ return nullptr; |
+ |
+ scoped_refptr<AbortOperationTranslator> out(new AbortOperationTranslator()); |
+ const base::DictionaryValue* dict = |
+ static_cast<const base::DictionaryValue*>(dict_value); |
+ |
+ const base::Value* file_system_id_value = NULL; |
+ if (!dict->GetWithoutPathExpansion("fileSystemId", &file_system_id_value)) |
+ return nullptr; |
+ if (!file_system_id_value->GetAsString(&out->file_system_id)) |
+ return nullptr; |
+ |
+ const base::Value* request_id_value = NULL; |
+ if (!dict->GetWithoutPathExpansion("requestId", &request_id_value)) |
+ return nullptr; |
+ if (!request_id_value->GetAsInteger(&out->request_id)) |
+ return nullptr; |
+ |
+ const base::Value* operation_request_id_value = NULL; |
+ if (!dict->GetWithoutPathExpansion( |
+ "operationRequestId", &operation_request_id_value)) |
+ return nullptr; |
+ if (!operation_request_id_value->GetAsInteger(&out->operation_request_id)) |
+ return nullptr; |
+ return out; |
+} |
+ |
+CloseFileOperationTranslator::~CloseFileOperationTranslator(){} |
+ |
+scoped_ptr<PP_FilesystemRequest> |
+CloseFileOperationTranslator::ToFilesystemRequest() { |
+ scoped_ptr<PP_FilesystemRequest> out(new PP_FilesystemRequest); |
+ if(!out.get()) |
+ return nullptr; |
+ |
+ out->operation_type = PP_OperationType_CLOSEFILE; |
+ out->request_id = request_id; |
+ out->value.as_close_file.open_request_id = open_request_id; |
+ |
+ return out.Pass(); |
+} |
+ |
+//static |
+scoped_refptr<CloseFileOperationTranslator> |
+CloseFileOperationTranslator::PopulateFromRequest( |
+ const base::ListValue &request) { |
+ if( request.empty() ) |
+ return nullptr; |
+ |
+ const base::Value *dict_value = nullptr; |
+ if(!request.Get(0,&dict_value)) |
+ return nullptr; |
+ |
+ scoped_refptr<CloseFileOperationTranslator> |
+ out(new CloseFileOperationTranslator()); |
+ |
+ if (!dict_value->IsType(base::Value::TYPE_DICTIONARY)) |
+ return nullptr; |
+ const base::DictionaryValue* dict = |
+ static_cast<const base::DictionaryValue*>(dict_value); |
+ const base::Value* file_system_id_value = NULL; |
+ if (!dict->GetWithoutPathExpansion("fileSystemId", &file_system_id_value)) |
+ return nullptr; |
+ if (!file_system_id_value->GetAsString(&out->file_system_id)) |
+ return nullptr; |
+ |
+ const base::Value* request_id_value = NULL; |
+ if (!dict->GetWithoutPathExpansion("requestId", &request_id_value)) |
+ return nullptr; |
+ if (!request_id_value->GetAsInteger(&out->request_id)) |
+ return nullptr; |
+ |
+ const base::Value* open_request_id_value = NULL; |
+ if (!dict->GetWithoutPathExpansion("openRequestId", &open_request_id_value)) |
+ return nullptr; |
+ if (!open_request_id_value->GetAsInteger(&out->open_request_id)) |
+ return nullptr; |
+ |
+ return out; |
+} |
+ |
+CloseFileOperationTranslator::CloseFileOperationTranslator(){} |
+ |
+//static |
+GetMetadataOperationTranslator::~GetMetadataOperationTranslator(){} |
+ |
+scoped_ptr<PP_FilesystemRequest> |
+GetMetadataOperationTranslator::ToFilesystemRequest() { |
+ scoped_ptr<PP_FilesystemRequest> out(new PP_FilesystemRequest); |
+ if(!out.get()) |
+ return nullptr; |
+ out->operation_type = PP_OperationType_GETMETADATA; |
+ out->request_id = request_id; |
+ out->value.as_metadata.thumbnail = PP_FromBool( thumbnail ); |
+ out->value.as_metadata.entry_path = entry_path.c_str(); |
+ |
+ return out.Pass(); |
+} |
+ |
+scoped_refptr<GetMetadataOperationTranslator> |
+GetMetadataOperationTranslator::PopulateFromRequest( |
+ const base::ListValue &request ) { |
+ |
+ if( request.empty() ) |
+ return nullptr; |
+ |
+ const base::Value *dict_value = nullptr; |
+ if(!request.Get(0,&dict_value)) |
+ return nullptr; |
+ |
+ scoped_refptr<GetMetadataOperationTranslator> |
+ out(new GetMetadataOperationTranslator()); |
+ |
+ if (!dict_value->IsType(base::Value::TYPE_DICTIONARY)) |
+ return nullptr; |
+ const base::DictionaryValue* dict = |
+ static_cast<const base::DictionaryValue*>(dict_value); |
+ const base::Value* file_system_id_value = NULL; |
+ |
+ if (!dict->GetWithoutPathExpansion("fileSystemId", &file_system_id_value)) |
+ return nullptr; |
+ if (!file_system_id_value->GetAsString(&out->file_system_id)) |
+ return nullptr; |
+ |
+ const base::Value* request_id_value = NULL; |
+ if (!dict->GetWithoutPathExpansion("requestId", &request_id_value)) |
+ return nullptr; |
+ if (!request_id_value->GetAsInteger(&out->request_id)) |
+ return nullptr; |
+ |
+ const base::Value* entry_path_value = NULL; |
+ if (!dict->GetWithoutPathExpansion("entryPath", &entry_path_value)) |
+ return nullptr; |
+ if (!entry_path_value->GetAsString(&out->entry_path)) |
+ return nullptr; |
+ |
+ const base::Value* thumbnail_value = NULL; |
+ if (!dict->GetWithoutPathExpansion("thumbnail", &thumbnail_value)) |
+ return nullptr; |
+ if (!thumbnail_value->GetAsBoolean(&out->thumbnail)) |
+ return nullptr; |
+ return out; |
+} |
+ |
+GetMetadataOperationTranslator::GetMetadataOperationTranslator(){} |
+ |
+ |
+CopyEntryOperationTranslator::~CopyEntryOperationTranslator(){} |
+ |
+scoped_ptr<PP_FilesystemRequest> |
+CopyEntryOperationTranslator::ToFilesystemRequest() { |
+ scoped_ptr<PP_FilesystemRequest> out(new PP_FilesystemRequest); |
+ out->operation_type = PP_OperationType_COPYENTRY; |
+ out->request_id = request_id; |
+ out->value.as_copy_entry.source_path = source_path.c_str(); |
+ out->value.as_copy_entry.target_path = target_path.c_str(); |
+ return out.Pass(); |
+} |
+ |
+// static |
+scoped_refptr<CopyEntryOperationTranslator> |
+CopyEntryOperationTranslator::PopulateFromRequest( |
+ const base::ListValue &request) { |
+ if( request.empty() ) |
+ return nullptr; |
+ |
+ const base::Value *dict_value = nullptr; |
+ if(!request.Get(0,&dict_value)) |
+ return nullptr; |
+ |
+ scoped_refptr<CopyEntryOperationTranslator> |
+ out(new CopyEntryOperationTranslator()); |
+ if (!dict_value->IsType(base::Value::TYPE_DICTIONARY)) |
+ return nullptr; |
+ |
+ const base::DictionaryValue* dict = |
+ static_cast<const base::DictionaryValue*>(dict_value); |
+ const base::Value* file_system_id_value = NULL; |
+ if (!dict->GetWithoutPathExpansion("fileSystemId", &file_system_id_value)) |
+ return nullptr; |
+ if (!file_system_id_value->GetAsString(&out->file_system_id)) |
+ return nullptr; |
+ |
+ const base::Value* request_id_value = NULL; |
+ if (!dict->GetWithoutPathExpansion("requestId", &request_id_value)) |
+ return nullptr; |
+ if (!request_id_value->GetAsInteger(&out->request_id)) |
+ return nullptr; |
+ |
+ const base::Value* source_path_value = NULL; |
+ if (!dict->GetWithoutPathExpansion("sourcePath", &source_path_value)) |
+ return nullptr; |
+ if (!source_path_value->GetAsString(&out->source_path)) |
+ return nullptr; |
+ |
+ const base::Value* target_path_value = NULL; |
+ if (!dict->GetWithoutPathExpansion("targetPath", &target_path_value)) |
+ return nullptr; |
+ if (!target_path_value->GetAsString(&out->target_path)) |
+ return nullptr; |
+ return out; |
+ |
+} |
+ |
+CopyEntryOperationTranslator::CopyEntryOperationTranslator(){} |
+ |
+CreateDirectoryOperationTranslator::~CreateDirectoryOperationTranslator(){} |
+ |
+scoped_ptr<PP_FilesystemRequest> |
+CreateDirectoryOperationTranslator::ToFilesystemRequest() { |
+ scoped_ptr<PP_FilesystemRequest> out(new PP_FilesystemRequest); |
+ if(!out.get()) |
+ return nullptr; |
+ out->operation_type = PP_OperationType_CREATEDIRECTORY; |
+ out->request_id = request_id; |
+ out->value.as_create_directory.directory_path = directory_path.c_str(); |
+ out->value.as_create_directory.recursive = PP_FromBool(recursive); |
+ return out.Pass(); |
+} |
+ |
+scoped_refptr<CreateDirectoryOperationTranslator> |
+CreateDirectoryOperationTranslator::PopulateFromRequest( |
+ const base::ListValue &request) { |
+ if( request.empty() ) |
+ return nullptr; |
+ |
+ const base::Value *dict_value = nullptr; |
+ if(!request.Get(0,&dict_value)) |
+ return nullptr; |
+ |
+ scoped_refptr<CreateDirectoryOperationTranslator> |
+ out(new CreateDirectoryOperationTranslator()); |
+ if (!dict_value->IsType(base::Value::TYPE_DICTIONARY)) |
+ return nullptr; |
+ |
+ const base::DictionaryValue* dict = |
+ static_cast<const base::DictionaryValue*>(dict_value); |
+ const base::Value* file_system_id_value = NULL; |
+ if (!dict->GetWithoutPathExpansion("fileSystemId", &file_system_id_value)) |
+ return nullptr; |
+ if (!file_system_id_value->GetAsString(&out->file_system_id)) |
+ return nullptr; |
+ |
+ const base::Value* request_id_value = NULL; |
+ if (!dict->GetWithoutPathExpansion("requestId", &request_id_value)) |
+ return nullptr; |
+ if (!request_id_value->GetAsInteger(&out->request_id)) |
+ return nullptr; |
+ |
+ const base::Value* directory_path_value = NULL; |
+ if (!dict->GetWithoutPathExpansion("directoryPath", &directory_path_value)) |
+ return nullptr; |
+ if (!directory_path_value->GetAsString(&out->directory_path)) |
+ return nullptr; |
+ |
+ const base::Value* recursive_value = NULL; |
+ if (!dict->GetWithoutPathExpansion("recursive", &recursive_value)) |
+ return nullptr; |
+ if (!recursive_value->GetAsBoolean(&out->recursive)) |
+ return nullptr; |
+ |
+ return out; |
+} |
+ |
+CreateDirectoryOperationTranslator::CreateDirectoryOperationTranslator(){} |
+ |
+CreateFileOperationTranslator::~CreateFileOperationTranslator(){} |
+ |
+scoped_ptr<PP_FilesystemRequest> |
+CreateFileOperationTranslator::ToFilesystemRequest() { |
+ scoped_ptr<PP_FilesystemRequest> out(new PP_FilesystemRequest); |
+ if(!out.get()) |
+ return scoped_ptr<PP_FilesystemRequest>(); |
+ out->operation_type = PP_OperationType_CREATEFILE; |
+ out->request_id = request_id; |
+ out->value.as_create_file.file_path = file_path.c_str(); |
+ return out.Pass(); |
+} |
+ |
+scoped_refptr<CreateFileOperationTranslator> |
+CreateFileOperationTranslator::PopulateFromRequest( |
+ const base::ListValue &request) { |
+ if( request.empty() ) |
+ return nullptr; |
+ |
+ const base::Value *dict_value = nullptr; |
+ if(!request.Get(0,&dict_value)) |
+ return nullptr; |
+ |
+ scoped_refptr<CreateFileOperationTranslator> |
+ out(new CreateFileOperationTranslator()); |
+ if (!dict_value->IsType(base::Value::TYPE_DICTIONARY)) |
+ return nullptr; |
+ |
+ const base::DictionaryValue* dict = |
+ static_cast<const base::DictionaryValue*>(dict_value); |
+ const base::Value* file_system_id_value = NULL; |
+ if (!dict->GetWithoutPathExpansion("fileSystemId", &file_system_id_value)) |
+ return nullptr; |
+ if (!file_system_id_value->GetAsString(&out->file_system_id)) |
+ return nullptr; |
+ |
+ const base::Value* request_id_value = NULL; |
+ if (!dict->GetWithoutPathExpansion("requestId", &request_id_value)) |
+ return nullptr; |
+ if (!request_id_value->GetAsInteger(&out->request_id)) |
+ return nullptr; |
+ |
+ const base::Value* file_path_value = NULL; |
+ if (!dict->GetWithoutPathExpansion("filePath", &file_path_value)) |
+ return nullptr; |
+ if (!file_path_value->GetAsString(&out->file_path)) |
+ return nullptr; |
+ return out; |
+} |
+ |
+CreateFileOperationTranslator::CreateFileOperationTranslator(){} |
+ |
+DeleteEntryOperationTranslator::~DeleteEntryOperationTranslator(){} |
+ |
+scoped_ptr<PP_FilesystemRequest> |
+DeleteEntryOperationTranslator::ToFilesystemRequest() { |
+ scoped_ptr<PP_FilesystemRequest> out(new PP_FilesystemRequest); |
+ out->operation_type = PP_OperationType_DELETEENTRY; |
+ out->request_id = request_id; |
+ out->value.as_delete_entry.entry_path = entry_path.c_str(); |
+ out->value.as_delete_entry.recursive = PP_FromBool(recursive); |
+ return out.Pass(); |
+} |
+ |
+scoped_refptr<DeleteEntryOperationTranslator> |
+DeleteEntryOperationTranslator::PopulateFromRequest( |
+ const base::ListValue &request) { |
+ if( request.empty() ) |
+ return nullptr; |
+ |
+ const base::Value *dict_value = nullptr; |
+ if(!request.Get(0,&dict_value)) |
+ return nullptr; |
+ |
+ if (!dict_value->IsType(base::Value::TYPE_DICTIONARY)) |
+ return nullptr; |
+ |
+ |
+ scoped_refptr<DeleteEntryOperationTranslator> |
+ out(new DeleteEntryOperationTranslator()); |
+ |
+ const base::DictionaryValue* dict = |
+ static_cast<const base::DictionaryValue*>(dict_value); |
+ const base::Value* file_system_id_value = NULL; |
+ |
+ if (!dict->GetWithoutPathExpansion("fileSystemId", &file_system_id_value)) |
+ return nullptr; |
+ if (!file_system_id_value->GetAsString(&out->file_system_id)) |
+ return nullptr; |
+ |
+ const base::Value* request_id_value = NULL; |
+ if (!dict->GetWithoutPathExpansion("requestId", &request_id_value)) |
+ return nullptr; |
+ if (!request_id_value->GetAsInteger(&out->request_id)) |
+ return nullptr; |
+ |
+ const base::Value* entry_path_value = NULL; |
+ if (!dict->GetWithoutPathExpansion("entryPath", &entry_path_value)) |
+ return nullptr; |
+ if (!entry_path_value->GetAsString(&out->entry_path)) |
+ return nullptr; |
+ |
+ const base::Value* recursive_value = NULL; |
+ if (!dict->GetWithoutPathExpansion("recursive", &recursive_value)) |
+ return nullptr; |
+ if (!recursive_value->GetAsBoolean(&out->recursive)) |
+ return nullptr; |
+ return out; |
+} |
+ |
+DeleteEntryOperationTranslator::DeleteEntryOperationTranslator(){} |
+ |
+MoveOperationTranslator::~MoveOperationTranslator(){} |
+ |
+scoped_ptr<PP_FilesystemRequest> |
+MoveOperationTranslator::ToFilesystemRequest() { |
+ scoped_ptr<PP_FilesystemRequest> out(new PP_FilesystemRequest); |
+ if(!out.get()) |
+ return nullptr; |
+ out->operation_type = PP_OperationType_MOVEENTRY; |
+ out->request_id = request_id; |
+ out->value.as_move_entry.source_path = source_path.c_str(); |
+ out->value.as_move_entry.target_path = target_path.c_str(); |
+ return out.Pass(); |
+} |
+ |
+scoped_refptr<MoveOperationTranslator> |
+MoveOperationTranslator::PopulateFromRequest(const base::ListValue &request) { |
+ if( request.empty() ) |
+ return nullptr; |
+ |
+ const base::Value *dict_value = nullptr; |
+ if(!request.Get(0,&dict_value)) |
+ return nullptr; |
+ |
+ if (!dict_value->IsType(base::Value::TYPE_DICTIONARY)) |
+ return nullptr; |
+ |
+ scoped_refptr<MoveOperationTranslator> out(new MoveOperationTranslator()); |
+ const base::DictionaryValue* dict = |
+ static_cast<const base::DictionaryValue*>(dict_value); |
+ const base::Value* file_system_id_value = NULL; |
+ if (!dict->GetWithoutPathExpansion("fileSystemId", &file_system_id_value)) |
+ return nullptr; |
+ if (!file_system_id_value->GetAsString(&out->file_system_id)) |
+ return nullptr; |
+ |
+ const base::Value* request_id_value = NULL; |
+ if (!dict->GetWithoutPathExpansion("requestId", &request_id_value)) |
+ return nullptr; |
+ if (!request_id_value->GetAsInteger(&out->request_id)) |
+ return nullptr; |
+ |
+ const base::Value* source_path_value = NULL; |
+ if (!dict->GetWithoutPathExpansion("sourcePath", &source_path_value)) |
+ return nullptr; |
+ if (!source_path_value->GetAsString(&out->source_path)) |
+ return nullptr; |
+ |
+ const base::Value* target_path_value = NULL; |
+ if (!dict->GetWithoutPathExpansion("targetPath", &target_path_value)) |
+ return nullptr; |
+ if (!target_path_value->GetAsString(&out->target_path)) |
+ return nullptr; |
+ return out; |
+} |
+ |
+MoveOperationTranslator::MoveOperationTranslator(){} |
+ |
+PP_OpenFileMode_Dev ParseOpenFileMode( const std::string &mode ) { |
+ if (mode=="WRITE") |
+ return PP_OpenFileMode_WRITE; |
+ else if ( mode=="READ" )//( mode=="read") |
+ return PP_OpenFileMode_READ; |
+ else |
+ return PP_OpenFileMode_NONE; |
+} |
+ |
+ |
+OpenFileOperationTranslator::~OpenFileOperationTranslator(){} |
+ |
+scoped_ptr<PP_FilesystemRequest> |
+OpenFileOperationTranslator::ToFilesystemRequest() { |
+ scoped_ptr<PP_FilesystemRequest> out(new PP_FilesystemRequest); |
+ if(!out.get()) |
+ return nullptr; |
+ out->operation_type = PP_OperationType_OPENFILE; |
+ out->request_id = request_id; |
+ out->value.as_open_file.file_path = file_path.c_str(); |
+ out->value.as_open_file.mode = mode; |
+ return out.Pass(); |
+} |
+ |
+//static |
+scoped_refptr<OpenFileOperationTranslator> |
+OpenFileOperationTranslator::PopulateFromRequest( |
+ const base::ListValue &request) { |
+ if( request.empty() ) |
+ return nullptr; |
+ |
+ const base::Value *dict_value = nullptr; |
+ if(!request.Get(0,&dict_value)) |
+ return nullptr; |
+ if (!dict_value->IsType(base::Value::TYPE_DICTIONARY)) |
+ return nullptr; |
+ |
+ scoped_refptr<OpenFileOperationTranslator> |
+ out(new OpenFileOperationTranslator()); |
+ const base::DictionaryValue* dict = |
+ static_cast<const base::DictionaryValue*>(dict_value); |
+ const base::Value* file_system_id_value = NULL; |
+ if (!dict->GetWithoutPathExpansion("fileSystemId", &file_system_id_value)) |
+ return nullptr; |
+ if (!file_system_id_value->GetAsString(&out->file_system_id)) |
+ return nullptr; |
+ |
+ const base::Value* request_id_value = NULL; |
+ if (!dict->GetWithoutPathExpansion("requestId", &request_id_value)) |
+ return nullptr; |
+ if (!request_id_value->GetAsInteger(&out->request_id)) |
+ return nullptr; |
+ |
+ const base::Value* file_path_value = NULL; |
+ if (!dict->GetWithoutPathExpansion("filePath", &file_path_value)) |
+ return nullptr; |
+ if (!file_path_value->GetAsString(&out->file_path)) |
+ return nullptr; |
+ |
+ const base::Value* mode_value = NULL; |
+ if (!dict->GetWithoutPathExpansion("mode", &mode_value)) |
+ return nullptr; |
+ std::string open_file_mode_as_string; |
+ if (!mode_value->GetAsString(&open_file_mode_as_string)) |
+ return nullptr; |
+ out->mode = ParseOpenFileMode(open_file_mode_as_string); |
+ |
+ return out; |
+} |
+ |
+OpenFileOperationTranslator::OpenFileOperationTranslator(){} |
+ |
+ReadDirectoryOperationTranslator::~ReadDirectoryOperationTranslator(){} |
+ |
+scoped_ptr<PP_FilesystemRequest> |
+ReadDirectoryOperationTranslator::ToFilesystemRequest() { |
+ scoped_ptr<PP_FilesystemRequest> out(new PP_FilesystemRequest); |
+ if(!out.get()) |
+ return nullptr; |
+ out->operation_type = PP_OperationType_READDIRECTORY; |
+ out->request_id = request_id; |
+ out->value.as_read_directory.directory_path = directory_path.c_str(); |
+ return out.Pass(); |
+} |
+ |
+scoped_refptr<ReadDirectoryOperationTranslator> |
+ReadDirectoryOperationTranslator::PopulateFromRequest( |
+ const base::ListValue &request) { |
+ if( request.empty() ) |
+ return nullptr; |
+ |
+ const base::Value *dict_value = nullptr; |
+ if(!request.Get(0,&dict_value)) |
+ return nullptr; |
+ |
+ if (!dict_value->IsType(base::Value::TYPE_DICTIONARY)) |
+ return nullptr; |
+ |
+ scoped_refptr<ReadDirectoryOperationTranslator> |
+ out(new ReadDirectoryOperationTranslator()); |
+ |
+ const base::DictionaryValue* dict = |
+ static_cast<const base::DictionaryValue*>(dict_value); |
+ const base::Value* file_system_id_value = NULL; |
+ if (!dict->GetWithoutPathExpansion("fileSystemId", &file_system_id_value)) |
+ return nullptr; |
+ if (!file_system_id_value->GetAsString(&out->file_system_id)) |
+ return nullptr; |
+ |
+ const base::Value* request_id_value = NULL; |
+ if (!dict->GetWithoutPathExpansion("requestId", &request_id_value)) |
+ return nullptr; |
+ if (!request_id_value->GetAsInteger(&out->request_id)) |
+ return nullptr; |
+ |
+ const base::Value* directory_path_value = NULL; |
+ if (!dict->GetWithoutPathExpansion("directoryPath", &directory_path_value)) |
+ return nullptr; |
+ if (!directory_path_value->GetAsString(&out->directory_path)) |
+ return nullptr; |
+ return out; |
+} |
+ |
+ReadDirectoryOperationTranslator::ReadDirectoryOperationTranslator(){} |
+ |
+ReadFileOperationTranslator::~ReadFileOperationTranslator(){} |
+ |
+scoped_ptr<PP_FilesystemRequest> |
+ReadFileOperationTranslator::ToFilesystemRequest() { |
+ scoped_ptr<PP_FilesystemRequest> out(new PP_FilesystemRequest); |
+ if(!out.get()) |
+ return scoped_ptr<PP_FilesystemRequest>(); |
+ out->operation_type = PP_OperationType_READFILE; |
+ out->request_id = request_id; |
+ out->value.as_read_file.open_request_id = open_request_id; |
+ out->value.as_read_file.offset = offset; |
+ out->value.as_read_file.length = length; |
+ return out.Pass(); |
+} |
+ |
+scoped_refptr<ReadFileOperationTranslator> |
+ReadFileOperationTranslator::PopulateFromRequest( |
+ const base::ListValue &request) { |
+ if( request.empty() ) |
+ return nullptr; |
+ |
+ const base::Value *dict_value = nullptr; |
+ if(!request.Get(0,&dict_value)) |
+ return nullptr; |
+ |
+ if (!dict_value->IsType(base::Value::TYPE_DICTIONARY)) |
+ return nullptr; |
+ scoped_refptr<ReadFileOperationTranslator> |
+ out(new ReadFileOperationTranslator()); |
+ const base::DictionaryValue* dict = |
+ static_cast<const base::DictionaryValue*>(dict_value); |
+ const base::Value* file_system_id_value = NULL; |
+ if (!dict->GetWithoutPathExpansion("fileSystemId", &file_system_id_value)) |
+ return nullptr; |
+ if (!file_system_id_value->GetAsString(&out->file_system_id)) |
+ return nullptr; |
+ |
+ const base::Value* request_id_value = NULL; |
+ if (!dict->GetWithoutPathExpansion("requestId", &request_id_value)) |
+ return nullptr; |
+ if (!request_id_value->GetAsInteger(&out->request_id)) |
+ return nullptr; |
+ |
+ const base::Value* open_request_id_value = NULL; |
+ if (!dict->GetWithoutPathExpansion("openRequestId", &open_request_id_value)) |
+ return nullptr; |
+ if (!open_request_id_value->GetAsInteger(&out->open_request_id)) |
+ return nullptr; |
+ |
+ const base::Value* offset_value = NULL; |
+ if (!dict->GetWithoutPathExpansion("offset", &offset_value)) |
+ return nullptr; |
+ if (!offset_value->GetAsDouble(&out->offset)) |
+ return nullptr; |
+ |
+ const base::Value* length_value = NULL; |
+ if (!dict->GetWithoutPathExpansion("length", &length_value)) |
+ return nullptr; |
+ if (!length_value->GetAsDouble(&out->length)) |
+ return nullptr; |
+ return out; |
+} |
+ |
+ReadFileOperationTranslator::ReadFileOperationTranslator(){} |
+ |
+TruncateOperationTranslator::~TruncateOperationTranslator(){} |
+ |
+scoped_ptr<PP_FilesystemRequest> |
+TruncateOperationTranslator::ToFilesystemRequest() { |
+ scoped_ptr<PP_FilesystemRequest> out(new PP_FilesystemRequest); |
+ if(!out.get()) |
+ return nullptr; |
+ out->operation_type = PP_OperationType_TRUNCATEENTRY; |
+ out->request_id = request_id; |
+ out->value.as_truncate.length = length; |
+ out->value.as_truncate.file_path = file_path.c_str(); |
+ return out.Pass(); |
+} |
+ |
+scoped_refptr<TruncateOperationTranslator> |
+TruncateOperationTranslator::PopulateFromRequest( |
+ const base::ListValue &request) { |
+ if( request.empty() ) |
+ return nullptr; |
+ |
+ const base::Value *dict_value = nullptr; |
+ if(!request.Get(0,&dict_value)) |
+ return nullptr; |
+ |
+ if (!dict_value->IsType(base::Value::TYPE_DICTIONARY)) |
+ return nullptr; |
+ |
+ scoped_refptr<TruncateOperationTranslator> |
+ out(new TruncateOperationTranslator()); |
+ |
+ const base::DictionaryValue* dict = |
+ static_cast<const base::DictionaryValue*>(dict_value); |
+ const base::Value* file_system_id_value = NULL; |
+ if (!dict->GetWithoutPathExpansion("fileSystemId", &file_system_id_value)) |
+ return nullptr; |
+ if (!file_system_id_value->GetAsString(&out->file_system_id)) |
+ return nullptr; |
+ |
+ const base::Value* request_id_value = NULL; |
+ if (!dict->GetWithoutPathExpansion("requestId", &request_id_value)) |
+ return nullptr; |
+ if (!request_id_value->GetAsInteger(&out->request_id)) |
+ return nullptr; |
+ |
+ const base::Value* file_path_value = NULL; |
+ if (!dict->GetWithoutPathExpansion("filePath", &file_path_value)) |
+ return nullptr; |
+ if (!file_path_value->GetAsString(&out->file_path)) |
+ return nullptr; |
+ |
+ const base::Value* length_value = NULL; |
+ if (!dict->GetWithoutPathExpansion("length", &length_value)) |
+ return nullptr; |
+ if (!length_value->GetAsDouble(&out->length)) |
+ return nullptr; |
+ return out; |
+} |
+ |
+TruncateOperationTranslator::TruncateOperationTranslator(){} |
+ |
+UnmountOperationTranslator::~UnmountOperationTranslator(){} |
+ |
+scoped_ptr<PP_FilesystemRequest> |
+UnmountOperationTranslator::ToFilesystemRequest() { |
+ scoped_ptr<PP_FilesystemRequest> out(new PP_FilesystemRequest); |
+ if(!out.get()) |
+ return scoped_ptr<PP_FilesystemRequest>(); |
+ out->operation_type = PP_OperationType_UNMOUNT; |
+ out->request_id = request_id; |
+ return out.Pass(); |
+} |
+ |
+scoped_refptr<UnmountOperationTranslator> |
+UnmountOperationTranslator::PopulateFromRequest( |
+ const base::ListValue &request) { |
+ |
+ if( request.empty() ) |
+ return nullptr; |
+ |
+ const base::Value *dict_value = nullptr; |
+ if(!request.Get(0,&dict_value)) |
+ return nullptr; |
+ |
+ if (!dict_value->IsType(base::Value::TYPE_DICTIONARY)) |
+ return nullptr; |
+ |
+ scoped_refptr<UnmountOperationTranslator> |
+ out(new UnmountOperationTranslator()); |
+ |
+ const base::DictionaryValue* dict = |
+ static_cast<const base::DictionaryValue*>(dict_value); |
+ const base::Value* file_system_id_value = NULL; |
+ if (!dict->GetWithoutPathExpansion("fileSystemId", &file_system_id_value)) |
+ return nullptr; |
+ if (!file_system_id_value->GetAsString(&out->file_system_id)) |
+ return nullptr; |
+ |
+ const base::Value* request_id_value = NULL; |
+ if (!dict->GetWithoutPathExpansion("requestId", &request_id_value)) |
+ return nullptr; |
+ if (!request_id_value->GetAsInteger(&out->request_id)) |
+ return nullptr; |
+ return out; |
+} |
+ |
+UnmountOperationTranslator::UnmountOperationTranslator(){} |
+ |
+WriteFileOperationTranslator::~WriteFileOperationTranslator(){} |
+ |
+scoped_ptr<PP_FilesystemRequest> |
+WriteFileOperationTranslator::ToFilesystemRequest() { |
+ scoped_ptr<PP_FilesystemRequest> out(new PP_FilesystemRequest); |
+ if(!out.get()) |
+ return nullptr; |
+ out->operation_type = PP_OperationType_WRITEFILE; |
+ out->request_id = request_id; |
+ out->value.as_write_file.open_request_id = open_request_id; |
+ out->value.as_write_file.offset = offset; |
+ out->value.as_write_file.data_size = data.size(); |
+ // Pass the address |
+ if(data.size()) |
+ out->value.as_write_file.data = &data[0]; |
+ else // or NULL if the browser sent an empty write request |
+ out->value.as_write_file.data = NULL; |
+ return out.Pass(); |
+} |
+ |
+scoped_refptr<WriteFileOperationTranslator> |
+WriteFileOperationTranslator::PopulateFromRequest( |
+ const base::ListValue &request, |
+ char* memory_address) { |
+ |
+ if( request.empty() ) |
+ return nullptr; |
+ |
+ const base::Value *dict_value = nullptr; |
+ if(!request.Get(0,&dict_value)) |
+ return nullptr; |
+ |
+ if (!dict_value->IsType(base::Value::TYPE_DICTIONARY)) |
+ return nullptr; |
+ |
+ scoped_refptr<WriteFileOperationTranslator> |
+ out(new WriteFileOperationTranslator()); |
+ const base::DictionaryValue* dict = |
+ static_cast<const base::DictionaryValue*>(dict_value); |
+ const base::Value* file_system_id_value = NULL; |
+ if (!dict->GetWithoutPathExpansion("fileSystemId", &file_system_id_value)) |
+ return nullptr; |
+ if (!file_system_id_value->GetAsString(&out->file_system_id)) |
+ return nullptr; |
+ |
+ const base::Value* request_id_value = NULL; |
+ if (!dict->GetWithoutPathExpansion("requestId", &request_id_value)) |
+ return nullptr; |
+ if (!request_id_value->GetAsInteger(&out->request_id)) |
+ return nullptr; |
+ |
+ const base::Value* open_request_id_value = NULL; |
+ if (!dict->GetWithoutPathExpansion("openRequestId", &open_request_id_value)) |
+ return nullptr; |
+ if (!open_request_id_value->GetAsInteger(&out->open_request_id)) |
+ return nullptr; |
+ |
+ const base::Value* offset_value = NULL; |
+ if (!dict->GetWithoutPathExpansion("offset", &offset_value)) |
+ return nullptr; |
+ if (!offset_value->GetAsDouble(&out->offset)) |
+ return nullptr; |
+ |
+ const base::Value* size_value = NULL; |
+ if (!dict->GetWithoutPathExpansion("size", &size_value)) |
+ return nullptr; |
+ if (!size_value->GetAsDouble(&out->size)) |
+ return nullptr; |
+ |
+ // Buffer what will be cached until released by the FS implementation |
+ out->data.assign(memory_address, |
+ memory_address+static_cast<size_t>(out->size)); |
+ return out; |
+} |
+ |
+WriteFileOperationTranslator::WriteFileOperationTranslator(){} |
+ |
+OperationTranslator::~OperationTranslator(){} |
+ |
+scoped_ptr<base::ListValue> |
+PluginToBrowserTranslator::GenerateReadFileSuccessResponse( |
+ uint32_t data_size, bool has_more, int32_t request_id, |
+ int time_span, const std::string& filesystem_id) { |
+ size_t index = 0; |
+ scoped_ptr<base::ListValue> response(new base::ListValue); |
+ if( !response->Set(index++, |
+ new base::FundamentalValue(PP_OperationType_READFILE))|| |
+ !response->Set(index++, new base::FundamentalValue(true))||// status = success |
+ !response->Set(index++, |
+ new base::StringValue(filesystem_id)) || |
+ !response->Set(index++, new base::FundamentalValue(request_id)) || |
+ !response->Set(index++, new base::FundamentalValue( |
+ static_cast<double>(data_size)))|| |
+ !response->Set(index++, new base::FundamentalValue(has_more))|| |
+ !response->Set(index++, new base::FundamentalValue(time_span))) |
+ return scoped_ptr<base::ListValue>(); |
+ return response.Pass(); |
+} |
+ |
+AddWatcherOperationTranslator::~AddWatcherOperationTranslator() {} |
+ |
+scoped_ptr<PP_FilesystemRequest> |
+AddWatcherOperationTranslator::ToFilesystemRequest() { |
+ scoped_ptr<PP_FilesystemRequest> out(new PP_FilesystemRequest); |
+ if(!out.get()) |
+ return scoped_ptr<PP_FilesystemRequest>(); |
+ out->operation_type = PP_OperationType_ADDWATCHER; |
+ out->request_id = request_id; |
+ out->value.as_add_watcher.entry_path = this->entry_path.c_str(); |
+ out->value.as_add_watcher.recursive = PP_FromBool(this->recursive); |
+ return out.Pass(); |
+} |
+ |
+scoped_refptr<AddWatcherOperationTranslator> |
+AddWatcherOperationTranslator::PopulateFromRequest( |
+ const base::ListValue& request) { |
+ if( request.empty() ) |
+ return nullptr; |
+ |
+ const base::Value *dict_value = nullptr; |
+ if(!request.Get(0,&dict_value)) |
+ return nullptr; |
+ |
+ if (!dict_value->IsType(base::Value::TYPE_DICTIONARY)) |
+ return nullptr; |
+ |
+ scoped_refptr<AddWatcherOperationTranslator> |
+ out(new AddWatcherOperationTranslator()); |
+ |
+ const base::DictionaryValue* dict = |
+ static_cast<const base::DictionaryValue*>(dict_value); |
+ const base::Value* file_system_id_value = NULL; |
+ if (!dict->GetWithoutPathExpansion("fileSystemId", &file_system_id_value)) |
+ return nullptr; |
+ if (!file_system_id_value->GetAsString(&out->file_system_id)) |
+ return nullptr; |
+ const base::Value* request_id_value = NULL; |
+ if (!dict->GetWithoutPathExpansion("requestId", &request_id_value)) |
+ return nullptr; |
+ if (!request_id_value->GetAsInteger(&out->request_id)) |
+ return nullptr; |
+ const base::Value* entry_path_value = NULL; |
+ if (!dict->GetWithoutPathExpansion("entryPath", &entry_path_value)) |
+ return nullptr; |
+ if (!entry_path_value->GetAsString(&out->entry_path)) |
+ return nullptr; |
+ const base::Value* recursive_value = NULL; |
+ if (!dict->GetWithoutPathExpansion("recursive",&recursive_value)) |
+ return nullptr; |
+ if (!recursive_value->GetAsBoolean(&out->recursive)) |
+ return nullptr; |
+ |
+ return out; |
+} |
+ |
+AddWatcherOperationTranslator::AddWatcherOperationTranslator() {} |
+ |
+RemoveWatcherOperationTranslator::~RemoveWatcherOperationTranslator() { |
+ |
+} |
+ |
+scoped_ptr<PP_FilesystemRequest> |
+RemoveWatcherOperationTranslator::ToFilesystemRequest() { |
+ scoped_ptr<PP_FilesystemRequest> out(new PP_FilesystemRequest); |
+ if(!out.get()) |
+ return scoped_ptr<PP_FilesystemRequest>(); |
+ out->operation_type = PP_OperationType_REMOVEWATCHER; |
+ out->request_id = request_id; |
+ out->value.as_add_watcher.entry_path = this->entry_path.c_str(); |
+ out->value.as_add_watcher.recursive = PP_FromBool(this->recursive); |
+ return out.Pass(); |
+} |
+ |
+scoped_refptr<RemoveWatcherOperationTranslator> |
+RemoveWatcherOperationTranslator::PopulateFromRequest( |
+ const base::ListValue& request){ |
+ if( request.empty() ) |
+ return nullptr; |
+ |
+ const base::Value *dict_value = nullptr; |
+ if(!request.Get(0,&dict_value)) |
+ return nullptr; |
+ |
+ if (!dict_value->IsType(base::Value::TYPE_DICTIONARY)) |
+ return nullptr; |
+ |
+ scoped_refptr<RemoveWatcherOperationTranslator> |
+ out(new RemoveWatcherOperationTranslator()); |
+ |
+ const base::DictionaryValue* dict = |
+ static_cast<const base::DictionaryValue*>(dict_value); |
+ const base::Value* file_system_id_value = NULL; |
+ if (!dict->GetWithoutPathExpansion("fileSystemId", &file_system_id_value)) |
+ return nullptr; |
+ if (!file_system_id_value->GetAsString(&out->file_system_id)) |
+ return nullptr; |
+ const base::Value* request_id_value = NULL; |
+ if (!dict->GetWithoutPathExpansion("requestId", &request_id_value)) |
+ return nullptr; |
+ if (!request_id_value->GetAsInteger(&out->request_id)) |
+ return nullptr; |
+ const base::Value* entry_path_value = NULL; |
+ if (!dict->GetWithoutPathExpansion("entryPath", &entry_path_value)) |
+ return nullptr; |
+ if (!entry_path_value->GetAsString(&out->entry_path)) |
+ return nullptr; |
+ const base::Value* recursive_value = NULL; |
+ if (!dict->GetWithoutPathExpansion("recursive",&recursive_value)) |
+ return nullptr; |
+ if (!recursive_value->GetAsBoolean(&out->recursive)) |
+ return nullptr; |
+ |
+ return out; |
+} |
+ |
+RemoveWatcherOperationTranslator::RemoveWatcherOperationTranslator() {} |
+ |
+scoped_ptr<base::ListValue> |
+PluginToBrowserTranslator::GenerateMountMessage( |
+ std::string filesystem_id, std::string display_name, |
+ bool writable, int32_t opened_files_limit) { |
+ |
+ scoped_ptr<base::DictionaryValue> payload(new base::DictionaryValue); |
+ if(!payload.get()) |
+ return scoped_ptr<base::ListValue>(); |
+ payload->Set("fileSystemId", |
+ new base::StringValue(filesystem_id)); |
+ payload->Set("displayName", |
+ new base::StringValue(display_name)); |
+ payload->Set("writable", |
+ new base::FundamentalValue(writable)); |
+ payload->Set("openedFilesLimit", |
+ new base::FundamentalValue(opened_files_limit)); |
+ scoped_ptr<base::ListValue> response(new base::ListValue); |
+ if(!response.get()) |
+ return scoped_ptr<base::ListValue>(); |
+ response->Set(0,payload.release()); |
+ return response.Pass(); |
+} |
+ |
+scoped_ptr<base::ListValue> PluginToBrowserTranslator::GenerateNotifyMessage( |
+ PP_Var notification_options) { |
+ scoped_ptr<base::DictionaryValue> notification(new base::DictionaryValue); |
+ |
+ DictionaryVar* dict_var = DictionaryVar::FromPPVar(notification_options); |
+ if(!dict_var) |
+ return nullptr; |
+ for (DictionaryVar::KeyValueMap::const_iterator iter = |
+ dict_var->key_value_map().begin(); |
+ iter != dict_var->key_value_map().end(); |
+ ++iter) { |
+ const std::string& key = iter->first; |
+ const PP_Var& child_var = iter->second.get(); |
+ switch(child_var.type) { |
+ case PP_VARTYPE_STRING: { |
+ StringVar* string = StringVar::FromPPVar(child_var); |
+ if(!string) |
+ return nullptr; |
+ const std::string& value = string->value(); |
+ |
+ if (key=="fileSystemId") { |
+ notification->SetString(key,value); |
+ } else if (key== "observedPath") { |
+ notification->SetString(key,value); |
+ } else if(key=="tag") { |
+ notification->SetString(key,value); |
+ } else return nullptr; |
+ break; |
+ } |
+ case PP_VARTYPE_BOOL: { |
+ if(key!="recursive") |
+ return nullptr; |
+ notification->SetBoolean("recursive", child_var.value.as_bool); |
+ break; |
+ } |
+ case PP_VARTYPE_INT32: { |
+ if (key!="changeType") |
+ return nullptr; |
+ if (child_var.value.as_int!=PP_ChangeType_CHANGED && |
+ child_var.value.as_int!=PP_ChangeType_DELETED) |
+ return nullptr; |
+ notification->SetString( "changeType", |
+ child_var.value.as_int!=PP_ChangeType_CHANGED ? |
+ "DELETED" : "CHANGED" ); |
+ break; |
+ } |
+ case PP_VARTYPE_ARRAY: { |
+ if (key!="changes") |
+ return nullptr; |
+ scoped_ptr<base::ListValue> changes(new base::ListValue); |
+ if (!changes) |
+ return nullptr; |
+ ArrayVar* array_var = ArrayVar::FromPPVar(child_var); |
+ if(!array_var) |
+ return nullptr; |
+ for( size_t i = 0; i < array_var->elements().size(); ++i ) { |
+ const PP_Var& c_child_var = array_var->elements()[i].get(); |
+ if( c_child_var.type != PP_VARTYPE_DICTIONARY ) |
+ return nullptr; |
+ DictionaryVar* c = DictionaryVar::FromPPVar(c_child_var); |
+ if (!c) |
+ return nullptr; |
+ scoped_ptr<base::DictionaryValue> change(new base::DictionaryValue); |
+ if (!change) |
+ return nullptr; |
+ for (DictionaryVar::KeyValueMap::const_iterator c_iter = |
+ c->key_value_map().begin(); |
+ c_iter != c->key_value_map().end(); |
+ ++c_iter) { |
+ const std::string& c_key = c_iter->first; |
+ const PP_Var& c_child_var = c_iter->second.get(); |
+ switch(c_child_var.type) { |
+ case PP_VARTYPE_STRING:{ |
+ StringVar* string = StringVar::FromPPVar(c_child_var); |
+ if(!string) |
+ return nullptr; |
+ const std::string& c_value = string->value(); |
+ if (c_key=="entryPath") |
+ change->SetString(c_key, c_value); |
+ else |
+ return nullptr; |
+ break; |
+ } |
+ case PP_VARTYPE_INT32: { |
+ if (c_key=="changeType") |
+ change->SetString( |
+ c_key, |
+ c_child_var.value.as_int!=PP_ChangeType_CHANGED ? |
+ "DELETED" : "CHANGED"); |
+ else |
+ return nullptr; |
+ break; |
+ } |
+ default: |
+ return nullptr; |
+ } |
+ } |
+ changes->Append(change.release()); |
+ } |
+ notification->Set(key,changes.release()); |
+ break; |
+ } |
+ default: |
+ return nullptr; |
+ } |
+ } |
+ |
+ scoped_ptr<base::ListValue> message(new base::ListValue); |
+ if (!message.get()) |
+ return nullptr; |
+ |
+ message->Append(notification.release()); |
+ return message.Pass(); |
+} |
+ |
+scoped_ptr<base::ListValue> |
+PluginToBrowserTranslator::GenerateSuccessResponse( |
+ PP_OperationType_Dev operation_type, |
+ const std::string &filesystem_id, |
+ int32_t request_id, int time_span) { |
+ |
+ scoped_ptr<base::ListValue> response(new base::ListValue); |
+ if(!response.get()) |
+ return scoped_ptr<base::ListValue>(); |
+ size_t index = 0; |
+ if ( !response->Set(index++, new base::FundamentalValue(operation_type))|| |
+ !response->Set(index++, |
+ new base::FundamentalValue(true)) || // status = success |
+ !response->Set(index++, |
+ new base::StringValue(filesystem_id))|| |
+ !response->Set(index++, new base::FundamentalValue(request_id)) || |
+ !response->Set(index++, new base::FundamentalValue(time_span))) { |
+ return scoped_ptr<base::ListValue>(); |
+ } |
+ return response.Pass(); |
+} |
+ |
+scoped_ptr<base::ListValue> PluginToBrowserTranslator::GenerateFailureResponse( |
+ PP_OperationType_Dev operation_type, int32_t error, |
+ const std::string &filesystem_id, int32_t request_id, int time_span) { |
+ scoped_ptr<base::ListValue> response(new base::ListValue); |
+ if(!response.get()) |
+ return scoped_ptr<base::ListValue>(); |
+ size_t index=0; |
+ if ( !response->Set(index++, new base::FundamentalValue(operation_type)) || |
+ !response->Set(index++, |
+ new base::FundamentalValue(false)) || // status = failure |
+ !response->Set(index++, |
+ new base::StringValue(filesystem_id)) || |
+ !response->Set(index++, new base::FundamentalValue(request_id)) || |
+ !response->Set(index++, |
+ new base::StringValue(PP_ErrorToString(error))) || |
+ !response->Set(index++, new base::FundamentalValue(time_span) ) ) |
+ return scoped_ptr<base::ListValue>(); |
+ return response.Pass(); |
+} |
+ |
+scoped_ptr<base::ListValue> PluginToBrowserTranslator::GenerateMetadataResponse( |
+ PP_Var metadata, int32_t request_id, |
+ const std::string &filesystem_id, int time_span) { |
+ |
+ scoped_ptr<base::DictionaryValue> entry_metadata= |
+ GenerateMetadataListFromPPVar( metadata ); |
+ if(!entry_metadata.get()) |
+ return nullptr; |
+ scoped_ptr<base::ListValue> response(new base::ListValue); |
+ size_t index = 0; |
+ if (!response->Set(index++, |
+ new base::FundamentalValue(PP_OperationType_GETMETADATA))|| |
+ !response->Set(index++, new base::FundamentalValue(true))|| //status = success |
+ !response->Set(index++, |
+ new base::StringValue(filesystem_id) ) || |
+ !response->Set(index++, new base::FundamentalValue(request_id) ) || |
+ !response->Set(index++, entry_metadata.release() ) || |
+ !response->Set(index++, new base::FundamentalValue(time_span) ) ) |
+ return nullptr; |
+ return response.Pass(); |
+} |
+ |
+scoped_ptr<base::ListValue> |
+PluginToBrowserTranslator::GenerateReadDirectoryResponse( |
+ PP_Var entries, |
+ PP_Bool has_more, int32_t request_id, |
+ const std::string &filesystem_id, int time_span) { |
+ |
+ scoped_ptr<base::ListValue> response(new base::ListValue); |
+ scoped_ptr<base::ListValue> list_value(new base::ListValue); |
+ if(!list_value.get()|| |
+ !response.get()) |
+ return nullptr; |
+ |
+ ArrayVar* array_var = ArrayVar::FromPPVar(entries); |
+ if(!array_var) |
+ return nullptr; |
+ |
+ scoped_ptr<base::DictionaryValue> entry_metadata; |
+ for( size_t i = 0; i < array_var->elements().size(); ++i ) { |
+ const PP_Var& child_var = array_var->elements()[i].get(); |
+ if( child_var.type != PP_VARTYPE_DICTIONARY ) |
+ return nullptr; |
+ entry_metadata = GenerateMetadataListFromPPVar(child_var); |
+ if(!entry_metadata.get()) |
+ return nullptr; |
+ list_value->Set(i,entry_metadata.release()); |
+ } |
+ |
+ size_t index = 0; |
+ if (!response->Set(index++, |
+ new base::FundamentalValue(PP_OperationType_READDIRECTORY))|| |
+ !response->Set(index++, |
+ new base::FundamentalValue(true))|| // status = success |
+ !response->Set(index++, |
+ new base::StringValue(filesystem_id) ) || |
+ !response->Set(index++, new base::FundamentalValue(request_id) ) || |
+ !response->Set(index++, list_value.release() ) || |
+ !response->Set(index++, |
+ new base::FundamentalValue( PP_ToBool( has_more ) ) ) || |
+ !response->Set(index++, new base::FundamentalValue( time_span ) ) ) |
+ return scoped_ptr<base::ListValue>(); |
+ return response.Pass(); |
+} |
+ |
+scoped_ptr<base::DictionaryValue> |
+PluginToBrowserTranslator::GenerateMetadataListFromPPVar(PP_Var metadata) { |
+ scoped_ptr<base::DictionaryValue> entry_metadata(new base::DictionaryValue); |
+ if(!entry_metadata.get()) |
+ return nullptr; |
+ |
+ DictionaryVar* dict_var = DictionaryVar::FromPPVar(metadata); |
+ if(!dict_var) |
+ return nullptr; |
+ for (DictionaryVar::KeyValueMap::const_iterator iter = |
+ dict_var->key_value_map().begin(); |
+ iter != dict_var->key_value_map().end(); |
+ ++iter) { |
+ const std::string& key = iter->first; |
+ const PP_Var& child_var = iter->second.get(); |
+ switch(child_var.type) { |
+ case PP_VARTYPE_STRING:{ |
+ StringVar* string = StringVar::FromPPVar(child_var); |
+ if(!string) |
+ return nullptr; |
+ const std::string& value = string->value(); |
+ |
+ if (key=="modificationTime") { |
+ scoped_ptr<base::DictionaryValue> |
+ modification_time(new base::DictionaryValue()); |
+ if(!modification_time.get()) |
+ return nullptr; |
+ modification_time->SetStringWithoutPathExpansion( |
+ "value", value); |
+ entry_metadata->Set(key, modification_time.release()); |
+ } else if (key=="name"||key=="mimeType"||key=="thumbnail") { |
+ entry_metadata->SetString(key,value); |
+ } else { |
+ return nullptr; |
+ } |
+ break; |
+ } |
+ case PP_VARTYPE_BOOL: { |
+ if(key!="isDirectory") |
+ return nullptr; |
+ entry_metadata->SetBoolean("isDirectory", child_var.value.as_bool); |
+ break; |
+ } |
+ case PP_VARTYPE_DOUBLE: { |
+ if (key!="size") |
+ return nullptr; |
+ entry_metadata->SetDouble("size", child_var.value.as_double ); |
+ break; |
+ } |
+ default: |
+ return nullptr; |
+ } |
+ } |
+ return entry_metadata.Pass(); |
+} |
+ |
+ |
+ |
+} // namespace |
+} // namespace proxy |
+} // namespace ppapi |