local_file_change_tracker.h revision 2385ea399aae016c0806a4f9ef3c9cfe3d2a39df
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
23namespace base {
24class SequencedTaskRunner;
25}
26
27namespace fileapi {
28class FileSystemContext;
29class FileSystemURL;
30}
31
32namespace 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.
37class 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