Home | History | Annotate | Download | only in pepper
      1 // Copyright (c) 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/pepper_file_system_host.h"
      6 
      7 #include "base/bind.h"
      8 #include "base/callback.h"
      9 #include "content/child/child_thread.h"
     10 #include "content/child/fileapi/file_system_dispatcher.h"
     11 #include "content/common/pepper_file_util.h"
     12 #include "content/renderer/pepper/pepper_plugin_instance_impl.h"
     13 #include "content/public/renderer/render_view.h"
     14 #include "content/public/renderer/renderer_ppapi_host.h"
     15 #include "ppapi/c/pp_errors.h"
     16 #include "ppapi/host/dispatch_host_message.h"
     17 #include "ppapi/host/ppapi_host.h"
     18 #include "ppapi/proxy/ppapi_messages.h"
     19 #include "ppapi/shared_impl/file_system_util.h"
     20 #include "ppapi/shared_impl/file_type_conversion.h"
     21 #include "storage/common/fileapi/file_system_util.h"
     22 #include "third_party/WebKit/public/web/WebDocument.h"
     23 #include "third_party/WebKit/public/web/WebFrame.h"
     24 #include "third_party/WebKit/public/web/WebView.h"
     25 
     26 namespace content {
     27 
     28 PepperFileSystemHost::PepperFileSystemHost(RendererPpapiHost* host,
     29                                            PP_Instance instance,
     30                                            PP_Resource resource,
     31                                            PP_FileSystemType type)
     32     : ResourceHost(host->GetPpapiHost(), instance, resource),
     33       renderer_ppapi_host_(host),
     34       type_(type),
     35       opened_(false),
     36       called_open_(false),
     37       weak_factory_(this) {}
     38 
     39 PepperFileSystemHost::PepperFileSystemHost(RendererPpapiHost* host,
     40                                            PP_Instance instance,
     41                                            PP_Resource resource,
     42                                            const GURL& root_url,
     43                                            PP_FileSystemType type)
     44     : ResourceHost(host->GetPpapiHost(), instance, resource),
     45       renderer_ppapi_host_(host),
     46       type_(type),
     47       opened_(true),
     48       root_url_(root_url),
     49       called_open_(true),
     50       weak_factory_(this) {}
     51 
     52 PepperFileSystemHost::~PepperFileSystemHost() {}
     53 
     54 int32_t PepperFileSystemHost::OnResourceMessageReceived(
     55     const IPC::Message& msg,
     56     ppapi::host::HostMessageContext* context) {
     57   PPAPI_BEGIN_MESSAGE_MAP(PepperFileSystemHost, msg)
     58     PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_FileSystem_Open,
     59                                       OnHostMsgOpen)
     60     PPAPI_DISPATCH_HOST_RESOURCE_CALL(
     61         PpapiHostMsg_FileSystem_InitIsolatedFileSystem,
     62         OnHostMsgInitIsolatedFileSystem)
     63   PPAPI_END_MESSAGE_MAP()
     64   return PP_ERROR_FAILED;
     65 }
     66 
     67 bool PepperFileSystemHost::IsFileSystemHost() { return true; }
     68 
     69 void PepperFileSystemHost::DidOpenFileSystem(
     70     const std::string& /* name_unused */,
     71     const GURL& root) {
     72   opened_ = true;
     73   root_url_ = root;
     74   reply_context_.params.set_result(PP_OK);
     75   host()->SendReply(reply_context_, PpapiPluginMsg_FileSystem_OpenReply());
     76   reply_context_ = ppapi::host::ReplyMessageContext();
     77 }
     78 
     79 void PepperFileSystemHost::DidFailOpenFileSystem(base::File::Error error) {
     80   int32 pp_error = ppapi::FileErrorToPepperError(error);
     81   opened_ = (pp_error == PP_OK);
     82   reply_context_.params.set_result(pp_error);
     83   host()->SendReply(reply_context_, PpapiPluginMsg_FileSystem_OpenReply());
     84   reply_context_ = ppapi::host::ReplyMessageContext();
     85 }
     86 
     87 int32_t PepperFileSystemHost::OnHostMsgOpen(
     88     ppapi::host::HostMessageContext* context,
     89     int64_t expected_size) {
     90   // Not allow multiple opens.
     91   if (called_open_)
     92     return PP_ERROR_INPROGRESS;
     93   called_open_ = true;
     94 
     95   storage::FileSystemType file_system_type =
     96       PepperFileSystemTypeToFileSystemType(type_);
     97   if (file_system_type == storage::kFileSystemTypeUnknown)
     98     return PP_ERROR_FAILED;
     99 
    100   GURL document_url = renderer_ppapi_host_->GetDocumentURL(pp_instance());
    101   if (!document_url.is_valid())
    102     return PP_ERROR_FAILED;
    103 
    104   FileSystemDispatcher* file_system_dispatcher =
    105       ChildThread::current()->file_system_dispatcher();
    106   reply_context_ = context->MakeReplyMessageContext();
    107   file_system_dispatcher->OpenFileSystem(
    108       document_url.GetOrigin(),
    109       file_system_type,
    110       base::Bind(&PepperFileSystemHost::DidOpenFileSystem,
    111                  weak_factory_.GetWeakPtr()),
    112       base::Bind(&PepperFileSystemHost::DidFailOpenFileSystem,
    113                  weak_factory_.GetWeakPtr()));
    114   return PP_OK_COMPLETIONPENDING;
    115 }
    116 
    117 int32_t PepperFileSystemHost::OnHostMsgInitIsolatedFileSystem(
    118     ppapi::host::HostMessageContext* context,
    119     const std::string& fsid,
    120     PP_IsolatedFileSystemType_Private type) {
    121   // Do not allow multiple opens.
    122   if (called_open_)
    123     return PP_ERROR_INPROGRESS;
    124   called_open_ = true;
    125 
    126   // Do a sanity check.
    127   if (!storage::ValidateIsolatedFileSystemId(fsid))
    128     return PP_ERROR_BADARGUMENT;
    129 
    130   RenderView* view =
    131       renderer_ppapi_host_->GetRenderViewForInstance(pp_instance());
    132   if (!view)
    133     return PP_ERROR_FAILED;
    134 
    135   const GURL& url = view->GetWebView()->mainFrame()->document().url();
    136   const std::string root_name = ppapi::IsolatedFileSystemTypeToRootName(type);
    137   if (root_name.empty())
    138     return PP_ERROR_BADARGUMENT;
    139   root_url_ = GURL(storage::GetIsolatedFileSystemRootURIString(
    140       url.GetOrigin(), fsid, root_name));
    141   opened_ = true;
    142   return PP_OK;
    143 }
    144 
    145 }  // namespace content
    146