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 bool preserve_last_modified
,
73 const FileOperationCallback
& callback
) {
74 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
77 void FakeFileSystem::Remove(const base::FilePath
& file_path
,
79 const FileOperationCallback
& callback
) {
80 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
83 void FakeFileSystem::CreateDirectory(
84 const base::FilePath
& directory_path
,
87 const FileOperationCallback
& callback
) {
88 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
91 void FakeFileSystem::CreateFile(const base::FilePath
& file_path
,
93 const std::string
& mime_type
,
94 const FileOperationCallback
& callback
) {
95 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
98 void FakeFileSystem::TouchFile(const base::FilePath
& file_path
,
99 const base::Time
& last_access_time
,
100 const base::Time
& last_modified_time
,
101 const FileOperationCallback
& callback
) {
102 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
105 void FakeFileSystem::TruncateFile(const base::FilePath
& file_path
,
107 const FileOperationCallback
& callback
) {
108 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
111 void FakeFileSystem::Pin(const base::FilePath
& file_path
,
112 const FileOperationCallback
& callback
) {
113 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
116 void FakeFileSystem::Unpin(const base::FilePath
& file_path
,
117 const FileOperationCallback
& callback
) {
118 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
121 void FakeFileSystem::GetFile(const base::FilePath
& file_path
,
122 const GetFileCallback
& callback
) {
123 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
126 void FakeFileSystem::GetFileForSaving(const base::FilePath
& file_path
,
127 const GetFileCallback
& callback
) {
128 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
131 void FakeFileSystem::GetFileContent(
132 const base::FilePath
& file_path
,
133 const GetFileContentInitializedCallback
& initialized_callback
,
134 const google_apis::GetContentCallback
& get_content_callback
,
135 const FileOperationCallback
& completion_callback
) {
136 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
140 base::Bind(&FakeFileSystem::GetFileContentAfterGetResourceEntry
,
141 weak_ptr_factory_
.GetWeakPtr(),
142 initialized_callback
, get_content_callback
,
143 completion_callback
));
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::Reset(const FileOperationCallback
& callback
) {
228 // Implementation of GetFileContent.
229 void FakeFileSystem::GetFileContentAfterGetResourceEntry(
230 const GetFileContentInitializedCallback
& initialized_callback
,
231 const google_apis::GetContentCallback
& get_content_callback
,
232 const FileOperationCallback
& completion_callback
,
234 scoped_ptr
<ResourceEntry
> entry
) {
235 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
237 if (error
!= FILE_ERROR_OK
) {
238 completion_callback
.Run(error
);
243 // We're only interested in a file.
244 if (entry
->file_info().is_directory()) {
245 completion_callback
.Run(FILE_ERROR_NOT_A_FILE
);
249 // Fetch google_apis::ResourceEntry for its |download_url|.
250 drive_service_
->GetResourceEntry(
251 entry
->resource_id(),
253 &FakeFileSystem::GetFileContentAfterGetWapiResourceEntry
,
254 weak_ptr_factory_
.GetWeakPtr(),
255 initialized_callback
,
256 get_content_callback
,
257 completion_callback
));
260 void FakeFileSystem::GetFileContentAfterGetWapiResourceEntry(
261 const GetFileContentInitializedCallback
& initialized_callback
,
262 const google_apis::GetContentCallback
& get_content_callback
,
263 const FileOperationCallback
& completion_callback
,
264 google_apis::GDataErrorCode gdata_error
,
265 scoped_ptr
<google_apis::ResourceEntry
> gdata_entry
) {
266 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
268 FileError error
= GDataToFileError(gdata_error
);
269 if (error
!= FILE_ERROR_OK
) {
270 completion_callback
.Run(error
);
275 scoped_ptr
<ResourceEntry
> entry(new ResourceEntry
);
276 std::string parent_resource_id
;
278 ConvertToResourceEntry(*gdata_entry
, entry
.get(), &parent_resource_id
);
280 entry
->set_parent_local_id(parent_resource_id
);
282 base::FilePath cache_path
=
283 cache_dir_
.path().AppendASCII(entry
->resource_id());
284 if (base::PathExists(cache_path
)) {
285 // Cache file is found.
286 initialized_callback
.Run(FILE_ERROR_OK
, entry
.Pass(), cache_path
,
288 completion_callback
.Run(FILE_ERROR_OK
);
292 initialized_callback
.Run(FILE_ERROR_OK
, entry
.Pass(), base::FilePath(),
293 base::Bind(&base::DoNothing
));
294 drive_service_
->DownloadFile(
296 gdata_entry
->resource_id(),
297 base::Bind(&FakeFileSystem::GetFileContentAfterDownloadFile
,
298 weak_ptr_factory_
.GetWeakPtr(),
299 completion_callback
),
300 get_content_callback
,
301 google_apis::ProgressCallback());
304 void FakeFileSystem::GetFileContentAfterDownloadFile(
305 const FileOperationCallback
& completion_callback
,
306 google_apis::GDataErrorCode gdata_error
,
307 const base::FilePath
& temp_file
) {
308 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
309 completion_callback
.Run(GDataToFileError(gdata_error
));
312 // Implementation of GetResourceEntry.
313 void FakeFileSystem::GetResourceEntryAfterGetAboutResource(
314 const GetResourceEntryCallback
& callback
,
315 google_apis::GDataErrorCode gdata_error
,
316 scoped_ptr
<google_apis::AboutResource
> about_resource
) {
317 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
319 FileError error
= GDataToFileError(gdata_error
);
320 if (error
!= FILE_ERROR_OK
) {
321 callback
.Run(error
, scoped_ptr
<ResourceEntry
>());
325 DCHECK(about_resource
);
326 scoped_ptr
<ResourceEntry
> root(new ResourceEntry
);
327 root
->mutable_file_info()->set_is_directory(true);
328 root
->set_resource_id(about_resource
->root_folder_id());
329 root
->set_title(util::kDriveMyDriveRootDirName
);
330 callback
.Run(error
, root
.Pass());
333 void FakeFileSystem::GetResourceEntryAfterGetParentEntryInfo(
334 const base::FilePath
& base_name
,
335 const GetResourceEntryCallback
& callback
,
337 scoped_ptr
<ResourceEntry
> parent_entry
) {
338 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
340 if (error
!= FILE_ERROR_OK
) {
341 callback
.Run(error
, scoped_ptr
<ResourceEntry
>());
345 DCHECK(parent_entry
);
346 drive_service_
->GetResourceListInDirectory(
347 parent_entry
->resource_id(),
349 &FakeFileSystem::GetResourceEntryAfterGetResourceList
,
350 weak_ptr_factory_
.GetWeakPtr(), base_name
, callback
));
353 void FakeFileSystem::GetResourceEntryAfterGetResourceList(
354 const base::FilePath
& base_name
,
355 const GetResourceEntryCallback
& callback
,
356 google_apis::GDataErrorCode gdata_error
,
357 scoped_ptr
<google_apis::ResourceList
> resource_list
) {
358 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
360 FileError error
= GDataToFileError(gdata_error
);
361 if (error
!= FILE_ERROR_OK
) {
362 callback
.Run(error
, scoped_ptr
<ResourceEntry
>());
366 DCHECK(resource_list
);
367 const ScopedVector
<google_apis::ResourceEntry
>& entries
=
368 resource_list
->entries();
369 for (size_t i
= 0; i
< entries
.size(); ++i
) {
370 scoped_ptr
<ResourceEntry
> entry(new ResourceEntry
);
371 std::string parent_resource_id
;
373 ConvertToResourceEntry(*entries
[i
], entry
.get(), &parent_resource_id
);
375 entry
->set_parent_local_id(parent_resource_id
);
377 if (entry
->base_name() == base_name
.AsUTF8Unsafe()) {
378 // Found the target entry.
379 callback
.Run(FILE_ERROR_OK
, entry
.Pass());
384 callback
.Run(FILE_ERROR_NOT_FOUND
, scoped_ptr
<ResourceEntry
>());
387 } // namespace test_util