1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
|
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_CHROMEOS_DRIVE_CHANGE_LIST_LOADER_H_
#define CHROME_BROWSER_CHROMEOS_DRIVE_CHANGE_LIST_LOADER_H_
#include <map>
#include <string>
#include <vector>
#include "base/callback_forward.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/scoped_vector.h"
#include "base/observer_list.h"
#include "base/time.h"
#include "chrome/browser/chromeos/drive/file_errors.h"
#include "chrome/browser/google_apis/gdata_errorcode.h"
class GURL;
namespace google_apis {
class AboutResource;
class AppList;
class ResourceList;
} // namespace google_apis
namespace drive {
class ChangeList;
class ChangeListLoaderObserver;
class ChangeListProcessor;
class DirectoryFetchInfo;
class DriveWebAppsRegistry;
class JobScheduler;
class ResourceEntry;
namespace internal {
class ResourceMetadata;
} // namespace internal
// Callback run as a response to SearchFromServer.
typedef base::Callback<void(ScopedVector<ChangeList> change_lists,
FileError error)> LoadFeedListCallback;
// ChangeListLoader is used to load feeds from WAPI (codename for
// Documents List API) or Google Drive API and load the cached metadata.
class ChangeListLoader {
public:
ChangeListLoader(internal::ResourceMetadata* resource_metadata,
JobScheduler* scheduler,
DriveWebAppsRegistry* webapps_registry);
~ChangeListLoader();
// Indicates whether there is a feed refreshing server request is in flight.
bool IsRefreshing() const;
// Adds and removes the observer.
void AddObserver(ChangeListLoaderObserver* observer);
void RemoveObserver(ChangeListLoaderObserver* observer);
// Checks for updates on the server. Does nothing if the change list is now
// being loaded or refreshed. |callback| must not be null.
void CheckForUpdates(const FileOperationCallback& callback);
// Starts the change list loading first from the cache. If loading from the
// cache is successful, runs |callback| immediately and starts checking
// server for updates in background. If loading from the cache is
// unsuccessful, starts loading from the server, and runs |callback| to tell
// the result to the caller when it is finished.
//
// If |directory_fetch_info| is not empty, the directory will be fetched
// first from the server, so the UI can show the directory contents
// instantly before the entire change list loading is complete.
//
// |callback| must not be null.
void LoadIfNeeded(const DirectoryFetchInfo& directory_fetch_info,
const FileOperationCallback& callback);
// Initiates the directory contents loading. This function first obtains
// the changestamp from the server in order to set the per-directory
// changestamp for the directory.
//
// Upon completion, |callback| is invoked. On success, the changestamp of
// the directory is updated. |callback| must not be null.
//
// Note that This function initiates the loading without comparing the
// directory changestamp against the server changestamp. The primary
// purpose of this function is to update parts of entries in the directory
// which can stale over time, such as thumbnail URLs.
void LoadDirectoryFromServer(const std::string& directory_resource_id,
const FileOperationCallback& callback);
// TODO(satorux): Make this private. crbug.com/232208
// Updates whole directory structure feeds collected in |feed_list|.
// Record file statistics as UMA histograms.
//
// See comments at ChangeListProcessor::ApplyFeeds() for
// |about_resource| and |is_delta_feed|.
// |callback| must not be null.
void UpdateFromFeed(scoped_ptr<google_apis::AboutResource> about_resource,
ScopedVector<ChangeList> change_lists,
bool is_delta_feed,
const base::Closure& callback);
private:
// Start metadata loading of |directory_fetch_info|, and calls |callback|
// when it's done. If there is already a loading job in-flight for
// |directory_fetch_info|, just append the |callback| to the callback queue
// of the already running job.
void Load(const DirectoryFetchInfo& directory_fetch_info,
const FileOperationCallback& callback);
// Part of Load(). DoInitialLoad() is called if it is the first time to Load.
// Otherwise DoUpdateLoad() is used. The difference of two cases are:
// - When we could load from cache, DoInitialLoad runs callback immediately
// and further operations (check changestamp and load from server if needed)
// in background.
// - Even when |directory_fetch_info| is set, DoInitialLoad runs change list
// loading after directory loading is finished.
void DoInitialLoad(const DirectoryFetchInfo& directory_fetch_info,
int64 local_changestamp);
void DoUpdateLoad(const DirectoryFetchInfo& directory_fetch_info,
int64 local_changestamp);
// Part of Load().
// This function should be called when the change list load is complete.
// Flushes the callbacks for change list loading and all directory loading.
void OnChangeListLoadComplete(FileError error);
// Part of Load().
// This function should be called when the directory load is complete.
// Flushes the callbacks waiting for the directory to be loaded.
void OnDirectoryLoadComplete(const DirectoryFetchInfo& directory_fetch_info,
FileError error);
// ================= Implementation for change list loading =================
// Initiates the change list loading from the server when |local_changestamp|
// is older than the server changestamp. If |directory_fetch_info| is set,
// do directory loading before change list loading.
void LoadFromServerIfNeeded(const DirectoryFetchInfo& directory_fetch_info,
int64 local_changestamp);
// Part of LoadFromServerIfNeeded().
// Called after GetAboutResource() for getting remote changestamp is complete.
void LoadFromServerIfNeededAfterGetAbout(
const DirectoryFetchInfo& directory_fetch_info,
int64 local_changestamp,
google_apis::GDataErrorCode status,
scoped_ptr<google_apis::AboutResource> about_resource);
// Part of LoadFromServerIfNeeded().
// When LoadFromServerIfNeeded is called with |directory_fetch_info| for a
// specific directory, it tries to load the directory before loading the
// content of full filesystem. This method is called after directory loading
// is finished, and proceeds to the normal pass: LoadChangeListServer.
void LoadChangeListFromServerAfterLoadDirectory(
const DirectoryFetchInfo& directory_fetch_info,
scoped_ptr<google_apis::AboutResource> about_resource,
int64 start_changestamp,
FileError error);
// Part of LoadFromServerIfNeeded().
// Starts loading the change list since |start_changestamp|, or the full
// resource list if |start_changestamp| is zero. For full update, the
// largest_change_id and root_folder_id from |about_resource| will be used.
void LoadChangeListFromServer(
scoped_ptr<google_apis::AboutResource> about_resource,
int64 start_changestamp);
// Part of LoadFromServerIfNeeded().
// Callback to fetch all the resource list response from the server.
// After all the resource list are fetched, |callback|
// will be invoked with the collected change lists.
void OnGetResourceList(ScopedVector<ChangeList> change_lists,
const LoadFeedListCallback& callback,
base::TimeTicks start_time,
google_apis::GDataErrorCode status,
scoped_ptr<google_apis::ResourceList> data);
// Part of LoadFromServerIfNeeded().
// Applies the change list loaded from the server to local metadata storage.
void UpdateMetadataFromFeedAfterLoadFromServer(
scoped_ptr<google_apis::AboutResource> about_resource,
bool is_delta_feed,
ScopedVector<ChangeList> change_lists,
FileError error);
// Part of LoadFromServerIfNeeded().
// Called when UpdateMetadataFromFeedAfterLoadFromServer is finished.
void OnUpdateFromFeed();
// ================= Implementation for directory loading =================
// Part of LoadDirectoryFromServer().
// Called after GetAboutResource() for getting remote changestamp is complete.
// Note that it directly proceeds to DoLoadDirectoryFromServer() not going
// through CheckChangestampAndLoadDirectoryIfNeeded, because the purpose of
// LoadDirectoryFromServer is to force reloading regardless of changestamp.
void LoadDirectoryFromServerAfterGetAbout(
const std::string& directory_resource_id,
const FileOperationCallback& callback,
google_apis::GDataErrorCode status,
scoped_ptr<google_apis::AboutResource> about_resource);
// Compares the directory's changestamp and |last_known_remote_changestamp_|.
// Starts DoLoadDirectoryFromServer() if the local data is old and runs
// |callback| when finished. If it is up to date, calls back immediately.
void CheckChangestampAndLoadDirectoryIfNeeded(
const DirectoryFetchInfo& directory_fetch_info,
int64 local_changestamp,
const FileOperationCallback& callback);
// Loads the directory contents from server, and updates the local metadata.
// Runs |callback| when it is finished.
void DoLoadDirectoryFromServer(const DirectoryFetchInfo& directory_fetch_info,
const FileOperationCallback& callback);
// Part of DoLoadDirectoryFromServer() for the grand root ("/drive").
void DoLoadGrandRootDirectoryFromServerAfterGetResourceEntryByPath(
const DirectoryFetchInfo& directory_fetch_info,
const FileOperationCallback& callback,
FileError error,
scoped_ptr<ResourceEntry> entry);
// Part of DoLoadDirectoryFromServer() for the grand root ("/drive").
void DoLoadGrandRootDirectoryFromServerAfterGetAboutResource(
const DirectoryFetchInfo& directory_fetch_info,
const FileOperationCallback& callback,
google_apis::GDataErrorCode status,
scoped_ptr<google_apis::AboutResource> about_resource);
// Part of DoLoadDirectoryFromServer() for a normal directory.
void DoLoadDirectoryFromServerAfterLoad(
const DirectoryFetchInfo& directory_fetch_info,
const FileOperationCallback& callback,
ScopedVector<ChangeList> change_lists,
FileError error);
// Part of DoLoadDirectoryFromServer().
void DoLoadDirectoryFromServerAfterRefresh(
const DirectoryFetchInfo& directory_fetch_info,
const FileOperationCallback& callback,
FileError error,
const base::FilePath& directory_path);
// ================= Implementation for other stuff =================
// Callback for handling response from |DriveAPIService::GetAppList|.
// If the application list is successfully parsed, passes the list to
// Drive webapps registry.
void OnGetAppList(google_apis::GDataErrorCode status,
scoped_ptr<google_apis::AppList> app_list);
// Part of UpdateFromFeed().
// Callback for ChangeListProcessor::ApplyFeeds.
void NotifyDirectoryChangedAfterApplyFeed(bool should_notify,
base::Time start_time,
const base::Closure& callback);
internal::ResourceMetadata* resource_metadata_; // Not owned.
JobScheduler* scheduler_; // Not owned.
DriveWebAppsRegistry* webapps_registry_; // Not owned.
ObserverList<ChangeListLoaderObserver> observers_;
scoped_ptr<ChangeListProcessor> change_list_processor_;
typedef std::map<std::string, std::vector<FileOperationCallback> >
LoadCallbackMap;
LoadCallbackMap pending_load_callback_;
// Indicates whether there is a feed refreshing server request is in flight.
int64 last_known_remote_changestamp_;
// True if the file system feed is loaded from the cache or from the server.
bool loaded_;
// Note: This should remain the last member so it'll be destroyed and
// invalidate its weak pointers before any other members are destroyed.
base::WeakPtrFactory<ChangeListLoader> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(ChangeListLoader);
};
} // namespace drive
#endif // CHROME_BROWSER_CHROMEOS_DRIVE_CHANGE_LIST_LOADER_H_
|