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/file_util.h"
11 #include "base/files/file_path.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"
20 #include "google_apis/drive/gdata_wapi_parser.h"
21 #include "testing/gtest/include/gtest/gtest.h"
26 using content::BrowserThread;
28 FakeFileSystem::FakeFileSystem(DriveServiceInterface* drive_service)
29 : drive_service_(drive_service),
30 weak_ptr_factory_(this) {
31 CHECK(cache_dir_.CreateUniqueTempDir());
34 FakeFileSystem::~FakeFileSystem() {
37 void FakeFileSystem::AddObserver(FileSystemObserver* observer) {
38 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
41 void FakeFileSystem::RemoveObserver(FileSystemObserver* observer) {
42 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
45 void FakeFileSystem::CheckForUpdates() {
46 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
49 void FakeFileSystem::TransferFileFromLocalToRemote(
50 const base::FilePath& local_src_file_path,
51 const base::FilePath& remote_dest_file_path,
52 const FileOperationCallback& callback) {
53 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
56 void FakeFileSystem::OpenFile(const base::FilePath& file_path,
58 const std::string& mime_type,
59 const OpenFileCallback& callback) {
60 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
63 void FakeFileSystem::Copy(const base::FilePath& src_file_path,
64 const base::FilePath& dest_file_path,
65 bool preserve_last_modified,
66 const FileOperationCallback& callback) {
67 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
70 void FakeFileSystem::Move(const base::FilePath& src_file_path,
71 const base::FilePath& dest_file_path,
72 const FileOperationCallback& callback) {
73 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
76 void FakeFileSystem::Remove(const base::FilePath& file_path,
78 const FileOperationCallback& callback) {
79 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
82 void FakeFileSystem::CreateDirectory(
83 const base::FilePath& directory_path,
86 const FileOperationCallback& callback) {
87 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
90 void FakeFileSystem::CreateFile(const base::FilePath& file_path,
92 const std::string& mime_type,
93 const FileOperationCallback& callback) {
94 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
97 void FakeFileSystem::TouchFile(const base::FilePath& file_path,
98 const base::Time& last_access_time,
99 const base::Time& last_modified_time,
100 const FileOperationCallback& callback) {
101 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
104 void FakeFileSystem::TruncateFile(const base::FilePath& file_path,
106 const FileOperationCallback& callback) {
107 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
110 void FakeFileSystem::Pin(const base::FilePath& file_path,
111 const FileOperationCallback& callback) {
112 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
115 void FakeFileSystem::Unpin(const base::FilePath& file_path,
116 const FileOperationCallback& callback) {
117 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
120 void FakeFileSystem::GetFile(const base::FilePath& file_path,
121 const GetFileCallback& callback) {
122 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
125 void FakeFileSystem::GetFileForSaving(const base::FilePath& file_path,
126 const GetFileCallback& callback) {
127 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
130 base::Closure FakeFileSystem::GetFileContent(
131 const base::FilePath& file_path,
132 const GetFileContentInitializedCallback& initialized_callback,
133 const google_apis::GetContentCallback& get_content_callback,
134 const FileOperationCallback& completion_callback) {
135 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
139 base::Bind(&FakeFileSystem::GetFileContentAfterGetResourceEntry,
140 weak_ptr_factory_.GetWeakPtr(),
141 initialized_callback, get_content_callback,
142 completion_callback));
143 return base::Bind(&base::DoNothing);
146 void FakeFileSystem::GetResourceEntry(
147 const base::FilePath& file_path,
148 const GetResourceEntryCallback& callback) {
149 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
151 // Now, we only support files under my drive.
152 DCHECK(!util::IsUnderDriveMountPoint(file_path));
154 if (file_path == util::GetDriveMyDriveRootPath()) {
155 // Specialized for the root entry.
156 drive_service_->GetAboutResource(
158 &FakeFileSystem::GetResourceEntryAfterGetAboutResource,
159 weak_ptr_factory_.GetWeakPtr(), callback));
166 &FakeFileSystem::GetResourceEntryAfterGetParentEntryInfo,
167 weak_ptr_factory_.GetWeakPtr(), file_path.BaseName(), callback));
170 void FakeFileSystem::ReadDirectory(
171 const base::FilePath& file_path,
172 const ReadDirectoryCallback& callback) {
173 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
176 void FakeFileSystem::Search(const std::string& search_query,
177 const GURL& next_link,
178 const SearchCallback& callback) {
179 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
182 void FakeFileSystem::SearchMetadata(
183 const std::string& query,
185 int at_most_num_matches,
186 const SearchMetadataCallback& callback) {
187 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
190 void FakeFileSystem::GetAvailableSpace(
191 const GetAvailableSpaceCallback& callback) {
192 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
195 void FakeFileSystem::GetShareUrl(
196 const base::FilePath& file_path,
197 const GURL& embed_origin,
198 const GetShareUrlCallback& callback) {
199 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
202 void FakeFileSystem::GetMetadata(
203 const GetFilesystemMetadataCallback& callback) {
204 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
207 void FakeFileSystem::MarkCacheFileAsMounted(
208 const base::FilePath& drive_file_path,
209 const MarkMountedCallback& callback) {
210 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
213 void FakeFileSystem::MarkCacheFileAsUnmounted(
214 const base::FilePath& cache_file_path,
215 const FileOperationCallback& callback) {
216 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
219 void FakeFileSystem::GetCacheEntry(
220 const base::FilePath& drive_file_path,
221 const GetCacheEntryCallback& callback) {
222 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
225 void FakeFileSystem::AddPermission(const base::FilePath& drive_file_path,
226 const std::string& email,
227 google_apis::drive::PermissionRole role,
228 const FileOperationCallback& callback) {
229 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
232 void FakeFileSystem::Reset(const FileOperationCallback& callback) {
235 void FakeFileSystem::GetPathFromResourceId(
236 const std::string& resource_id,
237 const GetFilePathCallback& callback) {
238 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
241 // Implementation of GetFileContent.
242 void FakeFileSystem::GetFileContentAfterGetResourceEntry(
243 const GetFileContentInitializedCallback& initialized_callback,
244 const google_apis::GetContentCallback& get_content_callback,
245 const FileOperationCallback& completion_callback,
247 scoped_ptr<ResourceEntry> entry) {
248 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
250 if (error != FILE_ERROR_OK) {
251 completion_callback.Run(error);
256 // We're only interested in a file.
257 if (entry->file_info().is_directory()) {
258 completion_callback.Run(FILE_ERROR_NOT_A_FILE);
262 // Fetch google_apis::ResourceEntry for its |download_url|.
263 drive_service_->GetResourceEntry(
264 entry->resource_id(),
266 &FakeFileSystem::GetFileContentAfterGetWapiResourceEntry,
267 weak_ptr_factory_.GetWeakPtr(),
268 initialized_callback,
269 get_content_callback,
270 completion_callback));
273 void FakeFileSystem::GetFileContentAfterGetWapiResourceEntry(
274 const GetFileContentInitializedCallback& initialized_callback,
275 const google_apis::GetContentCallback& get_content_callback,
276 const FileOperationCallback& completion_callback,
277 google_apis::GDataErrorCode gdata_error,
278 scoped_ptr<google_apis::ResourceEntry> gdata_entry) {
279 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
281 FileError error = GDataToFileError(gdata_error);
282 if (error != FILE_ERROR_OK) {
283 completion_callback.Run(error);
288 scoped_ptr<ResourceEntry> entry(new ResourceEntry);
289 std::string parent_resource_id;
291 ConvertToResourceEntry(*gdata_entry, entry.get(), &parent_resource_id);
293 entry->set_parent_local_id(parent_resource_id);
295 base::FilePath cache_path =
296 cache_dir_.path().AppendASCII(entry->resource_id());
297 if (base::PathExists(cache_path)) {
298 // Cache file is found.
299 initialized_callback.Run(FILE_ERROR_OK, cache_path, entry.Pass());
300 completion_callback.Run(FILE_ERROR_OK);
304 initialized_callback.Run(FILE_ERROR_OK, base::FilePath(), entry.Pass());
305 drive_service_->DownloadFile(
307 gdata_entry->resource_id(),
308 base::Bind(&FakeFileSystem::GetFileContentAfterDownloadFile,
309 weak_ptr_factory_.GetWeakPtr(),
310 completion_callback),
311 get_content_callback,
312 google_apis::ProgressCallback());
315 void FakeFileSystem::GetFileContentAfterDownloadFile(
316 const FileOperationCallback& completion_callback,
317 google_apis::GDataErrorCode gdata_error,
318 const base::FilePath& temp_file) {
319 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
320 completion_callback.Run(GDataToFileError(gdata_error));
323 // Implementation of GetResourceEntry.
324 void FakeFileSystem::GetResourceEntryAfterGetAboutResource(
325 const GetResourceEntryCallback& callback,
326 google_apis::GDataErrorCode gdata_error,
327 scoped_ptr<google_apis::AboutResource> about_resource) {
328 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
330 FileError error = GDataToFileError(gdata_error);
331 if (error != FILE_ERROR_OK) {
332 callback.Run(error, scoped_ptr<ResourceEntry>());
336 DCHECK(about_resource);
337 scoped_ptr<ResourceEntry> root(new ResourceEntry);
338 root->mutable_file_info()->set_is_directory(true);
339 root->set_resource_id(about_resource->root_folder_id());
340 root->set_title(util::kDriveMyDriveRootDirName);
341 callback.Run(error, root.Pass());
344 void FakeFileSystem::GetResourceEntryAfterGetParentEntryInfo(
345 const base::FilePath& base_name,
346 const GetResourceEntryCallback& callback,
348 scoped_ptr<ResourceEntry> parent_entry) {
349 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
351 if (error != FILE_ERROR_OK) {
352 callback.Run(error, scoped_ptr<ResourceEntry>());
356 DCHECK(parent_entry);
357 drive_service_->GetResourceListInDirectory(
358 parent_entry->resource_id(),
360 &FakeFileSystem::GetResourceEntryAfterGetResourceList,
361 weak_ptr_factory_.GetWeakPtr(), base_name, callback));
364 void FakeFileSystem::GetResourceEntryAfterGetResourceList(
365 const base::FilePath& base_name,
366 const GetResourceEntryCallback& callback,
367 google_apis::GDataErrorCode gdata_error,
368 scoped_ptr<google_apis::ResourceList> resource_list) {
369 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
371 FileError error = GDataToFileError(gdata_error);
372 if (error != FILE_ERROR_OK) {
373 callback.Run(error, scoped_ptr<ResourceEntry>());
377 DCHECK(resource_list);
378 const ScopedVector<google_apis::ResourceEntry>& entries =
379 resource_list->entries();
380 for (size_t i = 0; i < entries.size(); ++i) {
381 scoped_ptr<ResourceEntry> entry(new ResourceEntry);
382 std::string parent_resource_id;
384 ConvertToResourceEntry(*entries[i], entry.get(), &parent_resource_id);
386 entry->set_parent_local_id(parent_resource_id);
388 if (entry->base_name() == base_name.AsUTF8Unsafe()) {
389 // Found the target entry.
390 callback.Run(FILE_ERROR_OK, entry.Pass());
395 callback.Run(FILE_ERROR_NOT_FOUND, scoped_ptr<ResourceEntry>());
398 } // namespace test_util