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) 89d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) // Re-insert changes for the file with newer (bigger) sequence numbers, 90d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) // so that they won't be fetched by GetChangesForURL() soon. This could be 91d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) // useful for changes that have been failed to apply but would need to be 92d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) // retried again later. 93d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) void DemoteChangesForURL(const fileapi::FileSystemURL& url); 94d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Called by FileSyncService at the startup time to restore last dirty changes 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // left after the last shutdown (if any). 972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SyncStatusCode Initialize(fileapi::FileSystemContext* file_system_context); 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 99a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Resets all the changes recorded for the given |origin| and |type|. 100a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // TODO(kinuko,nhiroki): Ideally this should be automatically called in 101a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // DeleteFileSystem via QuotaUtil::DeleteOriginDataOnFileThread. 102a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) void ResetForFileSystem(const GURL& origin, fileapi::FileSystemType type); 103a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This method is (exceptionally) thread-safe. 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 num_changes() const { 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::AutoLock lock(num_changes_lock_); 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return num_changes_; 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) class TrackerDB; 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) friend class CannedSyncableFileSystem; 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) friend class LocalFileChangeTrackerTest; 1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) friend class LocalFileSyncContext; 115d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) friend class LocalFileSyncContextTest; 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) friend class SyncableFileSystemTest; 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct ChangeInfo { 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ChangeInfo(); 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ~ChangeInfo(); 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FileChangeList change_list; 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 change_seq; 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) typedef std::map<fileapi::FileSystemURL, ChangeInfo, 1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) fileapi::FileSystemURL::Comparator> 1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FileChangeMap; 1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) typedef std::map<int64, fileapi::FileSystemURL> ChangeSeqMap; 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 130a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) void UpdateNumChanges(); 131a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This does mostly same as calling GetNextChangedURLs with max_url=0 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // except that it returns urls in set rather than in deque. 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Used only in testings. 1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void GetAllChangedURLs(fileapi::FileSystemURLSet* urls); 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Used only in testings. 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void DropAllChanges(); 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Database related methods. 1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SyncStatusCode MarkDirtyOnDatabase(const fileapi::FileSystemURL& url); 1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SyncStatusCode ClearDirtyOnDatabase(const fileapi::FileSystemURL& url); 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SyncStatusCode CollectLastDirtyChanges( 1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) fileapi::FileSystemContext* file_system_context); 1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void RecordChange(const fileapi::FileSystemURL& url, 1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const FileChange& change); 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 149d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) static void RecordChangeToChangeMaps(const fileapi::FileSystemURL& url, 150d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) const FileChange& change, 151d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) int change_seq, 152d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) FileChangeMap* changes, 153d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) ChangeSeqMap* change_seqs); 154d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool initialized_; 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<base::SequencedTaskRunner> file_task_runner_; 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FileChangeMap changes_; 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ChangeSeqMap change_seqs_; 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 162d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // For mirrors. 163d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) FileChangeMap mirror_changes_; 164d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<TrackerDB> tracker_db_; 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Change sequence number. Briefly gives a hint about the order of changes, 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // but they are updated when a new change comes on the same file (as 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // well as Drive's changestamps). 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 current_change_seq_; 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This can be accessed on any threads (with num_changes_lock_). 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 num_changes_; 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mutable base::Lock num_changes_lock_; 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(LocalFileChangeTracker); 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace sync_file_system 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1812385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#endif // CHROME_BROWSER_SYNC_FILE_SYSTEM_LOCAL_LOCAL_FILE_CHANGE_TRACKER_H_ 182