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 SequencedTaskRunner;
     19 }  // namespace base
     20 
     21 namespace drive {
     22 
     23 class FileCacheEntry;
     24 
     25 namespace internal {
     26 
     27 // Interface class used for getting the free disk space. Tests can inject an
     28 // implementation that reports fake free disk space.
     29 class FreeDiskSpaceGetterInterface {
     30  public:
     31   virtual ~FreeDiskSpaceGetterInterface() {}
     32   virtual int64 AmountOfFreeDiskSpace() = 0;
     33 };
     34 
     35 // FileCache is used to maintain cache states of FileSystem.
     36 //
     37 // All non-static public member functions, unless mentioned otherwise (see
     38 // GetCacheFilePath() for example), should be run with |blocking_task_runner|.
     39 class FileCache {
     40  public:
     41   // Enum defining type of file operation e.g. copy or move, etc.
     42   enum FileOperationType {
     43     FILE_OPERATION_MOVE = 0,
     44     FILE_OPERATION_COPY,
     45   };
     46 
     47   typedef ResourceMetadataStorage::CacheEntryIterator Iterator;
     48 
     49   // |cache_file_directory| stores cached files.
     50   //
     51   // |blocking_task_runner| indicates the blocking worker pool for cache
     52   // operations. All operations on this FileCache must be run on this runner.
     53   // Must not be null.
     54   //
     55   // |free_disk_space_getter| is used to inject a custom free disk space
     56   // getter for testing. NULL must be passed for production code.
     57   //
     58   // Must be called on the UI thread.
     59   FileCache(ResourceMetadataStorage* storage,
     60             const base::FilePath& cache_file_directory,
     61             base::SequencedTaskRunner* blocking_task_runner,
     62             FreeDiskSpaceGetterInterface* free_disk_space_getter);
     63 
     64   // Returns true if the given path is under drive cache directory, i.e.
     65   // <user_profile_dir>/GCache/v1
     66   //
     67   // Can be called on any thread.
     68   bool IsUnderFileCacheDirectory(const base::FilePath& path) const;
     69 
     70   // Gets the cache entry for file corresponding to |id| and returns true if
     71   // entry exists in cache map.
     72   bool GetCacheEntry(const std::string& id, FileCacheEntry* entry);
     73 
     74   // Returns an object to iterate over entries.
     75   scoped_ptr<Iterator> GetIterator();
     76 
     77   // Frees up disk space to store a file with |num_bytes| size content, while
     78   // keeping cryptohome::kMinFreeSpaceInBytes bytes on the disk, if needed.
     79   // Returns true if we successfully manage to have enough space, otherwise
     80   // false.
     81   bool FreeDiskSpaceIfNeededFor(int64 num_bytes);
     82 
     83   // Checks if file corresponding to |id| exists in cache, and returns
     84   // FILE_ERROR_OK with |cache_file_path| storing the path to the file.
     85   // |cache_file_path| must not be null.
     86   FileError GetFile(const std::string& id, base::FilePath* cache_file_path);
     87 
     88   // Stores |source_path| as a cache of the remote content of the file
     89   // with |id| and |md5|.
     90   FileError Store(const std::string& id,
     91                   const std::string& md5,
     92                   const base::FilePath& source_path,
     93                   FileOperationType file_operation_type);
     94 
     95   // Pins the specified entry.
     96   FileError Pin(const std::string& id);
     97 
     98   // Unpins the specified entry.
     99   FileError Unpin(const std::string& id);
    100 
    101   // Sets the state of the cache entry corresponding to |id| as mounted.
    102   FileError MarkAsMounted(const std::string& id,
    103                           base::FilePath* cache_file_path);
    104 
    105   // Sets the state of the cache entry corresponding to file_path as unmounted.
    106   FileError MarkAsUnmounted(const base::FilePath& file_path);
    107 
    108   // Marks the specified entry dirty.
    109   FileError MarkDirty(const std::string& id);
    110 
    111   // Clears dirty state of the specified entry and updates its MD5.
    112   FileError ClearDirty(const std::string& id, const std::string& md5);
    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 and cache entries in DB.
    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   friend class FileCacheTestOnUIThread;
    140 
    141   ~FileCache();
    142 
    143   // Returns absolute path of the file if it were cached or to be cached.
    144   //
    145   // Can be called on any thread.
    146   base::FilePath GetCacheFilePath(const std::string& id) const;
    147 
    148   // Checks whether the current thread is on the right sequenced worker pool
    149   // with the right sequence ID. If not, DCHECK will fail.
    150   void AssertOnSequencedWorkerPool();
    151 
    152   // Destroys the cache on the blocking pool.
    153   void DestroyOnBlockingPool();
    154 
    155   // Returns true if we have sufficient space to store the given number of
    156   // bytes, while keeping cryptohome::kMinFreeSpaceInBytes bytes on the disk.
    157   bool HasEnoughSpaceFor(int64 num_bytes, const base::FilePath& path);
    158 
    159   // Renames cache files from old "prefix:id.md5" format to the new format.
    160   // TODO(hashimoto): Remove this method at some point.
    161   bool RenameCacheFilesToNewFormat();
    162 
    163   const base::FilePath cache_file_directory_;
    164 
    165   scoped_refptr<base::SequencedTaskRunner> blocking_task_runner_;
    166 
    167   ResourceMetadataStorage* storage_;
    168 
    169   FreeDiskSpaceGetterInterface* free_disk_space_getter_;  // Not owned.
    170 
    171   // IDs of files marked mounted.
    172   std::set<std::string> mounted_files_;
    173 
    174   // Note: This should remain the last member so it'll be destroyed and
    175   // invalidate its weak pointers before any other members are destroyed.
    176   base::WeakPtrFactory<FileCache> weak_ptr_factory_;
    177   DISALLOW_COPY_AND_ASSIGN(FileCache);
    178 };
    179 
    180 }  // namespace internal
    181 }  // namespace drive
    182 
    183 #endif  // CHROME_BROWSER_CHROMEOS_DRIVE_FILE_CACHE_H_
    184