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