1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/chromeos/drive/fake_file_system.h"
8 #include "base/bind_helpers.h"
9 #include "base/callback.h"
10 #include "base/files/file_path.h"
11 #include "base/files/file_util.h"
12 #include "base/logging.h"
13 #include "chrome/browser/chromeos/drive/drive.pb.h"
14 #include "chrome/browser/chromeos/drive/file_errors.h"
15 #include "chrome/browser/chromeos/drive/file_system_util.h"
16 #include "chrome/browser/chromeos/drive/resource_entry_conversion.h"
17 #include "chrome/browser/drive/drive_service_interface.h"
18 #include "content/public/browser/browser_thread.h"
19 #include "google_apis/drive/drive_api_parser.h"
24 using content::BrowserThread;
26 FakeFileSystem::FakeFileSystem(DriveServiceInterface* drive_service)
27 : drive_service_(drive_service),
28 weak_ptr_factory_(this) {
29 CHECK(cache_dir_.CreateUniqueTempDir());
32 FakeFileSystem::~FakeFileSystem() {
35 void FakeFileSystem::AddObserver(FileSystemObserver* observer) {
36 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
39 void FakeFileSystem::RemoveObserver(FileSystemObserver* observer) {
40 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
43 void FakeFileSystem::CheckForUpdates() {
44 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
47 void FakeFileSystem::TransferFileFromLocalToRemote(
48 const base::FilePath& local_src_file_path,
49 const base::FilePath& remote_dest_file_path,
50 const FileOperationCallback& callback) {
51 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
54 void FakeFileSystem::OpenFile(const base::FilePath& file_path,
56 const std::string& mime_type,
57 const OpenFileCallback& callback) {
58 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
61 void FakeFileSystem::Copy(const base::FilePath& src_file_path,
62 const base::FilePath& dest_file_path,
63 bool preserve_last_modified,
64 const FileOperationCallback& callback) {
65 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
68 void FakeFileSystem::Move(const base::FilePath& src_file_path,
69 const base::FilePath& dest_file_path,
70 const FileOperationCallback& callback) {
71 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
74 void FakeFileSystem::Remove(const base::FilePath& file_path,
76 const FileOperationCallback& callback) {
77 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
80 void FakeFileSystem::CreateDirectory(
81 const base::FilePath& directory_path,
84 const FileOperationCallback& callback) {
85 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
88 void FakeFileSystem::CreateFile(const base::FilePath& file_path,
90 const std::string& mime_type,
91 const FileOperationCallback& callback) {
92 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
95 void FakeFileSystem::TouchFile(const base::FilePath& file_path,
96 const base::Time& last_access_time,
97 const base::Time& last_modified_time,
98 const FileOperationCallback& callback) {
99 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
102 void FakeFileSystem::TruncateFile(const base::FilePath& file_path,
104 const FileOperationCallback& callback) {
105 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
108 void FakeFileSystem::Pin(const base::FilePath& file_path,
109 const FileOperationCallback& callback) {
110 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
113 void FakeFileSystem::Unpin(const base::FilePath& file_path,
114 const FileOperationCallback& callback) {
115 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
118 void FakeFileSystem::GetFile(const base::FilePath& file_path,
119 const GetFileCallback& callback) {
120 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
123 void FakeFileSystem::GetFileForSaving(const base::FilePath& file_path,
124 const GetFileCallback& callback) {
125 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
128 base::Closure FakeFileSystem::GetFileContent(
129 const base::FilePath& file_path,
130 const GetFileContentInitializedCallback& initialized_callback,
131 const google_apis::GetContentCallback& get_content_callback,
132 const FileOperationCallback& completion_callback) {
133 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
137 base::Bind(&FakeFileSystem::GetFileContentAfterGetResourceEntry,
138 weak_ptr_factory_.GetWeakPtr(),
139 initialized_callback, get_content_callback,
140 completion_callback));
141 return base::Bind(&base::DoNothing);
144 void FakeFileSystem::GetResourceEntry(
145 const base::FilePath& file_path,
146 const GetResourceEntryCallback& callback) {
147 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
149 if (file_path == util::GetDriveMyDriveRootPath()) {
150 // Specialized for the root entry.
151 drive_service_->GetAboutResource(
153 &FakeFileSystem::GetResourceEntryAfterGetAboutResource,
154 weak_ptr_factory_.GetWeakPtr(), callback));
158 // Now, we only support files under my drive.
159 DCHECK(util::GetDriveMyDriveRootPath().IsParent(file_path));
163 &FakeFileSystem::GetResourceEntryAfterGetParentEntryInfo,
164 weak_ptr_factory_.GetWeakPtr(), file_path.BaseName(), callback));
167 void FakeFileSystem::ReadDirectory(
168 const base::FilePath& file_path,
169 const ReadDirectoryEntriesCallback& entries_callback,
170 const FileOperationCallback& completion_callback) {
171 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
174 void FakeFileSystem::Search(const std::string& search_query,
175 const GURL& next_link,
176 const SearchCallback& callback) {
177 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
180 void FakeFileSystem::SearchMetadata(
181 const std::string& query,
183 int at_most_num_matches,
184 const SearchMetadataCallback& callback) {
185 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
188 void FakeFileSystem::GetAvailableSpace(
189 const GetAvailableSpaceCallback& callback) {
190 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
193 void FakeFileSystem::GetShareUrl(
194 const base::FilePath& file_path,
195 const GURL& embed_origin,
196 const GetShareUrlCallback& callback) {
197 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
200 void FakeFileSystem::GetMetadata(
201 const GetFilesystemMetadataCallback& callback) {
202 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
205 void FakeFileSystem::MarkCacheFileAsMounted(
206 const base::FilePath& drive_file_path,
207 const MarkMountedCallback& callback) {
208 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
211 void FakeFileSystem::MarkCacheFileAsUnmounted(
212 const base::FilePath& cache_file_path,
213 const FileOperationCallback& callback) {
214 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
217 void FakeFileSystem::AddPermission(const base::FilePath& drive_file_path,
218 const std::string& email,
219 google_apis::drive::PermissionRole role,
220 const FileOperationCallback& callback) {
221 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
224 void FakeFileSystem::Reset(const FileOperationCallback& callback) {
227 void FakeFileSystem::GetPathFromResourceId(
228 const std::string& resource_id,
229 const GetFilePathCallback& callback) {
230 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
233 // Implementation of GetFileContent.
234 void FakeFileSystem::GetFileContentAfterGetResourceEntry(
235 const GetFileContentInitializedCallback& initialized_callback,
236 const google_apis::GetContentCallback& get_content_callback,
237 const FileOperationCallback& completion_callback,
239 scoped_ptr<ResourceEntry> entry) {
240 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
242 if (error != FILE_ERROR_OK) {
243 completion_callback.Run(error);
248 // We're only interested in a file.
249 if (entry->file_info().is_directory()) {
250 completion_callback.Run(FILE_ERROR_NOT_A_FILE);
254 // Fetch google_apis::FileResource for its |download_url|.
255 drive_service_->GetFileResource(
256 entry->resource_id(),
258 &FakeFileSystem::GetFileContentAfterGetFileResource,
259 weak_ptr_factory_.GetWeakPtr(),
260 initialized_callback,
261 get_content_callback,
262 completion_callback));
265 void FakeFileSystem::GetFileContentAfterGetFileResource(
266 const GetFileContentInitializedCallback& initialized_callback,
267 const google_apis::GetContentCallback& get_content_callback,
268 const FileOperationCallback& completion_callback,
269 google_apis::GDataErrorCode gdata_error,
270 scoped_ptr<google_apis::FileResource> gdata_entry) {
271 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
273 FileError error = GDataToFileError(gdata_error);
274 if (error != FILE_ERROR_OK) {
275 completion_callback.Run(error);
280 scoped_ptr<ResourceEntry> entry(new ResourceEntry);
281 std::string parent_resource_id;
282 bool converted = ConvertFileResourceToResourceEntry(
283 *gdata_entry, entry.get(), &parent_resource_id);
285 entry->set_parent_local_id(parent_resource_id);
287 base::FilePath cache_path =
288 cache_dir_.path().AppendASCII(entry->resource_id());
289 if (entry->file_specific_info().is_hosted_document()) {
290 // For hosted documents return a dummy cache without server request.
291 int result = base::WriteFile(cache_path, "", 0);
292 DCHECK_EQ(0, result);
294 if (base::PathExists(cache_path)) {
295 // Cache file is found.
296 initialized_callback.Run(FILE_ERROR_OK, cache_path, entry.Pass());
297 completion_callback.Run(FILE_ERROR_OK);
301 initialized_callback.Run(FILE_ERROR_OK, base::FilePath(), entry.Pass());
302 drive_service_->DownloadFile(
304 gdata_entry->file_id(),
305 base::Bind(&FakeFileSystem::GetFileContentAfterDownloadFile,
306 weak_ptr_factory_.GetWeakPtr(),
307 completion_callback),
308 get_content_callback,
309 google_apis::ProgressCallback());
312 void FakeFileSystem::GetFileContentAfterDownloadFile(
313 const FileOperationCallback& completion_callback,
314 google_apis::GDataErrorCode gdata_error,
315 const base::FilePath& temp_file) {
316 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
317 completion_callback.Run(GDataToFileError(gdata_error));
320 // Implementation of GetResourceEntry.
321 void FakeFileSystem::GetResourceEntryAfterGetAboutResource(
322 const GetResourceEntryCallback& callback,
323 google_apis::GDataErrorCode gdata_error,
324 scoped_ptr<google_apis::AboutResource> about_resource) {
325 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
327 FileError error = GDataToFileError(gdata_error);
328 if (error != FILE_ERROR_OK) {
329 callback.Run(error, scoped_ptr<ResourceEntry>());
333 DCHECK(about_resource);
334 scoped_ptr<ResourceEntry> root(new ResourceEntry);
335 root->mutable_file_info()->set_is_directory(true);
336 root->set_resource_id(about_resource->root_folder_id());
337 root->set_title(util::kDriveMyDriveRootDirName);
338 callback.Run(error, root.Pass());
341 void FakeFileSystem::GetResourceEntryAfterGetParentEntryInfo(
342 const base::FilePath& base_name,
343 const GetResourceEntryCallback& callback,
345 scoped_ptr<ResourceEntry> parent_entry) {
346 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
348 if (error != FILE_ERROR_OK) {
349 callback.Run(error, scoped_ptr<ResourceEntry>());
353 DCHECK(parent_entry);
354 drive_service_->GetFileListInDirectory(
355 parent_entry->resource_id(),
357 &FakeFileSystem::GetResourceEntryAfterGetFileList,
358 weak_ptr_factory_.GetWeakPtr(), base_name, callback));
361 void FakeFileSystem::GetResourceEntryAfterGetFileList(
362 const base::FilePath& base_name,
363 const GetResourceEntryCallback& callback,
364 google_apis::GDataErrorCode gdata_error,
365 scoped_ptr<google_apis::FileList> file_list) {
366 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
368 FileError error = GDataToFileError(gdata_error);
369 if (error != FILE_ERROR_OK) {
370 callback.Run(error, scoped_ptr<ResourceEntry>());
375 const ScopedVector<google_apis::FileResource>& entries = file_list->items();
376 for (size_t i = 0; i < entries.size(); ++i) {
377 scoped_ptr<ResourceEntry> entry(new ResourceEntry);
378 std::string parent_resource_id;
379 bool converted = ConvertFileResourceToResourceEntry(
380 *entries[i], entry.get(), &parent_resource_id);
382 entry->set_parent_local_id(parent_resource_id);
384 if (entry->base_name() == base_name.AsUTF8Unsafe()) {
385 // Found the target entry.
386 callback.Run(FILE_ERROR_OK, entry.Pass());
391 callback.Run(FILE_ERROR_NOT_FOUND, scoped_ptr<ResourceEntry>());
394 } // namespace test_util