Home | History | Annotate | Download | only in pepper
      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