file_cache.h revision a36e5920737c6adbddd3e43b760e5de8431db6e0
1// Copyright (c) 2012 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#ifndef CHROME_BROWSER_CHROMEOS_DRIVE_FILE_CACHE_H_
6#define CHROME_BROWSER_CHROMEOS_DRIVE_FILE_CACHE_H_
7
8#include <set>
9#include <string>
10#include <vector>
11
12#include "base/callback_forward.h"
13#include "base/files/file_path.h"
14#include "base/memory/scoped_ptr.h"
15#include "base/memory/weak_ptr.h"
16#include "chrome/browser/chromeos/drive/file_errors.h"
17#include "chrome/browser/chromeos/drive/resource_metadata_storage.h"
18
19namespace base {
20class SequencedTaskRunner;
21}  // namespace base
22
23namespace drive {
24
25class FileCacheEntry;
26
27// Callback for GetCacheEntry.
28// |success| indicates if the operation was successful.
29// |cache_entry| is the obtained cache entry. On failure, |cache_state| is
30// set to TEST_CACHE_STATE_NONE.
31typedef base::Callback<void(bool success, const FileCacheEntry& cache_entry)>
32    GetCacheEntryCallback;
33
34// Callback for Iterate().
35typedef base::Callback<void(const std::string& resource_id,
36                            const FileCacheEntry& cache_entry)>
37    CacheIterateCallback;
38
39namespace internal {
40
41// Callback for GetFileFromCache.
42typedef base::Callback<void(FileError error,
43                            const base::FilePath& cache_file_path)>
44    GetFileFromCacheCallback;
45
46// Callback for ClearAllOnUIThread.
47// |success| indicates if the operation was successful.
48// TODO(satorux): Change this to FileError when it becomes necessary.
49typedef base::Callback<void(bool success)> ClearAllCallback;
50
51// Interface class used for getting the free disk space. Tests can inject an
52// implementation that reports fake free disk space.
53class FreeDiskSpaceGetterInterface {
54 public:
55  virtual ~FreeDiskSpaceGetterInterface() {}
56  virtual int64 AmountOfFreeDiskSpace() = 0;
57};
58
59// FileCache is used to maintain cache states of FileSystem.
60//
61// All non-static public member functions, unless mentioned otherwise (see
62// GetCacheFilePath() for example), should be run with |blocking_task_runner|.
63class FileCache {
64 public:
65  // Enum defining type of file operation e.g. copy or move, etc.
66  enum FileOperationType {
67    FILE_OPERATION_MOVE = 0,
68    FILE_OPERATION_COPY,
69  };
70
71  typedef ResourceMetadataStorage::CacheEntryIterator Iterator;
72
73  // Name of the cache metadata DB previously used.
74  // TODO(hashimoto): Remove this at some point.
75  static const base::FilePath::CharType kOldCacheMetadataDBName[];
76
77  // |cache_file_directory| stores cached files.
78  //
79  // |blocking_task_runner| is used to post a task to the blocking worker
80  // pool for file operations. Must not be null.
81  //
82  // |free_disk_space_getter| is used to inject a custom free disk space
83  // getter for testing. NULL must be passed for production code.
84  //
85  // Must be called on the UI thread.
86  FileCache(ResourceMetadataStorage* storage,
87            const base::FilePath& cache_file_directory,
88            base::SequencedTaskRunner* blocking_task_runner,
89            FreeDiskSpaceGetterInterface* free_disk_space_getter);
90
91  // Returns true if the given path is under drive cache directory, i.e.
92  // <user_profile_dir>/GCache/v1
93  //
94  // Can be called on any thread.
95  bool IsUnderFileCacheDirectory(const base::FilePath& path) const;
96
97  // Gets the cache entry for file corresponding to |resource_id| and runs
98  // |callback| with true and the entry found if entry exists in cache map.
99  // Otherwise, runs |callback| with false.
100  // |callback| must not be null.
101  // Must be called on the UI thread.
102  void GetCacheEntryOnUIThread(const std::string& resource_id,
103                               const GetCacheEntryCallback& callback);
104
105  // Gets the cache entry by the given resource ID.
106  // See also GetCacheEntryOnUIThread().
107  bool GetCacheEntry(const std::string& resource_id,
108                     FileCacheEntry* entry);
109
110  // Runs Iterate() with |iteration_callback| on |blocking_task_runner_| and
111  // runs |completion_callback| upon completion.
112  // Must be called on UI thread.
113  void IterateOnUIThread(const CacheIterateCallback& iteration_callback,
114                         const base::Closure& completion_callback);
115
116  // Returns an object to iterate over entries.
117  scoped_ptr<Iterator> GetIterator();
118
119  // Frees up disk space to store a file with |num_bytes| size content, while
120  // keeping kMinFreeSpace bytes on the disk, if needed.
121  // Returns true if we successfully manage to have enough space, otherwise
122  // false.
123  bool FreeDiskSpaceIfNeededFor(int64 num_bytes);
124
125  // Runs GetFile() on |blocking_task_runner_|, and calls |callback| with
126  // the result asynchronously.
127  // |callback| must not be null.
128  // Must be called on the UI thread.
129  void GetFileOnUIThread(const std::string& resource_id,
130                         const GetFileFromCacheCallback& callback);
131
132  // Checks if file corresponding to |resource_id| exists in cache, and returns
133  // FILE_ERROR_OK with |cache_file_path| storing the path to the file.
134  // |cache_file_path| must not be null.
135  FileError GetFile(const std::string& resource_id,
136                    base::FilePath* cache_file_path);
137
138  // Runs Store() on |blocking_task_runner_|, and calls |callback| with
139  // the result asynchronously.
140  // |callback| must not be null.
141  // Must be called on the UI thread.
142  void StoreOnUIThread(const std::string& resource_id,
143                       const std::string& md5,
144                       const base::FilePath& source_path,
145                       FileOperationType file_operation_type,
146                       const FileOperationCallback& callback);
147
148  // Stores |source_path| as a cache of the remote content of the file
149  // with |resource_id| and |md5|.
150  FileError Store(const std::string& resource_Id,
151                  const std::string& md5,
152                  const base::FilePath& source_path,
153                  FileOperationType file_operation_type);
154
155  // Runs Pin() on |blocking_task_runner_|, and calls |callback| with the result
156  // asynchronously.
157  // |callback| must not be null.
158  // Must be called on the UI thread.
159  void PinOnUIThread(const std::string& resource_id,
160                     const FileOperationCallback& callback);
161
162  // Pins the specified entry.
163  FileError Pin(const std::string& resource_id);
164
165  // Runs Unpin() on |blocking_task_runner_|, and calls |callback| with the
166  // result asynchronously.
167  // |callback| must not be null.
168  // Must be called on the UI thread.
169  void UnpinOnUIThread(const std::string& resource_id,
170                       const FileOperationCallback& callback);
171
172  // Unpins the specified entry.
173  FileError Unpin(const std::string& resource_id);
174
175  // Sets the state of the cache entry corresponding to |resource_id| as
176  // mounted.
177  // |callback| must not be null.
178  // Must be called on the UI thread.
179  void MarkAsMountedOnUIThread(const std::string& resource_id,
180                               const GetFileFromCacheCallback& callback);
181
182  // Set the state of the cache entry corresponding to file_path as unmounted.
183  // |callback| must not be null.
184  // Must be called on the UI thread.
185  void MarkAsUnmountedOnUIThread(const base::FilePath& file_path,
186                                 const FileOperationCallback& callback);
187
188  // Runs MarkDirty() on |blocking_task_runner_|, and calls |callback| with the
189  // result asynchronously.
190  // |callback| must not be null.
191  // Must be called on the UI thread.
192  void MarkDirtyOnUIThread(const std::string& resource_id,
193                           const FileOperationCallback& callback);
194
195  // Marks the specified entry dirty.
196  FileError MarkDirty(const std::string& resource_id);
197
198  // Clears dirty state of the specified entry and updates its MD5.
199  FileError ClearDirty(const std::string& resource_id,
200                       const std::string& md5);
201
202  // Runs Remove() on |blocking_task_runner_| and runs |callback| with the
203  // result.
204  // Must be called on the UI thread.
205  void RemoveOnUIThread(const std::string& resource_id,
206                        const FileOperationCallback& callback);
207
208  // Removes the specified cache entry and delete cache files if available.
209  // Synchronous version of RemoveOnUIThread().
210  FileError Remove(const std::string& resource_id);
211
212  // Does the following:
213  // - remove all the files in the cache directory.
214  // - re-create the |metadata_| instance.
215  // |callback| must not be null.
216  // Must be called on the UI thread.
217  void ClearAllOnUIThread(const ClearAllCallback& callback);
218
219  // Initializes the cache. Returns true on success.
220  bool Initialize();
221
222  // Destroys this cache. This function posts a task to the blocking task
223  // runner to safely delete the object.
224  // Must be called on the UI thread.
225  void Destroy();
226
227 private:
228  friend class FileCacheTest;
229  friend class FileCacheTestOnUIThread;
230
231  ~FileCache();
232
233  // Returns absolute path of the file if it were cached or to be cached.
234  //
235  // Can be called on any thread.
236  base::FilePath GetCacheFilePath(const std::string& resource_id) const;
237
238  // Checks whether the current thread is on the right sequenced worker pool
239  // with the right sequence ID. If not, DCHECK will fail.
240  void AssertOnSequencedWorkerPool();
241
242  // Destroys the cache on the blocking pool.
243  void DestroyOnBlockingPool();
244
245  // Used to implement Store and StoreLocallyModifiedOnUIThread.
246  // TODO(hidehiko): Merge this method with Store(), after
247  // StoreLocallyModifiedOnUIThread is removed.
248  FileError StoreInternal(const std::string& resource_id,
249                          const std::string& md5,
250                          const base::FilePath& source_path,
251                          FileOperationType file_operation_type);
252
253  // Used to implement MarkAsMountedOnUIThread.
254  FileError MarkAsMounted(const std::string& resource_id,
255                          base::FilePath* cache_file_path);
256
257  // Used to implement MarkAsUnmountedOnUIThread.
258  FileError MarkAsUnmounted(const base::FilePath& file_path);
259
260  // Used to implement ClearAllOnUIThread.
261  bool ClearAll();
262
263  // Returns true if we have sufficient space to store the given number of
264  // bytes, while keeping kMinFreeSpace bytes on the disk.
265  bool HasEnoughSpaceFor(int64 num_bytes, const base::FilePath& path);
266
267  // Imports old format DB from |old_db_path| and deletes it.
268  // TODO(hashimoto): Remove this method and FileCacheMetadata at some point.
269  bool ImportOldDB(const base::FilePath& old_db_path);
270
271  // Renames cache files from old "resource_id.md5" format to the new format.
272  // TODO(hashimoto): Remove this method at some point.
273  void RenameCacheFilesToNewFormat();
274
275  const base::FilePath cache_file_directory_;
276
277  scoped_refptr<base::SequencedTaskRunner> blocking_task_runner_;
278
279  ResourceMetadataStorage* storage_;
280
281  FreeDiskSpaceGetterInterface* free_disk_space_getter_;  // Not owned.
282
283  // Resource IDs of files marked mounted.
284  std::set<std::string> mounted_files_;
285
286  // Note: This should remain the last member so it'll be destroyed and
287  // invalidate its weak pointers before any other members are destroyed.
288  base::WeakPtrFactory<FileCache> weak_ptr_factory_;
289  DISALLOW_COPY_AND_ASSIGN(FileCache);
290};
291
292// The minimum free space to keep. Operations that add cache files return
293// FILE_ERROR_NO_LOCAL_SPACE if the available space is smaller than
294// this value.
295//
296// Copied from cryptohome/homedirs.h.
297// TODO(satorux): Share the constant.
298const int64 kMinFreeSpace = 512 * 1LL << 20;
299
300}  // namespace internal
301}  // namespace drive
302
303#endif  // CHROME_BROWSER_CHROMEOS_DRIVE_FILE_CACHE_H_
304