fileapi_message_filter.cc revision 868fa2fe829687343ffae624259930155e16dbd8
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"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/platform_file.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/threading/thread.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/time.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/browser/child_process_security_policy_impl.h"
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/browser/fileapi/browser_file_system_helper.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/browser/fileapi/chrome_blob_storage_context.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/common/fileapi/file_system_messages.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/common/fileapi/webblob_messages.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/user_metrics.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "googleurl/src/gurl.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ipc/ipc_platform_file.h"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/mime_util.h"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request_context.h"
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request_context_getter.h"
2790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "webkit/browser/blob/blob_storage_controller.h"
2890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "webkit/browser/fileapi/file_observers.h"
2990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "webkit/browser/fileapi/file_permission_policy.h"
3090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "webkit/browser/fileapi/file_system_context.h"
3190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "webkit/browser/fileapi/isolated_context.h"
3290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "webkit/browser/fileapi/local_file_system_operation.h"
3390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "webkit/browser/fileapi/sandbox_mount_point_provider.h"
34868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "webkit/browser/quota/quota_manager.h"
3590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "webkit/common/blob/blob_data.h"
3690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "webkit/common/blob/shareable_file_reference.h"
3790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "webkit/common/fileapi/directory_entry.h"
3890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "webkit/common/fileapi/file_system_types.h"
3990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "webkit/common/fileapi/file_system_util.h"
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using fileapi::FileSystemFileUtil;
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using fileapi::FileSystemMountPointProvider;
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using fileapi::FileSystemOperation;
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using fileapi::FileSystemURL;
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using fileapi::FileUpdateObserver;
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using fileapi::LocalFileSystemOperation;
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using fileapi::UpdateObserverList;
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using webkit_blob::BlobData;
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using webkit_blob::BlobStorageController;
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace content {
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void RevokeFilePermission(int child_id, const base::FilePath& path) {
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ChildProcessSecurityPolicyImpl::GetInstance()->RevokeAllPermissionsForFile(
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    child_id, path);
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)FileAPIMessageFilter::FileAPIMessageFilter(
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int process_id,
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    net::URLRequestContextGetter* request_context_getter,
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fileapi::FileSystemContext* file_system_context,
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ChromeBlobStorageContext* blob_storage_context)
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : process_id_(process_id),
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      context_(file_system_context),
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      request_context_getter_(request_context_getter),
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      request_context_(NULL),
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      blob_storage_context_(blob_storage_context) {
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(context_);
73868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK(request_context_getter_.get());
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(blob_storage_context);
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)FileAPIMessageFilter::FileAPIMessageFilter(
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int process_id,
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    net::URLRequestContext* request_context,
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fileapi::FileSystemContext* file_system_context,
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ChromeBlobStorageContext* blob_storage_context)
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : process_id_(process_id),
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      context_(file_system_context),
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      request_context_(request_context),
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      blob_storage_context_(blob_storage_context) {
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(context_);
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(request_context_);
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(blob_storage_context);
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FileAPIMessageFilter::OnChannelConnected(int32 peer_pid) {
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BrowserMessageFilter::OnChannelConnected(peer_pid);
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
94868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (request_context_getter_.get()) {
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(!request_context_);
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request_context_ = request_context_getter_->GetURLRequestContext();
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request_context_getter_ = NULL;
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(request_context_);
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FileAPIMessageFilter::OnChannelClosing() {
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BrowserMessageFilter::OnChannelClosing();
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Unregister all the blob URLs that are previously registered in this
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // process.
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (base::hash_set<std::string>::const_iterator iter = blob_urls_.begin();
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       iter != blob_urls_.end(); ++iter) {
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    blob_storage_context_->controller()->RemoveBlob(GURL(*iter));
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  in_transit_snapshot_files_.clear();
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Close all files that are previously OpenFile()'ed in this process.
115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!on_close_callbacks_.IsEmpty()) {
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DLOG(INFO)
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        << "File API: Renderer process shut down before NotifyCloseFile"
118c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        << " for " << on_close_callbacks_.size() << " files opened in PPAPI";
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
120c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
121c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  for (OnCloseCallbackMap::iterator itr(&on_close_callbacks_);
122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)       !itr.IsAtEnd(); itr.Advance()) {
123c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    itr.GetCurrentValue()->Run();
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
125c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
126c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  on_close_callbacks_.Clear();
127868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  operation_runner()->Shutdown();
128868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  operations_.clear();
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FileAPIMessageFilter::OverrideThreadForMessage(
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const IPC::Message& message,
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    BrowserThread::ID* thread) {
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (message.type() == FileSystemHostMsg_SyncGetPlatformPath::ID)
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *thread = BrowserThread::FILE;
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool FileAPIMessageFilter::OnMessageReceived(
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const IPC::Message& message, bool* message_was_ok) {
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *message_was_ok = true;
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool handled = true;
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IPC_BEGIN_MESSAGE_MAP_EX(FileAPIMessageFilter, message, *message_was_ok)
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER(FileSystemHostMsg_Open, OnOpen)
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER(FileSystemHostMsg_DeleteFileSystem, OnDeleteFileSystem)
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER(FileSystemHostMsg_Move, OnMove)
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER(FileSystemHostMsg_Copy, OnCopy)
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER(FileSystemMsg_Remove, OnRemove)
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER(FileSystemHostMsg_ReadMetadata, OnReadMetadata)
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER(FileSystemHostMsg_Create, OnCreate)
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER(FileSystemHostMsg_Exists, OnExists)
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER(FileSystemHostMsg_ReadDirectory, OnReadDirectory)
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER(FileSystemHostMsg_Write, OnWrite)
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER(FileSystemHostMsg_Truncate, OnTruncate)
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER(FileSystemHostMsg_TouchFile, OnTouchFile)
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER(FileSystemHostMsg_CancelWrite, OnCancel)
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER(FileSystemHostMsg_OpenFile, OnOpenFile)
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER(FileSystemHostMsg_NotifyCloseFile, OnNotifyCloseFile)
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER(FileSystemHostMsg_CreateSnapshotFile,
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        OnCreateSnapshotFile)
1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    IPC_MESSAGE_HANDLER(FileSystemHostMsg_DidReceiveSnapshotFile,
1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                        OnDidReceiveSnapshotFile)
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER(FileSystemHostMsg_WillUpdate, OnWillUpdate)
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER(FileSystemHostMsg_DidUpdate, OnDidUpdate)
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER(FileSystemHostMsg_SyncGetPlatformPath,
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        OnSyncGetPlatformPath)
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER(BlobHostMsg_StartBuildingBlob, OnStartBuildingBlob)
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER(BlobHostMsg_AppendBlobDataItem, OnAppendBlobDataItem)
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER(BlobHostMsg_SyncAppendSharedMemory,
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        OnAppendSharedMemory)
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER(BlobHostMsg_FinishBuildingBlob, OnFinishBuildingBlob)
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER(BlobHostMsg_CloneBlob, OnCloneBlob)
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER(BlobHostMsg_RemoveBlob, OnRemoveBlob)
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_UNHANDLED(handled = false)
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IPC_END_MESSAGE_MAP_EX()
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return handled;
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)FileAPIMessageFilter::~FileAPIMessageFilter() {}
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FileAPIMessageFilter::BadMessageReceived() {
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RecordAction(UserMetricsAction("BadMessageTerminate_FAMF"));
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BrowserMessageFilter::BadMessageReceived();
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FileAPIMessageFilter::OnOpen(
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int request_id, const GURL& origin_url, fileapi::FileSystemType type,
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int64 requested_size, bool create) {
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (type == fileapi::kFileSystemTypeTemporary) {
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RecordAction(UserMetricsAction("OpenFileSystemTemporary"));
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else if (type == fileapi::kFileSystemTypePersistent) {
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RecordAction(UserMetricsAction("OpenFileSystemPersistent"));
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
19490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // TODO(kinuko): Use this mode for IPC too.
19590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  fileapi::OpenFileSystemMode mode =
19690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      create ? fileapi::OPEN_FILE_SYSTEM_CREATE_IF_NONEXISTENT
19790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)             : fileapi::OPEN_FILE_SYSTEM_FAIL_IF_NONEXISTENT;
19890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  context_->OpenFileSystem(origin_url, type, mode, base::Bind(
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &FileAPIMessageFilter::DidOpenFileSystem, this, request_id));
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FileAPIMessageFilter::OnDeleteFileSystem(
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int request_id,
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL& origin_url,
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fileapi::FileSystemType type) {
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  context_->DeleteFileSystem(origin_url, type, base::Bind(
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &FileAPIMessageFilter::DidDeleteFileSystem, this, request_id));
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FileAPIMessageFilter::OnMove(
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int request_id, const GURL& src_path, const GURL& dest_path) {
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::PlatformFileError error;
2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FileSystemURL src_url(context_->CrackURL(src_path));
2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FileSystemURL dest_url(context_->CrackURL(dest_path));
2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const int src_permissions =
2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      fileapi::kReadFilePermissions | fileapi::kWriteFilePermissions;
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!HasPermissionsForFile(src_url, src_permissions, &error) ||
2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      !HasPermissionsForFile(
2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          dest_url, fileapi::kCreateFilePermissions, &error)) {
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Send(new FileSystemMsg_DidFail(request_id, error));
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
226868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  operations_[request_id] = operation_runner()->Move(
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      src_url, dest_url,
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&FileAPIMessageFilter::DidFinish, this, request_id));
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FileAPIMessageFilter::OnCopy(
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int request_id, const GURL& src_path, const GURL& dest_path) {
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::PlatformFileError error;
2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FileSystemURL src_url(context_->CrackURL(src_path));
2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FileSystemURL dest_url(context_->CrackURL(dest_path));
2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!HasPermissionsForFile(src_url, fileapi::kReadFilePermissions, &error) ||
2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      !HasPermissionsForFile(
2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          dest_url, fileapi::kCreateFilePermissions, &error)) {
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Send(new FileSystemMsg_DidFail(request_id, error));
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
244868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  operations_[request_id] = operation_runner()->Copy(
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      src_url, dest_url,
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&FileAPIMessageFilter::DidFinish, this, request_id));
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FileAPIMessageFilter::OnRemove(
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int request_id, const GURL& path, bool recursive) {
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::PlatformFileError error;
2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FileSystemURL url(context_->CrackURL(path));
2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!HasPermissionsForFile(url, fileapi::kWriteFilePermissions, &error)) {
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Send(new FileSystemMsg_DidFail(request_id, error));
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
259868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  operations_[request_id] = operation_runner()->Remove(
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      url, recursive,
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&FileAPIMessageFilter::DidFinish, this, request_id));
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FileAPIMessageFilter::OnReadMetadata(
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int request_id, const GURL& path) {
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::PlatformFileError error;
2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FileSystemURL url(context_->CrackURL(path));
2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!HasPermissionsForFile(url, fileapi::kReadFilePermissions, &error)) {
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Send(new FileSystemMsg_DidFail(request_id, error));
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
274868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  operations_[request_id] = operation_runner()->GetMetadata(
275868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      url, base::Bind(&FileAPIMessageFilter::DidGetMetadata, this, request_id));
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FileAPIMessageFilter::OnCreate(
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int request_id, const GURL& path, bool exclusive,
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool is_directory, bool recursive) {
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::PlatformFileError error;
2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FileSystemURL url(context_->CrackURL(path));
2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!HasPermissionsForFile(url, fileapi::kCreateFilePermissions, &error)) {
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Send(new FileSystemMsg_DidFail(request_id, error));
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (is_directory) {
290868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    operations_[request_id] = operation_runner()->CreateDirectory(
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        url, exclusive, recursive,
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&FileAPIMessageFilter::DidFinish, this, request_id));
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
294868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    operations_[request_id] = operation_runner()->CreateFile(
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        url, exclusive,
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&FileAPIMessageFilter::DidFinish, this, request_id));
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FileAPIMessageFilter::OnExists(
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int request_id, const GURL& path, bool is_directory) {
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::PlatformFileError error;
3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FileSystemURL url(context_->CrackURL(path));
3052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!HasPermissionsForFile(url, fileapi::kReadFilePermissions, &error)) {
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Send(new FileSystemMsg_DidFail(request_id, error));
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (is_directory) {
311868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    operations_[request_id] = operation_runner()->DirectoryExists(
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        url,
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&FileAPIMessageFilter::DidFinish, this, request_id));
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
315868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    operations_[request_id] = operation_runner()->FileExists(
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        url,
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&FileAPIMessageFilter::DidFinish, this, request_id));
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FileAPIMessageFilter::OnReadDirectory(
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int request_id, const GURL& path) {
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::PlatformFileError error;
3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FileSystemURL url(context_->CrackURL(path));
3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!HasPermissionsForFile(url, fileapi::kReadFilePermissions, &error)) {
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Send(new FileSystemMsg_DidFail(request_id, error));
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
331868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  operations_[request_id] = operation_runner()->ReadDirectory(
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      url, base::Bind(&FileAPIMessageFilter::DidReadDirectory,
333868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                      this, request_id));
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FileAPIMessageFilter::OnWrite(
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int request_id,
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL& path,
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL& blob_url,
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int64 offset) {
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!request_context_) {
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // We can't write w/o a request context, trying to do so will crash.
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NOTREACHED();
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FileSystemURL url(context_->CrackURL(path));
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::PlatformFileError error;
3502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!HasPermissionsForFile(url, fileapi::kWriteFilePermissions, &error)) {
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Send(new FileSystemMsg_DidFail(request_id, error));
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
355868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  operations_[request_id] = operation_runner()->Write(
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      request_context_, url, blob_url, offset,
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&FileAPIMessageFilter::DidWrite, this, request_id));
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FileAPIMessageFilter::OnTruncate(
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int request_id,
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL& path,
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int64 length) {
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::PlatformFileError error;
3652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FileSystemURL url(context_->CrackURL(path));
3662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!HasPermissionsForFile(url, fileapi::kWriteFilePermissions, &error)) {
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Send(new FileSystemMsg_DidFail(request_id, error));
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
371868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  operations_[request_id] = operation_runner()->Truncate(
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      url, length,
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&FileAPIMessageFilter::DidFinish, this, request_id));
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FileAPIMessageFilter::OnTouchFile(
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int request_id,
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL& path,
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const base::Time& last_access_time,
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const base::Time& last_modified_time) {
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
3822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FileSystemURL url(context_->CrackURL(path));
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::PlatformFileError error;
3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!HasPermissionsForFile(url, fileapi::kCreateFilePermissions, &error)) {
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Send(new FileSystemMsg_DidFail(request_id, error));
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
389868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  operations_[request_id] = operation_runner()->TouchFile(
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      url, last_access_time, last_modified_time,
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&FileAPIMessageFilter::DidFinish, this, request_id));
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FileAPIMessageFilter::OnCancel(
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int request_id,
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int request_id_to_cancel) {
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
398868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
399868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  OperationsMap::iterator found = operations_.find(request_id_to_cancel);
400868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (found != operations_.end()) {
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // The cancel will eventually send both the write failure and the cancel
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // success.
403868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    operation_runner()->Cancel(
404868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        found->second,
405868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        base::Bind(&FileAPIMessageFilter::DidFinish, this, request_id));
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // The write already finished; report that we failed to stop it.
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Send(new FileSystemMsg_DidFail(
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        request_id, base::PLATFORM_FILE_ERROR_INVALID_OPERATION));
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FileAPIMessageFilter::OnOpenFile(
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int request_id, const GURL& path, int file_flags) {
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::PlatformFileError error;
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int open_permissions = base::PLATFORM_FILE_OPEN |
4182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                               (file_flags & fileapi::kOpenFilePermissions);
4192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FileSystemURL url(context_->CrackURL(path));
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!HasPermissionsForFile(url, open_permissions, &error)) {
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Send(new FileSystemMsg_DidFail(request_id, error));
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
425c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  quota::QuotaLimitType quota_policy = quota::kQuotaLimitTypeUnknown;
426c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  quota::QuotaManagerProxy* quota_manager_proxy =
427c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      context_->quota_manager_proxy();
428c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  CHECK(quota_manager_proxy);
429c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  CHECK(quota_manager_proxy->quota_manager());
430c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
431c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (quota_manager_proxy->quota_manager()->IsStorageUnlimited(
432c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          url.origin(), FileSystemTypeToQuotaStorageType(url.type()))) {
433c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    quota_policy = quota::kQuotaLimitTypeUnlimited;
434c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  } else {
435c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    quota_policy = quota::kQuotaLimitTypeLimited;
436c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
437c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
438868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  operations_[request_id] = operation_runner()->OpenFile(
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      url, file_flags, peer_handle(),
440c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      base::Bind(&FileAPIMessageFilter::DidOpenFile, this, request_id,
441c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 quota_policy));
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
444c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void FileAPIMessageFilter::OnNotifyCloseFile(int file_open_id) {
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
447c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Remove |file_open_id| from the map of |on_close_callback|s.
448c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // It must only be called for a ID that is successfully opened and enrolled in
449c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // DidOpenFile.
450c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::Closure* on_close_callback = on_close_callbacks_.Lookup(file_open_id);
451c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (on_close_callback && !on_close_callback->is_null()) {
452c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    on_close_callback->Run();
453c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    on_close_callbacks_.Remove(file_open_id);
454c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FileAPIMessageFilter::OnWillUpdate(const GURL& path) {
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
4592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FileSystemURL url(context_->CrackURL(path));
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!url.is_valid())
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const UpdateObserverList* observers =
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      context_->GetUpdateObservers(url.type());
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!observers)
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  observers->Notify(&FileUpdateObserver::OnStartUpdate, MakeTuple(url));
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FileAPIMessageFilter::OnDidUpdate(const GURL& path, int64 delta) {
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
4712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FileSystemURL url(context_->CrackURL(path));
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!url.is_valid())
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const UpdateObserverList* observers =
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      context_->GetUpdateObservers(url.type());
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!observers)
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  observers->Notify(&FileUpdateObserver::OnUpdate, MakeTuple(url, delta));
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  observers->Notify(&FileUpdateObserver::OnEndUpdate, MakeTuple(url));
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FileAPIMessageFilter::OnSyncGetPlatformPath(
4832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const GURL& path, base::FilePath* platform_path) {
4842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SyncGetPlatformPath(context_, process_id_, path, platform_path);
4852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void FileAPIMessageFilter::OnCreateSnapshotFile(
4882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int request_id, const GURL& path) {
4892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
4902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FileSystemURL url(context_->CrackURL(path));
4912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Make sure if this file can be read by the renderer as this is
4932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // called when the renderer is about to create a new File object
4942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // (for reading the file).
4952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::PlatformFileError error;
4962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!HasPermissionsForFile(url, fileapi::kReadFilePermissions, &error)) {
4972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Send(new FileSystemMsg_DidFail(request_id, error));
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
4992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
501868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  operations_[request_id] = operation_runner()->CreateSnapshotFile(
5022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      url,
5032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&FileAPIMessageFilter::DidCreateSnapshot,
5042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 this, request_id, url));
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void FileAPIMessageFilter::OnDidReceiveSnapshotFile(int request_id) {
5082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
5092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  in_transit_snapshot_files_.erase(request_id);
5102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FileAPIMessageFilter::OnStartBuildingBlob(const GURL& url) {
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  blob_storage_context_->controller()->StartBuildingBlob(url);
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  blob_urls_.insert(url.spec());
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FileAPIMessageFilter::OnAppendBlobDataItem(
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL& url, const BlobData::Item& item) {
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
5212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (item.type() == BlobData::Item::TYPE_FILE_FILESYSTEM) {
5222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::PlatformFileError error;
5232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    FileSystemURL filesystem_url(context_->CrackURL(item.url()));
5242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!HasPermissionsForFile(filesystem_url,
5252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                               fileapi::kReadFilePermissions, &error)) {
5262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      OnRemoveBlob(url);
5272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return;
5282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
5292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (item.type() == BlobData::Item::TYPE_FILE &&
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      !ChildProcessSecurityPolicyImpl::GetInstance()->CanReadFile(
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          process_id_, item.path())) {
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    OnRemoveBlob(url);
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)  }
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  blob_storage_context_->controller()->AppendBlobDataItem(url, item);
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FileAPIMessageFilter::OnAppendSharedMemory(
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL& url, base::SharedMemoryHandle handle, size_t buffer_size) {
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(base::SharedMemory::IsHandleValid(handle));
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!buffer_size) {
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    BadMessageReceived();
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::SharedMemory shared_memory(handle, true, peer_handle());
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::SharedMemory shared_memory(handle, true);
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!shared_memory.Map(buffer_size)) {
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    OnRemoveBlob(url);
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BlobData::Item item;
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  item.SetToSharedBytes(static_cast<char*>(shared_memory.memory()),
5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        buffer_size);
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  blob_storage_context_->controller()->AppendBlobDataItem(url, item);
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FileAPIMessageFilter::OnFinishBuildingBlob(
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL& url, const std::string& content_type) {
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  blob_storage_context_->controller()->FinishBuildingBlob(url, content_type);
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FileAPIMessageFilter::OnCloneBlob(
5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL& url, const GURL& src_url) {
5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  blob_storage_context_->controller()->CloneBlob(url, src_url);
5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  blob_urls_.insert(url.spec());
5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FileAPIMessageFilter::OnRemoveBlob(const GURL& url) {
5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  blob_storage_context_->controller()->RemoveBlob(url);
5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  blob_urls_.erase(url.spec());
5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FileAPIMessageFilter::DidFinish(int request_id,
5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     base::PlatformFileError result) {
5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (result == base::PLATFORM_FILE_OK)
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Send(new FileSystemMsg_DidSucceed(request_id));
5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  else
5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Send(new FileSystemMsg_DidFail(request_id, result));
591868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  operations_.erase(request_id);
5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FileAPIMessageFilter::DidGetMetadata(
5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int request_id,
5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::PlatformFileError result,
5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const base::PlatformFileInfo& info,
5982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const base::FilePath& platform_path) {
5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (result == base::PLATFORM_FILE_OK)
6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Send(new FileSystemMsg_DidReadMetadata(request_id, info, platform_path));
6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  else
6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Send(new FileSystemMsg_DidFail(request_id, result));
603868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  operations_.erase(request_id);
6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FileAPIMessageFilter::DidReadDirectory(
6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int request_id,
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::PlatformFileError result,
60990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const std::vector<fileapi::DirectoryEntry>& entries,
6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool has_more) {
6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (result == base::PLATFORM_FILE_OK)
6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Send(new FileSystemMsg_DidReadDirectory(request_id, entries, has_more));
6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  else
6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Send(new FileSystemMsg_DidFail(request_id, result));
615868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  operations_.erase(request_id);
6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FileAPIMessageFilter::DidOpenFile(int request_id,
619c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                       quota::QuotaLimitType quota_policy,
6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       base::PlatformFileError result,
6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       base::PlatformFile file,
622c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                       const base::Closure& on_close_callback,
6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       base::ProcessHandle peer_handle) {
6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (result == base::PLATFORM_FILE_OK) {
6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC::PlatformFileForTransit file_for_transit =
6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        file != base::kInvalidPlatformFileValue ?
6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            IPC::GetFileHandleForProcess(file, peer_handle, true) :
6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            IPC::InvalidPlatformFileForTransit();
629c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    int file_open_id = on_close_callbacks_.Add(
630c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        new base::Closure(on_close_callback));
631c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
632c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    Send(new FileSystemMsg_DidOpenFile(request_id,
633c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                       file_for_transit,
634c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                       file_open_id,
635c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                       quota_policy));
6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
637c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    Send(new FileSystemMsg_DidFail(request_id,
638c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                   result));
6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
640868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  operations_.erase(request_id);
6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FileAPIMessageFilter::DidWrite(int request_id,
6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    base::PlatformFileError result,
6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    int64 bytes,
6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    bool complete) {
6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (result == base::PLATFORM_FILE_OK) {
6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Send(new FileSystemMsg_DidWrite(request_id, bytes, complete));
6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (complete)
650868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      operations_.erase(request_id);
6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Send(new FileSystemMsg_DidFail(request_id, result));
653868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    operations_.erase(request_id);
6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FileAPIMessageFilter::DidOpenFileSystem(int request_id,
6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                             base::PlatformFileError result,
6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                             const std::string& name,
6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                             const GURL& root) {
6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (result == base::PLATFORM_FILE_OK) {
6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(root.is_valid());
6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Send(new FileSystemMsg_DidOpenFileSystem(request_id, name, root));
6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Send(new FileSystemMsg_DidFail(request_id, result));
6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // For OpenFileSystem we do not create a new operation, so no unregister here.
6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FileAPIMessageFilter::DidDeleteFileSystem(
6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int request_id,
6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::PlatformFileError result) {
6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (result == base::PLATFORM_FILE_OK)
6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Send(new FileSystemMsg_DidSucceed(request_id));
6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  else
6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Send(new FileSystemMsg_DidFail(request_id, result));
6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // For DeleteFileSystem we do not create a new operation,
6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // so no unregister here.
6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FileAPIMessageFilter::DidCreateSnapshot(
6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int request_id,
6842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const fileapi::FileSystemURL& url,
6852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::PlatformFileError result,
6862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const base::PlatformFileInfo& info,
6872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const base::FilePath& platform_path,
6882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const scoped_refptr<webkit_blob::ShareableFileReference>& snapshot_file) {
6892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
690868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  operations_.erase(request_id);
691868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
6922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (result != base::PLATFORM_FILE_OK) {
6932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Send(new FileSystemMsg_DidFail(request_id, result));
6942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
6952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
6962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!ChildProcessSecurityPolicyImpl::GetInstance()->CanReadFile(
6982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          process_id_, platform_path)) {
6992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // In order for the renderer to be able to read the file, it must be granted
7002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // read permission for the file's platform path. By now, it has already been
7012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // verified that the renderer has sufficient permissions to read the file.
7022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // It is still possible that ChildProcessSecurityPolicyImpl doesn't reflect
7032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // that the renderer can read the file's platform path. If this is the case
7042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // the renderer should be granted read permission for the file's platform
7052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // path. This can happen in the following situations:
7062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // - the file comes from sandboxed filesystem. Reading sandboxed files is
7072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    //   always permitted, but only implicitly.
7082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // - the underlying filesystem returned newly created snapshot file.
70990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    // - the nominal path differs from the platform path. This can happen even
71090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    //   when the filesystem has been granted permissions. This happens with:
71190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    //   - Drive filesystems
71290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    //   - Picasa filesystems
713868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    //   - iTunes filesystems
714868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    DCHECK(snapshot_file.get() ||
715c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)           fileapi::SandboxMountPointProvider::IsSandboxType(url.type()) ||
71690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)           url.type() == fileapi::kFileSystemTypeDrive ||
717868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)           url.type() == fileapi::kFileSystemTypePicasa ||
718868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)           url.type() == fileapi::kFileSystemTypeItunes);
7192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ChildProcessSecurityPolicyImpl::GetInstance()->GrantReadFile(
7202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        process_id_, platform_path);
721868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (snapshot_file.get()) {
7222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      // This will revoke all permissions for the file when the last ref
7232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      // of the file is dropped (assuming it's ok).
7242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      snapshot_file->AddFinalReleaseCallback(
7252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          base::Bind(&RevokeFilePermission, process_id_));
7262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
7272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
7282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
729868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (snapshot_file.get()) {
7302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // This ref is held until OnDidReceiveSnapshotFile is called.
7312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    in_transit_snapshot_files_[request_id] = snapshot_file;
7322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
7332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Return the file info and platform_path.
7352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Send(new FileSystemMsg_DidCreateSnapshotFile(
7362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)               request_id, info, platform_path));
7372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool FileAPIMessageFilter::HasPermissionsForFile(
7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const FileSystemURL& url, int permissions, base::PlatformFileError* error) {
7412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return CheckFileSystemPermissionsForProcess(context_, process_id_, url,
7422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                              permissions, error);
7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
745868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)fileapi::FileSystemOperationRunner* FileAPIMessageFilter::operation_runner() {
746868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return context_->operation_runner();
7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace content
750