fake_file_system.cc revision 46d4c2bc3267f3f028f39e7e311b0f89aba2e4fd
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_api_util.h"
18#include "chrome/browser/drive/drive_service_interface.h"
19#include "content/public/browser/browser_thread.h"
20#include "google_apis/drive/drive_api_parser.h"
21#include "google_apis/drive/gdata_wapi_parser.h"
22#include "testing/gtest/include/gtest/gtest.h"
23
24namespace drive {
25namespace test_util {
26
27using content::BrowserThread;
28
29FakeFileSystem::FakeFileSystem(DriveServiceInterface* drive_service)
30    : drive_service_(drive_service),
31      weak_ptr_factory_(this) {
32  CHECK(cache_dir_.CreateUniqueTempDir());
33}
34
35FakeFileSystem::~FakeFileSystem() {
36}
37
38void FakeFileSystem::AddObserver(FileSystemObserver* observer) {
39  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
40}
41
42void FakeFileSystem::RemoveObserver(FileSystemObserver* observer) {
43  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
44}
45
46void FakeFileSystem::CheckForUpdates() {
47  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
48}
49
50void FakeFileSystem::TransferFileFromLocalToRemote(
51    const base::FilePath& local_src_file_path,
52    const base::FilePath& remote_dest_file_path,
53    const FileOperationCallback& callback) {
54  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
55}
56
57void FakeFileSystem::OpenFile(const base::FilePath& file_path,
58                              OpenMode open_mode,
59                              const std::string& mime_type,
60                              const OpenFileCallback& callback) {
61  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
62}
63
64void FakeFileSystem::Copy(const base::FilePath& src_file_path,
65                          const base::FilePath& dest_file_path,
66                          bool preserve_last_modified,
67                          const FileOperationCallback& callback) {
68  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
69}
70
71void FakeFileSystem::Move(const base::FilePath& src_file_path,
72                          const base::FilePath& dest_file_path,
73                          const FileOperationCallback& callback) {
74  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
75}
76
77void FakeFileSystem::Remove(const base::FilePath& file_path,
78                            bool is_recursive,
79                            const FileOperationCallback& callback) {
80  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
81}
82
83void FakeFileSystem::CreateDirectory(
84    const base::FilePath& directory_path,
85    bool is_exclusive,
86    bool is_recursive,
87    const FileOperationCallback& callback) {
88  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
89}
90
91void FakeFileSystem::CreateFile(const base::FilePath& file_path,
92                                bool is_exclusive,
93                                const std::string& mime_type,
94                                const FileOperationCallback& callback) {
95  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
96}
97
98void 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));
103}
104
105void FakeFileSystem::TruncateFile(const base::FilePath& file_path,
106                                  int64 length,
107                                  const FileOperationCallback& callback) {
108  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
109}
110
111void FakeFileSystem::Pin(const base::FilePath& file_path,
112                         const FileOperationCallback& callback) {
113  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
114}
115
116void FakeFileSystem::Unpin(const base::FilePath& file_path,
117                           const FileOperationCallback& callback) {
118  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
119}
120
121void FakeFileSystem::GetFile(const base::FilePath& file_path,
122                             const GetFileCallback& callback) {
123  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
124}
125
126void FakeFileSystem::GetFileForSaving(const base::FilePath& file_path,
127                                      const GetFileCallback& callback) {
128  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
129}
130
131base::Closure 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));
137
138  GetResourceEntry(
139      file_path,
140      base::Bind(&FakeFileSystem::GetFileContentAfterGetResourceEntry,
141                 weak_ptr_factory_.GetWeakPtr(),
142                 initialized_callback, get_content_callback,
143                 completion_callback));
144  return base::Bind(&base::DoNothing);
145}
146
147void FakeFileSystem::GetResourceEntry(
148    const base::FilePath& file_path,
149    const GetResourceEntryCallback& callback) {
150  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
151
152  // Now, we only support files under my drive.
153  DCHECK(!util::IsUnderDriveMountPoint(file_path));
154
155  if (file_path == util::GetDriveMyDriveRootPath()) {
156    // Specialized for the root entry.
157    drive_service_->GetAboutResource(
158        base::Bind(
159            &FakeFileSystem::GetResourceEntryAfterGetAboutResource,
160            weak_ptr_factory_.GetWeakPtr(), callback));
161    return;
162  }
163
164  GetResourceEntry(
165      file_path.DirName(),
166      base::Bind(
167          &FakeFileSystem::GetResourceEntryAfterGetParentEntryInfo,
168          weak_ptr_factory_.GetWeakPtr(), file_path.BaseName(), callback));
169}
170
171void FakeFileSystem::ReadDirectory(
172    const base::FilePath& file_path,
173    const ReadDirectoryEntriesCallback& entries_callback,
174    const FileOperationCallback& completion_callback) {
175  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
176}
177
178void FakeFileSystem::Search(const std::string& search_query,
179                            const GURL& next_link,
180                            const SearchCallback& callback) {
181  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
182}
183
184void FakeFileSystem::SearchMetadata(
185    const std::string& query,
186    int options,
187    int at_most_num_matches,
188    const SearchMetadataCallback& callback) {
189  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
190}
191
192void FakeFileSystem::GetAvailableSpace(
193    const GetAvailableSpaceCallback& callback) {
194  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
195}
196
197void FakeFileSystem::GetShareUrl(
198    const base::FilePath& file_path,
199    const GURL& embed_origin,
200    const GetShareUrlCallback& callback) {
201  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
202}
203
204void FakeFileSystem::GetMetadata(
205    const GetFilesystemMetadataCallback& callback) {
206  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
207}
208
209void FakeFileSystem::MarkCacheFileAsMounted(
210    const base::FilePath& drive_file_path,
211    const MarkMountedCallback& callback) {
212  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
213}
214
215void FakeFileSystem::MarkCacheFileAsUnmounted(
216    const base::FilePath& cache_file_path,
217    const FileOperationCallback& callback) {
218  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
219}
220
221void FakeFileSystem::AddPermission(const base::FilePath& drive_file_path,
222                                   const std::string& email,
223                                   google_apis::drive::PermissionRole role,
224                                   const FileOperationCallback& callback) {
225  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
226}
227
228void FakeFileSystem::Reset(const FileOperationCallback& callback) {
229}
230
231void FakeFileSystem::GetPathFromResourceId(
232    const std::string& resource_id,
233    const GetFilePathCallback& callback) {
234  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
235}
236
237// Implementation of GetFileContent.
238void FakeFileSystem::GetFileContentAfterGetResourceEntry(
239    const GetFileContentInitializedCallback& initialized_callback,
240    const google_apis::GetContentCallback& get_content_callback,
241    const FileOperationCallback& completion_callback,
242    FileError error,
243    scoped_ptr<ResourceEntry> entry) {
244  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
245
246  if (error != FILE_ERROR_OK) {
247    completion_callback.Run(error);
248    return;
249  }
250  DCHECK(entry);
251
252  // We're only interested in a file.
253  if (entry->file_info().is_directory()) {
254    completion_callback.Run(FILE_ERROR_NOT_A_FILE);
255    return;
256  }
257
258  // Fetch google_apis::FileResource for its |download_url|.
259  drive_service_->GetFileResource(
260      entry->resource_id(),
261      base::Bind(
262          &FakeFileSystem::GetFileContentAfterGetFileResource,
263          weak_ptr_factory_.GetWeakPtr(),
264          initialized_callback,
265          get_content_callback,
266          completion_callback));
267}
268
269void FakeFileSystem::GetFileContentAfterGetFileResource(
270    const GetFileContentInitializedCallback& initialized_callback,
271    const google_apis::GetContentCallback& get_content_callback,
272    const FileOperationCallback& completion_callback,
273    google_apis::GDataErrorCode gdata_error,
274    scoped_ptr<google_apis::FileResource> gdata_entry) {
275  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
276
277  FileError error = GDataToFileError(gdata_error);
278  if (error != FILE_ERROR_OK) {
279    completion_callback.Run(error);
280    return;
281  }
282  DCHECK(gdata_entry);
283
284  scoped_ptr<ResourceEntry> entry(new ResourceEntry);
285  std::string parent_resource_id;
286  bool converted = ConvertToResourceEntry(
287      *util::ConvertFileResourceToResourceEntry(*gdata_entry),
288      entry.get(), &parent_resource_id);
289  DCHECK(converted);
290  entry->set_parent_local_id(parent_resource_id);
291
292  base::FilePath cache_path =
293      cache_dir_.path().AppendASCII(entry->resource_id());
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);
298    return;
299  }
300
301  initialized_callback.Run(FILE_ERROR_OK, base::FilePath(), entry.Pass());
302  drive_service_->DownloadFile(
303      cache_path,
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());
310}
311
312void 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));
318}
319
320// Implementation of GetResourceEntry.
321void 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));
326
327  FileError error = GDataToFileError(gdata_error);
328  if (error != FILE_ERROR_OK) {
329    callback.Run(error, scoped_ptr<ResourceEntry>());
330    return;
331  }
332
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());
339}
340
341void FakeFileSystem::GetResourceEntryAfterGetParentEntryInfo(
342    const base::FilePath& base_name,
343    const GetResourceEntryCallback& callback,
344    FileError error,
345    scoped_ptr<ResourceEntry> parent_entry) {
346  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
347
348  if (error != FILE_ERROR_OK) {
349    callback.Run(error, scoped_ptr<ResourceEntry>());
350    return;
351  }
352
353  DCHECK(parent_entry);
354  drive_service_->GetFileListInDirectory(
355      parent_entry->resource_id(),
356      base::Bind(
357          &FakeFileSystem::GetResourceEntryAfterGetFileList,
358          weak_ptr_factory_.GetWeakPtr(), base_name, callback));
359}
360
361void 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));
367
368  FileError error = GDataToFileError(gdata_error);
369  if (error != FILE_ERROR_OK) {
370    callback.Run(error, scoped_ptr<ResourceEntry>());
371    return;
372  }
373
374  DCHECK(file_list);
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 = ConvertToResourceEntry(
380        *util::ConvertFileResourceToResourceEntry(*entries[i]), entry.get(),
381        &parent_resource_id);
382    DCHECK(converted);
383    entry->set_parent_local_id(parent_resource_id);
384
385    if (entry->base_name() == base_name.AsUTF8Unsafe()) {
386      // Found the target entry.
387      callback.Run(FILE_ERROR_OK, entry.Pass());
388      return;
389    }
390  }
391
392  callback.Run(FILE_ERROR_NOT_FOUND, scoped_ptr<ResourceEntry>());
393}
394
395}  // namespace test_util
396}  // namespace drive
397