Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / components / drive / change_list_loader.h
blob16882cfa2f1bf1521fc20908eeade39d821010ce
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.
5 #ifndef COMPONENTS_DRIVE_CHANGE_LIST_LOADER_H_
6 #define COMPONENTS_DRIVE_CHANGE_LIST_LOADER_H_
8 #include <string>
9 #include <vector>
11 #include "base/callback.h"
12 #include "base/memory/ref_counted.h"
13 #include "base/memory/scoped_ptr.h"
14 #include "base/memory/scoped_vector.h"
15 #include "base/observer_list.h"
16 #include "base/threading/thread_checker.h"
17 #include "components/drive/file_errors.h"
18 #include "google_apis/drive/drive_api_error_codes.h"
19 #include "google_apis/drive/drive_common_callbacks.h"
21 class GURL;
23 namespace base {
24 class CancellationFlag;
25 class ScopedClosureRunner;
26 class SequencedTaskRunner;
27 class Time;
28 } // namespace base
30 namespace google_apis {
31 class AboutResource;
32 } // namespace google_apis
34 namespace drive {
36 class EventLogger;
37 class JobScheduler;
38 class ResourceEntry;
40 namespace internal {
42 class ChangeList;
43 class ChangeListLoaderObserver;
44 class ChangeListProcessor;
45 class DirectoryLoader;
46 class ResourceMetadata;
48 // Delays execution of tasks as long as more than one lock is alive.
49 // Used to ensure that ChangeListLoader does not cause race condition by adding
50 // new entries created by sync tasks before they do.
51 // All code which may add entries found on the server to the local metadata
52 // should use this class.
53 class LoaderController {
54 public:
55 LoaderController();
56 ~LoaderController();
58 // Increments the lock count and returns an object which decrements the count
59 // on its destruction.
60 // While the lock count is positive, tasks will be pending.
61 scoped_ptr<base::ScopedClosureRunner> GetLock();
63 // Runs the task if the lock count is 0, otherwise it will be pending.
64 void ScheduleRun(const base::Closure& task);
66 private:
67 // Decrements the lock count.
68 void Unlock();
70 int lock_count_;
71 std::vector<base::Closure> pending_tasks_;
73 base::ThreadChecker thread_checker_;
75 base::WeakPtrFactory<LoaderController> weak_ptr_factory_;
76 DISALLOW_COPY_AND_ASSIGN(LoaderController);
79 // This class is responsible to load AboutResource from the server and cache it.
80 class AboutResourceLoader {
81 public:
82 explicit AboutResourceLoader(JobScheduler* scheduler);
83 ~AboutResourceLoader();
85 // Returns the cached about resource.
86 // NULL is returned if the cache is not available.
87 const google_apis::AboutResource* cached_about_resource() const {
88 return cached_about_resource_.get();
91 // Gets the 'latest' about resource and asynchronously runs |callback|. I.e.,
92 // 1) If the last call to UpdateAboutResource call is in-flight, wait for it.
93 // 2) Otherwise, if the resource is cached, just returns the cached value.
94 // 3) If neither of the above hold, queries the API server by calling
95 // |UpdateAboutResource|.
96 void GetAboutResource(const google_apis::AboutResourceCallback& callback);
98 // Gets the about resource from the server, and caches it if successful. This
99 // function calls JobScheduler::GetAboutResource internally. The cache will be
100 // used in |GetAboutResource|.
101 void UpdateAboutResource(const google_apis::AboutResourceCallback& callback);
103 private:
104 // Part of UpdateAboutResource().
105 // This function should be called when the latest about resource is being
106 // fetched from the server. The retrieved about resource is cloned, and one is
107 // cached and the other is passed to callbacks associated with |task_id|.
108 void UpdateAboutResourceAfterGetAbout(
109 int task_id,
110 google_apis::DriveApiErrorCode status,
111 scoped_ptr<google_apis::AboutResource> about_resource);
113 JobScheduler* scheduler_;
114 scoped_ptr<google_apis::AboutResource> cached_about_resource_;
116 // Identifier to denote the latest UpdateAboutResource call.
117 int current_update_task_id_;
118 // Mapping from each UpdateAboutResource task ID to the corresponding
119 // callbacks. Note that there will be multiple callbacks for a single task
120 // when GetAboutResource is called before the task completes.
121 std::map<int, std::vector<google_apis::AboutResourceCallback> >
122 pending_callbacks_;
124 base::ThreadChecker thread_checker_;
126 base::WeakPtrFactory<AboutResourceLoader> weak_ptr_factory_;
127 DISALLOW_COPY_AND_ASSIGN(AboutResourceLoader);
130 // ChangeListLoader is used to load the change list, the full resource list,
131 // and directory contents, from Google Drive API. The class also updates the
132 // resource metadata with the change list loaded from the server.
134 // Note that the difference between "resource list" and "change list" is
135 // subtle hence the two words are often used interchangeably. To be precise,
136 // "resource list" refers to metadata from the server when fetching the full
137 // resource metadata, or fetching directory contents, whereas "change list"
138 // refers to metadata from the server when fetching changes (delta).
139 class ChangeListLoader {
140 public:
141 // Resource feed fetcher from the server.
142 class FeedFetcher;
144 ChangeListLoader(EventLogger* logger,
145 base::SequencedTaskRunner* blocking_task_runner,
146 ResourceMetadata* resource_metadata,
147 JobScheduler* scheduler,
148 AboutResourceLoader* about_resource_loader,
149 LoaderController* apply_task_controller);
150 ~ChangeListLoader();
152 // Indicates whether there is a request for full resource list or change
153 // list fetching is in flight (i.e. directory contents fetching does not
154 // count).
155 bool IsRefreshing() const;
157 // Adds and removes the observer.
158 void AddObserver(ChangeListLoaderObserver* observer);
159 void RemoveObserver(ChangeListLoaderObserver* observer);
161 // Checks for updates on the server. Does nothing if the change list is now
162 // being loaded or refreshed. |callback| must not be null.
163 // Note: |callback| will be called if the check for updates actually
164 // runs, i.e. it may NOT be called if the checking is ignored.
165 void CheckForUpdates(const FileOperationCallback& callback);
167 // Starts the change list loading if needed. If the locally stored metadata is
168 // available, runs |callback| immediately and starts checking server for
169 // updates in background. If the locally stored metadata is not available,
170 // starts loading from the server, and runs |callback| to tell the result to
171 // the caller when it is finished.
173 // |callback| must not be null.
174 void LoadIfNeeded(const FileOperationCallback& callback);
176 private:
177 // Starts the resource metadata loading and calls |callback| when it's done.
178 void Load(const FileOperationCallback& callback);
179 void LoadAfterGetLargestChangestamp(bool is_initial_load,
180 const int64* local_changestamp,
181 FileError error);
182 void LoadAfterGetAboutResource(
183 int64 local_changestamp,
184 google_apis::DriveApiErrorCode status,
185 scoped_ptr<google_apis::AboutResource> about_resource);
187 // Part of Load().
188 // This function should be called when the change list load is complete.
189 // Flushes the callbacks for change list loading and all directory loading.
190 void OnChangeListLoadComplete(FileError error);
192 // Called when the loading about_resource_loader_->UpdateAboutResource is
193 // completed.
194 void OnAboutResourceUpdated(google_apis::DriveApiErrorCode error,
195 scoped_ptr<google_apis::AboutResource> resource);
197 // ================= Implementation for change list loading =================
199 // Part of LoadFromServerIfNeeded().
200 // Starts loading the change list since |start_changestamp|, or the full
201 // resource list if |start_changestamp| is zero.
202 void LoadChangeListFromServer(int64 start_changestamp);
204 // Part of LoadChangeListFromServer().
205 // Called when the entire change list is loaded.
206 void LoadChangeListFromServerAfterLoadChangeList(
207 scoped_ptr<google_apis::AboutResource> about_resource,
208 bool is_delta_update,
209 FileError error,
210 ScopedVector<ChangeList> change_lists);
212 // Part of LoadChangeListFromServer().
213 // Called when the resource metadata is updated.
214 void LoadChangeListFromServerAfterUpdate(
215 ChangeListProcessor* change_list_processor,
216 bool should_notify_changed_directories,
217 const base::Time& start_time,
218 FileError error);
220 EventLogger* logger_; // Not owned.
221 scoped_refptr<base::SequencedTaskRunner> blocking_task_runner_;
222 scoped_ptr<base::CancellationFlag> in_shutdown_;
223 ResourceMetadata* resource_metadata_; // Not owned.
224 JobScheduler* scheduler_; // Not owned.
225 AboutResourceLoader* about_resource_loader_; // Not owned.
226 LoaderController* loader_controller_; // Not owned.
227 base::ObserverList<ChangeListLoaderObserver> observers_;
228 std::vector<FileOperationCallback> pending_load_callback_;
229 FileOperationCallback pending_update_check_callback_;
231 // Running feed fetcher.
232 scoped_ptr<FeedFetcher> change_feed_fetcher_;
234 // True if the full resource list is loaded (i.e. the resource metadata is
235 // stored locally).
236 bool loaded_;
238 base::ThreadChecker thread_checker_;
240 // Note: This should remain the last member so it'll be destroyed and
241 // invalidate its weak pointers before any other members are destroyed.
242 base::WeakPtrFactory<ChangeListLoader> weak_ptr_factory_;
243 DISALLOW_COPY_AND_ASSIGN(ChangeListLoader);
246 } // namespace internal
247 } // namespace drive
249 #endif // COMPONENTS_DRIVE_CHANGE_LIST_LOADER_H_