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