fake_file_system.cc revision a36e5920737c6adbddd3e43b760e5de8431db6e0
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.
4
5#include "chrome/browser/chromeos/drive/fake_file_system.h"
6
7#include "base/bind.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 "chrome/browser/google_apis/drive_api_parser.h"
19#include "chrome/browser/google_apis/gdata_wapi_parser.h"
20#include "content/public/browser/browser_thread.h"
21
22namespace drive {
23namespace test_util {
24
25using content::BrowserThread;
26
27FakeFileSystem::FakeFileSystem(DriveServiceInterface* drive_service)
28    : drive_service_(drive_service),
29      weak_ptr_factory_(this) {
30}
31
32FakeFileSystem::~FakeFileSystem() {
33}
34
35bool FakeFileSystem::InitializeForTesting() {
36  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
37  return cache_dir_.CreateUniqueTempDir();
38}
39
40void FakeFileSystem::Initialize() {
41  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
42  InitializeForTesting();
43}
44
45void FakeFileSystem::AddObserver(FileSystemObserver* observer) {
46  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
47}
48
49void FakeFileSystem::RemoveObserver(FileSystemObserver* observer) {
50  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
51}
52
53void FakeFileSystem::CheckForUpdates() {
54  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
55}
56
57void FakeFileSystem::TransferFileFromRemoteToLocal(
58    const base::FilePath& remote_src_file_path,
59    const base::FilePath& local_dest_file_path,
60    const FileOperationCallback& callback) {
61  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
62}
63
64void FakeFileSystem::TransferFileFromLocalToRemote(
65    const base::FilePath& local_src_file_path,
66    const base::FilePath& remote_dest_file_path,
67    const FileOperationCallback& callback) {
68  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
69}
70
71void FakeFileSystem::OpenFile(const base::FilePath& file_path,
72                              OpenMode open_mode,
73                              const OpenFileCallback& callback) {
74  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
75}
76
77void FakeFileSystem::Copy(const base::FilePath& src_file_path,
78                          const base::FilePath& dest_file_path,
79                          const FileOperationCallback& callback) {
80  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
81}
82
83void FakeFileSystem::Move(const base::FilePath& src_file_path,
84                          const base::FilePath& dest_file_path,
85                          const FileOperationCallback& callback) {
86  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
87}
88
89void FakeFileSystem::Remove(const base::FilePath& file_path,
90                            bool is_recursive,
91                            const FileOperationCallback& callback) {
92  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
93}
94
95void FakeFileSystem::CreateDirectory(
96    const base::FilePath& directory_path,
97    bool is_exclusive,
98    bool is_recursive,
99    const FileOperationCallback& callback) {
100  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
101}
102
103void FakeFileSystem::CreateFile(const base::FilePath& file_path,
104                                bool is_exclusive,
105                                const FileOperationCallback& callback) {
106  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
107}
108
109void FakeFileSystem::TouchFile(const base::FilePath& file_path,
110                               const base::Time& last_access_time,
111                               const base::Time& last_modified_time,
112                               const FileOperationCallback& callback) {
113  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
114}
115
116void FakeFileSystem::TruncateFile(const base::FilePath& file_path,
117                                  int64 length,
118                                  const FileOperationCallback& callback) {
119  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
120}
121
122void FakeFileSystem::Pin(const base::FilePath& file_path,
123                         const FileOperationCallback& callback) {
124  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
125}
126
127void FakeFileSystem::Unpin(const base::FilePath& file_path,
128                           const FileOperationCallback& callback) {
129  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
130}
131
132void FakeFileSystem::GetFileByPath(const base::FilePath& file_path,
133                                   const GetFileCallback& callback) {
134  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
135}
136
137void FakeFileSystem::GetFileContentByPath(
138    const base::FilePath& file_path,
139    const GetFileContentInitializedCallback& initialized_callback,
140    const google_apis::GetContentCallback& get_content_callback,
141    const FileOperationCallback& completion_callback) {
142  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
143
144  GetResourceEntryByPath(
145      file_path,
146      base::Bind(&FakeFileSystem::GetFileContentByPathAfterGetResourceEntry,
147                 weak_ptr_factory_.GetWeakPtr(),
148                 initialized_callback, get_content_callback,
149                 completion_callback));
150}
151
152void FakeFileSystem::GetResourceEntryByPath(
153    const base::FilePath& file_path,
154    const GetResourceEntryCallback& callback) {
155  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
156
157  // Now, we only support files under my drive.
158  DCHECK(!util::IsUnderDriveMountPoint(file_path));
159
160  if (file_path == util::GetDriveMyDriveRootPath()) {
161    // Specialized for the root entry.
162    drive_service_->GetAboutResource(
163        base::Bind(
164            &FakeFileSystem::GetResourceEntryByPathAfterGetAboutResource,
165            weak_ptr_factory_.GetWeakPtr(), callback));
166    return;
167  }
168
169  GetResourceEntryByPath(
170      file_path.DirName(),
171      base::Bind(
172          &FakeFileSystem::GetResourceEntryByPathAfterGetParentEntryInfo,
173          weak_ptr_factory_.GetWeakPtr(), file_path.BaseName(), callback));
174}
175
176void FakeFileSystem::ReadDirectoryByPath(
177    const base::FilePath& file_path,
178    const ReadDirectoryCallback& callback) {
179  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
180}
181
182void FakeFileSystem::Search(const std::string& search_query,
183                            const GURL& next_url,
184                            const SearchCallback& callback) {
185  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
186}
187
188void FakeFileSystem::SearchMetadata(
189    const std::string& query,
190    int options,
191    int at_most_num_matches,
192    const SearchMetadataCallback& callback) {
193  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
194}
195
196void FakeFileSystem::GetAvailableSpace(
197    const GetAvailableSpaceCallback& callback) {
198  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
199}
200
201void FakeFileSystem::GetShareUrl(
202    const base::FilePath& file_path,
203    const GURL& embed_origin,
204    const GetShareUrlCallback& callback) {
205  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
206}
207
208void FakeFileSystem::GetMetadata(
209    const GetFilesystemMetadataCallback& callback) {
210  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
211}
212
213void FakeFileSystem::MarkCacheFileAsMounted(
214    const base::FilePath& drive_file_path,
215    const MarkMountedCallback& callback) {
216  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
217}
218
219void FakeFileSystem::MarkCacheFileAsUnmounted(
220    const base::FilePath& cache_file_path,
221    const FileOperationCallback& callback) {
222  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
223}
224
225void FakeFileSystem::GetCacheEntryByResourceId(
226    const std::string& resource_id,
227    const GetCacheEntryCallback& callback) {
228  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
229}
230
231void FakeFileSystem::Reload() {
232}
233
234// Implementation of GetFileContentByPath.
235void FakeFileSystem::GetFileContentByPathAfterGetResourceEntry(
236    const GetFileContentInitializedCallback& initialized_callback,
237    const google_apis::GetContentCallback& get_content_callback,
238    const FileOperationCallback& completion_callback,
239    FileError error,
240    scoped_ptr<ResourceEntry> entry) {
241  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
242
243  if (error != FILE_ERROR_OK) {
244    completion_callback.Run(error);
245    return;
246  }
247  DCHECK(entry);
248
249  // We're only interested in a file.
250  if (entry->file_info().is_directory()) {
251    completion_callback.Run(FILE_ERROR_NOT_A_FILE);
252    return;
253  }
254
255  // Fetch google_apis::ResourceEntry for its |download_url|.
256  drive_service_->GetResourceEntry(
257      entry->resource_id(),
258      base::Bind(
259          &FakeFileSystem::GetFileContentByPathAfterGetWapiResourceEntry,
260          weak_ptr_factory_.GetWeakPtr(),
261          initialized_callback,
262          get_content_callback,
263          completion_callback));
264}
265
266void FakeFileSystem::GetFileContentByPathAfterGetWapiResourceEntry(
267    const GetFileContentInitializedCallback& initialized_callback,
268    const google_apis::GetContentCallback& get_content_callback,
269    const FileOperationCallback& completion_callback,
270    google_apis::GDataErrorCode gdata_error,
271    scoped_ptr<google_apis::ResourceEntry> gdata_entry) {
272  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
273
274  FileError error = GDataToFileError(gdata_error);
275  if (error != FILE_ERROR_OK) {
276    completion_callback.Run(error);
277    return;
278  }
279  DCHECK(gdata_entry);
280
281  scoped_ptr<ResourceEntry> entry(new ResourceEntry);
282  bool converted = ConvertToResourceEntry(*gdata_entry, entry.get());
283  DCHECK(converted);
284
285  base::FilePath cache_path =
286      cache_dir_.path().AppendASCII(entry->resource_id());
287  if (base::PathExists(cache_path)) {
288    // Cache file is found.
289    initialized_callback.Run(FILE_ERROR_OK, entry.Pass(), cache_path,
290                             base::Closure());
291    completion_callback.Run(FILE_ERROR_OK);
292    return;
293  }
294
295  initialized_callback.Run(FILE_ERROR_OK, entry.Pass(), base::FilePath(),
296                           base::Bind(&base::DoNothing));
297  drive_service_->DownloadFile(
298      cache_path,
299      gdata_entry->resource_id(),
300      base::Bind(&FakeFileSystem::GetFileContentByPathAfterDownloadFile,
301                 weak_ptr_factory_.GetWeakPtr(),
302                 completion_callback),
303      get_content_callback,
304      google_apis::ProgressCallback());
305}
306
307void FakeFileSystem::GetFileContentByPathAfterDownloadFile(
308    const FileOperationCallback& completion_callback,
309    google_apis::GDataErrorCode gdata_error,
310    const base::FilePath& temp_file) {
311  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
312  completion_callback.Run(GDataToFileError(gdata_error));
313}
314
315// Implementation of GetResourceEntryByPath.
316void FakeFileSystem::GetResourceEntryByPathAfterGetAboutResource(
317    const GetResourceEntryCallback& callback,
318    google_apis::GDataErrorCode gdata_error,
319    scoped_ptr<google_apis::AboutResource> about_resource) {
320  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
321
322  FileError error = GDataToFileError(gdata_error);
323  if (error != FILE_ERROR_OK) {
324    callback.Run(error, scoped_ptr<ResourceEntry>());
325    return;
326  }
327
328  DCHECK(about_resource);
329  scoped_ptr<ResourceEntry> root(new ResourceEntry);
330  root->mutable_file_info()->set_is_directory(true);
331  root->set_resource_id(about_resource->root_folder_id());
332  root->set_title(util::kDriveMyDriveRootDirName);
333  callback.Run(error, root.Pass());
334}
335
336void FakeFileSystem::GetResourceEntryByPathAfterGetParentEntryInfo(
337    const base::FilePath& base_name,
338    const GetResourceEntryCallback& callback,
339    FileError error,
340    scoped_ptr<ResourceEntry> parent_entry) {
341  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
342
343  if (error != FILE_ERROR_OK) {
344    callback.Run(error, scoped_ptr<ResourceEntry>());
345    return;
346  }
347
348  DCHECK(parent_entry);
349  drive_service_->GetResourceListInDirectory(
350      parent_entry->resource_id(),
351      base::Bind(
352          &FakeFileSystem::GetResourceEntryByPathAfterGetResourceList,
353          weak_ptr_factory_.GetWeakPtr(), base_name, callback));
354}
355
356void FakeFileSystem::GetResourceEntryByPathAfterGetResourceList(
357    const base::FilePath& base_name,
358    const GetResourceEntryCallback& callback,
359    google_apis::GDataErrorCode gdata_error,
360    scoped_ptr<google_apis::ResourceList> resource_list) {
361  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
362
363  FileError error = GDataToFileError(gdata_error);
364  if (error != FILE_ERROR_OK) {
365    callback.Run(error, scoped_ptr<ResourceEntry>());
366    return;
367  }
368
369  DCHECK(resource_list);
370  const ScopedVector<google_apis::ResourceEntry>& entries =
371      resource_list->entries();
372  for (size_t i = 0; i < entries.size(); ++i) {
373    scoped_ptr<ResourceEntry> entry(new ResourceEntry);
374    bool converted = ConvertToResourceEntry(*entries[i], entry.get());
375    DCHECK(converted);
376
377    if (entry->base_name() == base_name.AsUTF8Unsafe()) {
378      // Found the target entry.
379      callback.Run(FILE_ERROR_OK, entry.Pass());
380      return;
381    }
382  }
383
384  callback.Run(FILE_ERROR_NOT_FOUND, scoped_ptr<ResourceEntry>());
385}
386
387}  // namespace test_util
388}  // namespace drive
389