17d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
27d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
37d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// found in the LICENSE file.
47d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
57d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "content/browser/renderer_host/pepper/pepper_file_system_browser_host.h"
67d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
77d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/bind.h"
87d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/callback.h"
9a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "content/browser/renderer_host/pepper/pepper_file_io_host.h"
10a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "content/browser/renderer_host/pepper/quota_reservation.h"
115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/common/pepper_file_util.h"
127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "content/public/browser/browser_ppapi_host.h"
137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "content/public/browser/browser_thread.h"
14f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "content/public/browser/plugin_service.h"
157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "content/public/browser/render_process_host.h"
167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "content/public/browser/storage_partition.h"
17f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "content/public/common/pepper_plugin_info.h"
18f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "net/base/mime_util.h"
197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "ppapi/c/pp_errors.h"
207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "ppapi/host/dispatch_host_message.h"
217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "ppapi/host/ppapi_host.h"
227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "ppapi/proxy/ppapi_messages.h"
23f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "ppapi/shared_impl/file_system_util.h"
247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "ppapi/shared_impl/file_type_conversion.h"
251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/file_system_operation_runner.h"
261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/isolated_context.h"
271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/quota/quota_manager_proxy.h"
281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/common/fileapi/file_system_util.h"
291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/common/quota/quota_types.h"
307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)namespace content {
327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)namespace {
347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
35a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// This is the minimum amount of quota we reserve per file system.
36a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)const int64_t kMinimumQuotaReservationSize = 1024 * 1024;  // 1 MB
37a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
3803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)scoped_refptr<storage::FileSystemContext> GetFileSystemContextFromRenderId(
39a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    int render_process_id) {
40effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  DCHECK_CURRENTLY_ON(BrowserThread::UI);
410f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  RenderProcessHost* host = RenderProcessHost::FromID(render_process_id);
420f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  if (!host)
437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return NULL;
440f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  StoragePartition* storage_partition = host->GetStoragePartition();
457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (!storage_partition)
467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return NULL;
477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return storage_partition->GetFileSystemContext();
487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}  // namespace
517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)PepperFileSystemBrowserHost::PepperFileSystemBrowserHost(BrowserPpapiHost* host,
537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                                         PP_Instance instance,
547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                                         PP_Resource resource,
557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                                         PP_FileSystemType type)
567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    : ResourceHost(host->GetPpapiHost(), instance, resource),
577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      browser_ppapi_host_(host),
587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      type_(type),
593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      called_open_(false),
60f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      opened_(false),
61f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      file_system_context_(NULL),
62a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      reserved_quota_(0),
63a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      reserving_quota_(false),
64a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      weak_factory_(this) {}
657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
66f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)PepperFileSystemBrowserHost::~PepperFileSystemBrowserHost() {
675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // If |files_| is not empty, the plugin failed to close some files. It must
685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // have crashed.
695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!files_.empty()) {
705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    file_system_context_->default_file_task_runner()->PostTask(
715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        FROM_HERE,
725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        base::Bind(&QuotaReservation::OnClientCrash, quota_reservation_));
735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
75f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // All FileRefs and FileIOs that reference us must have been destroyed. Cancel
76f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // all pending file system operations.
77f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (file_system_operation_runner_)
78f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    file_system_operation_runner_->Shutdown();
79f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
80f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
810f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)void PepperFileSystemBrowserHost::OpenExisting(const GURL& root_url,
820f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                                               const base::Closure& callback) {
830f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  root_url_ = root_url;
840f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  int render_process_id = 0;
850f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  int unused;
865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!browser_ppapi_host_->GetRenderFrameIDsForInstance(
87a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch          pp_instance(), &render_process_id, &unused)) {
880f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    NOTREACHED();
890f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  }
900f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  called_open_ = true;
910f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // Get the file system context asynchronously, and then complete the Open
920f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // operation by calling |callback|.
930f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  BrowserThread::PostTaskAndReplyWithResult(
940f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      BrowserThread::UI,
950f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      FROM_HERE,
960f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      base::Bind(&GetFileSystemContextFromRenderId, render_process_id),
97a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      base::Bind(&PepperFileSystemBrowserHost::OpenExistingFileSystem,
98a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                 weak_factory_.GetWeakPtr(),
99a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                 callback));
1004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
1014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)int32_t PepperFileSystemBrowserHost::OnResourceMessageReceived(
1037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    const IPC::Message& msg,
1047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    ppapi::host::HostMessageContext* context) {
105cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  PPAPI_BEGIN_MESSAGE_MAP(PepperFileSystemBrowserHost, msg)
106cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_FileSystem_Open,
107cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                      OnHostMsgOpen)
108cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    PPAPI_DISPATCH_HOST_RESOURCE_CALL(
109cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        PpapiHostMsg_FileSystem_InitIsolatedFileSystem,
110cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        OnHostMsgInitIsolatedFileSystem)
111cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_FileSystem_ReserveQuota,
112cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                      OnHostMsgReserveQuota)
113cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  PPAPI_END_MESSAGE_MAP()
1147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return PP_ERROR_FAILED;
1157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
1167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
117a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochbool PepperFileSystemBrowserHost::IsFileSystemHost() { return true; }
1187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
119a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void PepperFileSystemBrowserHost::OpenQuotaFile(
120a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    PepperFileIOHost* file_io_host,
12103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    const storage::FileSystemURL& url,
122a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    const OpenQuotaFileCallback& callback) {
123a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  int32_t id = file_io_host->pp_resource();
124a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  std::pair<FileMap::iterator, bool> insert_result =
125a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      files_.insert(std::make_pair(id, file_io_host));
126a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (insert_result.second) {
127a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    base::PostTaskAndReplyWithResult(
128a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        file_system_context_->default_file_task_runner(),
129a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        FROM_HERE,
130a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        base::Bind(&QuotaReservation::OpenFile, quota_reservation_, id, url),
131a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        callback);
132a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  } else {
133a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    NOTREACHED();
134a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
135a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
136a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
137a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void PepperFileSystemBrowserHost::CloseQuotaFile(
1385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    PepperFileIOHost* file_io_host,
1395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const ppapi::FileGrowth& file_growth) {
140a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  int32_t id = file_io_host->pp_resource();
141a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  FileMap::iterator it = files_.find(id);
142a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (it != files_.end()) {
143a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    files_.erase(it);
144a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  } else {
145a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    NOTREACHED();
146a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    return;
147a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
148a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
149a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  file_system_context_->default_file_task_runner()->PostTask(
150a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      FROM_HERE,
151a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      base::Bind(
152a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch          &QuotaReservation::CloseFile, quota_reservation_, id, file_growth));
153a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
154a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
1557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)int32_t PepperFileSystemBrowserHost::OnHostMsgOpen(
1567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    ppapi::host::HostMessageContext* context,
1577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    int64_t /* unused */) {
1587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // TODO(raymes): The file system size is now unused by FileSystemDispatcher.
1597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Figure out why. Why is the file system size signed?
1607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Not allow multiple opens.
1627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (called_open_)
1637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return PP_ERROR_INPROGRESS;
1647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  called_open_ = true;
1657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
16603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  storage::FileSystemType file_system_type =
1675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      PepperFileSystemTypeToFileSystemType(type_);
16803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  if (file_system_type == storage::kFileSystemTypeUnknown)
169f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return PP_ERROR_FAILED;
1707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  int render_process_id = 0;
1727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  int unused;
173a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  if (!browser_ppapi_host_->GetRenderFrameIDsForInstance(
174a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch          pp_instance(), &render_process_id, &unused)) {
175a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    return PP_ERROR_FAILED;
1767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
177f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  BrowserThread::PostTaskAndReplyWithResult(
1797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      BrowserThread::UI,
1807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      FROM_HERE,
1817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&GetFileSystemContextFromRenderId, render_process_id),
182a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      base::Bind(&PepperFileSystemBrowserHost::OpenFileSystem,
1837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                 weak_factory_.GetWeakPtr(),
1847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                 context->MakeReplyMessageContext(),
1857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                 file_system_type));
1867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return PP_OK_COMPLETIONPENDING;
1877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
1887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
189a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void PepperFileSystemBrowserHost::OpenExistingFileSystem(
1900f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    const base::Closure& callback,
19103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    scoped_refptr<storage::FileSystemContext> file_system_context) {
192f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (file_system_context.get()) {
1930f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    opened_ = true;
1940f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  } else {
1950f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    // If there is no file system context, we log a warning and continue with an
1960f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    // invalid resource (which will produce errors when used), since we have no
1970f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    // way to communicate the error to the caller.
1980f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    LOG(WARNING) << "Could not retrieve file system context.";
1990f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  }
200f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  SetFileSystemContext(file_system_context);
201a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
2025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (ShouldCreateQuotaReservation())
2035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    CreateQuotaReservation(callback);
2045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  else
2055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    callback.Run();
2060f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)}
2070f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
208a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void PepperFileSystemBrowserHost::OpenFileSystem(
2097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    ppapi::host::ReplyMessageContext reply_context,
21003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    storage::FileSystemType file_system_type,
21103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    scoped_refptr<storage::FileSystemContext> file_system_context) {
212f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (!file_system_context.get()) {
213eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    OpenFileSystemComplete(
2145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        reply_context, GURL(), std::string(), base::File::FILE_ERROR_FAILED);
2157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return;
2167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
217a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
218a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  SetFileSystemContext(file_system_context);
219a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
220a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  GURL origin =
221a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      browser_ppapi_host_->GetDocumentURLForInstance(pp_instance()).GetOrigin();
222a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  file_system_context_->OpenFileSystem(
223a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      origin,
224a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      file_system_type,
22503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      storage::OPEN_FILE_SYSTEM_CREATE_IF_NONEXISTENT,
2267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&PepperFileSystemBrowserHost::OpenFileSystemComplete,
227a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                 weak_factory_.GetWeakPtr(),
228a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                 reply_context));
229424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}
230424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
2317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void PepperFileSystemBrowserHost::OpenFileSystemComplete(
2327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    ppapi::host::ReplyMessageContext reply_context,
2334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    const GURL& root,
2347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    const std::string& /* unused */,
2355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::File::Error error) {
2365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int32 pp_error = ppapi::FileErrorToPepperError(error);
2377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (pp_error == PP_OK) {
2387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    opened_ = true;
2397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    root_url_ = root;
240a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
2415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (ShouldCreateQuotaReservation()) {
2425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      CreateQuotaReservation(
2435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          base::Bind(&PepperFileSystemBrowserHost::SendReplyForFileSystem,
2445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                     weak_factory_.GetWeakPtr(),
2455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                     reply_context,
2465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                     static_cast<int32_t>(PP_OK)));
247a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      return;
2485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
2497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
250a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  SendReplyForFileSystem(reply_context, pp_error);
2517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
2527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
253a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void PepperFileSystemBrowserHost::OpenIsolatedFileSystem(
254f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    ppapi::host::ReplyMessageContext reply_context,
255f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const std::string& fsid,
256f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    PP_IsolatedFileSystemType_Private type,
25703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    scoped_refptr<storage::FileSystemContext> file_system_context) {
258f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (!file_system_context.get()) {
259f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    SendReplyForIsolatedFileSystem(reply_context, fsid, PP_ERROR_FAILED);
260f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return;
261f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
262f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  SetFileSystemContext(file_system_context);
263f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
26403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  root_url_ = GURL(storage::GetIsolatedFileSystemRootURIString(
265f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      browser_ppapi_host_->GetDocumentURLForInstance(pp_instance()).GetOrigin(),
266a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      fsid,
267a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      ppapi::IsolatedFileSystemTypeToRootName(type)));
268f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (!root_url_.is_valid()) {
269f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    SendReplyForIsolatedFileSystem(reply_context, fsid, PP_ERROR_FAILED);
270f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return;
271f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
272f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
273f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  switch (type) {
274f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    case PP_ISOLATEDFILESYSTEMTYPE_PRIVATE_CRX:
275f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      opened_ = true;
276f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      SendReplyForIsolatedFileSystem(reply_context, fsid, PP_OK);
277f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      return;
278f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    case PP_ISOLATEDFILESYSTEMTYPE_PRIVATE_PLUGINPRIVATE:
279f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      OpenPluginPrivateFileSystem(reply_context, fsid, file_system_context_);
280f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      return;
281f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    default:
282f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      NOTREACHED();
283f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      SendReplyForIsolatedFileSystem(reply_context, fsid, PP_ERROR_BADARGUMENT);
284f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      return;
285f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
286f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
287f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
288f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void PepperFileSystemBrowserHost::OpenPluginPrivateFileSystem(
289f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    ppapi::host::ReplyMessageContext reply_context,
290f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const std::string& fsid,
29103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    scoped_refptr<storage::FileSystemContext> file_system_context) {
292a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  GURL origin =
293a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      browser_ppapi_host_->GetDocumentURLForInstance(pp_instance()).GetOrigin();
294f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (!origin.is_valid()) {
295f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    SendReplyForIsolatedFileSystem(reply_context, fsid, PP_ERROR_FAILED);
296f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return;
297f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
298f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
299f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const std::string& plugin_id = GeneratePluginId(GetPluginMimeType());
300f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (plugin_id.empty()) {
301f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    SendReplyForIsolatedFileSystem(reply_context, fsid, PP_ERROR_BADARGUMENT);
302f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return;
303f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
304f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
305f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  file_system_context->OpenPluginPrivateFileSystem(
306a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      origin,
30703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      storage::kFileSystemTypePluginPrivate,
308a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      fsid,
309a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      plugin_id,
31003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      storage::OPEN_FILE_SYSTEM_CREATE_IF_NONEXISTENT,
311f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      base::Bind(
312f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)          &PepperFileSystemBrowserHost::OpenPluginPrivateFileSystemComplete,
313a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch          weak_factory_.GetWeakPtr(),
314a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch          reply_context,
315a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch          fsid));
316f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
317f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
318f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void PepperFileSystemBrowserHost::OpenPluginPrivateFileSystemComplete(
319f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    ppapi::host::ReplyMessageContext reply_context,
320f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const std::string& fsid,
3215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::File::Error error) {
3225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int32 pp_error = ppapi::FileErrorToPepperError(error);
323f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (pp_error == PP_OK)
324f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    opened_ = true;
325f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  SendReplyForIsolatedFileSystem(reply_context, fsid, pp_error);
326f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
327f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
3287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)int32_t PepperFileSystemBrowserHost::OnHostMsgInitIsolatedFileSystem(
3297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    ppapi::host::HostMessageContext* context,
330f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const std::string& fsid,
331f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    PP_IsolatedFileSystemType_Private type) {
3324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Do not allow multiple opens.
3334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (called_open_)
3344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return PP_ERROR_INPROGRESS;
3357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  called_open_ = true;
336f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
3377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Do a sanity check.
33803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  if (!storage::ValidateIsolatedFileSystemId(fsid))
3397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return PP_ERROR_BADARGUMENT;
340424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
341424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  int render_process_id = 0;
342424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  int unused;
343a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  if (!browser_ppapi_host_->GetRenderFrameIDsForInstance(
344a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch          pp_instance(), &render_process_id, &unused)) {
34503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    storage::IsolatedContext::GetInstance()->RevokeFileSystem(fsid);
346424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    return PP_ERROR_FAILED;
347424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  }
348f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
34903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  root_url_ = GURL(storage::GetIsolatedFileSystemRootURIString(
350a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      browser_ppapi_host_->GetDocumentURLForInstance(pp_instance()).GetOrigin(),
351a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      fsid,
352a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      ppapi::IsolatedFileSystemTypeToRootName(type)));
353a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
354424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  BrowserThread::PostTaskAndReplyWithResult(
355424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      BrowserThread::UI,
356424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      FROM_HERE,
357424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      base::Bind(&GetFileSystemContextFromRenderId, render_process_id),
358a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      base::Bind(&PepperFileSystemBrowserHost::OpenIsolatedFileSystem,
359424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)                 weak_factory_.GetWeakPtr(),
360a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                 context->MakeReplyMessageContext(),
361a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                 fsid,
362a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                 type));
363424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  return PP_OK_COMPLETIONPENDING;
3647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
3657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)int32_t PepperFileSystemBrowserHost::OnHostMsgReserveQuota(
3675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ppapi::host::HostMessageContext* context,
3685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    int64_t amount,
3695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const ppapi::FileGrowthMap& file_growths) {
3705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(ChecksQuota());
371a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  DCHECK_GT(amount, 0);
3725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (reserving_quota_)
3745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return PP_ERROR_INPROGRESS;
3755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  reserving_quota_ = true;
3765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
377a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  int64_t reservation_amount =
378a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      std::max<int64_t>(kMinimumQuotaReservationSize, amount);
3795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  file_system_context_->default_file_task_runner()->PostTask(
3805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      FROM_HERE,
3815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::Bind(&QuotaReservation::ReserveQuota,
3825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                 quota_reservation_,
3835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                 reservation_amount,
3845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                 file_growths,
3855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                 base::Bind(&PepperFileSystemBrowserHost::GotReservedQuota,
3865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                            weak_factory_.GetWeakPtr(),
3875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                            context->MakeReplyMessageContext())));
3885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return PP_OK_COMPLETIONPENDING;
3905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
3915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
392a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void PepperFileSystemBrowserHost::SendReplyForFileSystem(
393a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    ppapi::host::ReplyMessageContext reply_context,
394a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    int32_t pp_error) {
395a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  reply_context.params.set_result(pp_error);
396a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  host()->SendReply(reply_context, PpapiPluginMsg_FileSystem_OpenReply());
397a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
398a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
399f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void PepperFileSystemBrowserHost::SendReplyForIsolatedFileSystem(
400f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    ppapi::host::ReplyMessageContext reply_context,
401f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const std::string& fsid,
402f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    int32_t error) {
403f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (error != PP_OK)
40403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    storage::IsolatedContext::GetInstance()->RevokeFileSystem(fsid);
405f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  reply_context.params.set_result(error);
406f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  host()->SendReply(reply_context,
407f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                    PpapiPluginMsg_FileSystem_InitIsolatedFileSystemReply());
408f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
409f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
410f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void PepperFileSystemBrowserHost::SetFileSystemContext(
41103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    scoped_refptr<storage::FileSystemContext> file_system_context) {
412f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  file_system_context_ = file_system_context;
413a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  if (type_ != PP_FILESYSTEMTYPE_EXTERNAL || root_url_.is_valid()) {
414f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    file_system_operation_runner_ =
415f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        file_system_context_->CreateFileSystemOperationRunner();
416f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
417f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
418f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
4195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool PepperFileSystemBrowserHost::ShouldCreateQuotaReservation() const {
4205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Some file system types don't have quota.
421a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (!ppapi::FileSystemTypeHasQuota(type_))
4225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return false;
423a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
4245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // For file system types with quota, some origins have unlimited storage.
42503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  storage::QuotaManagerProxy* quota_manager_proxy =
4265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      file_system_context_->quota_manager_proxy();
4275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  CHECK(quota_manager_proxy);
4285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  CHECK(quota_manager_proxy->quota_manager());
42903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  storage::FileSystemType file_system_type =
4305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      PepperFileSystemTypeToFileSystemType(type_);
4315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return !quota_manager_proxy->quota_manager()->IsStorageUnlimited(
4325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      root_url_.GetOrigin(),
43303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      storage::FileSystemTypeToQuotaStorageType(file_system_type));
4345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
4355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void PepperFileSystemBrowserHost::CreateQuotaReservation(
4375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const base::Closure& callback) {
438a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  DCHECK(root_url_.is_valid());
439a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  base::PostTaskAndReplyWithResult(
440a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      file_system_context_->default_file_task_runner(),
441a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      FROM_HERE,
442a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      base::Bind(&QuotaReservation::Create,
443a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                 file_system_context_,
444a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                 root_url_.GetOrigin(),
4455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                 PepperFileSystemTypeToFileSystemType(type_)),
446a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      base::Bind(&PepperFileSystemBrowserHost::GotQuotaReservation,
447a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                 weak_factory_.GetWeakPtr(),
448a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                 callback));
449a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
450a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
451a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void PepperFileSystemBrowserHost::GotQuotaReservation(
452a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    const base::Closure& callback,
453a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    scoped_refptr<QuotaReservation> quota_reservation) {
454a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  quota_reservation_ = quota_reservation;
455a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  callback.Run();
456a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
457a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
458a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void PepperFileSystemBrowserHost::GotReservedQuota(
4595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ppapi::host::ReplyMessageContext reply_context,
460a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    int64_t amount,
4615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const ppapi::FileSizeMap& file_sizes) {
462a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  DCHECK(reserving_quota_);
463a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  reserving_quota_ = false;
464a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  reserved_quota_ = amount;
465a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
4665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  reply_context.params.set_result(PP_OK);
4675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  host()->SendReply(
4685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      reply_context,
4695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      PpapiPluginMsg_FileSystem_ReserveQuotaReply(amount, file_sizes));
470a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
471a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
472f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)std::string PepperFileSystemBrowserHost::GetPluginMimeType() const {
473f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  base::FilePath plugin_path = browser_ppapi_host_->GetPluginPath();
474f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  PepperPluginInfo* info =
475f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      PluginService::GetInstance()->GetRegisteredPpapiPluginInfo(plugin_path);
476f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (!info || info->mime_types.empty())
477f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return std::string();
478f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Use the first element in |info->mime_types| even if several elements exist.
479f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return info->mime_types[0].mime_type;
480f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
481f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
482f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)std::string PepperFileSystemBrowserHost::GeneratePluginId(
483f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const std::string& mime_type) const {
484f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // TODO(nhiroki): This function is very specialized for specific plugins (MIME
485f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // types).  If we bring this API to stable, we might have to make it more
486f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // general.
487f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
488cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  std::string top_level_type;
489cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  std::string subtype;
490cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (!net::ParseMimeTypeWithoutParameter(
491cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          mime_type, &top_level_type, &subtype) ||
492cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      !net::IsValidTopLevelMimeType(top_level_type))
493f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return std::string();
494f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
495f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Replace a slash used for type/subtype separator with an underscore.
496cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  std::string output = top_level_type + "_" + subtype;
497f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
498f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Verify |output| contains only alphabets, digits, or "._-".
499a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  for (std::string::const_iterator it = output.begin(); it != output.end();
500a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch       ++it) {
501a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    if (!IsAsciiAlpha(*it) && !IsAsciiDigit(*it) && *it != '.' && *it != '_' &&
502a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        *it != '-') {
503f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      LOG(WARNING) << "Failed to generate a plugin id.";
504f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      return std::string();
505f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    }
506f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
507f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return output;
508f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
509f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
5107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}  // namespace content
511