- add sources.
[platform/framework/web/crosswalk.git] / src / chrome / browser / chromeos / drive / change_list_loader.h
1 // Copyright (c) 2012 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_CHROMEOS_DRIVE_CHANGE_LIST_LOADER_H_
6 #define CHROME_BROWSER_CHROMEOS_DRIVE_CHANGE_LIST_LOADER_H_
7
8 #include <map>
9 #include <set>
10 #include <string>
11 #include <vector>
12
13 #include "base/callback.h"
14 #include "base/memory/ref_counted.h"
15 #include "base/memory/scoped_ptr.h"
16 #include "base/memory/scoped_vector.h"
17 #include "base/observer_list.h"
18 #include "base/time/time.h"
19 #include "chrome/browser/chromeos/drive/file_errors.h"
20 #include "chrome/browser/google_apis/gdata_errorcode.h"
21
22 class GURL;
23
24 namespace base {
25 class SequencedTaskRunner;
26 }  // namespace base
27
28 namespace google_apis {
29 class AboutResource;
30 class ResourceList;
31 }  // namespace google_apis
32
33 namespace drive {
34
35 class DriveServiceInterface;
36 class JobScheduler;
37 class ResourceEntry;
38
39 namespace internal {
40
41 class ChangeList;
42 class ChangeListLoaderObserver;
43 class ChangeListProcessor;
44 class DirectoryFetchInfo;
45 class ResourceMetadata;
46
47 // Callback run as a response to SearchFromServer.
48 typedef base::Callback<void(ScopedVector<ChangeList> change_lists,
49                             FileError error)> LoadChangeListCallback;
50
51 // ChangeListLoader is used to load the change list, the full resource list,
52 // and directory contents, from WAPI (codename for Documents List API)
53 // or Google Drive API.  The class also updates the resource metadata with
54 // the change list loaded from the server.
55 //
56 // Note that the difference between "resource list" and "change list" is
57 // subtle hence the two words are often used interchangeably. To be precise,
58 // "resource list" refers to metadata from the server when fetching the full
59 // resource metadata, or fetching directory contents, whereas "change list"
60 // refers to metadata from the server when fetching changes (delta).
61 class ChangeListLoader {
62  public:
63   // Resource feed fetcher from the server.
64   class FeedFetcher;
65
66   ChangeListLoader(base::SequencedTaskRunner* blocking_task_runner,
67                    ResourceMetadata* resource_metadata,
68                    JobScheduler* scheduler,
69                    DriveServiceInterface* drive_service);
70   ~ChangeListLoader();
71
72   // Indicates whether there is a request for full resource list or change
73   // list fetching is in flight (i.e. directory contents fetching does not
74   // count).
75   bool IsRefreshing() const;
76
77   // Adds and removes the observer.
78   void AddObserver(ChangeListLoaderObserver* observer);
79   void RemoveObserver(ChangeListLoaderObserver* observer);
80
81   // Checks for updates on the server. Does nothing if the change list is now
82   // being loaded or refreshed. |callback| must not be null.
83   // Note: |callback| will be called if the check for updates actually
84   // runs, i.e. it may NOT be called if the checking is ignored.
85   void CheckForUpdates(const FileOperationCallback& callback);
86
87   // Starts the change list loading first from the cache. If loading from the
88   // cache is successful, runs |callback| immediately and starts checking
89   // server for updates in background. If loading from the cache is
90   // unsuccessful, starts loading from the server, and runs |callback| to tell
91   // the result to the caller when it is finished.
92   //
93   // If |directory_fetch_info| is not empty, the directory will be fetched
94   // first from the server, so the UI can show the directory contents
95   // instantly before the entire change list loading is complete.
96   //
97   // |callback| must not be null.
98   void LoadIfNeeded(const DirectoryFetchInfo& directory_fetch_info,
99                     const FileOperationCallback& callback);
100
101  private:
102   // Starts the resource metadata loading and calls |callback| when it's
103   // done. |directory_fetch_info| is used for fast fetch. If there is already
104   // a loading job in-flight for |directory_fetch_info|, just append the
105   // |callback| to the callback queue of the already running job.
106   void Load(const DirectoryFetchInfo& directory_fetch_info,
107             const FileOperationCallback& callback);
108
109   // Part of Load(). DoInitialLoad() is called if it is the first time to Load.
110   // Otherwise DoUpdateLoad() is used. The difference of two cases are:
111   // - When we could load from cache, DoInitialLoad runs callback immediately
112   //   and further operations (check changestamp and load from server if needed)
113   //   in background.
114   // - Even when |directory_fetch_info| is set, DoInitialLoad runs change list
115   //   loading after directory loading is finished.
116   void DoInitialLoad(const DirectoryFetchInfo& directory_fetch_info,
117                      int64 local_changestamp);
118   void DoUpdateLoad(const DirectoryFetchInfo& directory_fetch_info,
119                     int64 local_changestamp);
120
121   // Part of Load().
122   // This function should be called when the change list load is complete.
123   // Flushes the callbacks for change list loading and all directory loading.
124   void OnChangeListLoadComplete(FileError error);
125
126   // Part of Load().
127   // This function should be called when the directory load is complete.
128   // Flushes the callbacks waiting for the directory to be loaded.
129   void OnDirectoryLoadComplete(const DirectoryFetchInfo& directory_fetch_info,
130                                FileError error);
131
132   // ================= Implementation for change list loading =================
133
134   // Initiates the change list loading from the server when |local_changestamp|
135   // is older than the server changestamp. If |directory_fetch_info| is set,
136   // do directory loading before change list loading.
137   void LoadFromServerIfNeeded(const DirectoryFetchInfo& directory_fetch_info,
138                               int64 local_changestamp);
139
140   // Part of LoadFromServerIfNeeded().
141   // Called after GetAboutResource() for getting remote changestamp is complete.
142   void LoadFromServerIfNeededAfterGetAbout(
143       const DirectoryFetchInfo& directory_fetch_info,
144       int64 local_changestamp,
145       google_apis::GDataErrorCode status,
146       scoped_ptr<google_apis::AboutResource> about_resource);
147
148   // Part of LoadFromServerIfNeeded().
149   // When LoadFromServerIfNeeded is called with |directory_fetch_info| for a
150   // specific directory, it tries to load the directory before loading the
151   // content of full filesystem. This method is called after directory loading
152   // is finished, and proceeds to the normal pass: LoadChangeListServer.
153   void LoadFromServerIfNeededAfterLoadDirectory(
154       const DirectoryFetchInfo& directory_fetch_info,
155       scoped_ptr<google_apis::AboutResource> about_resource,
156       int64 start_changestamp,
157       FileError error);
158
159   // Part of LoadFromServerIfNeeded().
160   // Starts loading the change list since |start_changestamp|, or the full
161   // resource list if |start_changestamp| is zero. For full update, the
162   // largest_change_id and root_folder_id from |about_resource| will be used.
163   void LoadChangeListFromServer(
164       scoped_ptr<google_apis::AboutResource> about_resource,
165       int64 start_changestamp);
166
167   // Part of LoadChangeListFromServer().
168   // Called when the entire change list is loaded.
169   void LoadChangeListFromServerAfterLoadChangeList(
170       scoped_ptr<google_apis::AboutResource> about_resource,
171       bool is_delta_update,
172       FileError error,
173       ScopedVector<ChangeList> change_lists);
174
175   // Part of LoadChangeListFromServer().
176   // Called when the resource metadata is updated.
177   void LoadChangeListFromServerAfterUpdate();
178
179   // ================= Implementation for directory loading =================
180
181   // Compares the directory's changestamp and |last_known_remote_changestamp_|.
182   // Starts DoLoadDirectoryFromServer() if the local data is old and runs
183   // |callback| when finished. If it is up to date, calls back immediately.
184   void CheckChangestampAndLoadDirectoryIfNeeded(
185       const DirectoryFetchInfo& directory_fetch_info,
186       int64 local_changestamp,
187       const FileOperationCallback& callback);
188
189   // Loads the directory contents from server, and updates the local metadata.
190   // Runs |callback| when it is finished.
191   void DoLoadDirectoryFromServer(const DirectoryFetchInfo& directory_fetch_info,
192                                  const FileOperationCallback& callback);
193
194   // Part of DoLoadDirectoryFromServer() for the grand root ("/drive").
195   void DoLoadGrandRootDirectoryFromServerAfterGetResourceEntryByPath(
196       const DirectoryFetchInfo& directory_fetch_info,
197       const FileOperationCallback& callback,
198       FileError error,
199       scoped_ptr<ResourceEntry> entry);
200
201   // Part of DoLoadDirectoryFromServer() for the grand root ("/drive").
202   void DoLoadGrandRootDirectoryFromServerAfterGetAboutResource(
203       const DirectoryFetchInfo& directory_fetch_info,
204       const FileOperationCallback& callback,
205       google_apis::GDataErrorCode status,
206       scoped_ptr<google_apis::AboutResource> about_resource);
207
208   // Part of DoLoadDirectoryFromServer() for the grand root ("/drive").
209   void DoLoadDirectoryFromServerAfterAddMyDrive(
210       const DirectoryFetchInfo& directory_fetch_info,
211       const FileOperationCallback& callback,
212       std::string* local_id,
213       FileError error);
214
215   // Part of DoLoadDirectoryFromServer() for a normal directory.
216   void DoLoadDirectoryFromServerAfterLoad(
217       const DirectoryFetchInfo& directory_fetch_info,
218       const FileOperationCallback& callback,
219       FeedFetcher* fetcher,
220       FileError error,
221       ScopedVector<ChangeList> change_lists);
222
223   // Part of DoLoadDirectoryFromServer().
224   void DoLoadDirectoryFromServerAfterRefresh(
225       const DirectoryFetchInfo& directory_fetch_info,
226       const FileOperationCallback& callback,
227       const base::FilePath* directory_path,
228       FileError error);
229
230   // ================= Implementation for other stuff =================
231
232   // Updates from the whole change list collected in |change_lists|.
233   // Record file statistics as UMA histograms.
234   //
235   // See comments at ChangeListProcessor::Apply() for
236   // |about_resource| and |is_delta_update|.
237   // |callback| must not be null.
238   void UpdateFromChangeList(
239       scoped_ptr<google_apis::AboutResource> about_resource,
240       ScopedVector<ChangeList> change_lists,
241       bool is_delta_update,
242       const base::Closure& callback);
243
244   // Part of UpdateFromChangeList().
245   // Called when ChangeListProcessor::Apply() is complete.
246   // Notifies directory changes per the result of the change list processing.
247   void UpdateFromChangeListAfterApply(
248       ChangeListProcessor* change_list_processor,
249       bool should_notify,
250       base::Time start_time,
251       const base::Closure& callback,
252       FileError error);
253
254   scoped_refptr<base::SequencedTaskRunner> blocking_task_runner_;
255   ResourceMetadata* resource_metadata_;  // Not owned.
256   JobScheduler* scheduler_;  // Not owned.
257   DriveServiceInterface* drive_service_;  // Not owned.
258   ObserverList<ChangeListLoaderObserver> observers_;
259   typedef std::map<std::string, std::vector<FileOperationCallback> >
260       LoadCallbackMap;
261   LoadCallbackMap pending_load_callback_;
262   FileOperationCallback pending_update_check_callback_;
263
264   // Running feed fetcher.
265   scoped_ptr<FeedFetcher> change_feed_fetcher_;
266
267   // Set of the running feed fetcher for the fast fetch.
268   std::set<FeedFetcher*> fast_fetch_feed_fetcher_set_;
269
270   // The last known remote changestamp. Used to check if a directory
271   // changestamp is up-to-date for fast fetch.
272   int64 last_known_remote_changestamp_;
273
274   // The cache of the root_folder_id.
275   std::string root_folder_id_;
276
277   // True if the full resource list is loaded (i.e. the resource metadata is
278   // stored locally).
279   bool loaded_;
280
281   // Note: This should remain the last member so it'll be destroyed and
282   // invalidate its weak pointers before any other members are destroyed.
283   base::WeakPtrFactory<ChangeListLoader> weak_ptr_factory_;
284   DISALLOW_COPY_AND_ASSIGN(ChangeListLoader);
285 };
286
287 }  // namespace internal
288 }  // namespace drive
289
290 #endif  // CHROME_BROWSER_CHROMEOS_DRIVE_CHANGE_LIST_LOADER_H_