1 // Copyright 2013 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "content/renderer/pepper/resource_converter.h" 6 7 #include "base/bind.h" 8 #include "base/message_loop/message_loop.h" 9 #include "content/public/renderer/renderer_ppapi_host.h" 10 #include "content/renderer/pepper/pepper_file_system_host.h" 11 #include "ipc/ipc_message.h" 12 #include "ppapi/host/ppapi_host.h" 13 #include "ppapi/host/resource_host.h" 14 #include "ppapi/proxy/ppapi_messages.h" 15 #include "ppapi/shared_impl/resource_var.h" 16 #include "ppapi/shared_impl/scoped_pp_var.h" 17 #include "third_party/WebKit/public/platform/WebFileSystem.h" 18 #include "third_party/WebKit/public/web/WebDOMFileSystem.h" 19 20 namespace { 21 22 void FlushComplete( 23 const base::Callback<void(bool)>& callback, 24 const std::vector<scoped_refptr<content::HostResourceVar> >& browser_vars, 25 const std::vector<int>& pending_host_ids) { 26 CHECK(browser_vars.size() == pending_host_ids.size()); 27 for (size_t i = 0; i < browser_vars.size(); ++i) { 28 browser_vars[i]->set_pending_browser_host_id(pending_host_ids[i]); 29 } 30 callback.Run(true); 31 } 32 33 // Converts a blink::WebFileSystem::Type to a PP_FileSystemType. 34 PP_FileSystemType WebFileSystemTypeToPPAPI(blink::WebFileSystem::Type type) { 35 switch (type) { 36 case blink::WebFileSystem::TypeTemporary: 37 return PP_FILESYSTEMTYPE_LOCALTEMPORARY; 38 case blink::WebFileSystem::TypePersistent: 39 return PP_FILESYSTEMTYPE_LOCALPERSISTENT; 40 case blink::WebFileSystem::TypeIsolated: 41 return PP_FILESYSTEMTYPE_ISOLATED; 42 case blink::WebFileSystem::TypeExternal: 43 return PP_FILESYSTEMTYPE_EXTERNAL; 44 default: 45 NOTREACHED(); 46 return PP_FILESYSTEMTYPE_LOCALTEMPORARY; 47 } 48 } 49 50 // Given a V8 value containing a DOMFileSystem, creates a resource host and 51 // returns the resource information for serialization. 52 // On error, false. 53 bool DOMFileSystemToResource( 54 PP_Instance instance, 55 content::RendererPpapiHost* host, 56 const blink::WebDOMFileSystem& dom_file_system, 57 int* pending_renderer_id, 58 scoped_ptr<IPC::Message>* create_message, 59 scoped_ptr<IPC::Message>* browser_host_create_message) { 60 DCHECK(!dom_file_system.isNull()); 61 62 PP_FileSystemType file_system_type = 63 WebFileSystemTypeToPPAPI(dom_file_system.type()); 64 GURL root_url = dom_file_system.rootURL(); 65 66 // External file systems are not currently supported. (Without this check, 67 // there would be a CHECK-fail in FileRefResource.) 68 // TODO(mgiuca): Support external file systems. 69 if (file_system_type == PP_FILESYSTEMTYPE_EXTERNAL) 70 return false; 71 72 *pending_renderer_id = host->GetPpapiHost()->AddPendingResourceHost( 73 scoped_ptr<ppapi::host::ResourceHost>( 74 new content::PepperFileSystemHost(host, instance, 0, root_url, 75 file_system_type))); 76 if (*pending_renderer_id == 0) 77 return false; 78 79 create_message->reset( 80 new PpapiPluginMsg_FileSystem_CreateFromPendingHost(file_system_type)); 81 82 browser_host_create_message->reset( 83 new PpapiHostMsg_FileSystem_CreateFromRenderer(root_url.spec(), 84 file_system_type)); 85 return true; 86 } 87 88 } // namespace 89 90 namespace content { 91 92 ResourceConverter::~ResourceConverter() {} 93 94 ResourceConverterImpl::ResourceConverterImpl(PP_Instance instance, 95 RendererPpapiHost* host) 96 : instance_(instance), 97 host_(host) { 98 } 99 100 ResourceConverterImpl::~ResourceConverterImpl() { 101 // Verify Flush() was called. 102 DCHECK(browser_host_create_messages_.empty()); 103 DCHECK(browser_vars.empty()); 104 } 105 106 bool ResourceConverterImpl::FromV8Value(v8::Handle<v8::Object> val, 107 v8::Handle<v8::Context> context, 108 PP_Var* result, 109 bool* was_resource) { 110 v8::Context::Scope context_scope(context); 111 v8::HandleScope handle_scope(context->GetIsolate()); 112 113 *was_resource = false; 114 115 blink::WebDOMFileSystem dom_file_system = 116 blink::WebDOMFileSystem::fromV8Value(val); 117 if (!dom_file_system.isNull()) { 118 int pending_renderer_id; 119 scoped_ptr<IPC::Message> create_message; 120 scoped_ptr<IPC::Message> browser_host_create_message; 121 if (!DOMFileSystemToResource(instance_, host_, dom_file_system, 122 &pending_renderer_id, &create_message, 123 &browser_host_create_message)) { 124 return false; 125 } 126 DCHECK(create_message); 127 DCHECK(browser_host_create_message); 128 scoped_refptr<HostResourceVar> result_var = 129 CreateResourceVarWithBrowserHost( 130 pending_renderer_id, *create_message, *browser_host_create_message); 131 *result = result_var->GetPPVar(); 132 *was_resource = true; 133 return true; 134 } 135 136 // The value was not convertible to a resource. Return true with 137 // |was_resource| set to false. As per the interface of FromV8Value, |result| 138 // may be left unmodified in this case. 139 return true; 140 } 141 142 void ResourceConverterImpl::Flush(const base::Callback<void(bool)>& callback) { 143 host_->CreateBrowserResourceHosts( 144 instance_, 145 browser_host_create_messages_, 146 base::Bind(&FlushComplete, callback, browser_vars)); 147 browser_host_create_messages_.clear(); 148 browser_vars.clear(); 149 } 150 151 scoped_refptr<HostResourceVar> ResourceConverterImpl::CreateResourceVar( 152 int pending_renderer_id, 153 const IPC::Message& create_message) { 154 return new HostResourceVar(pending_renderer_id, create_message); 155 } 156 157 scoped_refptr<HostResourceVar> 158 ResourceConverterImpl::CreateResourceVarWithBrowserHost( 159 int pending_renderer_id, 160 const IPC::Message& create_message, 161 const IPC::Message& browser_host_create_message) { 162 scoped_refptr<HostResourceVar> result = 163 CreateResourceVar(pending_renderer_id, create_message); 164 browser_host_create_messages_.push_back(browser_host_create_message); 165 browser_vars.push_back(result); 166 return result; 167 } 168 169 } // namespace content 170