10f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 20f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 30f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)// found in the LICENSE file. 40f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 50f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "content/browser/renderer_host/pepper/pepper_file_io_host.h" 60f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 70f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "base/bind.h" 80f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "base/callback.h" 90f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "base/callback_helpers.h" 100f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "base/files/file_util_proxy.h" 110f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "base/memory/weak_ptr.h" 120f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "content/browser/renderer_host/pepper/pepper_file_ref_host.h" 13f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "content/browser/renderer_host/pepper/pepper_file_system_browser_host.h" 140f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "content/browser/renderer_host/pepper/pepper_security_helper.h" 150f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "content/common/fileapi/file_system_messages.h" 160f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "content/common/sandbox_util.h" 170f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "content/common/view_messages.h" 180f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "content/public/browser/browser_thread.h" 190f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "content/public/browser/content_browser_client.h" 200f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "content/public/browser/render_process_host.h" 210f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "content/public/browser/storage_partition.h" 220f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "content/public/common/content_client.h" 230f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "ppapi/c/pp_errors.h" 240f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "ppapi/c/ppb_file_io.h" 250f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "ppapi/host/dispatch_host_message.h" 260f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "ppapi/host/ppapi_host.h" 270f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "ppapi/proxy/ppapi_messages.h" 28f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "ppapi/shared_impl/file_system_util.h" 290f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "ppapi/shared_impl/file_type_conversion.h" 300f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "ppapi/shared_impl/time_conversion.h" 311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/file_observers.h" 321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/file_system_context.h" 331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/file_system_operation_runner.h" 341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/task_runner_bound_observer_list.h" 351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/common/fileapi/file_system_util.h" 360f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 370f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)namespace content { 380f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 390f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)using ppapi::FileIOStateManager; 400f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)using ppapi::PPTimeToTime; 410f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 420f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)namespace { 430f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 44a02191e04bc25c4935f804f2c080ae28663d096dBen MurdochPepperFileIOHost::UIThreadStuff GetUIThreadStuffForInternalFileSystems( 45a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch int render_process_id) { 460f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) PepperFileIOHost::UIThreadStuff stuff; 47effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DCHECK_CURRENTLY_ON(BrowserThread::UI); 480f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) RenderProcessHost* host = RenderProcessHost::FromID(render_process_id); 490f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) if (host) { 500f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) stuff.resolved_render_process_id = base::GetProcId(host->GetHandle()); 510f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) StoragePartition* storage_partition = host->GetStoragePartition(); 520f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) if (storage_partition) 530f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) stuff.file_system_context = storage_partition->GetFileSystemContext(); 540f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) } 550f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) return stuff; 560f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)} 570f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 580f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)base::ProcessId GetResolvedRenderProcessId(int render_process_id) { 59effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DCHECK_CURRENTLY_ON(BrowserThread::UI); 600f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) RenderProcessHost* host = RenderProcessHost::FromID(render_process_id); 610f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) if (!host) 620f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) return base::kNullProcessId; 630f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) return base::GetProcId(host->GetHandle()); 640f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)} 650f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 660f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)bool GetPluginAllowedToCallRequestOSFileHandle(int render_process_id, 670f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) const GURL& document_url) { 68effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DCHECK_CURRENTLY_ON(BrowserThread::UI); 690f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) ContentBrowserClient* client = GetContentClient()->browser(); 700f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) RenderProcessHost* host = RenderProcessHost::FromID(render_process_id); 71a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!host) 72a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return false; 730f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) return client->IsPluginAllowedToCallRequestOSFileHandle( 740f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) host->GetBrowserContext(), document_url); 750f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)} 760f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool FileOpenForWrite(int32_t open_flags) { 785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return (open_flags & (PP_FILEOPENFLAG_WRITE | PP_FILEOPENFLAG_APPEND)) != 0; 795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 8146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void FileCloser(base::File auto_close) { 8246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 8346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 8446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void DidCloseFile(const base::Closure& on_close_callback) { 8546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (!on_close_callback.is_null()) 8646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) on_close_callback.Run(); 8746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 8846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 8946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void DidOpenFile(base::WeakPtr<PepperFileIOHost> file_host, 9003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) storage::FileSystemOperation::OpenFileCallback callback, 9146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) base::File file, 9246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const base::Closure& on_close_callback) { 9346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (file_host) { 9446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) callback.Run(file.Pass(), on_close_callback); 9546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } else { 9646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) BrowserThread::PostTaskAndReply( 9746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) BrowserThread::FILE, 9846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) FROM_HERE, 9946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) base::Bind(&FileCloser, base::Passed(&file)), 10046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) base::Bind(&DidCloseFile, on_close_callback)); 10146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } 10246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 10346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 1040f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)} // namespace 1050f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 1060f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)PepperFileIOHost::PepperFileIOHost(BrowserPpapiHostImpl* host, 1070f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) PP_Instance instance, 1080f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) PP_Resource resource) 1090f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) : ResourceHost(host->GetPpapiHost(), instance, resource), 1100f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) browser_ppapi_host_(host), 1110f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) render_process_host_(NULL), 1121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci file_(BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE) 1131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci .get()), 114a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) open_flags_(0), 1150f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) file_system_type_(PP_FILESYSTEMTYPE_INVALID), 116a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) max_written_offset_(0), 11746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) check_quota_(false) { 1180f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) int unused; 119a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch if (!host->GetRenderFrameIDsForInstance( 120a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch instance, &render_process_id_, &unused)) { 1210f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) render_process_id_ = -1; 1220f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) } 1230f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)} 1240f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 125a02191e04bc25c4935f804f2c080ae28663d096dBen MurdochPepperFileIOHost::~PepperFileIOHost() {} 1260f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 1270f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)int32_t PepperFileIOHost::OnResourceMessageReceived( 1280f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) const IPC::Message& msg, 1290f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) ppapi::host::HostMessageContext* context) { 130cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) PPAPI_BEGIN_MESSAGE_MAP(PepperFileIOHost, msg) 131cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_FileIO_Open, OnHostMsgOpen) 132cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_FileIO_Touch, OnHostMsgTouch) 133cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_FileIO_SetLength, 134cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) OnHostMsgSetLength) 135cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_FileIO_Flush, 136cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) OnHostMsgFlush) 137cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_FileIO_Close, OnHostMsgClose) 138cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_FileIO_RequestOSFileHandle, 139cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) OnHostMsgRequestOSFileHandle) 140cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) PPAPI_END_MESSAGE_MAP() 1410f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) return PP_ERROR_FAILED; 1420f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)} 1430f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 1440f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)PepperFileIOHost::UIThreadStuff::UIThreadStuff() { 1450f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) resolved_render_process_id = base::kNullProcessId; 1460f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)} 1470f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 148a02191e04bc25c4935f804f2c080ae28663d096dBen MurdochPepperFileIOHost::UIThreadStuff::~UIThreadStuff() {} 1490f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 1500f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)int32_t PepperFileIOHost::OnHostMsgOpen( 1510f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) ppapi::host::HostMessageContext* context, 1520f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) PP_Resource file_ref_resource, 1530f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) int32_t open_flags) { 1540f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) int32_t rv = state_manager_.CheckOperationState( 1550f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) FileIOStateManager::OPERATION_EXCLUSIVE, false); 1560f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) if (rv != PP_OK) 1570f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) return rv; 1580f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 1590f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) int platform_file_flags = 0; 1600f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) if (!ppapi::PepperFileOpenFlagsToPlatformFileFlags(open_flags, 1610f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) &platform_file_flags)) 1620f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) return PP_ERROR_BADARGUMENT; 1630f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 1640f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) ppapi::host::ResourceHost* resource_host = 1650f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) host()->GetResourceHost(file_ref_resource); 1660f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) if (!resource_host || !resource_host->IsFileRefHost()) 1670f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) return PP_ERROR_BADRESOURCE; 1680f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) PepperFileRefHost* file_ref_host = 1690f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) static_cast<PepperFileRefHost*>(resource_host); 1700f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) if (file_ref_host->GetFileSystemType() == PP_FILESYSTEMTYPE_INVALID) 1710f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) return PP_ERROR_FAILED; 1720f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 173f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) file_system_host_ = file_ref_host->GetFileSystemHost(); 174f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 1750f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) open_flags_ = open_flags; 1760f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) file_system_type_ = file_ref_host->GetFileSystemType(); 1770f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) file_system_url_ = file_ref_host->GetFileSystemURL(); 1780f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 179a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // For external file systems, if there is a valid FileSystemURL, then treat 180a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // it like internal file systems and access it via the FileSystemURL. 181a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch bool is_internal_type = (file_system_type_ != PP_FILESYSTEMTYPE_EXTERNAL) || 182a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch file_system_url_.is_valid(); 183a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 184a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch if (is_internal_type) { 1850f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) if (!file_system_url_.is_valid()) 1860f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) return PP_ERROR_BADARGUMENT; 187a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 188a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // Not all external file systems are fully supported yet. 189a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // Whitelist the supported ones. 19003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (file_system_url_.mount_type() == storage::kFileSystemTypeExternal) { 191a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch switch (file_system_url_.type()) { 19203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) case storage::kFileSystemTypeNativeMedia: 19303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) case storage::kFileSystemTypeDeviceMedia: 19403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) case storage::kFileSystemTypePicasa: 19503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) case storage::kFileSystemTypeItunes: 19603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) case storage::kFileSystemTypeIphoto: 197a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch break; 198a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch default: 199a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch return PP_ERROR_NOACCESS; 200a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch } 201a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch } 202a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch if (!CanOpenFileSystemURLWithPepperFlags( 203a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch open_flags, render_process_id_, file_system_url_)) 2040f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) return PP_ERROR_NOACCESS; 2050f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) BrowserThread::PostTaskAndReplyWithResult( 2060f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) BrowserThread::UI, 2070f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) FROM_HERE, 208a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch base::Bind(&GetUIThreadStuffForInternalFileSystems, render_process_id_), 2090f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) base::Bind(&PepperFileIOHost::GotUIThreadStuffForInternalFileSystems, 21046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) AsWeakPtr(), 2110f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) context->MakeReplyMessageContext(), 2120f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) platform_file_flags)); 2130f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) } else { 2140f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) base::FilePath path = file_ref_host->GetExternalFilePath(); 2150f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) if (!CanOpenWithPepperFlags(open_flags, render_process_id_, path)) 2160f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) return PP_ERROR_NOACCESS; 2170f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) BrowserThread::PostTaskAndReplyWithResult( 2180f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) BrowserThread::UI, 2190f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) FROM_HERE, 2200f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) base::Bind(&GetResolvedRenderProcessId, render_process_id_), 2210f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) base::Bind(&PepperFileIOHost::GotResolvedRenderProcessId, 22246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) AsWeakPtr(), 2230f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) context->MakeReplyMessageContext(), 2240f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) path, 2250f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) platform_file_flags)); 2260f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) } 2270f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) state_manager_.SetPendingOperation(FileIOStateManager::OPERATION_EXCLUSIVE); 2280f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) return PP_OK_COMPLETIONPENDING; 2290f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)} 2300f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 2310f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)void PepperFileIOHost::GotUIThreadStuffForInternalFileSystems( 2320f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) ppapi::host::ReplyMessageContext reply_context, 2330f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) int platform_file_flags, 2340f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) UIThreadStuff ui_thread_stuff) { 235effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DCHECK_CURRENTLY_ON(BrowserThread::IO); 2360f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) file_system_context_ = ui_thread_stuff.file_system_context; 2370f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) resolved_render_process_id_ = ui_thread_stuff.resolved_render_process_id; 2380f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) if (resolved_render_process_id_ == base::kNullProcessId || 2390f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) !file_system_context_.get()) { 2400f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) reply_context.params.set_result(PP_ERROR_FAILED); 2415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SendOpenErrorReply(reply_context); 2420f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) return; 2430f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) } 2440f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 2450f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) if (!file_system_context_->GetFileSystemBackend(file_system_url_.type())) { 2460f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) reply_context.params.set_result(PP_ERROR_FAILED); 2475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SendOpenErrorReply(reply_context); 2480f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) return; 2490f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) } 250a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 251f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK(file_system_host_.get()); 252f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK(file_system_host_->GetFileSystemOperationRunner()); 25346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 254f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) file_system_host_->GetFileSystemOperationRunner()->OpenFile( 2550f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) file_system_url_, 2560f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) platform_file_flags, 25746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) base::Bind(&DidOpenFile, 25846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) AsWeakPtr(), 25946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) base::Bind(&PepperFileIOHost::DidOpenInternalFile, 26046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) AsWeakPtr(), 26146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) reply_context))); 2620f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)} 2630f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 2640f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)void PepperFileIOHost::DidOpenInternalFile( 2650f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) ppapi::host::ReplyMessageContext reply_context, 266cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::File file, 2670f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) const base::Closure& on_close_callback) { 268cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (file.IsValid()) { 2690f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) on_close_callback_ = on_close_callback; 270a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 2715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (FileOpenForWrite(open_flags_) && file_system_host_->ChecksQuota()) { 2725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) check_quota_ = true; 273a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) file_system_host_->OpenQuotaFile( 274a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) this, 2755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) file_system_url_, 276a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::Bind(&PepperFileIOHost::DidOpenQuotaFile, 27746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) AsWeakPtr(), 278a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) reply_context, 279cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::Passed(&file))); 280a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return; 281a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 282a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 283a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 284cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DCHECK(!file_.IsValid()); 285cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::File::Error error = 286cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) file.IsValid() ? base::File::FILE_OK : file.error_details(); 287cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) file_.SetFile(file.Pass()); 288cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) OnOpenProxyCallback(reply_context, error); 2890f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)} 2900f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 2910f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)void PepperFileIOHost::GotResolvedRenderProcessId( 2920f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) ppapi::host::ReplyMessageContext reply_context, 2930f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) base::FilePath path, 294cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) int file_flags, 2950f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) base::ProcessId resolved_render_process_id) { 296effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DCHECK_CURRENTLY_ON(BrowserThread::IO); 2970f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) resolved_render_process_id_ = resolved_render_process_id; 298cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) file_.CreateOrOpen( 2990f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) path, 300cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) file_flags, 301cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::Bind(&PepperFileIOHost::OnOpenProxyCallback, 30246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) AsWeakPtr(), 3030f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) reply_context)); 3040f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)} 3050f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 3060f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)int32_t PepperFileIOHost::OnHostMsgTouch( 3070f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) ppapi::host::HostMessageContext* context, 3080f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) PP_Time last_access_time, 3090f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) PP_Time last_modified_time) { 3100f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) int32_t rv = state_manager_.CheckOperationState( 3110f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) FileIOStateManager::OPERATION_EXCLUSIVE, true); 3120f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) if (rv != PP_OK) 3130f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) return rv; 3140f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 315cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (!file_.SetTimes( 316f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) PPTimeToTime(last_access_time), 317f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) PPTimeToTime(last_modified_time), 318f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) base::Bind(&PepperFileIOHost::ExecutePlatformGeneralCallback, 31946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) AsWeakPtr(), 320cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) context->MakeReplyMessageContext()))) { 321f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return PP_ERROR_FAILED; 322cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 3230f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 3240f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) state_manager_.SetPendingOperation(FileIOStateManager::OPERATION_EXCLUSIVE); 3250f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) return PP_OK_COMPLETIONPENDING; 3260f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)} 3270f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 3280f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)int32_t PepperFileIOHost::OnHostMsgSetLength( 3290f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) ppapi::host::HostMessageContext* context, 3300f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) int64_t length) { 3310f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) int32_t rv = state_manager_.CheckOperationState( 3320f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) FileIOStateManager::OPERATION_EXCLUSIVE, true); 3330f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) if (rv != PP_OK) 3340f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) return rv; 335a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (length < 0) 336a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return PP_ERROR_BADARGUMENT; 3370f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 3385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Quota checks are performed on the plugin side, in order to use the same 3395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // quota reservation and request system as Write. 3400f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 341cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (!file_.SetLength( 342a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch length, 343a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch base::Bind(&PepperFileIOHost::ExecutePlatformGeneralCallback, 34446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) AsWeakPtr(), 345cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) context->MakeReplyMessageContext()))) { 346a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return PP_ERROR_FAILED; 347cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 348a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 3490f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) state_manager_.SetPendingOperation(FileIOStateManager::OPERATION_EXCLUSIVE); 3500f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) return PP_OK_COMPLETIONPENDING; 3510f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)} 3520f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 3530f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)int32_t PepperFileIOHost::OnHostMsgFlush( 3540f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) ppapi::host::HostMessageContext* context) { 3550f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) int32_t rv = state_manager_.CheckOperationState( 3560f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) FileIOStateManager::OPERATION_EXCLUSIVE, true); 3570f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) if (rv != PP_OK) 3580f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) return rv; 3590f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 360cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (!file_.Flush( 3610f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) base::Bind(&PepperFileIOHost::ExecutePlatformGeneralCallback, 36246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) AsWeakPtr(), 363cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) context->MakeReplyMessageContext()))) { 3640f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) return PP_ERROR_FAILED; 365cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 3660f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 3670f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) state_manager_.SetPendingOperation(FileIOStateManager::OPERATION_EXCLUSIVE); 3680f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) return PP_OK_COMPLETIONPENDING; 3690f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)} 3700f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 3710f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)int32_t PepperFileIOHost::OnHostMsgClose( 3725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ppapi::host::HostMessageContext* context, 3735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const ppapi::FileGrowth& file_growth) { 3745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (check_quota_) { 3755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) file_system_host_->CloseQuotaFile(this, file_growth); 3765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) check_quota_ = false; 3775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 378a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 379cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (file_.IsValid()) { 380cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) file_.Close(base::Bind(&PepperFileIOHost::DidCloseFile, 38146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) AsWeakPtr())); 3820f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) } 3830f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) return PP_OK; 3840f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)} 3850f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 386a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void PepperFileIOHost::DidOpenQuotaFile( 387a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ppapi::host::ReplyMessageContext reply_context, 388cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::File file, 389a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) int64_t max_written_offset) { 390cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DCHECK(!file_.IsValid()); 391cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DCHECK(file.IsValid()); 392a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) max_written_offset_ = max_written_offset; 393cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) file_.SetFile(file.Pass()); 394a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 395cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) OnOpenProxyCallback(reply_context, base::File::FILE_OK); 396a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 397a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 398a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochvoid PepperFileIOHost::DidCloseFile(base::File::Error /*error*/) { 3990f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) // Silently ignore if we fail to close the file. 4000f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) if (!on_close_callback_.is_null()) { 4010f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) on_close_callback_.Run(); 4020f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) on_close_callback_.Reset(); 4030f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) } 4040f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)} 4050f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 4060f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)int32_t PepperFileIOHost::OnHostMsgRequestOSFileHandle( 4070f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) ppapi::host::HostMessageContext* context) { 4085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (open_flags_ != PP_FILEOPENFLAG_READ && file_system_host_->ChecksQuota()) 4090f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) return PP_ERROR_FAILED; 4100f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 4110f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) GURL document_url = 4120f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) browser_ppapi_host_->GetDocumentURLForInstance(pp_instance()); 4130f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) BrowserThread::PostTaskAndReplyWithResult( 4140f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) BrowserThread::UI, 4150f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) FROM_HERE, 4160f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) base::Bind(&GetPluginAllowedToCallRequestOSFileHandle, 4170f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) render_process_id_, 4180f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) document_url), 4190f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) base::Bind(&PepperFileIOHost::GotPluginAllowedToCallRequestOSFileHandle, 42046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) AsWeakPtr(), 4210f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) context->MakeReplyMessageContext())); 4220f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) return PP_OK_COMPLETIONPENDING; 4230f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)} 4240f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 4250f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)void PepperFileIOHost::GotPluginAllowedToCallRequestOSFileHandle( 4260f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) ppapi::host::ReplyMessageContext reply_context, 4270f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) bool plugin_allowed) { 428effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DCHECK_CURRENTLY_ON(BrowserThread::IO); 4290f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) if (!browser_ppapi_host_->external_plugin() || 4300f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) host()->permissions().HasPermission(ppapi::PERMISSION_PRIVATE) || 4310f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) plugin_allowed) { 4320f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) if (!AddFileToReplyContext(open_flags_, &reply_context)) 4330f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) reply_context.params.set_result(PP_ERROR_FAILED); 4340f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) } else { 4350f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) reply_context.params.set_result(PP_ERROR_NOACCESS); 4360f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) } 4370f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) host()->SendReply(reply_context, 4380f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) PpapiPluginMsg_FileIO_RequestOSFileHandleReply()); 4390f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)} 4400f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 4410f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)void PepperFileIOHost::ExecutePlatformGeneralCallback( 4420f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) ppapi::host::ReplyMessageContext reply_context, 4435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::File::Error error_code) { 444a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch reply_context.params.set_result(ppapi::FileErrorToPepperError(error_code)); 4450f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) host()->SendReply(reply_context, PpapiPluginMsg_FileIO_GeneralReply()); 4460f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) state_manager_.SetOperationFinished(); 4470f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)} 4480f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 449cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void PepperFileIOHost::OnOpenProxyCallback( 4500f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) ppapi::host::ReplyMessageContext reply_context, 451cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::File::Error error_code) { 4525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int32_t pp_error = ppapi::FileErrorToPepperError(error_code); 453cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (file_.IsValid() && !AddFileToReplyContext(open_flags_, &reply_context)) 4545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) pp_error = PP_ERROR_FAILED; 4555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) PP_Resource quota_file_system = 0; 4575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (pp_error == PP_OK) { 4585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) state_manager_.SetOpenSucceed(); 4595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // A non-zero resource id signals the plugin side to check quota. 4605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (check_quota_) 4615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) quota_file_system = file_system_host_->pp_resource(); 4620f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) } 4635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4640f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) reply_context.params.set_result(pp_error); 465a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch host()->SendReply( 466a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch reply_context, 467a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch PpapiPluginMsg_FileIO_OpenReply(quota_file_system, max_written_offset_)); 4680f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) state_manager_.SetOperationFinished(); 4690f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)} 4700f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 4715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void PepperFileIOHost::SendOpenErrorReply( 4725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ppapi::host::ReplyMessageContext reply_context) { 4735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) host()->SendReply(reply_context, PpapiPluginMsg_FileIO_OpenReply(0, 0)); 4740f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)} 4750f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 4760f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)bool PepperFileIOHost::AddFileToReplyContext( 4770f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) int32_t open_flags, 4780f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) ppapi::host::ReplyMessageContext* reply_context) const { 4795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::ProcessId plugin_process_id = 4805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::GetProcId(browser_ppapi_host_->GetPluginProcessHandle()); 4815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (plugin_process_id == base::kNullProcessId) 4820f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) plugin_process_id = resolved_render_process_id_; 4835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 484a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch IPC::PlatformFileForTransit transit_file = 485cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) BrokerGetFileHandleForProcess(file_.GetPlatformFile(), plugin_process_id, 486cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) false); 4870f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) if (transit_file == IPC::InvalidPlatformFileForTransit()) 4880f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) return false; 4895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4900f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) ppapi::proxy::SerializedHandle file_handle; 4915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // A non-zero resource id signals NaClIPCAdapter to create a NaClQuotaDesc. 4925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) PP_Resource quota_file_io = check_quota_ ? pp_resource() : 0; 4935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) file_handle.set_file_handle(transit_file, open_flags, quota_file_io); 4940f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) reply_context->params.AppendHandle(file_handle); 4950f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) return true; 4960f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)} 4970f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 4980f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)} // namespace content 499