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 "components/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 "components/drive/drive.pb.h"
14 #include "components/drive/file_errors.h"
15 #include "components/drive/file_system_core_util.h"
16 #include "components/drive/resource_entry_conversion.h"
17 #include "components/drive/service/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_CURRENTLY_ON(BrowserThread::UI
);
39 void FakeFileSystem::RemoveObserver(FileSystemObserver
* observer
) {
40 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
43 void FakeFileSystem::CheckForUpdates() {
44 DCHECK_CURRENTLY_ON(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_CURRENTLY_ON(BrowserThread::UI
);
54 void FakeFileSystem::OpenFile(const base::FilePath
& file_path
,
56 const std::string
& mime_type
,
57 const OpenFileCallback
& callback
) {
58 DCHECK_CURRENTLY_ON(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_CURRENTLY_ON(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_CURRENTLY_ON(BrowserThread::UI
);
74 void FakeFileSystem::Remove(const base::FilePath
& file_path
,
76 const FileOperationCallback
& callback
) {
77 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
80 void FakeFileSystem::CreateDirectory(
81 const base::FilePath
& directory_path
,
84 const FileOperationCallback
& callback
) {
85 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
88 void FakeFileSystem::CreateFile(const base::FilePath
& file_path
,
90 const std::string
& mime_type
,
91 const FileOperationCallback
& callback
) {
92 DCHECK_CURRENTLY_ON(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_CURRENTLY_ON(BrowserThread::UI
);
102 void FakeFileSystem::TruncateFile(const base::FilePath
& file_path
,
104 const FileOperationCallback
& callback
) {
105 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
108 void FakeFileSystem::Pin(const base::FilePath
& file_path
,
109 const FileOperationCallback
& callback
) {
110 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
113 void FakeFileSystem::Unpin(const base::FilePath
& file_path
,
114 const FileOperationCallback
& callback
) {
115 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
118 void FakeFileSystem::GetFile(const base::FilePath
& file_path
,
119 const GetFileCallback
& callback
) {
120 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
123 void FakeFileSystem::GetFileForSaving(const base::FilePath
& file_path
,
124 const GetFileCallback
& callback
) {
125 DCHECK_CURRENTLY_ON(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_CURRENTLY_ON(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_CURRENTLY_ON(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_CURRENTLY_ON(BrowserThread::UI
);
174 void FakeFileSystem::Search(const std::string
& search_query
,
175 const GURL
& next_link
,
176 const SearchCallback
& callback
) {
177 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
180 void FakeFileSystem::SearchMetadata(
181 const std::string
& query
,
183 int at_most_num_matches
,
184 const SearchMetadataCallback
& callback
) {
185 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
188 void FakeFileSystem::SearchByHashes(const std::set
<std::string
>& hashes
,
189 const SearchByHashesCallback
& callback
) {
190 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
193 void FakeFileSystem::GetAvailableSpace(
194 const GetAvailableSpaceCallback
& callback
) {
195 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
198 void FakeFileSystem::GetShareUrl(
199 const base::FilePath
& file_path
,
200 const GURL
& embed_origin
,
201 const GetShareUrlCallback
& callback
) {
202 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
205 void FakeFileSystem::GetMetadata(
206 const GetFilesystemMetadataCallback
& callback
) {
207 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
210 void FakeFileSystem::MarkCacheFileAsMounted(
211 const base::FilePath
& drive_file_path
,
212 const MarkMountedCallback
& callback
) {
213 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
216 void FakeFileSystem::MarkCacheFileAsUnmounted(
217 const base::FilePath
& cache_file_path
,
218 const FileOperationCallback
& callback
) {
219 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
222 void FakeFileSystem::AddPermission(const base::FilePath
& drive_file_path
,
223 const std::string
& email
,
224 google_apis::drive::PermissionRole role
,
225 const FileOperationCallback
& callback
) {
226 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
229 void FakeFileSystem::SetProperty(
230 const base::FilePath
& drive_file_path
,
231 google_apis::drive::Property::Visibility visibility
,
232 const std::string
& key
,
233 const std::string
& value
,
234 const FileOperationCallback
& callback
) {
235 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
238 void FakeFileSystem::Reset(const FileOperationCallback
& callback
) {
241 void FakeFileSystem::GetPathFromResourceId(
242 const std::string
& resource_id
,
243 const GetFilePathCallback
& callback
) {
244 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
247 void FakeFileSystem::FreeDiskSpaceIfNeededFor(
249 const FreeDiskSpaceCallback
& callback
) {
250 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
253 void FakeFileSystem::CalculateEvictableCacheSize(
254 const EvictableCacheSizeCallback
& callback
) {
255 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
258 // Implementation of GetFileContent.
259 void FakeFileSystem::GetFileContentAfterGetResourceEntry(
260 const GetFileContentInitializedCallback
& initialized_callback
,
261 const google_apis::GetContentCallback
& get_content_callback
,
262 const FileOperationCallback
& completion_callback
,
264 scoped_ptr
<ResourceEntry
> entry
) {
265 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
267 if (error
!= FILE_ERROR_OK
) {
268 completion_callback
.Run(error
);
273 // We're only interested in a file.
274 if (entry
->file_info().is_directory()) {
275 completion_callback
.Run(FILE_ERROR_NOT_A_FILE
);
279 // Fetch google_apis::FileResource for its |download_url|.
280 drive_service_
->GetFileResource(
281 entry
->resource_id(),
283 &FakeFileSystem::GetFileContentAfterGetFileResource
,
284 weak_ptr_factory_
.GetWeakPtr(),
285 initialized_callback
,
286 get_content_callback
,
287 completion_callback
));
290 void FakeFileSystem::GetFileContentAfterGetFileResource(
291 const GetFileContentInitializedCallback
& initialized_callback
,
292 const google_apis::GetContentCallback
& get_content_callback
,
293 const FileOperationCallback
& completion_callback
,
294 google_apis::DriveApiErrorCode gdata_error
,
295 scoped_ptr
<google_apis::FileResource
> gdata_entry
) {
296 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
298 FileError error
= GDataToFileError(gdata_error
);
299 if (error
!= FILE_ERROR_OK
) {
300 completion_callback
.Run(error
);
305 scoped_ptr
<ResourceEntry
> entry(new ResourceEntry
);
306 std::string parent_resource_id
;
307 bool converted
= ConvertFileResourceToResourceEntry(
308 *gdata_entry
, entry
.get(), &parent_resource_id
);
310 entry
->set_parent_local_id(parent_resource_id
);
312 base::FilePath cache_path
=
313 cache_dir_
.path().AppendASCII(entry
->resource_id());
314 if (entry
->file_specific_info().is_hosted_document()) {
315 // For hosted documents return a dummy cache without server request.
316 int result
= base::WriteFile(cache_path
, "", 0);
317 DCHECK_EQ(0, result
);
319 if (base::PathExists(cache_path
)) {
320 // Cache file is found.
321 initialized_callback
.Run(FILE_ERROR_OK
, cache_path
, entry
.Pass());
322 completion_callback
.Run(FILE_ERROR_OK
);
326 initialized_callback
.Run(FILE_ERROR_OK
, base::FilePath(), entry
.Pass());
327 drive_service_
->DownloadFile(
329 gdata_entry
->file_id(),
330 base::Bind(&FakeFileSystem::GetFileContentAfterDownloadFile
,
331 weak_ptr_factory_
.GetWeakPtr(),
332 completion_callback
),
333 get_content_callback
,
334 google_apis::ProgressCallback());
337 void FakeFileSystem::GetFileContentAfterDownloadFile(
338 const FileOperationCallback
& completion_callback
,
339 google_apis::DriveApiErrorCode gdata_error
,
340 const base::FilePath
& temp_file
) {
341 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
342 completion_callback
.Run(GDataToFileError(gdata_error
));
345 // Implementation of GetResourceEntry.
346 void FakeFileSystem::GetResourceEntryAfterGetAboutResource(
347 const GetResourceEntryCallback
& callback
,
348 google_apis::DriveApiErrorCode gdata_error
,
349 scoped_ptr
<google_apis::AboutResource
> about_resource
) {
350 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
352 FileError error
= GDataToFileError(gdata_error
);
353 if (error
!= FILE_ERROR_OK
) {
354 callback
.Run(error
, scoped_ptr
<ResourceEntry
>());
358 DCHECK(about_resource
);
359 scoped_ptr
<ResourceEntry
> root(new ResourceEntry
);
360 root
->mutable_file_info()->set_is_directory(true);
361 root
->set_resource_id(about_resource
->root_folder_id());
362 root
->set_title(util::kDriveMyDriveRootDirName
);
363 callback
.Run(error
, root
.Pass());
366 void FakeFileSystem::GetResourceEntryAfterGetParentEntryInfo(
367 const base::FilePath
& base_name
,
368 const GetResourceEntryCallback
& callback
,
370 scoped_ptr
<ResourceEntry
> parent_entry
) {
371 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
373 if (error
!= FILE_ERROR_OK
) {
374 callback
.Run(error
, scoped_ptr
<ResourceEntry
>());
378 DCHECK(parent_entry
);
379 drive_service_
->GetFileListInDirectory(
380 parent_entry
->resource_id(),
382 &FakeFileSystem::GetResourceEntryAfterGetFileList
,
383 weak_ptr_factory_
.GetWeakPtr(), base_name
, callback
));
386 void FakeFileSystem::GetResourceEntryAfterGetFileList(
387 const base::FilePath
& base_name
,
388 const GetResourceEntryCallback
& callback
,
389 google_apis::DriveApiErrorCode gdata_error
,
390 scoped_ptr
<google_apis::FileList
> file_list
) {
391 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
393 FileError error
= GDataToFileError(gdata_error
);
394 if (error
!= FILE_ERROR_OK
) {
395 callback
.Run(error
, scoped_ptr
<ResourceEntry
>());
400 const ScopedVector
<google_apis::FileResource
>& entries
= file_list
->items();
401 for (size_t i
= 0; i
< entries
.size(); ++i
) {
402 scoped_ptr
<ResourceEntry
> entry(new ResourceEntry
);
403 std::string parent_resource_id
;
404 bool converted
= ConvertFileResourceToResourceEntry(
405 *entries
[i
], entry
.get(), &parent_resource_id
);
407 entry
->set_parent_local_id(parent_resource_id
);
409 if (entry
->base_name() == base_name
.AsUTF8Unsafe()) {
410 // Found the target entry.
411 callback
.Run(FILE_ERROR_OK
, entry
.Pass());
416 callback
.Run(FILE_ERROR_NOT_FOUND
, scoped_ptr
<ResourceEntry
>());
419 } // namespace test_util