blob: 3e6d959722c7847b7f8e71da0e2de665d5c317a1 [file] [log] [blame]
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef WEBKIT_FILEAPI_LOCAL_FILE_SYSTEM_OPERATION_H_
#define WEBKIT_FILEAPI_LOCAL_FILE_SYSTEM_OPERATION_H_
#include <vector>
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/scoped_vector.h"
#include "webkit/fileapi/file_system_file_util.h"
#include "webkit/fileapi/file_system_operation.h"
#include "webkit/fileapi/file_system_operation_context.h"
#include "webkit/fileapi/file_system_url.h"
#include "webkit/fileapi/file_writer_delegate.h"
#include "webkit/quota/quota_types.h"
#include "webkit/storage/webkit_storage_export.h"
namespace chromeos {
class CrosMountPointProvider;
}
namespace fileapi {
class FileSystemContext;
// FileSystemOperation implementation for local file systems.
class WEBKIT_STORAGE_EXPORT LocalFileSystemOperation
: public NON_EXPORTED_BASE(FileSystemOperation) {
public:
virtual ~LocalFileSystemOperation();
// FileSystemOperation overrides.
virtual void CreateFile(const FileSystemURL& url,
bool exclusive,
const StatusCallback& callback) OVERRIDE;
virtual void CreateDirectory(const FileSystemURL& url,
bool exclusive,
bool recursive,
const StatusCallback& callback) OVERRIDE;
virtual void Copy(const FileSystemURL& src_url,
const FileSystemURL& dest_url,
const StatusCallback& callback) OVERRIDE;
virtual void Move(const FileSystemURL& src_url,
const FileSystemURL& dest_url,
const StatusCallback& callback) OVERRIDE;
virtual void DirectoryExists(const FileSystemURL& url,
const StatusCallback& callback) OVERRIDE;
virtual void FileExists(const FileSystemURL& url,
const StatusCallback& callback) OVERRIDE;
virtual void GetMetadata(const FileSystemURL& url,
const GetMetadataCallback& callback) OVERRIDE;
virtual void ReadDirectory(const FileSystemURL& url,
const ReadDirectoryCallback& callback) OVERRIDE;
virtual void Remove(const FileSystemURL& url, bool recursive,
const StatusCallback& callback) OVERRIDE;
virtual void Write(const net::URLRequestContext* url_request_context,
const FileSystemURL& url,
const GURL& blob_url,
int64 offset,
const WriteCallback& callback) OVERRIDE;
virtual void Truncate(const FileSystemURL& url, int64 length,
const StatusCallback& callback) OVERRIDE;
virtual void TouchFile(const FileSystemURL& url,
const base::Time& last_access_time,
const base::Time& last_modified_time,
const StatusCallback& callback) OVERRIDE;
virtual void OpenFile(const FileSystemURL& url,
int file_flags,
base::ProcessHandle peer_handle,
const OpenFileCallback& callback) OVERRIDE;
virtual void NotifyCloseFile(const FileSystemURL& url) OVERRIDE;
virtual void Cancel(const StatusCallback& cancel_callback) OVERRIDE;
virtual LocalFileSystemOperation* AsLocalFileSystemOperation() OVERRIDE;
virtual void CreateSnapshotFile(
const FileSystemURL& path,
const SnapshotFileCallback& callback) OVERRIDE;
void CopyInForeignFile(const FilePath& src_local_disk_path,
const FileSystemURL& dest_url,
const StatusCallback& callback);
// Synchronously gets the platform path for the given |url|.
void SyncGetPlatformPath(const FileSystemURL& url, FilePath* platform_path);
private:
class ScopedUpdateNotifier;
enum SetUpMode {
SETUP_FOR_READ,
SETUP_FOR_WRITE,
SETUP_FOR_CREATE,
};
// Only MountPointProviders or testing class can create a
// new operation directly.
friend class FileSystemTestHelper;
friend class IsolatedMountPointProvider;
friend class SandboxMountPointProvider;
friend class TestMountPointProvider;
friend class chromeos::CrosMountPointProvider;
friend class LocalFileSystemOperationTest;
friend class LocalFileSystemOperationWriteTest;
friend class FileWriterDelegateTest;
friend class FileSystemQuotaTest;
friend class LocalFileSystemTestOriginHelper;
friend class SyncableFileSystemOperation;
LocalFileSystemOperation(
FileSystemContext* file_system_context,
scoped_ptr<FileSystemOperationContext> operation_context);
FileSystemContext* file_system_context() const {
return operation_context_->file_system_context();
}
FileSystemOperationContext* operation_context() const {
return operation_context_.get();
}
// The unit tests that need to specify and control the lifetime of the
// file_util on their own should call this before performing the actual
// operation. If it is given it will not be overwritten by the class.
void set_override_file_util(FileSystemFileUtil* file_util) {
src_util_ = file_util;
dest_util_ = file_util;
}
// Queries the quota and usage and then runs the given |task|.
// If an error occurs during the quota query it runs |error_callback| instead.
void GetUsageAndQuotaThenRunTask(
const FileSystemURL& url,
const base::Closure& task,
const base::Closure& error_callback);
// Called after the quota info is obtained from the quota manager
// (which is triggered by GetUsageAndQuotaThenRunTask).
// Sets the quota info in the operation_context_ and then runs the given
// |task| if the returned quota status is successful, otherwise runs
// |error_callback|.
void DidGetUsageAndQuotaAndRunTask(
const base::Closure& task,
const base::Closure& error_callback,
quota::QuotaStatusCode status,
int64 usage, int64 quota);
// returns a closure which actually perform the write operation.
base::Closure GetWriteClosure(
const net::URLRequestContext* url_request_context,
const FileSystemURL& url,
const GURL& blob_url,
int64 offset,
const WriteCallback& callback);
void DidFailWrite(
const WriteCallback& callback,
base::PlatformFileError result);
// The 'body' methods that perform the actual work (i.e. posting the
// file task on proxy_) after the quota check.
void DoCreateFile(const FileSystemURL& url,
const StatusCallback& callback, bool exclusive);
void DoCreateDirectory(const FileSystemURL& url,
const StatusCallback& callback,
bool exclusive,
bool recursive);
void DoCopy(const FileSystemURL& src,
const FileSystemURL& dest,
const StatusCallback& callback);
void DoCopyInForeignFile(const FilePath& src_local_disk_file_path,
const FileSystemURL& dest,
const StatusCallback& callback);
void DoMove(const FileSystemURL& src,
const FileSystemURL& dest,
const StatusCallback& callback);
void DoTruncate(const FileSystemURL& url,
const StatusCallback& callback, int64 length);
void DoOpenFile(const FileSystemURL& url,
const OpenFileCallback& callback, int file_flags);
// Callback for CreateFile for |exclusive|=true cases.
void DidEnsureFileExistsExclusive(const StatusCallback& callback,
base::PlatformFileError rv,
bool created);
// Callback for CreateFile for |exclusive|=false cases.
void DidEnsureFileExistsNonExclusive(const StatusCallback& callback,
base::PlatformFileError rv,
bool created);
// Generic callback that translates platform errors to WebKit error codes.
void DidFinishFileOperation(const StatusCallback& callback,
base::PlatformFileError rv);
void DidDirectoryExists(const StatusCallback& callback,
base::PlatformFileError rv,
const base::PlatformFileInfo& file_info,
const FilePath& unused);
void DidFileExists(const StatusCallback& callback,
base::PlatformFileError rv,
const base::PlatformFileInfo& file_info,
const FilePath& unused);
void DidGetMetadata(const GetMetadataCallback& callback,
base::PlatformFileError rv,
const base::PlatformFileInfo& file_info,
const FilePath& platform_path);
void DidReadDirectory(const ReadDirectoryCallback& callback,
base::PlatformFileError rv,
const std::vector<base::FileUtilProxy::Entry>& entries,
bool has_more);
void DidWrite(const FileSystemURL& url,
base::PlatformFileError rv,
int64 bytes,
FileWriterDelegate::WriteProgressStatus write_status);
void DidTouchFile(const StatusCallback& callback,
base::PlatformFileError rv);
void DidOpenFile(const OpenFileCallback& callback,
base::PlatformFileError rv,
base::PassPlatformFile file,
bool created);
void DidCreateSnapshotFile(
const SnapshotFileCallback& callback,
base::PlatformFileError rv,
const base::PlatformFileInfo& file_info,
const FilePath& platform_path,
FileSystemFileUtil::SnapshotFilePolicy snapshot_policy);
// Checks the validity of a given |url| and populates |file_util| for |mode|.
base::PlatformFileError SetUp(
const FileSystemURL& url,
FileSystemFileUtil** file_util,
SetUpMode mode);
// Used only for internal assertions.
// Returns false if there's another inflight pending operation.
bool SetPendingOperationType(OperationType type);
scoped_ptr<FileSystemOperationContext> operation_context_;
FileSystemFileUtil* src_util_; // Not owned.
FileSystemFileUtil* dest_util_; // Not owned.
// This is set before any write operations to dispatch
// FileUpdateObserver::StartUpdate and FileUpdateObserver::EndUpdate.
ScopedVector<ScopedUpdateNotifier> scoped_update_notifiers_;
// These are all used only by Write().
friend class FileWriterDelegate;
scoped_ptr<FileWriterDelegate> file_writer_delegate_;
// write_callback is kept in this class for so that we can dispatch it when
// the operation is cancelled. calcel_callback is kept for canceling a
// Truncate() operation. We can't actually stop Truncate in another thread;
// after it resumed from the working thread, cancellation takes place.
WriteCallback write_callback_;
StatusCallback cancel_callback_;
void set_write_callback(const WriteCallback& write_callback) {
write_callback_ = write_callback;
}
// Used only by OpenFile, in order to clone the file handle back to the
// requesting process.
base::ProcessHandle peer_handle_;
// A flag to make sure we call operation only once per instance.
OperationType pending_operation_;
// LocalFileSystemOperation instance is usually deleted upon completion but
// could be deleted while it has inflight callbacks when Cancel is called.
base::WeakPtrFactory<LocalFileSystemOperation> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(LocalFileSystemOperation);
};
} // namespace fileapi
#endif // WEBKIT_FILEAPI_LOCAL_FILE_SYSTEM_OPERATION_H_