Home | History | Annotate | Download | only in drive
      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 
     11 #include "base/files/file_path.h"
     12 #include "base/memory/scoped_ptr.h"
     13 #include "base/memory/weak_ptr.h"
     14 #include "chrome/browser/chromeos/drive/file_errors.h"
     15 #include "chrome/browser/chromeos/drive/resource_metadata_storage.h"
     16 
     17 namespace base {
     18 class ScopedClosureRunner;
     19 class SequencedTaskRunner;
     20 }  // namespace base
     21 
     22 namespace drive {
     23 
     24 namespace internal {
     25 
     26 // Interface class used for getting the free disk space. Tests can inject an
     27 // implementation that reports fake free disk space.
     28 class FreeDiskSpaceGetterInterface {
     29  public:
     30   virtual ~FreeDiskSpaceGetterInterface() {}
     31   virtual int64 AmountOfFreeDiskSpace() = 0;
     32 };
     33 
     34 // FileCache is used to maintain cache states of FileSystem.
     35 //
     36 // All non-static public member functions, unless mentioned otherwise (see
     37 // GetCacheFilePath() for example), should be run with |blocking_task_runner|.
     38 class FileCache {
     39  public:
     40   // Enum defining type of file operation e.g. copy or move, etc.
     41   enum FileOperationType {
     42     FILE_OPERATION_MOVE = 0,
     43     FILE_OPERATION_COPY,
     44   };
     45 
     46   // |cache_file_directory| stores cached files.
     47   //
     48   // |blocking_task_runner| indicates the blocking worker pool for cache
     49   // operations. All operations on this FileCache must be run on this runner.
     50   // Must not be null.
     51   //
     52   // |free_disk_space_getter| is used to inject a custom free disk space
     53   // getter for testing. NULL must be passed for production code.
     54   //
     55   // Must be called on the UI thread.
     56   FileCache(ResourceMetadataStorage* storage,
     57             const base::FilePath& cache_file_directory,
     58             base::SequencedTaskRunner* blocking_task_runner,
     59             FreeDiskSpaceGetterInterface* free_disk_space_getter);
     60 
     61   // Returns true if the given path is under drive cache directory, i.e.
     62   // <user_profile_dir>/GCache/v1
     63   //
     64   // Can be called on any thread.
     65   bool IsUnderFileCacheDirectory(const base::FilePath& path) const;
     66 
     67   // Frees up disk space to store a file with |num_bytes| size content, while
     68   // keeping cryptohome::kMinFreeSpaceInBytes bytes on the disk, if needed.
     69   // Returns true if we successfully manage to have enough space, otherwise
     70   // false.
     71   bool FreeDiskSpaceIfNeededFor(int64 num_bytes);
     72 
     73   // Checks if file corresponding to |id| exists in cache, and returns
     74   // FILE_ERROR_OK with |cache_file_path| storing the path to the file.
     75   // |cache_file_path| must not be null.
     76   FileError GetFile(const std::string& id, base::FilePath* cache_file_path);
     77 
     78   // Stores |source_path| as a cache of the remote content of the file
     79   // with |id| and |md5|.
     80   // Pass an empty string as MD5 to mark the entry as dirty.
     81   FileError Store(const std::string& id,
     82                   const std::string& md5,
     83                   const base::FilePath& source_path,
     84                   FileOperationType file_operation_type);
     85 
     86   // Pins the specified entry.
     87   FileError Pin(const std::string& id);
     88 
     89   // Unpins the specified entry.
     90   FileError Unpin(const std::string& id);
     91 
     92   // Sets the state of the cache entry corresponding to |id| as mounted.
     93   FileError MarkAsMounted(const std::string& id,
     94                           base::FilePath* cache_file_path);
     95 
     96   // Sets the state of the cache entry corresponding to file_path as unmounted.
     97   FileError MarkAsUnmounted(const base::FilePath& file_path);
     98 
     99   // Opens the cache file corresponding to |id| for write. |file_closer| should
    100   // be kept alive until writing finishes.
    101   // This method must be called before writing to cache files.
    102   FileError OpenForWrite(const std::string& id,
    103                          scoped_ptr<base::ScopedClosureRunner>* file_closer);
    104 
    105   // Returns true if the cache file corresponding to |id| is write-opened.
    106   bool IsOpenedForWrite(const std::string& id);
    107 
    108   // Calculates MD5 of the cache file and updates the stored value.
    109   FileError UpdateMd5(const std::string& id);
    110 
    111   // Clears dirty state of the specified entry.
    112   FileError ClearDirty(const std::string& id);
    113 
    114   // Removes the specified cache entry and delete cache files if available.
    115   FileError Remove(const std::string& id);
    116 
    117   // Removes all the files in the cache directory.
    118   bool ClearAll();
    119 
    120   // Initializes the cache. Returns true on success.
    121   bool Initialize();
    122 
    123   // Destroys this cache. This function posts a task to the blocking task
    124   // runner to safely delete the object.
    125   // Must be called on the UI thread.
    126   void Destroy();
    127 
    128   // Moves files in the cache directory which are not managed by FileCache to
    129   // |dest_directory|.
    130   // |recovered_cache_info| should contain cache info recovered from the trashed
    131   // metadata DB. It is used to ignore non-dirty files.
    132   bool RecoverFilesFromCacheDirectory(
    133       const base::FilePath& dest_directory,
    134       const ResourceMetadataStorage::RecoveredCacheInfoMap&
    135           recovered_cache_info);
    136 
    137  private:
    138   friend class FileCacheTest;
    139 
    140   ~FileCache();
    141 
    142   // Returns absolute path of the file if it were cached or to be cached.
    143   //
    144   // Can be called on any thread.
    145   base::FilePath GetCacheFilePath(const std::string& id) const;
    146 
    147   // Checks whether the current thread is on the right sequenced worker pool
    148   // with the right sequence ID. If not, DCHECK will fail.
    149   void AssertOnSequencedWorkerPool();
    150 
    151   // Destroys the cache on the blocking pool.
    152   void DestroyOnBlockingPool();
    153 
    154   // Returns true if we have sufficient space to store the given number of
    155   // bytes, while keeping cryptohome::kMinFreeSpaceInBytes bytes on the disk.
    156   bool HasEnoughSpaceFor(int64 num_bytes, const base::FilePath& path);
    157 
    158   // Renames cache files from old "prefix:id.md5" format to the new format.
    159   // TODO(hashimoto): Remove this method at some point.
    160   bool RenameCacheFilesToNewFormat();
    161 
    162   // This method must be called after writing to a cache file.
    163   // Used to implement OpenForWrite().
    164   void CloseForWrite(const std::string& id);
    165 
    166   const base::FilePath cache_file_directory_;
    167 
    168   scoped_refptr<base::SequencedTaskRunner> blocking_task_runner_;
    169 
    170   ResourceMetadataStorage* storage_;
    171 
    172   FreeDiskSpaceGetterInterface* free_disk_space_getter_;  // Not owned.
    173 
    174   // IDs of files being write-opened.
    175   std::map<std::string, int> write_opened_files_;
    176 
    177   // IDs of files marked mounted.
    178   std::set<std::string> mounted_files_;
    179 
    180   // Note: This should remain the last member so it'll be destroyed and
    181   // invalidate its weak pointers before any other members are destroyed.
    182   // This object should be accessed only on |blocking_task_runner_|.
    183   base::WeakPtrFactory<FileCache> weak_ptr_factory_;
    184   DISALLOW_COPY_AND_ASSIGN(FileCache);
    185 };
    186 
    187 }  // namespace internal
    188 }  // namespace drive
    189 
    190 #endif  // CHROME_BROWSER_CHROMEOS_DRIVE_FILE_CACHE_H_
    191