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_RESOURCE_METADATA_H_
      6 #define CHROME_BROWSER_CHROMEOS_DRIVE_RESOURCE_METADATA_H_
      7 
      8 #include <map>
      9 #include <set>
     10 #include <string>
     11 #include <vector>
     12 
     13 #include "base/callback_forward.h"
     14 #include "base/files/file_path.h"
     15 #include "base/memory/scoped_ptr.h"
     16 #include "base/memory/weak_ptr.h"
     17 #include "base/time/time.h"
     18 #include "chrome/browser/chromeos/drive/file_errors.h"
     19 #include "chrome/browser/chromeos/drive/resource_metadata_storage.h"
     20 
     21 namespace base {
     22 class SequencedTaskRunner;
     23 }
     24 
     25 namespace drive {
     26 
     27 class ResourceEntry;
     28 
     29 typedef std::vector<ResourceEntry> ResourceEntryVector;
     30 typedef std::map<std::string /* resource_id */, ResourceEntry>
     31     ResourceEntryMap;
     32 
     33 // Holds information needed to fetch contents of a directory.
     34 // This object is copyable.
     35 class DirectoryFetchInfo {
     36  public:
     37   DirectoryFetchInfo() : changestamp_(0) {}
     38   DirectoryFetchInfo(const std::string& resource_id,
     39                      int64 changestamp)
     40       : resource_id_(resource_id),
     41         changestamp_(changestamp) {
     42   }
     43 
     44   // Returns true if the object is empty.
     45   bool empty() const { return resource_id_.empty(); }
     46 
     47   // Resource ID of the directory.
     48   const std::string& resource_id() const { return resource_id_; }
     49 
     50   // Changestamp of the directory. The changestamp is used to determine if
     51   // the directory contents should be fetched.
     52   int64 changestamp() const { return changestamp_; }
     53 
     54   // Returns a string representation of this object.
     55   std::string ToString() const;
     56 
     57  private:
     58   const std::string resource_id_;
     59   const int64 changestamp_;
     60 };
     61 
     62 // Callback similar to FileOperationCallback but with a given |file_path|.
     63 // Used for operations that change a file path like moving files.
     64 typedef base::Callback<void(FileError error,
     65                             const base::FilePath& file_path)>
     66     FileMoveCallback;
     67 
     68 // Used to get a resource entry from the file system.
     69 // If |error| is not FILE_ERROR_OK, |entry_info| is set to NULL.
     70 typedef base::Callback<void(FileError error,
     71                             scoped_ptr<ResourceEntry> entry)>
     72     GetResourceEntryCallback;
     73 
     74 typedef base::Callback<void(FileError error,
     75                             scoped_ptr<ResourceEntryVector> entries)>
     76     ReadDirectoryCallback;
     77 
     78 typedef base::Callback<void(int64)> GetChangestampCallback;
     79 
     80 // This is a part of EntryInfoPairResult.
     81 struct EntryInfoResult {
     82   EntryInfoResult();
     83   ~EntryInfoResult();
     84 
     85   base::FilePath path;
     86   FileError error;
     87   scoped_ptr<ResourceEntry> entry;
     88 };
     89 
     90 // The result of GetResourceEntryPairCallback(). Used to get a pair of entries
     91 // in one function call.
     92 struct EntryInfoPairResult {
     93   EntryInfoPairResult();
     94   ~EntryInfoPairResult();
     95 
     96   EntryInfoResult first;
     97   EntryInfoResult second;  // Only filled if the first entry is found.
     98 };
     99 
    100 // Used to receive the result from GetResourceEntryPairCallback().
    101 typedef base::Callback<void(scoped_ptr<EntryInfoPairResult> pair_result)>
    102     GetResourceEntryPairCallback;
    103 
    104 typedef base::Callback<void(const ResourceEntry& entry)> IterateCallback;
    105 
    106 namespace internal {
    107 
    108 // Storage for Drive Metadata.
    109 // All methods must be run with |blocking_task_runner| unless otherwise noted.
    110 class ResourceMetadata {
    111  public:
    112   typedef ResourceMetadataStorage::Iterator Iterator;
    113 
    114   ResourceMetadata(
    115       ResourceMetadataStorage* storage,
    116       scoped_refptr<base::SequencedTaskRunner> blocking_task_runner);
    117 
    118   // Initializes this object.
    119   // This method should be called before any other methods.
    120   FileError Initialize() WARN_UNUSED_RESULT;
    121 
    122   // Destroys this object.  This method posts a task to |blocking_task_runner_|
    123   // to safely delete this object.
    124   // Must be called on the UI thread.
    125   void Destroy();
    126 
    127   // Resets this object.
    128   // Must be called on the UI thread.
    129   void ResetOnUIThread(const FileOperationCallback& callback);
    130 
    131   // Synchronous version of ResetOnUIThread.
    132   FileError Reset();
    133 
    134   // Largest change timestamp that was the source of content for the current
    135   // state of the root directory.
    136   // Must be called on the UI thread.
    137   void GetLargestChangestampOnUIThread(const GetChangestampCallback& callback);
    138   void SetLargestChangestampOnUIThread(int64 value,
    139                                        const FileOperationCallback& callback);
    140 
    141   // Synchronous version of GetLargestChangestampOnUIThread.
    142   int64 GetLargestChangestamp();
    143 
    144   // Synchronous version of SetLargestChangestampOnUIThread.
    145   FileError SetLargestChangestamp(int64 value);
    146 
    147   // Runs AddEntry() on blocking pool. Upon completion, the |callback| will be
    148   // called with the new file path.
    149   // |callback| must not be null.
    150   // Must be called on the UI thread.
    151   void AddEntryOnUIThread(const ResourceEntry& entry,
    152                           const FileMoveCallback& callback);
    153 
    154   // Adds |entry| to the metadata tree based on its parent_resource_id
    155   // synchronously.
    156   FileError AddEntry(const ResourceEntry& entry);
    157 
    158   // Moves entry specified by |file_path| to the directory specified by
    159   // |directory_path| and calls the callback asynchronously. Removes the entry
    160   // from the previous parent. |callback| must not be null.
    161   // Must be called on the UI thread.
    162   void MoveEntryToDirectoryOnUIThread(const base::FilePath& file_path,
    163                                       const base::FilePath& directory_path,
    164                                       const FileMoveCallback& callback);
    165 
    166   // Renames entry specified by |file_path| with the new name |new_name| and
    167   // calls |callback| asynchronously. |callback| must not be null.
    168   // Must be called on the UI thread.
    169   void RenameEntryOnUIThread(const base::FilePath& file_path,
    170                              const std::string& new_name,
    171                              const FileMoveCallback& callback);
    172 
    173   // Removes entry with |resource_id| from its parent.
    174   FileError RemoveEntry(const std::string& resource_id);
    175 
    176   // Finds an entry (a file or a directory) by |resource_id|.
    177   // |callback| must not be null.
    178   // Must be called on the UI thread.
    179   void GetResourceEntryByIdOnUIThread(const std::string& resource_id,
    180                                       const GetResourceEntryCallback& callback);
    181 
    182   // Synchronous version of GetResourceEntryByIdOnUIThread().
    183   FileError GetResourceEntryById(const std::string& resource_id,
    184                                  ResourceEntry* out_entry);
    185 
    186   // Finds an entry (a file or a directory) by |file_path|.
    187   // |callback| must not be null.
    188   // Must be called on the UI thread.
    189   void GetResourceEntryByPathOnUIThread(
    190       const base::FilePath& file_path,
    191       const GetResourceEntryCallback& callback);
    192 
    193   // Synchronous version of GetResourceEntryByPathOnUIThread().
    194   FileError GetResourceEntryByPath(const base::FilePath& file_path,
    195                                    ResourceEntry* out_entry);
    196 
    197   // Finds and reads a directory by |file_path|.
    198   // |callback| must not be null.
    199   // Must be called on the UI thread.
    200   void ReadDirectoryByPathOnUIThread(const base::FilePath& file_path,
    201                                      const ReadDirectoryCallback& callback);
    202 
    203   // Synchronous version of ReadDirectoryByPathOnUIThread().
    204   FileError ReadDirectoryByPath(const base::FilePath& file_path,
    205                                 ResourceEntryVector* out_entries);
    206 
    207   // Similar to GetResourceEntryByPath() but this function finds a pair of
    208   // entries by |first_path| and |second_path|. If the entry for
    209   // |first_path| is not found, this function does not try to get the
    210   // entry of |second_path|. |callback| must not be null.
    211   // Must be called on the UI thread.
    212   void GetResourceEntryPairByPathsOnUIThread(
    213       const base::FilePath& first_path,
    214       const base::FilePath& second_path,
    215       const GetResourceEntryPairCallback& callback);
    216 
    217   // Replaces an existing entry whose ID is |entry.resource_id()| with |entry|.
    218   FileError RefreshEntry(const ResourceEntry& entry);
    219 
    220   // Removes all child files of the directory pointed by
    221   // |directory_fetch_info| and replaces them with
    222   // |entry_map|. The changestamp of the directory will be updated per
    223   // |directory_fetch_info|. |callback| is called with the directory path.
    224   // |callback| must not be null.
    225   // Must be called on the UI thread.
    226   void RefreshDirectoryOnUIThread(
    227       const DirectoryFetchInfo& directory_fetch_info,
    228       const ResourceEntryMap& entry_map,
    229       const FileMoveCallback& callback);
    230 
    231   // Recursively get child directories of entry pointed to by |resource_id|.
    232   void GetChildDirectories(const std::string& resource_id,
    233                            std::set<base::FilePath>* child_directories);
    234 
    235   // Returns the resource id of the resource named |base_name| directly under
    236   // the directory with |parent_resource_id|.
    237   // If not found, empty string will be returned.
    238   std::string GetChildResourceId(
    239       const std::string& parent_resource_id, const std::string& base_name);
    240 
    241   // Returns an object to iterate over entries.
    242   scoped_ptr<Iterator> GetIterator();
    243 
    244   // Returns virtual file path of the entry.
    245   base::FilePath GetFilePath(const std::string& resource_id);
    246 
    247  private:
    248   // Note: Use Destroy() to delete this object.
    249   ~ResourceMetadata();
    250 
    251   // Sets up entries which should be present by default.
    252   bool SetUpDefaultEntries();
    253 
    254   // Used to implement Destroy().
    255   void DestroyOnBlockingPool();
    256 
    257   // Used to implement MoveEntryToDirectoryOnUIThread().
    258   FileError MoveEntryToDirectory(const base::FilePath& file_path,
    259                                  const base::FilePath& directory_path,
    260                                  base::FilePath* out_file_path);
    261 
    262   // Used to implement RenameEntryOnUIThread().
    263   FileError RenameEntry(const base::FilePath& file_path,
    264                         const std::string& new_name,
    265                         base::FilePath* out_file_path);
    266 
    267   // Used to implement RefreshDirectoryOnUIThread().
    268   FileError RefreshDirectory(const DirectoryFetchInfo& directory_fetch_info,
    269                              const ResourceEntryMap& entry_map,
    270                              base::FilePath* out_file_path);
    271 
    272   // Continues with GetResourceEntryPairByPathsOnUIThread after the first
    273   // entry has been asynchronously fetched. This fetches the second entry
    274   // only if the first was found.
    275   void GetResourceEntryPairByPathsOnUIThreadAfterGetFirst(
    276       const base::FilePath& first_path,
    277       const base::FilePath& second_path,
    278       const GetResourceEntryPairCallback& callback,
    279       FileError error,
    280       scoped_ptr<ResourceEntry> entry);
    281 
    282   // Continues with GetResourceEntryPairByPathsOnUIThread after the second
    283   // entry has been asynchronously fetched.
    284   void GetResourceEntryPairByPathsOnUIThreadAfterGetSecond(
    285       const base::FilePath& second_path,
    286       const GetResourceEntryPairCallback& callback,
    287       scoped_ptr<EntryInfoPairResult> result,
    288       FileError error,
    289       scoped_ptr<ResourceEntry> entry);
    290 
    291   // Searches for |file_path| synchronously.
    292   bool FindEntryByPathSync(const base::FilePath& file_path,
    293                            ResourceEntry* out_entry);
    294 
    295   // Puts an entry under its parent directory. Removes the child from the old
    296   // parent if there is. This method will also do name de-duplication to ensure
    297   // that the exposed presentation path does not have naming conflicts. Two
    298   // files with the same name "Foo" will be renames to "Foo (1)" and "Foo (2)".
    299   bool PutEntryUnderDirectory(const ResourceEntry& entry);
    300 
    301   // Removes the entry and its descendants.
    302   bool RemoveEntryRecursively(const std::string& resource_id);
    303 
    304   scoped_refptr<base::SequencedTaskRunner> blocking_task_runner_;
    305 
    306   ResourceMetadataStorage* storage_;
    307 
    308   // This should remain the last member so it'll be destroyed first and
    309   // invalidate its weak pointers before other members are destroyed.
    310   base::WeakPtrFactory<ResourceMetadata> weak_ptr_factory_;
    311 
    312   DISALLOW_COPY_AND_ASSIGN(ResourceMetadata);
    313 };
    314 
    315 }  // namespace internal
    316 }  // namespace drive
    317 
    318 #endif  // CHROME_BROWSER_CHROMEOS_DRIVE_RESOURCE_METADATA_H_
    319