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"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/platform_file.h"
157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/sequenced_task_runner.h"
162385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#include "base/strings/string_util.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/threading/thread.h"
18eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/time/time.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/browser/child_process_security_policy_impl.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"
307dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "url/gurl.h"
3158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "webkit/browser/blob/blob_storage_context.h"
3258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "webkit/browser/blob/blob_storage_host.h"
3390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "webkit/browser/fileapi/file_observers.h"
3490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "webkit/browser/fileapi/file_permission_policy.h"
3590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "webkit/browser/fileapi/file_system_context.h"
3690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "webkit/browser/fileapi/isolated_context.h"
3790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "webkit/common/blob/blob_data.h"
3890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "webkit/common/blob/shareable_file_reference.h"
3990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "webkit/common/fileapi/directory_entry.h"
4068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "webkit/common/fileapi/file_system_info.h"
4190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "webkit/common/fileapi/file_system_types.h"
4290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "webkit/common/fileapi/file_system_util.h"
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using fileapi::FileSystemFileUtil;
457dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochusing fileapi::FileSystemBackend;
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using fileapi::FileSystemOperation;
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using fileapi::FileSystemURL;
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using webkit_blob::BlobData;
4958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)using webkit_blob::BlobStorageContext;
5058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)using webkit_blob::BlobStorageHost;
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace content {
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void RevokeFilePermission(int child_id, const base::FilePath& path) {
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ChildProcessSecurityPolicyImpl::GetInstance()->RevokeAllPermissionsForFile(
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    child_id, path);
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)FileAPIMessageFilter::FileAPIMessageFilter(
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int process_id,
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    net::URLRequestContextGetter* request_context_getter,
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fileapi::FileSystemContext* file_system_context,
672385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    ChromeBlobStorageContext* blob_storage_context,
682385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    StreamContext* stream_context)
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : process_id_(process_id),
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      context_(file_system_context),
71d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      security_policy_(ChildProcessSecurityPolicyImpl::GetInstance()),
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      request_context_getter_(request_context_getter),
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      request_context_(NULL),
742385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      blob_storage_context_(blob_storage_context),
752385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      stream_context_(stream_context) {
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(context_);
77868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK(request_context_getter_.get());
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(blob_storage_context);
792385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  DCHECK(stream_context);
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)FileAPIMessageFilter::FileAPIMessageFilter(
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int process_id,
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    net::URLRequestContext* request_context,
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fileapi::FileSystemContext* file_system_context,
862385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    ChromeBlobStorageContext* blob_storage_context,
872385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    StreamContext* stream_context)
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : process_id_(process_id),
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      context_(file_system_context),
90d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      security_policy_(ChildProcessSecurityPolicyImpl::GetInstance()),
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      request_context_(request_context),
922385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      blob_storage_context_(blob_storage_context),
932385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      stream_context_(stream_context) {
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(context_);
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(request_context_);
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(blob_storage_context);
972385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  DCHECK(stream_context);
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FileAPIMessageFilter::OnChannelConnected(int32 peer_pid) {
101bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
103868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (request_context_getter_.get()) {
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(!request_context_);
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request_context_ = request_context_getter_->GetURLRequestContext();
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request_context_getter_ = NULL;
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(request_context_);
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
109bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch
11058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  blob_storage_host_.reset(
11158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      new BlobStorageHost(blob_storage_context_->context()));
11258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
113bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  operation_runner_ = context_->CreateFileSystemOperationRunner();
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FileAPIMessageFilter::OnChannelClosing() {
117bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1192385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  // Unregister all the blob and stream URLs that are previously registered in
1202385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  // this process.
12158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  blob_storage_host_.reset();
1222385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  for (base::hash_set<std::string>::const_iterator iter = stream_urls_.begin();
1232385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch       iter != stream_urls_.end(); ++iter) {
1242385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    stream_context_->registry()->UnregisterStream(GURL(*iter));
1252385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  }
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  in_transit_snapshot_files_.clear();
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
129bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  operation_runner_.reset();
130868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  operations_.clear();
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)base::TaskRunner* FileAPIMessageFilter::OverrideTaskRunnerForMessage(
1347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    const IPC::Message& message) {
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (message.type() == FileSystemHostMsg_SyncGetPlatformPath::ID)
136a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    return context_->default_file_task_runner();
1377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return NULL;
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool FileAPIMessageFilter::OnMessageReceived(
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const IPC::Message& message, bool* message_was_ok) {
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *message_was_ok = true;
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool handled = true;
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IPC_BEGIN_MESSAGE_MAP_EX(FileAPIMessageFilter, message, *message_was_ok)
1454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    IPC_MESSAGE_HANDLER(FileSystemHostMsg_OpenFileSystem, OnOpenFileSystem)
14668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    IPC_MESSAGE_HANDLER(FileSystemHostMsg_ResolveURL, OnResolveURL)
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER(FileSystemHostMsg_DeleteFileSystem, OnDeleteFileSystem)
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER(FileSystemHostMsg_Move, OnMove)
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER(FileSystemHostMsg_Copy, OnCopy)
1504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    IPC_MESSAGE_HANDLER(FileSystemHostMsg_Remove, OnRemove)
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER(FileSystemHostMsg_ReadMetadata, OnReadMetadata)
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER(FileSystemHostMsg_Create, OnCreate)
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER(FileSystemHostMsg_Exists, OnExists)
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER(FileSystemHostMsg_ReadDirectory, OnReadDirectory)
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER(FileSystemHostMsg_Write, OnWrite)
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER(FileSystemHostMsg_Truncate, OnTruncate)
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER(FileSystemHostMsg_TouchFile, OnTouchFile)
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER(FileSystemHostMsg_CancelWrite, OnCancel)
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER(FileSystemHostMsg_CreateSnapshotFile,
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        OnCreateSnapshotFile)
1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    IPC_MESSAGE_HANDLER(FileSystemHostMsg_DidReceiveSnapshotFile,
1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                        OnDidReceiveSnapshotFile)
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER(FileSystemHostMsg_SyncGetPlatformPath,
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        OnSyncGetPlatformPath)
1652385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    IPC_MESSAGE_HANDLER(BlobHostMsg_StartBuilding, OnStartBuildingBlob)
1662385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    IPC_MESSAGE_HANDLER(BlobHostMsg_AppendBlobDataItem,
1672385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch                        OnAppendBlobDataItemToBlob)
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER(BlobHostMsg_SyncAppendSharedMemory,
1692385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch                        OnAppendSharedMemoryToBlob)
1702385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    IPC_MESSAGE_HANDLER(BlobHostMsg_FinishBuilding, OnFinishBuildingBlob)
17158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    IPC_MESSAGE_HANDLER(BlobHostMsg_IncrementRefCount,
17258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                        OnIncrementBlobRefCount)
17358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    IPC_MESSAGE_HANDLER(BlobHostMsg_DecrementRefCount,
17458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                        OnDecrementBlobRefCount)
17558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    IPC_MESSAGE_HANDLER(BlobHostMsg_RegisterPublicURL,
17658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                        OnRegisterPublicBlobURL)
17758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    IPC_MESSAGE_HANDLER(BlobHostMsg_RevokePublicURL, OnRevokePublicBlobURL)
1782385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    IPC_MESSAGE_HANDLER(StreamHostMsg_StartBuilding, OnStartBuildingStream)
1792385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    IPC_MESSAGE_HANDLER(StreamHostMsg_AppendBlobDataItem,
1802385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch                        OnAppendBlobDataItemToStream)
1812385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    IPC_MESSAGE_HANDLER(StreamHostMsg_SyncAppendSharedMemory,
1822385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch                        OnAppendSharedMemoryToStream)
1832385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    IPC_MESSAGE_HANDLER(StreamHostMsg_FinishBuilding, OnFinishBuildingStream)
184424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    IPC_MESSAGE_HANDLER(StreamHostMsg_AbortBuilding, OnAbortBuildingStream)
1852385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    IPC_MESSAGE_HANDLER(StreamHostMsg_Clone, OnCloneStream)
1862385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    IPC_MESSAGE_HANDLER(StreamHostMsg_Remove, OnRemoveStream)
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_UNHANDLED(handled = false)
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IPC_END_MESSAGE_MAP_EX()
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return handled;
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)FileAPIMessageFilter::~FileAPIMessageFilter() {}
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FileAPIMessageFilter::BadMessageReceived() {
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RecordAction(UserMetricsAction("BadMessageTerminate_FAMF"));
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BrowserMessageFilter::BadMessageReceived();
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void FileAPIMessageFilter::OnOpenFileSystem(int request_id,
2004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                            const GURL& origin_url,
2014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                            fileapi::FileSystemType type) {
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (type == fileapi::kFileSystemTypeTemporary) {
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RecordAction(UserMetricsAction("OpenFileSystemTemporary"));
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else if (type == fileapi::kFileSystemTypePersistent) {
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RecordAction(UserMetricsAction("OpenFileSystemPersistent"));
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
20890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  fileapi::OpenFileSystemMode mode =
2094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      fileapi::OPEN_FILE_SYSTEM_CREATE_IF_NONEXISTENT;
21090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  context_->OpenFileSystem(origin_url, type, mode, base::Bind(
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &FileAPIMessageFilter::DidOpenFileSystem, this, request_id));
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void FileAPIMessageFilter::OnResolveURL(
21568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    int request_id,
21668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    const GURL& filesystem_url) {
21768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
21868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  FileSystemURL url(context_->CrackURL(filesystem_url));
21968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  if (!ValidateFileSystemURL(request_id, url))
22068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    return;
22168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  if (!security_policy_->CanReadFileSystemFile(process_id_, url)) {
22268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    Send(new FileSystemMsg_DidFail(request_id,
22368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                                   base::PLATFORM_FILE_ERROR_SECURITY));
22468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    return;
22568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  }
22668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
22768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  context_->ResolveURL(url, base::Bind(
22868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      &FileAPIMessageFilter::DidResolveURL, this, request_id));
22968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
23068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FileAPIMessageFilter::OnDeleteFileSystem(
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int request_id,
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL& origin_url,
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fileapi::FileSystemType type) {
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  context_->DeleteFileSystem(origin_url, type, base::Bind(
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &FileAPIMessageFilter::DidDeleteFileSystem, this, request_id));
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FileAPIMessageFilter::OnMove(
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int request_id, const GURL& src_path, const GURL& dest_path) {
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FileSystemURL src_url(context_->CrackURL(src_path));
2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FileSystemURL dest_url(context_->CrackURL(dest_path));
245d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  if (!ValidateFileSystemURL(request_id, src_url) ||
246d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      !ValidateFileSystemURL(request_id, dest_url)) {
247d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    return;
248d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  }
249d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  if (!security_policy_->CanReadFileSystemFile(process_id_, src_url) ||
2508bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      !security_policy_->CanDeleteFileSystemFile(process_id_, src_url) ||
251d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      !security_policy_->CanCreateFileSystemFile(process_id_, dest_url)) {
252d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    Send(new FileSystemMsg_DidFail(request_id,
253d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                                   base::PLATFORM_FILE_ERROR_SECURITY));
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
257868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  operations_[request_id] = operation_runner()->Move(
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      src_url, dest_url,
25968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      fileapi::FileSystemOperation::OPTION_NONE,
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&FileAPIMessageFilter::DidFinish, this, request_id));
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FileAPIMessageFilter::OnCopy(
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int request_id, const GURL& src_path, const GURL& dest_path) {
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FileSystemURL src_url(context_->CrackURL(src_path));
2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FileSystemURL dest_url(context_->CrackURL(dest_path));
268d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  if (!ValidateFileSystemURL(request_id, src_url) ||
269d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      !ValidateFileSystemURL(request_id, dest_url)) {
270d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    return;
271d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  }
272d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  if (!security_policy_->CanReadFileSystemFile(process_id_, src_url) ||
2734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      !security_policy_->CanCopyIntoFileSystemFile(process_id_, dest_url)) {
274d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    Send(new FileSystemMsg_DidFail(request_id,
275d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                                   base::PLATFORM_FILE_ERROR_SECURITY));
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
279868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  operations_[request_id] = operation_runner()->Copy(
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      src_url, dest_url,
28168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      fileapi::FileSystemOperation::OPTION_NONE,
28258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      fileapi::FileSystemOperationRunner::CopyProgressCallback(),
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&FileAPIMessageFilter::DidFinish, this, request_id));
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FileAPIMessageFilter::OnRemove(
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int request_id, const GURL& path, bool recursive) {
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FileSystemURL url(context_->CrackURL(path));
290d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  if (!ValidateFileSystemURL(request_id, url))
291d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    return;
2928bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (!security_policy_->CanDeleteFileSystemFile(process_id_, url)) {
293d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    Send(new FileSystemMsg_DidFail(request_id,
294d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                                   base::PLATFORM_FILE_ERROR_SECURITY));
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
298868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  operations_[request_id] = operation_runner()->Remove(
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      url, recursive,
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&FileAPIMessageFilter::DidFinish, this, request_id));
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FileAPIMessageFilter::OnReadMetadata(
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int request_id, const GURL& path) {
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FileSystemURL url(context_->CrackURL(path));
307d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  if (!ValidateFileSystemURL(request_id, url))
308d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    return;
309d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  if (!security_policy_->CanReadFileSystemFile(process_id_, url)) {
310d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    Send(new FileSystemMsg_DidFail(request_id,
311d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                                   base::PLATFORM_FILE_ERROR_SECURITY));
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
315868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  operations_[request_id] = operation_runner()->GetMetadata(
316868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      url, base::Bind(&FileAPIMessageFilter::DidGetMetadata, this, request_id));
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FileAPIMessageFilter::OnCreate(
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int request_id, const GURL& path, bool exclusive,
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool is_directory, bool recursive) {
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FileSystemURL url(context_->CrackURL(path));
324d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  if (!ValidateFileSystemURL(request_id, url))
325d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    return;
326d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  if (!security_policy_->CanCreateFileSystemFile(process_id_, url)) {
327d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    Send(new FileSystemMsg_DidFail(request_id,
328d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                                   base::PLATFORM_FILE_ERROR_SECURITY));
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (is_directory) {
333868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    operations_[request_id] = operation_runner()->CreateDirectory(
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        url, exclusive, recursive,
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&FileAPIMessageFilter::DidFinish, this, request_id));
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
337868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    operations_[request_id] = operation_runner()->CreateFile(
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        url, exclusive,
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&FileAPIMessageFilter::DidFinish, this, request_id));
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FileAPIMessageFilter::OnExists(
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int request_id, const GURL& path, bool is_directory) {
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FileSystemURL url(context_->CrackURL(path));
347d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  if (!ValidateFileSystemURL(request_id, url))
348d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    return;
349d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  if (!security_policy_->CanReadFileSystemFile(process_id_, url)) {
350d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    Send(new FileSystemMsg_DidFail(request_id,
351d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                                   base::PLATFORM_FILE_ERROR_SECURITY));
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (is_directory) {
356868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    operations_[request_id] = operation_runner()->DirectoryExists(
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        url,
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&FileAPIMessageFilter::DidFinish, this, request_id));
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
360868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    operations_[request_id] = operation_runner()->FileExists(
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        url,
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&FileAPIMessageFilter::DidFinish, this, request_id));
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FileAPIMessageFilter::OnReadDirectory(
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int request_id, const GURL& path) {
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
3692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FileSystemURL url(context_->CrackURL(path));
370d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  if (!ValidateFileSystemURL(request_id, url))
371d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    return;
372d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  if (!security_policy_->CanReadFileSystemFile(process_id_, url)) {
373d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    Send(new FileSystemMsg_DidFail(request_id,
374d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                                   base::PLATFORM_FILE_ERROR_SECURITY));
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
378868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  operations_[request_id] = operation_runner()->ReadDirectory(
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      url, base::Bind(&FileAPIMessageFilter::DidReadDirectory,
380868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                      this, request_id));
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
38358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void FileAPIMessageFilter::OnWrite(
38458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    int request_id,
38558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    const GURL& path,
38658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    const std::string& blob_uuid,
38758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    int64 offset) {
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!request_context_) {
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // We can't write w/o a request context, trying to do so will crash.
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NOTREACHED();
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FileSystemURL url(context_->CrackURL(path));
396d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  if (!ValidateFileSystemURL(request_id, url))
397d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    return;
398d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  if (!security_policy_->CanWriteFileSystemFile(process_id_, url)) {
399d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    Send(new FileSystemMsg_DidFail(request_id,
400d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                                   base::PLATFORM_FILE_ERROR_SECURITY));
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  scoped_ptr<webkit_blob::BlobDataHandle> blob =
40558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      blob_storage_context_->context()->GetBlobDataFromUUID(blob_uuid);
40658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
407868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  operations_[request_id] = operation_runner()->Write(
40858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      request_context_, url, blob.Pass(), offset,
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&FileAPIMessageFilter::DidWrite, this, request_id));
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FileAPIMessageFilter::OnTruncate(
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int request_id,
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL& path,
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int64 length) {
4162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FileSystemURL url(context_->CrackURL(path));
417d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  if (!ValidateFileSystemURL(request_id, url))
418d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    return;
419d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  if (!security_policy_->CanWriteFileSystemFile(process_id_, url)) {
420d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    Send(new FileSystemMsg_DidFail(request_id,
421d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                                   base::PLATFORM_FILE_ERROR_SECURITY));
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
425868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  operations_[request_id] = operation_runner()->Truncate(
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      url, length,
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&FileAPIMessageFilter::DidFinish, this, request_id));
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FileAPIMessageFilter::OnTouchFile(
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int request_id,
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL& path,
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const base::Time& last_access_time,
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const base::Time& last_modified_time) {
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
4362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FileSystemURL url(context_->CrackURL(path));
437d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  if (!ValidateFileSystemURL(request_id, url))
438d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    return;
439d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  if (!security_policy_->CanCreateFileSystemFile(process_id_, url)) {
440d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    Send(new FileSystemMsg_DidFail(request_id,
441d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                                   base::PLATFORM_FILE_ERROR_SECURITY));
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
445868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  operations_[request_id] = operation_runner()->TouchFile(
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      url, last_access_time, last_modified_time,
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&FileAPIMessageFilter::DidFinish, this, request_id));
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FileAPIMessageFilter::OnCancel(
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int request_id,
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int request_id_to_cancel) {
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
454868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
455868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  OperationsMap::iterator found = operations_.find(request_id_to_cancel);
456868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (found != operations_.end()) {
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // The cancel will eventually send both the write failure and the cancel
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // success.
459868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    operation_runner()->Cancel(
460868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        found->second,
461868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        base::Bind(&FileAPIMessageFilter::DidFinish, this, request_id));
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // The write already finished; report that we failed to stop it.
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Send(new FileSystemMsg_DidFail(
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        request_id, base::PLATFORM_FILE_ERROR_INVALID_OPERATION));
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FileAPIMessageFilter::OnSyncGetPlatformPath(
4702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const GURL& path, base::FilePath* platform_path) {
4712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SyncGetPlatformPath(context_, process_id_, path, platform_path);
4722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void FileAPIMessageFilter::OnCreateSnapshotFile(
4752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int request_id, const GURL& path) {
4762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
4772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FileSystemURL url(context_->CrackURL(path));
4782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Make sure if this file can be read by the renderer as this is
4802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // called when the renderer is about to create a new File object
4812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // (for reading the file).
482d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  if (!ValidateFileSystemURL(request_id, url))
483d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    return;
484d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  if (!security_policy_->CanReadFileSystemFile(process_id_, url)) {
485d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    Send(new FileSystemMsg_DidFail(request_id,
486d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                                   base::PLATFORM_FILE_ERROR_SECURITY));
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
4882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
490868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  operations_[request_id] = operation_runner()->CreateSnapshotFile(
4912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      url,
4922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&FileAPIMessageFilter::DidCreateSnapshot,
4932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 this, request_id, url));
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void FileAPIMessageFilter::OnDidReceiveSnapshotFile(int request_id) {
4972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
4982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  in_transit_snapshot_files_.erase(request_id);
4992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
50158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void FileAPIMessageFilter::OnStartBuildingBlob(const std::string& uuid) {
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
50358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  ignore_result(blob_storage_host_->StartBuildingBlob(uuid));
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5062385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochvoid FileAPIMessageFilter::OnAppendBlobDataItemToBlob(
50758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    const std::string& uuid, const BlobData::Item& item) {
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
5092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (item.type() == BlobData::Item::TYPE_FILE_FILESYSTEM) {
51058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    FileSystemURL filesystem_url(context_->CrackURL(item.filesystem_url()));
511d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    if (!FileSystemURLIsValid(context_, filesystem_url) ||
512d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        !security_policy_->CanReadFileSystemFile(process_id_, filesystem_url)) {
51358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      ignore_result(blob_storage_host_->CancelBuildingBlob(uuid));
5142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return;
5152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
5162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (item.type() == BlobData::Item::TYPE_FILE &&
518d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      !security_policy_->CanReadFile(process_id_, item.path())) {
51958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    ignore_result(blob_storage_host_->CancelBuildingBlob(uuid));
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (item.length() == 0) {
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    BadMessageReceived();
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
52658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  ignore_result(blob_storage_host_->AppendBlobDataItem(uuid, item));
5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5292385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochvoid FileAPIMessageFilter::OnAppendSharedMemoryToBlob(
53058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    const std::string& uuid,
53158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    base::SharedMemoryHandle handle,
53258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    size_t buffer_size) {
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(base::SharedMemory::IsHandleValid(handle));
5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!buffer_size) {
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    BadMessageReceived();
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
5397dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  base::SharedMemory shared_memory(handle, true, PeerHandle());
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::SharedMemory shared_memory(handle, true);
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!shared_memory.Map(buffer_size)) {
54458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    ignore_result(blob_storage_host_->CancelBuildingBlob(uuid));
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BlobData::Item item;
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  item.SetToSharedBytes(static_cast<char*>(shared_memory.memory()),
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        buffer_size);
55158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  ignore_result(blob_storage_host_->AppendBlobDataItem(uuid, item));
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FileAPIMessageFilter::OnFinishBuildingBlob(
55558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    const std::string& uuid, const std::string& content_type) {
55658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
55758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  ignore_result(blob_storage_host_->FinishBuildingBlob(uuid, content_type));
55858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // TODO(michaeln): check return values once blink has migrated, crbug/174200
55958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
56058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
56158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void FileAPIMessageFilter::OnIncrementBlobRefCount(const std::string& uuid) {
56258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
56358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  ignore_result(blob_storage_host_->IncrementBlobRefCount(uuid));
56458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
56558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
56658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void FileAPIMessageFilter::OnDecrementBlobRefCount(const std::string& uuid) {
56758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
56858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  ignore_result(blob_storage_host_->DecrementBlobRefCount(uuid));
56958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
57058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
57158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void FileAPIMessageFilter::OnRegisterPublicBlobURL(
57258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    const GURL& public_url, const std::string& uuid) {
57358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
57458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  ignore_result(blob_storage_host_->RegisterPublicBlobURL(public_url, uuid));
57558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
57658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
57758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void FileAPIMessageFilter::OnRevokePublicBlobURL(const GURL& public_url) {
57858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
57958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  ignore_result(blob_storage_host_->RevokePublicBlobURL(public_url));
58058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
58158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
5822385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochvoid FileAPIMessageFilter::OnStartBuildingStream(
5832385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    const GURL& url, const std::string& content_type) {
5842385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
5852385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  // Only an internal Blob URL is expected here. See the BlobURL of the Blink.
5862385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  if (!StartsWithASCII(
5872385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch          url.path(), "blobinternal%3A///", true /* case_sensitive */)) {
5882385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    NOTREACHED() << "Malformed Stream URL: " << url.spec();
5892385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    BadMessageReceived();
5902385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    return;
5912385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  }
5922385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  // Use an empty security origin for now. Stream accepts a security origin
5932385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  // but how it's handled is not fixed yet.
5942385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  new Stream(stream_context_->registry(),
5952385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch             NULL /* write_observer */,
5962385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch             url);
5972385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  stream_urls_.insert(url.spec());
5982385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch}
5992385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
6002385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochvoid FileAPIMessageFilter::OnAppendBlobDataItemToStream(
6012385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    const GURL& url, const BlobData::Item& item) {
6022385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
6032385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
6042385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  scoped_refptr<Stream> stream(GetStreamForURL(url));
6053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Stream instances may be deleted on error. Just abort if there's no Stream
6063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // instance for |url| in the registry.
6073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (!stream.get())
6082385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    return;
6092385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
6102385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  // Data for stream is delivered as TYPE_BYTES item.
6112385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  if (item.type() != BlobData::Item::TYPE_BYTES) {
6122385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    BadMessageReceived();
6132385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    return;
6142385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  }
6152385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  stream->AddData(item.bytes(), item.length());
6162385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch}
6172385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
6182385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochvoid FileAPIMessageFilter::OnAppendSharedMemoryToStream(
6192385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    const GURL& url, base::SharedMemoryHandle handle, size_t buffer_size) {
6202385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  DCHECK(base::SharedMemory::IsHandleValid(handle));
6212385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  if (!buffer_size) {
6222385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    BadMessageReceived();
6232385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    return;
6242385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  }
6252385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#if defined(OS_WIN)
6262385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  base::SharedMemory shared_memory(handle, true, PeerHandle());
6272385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#else
6282385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  base::SharedMemory shared_memory(handle, true);
6292385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#endif
6302385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  if (!shared_memory.Map(buffer_size)) {
6312385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    OnRemoveStream(url);
6322385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    return;
6332385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  }
6342385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
6352385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  scoped_refptr<Stream> stream(GetStreamForURL(url));
6363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (!stream.get())
6372385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    return;
6382385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
6392385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  stream->AddData(static_cast<char*>(shared_memory.memory()), buffer_size);
6402385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch}
6412385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
6422385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochvoid FileAPIMessageFilter::OnFinishBuildingStream(const GURL& url) {
6432385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
6442385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  scoped_refptr<Stream> stream(GetStreamForURL(url));
6452385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  if (stream.get())
6462385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    stream->Finalize();
6472385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch}
6482385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
649424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void FileAPIMessageFilter::OnAbortBuildingStream(const GURL& url) {
650424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
651424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  scoped_refptr<Stream> stream(GetStreamForURL(url));
652424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  if (stream.get())
653424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    stream->Abort();
654424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}
655424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
6562385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochvoid FileAPIMessageFilter::OnCloneStream(
6572385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    const GURL& url, const GURL& src_url) {
6582385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
6593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Abort if there's no Stream instance for |src_url| (source Stream which
6603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // we're going to make |url| point to) in the registry.
6613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (!GetStreamForURL(src_url))
6622385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    return;
6632385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
6642385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  stream_context_->registry()->CloneStream(url, src_url);
6652385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  stream_urls_.insert(url.spec());
6662385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch}
6672385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
6682385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochvoid FileAPIMessageFilter::OnRemoveStream(const GURL& url) {
6692385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
6702385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
6713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (!GetStreamForURL(url).get())
6722385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    return;
6732385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
6742385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  stream_context_->registry()->UnregisterStream(url);
6752385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  stream_urls_.erase(url.spec());
6762385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch}
6772385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FileAPIMessageFilter::DidFinish(int request_id,
6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     base::PlatformFileError result) {
6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (result == base::PLATFORM_FILE_OK)
6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Send(new FileSystemMsg_DidSucceed(request_id));
6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  else
6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Send(new FileSystemMsg_DidFail(request_id, result));
684868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  operations_.erase(request_id);
6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FileAPIMessageFilter::DidGetMetadata(
6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int request_id,
6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::PlatformFileError result,
6907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    const base::PlatformFileInfo& info) {
6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (result == base::PLATFORM_FILE_OK)
6927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    Send(new FileSystemMsg_DidReadMetadata(request_id, info));
6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  else
6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Send(new FileSystemMsg_DidFail(request_id, result));
695868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  operations_.erase(request_id);
6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FileAPIMessageFilter::DidReadDirectory(
6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int request_id,
7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::PlatformFileError result,
70190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const std::vector<fileapi::DirectoryEntry>& entries,
7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool has_more) {
7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (result == base::PLATFORM_FILE_OK)
7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Send(new FileSystemMsg_DidReadDirectory(request_id, entries, has_more));
7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  else
7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Send(new FileSystemMsg_DidFail(request_id, result));
707868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  operations_.erase(request_id);
7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FileAPIMessageFilter::DidWrite(int request_id,
7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    base::PlatformFileError result,
7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    int64 bytes,
7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    bool complete) {
7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (result == base::PLATFORM_FILE_OK) {
7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Send(new FileSystemMsg_DidWrite(request_id, bytes, complete));
7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (complete)
717868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      operations_.erase(request_id);
7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Send(new FileSystemMsg_DidFail(request_id, result));
720868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    operations_.erase(request_id);
7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FileAPIMessageFilter::DidOpenFileSystem(int request_id,
7254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                             const GURL& root,
72668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                                             const std::string& filesystem_name,
7274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                             base::PlatformFileError result) {
7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (result == base::PLATFORM_FILE_OK) {
7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(root.is_valid());
73168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    Send(new FileSystemMsg_DidOpenFileSystem(
73268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)        request_id, filesystem_name, root));
7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Send(new FileSystemMsg_DidFail(request_id, result));
7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // For OpenFileSystem we do not create a new operation, so no unregister here.
7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
73968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void FileAPIMessageFilter::DidResolveURL(int request_id,
74068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                                         base::PlatformFileError result,
74168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                                         const fileapi::FileSystemInfo& info,
74268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                                         const base::FilePath& file_path,
74368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                                         bool is_directory) {
74468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
74568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  if (result == base::PLATFORM_FILE_OK) {
74668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    DCHECK(info.root_url.is_valid());
74768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    Send(new FileSystemMsg_DidResolveURL(
74868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)        request_id, info, file_path, is_directory));
74968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  } else {
75068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    Send(new FileSystemMsg_DidFail(request_id, result));
75168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  }
75268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // For ResolveURL we do not create a new operation, so no unregister here.
75368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
75468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FileAPIMessageFilter::DidDeleteFileSystem(
7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int request_id,
7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::PlatformFileError result) {
7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (result == base::PLATFORM_FILE_OK)
7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Send(new FileSystemMsg_DidSucceed(request_id));
7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  else
7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Send(new FileSystemMsg_DidFail(request_id, result));
7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // For DeleteFileSystem we do not create a new operation,
7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // so no unregister here.
7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FileAPIMessageFilter::DidCreateSnapshot(
7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int request_id,
7682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const fileapi::FileSystemURL& url,
7692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::PlatformFileError result,
7702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const base::PlatformFileInfo& info,
7712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const base::FilePath& platform_path,
7723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    const scoped_refptr<webkit_blob::ShareableFileReference>& /* unused */) {
7732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
774868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  operations_.erase(request_id);
775868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
7762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (result != base::PLATFORM_FILE_OK) {
7772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Send(new FileSystemMsg_DidFail(request_id, result));
7782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
7792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
7802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_refptr<webkit_blob::ShareableFileReference> file_ref =
7823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      webkit_blob::ShareableFileReference::Get(platform_path);
783d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  if (!security_policy_->CanReadFile(process_id_, platform_path)) {
7847dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    // Give per-file read permission to the snapshot file if it hasn't it yet.
7857dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    // In order for the renderer to be able to read the file via File object,
7867dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    // it must be granted per-file read permission for the file's platform
7877dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    // path. By now, it has already been verified that the renderer has
7887dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    // sufficient permissions to read the file, so giving per-file permission
7897dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    // here must be safe.
790d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    security_policy_->GrantReadFile(process_id_, platform_path);
7917dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
7927dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    // Revoke all permissions for the file when the last ref of the file
7937dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    // is dropped.
7947dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    if (!file_ref.get()) {
7957dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      // Create a reference for temporary permission handling.
7967dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      file_ref = webkit_blob::ShareableFileReference::GetOrCreate(
7977dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          platform_path,
7987dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          webkit_blob::ShareableFileReference::DONT_DELETE_ON_FINAL_RELEASE,
799a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)          context_->default_file_task_runner());
8002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
8017dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    file_ref->AddFinalReleaseCallback(
8027dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        base::Bind(&RevokeFilePermission, process_id_));
8032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
8042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8057dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (file_ref.get()) {
8062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // This ref is held until OnDidReceiveSnapshotFile is called.
8077dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    in_transit_snapshot_files_[request_id] = file_ref;
8082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
8092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Return the file info and platform_path.
8112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Send(new FileSystemMsg_DidCreateSnapshotFile(
8122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)               request_id, info, platform_path));
8132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
8142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
815d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)bool FileAPIMessageFilter::ValidateFileSystemURL(
816d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    int request_id, const fileapi::FileSystemURL& url) {
817a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (!FileSystemURLIsValid(context_, url)) {
818a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    Send(new FileSystemMsg_DidFail(request_id,
819a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                   base::PLATFORM_FILE_ERROR_INVALID_URL));
820a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    return false;
821a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
822a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
823a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Deny access to files in PluginPrivate FileSystem from JavaScript.
824a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // TODO(nhiroki): Move this filter somewhere else since this is not for
825a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // validation.
826a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (url.type() == fileapi::kFileSystemTypePluginPrivate) {
827a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    Send(new FileSystemMsg_DidFail(request_id,
828a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                   base::PLATFORM_FILE_ERROR_SECURITY));
829a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    return false;
830a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
831a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
832a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  return true;
8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8352385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochscoped_refptr<Stream> FileAPIMessageFilter::GetStreamForURL(const GURL& url) {
8362385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  return stream_context_->registry()->GetStream(url);
8372385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch}
8382385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace content
840