1c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved. 2c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// found in the LICENSE file. 4c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 5c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "content/renderer/pepper/pepper_file_system_host.h" 6c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 7c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/bind.h" 8c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/callback.h" 9868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "content/child/child_thread.h" 10868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "content/child/fileapi/file_system_dispatcher.h" 1158e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch#include "content/renderer/pepper/pepper_plugin_instance_impl.h" 12b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#include "content/public/renderer/render_view.h" 13c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "content/public/renderer/renderer_ppapi_host.h" 14c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "ppapi/c/pp_errors.h" 15c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "ppapi/host/dispatch_host_message.h" 16c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "ppapi/host/ppapi_host.h" 17c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "ppapi/proxy/ppapi_messages.h" 18c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "ppapi/shared_impl/file_type_conversion.h" 197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "third_party/WebKit/public/web/WebDocument.h" 207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "third_party/WebKit/public/web/WebElement.h" 217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "third_party/WebKit/public/web/WebFrame.h" 227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "third_party/WebKit/public/web/WebPluginContainer.h" 237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "third_party/WebKit/public/web/WebView.h" 2490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "webkit/common/fileapi/file_system_util.h" 25c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 26c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace content { 27c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 28c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace { 29c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 30b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)bool LooksLikeAGuid(const std::string& fsid) { 31b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) const size_t kExpectedFsIdSize = 32; 32b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (fsid.size() != kExpectedFsIdSize) 33b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return false; 34b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) for (std::string::const_iterator it = fsid.begin(); it != fsid.end(); ++it) { 35b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (('A' <= *it && *it <= 'F') || 36b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) ('0' <= *it && *it <= '9')) 37b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) continue; 38b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return false; 39b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) } 40b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return true; 41b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)} 42b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 43c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} // namespace 44c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 45c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)PepperFileSystemHost::PepperFileSystemHost(RendererPpapiHost* host, 46c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) PP_Instance instance, 47c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) PP_Resource resource, 48c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) PP_FileSystemType type) 49c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) : ResourceHost(host->GetPpapiHost(), instance, resource), 50c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) renderer_ppapi_host_(host), 51c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) weak_factory_(this), 52c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) type_(type), 53c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) opened_(false), 54c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) called_open_(false) { 55c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 56c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 57c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)PepperFileSystemHost::~PepperFileSystemHost() { 58c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 59c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 60c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)int32_t PepperFileSystemHost::OnResourceMessageReceived( 61c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const IPC::Message& msg, 62c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ppapi::host::HostMessageContext* context) { 63c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) IPC_BEGIN_MESSAGE_MAP(PepperFileSystemHost, msg) 64b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) PPAPI_DISPATCH_HOST_RESOURCE_CALL( 65b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) PpapiHostMsg_FileSystem_Open, 66b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) OnHostMsgOpen) 67b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) PPAPI_DISPATCH_HOST_RESOURCE_CALL( 68b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) PpapiHostMsg_FileSystem_InitIsolatedFileSystem, 69b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) OnHostMsgInitIsolatedFileSystem) 70c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) IPC_END_MESSAGE_MAP() 71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return PP_ERROR_FAILED; 72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 73c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 74a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)bool PepperFileSystemHost::IsFileSystemHost() { 75a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return true; 76868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 77868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 7890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void PepperFileSystemHost::DidOpenFileSystem( 7990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const std::string& /* name_unused */, 8090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const GURL& root) { 8190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) opened_ = true; 82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) root_url_ = root; 8390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) reply_context_.params.set_result(PP_OK); 8490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) host()->SendReply(reply_context_, PpapiPluginMsg_FileSystem_OpenReply()); 8590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) reply_context_ = ppapi::host::ReplyMessageContext(); 8690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 8790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 8890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void PepperFileSystemHost::DidFailOpenFileSystem( 8990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::PlatformFileError error) { 9090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) int32 pp_error = ppapi::PlatformFileErrorToPepperError(error); 9190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) opened_ = (pp_error == PP_OK); 92c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) reply_context_.params.set_result(pp_error); 9390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) host()->SendReply(reply_context_, PpapiPluginMsg_FileSystem_OpenReply()); 94c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) reply_context_ = ppapi::host::ReplyMessageContext(); 95c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 96c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 97c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)int32_t PepperFileSystemHost::OnHostMsgOpen( 98c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ppapi::host::HostMessageContext* context, 99c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int64_t expected_size) { 100c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Not allow multiple opens. 101c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (called_open_) 102c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return PP_ERROR_INPROGRESS; 103c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) called_open_ = true; 104c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 105c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) fileapi::FileSystemType file_system_type; 106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) switch (type_) { 107c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case PP_FILESYSTEMTYPE_LOCALTEMPORARY: 108c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) file_system_type = fileapi::kFileSystemTypeTemporary; 109c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) break; 110c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case PP_FILESYSTEMTYPE_LOCALPERSISTENT: 111c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) file_system_type = fileapi::kFileSystemTypePersistent; 112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) break; 113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case PP_FILESYSTEMTYPE_EXTERNAL: 114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) file_system_type = fileapi::kFileSystemTypeExternal; 115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) break; 116c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) default: 117c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return PP_ERROR_FAILED; 118c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 12058e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch PepperPluginInstance* plugin_instance = 121c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) renderer_ppapi_host_->GetPluginInstance(pp_instance()); 122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!plugin_instance) 123c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return PP_ERROR_FAILED; 124c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 125c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FileSystemDispatcher* file_system_dispatcher = 126c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ChildThread::current()->file_system_dispatcher(); 127c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) reply_context_ = context->MakeReplyMessageContext(); 128eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch file_system_dispatcher->OpenFileSystem( 129bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch GURL(plugin_instance->GetContainer()->element().document().url()). 130c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GetOrigin(), 131c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) file_system_type, expected_size, true /* create */, 13290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::Bind(&PepperFileSystemHost::DidOpenFileSystem, 13390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) weak_factory_.GetWeakPtr()), 13490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::Bind(&PepperFileSystemHost::DidFailOpenFileSystem, 135eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch weak_factory_.GetWeakPtr())); 136c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return PP_OK_COMPLETIONPENDING; 137c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 138c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 139b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)int32_t PepperFileSystemHost::OnHostMsgInitIsolatedFileSystem( 140b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) ppapi::host::HostMessageContext* context, 141b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) const std::string& fsid) { 1427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) called_open_ = true; 143b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) // Do a sanity check. 144b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (!LooksLikeAGuid(fsid)) 145b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return PP_ERROR_BADARGUMENT; 146b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) RenderView* view = 147b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) renderer_ppapi_host_->GetRenderViewForInstance(pp_instance()); 148b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (!view) 149b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return PP_ERROR_FAILED; 150b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) const GURL& url = view->GetWebView()->mainFrame()->document().url(); 151b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) root_url_ = GURL(fileapi::GetIsolatedFileSystemRootURIString( 152b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) url.GetOrigin(), fsid, "crxfs")); 153b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) opened_ = true; 154b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return PP_OK; 155b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)} 156b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 157c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} // namespace content 158