local_file_change_tracker.h revision d0247b1b59f9c528cb6df88b4f2b9afaf80d181e
190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 52385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#ifndef CHROME_BROWSER_SYNC_FILE_SYSTEM_LOCAL_LOCAL_FILE_CHANGE_TRACKER_H_ 62385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#define CHROME_BROWSER_SYNC_FILE_SYSTEM_LOCAL_LOCAL_FILE_CHANGE_TRACKER_H_ 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <deque> 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <map> 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string> 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/compiler_specific.h" 142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/file_path.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/ref_counted.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/synchronization/lock.h" 182385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#include "chrome/browser/sync_file_system/file_change.h" 192385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#include "chrome/browser/sync_file_system/sync_status_code.h" 2090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "webkit/browser/fileapi/file_observers.h" 2190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "webkit/browser/fileapi/file_system_url.h" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace base { 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class SequencedTaskRunner; 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace fileapi { 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class FileSystemContext; 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class FileSystemURL; 302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace sync_file_system { 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tracks local file changes for cloud-backed file systems. 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// All methods must be called on the file_task_runner given to the constructor. 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Owned by FileSystemContext. 372385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochclass LocalFileChangeTracker 382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : public fileapi::FileUpdateObserver, 392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public fileapi::FileChangeObserver { 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |file_task_runner| must be the one where the observee file operations run. 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // (So that we can make sure DB operations are done before actual update 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // happens) 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LocalFileChangeTracker(const base::FilePath& base_path, 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::SequencedTaskRunner* file_task_runner); 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~LocalFileChangeTracker(); 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // FileUpdateObserver overrides. 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void OnStartUpdate(const fileapi::FileSystemURL& url) OVERRIDE; 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void OnUpdate( 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const fileapi::FileSystemURL& url, int64 delta) OVERRIDE {} 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void OnEndUpdate(const fileapi::FileSystemURL& url) OVERRIDE; 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // FileChangeObserver overrides. 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void OnCreateFile(const fileapi::FileSystemURL& url) OVERRIDE; 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void OnCreateFileFrom(const fileapi::FileSystemURL& url, 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const fileapi::FileSystemURL& src) OVERRIDE; 582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void OnRemoveFile(const fileapi::FileSystemURL& url) OVERRIDE; 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void OnModifyFile(const fileapi::FileSystemURL& url) OVERRIDE; 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void OnCreateDirectory(const fileapi::FileSystemURL& url) OVERRIDE; 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void OnRemoveDirectory(const fileapi::FileSystemURL& url) OVERRIDE; 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Retrieves an array of |url| which have more than one pending changes. 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If |max_urls| is non-zero (recommended in production code) this 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // returns URLs up to the number from the ones that have smallest 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // change_seq numbers (i.e. older changes). 672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void GetNextChangedURLs(std::deque<fileapi::FileSystemURL>* urls, 682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int max_urls); 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns all changes recorded for the given |url|. 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This should be called after writing is disabled. 722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void GetChangesForURL(const fileapi::FileSystemURL& url, 732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FileChangeList* changes); 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Clears the pending changes recorded in this tracker for |url|. 762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void ClearChangesForURL(const fileapi::FileSystemURL& url); 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 78d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // Creates a fresh (empty) in-memory record for |url|. 79d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // Note that new changes are recorded to the mirror too. 80d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) void CreateFreshMirrorForURL(const fileapi::FileSystemURL& url); 81d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 82d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // Removes a mirror for |url|, and commits the change status to database. 83d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) void RemoveMirrorAndCommitChangesForURL(const fileapi::FileSystemURL& url); 84d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 85d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // Resets the changes to the ones recorded in mirror for |url|, and 86d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // commits the updated change status to database. 87d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) void ResetToMirrorAndCommitChangesForURL(const fileapi::FileSystemURL& url); 88d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Called by FileSyncService at the startup time to restore last dirty changes 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // left after the last shutdown (if any). 912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SyncStatusCode Initialize(fileapi::FileSystemContext* file_system_context); 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This method is (exceptionally) thread-safe. 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 num_changes() const { 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::AutoLock lock(num_changes_lock_); 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return num_changes_; 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void UpdateNumChanges(); 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) class TrackerDB; 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) friend class CannedSyncableFileSystem; 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) friend class LocalFileChangeTrackerTest; 1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) friend class LocalFileSyncContext; 106d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) friend class LocalFileSyncContextTest; 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) friend class SyncableFileSystemTest; 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct ChangeInfo { 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ChangeInfo(); 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ~ChangeInfo(); 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FileChangeList change_list; 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 change_seq; 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) typedef std::map<fileapi::FileSystemURL, ChangeInfo, 1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) fileapi::FileSystemURL::Comparator> 1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FileChangeMap; 1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) typedef std::map<int64, fileapi::FileSystemURL> ChangeSeqMap; 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This does mostly same as calling GetNextChangedURLs with max_url=0 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // except that it returns urls in set rather than in deque. 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Used only in testings. 1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void GetAllChangedURLs(fileapi::FileSystemURLSet* urls); 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Used only in testings. 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void DropAllChanges(); 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Database related methods. 1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SyncStatusCode MarkDirtyOnDatabase(const fileapi::FileSystemURL& url); 1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SyncStatusCode ClearDirtyOnDatabase(const fileapi::FileSystemURL& url); 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SyncStatusCode CollectLastDirtyChanges( 1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) fileapi::FileSystemContext* file_system_context); 1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void RecordChange(const fileapi::FileSystemURL& url, 1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const FileChange& change); 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 138d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) static void RecordChangeToChangeMaps(const fileapi::FileSystemURL& url, 139d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) const FileChange& change, 140d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) int change_seq, 141d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) FileChangeMap* changes, 142d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) ChangeSeqMap* change_seqs); 143d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool initialized_; 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<base::SequencedTaskRunner> file_task_runner_; 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FileChangeMap changes_; 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ChangeSeqMap change_seqs_; 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 151d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // For mirrors. 152d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) FileChangeMap mirror_changes_; 153d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<TrackerDB> tracker_db_; 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Change sequence number. Briefly gives a hint about the order of changes, 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // but they are updated when a new change comes on the same file (as 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // well as Drive's changestamps). 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 current_change_seq_; 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This can be accessed on any threads (with num_changes_lock_). 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 num_changes_; 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mutable base::Lock num_changes_lock_; 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(LocalFileChangeTracker); 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace sync_file_system 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1702385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#endif // CHROME_BROWSER_SYNC_FILE_SYSTEM_LOCAL_LOCAL_FILE_CHANGE_TRACKER_H_ 171