15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/browser/fileapi/fileapi_message_filter.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string>
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector>
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h"
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/file_path.h"
122385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#include "base/logging.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/sequenced_task_runner.h"
152385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#include "base/strings/string_util.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/threading/thread.h"
17eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/time/time.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/browser/child_process_security_policy_impl.h"
19a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "content/browser/fileapi/blob_storage_host.h"
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/browser/fileapi/browser_file_system_helper.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/browser/fileapi/chrome_blob_storage_context.h"
222385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#include "content/browser/streams/stream_registry.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/common/fileapi/file_system_messages.h"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/common/fileapi/webblob_messages.h"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/user_metrics.h"
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ipc/ipc_platform_file.h"
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/mime_util.h"
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request_context.h"
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request_context_getter.h"
301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/blob/blob_storage_context.h"
311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/file_observers.h"
321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/file_permission_policy.h"
331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/file_system_context.h"
341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/isolated_context.h"
351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/common/blob/blob_data.h"
361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/common/blob/shareable_file_reference.h"
371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/common/fileapi/directory_entry.h"
381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/common/fileapi/file_system_info.h"
391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/common/fileapi/file_system_types.h"
401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/common/fileapi/file_system_util.h"
417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "url/gurl.h"
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)using storage::FileSystemFileUtil;
4403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)using storage::FileSystemBackend;
4503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)using storage::FileSystemOperation;
4603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)using storage::FileSystemURL;
4703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)using storage::BlobData;
4803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)using storage::BlobStorageContext;
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace content {
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const uint32 kFilteredMessageClasses[] = {
555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  BlobMsgStart,
565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  FileSystemMsgStart,
575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)};
585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void RevokeFilePermission(int child_id, const base::FilePath& path) {
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ChildProcessSecurityPolicyImpl::GetInstance()->RevokeAllPermissionsForFile(
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    child_id, path);
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)FileAPIMessageFilter::FileAPIMessageFilter(
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int process_id,
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    net::URLRequestContextGetter* request_context_getter,
6903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    storage::FileSystemContext* file_system_context,
702385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    ChromeBlobStorageContext* blob_storage_context,
712385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    StreamContext* stream_context)
7203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    : BrowserMessageFilter(kFilteredMessageClasses,
7303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                           arraysize(kFilteredMessageClasses)),
745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      process_id_(process_id),
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      context_(file_system_context),
76d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      security_policy_(ChildProcessSecurityPolicyImpl::GetInstance()),
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      request_context_getter_(request_context_getter),
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      request_context_(NULL),
792385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      blob_storage_context_(blob_storage_context),
802385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      stream_context_(stream_context) {
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(context_);
82868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK(request_context_getter_.get());
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(blob_storage_context);
842385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  DCHECK(stream_context);
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)FileAPIMessageFilter::FileAPIMessageFilter(
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int process_id,
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    net::URLRequestContext* request_context,
9003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    storage::FileSystemContext* file_system_context,
912385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    ChromeBlobStorageContext* blob_storage_context,
922385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    StreamContext* stream_context)
9303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    : BrowserMessageFilter(kFilteredMessageClasses,
9403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                           arraysize(kFilteredMessageClasses)),
955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      process_id_(process_id),
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      context_(file_system_context),
97d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      security_policy_(ChildProcessSecurityPolicyImpl::GetInstance()),
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      request_context_(request_context),
992385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      blob_storage_context_(blob_storage_context),
1002385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      stream_context_(stream_context) {
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(context_);
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(request_context_);
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(blob_storage_context);
1042385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  DCHECK(stream_context);
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FileAPIMessageFilter::OnChannelConnected(int32 peer_pid) {
108bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
110868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (request_context_getter_.get()) {
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(!request_context_);
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request_context_ = request_context_getter_->GetURLRequestContext();
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request_context_getter_ = NULL;
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(request_context_);
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
116bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch
11758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  blob_storage_host_.reset(
11858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      new BlobStorageHost(blob_storage_context_->context()));
11958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
120bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  operation_runner_ = context_->CreateFileSystemOperationRunner();
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FileAPIMessageFilter::OnChannelClosing() {
124bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1262385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  // Unregister all the blob and stream URLs that are previously registered in
1272385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  // this process.
12858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  blob_storage_host_.reset();
1292385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  for (base::hash_set<std::string>::const_iterator iter = stream_urls_.begin();
1302385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch       iter != stream_urls_.end(); ++iter) {
1312385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    stream_context_->registry()->UnregisterStream(GURL(*iter));
1322385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  }
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  in_transit_snapshot_files_.clear();
1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
136bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  operation_runner_.reset();
137868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  operations_.clear();
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)base::TaskRunner* FileAPIMessageFilter::OverrideTaskRunnerForMessage(
1417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    const IPC::Message& message) {
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (message.type() == FileSystemHostMsg_SyncGetPlatformPath::ID)
143a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    return context_->default_file_task_runner();
1447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return NULL;
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
147cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)bool FileAPIMessageFilter::OnMessageReceived(const IPC::Message& message) {
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool handled = true;
149cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  IPC_BEGIN_MESSAGE_MAP(FileAPIMessageFilter, message)
1504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    IPC_MESSAGE_HANDLER(FileSystemHostMsg_OpenFileSystem, OnOpenFileSystem)
15168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    IPC_MESSAGE_HANDLER(FileSystemHostMsg_ResolveURL, OnResolveURL)
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER(FileSystemHostMsg_DeleteFileSystem, OnDeleteFileSystem)
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER(FileSystemHostMsg_Move, OnMove)
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER(FileSystemHostMsg_Copy, OnCopy)
1554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    IPC_MESSAGE_HANDLER(FileSystemHostMsg_Remove, OnRemove)
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER(FileSystemHostMsg_ReadMetadata, OnReadMetadata)
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER(FileSystemHostMsg_Create, OnCreate)
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER(FileSystemHostMsg_Exists, OnExists)
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER(FileSystemHostMsg_ReadDirectory, OnReadDirectory)
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER(FileSystemHostMsg_Write, OnWrite)
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER(FileSystemHostMsg_Truncate, OnTruncate)
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER(FileSystemHostMsg_TouchFile, OnTouchFile)
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER(FileSystemHostMsg_CancelWrite, OnCancel)
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER(FileSystemHostMsg_CreateSnapshotFile,
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        OnCreateSnapshotFile)
1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    IPC_MESSAGE_HANDLER(FileSystemHostMsg_DidReceiveSnapshotFile,
1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                        OnDidReceiveSnapshotFile)
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER(FileSystemHostMsg_SyncGetPlatformPath,
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        OnSyncGetPlatformPath)
1702385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    IPC_MESSAGE_HANDLER(BlobHostMsg_StartBuilding, OnStartBuildingBlob)
1712385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    IPC_MESSAGE_HANDLER(BlobHostMsg_AppendBlobDataItem,
1722385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch                        OnAppendBlobDataItemToBlob)
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER(BlobHostMsg_SyncAppendSharedMemory,
1742385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch                        OnAppendSharedMemoryToBlob)
1752385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    IPC_MESSAGE_HANDLER(BlobHostMsg_FinishBuilding, OnFinishBuildingBlob)
17658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    IPC_MESSAGE_HANDLER(BlobHostMsg_IncrementRefCount,
17758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                        OnIncrementBlobRefCount)
17858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    IPC_MESSAGE_HANDLER(BlobHostMsg_DecrementRefCount,
17958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                        OnDecrementBlobRefCount)
18058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    IPC_MESSAGE_HANDLER(BlobHostMsg_RegisterPublicURL,
18158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                        OnRegisterPublicBlobURL)
18258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    IPC_MESSAGE_HANDLER(BlobHostMsg_RevokePublicURL, OnRevokePublicBlobURL)
1832385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    IPC_MESSAGE_HANDLER(StreamHostMsg_StartBuilding, OnStartBuildingStream)
1842385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    IPC_MESSAGE_HANDLER(StreamHostMsg_AppendBlobDataItem,
1852385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch                        OnAppendBlobDataItemToStream)
1862385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    IPC_MESSAGE_HANDLER(StreamHostMsg_SyncAppendSharedMemory,
1872385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch                        OnAppendSharedMemoryToStream)
1882385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    IPC_MESSAGE_HANDLER(StreamHostMsg_FinishBuilding, OnFinishBuildingStream)
189424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    IPC_MESSAGE_HANDLER(StreamHostMsg_AbortBuilding, OnAbortBuildingStream)
1902385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    IPC_MESSAGE_HANDLER(StreamHostMsg_Clone, OnCloneStream)
1912385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    IPC_MESSAGE_HANDLER(StreamHostMsg_Remove, OnRemoveStream)
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_UNHANDLED(handled = false)
193cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  IPC_END_MESSAGE_MAP()
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return handled;
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)FileAPIMessageFilter::~FileAPIMessageFilter() {}
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FileAPIMessageFilter::BadMessageReceived() {
2005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  RecordAction(base::UserMetricsAction("BadMessageTerminate_FAMF"));
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BrowserMessageFilter::BadMessageReceived();
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void FileAPIMessageFilter::OnOpenFileSystem(int request_id,
2054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                            const GURL& origin_url,
20603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                                            storage::FileSystemType type) {
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
20803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  if (type == storage::kFileSystemTypeTemporary) {
2095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    RecordAction(base::UserMetricsAction("OpenFileSystemTemporary"));
21003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  } else if (type == storage::kFileSystemTypePersistent) {
2115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    RecordAction(base::UserMetricsAction("OpenFileSystemPersistent"));
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
21303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  storage::OpenFileSystemMode mode =
21403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      storage::OPEN_FILE_SYSTEM_CREATE_IF_NONEXISTENT;
21590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  context_->OpenFileSystem(origin_url, type, mode, base::Bind(
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &FileAPIMessageFilter::DidOpenFileSystem, this, request_id));
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void FileAPIMessageFilter::OnResolveURL(
22068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    int request_id,
22168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    const GURL& filesystem_url) {
22268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
22368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  FileSystemURL url(context_->CrackURL(filesystem_url));
22468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  if (!ValidateFileSystemURL(request_id, url))
22568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    return;
22668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  if (!security_policy_->CanReadFileSystemFile(process_id_, url)) {
22768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    Send(new FileSystemMsg_DidFail(request_id,
2285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                   base::File::FILE_ERROR_SECURITY));
22968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    return;
23068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  }
23168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
23268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  context_->ResolveURL(url, base::Bind(
23368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      &FileAPIMessageFilter::DidResolveURL, this, request_id));
23468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
23568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
23603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)void FileAPIMessageFilter::OnDeleteFileSystem(int request_id,
23703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                                              const GURL& origin_url,
23803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                                              storage::FileSystemType type) {
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  context_->DeleteFileSystem(origin_url, type, base::Bind(
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &FileAPIMessageFilter::DidDeleteFileSystem, this, request_id));
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FileAPIMessageFilter::OnMove(
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int request_id, const GURL& src_path, const GURL& dest_path) {
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FileSystemURL src_url(context_->CrackURL(src_path));
2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FileSystemURL dest_url(context_->CrackURL(dest_path));
249d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  if (!ValidateFileSystemURL(request_id, src_url) ||
250d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      !ValidateFileSystemURL(request_id, dest_url)) {
251d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    return;
252d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  }
253d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  if (!security_policy_->CanReadFileSystemFile(process_id_, src_url) ||
2548bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      !security_policy_->CanDeleteFileSystemFile(process_id_, src_url) ||
255d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      !security_policy_->CanCreateFileSystemFile(process_id_, dest_url)) {
256d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    Send(new FileSystemMsg_DidFail(request_id,
2575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                   base::File::FILE_ERROR_SECURITY));
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
261868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  operations_[request_id] = operation_runner()->Move(
26203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      src_url,
26303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      dest_url,
26403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      storage::FileSystemOperation::OPTION_NONE,
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&FileAPIMessageFilter::DidFinish, this, request_id));
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FileAPIMessageFilter::OnCopy(
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int request_id, const GURL& src_path, const GURL& dest_path) {
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FileSystemURL src_url(context_->CrackURL(src_path));
2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FileSystemURL dest_url(context_->CrackURL(dest_path));
273d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  if (!ValidateFileSystemURL(request_id, src_url) ||
274d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      !ValidateFileSystemURL(request_id, dest_url)) {
275d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    return;
276d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  }
277d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  if (!security_policy_->CanReadFileSystemFile(process_id_, src_url) ||
2784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      !security_policy_->CanCopyIntoFileSystemFile(process_id_, dest_url)) {
279d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    Send(new FileSystemMsg_DidFail(request_id,
2805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                   base::File::FILE_ERROR_SECURITY));
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
284868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  operations_[request_id] = operation_runner()->Copy(
28503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      src_url,
28603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      dest_url,
28703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      storage::FileSystemOperation::OPTION_NONE,
28803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      storage::FileSystemOperationRunner::CopyProgressCallback(),
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&FileAPIMessageFilter::DidFinish, this, request_id));
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FileAPIMessageFilter::OnRemove(
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int request_id, const GURL& path, bool recursive) {
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FileSystemURL url(context_->CrackURL(path));
296d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  if (!ValidateFileSystemURL(request_id, url))
297d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    return;
2988bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (!security_policy_->CanDeleteFileSystemFile(process_id_, url)) {
299d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    Send(new FileSystemMsg_DidFail(request_id,
3005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                   base::File::FILE_ERROR_SECURITY));
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
304868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  operations_[request_id] = operation_runner()->Remove(
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      url, recursive,
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&FileAPIMessageFilter::DidFinish, this, request_id));
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FileAPIMessageFilter::OnReadMetadata(
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int request_id, const GURL& path) {
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FileSystemURL url(context_->CrackURL(path));
313d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  if (!ValidateFileSystemURL(request_id, url))
314d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    return;
315d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  if (!security_policy_->CanReadFileSystemFile(process_id_, url)) {
316d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    Send(new FileSystemMsg_DidFail(request_id,
3175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                   base::File::FILE_ERROR_SECURITY));
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
321868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  operations_[request_id] = operation_runner()->GetMetadata(
322868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      url, base::Bind(&FileAPIMessageFilter::DidGetMetadata, this, request_id));
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FileAPIMessageFilter::OnCreate(
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int request_id, const GURL& path, bool exclusive,
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool is_directory, bool recursive) {
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FileSystemURL url(context_->CrackURL(path));
330d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  if (!ValidateFileSystemURL(request_id, url))
331d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    return;
332d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  if (!security_policy_->CanCreateFileSystemFile(process_id_, url)) {
333d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    Send(new FileSystemMsg_DidFail(request_id,
3345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                   base::File::FILE_ERROR_SECURITY));
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (is_directory) {
339868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    operations_[request_id] = operation_runner()->CreateDirectory(
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        url, exclusive, recursive,
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&FileAPIMessageFilter::DidFinish, this, request_id));
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
343868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    operations_[request_id] = operation_runner()->CreateFile(
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        url, exclusive,
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&FileAPIMessageFilter::DidFinish, this, request_id));
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FileAPIMessageFilter::OnExists(
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int request_id, const GURL& path, bool is_directory) {
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
3522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FileSystemURL url(context_->CrackURL(path));
353d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  if (!ValidateFileSystemURL(request_id, url))
354d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    return;
355d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  if (!security_policy_->CanReadFileSystemFile(process_id_, url)) {
356d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    Send(new FileSystemMsg_DidFail(request_id,
3575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                   base::File::FILE_ERROR_SECURITY));
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (is_directory) {
362868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    operations_[request_id] = operation_runner()->DirectoryExists(
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        url,
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&FileAPIMessageFilter::DidFinish, this, request_id));
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
366868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    operations_[request_id] = operation_runner()->FileExists(
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        url,
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&FileAPIMessageFilter::DidFinish, this, request_id));
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FileAPIMessageFilter::OnReadDirectory(
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int request_id, const GURL& path) {
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
3752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FileSystemURL url(context_->CrackURL(path));
376d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  if (!ValidateFileSystemURL(request_id, url))
377d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    return;
378d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  if (!security_policy_->CanReadFileSystemFile(process_id_, url)) {
379d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    Send(new FileSystemMsg_DidFail(request_id,
3805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                   base::File::FILE_ERROR_SECURITY));
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
384868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  operations_[request_id] = operation_runner()->ReadDirectory(
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      url, base::Bind(&FileAPIMessageFilter::DidReadDirectory,
386868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                      this, request_id));
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
38958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void FileAPIMessageFilter::OnWrite(
39058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    int request_id,
39158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    const GURL& path,
39258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    const std::string& blob_uuid,
39358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    int64 offset) {
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!request_context_) {
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // We can't write w/o a request context, trying to do so will crash.
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NOTREACHED();
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FileSystemURL url(context_->CrackURL(path));
402d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  if (!ValidateFileSystemURL(request_id, url))
403d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    return;
404d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  if (!security_policy_->CanWriteFileSystemFile(process_id_, url)) {
405d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    Send(new FileSystemMsg_DidFail(request_id,
4065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                   base::File::FILE_ERROR_SECURITY));
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  scoped_ptr<storage::BlobDataHandle> blob =
41158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      blob_storage_context_->context()->GetBlobDataFromUUID(blob_uuid);
41258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
413868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  operations_[request_id] = operation_runner()->Write(
41458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      request_context_, url, blob.Pass(), offset,
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&FileAPIMessageFilter::DidWrite, this, request_id));
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FileAPIMessageFilter::OnTruncate(
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int request_id,
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL& path,
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int64 length) {
4222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FileSystemURL url(context_->CrackURL(path));
423d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  if (!ValidateFileSystemURL(request_id, url))
424d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    return;
425d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  if (!security_policy_->CanWriteFileSystemFile(process_id_, url)) {
426d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    Send(new FileSystemMsg_DidFail(request_id,
4275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                   base::File::FILE_ERROR_SECURITY));
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
431868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  operations_[request_id] = operation_runner()->Truncate(
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      url, length,
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&FileAPIMessageFilter::DidFinish, this, request_id));
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FileAPIMessageFilter::OnTouchFile(
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int request_id,
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL& path,
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const base::Time& last_access_time,
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const base::Time& last_modified_time) {
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
4422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FileSystemURL url(context_->CrackURL(path));
443d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  if (!ValidateFileSystemURL(request_id, url))
444d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    return;
445d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  if (!security_policy_->CanCreateFileSystemFile(process_id_, url)) {
446d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    Send(new FileSystemMsg_DidFail(request_id,
4475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                   base::File::FILE_ERROR_SECURITY));
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
451868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  operations_[request_id] = operation_runner()->TouchFile(
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      url, last_access_time, last_modified_time,
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&FileAPIMessageFilter::DidFinish, this, request_id));
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FileAPIMessageFilter::OnCancel(
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int request_id,
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int request_id_to_cancel) {
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
460868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
461868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  OperationsMap::iterator found = operations_.find(request_id_to_cancel);
462868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (found != operations_.end()) {
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // The cancel will eventually send both the write failure and the cancel
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // success.
465868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    operation_runner()->Cancel(
466868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        found->second,
467868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        base::Bind(&FileAPIMessageFilter::DidFinish, this, request_id));
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // The write already finished; report that we failed to stop it.
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Send(new FileSystemMsg_DidFail(
4715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        request_id, base::File::FILE_ERROR_INVALID_OPERATION));
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FileAPIMessageFilter::OnSyncGetPlatformPath(
4762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const GURL& path, base::FilePath* platform_path) {
4772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SyncGetPlatformPath(context_, process_id_, path, platform_path);
4782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void FileAPIMessageFilter::OnCreateSnapshotFile(
4812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int request_id, const GURL& path) {
4822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
4832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FileSystemURL url(context_->CrackURL(path));
4842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Make sure if this file can be read by the renderer as this is
4862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // called when the renderer is about to create a new File object
4872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // (for reading the file).
488d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  if (!ValidateFileSystemURL(request_id, url))
489d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    return;
490d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  if (!security_policy_->CanReadFileSystemFile(process_id_, url)) {
491d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    Send(new FileSystemMsg_DidFail(request_id,
4925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                   base::File::FILE_ERROR_SECURITY));
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
4942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
496a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  FileSystemBackend* backend = context_->GetFileSystemBackend(url.type());
497a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (backend->SupportsStreaming(url)) {
498a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    operations_[request_id] = operation_runner()->GetMetadata(
499a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        url,
500a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        base::Bind(&FileAPIMessageFilter::DidGetMetadataForStreaming,
501a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                   this, request_id));
502a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  } else {
503a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    operations_[request_id] = operation_runner()->CreateSnapshotFile(
504a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        url,
505a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        base::Bind(&FileAPIMessageFilter::DidCreateSnapshot,
506a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                   this, request_id, url));
507a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void FileAPIMessageFilter::OnDidReceiveSnapshotFile(int request_id) {
5112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
5122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  in_transit_snapshot_files_.erase(request_id);
5132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
51558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void FileAPIMessageFilter::OnStartBuildingBlob(const std::string& uuid) {
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
51758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  ignore_result(blob_storage_host_->StartBuildingBlob(uuid));
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5202385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochvoid FileAPIMessageFilter::OnAppendBlobDataItemToBlob(
52158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    const std::string& uuid, const BlobData::Item& item) {
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
5232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (item.type() == BlobData::Item::TYPE_FILE_FILESYSTEM) {
52458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    FileSystemURL filesystem_url(context_->CrackURL(item.filesystem_url()));
525d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    if (!FileSystemURLIsValid(context_, filesystem_url) ||
526d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        !security_policy_->CanReadFileSystemFile(process_id_, filesystem_url)) {
52758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      ignore_result(blob_storage_host_->CancelBuildingBlob(uuid));
5282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return;
5292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
5302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (item.type() == BlobData::Item::TYPE_FILE &&
532d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      !security_policy_->CanReadFile(process_id_, item.path())) {
53358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    ignore_result(blob_storage_host_->CancelBuildingBlob(uuid));
5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (item.length() == 0) {
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    BadMessageReceived();
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
54058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  ignore_result(blob_storage_host_->AppendBlobDataItem(uuid, item));
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5432385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochvoid FileAPIMessageFilter::OnAppendSharedMemoryToBlob(
54458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    const std::string& uuid,
54558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    base::SharedMemoryHandle handle,
54658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    size_t buffer_size) {
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(base::SharedMemory::IsHandleValid(handle));
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!buffer_size) {
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    BadMessageReceived();
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
5537dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  base::SharedMemory shared_memory(handle, true, PeerHandle());
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::SharedMemory shared_memory(handle, true);
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!shared_memory.Map(buffer_size)) {
55858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    ignore_result(blob_storage_host_->CancelBuildingBlob(uuid));
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BlobData::Item item;
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  item.SetToSharedBytes(static_cast<char*>(shared_memory.memory()),
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        buffer_size);
56558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  ignore_result(blob_storage_host_->AppendBlobDataItem(uuid, item));
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FileAPIMessageFilter::OnFinishBuildingBlob(
56958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    const std::string& uuid, const std::string& content_type) {
57058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
57158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  ignore_result(blob_storage_host_->FinishBuildingBlob(uuid, content_type));
57258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // TODO(michaeln): check return values once blink has migrated, crbug/174200
57358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
57458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
57558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void FileAPIMessageFilter::OnIncrementBlobRefCount(const std::string& uuid) {
57658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
57758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  ignore_result(blob_storage_host_->IncrementBlobRefCount(uuid));
57858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
57958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
58058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void FileAPIMessageFilter::OnDecrementBlobRefCount(const std::string& uuid) {
58158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
58258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  ignore_result(blob_storage_host_->DecrementBlobRefCount(uuid));
58358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
58458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
58558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void FileAPIMessageFilter::OnRegisterPublicBlobURL(
58658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    const GURL& public_url, const std::string& uuid) {
58758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
58858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  ignore_result(blob_storage_host_->RegisterPublicBlobURL(public_url, uuid));
58958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
59058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
59158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void FileAPIMessageFilter::OnRevokePublicBlobURL(const GURL& public_url) {
59258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
59358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  ignore_result(blob_storage_host_->RevokePublicBlobURL(public_url));
59458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
59558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
5962385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochvoid FileAPIMessageFilter::OnStartBuildingStream(
5972385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    const GURL& url, const std::string& content_type) {
5982385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
5992385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  // Only an internal Blob URL is expected here. See the BlobURL of the Blink.
6002385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  if (!StartsWithASCII(
6012385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch          url.path(), "blobinternal%3A///", true /* case_sensitive */)) {
6022385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    NOTREACHED() << "Malformed Stream URL: " << url.spec();
6032385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    BadMessageReceived();
6042385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    return;
6052385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  }
6062385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  // Use an empty security origin for now. Stream accepts a security origin
6072385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  // but how it's handled is not fixed yet.
6082385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  new Stream(stream_context_->registry(),
6092385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch             NULL /* write_observer */,
6102385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch             url);
6112385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  stream_urls_.insert(url.spec());
6122385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch}
6132385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
6142385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochvoid FileAPIMessageFilter::OnAppendBlobDataItemToStream(
6152385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    const GURL& url, const BlobData::Item& item) {
6162385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
6172385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
6182385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  scoped_refptr<Stream> stream(GetStreamForURL(url));
6193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Stream instances may be deleted on error. Just abort if there's no Stream
6203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // instance for |url| in the registry.
6213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (!stream.get())
6222385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    return;
6232385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
6242385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  // Data for stream is delivered as TYPE_BYTES item.
6252385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  if (item.type() != BlobData::Item::TYPE_BYTES) {
6262385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    BadMessageReceived();
6272385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    return;
6282385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  }
6292385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  stream->AddData(item.bytes(), item.length());
6302385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch}
6312385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
6322385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochvoid FileAPIMessageFilter::OnAppendSharedMemoryToStream(
6332385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    const GURL& url, base::SharedMemoryHandle handle, size_t buffer_size) {
6342385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  DCHECK(base::SharedMemory::IsHandleValid(handle));
6352385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  if (!buffer_size) {
6362385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    BadMessageReceived();
6372385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    return;
6382385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  }
6392385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#if defined(OS_WIN)
6402385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  base::SharedMemory shared_memory(handle, true, PeerHandle());
6412385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#else
6422385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  base::SharedMemory shared_memory(handle, true);
6432385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#endif
6442385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  if (!shared_memory.Map(buffer_size)) {
6452385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    OnRemoveStream(url);
6462385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    return;
6472385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  }
6482385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
6492385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  scoped_refptr<Stream> stream(GetStreamForURL(url));
6503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (!stream.get())
6512385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    return;
6522385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
6532385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  stream->AddData(static_cast<char*>(shared_memory.memory()), buffer_size);
6542385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch}
6552385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
6562385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochvoid FileAPIMessageFilter::OnFinishBuildingStream(const GURL& url) {
6572385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
6582385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  scoped_refptr<Stream> stream(GetStreamForURL(url));
6592385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  if (stream.get())
6602385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    stream->Finalize();
6612385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch}
6622385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
663424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void FileAPIMessageFilter::OnAbortBuildingStream(const GURL& url) {
664424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
665424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  scoped_refptr<Stream> stream(GetStreamForURL(url));
666424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  if (stream.get())
667424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    stream->Abort();
668424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}
669424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
6702385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochvoid FileAPIMessageFilter::OnCloneStream(
6712385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    const GURL& url, const GURL& src_url) {
6722385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
6733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Abort if there's no Stream instance for |src_url| (source Stream which
6743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // we're going to make |url| point to) in the registry.
6751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!GetStreamForURL(src_url).get())
6762385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    return;
6772385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
6782385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  stream_context_->registry()->CloneStream(url, src_url);
6792385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  stream_urls_.insert(url.spec());
6802385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch}
6812385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
6822385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochvoid FileAPIMessageFilter::OnRemoveStream(const GURL& url) {
6832385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
6842385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
6853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (!GetStreamForURL(url).get())
6862385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    return;
6872385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
6882385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  stream_context_->registry()->UnregisterStream(url);
6892385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  stream_urls_.erase(url.spec());
6902385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch}
6912385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FileAPIMessageFilter::DidFinish(int request_id,
6935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                     base::File::Error result) {
6945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (result == base::File::FILE_OK)
6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Send(new FileSystemMsg_DidSucceed(request_id));
6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  else
6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Send(new FileSystemMsg_DidFail(request_id, result));
698868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  operations_.erase(request_id);
6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FileAPIMessageFilter::DidGetMetadata(
7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int request_id,
7035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::File::Error result,
7045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const base::File::Info& info) {
7055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (result == base::File::FILE_OK)
7067d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    Send(new FileSystemMsg_DidReadMetadata(request_id, info));
7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  else
7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Send(new FileSystemMsg_DidFail(request_id, result));
709868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  operations_.erase(request_id);
7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
712a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void FileAPIMessageFilter::DidGetMetadataForStreaming(
713a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    int request_id,
714a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    base::File::Error result,
715a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const base::File::Info& info) {
716a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (result == base::File::FILE_OK) {
717a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // For now, streaming Blobs are implemented as a successful snapshot file
718a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // creation with an empty path.
719a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    Send(new FileSystemMsg_DidCreateSnapshotFile(request_id, info,
720a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                                 base::FilePath()));
721a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  } else {
722a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    Send(new FileSystemMsg_DidFail(request_id, result));
723a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
724a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  operations_.erase(request_id);
725a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
726a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FileAPIMessageFilter::DidReadDirectory(
7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int request_id,
7295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::File::Error result,
73003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    const std::vector<storage::DirectoryEntry>& entries,
7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool has_more) {
732a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (result == base::File::FILE_OK) {
733effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    if (!entries.empty() || !has_more)
734effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      Send(new FileSystemMsg_DidReadDirectory(request_id, entries, has_more));
735a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  } else {
736a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    DCHECK(!has_more);
7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Send(new FileSystemMsg_DidFail(request_id, result));
738a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
739a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (!has_more)
740a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    operations_.erase(request_id);
7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FileAPIMessageFilter::DidWrite(int request_id,
7445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                    base::File::Error result,
7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    int64 bytes,
7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    bool complete) {
7475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (result == base::File::FILE_OK) {
7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Send(new FileSystemMsg_DidWrite(request_id, bytes, complete));
7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (complete)
750868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      operations_.erase(request_id);
7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Send(new FileSystemMsg_DidFail(request_id, result));
753868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    operations_.erase(request_id);
7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FileAPIMessageFilter::DidOpenFileSystem(int request_id,
7584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                             const GURL& root,
75968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                                             const std::string& filesystem_name,
7605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                             base::File::Error result) {
7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
7625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (result == base::File::FILE_OK) {
7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(root.is_valid());
76468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    Send(new FileSystemMsg_DidOpenFileSystem(
76568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)        request_id, filesystem_name, root));
7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Send(new FileSystemMsg_DidFail(request_id, result));
7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // For OpenFileSystem we do not create a new operation, so no unregister here.
7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7720529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochvoid FileAPIMessageFilter::DidResolveURL(
7730529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    int request_id,
7740529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    base::File::Error result,
77503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    const storage::FileSystemInfo& info,
7760529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    const base::FilePath& file_path,
77703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    storage::FileSystemContext::ResolvedEntryType type) {
77868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
7790529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if (result == base::File::FILE_OK &&
78003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      type == storage::FileSystemContext::RESOLVED_ENTRY_NOT_FOUND)
7810529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    result = base::File::FILE_ERROR_NOT_FOUND;
7820529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
7835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (result == base::File::FILE_OK) {
78468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    DCHECK(info.root_url.is_valid());
78568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    Send(new FileSystemMsg_DidResolveURL(
78603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        request_id,
78703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        info,
78803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        file_path,
78903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        type == storage::FileSystemContext::RESOLVED_ENTRY_DIRECTORY));
79068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  } else {
79168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    Send(new FileSystemMsg_DidFail(request_id, result));
79268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  }
79368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // For ResolveURL we do not create a new operation, so no unregister here.
79468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
79568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FileAPIMessageFilter::DidDeleteFileSystem(
7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int request_id,
7985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::File::Error result) {
7995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (result == base::File::FILE_OK)
8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Send(new FileSystemMsg_DidSucceed(request_id));
8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  else
8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Send(new FileSystemMsg_DidFail(request_id, result));
8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // For DeleteFileSystem we do not create a new operation,
8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // so no unregister here.
8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FileAPIMessageFilter::DidCreateSnapshot(
8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int request_id,
80903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    const storage::FileSystemURL& url,
8105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::File::Error result,
8115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const base::File::Info& info,
8122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const base::FilePath& platform_path,
81303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    const scoped_refptr<storage::ShareableFileReference>& /* unused */) {
8142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
815868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  operations_.erase(request_id);
816868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
8175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (result != base::File::FILE_OK) {
8182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Send(new FileSystemMsg_DidFail(request_id, result));
8192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
8202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
8212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
82203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  scoped_refptr<storage::ShareableFileReference> file_ref =
82303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      storage::ShareableFileReference::Get(platform_path);
824d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  if (!security_policy_->CanReadFile(process_id_, platform_path)) {
8257dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    // Give per-file read permission to the snapshot file if it hasn't it yet.
8267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    // In order for the renderer to be able to read the file via File object,
8277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    // it must be granted per-file read permission for the file's platform
8287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    // path. By now, it has already been verified that the renderer has
8297dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    // sufficient permissions to read the file, so giving per-file permission
8307dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    // here must be safe.
831d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    security_policy_->GrantReadFile(process_id_, platform_path);
8327dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
8337dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    // Revoke all permissions for the file when the last ref of the file
8347dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    // is dropped.
8357dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    if (!file_ref.get()) {
8367dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      // Create a reference for temporary permission handling.
83703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      file_ref = storage::ShareableFileReference::GetOrCreate(
8387dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          platform_path,
83903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)          storage::ShareableFileReference::DONT_DELETE_ON_FINAL_RELEASE,
840a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)          context_->default_file_task_runner());
8412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
8427dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    file_ref->AddFinalReleaseCallback(
8437dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        base::Bind(&RevokeFilePermission, process_id_));
8442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
8452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8467dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (file_ref.get()) {
8472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // This ref is held until OnDidReceiveSnapshotFile is called.
8487dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    in_transit_snapshot_files_[request_id] = file_ref;
8492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
8502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Return the file info and platform_path.
8522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Send(new FileSystemMsg_DidCreateSnapshotFile(
8535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      request_id, info, platform_path));
8542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
8552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
856d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)bool FileAPIMessageFilter::ValidateFileSystemURL(
85703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    int request_id,
85803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    const storage::FileSystemURL& url) {
859a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (!FileSystemURLIsValid(context_, url)) {
860a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    Send(new FileSystemMsg_DidFail(request_id,
8615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                   base::File::FILE_ERROR_INVALID_URL));
862a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    return false;
863a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
864a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
865a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Deny access to files in PluginPrivate FileSystem from JavaScript.
866a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // TODO(nhiroki): Move this filter somewhere else since this is not for
867a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // validation.
86803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  if (url.type() == storage::kFileSystemTypePluginPrivate) {
869a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    Send(new FileSystemMsg_DidFail(request_id,
8705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                   base::File::FILE_ERROR_SECURITY));
871a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    return false;
872a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
873a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
874a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  return true;
8755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8772385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochscoped_refptr<Stream> FileAPIMessageFilter::GetStreamForURL(const GURL& url) {
8782385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  return stream_context_->registry()->GetStream(url);
8792385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch}
8802385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace content
882