local_file_sync_service.h revision d0247b1b59f9c528cb6df88b4f2b9afaf80d181e
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_SYNC_SERVICE_H_
6#define CHROME_BROWSER_SYNC_FILE_SYSTEM_LOCAL_LOCAL_FILE_SYNC_SERVICE_H_
7
8#include <map>
9#include <set>
10#include <string>
11
12#include "base/basictypes.h"
13#include "base/callback.h"
14#include "base/memory/ref_counted.h"
15#include "base/memory/weak_ptr.h"
16#include "base/observer_list.h"
17#include "chrome/browser/sync_file_system/local/local_origin_change_observer.h"
18#include "chrome/browser/sync_file_system/remote_change_processor.h"
19#include "chrome/browser/sync_file_system/sync_callbacks.h"
20#include "chrome/browser/sync_file_system/sync_status_code.h"
21
22class GURL;
23class Profile;
24
25namespace fileapi {
26class FileSystemContext;
27}
28
29namespace webkit_blob {
30class ScopedFile;
31}
32
33namespace sync_file_system {
34
35class FileChange;
36class LocalChangeProcessor;
37class LocalFileSyncContext;
38struct LocalFileSyncInfo;
39
40// Maintains local file change tracker and sync status.
41// Owned by SyncFileSystemService (which is a per-profile object).
42class LocalFileSyncService
43    : public RemoteChangeProcessor,
44      public LocalOriginChangeObserver,
45      public base::SupportsWeakPtr<LocalFileSyncService> {
46 public:
47  class Observer {
48   public:
49    Observer() {}
50    virtual ~Observer() {}
51
52    // This is called when there're one or more local changes available.
53    // |pending_changes_hint| indicates the pending queue length to help sync
54    // scheduling but the value may not be accurately reflect the real-time
55    // value.
56    virtual void OnLocalChangeAvailable(int64 pending_changes_hint) = 0;
57
58   private:
59    DISALLOW_COPY_AND_ASSIGN(Observer);
60  };
61
62  typedef base::Callback<void(SyncStatusCode status,
63                              bool has_pending_changes)>
64      HasPendingLocalChangeCallback;
65
66  explicit LocalFileSyncService(Profile* profile);
67  virtual ~LocalFileSyncService();
68
69  void Shutdown();
70
71  void MaybeInitializeFileSystemContext(
72      const GURL& app_origin,
73      fileapi::FileSystemContext* file_system_context,
74      const SyncStatusCallback& callback);
75
76  void AddChangeObserver(Observer* observer);
77
78  // Registers |url| to wait until sync is enabled for |url|.
79  // |on_syncable_callback| is to be called when |url| becomes syncable
80  // (i.e. when we have no pending writes and the file is successfully locked
81  // for sync).
82  // Calling this method again while this already has another URL waiting
83  // for sync will overwrite the previously registered URL.
84  void RegisterURLForWaitingSync(const fileapi::FileSystemURL& url,
85                                 const base::Closure& on_syncable_callback);
86
87  // Synchronize one (or a set of) local change(s) to the remote server
88  // using local_change_processor given by SetLocalChangeProcessor().
89  // |processor| must have same or longer lifetime than this service.
90  // It is invalid to call this method before calling SetLocalChangeProcessor().
91  void ProcessLocalChange(const SyncFileCallback& callback);
92
93  // Sets a local change processor.  This must be called before any
94  // ProcessLocalChange().
95  void SetLocalChangeProcessor(LocalChangeProcessor* processor);
96
97  // Returns true via |callback| if the given file |url| has local pending
98  // changes.
99  void HasPendingLocalChanges(
100      const fileapi::FileSystemURL& url,
101      const HasPendingLocalChangeCallback& callback);
102
103  // A local or remote sync has been finished (either successfully or
104  // with an error). Clears the internal sync flag and enable writing for |url|.
105  void ClearSyncFlagForURL(const fileapi::FileSystemURL& url);
106
107  // Returns the metadata of a remote file pointed by |url|.
108  virtual void GetLocalFileMetadata(
109      const fileapi::FileSystemURL& url,
110      const SyncFileMetadataCallback& callback);
111
112  // RemoteChangeProcessor overrides.
113  virtual void PrepareForProcessRemoteChange(
114      const fileapi::FileSystemURL& url,
115      const PrepareChangeCallback& callback) OVERRIDE;
116  virtual void ApplyRemoteChange(
117      const FileChange& change,
118      const base::FilePath& local_path,
119      const fileapi::FileSystemURL& url,
120      const SyncStatusCallback& callback) OVERRIDE;
121  virtual void ClearLocalChanges(
122      const fileapi::FileSystemURL& url,
123      const base::Closure& completion_callback) OVERRIDE;
124  virtual void RecordFakeLocalChange(
125      const fileapi::FileSystemURL& url,
126      const FileChange& change,
127      const SyncStatusCallback& callback) OVERRIDE;
128
129  // LocalOriginChangeObserver override.
130  virtual void OnChangesAvailableInOrigins(
131      const std::set<GURL>& origins) OVERRIDE;
132
133  // Called when a particular origin (app) is disabled/enabled while
134  // the service is running. This may be called for origins/apps that
135  // are not initialized for the service.
136  void SetOriginEnabled(const GURL& origin, bool enabled);
137
138 private:
139  friend class OriginChangeMapTest;
140
141  class OriginChangeMap {
142   public:
143    typedef std::map<GURL, int64> Map;
144
145    OriginChangeMap();
146    ~OriginChangeMap();
147
148    // Sets |origin| to the next origin to process. (For now we simply apply
149    // round-robin to pick the next origin to avoid starvation.)
150    // Returns false if no origins to process.
151    bool NextOriginToProcess(GURL* origin);
152
153    int64 GetTotalChangeCount() const;
154
155    // Update change_count_map_ for |origin|.
156    void SetOriginChangeCount(const GURL& origin, int64 changes);
157
158    void SetOriginEnabled(const GURL& origin, bool enabled);
159
160   private:
161    // Per-origin changes (cached info, could be stale).
162    Map change_count_map_;
163    Map::iterator next_;
164
165    // Holds a set of disabled (but initialized) origins.
166    std::set<GURL> disabled_origins_;
167  };
168
169  void DidInitializeFileSystemContext(
170      const GURL& app_origin,
171      fileapi::FileSystemContext* file_system_context,
172      const SyncStatusCallback& callback,
173      SyncStatusCode status);
174  void DidInitializeForRemoteSync(
175      const fileapi::FileSystemURL& url,
176      fileapi::FileSystemContext* file_system_context,
177      const PrepareChangeCallback& callback,
178      SyncStatusCode status);
179
180  // Runs local_sync_callback_ and resets it.
181  void RunLocalSyncCallback(
182      SyncStatusCode status,
183      const fileapi::FileSystemURL& url);
184
185  // Callbacks for ProcessLocalChange.
186  void DidGetFileForLocalSync(
187      SyncStatusCode status,
188      const LocalFileSyncInfo& sync_file_info,
189      scoped_ptr<webkit_blob::ScopedFile> snapshot);
190  void ProcessNextChangeForURL(
191      scoped_ptr<webkit_blob::ScopedFile> snapshot,
192      const LocalFileSyncInfo& sync_file_info,
193      const FileChange& last_change,
194      const FileChangeList& changes,
195      SyncStatusCode status);
196
197  Profile* profile_;
198
199  scoped_refptr<LocalFileSyncContext> sync_context_;
200
201  // Origin to context map. (Assuming that as far as we're in the same
202  // profile single origin wouldn't belong to multiple FileSystemContexts.)
203  std::map<GURL, fileapi::FileSystemContext*> origin_to_contexts_;
204
205  // Origins which have pending changes but have not been initialized yet.
206  // (Used only for handling dirty files left in the local tracker database
207  // after a restart.)
208  std::set<GURL> pending_origins_with_changes_;
209
210  OriginChangeMap origin_change_map_;
211
212  // This callback is non-null while a local sync is running (i.e.
213  // ProcessLocalChange has been called and has not been returned yet).
214  SyncFileCallback local_sync_callback_;
215
216  LocalChangeProcessor* local_change_processor_;
217
218  ObserverList<Observer> change_observers_;
219
220  DISALLOW_COPY_AND_ASSIGN(LocalFileSyncService);
221};
222
223}  // namespace sync_file_system
224
225#endif  // CHROME_BROWSER_SYNC_FILE_SYSTEM_LOCAL_LOCAL_FILE_SYNC_SERVICE_H_
226