pepper_file_system_browser_host.cc revision cedac228d2dd51db4b79ea1e72c7f249408ee061
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"
117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "content/public/browser/browser_ppapi_host.h"
127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "content/public/browser/browser_thread.h"
13f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "content/public/browser/plugin_service.h"
147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "content/public/browser/render_process_host.h"
157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "content/public/browser/storage_partition.h"
16f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "content/public/common/pepper_plugin_info.h"
17f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "net/base/mime_util.h"
187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "ppapi/c/pp_errors.h"
197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "ppapi/host/dispatch_host_message.h"
207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "ppapi/host/ppapi_host.h"
217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "ppapi/proxy/ppapi_messages.h"
22f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "ppapi/shared_impl/file_system_util.h"
237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "ppapi/shared_impl/file_type_conversion.h"
247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "webkit/browser/fileapi/file_system_operation_runner.h"
25f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "webkit/browser/fileapi/isolated_context.h"
265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "webkit/browser/quota/quota_manager_proxy.h"
277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "webkit/common/fileapi/file_system_util.h"
285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "webkit/common/quota/quota_types.h"
297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)namespace content {
317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)namespace {
337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
34a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// This is the minimum amount of quota we reserve per file system.
35a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)const int64_t kMinimumQuotaReservationSize = 1024 * 1024;  // 1 MB
36a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
37a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochscoped_refptr<fileapi::FileSystemContext> GetFileSystemContextFromRenderId(
38a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    int render_process_id) {
39effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  DCHECK_CURRENTLY_ON(BrowserThread::UI);
400f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  RenderProcessHost* host = RenderProcessHost::FromID(render_process_id);
410f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  if (!host)
427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return NULL;
430f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  StoragePartition* storage_partition = host->GetStoragePartition();
447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (!storage_partition)
457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return NULL;
467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return storage_partition->GetFileSystemContext();
477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}  // namespace
507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)PepperFileSystemBrowserHost::PepperFileSystemBrowserHost(BrowserPpapiHost* host,
527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                                         PP_Instance instance,
537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                                         PP_Resource resource,
547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                                         PP_FileSystemType type)
557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    : ResourceHost(host->GetPpapiHost(), instance, resource),
567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      browser_ppapi_host_(host),
577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      type_(type),
583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      called_open_(false),
59f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      opened_(false),
60f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      file_system_context_(NULL),
61a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      reserved_quota_(0),
62a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      reserving_quota_(false),
63a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      weak_factory_(this) {}
647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
65f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)PepperFileSystemBrowserHost::~PepperFileSystemBrowserHost() {
665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // If |files_| is not empty, the plugin failed to close some files. It must
675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // have crashed.
685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!files_.empty()) {
695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    file_system_context_->default_file_task_runner()->PostTask(
705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        FROM_HERE,
715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        base::Bind(&QuotaReservation::OnClientCrash, quota_reservation_));
725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
74f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // All FileRefs and FileIOs that reference us must have been destroyed. Cancel
75f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // all pending file system operations.
76f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (file_system_operation_runner_)
77f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    file_system_operation_runner_->Shutdown();
78f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
79f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
800f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)void PepperFileSystemBrowserHost::OpenExisting(const GURL& root_url,
810f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                                               const base::Closure& callback) {
820f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  root_url_ = root_url;
830f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  int render_process_id = 0;
840f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  int unused;
855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!browser_ppapi_host_->GetRenderFrameIDsForInstance(
86a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch          pp_instance(), &render_process_id, &unused)) {
870f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    NOTREACHED();
880f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  }
890f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  called_open_ = true;
900f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // Get the file system context asynchronously, and then complete the Open
910f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // operation by calling |callback|.
920f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  BrowserThread::PostTaskAndReplyWithResult(
930f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      BrowserThread::UI,
940f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      FROM_HERE,
950f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      base::Bind(&GetFileSystemContextFromRenderId, render_process_id),
96a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      base::Bind(&PepperFileSystemBrowserHost::OpenExistingFileSystem,
97a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                 weak_factory_.GetWeakPtr(),
98a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                 callback));
994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
1004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)int32_t PepperFileSystemBrowserHost::OnResourceMessageReceived(
1027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    const IPC::Message& msg,
1037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    ppapi::host::HostMessageContext* context) {
104cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  PPAPI_BEGIN_MESSAGE_MAP(PepperFileSystemBrowserHost, msg)
105cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_FileSystem_Open,
106cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                      OnHostMsgOpen)
107cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    PPAPI_DISPATCH_HOST_RESOURCE_CALL(
108cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        PpapiHostMsg_FileSystem_InitIsolatedFileSystem,
109cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        OnHostMsgInitIsolatedFileSystem)
110cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_FileSystem_ReserveQuota,
111cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                      OnHostMsgReserveQuota)
112cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  PPAPI_END_MESSAGE_MAP()
1137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return PP_ERROR_FAILED;
1147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
1157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
116a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochbool PepperFileSystemBrowserHost::IsFileSystemHost() { return true; }
1177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
118a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void PepperFileSystemBrowserHost::OpenQuotaFile(
119a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    PepperFileIOHost* file_io_host,
1205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const fileapi::FileSystemURL& url,
121a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    const OpenQuotaFileCallback& callback) {
122a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  int32_t id = file_io_host->pp_resource();
123a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  std::pair<FileMap::iterator, bool> insert_result =
124a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      files_.insert(std::make_pair(id, file_io_host));
125a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (insert_result.second) {
126a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    base::PostTaskAndReplyWithResult(
127a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        file_system_context_->default_file_task_runner(),
128a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        FROM_HERE,
129a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        base::Bind(&QuotaReservation::OpenFile, quota_reservation_, id, url),
130a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        callback);
131a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  } else {
132a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    NOTREACHED();
133a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
134a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
135a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
136a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void PepperFileSystemBrowserHost::CloseQuotaFile(
1375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    PepperFileIOHost* file_io_host,
1385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const ppapi::FileGrowth& file_growth) {
139a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  int32_t id = file_io_host->pp_resource();
140a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  FileMap::iterator it = files_.find(id);
141a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (it != files_.end()) {
142a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    files_.erase(it);
143a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  } else {
144a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    NOTREACHED();
145a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    return;
146a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
147a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
148a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  file_system_context_->default_file_task_runner()->PostTask(
149a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      FROM_HERE,
150a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      base::Bind(
151a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch          &QuotaReservation::CloseFile, quota_reservation_, id, file_growth));
152a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
153a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
1547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)int32_t PepperFileSystemBrowserHost::OnHostMsgOpen(
1557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    ppapi::host::HostMessageContext* context,
1567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    int64_t /* unused */) {
1577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // TODO(raymes): The file system size is now unused by FileSystemDispatcher.
1587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Figure out why. Why is the file system size signed?
1597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Not allow multiple opens.
1617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (called_open_)
1627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return PP_ERROR_INPROGRESS;
1637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  called_open_ = true;
1647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
165f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  fileapi::FileSystemType file_system_type =
166f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      ppapi::PepperFileSystemTypeToFileSystemType(type_);
167f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (file_system_type == fileapi::kFileSystemTypeUnknown)
168f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return PP_ERROR_FAILED;
1697d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  int render_process_id = 0;
1717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  int unused;
172a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  if (!browser_ppapi_host_->GetRenderFrameIDsForInstance(
173a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch          pp_instance(), &render_process_id, &unused)) {
174a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    return PP_ERROR_FAILED;
1757d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
176f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  BrowserThread::PostTaskAndReplyWithResult(
1787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      BrowserThread::UI,
1797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      FROM_HERE,
1807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&GetFileSystemContextFromRenderId, render_process_id),
181a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      base::Bind(&PepperFileSystemBrowserHost::OpenFileSystem,
1827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                 weak_factory_.GetWeakPtr(),
1837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                 context->MakeReplyMessageContext(),
1847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                 file_system_type));
1857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return PP_OK_COMPLETIONPENDING;
1867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
1877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
188a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void PepperFileSystemBrowserHost::OpenExistingFileSystem(
1890f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    const base::Closure& callback,
190f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    scoped_refptr<fileapi::FileSystemContext> file_system_context) {
191f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (file_system_context.get()) {
1920f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    opened_ = true;
1930f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  } else {
1940f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    // If there is no file system context, we log a warning and continue with an
1950f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    // invalid resource (which will produce errors when used), since we have no
1960f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    // way to communicate the error to the caller.
1970f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    LOG(WARNING) << "Could not retrieve file system context.";
1980f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  }
199f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  SetFileSystemContext(file_system_context);
200a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
2015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (ShouldCreateQuotaReservation())
2025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    CreateQuotaReservation(callback);
2035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  else
2045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    callback.Run();
2050f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)}
2060f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
207a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void PepperFileSystemBrowserHost::OpenFileSystem(
2087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    ppapi::host::ReplyMessageContext reply_context,
2097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    fileapi::FileSystemType file_system_type,
210f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    scoped_refptr<fileapi::FileSystemContext> file_system_context) {
211f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (!file_system_context.get()) {
212eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    OpenFileSystemComplete(
2135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        reply_context, GURL(), std::string(), base::File::FILE_ERROR_FAILED);
2147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return;
2157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
216a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
217a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  SetFileSystemContext(file_system_context);
218a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
219a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  GURL origin =
220a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      browser_ppapi_host_->GetDocumentURLForInstance(pp_instance()).GetOrigin();
221a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  file_system_context_->OpenFileSystem(
222a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      origin,
223a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      file_system_type,
2247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      fileapi::OPEN_FILE_SYSTEM_CREATE_IF_NONEXISTENT,
2257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&PepperFileSystemBrowserHost::OpenFileSystemComplete,
226a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                 weak_factory_.GetWeakPtr(),
227a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                 reply_context));
228424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}
229424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
2307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void PepperFileSystemBrowserHost::OpenFileSystemComplete(
2317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    ppapi::host::ReplyMessageContext reply_context,
2324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    const GURL& root,
2337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    const std::string& /* unused */,
2345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::File::Error error) {
2355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int32 pp_error = ppapi::FileErrorToPepperError(error);
2367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (pp_error == PP_OK) {
2377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    opened_ = true;
2387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    root_url_ = root;
239a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
2405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (ShouldCreateQuotaReservation()) {
2415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      CreateQuotaReservation(
2425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          base::Bind(&PepperFileSystemBrowserHost::SendReplyForFileSystem,
2435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                     weak_factory_.GetWeakPtr(),
2445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                     reply_context,
2455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                     static_cast<int32_t>(PP_OK)));
246a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      return;
2475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
2487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
249a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  SendReplyForFileSystem(reply_context, pp_error);
2507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
2517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
252a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void PepperFileSystemBrowserHost::OpenIsolatedFileSystem(
253f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    ppapi::host::ReplyMessageContext reply_context,
254f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const std::string& fsid,
255f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    PP_IsolatedFileSystemType_Private type,
256f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    scoped_refptr<fileapi::FileSystemContext> file_system_context) {
257f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (!file_system_context.get()) {
258f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    SendReplyForIsolatedFileSystem(reply_context, fsid, PP_ERROR_FAILED);
259f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return;
260f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
261f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  SetFileSystemContext(file_system_context);
262f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
263f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  root_url_ = GURL(fileapi::GetIsolatedFileSystemRootURIString(
264f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      browser_ppapi_host_->GetDocumentURLForInstance(pp_instance()).GetOrigin(),
265a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      fsid,
266a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      ppapi::IsolatedFileSystemTypeToRootName(type)));
267f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (!root_url_.is_valid()) {
268f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    SendReplyForIsolatedFileSystem(reply_context, fsid, PP_ERROR_FAILED);
269f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return;
270f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
271f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
272f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  switch (type) {
273f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    case PP_ISOLATEDFILESYSTEMTYPE_PRIVATE_CRX:
274f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      opened_ = true;
275f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      SendReplyForIsolatedFileSystem(reply_context, fsid, PP_OK);
276f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      return;
277f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    case PP_ISOLATEDFILESYSTEMTYPE_PRIVATE_PLUGINPRIVATE:
278f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      OpenPluginPrivateFileSystem(reply_context, fsid, file_system_context_);
279f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      return;
280f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    default:
281f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      NOTREACHED();
282f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      SendReplyForIsolatedFileSystem(reply_context, fsid, PP_ERROR_BADARGUMENT);
283f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      return;
284f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
285f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
286f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
287f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void PepperFileSystemBrowserHost::OpenPluginPrivateFileSystem(
288f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    ppapi::host::ReplyMessageContext reply_context,
289f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const std::string& fsid,
290f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    scoped_refptr<fileapi::FileSystemContext> file_system_context) {
291a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  GURL origin =
292a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      browser_ppapi_host_->GetDocumentURLForInstance(pp_instance()).GetOrigin();
293f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (!origin.is_valid()) {
294f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    SendReplyForIsolatedFileSystem(reply_context, fsid, PP_ERROR_FAILED);
295f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return;
296f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
297f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
298f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const std::string& plugin_id = GeneratePluginId(GetPluginMimeType());
299f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (plugin_id.empty()) {
300f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    SendReplyForIsolatedFileSystem(reply_context, fsid, PP_ERROR_BADARGUMENT);
301f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return;
302f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
303f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
304f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  file_system_context->OpenPluginPrivateFileSystem(
305a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      origin,
306a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      fileapi::kFileSystemTypePluginPrivate,
307a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      fsid,
308a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      plugin_id,
309f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      fileapi::OPEN_FILE_SYSTEM_CREATE_IF_NONEXISTENT,
310f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      base::Bind(
311f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)          &PepperFileSystemBrowserHost::OpenPluginPrivateFileSystemComplete,
312a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch          weak_factory_.GetWeakPtr(),
313a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch          reply_context,
314a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch          fsid));
315f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
316f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
317f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void PepperFileSystemBrowserHost::OpenPluginPrivateFileSystemComplete(
318f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    ppapi::host::ReplyMessageContext reply_context,
319f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const std::string& fsid,
3205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::File::Error error) {
3215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int32 pp_error = ppapi::FileErrorToPepperError(error);
322f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (pp_error == PP_OK)
323f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    opened_ = true;
324f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  SendReplyForIsolatedFileSystem(reply_context, fsid, pp_error);
325f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
326f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
3277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)int32_t PepperFileSystemBrowserHost::OnHostMsgInitIsolatedFileSystem(
3287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    ppapi::host::HostMessageContext* context,
329f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const std::string& fsid,
330f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    PP_IsolatedFileSystemType_Private type) {
3314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Do not allow multiple opens.
3324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (called_open_)
3334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return PP_ERROR_INPROGRESS;
3347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  called_open_ = true;
335f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
3367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Do a sanity check.
3371e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (!fileapi::ValidateIsolatedFileSystemId(fsid))
3387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return PP_ERROR_BADARGUMENT;
339424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
340424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  int render_process_id = 0;
341424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  int unused;
342a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  if (!browser_ppapi_host_->GetRenderFrameIDsForInstance(
343a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch          pp_instance(), &render_process_id, &unused)) {
344f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    fileapi::IsolatedContext::GetInstance()->RevokeFileSystem(fsid);
345424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    return PP_ERROR_FAILED;
346424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  }
347f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
348a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  root_url_ = GURL(fileapi::GetIsolatedFileSystemRootURIString(
349a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      browser_ppapi_host_->GetDocumentURLForInstance(pp_instance()).GetOrigin(),
350a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      fsid,
351a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      ppapi::IsolatedFileSystemTypeToRootName(type)));
352a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
353424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  BrowserThread::PostTaskAndReplyWithResult(
354424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      BrowserThread::UI,
355424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      FROM_HERE,
356424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      base::Bind(&GetFileSystemContextFromRenderId, render_process_id),
357a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      base::Bind(&PepperFileSystemBrowserHost::OpenIsolatedFileSystem,
358424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)                 weak_factory_.GetWeakPtr(),
359a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                 context->MakeReplyMessageContext(),
360a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                 fsid,
361a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                 type));
362424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  return PP_OK_COMPLETIONPENDING;
3637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
3647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)int32_t PepperFileSystemBrowserHost::OnHostMsgReserveQuota(
3665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ppapi::host::HostMessageContext* context,
3675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    int64_t amount,
3685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const ppapi::FileGrowthMap& file_growths) {
3695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(ChecksQuota());
370a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  DCHECK_GT(amount, 0);
3715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (reserving_quota_)
3735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return PP_ERROR_INPROGRESS;
3745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  reserving_quota_ = true;
3755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
376a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  int64_t reservation_amount =
377a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      std::max<int64_t>(kMinimumQuotaReservationSize, amount);
3785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  file_system_context_->default_file_task_runner()->PostTask(
3795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      FROM_HERE,
3805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::Bind(&QuotaReservation::ReserveQuota,
3815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                 quota_reservation_,
3825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                 reservation_amount,
3835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                 file_growths,
3845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                 base::Bind(&PepperFileSystemBrowserHost::GotReservedQuota,
3855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                            weak_factory_.GetWeakPtr(),
3865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                            context->MakeReplyMessageContext())));
3875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return PP_OK_COMPLETIONPENDING;
3895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
3905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
391a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void PepperFileSystemBrowserHost::SendReplyForFileSystem(
392a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    ppapi::host::ReplyMessageContext reply_context,
393a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    int32_t pp_error) {
394a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  reply_context.params.set_result(pp_error);
395a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  host()->SendReply(reply_context, PpapiPluginMsg_FileSystem_OpenReply());
396a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
397a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
398f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void PepperFileSystemBrowserHost::SendReplyForIsolatedFileSystem(
399f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    ppapi::host::ReplyMessageContext reply_context,
400f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const std::string& fsid,
401f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    int32_t error) {
402f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (error != PP_OK)
403f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    fileapi::IsolatedContext::GetInstance()->RevokeFileSystem(fsid);
404f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  reply_context.params.set_result(error);
405f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  host()->SendReply(reply_context,
406f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                    PpapiPluginMsg_FileSystem_InitIsolatedFileSystemReply());
407f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
408f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
409f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void PepperFileSystemBrowserHost::SetFileSystemContext(
410f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    scoped_refptr<fileapi::FileSystemContext> file_system_context) {
411f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  file_system_context_ = file_system_context;
412a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  if (type_ != PP_FILESYSTEMTYPE_EXTERNAL || root_url_.is_valid()) {
413f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    file_system_operation_runner_ =
414f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        file_system_context_->CreateFileSystemOperationRunner();
415f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
416f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
417f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
4185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool PepperFileSystemBrowserHost::ShouldCreateQuotaReservation() const {
4195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Some file system types don't have quota.
420a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (!ppapi::FileSystemTypeHasQuota(type_))
4215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return false;
422a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
4235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // For file system types with quota, some origins have unlimited storage.
4245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  quota::QuotaManagerProxy* quota_manager_proxy =
4255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      file_system_context_->quota_manager_proxy();
4265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  CHECK(quota_manager_proxy);
4275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  CHECK(quota_manager_proxy->quota_manager());
4285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  fileapi::FileSystemType file_system_type =
4295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      ppapi::PepperFileSystemTypeToFileSystemType(type_);
4305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return !quota_manager_proxy->quota_manager()->IsStorageUnlimited(
4315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      root_url_.GetOrigin(),
4325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      fileapi::FileSystemTypeToQuotaStorageType(file_system_type));
4335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
4345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void PepperFileSystemBrowserHost::CreateQuotaReservation(
4365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const base::Closure& callback) {
437a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  DCHECK(root_url_.is_valid());
438a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  base::PostTaskAndReplyWithResult(
439a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      file_system_context_->default_file_task_runner(),
440a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      FROM_HERE,
441a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      base::Bind(&QuotaReservation::Create,
442a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                 file_system_context_,
443a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                 root_url_.GetOrigin(),
444a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                 ppapi::PepperFileSystemTypeToFileSystemType(type_)),
445a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      base::Bind(&PepperFileSystemBrowserHost::GotQuotaReservation,
446a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                 weak_factory_.GetWeakPtr(),
447a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                 callback));
448a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
449a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
450a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void PepperFileSystemBrowserHost::GotQuotaReservation(
451a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    const base::Closure& callback,
452a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    scoped_refptr<QuotaReservation> quota_reservation) {
453a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  quota_reservation_ = quota_reservation;
454a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  callback.Run();
455a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
456a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
457a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void PepperFileSystemBrowserHost::GotReservedQuota(
4585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ppapi::host::ReplyMessageContext reply_context,
459a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    int64_t amount,
4605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const ppapi::FileSizeMap& file_sizes) {
461a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  DCHECK(reserving_quota_);
462a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  reserving_quota_ = false;
463a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  reserved_quota_ = amount;
464a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
4655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  reply_context.params.set_result(PP_OK);
4665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  host()->SendReply(
4675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      reply_context,
4685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      PpapiPluginMsg_FileSystem_ReserveQuotaReply(amount, file_sizes));
469a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
470a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
471f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)std::string PepperFileSystemBrowserHost::GetPluginMimeType() const {
472f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  base::FilePath plugin_path = browser_ppapi_host_->GetPluginPath();
473f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  PepperPluginInfo* info =
474f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      PluginService::GetInstance()->GetRegisteredPpapiPluginInfo(plugin_path);
475f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (!info || info->mime_types.empty())
476f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return std::string();
477f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Use the first element in |info->mime_types| even if several elements exist.
478f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return info->mime_types[0].mime_type;
479f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
480f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
481f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)std::string PepperFileSystemBrowserHost::GeneratePluginId(
482f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const std::string& mime_type) const {
483f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // TODO(nhiroki): This function is very specialized for specific plugins (MIME
484f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // types).  If we bring this API to stable, we might have to make it more
485f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // general.
486f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
487cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  std::string top_level_type;
488cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  std::string subtype;
489cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (!net::ParseMimeTypeWithoutParameter(
490cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          mime_type, &top_level_type, &subtype) ||
491cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      !net::IsValidTopLevelMimeType(top_level_type))
492f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return std::string();
493f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
494f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Replace a slash used for type/subtype separator with an underscore.
495cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  std::string output = top_level_type + "_" + subtype;
496f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
497f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Verify |output| contains only alphabets, digits, or "._-".
498a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  for (std::string::const_iterator it = output.begin(); it != output.end();
499a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch       ++it) {
500a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    if (!IsAsciiAlpha(*it) && !IsAsciiDigit(*it) && *it != '.' && *it != '_' &&
501a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        *it != '-') {
502f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      LOG(WARNING) << "Failed to generate a plugin id.";
503f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      return std::string();
504f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    }
505f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
506f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return output;
507f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
508f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
5097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}  // namespace content
510