Commit 396756c4 authored by Austin Tankiang's avatar Austin Tankiang Committed by Commit Bot

Remove legacy Drive file system type

With the switch to DriveFS, the legacy drive client is no longer needed,
so remove it.

Bug: 1003238
Change-Id: I7e2bf4afb1bc518962f5629eebfba929c918792e
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1803947Reviewed-by: default avatarSam McNally <sammc@chromium.org>
Reviewed-by: default avatarLei Zhang <thestig@chromium.org>
Commit-Queue: Austin Tankiang <austinct@chromium.org>
Cr-Commit-Position: refs/heads/master@{#697469}
parent a2f0faad
......@@ -380,7 +380,6 @@
#include "chrome/browser/chromeos/chrome_browser_main_chromeos.h"
#include "chrome/browser/chromeos/chrome_content_browser_client_chromeos_part.h"
#include "chrome/browser/chromeos/drive/fileapi/drivefs_file_system_backend_delegate.h"
#include "chrome/browser/chromeos/drive/fileapi/file_system_backend_delegate.h"
#include "chrome/browser/chromeos/file_manager/app_id.h"
#include "chrome/browser/chromeos/file_system_provider/fileapi/backend_delegate.h"
#include "chrome/browser/chromeos/fileapi/external_file_url_loader_factory.h"
......@@ -3552,7 +3551,6 @@ void ChromeContentBrowserClient::GetAdditionalFileSystemBackends(
content::BrowserContext::GetMountPoints(browser_context);
DCHECK(external_mount_points);
auto backend = std::make_unique<chromeos::FileSystemBackend>(
std::make_unique<drive::FileSystemBackendDelegate>(),
std::make_unique<chromeos::file_system_provider::BackendDelegate>(),
std::make_unique<chromeos::MTPFileSystemBackendDelegate>(
storage_partition_path),
......
......@@ -844,26 +844,14 @@ source_set("chromeos") {
"drive/debug_info_collector.h",
"drive/download_handler.cc",
"drive/download_handler.h",
"drive/drive_file_stream_reader.cc",
"drive/drive_file_stream_reader.h",
"drive/drive_integration_service.cc",
"drive/drive_integration_service.h",
"drive/file_system_util.cc",
"drive/file_system_util.h",
"drive/fileapi/async_file_util.cc",
"drive/fileapi/async_file_util.h",
"drive/fileapi/drivefs_async_file_util.cc",
"drive/fileapi/drivefs_async_file_util.h",
"drive/fileapi/drivefs_file_system_backend_delegate.cc",
"drive/fileapi/drivefs_file_system_backend_delegate.h",
"drive/fileapi/file_system_backend_delegate.cc",
"drive/fileapi/file_system_backend_delegate.h",
"drive/fileapi/fileapi_worker.cc",
"drive/fileapi/fileapi_worker.h",
"drive/fileapi/webkit_file_stream_reader_impl.cc",
"drive/fileapi/webkit_file_stream_reader_impl.h",
"drive/fileapi/webkit_file_stream_writer_impl.cc",
"drive/fileapi/webkit_file_stream_writer_impl.h",
"drive/write_on_cache_file.cc",
"drive/write_on_cache_file.h",
"eol_notification.cc",
......@@ -2509,11 +2497,8 @@ source_set("unit_tests") {
"customization/customization_document_unittest.cc",
"dbus/proxy_resolution_service_provider_unittest.cc",
"drive/download_handler_unittest.cc",
"drive/drive_file_stream_reader_unittest.cc",
"drive/drive_integration_service_unittest.cc",
"drive/file_system_util_unittest.cc",
"drive/fileapi/fileapi_worker_unittest.cc",
"drive/fileapi/webkit_file_stream_reader_impl_unittest.cc",
"drive/write_on_cache_file_unittest.cc",
"events/event_rewriter_unittest.cc",
"extensions/active_tab_permission_granter_delegate_chromeos_unittest.cc",
......
// Copyright 2013 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 CHROME_BROWSER_CHROMEOS_DRIVE_DRIVE_FILE_STREAM_READER_H_
#define CHROME_BROWSER_CHROMEOS_DRIVE_DRIVE_FILE_STREAM_READER_H_
#include <stdint.h>
#include <memory>
#include <string>
#include <vector>
#include "base/callback.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/threading/thread_checker.h"
#include "components/drive/file_errors.h"
#include "google_apis/drive/drive_api_error_codes.h"
#include "net/base/completion_once_callback.h"
namespace base {
class SequencedTaskRunner;
} // namespace base
namespace net {
class HttpByteRange;
class IOBuffer;
} // namespace net
namespace drive {
namespace util {
class LocalFileReader;
} // namespace util
namespace internal {
// An interface to dispatch the reading operation. If the file is locally
// cached, LocalReaderProxy defined below will be used. Otherwise (i.e. the
// file is being downloaded from the server), NetworkReaderProxy will be used.
class ReaderProxy {
public:
virtual ~ReaderProxy() {}
// Called from DriveFileStreamReader::Read method.
virtual int Read(net::IOBuffer* buffer,
int buffer_length,
net::CompletionOnceCallback callback) = 0;
// Called when the data from the server is received.
virtual void OnGetContent(std::unique_ptr<std::string> data) = 0;
// Called when the accessing to the file system is completed.
virtual void OnCompleted(FileError error) = 0;
};
// The read operation implementation for the locally cached files.
class LocalReaderProxy : public ReaderProxy {
public:
// The |file_reader| should be the instance which is already opened.
// This class takes its ownership.
// |length| is the number of bytes to be read. It must be equal or
// smaller than the remaining data size in the |file_reader|.
LocalReaderProxy(std::unique_ptr<util::LocalFileReader> file_reader,
int64_t length);
~LocalReaderProxy() override;
// ReaderProxy overrides.
int Read(net::IOBuffer* buffer,
int buffer_length,
net::CompletionOnceCallback callback) override;
void OnGetContent(std::unique_ptr<std::string> data) override;
void OnCompleted(FileError error) override;
private:
std::unique_ptr<util::LocalFileReader> file_reader_;
// Callback for the LocalFileReader::Read.
void OnReadCompleted(net::CompletionOnceCallback callback, int read_result);
// The number of remaining bytes to be read.
int64_t remaining_length_;
THREAD_CHECKER(thread_checker_);
// This should remain the last member so it'll be destroyed first and
// invalidate its weak pointers before other members are destroyed.
base::WeakPtrFactory<LocalReaderProxy> weak_ptr_factory_{this};
DISALLOW_COPY_AND_ASSIGN(LocalReaderProxy);
};
// The read operation implementation for the file which is being downloaded.
class NetworkReaderProxy : public ReaderProxy {
public:
// If the instance is deleted during the download process, it is necessary
// to cancel the job. |job_canceller| should be the callback to run the
// cancelling. |full_content_length| is necessary for determining whether the
// deletion is done in the middle of download process.
NetworkReaderProxy(int64_t offset,
int64_t content_length,
int64_t full_content_length,
const base::Closure& job_canceller);
~NetworkReaderProxy() override;
// ReaderProxy overrides.
int Read(net::IOBuffer* buffer,
int buffer_length,
net::CompletionOnceCallback callback) override;
void OnGetContent(std::unique_ptr<std::string> data) override;
void OnCompleted(FileError error) override;
private:
// The data received from the server, but not yet read.
std::vector<std::unique_ptr<std::string>> pending_data_;
// The number of bytes to be skipped.
int64_t remaining_offset_;
// The number of bytes of remaining data (including the data not yet
// received from the server).
int64_t remaining_content_length_;
// Flag to remember whether this read request is for reading till the end of
// the file.
const bool is_full_download_;
int error_code_;
// To support pending Read(), it is necessary to keep its arguments.
scoped_refptr<net::IOBuffer> buffer_;
int buffer_length_;
net::CompletionOnceCallback callback_;
THREAD_CHECKER(thread_checker_);
// Keeps the closure to cancel downloading job if necessary.
// Will be reset when the job is completed (regardless whether the job is
// successfully done or not).
base::Closure job_canceller_;
DISALLOW_COPY_AND_ASSIGN(NetworkReaderProxy);
};
} // namespace internal
class FileSystemInterface;
class ResourceEntry;
// The stream reader for a file in FileSystem. Instances of this class
// should live on IO thread.
// Operations to communicate with a locally cached file will run on
// |file_task_runner| specified by the constructor.
class DriveFileStreamReader {
public:
// Callback to return the FileSystemInterface instance. This is an
// injecting point for testing.
// Note that the callback will be copied between threads (IO and UI), and
// will be called on UI thread.
typedef base::Callback<FileSystemInterface*()> FileSystemGetter;
// Callback to return the result of Initialize().
// |error| is net::Error code.
typedef base::OnceCallback<void(int error,
std::unique_ptr<ResourceEntry> entry)>
InitializeCompletionOnceCallback;
DriveFileStreamReader(const FileSystemGetter& file_system_getter,
base::SequencedTaskRunner* file_task_runner);
~DriveFileStreamReader();
// Returns true if the reader is initialized.
bool IsInitialized() const;
// Initializes the stream for the |drive_file_path|.
// |callback| must not be null.
void Initialize(const base::FilePath& drive_file_path,
const net::HttpByteRange& byte_range,
InitializeCompletionOnceCallback callback);
// Reads the data into |buffer| at most |buffer_length|, and returns
// the number of bytes. If an error happened, returns an error code.
// If no data is available yet, returns net::ERR_IO_PENDING immediately,
// and when the data is available the actual Read operation is done
// and |callback| will be run with the result.
// The Read() method must not be called before the Initialize() is completed
// successfully, or if there is pending read operation.
// Neither |buffer| nor |callback| must be null.
int Read(net::IOBuffer* buffer,
int buffer_length,
net::CompletionOnceCallback callback);
private:
// Used to store the cancel closure returned by FileSystemInterface.
void StoreCancelDownloadClosure(const base::Closure& cancel_download_closure);
// Part of Initialize. Called after GetFileContent's initialization
// is done.
void InitializeAfterGetFileContentInitialized(
const net::HttpByteRange& byte_range,
FileError error,
const base::FilePath& local_cache_file_path,
std::unique_ptr<ResourceEntry> entry);
// Part of Initialize. Called when the local file open process is done.
void InitializeAfterLocalFileOpen(
int64_t length,
std::unique_ptr<ResourceEntry> entry,
std::unique_ptr<util::LocalFileReader> file_reader,
int open_result);
// Called when the data is received from the server.
void OnGetContent(google_apis::DriveApiErrorCode error_code,
std::unique_ptr<std::string> data);
// Called when GetFileContent is completed.
void OnGetFileContentCompletion(
FileError error);
InitializeCompletionOnceCallback init_callback_;
const FileSystemGetter file_system_getter_;
scoped_refptr<base::SequencedTaskRunner> file_task_runner_;
base::Closure cancel_download_closure_;
std::unique_ptr<internal::ReaderProxy> reader_proxy_;
THREAD_CHECKER(thread_checker_);
// This should remain the last member so it'll be destroyed first and
// invalidate its weak pointers before other members are destroyed.
base::WeakPtrFactory<DriveFileStreamReader> weak_ptr_factory_{this};
DISALLOW_COPY_AND_ASSIGN(DriveFileStreamReader);
};
} // namespace drive
#endif // CHROME_BROWSER_CHROMEOS_DRIVE_DRIVE_FILE_STREAM_READER_H_
// Copyright 2014 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 CHROME_BROWSER_CHROMEOS_DRIVE_FILEAPI_ASYNC_FILE_UTIL_H_
#define CHROME_BROWSER_CHROMEOS_DRIVE_FILEAPI_ASYNC_FILE_UTIL_H_
#include <stdint.h>
#include <memory>
#include "base/callback.h"
#include "base/macros.h"
#include "storage/browser/fileapi/async_file_util.h"
namespace drive {
namespace internal {
// The implementation of storage::AsyncFileUtil for Drive File System.
class AsyncFileUtil : public storage::AsyncFileUtil {
public:
AsyncFileUtil();
~AsyncFileUtil() override;
// storage::AsyncFileUtil overrides.
void CreateOrOpen(
std::unique_ptr<storage::FileSystemOperationContext> context,
const storage::FileSystemURL& url,
int file_flags,
CreateOrOpenCallback callback) override;
void EnsureFileExists(
std::unique_ptr<storage::FileSystemOperationContext> context,
const storage::FileSystemURL& url,
EnsureFileExistsCallback callback) override;
void CreateDirectory(
std::unique_ptr<storage::FileSystemOperationContext> context,
const storage::FileSystemURL& url,
bool exclusive,
bool recursive,
StatusCallback callback) override;
void GetFileInfo(std::unique_ptr<storage::FileSystemOperationContext> context,
const storage::FileSystemURL& url,
int fields,
GetFileInfoCallback callback) override;
void ReadDirectory(
std::unique_ptr<storage::FileSystemOperationContext> context,
const storage::FileSystemURL& url,
ReadDirectoryCallback callback) override;
void Touch(std::unique_ptr<storage::FileSystemOperationContext> context,
const storage::FileSystemURL& url,
const base::Time& last_access_time,
const base::Time& last_modified_time,
StatusCallback callback) override;
void Truncate(std::unique_ptr<storage::FileSystemOperationContext> context,
const storage::FileSystemURL& url,
int64_t length,
StatusCallback callback) override;
void CopyFileLocal(
std::unique_ptr<storage::FileSystemOperationContext> context,
const storage::FileSystemURL& src_url,
const storage::FileSystemURL& dest_url,
CopyOrMoveOption option,
CopyFileProgressCallback progress_callback,
StatusCallback callback) override;
void MoveFileLocal(
std::unique_ptr<storage::FileSystemOperationContext> context,
const storage::FileSystemURL& src_url,
const storage::FileSystemURL& dest_url,
CopyOrMoveOption option,
StatusCallback callback) override;
void CopyInForeignFile(
std::unique_ptr<storage::FileSystemOperationContext> context,
const base::FilePath& src_file_path,
const storage::FileSystemURL& dest_url,
StatusCallback callback) override;
void DeleteFile(std::unique_ptr<storage::FileSystemOperationContext> context,
const storage::FileSystemURL& url,
StatusCallback callback) override;
void DeleteDirectory(
std::unique_ptr<storage::FileSystemOperationContext> context,
const storage::FileSystemURL& url,
StatusCallback callback) override;
void DeleteRecursively(
std::unique_ptr<storage::FileSystemOperationContext> context,
const storage::FileSystemURL& url,
StatusCallback callback) override;
void CreateSnapshotFile(
std::unique_ptr<storage::FileSystemOperationContext> context,
const storage::FileSystemURL& url,
CreateSnapshotFileCallback callback) override;
private:
DISALLOW_COPY_AND_ASSIGN(AsyncFileUtil);
};
} // namespace internal
} // namespace drive
#endif // CHROME_BROWSER_CHROMEOS_DRIVE_FILEAPI_ASYNC_FILE_UTIL_H_
// Copyright 2014 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.
#include "chrome/browser/chromeos/drive/fileapi/file_system_backend_delegate.h"
#include <memory>
#include "base/bind.h"
#include "base/files/file_path.h"
#include "base/task/post_task.h"
#include "chrome/browser/chromeos/drive/file_system_util.h"
#include "chrome/browser/chromeos/drive/fileapi/async_file_util.h"
#include "chrome/browser/chromeos/drive/fileapi/fileapi_worker.h"
#include "chrome/browser/chromeos/drive/fileapi/webkit_file_stream_reader_impl.h"
#include "chrome/browser/chromeos/drive/fileapi/webkit_file_stream_writer_impl.h"
#include "components/drive/chromeos/file_system_interface.h"
#include "components/drive/drive_api_util.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "storage/browser/fileapi/async_file_util.h"
#include "storage/browser/fileapi/file_stream_reader.h"
#include "storage/browser/fileapi/file_system_context.h"
#include "storage/browser/fileapi/file_system_url.h"
using content::BrowserThread;
namespace drive {
namespace {
// Called on the UI thread after GetRedirectURLForContentsOnUIThread. Obtains
// the browser URL from |entry|. |callback| will be called on the IO thread.
void GetRedirectURLForContentsOnUIThreadWithResourceEntry(
const storage::URLCallback& callback,
FileError error,
std::unique_ptr<ResourceEntry> entry) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
GURL url;
if (error == FILE_ERROR_OK && entry->has_file_specific_info() &&
entry->file_specific_info().is_hosted_document()) {
url = GURL(entry->alternate_url());
}
base::PostTask(FROM_HERE, {BrowserThread::IO}, base::BindOnce(callback, url));
}
// Called on the UI thread after
// FileSystemBackendDelegate::GetRedirectURLForContents. Requestes to obtain
// ResourceEntry for the |url|.
void GetRedirectURLForContentsOnUIThread(
const storage::FileSystemURL& url,
const storage::URLCallback& callback) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
FileSystemInterface* const file_system =
fileapi_internal::GetFileSystemFromUrl(url);
if (!file_system) {
base::PostTask(FROM_HERE, {BrowserThread::IO},
base::BindOnce(callback, GURL()));
return;
}
const base::FilePath file_path = util::ExtractDrivePathFromFileSystemUrl(url);
if (file_path.empty()) {
base::PostTask(FROM_HERE, {BrowserThread::IO},
base::BindOnce(callback, GURL()));
return;
}
file_system->GetResourceEntry(
file_path,
base::BindOnce(&GetRedirectURLForContentsOnUIThreadWithResourceEntry,
callback));
}
} // namespace
FileSystemBackendDelegate::FileSystemBackendDelegate()
: async_file_util_(new internal::AsyncFileUtil) {
}
FileSystemBackendDelegate::~FileSystemBackendDelegate() = default;
storage::AsyncFileUtil* FileSystemBackendDelegate::GetAsyncFileUtil(
storage::FileSystemType type) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
DCHECK_EQ(storage::kFileSystemTypeDrive, type);
return async_file_util_.get();
}
std::unique_ptr<storage::FileStreamReader>
FileSystemBackendDelegate::CreateFileStreamReader(
const storage::FileSystemURL& url,
int64_t offset,
int64_t max_bytes_to_read,
const base::Time& expected_modification_time,
storage::FileSystemContext* context) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
DCHECK_EQ(storage::kFileSystemTypeDrive, url.type());
base::FilePath file_path = util::ExtractDrivePathFromFileSystemUrl(url);
if (file_path.empty())
return std::unique_ptr<storage::FileStreamReader>();
return std::unique_ptr<storage::FileStreamReader>(
new internal::WebkitFileStreamReaderImpl(
base::Bind(&fileapi_internal::GetFileSystemFromUrl, url),
context->default_file_task_runner(), file_path, offset,
expected_modification_time));
}
std::unique_ptr<storage::FileStreamWriter>
FileSystemBackendDelegate::CreateFileStreamWriter(
const storage::FileSystemURL& url,
int64_t offset,
storage::FileSystemContext* context) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
DCHECK_EQ(storage::kFileSystemTypeDrive, url.type());
base::FilePath file_path = util::ExtractDrivePathFromFileSystemUrl(url);
// Hosted documents don't support stream writer.
if (file_path.empty() || util::HasHostedDocumentExtension(file_path))
return std::unique_ptr<storage::FileStreamWriter>();
return std::unique_ptr<storage::FileStreamWriter>(
new internal::WebkitFileStreamWriterImpl(
base::Bind(&fileapi_internal::GetFileSystemFromUrl, url),
context->default_file_task_runner(), file_path, offset));
}
storage::WatcherManager* FileSystemBackendDelegate::GetWatcherManager(
storage::FileSystemType type) {
NOTIMPLEMENTED();
return nullptr;
}
void FileSystemBackendDelegate::GetRedirectURLForContents(
const storage::FileSystemURL& url,
const storage::URLCallback& callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
base::PostTask(
FROM_HERE, {BrowserThread::UI},
base::BindOnce(&GetRedirectURLForContentsOnUIThread, url, callback));
}
} // namespace drive
// Copyright 2014 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 CHROME_BROWSER_CHROMEOS_DRIVE_FILEAPI_FILE_SYSTEM_BACKEND_DELEGATE_H_
#define CHROME_BROWSER_CHROMEOS_DRIVE_FILEAPI_FILE_SYSTEM_BACKEND_DELEGATE_H_
#include <stdint.h>
#include <memory>
#include "base/macros.h"
#include "chrome/browser/chromeos/fileapi/file_system_backend_delegate.h"
namespace storage {
class AsyncFileUtil;
class FileSystemContext;
class FileStreamReader;
class FileSystemURL;
class FileStreamWriter;
class WatcherManager;
} // namespace storage
namespace drive {
// Delegate implementation of the some methods in chromeos::FileSystemBackend
// for Drive file system.
class FileSystemBackendDelegate : public chromeos::FileSystemBackendDelegate {
public:
FileSystemBackendDelegate();
~FileSystemBackendDelegate() override;
// FileSystemBackend::Delegate overrides.
storage::AsyncFileUtil* GetAsyncFileUtil(
storage::FileSystemType type) override;
std::unique_ptr<storage::FileStreamReader> CreateFileStreamReader(
const storage::FileSystemURL& url,
int64_t offset,
int64_t max_bytes_to_read,
const base::Time& expected_modification_time,
storage::FileSystemContext* context) override;
std::unique_ptr<storage::FileStreamWriter> CreateFileStreamWriter(
const storage::FileSystemURL& url,
int64_t offset,
storage::FileSystemContext* context) override;
storage::WatcherManager* GetWatcherManager(
storage::FileSystemType type) override;
void GetRedirectURLForContents(const storage::FileSystemURL& url,
const storage::URLCallback& callback) override;
private:
std::unique_ptr<storage::AsyncFileUtil> async_file_util_;
DISALLOW_COPY_AND_ASSIGN(FileSystemBackendDelegate);
};
} // namespace drive
#endif // CHROME_BROWSER_CHROMEOS_DRIVE_FILEAPI_FILE_SYSTEM_BACKEND_DELEGATE_H_
// Copyright 2014 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.
//
// This file provides the core implementation of fileapi methods.
// The functions should be called on UI thread.
// Note that most method invocation of fileapi is done on IO thread. The gap is
// filled by FileSystemProxy.
// Also, the order of arguments for the functions which take FileSystemInterface
// at the last is intentional. The instance of FileSystemInterface should be
// accessible only on UI thread, but arguments are passed on IO thread.
// So, here is an intended use case:
// 1) Bind arguments on IO thread. Then a callback instance whose type is
// Callback<void(FileSysstemInterface*)> is created.
// 2) Post the task to the UI thread.
// 3) On UI thread, check if the instance of FileSystemInterface is alive or
// not. If yes, Run the callback with it.
#ifndef CHROME_BROWSER_CHROMEOS_DRIVE_FILEAPI_FILEAPI_WORKER_H_
#define CHROME_BROWSER_CHROMEOS_DRIVE_FILEAPI_FILEAPI_WORKER_H_
#include <stdint.h>
#include <vector>
#include "base/callback_forward.h"
#include "base/memory/weak_ptr.h"
#include "components/drive/file_errors.h"
#include "components/services/filesystem/public/mojom/types.mojom.h"
#include "storage/browser/blob/scoped_file.h"
namespace base {
class FilePath;
} // namespace base
namespace storage {
struct DirectoryEntry;
class FileSystemURL;
} // namespace storage
namespace drive {
class FileSystemInterface;
namespace fileapi_internal {
typedef base::Callback<FileSystemInterface*()> FileSystemGetter;
typedef base::Callback<
void(base::File::Error result)> StatusCallback;
typedef base::Callback<
void(base::File::Error result,
const base::File::Info& file_info)> GetFileInfoCallback;
typedef base::RepeatingCallback<void(
base::File::Error result,
std::vector<filesystem::mojom::DirectoryEntry> file_list,
bool has_more)>
ReadDirectoryCallback;
typedef base::Callback<void(base::File::Error result,
const base::File::Info& file_info,
const base::FilePath& snapshot_file_path,
storage::ScopedFile::ScopeOutPolicy
scope_out_policy)> CreateSnapshotFileCallback;
typedef base::Callback<
void(base::File::Error result,
const base::FilePath& snapshot_file_path,
const base::Closure& close_callback)>
CreateWritableSnapshotFileCallback;
typedef base::Callback<
void(base::File file,
const base::Closure& close_callback)> OpenFileCallback;
// Gets the profile of the Drive entry pointed by |url|. Used as
// FileSystemGetter callback by binding an URL on the IO thread and passing to
// the UI thread.
FileSystemInterface* GetFileSystemFromUrl(const storage::FileSystemURL& url);
// Runs |file_system_getter| to obtain the instance of FileSystemInstance,
// and then runs |callback| with it.
// If |file_system_getter| returns NULL, runs |error_callback| instead.
// This function must be called on UI thread.
// |file_system_getter| and |callback| must not be null, but
// |error_callback| can be null (if no operation is necessary for error
// case).
void RunFileSystemCallback(
const FileSystemGetter& file_system_getter,
const base::Callback<void(FileSystemInterface*)>& callback,
const base::Closure& error_callback);
// Returns the metadata info of the file at |file_path|.
// Called from FileSystemProxy::GetFileInfo().
void GetFileInfo(const base::FilePath& file_path,
const GetFileInfoCallback& callback,
FileSystemInterface* file_system);
// Copies a file from |src_file_path| to |dest_file_path|.
// Called from FileSystemProxy::Copy().
void Copy(const base::FilePath& src_file_path,
const base::FilePath& dest_file_path,
bool preserve_last_modified,
const StatusCallback& callback,
FileSystemInterface* file_system);
// Moves a file from |src_file_path| to |dest_file_path|.
// Called from FileSystemProxy::Move().
void Move(const base::FilePath& src_file_path,
const base::FilePath& dest_file_path,
const StatusCallback& callback,
FileSystemInterface* file_system);
// Copies a file at |src_foreign_file_path|, which is not managed by Drive File
// System, to |dest_file_path|.
void CopyInForeignFile(const base::FilePath& src_foreign_file_path,
const base::FilePath& dest_file_path,
const StatusCallback& callback,
FileSystemInterface* file_system);
// Reads the contents of the directory at |file_path|.
// Called from FileSystemProxy::ReadDirectory().
void ReadDirectory(const base::FilePath& file_path,
const ReadDirectoryCallback& callback,
FileSystemInterface* file_system);
// Removes a file at |file_path|. Called from FileSystemProxy::Remove().
void Remove(const base::FilePath& file_path,
bool is_recursive,
const StatusCallback& callback,
FileSystemInterface* file_system);
// Creates a new directory at |file_path|.
// Called from FileSystemProxy::CreateDirectory().
void CreateDirectory(const base::FilePath& file_path,
bool is_exclusive,
bool is_recursive,
const StatusCallback& callback,
FileSystemInterface* file_system);
// Creates a new file at |file_path|.
// Called from FileSystemProxy::CreateFile().
void CreateFile(const base::FilePath& file_path,
bool is_exclusive,
const StatusCallback& callback,
FileSystemInterface* file_system);
// Truncates the file at |file_path| to |length| bytes.
// Called from FileSystemProxy::Truncate().
void Truncate(const base::FilePath& file_path,
int64_t length,
const StatusCallback& callback,
FileSystemInterface* file_system);
// Creates a snapshot for the file at |file_path|.
// Called from FileSystemProxy::CreateSnapshotFile().
void CreateSnapshotFile(const base::FilePath& file_path,
const CreateSnapshotFileCallback& callback,
FileSystemInterface* file_system);
// Creates a writable snapshot for the file at |file_path|.
// After writing operation is done, |close_callback| must be called.
void CreateWritableSnapshotFile(
const base::FilePath& file_path,
const CreateWritableSnapshotFileCallback& callback,
FileSystemInterface* file_system);
// Opens the file at |file_path| with options |file_flags|.
// Called from FileSystemProxy::OpenFile.
void OpenFile(const base::FilePath& file_path,
int file_flags,
const OpenFileCallback& callback,
FileSystemInterface* file_system);
// Changes timestamp of the file at |file_path| to |last_access_time| and
// |last_modified_time|. Called from FileSystemProxy::TouchFile().
void TouchFile(const base::FilePath& file_path,
const base::Time& last_access_time,
const base::Time& last_modified_time,
const StatusCallback& callback,
FileSystemInterface* file_system);
} // namespace fileapi_internal
} // namespace drive
#endif // CHROME_BROWSER_CHROMEOS_DRIVE_FILEAPI_FILEAPI_WORKER_H_
// Copyright 2014 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.
#include "chrome/browser/chromeos/drive/fileapi/fileapi_worker.h"
#include <stdint.h>
#include <memory>
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/files/file_util.h"
#include "components/drive/chromeos/dummy_file_system.h"
#include "content/public/test/browser_task_environment.h"
#include "content/public/test/test_utils.h"
#include "google_apis/drive/test_util.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace drive {
namespace fileapi_internal {
namespace {
// Increments |num_called| for checking how many times the closure is called.
void Increment(int* num_called) {
++*num_called;
}
// Returns the |instance| as is.
FileSystemInterface* GetFileSystem(FileSystemInterface* instance) {
return instance;
}
// A test file system that always returns |local_file_path|. For testing
// purpose, it checks if |open_mode| is the expected value, and record if the
// close callback is called.
class TestFileSystemForOpenFile : public DummyFileSystem {
public:
TestFileSystemForOpenFile(const base::FilePath& local_file_path,
OpenMode expected_open_mode)
: local_file_path_(local_file_path),
expected_open_mode_(expected_open_mode),
closed_(false) {
}
void OpenFile(const base::FilePath& file_path,
OpenMode open_mode,
const std::string& mime_type,
drive::OpenFileCallback callback) override {
EXPECT_EQ(expected_open_mode_, open_mode);
std::move(callback).Run(
FILE_ERROR_OK, local_file_path_,
base::Bind(&TestFileSystemForOpenFile::Close, base::Unretained(this)));
}
void Close() {
closed_ = true;
}
bool closed() const { return closed_; }
private:
const base::FilePath local_file_path_;
const OpenMode expected_open_mode_;
bool closed_;
};
// Helper function of testing OpenFile() for write access. It checks that the
// file handle correctly writes to the expected file.
void VerifyWrite(int64_t expected_size,
const base::FilePath& expected_written_path,
const std::string& write_data,
base::File file,
const base::Closure& close_callback) {
// Check that the file was properly opened.
EXPECT_TRUE(file.IsValid());
EXPECT_FALSE(close_callback.is_null());
// Check that the file has the expected length (i.e., truncated or not)
base::File::Info info;
EXPECT_TRUE(file.GetInfo(&info));
EXPECT_EQ(expected_size, info.size);
// Write some data.
const int data_size = static_cast<int>(write_data.size());
EXPECT_EQ(data_size, file.Write(0, write_data.c_str(), data_size));
EXPECT_TRUE(file.SetLength(data_size));
// Close.
file.Close();
close_callback.Run();
// Checks that the written content goes to |expected_written_path|. I.e.,
// the |file| handle is pointing to the file.
std::string written;
EXPECT_TRUE(base::ReadFileToString(expected_written_path, &written));
EXPECT_EQ(write_data, written);
}
// Helper function of testing OpenFile() for read access. It checks that the
// file is readable and contains |expected_data|.
void VerifyRead(const std::string& expected_data,
base::File file,
const base::Closure& close_callback) {
// Check that the file was properly opened.
EXPECT_TRUE(file.IsValid());
EXPECT_FALSE(close_callback.is_null());
// Check that the file has the expected content.
const int data_size = static_cast<int>(expected_data.size());
base::File::Info info;
EXPECT_TRUE(file.GetInfo(&info));
EXPECT_EQ(data_size, info.size);
std::vector<char> buffer(data_size);
EXPECT_EQ(data_size, file.Read(0, buffer.data(), data_size));
EXPECT_EQ(expected_data, std::string(buffer.begin(), buffer.end()));
// Close.
file.Close();
close_callback.Run();
}
} // namespace
class FileApiWorkerTest : public testing::Test {
private:
content::BrowserTaskEnvironment task_environment_;
};
TEST_F(FileApiWorkerTest, RunFileSystemCallbackSuccess) {
DummyFileSystem dummy_file_system;
FileSystemInterface* file_system = nullptr;
RunFileSystemCallback(
base::Bind(&GetFileSystem, &dummy_file_system),
google_apis::test_util::CreateCopyResultCallback(&file_system),
base::Closure());
EXPECT_EQ(&dummy_file_system, file_system);
}
TEST_F(FileApiWorkerTest, RunFileSystemCallbackFail) {
FileSystemInterface* file_system = nullptr;
// Make sure on_error_callback is called if file_system_getter returns NULL.
int num_called = 0;
RunFileSystemCallback(
base::Bind(&GetFileSystem, static_cast<FileSystemInterface*>(nullptr)),
google_apis::test_util::CreateCopyResultCallback(&file_system),
base::Bind(&Increment, &num_called));
EXPECT_EQ(1, num_called);
// Just make sure this null |on_error_callback| doesn't cause a crash.
RunFileSystemCallback(
base::Bind(&GetFileSystem, static_cast<FileSystemInterface*>(nullptr)),
google_apis::test_util::CreateCopyResultCallback(&file_system),
base::Closure());
}
TEST_F(FileApiWorkerTest, OpenFileForCreateWrite) {
const base::FilePath kDummyPath = base::FilePath::FromUTF8Unsafe("whatever");
const std::string kWriteData = "byebye";
base::FilePath temp_path;
base::CreateTemporaryFile(&temp_path);
// CREATE => CREATE (fails if file exists.)
TestFileSystemForOpenFile file_system(temp_path, CREATE_FILE);
const int64_t kExpectedSize = 0;
OpenFile(kDummyPath,
base::File::FLAG_CREATE | base::File::FLAG_WRITE,
base::Bind(&VerifyWrite, kExpectedSize, temp_path, kWriteData),
&file_system);
content::RunAllTasksUntilIdle();
EXPECT_TRUE(file_system.closed());
}
TEST_F(FileApiWorkerTest, OpenFileForOpenAlwaysWrite) {
const base::FilePath kDummyPath = base::FilePath::FromUTF8Unsafe("whatever");
const std::string kWriteData = "byebye";
const std::string kInitialData = "hello";
base::FilePath temp_path;
base::CreateTemporaryFile(&temp_path);
google_apis::test_util::WriteStringToFile(temp_path, kInitialData);
// OPEN_ALWAYS => OPEN_OR_CREATE (success whether file exists or not.)
// No truncation should take place.
TestFileSystemForOpenFile file_system(temp_path, OPEN_OR_CREATE_FILE);
const int64_t kExpectedSize = static_cast<int64_t>(kInitialData.size());
OpenFile(kDummyPath,
base::File::FLAG_OPEN_ALWAYS | base::File::FLAG_WRITE,
base::Bind(&VerifyWrite, kExpectedSize, temp_path, kWriteData),
&file_system);
content::RunAllTasksUntilIdle();
EXPECT_TRUE(file_system.closed());
}
TEST_F(FileApiWorkerTest, OpenFileForOpenTruncatedWrite) {
const base::FilePath kDummyPath = base::FilePath::FromUTF8Unsafe("whatever");
const std::string kInitialData = "hello";
const std::string kWriteData = "byebye";
base::FilePath temp_path;
base::CreateTemporaryFile(&temp_path);
google_apis::test_util::WriteStringToFile(temp_path, kInitialData);
// OPEN_TRUNCATED => OPEN (failure when the file did not exist.)
// It should truncate the file before passing to the callback.
TestFileSystemForOpenFile file_system(temp_path, OPEN_FILE);
const int64_t kExpectedSize = 0;
OpenFile(kDummyPath,
base::File::FLAG_OPEN_TRUNCATED | base::File::FLAG_WRITE,
base::Bind(&VerifyWrite, kExpectedSize, temp_path, kWriteData),
&file_system);
content::RunAllTasksUntilIdle();
EXPECT_TRUE(file_system.closed());
}
TEST_F(FileApiWorkerTest, OpenFileForOpenCreateAlwaysWrite) {
const base::FilePath kDummyPath = base::FilePath::FromUTF8Unsafe("whatever");
const std::string kInitialData = "hello";
const std::string kWriteData = "byebye";
base::FilePath temp_path;
base::CreateTemporaryFile(&temp_path);
google_apis::test_util::WriteStringToFile(temp_path, kInitialData);
// CREATE_ALWAYS => OPEN_OR_CREATE (success whether file exists or not.)
// It should truncate the file before passing to the callback.
TestFileSystemForOpenFile file_system(temp_path, OPEN_OR_CREATE_FILE);
const int64_t kExpectedSize = 0;
OpenFile(kDummyPath,
base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE,
base::Bind(&VerifyWrite, kExpectedSize, temp_path, kWriteData),
&file_system);
content::RunAllTasksUntilIdle();
EXPECT_TRUE(file_system.closed());
}
TEST_F(FileApiWorkerTest, OpenFileForOpenRead) {
const base::FilePath kDummyPath = base::FilePath::FromUTF8Unsafe("whatever");
const std::string kInitialData = "hello";
base::FilePath temp_path;
base::CreateTemporaryFile(&temp_path);
google_apis::test_util::WriteStringToFile(temp_path, kInitialData);
// OPEN => OPEN (failure when the file did not exist.)
TestFileSystemForOpenFile file_system(temp_path, OPEN_FILE);
OpenFile(kDummyPath,
base::File::FLAG_OPEN | base::File::FLAG_READ,
base::Bind(&VerifyRead, kInitialData),
&file_system);
content::RunAllTasksUntilIdle();
EXPECT_TRUE(file_system.closed());
}
} // namespace fileapi_internal
} // namespace drive
// Copyright 2014 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.
#include "chrome/browser/chromeos/drive/fileapi/webkit_file_stream_reader_impl.h"
#include <utility>
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/callback.h"
#include "base/logging.h"
#include "chrome/browser/chromeos/drive/drive_file_stream_reader.h"
#include "components/drive/drive.pb.h"
#include "content/public/browser/browser_thread.h"
#include "net/base/io_buffer.h"
#include "net/base/net_errors.h"
#include "net/http/http_byte_range.h"
using content::BrowserThread;
namespace drive {
namespace internal {
WebkitFileStreamReaderImpl::WebkitFileStreamReaderImpl(
const DriveFileStreamReader::FileSystemGetter& file_system_getter,
base::SequencedTaskRunner* file_task_runner,
const base::FilePath& drive_file_path,
int64_t offset,
const base::Time& expected_modification_time)
: stream_reader_(
new DriveFileStreamReader(file_system_getter, file_task_runner)),
drive_file_path_(drive_file_path),
offset_(offset),
expected_modification_time_(expected_modification_time),
file_size_(-1) {
DCHECK_GE(offset, 0);
}
WebkitFileStreamReaderImpl::~WebkitFileStreamReaderImpl() = default;
int WebkitFileStreamReaderImpl::Read(net::IOBuffer* buffer,
int buffer_length,
net::CompletionOnceCallback callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
DCHECK(stream_reader_);
DCHECK(buffer);
DCHECK(callback);
if (stream_reader_->IsInitialized())
return stream_reader_->Read(buffer, buffer_length, std::move(callback));
net::HttpByteRange byte_range;
byte_range.set_first_byte_position(offset_);
stream_reader_->Initialize(
drive_file_path_, byte_range,
base::BindOnce(
&WebkitFileStreamReaderImpl::OnStreamReaderInitialized,
weak_ptr_factory_.GetWeakPtr(),
base::BindOnce(
&WebkitFileStreamReaderImpl::ReadAfterStreamReaderInitialized,
weak_ptr_factory_.GetWeakPtr(), base::WrapRefCounted(buffer),
buffer_length, std::move(callback))));
return net::ERR_IO_PENDING;
}
int64_t WebkitFileStreamReaderImpl::GetLength(
net::Int64CompletionOnceCallback callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
DCHECK(stream_reader_);
DCHECK(callback);
if (stream_reader_->IsInitialized()) {
// Returns file_size regardless of |offset_|.
return file_size_;
}
net::HttpByteRange byte_range;
byte_range.set_first_byte_position(offset_);
stream_reader_->Initialize(
drive_file_path_, byte_range,
base::BindOnce(
&WebkitFileStreamReaderImpl::OnStreamReaderInitialized,
weak_ptr_factory_.GetWeakPtr(),
base::BindOnce(&WebkitFileStreamReaderImpl::
GetLengthAfterStreamReaderInitialized,
weak_ptr_factory_.GetWeakPtr(), std::move(callback))));
return net::ERR_IO_PENDING;
}
void WebkitFileStreamReaderImpl::OnStreamReaderInitialized(
net::CompletionOnceCallback callback,
int error,
std::unique_ptr<ResourceEntry> entry) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
DCHECK(stream_reader_);
DCHECK(callback);
// TODO(hashimoto): Report ERR_UPLOAD_FILE_CHANGED when modification time
// doesn't match. crbug.com/346625
if (error != net::OK) {
// Found an error. Close the |stream_reader_| and notify it to the caller.
stream_reader_.reset();
std::move(callback).Run(error);
return;
}
// Remember the size of the file.
file_size_ = entry->file_info().size();
std::move(callback).Run(net::OK);
}
void WebkitFileStreamReaderImpl::ReadAfterStreamReaderInitialized(
scoped_refptr<net::IOBuffer> buffer,
int buffer_length,
net::CompletionOnceCallback callback,
int initialization_result) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
DCHECK(callback);
if (initialization_result != net::OK) {
std::move(callback).Run(initialization_result);
return;
}
DCHECK(stream_reader_);
read_callback_ = std::move(callback);
int result =
stream_reader_->Read(buffer.get(), buffer_length,
base::BindOnce(&WebkitFileStreamReaderImpl::OnRead,
weak_ptr_factory_.GetWeakPtr()));
if (result != net::ERR_IO_PENDING)
std::move(read_callback_).Run(result);
}
void WebkitFileStreamReaderImpl::OnRead(int result) {
std::move(read_callback_).Run(result);
}
void WebkitFileStreamReaderImpl::GetLengthAfterStreamReaderInitialized(
net::Int64CompletionOnceCallback callback,
int initialization_result) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
DCHECK(callback);
if (initialization_result != net::OK) {
std::move(callback).Run(initialization_result);
return;
}
DCHECK_GE(file_size_, 0);
std::move(callback).Run(file_size_);
}
} // namespace internal
} // namespace drive
// Copyright 2014 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 CHROME_BROWSER_CHROMEOS_DRIVE_FILEAPI_WEBKIT_FILE_STREAM_READER_IMPL_H_
#define CHROME_BROWSER_CHROMEOS_DRIVE_FILEAPI_WEBKIT_FILE_STREAM_READER_IMPL_H_
#include <stdint.h>
#include <memory>
#include "base/files/file_path.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "base/time/time.h"
#include "chrome/browser/chromeos/drive/drive_file_stream_reader.h"
#include "net/base/completion_once_callback.h"
#include "storage/browser/fileapi/file_stream_reader.h"
namespace base {
class SequencedTaskRunner;
} // namespace base
namespace drive {
class ResourceEntry;
namespace internal {
// The implementation of storage::FileStreamReader for drive file system.
// storage::FileStreamReader does not provide a way for explicit
// initialization, hence the initialization of this class will be done lazily.
// Note that when crbug.com/225339 is resolved, this class will be also
// initialized explicitly.
class WebkitFileStreamReaderImpl : public storage::FileStreamReader {
public:
WebkitFileStreamReaderImpl(
const DriveFileStreamReader::FileSystemGetter& file_system_getter,
base::SequencedTaskRunner* file_task_runner,
const base::FilePath& drive_file_path,
int64_t offset,
const base::Time& expected_modification_time);
~WebkitFileStreamReaderImpl() override;
// storage::FileStreamReader override.
int Read(net::IOBuffer* buffer,
int buffer_length,
net::CompletionOnceCallback callback) override;
int64_t GetLength(net::Int64CompletionOnceCallback callback) override;
private:
// Called upon the initialization completion of |stream_reader_|.
// Processes the result of the initialization with checking last
// modified time, and calls |callback| with net::Error code as its result.
void OnStreamReaderInitialized(net::CompletionOnceCallback callback,
int error,
std::unique_ptr<ResourceEntry> entry);
// Part of Read(). Called after all the initialization process is completed.
void ReadAfterStreamReaderInitialized(scoped_refptr<net::IOBuffer> buffer,
int buffer_length,
net::CompletionOnceCallback callback,
int initialization_result);
// Part of Read(). Passed in to DriveFileStreamReader::Read().
void OnRead(int result);
// Part of GetLength(). Called after all the initialization process is
// completed.
void GetLengthAfterStreamReaderInitialized(
net::Int64CompletionOnceCallback callback,
int initialization_result);
net::CompletionOnceCallback read_callback_;
std::unique_ptr<DriveFileStreamReader> stream_reader_;
const base::FilePath drive_file_path_;
const int64_t offset_;
const base::Time expected_modification_time_;
// This is available only after initialize is done.
int64_t file_size_;
// This should remain the last member so it'll be destroyed first and
// invalidate its weak pointers before other members are destroyed.
base::WeakPtrFactory<WebkitFileStreamReaderImpl> weak_ptr_factory_{this};
DISALLOW_COPY_AND_ASSIGN(WebkitFileStreamReaderImpl);
};
} // namespace internal
} // namespace drive
#endif // CHROME_BROWSER_CHROMEOS_DRIVE_FILEAPI_WEBKIT_FILE_STREAM_READER_IMPL_H_
// Copyright 2014 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.
#include "chrome/browser/chromeos/drive/fileapi/webkit_file_stream_reader_impl.h"
#include <stddef.h>
#include <stdint.h>
#include <memory>
#include <string>
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/run_loop.h"
#include "base/threading/thread.h"
#include "base/time/time.h"
#include "components/drive/chromeos/drive_test_util.h"
#include "components/drive/chromeos/fake_file_system.h"
#include "components/drive/chromeos/file_system_interface.h"
#include "components/drive/file_system_core_util.h"
#include "components/drive/service/fake_drive_service.h"
#include "components/drive/service/test_util.h"
#include "content/public/test/browser_task_environment.h"
#include "google_apis/drive/drive_api_parser.h"
#include "google_apis/drive/time_util.h"
#include "net/base/io_buffer.h"
#include "net/base/net_errors.h"
#include "net/base/test_completion_callback.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace drive {
namespace internal {
class WebkitFileStreamReaderImplTest : public ::testing::Test {
protected:
// Because the testee should live on IO thread, the main thread is
// reused as IO thread, and UI thread will be run on background.
WebkitFileStreamReaderImplTest()
: task_environment_(content::BrowserTaskEnvironment::IO_MAINLOOP) {}
void SetUp() override {
worker_thread_ =
std::make_unique<base::Thread>("WebkitFileStreamReaderImplTest");
ASSERT_TRUE(worker_thread_->Start());
// Initialize FakeDriveService.
fake_drive_service_ = std::make_unique<FakeDriveService>();
ASSERT_TRUE(test_util::SetUpTestEntries(fake_drive_service_.get()));
// Create a testee instance.
fake_file_system_ =
std::make_unique<test_util::FakeFileSystem>(fake_drive_service_.get());
}
FileSystemInterface* GetFileSystem() {
return fake_file_system_.get();
}
DriveFileStreamReader::FileSystemGetter GetFileSystemGetter() {
return base::Bind(&WebkitFileStreamReaderImplTest::GetFileSystem,
base::Unretained(this));
}
content::BrowserTaskEnvironment task_environment_;
std::unique_ptr<base::Thread> worker_thread_;
std::unique_ptr<FakeDriveService> fake_drive_service_;
std::unique_ptr<test_util::FakeFileSystem> fake_file_system_;
};
TEST_F(WebkitFileStreamReaderImplTest, ReadThenGetLength) {
const base::FilePath kDriveFile =
util::GetDriveMyDriveRootPath().AppendASCII("File 1.txt");
std::unique_ptr<WebkitFileStreamReaderImpl> reader(
new WebkitFileStreamReaderImpl(
GetFileSystemGetter(), worker_thread_->task_runner().get(),
kDriveFile,
0, // offset
base::Time())); // expected modification time
std::string content;
ASSERT_EQ(net::OK, test_util::ReadAllData(reader.get(), &content));
net::TestInt64CompletionCallback callback;
int64_t length = reader->GetLength(callback.callback());
length = callback.GetResult(length);
EXPECT_EQ(content.size(), static_cast<size_t>(length));
}
TEST_F(WebkitFileStreamReaderImplTest, GetLengthThenRead) {
const base::FilePath kDriveFile =
util::GetDriveMyDriveRootPath().AppendASCII("File 1.txt");
std::unique_ptr<WebkitFileStreamReaderImpl> reader(
new WebkitFileStreamReaderImpl(
GetFileSystemGetter(), worker_thread_->task_runner().get(),
kDriveFile,
0, // offset
base::Time())); // expected modification time
net::TestInt64CompletionCallback callback;
int64_t length = reader->GetLength(callback.callback());
length = callback.GetResult(length);
std::string content;
ASSERT_EQ(net::OK, test_util::ReadAllData(reader.get(), &content));
EXPECT_EQ(content.size(), static_cast<size_t>(length));
}
TEST_F(WebkitFileStreamReaderImplTest, ReadWithOffset) {
const base::FilePath kDriveFile =
util::GetDriveMyDriveRootPath().AppendASCII("File 1.txt");
const int kOffset = 5;
std::unique_ptr<WebkitFileStreamReaderImpl> reader(
new WebkitFileStreamReaderImpl(
GetFileSystemGetter(), worker_thread_->task_runner().get(),
kDriveFile, kOffset,
base::Time())); // expected modification time
std::string content;
ASSERT_EQ(net::OK, test_util::ReadAllData(reader.get(), &content));
net::TestInt64CompletionCallback callback;
int64_t length = reader->GetLength(callback.callback());
length = callback.GetResult(length);
EXPECT_EQ(content.size() + kOffset, static_cast<size_t>(length));
}
TEST_F(WebkitFileStreamReaderImplTest, ReadError) {
const base::FilePath kDriveFile =
util::GetDriveMyDriveRootPath().AppendASCII("non-existing.txt");
std::unique_ptr<WebkitFileStreamReaderImpl> reader(
new WebkitFileStreamReaderImpl(
GetFileSystemGetter(), worker_thread_->task_runner().get(),
kDriveFile,
0, // offset
base::Time())); // expected modification time
const int kBufferSize = 10;
scoped_refptr<net::IOBuffer> io_buffer =
base::MakeRefCounted<net::IOBuffer>(kBufferSize);
net::TestCompletionCallback callback;
int result = reader->Read(io_buffer.get(), kBufferSize, callback.callback());
result = callback.GetResult(result);
EXPECT_EQ(net::ERR_FILE_NOT_FOUND, result);
}
TEST_F(WebkitFileStreamReaderImplTest, GetLengthError) {
const base::FilePath kDriveFile =
util::GetDriveMyDriveRootPath().AppendASCII("non-existing.txt");
std::unique_ptr<WebkitFileStreamReaderImpl> reader(
new WebkitFileStreamReaderImpl(
GetFileSystemGetter(), worker_thread_->task_runner().get(),
kDriveFile,
0, // offset
base::Time())); // expected modification time
net::TestInt64CompletionCallback callback;
int64_t result = reader->GetLength(callback.callback());
result = callback.GetResult(result);
EXPECT_EQ(net::ERR_FILE_NOT_FOUND, result);
}
TEST_F(WebkitFileStreamReaderImplTest, LastModification) {
const base::FilePath kDriveFile =
util::GetDriveMyDriveRootPath().AppendASCII("File 1.txt");
base::Time expected_modification_time;
ASSERT_TRUE(google_apis::util::GetTimeFromString(
"2011-12-14T00:40:47.330Z", &expected_modification_time));
FileError error = FILE_ERROR_FAILED;
std::unique_ptr<ResourceEntry> entry;
fake_file_system_->GetResourceEntry(
kDriveFile,
google_apis::test_util::CreateCopyResultCallback(&error, &entry));
base::RunLoop().RunUntilIdle();
EXPECT_EQ(FILE_ERROR_OK, error);
ASSERT_TRUE(entry);
google_apis::DriveApiErrorCode status = google_apis::DRIVE_OTHER_ERROR;
std::unique_ptr<google_apis::FileResource> server_entry;
fake_drive_service_->UpdateResource(
entry->resource_id(),
std::string(), // parent_resource_id
std::string(), // title
expected_modification_time, base::Time(),
google_apis::drive::Properties(),
google_apis::test_util::CreateCopyResultCallback(&status, &server_entry));
base::RunLoop().RunUntilIdle();
EXPECT_EQ(google_apis::HTTP_SUCCESS, status);
std::unique_ptr<WebkitFileStreamReaderImpl> reader(
new WebkitFileStreamReaderImpl(GetFileSystemGetter(),
worker_thread_->task_runner().get(),
kDriveFile,
0, // offset
expected_modification_time));
net::TestInt64CompletionCallback callback;
int64_t result = reader->GetLength(callback.callback());
result = callback.GetResult(result);
std::string content;
ASSERT_EQ(net::OK, test_util::ReadAllData(reader.get(), &content));
EXPECT_GE(content.size(), static_cast<size_t>(result));
}
// TODO(hashimoto): Enable this test. crbug.com/346625
TEST_F(WebkitFileStreamReaderImplTest, DISABLED_LastModificationError) {
const base::FilePath kDriveFile =
util::GetDriveMyDriveRootPath().AppendASCII("File 1.txt");
std::unique_ptr<WebkitFileStreamReaderImpl> reader(
new WebkitFileStreamReaderImpl(GetFileSystemGetter(),
worker_thread_->task_runner().get(),
kDriveFile,
0, // offset
base::Time::FromInternalValue(1)));
net::TestInt64CompletionCallback callback;
int64_t result = reader->GetLength(callback.callback());
result = callback.GetResult(result);
EXPECT_EQ(net::ERR_UPLOAD_FILE_CHANGED, result);
}
} // namespace internal
} // namespace drive
// Copyright 2014 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.
#include "chrome/browser/chromeos/drive/fileapi/webkit_file_stream_writer_impl.h"
#include <utility>
#include "base/bind.h"
#include "base/task/post_task.h"
#include "chrome/browser/chromeos/drive/fileapi/fileapi_worker.h"
#include "components/drive/file_system_core_util.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "google_apis/drive/task_util.h"
#include "net/base/io_buffer.h"
#include "net/base/net_errors.h"
#include "storage/browser/fileapi/file_stream_writer.h"
using content::BrowserThread;
namespace drive {
namespace internal {
namespace {
// Creates a writable snapshot file of the |drive_path|.
void CreateWritableSnapshotFile(
const WebkitFileStreamWriterImpl::FileSystemGetter& file_system_getter,
const base::FilePath& drive_path,
const fileapi_internal::CreateWritableSnapshotFileCallback& callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
base::PostTask(
FROM_HERE, {BrowserThread::UI},
base::BindOnce(
&fileapi_internal::RunFileSystemCallback, file_system_getter,
base::Bind(&fileapi_internal::CreateWritableSnapshotFile, drive_path,
google_apis::CreateRelayCallback(callback)),
google_apis::CreateRelayCallback(
base::Bind(callback, base::File::FILE_ERROR_FAILED,
base::FilePath(), base::Closure()))));
}
} // namespace
WebkitFileStreamWriterImpl::WebkitFileStreamWriterImpl(
const FileSystemGetter& file_system_getter,
base::TaskRunner* file_task_runner,
const base::FilePath& file_path,
int64_t offset)
: file_system_getter_(file_system_getter),
file_task_runner_(file_task_runner),
file_path_(file_path),
offset_(offset) {}
WebkitFileStreamWriterImpl::~WebkitFileStreamWriterImpl() {
if (local_file_writer_) {
// If the file is opened, close it at destructor.
// It is necessary to close the local file in advance.
local_file_writer_.reset();
DCHECK(!close_callback_on_ui_thread_.is_null());
base::PostTask(FROM_HERE, {BrowserThread::UI},
close_callback_on_ui_thread_);
}
}
int WebkitFileStreamWriterImpl::Write(net::IOBuffer* buf,
int buf_len,
net::CompletionOnceCallback callback) {
DCHECK(pending_write_callback_.is_null());
DCHECK(pending_cancel_callback_.is_null());
DCHECK(callback);
// If the local file is already available, just delegate to it.
if (local_file_writer_)
return local_file_writer_->Write(buf, buf_len, std::move(callback));
// The local file is not yet ready. Create the writable snapshot.
if (file_path_.empty())
return net::ERR_FILE_NOT_FOUND;
pending_write_callback_ = std::move(callback);
CreateWritableSnapshotFile(
file_system_getter_, file_path_,
base::Bind(
&WebkitFileStreamWriterImpl::WriteAfterCreateWritableSnapshotFile,
weak_ptr_factory_.GetWeakPtr(), base::RetainedRef(buf), buf_len));
return net::ERR_IO_PENDING;
}
int WebkitFileStreamWriterImpl::Cancel(net::CompletionOnceCallback callback) {
DCHECK(pending_cancel_callback_.is_null());
DCHECK(callback);
// If LocalFileWriter is already created, just delegate the cancel to it.
if (local_file_writer_)
return local_file_writer_->Cancel(std::move(callback));
// If file open operation is in-flight, wait for its completion and cancel
// further write operation in WriteAfterCreateWritableSnapshotFile.
if (!pending_write_callback_.is_null()) {
// Dismiss pending write callback immediately.
pending_write_callback_.Reset();
pending_cancel_callback_ = std::move(callback);
return net::ERR_IO_PENDING;
}
// Write() is not called yet.
return net::ERR_UNEXPECTED;
}
int WebkitFileStreamWriterImpl::Flush(net::CompletionOnceCallback callback) {
DCHECK(pending_cancel_callback_.is_null());
DCHECK(callback);
// If LocalFileWriter is already created, just delegate to it.
if (local_file_writer_)
return local_file_writer_->Flush(std::move(callback));
// There shouldn't be in-flight Write operation.
DCHECK(pending_write_callback_.is_null());
// Here is the case Flush() is called before any Write() invocation.
// Do nothing.
// Synchronization to the remote server is not done until the file is closed.
return net::OK;
}
void WebkitFileStreamWriterImpl::WriteAfterCreateWritableSnapshotFile(
net::IOBuffer* buf,
int buf_len,
base::File::Error open_result,
const base::FilePath& local_path,
const base::Closure& close_callback_on_ui_thread) {
DCHECK(!local_file_writer_);
if (!pending_cancel_callback_.is_null()) {
DCHECK(pending_write_callback_.is_null());
// Cancel() is called during the creation of the snapshot file.
// Don't write to the file.
if (open_result == base::File::FILE_OK) {
// Here the file is internally created. To revert the operation, close
// the file.
DCHECK(!close_callback_on_ui_thread.is_null());
base::PostTask(FROM_HERE, {BrowserThread::UI},
close_callback_on_ui_thread);
}
std::move(pending_cancel_callback_).Run(net::OK);
return;
}
DCHECK(!pending_write_callback_.is_null());
if (open_result != base::File::FILE_OK) {
DCHECK(close_callback_on_ui_thread.is_null());
std::move(pending_write_callback_)
.Run(net::FileErrorToNetError(open_result));
return;
}
// Keep |close_callback| to close the file when the stream is destructed.
DCHECK(!close_callback_on_ui_thread.is_null());
close_callback_on_ui_thread_ = close_callback_on_ui_thread;
local_file_writer_ = storage::FileStreamWriter::CreateForLocalFile(
file_task_runner_.get(), local_path, offset_,
storage::FileStreamWriter::OPEN_EXISTING_FILE);
int result = local_file_writer_->Write(
buf, buf_len,
base::BindOnce(&WebkitFileStreamWriterImpl::OnWrite,
weak_ptr_factory_.GetWeakPtr()));
if (result != net::ERR_IO_PENDING)
OnWrite(result);
}
void WebkitFileStreamWriterImpl::OnWrite(int result) {
std::move(pending_write_callback_).Run(result);
}
} // namespace internal
} // namespace drive
// Copyright 2014 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 CHROME_BROWSER_CHROMEOS_DRIVE_FILEAPI_WEBKIT_FILE_STREAM_WRITER_IMPL_H_
#define CHROME_BROWSER_CHROMEOS_DRIVE_FILEAPI_WEBKIT_FILE_STREAM_WRITER_IMPL_H_
#include <stdint.h>
#include <memory>
#include "base/callback.h"
#include "base/files/file.h"
#include "base/files/file_path.h"
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "storage/browser/fileapi/file_stream_writer.h"
namespace base {
class TaskRunner;
} // namespace base
namespace net {
class IOBuffer;
} // namespace net
namespace drive {
class FileSystemInterface;
namespace internal {
// The implementation of storage::FileStreamWriter for the Drive File System.
class WebkitFileStreamWriterImpl : public storage::FileStreamWriter {
public:
// Callback to return the FileSystemInterface instance. This is an
// injecting point for testing.
// Note that the callback will be copied between threads (IO and UI), and
// will be called on UI thread.
typedef base::Callback<FileSystemInterface*()> FileSystemGetter;
// Creates a writer for a file at |file_path| on FileSystem returned by
// |file_system_getter| that starts writing from |offset|.
// When invalid parameters are set, the first call to Write() method fails.
// Uses |file_task_runner| for local file operations.
WebkitFileStreamWriterImpl(const FileSystemGetter& file_system_getter,
base::TaskRunner* file_task_runner,
const base::FilePath& file_path,
int64_t offset);
~WebkitFileStreamWriterImpl() override;
// FileWriter override.
int Write(net::IOBuffer* buf,
int buf_len,
net::CompletionOnceCallback callback) override;
int Cancel(net::CompletionOnceCallback callback) override;
int Flush(net::CompletionOnceCallback callback) override;
private:
// Part of Write(). Called after CreateWritableSnapshotFile is completed.
void WriteAfterCreateWritableSnapshotFile(
net::IOBuffer* buf,
int buf_len,
base::File::Error open_result,
const base::FilePath& local_path,
const base::Closure& close_callback_on_ui_thread);
// Part of Write(). Passed in to FileStreamWriter::Write().
void OnWrite(int result);
FileSystemGetter file_system_getter_;
scoped_refptr<base::TaskRunner> file_task_runner_;
const base::FilePath file_path_;
const int64_t offset_;
std::unique_ptr<storage::FileStreamWriter> local_file_writer_;
base::Closure close_callback_on_ui_thread_;
net::CompletionOnceCallback pending_write_callback_;
net::CompletionOnceCallback pending_cancel_callback_;
// Note: This should remain the last member so it'll be destroyed and
// invalidate the weak pointers before any other members are destroyed.
base::WeakPtrFactory<WebkitFileStreamWriterImpl> weak_ptr_factory_{this};
DISALLOW_COPY_AND_ASSIGN(WebkitFileStreamWriterImpl);
};
} // namespace internal
} // namespace drive
#endif // CHROME_BROWSER_CHROMEOS_DRIVE_FILEAPI_WEBKIT_FILE_STREAM_WRITER_IMPL_H_
......@@ -62,7 +62,6 @@ bool FileSystemBackend::CanHandleURL(const storage::FileSystemURL& url) {
}
FileSystemBackend::FileSystemBackend(
std::unique_ptr<FileSystemBackendDelegate> drive_delegate,
std::unique_ptr<FileSystemBackendDelegate> file_system_provider_delegate,
std::unique_ptr<FileSystemBackendDelegate> mtp_delegate,
std::unique_ptr<FileSystemBackendDelegate> arc_content_delegate,
......@@ -72,7 +71,6 @@ FileSystemBackend::FileSystemBackend(
storage::ExternalMountPoints* system_mount_points)
: file_access_permissions_(new FileAccessPermissions()),
local_file_util_(storage::AsyncFileUtil::CreateForLocalFileSystem()),
drive_delegate_(std::move(drive_delegate)),
file_system_provider_delegate_(std::move(file_system_provider_delegate)),
mtp_delegate_(std::move(mtp_delegate)),
arc_content_delegate_(std::move(arc_content_delegate)),
......@@ -278,8 +276,6 @@ std::vector<base::FilePath> FileSystemBackend::GetRootDirectories() const {
storage::AsyncFileUtil* FileSystemBackend::GetAsyncFileUtil(
storage::FileSystemType type) {
switch (type) {
case storage::kFileSystemTypeDrive:
return drive_delegate_->GetAsyncFileUtil(type);
case storage::kFileSystemTypeProvided:
return file_system_provider_delegate_->GetAsyncFileUtil(type);
case storage::kFileSystemTypeNativeLocal:
......@@ -406,9 +402,6 @@ FileSystemBackend::CreateFileStreamReader(
return std::unique_ptr<storage::FileStreamReader>();
switch (url.type()) {
case storage::kFileSystemTypeDrive:
return drive_delegate_->CreateFileStreamReader(
url, offset, max_bytes_to_read, expected_modification_time, context);
case storage::kFileSystemTypeProvided:
return file_system_provider_delegate_->CreateFileStreamReader(
url, offset, max_bytes_to_read, expected_modification_time, context);
......@@ -447,8 +440,6 @@ FileSystemBackend::CreateFileStreamWriter(
return std::unique_ptr<storage::FileStreamWriter>();
switch (url.type()) {
case storage::kFileSystemTypeDrive:
return drive_delegate_->CreateFileStreamWriter(url, offset, context);
case storage::kFileSystemTypeProvided:
return file_system_provider_delegate_->CreateFileStreamWriter(
url, offset, context);
......@@ -489,9 +480,6 @@ void FileSystemBackend::GetRedirectURLForContents(
return callback.Run(GURL());
switch (url.type()) {
case storage::kFileSystemTypeDrive:
drive_delegate_->GetRedirectURLForContents(url, callback);
return;
case storage::kFileSystemTypeProvided:
file_system_provider_delegate_->GetRedirectURLForContents(url,
callback);
......
......@@ -73,7 +73,6 @@ class FileSystemBackend : public storage::ExternalFileSystemBackend {
// |system_mount_points| should outlive FileSystemBackend instance.
FileSystemBackend(
std::unique_ptr<FileSystemBackendDelegate> drive_delegate,
std::unique_ptr<FileSystemBackendDelegate> file_system_provider_delegate,
std::unique_ptr<FileSystemBackendDelegate> mtp_delegate,
std::unique_ptr<FileSystemBackendDelegate> arc_content_delegate,
......@@ -150,9 +149,6 @@ class FileSystemBackend : public storage::ExternalFileSystemBackend {
std::unique_ptr<FileAccessPermissions> file_access_permissions_;
std::unique_ptr<storage::AsyncFileUtil> local_file_util_;
// The delegate instance for the drive file system related operations.
std::unique_ptr<FileSystemBackendDelegate> drive_delegate_;
// The delegate instance for the provided file system related operations.
std::unique_ptr<FileSystemBackendDelegate> file_system_provider_delegate_;
......
......@@ -41,7 +41,6 @@ TEST(ChromeOSFileSystemBackendTest, DefaultMountPoints) {
scoped_refptr<storage::ExternalMountPoints> mount_points(
storage::ExternalMountPoints::CreateRefCounted());
chromeos::FileSystemBackend backend(
nullptr, // drive_delegate
nullptr, // file_system_provider_delegate
nullptr, // mtp_delegate
nullptr, // arc_content_delegate
......@@ -70,7 +69,6 @@ TEST(ChromeOSFileSystemBackendTest, GetRootDirectories) {
storage::ExternalMountPoints::CreateRefCounted());
chromeos::FileSystemBackend backend(
nullptr, // drive_delegate
nullptr, // file_system_provider_delegate
nullptr, // mtp_delegate
nullptr, // arc_content_delegate
......@@ -117,7 +115,6 @@ TEST(ChromeOSFileSystemBackendTest, AccessPermissions) {
scoped_refptr<storage::ExternalMountPoints> system_mount_points(
storage::ExternalMountPoints::CreateRefCounted());
chromeos::FileSystemBackend backend(
nullptr, // drive_delegate
nullptr, // file_system_provider_delegate
nullptr, // mtp_delegate
nullptr, // arc_content_delegate
......@@ -188,7 +185,6 @@ TEST(ChromeOSFileSystemBackendTest, GetVirtualPathConflictWithSystemPoints) {
scoped_refptr<storage::ExternalMountPoints> system_mount_points(
storage::ExternalMountPoints::CreateRefCounted());
chromeos::FileSystemBackend backend(
nullptr, // drive_delegate
nullptr, // file_system_provider_delegate
nullptr, // mtp_delegate
nullptr, // arc_content_delegate
......
......@@ -27,32 +27,6 @@ using content::BrowserThread;
namespace chromeos {
namespace {
void OnGetMetadataOnIOThread(
storage::FileSystemOperation::GetMetadataCallback callback,
base::File::Error result,
const base::File::Info& info) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
base::PostTask(FROM_HERE, {BrowserThread::UI},
base::BindOnce(std::move(callback), result, info));
}
void GetMetadataOnIOThread(
scoped_refptr<storage::FileSystemContext> file_system_context,
const storage::FileSystemURL& url,
int fields,
storage::FileSystemOperation::GetMetadataCallback callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
file_system_context->operation_runner()->GetMetadata(
url, fields,
base::BindOnce(&OnGetMetadataOnIOThread, std::move(callback)));
}
} // namespace
const char RecentDriveSource::kLoadHistogramName[] =
"FileBrowser.Recent.LoadDrive";
......@@ -68,7 +42,6 @@ void RecentDriveSource::GetRecentFiles(Params params) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
DCHECK(!params_.has_value());
DCHECK(files_.empty());
DCHECK_EQ(0, num_inflight_stats_);
DCHECK(build_start_time_.is_null());
params_.emplace(std::move(params));
......@@ -79,18 +52,10 @@ void RecentDriveSource::GetRecentFiles(Params params) {
drive::util::GetIntegrationServiceByProfile(profile_);
if (!integration_service) {
// |integration_service| is nullptr if Drive is disabled.
OnSearchMetadata(drive::FILE_ERROR_FAILED, nullptr);
OnComplete();
return;
}
if (integration_service->file_system()) {
integration_service->file_system()->SearchMetadata(
"" /* query */, drive::SEARCH_METADATA_EXCLUDE_DIRECTORIES,
params_.value().max_files(), drive::MetadataSearchOrder::LAST_MODIFIED,
base::BindOnce(&RecentDriveSource::OnSearchMetadata,
weak_ptr_factory_.GetWeakPtr()));
return;
}
auto query_params = drivefs::mojom::QueryParameters::New();
query_params->page_size = params_->max_files();
query_params->query_source =
......@@ -105,67 +70,9 @@ void RecentDriveSource::GetRecentFiles(Params params) {
&RecentDriveSource::GotSearchResults, weak_ptr_factory_.GetWeakPtr()));
}
void RecentDriveSource::OnSearchMetadata(
drive::FileError error,
std::unique_ptr<drive::MetadataSearchResultVector> results) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
DCHECK(params_.has_value());
DCHECK(files_.empty());
DCHECK_EQ(0, num_inflight_stats_);
DCHECK(!build_start_time_.is_null());
if (error != drive::FILE_ERROR_OK) {
OnComplete();
return;
}
DCHECK(results.get());
std::string extension_id = params_.value().origin().host();
for (const auto& result : *results) {
if (result.is_directory)
continue;
base::FilePath virtual_path =
file_manager::util::ConvertDrivePathToRelativeFileSystemPath(
profile_, extension_id, result.path);
storage::FileSystemURL url =
params_.value().file_system_context()->CreateCrackedFileSystemURL(
params_.value().origin(), storage::kFileSystemTypeExternal,
virtual_path);
++num_inflight_stats_;
base::PostTask(
FROM_HERE, {BrowserThread::IO},
base::BindOnce(
&GetMetadataOnIOThread,
base::WrapRefCounted(params_.value().file_system_context()), url,
storage::FileSystemOperation::GET_METADATA_FIELD_LAST_MODIFIED,
base::BindOnce(&RecentDriveSource::OnGetMetadata,
weak_ptr_factory_.GetWeakPtr(), url)));
}
if (num_inflight_stats_ == 0)
OnComplete();
}
void RecentDriveSource::OnGetMetadata(const storage::FileSystemURL& url,
base::File::Error result,
const base::File::Info& info) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
if (result == base::File::FILE_OK)
files_.emplace_back(url, info.last_modified);
--num_inflight_stats_;
if (num_inflight_stats_ == 0)
OnComplete();
}
void RecentDriveSource::OnComplete() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
DCHECK(params_.has_value());
DCHECK_EQ(0, num_inflight_stats_);
DCHECK(!build_start_time_.is_null());
UMA_HISTOGRAM_TIMES(kLoadHistogramName,
......@@ -179,7 +86,6 @@ void RecentDriveSource::OnComplete() {
DCHECK(!params_.has_value());
DCHECK(files_.empty());
DCHECK_EQ(0, num_inflight_stats_);
DCHECK(build_start_time_.is_null());
std::move(params.callback()).Run(std::move(files));
......
......@@ -16,17 +16,10 @@
#include "base/time/time.h"
#include "chrome/browser/chromeos/fileapi/recent_source.h"
#include "chromeos/components/drivefs/mojom/drivefs.mojom.h"
#include "components/drive/chromeos/file_system_interface.h"
#include "components/drive/file_errors.h"
class Profile;
namespace storage {
class FileSystemURL;
} // namespace storage
namespace chromeos {
class RecentFile;
......@@ -47,12 +40,6 @@ class RecentDriveSource : public RecentSource {
private:
static const char kLoadHistogramName[];
void OnSearchMetadata(
drive::FileError error,
std::unique_ptr<drive::MetadataSearchResultVector> results);
void OnGetMetadata(const storage::FileSystemURL& url,
base::File::Error result,
const base::File::Info& info);
void OnComplete();
void GotSearchResults(
......@@ -66,7 +53,6 @@ class RecentDriveSource : public RecentSource {
base::TimeTicks build_start_time_;
int num_inflight_stats_ = 0;
std::vector<RecentFile> files_;
drivefs::mojom::SearchQueryPtr search_query_;
......
......@@ -58,8 +58,7 @@ class PlatformUtilTestContentBrowserClient : public ChromeContentBrowserClient {
// New FileSystemBackend that uses our MockSpecialStoragePolicy.
additional_backends->push_back(
std::make_unique<chromeos::FileSystemBackend>(
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
external_mount_points,
nullptr, nullptr, nullptr, nullptr, nullptr, external_mount_points,
storage::ExternalMountPoints::GetSystemInstance()));
}
};
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment