Home | History | Annotate | Download | only in local
      1 // Copyright 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 #ifndef CHROME_BROWSER_SYNC_FILE_SYSTEM_LOCAL_LOCAL_FILE_CHANGE_TRACKER_H_
      6 #define CHROME_BROWSER_SYNC_FILE_SYSTEM_LOCAL_LOCAL_FILE_CHANGE_TRACKER_H_
      7 
      8 #include <deque>
      9 #include <map>
     10 #include <string>
     11 
     12 #include "base/basictypes.h"
     13 #include "base/compiler_specific.h"
     14 #include "base/files/file_path.h"
     15 #include "base/memory/ref_counted.h"
     16 #include "base/memory/scoped_ptr.h"
     17 #include "base/synchronization/lock.h"
     18 #include "chrome/browser/sync_file_system/file_change.h"
     19 #include "chrome/browser/sync_file_system/sync_status_code.h"
     20 #include "webkit/browser/fileapi/file_observers.h"
     21 #include "webkit/browser/fileapi/file_system_url.h"
     22 
     23 namespace base {
     24 class SequencedTaskRunner;
     25 }
     26 
     27 namespace fileapi {
     28 class FileSystemContext;
     29 class FileSystemURL;
     30 }
     31 
     32 namespace sync_file_system {
     33 
     34 // Tracks local file changes for cloud-backed file systems.
     35 // All methods must be called on the file_task_runner given to the constructor.
     36 // Owned by FileSystemContext.
     37 class LocalFileChangeTracker
     38     : public fileapi::FileUpdateObserver,
     39       public fileapi::FileChangeObserver {
     40  public:
     41   // |file_task_runner| must be the one where the observee file operations run.
     42   // (So that we can make sure DB operations are done before actual update
     43   // happens)
     44   LocalFileChangeTracker(const base::FilePath& base_path,
     45                          base::SequencedTaskRunner* file_task_runner);
     46   virtual ~LocalFileChangeTracker();
     47 
     48   // FileUpdateObserver overrides.
     49   virtual void OnStartUpdate(const fileapi::FileSystemURL& url) OVERRIDE;
     50   virtual void OnUpdate(
     51       const fileapi::FileSystemURL& url, int64 delta) OVERRIDE {}
     52   virtual void OnEndUpdate(const fileapi::FileSystemURL& url) OVERRIDE;
     53 
     54   // FileChangeObserver overrides.
     55   virtual void OnCreateFile(const fileapi::FileSystemURL& url) OVERRIDE;
     56   virtual void OnCreateFileFrom(const fileapi::FileSystemURL& url,
     57                                 const fileapi::FileSystemURL& src) OVERRIDE;
     58   virtual void OnRemoveFile(const fileapi::FileSystemURL& url) OVERRIDE;
     59   virtual void OnModifyFile(const fileapi::FileSystemURL& url) OVERRIDE;
     60   virtual void OnCreateDirectory(const fileapi::FileSystemURL& url) OVERRIDE;
     61   virtual void OnRemoveDirectory(const fileapi::FileSystemURL& url) OVERRIDE;
     62 
     63   // Retrieves an array of |url| which have more than one pending changes.
     64   // If |max_urls| is non-zero (recommended in production code) this
     65   // returns URLs up to the number from the ones that have smallest
     66   // change_seq numbers (i.e. older changes).
     67   void GetNextChangedURLs(std::deque<fileapi::FileSystemURL>* urls,
     68                           int max_urls);
     69 
     70   // Returns all changes recorded for the given |url|.
     71   // This should be called after writing is disabled.
     72   void GetChangesForURL(const fileapi::FileSystemURL& url,
     73                         FileChangeList* changes);
     74 
     75   // Clears the pending changes recorded in this tracker for |url|.
     76   void ClearChangesForURL(const fileapi::FileSystemURL& url);
     77 
     78   // Called by FileSyncService at the startup time to restore last dirty changes
     79   // left after the last shutdown (if any).
     80   SyncStatusCode Initialize(fileapi::FileSystemContext* file_system_context);
     81 
     82   // This method is (exceptionally) thread-safe.
     83   int64 num_changes() const {
     84     base::AutoLock lock(num_changes_lock_);
     85     return num_changes_;
     86   }
     87 
     88   void UpdateNumChanges();
     89 
     90  private:
     91   class TrackerDB;
     92   friend class CannedSyncableFileSystem;
     93   friend class LocalFileChangeTrackerTest;
     94   friend class LocalFileSyncContext;
     95   friend class SyncableFileSystemTest;
     96 
     97   struct ChangeInfo {
     98     ChangeInfo();
     99     ~ChangeInfo();
    100     FileChangeList change_list;
    101     int64 change_seq;
    102   };
    103 
    104   typedef std::map<fileapi::FileSystemURL, ChangeInfo,
    105       fileapi::FileSystemURL::Comparator>
    106           FileChangeMap;
    107   typedef std::map<int64, fileapi::FileSystemURL> ChangeSeqMap;
    108 
    109   // This does mostly same as calling GetNextChangedURLs with max_url=0
    110   // except that it returns urls in set rather than in deque.
    111   // Used only in testings.
    112   void GetAllChangedURLs(fileapi::FileSystemURLSet* urls);
    113 
    114   // Used only in testings.
    115   void DropAllChanges();
    116 
    117   // Database related methods.
    118   SyncStatusCode MarkDirtyOnDatabase(const fileapi::FileSystemURL& url);
    119   SyncStatusCode ClearDirtyOnDatabase(const fileapi::FileSystemURL& url);
    120 
    121   SyncStatusCode CollectLastDirtyChanges(
    122       fileapi::FileSystemContext* file_system_context);
    123   void RecordChange(const fileapi::FileSystemURL& url,
    124                     const FileChange& change);
    125 
    126   bool initialized_;
    127 
    128   scoped_refptr<base::SequencedTaskRunner> file_task_runner_;
    129 
    130   FileChangeMap changes_;
    131   ChangeSeqMap change_seqs_;
    132 
    133   scoped_ptr<TrackerDB> tracker_db_;
    134 
    135   // Change sequence number. Briefly gives a hint about the order of changes,
    136   // but they are updated when a new change comes on the same file (as
    137   // well as Drive's changestamps).
    138   int64 current_change_seq_;
    139 
    140   // This can be accessed on any threads (with num_changes_lock_).
    141   int64 num_changes_;
    142   mutable base::Lock num_changes_lock_;
    143 
    144   DISALLOW_COPY_AND_ASSIGN(LocalFileChangeTracker);
    145 };
    146 
    147 }  // namespace sync_file_system
    148 
    149 #endif  // CHROME_BROWSER_SYNC_FILE_SYSTEM_LOCAL_LOCAL_FILE_CHANGE_TRACKER_H_
    150